Sign in Join
Wiki copytemporary

How To Write Lazarus Component/es: what changed

Revision 2 to 3. Removed lines have a minus sign; added lines have a plus sign.

OldNewLine
1-Esta es una guía sobre como construir componentes.
1+Esta es una guía sobre como construir componentes.
22
3+## Contents
4+
5+ * 1 Paso 1: Crear el paquete
6+ * 2 Paso 2: Crear la unidad
7+ * 2.1 Crear una nueva unidad
8+ * 2.2 Añadir una unidad existente
9+ * 3 Paso 3: Crear iconos para el paquete
10+ * 3.1 Utilizando el Editor de Imágen de Lazarus
11+ * 3.2 Utilizando lazres
12+ * 3.3 Utilizando glazres
13+ * 4 Recompilando paquetes
14+ * 5 Eliminando paquetes
15+ * 6 Mejorando mycom.pas
16+ * 7 Utilizando componentes (visuales) embebidos
17+ * 8 Using custom paint procedure
18+ * 9 Integrando el componente con el IDE
19+ * 9.1 Editores de propiedades
20+ * 9.2 Editores de componentes
21+ * 10 Depurando un componente en tiempo de diseño
22+ * 11 See also
23+
324## Paso 1: Crear el paquete
425
5-- En el menú de Lazarus, clic en **Paquete \> Nuevo Paquete** para ejecutar el administrador de paquetes.
26+ * En el menú de Lazarus, clic en **Paquete > Nuevo Paquete** para ejecutar el administrador de paquetes.
627
7-![](/wiki-images/7/7c/Package_menu.png)
28+[![package menu.png](/wiki-images/f/fb/package_menu.png)](</File:package_menu.png>)
829
9-- Un dialogo **Guardar** aparecerá. Elije una carpeta y un nombre y presiona guardar. Si el IDE pregunta por usar nombres de archivo en minúsculas presiona 'sí'.
30+ * Un dialogo **Guardar** aparecerá. Elije una carpeta y un nombre y presiona guardar. Si el IDE pregunta por usar nombres de archivo en minúsculas presiona 'sí'.
1031
11-- Felicidades: Has creado tu primer paquete.
32+ * Felicidades: Has creado tu primer paquete.
1233
13-![](/wiki-images/3/37/How_to_write_lazarus_component_package_maker.png)
34+[![Package Maker](/wiki-images/3/37/How_to_write_lazarus_component_package_maker.png)](</File:How_to_write_lazarus_component_package_maker.png> "Package Maker")
1435
1536## Paso 2: Crear la unidad
1637
17-Puedes crear una nueva unidad o usar un archivo existente. Las dos opciones son desarrolladas debajo.
38+Puedes crear una nueva unidad o usar un archivo existente. Las dos opciones son desarrolladas debajo.
1839
1940### Crear una nueva unidad
2041
21-- Usa el botón **Add \> Nuevo componente**.
42+ * Usa el botón **Add > Nuevo componente**.
2243
23-![](/wiki-images/5/56/Package_new_component.png)
44+[![package new component.png](/wiki-images/6/60/package_new_component.png)](</File:package_new_component.png>)
2445
25-- Escoge un componente tal como TComboBox.
26-- Escoge *customcontrol1.pas* como **Nombre de fichero para la unit** y *CustomControl1* como **Nombre de la unit**.
27-- Ahora ya puedes asignar al componenete un icono y determinar en que solapa de la paleta del IDE de Lazarus aparecera el componente.
28-- Click en **Crear Nuevo Componente**.
46+ * Escoge un componente tal como TComboBox.
47+ * Escoge _customcontrol1.pas_ como **Nombre de fichero para la unit** y _CustomControl1_ como **Nombre de la unit**.
48+ * Ahora ya puedes asignar al componenete un icono y determinar en que solapa de la paleta del IDE de Lazarus aparecera el componente.
49+ * Click en **Crear Nuevo Componente**.
2950
30-``` pascal
51+```
3152unit CustomControl1;
32-
33-{$mode objfpc}{$H+}
34-
35-interface
36-
37-uses
38- Classes, SysUtils, LResources, Forms, Controls, Graphics, Dialogs, StdCtrls;
39-
40-type
41- TCustomControl1 = class(TComboBox)
42- private
43- { Declaraciones Privadas}
44- protected
45- { Declaraciones Protegidas }
46- public
47- { Declaraciones Públicas }
48- published
49- { Declaraciones Publicadas }
50- end;
51-
52-procedure Register;
53-
54-implementation
53+
54+ {$mode objfpc}{$H+}
55+
56+ interface
57+
58+ uses
59+ Classes, SysUtils, LResources, Forms, Controls, Graphics, Dialogs, StdCtrls;
60+
61+ type
62+ TCustomControl1 = class(TComboBox)
63+ private
64+ { Declaraciones Privadas}
65+ protected
66+ { Declaraciones Protegidas }
67+ public
68+ { Declaraciones Públicas }
69+ published
70+ { Declaraciones Publicadas }
71+ end;
72+
73+ procedure Register;
74+
75+ implementation
76+
77+ procedure Register;
78+ begin
79+ RegisterComponents('Standard',[TCustomControl1]);
80+ end;
81+
82+ end.
83+```
5584
56-procedure Register;
57-begin
58- RegisterComponents('Standard',[TCustomControl1]);
59-end;
85+ * Instala el paquete haciendo clic en el botón **Use - > Install** arriba del editor del paquete.
6086
61-end.
62-```
87+[![package install.png](/wiki-images/2/2a/package_install.png)](</File:package_install.png>)
6388
64-- Instala el paquete haciendo clic en el botón **Use -\> Install** arriba del editor del paquete.
89+ * Ahora el IDE te preguntará ¿Desea reconstruir ahora Lazarus?, le indicamos que [Si].
6590
66-![](/wiki-images/3/36/Package_install.png)
91+[![package rebuild.png](/wiki-images/6/67/package_rebuild.png)](</File:package_rebuild.png>)
6792
68-- Ahora el IDE te preguntará ¿Desea reconstruir ahora Lazarus?, le indicamos que \[Si\].
93+ * Una vez reiniciado el IDE de Lazarus deberiamos poder ver el nuevo componente en la paleta dentro de la solapa adecuada. Felicidades, ya tienes instalado tu primer paquete con tu primer paquete de componente.
6994
70-![](/wiki-images/9/9b/Package_rebuild.png)
95+[![package installed.png](/wiki-images/7/79/package_installed.png)](</File:package_installed.png>)
7196
72-- Una vez reiniciado el IDE de Lazarus deberiamos poder ver el nuevo componente en la paleta dentro de la solapa adecuada. Felicidades, ya tienes instalado tu primer paquete con tu primer paquete de componente.
97+[![Note-icon.png](/wiki-images/b/be/Note-icon.png)](</File:Note-icon.png>)
7398
74-![](/wiki-images/3/35/Package_installed.png)
99+**Nota:** Si no ves tu nuevo componente en la paleta, es más que probable que no estés corriendo la versión re-compilada de Lazarus. Puedes establecer donde se construirá Lazarus seleccionando el trayecto en Herramientas -> Opciones -> Entorno -> Archivos -> Directorio de Lazarus (predeterminado para todos los proyectos). En lugar de llamar a Lazarus directamente, puedes además utilizar **startlazarus** , el cual inicia el nuevo Lazarus recomplilado en caso de que no se tenga acceso al directorio ~/.lazarus en modo escritura.
75100
76101### Añadir una unidad existente
77102
78-Si ya tienes una unidad creada la puedes añadir al paquete:
103+Si ya tienes una unidad creada la puedes añadir al paquete:
79104
80-![](/wiki-images/1/11/Package_existing_unit.png)
105+
106+[![package existing unit.png](/wiki-images/a/a4/package_existing_unit.png)](</File:package_existing_unit.png>)
81107
82-- Click the **Add** button, go to the **Add Files** tab. At the Unit file name, browse to your existing file. Click **Add files to package**. If the package manager complains that the unit is not in the unit path, click yes to add the directory to the unit path.
83-- Click the **Add** button again, go to the **Add Files** tab, browse to the *.lrs* file and click OK (See Step 3 about creating this icon file).
84-- Click the **Add** button again, go to the **New Requirement** tab. In the Package name select **LCL** and click OK.
108+ * Click the **Add** button, go to the **Add Files** tab. At the Unit file name, browse to your existing file. Click **Add files to package**. If the package manager complains that the unit is not in the unit path, click yes to add the directory to the unit path.
109+ * Click the **Add** button again, go to the **Add Files** tab, browse to the _.lrs_ file and click OK (See Step 3 about creating this icon file).
110+ * Click the **Add** button again, go to the **New Requirement** tab. In the Package name select **LCL** and click OK.
85111
86-El resultado final debería parecerse a esto:
112+El resultado final debería parecerse a esto:
87113
88-![](/wiki-images/d/d9/How_to_write_lazarus_component_package_maker_done.png)
114+[![Package Maker](/wiki-images/d/d9/How_to_write_lazarus_component_package_maker_done.png)](</File:How_to_write_lazarus_component_package_maker_done.png> "Package Maker")
89115
90-- Click bajo el árbol de ficheros en el Gestor de Paquetes. En Propiedades de Fichero, asegúrate que la *Register unit* se encuentra chequeada.
91-- Click en el pulsador de Opciones. Selecciona la solapa de Integración del IDE. En Tipo de Paquete, asegúrate que están seleccionados Designtime y Runtime.
92-- Click en el pulsador de Compilar para chequearque todo se compile sin errores.
93-- Click en el pulsador de Instalar. Lazarus se reconstruirá y reiniciará automáticamente.
116+ * Click bajo el árbol de ficheros en el Gestor de Paquetes. En Propiedades de Fichero, asegúrate que la _Register unit_ se encuentra chequeada.
117+ * Click en el pulsador de Opciones. Selecciona la solapa de Integración del IDE. En Tipo de Paquete, asegúrate que están seleccionados Designtime y Runtime.
118+ * Click en el pulsador de Compilar para chequearque todo se compile sin errores.
119+ * Click en el pulsador de Instalar. Lazarus se reconstruirá y reiniciará automáticamente.
94120
95-El componente se ha creado y está listo para ser utilizado:
121+El componente se ha creado y está listo para ser utilizado:
96122
97-![](/wiki-images/3/3c/How_to_write_lazarus_component_created.png)
123+[![Component Created](/wiki-images/3/3c/How_to_write_lazarus_component_created.png)](</File:How_to_write_lazarus_component_created.png> "Component Created")
98124
99125## Paso 3: Crear iconos para el paquete
100126
101-Se deben crear iconos con dimensiones 24x24 píxeles y formato de fichero PNG.
127+Se deben crear iconos con dimensiones 24x24 píxeles y formato de fichero PNG.
102128
103129FPC es capaz de utilizar ficheros de recurso estandar `.rc` y recursos compilados `.res` desde la versión 2.6. Ver [[Lazarus Resources|Lazarus_Resources#FPC_resources]]
104130
105-Por hacer: escribir la descripción de creación de iconos utilizando recursos FPC.
131+Por hacer: escribir la descripción de creación de iconos utilizando recursos FPC.
106132
107-Los `.lrs`: ver más abajo.
133+Los `.lrs`: ver más abajo.
108134
109135### Utilizando el Editor de Imágen de Lazarus
110136
111-Puedes utilizar el [[Lazarus Image Editor|Editor de Imágenes de Lazarus]] para crear los iconos en formato ".lrs".
137+Puedes utilizar el [[Lazarus Image Editor|Editor de Imágenes de Lazarus]] para crear los iconos en formato ".lrs".
112138
113139### Utilizando lazres
114140
115-`lazres` se encuentra habitualmente en el directorio tools de Lazarus.
141+`lazres` se encuentra habitualmente en el directorio tools de Lazarus.
116142
117-Se necesita compilarlo para su primer uso [[lazres]]. Simplemente abre el fichero *lazres.lpi* en el IDE y haz click en **run \> build** en el menu.
143+Se necesita compilarlo para su primer uso [[lazres]]. Simplemente abre el fichero _lazres.lpi_ en el IDE y haz click en **run > build** en el menu.
118144
119145**Create lrs file**
120146
121-Para crear el fichero lrs arranca:
147+Para crear el fichero lrs arranca:
122148
123149`~/lazarus/tools/lazres samplepackage.lrs TMyCom.png`
124150
125-Donde:
151+Donde:
126152
127-- *samplepackage* es el nombre de tu paquete.
128-- *TMyCom* es el nombre de tu componente. **El nombre de la imagen debe coincidir con el nombre de tu componente**.
153+ * _samplepackage_ es el nombre de tu paquete.
154+ * _TMyCom_ es el nombre de tu componente. **El nombre de la imagen debe coincidir con el nombre de tu componente**.
129155
130156Puedes añadir más de una imagen al fichero lrs añadiendo el nombre del fichero de imagen al final. E.g. ~/lazarus/tools/lazres samplepackage.lrs TMyCom.png TMyOtherCom.png ... Y **Ejemplo**
131157
132-El siguiente es un ejemplo del fichero *samplepackage.lrs* resultante.
133-
134- LazarusResources.Add('TMyCom','PNG',[
158+El siguiente es un ejemplo del fichero _samplepackage.lrs_ resultante.
159+```
160+LazarusResources.Add('TMyCom','PNG',[
135161 #137'PNG'#13#10#26#10#0#0#0#13'IHDR'#0#0#0#24#0#0#0#24#8#2#0#0#0'o'#21#170#175
136162 +#0#0#0#4'gAMA'#0#0#177#143#11#252'a'#5#0#0#0'|IDAT8O'#237#212#209#10#192' '#8
137163 +#5'P'#247#231#251's'#215#138#133#164#166'\'#220#195'`'#209'c'#157'L'#173#131
138164 +#153#169'd4'#168'dP'#137'r_'#235'5'#136'@Zmk'#16'd9'#144#176#232#164'1'#247
139165 +'I'#8#160'IL'#206'C'#179#144#12#199#140'.'#134#244#141'~'#168#247#209'S~;'#29
140166 +'V+'#196#201'^'#10#15#150'?'#255#18#227#206'NZ>42'#181#159#226#144#15'@'#201
141167 +#148#168'e'#224'7f<@4'#130'u_YD'#23#213#131#134'Q]'#158#188#135#0#0#0#0'IEND'
142168 +#174'B`'#130
143169 ]);
144-
145-Asegúrate de incluir tu fichero de recursos en la fuente de tu nuevo componente añadiendo lo siguiente al fondo de la unit del componente e incluyendo **"LResources"** en la claúsula **uses**.
170+```
146171
147-``` pascal
172+Asegúrate de incluir tu fichero de recursos en la fuente de tu nuevo componente añadiendo lo siguiente al fondo de la unit del componente e incluyendo **"LResources"** en la claúsula **uses**.
173+```
148174initialization
149- {$I samplepackage.lrs}
175+ {$I samplepackage.lrs}
150176```
151177
152178### Utilizando glazres
153179
154-**GLazRes** is the graphical version of `lazres` that can assemble files into a Lazarus resource file (.lrs). It can be found in the tools directory of a Lazarus installation.
180+**GLazRes** is the graphical version of `lazres` that can assemble files into a Lazarus resource file (.lrs). It can be found in the tools directory of a Lazarus installation.
155181
156182## Recompilando paquetes
157183
158-Es necesario reconstruir el paquete cada vez que se realizan cambios en el fichero *mycom.pas* . Para reconstruir el paquete ve a Paquete -\> Abrir Archivo de Paquete (.lpk)...-\> Seleccionar el fichero *samplepackage.lpk* en el gestor de paquetes y hacer click en el pulsador Usar -\> Instalar.
184+Es necesario reconstruir el paquete cada vez que se realizan cambios en el fichero _mycom.pas_ . Para reconstruir el paquete ve a Paquete -> Abrir Archivo de Paquete (.lpk)...-> Seleccionar el fichero _samplepackage.lpk_ en el gestor de paquetes y hacer click en el pulsador Usar -> Instalar.
159185
160186## Eliminando paquetes
161187
162-- Para eliminar componentes instalados: en el menú del IDE hacer Click en Paquete -\> \> Instalar/Desinstalar Paquetes. La siguiente imagen muestra la utilidad de Paquetes Instalados.
188+ * Para eliminar componentes instalados: en el menú del IDE hacer Click en Paquete -> > Instalar/Desinstalar Paquetes. La siguiente imagen muestra la utilidad de Paquetes Instalados.
163189
164-![`Installed Components`](/wiki-images/0/0e/How_to_write_lazarus_component_installed_components.png)
190+```
191+[![Installed Components](/wiki-images/0/0e/How_to_write_lazarus_component_installed_components.png)](</File:How_to_write_lazarus_component_installed_components.png> "Installed Components")
192+```
165193
166-- Selecciona el paquete que necesitas desinstalar y haz Click en Desinstalar Selección.
194+ * Selecciona el paquete que necesitas desinstalar y haz Click en Desinstalar Selección.
167195
168-Si algo va mal con un paquete (e.g. el directorio del paquete se ha borrado sin que primeramente se haya desinstalado), entonces Lazarus no permitirá desinstalar los paquetes. Para solucionar el problema se procede a seleccionar Herramientas en el menú del IDE y a continuación Construir Lazarus, lo cual hará que Lazarus reconstruya todos los paquetes y reinicie. A partir de ahí ya debería permitirte desinstalar los paquetes problemáticos.
196+Si algo va mal con un paquete (e.g. el directorio del paquete se ha borrado sin que primeramente se haya desinstalado), entonces Lazarus no permitirá desinstalar los paquetes. Para solucionar el problema se procede a seleccionar Herramientas en el menú del IDE y a continuación Construir Lazarus, lo cual hará que Lazarus reconstruya todos los paquetes y reinicie. A partir de ahí ya debería permitirte desinstalar los paquetes problemáticos.
169197
170198## Mejorando mycom.pas
171199
172-- El código en *mycom.pas* te muestra lo básico que necesitas para crear un componente. Lo siguiente es una mejora con algunos tips sobre como escribir procedimientos y eventos para componentes.
173-- El*OnChange2* muestra como crear eventos.
174-- El *OnSample* muestra como crear eventos personlizados.
175-- *MyText* y *MyText2* muestran caminos diferentes de escribir propiedades.
176-- Puedes utilizar TComboBox en lugar de TCustomComboBox como clase base, la cual publica todas las propiedades como TComboBox.
177-- Si se utiliza TCustomComboBox como la clase base, notarás que se pierden un montón de propiedades y eventos en el Inspector de Objetos del IDE. Para añadir estas propiedades y eventos, simplemente copia y pega las propiedades tal como se listan abajo.*// properties from TComboBox*. Esta lista de propiedades se pueden obtener desde la declaración de TComboBox en la unidad StdCtrls. Omite cualquier propiedad que necesites manegar por ti mismo.
200+ * El código en _mycom.pas_ te muestra lo básico que necesitas para crear un componente. Lo siguiente es una mejora con algunos tips sobre como escribir procedimientos y eventos para componentes.
201+ * El _OnChange2_ muestra como crear eventos.
202+ * El _OnSample_ muestra como crear eventos personlizados.
203+ * _MyText_ y _MyText2_ muestran caminos diferentes de escribir propiedades.
204+ * Puedes utilizar TComboBox en lugar de TCustomComboBox como clase base, la cual publica todas las propiedades como TComboBox.
205+ * Si se utiliza TCustomComboBox como la clase base, notarás que se pierden un montón de propiedades y eventos en el Inspector de Objetos del IDE. Para añadir estas propiedades y eventos, simplemente copia y pega las propiedades tal como se listan abajo._// properties from TComboBox_. Esta lista de propiedades se pueden obtener desde la declaración de TComboBox en la unidad StdCtrls. Omite cualquier propiedad que necesites manegar por ti mismo.
178206
179-``` pascal
207+```
180208unit mycom;
181-
182-{$mode objfpc}{$H+}
183-
184-interface
185-
186-uses
187- Classes, SysUtils, StdCtrls, Forms, Dialogs,
188- LCLType,LCLIntf,lresources,LCLProc;
189-
190-type
191-
192- TSampleEvent = procedure(MyText: String) of Object;
193-
194- TMyCom = class (TCustomComboBox)
195- private
196- FMyText: String;
197- FOnChange2: TNotifyEvent;
198- FOnSample: TSampleEvent;
199- public
200- constructor Create(TheOwner: TComponent); override;
201- procedure CreateWnd; override;
202- procedure Change; override;
203- protected
204- function GetMyText2: String;
205- procedure SetMyText2(MyText: String);
206- published
207- property MyText: String read FMyText write FMyText;
208- property MyText2: String read GetMyText2 write SetMyText2;
209- property OnChange2: TNotifyEvent read FOnChange2 write FOnChange2;
210- property OnSample: TSampleEvent read FOnSample write FOnSample;
211209
212- // properties from TComboBox
213- property Align;
214- property Anchors;
215- property ArrowKeysTraverseList;
216- property AutoComplete;
217- property AutoCompleteText;
218- property AutoDropDown;
219- property AutoSelect;
220- property AutoSize;
221- property BidiMode;
222- property BorderSpacing;
223- property CharCase;
224- property Color;
225- property Ctl3D;
226- property Constraints;
227- property DragCursor;
228- property DragMode;
229- property DropDownCount;
230- property Enabled;
231- property Font;
232- property ItemHeight;
233- property ItemIndex;
234- property Items;
235- property ItemWidth;
236- property MaxLength;
237- property OnChange;
238- property OnChangeBounds;
239- property OnClick;
240- property OnCloseUp;
241- property OnContextPopup;
242- property OnDblClick;
243- property OnDragDrop;
244- property OnDragOver;
245- property OnDrawItem;
246- property OnEndDrag;
247- property OnDropDown;
248- property OnEditingDone;
249- property OnEnter;
250- property OnExit;
251- property OnGetItems;
252- property OnKeyDown;
253- property OnKeyPress;
254- property OnKeyUp;
255- property OnMeasureItem;
256- property OnMouseDown;
257- property OnMouseMove;
258- property OnMouseUp;
259- property OnStartDrag;
260- property OnSelect;
261- property OnUTF8KeyPress;
262- property ParentBidiMode;
263- property ParentColor;
264- property ParentCtl3D;
265- property ParentFont;
266- property ParentShowHint;
267- property PopupMenu;
268- property ReadOnly;
269- property ShowHint;
270- property Sorted;
271- property Style;
272- property TabOrder;
273- property TabStop;
274- property Text;
275- property Visible;
276- end;
277-
278-procedure Register;
279-
280-implementation
281-
282-procedure Register;
283-begin
284- RegisterComponents('Sample',[TMyCom]);
285-end;
286-
287-constructor TMyCom.Create(TheOwner: TComponent);
288-begin
289- inherited Create(TheOwner);
290- Self.Style := csDropDownList;
291-end;
292-
293-procedure TMyCom.CreateWnd;
294-begin
295- inherited CreateWnd;
296- Items.Assign(Screen.Fonts);
297-end;
298-
299-procedure TMyCom.Change;
300-begin
301- inherited;
302- if Assigned(FOnChange2) then FOnChange2(Self);
303- if Assigned(FOnSample) then FOnSample(FMyText);
304-end;
305-
306-function TMyCom.GetMyText2: String;
307-begin
308- Result:=FMyText;
309-end;
310-
311-procedure TMyCom.SetMyText2(MyText: String);
312-begin
313- FMyText:=MyText;
314-end;
315-
316-initialization
317- {$I samplepackage.lrs}
318-
319-end.
210+ {$mode objfpc}{$H+}
211+
212+ interface
213+
214+ uses
215+ Classes, SysUtils, StdCtrls, Forms, Dialogs,
216+ LCLType,LCLIntf,lresources,LCLProc;
217+
218+ type
219+
220+ TSampleEvent = procedure(MyText: String) of Object;
221+
222+ TMyCom = class (TCustomComboBox)
223+ private
224+ FMyText: String;
225+ FOnChange2: TNotifyEvent;
226+ FOnSample: TSampleEvent;
227+ public
228+ constructor Create(TheOwner: TComponent); override;
229+ procedure CreateWnd; override;
230+ procedure Change; override;
231+ protected
232+ function GetMyText2: String;
233+ procedure SetMyText2(MyText: String);
234+ published
235+ property MyText: String read FMyText write FMyText;
236+ property MyText2: String read GetMyText2 write SetMyText2;
237+ property OnChange2: TNotifyEvent read FOnChange2 write FOnChange2;
238+ property OnSample: TSampleEvent read FOnSample write FOnSample;
239+
240+ // properties from TComboBox
241+ property Align;
242+ property Anchors;
243+ property ArrowKeysTraverseList;
244+ property AutoComplete;
245+ property AutoCompleteText;
246+ property AutoDropDown;
247+ property AutoSelect;
248+ property AutoSize;
249+ property BidiMode;
250+ property BorderSpacing;
251+ property CharCase;
252+ property Color;
253+ property Ctl3D;
254+ property Constraints;
255+ property DragCursor;
256+ property DragMode;
257+ property DropDownCount;
258+ property Enabled;
259+ property Font;
260+ property ItemHeight;
261+ property ItemIndex;
262+ property Items;
263+ property ItemWidth;
264+ property MaxLength;
265+ property OnChange;
266+ property OnChangeBounds;
267+ property OnClick;
268+ property OnCloseUp;
269+ property OnContextPopup;
270+ property OnDblClick;
271+ property OnDragDrop;
272+ property OnDragOver;
273+ property OnDrawItem;
274+ property OnEndDrag;
275+ property OnDropDown;
276+ property OnEditingDone;
277+ property OnEnter;
278+ property OnExit;
279+ property OnGetItems;
280+ property OnKeyDown;
281+ property OnKeyPress;
282+ property OnKeyUp;
283+ property OnMeasureItem;
284+ property OnMouseDown;
285+ property OnMouseMove;
286+ property OnMouseUp;
287+ property OnStartDrag;
288+ property OnSelect;
289+ property OnUTF8KeyPress;
290+ property ParentBidiMode;
291+ property ParentColor;
292+ property ParentCtl3D;
293+ property ParentFont;
294+ property ParentShowHint;
295+ property PopupMenu;
296+ property ReadOnly;
297+ property ShowHint;
298+ property Sorted;
299+ property Style;
300+ property TabOrder;
301+ property TabStop;
302+ property Text;
303+ property Visible;
304+ end;
305+
306+ procedure Register;
307+
308+ implementation
309+
310+ procedure Register;
311+ begin
312+ RegisterComponents('Sample',[TMyCom]);
313+ end;
314+
315+ constructor TMyCom.Create(TheOwner: TComponent);
316+ begin
317+ inherited Create(TheOwner);
318+ Self.Style := csDropDownList;
319+ end;
320+
321+ procedure TMyCom.CreateWnd;
322+ begin
323+ inherited CreateWnd;
324+ Items.Assign(Screen.Fonts);
325+ end;
326+
327+ procedure TMyCom.Change;
328+ begin
329+ inherited;
330+ if Assigned(FOnChange2) then FOnChange2(Self);
331+ if Assigned(FOnSample) then FOnSample(FMyText);
332+ end;
333+
334+ function TMyCom.GetMyText2: String;
335+ begin
336+ Result:=FMyText;
337+ end;
338+
339+ procedure TMyCom.SetMyText2(MyText: String);
340+ begin
341+ FMyText:=MyText;
342+ end;
343+
344+ initialization
345+ {$I samplepackage.lrs}
346+
347+ end.
320348```
321349
322-Además notarás que existen en el Inspector de Objetos del IDE algunos elementos no declarados y posiblemente innecesarios. Para removerlos, los que no necesites, puedes declararlos en la sección *Published* como simples variables. Por ejemplo:
323-
324-``` pascal
350+Además notarás que existen en el Inspector de Objetos del IDE algunos elementos no declarados y posiblemente innecesarios. Para removerlos, los que no necesites, puedes declararlos en la sección _Published_ como simples variables. Por ejemplo:
351+```
325352Published
326-...
327- property Height: Integer;
328- property Width: Integer;
329-...
353+ ...
354+ property Height: Integer;
355+ property Width: Integer;
356+ ...
330357```
331358
332359## Utilizando componentes (visuales) embebidos
333360
334-Puedes utilizar componenetes estandar embebidos dentro de tus propios componentes (mira por ejemplo en TLabeledEdit o TButtonPanel).
335-
336-Digamos que necesitas crear un panel personalizado con un TLabel en el mismo. Con los pasos descritos se pueden crear el paquete base y los ficheros fuente.
361+Puedes utilizar componenetes estandar embebidos dentro de tus propios componentes (mira por ejemplo en TLabeledEdit o TButtonPanel).
337362
338-Ahora haz lo siguiente para añadir un TLabel al componente:
363+Digamos que necesitas crear un panel personalizado con un TLabel en el mismo. Con los pasos descritos se pueden crear el paquete base y los ficheros fuente.
339364
340-- Añade un atributo para el componente label(FEmbeddedLabel: TLabel;).
341-- Añade una propiedad publicada de solo lectura para el componente label (property EmbeddedLabel: TLabel read FEmbeddedLabel;)
342-- Create the label in the component's (overridden) constructor (FEmbeddedLabel := TLabel.Create(self); )
343-- Set the parent of the component (FEmbeddedLabel.Parent := self;)
344-- If the component to be embedded is not a 'subcomponent' by default (like TBoundLabel, TPanelBitBtn etc) then add the call to SetSubComponent. This is necessary for the IDE so it knows that it has to store the properties of the embedded component as well. TLabel is not a subcomponent by default so the call to the method must be added (FEmbeddedLabel.SetSubComponent(true);).
365+Ahora haz lo siguiente para añadir un TLabel al componente:
345366
346-To sum it up you would get something like this (solamente se muestran las partes esenciales):
367+ * Añade un atributo para el componente label(FEmbeddedLabel: TLabel;).
368+ * Añade una propiedad publicada de solo lectura para el componente label (property EmbeddedLabel: TLabel read FEmbeddedLabel;)
369+ * Create the label in the component's (overridden) constructor (FEmbeddedLabel := TLabel.Create(self); )
370+ * Set the parent of the component (FEmbeddedLabel.Parent := self;)
371+ * If the component to be embedded is not a 'subcomponent' by default (like TBoundLabel, TPanelBitBtn etc) then add the call to SetSubComponent. This is necessary for the IDE so it knows that it has to store the properties of the embedded component as well. TLabel is not a subcomponent by default so the call to the method must be added (FEmbeddedLabel.SetSubComponent(true);).
347372
348-``` pascal
373+To sum it up you would get something like this (solamente se muestran las partes esenciales):
374+```
349375TEnhancedPanel = class(TCustomControl)
350-private
351- { El nuevo atributo para el label embebido }
352- FEmbeddedLabel: TLabel;
353-
354-public
355- { El contructor debe ser overriden para que el label pueda crearse }
356- constructor Create(AOwner: TComponent); override;
357-
358-published
359- { Hacer el label visible en el IDE }
360- property EmbeddedLabel: TLabel read FEmbeddedLabel;
361-end;
362-
363-implementation
364-
365-constructor TEnhancedPanel.Create(AOwner: TComponent);
366-begin
367- inherited Create(AOwner);
368-
369- // Establece el ancho y alto por defecto
370- with GetControlClassDefaultSize do
371- SetInitialBounds(0, 0, CX, CY);
372-
373- // Add the embedded label
374- FEmbeddedLabel := TLabel.Create(Self); // Add the embedded label
375- FEmbeddedLabel.Parent := self; // Show the label in the panel
376- FEmbeddedLabel.SetSubComponent(true); // Tell the IDE to store the modified properties
377- FLabel.Name := 'EmbeddedLabel';
378- FLabel.Caption := 'Howdy World!';
379-
380- // Make sure the embedded label can not be selected/deleted within the IDE
381- FLabel.ControlStyle := FLabel.ControlStyle - [csNoDesignSelectable];
382-
383- // Establecer otras propiedades si es neceario
384- //...
385-
386-end;
376+ private
377+ { El nuevo atributo para el label embebido }
378+ FEmbeddedLabel: TLabel;
379+
380+ public
381+ { El contructor debe ser overriden para que el label pueda crearse }
382+ constructor Create(AOwner: TComponent); override;
383+
384+ published
385+ { Hacer el label visible en el IDE }
386+ property EmbeddedLabel: TLabel read FEmbeddedLabel;
387+ end;
388+
389+ implementation
390+
391+ constructor TEnhancedPanel.Create(AOwner: TComponent);
392+ begin
393+ inherited Create(AOwner);
394+
395+ // Establece el ancho y alto por defecto
396+ with GetControlClassDefaultSize do
397+ SetInitialBounds(0, 0, CX, CY);
398+
399+ // Add the embedded label
400+ FEmbeddedLabel := TLabel.Create(Self); // Add the embedded label
401+ FEmbeddedLabel.Parent := self; // Show the label in the panel
402+ FEmbeddedLabel.SetSubComponent(true); // Tell the IDE to store the modified properties
403+ FLabel.Name := 'EmbeddedLabel';
404+ FLabel.Caption := 'Howdy World!';
405+
406+ // Make sure the embedded label can not be selected/deleted within the IDE
407+ FLabel.ControlStyle := FLabel.ControlStyle - [csNoDesignSelectable];
408+
409+ // Establecer otras propiedades si es neceario
410+ //...
411+
412+ end;
387413```
388414
389415## Using custom paint procedure
390416
391-You can always subclass a component inside your program. For example, this implements a custom Paint procedure to a TLabel:
392-
393-``` pascal
417+You can always subclass a component inside your program. For example, this implements a custom Paint procedure to a TLabel:
418+```
394419type
395- TMyLabel = class(TLabel)
396- protected
397- procedure Paint; override;
398- end;
399-{...}
400-implementation
401-{...}
402-procedure TMyLabel.Paint;
403-begin
404- // your code to implement Paint, for example
405- Canvas.TextOut(0,0,Caption);
406-end;
420+ TMyLabel = class(TLabel)
421+ protected
422+ procedure Paint; override;
423+ end;
424+ {...}
425+ implementation
426+ {...}
427+ procedure TMyLabel.Paint;
428+ begin
429+ // your code to implement Paint, for example
430+ Canvas.TextOut(0,0,Caption);
431+ end;
407432```
408433
409-Now you can create a MyLabel inside your program, at run time, with that overridden Paint procedure instead of the standard one.
410-
411-For most components, and for most methods, it would be recommendable to call inherited procedure inside it:
434+Now you can create a MyLabel inside your program, at run time, with that overridden Paint procedure instead of the standard one.
412435
413-``` pascal
436+For most components, and for most methods, it would be recommendable to call inherited procedure inside it:
437+```
414438procedure TMyLabel.Paint;
415-begin
416-
417- inherited Paint; /////////////////////
418-
419- // your code to implement Paint, for example
420- Canvas.TextOut(0,0,Caption);
421-end;
439+ begin
440+
441+ inherited Paint; /////////////////////
442+
443+ // your code to implement Paint, for example
444+ Canvas.TextOut(0,0,Caption);
445+ end;
422446```
423447
424-However, inherited behavior is not desirable in this case, since the second writing action would overlap the first (inherited) one.
448+However, inherited behavior is not desirable in this case, since the second writing action would overlap the first (inherited) one.
425449
426450## Integrando el componente con el IDE
427451
428452### Editores de propiedades
429453
430-Los editores de propiedades proveen diálogos personalizados para editar propiedades en el Inspector de Objetos. Para la mayor parte de las propiedades, tales como cadenas, listados de cadenas, imágenes, tipos enumerados y otros, hay ya editores de propiedades por defecto, pero pero si un componente personalizado tiene cualquier tipo de propiedad especial se hace necesario un diálogo personalizado para editar la propiedad.
431-
432-Cada editor de propiedad es una clase, la cual debe descender de TPropertyEditor o de uno de sus descendientes e implementar métodos de esta clase base. Deberían registrase en el procedimiento 'Register' utilizando la función RegisterPropertyEditor de la unidad PropEdits. Es un estandar nombrar a los editores de propiedades con el nombre de la propiedad seguido por 'Property', por ejemplo TFieldProperty para el editor de propiedades de la propiedad TField.
454+Los editores de propiedades proveen diálogos personalizados para editar propiedades en el Inspector de Objetos. Para la mayor parte de las propiedades, tales como cadenas, listados de cadenas, imágenes, tipos enumerados y otros, hay ya editores de propiedades por defecto, pero pero si un componente personalizado tiene cualquier tipo de propiedad especial se hace necesario un diálogo personalizado para editar la propiedad.
433455
434-``` pascal
435- TPropertyEditor = class
436- public
437- function AllEqual: Boolean; Virtual;
438- function AutoFill: Boolean; Virtual;
439- procedure Edit; Virtual; // Activated by double-clicking the property value
440- procedure ShowValue; Virtual; // Activated by control-clicking the property value
441- function GetAttributes: TPropertyAttributes; Virtual;
442- function GetEditLimit: Integer; Virtual;
443- function GetName: ShortString; Virtual;
444- procedure GetProperties(Proc: TGetPropEditProc); Virtual;
445- function GetHint(HintType: TPropEditHint; x, y: integer): String; Virtual;
446- function GetDefaultValue: AnsiString; Virtual;
447- procedure GetValues(Proc: TGetStrProc); Virtual;
448- procedure SetValue(const NewValue: AnsiString); Virtual;
449- procedure UpdateSubProperties; Virtual;
450- function SubPropertiesNeedsUpdate: Boolean; Virtual;
451- function IsDefaultValue: Boolean; Virtual;
452- function IsNotDefaultValue: Boolean; Virtual;
453- // ... shortened
454- end;
456+Cada editor de propiedad es una clase, la cual debe descender de TPropertyEditor o de uno de sus descendientes e implementar métodos de esta clase base. Deberían registrase en el procedimiento 'Register' utilizando la función RegisterPropertyEditor de la unidad PropEdits. Es un estandar nombrar a los editores de propiedades con el nombre de la propiedad seguido por 'Property', por ejemplo TFieldProperty para el editor de propiedades de la propiedad TField.
455457```
456-
457-Un buen ejemplo para un editor de propiedades es el de TFont.
458+TPropertyEditor = class
459+ public
460+ function AllEqual: Boolean; Virtual;
461+ function AutoFill: Boolean; Virtual;
462+ procedure Edit; Virtual; // Activated by double-clicking the property value
463+ procedure ShowValue; Virtual; // Activated by control-clicking the property value
464+ function GetAttributes: TPropertyAttributes; Virtual;
465+ function GetEditLimit: Integer; Virtual;
466+ function GetName: ShortString; Virtual;
467+ procedure GetProperties(Proc: TGetPropEditProc); Virtual;
468+ function GetHint(HintType: TPropEditHint; x, y: integer): String; Virtual;
469+ function GetDefaultValue: AnsiString; Virtual;
470+ procedure GetValues(Proc: TGetStrProc); Virtual;
471+ procedure SetValue(const NewValue: AnsiString); Virtual;
472+ procedure UpdateSubProperties; Virtual;
473+ function SubPropertiesNeedsUpdate: Boolean; Virtual;
474+ function IsDefaultValue: Boolean; Virtual;
475+ function IsNotDefaultValue: Boolean; Virtual;
476+ // ... shortened
477+ end;
478+```
458479
459-Uno de los casos más habituales de editores de propiedades es el de propiedades que son clases. Debido a que classes tiene bastantes campos y puede tener una variedad de formatos no es posible para Lazarus tener el campo de edición del inspector de objetos capaz de editarlo, tal como es realizado para cadenas y tipos numéricos.
480+
481+Un buen ejemplo para un editor de propiedades es el de TFont.
460482
461-Para clases, una convención es tener el valor del campo mostrado permanentemente de la clase entre paréntesis, por ejemplo "(TFont)" y el pulsador "..." muestra un diálogo para editar esta clase. Este comportamiento, excepto para el diálogo, se implementa por medio de un editor estandar de de propiedades para clases llamado TClassPropertyEditor, del cual puede heredar cuando se escriben editores de propiedades para clases:
483+Uno de los casos más habituales de editores de propiedades es el de propiedades que son clases. Debido a que classes tiene bastantes campos y puede tener una variedad de formatos no es posible para Lazarus tener el campo de edición del inspector de objetos capaz de editarlo, tal como es realizado para cadenas y tipos numéricos.
462484
463-``` pascal
485+Para clases, una convención es tener el valor del campo mostrado permanentemente de la clase entre paréntesis, por ejemplo "(TFont)" y el pulsador "..." muestra un diálogo para editar esta clase. Este comportamiento, excepto para el diálogo, se implementa por medio de un editor estandar de de propiedades para clases llamado TClassPropertyEditor, del cual puede heredar cuando se escriben editores de propiedades para clases:
486+```
464487TClassPropertyEditor = class(TPropertyEditor)
465-public
466- constructor Create(Hook: TPropertyEditorHook; APropCount: Integer); Override;
467- function GetAttributes: TPropertyAttributes; Override;
468- procedure GetProperties(Proc: TGetPropEditProc); Override;
469- function GetValue: AnsiString; Override;
470- property SubPropsTypeFilter: TTypeKinds Read FSubPropsTypeFilter
471- Write SetSubPropsTypeFilter
472- Default tkAny;
473-end;
488+ public
489+ constructor Create(Hook: TPropertyEditorHook; APropCount: Integer); Override;
490+ function GetAttributes: TPropertyAttributes; Override;
491+ procedure GetProperties(Proc: TGetPropEditProc); Override;
492+ function GetValue: AnsiString; Override;
493+ property SubPropsTypeFilter: TTypeKinds Read FSubPropsTypeFilter
494+ Write SetSubPropsTypeFilter
495+ Default tkAny;
496+ end;
474497```
475498
476-Volviendo al ejemplo de TFont, heredando desde TClassPropertyEditor already offers part of the desired behavior and then the TFontPropertyEditor class only needs to implement showing the dialog in the Edit method and set the attributes for the editor:
477-
478-``` pascal
479- TFontPropertyEditor = class(TClassPropertyEditor)
480- public
481- procedure Edit; Override;
482- function GetAttributes: TPropertyAttributes; Override;
483- end;
484-
485-procedure TFontPropertyEditor.Edit;
486-var
487- FontDialog: TFontDialog;
488-begin
489- FontDialog := TFontDialog.Create(NIL);
490- try
491- FontDialog.Font := TFont(GetObjectValue(TFont));
492- FontDialog.Options := FontDialog.Options + [fdShowHelp, fdForceFontExist];
493- if FontDialog.Execute then SetPtrValue(FontDialog.Font);
494- finally
495- FontDialog.Free;
496- end;
497-end;
498-
499-function TFontPropertyEditor.GetAttributes: TPropertyAttributes;
500-begin
501- Result := [paMultiSelect, paSubProperties, paDialog, paReadOnly];
502-end;
499+Volviendo al ejemplo de TFont, heredando desde TClassPropertyEditor already offers part of the desired behavior and then the TFontPropertyEditor class only needs to implement showing the dialog in the Edit method and set the attributes for the editor:
503500```
501+TFontPropertyEditor = class(TClassPropertyEditor)
502+ public
503+ procedure Edit; Override;
504+ function GetAttributes: TPropertyAttributes; Override;
505+ end;
506+
507+ procedure TFontPropertyEditor.Edit;
508+ var
509+ FontDialog: TFontDialog;
510+ begin
511+ FontDialog := TFontDialog.Create(NIL);
512+ try
513+ FontDialog.Font := TFont(GetObjectValue(TFont));
514+ FontDialog.Options := FontDialog.Options + [fdShowHelp, fdForceFontExist];
515+ if FontDialog.Execute then SetPtrValue(FontDialog.Font);
516+ finally
517+ FontDialog.Free;
518+ end;
519+ end;
520+
521+ function TFontPropertyEditor.GetAttributes: TPropertyAttributes;
522+ begin
523+ Result := [paMultiSelect, paSubProperties, paDialog, paReadOnly];
524+ end;
525+```
504526
505527### Editores de componentes
506528
507-Los editores de componentes controlan el comportamiento de los mismos en cuanto a clickeo derecho y doble click en el diseñador de formularios.
508-
509-Cada componente del editor es una clase, la cual debería descender de TComponentEditor o uno de sus descendientes e implementar métodos para esta clase base. Se deberían registrar en el procedimiento 'Register' utilizando la función RegisterComponentEditor de la unidad ComponentEditors. Es un estandar para nombrar los editores de componentes con el nombre del componente seguido por 'Editor', por ejemplo TStringGridComponentEditor para la propiedad de editior del componente TStringGrid. Although user component editors deberían estar basados en TComponentEditor, la mayoría de sus métodos son actualmente un ancestor, por lo que es necesario conocer además TBaseComponentEditor:
529+Los editores de componentes controlan el comportamiento de los mismos en cuanto a clickeo derecho y doble click en el diseñador de formularios.
510530
511-``` pascal
512- TBaseComponentEditor = class
513- protected
514- public
515- constructor Create(AComponent: TComponent;
516- ADesigner: TComponentEditorDesigner); Virtual;
517- procedure Edit; Virtual; Abstract;
518- procedure ExecuteVerb(Index: Integer); Virtual; Abstract;
519- function GetVerb(Index: Integer): String; Virtual; Abstract;
520- function GetVerbCount: Integer; Virtual; Abstract;
521- procedure PrepareItem(Index: Integer; const AnItem: TMenuItem); Virtual; Abstract;
522- procedure Copy; Virtual; Abstract;
523- function IsInInlined: Boolean; Virtual; Abstract;
524- function GetComponent: TComponent; Virtual; Abstract;
525- function GetDesigner: TComponentEditorDesigner; Virtual; Abstract;
526- function GetHook(out Hook: TPropertyEditorHook): Boolean; Virtual; Abstract;
527- procedure Modified; Virtual; Abstract;
528- end;
531+Cada componente del editor es una clase, la cual debería descender de TComponentEditor o uno de sus descendientes e implementar métodos para esta clase base. Se deberían registrar en el procedimiento 'Register' utilizando la función RegisterComponentEditor de la unidad ComponentEditors. Es un estandar para nombrar los editores de componentes con el nombre del componente seguido por 'Editor', por ejemplo TStringGridComponentEditor para la propiedad de editior del componente TStringGrid. Although user component editors deberían estar basados en TComponentEditor, la mayoría de sus métodos son actualmente un ancestor, por lo que es necesario conocer además TBaseComponentEditor:
529532```
530-
531-El método más importante de un editor componente es Edit, el cual se llama cuando se hace doble click sobre el componente. Cuando se invocael menú contextual del componente se realiza la llamada a los métodos GetVerbCount y GetVerb para construir el menú. Si se selecciona uno de los verbs (que significa elementos del menú en este caso) entonces se llama a ExecuteVerb. Existe un componente de editor por defecto (TDefaultEditor) el cual implementa Edit para buscar en las propiedades del componente la más apropiada para ser editada. Usualmente escoge un evento, el cual se edita añadiendo su estructura de código en el editor de código y estableciendo el cursor a ubicar al cual añadir código.
532-
533-Otros métodos importantes para TBasComponentEditor son:: ExecuteVerb(Index), el cual ejecuta uno de los elementos extra del menú ubicado en el menu popup del click derecho; GetVerb – Para retornar el nombre de cada elemento extra del menú popup. Ten en cuenta que es responsabilidad del editor de componente ubicar special menu item caption characters like & to create a keyboard accelerator and “-” to create a separator; GetVerbCount – Returns the amount of items to be added to the popup menu. The index for the routines GetVerb and ExecuteVerb is zero based, going from 0 to GetVerbCount – 1; PrepareItem – Called for each verb after the menu item was created. Allows the menu item to be customized such as by adding subitems, adding a checkbox or even hiding it by setting Visible to false; Copy - Called when the component is being copied to the clipboard. The component data for use by Lazarus will always be added and cannot be modified. This method is instead for adding a different kind of clipboard information to paste the component in other applications, but which won't affect the Lazarus paste.
534-
535-Un simple e interesante ejemplo es el editor de componente TCheckListBox el cual crea un diálogo de edición. Más conveniente que implementar todos los métodos desde TBaseComponentEditor es heredarlos desde TComponentEditor, y esto es lo que TCheckListBoxEditor hace. Esta clase base añade implementaciones vacía para la mayor parte de los métodos y agunos por defecto para otros. Para Edit llama a ExecuteVerb(0), por lo que si el primer elemento es idéntico a la acción doble click, la cual es una convención para editor, no habrá necesidad de implementar Edit. Esta acción básica para doble-click y el primer elemento de del menú es a menudo un diálogo, y para TCheckListBox se realiza además:
536-
537-``` pascal
538- TCheckListBoxComponentEditor = class(TComponentEditor)
539- protected
540- procedure DoShowEditor;
541- public
542- procedure ExecuteVerb(Index: Integer); override;
543- function GetVerb(Index: Integer): String; override;
544- function GetVerbCount: Integer; override;
545- end;
546-
547-procedure TCheckGroupComponentEditor.DoShowEditor;
548-var
549- Dlg: TCheckGroupEditorDlg;
550-begin
551- Dlg := TCheckGroupEditorDlg.Create(NIL);
552- try
553- // .. shortened
554- Dlg.ShowModal;
555- // .. shortened
556- finally
557- Dlg.Free;
558- end;
559-end;
533+TBaseComponentEditor = class
534+ protected
535+ public
536+ constructor Create(AComponent: TComponent;
537+ ADesigner: TComponentEditorDesigner); Virtual;
538+ procedure Edit; Virtual; Abstract;
539+ procedure ExecuteVerb(Index: Integer); Virtual; Abstract;
540+ function GetVerb(Index: Integer): String; Virtual; Abstract;
541+ function GetVerbCount: Integer; Virtual; Abstract;
542+ procedure PrepareItem(Index: Integer; const AnItem: TMenuItem); Virtual; Abstract;
543+ procedure Copy; Virtual; Abstract;
544+ function IsInInlined: Boolean; Virtual; Abstract;
545+ function GetComponent: TComponent; Virtual; Abstract;
546+ function GetDesigner: TComponentEditorDesigner; Virtual; Abstract;
547+ function GetHook(out Hook: TPropertyEditorHook): Boolean; Virtual; Abstract;
548+ procedure Modified; Virtual; Abstract;
549+ end;
550+```
560551
561-procedure TCheckGroupComponentEditor.ExecuteVerb(Index: Integer);
562-begin
563- case Index of
564- 0: DoShowEditor;
565- end;
566-end;
552+El método más importante de un editor componente es Edit, el cual se llama cuando se hace doble click sobre el componente. Cuando se invocael menú contextual del componente se realiza la llamada a los métodos GetVerbCount y GetVerb para construir el menú. Si se selecciona uno de los verbs (que significa elementos del menú en este caso) entonces se llama a ExecuteVerb. Existe un componente de editor por defecto (TDefaultEditor) el cual implementa Edit para buscar en las propiedades del componente la más apropiada para ser editada. Usualmente escoge un evento, el cual se edita añadiendo su estructura de código en el editor de código y estableciendo el cursor a ubicar al cual añadir código.
567553
568-function TCheckGroupComponentEditor.GetVerb(Index: Integer): String;
569-begin
570- Result := 'CheckBox Editor...';
571-end;
554+Otros métodos importantes para TBasComponentEditor son:: ExecuteVerb(Index), el cual ejecuta uno de los elementos extra del menú ubicado en el menu popup del click derecho; GetVerb – Para retornar el nombre de cada elemento extra del menú popup. Ten en cuenta que es responsabilidad del editor de componente ubicar special menu item caption characters like & to create a keyboard accelerator and “-” to create a separator; GetVerbCount – Returns the amount of items to be added to the popup menu. The index for the routines GetVerb and ExecuteVerb is zero based, going from 0 to GetVerbCount – 1; PrepareItem – Called for each verb after the menu item was created. Allows the menu item to be customized such as by adding subitems, adding a checkbox or even hiding it by setting Visible to false; Copy - Called when the component is being copied to the clipboard. The component data for use by Lazarus will always be added and cannot be modified. This method is instead for adding a different kind of clipboard information to paste the component in other applications, but which won't affect the Lazarus paste.
572555
573-function TCheckGroupComponentEditor.GetVerbCount: Integer;
574-begin
575- Result := 1;
576-end;
556+
557+Un simple e interesante ejemplo es el editor de componente TCheckListBox el cual crea un diálogo de edición. Más conveniente que implementar todos los métodos desde TBaseComponentEditor es heredarlos desde TComponentEditor, y esto es lo que TCheckListBoxEditor hace. Esta clase base añade implementaciones vacía para la mayor parte de los métodos y agunos por defecto para otros. Para Edit llama a ExecuteVerb(0), por lo que si el primer elemento es idéntico a la acción doble click, la cual es una convención para editor, no habrá necesidad de implementar Edit. Esta acción básica para doble-click y el primer elemento de del menú es a menudo un diálogo, y para TCheckListBox se realiza además:
577558```
559+TCheckListBoxComponentEditor = class(TComponentEditor)
560+ protected
561+ procedure DoShowEditor;
562+ public
563+ procedure ExecuteVerb(Index: Integer); override;
564+ function GetVerb(Index: Integer): String; override;
565+ function GetVerbCount: Integer; override;
566+ end;
567+
568+ procedure TCheckGroupComponentEditor.DoShowEditor;
569+ var
570+ Dlg: TCheckGroupEditorDlg;
571+ begin
572+ Dlg := TCheckGroupEditorDlg.Create(NIL);
573+ try
574+ // .. shortened
575+ Dlg.ShowModal;
576+ // .. shortened
577+ finally
578+ Dlg.Free;
579+ end;
580+ end;
581+
582+ procedure TCheckGroupComponentEditor.ExecuteVerb(Index: Integer);
583+ begin
584+ case Index of
585+ 0: DoShowEditor;
586+ end;
587+ end;
588+
589+ function TCheckGroupComponentEditor.GetVerb(Index: Integer): String;
590+ begin
591+ Result := 'CheckBox Editor...';
592+ end;
593+
594+ function TCheckGroupComponentEditor.GetVerbCount: Integer;
595+ begin
596+ Result := 1;
597+ end;
598+```
578599
579600## Depurando un componente en tiempo de diseño
580601
581-Para detectar errores en tiempo de diseño en un (nuevamente creado) *dbgcomponent*:
602+Para detectar errores en tiempo de diseño en un (nuevamente creado) _dbgcomponent_ :
582603
583-- Abrir proyecto `C:\lazarus\ide\lazarus.lpi`;
584-- Ejecutar proyecto;
585-- Establecer punto de interrupción en *dbgcomponent* in main (1st) app;
586-- use *dbgcomponent* pascal code in second app;
587-- step through design-time component code in debug-session; do whatever is necessary;
604+ * Abrir proyecto `C:\lazarus\ide\lazarus.lpi`;
605+ * Ejecutar proyecto;
606+ * Establecer punto de interrupción en _dbgcomponent_ in main (1st) app;
607+ * use _dbgcomponent_ pascal code in second app;
608+ * step through design-time component code in debug-session; do whatever is necessary;
588609
589610## See also
590611
591-- [[Extending the IDE]]
592-- [[Lazarus Packages]] - A guide for creating a package under Lazarus
593-- [[Components and Code examples]]
594-- [[Lazarus Components]]
595-- [[IDE Window: Add to Package]]
612+ * [[Extending the IDE]]
613+ * [[Lazarus Packages]] \- A guide for creating a package under Lazarus
614+ * [[Components and Code examples]]
615+ * [[Lazarus Components]]
616+ * [IDE Window: Add to Package](</index.php?title=IDE_Window:_Add_to_Package&action=edit&redlink=1> "IDE Window: Add to Package \(page does not exist\)")
596617
597-You can post questions regarding this page [here](http://forum.lazarus.freepascal.org/index.php/topic,5789.0.html)
618+You can post questions regarding this page [here](<http://forum.lazarus.freepascal.org/index.php/topic,5789.0.html>)
598619
599620---
600-*From the Free Pascal wiki, page "How To Write Lazarus Component/es", as it stood on 2020-02-17 after a change by Trev, out of the wiki's dump of 2024-05-26. Copyright stays with the author who wrote it, according to the old wiki's [[Licensing]] page. If you have concerns about this material, [message the admin](/wiki-contact).*
621+*From the Free Pascal wiki, page "How To Write Lazarus Component/es", as the Internet Archive kept it on 2022-08-17. Copyright stays with the author who wrote it, according to the old wiki's [[Licensing]] page. If you have concerns about this material, [message the admin](/wiki-contact).*

Back to history