Difference between revisions of "LMD VCL - LMD-Tools FAQ"

From LMD
Jump to: navigation, search
 
(23 intermediate revisions by 3 users not shown)
Line 2: Line 2:
  
 
==General==
 
==General==
===CBuilder SpeedUp===
+
=== C++ Builder Notes ===
<c>
+
* WebPack: If you encounter linker errors like [Linker Error] Unresolved external "InternetCloseHandle" referenced from... Simply add wininet.lib to your project (file can be found in \lib directory of your C++ Builder / BDS / CRS installation).
#include <oleidl.h>
+
* TextPack: When Runtime Packages are used (Project options, "Build with runtime packages"), it must be assured that lmdparse4rt_XX (XX represents the compiler version) is mentioned before the TextPack packages. Otherwise an exception during application start will occur.
HKEY_CURRECTUSER
+
* TLMDHideNonVC: This component has no functionality in LMD-Tools for CBuilder 5 (and higher) and is included for the sake of compatibility only. Please do not use this component in C++  Builder projects.  
SaveSettings
+
* TLMDFormDisplay: The AddForm method of TLMDFormDisplay was renamed to AddFormExt due to naming conflicts with CBuilder routines.
#define NO_WIN32_LEAN_AND_MEAN
 
</c>
 
NO_WIN32_LEAN_AND_MEAN
 
When this macro is defined, VCL.H does not define WIN32_LEAN_AND_MEAN. Default: OFF
 
  
VCL_FULL
+
=== C++Builder: "[dcc32 Error] LMDXML.pas(478): E2134 Type '<void>' has no type info" ===
Same as NO_WIN32_LEAN_AND_MEAN (NOTE: This macro is for BCB v1.0 backward compatibility) Default: OFF
+
Please turn off “Emit runtime type info” in compiler options to make code work.
  
INC_VCLDB_HEADERS
+
=== Packages & Compatibility ===
When this macro is defined, VCL.H includes the core Database headers of VCL.
+
==== Compatibility Components are not installed by default! ====
(Defining this macro is functionally equivalent to including VCLDB.H) Default: OFF
+
User who you used the older components of version 1/3 in their projects (e.g. the ones from the LMD Free tab) must explicitly mark the corresponding check box in the installation options to install the LMD-Tools compatibility components.<br>
 
+
<b>Please note:</b><br> No components were left out, they're all still available (and will be available in the future). However we want to avoid that new user use these controls because they will not be improved in the future (because they're replaced by improved controls).
INC_ALLVCL_HEADERS When this macro is defined, VCL.H includes all VCL headers.
 
(Defining this macro is functionally equivalent to including VCLMAX.H) Default: OFF
 
 
 
===Installation===
 
====Installing Source Version (Release 7)====
 
Make sure to install first the CE special packages (DesignPack, BarPack and StoragePack) and at last LMD-Tools Core Package (oldest to latest package).  I strongly suggest to install all to the same installation path. Make sure that the source path is available in Library path settings and is  in best case the first path mentioned. Then load the <br>
 
__lmd2003all_d5.bpg
 
project group. <br>
 
This project group contains all package files in the order we suggest to install them. Ignore if e.g. dcllmdold.dpk is not found (or CE packages if you did not install them). However the most important point is, that dcllmdshared_d5 is the first package to be compiled. As a rule: lmd*.bpl are runtime packages, dcllmd*.bpl packages are designtime packages. Only for designtime packages press "Install" button.
 
The compiler will place all new packages into your projects\bpl folder, so I suggest you remove runtime packages from previous installation. <br>
 
Do not use "Build ALL" command, because this feature is buggy in D5.  If any further problems occur please let me know.<br>
 
 
 
====Version Mix Up====
 
if Delphi claims that it can't find a file (though DCUs are available and Library Path is set correctly - see Environment Options), there can be only possible cause for the problem: There is a version mix up.
 
For the offending files please check whether a previous version was completely uninstalled, that no parts are compiled into existing packages (e.g. your personal packages, you might have to rebuild the package), that your project was REBUILD (to force the compilation of latest PAS/DCU files). Furthermore the project files may have references to older package files (especially if you use runtime packages, simply check Package settings in Project Options.
 
 
 
===="Entry Point not found" (Release 6)====
 
Each time you receive "Entry Point not found" or "Could not find [..]" error, you can be sure that it is caused by a version mix up. I guess somehow you did not uninstall a previous version completely. E.g. if you compiled sourcecode, Delphi places created runtime BPL's automatically into the default BPL output path
 
(can be set in Environment Options dialog). Older version may have installed them in System directory - so there is the possible version conflict.
 
To completely remove an old LMD-Tools version (the hard way):
 
* Close Delphi (Note: Be sure that you did not include any LMD-Tools units in own packages, otherwise
 
open these packages, remove LMD-Tools units and recompile them).
 
** Use all uninstallers for previous version
 
** Delete all LMD-Tools directoies
 
** Delete all LMD-Tools path settings from Extras|Environment Options|Tab Library
 
** Now most important point: Search your harddisk (at least in your system directory
 
and the Delphi Projects\BPL path) for LMD BPLs.
 
* Use as search string lmd*.bpl for runtime packages.
 
* Use as search string dcllmd*.bpl for designtime packages.
 
* Remove them all
 
To install LMD-Tools sourcecode:
 
* Use the LMD-Tools 6 source installer
 
* After installation check whether paths to LMD-Tools Source files are correctly set. If for any reason not, add them yourself
 
* We have extremly simplified source compilation. Load the correct project group (e.g. lmdtools_d6.bpg for Delphi 6). and compile one package after another. Install only Desigtime packages (dcllmd*.bpk). All compiled packages can be found after compilation in the Projects\BPL path of your Delphi version.
 
Note: Simply ignore errors for RichPack and ShellPack project files, both packages are not included in current release and will be available in the next days.<br>
 
<br>
 
To install LMD-Tools default packages:
 
Run the correct installer. The only issues which could go wrong are:
 
* Paths are not updated: Solution is to add paths manually
 
* Packages are not seen in Delphi: Add dcl*.bpl packages manually from the Install Packages dialog.
 
  
 +
==== ToolBar97 components ====
 +
The <b>registered</b> VCL Win32 versions of LMD-Tools include a license for the Toolbar97 components. Please note that no precompiled packages are installed during installation, simply install the DPK if you want to use the ToolBar97 components. The ToolBar97 units can be found in the \lib\toolb97 folder. Documentation can be found in HTML format in the \help folder.
  
 
==LMD-Tools==
 
==LMD-Tools==
Line 65: Line 23:
 
==== Pasting components from ClipBoard not possible ====
 
==== Pasting components from ClipBoard not possible ====
 
Because of a glitch with inner controls pasting components from clipboard onto TLMDCaptionPanel components is not possible (controls will be simply not visible). However there is a simple workaround.  
 
Because of a glitch with inner controls pasting components from clipboard onto TLMDCaptionPanel components is not possible (controls will be simply not visible). However there is a simple workaround.  
In context menu of form select “View as Text” and move the object data within the PanelClient object of TLMDCaptionPanel directly in DFM code. Example:<br>
+
In context menu of form select "View as Text" and move the object data within the PanelClient object of TLMDCaptionPanel directly in DFM code. Example:<br>
  
 
[1] This is an empty TLMDCaptionPanel
 
[1] This is an empty TLMDCaptionPanel
<delphi>
+
<syntaxhighlight lang="delphi">
 
   object LMDCaptionPanel1: TLMDCaptionPanel
 
   object LMDCaptionPanel1: TLMDCaptionPanel
 
     Left = 304
 
     Left = 304
Line 80: Line 38:
 
     end
 
     end
 
   end
 
   end
</delphi><br>
+
</syntaxhighlight><br>
[2] Move component data between “object TLMDCaptionPanelClient” and “end”, e.g.
+
[2] Move component data between "object TLMDCaptionPanelClient" and "end", e.g.
<delphi>
+
<syntaxhighlight lang="delphi">
 
   object LMDCaptionPanel1: TLMDCaptionPanel
 
   object LMDCaptionPanel1: TLMDCaptionPanel
 
     Left = 304
 
     Left = 304
Line 102: Line 60:
 
     end
 
     end
 
   end
 
   end
</delphi>
+
</syntaxhighlight>
  
 
=== TLMDFormDisplay ===
 
=== TLMDFormDisplay ===
Line 108: Line 66:
 
To access controls on forms displayed in a TLMDFormDisplay component you have to typecast the active form. E.g. to access an Edit control on a form called TMyForm called Edit1, you have to typecast to:
 
To access controls on forms displayed in a TLMDFormDisplay component you have to typecast the active form. E.g. to access an Edit control on a form called TMyForm called Edit1, you have to typecast to:
  
<delphi>TMyForm(MyFormDisplay.ActiveForm).Edit1.Text:='SampleText';</delphi>
+
<syntaxhighlight lang="delphi">TMyForm(MyFormDisplay.ActiveForm).Edit1.Text:='SampleText';</syntaxhighlight>
 
<br>
 
<br>
 
<b>Reason</b><br>
 
<b>Reason</b><br>
Line 120: Line 78:
 
To mimic TLMDOneInstance without using the control: In the project source file add LMDClass unit to uses clause and check LMDApplication.IsPrevRunning property before any form is loaded (this global property tells you, whether a previous instance is running). If yes, simple exit the application and call LMDActivatePrevInstance method from LMDUtils.pas to activate the already running instance.  
 
To mimic TLMDOneInstance without using the control: In the project source file add LMDClass unit to uses clause and check LMDApplication.IsPrevRunning property before any form is loaded (this global property tells you, whether a previous instance is running). If yes, simple exit the application and call LMDActivatePrevInstance method from LMDUtils.pas to activate the already running instance.  
 
To explicitely allow restart simply use a command line parameter, so that test for previous instance is skipped when command line parameter is set.
 
To explicitely allow restart simply use a command line parameter, so that test for previous instance is skipped when command line parameter is set.
 +
 +
=== TLMDTrayIcon ===
 +
==== Starting a trayicon application in hidden state ====
 +
The TrayIcon demo from version LMD-Tools 8.10 on (check <b>lmdtools\Other\LMD Sys\LMDTrayIcon</b> in demos folder) demonstrates this feature (trayicon in taskbar is visible only). To achieve this feature, the project sourcecode must be altered as follows:
 +
<br><br>
 +
<b>Before Delphi/CRS 2007</b>
 +
<syntaxhighlight lang="delphi">
 +
begin
 +
  Application.Initialize;
 +
  Application.Title := 'Traytool 1.0';
 +
  Application.ShowMainForm := false;
 +
  Application.CreateForm(TForm1, Form1);
 +
  Application.Run;
 +
end.
 +
</syntaxhighlight><br>
 +
<b>Delphi/CRS 2007 and higher</b>
 +
<syntaxhighlight lang="delphi">
 +
begin
 +
  Application.Initialize;
 +
  Application.Title := 'Traytool 1.0';
 +
  if LMDSIWindowsVistaUp then
 +
    Application.MainFormOnTaskBar := true;  // not required, but supported since 8.10 (--> Aero Glass)
 +
  Application.ShowMainForm := false;
 +
  Application.CreateForm(TForm1, Form1);
 +
  Form1.trayicon.HideApplication;
 +
  Application.Run;
 +
end.
 +
</syntaxhighlight>
 +
Recent Delphi releases require additional code (caused by correct Vista support and the new MainFormOnTaskBar feature).
 +
=== Container Controls ===
 +
==== How to use TLMDStringStringList component correctly? How to add / remove items at runtime? ====
 +
Against the VCL TStrings or TStringList objects the TLMDStringList class is a container for ANY number of TStrings objects. Component does not hold TStrings directly, but TLMDStringListItem objects which provide an Items property for the internal TStringlist object (use this Items property to get access to all properties and methods of the known TStringList oject).<br>
 +
As follows examples for working with TLMDStringList component. To add a new item to the TLMDStringList class write e.g.:
 +
<syntaxhighlight lang="delphi">myIndex:=LMDStringList1.Add(nil); // now you have created a new item with Index myIndex (--> declare as Integer).</syntaxhighlight>
 +
The new created type is a TLMDStringListItem class, which CONTAINS a TStringList object as Items property.
 +
Use this Items property as you would use a TStrings or TStringlist object. To assign e.g. a TStringlist object write:
 +
<syntaxhighlight lang="delphi">
 +
LMDStringList1.Items[myIndex].Items.Assign(myExternalVCLStringList);// or alternatively write
 +
LMDStringList1.Items[myIndex].Items:=myExternalVCLStringList;
 +
</syntaxhighlight>
 +
Because TLMDStringListItems array is default array you could also write
 +
<syntaxhighlight lang="delphi">LMDStringList1[myIndex].Items:=myExternalVCLStringList;</syntaxhighlight>
 +
Knowing this you should be able to access single lines or a full stringlist, one example from the helpfile:
 +
<syntaxhighlight lang="delphi">
 +
MyLabel.Caption:=LMDStringList1[myIndex].Items[5];
 +
</syntaxhighlight>
 +
This line would assign the 6th line of your recently created stringlist to the Caption property of MyLabel. Other examples:
 +
<syntaxhighlight lang="delphi">
 +
LMDStringList1[myIndex].Items.Add('New String'); // Adds new string to the StringList with ID 'myindex'
 +
LMDStringList1[myIndex].Items.Delete(3); // Deletes string with index 3 from StringList with ID 'myindex'
 +
</syntaxhighlight>
 +
TLMDStringList can handle many TLMDStringListItem objects. Using the .Add method as above you can add as many items as you like. To delete an item from the TLMDStringList class use the .Delete method. To delete the TLMDStringList object itself use
 +
<syntaxhighlight lang="delphi">
 +
LMDStringList1.Delete(myIndex);
 +
</syntaxhighlight>
 +
To insert a new item at a specific position (here at index 2) use e.g.
 +
<syntaxhighlight lang="delphi">myIndex:=LMDStringList1.Insert(2, nil);</syntaxhighlight>
 +
Check the helpfile or use Code Completion in editor for other standard methods (like Move, LoadFromFile, SaveToFile etc.). Major advantage of using TLMDStringList is saving of large number of text snippets in one component and possibility to compress large large text snippets.
 +
  
 
=== Dialog Controls ===
 
=== Dialog Controls ===
 +
 
==== Using OnCustomize event in native LMD Dialog controls ====
 
==== Using OnCustomize event in native LMD Dialog controls ====
<delphi>
+
<syntaxhighlight lang="delphi">procedure TForm1.dCustomize(Sender: TObject);
procedure TForm1.dCustomize(Sender: TObject);
 
 
var
 
var
 
i:Integer;
 
i:Integer;
 
begin
 
begin
 
with TForm(Sender) do
 
with TForm(Sender) do
for i:=0 to ComponentCount-1 do
+
for i:=0 to ComponentCount-1 do
if (Components[i] is TLMDButton) and (TLMDButton(Components[i]).Caption='&New Folder') then
+
if (Components[i] is TLMDButton) and (TLMDButton(Components[i]).Caption='&amp;New Folder') then
TLMDButton(Components[i]).Caption:='MyString';
+
TLMDButton(Components[i]).Caption:='MyString';
end;
+
end;</syntaxhighlight>
</delphi>
+
 
 +
=== Some notes on Unicode issues ===
 +
 
 +
Since release 10.05 unicode support was added in LMD Tools. Since that moment labels, buttons, edit controls of LMD Tools could display/edit unicode text. The main change were made to LMDGraphUtils, where two methods were changed: LMDDrawTextExt and LMDDrawTextCalcExt. Before release 10.05 they used DrawTextEx only; since release 10.05 they use DrawTextExW if LMD_UNICODE switch is defined.
 +
 
 +
This caused a side effect: some applications that worked correctly in ANSI version (those that used non-latin charsets), do not work if LMD_UNICODE is defined, e.g. following code resulted incorrect captions:
 +
<syntaxhighlight lang="delphi">LMDButton1.Font.Charset:=ARABIC_CHARSET;
 +
LMDButton1.Caption&nbsp;:= #NN#NN#NN#NN; //#NN are some byte values - codes of symbols</syntaxhighlight>
 +
In release 10.10 we added ForceANSI property in TLMDApplication class. Setting this property to true enforces calling ANSI version of DrawTextEx in LMD Tools text drawing routines even if LMD_UNICODE switch is defined.
 +
 
 +
This allows to use ANSI in LMD Tools and UNICODE in ElPack at the same time.
 +
 
 +
'''Note:''' For Delphi 2009 and upper versions, LMD_UNICODE is always defined.
 +
 
 +
=== Some notes on using DB-aware controls ===
 +
 
 +
==== LMDDBSpinEdit and LMDDBExtSpinEdit: MinValue and MaxValue issues ====
 +
 
 +
In 10.14 release TLMDDBSpinEdit and TLMDDBExtSpinEdit received two new boolean properties: UseDBMinMax and  UseZeroLogic. Both are set to true by default for compatibility. These flags were introduced because of some peculiarities of using MinValue and MaxValue in db-aware spin edits.
 +
 
 +
The help topic on TIntegerField states:
 +
 
 +
<pre>
 +
If the value of MaxValue is 0, the integer field can have a value up to the maximum value that can be represented by the native database type.
 +
...
 +
If the value of MinValue is 0, the integer field can have a value as small as the native database type can represent.
 +
</pre>
 +
 
 +
This logic has immanent drawback which causes usage of some intervals impossible: e.g. we cannot use [0, N], or [-N, 0] intervals, because zeros removes the constraint.
 +
Another issue is that MinValue and MaxValue not always can be read from database field definitions.
 +
 
 +
If UseDBMinMax is set to true, then MinValue and MaxValue properties are overriden from field properties. Otherwise, they will have values set by programmer in designtime or runtime.
 +
 
 +
If UseZeroLogic is set to true, then zeros remove constraints, allowing maximum positive value if MaxValue = 0, and minimum negative value if MinValue = 0.  If UseZeroLogic is false, then MinValue = 0 means that no negative values are allowed and, respectively, MaxValue = 0 means that no positive values are allowed. When UseZeroLogic is false, programmer can use boolean flags InfiniteMin and InfiniteMax to remove min-max constraints.
 +
 
 +
=== ListIndex vs. ImageIndex property ===
 +
 
 +
Since LMD Tools 2012.1, ImageIndex property is used instead of ListIndex in TLMDBaseGraphicButton to define image taken from imagelist.
 +
 
 +
This is made to make usage of two-dimensional imagelists consistent with one-dimensional imagelists.
 +
 
 +
If you want to force former use of ListIndex in TLMDBaseGraphicButton, locate {.$DEFINE LMD_FORCELISTINDEXUSE} entry in lmdcmps.inc file and remove dot. In this case ListIndex will be used to define image index in one-dimensional imagelists like TLMDBitmapList, TLMDGraphicList etc, like it was in versions prior to LMD Tools 2012.1.
 +
 
 +
== LMD TextPack ==
 +
 
 +
==== Using embedded controls in LMDTextPanel ====
 +
 
 +
'''Question'''<br>
 +
 
 +
I use html parser in LMDTextPanel control. The text is an HTML code like that<br>
 +
 
 +
<syntaxhighlight lang="html">
 +
<control vclclass=TButton name="b1" Caption="Hello" width="50" height="50"><BR>
 +
<control vclclass=TLMDEdit name="e1" width="100" height="20"><BR>
 +
</syntaxhighlight>
 +
 
 +
Why the embedded TLMDEdit control is now shown in runtime?<br>
 +
 
 +
'''Answer'''<br>
 +
 
 +
You can use TEdit, TButton, TCheckBox, TRadioButton as embedded controls without any additional code, because these classes are automatically registered in constructor TLMDEmbdControl.Create.<br>
 +
 
 +
However, you can use any other control TSomeControl provided that RegisterClass(TSomeControl) was called prior to html parsing.<br>
 +
 
 +
For example, your code will work fine if you add LMDEdit to uses clause and code RegisterClass(TLMDEdit) in FormCreate.<br>
 +
 
 +
Note for C++ Builder users:
 +
 
 +
    Use RegisterClass('''__classid'''(TLMDEdit))
 +
 
 +
instead of
  
===Help Index problems until Delphi 7===
+
    RegisterClass(TLMDEdit).
Itsa actually a limitation of WinHelp and the amount of Indexes it can deal with. Go over the limit and the index part of WinHelp just packs up and goes home. The only solution is to open OpenHelp and remove a few indexes from the index tab until you get under the WinHelp threshold.
 

Latest revision as of 14:08, 18 August 2017

[edit]

<< Back to Overview page

General

C++ Builder Notes

  • WebPack: If you encounter linker errors like [Linker Error] Unresolved external "InternetCloseHandle" referenced from... Simply add wininet.lib to your project (file can be found in \lib directory of your C++ Builder / BDS / CRS installation).
  • TextPack: When Runtime Packages are used (Project options, "Build with runtime packages"), it must be assured that lmdparse4rt_XX (XX represents the compiler version) is mentioned before the TextPack packages. Otherwise an exception during application start will occur.
  • TLMDHideNonVC: This component has no functionality in LMD-Tools for CBuilder 5 (and higher) and is included for the sake of compatibility only. Please do not use this component in C++ Builder projects.
  • TLMDFormDisplay: The AddForm method of TLMDFormDisplay was renamed to AddFormExt due to naming conflicts with CBuilder routines.

C++Builder: "[dcc32 Error] LMDXML.pas(478): E2134 Type '<void>' has no type info"

Please turn off “Emit runtime type info” in compiler options to make code work.

Packages & Compatibility

Compatibility Components are not installed by default!

User who you used the older components of version 1/3 in their projects (e.g. the ones from the LMD Free tab) must explicitly mark the corresponding check box in the installation options to install the LMD-Tools compatibility components.
Please note:
No components were left out, they're all still available (and will be available in the future). However we want to avoid that new user use these controls because they will not be improved in the future (because they're replaced by improved controls).

ToolBar97 components

The registered VCL Win32 versions of LMD-Tools include a license for the Toolbar97 components. Please note that no precompiled packages are installed during installation, simply install the DPK if you want to use the ToolBar97 components. The ToolBar97 units can be found in the \lib\toolb97 folder. Documentation can be found in HTML format in the \help folder.

LMD-Tools

TLMDCaptionPanel (-Group)

Pasting components from ClipBoard not possible

Because of a glitch with inner controls pasting components from clipboard onto TLMDCaptionPanel components is not possible (controls will be simply not visible). However there is a simple workaround. In context menu of form select "View as Text" and move the object data within the PanelClient object of TLMDCaptionPanel directly in DFM code. Example:

[1] This is an empty TLMDCaptionPanel

  object LMDCaptionPanel1: TLMDCaptionPanel
    Left = 304
    Top = 144
    Width = 193
    Height = 121
    Bevel.Mode = bmStandard
    Bevel.StandardStyle = lsWindowBorder
    TabOrder = 0
    object TLMDCaptionPanelClient
    end
  end

[2] Move component data between "object TLMDCaptionPanelClient" and "end", e.g.

  object LMDCaptionPanel1: TLMDCaptionPanel
    Left = 304
    Top = 144
    Width = 193
    Height = 121
    Bevel.Mode = bmStandard
    Bevel.StandardStyle = lsWindowBorder
    TabOrder = 0
    object TLMDCaptionPanelClient
      object Button1: TButton
        Left = 80
        Top = 40
        Width = 75
        Height = 25
        Caption = 'Button1'
        TabOrder = 0
      end
    end
  end

TLMDFormDisplay

How to access specific controls on displayed forms?

To access controls on forms displayed in a TLMDFormDisplay component you have to typecast the active form. E.g. to access an Edit control on a form called TMyForm called Edit1, you have to typecast to:

TMyForm(MyFormDisplay.ActiveForm).Edit1.Text:='SampleText';


Reason
The Internal Forms array or ActiveForm property use the abstract TCustomForm class. This fact allows you to add any form which is derived from TCustomForm to the TLMDFormDisplay component. The side effect is however, that TLMDFormDisplay control does not know of any special features which are available for a specific descendant (thus typecasting to desired form type is required).

TLMDOneInstance

Flickering of main window when second instance is started.

There are two ways to workaround this:

  • You create a small separate application which has nothing else to do except closing the current instance and restarting it..
  • You do not use the component but internal functions of LMD-Tools (more complex, but elegant).

To mimic TLMDOneInstance without using the control: In the project source file add LMDClass unit to uses clause and check LMDApplication.IsPrevRunning property before any form is loaded (this global property tells you, whether a previous instance is running). If yes, simple exit the application and call LMDActivatePrevInstance method from LMDUtils.pas to activate the already running instance. To explicitely allow restart simply use a command line parameter, so that test for previous instance is skipped when command line parameter is set.

TLMDTrayIcon

Starting a trayicon application in hidden state

The TrayIcon demo from version LMD-Tools 8.10 on (check lmdtools\Other\LMD Sys\LMDTrayIcon in demos folder) demonstrates this feature (trayicon in taskbar is visible only). To achieve this feature, the project sourcecode must be altered as follows:

Before Delphi/CRS 2007

begin
  Application.Initialize;
  Application.Title := 'Traytool 1.0';
  Application.ShowMainForm := false;
  Application.CreateForm(TForm1, Form1);
  Application.Run;
end.

Delphi/CRS 2007 and higher

begin
  Application.Initialize;
  Application.Title := 'Traytool 1.0';
  if LMDSIWindowsVistaUp then
    Application.MainFormOnTaskBar := true;  // not required, but supported since 8.10 (--> Aero Glass)
  Application.ShowMainForm := false;
  Application.CreateForm(TForm1, Form1);
  Form1.trayicon.HideApplication;
  Application.Run;
end.

Recent Delphi releases require additional code (caused by correct Vista support and the new MainFormOnTaskBar feature).

Container Controls

How to use TLMDStringStringList component correctly? How to add / remove items at runtime?

Against the VCL TStrings or TStringList objects the TLMDStringList class is a container for ANY number of TStrings objects. Component does not hold TStrings directly, but TLMDStringListItem objects which provide an Items property for the internal TStringlist object (use this Items property to get access to all properties and methods of the known TStringList oject).
As follows examples for working with TLMDStringList component. To add a new item to the TLMDStringList class write e.g.:

myIndex:=LMDStringList1.Add(nil); // now you have created a new item with Index myIndex (--> declare as Integer).

The new created type is a TLMDStringListItem class, which CONTAINS a TStringList object as Items property. Use this Items property as you would use a TStrings or TStringlist object. To assign e.g. a TStringlist object write:

LMDStringList1.Items[myIndex].Items.Assign(myExternalVCLStringList);// or alternatively write
LMDStringList1.Items[myIndex].Items:=myExternalVCLStringList;

Because TLMDStringListItems array is default array you could also write

LMDStringList1[myIndex].Items:=myExternalVCLStringList;

Knowing this you should be able to access single lines or a full stringlist, one example from the helpfile:

MyLabel.Caption:=LMDStringList1[myIndex].Items[5];

This line would assign the 6th line of your recently created stringlist to the Caption property of MyLabel. Other examples:

LMDStringList1[myIndex].Items.Add('New String'); // Adds new string to the StringList with ID 'myindex'
LMDStringList1[myIndex].Items.Delete(3); // Deletes string with index 3 from StringList with ID 'myindex'

TLMDStringList can handle many TLMDStringListItem objects. Using the .Add method as above you can add as many items as you like. To delete an item from the TLMDStringList class use the .Delete method. To delete the TLMDStringList object itself use

LMDStringList1.Delete(myIndex);

To insert a new item at a specific position (here at index 2) use e.g.

myIndex:=LMDStringList1.Insert(2, nil);

Check the helpfile or use Code Completion in editor for other standard methods (like Move, LoadFromFile, SaveToFile etc.). Major advantage of using TLMDStringList is saving of large number of text snippets in one component and possibility to compress large large text snippets.


Dialog Controls

Using OnCustomize event in native LMD Dialog controls

procedure TForm1.dCustomize(Sender: TObject);
var
i:Integer;
begin
with TForm(Sender) do
 for i:=0 to ComponentCount-1 do
 if (Components[i] is TLMDButton) and (TLMDButton(Components[i]).Caption='&amp;New Folder') then
 TLMDButton(Components[i]).Caption:='MyString';
end;

Some notes on Unicode issues

Since release 10.05 unicode support was added in LMD Tools. Since that moment labels, buttons, edit controls of LMD Tools could display/edit unicode text. The main change were made to LMDGraphUtils, where two methods were changed: LMDDrawTextExt and LMDDrawTextCalcExt. Before release 10.05 they used DrawTextEx only; since release 10.05 they use DrawTextExW if LMD_UNICODE switch is defined.

This caused a side effect: some applications that worked correctly in ANSI version (those that used non-latin charsets), do not work if LMD_UNICODE is defined, e.g. following code resulted incorrect captions:

LMDButton1.Font.Charset:=ARABIC_CHARSET;
 LMDButton1.Caption&nbsp;:= #NN#NN#NN#NN; //#NN are some byte values - codes of symbols

In release 10.10 we added ForceANSI property in TLMDApplication class. Setting this property to true enforces calling ANSI version of DrawTextEx in LMD Tools text drawing routines even if LMD_UNICODE switch is defined.

This allows to use ANSI in LMD Tools and UNICODE in ElPack at the same time.

Note: For Delphi 2009 and upper versions, LMD_UNICODE is always defined.

Some notes on using DB-aware controls

LMDDBSpinEdit and LMDDBExtSpinEdit: MinValue and MaxValue issues

In 10.14 release TLMDDBSpinEdit and TLMDDBExtSpinEdit received two new boolean properties: UseDBMinMax and UseZeroLogic. Both are set to true by default for compatibility. These flags were introduced because of some peculiarities of using MinValue and MaxValue in db-aware spin edits.

The help topic on TIntegerField states:

If the value of MaxValue is 0, the integer field can have a value up to the maximum value that can be represented by the native database type.
...
If the value of MinValue is 0, the integer field can have a value as small as the native database type can represent.

This logic has immanent drawback which causes usage of some intervals impossible: e.g. we cannot use [0, N], or [-N, 0] intervals, because zeros removes the constraint. Another issue is that MinValue and MaxValue not always can be read from database field definitions.

If UseDBMinMax is set to true, then MinValue and MaxValue properties are overriden from field properties. Otherwise, they will have values set by programmer in designtime or runtime.

If UseZeroLogic is set to true, then zeros remove constraints, allowing maximum positive value if MaxValue = 0, and minimum negative value if MinValue = 0. If UseZeroLogic is false, then MinValue = 0 means that no negative values are allowed and, respectively, MaxValue = 0 means that no positive values are allowed. When UseZeroLogic is false, programmer can use boolean flags InfiniteMin and InfiniteMax to remove min-max constraints.

ListIndex vs. ImageIndex property

Since LMD Tools 2012.1, ImageIndex property is used instead of ListIndex in TLMDBaseGraphicButton to define image taken from imagelist.

This is made to make usage of two-dimensional imagelists consistent with one-dimensional imagelists.

If you want to force former use of ListIndex in TLMDBaseGraphicButton, locate {.$DEFINE LMD_FORCELISTINDEXUSE} entry in lmdcmps.inc file and remove dot. In this case ListIndex will be used to define image index in one-dimensional imagelists like TLMDBitmapList, TLMDGraphicList etc, like it was in versions prior to LMD Tools 2012.1.

LMD TextPack

Using embedded controls in LMDTextPanel

Question

I use html parser in LMDTextPanel control. The text is an HTML code like that

<control vclclass=TButton name="b1" Caption="Hello" width="50" height="50"><BR> 
<control vclclass=TLMDEdit name="e1" width="100" height="20"><BR>

Why the embedded TLMDEdit control is now shown in runtime?

Answer

You can use TEdit, TButton, TCheckBox, TRadioButton as embedded controls without any additional code, because these classes are automatically registered in constructor TLMDEmbdControl.Create.

However, you can use any other control TSomeControl provided that RegisterClass(TSomeControl) was called prior to html parsing.

For example, your code will work fine if you add LMDEdit to uses clause and code RegisterClass(TLMDEdit) in FormCreate.

Note for C++ Builder users:

   Use RegisterClass(__classid(TLMDEdit)) 

instead of

   RegisterClass(TLMDEdit).