@wp
Thank you for the guidance.
It may help people starting his first package (like me) to easyly reuse some parts of his code.
Report from executing the recipe:
- here is an example how to create a "TYellowEdit", a TEdit descendant which uses a yellow color.
(1) Write the unit for the new component. In my example this is the unit MyEditCtrls. It contains the code for the new component - in this case, extremely simple: it just sets the inherited Color property to clYellow when the component is created.
-- done
(2) Write a simple test application to make sure that the new component behaves correctly. Do this before installation, because upon installation the new component will become part of the IDE. When the new component crashes it may crash the entire IDE. And debugging this issue is much easier with a standalone application than debugging the IDE. The application "runtime_test" is included in the upload for this purpose.
-- done
(3) Now we are ready to create the package. Let's first create the runtime package.
(4) Restart the IDE in order to wipe out the previous test project.
-- done – closed current project file, opened a new project of type „application”
(5) Select "Package" > "New Package". Save the new package to some convenient name - I used the name "MyCtrlsR"; the appended "R" indicates that this will be the runtime package. Note the newly opened form which is the package editor.
-- done
(6) In order to make it a "runtime" package select "Options" > "IDE Integration" in the package editor form, and pick "Runtime" in the "Package type" box.
-- done
(7) Click on "Add" > "Add files from file system" in the package editor and select our component unit file.
-- done
(8) Click on "Add" > "New Requirement" in the package editor and add the "LCL" package to the requirements of the package. This is important because otherwise the new component would not find the units on which it depends. Now the treeview of the package editor shows the node "LCL" under "Required Packages".
-- done
(9) Save the package file ("Save"). Then "Compile"
-- done
(10) If this works without error, the runtime package is complete. However, since it is a runtime package, it does not show up in the component palette - this job is done by the designtime package.
-- OK, now tried to use them in a new application testR via adding MyEditCtrls in its unit1 uses (at interface section) clause – compiled and runs OK
(11) In order to create a designtime package, do "Package" > "New Package" again, and save the newly created packages under essentially the same name as the runtime package, but add something to indicate that this is the designtime package. In my attachment, the designtime package is called "MyCtrlsD" - the "D" to indicate ... (you know what I mean?).
-- done
(12) Now again "Options" > "IDE integration" and select "Designtime" as Package type"
-- done
(13) Click on "Add" > "New File" and select "Pascal unit" in order to create a new unit which will contain the registration code which integrates the new component into the IDE. Provide a procedure "Register" which calls "RegisterComponents" for all classes to be registered (to be included in an array). In our case this will be: RegisterComponents('MyCtrls', [TYellowEdit]). The "MyCtrls" instructs the IDE to put the new component on a new page "MyCtrls" on the component palette.
-- OK
(14) Save the new unit under a name indicating that it contains the registration code, e.g. MyCtrlsReg.
-- done
(15) The registration unit should show an icon with a green arrow in the package editor tree. If not, select the registration unit in the package editor and check the box "Register unit" in the lower part of the form. This makes sure that our Register unit is really called.
-- done, green mark present
(16) Click on "Add" > "New Requirement" and add the runtime package. The package file tree now must show "MyCtrlsR" under "Required packages". This way the designtime package finds the runtime code of the component. Do not add the units that were already included in the runtime package - this would make your component uncompilable.
-- done
(17) Ready to test: Click "Compile" - it should compile successfully, otherwise seek the error... (Since we have a designtime package the compiler may warn you about incorrect compilation settings. Just select any and proceed.
-- error, MyCtrlsReg do not recognize RegisterComponents.
Added „uses classes, LResources, myEditCtrls” in interface section of myCtrlsReg unit;
-- after that compilation is OK
(18) Now you can already install the new component: Click "Use" > "Install". This rebuilds the IDE, and afterwards you find the new component in the palette, "MyCtrls".
-- done, after rebuilding the Lazarus IDE has a new Componet palette page „MyCtrls” and default icon (3 colored cubes)
(19) Create a new project, drop the new component and test it again.
-- done → compile error: „unit1.pas(8,58) Fatal: Can't find unit MyEditCtrls used by Unit1”;
-- however YellowEedit was succesfully dropped on Form1 Form design tab;
-- manually added unit file to project (via Project Inspector), compiled with Warning: other unit files search path (aka unit path) of "project1" contains "C:\Users\<me>\Documents\lazarus\Projects\drills\packageD", which belongs to package "MyCtrlsD";
-- changed option for package MyCtrlsD – add uses option → NOW ALL IS OK, COMPILATION GOES WITH NO ERRORS OR WARNINGS
(20) Almost done... What is left is the palette icon. For high-dpi scaling you need three images, the first one 24x24 for 96ppi standard screens, the second one 36x36 for 144ppi high-dpi screens, and the third one 48x48 for 192ppi "very-high-dpi" screens. Use your favourite image editor to draw these images and save them in png format: the 24x24 image should have the name of the componentclass (here: tyellowedit.png), and for the other images the magnification factor (150%, 200%) should be added, e.g. tyellowedit_150.png and tyellowedit_200.png. To facilitate drawing you may also draw the images in scalable vector format and export the png images from there. I am attaching the standard TEdit images (in folder images/components of your Lazarus installation) which I edited to have a yellow background.
(21) For adding these images to the package you must create a resource file. I am describing the usual .res resource format here (rather than the old .lrs format): If you never have done this before load the project lazres into the IDE, it is in folder tools of your Lazarus installation, and build the executable. Copy the executable in the folder in which you stored the images. Write a batch file on Windows (or a shell script on *nix) which executes lazres with the image names and the desired resource file name as parameters, e.g. "lazres myctrls_images.res tyellowedit.png tyellowedit_150.png tyellowedit_200.png". The first parameter is the name of the resource file to be created. The following parameters are the image files to be included. (You may use paths if the files are in different folders)
(22) Load the registration unit, myctrlsreg, into the IDE once again and add the line "{$R myctrls_images.res}" after the uses clause of the implementation section.
(23) Now "Use" > "install" the designtime package again (or use "Tools" > "Build Lazarus with profile..."). When completed, your component has its new icon on the component palette.
Unit defining TYellowEdit:
unit MyEditCtrls;
{$mode ObjFPC}{$H+}
interface
uses
Classes, SysUtils, graphics, StdCtrls, controls;
type TYellowEdit = class (TEdit)
constructor Create(AOwner: TComponent); override;
end;
implementation
constructor TYellowEdit.Create(AOwner: TComponent);
begin
inherited Create(AOwner);
if AOwner is TWinControl then
Parent:=AOwner as TWinControl;
Color:=clYellow;
Width:=200;
end;
end.
Unit used for registration TYellowEdit:
unit myCtrlsReg;
interface
uses classes, LResources, myEditCtrls;
procedure Register;
implementation
procedure Register;
begin
RegisterComponents('MyCtrls', [TYellowEdit]);
end;
end.
Anyway, Lazarus documentation at packages has bugs and is not as informative as wp's recipe, IMO