├── .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 | ![Demo](https://github.com/havlicekp/form-designer/blob/master/images/demo.gif) 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 |
frmComponentsForm
104 | dfm 105 |
106 | 107 | 108 |
frmDesignForm
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 | --------------------------------------------------------------------------------