frmSelectSame.bas 32 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713
  1. VERSION 5.00
  2. Begin {C62A69F0-16DC-11CE-9E98-00AA00574A4F} frmSelectSame
  3. Caption = "相似选择-魔改版 蘭雅"
  4. ClientHeight = 5775
  5. ClientLeft = 495
  6. ClientTop = 5895
  7. ClientWidth = 2625
  8. OleObjectBlob = "frmSelectSame.frx":0000
  9. ShowModal = 0 'False
  10. End
  11. Attribute VB_Name = "frmSelectSame"
  12. Attribute VB_GlobalNameSpace = False
  13. Attribute VB_Creatable = False
  14. Attribute VB_PredeclaredId = True
  15. Attribute VB_Exposed = False
  16. '// This is free and unencumbered software released into the public domain.
  17. '// For more information, please refer to https://github.com/hongwenjun
  18. '// Attribute VB_Name = "相似选择-魔改版 蘭雅" frmSelectSame 2023.6.12
  19. Option Explicit
  20. '需要显式声明所有变量。 这可以防止无意中使用缓慢的“Variant”类型变量,这些变量在特定类型未知时使用。
  21. 'Requires explicit declaration of all variables. This protects against inadvertent use of the slow 'Variant' type variables which are used when the specific type is unknown.
  22. Public ssreg As ShapeRange
  23. Private Const TOOLNAME As String = "VBA_SelectSame"
  24. Private Const SECTION As String = "Options"
  25. Private Sub btnSelect_Click()
  26. If 0 = ActiveSelectionRange.Count Then Exit Sub
  27. On Error GoTo ErrorHandler
  28. Dim fLeft As Double, fTop As Double
  29. fLeft = frmSelectSame.Left
  30. fTop = frmSelectSame.Top
  31. SaveSetting "SelectSame", "Preferences", "form_left", fLeft
  32. SaveSetting "SelectSame", "Preferences", "form_top", fTop
  33. '// 区域范围选择,需要关闭刷新优化
  34. If OptBt.value = False Then
  35. API.BeginOpt
  36. Else
  37. add_ssreg
  38. End If
  39. If (chkFill = False And chkOutline = False And chkOutlineColor = False And _
  40. chkOutlineLength = False And chkSize = False And chkWHratio = False And _
  41. chkType = False And chkNodes = False And chkSegments = False And _
  42. chkPaths = False And chkFontName = False And chkFontSize = False And chkShapeName = False) Then
  43. MsgBox "请至少选择一个选项", vbCritical, "Select Same"
  44. GoTo ErrorHandler
  45. End If
  46. '// "ME"是一个VBA保留字,返回对当前代码所在窗体(或类模块)的引用。 chk... 函数返回同名复选按钮的当前值。
  47. '// "ME" is a VBA reserved word, returning a reference to the form (or class module) in which the current code is located.
  48. '// The chk... functions return the current Value of the check buttons of the same name.
  49. With Me
  50. .SelectAllSimilar .chkFill, .chkOutline, .chkOutlineColor, .chkOutlineLength, _
  51. .chkSize, .chkWHratio, .chkType, .chkNodes, .chkSegments, .chkPaths, _
  52. .OptDoc, .Optpage, .Optlayer, .chkInGroups, .chkColorMark, .chkIndiv, _
  53. .chkFontName, .chkFontSize, .chkShapeName
  54. End With
  55. API.EndOpt
  56. Exit Sub
  57. ErrorHandler:
  58. Application.Optimization = False
  59. End Sub
  60. Sub SelectAllSimilar(Optional CheckFill As Boolean = True, _
  61. Optional CheckOutline As Boolean = True, _
  62. Optional CheckOutlineColor As Boolean = True, _
  63. Optional CheckOutlineLength As Boolean = True, _
  64. Optional CheckSize As Boolean = False, _
  65. Optional CheckWHratio As Boolean = False, _
  66. Optional CheckType As Boolean = True, _
  67. Optional CountNodes As Boolean = False, _
  68. Optional CountSegments As Boolean = False, _
  69. Optional CountPaths As Boolean = False, _
  70. Optional WithinDoc As Boolean = False, _
  71. Optional WithinPage As Boolean = True, _
  72. Optional WithinLayer As Boolean = False, _
  73. Optional WithinGroups As Boolean = True, _
  74. Optional CheckColorMark As Boolean = False, _
  75. Optional CheckIndiv As Boolean = True, _
  76. Optional CheckFontName As Boolean = False, _
  77. Optional CheckFontSize As Boolean = False, _
  78. Optional CheckShapeName As Boolean = False)
  79. 'Object variables. Reference to:
  80. Dim shpsSelected As Shapes 'selected shapes,
  81. Dim shpsToTest As Shapes 'full set of shapes to be tested, ' 待测形状全部集合
  82. Dim pagesr As ShapeRange 'pages shapes collection,
  83. Dim docsr As New ShapeRange
  84. Dim shpModel As Shape 'a pre-selected shape,
  85. Dim shpToMatch As Shape 'a shape to be matched,
  86. 'Dim oScript As Object 'CorelScript object,
  87. Dim clnModelShapes As Collection 'our list of pre-selected shapes, '定义源对象集合
  88. Dim clnSubShapes As Collection 'our list of shapes inside a group. '定义群组内的目标对象
  89. Dim P As Page, p1 As Page '文档中查找使用
  90. Dim shr As ShapeRange, sr As New ShapeRange
  91. Dim i As Integer ' '文档中循环查找计数使用
  92. Dim fsn As Shape '// 扩展功能: 字体字号标记名检测源对象
  93. On Error GoTo NothingSelected 'Get a reference to any
  94. Set shr = ActiveSelectionRange
  95. Set shpsSelected = ActiveDocument.Selection.Shapes
  96. ' On Error GoTo 0 'pre-selected shapes. 将文档中当前选中的范围作为源对象
  97. If shpsSelected.Count > 0 Then 'Gather the pre-selected shapes
  98. Set clnModelShapes = New Collection 'into a new collection for
  99. For Each shpModel In shpsSelected 'simple processing. 建立源对象集合
  100. clnModelShapes.Add shpModel
  101. Next
  102. '// 魔改分支 字体-字号-标记名
  103. If CheckFontName Or CheckFontSize Or CheckShapeName Then
  104. Set fsn = shr(1)
  105. End If
  106. '===================================
  107. ' TurnOptimizations cdrOptimizationOn
  108. '===================================
  109. If WithinPage Then
  110. If OptBt.value = True Then
  111. Set shpsToTest = ssreg.Shapes
  112. OptBt.value = 0
  113. API.BeginOpt
  114. Else
  115. Set shpsToTest = ActivePage.Shapes
  116. End If
  117. 'Ensure that "Edit across layers"
  118. 'is ON. Otherwise, selecting
  119. ' Set oScript = CorelScript 'across layers, followed by
  120. ' oScript.SetMultiLayer True 'grouping, can flatten all
  121. ' Set oScript = Nothing 'layers into one. 选中表示将对当前页面的所有对象与源对象进行匹配,否则只匹配当前图层的对象
  122. 'Replace the above with this line, CoreScript is not longer support X7+
  123. ActiveDocument.EditAcrossLayers = True
  124. End If
  125. If WithinLayer Then
  126. Set shpsToTest = ActivePage.ActiveLayer.Shapes
  127. End If
  128. If WithinDoc Then '在当前文档查找,将当前页面相应的对象加入到待比较范围
  129. For i = 1 To ActiveDocument.Pages.Count
  130. ActiveDocument.Pages(i).Activate
  131. Set p1 = ActiveDocument.Pages(i)
  132. Set pagesr = ActivePage.SelectShapesFromRectangle(0, p1.CenterY * 2, p1.CenterX * 2, 0, False).Shapes.all
  133. Debug.Print p1.CenterY * 2 & p1.CenterX * 2
  134. docsr.AddRange pagesr '各页面依次查找,相应的对象加入到待比较范围
  135. Next i
  136. Set shpsToTest = docsr.Shapes
  137. ' MsgBox "共有待比较对象 " & shpsToTest.Count & " 个"
  138. Label13.Caption = "共有待比较对象 " & shpsToTest.Count & " 个"
  139. 'p1.Activate
  140. End If
  141. If WithinGroups Then 'Check through flattened list.
  142. Set clnSubShapes = FlatShapeList(shpsToTest)
  143. '=======
  144. For Each shpToMatch In clnSubShapes
  145. If Not shpToMatch.Selected Then 'If the shape is not yet selected,
  146. '==================== 'check the models for a match.
  147. For Each shpModel In clnModelShapes
  148. If ShapesMatch(shpToMatch, shpModel, CheckFill, _
  149. CheckOutline, CheckOutlineColor, CheckOutlineLength, CheckSize, CheckWHratio, _
  150. CheckType, CountNodes, CountSegments, CountPaths, CheckIndiv) Then
  151. 'shpToMatch.AddToSelection
  152. sr.Add shpToMatch
  153. Exit For 'If a match has now been found,
  154. End If 'we can skip any remaining models.
  155. Next
  156. '=====================
  157. End If
  158. Next
  159. '=======
  160. Else 'Check through top-level list.
  161. For Each shpToMatch In shpsToTest
  162. If Not shpToMatch.Selected Then 'If the shape is not yet selected,
  163. 'check the models for a match.
  164. For Each shpModel In clnModelShapes
  165. If ShapesMatch(shpToMatch, shpModel, CheckFill, _
  166. CheckOutline, CheckOutlineColor, CheckOutlineLength, CheckSize, CheckWHratio, _
  167. CheckType, CountNodes, CountSegments, CountPaths, CheckIndiv) Then
  168. 'shpToMatch.AddToSelection
  169. sr.Add shpToMatch
  170. Exit For 'If a match has now been found,
  171. End If 'we can skip any remaining models.
  172. Next
  173. End If
  174. Next
  175. End If
  176. '===================================
  177. ' TurnOptimizations cdrOptimizationOff
  178. 'CorelScript.RedrawScreen
  179. '===================================
  180. 'sr.Add ActiveDocument.Selection
  181. If CheckColorMark And sr.Count > 0 Then sr.SetOutlineProperties , , CreateCMYKColor(0, 100, 0, 0) '轮廓线上色
  182. sr.AddRange shr
  183. '// 魔改分支 字体-字号-标记名
  184. If CheckFontName Or CheckFontSize Or CheckShapeName Then
  185. If CheckFontName Then ShapesMatch_Font_Name fsn, sr, "FontName"
  186. If CheckFontSize Then ShapesMatch_Font_Name fsn, sr, "FontSize"
  187. If CheckShapeName Then ShapesMatch_Font_Name fsn, sr, "ShapeName"
  188. End If
  189. sr.CreateSelection
  190. '// 显示找到对象
  191. Label13.Caption = "共找到 " & sr.Count & " 个对象"
  192. End If
  193. Set clnModelShapes = Nothing 'Release the memory allocated
  194. Set shpsToTest = Nothing
  195. Exit Sub
  196. NothingSelected:
  197. End Sub
  198. '// 添加区域选择分支
  199. Private Function add_ssreg()
  200. Dim ssr As ShapeRange, shr As ShapeRange
  201. Dim x1 As Double, y1 As Double, x2 As Double, y2 As Double
  202. Dim Shift As Long
  203. Dim b As Boolean
  204. Set shr = ActiveSelectionRange
  205. b = ActiveDocument.GetUserArea(x1, y1, x2, y2, Shift, 10, False, cdrCursorWeldSingle)
  206. If Not b Then
  207. Set ssreg = ActivePage.SelectShapesFromRectangle(x1, y1, x2, y2, True).Shapes.all
  208. End If
  209. ActiveDocument.ClearSelection
  210. shr.CreateSelection
  211. End Function
  212. '// 魔改分支 字体-字号-标记名 检查匹配
  213. Private Function ShapesMatch_Font_Name(ByVal fsn As Shape, sr As ShapeRange, Check_Case As String)
  214. Dim xz As String, sh_name As String, strFontName As String
  215. Dim FontSize As Double
  216. Dim srText As ShapeRange
  217. Set srText = sr.Shapes.FindShapes(Type:=cdrTextShape)
  218. Select Case Check_Case
  219. Case "FontName"
  220. If fsn.Type = cdrTextShape Then
  221. strFontName = fsn.text.Story.Font
  222. Set sr = srText.Shapes.FindShapes(Query:="@type ='text:artistic' or @type ='text:paragraph' and @com.text.story.font = '" & strFontName & "'")
  223. End If
  224. Case "FontSize"
  225. If fsn.Type = cdrTextShape Then
  226. FontSize = fsn.text.Story.size
  227. Set sr = srText.Shapes.FindShapes(Query:="@type ='text:artistic' or @type ='text:paragraph' and (@com.text.story.size - " & FontSize & ").abs() < 0.1 ")
  228. End If
  229. Case "ShapeName"
  230. sh_name = fsn.Name
  231. Set sr = sr.Shapes.FindShapes(Query:="@name ='" & sh_name & "'")
  232. End Select
  233. End Function
  234. Private Function ShapesMatch(shpShape As Shape, shpModel As Shape, _
  235. Optional CheckFill As Boolean = True, _
  236. Optional CheckOutline As Boolean = True, _
  237. Optional CheckOutlineColor As Boolean = True, _
  238. Optional CheckOutlineLength As Boolean = True, _
  239. Optional CheckSize As Boolean = False, _
  240. Optional CheckWHratio As Boolean = False, _
  241. Optional CheckType As Boolean = True, _
  242. Optional CountNodes As Boolean = False, _
  243. Optional CountSegments As Boolean = False, _
  244. Optional CountPaths As Boolean = False, _
  245. Optional CheckIndiv As Boolean = False) As Boolean
  246. 'Sizes "match" if they differ by less than one per cent
  247. Dim ToleranceSize As Double '面积大小允许波动
  248. ToleranceSize = Me.TextBox1 / 100 '面积大小允许波动,以百分比为单位
  249. Dim ToleranceLength As Double '线长允许波动
  250. ToleranceLength = Me.TextBox2 / 100 '长度允许波动,以百分比为单位
  251. Dim ToleranceNodesCount As Long '节点数量允许波动,以 点 单位
  252. ToleranceNodesCount = Me.TextBox3 '节点数量允许波动,以 点 单位
  253. Dim ToleranceSubPathsCount As Long '子路径 子线段 允许波动,以 条 为单位
  254. ToleranceSubPathsCount = Me.TextBox4 '子路径 子线段 允许波动,以 条 为单位
  255. Dim ToleranceWHratio As Double '长宽比 允许波动,以 百分比 为单位
  256. ToleranceWHratio = Me.TextBox5 '长宽比 允许波动,以 百分比 为单位
  257. Dim ToleranceSegmentsCount As Long '线段数 允许波动,以 个 为单位
  258. ToleranceSegmentsCount = Me.TextBox6 '线段数 允许波动,以 个 为单位
  259. 'Object Variables. 'Reference to:
  260. Dim clrModel As Color 'color features of model shape,
  261. Dim clrShape As Color 'color features of shape to be tested
  262. Dim fillModel As Fill 'fill style of model shape,
  263. Dim outlnModel As Outline 'outline style of model shape,
  264. Dim crvModel As Curve 'Bezier curve of model shape,
  265. Dim crvShape As Curve 'Bezier curve of shape to be tested,
  266. Dim fntModel As StructFontProperties 'font properties of model text shape,
  267. Dim trgModel As text 'general text properties of model shape.
  268. Dim spath As SubPath, opath As SubPath
  269. Dim j As Integer
  270. 'Simple Variables. Storage of:
  271. Dim dblWidth As Double 'width of a shape,
  272. Dim dblHeight As Double 'height of a shape,
  273. Dim lngShapeType As cdrShapeType 'code for type of shape to be tested,
  274. Dim lngModelType As cdrShapeType 'code for the type of a model shape,
  275. Dim lngType As Long 'code for the type of a fill, color,
  276. 'or outline.
  277. 'Does the SHAPE match the MODEL ?
  278. 'Exit immediately on any mismatch.
  279. With shpShape
  280. lngShapeType = .Type 'Same basic TYPE of shape ?
  281. lngModelType = shpModel.Type
  282. If CheckType Then If lngShapeType <> lngModelType Then GoTo NoMatch
  283. 'A GROUP ? delegate to GroupsMatch()
  284. ' If lngShapeType = cdrGroupShape Then
  285. ' ShapesMatch = GroupsMatch(shpShape, shpModel, CheckSize, _
  286. ' CountNodes, CountPaths)
  287. ' Exit Function
  288. ' End If
  289. 'Does SIZE count ? Is so, are the
  290. If CheckSize Then 'size differences significant ?
  291. dblWidth = shpModel.SizeWidth
  292. If Abs(.SizeWidth - dblWidth) > (dblWidth * _
  293. ToleranceSize) Then GoTo NoMatch
  294. dblHeight = shpModel.SizeHeight
  295. If Abs(.SizeHeight - dblHeight) > (dblHeight * _
  296. ToleranceSize) Then GoTo NoMatch
  297. End If
  298. If CheckWHratio Then 'size width and height ratio differences significant ?
  299. dblWidth = shpModel.SizeWidth
  300. dblHeight = shpModel.SizeHeight
  301. If Abs(.SizeHeight / .SizeWidth - dblHeight / dblWidth) > (dblHeight / dblWidth * ToleranceWHratio) Then GoTo NoMatch
  302. End If
  303. If CountNodes Or CountPaths Or CheckOutlineLength Or CountSegments Then
  304. 'Only Curves can match ...
  305. If lngShapeType <> cdrCurveShape Then GoTo NoMatch
  306. Set crvShape = .Curve
  307. Set crvModel = shpModel.Curve
  308. 'If CheckIndiv Then '逐条子路径比较
  309. 'If Abs(crvShape.SubPaths.Count - crvModel.SubPaths.Count) <> 0 Then GoTo NoMatch
  310. 'For j = 1 To crvShape.SubPaths.Count
  311. 'If Abs(crvShape.SubPath(j).Nodes.Count - crvModel.SubPath(j).Nodes.Count) > ToleranceNodesCount Then GoTo NoMatch
  312. 'Next j
  313. If CountPaths Then 'Do the PATH counts match ?
  314. If VersionMajor > 12 Then 'GDG ##########################################
  315. If Abs(crvShape.SubPaths.Count - crvModel.SubPaths.Count) > ToleranceSubPathsCount Then GoTo NoMatch
  316. 'MsgBox "subpaths1: " & crvShape.SubPaths.Count & "subpaths2: " & crvModel.SubPaths.Count
  317. Else
  318. If Abs(crvShape.SubPathCount - crvModel.SubPathCount) > ToleranceSubPathsCount Then GoTo NoMatch
  319. End If 'GDG #############################################################
  320. End If
  321. If CountNodes Then 'Do the NODE counts match ?
  322. If VersionMajor > 12 Then 'GDG ##########################################
  323. If Abs(crvShape.Nodes.Count - crvModel.Nodes.Count) > ToleranceNodesCount Then GoTo NoMatch
  324. Else
  325. If Abs(crvShape.NodeCount - crvModel.NodeCount) > ToleranceNodesCount Then GoTo NoMatch
  326. End If 'GDG #############################################################
  327. End If
  328. If CountSegments Then 'Do the Segments counts match ?
  329. If VersionMajor > 12 Then 'GDG ##########################################
  330. If Abs(crvShape.Segments.Count - crvModel.Segments.Count) > ToleranceSegmentsCount Then GoTo NoMatch
  331. Else
  332. If Abs(crvShape.SegmentCount - crvModel.SegmentCount) > ToleranceSegmentsCount Then GoTo NoMatch
  333. End If 'GDG #############################################################
  334. End If
  335. If CheckOutlineLength Then 'Do the curve length match ?
  336. If VersionMajor > 12 Then 'GDG ##########################################
  337. If Abs(crvShape.Length - crvModel.Length) > crvModel.Length * ToleranceLength Then GoTo NoMatch
  338. 'MsgBox "subpaths1: " & crvShape.SubPaths.Count & "subpaths2: " & crvModel.SubPaths.Count
  339. Else
  340. If Abs(crvShape.Length - crvModel.Length) > crvModel.Length * ToleranceLength Then GoTo NoMatch
  341. End If 'GDG #############################################################
  342. End If
  343. End If
  344. If CheckFill Then
  345. Set fillModel = shpModel.Fill
  346. With .Fill 'Is the FILL type the same ?
  347. lngType = .Type
  348. If lngType <> shpModel.Fill.Type Then GoTo NoMatch
  349. If lngType = cdrUniformFill Then
  350. 'Does the uniform fill match ?
  351. If VersionMajor > 12 Then 'GDG ##########################################
  352. 'GDG ##########################################
  353. Dim col1 As New Color
  354. col1.CopyAssign .UniformColor
  355. Dim col2 As New Color
  356. col2.CopyAssign shpModel.Fill.UniformColor
  357. 'GDG ##########################################
  358. If col1.IsSame(col2) = False Then GoTo NoMatch
  359. Else
  360. Set clrModel = fillModel.UniformColor
  361. lngType = .UniformColor.Type
  362. If lngType <> clrModel.Type Then GoTo NoMatch
  363. If .UniformColor.Name(True) <> clrModel.Name(True) Then GoTo NoMatch
  364. End If 'GDG #############################################################
  365. End If
  366. End With
  367. End If
  368. If CheckOutline Then '(Groups have no outline)
  369. If lngShapeType <> cdrGroupShape Then
  370. Set outlnModel = shpModel.Outline
  371. If Not outlnModel Is Nothing Then
  372. With .Outline
  373. lngType = .Type
  374. If lngType <> outlnModel.Type Then GoTo NoMatch
  375. If lngType > 0 Then 'Does the shape have an OUTLINE ?
  376. 'Same LINE WIDTH ?
  377. If .Width <> outlnModel.Width Then GoTo NoMatch
  378. 'Matching LINE COLOR ?
  379. ' Set clrShape = .Color
  380. ' lngType = clrShape.Type
  381. ' Set clrModel = outlnModel.Color
  382. ' If lngType <> clrModel.Type Then GoTo NoMatch
  383. ' If clrShape.Name(True) <> clrModel.Name(True) Then GoTo NoMatch
  384. End If
  385. End With
  386. End If
  387. End If
  388. End If
  389. If CheckOutlineColor Then '(Groups have no outline)
  390. If lngShapeType <> cdrGroupShape Then
  391. Set outlnModel = shpModel.Outline
  392. If Not outlnModel Is Nothing Then
  393. With .Outline
  394. lngType = .Type
  395. If lngType <> outlnModel.Type Then GoTo NoMatch
  396. If lngType > 0 Then 'Does the shape have an OUTLINE ?
  397. 'Matching LINE COLOR ?
  398. If VersionMajor > 12 Then 'GDG ##########################################
  399. 'GDG ##########################################
  400. Dim col3 As New Color
  401. col3.CopyAssign .Color
  402. Dim col4 As New Color
  403. col4.CopyAssign shpModel.Outline.Color
  404. 'GDG ##########################################
  405. If col3.IsSame(col4) = False Then GoTo NoMatch
  406. Else
  407. Set clrShape = .Color
  408. lngType = clrShape.Type
  409. Set clrModel = outlnModel.Color
  410. If lngType <> clrModel.Type Then GoTo NoMatch
  411. If clrShape.Name(True) <> clrModel.Name(True) _
  412. Then GoTo NoMatch
  413. End If
  414. End If
  415. End With
  416. End If
  417. End If
  418. End If
  419. End With
  420. ShapesMatch = True
  421. Exit Function
  422. NoMatch:
  423. ShapesMatch = False
  424. NoMatchExit:
  425. ShapesMatch = False
  426. Exit Function
  427. End Function
  428. Private Function GroupsMatch(Group As Shape, GroupModel As Shape, _
  429. Optional CheckFill As Boolean = True, _
  430. Optional CheckOutline As Boolean = True, _
  431. Optional CheckOutlineColor As Boolean = True, _
  432. Optional CheckOutlineLength As Boolean = True, _
  433. Optional CheckSize As Boolean = False, _
  434. Optional CheckType As Boolean = True, _
  435. Optional CountNodes As Boolean = False, _
  436. Optional CountPaths As Boolean = False) As Boolean
  437. 'Object Variables. Reference to:
  438. Dim shpsModels As Shapes 'shapes in the pre-selected group,
  439. Dim shpsInGroup As Shapes 'shapes in the group to be tested,
  440. Dim shpModel As Shape 'a shape in the pre-selected group,
  441. Dim shpInGroup As Shape 'a shape in the group to be tested.
  442. 'Simple Variables Storage of:
  443. Dim lngInGroup As Long 'number of shapes in a group,
  444. Dim i As Long 'a numeric index to a
  445. 'particular sub-group.
  446. 'On Error GoTo NoMatch 'Shape & model must be groups.
  447. Set shpsModels = GroupModel.Shapes
  448. Set shpsInGroup = Group.Shapes
  449. 'On Error GoTo 0
  450. 'Same number of shapes
  451. lngInGroup = shpsModels.Count 'in each group ?
  452. If shpsInGroup.Count <> lngInGroup Then GoTo NoMatch
  453. For i = 1 To lngInGroup 'Try to Match all sub-shapes,
  454. Set shpInGroup = shpsInGroup(i) 'and GroupsMatch all sub-groups.
  455. Set shpModel = shpsModels(i)
  456. If shpModel.Type <> cdrGroupShape Then
  457. If Not ShapesMatch(shpInGroup, shpModel, _
  458. CheckSize, CountNodes) Then GoTo NoMatch
  459. Else
  460. If Not GroupsMatch(shpInGroup, shpModel, _
  461. CheckSize, CountNodes) Then GoTo NoMatch
  462. End If
  463. Next i
  464. GroupsMatch = True
  465. Exit Function
  466. NoMatch:
  467. GroupsMatch = False
  468. End Function
  469. Private Function FlatShapeList(TopLevelShapes As Shapes) As Collection
  470. 'Object Variables. Reference to:
  471. Dim shpTopLevel As Shape 'a top-level shape,
  472. Dim shpInGroup As Shape 'a shape inside a group,
  473. Dim clnAllShapes As Collection 'our list of all members and
  474. 'descendants of TopLevelShapes.
  475. If TopLevelShapes.Count Then
  476. Set clnAllShapes = New Collection
  477. For Each shpTopLevel In TopLevelShapes
  478. 'Add shape to list, keyed under
  479. 'a string version of its unique ID
  480. clnAllShapes.Add shpTopLevel
  481. 'If the shape is a group, then
  482. 'also gather all its descendants
  483. 'and add them to the list.
  484. If shpTopLevel.Type = cdrGroupShape Then
  485. For Each shpInGroup In ShapesInGroup(shpTopLevel)
  486. clnAllShapes.Add shpInGroup
  487. Next
  488. End If
  489. Next
  490. Set FlatShapeList = clnAllShapes 'Return the assembled collection.
  491. Else
  492. Set FlatShapeList = Nothing
  493. End If
  494. End Function
  495. Private Function ShapesInGroup(GroupShape As Shape) As Collection
  496. 'Object Variables. Reference to:
  497. Dim shpsInGroup As Shapes 'the set of shapes inside a group,
  498. Dim shpInGroup As Shape 'a particular shape in a group,
  499. Dim shpNested As Shape 'a shape inside a sub-group,
  500. Dim clnShapeList As Collection 'our list of all nested shapes.
  501. If GroupShape.Type = cdrGroupShape Then
  502. Set shpsInGroup = GroupShape.Shapes 'Get a reference to the
  503. 'shapes in this group.
  504. Set clnShapeList = New Collection
  505. For Each shpInGroup In shpsInGroup
  506. clnShapeList.Add shpInGroup 'Add all shapes in the group to
  507. 'our main collection.
  508. If shpInGroup.Type = cdrGroupShape Then
  509. 'Recurse to get nested shapes.
  510. For Each shpNested In ShapesInGroup(shpInGroup)
  511. clnShapeList.Add shpNested
  512. Next
  513. End If
  514. Next
  515. Set ShapesInGroup = clnShapeList 'Return the assembled collection.
  516. Else
  517. Set ShapesInGroup = Nothing 'Release the memory if the
  518. End If 'collection is not needed
  519. End Function
  520. Private Sub UserForm_Activate()
  521. Const YES As String = "True"
  522. Const NO As String = "False"
  523. OptDoc = GetSetting(TOOLNAME, SECTION, "InDoc", NO)
  524. Optlayer = GetSetting(TOOLNAME, SECTION, "InLayer", NO)
  525. Optpage = GetSetting(TOOLNAME, SECTION, "InPage", YES)
  526. chkColorMark = GetSetting(TOOLNAME, SECTION, "ColorMark", YES)
  527. chkFill = GetSetting(TOOLNAME, SECTION, "Fill", YES)
  528. chkInGroups = GetSetting(TOOLNAME, SECTION, "InGroups", YES)
  529. chkNodes = GetSetting(TOOLNAME, SECTION, "Nodes", NO)
  530. chkSegments = GetSetting(TOOLNAME, SECTION, "Segments", NO)
  531. chkOutline = GetSetting(TOOLNAME, SECTION, "Outline", YES)
  532. chkOutlineColor = GetSetting(TOOLNAME, SECTION, "OutlineColor", NO)
  533. chkOutlineLength = GetSetting(TOOLNAME, SECTION, "OutlineLength", YES)
  534. chkPaths = GetSetting(TOOLNAME, SECTION, "Paths", NO)
  535. chkSize = GetSetting(TOOLNAME, SECTION, "Size", NO)
  536. chkWHratio = GetSetting(TOOLNAME, SECTION, "WHratio", NO)
  537. chkType = GetSetting(TOOLNAME, SECTION, "Type", YES)
  538. chkIndiv = GetSetting(TOOLNAME, SECTION, "Indiv", NO)
  539. chkColorMark = GetSetting(TOOLNAME, SECTION, "ColorMark", NO)
  540. saveFormPos False
  541. End Sub
  542. Private Sub UserForm_QueryClose(Cancel As Integer, CloseMode As Integer)
  543. saveFormPos True
  544. End Sub
  545. Sub saveFormPos(bDoSave As Boolean)
  546. Dim dL, dT
  547. If bDoSave Then 'save position
  548. SaveSetting TOOLNAME, SECTION, "form_left", Me.Left
  549. SaveSetting TOOLNAME, SECTION, "form_top", Me.Top
  550. Else 'place instead.
  551. dL = GetSetting(TOOLNAME, SECTION, "form_left", 900)
  552. dT = GetSetting(TOOLNAME, SECTION, "form_top", 200)
  553. Me.Left = dL: Me.Top = dT
  554. End If
  555. End Sub
  556. Private Sub OptDoc_Click()
  557. SaveSetting TOOLNAME, SECTION, "InDoc", CStr(OptDoc)
  558. End Sub
  559. Private Sub Optlayer_Click()
  560. SaveSetting TOOLNAME, SECTION, "InLayer", CStr(Optlayer)
  561. End Sub
  562. Private Sub Optpage_Click()
  563. SaveSetting TOOLNAME, SECTION, "InPage", CStr(Optpage)
  564. End Sub
  565. Private Sub chkColorMark_Click()
  566. SaveSetting TOOLNAME, SECTION, "ColorMark", CStr(chkColorMark)
  567. End Sub
  568. Private Sub chkIndiv_Click()
  569. SaveSetting TOOLNAME, SECTION, "Indiv", CStr(chkIndiv)
  570. End Sub
  571. Private Sub chkFill_Click()
  572. SaveSetting TOOLNAME, SECTION, "Fill", CStr(chkFill)
  573. End Sub
  574. Private Sub chkInGroups_Click()
  575. SaveSetting TOOLNAME, SECTION, "InGroups", CStr(chkInGroups)
  576. End Sub
  577. Private Sub chkNodes_Click()
  578. SaveSetting TOOLNAME, SECTION, "Nodes", CStr(chkNodes)
  579. End Sub
  580. Private Sub chkSegments_Click()
  581. SaveSetting TOOLNAME, SECTION, "Segments", CStr(chkSegments)
  582. End Sub
  583. Private Sub chkOutline_Click()
  584. SaveSetting TOOLNAME, SECTION, "Outline", CStr(chkOutline)
  585. End Sub
  586. Private Sub chkOutlineColor_Click()
  587. SaveSetting TOOLNAME, SECTION, "OutlineColor", CStr(chkOutlineColor)
  588. End Sub
  589. Private Sub chkPaths_Click()
  590. SaveSetting TOOLNAME, SECTION, "Paths", CStr(chkPaths)
  591. End Sub
  592. Private Sub chkSize_Click()
  593. SaveSetting TOOLNAME, SECTION, "Size", CStr(chkSize)
  594. End Sub
  595. Private Sub chkWHratio_Click()
  596. SaveSetting TOOLNAME, SECTION, "WHratio", CStr(chkWHratio)
  597. End Sub
  598. Private Sub chkType_Click()
  599. SaveSetting TOOLNAME, SECTION, "Type", CStr(chkType)
  600. End Sub
  601. Private Sub chkOutLineLength_Click()
  602. SaveSetting TOOLNAME, SECTION, "OutlineLength", CStr(chkOutlineLength)
  603. End Sub