├── .gitignore
├── LICENSE
├── README.md
├── images
└── demo.gif
└── src
├── FormDesigner.Demo
├── ComponentsForm.dfm
├── ComponentsForm.pas
├── DesignForm.dfm
├── DesignForm.pas
├── FormDesigner.Demo.dpr
├── FormDesigner.Demo.dproj
├── FormDesigner.Demo.ico
├── Images
│ ├── tbutton.png
│ ├── tcheckbox.png
│ ├── tcombobox.png
│ ├── tedit.png
│ ├── tgroupbox.png
│ ├── tlabel.png
│ ├── tlistbox.png
│ ├── tmemo.png
│ ├── tpanel.png
│ ├── tprogressbar.png
│ ├── tradiobutton.png
│ ├── tradiogroup.png
│ └── tshape.png
└── fdUtils.pas
├── FormDesigner.Package
├── FormDesigner.Designer.pas
├── FormDesigner.DragHandles.pas
├── FormDesigner.Interfaces.pas
├── FormDesigner.Package.dpk
├── FormDesigner.Package.dproj
├── FormDesigner.Utils.pas
└── TFORMDESIGNER.PNG
└── FormDesigner.groupproj
/.gitignore:
--------------------------------------------------------------------------------
1 |
2 | # Created by https://www.gitignore.io/api/delphi
3 | # Edit at https://www.gitignore.io/?templates=delphi
4 |
5 | ### Delphi ###
6 | # Uncomment these types if you want even more clean repository. But be careful.
7 | # It can make harm to an existing project source. Read explanations below.
8 | #
9 |
10 | # Resource files are binaries containing manifest, project icon and version info.
11 | # They can not be viewed as text or compared by diff-tools. Consider replacing them with .rc files.
12 | *.res
13 |
14 | # Type library file (binary). In old Delphi versions it should be stored.
15 | # Since Delphi 2009 it is produced from .ridl file and can safely be ignored.
16 | #*.tlb
17 | # Diagram Portfolio file. Used by the diagram editor up to Delphi 7.
18 | # Uncomment this if you are not using diagrams or use newer Delphi version.
19 | #*.ddp
20 | # Visual LiveBindings file. Added in Delphi XE2.
21 | # Uncomment this if you are not using LiveBindings Designer.
22 | #*.vlb
23 | # Deployment Manager configuration file for your project. Added in Delphi XE2.
24 | # Uncomment this if it is not mobile development and you do not use remote debug feature.
25 | #*.deployproj
26 | # C++ object files produced when C/C++ Output file generation is configured.
27 | # Uncomment this if you are not using external objects (zlib library for example).
28 | #*.obj
29 |
30 | # Delphi compiler-generated binaries (safe to delete)
31 | *.exe
32 | *.dll
33 | *.bpl
34 | *.bpi
35 | *.dcp
36 | *.so
37 | *.apk
38 | *.drc
39 | *.map
40 | *.dres
41 | *.rsm
42 | *.tds
43 | *.dcu
44 | *.lib
45 | *.a
46 | *.o
47 | *.ocx
48 |
49 | # Delphi autogenerated files (duplicated info)
50 | *.cfg
51 | *.hpp
52 | *Resource.rc
53 |
54 | # Delphi local files (user-specific info)
55 | *.local
56 | *.identcache
57 | *.projdata
58 | *.tvsconfig
59 | *.dsk
60 |
61 | # Delphi history and backups
62 | __history/
63 | __recovery/
64 | *.~*
65 |
66 | # Castalia statistics file (since XE7 Castalia is distributed with Delphi)
67 | *.stat
68 |
69 | # Boss dependency manager vendor folder https://github.com/HashLoad/boss
70 | modules/
71 |
72 | # End of https://www.gitignore.io/api/delphi
73 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2019 havlicekp
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # Form Designer component for Delphi (VCL)
2 |
3 | 
4 |
5 | Form Designer (TFormDesigner) can be used to design and modify Delphi (VCL) forms at runtime. The behavior and appearance is similar to that of Delphi IDE.
6 |
7 | The repository contains both the TFormDesigner component and Demo project.
8 |
9 | ## Installation
10 |
11 | 1. Download or clone the repository and open grouped project ``src\FormDesigner.groupproj``.
12 | 2. Right-click on the FormDesigner.Package.dproj and choose **Install**.
13 | 3. **Form Designer** tab will appear on your Component Toolbar.
14 |
15 | ## Usage
16 |
17 | 1. Drop the the **TFormDesigner** component onto a form.
18 | 2. Customize component's self-explanatory properties like DragHandleColor, DrawGrid or SnapToGrid.
19 | 3. During runtime call ``AddControl`` methods to instruct TFormDesigner which controls should be possible to move/re-size. There are two versions of ``AddControl``:
20 |
21 | * The first accepts an instance of an existing control - typically, this would be a control already present on a TForm.
22 | ```pascal
23 | procedure AddControl(AControl: TControl); overload;
24 | ```
25 |
26 | * The second version accepts class of a control (TControlClass) to be created dynamically. The control will be created by user action, either by a mouse click on a form hosting the TFormDesigner or by dragging a mouse around thus specifying new control dimensions.
27 | ```pascal
28 | procedure AddControl(ControlClass: TControlClass); overload
29 | ```
30 | 4. Set ``Enabled`` to False to take away TFormDesigner's reign over the hosting TForm and its controls.
31 |
32 | ## Notes
33 |
34 | * TFormDesigner was tested only under **Windows 10** and Embarcadero® **Delphi 10.3** Community Edition.
35 | * The code is peppered with more recent language features like **generics**, **anonymous methods** or **class helpers**. Although, it should be fairly easy to revert those and use the code in older version of Delphi.
36 |
--------------------------------------------------------------------------------
/images/demo.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/havlicekp/form-designer/eef60c939b900d12f6addaa06a985c06410e6362/images/demo.gif
--------------------------------------------------------------------------------
/src/FormDesigner.Demo/ComponentsForm.dfm:
--------------------------------------------------------------------------------
1 | object frmComponentsForm: TfrmComponentsForm
2 | Left = 0
3 | Top = 0
4 | AutoSize = True
5 | BorderIcons = []
6 | BorderStyle = bsToolWindow
7 | ClientHeight = 30
8 | ClientWidth = 64
9 | Color = clBtnFace
10 | Font.Charset = DEFAULT_CHARSET
11 | Font.Color = clWindowText
12 | Font.Height = -11
13 | Font.Name = 'Tahoma'
14 | Font.Style = []
15 | OldCreateOrder = False
16 | StyleElements = [seFont, seBorder]
17 | OnCreate = FormCreate
18 | PixelsPerInch = 96
19 | TextHeight = 13
20 | object tbControls: TToolBar
21 | Left = 0
22 | Top = 0
23 | Width = 64
24 | Height = 30
25 | Align = alNone
26 | AutoSize = True
27 | ButtonHeight = 30
28 | ButtonWidth = 31
29 | Color = clMedGray
30 | Constraints.MinWidth = 64
31 | Images = ilImages
32 | ParentColor = False
33 | TabOrder = 0
34 | Transparent = False
35 | StyleElements = []
36 | end
37 | object ilImages: TImageList
38 | ColorDepth = cd32Bit
39 | DrawingStyle = dsTransparent
40 | Height = 24
41 | Width = 24
42 | Left = 32
43 | Top = 152
44 | Bitmap = {
45 | 494C01010A001800040018001800FFFFFFFF2110FFFFFFFFFFFFFFFF424D3600
46 | 000000000000360000002800000060000000480000000100200000000000006C
47 | 0000000000000000000000000000000000000000000000000000000000000000
48 | 0000000000000000000000000000000000000000000000000000000000000000
49 | 0000000000000000000000000000000000000000000000000000000000000000
50 | 0000000000000000000000000000000000000000000000000000000000000000
51 | 0000000000000000000000000000000000000000000000000000000000000000
52 | 0000000000000000000000000000000000000000000000000000000000000000
53 | 0000000000000000000000000000000000000000000000000000000000000000
54 | 0000000000000000000000000000000000000000000000000000000000000000
55 | 0000000000000000000000000000000000000000000000000000000000000000
56 | 0000000000000000000000000000000000000000000000000000000000000000
57 | 0000000000000000000000000000000000000000000000000000000000000000
58 | 0000000000000000000000000000000000000000000000000000000000000000
59 | 0000000000000000000000000000000000000000000000000000000000000000
60 | 0000000000000000000000000000000000000000000000000000000000000000
61 | 0000000000000000000000000000000000000000000000000000000000000000
62 | 0000000000000000000000000000000000000000000000000000000000000000
63 | 0000000000000000000000000000000000000000000000000000000000000000
64 | 0000000000000000000000000000000000000000000000000000000000000000
65 | 0000000000000000000000000000000000000000000000000000000000000000
66 | 0000000000000000000000000000000000000000000000000000000000000000
67 | 0000000000000000000000000000000000000000000000000000000000000000
68 | 0000000000000000000000000000000000000000000000000000000000000000
69 | 0000000000000000000000000000000000000000000000000000000000000000
70 | 0000000000000000000000000000000000000000000000000000000000000000
71 | 0000000000000000000000000000000000000000000000000000000000000000
72 | 0000000000000000000000000000000000000000000000000000000000000000
73 | 0000000000000000000000000000000000000000000000000000000000000000
74 | 0000000000000000000000000000000000000000000000000000000000000000
75 | 0000000000000000000000000000000000000000000000000000000000000000
76 | 0000000000000000000000000000000000000000000000000000000000000000
77 | 0000000000000000000000000000000000000000000000000000000000000000
78 | 0000000000000000000000000000000000000000000000000000000000000000
79 | 0000000000000000000000000000000000000000000000000000000000000000
80 | 0000000000000000000000000000000000000000000000000000000000000000
81 | 0000000000000000000000000000000000000000000000000000000000000000
82 | 0000000000000000000000000000000000000000000000000000000000000000
83 | 0000000000000000000000000000000000000000000000000000000000008A8A
84 | 8AF1999999FF999999FF999999FF999999FF999999FF999999FF999999FF9999
85 | 99FF999999FF999999FF999999FF999999FF999999FF999999FF999999FF9999
86 | 99FF8A8A8AF10000000000000000000000000000000000000000000000000000
87 | 0000000000000000000000000000000000000000000000000000000000000000
88 | 0000000000000000000000000000000000000000000000000000000000000000
89 | 0000000000000000000000000000000000000000000000000000000000000000
90 | 0000000000000000000000000000000000000000000000000000000000000000
91 | 0000000000000000000000000000000000000000000000000000000000000000
92 | 0000000000000000000000000000000000000000000000000000000000000000
93 | 0000000000000000000000000000000000000000000000000000000000000000
94 | 0000000000000000000000000000000000000000000000000000000000000000
95 | 0000000000000000000000000000000000000000000000000000000000009999
96 | 99FFECECECFFF0F0F0FFF0F0F0FFF0F0F0FFEFEFEFFFEFEFEFFFEFEFEFFFEEEE
97 | EEFFEEEEEEFFEEEEEEFFEDEDEDFFEDEDEDFFEDEDEDFFECECECFFECECECFFE8E8
98 | E8FF999999FF0000000000000000000000000000000000000000000000000000
99 | 0000000000000000000000000000000000000000000000000000000000000000
100 | 0000000000000000000000000000000000000000000000000000000000000000
101 | 0000000000000000000000000000000000000000000000000000000000000000
102 | 0000000000000000000000000000000000000000000000000000000000000000
103 | 0000000000000000000000000000000000000000000000000000000000000000
104 | 0000000000000000000000000000000000000000000000000000000000000000
105 | 0000000000000000000000000000000000000000000000000000000000000000
106 | 0000000000000000000000000000000000000000000000000000000000000000
107 | 0000000000000000000000000000000000000000000000000000000000009999
108 | 99FFF1F1F1FFF7F7F7FFF6F6F6FFF6F6F6FFF6F6F6FFF5F5F5FFF5F5F5FFF5F5
109 | F5FFF4F4F4FFF4F4F4FFF4F4F4FFF3F3F3FFF3F3F3FFF3F3F3FFF2F2F2FFEDED
110 | EDFF999999FF0000000000000000000000000000000000000000000000000000
111 | 0000000000000000000000000000000000000000001521212182525252CD7373
112 | 73F3737373F3525252CD20202081000000140000000000000000000000000000
113 | 0000000000000000000000000000000000000000000000000000000000000000
114 | 0000000000000000000000000000000000000000000000000000000000000000
115 | 0000000000000000000000000000000000000000000000000000000000000000
116 | 0000000000000000000000000000000000000000000000000000000000000000
117 | 0000000000000000000000000000000000000000000000000000000000000000
118 | 0000000000000000000000000000000000000000000000000000000000000000
119 | 0000000000000000000000000000000000000000000000000000000000009999
120 | 99FFF1F1F1FFF7F7F7FFF7F7F7FFF6F6F6FFF6F6F6FFF6F6F6FFF5F5F5FFF5F5
121 | F5FFF5F5F5FFF4F4F4FFF4F4F4FFF4F4F4FFF3F3F3FFF3F3F3FFF3F3F3FFEDED
122 | EDFF999999FF0000000000000000000000000000000000000000000000000000
123 | 00000000000000000000000000000D0D0D54747474F1B6B6B6FFE3E3E3FFF9F9
124 | F9FFF9F9F9FFE3E3E3FFB6B6B6FF737373F00D0D0D5200000000000000000000
125 | 0000000000000000000000000000000000000000000000000000000000000000
126 | 0000000000000000000000000000000000000000000000000000000000000000
127 | 0000000000000000000000000000000000000000000000000000000000000000
128 | 0000000000000000000000000000000000000000000000000000000000000000
129 | 0000000000000000000000000000000000000000000000000000000000000000
130 | 0000000000000000000000000000000000000000000000000000000000000000
131 | 0000000000000000000000000000000000000000000000000000000000009999
132 | 99FFF1F1F1FFF7F7F7FFF7F7F7FFF7F7F7FFF6F6F6FFF6F6F6FFF6F6F6FFF5F5
133 | F5FFF5F5F5FFF5F5F5FFF4F4F4FFF4F4F4FFF4F4F4FFF3F3F3FFF3F3F3FFEEEE
134 | EEFF999999FF0000000000000000000000000000000000000000000000000000
135 | 000000000000000000000D0D0D548C8C8CFEE7E7E7FFFFFFFFFFFFFFFFFFFFFF
136 | FFFFFFFFFFFFFFFFFFFFFFFFFFFFE7E7E7FF8C8C8CFE0D0D0D52000000000000
137 | 0000000000000000000000000000000000000000000000000000000000000000
138 | 0000000000000000000000000000000000000000000000000000000000000000
139 | 0000000000000000000000000000000000000000000000000000000000000000
140 | 0000000000000000000000000000000000000000000000000000000000000000
141 | 0000000000000000000000000000000000000000000000000000000000000000
142 | 0000000000000000000000000000000000000000000000000000000000000000
143 | 0000000000000000000000000000000000000000000000000000000000009999
144 | 99FFF2F2F2FFF7F7F7FFF7F7F7FFF7F7F7FFF7F7F7FFF6F6F6FFF6F6F6FFF6F6
145 | F6FFF5F5F5FFF5F5F5FFF5F5F5FFF4F4F4FFF4F4F4FFF4F4F4FFF3F3F3FFEEEE
146 | EEFF999999FF0000000000000000000000000000000000000000000000000000
147 | 00000000000000000016767676F2E7E7E7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
148 | FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE7E7E7FF737373F0000000140000
149 | 0000000000000000000000000000000000000000000000000000000000000000
150 | 0000000000000000000000000000000000000000000000000000000000000000
151 | 0000000000000000000000000000000000000000000000000000000000000000
152 | 0000000000000000000000000000000000000000000000000000000000000000
153 | 0000000000000000000000000000000000000000000000000000000000000000
154 | 0000000000000000000000000000000000000000000000000000000000000000
155 | 0000000000000000000000000000000000000000000000000000000000009999
156 | 99FFF2F2F2FFF8F8F8FFF7F7F7FFF7F7F7FFF7F7F7FFF7F7F7FFF6F6F6FFF6F6
157 | F6FFF6F6F6FFF5F5F5FFF5F5F5FFF5F5F5FFF4F4F4FFF4F4F4FFF4F4F4FFEEEE
158 | EEFF999999FF0000000000000000000000000000000000000000000000000000
159 | 00000000000021212183B6B6B6FFFFFFFFFFFFFFFFFFFFF9F9FFFF7676FFFF19
160 | 19FFFF1919FFFF7676FFFFF9F9FFFFFFFFFFFFFFFFFFB6B6B6FF202020810000
161 | 0000000000000000000000000000000000000000000000000000000000000000
162 | 0000000000000000000000000000000000000000000000000000000000000000
163 | 0000000000000000000000000000000000000000000000000000000000000000
164 | 0000000000000000000000000000000000000000000000000000000000000000
165 | 0000000000000000000000000000000000000000000000000000000000000000
166 | 0000000000000000000000000000000000000000000000000000000000000000
167 | 0000000000000000000000000000000000000000000000000000000000009999
168 | 99FFF2F2F2FFF8F8F8FFF8F8F8FFF7F7F7FFF7F7F7FFF7F7F7FFF7F7F7FFF6F6
169 | F6FFF6F6F6FFF6F6F6FFF5F5F5FFF5F5F5FFF5F5F5FFF4F4F4FFF4F4F4FFEFEF
170 | EFFF999999FF0000000000000000000000000000000000000000000000000000
171 | 000000000000545454CFE4E4E4FFFFFFFFFFFFFFFFFFFF7676FFFF0000FFFF00
172 | 00FFFF0000FFFF0000FFFF7777FFFFFFFFFFFFFFFFFFE3E3E3FF525252CE0000
173 | 0000000000000000000000000000000000000000000000000000000000000000
174 | 0000000000000000000000000000000000000000000000000000000000000000
175 | 0000000000000000000000000000000000000000000000000000000000000000
176 | 0000000000000000000000000000000000000000000000000000000000000000
177 | 0000000000000000000000000000000000000000000000000000000000000000
178 | 0000000000000000000000000000000000000000000000000000000000000000
179 | 0000000000000000000000000000000000000000000000000000000000009999
180 | 99FFF3F3F3FFF8F8F8FFF8F8F8FFF8F8F8FFF7F7F7FFF7F7F7FFF7F7F7FFF7F7
181 | F7FFF6F6F6FFF6F6F6FFF6F6F6FFF5F5F5FFF5F5F5FFF5F5F5FFF4F4F4FFEFEF
182 | EFFF999999FF0000000000000000000000000000000000000000000000000000
183 | 000000000000727272F2F9F9F9FFFFFFFFFFFFFFFFFFFF1919FFFF0000FFFF00
184 | 00FFFF0000FFFF0000FFFF1A1AFFFFFFFFFFFFFFFFFFF8F8F8FF717171F10000
185 | 0000000000000000000000000000000000000000000000000000000000000000
186 | 0000000000000000000000000000000000000000000000000000000000000000
187 | 0000000000000000000000000000000000000000000000000000000000000000
188 | 0000000000000000000000000000000000000000000000000000000000000000
189 | 0000000000000000000000000000000000000000000000000000000000000000
190 | 0000000000000000000000000000000000000000000000000000000000000000
191 | 0000000000000000000000000000000000000000000000000000000000009999
192 | 99FFF3F3F3FFF9F9F9FFF8F8F8FFF8F8F8FFF8F8F8FFF7F7F7FFF7F7F7FFF7F7
193 | F7FFF7F7F7FFF6F6F6FFF6F6F6FFF6F6F6FFF5F5F5FFF5F5F5FFF5F5F5FFEFEF
194 | EFFF999999FF0000000000000000000000000000000000000000000000000000
195 | 000000000000737373F3F9F9F9FFFFFFFFFFFFFFFFFFFF1818FFFF0000FFFF00
196 | 00FFFF0000FFFF0000FFFF1717FFFFFFFFFFFFFFFFFFF9F9F9FF727272F20000
197 | 0000000000000000000000000000000000000000000000000000000000000000
198 | 0000000000000000000000000000000000000000000000000000000000000000
199 | 0000000000000000000000000000000000000000000000000000000000000000
200 | 0000000000000000000000000000000000000000000000000000000000000000
201 | 0000000000000000000000000000000000000000000000000000000000000000
202 | 0000000000000000000000000000000000000000000000000000000000000000
203 | 0000000000000000000000000000000000000000000000000000000000009999
204 | 99FFF3F3F3FFF9F9F9FFF9F9F9FFF8F8F8FFF8F8F8FFF8F8F8FFF7F7F7FFF7F7
205 | F7FFF7F7F7FFF7F7F7FFF6F6F6FFF6F6F6FFF6F6F6FFF5F5F5FFF5F5F5FFF0F0
206 | F0FF999999FF0000000000000000000000000000000000000000000000000000
207 | 000000000000545454D0E4E4E4FFFFFFFFFFFFFFFFFFFF7676FFFF0000FFFF00
208 | 00FFFF0000FFFF0000FFFF7676FFFFFFFFFFFFFFFFFFE3E3E3FF525252CE0000
209 | 0000000000000000000000000000000000000000000000000000000000000000
210 | 0000000000000000000000000000000000000000000000000000000000000000
211 | 0000000000000000000000000000000000000000000000000000000000000000
212 | 0000000000000000000000000000000000000000000000000000000000000000
213 | 0000000000000000000000000000000000000000000000000000000000000000
214 | 0000000000000000000000000000000000000000000000000000000000000000
215 | 0000000000000000000000000000000000000000000000000000000000009999
216 | 99FFF4F4F4FFF9F9F9FFF9F9F9FFF9F9F9FFF8F8F8FFF8F8F8FFF8F8F8FFF7F7
217 | F7FFF7F7F7FFF7F7F7FFF7F7F7FFF6F6F6FFF6F6F6FFF6F6F6FFF5F5F5FFF0F0
218 | F0FF999999FF0000000000000000000000000000000000000000000000000000
219 | 00000000000022222284B7B7B7FFFFFFFFFFFFFFFFFFFFF9F9FFFF7575FFFF18
220 | 18FFFF1919FFFF7676FFFFF9F9FFFFFFFFFFFFFFFFFFB6B6B6FF212121820000
221 | 0000000000000000000000000000000000000000000000000000000000000000
222 | 0000000000000000000000000000000000000000000000000000000000000000
223 | 0000000000000000000000000000000000000000000000000000000000000000
224 | 0000000000000000000000000000000000000000000000000000000000000000
225 | 0000000000000000000000000000000000000000000000000000000000000000
226 | 0000000000000000000000000000000000000000000000000000000000000000
227 | 0000000000000000000000000000000000000000000000000000000000009999
228 | 99FFF4F4F4FFFAFAFAFFF9F9F9FFF9F9F9FFF9F9F9FFF8F8F8FFF8F8F8FFF8F8
229 | F8FFF7F7F7FFF7F7F7FFF7F7F7FFF7F7F7FFF6F6F6FFF6F6F6FFF6F6F6FFF0F0
230 | F0FF999999FF0000000000000000000000000000000000000000000000000000
231 | 00000000000000000016767676F2E8E8E8FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
232 | FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE7E7E7FF757575F1000000150000
233 | 0000000000000000000000000000000000000000000000000000000000000000
234 | 0000000000000000000000000000000000000000000000000000000000000000
235 | 0000000000000000000000000000000000000000000000000000000000000000
236 | 0000000000000000000000000000000000000000000000000000000000000000
237 | 0000000000000000000000000000000000000000000000000000000000000000
238 | 0000000000000000000000000000000000000000000000000000000000000000
239 | 0000000000000000000000000000000000000000000000000000000000009999
240 | 99FFF4F4F4FFFAFAFAFFFAFAFAFFF9F9F9FFF9F9F9FFF9F9F9FFF8F8F8FFF8F8
241 | F8FFF8F8F8FFF7F7F7FFF7F7F7FFF7F7F7FFF7F7F7FFF6F6F6FFF6F6F6FFF0F0
242 | F0FF999999FF0000000000000000000000000000000000000000000000000000
243 | 000000000000000000000E0E0E558C8C8CFEE8E8E8FFFFFFFFFFFFFFFFFFFFFF
244 | FFFFFFFFFFFFFFFFFFFFFFFFFFFFE7E7E7FF8C8C8CFE0D0D0D54000000000000
245 | 0000000000000000000000000000000000000000000000000000000000000000
246 | 0000000000000000000000000000000000000000000000000000000000000000
247 | 0000000000000000000000000000000000000000000000000000000000000000
248 | 0000000000000000000000000000000000000000000000000000000000000000
249 | 0000000000000000000000000000000000000000000000000000000000000000
250 | 0000000000000000000000000000000000000000000000000000000000000000
251 | 0000000000000000000000000000000000000000000000000000000000009999
252 | 99FFF5F5F5FFFAFAFAFFFAFAFAFFFAFAFAFFF9F9F9FFF9F9F9FFF9F9F9FFF8F8
253 | F8FFF8F8F8FFF8F8F8FFF7F7F7FFF7F7F7FFF7F7F7FFF7F7F7FFF6F6F6FFF0F0
254 | F0FF999999FF0000000000000000000000000000000000000000000000000000
255 | 00000000000000000000000000000E0E0E55767676F2B7B7B7FFE4E4E4FFFAFA
256 | FAFFFAFAFAFFE4E4E4FFB6B6B6FF767676F20D0D0D5400000000000000000000
257 | 0000000000000000000000000000000000000000000000000000000000000000
258 | 0000000000000000000000000000000000000000000000000000000000000000
259 | 0000000000000000000000000000000000000000000000000000000000000000
260 | 0000000000000000000000000000000000000000000000000000000000000000
261 | 0000000000000000000000000000000000000000000000000000000000000000
262 | 0000000000000000000000000000000000000000000000000000000000000000
263 | 0000000000000000000000000000000000000000000000000000000000009999
264 | 99FFF5F5F5FFFBFBFBFFFAFAFAFFFAFAFAFFFAFAFAFFF9F9F9FFF9F9F9FFF9F9
265 | F9FFF8F8F8FFF8F8F8FFF8F8F8FFF7F7F7FFF7F7F7FFF7F7F7FFF7F7F7FFF0F0
266 | F0FF999999FF0000000000000000000000000000000000000000000000000000
267 | 0000000000000000000000000000000000000000001622222284545454CF7474
268 | 74F4747474F4525252CE21212183000000160000000000000000000000000000
269 | 0000000000000000000000000000000000000000000000000000000000000000
270 | 0000000000000000000000000000000000000000000000000000000000000000
271 | 0000000000000000000000000000000000000000000000000000000000000000
272 | 0000000000000000000000000000000000000000000000000000000000000000
273 | 0000000000000000000000000000000000000000000000000000000000000000
274 | 0000000000000000000000000000000000000000000000000000000000000000
275 | 0000000000000000000000000000000000000000000000000000000000009999
276 | 99FFEFEFEFFFF4F4F4FFF4F4F4FFF3F3F3FFF3F3F3FFF3F3F3FFF2F2F2FFF2F2
277 | F2FFF2F2F2FFF1F1F1FFF1F1F1FFF1F1F1FFF1F1F1FFF1F1F1FFF1F1F1FFECEC
278 | ECFF999999FF0000000000000000000000000000000000000000000000000000
279 | 0000000000000000000000000000000000000000000000000000000000000000
280 | 0000000000000000000000000000000000000000000000000000000000000000
281 | 0000000000000000000000000000000000000000000000000000000000000000
282 | 0000000000000000000000000000000000000000000000000000000000000000
283 | 0000000000000000000000000000000000000000000000000000000000000000
284 | 0000000000000000000000000000000000000000000000000000000000000000
285 | 0000000000000000000000000000000000000000000000000000000000000000
286 | 0000000000000000000000000000000000000000000000000000000000000000
287 | 0000000000000000000000000000000000000000000000000000000000008A8A
288 | 8AF1999999FF999999FF999999FF999999FF999999FF999999FF999999FF9999
289 | 99FF999999FF999999FF999999FF999999FF999999FF999999FF999999FF9999
290 | 99FF8A8A8AF10000000000000000000000000000000000000000000000000000
291 | 0000000000000000000000000000000000000000000000000000000000000000
292 | 0000000000000000000000000000000000000000000000000000000000000000
293 | 0000000000000000000000000000000000000000000000000000000000000000
294 | 0000000000000000000000000000000000000000000000000000000000000000
295 | 0000000000000000000000000000000000000000000000000000000000000000
296 | 0000000000000000000000000000000000000000000000000000000000000000
297 | 0000000000000000000000000000000000000000000000000000000000000000
298 | 0000000000000000000000000000000000000000000000000000000000000000
299 | 0000000000000000000000000000000000000000000000000000000000000000
300 | 0000000000000000000000000000000000000000000000000000000000000000
301 | 0000000000000000000000000000000000000000000000000000000000000000
302 | 0000000000000000000000000000000000000000000000000000000000000000
303 | 0000000000000000000000000000000000000000000000000000000000000000
304 | 0000000000000000000000000000000000000000000000000000000000000000
305 | 0000000000000000000000000000000000000000000000000000000000000000
306 | 0000000000000000000000000000000000000000000000000000000000000000
307 | 0000000000000000000000000000000000000000000000000000000000000000
308 | 0000000000000000000000000000000000000000000000000000000000000000
309 | 0000000000000000000000000000000000000000000000000000000000000000
310 | 0000000000000000000000000000000000000000000000000000000000000000
311 | 0000000000000000000000000000000000000000000000000000000000000000
312 | 0000000000000000000000000000000000000000000000000000000000000000
313 | 0000000000000000000000000000000000000000000000000000000000000000
314 | 0000000000000000000000000000000000000000000000000000000000000000
315 | 0000000000000000000000000000000000000000000000000000000000000000
316 | 0000000000000000000000000000000000000000000000000000000000000000
317 | 0000000000000000000000000000000000000000000000000000000000000000
318 | 0000000000000000000000000000000000000000000000000000000000000000
319 | 0000000000000000000000000000000000000000000000000000000000000000
320 | 0000000000000000000000000000000000000000000000000000000000000000
321 | 0000000000000000000000000000000000000000000000000000000000000000
322 | 0000000000000000000000000000000000000000000000000000000000000000
323 | 0000000000000000000000000000000000000000000000000000000000000000
324 | 0000000000000000000000000000000000000000000000000000000000000000
325 | 0000000000000000000000000000000000000000000000000000000000000000
326 | 0000000000000000000000000000000000000000000000000000000000000000
327 | 0000000000000000000000000000000000000000000000000000000000000000
328 | 0000000000000000000000000000000000000000000000000000000000000000
329 | 0000000000000000000000000000000000000000000000000000000000000000
330 | 0000000000000000000000000000000000000000000000000000000000000000
331 | 0000000000000000000000000000000000000000000000000000000000000000
332 | 0000000000000000000000000000000000000000000000000000000000000000
333 | 0000000000000000000000000000000000000000000000000000000000000000
334 | 0000000000000000000000000000000000000000000000000000000000000000
335 | 0000000000000000000000000000000000000000000000000000000000000000
336 | 0000000000000000000000000000000000000000000000000000000000000000
337 | 0000000000000000000000000000000000000000000000000000000000000000
338 | 0000000000000000000000000000000000000000000000000000000000000000
339 | 0000000000000000000000000000000000000000000000000000000000000000
340 | 0000000000000000000000000000000000000000000000000000000000000000
341 | 0000000000000000000000000000000000000000000000000000000000000000
342 | 0000000000000000000000000000000000000000000000000000000000000000
343 | 0000000000000000000000000000000000000000000000000000000000000000
344 | 0000000000000000000000000000000000000000000000000000000000000000
345 | 0000000000000000000000000000000000000000000000000000000000000000
346 | 0000000000000000000000000000000000000000000000000000000000000000
347 | 0000000000000000000000000000000000000000000000000000000000000000
348 | 0000000000000000000000000000000000000000000000000000000000000000
349 | 0000000000000000000000000000000000000000000000000000000000000000
350 | 0000000000000000000000000000000000000000000000000000000000000000
351 | 0000000000000000000000000000000000000000000000000000000000000000
352 | 0000000000000000000000000000000000000000000000000000000000000000
353 | 0000000000000000000000000000000000000000000000000000000000000000
354 | 0000000000000000000000000000000000000000000000000000000000000000
355 | 0000000000000000000000000000000000000000000000000000000000000000
356 | 0000000000000000000000000000000000000000000000000000000000000000
357 | 0000000000000000000000000000000000000000000000000000000000000000
358 | 0000000000000000000000000000000000000000000000000000000000000000
359 | 0000000000000000000000000000000000000000000000000000000000000000
360 | 0000000000000000000000000000000000000000000000000000000000000000
361 | 0000000000000000000000000000000000000000000000000000000000000000
362 | 0000000000000000000000000000000000000000000000000000000000000000
363 | 0000000000000000000000000000000000000000000000000000000000000000
364 | 0000000000000000000000000000000000000000000000000000000000000000
365 | 0000000000000000000000000000000000000000000000000000000000000000
366 | 0000000000000000000000000000000000000000000000000000000000000000
367 | 0000000000000000000000000000000000000000000000000000000000000000
368 | 0000000000000000000000000000000000000000000000000000000000000000
369 | 0000B99D7EFFB99D7EFFB99D7EFFB99D7EFFB99D7EFFB99D7EFFB99D7EFFB99D
370 | 7EFFB99D7EFFB99D7EFFB99D7EFFB99D7EFFB99D7EFFB99D7EFFB99D7EFFB99D
371 | 7EFF000000000000000000000000000000000000000000000000000000008A8A
372 | 8AF1999999FF999999FF999999FF999999FF999999FF999999FF999999FF9999
373 | 99FF999999FF999999FF999999FF999999FF999999FF999999FF999999FF9999
374 | 99FF8A8A8AF10000000000000000000000000000000000000000000000000000
375 | 0000000000000000000000000000000000000000000000000000000000000000
376 | 0000000000000000000000000000000000000000000000000000000000000000
377 | 00000000000000000000000000000000000000000000000000004C4C4CFF4C4C
378 | 4CFF4C4C4CFF4C4C4CFF4C4C4CFF4C4C4CFF4C4C4CFF4C4C4CFF4C4C4CFF4C4C
379 | 4CFF4C4C4CFF4C4C4CFF4C4C4CFF4C4C4CFF4C4C4CFF4C4C4CFF4C4C4CFF4C4C
380 | 4CFF4C4C4CFF0000000000000000000000000000000000000000000000000000
381 | 0000B99D7EFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
382 | FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB99D
383 | 7EFF000000000000000000000000000000000000000000000000000000009999
384 | 99FFECECECFFF0F0F0FFF0F0F0FFF0F0F0FFEFEFEFFFEFEFEFFFEFEFEFFFEEEE
385 | EEFFEEEEEEFFEEEEEEFFEDEDEDFFEDEDEDFFEDEDEDFFECECECFFECECECFFE8E8
386 | E8FF999999FF0000000000000000000000000000000000000000000000000000
387 | 0000000000000000000000000000000000000000000000000000000000000000
388 | 0000000000000000000000000000000000000000000000000000000000000000
389 | 00000000000000000000000000000000000000000000000000004C4C4CFFFFFF
390 | FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
391 | FFFFFFFFFFFFFFFFFFFFFFFFFFFF4C4C4CFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
392 | FFFF4C4C4CFF0000000000000000000000000000000000000000000000000000
393 | 0000B99D7EFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
394 | FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB99D
395 | 7EFF000000000000000000000000000000000000000000000000000000009999
396 | 99FFF1F1F1FFF7F7F7FFF6F6F6FFF6F6F6FFF6F6F6FFF5F5F5FFF5F5F5FFF5F5
397 | F5FFF4F4F4FFF4F4F4FFF4F4F4FFF3F3F3FFF3F3F3FFF3F3F3FFF2F2F2FFEDED
398 | EDFF999999FF0000000000000000000000000000000000000000000000000000
399 | 0000000000000000000000000000000000000000000000000000000000000000
400 | 0000000000000000000000000000000000000000000000000000000000000000
401 | 00000000000000000000000000000000000000000000000000004C4C4CFFFFFF
402 | FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
403 | FFFFFFFFFFFFFFFFFFFFFFFFFFFF4C4C4CFFFFFFFFFF7E7E7EFF7E7E7EFFFFFF
404 | FFFF4C4C4CFF0000000000000000000000000000000000000000000000000000
405 | 0000B99D7EFFFFFFFFFFFFFFFFFF323232FF323232FF323232FFFFFFFFFF3232
406 | 32FF323232FF323232FFFFFFFFFF323232FF323232FFFFFFFFFFFFFFFFFFB99D
407 | 7EFF000000000000000000000000000000000000000000000000000000009999
408 | 99FFF1F1F1FFF7F7F7FFF7F7F7FFF6F6F6FFF6F6F6FFF6F6F6FFF5F5F5FFF5F5
409 | F5FFF5F5F5FFF4F4F4FFF4F4F4FFF4F4F4FFF3F3F3FFF3F3F3FFF3F3F3FFEDED
410 | EDFF999999FF0000000000000000000000000000000000000000BE6A36FFBE6A
411 | 36FFBE6A36FFBE6A36FFBE6A36FFBE6A36FFBE6A36FFBE6A36FFBE6A36FF0000
412 | 0000000000000000000000000000000000000000000000000000000000000000
413 | 00000000000000000000000000000000000000000000000000004C4C4CFFFFFF
414 | FFFFFFFFFFFF000000FF000000FF000000FF000000FF000000FF000000FF0000
415 | 00FFFFFFFFFFFFFFFFFFFFFFFFFF4C4C4CFFD3D3D3FF2E2E2EFF2E2E2EFFD3D3
416 | D3FF4C4C4CFF0000000000000000000000000000000000000000000000000000
417 | 0000B99D7EFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
418 | FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB99D
419 | 7EFF000000000000000000000000000000000000000000000000000000009999
420 | 99FFF1F1F1FFF7F7F7FFF7F7F7FFF7F7F7FFF6F6F6FFF6F6F6FFF6F6F6FFF5F5
421 | F5FFF5F5F5FFF5F5F5FFF4F4F4FFF4F4F4FFF4F4F4FFF3F3F3FFF3F3F3FFEEEE
422 | EEFF999999FF0000000000000000000000000000000000000000000000000000
423 | 0000000000000000000000000000000000000000000000000000000000000000
424 | 0000000000000000000300000008000000000000000000000000000000000000
425 | 00000000000A00000007000000000000000000000000000000004C4C4CFFFFFF
426 | FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
427 | FFFFFFFFFFFFFFFFFFFFFFFFFFFF4C4C4CFFFFFFFFFFFBFBFBFFFBFBFBFFFFFF
428 | FFFF4C4C4CFF0000000000000000000000000000000000000000000000000000
429 | 0000B99D7EFFFFFFFFFFFFFFFFFF323232FF323232FF323232FF323232FF3232
430 | 32FFFFFFFFFF323232FF323232FF323232FF323232FFFFFFFFFFFFFFFFFFB99D
431 | 7EFF000000000000000000000000000000000000000000000000000000009999
432 | 99FFF2F2F2FFF7F7F7FFF7F7F7FFF7F7F7FFF7F7F7FFF6F6F6FFF6F6F6FFF6F6
433 | F6FFF5F5F5FFF5F5F5FFF5F5F5FFF4F4F4FFF4F4F4FFF4F4F4FFF3F3F3FFEEEE
434 | EEFF999999FF0000000000000000000000000000000000000000010000169452
435 | 2BE10000000A0000000000000000000000000100001495532BE20000000D4E2C
436 | 16A43E2211926F3E1FC3804724D14F2C17A500000009000000000201001D6D3D
437 | 1FC1784322CB774322CA180D075B0000000000000000000000004C4C4CFFFFFF
438 | FFFFFFFFFFFF000000FF000000FF000000FF000000FF000000FF000000FF0000
439 | 00FF000000FFFFFFFFFFFFFFFFFF4C4C4CFF4C4C4CFF4C4C4CFF4C4C4CFF4C4C
440 | 4CFF4C4C4CFF0000000000000000000000000000000000000000000000000000
441 | 0000B99D7EFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBFBFBFFF4F4
442 | F4FFF6F6F6FFFBFBFBFFFEFEFEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB99D
443 | 7EFF000000000000000000000000000000000000000000000000000000009999
444 | 99FFF2F2F2FFF8F8F8FFF7F7F7FFF7F7F7FFF7F7F7FFF7F7F7FFF6F6F6FFF6F6
445 | F6FFF6F6F6FFF5F5F5FFF5F5F5FFF5F5F5FFF4F4F4FFF4F4F4FFF4F4F4FFEEEE
446 | EEFF999999FF0000000000000000000000000000000000000000000000005E35
447 | 1BB4160C065800000000000000000000000023140A6F4F2C17A5000000005931
448 | 19AF4527139B00000000000000014E2C16A426160B740000000060351BB52213
449 | 0A6D00000000000000000000000C0000000000000000000000004C4C4CFFFFFF
450 | FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
451 | FFFFFFFFFFFFFFFFFFFFFFFFFFFF4C4C4CFFB3C0C5FFB3C0C5FFB3C0C5FFB3C0
452 | C5FF4C4C4CFF0000000000000000000000000000000000000000000000000000
453 | 0000B99D7EFFFFFFFFFFFFFFFFFF323232FF323232FFFEFEFEFFEBEBEBFFDADA
454 | DAFFD9D9D9FFE6E7E7FF323232FF323232FFFFFFFFFFFFFFFFFFFFFFFFFFB99D
455 | 7EFF000000000000000000000000000000000000000000000000000000009999
456 | 99FFF2F2F2FFF8F8F8FFF8F8F8FFF7F7F7FFF7F7F7FFF7F7F7FFF7F7F7FFF6F6
457 | F6FFF6F6F6FFF6F6F6FFF5F5F5FFF5F5F5FFF5F5F5FFF4F4F4FFF4F4F4FFEFEF
458 | EFFF999999FF000000000000000000000000000000000000000000000000130A
459 | 0552854B26D644261399442613994426139993522AE00D070343000000005931
460 | 19AF1009044B00000000000000000B06033F66381DBB00000002AE6132F40000
461 | 00060000000000000000000000000000000000000000000000004C4C4CFFFFFF
462 | FFFFFFFFFFFF000000FF000000FF000000FF000000FF000000FF000000FF0000
463 | 00FFFFFFFFFFFFFFFFFFFFFFFFFF4C4C4CFFB3C0C5FFB3C0C5FFB3C0C5FFB3C0
464 | C5FF4C4C4CFF0000000000000000000000000000000000000000000000000000
465 | 0000B99D7EFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFEFEFF898A8AFF6673
466 | 86FF6A7B95FFB6B8BAFFDADBDBFFF2F2F2FFFDFDFDFFFFFFFFFFFFFFFFFFB99D
467 | 7EFF000000000000000000000000000000000000000000000000000000009999
468 | 99FFF3F3F3FFF8F8F8FFF8F8F8FFF8F8F8FFF7F7F7FFF7F7F7FFF7F7F7FFF7F7
469 | F7FFF6F6F6FFF6F6F6FFF6F6F6FFF5F5F5FFF5F5F5FFF5F5F5FFF4F4F4FFEFEF
470 | EFFF999999FF0000000000000000000000000000000000000000000000000000
471 | 00069F592DEA180D075B0D07034423130A6E8F5029DE00000002000000005931
472 | 19AF110A054E000000000000000007040231764121C900000001A75D30EF0000
473 | 00070000000000000000000000000000000000000000000000004C4C4CFFFFFF
474 | FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
475 | FFFFFFFFFFFFFFFFFFFFFFFFFFFF4C4C4CFFB3C0C5FFB3C0C5FFB3C0C5FFB3C0
476 | C5FF4C4C4CFF0000000000000000000000000000000000000000000000000000
477 | 0000B99D7EFFFFFFFFFFFFFFFFFF323232FF323232FF323232FFBDC0C5FFD1E3
478 | FDFF8AA8D0FF119397FFA6B2B2FF323232FF323232FFFDFDFDFFFFFFFFFFB99D
479 | 7EFF000000000000000000000000000000000000000000000000000000009999
480 | 99FFF3F3F3FFF9F9F9FFF8F8F8FFF8F8F8FFF8F8F8FFF7F7F7FFF7F7F7FFF7F7
481 | F7FFF7F7F7FFF6F6F6FFF6F6F6FFF6F6F6FFF5F5F5FFF5F5F5FFF5F5F5FFEFEF
482 | EFFF999999FF0000000000000000000000000000000000000000000000000000
483 | 00003A21118E24140A7000000000371F108A2E1A0D7E00000000000000005931
484 | 19AF4B2A16A100000000000000002B180C7A4326139800000000522D17A82314
485 | 0A6F0000000000000000000000020000000000000000000000004C4C4CFFFFFF
486 | FFFFFFFFFFFF000000FF000000FF000000FF000000FF000000FF000000FFFFFF
487 | FFFFFFFFFFFFFFFFFFFFFFFFFFFF4C4C4CFFB3C0C5FFB3C0C5FFB3C0C5FFB3C0
488 | C5FF4C4C4CFF0000000000000000000000000000000000000000000000000000
489 | 0000B99D7EFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCFCFCFF8A9E
490 | B2FF7BBCC0FF11C6C6FF09A7A7FFA6B2B2FFD9DADAFFF2F2F2FFFDFDFDFFB99D
491 | 7EFF000000000000000000000000000000000000000000000000000000009999
492 | 99FFF3F3F3FFF9F9F9FFF9F9F9FFF8F8F8FFF8F8F8FFF8F8F8FFF7F7F7FFF7F7
493 | F7FFF7F7F7FFF7F7F7FFF6F6F6FFF6F6F6FFF6F6F6FFF5F5F5FFF5F5F5FFF0F0
494 | F0FF999999FF0000000000000000000000000000000000000000000000000000
495 | 00000503012B7B4423CD0000000294522BE10201001F00000000000000005931
496 | 19AF3D221191673A1EBC61371BB7854B26D60201001D0000000001000017683A
497 | 1EBD6A3B1EBE61361BB623130A6E0000000000000000000000004C4C4CFFFFFF
498 | FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
499 | FFFFFFFFFFFFFFFFFFFFFFFFFFFF4C4C4CFFB3C0C5FFB3C0C5FFB3C0C5FFB3C0
500 | C5FF4C4C4CFF0000000000000000000000000000000000000000000000000000
501 | 0000B99D7EFFFFFFFFFFFFFFFFFF323232FF323232FFFFFFFFFFFFFFFFFFA8D3
502 | D3FF6BD2D2FF80DADAFF11C9C9FF09A7A7FFA5B2B2FFD9DADAFFF2F2F2FFB89C
503 | 7DFF000000000000000000000000000000000000000000000000000000009999
504 | 99FFF4F4F4FFF9F9F9FFF9F9F9FFF9F9F9FFF8F8F8FFF8F8F8FFF8F8F8FFF7F7
505 | F7FFF7F7F7FFF7F7F7FFF7F7F7FFF6F6F6FFF6F6F6FFF6F6F6FFF5F5F5FFF0F0
506 | F0FF999999FF0000000000000000000000000000000000000000000000000000
507 | 000000000000764121C925140A7164381CB90000000000000000000000005931
508 | 19AF0E0704460000000D03010021000000020000000000000000000000000000
509 | 00000100001403020123000000010000000000000000000000004C4C4CFFFFFF
510 | FFFFFFFFFFFF000000FF000000FF000000FF000000FF000000FF000000FF0000
511 | 00FF000000FFFFFFFFFFFFFFFFFF4C4C4CFFB3C0C5FFB3C0C5FFB3C0C5FFB3C0
512 | C5FF4C4C4CFF0000000000000000000000000000000000000000000000000000
513 | 0000B99D7EFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
514 | FFFFAAD2D2FF6AD2D2FF80DBDBFF11C7C7FF09A9A9FFA5B2B2FFDADBDBFFB095
515 | 78FF000000020000000000000000000000000000000000000000000000009999
516 | 99FFF4F4F4FFFAFAFAFFF9F9F9FFF9F9F9FFF9F9F9FFF8F8F8FFF8F8F8FFF8F8
517 | F8FFF7F7F7FFF7F7F7FFF7F7F7FFF7F7F7FFF6F6F6FFF6F6F6FFF6F6F6FFF0F0
518 | F0FF999999FF0000000000000000000000000000000000000000000000000000
519 | 0000000000001E110867AB6031F2150C06560000000000000000000000005931
520 | 19AF0E0704460000000000000000000000000000000000000000000000000000
521 | 00000000000000000000000000000000000000000000000000004C4C4CFFFFFF
522 | FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
523 | FFFFFFFFFFFFFFFFFFFFFFFFFFFF4C4C4CFFB3C0C5FFB3C0C5FFB3C0C5FFB3C0
524 | C5FF4C4C4CFF0000000000000000000000000000000000000000000000000000
525 | 0000B99D7EFFFFFFFFFFFFFFFFFF323232FF323232FF323232FF323232FFFFFF
526 | FFFFFFFFFFFFA7D3D3FF6AD2D2FF80D9D9FF11CACAFF08AAAAFFA5B3B3FF9E87
527 | 6DFF0000000D0000000200000000000000000000000000000000000000009999
528 | 99FFF4F4F4FFFAFAFAFFFAFAFAFFF9F9F9FFF9F9F9FFF9F9F9FFF8F8F8FFF8F8
529 | F8FFF8F8F8FFF7F7F7FFF7F7F7FFF7F7F7FFF7F7F7FFF6F6F6FFF6F6F6FFF0F0
530 | F0FF999999FF0000000000000000000000000000000000000000000000000000
531 | 0000000000000000000F29170C77000000070000000000000000000000004E2C
532 | 16A40C0603410000000000000000000000000000000000000000000000000000
533 | 00000000000000000000000000000000000000000000000000004C4C4CFFFFFF
534 | FFFFFFFFFFFF000000FF000000FF000000FF000000FF000000FF000000FF0000
535 | 00FFFFFFFFFFFFFFFFFFFFFFFFFF4C4C4CFF4C4C4CFF4C4C4CFF4C4C4CFF4C4C
536 | 4CFF4C4C4CFF0000000000000000000000000000000000000000000000000000
537 | 0000B99D7EFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
538 | FFFFFFFFFFFFFFFFFFFFA7D0D0FF6AD2D2FF80DADAFF11CACAFF09A7A7FF8573
539 | 5FFF000000250000000D00000002000000000000000000000000000000009999
540 | 99FFF5F5F5FFFAFAFAFFFAFAFAFFFAFAFAFFF9F9F9FFF9F9F9FFF9F9F9FFF8F8
541 | F8FFF8F8F8FFF8F8F8FFF7F7F7FFF7F7F7FFF7F7F7FFF7F7F7FFF6F6F6FFF0F0
542 | F0FF999999FF0000000000000000000000000000000000000000000000000000
543 | 0000000000000000000000000000000000000000000000000000000000000000
544 | 0000000000000000000000000000000000000000000000000000000000000000
545 | 00000000000000000000000000000000000000000000000000004C4C4CFFFFFF
546 | FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
547 | FFFFFFFFFFFFFFFFFFFFFFFFFFFF4C4C4CFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
548 | FFFF4C4C4CFF0000000000000000000000000000000000000000000000000000
549 | 0000B99D7EFFFFFFFFFFFFFFFFFF323232FF323232FF323232FF323232FF3232
550 | 32FF323232FFFFFFFFFFFFFFFFFFA7D0D0FF6BD2D2FF7ED8D8FF539595FF8986
551 | 82FF02030352000000250000000C000000020000000000000000000000009999
552 | 99FFF5F5F5FFFBFBFBFFFAFAFAFFFAFAFAFFFAFAFAFFF9F9F9FFF9F9F9FFF9F9
553 | F9FFF8F8F8FFF8F8F8FFF8F8F8FFF7F7F7FFF7F7F7FFF7F7F7FFF7F7F7FFF0F0
554 | F0FF999999FF0000000000000000000000000000000000000000000000000000
555 | 0000000000000000000000000000000000000000000000000000000000000000
556 | 0000000000000000000000000000000000000000000000000000000000000000
557 | 00000000000000000000000000000000000000000000000000004C4C4CFFFFFF
558 | FFFFFFFFFFFF000000FF000000FF000000FF000000FF000000FF000000FF0000
559 | 00FF000000FFFFFFFFFFFFFFFFFF4C4C4CFFD5D5D5FF494949FF494949FFD5D5
560 | D5FF4C4C4CFF0000000000000000000000000000000000000000000000000000
561 | 0000B99D7EFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
562 | FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA4D1D1FF79A4A4FFCDCDCDFFBCBD
563 | BDFF393A4CDC000003550000001E000000060000000000000000000000009999
564 | 99FFEFEFEFFFA07458FF874F2AFF874F2AFF874F2AFF874F2AFF874F2AFF874F
565 | 2AFFA07559FFF1F1F1FFF1F1F1FFF1F1F1FFF1F1F1FFF1F1F1FFF1F1F1FFECEC
566 | ECFF999999FF0000000000000000000000000000000000000000000000000000
567 | 0000000000000000000000000000000000000000000000000000000000000000
568 | 0000000000000000000000000000000000000000000000000000000000000000
569 | 00000000000000000000000000000000000000000000000000004C4C4CFFFFFF
570 | FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
571 | FFFFFFFFFFFFFFFFFFFFFFFFFFFF4C4C4CFFFEFEFEFF676767FF606060FFFDFD
572 | FDFF4C4C4CFF0000000000000000000000000000000000000000000000000000
573 | 0000B99D7EFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
574 | FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDFE0E0FFCACACAFF8E8E
575 | 9FFF2C2CBDFD05068BF600000134000000070000000000000000000000008A8A
576 | 8AF1999999FFA6683FFFA6683FFFA6683FFFA6683FFFA6683FFFA6683FFFA668
577 | 3FFFA6683FFF999999FF999999FF999999FF999999FF999999FF999999FF9999
578 | 99FF8A8A8AF10000000000000000000000000000000000000000000000000000
579 | 0000000000000000000000000000000000000000000000000000000000000000
580 | 0000000000000000000000000000000000000000000000000000000000000000
581 | 00000000000000000000000000000000000000000000000000004C4C4CFFFFFF
582 | FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
583 | FFFFFFFFFFFFFFFFFFFFFFFFFFFF4C4C4CFFFFFFFFFFFDFDFDFFFDFDFDFFFFFF
584 | FFFF4C4C4CFF0000000000000000000000000000000000000000000000000000
585 | 0000B99D7EFFB99D7EFFB99D7EFFB99D7EFFB99D7EFFB99D7EFFB99D7EFFB99D
586 | 7EFFB99D7EFFB99D7EFFB99D7EFFB99D7EFFB99D7EFFB99D7EFFA4917AFF6B6A
587 | DAFF7E7EF4FF1E1F81EA0000001A000000020000000000000000000000000000
588 | 000000000000744C32C5C48154FFC48154FFC48154FFC48154FFC48154FFC481
589 | 54FF744B31C40000000000000000000000000000000000000000000000000000
590 | 0000000000000000000000000000000000000000000000000000000000000000
591 | 0000000000000000000000000000000000000000000000000000000000000000
592 | 0000000000000000000000000000000000000000000000000000000000000000
593 | 00000000000000000000000000000000000000000000000000004C4C4CFF4C4C
594 | 4CFF4C4C4CFF4C4C4CFF4C4C4CFF4C4C4CFF4C4C4CFF4C4C4CFF4C4C4CFF4C4C
595 | 4CFF4C4C4CFF4C4C4CFF4C4C4CFF4C4C4CFF4C4C4CFF4C4C4CFF4C4C4CFF4C4C
596 | 4CFF4C4C4CFF0000000000000000000000000000000000000000000000000000
597 | 0000000000000000000000000000000000000000000000000000000000000000
598 | 0000000000000000000000000000000000000000000000000000000000000000
599 | 0D571A1B7BD90000001400000002000000000000000000000000000000000000
600 | 0000000000000000000000000000000000000000000000000000000000000000
601 | 0000000000000000000000000000000000000000000000000000000000000000
602 | 0000000000000000000000000000000000000000000000000000000000000000
603 | 0000000000000000000000000000000000000000000000000000000000000000
604 | 0000000000000000000000000000000000000000000000000000000000000000
605 | 0000000000000000000000000000000000000000000000000000000000000000
606 | 0000000000000000000000000000000000000000000000000000000000000000
607 | 0000000000000000000000000000000000000000000000000000000000000000
608 | 0000000000000000000000000000000000000000000000000000000000000000
609 | 0000000000000000000000000000000000000000000000000000000000000000
610 | 0000000000000000000000000000000000000000000000000000000000000000
611 | 0000000000000000000000000000000000000000000000000000000000000000
612 | 0000000000000000000000000000000000000000000000000000000000000000
613 | 0000000000000000000000000000000000000000000000000000000000000000
614 | 0000000000000000000000000000000000000000000000000000000000000000
615 | 0000000000000000000000000000000000000000000000000000000000000000
616 | 0000000000000000000000000000000000000000000000000000000000000000
617 | 0000000000000000000000000000000000000000000000000000000000000000
618 | 0000000000000000000000000000000000000000000000000000000000000000
619 | 0000000000000000000000000000000000000000000000000000000000000000
620 | 0000000000000000000000000000000000000000000000000000000000000000
621 | 0000000000000000000000000000000000000000000000000000000000000000
622 | 0000000000000000000000000000000000000000000000000000000000000000
623 | 0000000000000000000000000000000000000000000000000000000000000000
624 | 0000000000000000000000000000000000000000000000000000000000000000
625 | 0000000000000000000000000000000000000000000000000000000000000000
626 | 0000000000000000000000000000000000000000000000000000000000000000
627 | 0000000000000000000000000000000000000000000000000000000000000000
628 | 0000000000000000000000000000000000000000000000000000000000000000
629 | 0000000000000000000000000000000000000000000000000000000000000000
630 | 0000000000000000000000000000000000000000000000000000000000000000
631 | 0000000000000000000000000000000000000000000000000000000000000000
632 | 0000000000000000000000000000000000000000000000000000000000000000
633 | 0000000000000000000000000000000000000000000000000000000000000000
634 | 0000000000000000000000000000000000000000000000000000000000000000
635 | 0000000000000000000000000000000000000000000000000000000000000000
636 | 0000000000000000000000000000000000000000000000000000000000000000
637 | 0000000000000000000000000000000000000000000000000000000000000000
638 | 0000000000000000000000000000000000000000000000000000000000000000
639 | 0000000000000000000000000000000000000000000000000000000000000000
640 | 0000000000000000000000000000000000000000000000000000000000000000
641 | 0000000000000000000000000000000000000000000000000000000000000000
642 | 0000000000000000000000000000000000000000000000000000000000000000
643 | 0000000000000000000000000000000000000000000000000000000000000000
644 | 0000000000000000000000000000000000000000000000000000000000000000
645 | 0000000000000000000000000000000000000000000000000000000000000000
646 | 0000000000000000000000000000000000000000000000000000000000000000
647 | 0000000000000000000000000000000000000000000000000000000000000000
648 | 0000000000000000000000000000000000000000000000000000000000000000
649 | 0000000000000000000000000000000000000000000000000000000000000000
650 | 0000000000000000000000000000000000000000000000000000000000000000
651 | 0000000000000000000000000000000000000000000000000000000000000000
652 | 0000000000000000000000000000000000000000000000000000000000000000
653 | 0000000000000000000000000000000000000000000000000000000000000000
654 | 0000000000000000000000000000000000000000000000000000000000000000
655 | 0000000000000000000000000000000000000000000000000000000000000000
656 | 0000000000000000000000000000000000000000000000000000000000000000
657 | 0000000000000000000000000000000000000000000000000000000000000000
658 | 0000000000000000000000000000000000000000000000000000000000000000
659 | 0000000000000000000000000000000000000000000000000000000000000000
660 | 0000000000000000000000000000000000000000000000000000000000000000
661 | 0000000000000000000000000000000000000000000000000000000000000000
662 | 0000000000000000000000000000000000000000000000000000000000000000
663 | 0000000000000000000000000000000000000000000000000000000000000000
664 | 0000000000000000000000000000000000000000000000000000000000000000
665 | 00000000000000000000000000000000000000000000000000004C4C4CFF4C4C
666 | 4CFF4C4C4CFF4C4C4CFF4C4C4CFF4C4C4CFF4C4C4CFF4C4C4CFF4C4C4CFF4C4C
667 | 4CFF4C4C4CFF4C4C4CFF4C4C4CFF4C4C4CFF4C4C4CFF4C4C4CFF4C4C4CFF4C4C
668 | 4CFF4C4C4CFF0000000000000000000000000000000000000000000000000000
669 | 0000000000000000000000000000000000000000000000000000000000000000
670 | 0000000000000000000000000000000000000000000000000000000000000000
671 | 0000000000000000000000000000000000000000000000000000000000000000
672 | 0000000000000000000000000000000000000000000000000000000000000000
673 | 0000000000000000000000000000000000000000000000000000000000000000
674 | 0000000000000000000000000000000000000000000000000000000000000000
675 | 0000000000000000000000000000000000000000000000000000000000000000
676 | 0000000000000000000000000000000000000000000000000000000000000000
677 | 00000000000000000000000000000000000000000000000000004C4C4CFFFFFF
678 | FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
679 | FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
680 | FFFF4C4C4CFF0000000000000000000000000000000000000000000000000000
681 | 0000000000000000000000000000000000000000000000000000000000000000
682 | 0000000000000000000000000000000000000000000000000000000000000000
683 | 000000000000000000000000000000000000361E0F86BE6A34F9C87036FFC870
684 | 36FFC87036FFC87036FFC87036FFC87036FFC87036FFC87036FFC87036FFC870
685 | 36FFC87036FFC87036FFC87036FFC87036FFC87036FFC87036FFC87036FFC870
686 | 36FFC87036FFC87036FFBE6A34F9351D0E840000000000000000000000000000
687 | 000000000000B36633F1C87036FFC87036FFC87036FFC87036FFC87036FFC870
688 | 36FFC87036FFC87036FFC87036FFC87036FFC87036FFC87036FFC87036FFB265
689 | 32F10000000000000000000000000000000000000000000000004C4C4CFFFFFF
690 | FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
691 | FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
692 | FFFF4C4C4CFF00000000000000000000000000000000B99D7EFFB99D7EFFB99D
693 | 7EFFB99D7EFFB99D7EFFB99D7EFFB99D7EFFB99D7EFFB99D7EFFB99D7EFFB99D
694 | 7EFFB99D7EFFB99D7EFFB99D7EFFB99D7EFFB99D7EFFB99D7EFFB99D7EFFB99D
695 | 7EFFB99D7EFFB99D7EFFB99D7EFF00000000BE6A34F9E3CFC2FFECECECFFECEC
696 | ECFFECECECFFECECECFFECECECFFECECECFFECECECFFECECECFFECECECFFECEC
697 | ECFFECECECFFECECECFFECECECFFECECECFFECECECFFECECECFFECECECFFECEC
698 | ECFFECECECFFECECECFFE3CFC1FFBD6A33F80000000000000000000000000000
699 | 000000000000C87036FFDCD1CAFFDAD5D1FFD9D4D0FFD8D3CFFFD7D2CEFFD5D0
700 | CCFFD4CFCBFFD2CDC9FFD1CCC8FFCFCAC6FFCEC9C5FFCCC7C3FFCCC1BAFFC870
701 | 36FF0000000000000000000000000000000000000000000000004C4C4CFFFFFF
702 | FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
703 | FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
704 | FFFF4C4C4CFF00000000000000000000000000000000B99D7EFFFFFFFFFFFFFF
705 | FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
706 | FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
707 | FFFFFFFFFFFFFFFFFFFFB99D7EFF00000000C87036FFECECECFFECECECFFECEC
708 | ECFFECECECFFECECECFFECECECFFECECECFFECECECFFECECECFFECECECFFECEC
709 | ECFFECECECFFECECECFFECECECFFECECECFFECECECFFECECECFFECECECFFECEC
710 | ECFFECECECFFECECECFFECECECFFC87036FF0000000000000000000000000000
711 | 000000000000C87036FFDED9D6FFDEDEDEFFDCDCDCFFDBDBDBFFD9D9D9FFD8D8
712 | D8FFD6D6D6FFD5D5D5FFD3D3D3FFD2D2D2FFD0D0D0FFCFCFCFFFCDC8C5FFC870
713 | 36FF0000000000000000000000000000000000000000000000004C4C4CFFFFFF
714 | FFFFFFFFFFFF000000FF000000FF000000FF000000FF000000FF000000FF0000
715 | 00FF000000FF000000FF000000FF000000FF000000FF000000FFFFFFFFFFFFFF
716 | FFFF4C4C4CFF00000000000000000000000000000000B99D7EFFFFFFFFFFFFFF
717 | FFFFF9F9F9FFF8F8F8FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
718 | FFFFF4F4F4FFFFFFFFFFFFFFFFFFFFFFFFFF000000FF000000FFFFFFFFFF0000
719 | 00FF000000FFFFFFFFFFB99D7EFF00000000C87036FFECECECFFECECECFFECEC
720 | ECFFECECECFFECECECFFECECECFFECECECFFECECECFFECECECFFECECECFFECEC
721 | ECFFECECECFFECECECFFECECECFFECECECFFECECECFFECECECFFECECECFFECEC
722 | ECFFECECECFFECECECFFECECECFFC87036FF0000000000000000000000000000
723 | 000000000000C87036FFE0DBD8FFDFDFDFFFDEDEDEFFDCDCDCFFDBDBDBFFDDA3
724 | A3FFD8D8D8FFD6D6D6FFD5D5D5FFD3D3D3FFD2D2D2FFD0D0D0FFCFCAC7FFC870
725 | 36FF0000000000000000000000000000000000000000000000004C4C4CFFFFFF
726 | FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
727 | FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
728 | FFFF4C4C4CFF00000000000000000000000000000000B99D7EFFFFFFFFFFA7A7
729 | A7FF1B1B1BFF444444FF828282FF1E1E1EFFFFFFFFFFC6C6C6FF434343FF4F4F
730 | 4FFF3C3C3CFF272727FFC3C3C3FFFFFFFFFFFFFFFFFFFFFFFFFF000000FFFFFF
731 | FFFFFFFFFFFFFFFFFFFFB99D7EFF00000000C87036FFECECECFFECECECFFECEC
732 | ECFFECECECFFECECECFFECECECFFD4D4D4FF5D5D5DFF606060FF5C5C5CFFCECE
733 | CEFFECECECFF727272FFEAEAEAFF696969FFCACACAFFECECECFFECECECFFECEC
734 | ECFFECECECFFECECECFFECECECFFC87036FF0000000000000000000000000000
735 | 000000000000C87036FFE1DCD9FFE1E1E1FFDFDFDFFFDEDEDEFFE37474FFEC00
736 | 00FFE36C6CFFD8D8D8FFD6D6D6FFD5D5D5FFD3D3D3FFD2D2D2FFD0CBC8FFC870
737 | 36FF0000000000000000000000000000000000000000000000004C4C4CFFFFFF
738 | FFFFFFFFFFFF000000FF000000FF000000FF000000FF000000FF000000FF0000
739 | 00FF000000FF000000FF000000FF000000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
740 | FFFF4C4C4CFF00000000000000000000000000000000B99D7EFFFFFFFFFF3D3D
741 | 3DFFBCBCBCFFFFFFFFFFA9A9A9FF0E0E0EFFFFFFFFFFC2C2C2FF0D0D0DFFE2E2
742 | E2FFFFFFFFFFCCCCCCFF1F1F1FFFF9F9F9FFFFFFFFFFFFFFFFFF000000FFFFFF
743 | FFFFFFFFFFFFFFFFFFFFB99D7EFF00000000C87036FFECECECFFECECECFFECEC
744 | ECFFECECECFFECECECFFECECECFF494949FFD0D0D0FFECECECFFDCDCDCFF4949
745 | 49FFEBEBEBFF545454FF6B6B6BFFA7A7A7FFECECECFFECECECFFECECECFFECEC
746 | ECFFECECECFFECECECFFECECECFFC87036FF0000000000000000000000000000
747 | 000000000000C87036FFE2DDDAFFE2E2E2FFE1E1E1FFE57676FFEC0000FFEC00
748 | 00FFEC0000FFE36C6CFFD8D8D8FFD6D6D6FFD5D5D5FFD3D3D3FFD1CCC9FFC870
749 | 36FF0000000000000000000000000000000000000000000000004C4C4CFFFFFF
750 | FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
751 | FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
752 | FFFF4C4C4CFF00000000000000000000000000000000B99D7EFFFFFFFFFF6C6C
753 | 6CFF646464FFD7D7D7FFF2F2F2FF0E0E0EFFFFFFFFFFC2C2C2FF414141FFFFFF
754 | FFFFFFFFFFFFFFFFFFFF333333FFD0D0D0FFFFFFFFFFFFFFFFFF000000FFFFFF
755 | FFFFFFFFFFFFFFFFFFFFB99D7EFF00000000C87036FFECECECFFECECECFFECEC
756 | ECFFECECECFFECECECFFE3E3E3FF515151FFECECECFFECECECFFECECECFF6767
757 | 67FFD2D2D2FF474747FF494949FFE6E6E6FFECECECFFECECECFFECECECFFECEC
758 | ECFFECECECFFECECECFFECECECFFC87036FF0000000000000000000000000000
759 | 000000000000C87036FFE3DEDBFFE4E4E4FFE77878FFEC0000FFEC0000FFEC00
760 | 00FFEC0000FFEC0000FFE36C6CFFD8D8D8FFD6D6D6FFD5D5D5FFD2CDCAFFC870
761 | 36FF0000000000000000000000000000000000000000000000004C4C4CFFFFFF
762 | FFFFFFFFFFFF000000FF000000FF000000FF000000FF000000FF000000FF0000
763 | 00FF000000FF000000FF000000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
764 | FFFF4C4C4CFF00000000000000000000000000000000B99D7EFFFFFFFFFFFAFA
765 | FAFF999999FF5D5D5DFF3C3C3CFF0E0E0EFFFFFFFFFFC2C2C2FF3D3D3DFFFFFF
766 | FFFFFFFFFFFFFFFFFFFF404040FFC3C3C3FFFFFFFFFFFFFFFFFF000000FFFFFF
767 | FFFFFFFFFFFFFFFFFFFFB99D7EFF00000000C87036FFECECECFFECECECFFECEC
768 | ECFFECECECFFECECECFFE6E6E6FF525252FFECECECFFECECECFFECECECFF6767
769 | 67FFCECECEFF545454FFC5C5C5FF585858FFE7E7E7FFECECECFFECECECFFECEC
770 | ECFFECECECFFECECECFFECECECFFC87036FF0000000000000000000000000000
771 | 000000000000C87036FFE5E0DDFFE7ACACFFEC0000FFEC0000FFEC0000FFE936
772 | 36FFEC0000FFEC0000FFEC0000FFE26B6BFFD8D8D8FFD6D6D6FFD4CFCCFFC870
773 | 36FF0000000000000000000000000000000000000000000000004C4C4CFFFFFF
774 | FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
775 | FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
776 | FFFF4C4C4CFF00000000000000000000000000000000B99D7EFFFFFFFFFFEFEF
777 | EFFFF3F3F3FFFFFFFFFFDBDBDBFF222222FFFFFFFFFFC2C2C2FF0A0A0AFFDFDF
778 | DFFFFFFFFFFFEAEAEAFF151515FFEBEBEBFFFFFFFFFFFFFFFFFF000000FFFFFF
779 | FFFFFFFFFFFFFFFFFFFFB99D7EFF00000000C87036FFECECECFFECECECFFECEC
780 | ECFFECECECFFECECECFFECECECFF505050FFCCCCCCFFECECECFFDCDCDCFF4444
781 | 44FFEAEAEAFF545454FFECECECFFD2D2D2FFDEDEDEFFECECECFFECECECFFECEC
782 | ECFFECECECFFECECECFFECECECFFC87036FF0000000000000000000000000000
783 | 000000000000C87036FFE6E1DEFFE7E7E7FFE87171FFEC0000FFE76868FFE1E1
784 | E1FFE56E6EFFEC0000FFEC0000FFEC0000FFE36C6CFFD8D8D8FFD5D0CDFFC870
785 | 36FF0000000000000000000000000000000000000000000000004C4C4CFFFFFF
786 | FFFFFFFFFFFF000000FF000000FF000000FF000000FF000000FF000000FF0000
787 | 00FF000000FF000000FF000000FF000000FF000000FFFFFFFFFFFFFFFFFFFFFF
788 | FFFF4C4C4CFF00000000000000000000000000000000B99D7EFFFFFFFFFFDBDB
789 | DBFF2E2E2EFF4F4F4FFF252525FF949494FFFFFFFFFFC2C2C2FF3C3C3CFF5050
790 | 50FF505050FF1E1E1EFF939393FFFFFFFFFFFFFFFFFFFFFFFFFF000000FFFFFF
791 | FFFFFFFFFFFFFFFFFFFFB99D7EFF00000000C87036FFECECECFFECECECFFECEC
792 | ECFFECECECFFECECECFFECECECFFD9D9D9FF626262FF5E5E5EFF5A5A5AFFCBCB
793 | CBFFECECECFF545454FFECECECFFECECECFFECECECFFECECECFFECECECFFECEC
794 | ECFFECECECFFECECECFFECECECFFC87036FF0000000000000000000000000000
795 | 000000000000C87036FFE8E3E0FFE8E8E8FFE7E7E7FFE6ACACFFE4E4E4FFE2E2
796 | E2FFE1E1E1FFE56E6EFFEC0000FFEC0000FFEC0000FFDEA3A3FFD7D2CFFFC870
797 | 36FF0000000000000000000000000000000000000000000000004C4C4CFFFFFF
798 | FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
799 | FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
800 | FFFF4C4C4CFF00000000000000000000000000000000B99D7EFFFFFFFFFFFFFF
801 | FFFFFAFAFAFFDDDDDDFFECECECFFFFFFFFFFFFFFFFFFC2C2C2FF464646FFFFFF
802 | FFFFDCDCDCFFF1F1F1FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF000000FFFFFF
803 | FFFFFFFFFFFFFFFFFFFFB99D7EFF00000000C87036FFECECECFFECECECFFECEC
804 | ECFFECECECFFECECECFFECECECFFECECECFFECECECFFECECECFFECECECFFECEC
805 | ECFFECECECFFD8D8D8FFECECECFFECECECFFECECECFFECECECFFECECECFFECEC
806 | ECFFECECECFFECECECFFECECECFFC87036FF0000000000000000000000000000
807 | 000000000000C87036FFE9E4E1FFEAEAEAFFE8E8E8FFE7E7E7FFE5E5E5FFE4E4
808 | E4FFE2E2E2FFE1E1E1FFE56E6EFFEC0000FFE56666FFDBDBDBFFD8D3D0FFC870
809 | 36FF0000000000000000000000000000000000000000000000004C4C4CFFFFFF
810 | FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
811 | FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
812 | FFFF4C4C4CFF00000000000000000000000000000000B99D7EFFFFFFFFFFFFFF
813 | FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC2C2C2FF464646FFFFFF
814 | FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF000000FFFFFF
815 | FFFFFFFFFFFFFFFFFFFFB99D7EFF00000000C87036FFECECECFFECECECFFECEC
816 | ECFFECECECFFECECECFFECECECFFECECECFFECECECFFECECECFFECECECFFECEC
817 | ECFFECECECFFECECECFFECECECFFECECECFFECECECFFECECECFFECECECFFECEC
818 | ECFFECECECFFECECECFFECECECFFC87036FF0000000000000000000000000000
819 | 000000000000C87036FFEBE6E3FFEBEBEBFFEAEAEAFFE8E8E8FFE7E7E7FFE5E5
820 | E5FFE4E4E4FFE2E2E2FFE1E1E1FFE2A8A8FFDEDEDEFFDCDCDCFFDAD5D2FFC870
821 | 36FF0000000000000000000000000000000000000000000000004C4C4CFF4C4C
822 | 4CFF4C4C4CFF4C4C4CFF4C4C4CFF4C4C4CFF4C4C4CFF4C4C4CFF4C4C4CFF4C4C
823 | 4CFF4C4C4CFF4C4C4CFF4C4C4CFF4C4C4CFF4C4C4CFF4C4C4CFF4C4C4CFF4C4C
824 | 4CFF4C4C4CFF00000000000000000000000000000000B99D7EFFFFFFFFFFFFFF
825 | FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC6C6C6FF525252FFFFFF
826 | FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF000000FF000000FFFFFFFFFF0000
827 | 00FF000000FFFFFFFFFFB99D7EFF00000000BE6A34F9E3D0C3FFECECECFFECEC
828 | ECFFECECECFFECECECFFECECECFFECECECFFECECECFFECECECFFECECECFFECEC
829 | ECFFECECECFFECECECFFECECECFFECECECFFECECECFFECECECFFECECECFFECEC
830 | ECFFECECECFFECECECFFE3CFC2FFBD6A33F80000000000000000000000000000
831 | 000000000000C87036FFECE7E4FFEDEDEDFFEBEBEBFFEAEAEAFFE8E8E8FFE7E7
832 | E7FFE5E5E5FFE4E4E4FFE2E2E2FFE1E1E1FFDFDFDFFFDEDEDEFFDBD6D3FFC870
833 | 36FF0000000000000000000000000000000000000000000000004C4C4CFFFFFF
834 | FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
835 | FFFFFFFFFFFFFFFFFFFFFFFFFFFF4C4C4CFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
836 | FFFF4C4C4CFF00000000000000000000000000000000B99D7EFFFFFFFFFFFFFF
837 | FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
838 | FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
839 | FFFFFFFFFFFFFFFFFFFFB99D7EFF00000000381F0F88BE6A34F9C87036FFC870
840 | 36FFC87036FFC87036FFC87036FFC87036FFC87036FFC87036FFC87036FFC870
841 | 36FFC87036FFC87036FFC87036FFC87036FFC87036FFC87036FFC87036FFC870
842 | 36FFC87036FFC87036FFBE6A34F9361E0F860000000000000000000000000000
843 | 000000000000C87036FFECE1DAFFEBE6E2FFEAE5E1FFE8E3DFFFE7E2DEFFE6E1
844 | DDFFE5E0DCFFE3DEDAFFE2DDD9FFE0DBD7FFDFDAD6FFDDD8D4FFDCD1CAFFC870
845 | 36FF0000000000000000000000000000000000000000000000004C4C4CFFFFFF
846 | FFFF7E7E7EFF7E7E7EFF7E7E7EFF7E7E7EFF7E7E7EFF7E7E7EFF7E7E7EFF7E7E
847 | 7EFF7E7E7EFF7E7E7EFFFFFFFFFF4C4C4CFFFFFFFFFF7E7E7EFF7E7E7EFFFFFF
848 | FFFF4C4C4CFF00000000000000000000000000000000B99D7EFFB99D7EFFB99D
849 | 7EFFB99D7EFFB99D7EFFB99D7EFFB99D7EFFB99D7EFFB99D7EFFB99D7EFFB99D
850 | 7EFFB99D7EFFB99D7EFFB99D7EFFB99D7EFFB99D7EFFB99D7EFFB99D7EFFB99D
851 | 7EFFB99D7EFFB99D7EFFB99D7EFF000000000000000000000000000000000000
852 | 0000000000000000000000000000000000000000000000000000000000000000
853 | 0000000000000000000000000000000000000000000000000000000000000000
854 | 0000000000000000000000000000000000000000000000000000000000000000
855 | 000000000000B36633F1C87036FFC87036FFC87036FFC87036FFC87036FFC870
856 | 36FFC87036FFC87036FFC87036FFC87036FFC87036FFC87036FFC87036FFB366
857 | 33F10000000000000000000000000000000000000000000000004C4C4CFFFFFF
858 | FFFF7E7E7EFF7E7E7EFF7E7E7EFF7E7E7EFF7E7E7EFF7E7E7EFF7E7E7EFF7E7E
859 | 7EFF7E7E7EFF7E7E7EFFFFFFFFFF4C4C4CFFD3D3D3FF2E2E2EFF2E2E2EFFD3D3
860 | D3FF4C4C4CFF0000000000000000000000000000000000000000000000000000
861 | 0000000000000000000000000000000000000000000000000000000000000000
862 | 0000000000000000000000000000000000000000000000000000000000000000
863 | 0000000000000000000000000000000000000000000000000000000000000000
864 | 0000000000000000000000000000000000000000000000000000000000000000
865 | 0000000000000000000000000000000000000000000000000000000000000000
866 | 0000000000000000000000000000000000000000000000000000000000000000
867 | 0000000000000000000000000000000000000000000000000000000000000000
868 | 0000000000000000000000000000000000000000000000000000000000000000
869 | 00000000000000000000000000000000000000000000000000004C4C4CFFFFFF
870 | FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
871 | FFFFFFFFFFFFFFFFFFFFFFFFFFFF4C4C4CFFFFFFFFFFFBFBFBFFFBFBFBFFFFFF
872 | FFFF4C4C4CFF0000000000000000000000000000000000000000000000000000
873 | 0000000000000000000000000000000000000000000000000000000000000000
874 | 0000000000000000000000000000000000000000000000000000000000000000
875 | 0000000000000000000000000000000000000000000000000000000000000000
876 | 0000000000000000000000000000000000000000000000000000000000000000
877 | 0000000000000000000000000000000000000000000000000000000000000000
878 | 0000000000000000000000000000000000000000000000000000000000000000
879 | 0000000000000000000000000000000000000000000000000000000000000000
880 | 0000000000000000000000000000000000000000000000000000000000000000
881 | 00000000000000000000000000000000000000000000000000004C4C4CFF4C4C
882 | 4CFF4C4C4CFF4C4C4CFF4C4C4CFF4C4C4CFF4C4C4CFF4C4C4CFF4C4C4CFF4C4C
883 | 4CFF4C4C4CFF4C4C4CFF4C4C4CFF4C4C4CFF4C4C4CFF4C4C4CFF4C4C4CFF4C4C
884 | 4CFF4C4C4CFF0000000000000000000000000000000000000000000000000000
885 | 0000000000000000000000000000000000000000000000000000000000000000
886 | 0000000000000000000000000000000000000000000000000000000000000000
887 | 0000000000000000000000000000000000000000000000000000000000000000
888 | 0000000000000000000000000000000000000000000000000000000000000000
889 | 0000000000000000000000000000000000000000000000000000000000000000
890 | 0000000000000000000000000000000000000000000000000000000000000000
891 | 0000000000000000000000000000000000000000000000000000000000000000
892 | 0000000000000000000000000000000000000000000000000000000000000000
893 | 0000000000000000000000000000000000000000000000000000000000000000
894 | 0000000000000000000000000000000000000000000000000000000000000000
895 | 0000000000000000000000000000000000000000000000000000000000000000
896 | 0000000000000000000000000000000000000000000000000000000000000000
897 | 0000000000000000000000000000000000000000000000000000000000000000
898 | 0000000000000000000000000000000000000000000000000000000000000000
899 | 0000000000000000000000000000000000000000000000000000000000000000
900 | 0000000000000000000000000000000000000000000000000000000000000000
901 | 0000000000000000000000000000000000000000000000000000000000000000
902 | 0000000000000000000000000000000000000000000000000000000000000000
903 | 0000000000000000000000000000000000000000000000000000000000000000
904 | 0000000000000000000000000000000000000000000000000000000000000000
905 | 0000000000000000000000000000000000000000000000000000000000000000
906 | 0000000000000000000000000000000000000000000000000000000000000000
907 | 0000000000000000000000000000000000000000000000000000000000000000
908 | 0000000000000000000000000000000000000000000000000000000000000000
909 | 0000000000000000000000000000000000000000000000000000000000000000
910 | 0000000000000000000000000000000000000000000000000000000000000000
911 | 000000000000000000000000000000000000424D3E000000000000003E000000
912 | 2800000060000000480000000100010000000000600300000000000000000000
913 | 000000000000000000000000FFFFFF0000000000000000000000000000000000
914 | 0000000000000000000000000000000000000000000000000000000000000000
915 | 0000000000000000000000000000000000000000000000000000000000000000
916 | 0000000000000000000000000000000000000000000000000000000000000000
917 | 0000000000000000000000000000000000000000000000000000000000000000
918 | 0000000000000000000000000000000000000000000000000000000000000000
919 | 0000000000000000000000000000000000000000000000000000000000000000
920 | 0000000000000000000000000000000000000000000000000000000000000000
921 | 0000000000000000000000000000000000000000000000000000000000000000
922 | 0000000000000000000000000000000000000000000000000000000000000000
923 | 0000000000000000000000000000000000000000000000000000000000000000
924 | 0000000000000000000000000000000000000000000000000000000000000000
925 | 0000000000000000000000000000000000000000000000000000000000000000
926 | 0000000000000000000000000000000000000000000000000000000000000000
927 | 0000000000000000000000000000000000000000000000000000000000000000
928 | 0000000000000000000000000000000000000000000000000000000000000000
929 | 0000000000000000000000000000000000000000000000000000000000000000
930 | 0000000000000000000000000000000000000000000000000000000000000000
931 | 0000000000000000000000000000000000000000000000000000000000000000
932 | 0000000000000000000000000000000000000000000000000000000000000000
933 | 0000000000000000000000000000000000000000000000000000000000000000
934 | 0000000000000000000000000000000000000000000000000000000000000000
935 | 0000000000000000000000000000000000000000000000000000000000000000
936 | 0000000000000000000000000000000000000000000000000000000000000000
937 | 0000000000000000000000000000000000000000000000000000000000000000
938 | 0000000000000000000000000000000000000000000000000000000000000000
939 | 0000000000000000000000000000000000000000000000000000000000000000
940 | 0000000000000000000000000000000000000000000000000000000000000000
941 | 000000000000}
942 | end
943 | end
944 |
--------------------------------------------------------------------------------
/src/FormDesigner.Demo/ComponentsForm.pas:
--------------------------------------------------------------------------------
1 | unit ComponentsForm;
2 |
3 | interface
4 |
5 | uses
6 | Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics,
7 | Vcl.Controls, Vcl.Forms, Vcl.Dialogs, FormDesigner.Designer, Vcl.StdCtrls,
8 | Vcl.ExtCtrls, Vcl.ComCtrls, System.ImageList, Vcl.ImgList, Vcl.ToolWin,
9 | Vcl.Menus, fdUtils;
10 |
11 | type
12 | TfrmComponentsForm = class(TForm)
13 | ilImages: TImageList;
14 | tbControls: TToolBar;
15 | procedure FormCreate(Sender: TObject);
16 | procedure ButtonClick(Sender: TObject);
17 | end;
18 |
19 | var
20 | frmComponentsForm: TfrmComponentsForm;
21 |
22 | implementation
23 |
24 | {$R *.dfm}
25 |
26 | uses
27 | DesignForm;
28 |
29 | const
30 | ControlClasses: array[0..12] of TControlClass =
31 | (TButton, TLabel, TEdit, TCheckBox, TRadioButton, TMemo, TComboBox,
32 | TListBox, TProgressBar, TGroupBox, TPanel, TRadioGroup, TShape);
33 |
34 | procedure TfrmComponentsForm.FormCreate(Sender: TObject);
35 | var
36 | ControlClass: TControlClass;
37 | ImageIndex: Integer;
38 | i: Integer;
39 | Btn: TToolButton;
40 | begin
41 | for i := 0 to Length(ControlClasses) - 1 do
42 | begin
43 | ControlClass := ControlClasses[i];
44 | ImageIndex := AddResourceToImageList(ilImages, ControlClass.ClassName);
45 | Btn := AddControlToToolbar(tbControls, ImageIndex, ControlClass.ClassName, ControlClass);
46 | Btn.OnClick := ButtonClick;
47 | end;
48 | end;
49 |
50 | procedure TfrmComponentsForm.ButtonClick(Sender: TObject);
51 | var
52 | Button: TToolButton;
53 | ControlClass: TControlClass;
54 | begin
55 | Button := TToolButton(Sender);
56 | ControlClass := TControlClass(Button.Tag);
57 | frmDesignForm.fdDesigner.AddControl(ControlClass);
58 | end;
59 |
60 | end.
61 |
--------------------------------------------------------------------------------
/src/FormDesigner.Demo/DesignForm.dfm:
--------------------------------------------------------------------------------
1 | object frmDesignForm: TfrmDesignForm
2 | Left = 0
3 | Top = 0
4 | Caption = 'Form Designer'
5 | ClientHeight = 336
6 | ClientWidth = 635
7 | Color = clBtnFace
8 | DoubleBuffered = True
9 | Font.Charset = DEFAULT_CHARSET
10 | Font.Color = clWindowText
11 | Font.Height = -11
12 | Font.Name = 'Tahoma'
13 | Font.Style = []
14 | OldCreateOrder = False
15 | OnActivate = FormActivate
16 | PixelsPerInch = 96
17 | TextHeight = 13
18 | object fdDesigner: TFormDesigner
19 | ShowHints = True
20 | OnControlAdded = fdDesignerControlAdded
21 | OnControlSelected = fdDesignerEvent
22 | OnControlModified = fdDesignerEvent
23 | Left = 48
24 | Top = 48
25 | end
26 | end
27 |
--------------------------------------------------------------------------------
/src/FormDesigner.Demo/DesignForm.pas:
--------------------------------------------------------------------------------
1 | unit DesignForm;
2 |
3 | interface
4 |
5 | uses System.Classes, System.SysUtils, Vcl.Controls, Vcl.Forms, Vcl.ComCtrls,
6 | FormDesigner.Designer, Vcl.ToolWin, Vcl.StdCtrls,
7 | ComponentsForm, fdUtils;
8 |
9 | type
10 | TfrmDesignForm = class(TForm)
11 | fdDesigner: TFormDesigner;
12 | procedure FormActivate(Sender: TObject);
13 | procedure fdDesignerControlAdded(Sender: TObject);
14 | procedure fdDesignerEvent(Sender: TObject);
15 | end;
16 |
17 | var
18 | frmDesignForm: TfrmDesignForm;
19 | frmComponentsForm: TfrmComponentsForm;
20 |
21 | implementation
22 |
23 | {$R *.dfm}
24 |
25 | procedure TfrmDesignForm.fdDesignerControlAdded(Sender: TObject);
26 | var
27 | i: Integer;
28 | Button: TToolButton;
29 | begin
30 | for i := 0 to frmComponentsForm.tbControls.ButtonCount - 1 do
31 | begin
32 | Button := frmComponentsForm.tbControls.Buttons[i];
33 | if Button.Down then
34 | Button.Down := False;
35 | end;
36 | end;
37 |
38 | procedure TfrmDesignForm.fdDesignerEvent(Sender: TObject);
39 | begin
40 | Caption := 'Form Designer - ' + FormatControlInfo(TControl(Sender));
41 | end;
42 |
43 | procedure TfrmDesignForm.FormActivate(Sender: TObject);
44 | begin
45 | if not Assigned(frmComponentsForm) then
46 | begin
47 | frmComponentsForm := TfrmComponentsForm.Create(Self);
48 | frmComponentsForm.Top := Top;
49 | frmComponentsForm.Left := Left - frmComponentsForm.Width - 10;
50 | frmComponentsForm.Show;
51 | end;
52 | end;
53 |
54 | end.
55 |
--------------------------------------------------------------------------------
/src/FormDesigner.Demo/FormDesigner.Demo.dpr:
--------------------------------------------------------------------------------
1 | program FormDesigner.Demo;
2 |
3 | {$R *.dres}
4 |
5 | uses
6 | Vcl.Forms,
7 | ComponentsForm in 'ComponentsForm.pas' {frmComponentsForm},
8 | Vcl.Themes,
9 | Vcl.Styles,
10 | fdUtils in 'fdUtils.pas',
11 | DesignForm in 'DesignForm.pas' {frmDesignForm};
12 |
13 | {$R *.res}
14 |
15 | begin
16 | Application.Initialize;
17 | Application.MainFormOnTaskbar := True;
18 | Application.CreateForm(TfrmDesignForm, frmDesignForm);
19 | Application.Run;
20 | end.
21 |
--------------------------------------------------------------------------------
/src/FormDesigner.Demo/FormDesigner.Demo.dproj:
--------------------------------------------------------------------------------
1 |
2 |
3 | {0DCC20B9-B0CC-4F09-ACB2-E1ACB00A9A54}
4 | 18.6
5 | VCL
6 | FormDesigner.Demo.dpr
7 | True
8 | Release
9 | Win32
10 | 1
11 | Application
12 |
13 |
14 | true
15 |
16 |
17 | true
18 | Base
19 | true
20 |
21 |
22 | true
23 | Base
24 | true
25 |
26 |
27 | true
28 | Cfg_1
29 | true
30 | true
31 |
32 |
33 | true
34 | Base
35 | true
36 |
37 |
38 | true
39 | Cfg_2
40 | true
41 | true
42 |
43 |
44 | .\$(Platform)\$(Config)
45 | .\$(Platform)\$(Config)
46 | false
47 | false
48 | false
49 | false
50 | false
51 | System;Xml;Data;Datasnap;Web;Soap;Vcl;Vcl.Imaging;Vcl.Touch;Vcl.Samples;Vcl.Shell;$(DCC_Namespace)
52 | $(BDS)\bin\delphi_PROJECTICON.ico
53 | $(BDS)\bin\Artwork\Windows\UWP\delphi_UwpDefault_44.png
54 | $(BDS)\bin\Artwork\Windows\UWP\delphi_UwpDefault_150.png
55 | FormDesigner_Demo
56 |
57 |
58 | DBXSqliteDriver;IndyIPCommon;RESTComponents;bindcompdbx;DBXInterBaseDriver;vcl;IndyIPServer;vclactnband;vclFireDAC;IndySystem;tethering;svnui;dsnapcon;FireDACADSDriver;madExcept_;FireDACMSAccDriver;fmxFireDAC;vclimg;madBasic_;FireDAC;vcltouch;vcldb;bindcompfmx;svn;FireDACSqliteDriver;FireDACPgDriver;inetdb;soaprtl;DbxCommonDriver;fmx;FireDACIBDriver;fmxdae;xmlrtl;soapmidas;fmxobj;vclwinx;rtl;madDisAsm_;DbxClientDriver;CustomIPTransport;vcldsnap;dbexpress;IndyCore;vclx;bindcomp;appanalytics;dsnap;FireDACCommon;IndyIPClient;Sizer;bindcompvcl;RESTBackendComponents;VCLRESTComponents;soapserver;dbxcds;VclSmp;adortl;vclie;bindengine;DBXMySQLDriver;CloudService;dsnapxml;FireDACMySQLDriver;dbrtl;IndyProtocols;inetdbxpress;FireDACCommonODBC;FireDACCommonDriver;inet;fmxase;$(DCC_UsePackage)
59 | Winapi;System.Win;Data.Win;Datasnap.Win;Web.Win;Soap.Win;Xml.Win;Bde;$(DCC_Namespace)
60 | Debug
61 | true
62 | CompanyName=;FileDescription=$(MSBuildProjectName);FileVersion=1.0.0.0;InternalName=;LegalCopyright=;LegalTrademarks=;OriginalFilename=;ProgramID=com.embarcadero.$(MSBuildProjectName);ProductName=$(MSBuildProjectName);ProductVersion=1.0.0.0;Comments=
63 | 1033
64 | $(BDS)\bin\default_app.manifest
65 |
66 |
67 | DEBUG;$(DCC_Define)
68 | true
69 | false
70 | true
71 | true
72 | true
73 |
74 |
75 | false
76 | true
77 | PerMonitorV2
78 | FormDesigner.Designer;$(DCC_UsePackage)
79 | true
80 | 1033
81 | ..\FormDesigner.Package\Win32\Debug;$(DCC_UnitSearchPath)
82 | FormDesigner.Demo.ico
83 |
84 |
85 | false
86 | RELEASE;$(DCC_Define)
87 | 0
88 | 0
89 |
90 |
91 | true
92 | PerMonitorV2
93 | ..\FormDesigner.Package\Win32\Release;$(DCC_UnitSearchPath)
94 | true
95 | 1033
96 | FormDesigner.Demo.ico
97 |
98 |
99 |
100 | MainSource
101 |
102 |
103 |
104 | dfm
105 |
106 |
107 |
108 |
109 | dfm
110 |
111 |
112 | RCDATA
113 | TBUTTON
114 |
115 |
116 | RCDATA
117 | TCHECKBOX
118 |
119 |
120 | RCDATA
121 | TCOMBOBOX
122 |
123 |
124 | RCDATA
125 | TEDIT
126 |
127 |
128 | RCDATA
129 | TGROUPBOX
130 |
131 |
132 | RCDATA
133 | TLABEL
134 |
135 |
136 | RCDATA
137 | TLISTBOX
138 |
139 |
140 | RCDATA
141 | TMEMO
142 |
143 |
144 | RCDATA
145 | TPANEL
146 |
147 |
148 | RCDATA
149 | TRADIOBUTTON
150 |
151 |
152 | RCDATA
153 | TRADIOGROUP
154 |
155 |
156 | RCDATA
157 | TPROGRESSBAR
158 |
159 |
160 | RCDATA
161 | TSHAPE
162 |
163 |
164 | Cfg_2
165 | Base
166 |
167 |
168 | Base
169 |
170 |
171 | Cfg_1
172 | Base
173 |
174 |
175 |
176 | Delphi.Personality.12
177 | Application
178 |
179 |
180 |
181 | FormDesigner.Demo.dpr
182 |
183 |
184 | Microsoft Office 2000 Sample Automation Server Wrapper Components
185 | Microsoft Office XP Sample Automation Server Wrapper Components
186 |
187 |
188 |
189 |
190 |
191 | .\
192 | true
193 |
194 |
195 |
196 |
197 | .\
198 | true
199 |
200 |
201 |
202 |
203 | .\
204 | true
205 |
206 |
207 |
208 |
209 | .\
210 | true
211 |
212 |
213 |
214 |
215 | .\
216 | true
217 |
218 |
219 |
220 |
221 | .\
222 | true
223 |
224 |
225 |
226 |
227 | .\
228 | true
229 |
230 |
231 |
232 |
233 | .\
234 | true
235 |
236 |
237 |
238 |
239 | .\
240 | true
241 |
242 |
243 |
244 |
245 | .\
246 | true
247 |
248 |
249 |
250 |
251 | .\
252 | true
253 |
254 |
255 |
256 |
257 | .\
258 | true
259 |
260 |
261 |
262 |
263 | .\
264 | true
265 |
266 |
267 |
268 |
269 | .\
270 | true
271 |
272 |
273 |
274 |
275 | .\
276 | true
277 |
278 |
279 |
280 |
281 | .\
282 | true
283 |
284 |
285 |
286 |
287 | FormDesigner_Demo.exe
288 | true
289 |
290 |
291 |
292 |
293 | .\
294 | true
295 |
296 |
297 |
298 |
299 | .\
300 | true
301 |
302 |
303 |
304 |
305 | .\
306 | true
307 |
308 |
309 |
310 |
311 | .\
312 | true
313 |
314 |
315 |
316 |
317 | .\
318 | true
319 |
320 |
321 |
322 |
323 | .\
324 | true
325 |
326 |
327 |
328 |
329 | .\
330 | true
331 |
332 |
333 |
334 |
335 | .\
336 | true
337 |
338 |
339 |
340 |
341 | .\
342 | true
343 |
344 |
345 |
346 |
347 | .\
348 | true
349 |
350 |
351 |
352 |
353 | FormDesigner_Demo.exe
354 | true
355 |
356 |
357 |
358 |
359 | 1
360 |
361 |
362 | Contents\MacOS
363 | 1
364 |
365 |
366 | 0
367 |
368 |
369 |
370 |
371 | classes
372 | 1
373 |
374 |
375 |
376 |
377 | res\xml
378 | 1
379 |
380 |
381 |
382 |
383 | library\lib\armeabi-v7a
384 | 1
385 |
386 |
387 |
388 |
389 | library\lib\armeabi
390 | 1
391 |
392 |
393 |
394 |
395 | library\lib\mips
396 | 1
397 |
398 |
399 |
400 |
401 | library\lib\armeabi-v7a
402 | 1
403 |
404 |
405 |
406 |
407 | res\drawable
408 | 1
409 |
410 |
411 |
412 |
413 | res\values
414 | 1
415 |
416 |
417 |
418 |
419 | res\values-v21
420 | 1
421 |
422 |
423 |
424 |
425 | res\drawable
426 | 1
427 |
428 |
429 |
430 |
431 | res\drawable-xxhdpi
432 | 1
433 |
434 |
435 |
436 |
437 | res\drawable-ldpi
438 | 1
439 |
440 |
441 |
442 |
443 | res\drawable-mdpi
444 | 1
445 |
446 |
447 |
448 |
449 | res\drawable-hdpi
450 | 1
451 |
452 |
453 |
454 |
455 | res\drawable-xhdpi
456 | 1
457 |
458 |
459 |
460 |
461 | res\drawable-small
462 | 1
463 |
464 |
465 |
466 |
467 | res\drawable-normal
468 | 1
469 |
470 |
471 |
472 |
473 | res\drawable-large
474 | 1
475 |
476 |
477 |
478 |
479 | res\drawable-xlarge
480 | 1
481 |
482 |
483 |
484 |
485 | 1
486 |
487 |
488 | Contents\MacOS
489 | 1
490 |
491 |
492 | 0
493 |
494 |
495 |
496 |
497 | Contents\MacOS
498 | 1
499 | .framework
500 |
501 |
502 | Contents\MacOS
503 | 1
504 | .framework
505 |
506 |
507 | 0
508 |
509 |
510 |
511 |
512 | 1
513 | .dylib
514 |
515 |
516 | 1
517 | .dylib
518 |
519 |
520 | 1
521 | .dylib
522 |
523 |
524 | Contents\MacOS
525 | 1
526 | .dylib
527 |
528 |
529 | Contents\MacOS
530 | 1
531 | .dylib
532 |
533 |
534 | 0
535 | .dll;.bpl
536 |
537 |
538 |
539 |
540 | 1
541 | .dylib
542 |
543 |
544 | 1
545 | .dylib
546 |
547 |
548 | 1
549 | .dylib
550 |
551 |
552 | Contents\MacOS
553 | 1
554 | .dylib
555 |
556 |
557 | Contents\MacOS
558 | 1
559 | .dylib
560 |
561 |
562 | 0
563 | .bpl
564 |
565 |
566 |
567 |
568 | 0
569 |
570 |
571 | 0
572 |
573 |
574 | 0
575 |
576 |
577 | 0
578 |
579 |
580 | Contents\Resources\StartUp\
581 | 0
582 |
583 |
584 | Contents\Resources\StartUp\
585 | 0
586 |
587 |
588 | 0
589 |
590 |
591 |
592 |
593 | 1
594 |
595 |
596 | 1
597 |
598 |
599 | 1
600 |
601 |
602 |
603 |
604 | 1
605 |
606 |
607 | 1
608 |
609 |
610 | 1
611 |
612 |
613 |
614 |
615 | 1
616 |
617 |
618 | 1
619 |
620 |
621 | 1
622 |
623 |
624 |
625 |
626 | 1
627 |
628 |
629 | 1
630 |
631 |
632 | 1
633 |
634 |
635 |
636 |
637 | 1
638 |
639 |
640 | 1
641 |
642 |
643 | 1
644 |
645 |
646 |
647 |
648 | 1
649 |
650 |
651 | 1
652 |
653 |
654 | 1
655 |
656 |
657 |
658 |
659 | 1
660 |
661 |
662 | 1
663 |
664 |
665 | 1
666 |
667 |
668 |
669 |
670 | 1
671 |
672 |
673 |
674 |
675 | ..\$(PROJECTNAME).app.dSYM\Contents\Resources\DWARF
676 | 1
677 |
678 |
679 | ..\$(PROJECTNAME).app.dSYM\Contents\Resources\DWARF
680 | 1
681 |
682 |
683 |
684 |
685 | 1
686 |
687 |
688 | 1
689 |
690 |
691 |
692 |
693 | ..\
694 | 1
695 |
696 |
697 | ..\
698 | 1
699 |
700 |
701 |
702 |
703 | 1
704 |
705 |
706 | 1
707 |
708 |
709 | 1
710 |
711 |
712 |
713 |
714 | 1
715 |
716 |
717 | 1
718 |
719 |
720 | 1
721 |
722 |
723 |
724 |
725 | ..\$(PROJECTNAME).app.dSYM\Contents\Resources\DWARF
726 | 1
727 |
728 |
729 |
730 |
731 | ..\
732 | 1
733 |
734 |
735 | ..\
736 | 1
737 |
738 |
739 |
740 |
741 | Contents
742 | 1
743 |
744 |
745 | Contents
746 | 1
747 |
748 |
749 |
750 |
751 | Contents\Resources
752 | 1
753 |
754 |
755 | Contents\Resources
756 | 1
757 |
758 |
759 |
760 |
761 | library\lib\armeabi-v7a
762 | 1
763 |
764 |
765 | 1
766 |
767 |
768 | 1
769 |
770 |
771 | 1
772 |
773 |
774 | 1
775 |
776 |
777 | Contents\MacOS
778 | 1
779 |
780 |
781 | Contents\MacOS
782 | 1
783 |
784 |
785 | 0
786 |
787 |
788 |
789 |
790 | 1
791 |
792 |
793 | 1
794 |
795 |
796 |
797 |
798 | Assets
799 | 1
800 |
801 |
802 | Assets
803 | 1
804 |
805 |
806 |
807 |
808 | Assets
809 | 1
810 |
811 |
812 | Assets
813 | 1
814 |
815 |
816 |
817 |
818 |
819 |
820 |
821 |
822 |
823 |
824 |
825 |
826 |
827 | True
828 |
829 | False
830 |
831 | 12
832 |
833 |
834 |
835 |
836 |
837 |
--------------------------------------------------------------------------------
/src/FormDesigner.Demo/FormDesigner.Demo.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/havlicekp/form-designer/eef60c939b900d12f6addaa06a985c06410e6362/src/FormDesigner.Demo/FormDesigner.Demo.ico
--------------------------------------------------------------------------------
/src/FormDesigner.Demo/Images/tbutton.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/havlicekp/form-designer/eef60c939b900d12f6addaa06a985c06410e6362/src/FormDesigner.Demo/Images/tbutton.png
--------------------------------------------------------------------------------
/src/FormDesigner.Demo/Images/tcheckbox.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/havlicekp/form-designer/eef60c939b900d12f6addaa06a985c06410e6362/src/FormDesigner.Demo/Images/tcheckbox.png
--------------------------------------------------------------------------------
/src/FormDesigner.Demo/Images/tcombobox.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/havlicekp/form-designer/eef60c939b900d12f6addaa06a985c06410e6362/src/FormDesigner.Demo/Images/tcombobox.png
--------------------------------------------------------------------------------
/src/FormDesigner.Demo/Images/tedit.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/havlicekp/form-designer/eef60c939b900d12f6addaa06a985c06410e6362/src/FormDesigner.Demo/Images/tedit.png
--------------------------------------------------------------------------------
/src/FormDesigner.Demo/Images/tgroupbox.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/havlicekp/form-designer/eef60c939b900d12f6addaa06a985c06410e6362/src/FormDesigner.Demo/Images/tgroupbox.png
--------------------------------------------------------------------------------
/src/FormDesigner.Demo/Images/tlabel.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/havlicekp/form-designer/eef60c939b900d12f6addaa06a985c06410e6362/src/FormDesigner.Demo/Images/tlabel.png
--------------------------------------------------------------------------------
/src/FormDesigner.Demo/Images/tlistbox.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/havlicekp/form-designer/eef60c939b900d12f6addaa06a985c06410e6362/src/FormDesigner.Demo/Images/tlistbox.png
--------------------------------------------------------------------------------
/src/FormDesigner.Demo/Images/tmemo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/havlicekp/form-designer/eef60c939b900d12f6addaa06a985c06410e6362/src/FormDesigner.Demo/Images/tmemo.png
--------------------------------------------------------------------------------
/src/FormDesigner.Demo/Images/tpanel.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/havlicekp/form-designer/eef60c939b900d12f6addaa06a985c06410e6362/src/FormDesigner.Demo/Images/tpanel.png
--------------------------------------------------------------------------------
/src/FormDesigner.Demo/Images/tprogressbar.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/havlicekp/form-designer/eef60c939b900d12f6addaa06a985c06410e6362/src/FormDesigner.Demo/Images/tprogressbar.png
--------------------------------------------------------------------------------
/src/FormDesigner.Demo/Images/tradiobutton.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/havlicekp/form-designer/eef60c939b900d12f6addaa06a985c06410e6362/src/FormDesigner.Demo/Images/tradiobutton.png
--------------------------------------------------------------------------------
/src/FormDesigner.Demo/Images/tradiogroup.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/havlicekp/form-designer/eef60c939b900d12f6addaa06a985c06410e6362/src/FormDesigner.Demo/Images/tradiogroup.png
--------------------------------------------------------------------------------
/src/FormDesigner.Demo/Images/tshape.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/havlicekp/form-designer/eef60c939b900d12f6addaa06a985c06410e6362/src/FormDesigner.Demo/Images/tshape.png
--------------------------------------------------------------------------------
/src/FormDesigner.Demo/fdUtils.pas:
--------------------------------------------------------------------------------
1 | unit fdUtils;
2 |
3 | interface
4 |
5 | uses Classes, ExtCtrls, Controls, Windows, Vcl.Imaging.PngImage, Vcl.ComCtrls,
6 | Vcl.Graphics, System.SysUtils;
7 |
8 | function AddResourceToImageList(ImageList: TImageList; ResourceName: String): Integer;
9 | function AddControlToToolbar(ToolBar: TToolBar; AImageIndex: Integer; ControlName: String; ControlClass: TControlClass) : TToolButton;
10 | function FormatControlInfo(Control: TControl): String;
11 |
12 | implementation
13 |
14 | function AddControlToToolbar(ToolBar: TToolBar; AImageIndex: Integer; ControlName: String; ControlClass: TControlClass) : TToolButton;
15 | var
16 | Button, LastBtn: TToolButton;
17 | LastBtnIdx: Integer;
18 | begin
19 | Button := TToolButton.Create(ToolBar);
20 | with Button do
21 | begin
22 | ImageIndex := AImageIndex;
23 | Hint := ControlName;
24 | ShowHint := True;
25 | Style := tbsCheck;
26 | Grouped := True;
27 | Tag := Integer(ControlClass);
28 | end;
29 | LastBtnIdx := ToolBar.ButtonCount - 1;
30 | if LastBtnIdx > -1 then
31 | begin
32 | LastBtn := ToolBar.Buttons[LastBtnIdx];
33 | Button.Left := LastBtn.Left + LastBtn.Width;
34 | Button.Top := LastBtn.Top + LastBtn.Height;
35 | end;
36 | Button.Parent := ToolBar;
37 | Result := Button;
38 | end;
39 |
40 | function AddResourceToImageList(ImageList: TImageList;
41 | ResourceName: String): Integer;
42 | var
43 | Png: TPngImage;
44 | Bitmap: TBitmap;
45 | begin
46 | Png := TPngImage.Create;
47 | Bitmap := TBitmap.Create;
48 | try
49 | Png.LoadFromResourceName(HInstance, ResourceName);
50 | Bitmap.Assign(Png);
51 | Bitmap.AlphaFormat := afIgnored;
52 | Result := ImageList.Add(Bitmap, nil);
53 | finally
54 | Png.Free;
55 | Bitmap.Free;
56 | end;
57 | end;
58 |
59 | function FormatControlInfo(Control: TControl): String;
60 | begin
61 | if Assigned(Control) then
62 | Result :=
63 | Format('%s: %s; Rect (%d, %d, %d, %d); Width: %d, Height: %d',
64 | [Control.Name, Control.ClassName, Control.Left, Control.Top,
65 | Control.BoundsRect.Right, Control.BoundsRect.Bottom, Control.Width,
66 | Control.Height])
67 | else
68 | Result := 'Nothing Selected';
69 | end;
70 |
71 |
72 | end.
73 |
--------------------------------------------------------------------------------
/src/FormDesigner.Package/FormDesigner.Designer.pas:
--------------------------------------------------------------------------------
1 | unit FormDesigner.Designer;
2 |
3 | interface
4 |
5 | uses Classes, Controls, Graphics, Windows, Messages, Forms, SysUtils, StdCtrls,
6 | System.Generics.Collections, Vcl.AppEvnts, TypInfo, ExtCtrls,
7 | System.DateUtils, RTTI, System.SyncObjs, FormDesigner.Interfaces,
8 | FormDesigner.Utils, FormDesigner.DragHandles;
9 |
10 | type
11 |
12 | /// Conrols behavior of TFormDesigner during moving/sizing.
13 | TDragMode = (
14 | /// Changes to control's position/size are projected with a focus
15 | /// rectangle and are applied after the mouse is released.
16 | dmDeferred,
17 |
18 | /// Changes to control's position/size are visible immediatelly
19 | /// while dragging the mouse. EXPERIMENTAL, needs more work.
20 | dmImmediate);
21 |
22 | /// Callback for TFormDesigner.ForEachDragHandle
23 | TDragHandleProc = reference to procedure(DragHandle: TDragHandle);
24 |
25 | TMessageHandler = procedure(Sender: TControl; X, Y: integer) of object;
26 | TDragHandleClass = class of TDragHandle;
27 | TFormDesignerException = class(Exception);
28 | TWindowProc = function(Wnd: HWnd; msg: Cardinal; wParam: wParam;
29 | lParam: lParam): LResult; stdcall;
30 | TControlInfo = class;
31 | TRectModifiers = class;
32 |
33 | TFormDesigner = class(TComponent, IFormDesigner)
34 | strict private
35 | FParent: TWinControl;
36 | FChild: TControl;
37 | FDragHandleSize: Byte;
38 | FDragRect: TRect;
39 | FDragHandlesVisible: Boolean;
40 | FControls: TObjectList;
41 | FDragHandleColor: TColor;
42 | FState: TFormDesignerState;
43 | FApplicationEvents: TApplicationEvents;
44 | FForm: TForm;
45 | FShowHints: Boolean;
46 | FCurrentDragHandle: TDragHandle;
47 | FDrawGrid: Boolean;
48 | FFormOnPaint: TNotifyEvent;
49 | FGridGap: integer;
50 | FSnapToGrid: Boolean;
51 | FToolTip: TBalloonHint;
52 | FDragMode: TDragMode;
53 | FLastMouseMove: TDateTime;
54 | FHintTimer: TTimer;
55 | FLastHintedControl: TControl;
56 | FOldRect: TRect;
57 | FControlToAdd: TControl;
58 | FControlToAddRect: TRect;
59 | FControlToAddAutoSize: Boolean;
60 | // Where a control was clicked in client (control)
61 | // coordinates. Used while dragging the control
62 | FClickOrigin: TPoint;
63 | // Initial mouse position when setting dimensions
64 | // for a new control (by dragging a focus rect)
65 | FSizingOrigin: TPoint;
66 | // Mouse position in parent coordinages
67 | // when a button was pressed
68 | FButtonDownOrigin: TPoint;
69 | FRectModifiers: TRectModifiers;
70 | FOnControlSelected: TNotifyEvent;
71 | FOnControlModified: TNotifyEvent;
72 | FOnControlAdded: TNotifyEvent;
73 | FDragHandleBorderColor: TColor;
74 | FEnabled: Boolean;
75 | procedure SetEnabled(const Value: Boolean);
76 | procedure SetShowHints(const Value: Boolean);
77 | procedure SetChild(const Value: TControl);
78 | procedure SetDragHandleSize(const Value: Byte);
79 | procedure SetDragHandlesVisible(const Value: Boolean);
80 | procedure SetDragHandleColor(const Value: TColor);
81 | procedure SetGridGap(const Value: Integer);
82 | procedure SetDrawGrid(const Value: Boolean);
83 | procedure SetDragHandleBorderColor(const Value: TColor);
84 | procedure CancelSizeMove(WindowHandle: HWnd);
85 | procedure ClipCursor;
86 | procedure UpdateDragHandles;
87 | procedure MessageReceivedHandler(var msg: tagMSG; var Handled: Boolean);
88 | procedure FormPaintHandler(Sender: TObject);
89 | procedure ForEachDragHandle(Proc: TDragHandleProc);
90 | procedure HintTimerHandler(Sender: TObject);
91 | function DragHandleOfType(DragHandleClass: TDragHandleClass): TDragHandle;
92 | function IsOwnedControl(Control: TControl): Boolean;
93 | function AlignToGrid(Num: integer; Offset: integer = 0): integer;
94 | procedure MouseUpHandler(var msg: tagMSG; ApplyChanges: Boolean);
95 | procedure UpdateChildPos(Sender: TControl; X, Y: integer);
96 | function TryGetParent(const HWnd: HWnd; pt: TPoint;
97 | var Control: TControl): Boolean;
98 | function FindControl(const Handle: HWnd): TControl;
99 | procedure MouseMoveHandler(var msg: tagMSG);
100 | procedure StartMoving(Sender: TControl; X, Y: integer);
101 | procedure KeyDownHandler(var msg: tagMSG);
102 | procedure DrawRect(OnlyCleanUp: Boolean = False);
103 | procedure StartSizing(DragHandle: TDragHandle; MousePos: TPoint);
104 | property DragHandlesVisible: Boolean read FDragHandlesVisible
105 | write SetDragHandlesVisible;
106 | property Child: TControl read FChild write SetChild;
107 | procedure SetupControlToAdd(var pt: TPoint; Control: TControl);
108 | procedure MouseDownHandler(var msg: tagMSG);
109 | procedure SetCursor(CtrlInfo: TControlInfo);
110 | procedure RestoreCursor(CtrlInfo: TControlInfo);
111 | procedure ControlSelected;
112 | procedure ControlModified;
113 | procedure ControlAdded;
114 | public
115 | function GetDragRect: TRect;
116 | function GetChildRect: TRect;
117 | procedure UpdateDragRect(Rect: TRect; Directions: TDirections);
118 | procedure AddControl(ControlClass: TControlClass); overload;
119 | procedure AddControl(AControl: TControl); overload;
120 | procedure RemoveControl(Control: TControl);
121 | constructor Create(AOwner: TComponent); override;
122 | destructor Destroy; override;
123 | published
124 | property Enabled: Boolean read FEnabled write SetEnabled default True;
125 | property DragHandleSize: Byte read FDragHandleSize write SetDragHandleSize
126 | default 8;
127 | property DragHandleBorderColor: TColor read FDragHandleBorderColor
128 | write SetDragHandleBorderColor default TColor($D77800);
129 | // RGB(0, 120, 215);
130 | property SnapToGrid: Boolean read FSnapToGrid write FSnapToGrid
131 | default True;
132 | property DragHandleColor: TColor read FDragHandleColor
133 | write SetDragHandleColor default TColor($F3D6B2); // RGB(178, 214, 243);
134 | property DrawGrid: Boolean read FDrawGrid write SetDrawGrid default True;
135 | property GridGap: integer read FGridGap write SetGridGap default 8;
136 | property ShowHints: Boolean read FShowHints write SetShowHints
137 | default False;
138 | property DragMode: TDragMode read FDragMode write FDragMode
139 | default dmDeferred;
140 | property OnControlAdded: TNotifyEvent read FOnControlAdded
141 | write FOnControlAdded;
142 | property OnControlSelected: TNotifyEvent read FOnControlSelected
143 | write FOnControlSelected;
144 | property OnControlModified: TNotifyEvent read FOnControlModified
145 | write FOnControlModified;
146 | end;
147 |
148 | /// Holds information about a control managed by TFormDesigner
149 | TControlInfo = class
150 | public
151 | FormDesigner: TFormDesigner;
152 | Control: TControl;
153 | PrevCursor: TCursor;
154 |
155 | /// Used to replace Window procedure for Delphi controls
156 | PrevWndMethod: TWndMethod;
157 |
158 | /// Used to replace Window procedure for controls not managed by Delphi
159 | /// (like Edit inside a ComboBox)
160 | PrevWindowProc: TWindowProc;
161 |
162 | procedure ControlWindowProc(var msg: TMessage);
163 | end;
164 |
165 | /// There are slight differences among TControl.BoundsRect
166 | /// For TButton, BoundsRect includes 1px gap around the control, which accomodes focus rectangle
167 | /// For TComboBox or TEdit, there is no such gap so the focus rect has to be expanded
168 | /// These differences are handled by TRectModifier
169 | TRectModifier = class abstract
170 | public
171 | function Modify(var Rect: TRect): TRect; virtual; abstract;
172 | end;
173 |
174 | /// Base class for TRectModifier. Its method returns
175 | /// TRect without any changes
176 | TRectModifierBase = class(TRectModifier)
177 | function Modify(var Rect: TRect): TRect; override;
178 | end;
179 |
180 | /// Inflates TRect by a specified number of pixels
181 | TInflatingRectModifier = class(TRectModifierBase)
182 | strict private
183 | FInflateBy: integer;
184 | public
185 | constructor Create(InflateBy: integer);
186 | function Modify(var Rect: TRect): TRect; override;
187 | end;
188 |
189 | TRectModifiers = class
190 | strict private
191 | FRectModifiers: TObjectDictionary;
192 | FDefaultRectModifier: TRectModifier;
193 | public
194 | constructor Create;
195 | destructor Destroy; override;
196 | function GetForControl(Control: TControl): TRectModifier;
197 | end;
198 |
199 | procedure Register;
200 |
201 | const
202 | DragHandleClasses: array [0 .. 7] of TDragHandleClass = (TUpDragHandle,
203 | TDownDragHandle, TLeftDragHandle, TRightDragHandle, TUpLeftDragHandle,
204 | TUpRightDragHandle, TDownLeftDragHandle, TDownRightDragHandle);
205 |
206 | implementation
207 |
208 | // Filters Window messages and skips those related to keyboard or mouse
209 | // interaction. The aim is to hide any control interaction while they are managed by
210 | // TFormDesigner
211 | function IsAllowedMessage(const msg: Cardinal): Boolean;
212 | begin
213 | Result := (msg <> WM_SETFOCUS) and (msg <> WM_LBUTTONDOWN) and
214 | (msg <> WM_CHAR) and (msg <> WM_KEYDOWN) and (msg <> WM_LBUTTONDBLCLK) and
215 | (msg <> WM_MOUSEMOVE);
216 | end;
217 |
218 | // Window procedure for controls managed by Delphi
219 | procedure TControlInfo.ControlWindowProc(var msg: TMessage);
220 | begin
221 | if not FormDesigner.Enabled or IsAllowedMessage(msg.msg) then
222 | PrevWndMethod(msg);
223 | end;
224 |
225 | // Windows procedure for controls not managed by Delphi, like EDIT inside a
226 | // TComboBox. It is set by using SetWindowLong. In this case instance
227 | // methods can't be used.
228 | // If Form Designer is enabled, set arrow as a cursor.
229 | function ComboEditWindowProcedure(Wnd: HWnd; msg: Cardinal; wParam: wParam;
230 | lParam: lParam): LResult; stdcall;
231 | var
232 | ControlInfo: TControlInfo;
233 | begin
234 | Result := 0;
235 | ControlInfo := TControlInfo(GetProp(Wnd, 'TControlInfo'));
236 | if (msg = WM_SETCURSOR) and ControlInfo.FormDesigner.Enabled then
237 | SetCursor(LoadCursor(0, IDC_ARROW))
238 | else if not ControlInfo.FormDesigner.Enabled or IsAllowedMessage(msg) then
239 | Result := CallWindowProc(Addr(ControlInfo.PrevWindowProc), Wnd, msg,
240 | wParam, lParam);
241 | end;
242 |
243 |
244 | // -----------------------------------------------------------------
245 | // TFormDesigner
246 | // -----------------------------------------------------------------
247 |
248 | constructor TFormDesigner.Create(AOwner: TComponent);
249 | var
250 | DragHandleClass: TDragHandleClass;
251 | DragHandle: TDragHandle;
252 | begin
253 | inherited Create(AOwner);
254 | if AOwner is TForm then
255 | FForm := TForm(AOwner)
256 | else
257 | FForm := TForm(GetParentForm(TControl(AOwner)));
258 |
259 | FForm.RemoveWindowStyle(WS_CLIPCHILDREN);
260 | FRectModifiers := TRectModifiers.Create;
261 | FControls := TObjectList.Create;
262 |
263 | FDragHandleColor := RGB(178, 214, 243);
264 | FDragHandleBorderColor := RGB(0, 120, 215);
265 | FDragHandleSize := 8;
266 | FGridGap := 8;
267 | FSnapToGrid := True;
268 | FDragMode := dmDeferred;
269 | FEnabled := True;
270 | DrawGrid := True;
271 |
272 | for DragHandleClass in DragHandleClasses do
273 | begin
274 | DragHandle := DragHandleClass.Create(Self);
275 | with DragHandle do
276 | begin
277 | Size := FDragHandleSize;
278 | Color := FDragHandleColor;
279 | BorderColor := FDragHandleBorderColor;
280 | FormDesigner := Self;
281 | end;
282 | InsertComponent(DragHandle);
283 | end;
284 |
285 | if not(csDesigning in ComponentState) then
286 | begin
287 | FApplicationEvents := TApplicationEvents.Create(nil);
288 | FApplicationEvents.OnMessage := MessageReceivedHandler;
289 | FHintTimer := TTimer.Create(nil);
290 | with FHintTimer do
291 | begin
292 | Interval := 200;
293 | Enabled := FShowHints;
294 | OnTimer := HintTimerHandler;
295 | end;
296 | end;
297 |
298 | FToolTip := TBalloonHint.Create(nil);
299 | FToolTip.HideAfter := 2000;
300 | FToolTip.Style := TBalloonHintStyle.bhsStandard;
301 |
302 | end;
303 |
304 | destructor TFormDesigner.Destroy;
305 | begin
306 | FApplicationEvents.Free;
307 | FRectModifiers.Free;
308 | FHintTimer.Free;
309 | FToolTip.Free;
310 | FControls.Free;
311 | inherited Destroy;
312 | end;
313 |
314 | procedure TFormDesigner.MessageReceivedHandler(var msg: tagMSG;
315 | var Handled: Boolean);
316 | begin
317 | if (FEnabled) then
318 | begin
319 | case msg.message of
320 | WM_MOUSEMOVE:
321 | MouseMoveHandler(msg);
322 |
323 | WM_LBUTTONDOWN:
324 | MouseDownHandler(msg);
325 |
326 | WM_LBUTTONUP:
327 | MouseUpHandler(msg, True);
328 |
329 | WM_KEYDOWN:
330 | KeyDownHandler(msg);
331 | end;
332 | end;
333 | end;
334 |
335 | procedure TFormDesigner.MouseDownHandler(var msg: tagMSG);
336 | var
337 | GraphicCtrl, Control: TControl;
338 | pt: TPoint;
339 | begin
340 | if IsMessageForWindow(msg.HWnd, FForm.Handle) then
341 | begin
342 | pt := MAKEPOINT(msg.lParam);
343 | Control := FindControl(msg.HWnd);
344 | if (Control is TDragHandle) then
345 | begin
346 | StartSizing(TDragHandle(Control), MAKEPOINT(msg.lParam))
347 | end
348 | else if Assigned(FControlToAdd) and (FState = fdsReady) then
349 | begin
350 | SetupControlToAdd(pt, Control);
351 | StartSizing(DragHandleOfType(TDownRightDragHandle), TPoint.Zero);
352 | end
353 | else if Assigned(Control) or TryGetParent(msg.HWnd, pt, Control) then
354 | begin
355 | // Is there a TGraphicControl (TLabel, .. ) under the cursor?
356 | GraphicCtrl := TWinControl(Control).ControlAtPos(pt, True);
357 | if GraphicCtrl <> nil then
358 | begin
359 | if IsOwnedControl(GraphicCtrl) then
360 | StartMoving(GraphicCtrl, pt.X, pt.Y)
361 | end
362 | else
363 | begin
364 | // Handle clicks on an owned control or parent form
365 | if IsOwnedControl(Control) or (Control = FForm) then
366 | begin
367 | if Control.Parent <> nil then
368 | pt := Control.Parent.ScreenToClient(Control.ClientToScreen(pt));
369 | StartMoving(Control, pt.X, pt.Y);
370 | end;
371 | end;
372 | end
373 | end;
374 | end;
375 |
376 | procedure TFormDesigner.MouseMoveHandler(var msg: tagMSG);
377 | var
378 | pt: TPoint;
379 | Control: TControl;
380 | begin
381 | if not(FState = fdsReady) then
382 | begin
383 | if IsMessageForWindow(msg.HWnd, FForm.Handle) then
384 | begin
385 | pt := MAKEPOINT(msg.lParam);
386 | Control := FindControl(msg.HWnd);
387 | if Assigned(Control) or TryGetParent(msg.HWnd, pt, Control) then
388 | begin
389 | pt := FChild.Parent.ScreenToClient(Control.ClientToScreen(pt));
390 | if FState = fdsMoving then
391 | UpdateChildPos(Control.Parent, pt.X, pt.Y)
392 | else
393 | FCurrentDragHandle.UpdateChildSize(Control.Parent, pt.X, pt.Y);
394 | end;
395 | end
396 | end
397 | else if FShowHints and (msg.HWnd = FForm.Handle) and
398 | not Assigned(FForm.ControlAtPos(MAKEPOINT(msg.lParam), True, True, True))
399 | then
400 | begin
401 | // Hide hint when mouse is over the FForm
402 | FToolTip.HideHint;
403 | FLastHintedControl := nil;
404 | end;
405 |
406 | end;
407 |
408 | procedure TFormDesigner.KeyDownHandler(var msg: tagMSG);
409 | var
410 | Shift: TShiftState;
411 | Key: Word;
412 |
413 | procedure UpdateChildProp(CtrlPropName, ShiftPropName: String;
414 | Value: integer);
415 | var
416 | PropValue: integer;
417 | begin
418 | if (ssCtrl in Shift) then
419 | begin
420 | PropValue := GetOrdProp(FChild, CtrlPropName);
421 | PropValue := PropValue + Value;
422 | SetOrdProp(FChild, CtrlPropName, PropValue);
423 | end
424 | else if (ssShift in Shift) then
425 | begin
426 | PropValue := GetOrdProp(FChild, ShiftPropName);
427 | PropValue := PropValue + Value;
428 | SetOrdProp(FChild, ShiftPropName, PropValue);
429 | end;
430 | FDragRect := FChild.BoundsRect;
431 | UpdateDragHandles;
432 | ControlModified;
433 | end;
434 |
435 | begin
436 | if IsMessageForWindow(msg.HWnd, FForm.Handle) then
437 | begin
438 | Shift := KeyDataToShiftState(msg.lParam);
439 | Key := Word(msg.wParam);
440 | case FState of
441 |
442 | fdsReady:
443 | case Key of
444 | VK_UP:
445 | UpdateChildProp('Top', 'Height', -1);
446 | VK_DOWN:
447 | UpdateChildProp('Top', 'Height', 1);
448 | VK_LEFT:
449 | UpdateChildProp('Left', 'Width', -1);
450 | VK_RIGHT:
451 | UpdateChildProp('Left', 'Width', 1);
452 | VK_DELETE:
453 | begin
454 | if FChild <> nil then
455 | begin
456 | RemoveControl(FChild);
457 | if (FChild is TWinControl) then
458 | if TWinControl(FChild).ControlCount <> 0 then
459 | EnumChilds(TWinControl(FChild), RemoveControl);
460 | if (FParent is TForm) then
461 | TForm(FParent).ActiveControl := nil;
462 | FChild.Free;
463 | if FControls.Count <> 0 then
464 | Child := FControls[0].Control
465 | else
466 | begin
467 | Child := nil;
468 | DragHandlesVisible := False;
469 | end;
470 | end;
471 | end;
472 | end;
473 |
474 | fdsMoving, fdsSizing:
475 | if (Key = VK_ESCAPE) then
476 | CancelSizeMove(msg.HWnd);
477 |
478 | end;
479 | end;
480 | end;
481 |
482 | procedure TFormDesigner.SetupControlToAdd(var pt: TPoint; Control: TControl);
483 | var
484 | Parent: TWinControl;
485 | begin
486 | FSizingOrigin := TPoint.Create(pt.X, pt.Y);
487 | if (csAcceptsControls in Control.ControlStyle) then
488 | Parent := TWinControl(Control)
489 | else
490 | begin
491 | Parent := Control.Parent;
492 | pt := Parent.ScreenToClient(Control.ClientToScreen(pt));
493 | end;
494 | Parent.RemoveWindowStyle(WS_CLIPCHILDREN);
495 | with FControlToAdd do
496 | begin
497 | Visible := False;
498 | Name := GetControlName(FForm, FControlToAdd.ClassType);
499 | SetControlText(FControlToAdd, Name);
500 | Left := AlignToGrid(pt.X);
501 | Top := AlignToGrid(pt.Y);
502 | Width := 0;
503 | Height := 0;
504 | end;
505 | FControlToAdd.Parent := Parent;
506 | Child := FControlToAdd;
507 | end;
508 |
509 | procedure TFormDesigner.ClipCursor;
510 | var
511 | Rect: TRect;
512 | begin
513 | Rect := FParent.ClientRect.ClientToScreen(FParent);
514 | Windows.ClipCursor(@Rect);
515 | end;
516 |
517 | // ApplyChanges tells whether changes to FChild's size/position should
518 | // be applied on the button relase. When False, FChild's size/position
519 | // is not changed.
520 | procedure TFormDesigner.MouseUpHandler(var msg: tagMSG; ApplyChanges: Boolean);
521 | var
522 | MousePos: TPoint;
523 | begin
524 | if (FState <> fdsReady) and IsMessageForWindow(msg.HWnd, FForm.Handle) then
525 | begin
526 | FState := fdsReady;
527 | FCurrentDragHandle := nil;
528 | FToolTip.HideHint;
529 | Windows.ClipCursor(nil);
530 |
531 | if Assigned(FChild) then
532 | begin
533 | // Clean up the last focus rect drawn
534 | DrawRect(True);
535 | // Should we apply changes to size/position?
536 | if ApplyChanges then
537 | begin
538 | FChild.BoundsRect := FDragRect;
539 | UpdateDragHandles;
540 | end;
541 | DragHandlesVisible := True;
542 | end;
543 |
544 | if Assigned(FControlToAdd) then
545 | begin
546 | MousePos.SetLocation(MAKEPOINT(msg.lParam));
547 | if FControlToAdd.BoundsRect.BottomRight.IsZero or
548 | PointsEqual(FSizingOrigin, MousePos) then
549 | begin
550 | if (FSnapToGrid) then
551 | begin
552 | FControlToAdd.Left := AlignToGrid(FControlToAdd.Left);
553 | FControlToAdd.Top := AlignToGrid(FControlToAdd.Top);
554 | end;
555 | FControlToAdd.Width := FControlToAddRect.Width;
556 | FControlToAdd.Height := FControlToAddRect.Height;
557 | Child := FControlToAdd;
558 | end;
559 | if FControlToAddAutoSize then
560 | SetOrdProp(FControlToAdd, 'AutoSize', NativeInt(True));
561 | FControlToAdd.Visible := True;
562 | AddControl(FControlToAdd);
563 | ControlAdded;
564 | FControlToAdd := nil;
565 | UpdateDragHandles;
566 | end;
567 | ControlModified;
568 | end;
569 | end;
570 |
571 | procedure TFormDesigner.DrawRect(OnlyCleanUp: Boolean = False);
572 | var
573 | DC: HDC;
574 | RectModifier: TRectModifier;
575 | begin
576 | if (FDragMode = dmDeferred) or Assigned(FControlToAdd) then
577 | begin
578 | DC := GetDC(FParent.Handle);
579 | try
580 | RectModifier := FRectModifiers.GetForControl(FChild);
581 | DrawFocusRect(DC, RectModifier.Modify(FOldRect));
582 | if not OnlyCleanUp then
583 | begin
584 | DrawFocusRect(DC, RectModifier.Modify(FDragRect));
585 | FOldRect := FDragRect;
586 | end;
587 | finally
588 | ReleaseDC(FParent.Handle, DC);
589 | end;
590 | end;
591 | end;
592 |
593 | function TFormDesigner.AlignToGrid(Num: integer; Offset: integer = 0): integer;
594 | var
595 | Remainder: integer;
596 | begin
597 | Result := Num;
598 | if FSnapToGrid then
599 | begin
600 | Remainder := Num mod FGridGap;
601 | if (Remainder > (FGridGap div 2)) then
602 | begin
603 | Result := Num + Offset + (FGridGap - Remainder);
604 | end
605 | else
606 | begin
607 | Result := Num + Offset - Remainder;
608 | end;
609 | end;
610 | end;
611 |
612 | procedure TFormDesigner.StartMoving(Sender: TControl; X, Y: integer);
613 | begin
614 | FButtonDownOrigin := TPoint.Create(X, Y);
615 | FToolTip.HideHint;
616 | DragHandlesVisible := False;
617 | if Assigned(FChild) then
618 | FDragRect := Child.BoundsRect;
619 | FOldRect := TRect.Empty;
620 |
621 | if not(Sender is TForm) then
622 | begin
623 | if Child <> Sender then
624 | Child := Sender;
625 | FClickOrigin.X := X - FChild.Left;
626 | FClickOrigin.Y := Y - FChild.Top;
627 | FState := fdsMoving;
628 | ClipCursor;
629 | DrawRect;
630 | end
631 | else
632 | begin
633 | Child := nil;
634 | end;
635 | end;
636 |
637 | procedure TFormDesigner.CancelSizeMove(WindowHandle: HWnd);
638 | var
639 | msg: tagMSG;
640 | begin
641 | msg.HWnd := WindowHandle;
642 | MouseUpHandler(msg, False);
643 | end;
644 |
645 | procedure TFormDesigner.StartSizing(DragHandle: TDragHandle; MousePos: TPoint);
646 | begin
647 | FCurrentDragHandle := DragHandle;
648 | FCurrentDragHandle.SetSizingOrigin(MousePos.X, MousePos.Y);
649 | FState := fdsSizing;
650 | DragHandlesVisible := False;
651 | ClipCursor;
652 | FDragRect := FChild.BoundsRect;
653 | FOldRect := TRect.Empty;
654 | FToolTip.HideHint;
655 | DrawRect;
656 | end;
657 |
658 | procedure TFormDesigner.AddControl(ControlClass: TControlClass);
659 | begin
660 | FControlToAdd := ControlClass.Create(FForm);
661 | FControlToAddRect := FControlToAdd.BoundsRect;
662 | if IsPublishedProp(FControlToAdd, 'AutoSize') then
663 | begin
664 | FControlToAddAutoSize := Boolean(GetObjectProp(FControlToAdd, 'AutoSize'));
665 | if (FControlToAddAutoSize) then
666 | SetObjectProp(FControlToAdd, 'AutoSize', TObject(False));
667 | end
668 | else
669 | FControlToAddAutoSize := False;
670 | end;
671 |
672 | procedure TFormDesigner.AddControl(AControl: TControl);
673 | var
674 | ControlInfo: TControlInfo;
675 | EditWnd: HWnd;
676 | begin
677 | ControlInfo := TControlInfo.Create;
678 | with ControlInfo do
679 | begin
680 | Control := AControl;
681 | FormDesigner := Self;
682 | PrevWndMethod := Control.WindowProc;
683 | Control.WindowProc := ControlWindowProc;
684 | SetCursor(ControlInfo);
685 | if (AControl is TComboBox) then
686 | begin
687 | EditWnd := GetWindow(TComboBox(Control).Handle, GW_CHILD);
688 | SetProp(EditWnd, 'TControlInfo', DWORD(ControlInfo));
689 | @PrevWindowProc := Pointer(SetWindowLong(EditWnd, GWL_WNDPROC,
690 | Longint(@ComboEditWindowProcedure)));
691 | end;
692 | if Control is TWinControl then
693 | begin
694 | TWinControl(AControl).RemoveWindowStyle(WS_CLIPCHILDREN);
695 | end;
696 | end;
697 | FControls.Add(ControlInfo);
698 | end;
699 |
700 | procedure TFormDesigner.RemoveControl(Control: TControl);
701 | var
702 | i: Byte;
703 | begin
704 | if FControls.Count <> 0 then
705 | begin
706 | for i := 0 to FControls.Count - 1 do
707 | if FControls[i].Control = Control then
708 | begin
709 | Control.WindowProc := FControls[i].PrevWndMethod;
710 | FControls.Remove(FControls[i]);
711 | Exit;
712 | end;
713 | end;
714 | raise TFormDesignerException.Create('Unable to remove a control');
715 | end;
716 |
717 | procedure TFormDesigner.UpdateChildPos(Sender: TControl; X, Y: integer);
718 | begin
719 | if PointsEqual(FButtonDownOrigin, TPoint.Create(X, Y)) then
720 | Exit;
721 |
722 | FLastMouseMove := Now;
723 | DrawRect;
724 |
725 | if (FSnapToGrid) then
726 | begin
727 | FDragRect.Left := AlignToGrid(X - FClickOrigin.X, FChild.Left mod FGridGap);
728 | FDragRect.Top := AlignToGrid(Y - FClickOrigin.Y, FChild.Top mod FGridGap);
729 | end
730 | else
731 | begin
732 | FDragRect.Left := X - FClickOrigin.X;
733 | FDragRect.Top := Y - FClickOrigin.Y;
734 | end;
735 |
736 | FDragRect.Bottom := FDragRect.Top + FChild.Height;
737 | FDragRect.Right := FDragRect.Left + FChild.Width;
738 |
739 | if FDragMode = dmImmediate then
740 | FChild.BoundsRect := FDragRect
741 | else
742 | DrawRect;
743 |
744 | end;
745 |
746 | procedure TFormDesigner.HintTimerHandler(Sender: TObject);
747 | var
748 | ms: Int64;
749 | Control, Child: TControl;
750 | CursorPos: TPoint;
751 | begin
752 | if FEnabled and (FState = fdsReady) then
753 | begin
754 | ms := System.DateUtils.MilliSecondsBetween(Now, FLastMouseMove);
755 | if ms > 50 then
756 | begin
757 | CursorPos := Mouse.CursorPos;
758 | Control := Controls.FindVCLWindow(CursorPos);
759 | if Assigned(Control) then
760 | begin
761 | Child := TWinControl(Control)
762 | .ControlAtPos(Control.ScreenToClient(CursorPos), True, True, True);
763 | // Is there a pure Delphi control? (TLabel, TShape, ... )
764 | if Assigned(Child) then
765 | Control := Child;
766 | if (Control <> FLastHintedControl) and IsOwnedControl(Control) then
767 | begin
768 | FLastHintedControl := Control;
769 | FToolTip.Description :=
770 | Format('%s: %s%sBounds: %d, %d, %d, %d; Size: %d, %d',
771 | [Control.Name, Control.ClassName, sLineBreak, Control.Left,
772 | Control.Top, Control.BoundsRect.Right, Control.BoundsRect.Bottom,
773 | Control.Width, Control.Height, sLineBreak]);
774 | CursorPos.Offset(34, 24);
775 | FToolTip.ShowHint(CursorPos);
776 | end;
777 | end
778 | else
779 | FToolTip.HideHint;
780 | end;
781 | end;
782 | end;
783 |
784 | procedure TFormDesigner.FormPaintHandler;
785 | var
786 | i, j: integer;
787 | begin
788 | if FEnabled then
789 | begin
790 | for i := 0 to FForm.Height - 1 do
791 | begin
792 | if (i mod FGridGap) = 0 then
793 | for j := 0 to FForm.Width - 1 do
794 | if (j mod FGridGap) = 0 then
795 | FForm.Canvas.Pixels[j, i] := clBlack;
796 | end;
797 | if Assigned(FFormOnPaint) then
798 | FFormOnPaint(Self);
799 | end;
800 | end;
801 |
802 | procedure TFormDesigner.SetChild(const Value: TControl);
803 | begin
804 | FChild := Value;
805 | if Assigned(FChild) then
806 | begin
807 | FParent := FChild.Parent;
808 | FDragRect := Child.BoundsRect;
809 | // Internally, Delphi manipulates windows during BringToFront
810 | // which brings troubles with painting focus rect
811 | // --> FChild.BringToFront;
812 | ForEachDragHandle(
813 | procedure(DragHandle: TDragHandle)
814 | begin
815 | DragHandle.Parent := FParent;
816 | DragHandle.BringToFront;
817 | DragHandle.UpdatePosition(FChild);
818 | end);
819 | end
820 | else
821 | begin
822 | FDragRect := TRect.Empty;
823 | end;
824 | FOldRect := TRect.Empty;
825 | ControlSelected;
826 | end;
827 |
828 | procedure TFormDesigner.UpdateDragHandles();
829 | begin
830 | ForEachDragHandle(
831 | procedure(DragHandle: TDragHandle)
832 | begin
833 | DragHandle.UpdatePosition(FChild);
834 | end);
835 | end;
836 |
837 | procedure TFormDesigner.UpdateDragRect(Rect: TRect; Directions: TDirections);
838 | begin
839 | FDragRect := Rect;
840 | if FSnapToGrid then
841 | begin
842 | if dLeft in Directions then
843 | FDragRect.Left := AlignToGrid(FDragRect.Left);
844 |
845 | if dRight in Directions then
846 | FDragRect.Right := AlignToGrid(FDragRect.Right);
847 |
848 | if dTop in Directions then
849 | FDragRect.Top := AlignToGrid(FDragRect.Top);
850 |
851 | if dBottom in Directions then
852 | FDragRect.Bottom := AlignToGrid(FDragRect.Bottom);
853 | end;
854 |
855 | if (FDragMode = dmImmediate) then
856 | FChild.BoundsRect := FDragRect
857 | else
858 | DrawRect;
859 | end;
860 |
861 | function TFormDesigner.TryGetParent(const HWnd: HWnd; pt: TPoint;
862 | var Control: TControl): Boolean;
863 | var
864 | ClsName: array [0 .. 5] of char;
865 | begin
866 | Result := False;
867 | GetClassName(HWnd, ClsName, 5);
868 | if UpperCase(ClsName) = 'EDIT' then
869 | begin
870 | // Probably TComboBox, find EDIT's parent
871 | Control := FindControl(GetParent(HWnd));
872 | if (Control <> nil) then
873 | begin
874 | ClientToScreen(HWnd, pt);
875 | pt := Control.ScreenToClient(pt);
876 | Result := True;
877 | end;
878 | end;
879 | end;
880 |
881 | procedure TFormDesigner.SetDragHandleBorderColor(const Value: TColor);
882 | begin
883 | FDragHandleBorderColor := Value;
884 | ForEachDragHandle(
885 | procedure(DragHandle: TDragHandle)
886 | begin
887 | DragHandle.BorderColor := FDragHandleBorderColor;
888 | end);
889 | end;
890 |
891 | procedure TFormDesigner.SetDragHandleColor(const Value: TColor);
892 | begin
893 | FDragHandleColor := Value;
894 | ForEachDragHandle(
895 | procedure(DragHandle: TDragHandle)
896 | begin
897 | DragHandle.Color := FDragHandleColor;
898 | end);
899 | end;
900 |
901 | procedure TFormDesigner.SetDrawGrid(const Value: Boolean);
902 | begin
903 | if FDrawGrid <> Value then
904 | begin
905 | FDrawGrid := Value;
906 | if FDrawGrid then
907 | begin
908 | if Assigned(FForm.OnPaint) then
909 | FFormOnPaint := FForm.OnPaint;
910 | FForm.OnPaint := FormPaintHandler;
911 | end
912 | else
913 | begin
914 | if Assigned(FFormOnPaint) then
915 | begin
916 | FForm.OnPaint := FFormOnPaint;
917 | FFormOnPaint := nil;
918 | end
919 | else
920 | FForm.OnPaint := nil;
921 | end;
922 | FForm.Refresh;
923 | end;
924 | end;
925 |
926 | procedure TFormDesigner.SetCursor(CtrlInfo: TControlInfo);
927 | begin
928 | with CtrlInfo do
929 | begin
930 | PrevCursor := Control.Cursor;
931 | Control.Cursor := crArrow;
932 | end;
933 | end;
934 |
935 | procedure TFormDesigner.RestoreCursor(CtrlInfo: TControlInfo);
936 | begin
937 | CtrlInfo.Control.Cursor := CtrlInfo.PrevCursor;
938 | end;
939 |
940 | procedure TFormDesigner.SetEnabled(const Value: Boolean);
941 | var
942 | CtrlInfo: TControlInfo;
943 | begin
944 | if FEnabled <> Value then
945 | begin
946 | FEnabled := Value;
947 | if not FEnabled then
948 | begin
949 | Child := nil;
950 | DragHandlesVisible := False;
951 | for CtrlInfo in FControls do
952 | RestoreCursor(CtrlInfo);
953 | end
954 | else
955 | begin
956 | for CtrlInfo in FControls do
957 | SetCursor(CtrlInfo);
958 | end;
959 | FForm.Refresh;
960 | end;
961 | end;
962 |
963 | procedure TFormDesigner.SetDragHandleSize(const Value: Byte);
964 | begin
965 | FDragHandleSize := Value;
966 | ForEachDragHandle(
967 | procedure(DragHandle: TDragHandle)
968 | begin
969 | DragHandle.Width := Value;
970 | DragHandle.Height := Value;
971 | end);
972 | end;
973 |
974 | procedure TFormDesigner.SetDragHandlesVisible(const Value: Boolean);
975 | begin
976 | FDragHandlesVisible := Value;
977 | ForEachDragHandle(
978 | procedure(DragHandle: TDragHandle)
979 | begin
980 | DragHandle.Visible := Value;
981 | end);
982 | FForm.Update;
983 | end;
984 |
985 | function TFormDesigner.GetChildRect: TRect;
986 | begin
987 | Result := FChild.BoundsRect;
988 | end;
989 |
990 | function TFormDesigner.GetDragRect: TRect;
991 | begin
992 | Result := FDragRect;
993 | end;
994 |
995 | function TFormDesigner.DragHandleOfType(DragHandleClass: TDragHandleClass)
996 | : TDragHandle;
997 | var
998 | i: integer;
999 | DragHandle: TDragHandle;
1000 | begin
1001 | for i := 0 to ComponentCount - 1 do
1002 | begin
1003 | DragHandle := TDragHandle(Components[i]);
1004 | if DragHandle.ClassNameIs(DragHandleClass.ClassName) then
1005 | begin
1006 | Result := DragHandle;
1007 | Exit;
1008 | end;
1009 | end;
1010 | raise TFormDesignerException.Create('Unknow DragHandle Type');
1011 | end;
1012 |
1013 | procedure TFormDesigner.SetGridGap(const Value: integer);
1014 | begin
1015 | FGridGap := Value;
1016 | FForm.Refresh;
1017 | end;
1018 |
1019 | procedure TFormDesigner.SetShowHints(const Value: Boolean);
1020 | begin
1021 | FShowHints := Value;
1022 | if not(csDesigning in ComponentState) then
1023 | begin
1024 | FHintTimer.Enabled := Value;
1025 | end;
1026 | end;
1027 |
1028 | function TFormDesigner.IsOwnedControl(Control: TControl): Boolean;
1029 | var
1030 | ControlInfo: TControlInfo;
1031 | begin
1032 | Result := False;
1033 | for ControlInfo in FControls do
1034 | if ControlInfo.Control = Control then
1035 | begin
1036 | Result := True;
1037 | Exit;
1038 | end;
1039 | end;
1040 |
1041 | function TFormDesigner.FindControl(const Handle: HWnd): TControl;
1042 | begin
1043 | Result := Vcl.Controls.FindControl(Handle);
1044 | if not Assigned(Result) then
1045 | TryGetParent(Handle, TPoint.Zero, Result);
1046 | end;
1047 |
1048 | procedure TFormDesigner.ForEachDragHandle(Proc: TDragHandleProc);
1049 | var
1050 | i: integer;
1051 | begin
1052 | for i := 0 to ComponentCount - 1 do
1053 | Proc(TDragHandle(Components[i]));
1054 | end;
1055 |
1056 | procedure TFormDesigner.ControlModified;
1057 | begin
1058 | if (Assigned(FOnControlModified)) then
1059 | FOnControlModified(FChild);
1060 | end;
1061 |
1062 | procedure TFormDesigner.ControlSelected;
1063 | begin
1064 | if (Assigned(FOnControlSelected)) then
1065 | FOnControlSelected(FChild);
1066 | end;
1067 |
1068 | procedure TFormDesigner.ControlAdded;
1069 | begin
1070 | if (Assigned(FOnControlAdded)) then
1071 | FOnControlAdded(FChild);
1072 | end;
1073 |
1074 |
1075 | // -----------------------------------------------------------------
1076 | // TInflatingRectModifier
1077 | // -----------------------------------------------------------------
1078 |
1079 | constructor TInflatingRectModifier.Create(InflateBy: integer);
1080 | begin
1081 | FInflateBy := InflateBy;
1082 | end;
1083 |
1084 | function TInflatingRectModifier.Modify(var Rect: TRect): TRect;
1085 | var
1086 | InflatedRect: TRect;
1087 | begin
1088 | InflatedRect := Rect;
1089 | InflatedRect.Inflate(FInflateBy, FInflateBy, FInflateBy, FInflateBy);
1090 | Result := InflatedRect;
1091 | end;
1092 |
1093 |
1094 | // -----------------------------------------------------------------
1095 | // TRectModifierBase
1096 | // -----------------------------------------------------------------
1097 |
1098 | function TRectModifierBase.Modify(var Rect: TRect): TRect;
1099 | begin
1100 | Result := Rect;
1101 | end;
1102 |
1103 |
1104 | // -----------------------------------------------------------------
1105 | // TRectModifiers
1106 | // -----------------------------------------------------------------
1107 |
1108 | function TRectModifiers.GetForControl(Control: TControl): TRectModifier;
1109 | var
1110 | BaseClass: TControlClass;
1111 | begin
1112 | for BaseClass in FRectModifiers.Keys do
1113 | begin
1114 | if Control.InheritsFrom(BaseClass) then
1115 | begin
1116 | Result := FRectModifiers.Items[BaseClass];
1117 | Exit;
1118 | end;
1119 | end;
1120 | Result := FDefaultRectModifier;
1121 | end;
1122 |
1123 | constructor TRectModifiers.Create;
1124 | var
1125 | InflatingRectModifier: TRectModifier;
1126 | begin
1127 | FDefaultRectModifier := TRectModifierBase.Create;
1128 | InflatingRectModifier := TInflatingRectModifier.Create(1);
1129 |
1130 | FRectModifiers := TObjectDictionary.Create
1131 | ([doOwnsValues]);
1132 | with FRectModifiers do
1133 | begin
1134 | Add(TCustomEdit, InflatingRectModifier);
1135 | Add(TCustomListControl, InflatingRectModifier);
1136 | end;
1137 | end;
1138 |
1139 | destructor TRectModifiers.Destroy;
1140 | begin
1141 | // No need to free FRectModifiers entries since
1142 | // it has set dsOwnValues
1143 | FDefaultRectModifier.Free;
1144 | inherited Destroy;
1145 | end;
1146 |
1147 | procedure Register;
1148 | begin
1149 | RegisterComponents('Form Designer', [TFormDesigner]);
1150 | end;
1151 |
1152 | end.
1153 |
--------------------------------------------------------------------------------
/src/FormDesigner.Package/FormDesigner.DragHandles.pas:
--------------------------------------------------------------------------------
1 | unit FormDesigner.DragHandles;
2 |
3 | interface
4 |
5 | uses Classes, Controls, Graphics, Windows, Messages, Forms, SysUtils, StdCtrls,
6 | RTTI, System.Generics.Collections, FormDesigner.Interfaces,
7 | FormDesigner.Utils;
8 |
9 | type
10 |
11 | /// Base class for drag handles
12 | TDragHandle = class(TCustomControl)
13 | protected
14 | FClickOrigin: TPoint;
15 | FHorizontalFix: TDirection;
16 | FVerticalFix: TDirection;
17 | FFormDesigner: IFormDesigner;
18 | FSize: Byte;
19 | FBorderColor: TColor;
20 | function GetRectSide(const Rect: TRect; Direction: TDirection) : Integer;
21 | procedure SetSize(const Value: Byte);
22 | public
23 | property Color;
24 | property BorderColor : TColor read FBorderColor write FBorderColor;
25 | property FormDesigner: IFormDesigner read FFormDesigner write FFormDesigner;
26 | property Size: Byte read FSize write SetSize;
27 | procedure UpdateChildSize(Sender: TControl; X, Y: Integer); virtual; abstract;
28 | procedure SetSizingOrigin(const X, Y: Integer);
29 | procedure UpdatePosition(Control: TControl); virtual; abstract;
30 | procedure Paint; override;
31 | constructor Create(AOwner: TComponent); override;
32 | end;
33 |
34 | THorizontalDragHandle = class(TDragHandle)
35 | procedure UpdateChildSize(Sender: TControl; X, Y: Integer); override;
36 | end;
37 |
38 | TVerticalDragHandle = class(TDragHandle)
39 | procedure UpdateChildSize(Sender: TControl; X, Y: Integer); override;
40 | end;
41 |
42 | TMultiDirectionalDragHandle = class(TDragHandle)
43 | procedure UpdateChildSize(Sender: TControl; X, Y: Integer); override;
44 | end;
45 |
46 | TUpDragHandle = class(TVerticalDragHandle)
47 | public
48 | procedure UpdatePosition(Control: TControl); override;
49 | constructor Create(AOwner: TComponent); override;
50 | end;
51 |
52 | TDownDragHandle = class(TVerticalDragHandle)
53 | public
54 | procedure UpdatePosition(Control: TControl); override;
55 | constructor Create(AOwner: TComponent); override;
56 | end;
57 |
58 | TLeftDragHandle = class(THorizontalDragHandle)
59 | public
60 | procedure UpdatePosition(Control: TControl); override;
61 | constructor Create(AOwner: TComponent); override;
62 | end;
63 |
64 | TRightDragHandle = class(THorizontalDragHandle)
65 | public
66 | procedure UpdatePosition(Control: TControl); override;
67 | constructor Create(AOwner: TComponent); override;
68 | end;
69 |
70 | TUpLeftDragHandle = class(TMultiDirectionalDragHandle)
71 | public
72 | procedure UpdatePosition(Control: TControl); override;
73 | constructor Create(AOwner: TComponent); override;
74 | end;
75 |
76 | TUpRightDragHandle = class(TMultiDirectionalDragHandle)
77 | public
78 | procedure UpdatePosition(Control: TControl); override;
79 | constructor Create(AOwner: TComponent); override;
80 | end;
81 |
82 | TDownLeftDragHandle = class(TMultiDirectionalDragHandle)
83 | public
84 | procedure UpdatePosition(Control: TControl); override;
85 | constructor Create(AOwner: TComponent); override;
86 | end;
87 |
88 | TDownRightDragHandle = class(TMultiDirectionalDragHandle)
89 | public
90 | procedure UpdatePosition(Control: TControl); override;
91 | constructor Create(AOwner: TComponent); override;
92 | end;
93 |
94 | implementation
95 |
96 | constructor TDragHandle.Create;
97 | begin
98 | inherited Create(AOwner);
99 | Visible := False;
100 | FClickOrigin := TPoint.Zero;
101 | FBorderColor := RGB(0, 120, 215);
102 | end;
103 |
104 | procedure TDragHandle.SetSize(const Value: Byte);
105 | begin
106 | FSize := Value;
107 | Width := Value;
108 | Height := Value;
109 | end;
110 |
111 | procedure TDragHandle.SetSizingOrigin(const X, Y: Integer);
112 | var
113 | HalfWidth: Integer;
114 | begin
115 | inherited;
116 | HalfWidth := Width div 2;
117 | if (X <> HalfWidth) then
118 | begin
119 | if (X > HalfWidth) then
120 | FClickOrigin.X := -(X mod HalfWidth)
121 | else
122 | FClickOrigin.X := HalfWidth - X;
123 | end;
124 |
125 | if (Y <> HalfWidth) then
126 | begin
127 | if (Y > HalfWidth) then
128 | FClickOrigin.Y := -(Y mod HalfWidth)
129 | else
130 | FClickOrigin.Y := HalfWidth - Y;
131 | end;
132 | end;
133 |
134 | procedure TDragHandle.Paint;
135 | begin
136 | inherited;
137 | Canvas.Pen.Color := FBorderColor;
138 | Canvas.FillRect(ClientRect);
139 | Canvas.Brush.Color := Color;
140 | Canvas.Rectangle(0, 0, BoundsRect.Width, BoundsRect.Height);
141 | end;
142 |
143 | constructor TUpDragHandle.Create;
144 | begin
145 | inherited Create(AOwner);
146 | Cursor := crSizeNS;
147 | FVerticalFix := dBottom;
148 | end;
149 |
150 | constructor TDownDragHandle.Create;
151 | begin
152 | inherited Create(AOwner);
153 | Cursor := crSizeNS;
154 | FVerticalFix := dTop;
155 | end;
156 |
157 | constructor TLeftDragHandle.Create;
158 | begin
159 | inherited Create(AOwner);
160 | Cursor := crSizeWE;
161 | FHorizontalFix := dRight;
162 | end;
163 |
164 | constructor TRightDragHandle.Create;
165 | begin
166 | inherited Create(AOwner);
167 | Cursor := crSizeWE;
168 | FHorizontalFix := dLeft;
169 | end;
170 |
171 | constructor TUpLeftDragHandle.Create;
172 | begin
173 | inherited Create(AOwner);
174 | Cursor := crSizeNWSE;
175 | FHorizontalFix := dRight;
176 | FVerticalFix := dBottom;
177 | end;
178 |
179 | constructor TUpRightDragHandle.Create;
180 | begin
181 | inherited Create(AOwner);
182 | Cursor := crSizeNESW;
183 | FHorizontalFix := dLeft;
184 | FVerticalFix := dBottom;
185 | end;
186 |
187 | constructor TDownLeftDragHandle.Create;
188 | begin
189 | inherited Create(AOwner);
190 | Cursor := crSizeNESW;
191 | FHorizontalFix := dRight;
192 | FVerticalFix := dTop;
193 | end;
194 |
195 | constructor TDownRightDragHandle.Create;
196 | begin
197 | inherited Create(AOwner);
198 | Cursor := crSizeNWSE;
199 | FHorizontalFix := dLeft;
200 | FVerticalFix := dTop;
201 | end;
202 |
203 | procedure TUpDragHandle.UpdatePosition(Control: TControl);
204 | begin
205 | Left := Control.Left + ((Control.Width - Width) div 2);
206 | Top := Control.Top - (Height div 2);
207 | end;
208 |
209 | procedure TDownDragHandle.UpdatePosition(Control: TControl);
210 | begin
211 | Left := Control.Left + ((Control.Width - Width) div 2);
212 | Top := Control.Top + Control.Height - (Height div 2);
213 | end;
214 |
215 | procedure TLeftDragHandle.UpdatePosition(Control: TControl);
216 | begin
217 | Left := Control.Left - (Width div 2);
218 | Top := Control.Top + ((Control.Height - Height) div 2);
219 | end;
220 |
221 | procedure TRightDragHandle.UpdatePosition(Control: TControl);
222 | begin
223 | Left := Control.Left + Control.Width - (Width div 2);
224 | Top := Control.Top + ((Control.Height - Height) div 2);
225 | end;
226 |
227 | procedure TUpLeftDragHandle.UpdatePosition(Control: TControl);
228 | begin
229 | Left := Control.Left - (Width div 2);
230 | Top := Control.Top - (Height div 2);
231 | end;
232 |
233 | procedure TDownLeftDragHandle.UpdatePosition(Control: TControl);
234 | begin
235 | Left := Control.Left - (Width div 2);
236 | Top := Control.Top + Control.Height - (Height div 2);
237 | end;
238 |
239 | procedure TUpRightDragHandle.UpdatePosition(Control: TControl);
240 | begin
241 | Left := Control.BoundsRect.Right - (Width div 2);
242 | Top := Control.Top - (Height div 2);
243 | end;
244 |
245 | procedure TDownRightDragHandle.UpdatePosition(Control: TControl);
246 | begin
247 | Left := Control.BoundsRect.Right - (Width div 2);
248 | Top := Control.Top + Control.Height - (Height div 2);
249 | end;
250 |
251 | procedure TVerticalDragHandle.UpdateChildSize(Sender: TControl; X, Y: Integer);
252 | var
253 | DragRect: TRect;
254 | ChildRect: TRect;
255 | VerticalFix: Integer;
256 | begin
257 | DragRect := FFormDesigner.GetDragRect();
258 | ChildRect := FFormDesigner.GetChildRect();
259 | VerticalFix := GetRectSide(ChildRect, FVerticalFix);
260 | with DragRect do
261 | begin
262 | if (Y <> Top) and (Y <> Bottom) then
263 | begin
264 | if Y >= VerticalFix then
265 | begin
266 | Top := VerticalFix;
267 | Bottom := Y + FClickOrigin.Y;
268 | FFormDesigner.UpdateDragRect(DragRect, [dBottom]);
269 | end
270 | else
271 | begin
272 | Top := Y + FClickOrigin.Y;
273 | Bottom := VerticalFix;
274 | FFormDesigner.UpdateDragRect(DragRect, [dTop]);
275 | end;
276 | end;
277 | end;
278 | end;
279 |
280 | procedure THorizontalDragHandle.UpdateChildSize(Sender: TControl; X: Integer; Y: Integer);
281 | var
282 | DragRect: TRect;
283 | ChildRect: TRect;
284 | HorizontalFix: Integer;
285 | begin
286 | DragRect := FFormDesigner.GetDragRect();
287 | ChildRect := FFormDesigner.GetChildRect();
288 | HorizontalFix := GetRectSide(ChildRect, FHorizontalFix);
289 | with DragRect do
290 | begin
291 | if (X <> Right) and (X <> Left) then
292 | begin
293 | if X > HorizontalFix then
294 | begin
295 | Left := HorizontalFix;
296 | Right := X + FClickOrigin.X;
297 | FFormDesigner.UpdateDragRect(DragRect, [dRight]);
298 | end
299 | else
300 | begin
301 | Left := X + FClickOrigin.X;
302 | Right := HorizontalFix;
303 | FFormDesigner.UpdateDragRect(DragRect, [dLeft]);
304 | end;
305 | end;
306 | end;
307 | end;
308 |
309 | procedure TMultiDirectionalDragHandle.UpdateChildSize(Sender: TControl; X, Y: Integer);
310 | var
311 | DragRect: TRect;
312 | ChildRect: TRect;
313 | HorizontalFix, VerticalFix: Integer;
314 | begin
315 | DragRect := FFormDesigner.GetDragRect();
316 | ChildRect := FFormDesigner.GetChildRect();
317 | HorizontalFix := GetRectSide(ChildRect, FHorizontalFix);
318 | VerticalFix := GetRectSide(ChildRect, FVerticalFix);
319 | with DragRect do
320 | begin
321 | if (X > HorizontalFix) and (Y > VerticalFix) then
322 | begin
323 | Left := HorizontalFix;
324 | Top := VerticalFix;
325 | Right := X + FClickOrigin.X;
326 | Bottom := Y + FClickOrigin.Y;
327 | FFormDesigner.UpdateDragRect(DragRect, [dRight, dBottom]);
328 | end;
329 | if (X < HorizontalFix) and (Y > VerticalFix) then
330 | begin
331 | Left := X + FClickOrigin.X;
332 | Top := VerticalFix;
333 | Right := HorizontalFix;
334 | Bottom := Y + FClickOrigin.Y;
335 | FFormDesigner.UpdateDragRect(DragRect, [dLeft, dBottom]);
336 | end;
337 | if (X > HorizontalFix) and (Y < VerticalFix) then
338 | begin
339 | Left := HorizontalFix;
340 | Top := Y + FClickOrigin.Y;
341 | Right := X + FClickOrigin.X;
342 | Bottom := VerticalFix;
343 | FFormDesigner.UpdateDragRect(DragRect, [dRight, dTop]);
344 | end;
345 | if (X < HorizontalFix) and (Y < VerticalFix) then
346 | begin
347 | Left := X + FClickOrigin.X;
348 | Top := Y + FClickOrigin.Y;
349 | Right := HorizontalFix;
350 | Bottom := VerticalFix;
351 | FFormDesigner.UpdateDragRect(DragRect, [dLeft, dTop]);
352 | end;
353 | end;
354 | end;
355 |
356 | function TDragHandle.GetRectSide(const Rect: TRect; Direction: TDirection): Integer;
357 | var
358 | RectType: TRttiType;
359 | Field: TRttiField;
360 | DirectionStr: String;
361 | begin
362 | DirectionStr := TRttiEnumerationType.GetName(Direction);
363 | Assert(DirectionStr.StartsWith('d'));
364 | DirectionStr := DirectionStr.Remove(0, 1);
365 | RectType := TRTTIContext.Create.GetType(TypeInfo(TRect));
366 | Field := RectType.GetField(DirectionStr);
367 | Result := Field.GetValue(@Rect).AsInteger;
368 | end;
369 |
370 | end.
371 |
--------------------------------------------------------------------------------
/src/FormDesigner.Package/FormDesigner.Interfaces.pas:
--------------------------------------------------------------------------------
1 | unit FormDesigner.Interfaces;
2 |
3 | interface
4 |
5 | uses Classes, Controls, Graphics, Windows, Messages, Forms, SysUtils, StdCtrls,
6 | System.Generics.Collections;
7 |
8 | type
9 |
10 | TFormDesignerState = (fdsReady, fdsMoving, fdsSizing);
11 | TDirection = (dBottom, dTop, dLeft, dRight);
12 | TDirections = set of TDirection;
13 |
14 | IFormDesigner = interface
15 | function GetDragRect : TRect;
16 | function GetChildRect : TRect;
17 | procedure UpdateDragRect(Rect: TRect; Direction: TDirections);
18 | end;
19 |
20 | implementation
21 |
22 | end.
23 |
--------------------------------------------------------------------------------
/src/FormDesigner.Package/FormDesigner.Package.dpk:
--------------------------------------------------------------------------------
1 | package FormDesigner.Package;
2 |
3 | {$R *.res}
4 | {$R *.dres}
5 | {$IFDEF IMPLICITBUILDING This IFDEF should not be used by users}
6 | {$ALIGN 8}
7 | {$ASSERTIONS ON}
8 | {$BOOLEVAL OFF}
9 | {$DEBUGINFO OFF}
10 | {$EXTENDEDSYNTAX ON}
11 | {$IMPORTEDDATA ON}
12 | {$IOCHECKS ON}
13 | {$LOCALSYMBOLS OFF}
14 | {$LONGSTRINGS ON}
15 | {$OPENSTRINGS ON}
16 | {$OPTIMIZATION ON}
17 | {$OVERFLOWCHECKS OFF}
18 | {$RANGECHECKS OFF}
19 | {$REFERENCEINFO OFF}
20 | {$SAFEDIVIDE OFF}
21 | {$STACKFRAMES OFF}
22 | {$TYPEDADDRESS OFF}
23 | {$VARSTRINGCHECKS ON}
24 | {$WRITEABLECONST OFF}
25 | {$MINENUMSIZE 1}
26 | {$IMAGEBASE $400000}
27 | {$DEFINE RELEASE}
28 | {$ENDIF IMPLICITBUILDING}
29 | {$IMPLICITBUILD ON}
30 |
31 | requires
32 | rtl,
33 | vcl;
34 |
35 | contains
36 | FormDesigner.Interfaces in 'FormDesigner.Interfaces.pas',
37 | FormDesigner.DragHandles in 'FormDesigner.DragHandles.pas',
38 | FormDesigner.Designer in 'FormDesigner.Designer.pas',
39 | FormDesigner.Utils in 'FormDesigner.Utils.pas';
40 |
41 | end.
42 |
--------------------------------------------------------------------------------
/src/FormDesigner.Package/FormDesigner.Package.dproj:
--------------------------------------------------------------------------------
1 |
2 |
3 | {6895A4E9-60A4-4AF6-83CE-86F8765435A3}
4 | FormDesigner.Package.dpk
5 | 18.6
6 | VCL
7 | True
8 | Release
9 | Win32
10 | 1
11 | Package
12 |
13 |
14 | true
15 |
16 |
17 | true
18 | Base
19 | true
20 |
21 |
22 | true
23 | Base
24 | true
25 |
26 |
27 | true
28 | Cfg_1
29 | true
30 | true
31 |
32 |
33 | true
34 | Base
35 | true
36 |
37 |
38 | .\$(Platform)\$(Config)
39 | .\$(Platform)\$(Config)
40 | false
41 | false
42 | false
43 | false
44 | false
45 | true
46 | true
47 | System;Xml;Data;Datasnap;Web;Soap;Vcl;Vcl.Imaging;Vcl.Touch;Vcl.Samples;Vcl.Shell;$(DCC_Namespace)
48 | All
49 | FormDesigner_Package
50 |
51 |
52 | Winapi;System.Win;Data.Win;Datasnap.Win;Web.Win;Soap.Win;Xml.Win;Bde;$(DCC_Namespace)
53 | Debug
54 | true
55 | CompanyName=;FileDescription=$(MSBuildProjectName);FileVersion=1.0.0.0;InternalName=;LegalCopyright=;LegalTrademarks=;OriginalFilename=;ProgramID=com.embarcadero.$(MSBuildProjectName);ProductName=$(MSBuildProjectName);ProductVersion=1.0.0.0;Comments=
56 | 1033
57 | vcl;rtl;$(DCC_UsePackage)
58 |
59 |
60 | DEBUG;$(DCC_Define)
61 | true
62 | false
63 | true
64 | true
65 | true
66 |
67 |
68 | false
69 | true
70 | 1033
71 |
72 |
73 | false
74 | RELEASE;$(DCC_Define)
75 | 0
76 | 0
77 |
78 |
79 |
80 | MainSource
81 |
82 |
83 |
84 |
85 |
86 |
87 |
88 |
89 | RCDATA
90 | TFORMDESIGNER_PNG
91 |
92 |
93 | Cfg_2
94 | Base
95 |
96 |
97 | Base
98 |
99 |
100 | Cfg_1
101 | Base
102 |
103 |
104 |
105 | Delphi.Personality.12
106 | Package
107 |
108 |
109 |
110 | FormDesigner.Package.dpk
111 |
112 |
113 | Microsoft Office 2000 Sample Automation Server Wrapper Components
114 | Microsoft Office XP Sample Automation Server Wrapper Components
115 |
116 |
117 |
118 |
119 |
120 | true
121 |
122 |
123 |
124 |
125 | FormDesigner_Package.bpl
126 | true
127 |
128 |
129 |
130 |
131 | true
132 |
133 |
134 |
135 |
136 | FormDesigner_Package.bpl
137 | true
138 |
139 |
140 |
141 |
142 | true
143 |
144 |
145 |
146 |
147 | true
148 |
149 |
150 |
151 |
152 | true
153 |
154 |
155 |
156 |
157 | 1
158 |
159 |
160 | 0
161 |
162 |
163 |
164 |
165 | classes
166 | 1
167 |
168 |
169 |
170 |
171 | res\xml
172 | 1
173 |
174 |
175 |
176 |
177 | library\lib\armeabi-v7a
178 | 1
179 |
180 |
181 |
182 |
183 | library\lib\armeabi
184 | 1
185 |
186 |
187 |
188 |
189 | library\lib\mips
190 | 1
191 |
192 |
193 |
194 |
195 | library\lib\armeabi-v7a
196 | 1
197 |
198 |
199 |
200 |
201 | res\drawable
202 | 1
203 |
204 |
205 |
206 |
207 | res\values
208 | 1
209 |
210 |
211 |
212 |
213 | res\values-v21
214 | 1
215 |
216 |
217 |
218 |
219 | res\drawable
220 | 1
221 |
222 |
223 |
224 |
225 | res\drawable-xxhdpi
226 | 1
227 |
228 |
229 |
230 |
231 | res\drawable-ldpi
232 | 1
233 |
234 |
235 |
236 |
237 | res\drawable-mdpi
238 | 1
239 |
240 |
241 |
242 |
243 | res\drawable-hdpi
244 | 1
245 |
246 |
247 |
248 |
249 | res\drawable-xhdpi
250 | 1
251 |
252 |
253 |
254 |
255 | res\drawable-small
256 | 1
257 |
258 |
259 |
260 |
261 | res\drawable-normal
262 | 1
263 |
264 |
265 |
266 |
267 | res\drawable-large
268 | 1
269 |
270 |
271 |
272 |
273 | res\drawable-xlarge
274 | 1
275 |
276 |
277 |
278 |
279 | 1
280 |
281 |
282 | 1
283 |
284 |
285 | 0
286 |
287 |
288 |
289 |
290 | 1
291 | .framework
292 |
293 |
294 | 1
295 | .framework
296 |
297 |
298 | 0
299 |
300 |
301 |
302 |
303 | 1
304 | .dylib
305 |
306 |
307 | 1
308 | .dylib
309 |
310 |
311 | 0
312 | .dll;.bpl
313 |
314 |
315 |
316 |
317 | 1
318 | .dylib
319 |
320 |
321 | 1
322 | .dylib
323 |
324 |
325 | 1
326 | .dylib
327 |
328 |
329 | 1
330 | .dylib
331 |
332 |
333 | 1
334 | .dylib
335 |
336 |
337 | 0
338 | .bpl
339 |
340 |
341 |
342 |
343 | 0
344 |
345 |
346 | 0
347 |
348 |
349 | 0
350 |
351 |
352 | 0
353 |
354 |
355 | 0
356 |
357 |
358 | 0
359 |
360 |
361 | 0
362 |
363 |
364 |
365 |
366 | 1
367 |
368 |
369 | 1
370 |
371 |
372 | 1
373 |
374 |
375 |
376 |
377 | 1
378 |
379 |
380 | 1
381 |
382 |
383 | 1
384 |
385 |
386 |
387 |
388 | 1
389 |
390 |
391 | 1
392 |
393 |
394 | 1
395 |
396 |
397 |
398 |
399 | 1
400 |
401 |
402 | 1
403 |
404 |
405 | 1
406 |
407 |
408 |
409 |
410 | 1
411 |
412 |
413 | 1
414 |
415 |
416 | 1
417 |
418 |
419 |
420 |
421 | 1
422 |
423 |
424 | 1
425 |
426 |
427 | 1
428 |
429 |
430 |
431 |
432 | 1
433 |
434 |
435 | 1
436 |
437 |
438 | 1
439 |
440 |
441 |
442 |
443 | 1
444 |
445 |
446 |
447 |
448 | ..\$(PROJECTNAME).app.dSYM\Contents\Resources\DWARF
449 | 1
450 |
451 |
452 | ..\$(PROJECTNAME).app.dSYM\Contents\Resources\DWARF
453 | 1
454 |
455 |
456 |
457 |
458 |
459 |
460 |
461 | 1
462 |
463 |
464 | 1
465 |
466 |
467 | 1
468 |
469 |
470 |
471 |
472 |
473 |
474 |
475 | Contents\Resources
476 | 1
477 |
478 |
479 | Contents\Resources
480 | 1
481 |
482 |
483 |
484 |
485 | library\lib\armeabi-v7a
486 | 1
487 |
488 |
489 | 1
490 |
491 |
492 | 1
493 |
494 |
495 | 1
496 |
497 |
498 | 1
499 |
500 |
501 | 1
502 |
503 |
504 | 1
505 |
506 |
507 | 0
508 |
509 |
510 |
511 |
512 | 1
513 |
514 |
515 | 1
516 |
517 |
518 |
519 |
520 | Assets
521 | 1
522 |
523 |
524 | Assets
525 | 1
526 |
527 |
528 |
529 |
530 | Assets
531 | 1
532 |
533 |
534 | Assets
535 | 1
536 |
537 |
538 |
539 |
540 |
541 |
542 |
543 |
544 |
545 |
546 |
547 |
548 |
549 | True
550 |
551 |
552 | 12
553 |
554 |
555 |
556 |
557 |
558 |
--------------------------------------------------------------------------------
/src/FormDesigner.Package/FormDesigner.Utils.pas:
--------------------------------------------------------------------------------
1 | unit FormDesigner.Utils;
2 |
3 | interface
4 |
5 | uses Classes, Controls, Windows, SysUtils, IOUtils, WinApi.Messages;
6 |
7 | type
8 |
9 | TEnumChildsProc = reference to procedure(Control: TControl);
10 |
11 | TQueue = class
12 | strict private
13 | FList: TList;
14 | FMax: Longint;
15 | function GetCount: Longint;
16 | public
17 | function Get: Longint;
18 | procedure Add(Value: Longint);
19 | constructor Create(Max: Longint);
20 | destructor Destroy; override;
21 | property Count: Longint read GetCount;
22 | end;
23 |
24 | TRectHelper = record helper for TRect
25 | function ClientToScreen(Window: TWinControl) : TRect;
26 | end;
27 |
28 | TWinControlHelder = class helper for TWinControl
29 | procedure RemoveWindowStyle(Style: Integer);
30 | end;
31 |
32 | function GET_X_LPARAM(lParam: lParam): Integer;
33 | function GET_Y_LPARAM(lParam: lParam): Integer;
34 | function MAKEPOINT(lParam: lParam) : TPoint;
35 | function GetControlName(Parent: TWinControl; Cls: TClass): String;
36 | function GetMessageName(Msg: Cardinal) : String;
37 | procedure Log(msg: string); overload;
38 | procedure Log(const source, msg: string; const Rect: TRect); overload;
39 | procedure Log(const source: string; const message: string); overload;
40 | procedure Log(const Format: string; const Args: array of const); overload;
41 | procedure Log(const source: string; const Format: string; const Args: array of const); overload;
42 |
43 | procedure EnumChilds(RootCtrl: TWinControl; Proc: TEnumChildsProc);
44 | procedure SetControlText(Control: TControl; Text: String);
45 | function IsMessageForWindow(MsgHandle: HWnd; WindowHandle: HWnd) : Boolean;
46 |
47 | implementation
48 |
49 | // -----------------------------------------------------------------
50 | // TQueue
51 | // -----------------------------------------------------------------
52 |
53 | constructor TQueue.Create;
54 | begin
55 | inherited Create;
56 | FList := TList.Create;
57 | FMax := Max;
58 | end;
59 |
60 | destructor TQueue.Destroy;
61 | begin
62 | inherited;
63 | FList.Free;
64 | end;
65 |
66 | procedure TQueue.Add;
67 | begin
68 | if FList.Count < FMax then
69 | FList.Add(Pointer(Value));
70 | end;
71 |
72 | function TQueue.Get: Longint;
73 | begin
74 | Result := Longint(FList.Last);
75 | FList.Remove(FList.Last);
76 | end;
77 |
78 | function TQueue.GetCount: Longint;
79 | begin
80 | Result := FList.Count;
81 | end;
82 |
83 | // -----------------------------------------------------------------
84 | // TRectHelper
85 | // -----------------------------------------------------------------
86 |
87 | function TRectHelper.ClientToScreen(Window: TWinControl) : TRect;
88 | begin
89 | Result.TopLeft := Window.ClientToScreen(TopLeft);
90 | Result.BottomRight := Window.ClientToScreen(BottomRight);
91 | end;
92 |
93 | // -----------------------------------------------------------------
94 | // TWinControl Style
95 | // -----------------------------------------------------------------
96 |
97 | procedure TWinControlHelder.RemoveWindowStyle(Style: Integer);
98 | begin
99 | SetWindowLong(Handle, GWL_STYLE, GetWindowLong(Handle, GWL_STYLE) and
100 | not Style);
101 | end;
102 |
103 | // -----------------------------------------------------------------
104 | // Routines
105 | // -----------------------------------------------------------------
106 |
107 | procedure EnumChilds(RootCtrl: TWinControl; Proc: TEnumChildsProc);
108 | var
109 | i: byte;
110 | begin
111 | if RootCtrl.ControlCount <> 0 then
112 | for i := 0 to RootCtrl.ControlCount - 1 do
113 | begin
114 | Proc(RootCtrl.Controls[i]);
115 | if RootCtrl.Controls[i] is TWinControl then
116 | if (RootCtrl.Controls[i] as TWinControl).ControlCount <> 0 then
117 | EnumChilds(RootCtrl.Controls[i] as TWinControl, Proc);
118 | end;
119 | end;
120 |
121 | function GetControlName(Parent: TWinControl; Cls: TClass): String;
122 | var
123 | CtrlCount: Integer;
124 | begin
125 | CtrlCount := 1;
126 | EnumChilds(Parent, procedure (Ctrl: TControl)
127 | begin
128 | if (Ctrl is Cls) then
129 | Inc(CtrlCount);
130 | end);
131 | // i.e. Button1
132 | Result := Format('%s%d', [Copy(Cls.ClassName, 2, Length(Cls.ClassName) - 1), CtrlCount]);
133 | end;
134 |
135 | function MAKEPOINT(lParam: lParam) : TPoint;
136 | begin
137 | Result := TPoint.Create(GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam));
138 | end;
139 |
140 | function GET_X_LPARAM(lParam: lParam): Integer;
141 | begin
142 | Result := Smallint(LoWord(lParam));
143 | end;
144 |
145 | function GET_Y_LPARAM(lParam: lParam): Integer;
146 | begin
147 | Result := Smallint(HiWord(lParam));
148 | end;
149 |
150 | function GetMessageName(Msg: Cardinal) : String;
151 | begin
152 | case Msg of
153 | WM_MOUSEMOVE: Result := 'WM_MOUSEMOVE';
154 | WM_LBUTTONDOWN: Result := 'WM_LBUTTONDOWN';
155 | WM_LBUTTONUP: Result := 'WM_LBUTTONUP';
156 | end;
157 | end;
158 |
159 | procedure SetControlText(Control: TControl; Text: String);
160 | begin
161 | Control.Perform(WM_SETTEXT, NativeInt(0), NativeInt(PChar(Text)));
162 | end;
163 |
164 | function IsMessageForWindow(MsgHandle: HWnd; WindowHandle: HWnd) : Boolean;
165 | var
166 | Parent: HWnd;
167 | begin
168 | if MsgHandle = WindowHandle then
169 | begin
170 | Result := True;
171 | end
172 | else
173 | begin
174 | Parent := GetAncestor(MsgHandle, GA_ROOT);
175 | Result := (Parent <> 0) and (Parent = WindowHandle);
176 | end;
177 | end;
178 |
179 |
180 | // -----------------------------------------------------------------
181 | // Logging
182 | // -----------------------------------------------------------------
183 |
184 | function GetLogFilePath : String;
185 | var
186 | logPath: string;
187 | appDataPath: string;
188 | begin
189 | appDataPath := SysUtils.GetEnvironmentVariable('APPDATA');
190 | logPath := TPath.Combine(appDataPath, 'FormDesigner.Package');
191 | ForceDirectories(logPath);
192 | Result := TPath.Combine(logPath, 'log.txt');
193 | end;
194 |
195 | procedure Log(msg: string);
196 | begin
197 | {$IFDEF DEBUG}
198 | TFile.AppendAllText(GetLogFilePath, Format('%s %d %s', [FormatDateTime('c', Now),
199 | GetCurrentThreadId, msg + sLineBreak]));
200 | {$ENDIF}
201 | end;
202 |
203 | procedure Log(const source, msg: string; const Rect: TRect); overload;
204 | begin
205 | Log(source, msg + ' (%d, %d, %d, %d)', [Rect.Left, Rect.Top, Rect.Right, Rect.Bottom]);
206 | end;
207 |
208 | procedure Log(const source: string; const message: string);
209 | begin
210 | Log(source + ' ' + message);
211 | end;
212 |
213 | procedure Log(const Format: string; const Args: array of const);
214 | var
215 | msg: string;
216 | begin
217 | msg := System.SysUtils.Format(Format, Args);
218 | Log(msg);
219 | end;
220 |
221 | procedure Log(const source: string; const Format: string; const Args: array of const);
222 | var
223 | msg: string;
224 | begin
225 | msg := source + ' ' + System.SysUtils.Format(Format, Args);
226 | Log(msg);
227 | end;
228 |
229 | end.
230 |
--------------------------------------------------------------------------------
/src/FormDesigner.Package/TFORMDESIGNER.PNG:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/havlicekp/form-designer/eef60c939b900d12f6addaa06a985c06410e6362/src/FormDesigner.Package/TFORMDESIGNER.PNG
--------------------------------------------------------------------------------
/src/FormDesigner.groupproj:
--------------------------------------------------------------------------------
1 |
2 |
3 | {09BEAE01-9B0C-4609-8CD2-86C0B619DA28}
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 | Default.Personality.12
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
--------------------------------------------------------------------------------