Difference between revisions of "How To Write Lazarus Component"

From Lazarus wiki
Jump to navigationJump to search
Line 132: Line 132:
 
* The ''OnSample'' shows how to create custom events
 
* The ''OnSample'' shows how to create custom events
 
* ''MyText'' and ''MyText2'' shows different ways to write properties.
 
* ''MyText'' and ''MyText2'' shows different ways to write properties.
* You can use TComboBox instead of TCustomComboBox as the base class, but you won't be able to override some procedures like ''Change'' which calls the OnChange event for the TCustomComboBox.
+
* You can use TComboBox instead of TCustomComboBox as the base class, which publishes all properties as TComboBox.  
 
* If TCustomComboBox is used as the base class, you'll notice a lot of properties and events will be missing at the Object Inspector in the IDE. To add those properties and events just copy and paste the properties as listed below ''// properties from TComboBox''. These list of properties can be got from the TComboBox declaration in the StdCtrls unit. Omit any property which you want to handle yourself.
 
* If TCustomComboBox is used as the base class, you'll notice a lot of properties and events will be missing at the Object Inspector in the IDE. To add those properties and events just copy and paste the properties as listed below ''// properties from TComboBox''. These list of properties can be got from the TComboBox declaration in the StdCtrls unit. Omit any property which you want to handle yourself.
  

Revision as of 16:13, 30 September 2009

Introduction

This is a basic guide on how to build components. It was tested on Windows XP running Lazarus 0.9.25 beta.

Step 1: Create The Package

  • On the Lazarus IDE menu, click Package > New Package to open the Package Manager. The following image shows the Package Manager
Package Maker
  • Use the Save button at top left.
  • Depending on your 'naming' setting in the 'environment options', the IDE will ask you to save the file lowercase. Say yes.

Congratulations: You have just created your first package!

Step 2: Create The Unit

  • Use the Add button -> New component
  • Choose a component in the ancestor type combobox. For instance: TCustomComboBox.
  • Choose mycom.pas as filename
  • Click Ok
  • The file will be added to the package and opened in the editor. Use something like the following code (The 'Sample' parameter in the RegisterComponents tells the IDE to put the component in a tab called Sample in the components tab)

<delphi> unit mycom;

{$mode objfpc}{$H+}

interface

uses

 Classes, SysUtils, StdCtrls, Forms, lresources;

type

 TMyCom = class (TCustomComboBox)
 private
 public
 end;

procedure Register;

implementation

procedure Register; begin

 RegisterComponents('Sample',[TMyCom]);

end;

initialization

 {$I samplepackage.lrs}

end. </delphi>


  • Install the package by clicking the 'install' button in the top of the package editor.
  • Lazarus will ask to save the package, save the package as samplepackage.lpk. Then the IDE will ask you, if the IDE should be rebuilt. Say yes.
  • The packages are statically linked, so a restart of the IDE is needed.
  • Restart Lazarus and see your new component in the component palette (For example: A TBevel1 will be on the 'Additional' page).
  • If you do not see your new component in the component palette, it is most likely that you are not running the re-compiled version of Lazarus. You can set where Lazarus builds to in: Environment -> Environment options -> Files -> Lazarus directory. Instead of calling lazarus directly, you also can use startlazarus, which starts the newly created lazarus, for example the lazarus executable in the ~/.lazarus directory, if you don't have write access to the directory lazarus was installed into.

Congratulations: You have just installed your first package with your first package component.


Step 2.2: Add an existing Unit

If you already had a unit mycom.pas, you can add it to the package with:

  • Click the Add button, goto the Add Unit tab. At the Unit file name, browse to the mycom.pas file. Click the Add Unit button to confirm. If the packet manager complains that the unit is not in the unitpath, click yes to add the directory to the unit path.
  • Click the Add button again, goto the Add File tab and browse to the samplepackage.lrs file and click Ok.
  • Click the Add button again, goto the New Requirement tab, in the Package name select LCL (as the base class, TCustomComboBox, uses this) and click Ok.

End result should look like this:

Package Maker
  • Click on mycom.pas under the Files tree in the Package Manager. In the File Properties, make sure Register unit is checked.
  • Click the Options button. Select the IDE Integration tab. At the Package Type make sure Designtime and Runtime is selected.
  • Click the Compile button to check to see if the files compile without errors.
  • Click the Install button, Lazarus will rebuild and restart automatically.

The component is created and ready to be used:

Component Created

Step 3: Create Icons For The Package

  • Size of PNG file should be 24x24

To create the lrs file run (where samplepackage is the name of your package and TMyCom is the name of your component):

~/lazarus/tools/lazres samplepackage.lrs TMyCom.png
  • You may need to compile lazres at first use. Simply open the lazres.lpi in the IDE and at the menu click run > build.

You can add more than one image to the lrs file by appending the image filename at the end. Eg. ~/lazarus/tools/lazres samplepackage.lrs TMyCom.png TMyOtherCom.png ...

Following is a sample of the resulting samplepackage.lrs file.

LazarusResources.Add('TMyCom','PNG',[
  #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
  +#0#0#0#4'gAMA'#0#0#177#143#11#252'a'#5#0#0#0'|IDAT8O'#237#212#209#10#192' '#8
  +#5'P'#247#231#251's'#215#138#133#164#166'\'#220#195'`'#209'c'#157'L'#173#131
  +#153#169'd4'#168'dP'#137'r_'#235'5'#136'@Zmk'#16'd9'#144#176#232#164'1'#247
  +'I'#8#160'IL'#206'C'#179#144#12#199#140'.'#134#244#141'~'#168#247#209'S~;'#29
  +'V+'#196#201'^'#10#15#150'?'#255#18#227#206'NZ>42'#181#159#226#144#15'@'#201
  +#148#168'e'#224'7f<@4'#130'u_YD'#23#213#131#134'Q]'#158#188#135#0#0#0#0'IEND'
  +#174'B`'#130
]);

  • Click the Add button again, goto the Add File tab and browse to the samplepackage.lrs file and click Ok.

Recompiling Packages

You need to rebuild the package everytime you make changes to the mycom.pas file. To rebuild the package, open the samplepackage.lpk file in the Package Manager and click the Install button.

Removing Packages

  • To remove installed components, on the IDE menu, click Package > Configure installed packages. The following image shows the Installed Packages tool.
Installed Components
  • Select the package you want to uninstall and click Uninstall selection.

If something goes wrong with a package (eg package directory is deleted without first uninstalling it), Lazarus may not allow you to uninstall packages. To fix the problem, at the IDE menu click Tools > Build Lazarus. Lazarus will rebuild all packages and restart. You should now be able to uninstall problematic packages.

Enhancing mycom.pas

  • The codes in mycom.pas above gives you the basics on what you need to create a component. The following is an enhanced version with some tips on how to write procedures and events for components.
  • The OnChange2 shows how to create events
  • The OnSample shows how to create custom events
  • MyText and MyText2 shows different ways to write properties.
  • You can use TComboBox instead of TCustomComboBox as the base class, which publishes all properties as TComboBox.
  • If TCustomComboBox is used as the base class, you'll notice a lot of properties and events will be missing at the Object Inspector in the IDE. To add those properties and events just copy and paste the properties as listed below // properties from TComboBox. These list of properties can be got from the TComboBox declaration in the StdCtrls unit. Omit any property which you want to handle yourself.

<delphi> unit mycom;

{$mode objfpc}{$H+}

interface

uses

 Classes, SysUtils, StdCtrls, Forms, Dialogs,
 LCLType,LCLIntf,lresources,LCLProc;

type

 TSampleEvent = procedure(MyText: String) of Object;
 TMyCom = class (TCustomComboBox)
 private
   FMyText: String;
   FOnChange2: TNotifyEvent;
   FOnSample: TSampleEvent;
 public
   constructor Create(TheOwner: TComponent); override;
   procedure CreateWnd; override;
   procedure Change; override;
 protected
   function GetMyText2: String;
   procedure SetMyText2(MyText: String);
 published
   property MyText: String read FMyText write FMyText;
   property MyText2: String read GetMyText2 write SetMyText2;
   property OnChange2: TNotifyEvent read FOnChange2 write FOnChange2;
   property OnSample: TSampleEvent read FOnSample write FOnSample;
   
   // properties from TComboBox
   property Align;
   property Anchors;
   property ArrowKeysTraverseList;
   property AutoComplete;
   property AutoCompleteText;
   property AutoDropDown;
   property AutoSelect;
   property AutoSize;
   property BidiMode;
   property BorderSpacing;
   property CharCase;
   property Color;
   property Ctl3D;
   property Constraints;
   property DragCursor;
   property DragMode;
   property DropDownCount;
   property Enabled;
   property Font;
   property ItemHeight;
   property ItemIndex;
   property Items;
   property ItemWidth;
   property MaxLength;
   property OnChange;
   property OnChangeBounds;
   property OnClick;
   property OnCloseUp;
   property OnContextPopup;
   property OnDblClick;
   property OnDragDrop;
   property OnDragOver;
   property OnDrawItem;
   property OnEndDrag;
   property OnDropDown;
   property OnEditingDone;
   property OnEnter;
   property OnExit;
   property OnGetItems;
   property OnKeyDown;
   property OnKeyPress;
   property OnKeyUp;
   property OnMeasureItem;
   property OnMouseDown;
   property OnMouseMove;
   property OnMouseUp;
   property OnStartDrag;
   property OnSelect;
   property OnUTF8KeyPress;
   property ParentBidiMode;
   property ParentColor;
   property ParentCtl3D;
   property ParentFont;
   property ParentShowHint;
   property PopupMenu;
   property ReadOnly;
   property ShowHint;
   property Sorted;
   property Style;
   property TabOrder;
   property TabStop;
   property Text;
   property Visible;    
 end;

procedure Register;

implementation

procedure Register; begin

 RegisterComponents('Sample',[TMyCom]);

end;

constructor TMyCom.Create(TheOwner: TComponent); begin

 inherited Create(TheOwner);
 Self.Style := csDropDownList;

end;

procedure TMyCom.CreateWnd; begin

 inherited CreateWnd;
 Items.Assign(Screen.Fonts);

end;

procedure TMyCom.Change; begin

 inherited;
 if Assigned(FOnChange2) then FOnChange2(Self);
 if Assigned(FOnSample) then FOnSample(FMyText);

end;

function TMyCom.GetMyText2: String; begin

 Result:=FMyText;

end;

procedure TMyCom.SetMyText2(MyText: String); begin

 FMyText:=MyText;

end;

initialization

 {$I samplepackage.lrs}

end. </delphi>

Reference

You can post question regarding this page here

Author

 Original Author