Recent

Author Topic: Creating Run and Design packages from IDE - a newbie problem  (Read 891 times)

WooBean

  • Full Member
  • ***
  • Posts: 148
Creating Run and Design packages from IDE - a newbie problem
« on: September 14, 2022, 08:49:46 am »
Hi, more or less advanced programers!
 
Has anybody managed to create a run and design time package from Lazarus IDE using Main menu/Package/New package way? If so, how you managed to assign a component icon to Components Palette. I tried to follow what authors have written at https://wiki.freepascal.org/Lazarus_Packages but it seems to me that something is missing or missleading.

I tried to analize a working package LazSerial (run and design) and I think that I could follow (by hands) its pattern of defining the package but what is the Lazarus IDE for? 

Lazarus 2.2.0 (rev lazarus_2_2_0) FPC 3.2.2 x86_64-win64-win32/win64

WooBean 
« Last Edit: September 14, 2022, 12:45:07 pm by WooBean »
Win7/64, Lazarus 2.2.0, FPC 3.2.2, x86_64-win64-win32/win64

GetMem

  • Hero Member
  • *****
  • Posts: 3813
Re: Creating Run and Design packages from IDE - a newbie problem
« Reply #1 on: September 14, 2022, 05:55:03 pm »

WooBean

  • Full Member
  • ***
  • Posts: 148
Re: Creating Run and Design packages from IDE - a newbie problem
« Reply #2 on: September 14, 2022, 07:14:08 pm »
@GetMem

Thanks for the guidance. I was here (https://wiki.freepascal.org/How_To_Write_Lazarus_Component) for a while but I'll give it a second chance.
It would be useful to have an example how to create 'stupid'  design and runtime package (let's say a yellow TEdit as a component) just to demonstrate steps needed. 
Win7/64, Lazarus 2.2.0, FPC 3.2.2, x86_64-win64-win32/win64

WooBean

  • Full Member
  • ***
  • Posts: 148
Re: Creating Run and Design packages from IDE - a newbie problem
« Reply #3 on: September 19, 2022, 09:37:38 pm »
Nobody managed to create a package to be used at design and runtime via Lazarus IDE and its built-in tool?

I tried to follow wiki explanations from the sites:
https://wiki.freepascal.org/How_To_Write_Lazarus_Component
https://wiki.freepascal.org/Lazarus_Packages

Sorry to say but trying to guess what I should do and what is omitted led me to think that the only way to create my own package/component is to study existing packages an repeat its way of definining package.
At least IDE recompiles, component can be registered and seen at the palette. Trying to follow mentioned wiki sites allways causes produsing dead lazarus.exe file. Thanks to idea of keeping lazarus.old.exe there is a salvage.
Win7/64, Lazarus 2.2.0, FPC 3.2.2, x86_64-win64-win32/win64

WooBean

  • Full Member
  • ***
  • Posts: 148
Re: Creating Run and Design packages from IDE - a newbie problem
« Reply #4 on: September 23, 2022, 08:10:58 am »
Need a help? - help yourself.

Finally, I have found that sites https://wiki.freepascal.org/How_To_Write_Lazarus_Component and https://wiki.freepascal.org/Lazarus_Packages  wrongly point out how to include resource file (LRS) into (user created) unit of a package. Instead using it in initialization section we should put it in the Register procedure like below:
Code: Pascal  [Select][+][-]
  1. unit myRDclass;
  2. interface uses ..., LResources;
  3. ...
  4.   procedure Register;
  5. implementation
  6.   procedure Register;
  7.   begin
  8.     {$i myRDPackage.lrs}
  9. //containing 3 PNG icons (24x24, 36x36, 48x48) named as a class ie.
  10. //TmyRDclass.PNG, TmyRDclass_150.PNG, TmyRDclass_200.PNG
  11.     RegisterComponents('My components',[TmyRDclass]);  
  12.   end;
  13. ...
  14. initialization
  15. ...
  16. //{$i myRDPackage.lrs}   - do not put it here!!!
  17. end.
  18.  

Problem solved,  seems to me.
« Last Edit: September 23, 2022, 05:07:23 pm by WooBean »
Win7/64, Lazarus 2.2.0, FPC 3.2.2, x86_64-win64-win32/win64

ojz0r

  • New Member
  • *
  • Posts: 49
Re: Creating Run and Design packages from IDE - a newbie problem
« Reply #5 on: September 23, 2022, 08:21:58 am »
I've been wanting to do this as well but have not gotten around to it yet.
What is the content of the .lrs file? How do you generate it?

It would be awsome if you could update the wiki to reflect your discovery.
Just trying to learn.

WooBean

  • Full Member
  • ***
  • Posts: 148
Re: Creating Run and Design packages from IDE - a newbie problem
« Reply #6 on: September 23, 2022, 08:49:14 am »
...
What is the content of the .lrs file? How do you generate it?
It would be awsome if you could update the wiki to reflect your discovery.
1. It is  explained at https://wiki.freepascal.org/How_To_Write_Lazarus_Component quite well. You can goo.. "LRS Explorer" too.
2. Someone should confirm my "discoveries" first.
Win7/64, Lazarus 2.2.0, FPC 3.2.2, x86_64-win64-win32/win64

KodeZwerg

  • Sr. Member
  • ****
  • Posts: 484
  • Fifty shades of code.
    • Delphi & FreePascal
Re: Creating Run and Design packages from IDE - a newbie problem
« Reply #7 on: September 23, 2022, 02:51:38 pm »
I will try out at weekend to do a component that register with selfmade glyph into palette.
Delphi way would be to have that resource file named like the package but not including it into source, that does the IDE automatic.
(including into source would mean that this resource is afterwards also compiled into your binary if i am not wrong)
« Last Edit: Tomorrow at 31:76:97 by KodeZwerg »

wp

  • Hero Member
  • *****
  • Posts: 10252
Re: Creating Run and Design packages from IDE - a newbie problem
« Reply #8 on: September 23, 2022, 05:31:12 pm »
It would be useful to have an example how to create 'stupid'  design and runtime package (let's say a yellow TEdit as a component) just to demonstrate steps needed.
OK - here is an example how to create a "TYellowEdit", a TEdit descendant which uses a yellow color.
  • 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.
  • 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.
  • Now we are ready to create the package. Let's first create the runtime package.
  • Restart the IDE in order to wipe out the previous test project.
  • 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.
  • 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.
  • Click on "Add" > "Add files from file system" in the package editor and select our component unit file.
  • 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".
  • Save the package file ("Save"). Then "Compile"
  • 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.
  • 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?).
  • Now again "Options" > "IDE integration" and select "Designtime" as Package type"
  • 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.
  • Save the new unit under a name indicating that it contains the registration code, e.g. MyCtrlsReg.
  • 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.
  • 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.
  • 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.
  • 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".
  • Create a new project, drop the new component and test it again.
  • 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.
  • 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)
  • 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.
  • 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.

I wrote this while creating the attached component. So, hopefully, nothing is forgotten...

Since the post is already quite long I did not write about complications that you may have to expect later when you extend the package. (e.g. it is highly recommended to put the units of the runtime and designtime packages in separate directories).

WooBean

  • Full Member
  • ***
  • Posts: 148
Re: Creating Run and Design packages from IDE - a newbie problem
« Reply #9 on: September 29, 2022, 05:12:11 pm »
@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:
Code: Pascal  [Select][+][-]
  1. unit MyEditCtrls;
  2. {$mode ObjFPC}{$H+}
  3.  
  4. interface
  5.  
  6. uses
  7.   Classes, SysUtils, graphics, StdCtrls, controls;
  8. type TYellowEdit = class (TEdit)
  9.    constructor Create(AOwner: TComponent); override;
  10. end;
  11.  
  12. implementation
  13.   constructor TYellowEdit.Create(AOwner: TComponent);
  14.   begin
  15.     inherited Create(AOwner);
  16.     if AOwner is TWinControl then
  17.       Parent:=AOwner as TWinControl;
  18.     Color:=clYellow;
  19.     Width:=200;
  20.   end;
  21. end.
  22.  

Unit used for registration TYellowEdit:
Code: Pascal  [Select][+][-]
  1. unit myCtrlsReg;
  2. interface
  3. uses classes, LResources, myEditCtrls;
  4.  
  5.   procedure Register;
  6. implementation
  7.   procedure Register;
  8.   begin
  9.     RegisterComponents('MyCtrls', [TYellowEdit]);
  10.   end;
  11. end.
  12.  

Anyway, Lazarus documentation at packages has bugs and is not as informative as wp's recipe, IMO


Win7/64, Lazarus 2.2.0, FPC 3.2.2, x86_64-win64-win32/win64

 

TinyPortal © 2005-2018