Recent

Author Topic: Implementation of IDropTarget  (Read 7142 times)

antekgla

  • New Member
  • *
  • Posts: 22
Implementation of IDropTarget
« on: September 21, 2017, 11:39:19 pm »
Hi!
I have a application to process files with a Memo with filenames what support Drag and Drop of files thru OnDropFiles method and works fine.

I want now to add a item to right click of any file or folder in Windows Explorer to add the files/s or folder/s names to the Memo.

I tried with Registry manipulation. and works but they have several limitations.
The main limitation is the max of 15 files until my new entry dissapears from right click menu.
I know what with MultipleInvokePromptMinimum key in registry I can stretch that limit to 100 files, but it is not enough for my application.

So I read what the best way to achieve this is implement IDropTarget and make a
shell\open\DropTarget branch in the registry for my application.

I read http://wiki.freepascal.org/Drag_and_Drop_sample but dont apply to filenames in the explorer, only text from another controls or applications.

Anyone could give an advice in how achieve this?

Thanks in advance.
« Last Edit: September 22, 2017, 04:37:47 pm by antekgla »

jamie

  • Hero Member
  • *****
  • Posts: 6091
Re: Implementation of IDropTarget
« Reply #1 on: September 22, 2017, 11:49:17 pm »
why can't you use one of the Dialogs or shell Dialog that already exist in laz?

 That way you keep it local to your app and it'll also work cross platform.
The only true wisdom is knowing you know nothing

antekgla

  • New Member
  • *
  • Posts: 22
Re: Implementation of IDropTarget
« Reply #2 on: September 23, 2017, 12:53:02 am »
why can't you use one of the Dialogs or shell Dialog that already exist in laz?

 That way you keep it local to your app and it'll also work cross platform.

I dont know what you are refering.
What dialogs?

I am to try to launch my application from Windows Explorer thru a right click on file/s or folder/s and pass this files/folder names to my application.

molly

  • Hero Member
  • *****
  • Posts: 2330
Re: Implementation of IDropTarget
« Reply #3 on: September 23, 2017, 02:46:10 am »
afaik:
Code: [Select]
var
  i : integer;
begin
  for i := 1 to ParamCount
      do Memo.Lines.Add(ParamStr(i));
end;

But, that requires some additional work when your application is already running. Think IPC/OneInstance.

taazz

  • Hero Member
  • *****
  • Posts: 5368
Re: Implementation of IDropTarget
« Reply #4 on: September 23, 2017, 03:55:58 am »
1) a complete drag and drop suit can be downloaded from http://melander.dk/delphi/dragdrop/ .It is written for delphi but it should be dead easy to port to fpc for windows.
2) An other (a bit old and probably deprecated) way is to use DDE to communicate with the OS, I can testify that DDE worked for me for windows 7 32bit, I haven't tried it on 64bit. For this to work you will need to download
a)the DDE Components v.2.0 by Konrad Baechler https://torry.net/pages.php?id=230 direct link https://torry.net/vcl/system/dde/kbdde.zip
b)Peter Below's excellent demo which I can not find online at the moment so I'm posting the code here from my library.
c) Use * at the registry for all files I guess.
Code: Pascal  [Select][+][-]
  1. //> 1) How do I programmatically set file associations so when a person double
  2. //> clicks it will open my application?
  3. //>
  4. //> 2) Once a file association is set, when double clicking, if my app is already
  5. //> open, a second instance is opened. How do I prevent a second instance from
  6. //> opening (I can do this with the "lonely" component) yet STILL have the existing
  7. //> app that is opened get a message to process the file that is double clicked?
  8. //
  9. //These two questions are connected, you need to create a number of keys in the
  10. //registry and make your application a DDE server. Since this question comes up
  11. //regularly i have created a sample application to show the steps involved. The app
  12. //registers itself when started but you can move that part to an installation
  13. //program, of course.
  14.  
  15. //Apologies to any lurkers for the size of this message, but i think in this case
  16. //well commented code is more important than a small message size.
  17.  
  18. {+------------------------------------------------------------
  19.  | Unit FileAssociation_Demo1
  20.  |
  21.  | Version: 1.0  Created: 14.03.99
  22.  |               Last Modified: 14.03.99
  23.  | Environment : Delphi 4.02, tested on Win95B
  24.  | Author : P. Below
  25.  | Project: Sample applications
  26.  | Description:
  27.  |   This is a simple demo application that shows how to register
  28.  |   an application as server for a file extension (.TED in this
  29.  |   case) and how to use DDE to open files from Explorer in
  30.  |   an existing instance of the program.
  31.  |   A file association requires, at minimum, the following keys
  32.  |   in the registry under HKEY_CLASSES_ROOT (HKCR):
  33.  |
  34.  |   HKCR\<extension> = <filetype>
  35.  |   HKCR\<filetype>  = <description>
  36.  |   HKCR\<filetype>\shell\open\command = <application> "%1"
  37.  |
  38.  |   "open" is one of the standard verbs, others that may be used
  39.  |   are "edit", "print", and "printto". If all verbs are implemented
  40.  |   by the same application command line switches may be used
  41.  |   to differentiate the action to take in the command key string.
  42.  |   See the entry for HKCR\rtffile in regedit.exe for an example.
  43.  |
  44.  |   If only the three keys above are present Explorer will open
  45.  |   a new instance of the application for each file. To get it to
  46.  |   use an existing instance one needs to make the application into
  47.  |   a DDE server and add some more keys to the registry:
  48.  |
  49.  |   HKCR\<filetype>\shell\open\ddeexec = <macrostring>
  50.  |   HKCR\<filetype>\shell\open\ddeexec\topic = <topicname>
  51.  |   HKCR\<filetype>\shell\open\ddeexec\application = <DDE Servername>
  52.  |
  53.  |   If a TDDEServerConv object is used to implement the DDE server
  54.  |   then <topicname> is the name of the TDDEServerConv component
  55.  |   and <DDE Servername> is the applications filename, without
  56.  |   path and extension.
  57.  |
  58.  |   To test this application copy a number of textfiles (e.g. PAS
  59.  |   files) to extension TED and open them in Explorer. Note that
  60.  |   you have to run the application once manually to get it to
  61.  |   register itself.
  62.  +------------------------------------------------------------}
  63. Unit Fileassociation_demo1;
  64.  
  65. Interface
  66.  
  67. Uses
  68.   Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
  69.   StdCtrls, DdeMan, ComCtrls;
  70.  
  71. Type
  72.   TForm1 = Class(TForm)
  73.     TEDDdeServer: TDdeServerConv;
  74.     PageControl1: TPageControl;
  75.     Procedure FormCreate(Sender: TObject);
  76.     Procedure TEDDdeServerExecuteMacro(Sender: TObject; Msg: TStrings);
  77.   Private
  78.     Procedure RegisterAssociation;
  79.     Procedure AddFileeditor(Const filename: String);
  80.     { Private declarations }
  81.   Public
  82.     { Public declarations }
  83.   End;
  84.  
  85. Var
  86.   Form1: TForm1;
  87.  
  88. Implementation
  89.  
  90. Uses Registry, ShlObj;
  91. {$R *.DFM}
  92.  
  93. Type
  94.   ERegistryError = Class( Exception );
  95. ResourceString
  96.   eCannotCreateKey =
  97.     'Cannot create key %s, the user account may not have the required '+
  98.     'rights to create registry keys under HKEY_CLASSES_ROOT.';
  99.  
  100. {+------------------------------------------------------------
  101.  | Procedure CreateKey
  102.  |
  103.  | Description:
  104.  |   This is a helper routine which uses the passed reg object
  105.  |   to create a registry key.
  106.  | Error Conditions:
  107.  |   If the key cannot be created a ERegistryError exception is
  108.  |   raised.
  109.  | Created: 14.03.99 by P. Below
  110.  +------------------------------------------------------------}
  111. Procedure CreateKey( reg: TRegistry; Const keyname: String );
  112.   Begin
  113.     If not reg.OpenKey( keyname, True ) Then
  114.       raise ERegistryError.CreateFmt( eCannotCreateKey, [keyname] );
  115.   End; { CreateKey }
  116.  
  117. {+------------------------------------------------------------
  118.  | Procedure RegisterFiletype
  119.  |
  120.  | Parameters :
  121.  |   extension  : file extension, including the dot, to register
  122.  |   filetype   : string to use as key for the file extension
  123.  |   description: string to show in Explorer for files with this
  124.  |                extension. If description is empty the file
  125.  |                type will not show up in Explorers list of
  126.  |                registered associations!
  127.  |   verb       : action to register, 'open', 'edit', 'print' etc.
  128.  |                The action will turn up as entry in the files
  129.  |                context menu in Explorer.
  130.  |   serverapp  : full pathname of the executable to associate with
  131.  |                the file extension, including any command line
  132.  |                switches. Include the "%1" placeholder as well.
  133.  |                Actions like printto may require more than one
  134.  |                placeholder.
  135.  | Description:
  136.  |   Creates the three basic registry keys for a file extension.
  137.  |   HKCR\<extension> = <filetype>
  138.  |   HKCR\<filetype>  = <description>
  139.  |   HKCR\<filetype>\shell\<verb>\command = <serverapp>
  140.  |   If the keys already exist they are overwritten!
  141.  | Error Conditions:
  142.  |   A ERegistryError exception will result if a key cannot be
  143.  |   created. Failure to create a key is usually due to insufficient
  144.  |   user rights and only a problem on NT.
  145.  | Created: 14.03.99 by P. Below
  146.  +------------------------------------------------------------}
  147. Procedure RegisterFiletype( Const extension, filetype, description,
  148.              verb, serverapp: String );
  149.   Var
  150.     reg: TRegistry;
  151.     keystring: String;
  152.   Begin
  153.     reg:= TRegistry.Create;
  154.     Try
  155.       reg.Rootkey := HKEY_CLASSES_ROOT;
  156.       CreateKey( reg, extension );
  157.       reg.WriteString( '', filetype );
  158.       reg.CloseKey;
  159.       CreateKey( reg, filetype );
  160.       reg.WriteString('', description );
  161.       reg.closekey;
  162.       keystring := Format('%s\shell\%s\command', [filetype, verb] );
  163.       CreateKey( reg, keystring );
  164.       reg.WriteString( '', serverapp );
  165.       reg.CloseKey;
  166.     Finally
  167.       reg.free;
  168.     End;
  169.   End; { RegisterFiletype }
  170.  
  171. {+------------------------------------------------------------
  172.  | Procedure RegisterDDEServer
  173.  |
  174.  | Parameters :
  175.  |   filetype  : file type key name to register the server for
  176.  |   verb      : action to register, 'open', 'edit', 'print' etc.
  177.  |   topic     : DDE topic name to use. This is usually the name
  178.  |               of a TDDEServerConv component.
  179.  |   servername: DDE server name to use. This is usually the
  180.  |               filename of the executable, without extension
  181.  |               and path.
  182.  |   macro     : DDE macro to execute for the action, needs to
  183.  |               include a "%1" placeholder for a filename.
  184.  | Description:
  185.  |   Creates the registry keys required to open files of this type
  186.  |   via DDE from Explorer or ShellExecute. RegisterFileType needs
  187.  |   to be called first to associate the filetype with an extension.
  188.  |   The registry keys added are
  189.  |   HKCR\<filetype>\shell\<verb>\ddeexec = <macro>
  190.  |   HKCR\<filetype>\shell\<verb>\ddeexec\topic = <topic>
  191.  |   HKCR\<filetype>\shell\<verb>\ddeexec\application = <servername>
  192.  |   If the keys already exist they are overwritten!
  193.  | Error Conditions:
  194.  |   A ERegistryError exception will result if a key cannot be
  195.  |   created. Failure to create a key is usually due to insufficient
  196.  |   user rights and only a problem on NT.
  197.  | Created: 14.03.99 by P. Below
  198.  +------------------------------------------------------------}
  199. Procedure RegisterDDEServer( Const filetype, verb, topic, servername, macro:
  200. String );
  201.   Var
  202.     reg: TRegistry;
  203.     keystring: String;
  204.   Begin
  205.     reg:= TRegistry.Create;
  206.     Try
  207.       reg.Rootkey := HKEY_CLASSES_ROOT;
  208.       keystring := Format( '%s\shell\%s\ddeexec',[filetype, verb] );
  209.       CreateKey( reg, keystring );
  210.       reg.WriteString( '', macro );
  211.       reg.CloseKey;
  212.       CreateKey( reg, keystring + '\Application' );
  213.       reg.WriteString( '', servername );
  214.       reg.CloseKey;
  215.       CreateKey( reg, keystring + '\topic' );
  216.       reg.WriteString( '', topic );
  217.       reg.CloseKey;
  218.     Finally
  219.       reg.free;
  220.     End;
  221.   End; { RegisterDDEServer }
  222.  
  223. {+------------------------------------------------------------
  224.  | Procedure TForm1.RegisterAssociation
  225.  |
  226.  | Call method: static
  227.  | Visibility : private
  228.  | Description:
  229.  |   Register this application as server for the .TED file
  230.  |   extension.
  231.  | Error Conditions:
  232.  |   A ERegistryError exception will result if a key cannot be
  233.  |   created.
  234.  | Created: 14.03.99 by P. Below
  235.  +------------------------------------------------------------}
  236. Procedure TForm1.RegisterAssociation;
  237.   Begin
  238.     RegisterFiletype(
  239.       '.TED',
  240.       'TEDFile',
  241.       'TED File',
  242.       'open',
  243.       Application.Exename+' "%1"' );
  244.     RegisterDDEServer(
  245.       'TEDFile',
  246.       'open',
  247.       TEDDdeServer.Name,
  248.       Uppercase( ChangeFileExt(
  249.                    ExtractFilename( Application.Exename ),
  250.                    EmptyStr )),
  251.       '[Open("%1")]' );
  252.     ShChangeNotify( SHCNE_ASSOCCHANGED, 0, Nil, Nil );
  253.   End; { TForm1.RegisterAssociation }
  254.  
  255. {+------------------------------------------------------------
  256.  | Procedure TForm1.FormCreate
  257.  |
  258.  | Event      : OnCreate
  259.  | Used by    : the form
  260.  | Call method: static
  261.  | Visibility : published
  262.  | Description:
  263.  |   On form creation we register the application as server for
  264.  |   the .TED extension and create editors for any file that
  265.  |   may have been passed on the commandline.
  266.  |   Note that the commandline processing code needs to be
  267.  |   changed if command line switches are used to select
  268.  |   between different actions!
  269.  | Error Conditions:
  270.  |   A ERegistryError exception may be raised in the registration
  271.  |   process.
  272.  | Created: 14.03.99 by P. Below
  273.  +------------------------------------------------------------}
  274. Procedure TForm1.FormCreate(Sender: TObject);
  275.   Var
  276.     i: integer;
  277.   Begin
  278.     RegisterAssociation;
  279.     For i:= 1 To ParamCount Do
  280.       AddFileeditor( ParamStr( i ));
  281.   End; { TForm1.FormCreate }
  282.  
  283. {+------------------------------------------------------------
  284.  | Procedure TForm1.TEDDdeServerExecuteMacro
  285.  |
  286.  | Event      : OnExecuteMacro
  287.  | Used by    : TEDDdeServer
  288.  | Call method: static
  289.  | Visibility : published
  290.  | Description:
  291.  |   This method is called when the DDE server receives a macro
  292.  |   request. In this case the request will always be a single
  293.  |   line but the code is able to deal with several macros rolled
  294.  |   into one request, as long as the macros are separated by
  295.  |   line breaks.
  296.  | Error Conditions: none
  297.  | Created: 14.03.99 by P. Below
  298.  +------------------------------------------------------------}
  299. Procedure TForm1.TEDDdeServerExecuteMacro(Sender: TObject; Msg: TStrings);
  300.   Var
  301.     filename: String;
  302.     i, n: Integer;
  303.   Begin
  304.     If Msg.Count > 0 Then Begin
  305.       For i := 0 To Msg.Count-1 Do Begin
  306.         filename := Msg[i];
  307.         If Pos('[Open(', filename) = 1 Then Begin
  308.           n:= Pos('"', filename );
  309.           If n > 0 Then Begin
  310.             Delete( filename, 1, n );
  311.             n:= Pos('"', filename );
  312.             If n > 0 Then
  313.               Delete( filename, n, maxint );
  314.             AddFileeditor( filename );
  315.           End; { if }
  316.         End; { If }
  317.       End; { For }
  318.     End; { if }
  319.   End; { TForm1.TEDDdeServerExecuteMacro }
  320.  
  321. {+------------------------------------------------------------
  322.  | Procedure TForm1.AddFileeditor
  323.  |
  324.  | Parameters :
  325.  |   filename: full pathname of a file to view
  326.  | Call method: static
  327.  | Visibility : private
  328.  | Description:
  329.  |   Creates a new tabsheet in the pagecontrol and a TMemo on
  330.  |   this tabsheet. The file is loaded into the memo and the
  331.  |   tabsheet is made active.
  332.  | Error Conditions:
  333.  |   Exceptions may result if the file is not found or is not
  334.  |   a textfile.
  335.  | Created: 14.03.99 by P. Below
  336.  +------------------------------------------------------------}
  337. Procedure TForm1.AddFileeditor( Const filename: String );
  338.   Var
  339.     tab: TTabSheet;
  340.     memo: TMemo;
  341.   Begin
  342.     tab := TTabsheet.Create(self);
  343.     tab.Pagecontrol := pagecontrol1;
  344.     tab.caption := Extractfilename( filename );
  345.     memo := TMemo.Create( tab );
  346.     memo.Align := alClient;
  347.     memo.Parent := tab;
  348.     memo.lines.LoadFromFile( filename );
  349.     Pagecontrol1.ActivePage := tab;
  350.   End; { TForm1.AddFileeditor }
  351.  
  352. End.
  353.  
  354. {
  355. object Form1: TForm1
  356.   Left = 192
  357.   Top = 128
  358.   AutoScroll = False
  359.   Caption = 'Form1'
  360.   ClientHeight = 373
  361.   ClientWidth = 632
  362.   Color = clBtnFace
  363.   Font.Charset = DEFAULT_CHARSET
  364.   Font.Color = clWindowText
  365.   Font.Height = -13
  366.   Font.Name = 'MS Sans Serif'
  367.   Font.Style = []
  368.   OldCreateOrder = False
  369.   OnCreate = FormCreate
  370.   PixelsPerInch = 120
  371.   TextHeight = 16
  372.   object PageControl1: TPageControl
  373.     Left = 0
  374.     Top = 0
  375.     Width = 632
  376.     Height = 373
  377.     Align = alClient
  378.     TabOrder = 0
  379.   end
  380.   object TEDDdeServer: TDdeServerConv
  381.     OnExecuteMacro = TEDDdeServerExecuteMacro
  382.     Left = 32
  383.     Top = 24
  384.   end
  385. end
  386.  
  387. }
  388.  
  389.  
  390.  
  391. //Peter Below (TeamB)  100113.1101@compuserve.com)
  392. //No e-mail responses, please, unless explicitely requested!
  393.  
« Last Edit: September 23, 2017, 03:59:27 am by taazz »
Good judgement is the result of experience … Experience is the result of bad judgement.

OS : Windows 7 64 bit
Laz: Lazarus 1.4.4 FPC 2.6.4 i386-win32-win32/win64

antekgla

  • New Member
  • *
  • Posts: 22
Re: Implementation of IDropTarget
« Reply #5 on: September 23, 2017, 05:11:09 am »
@molly thanks, but i have implemented the Params handling what with the component One Instance works great.
So I added a shortcut to my application in the Send to folder and works.

My goal is different now. I am trying to implement the handling of IDropTarget.

@taazz Thanks for taking the time to respond with such level of information. i appreciate it... but

1) As you says the component suite is for Delphi and I'm not that experienced in Lazarus to try to port such a big project. Sadly the author is not interested in do it either. Someone already asked.

2)
a) Again Delphi (v2) Component.
b) I have no intention of associate any file extension with my app, as the code of Peter Bellow do, because my app is something like a Copy App so I want to select the files in explorer (any files: audio, video, docs, etc), right click and open my App with the filenames in the memo.

Thanks anyway!

I am thinking maybe use the The Drag and Drop Component Suite for Delphi in my Delphi 7 to do the Shell extension and pass the filenames to my app (something what I was trying to avoid), but my main concern is the Unicode because Delphi 7 is not Unicode ready.


taazz

  • Hero Member
  • *****
  • Posts: 5368
Re: Implementation of IDropTarget
« Reply #6 on: September 23, 2017, 05:34:38 am »
1) As you says the component suite is for Delphi and I'm not that experienced in Lazarus to try to port such a big project. Sadly the author is not interested in do it either. Someone already asked.

It is a single file that you need to port (as far as I remember) and since you are only after the idroptarget one or two classes (haven't looked closely for too long to remember) from that file are relevant. I would guess that it will be faster to try and port the two classes than to install delphi 7.

a) Again Delphi (v2) Component.

It is a complete unit the only thing missing is the ddeml.pas which is a simple container for the ddeml.h file of the SDK again, try to find a jwddeml or something along those lines from jedi and the component should work as is on lcl for windows only.

b) I have no intention of associate any file extension with my app, as the code of Peter Bellow do, because my app is something like a Copy App so I want to select the files in explorer (any files: audio, video, docs, etc), right click and open my App with the filenames in the memo.
yeah the '*' registry key you linked in your first post does exactly that associates your application with all the files in windows. Sorry but you allready use file type association.
Thanks anyway!
You are welcome.
I am thinking maybe use the The Drag and Drop Component Suite for Delphi in my Delphi 7 to do the Shell extension and pass the filenames to my app (something what I was trying to avoid), but my main concern is the Unicode because Delphi 7 is not Unicode ready.
I do not think that drag and drop supports shell extensions, what you are looking for is namespace shell extensions (NSE) and there are a couple of delphi projects out there that you can use for inspiration or copy and they all require you to associate your application with a file type (* for all of them). In any case you have to decide where you want to invest your time.
Good judgement is the result of experience … Experience is the result of bad judgement.

OS : Windows 7 64 bit
Laz: Lazarus 1.4.4 FPC 2.6.4 i386-win32-win32/win64

six1

  • Full Member
  • ***
  • Posts: 117
Re: Implementation of IDropTarget
« Reply #7 on: October 29, 2017, 11:18:31 am »
Hi,
i've ported the drag and Drop Suite 5.2 from Andres Melander to Lazarus.
I needed Drag&Drop in one of my Projects and i wasn't able to implement this on my own.
So i decided to try to translate "Melanders Suite" for Lazarus. It was two Day Story for me, but now
it is working fine except Part of Ownerdraw TMenuItem... this is not implemented in Lazarus...
but DropSource and DropTarget is working fine.

I was asking Andres Melander, if i can publish the Lazarus Version of his Drag&Drop Components...
depends on his answer, if i can do this...

stay tuned, i will tell you as far as i got an answer from him...



best, Michael
« Last Edit: October 29, 2017, 11:22:39 am by six1 »

avra

  • Hero Member
  • *****
  • Posts: 2514
    • Additional info
Re: Implementation of IDropTarget
« Reply #8 on: October 29, 2017, 02:04:04 pm »
I was asking Andres Melander, if i can publish the Lazarus Version of his Drag&Drop Components...
depends on his answer, if i can do this...
Well, on http://melander.dk/delphi/dragdrop I can see that component suite is "freeware VCL component library" having "Creative Commons Attribution-Share Alike 3.0 Unported License". Looking at https://creativecommons.org/licenses/by-sa/3.0/ and https://tldrlegal.com/license/creative-commons-attribution-(cc) I see that you can share your conversion as long as you follow license terms (credit the author, indicate that changes were made, put link to license, and use the same license). It is always nice to inform an author, but license does not request to ask him for publishing permission.
ct2laz - Conversion between Lazarus and CodeTyphon
bithelpers - Bit manipulation for standard types
pasettimino - Siemens S7 PLC lib

JuhaManninen

  • Global Moderator
  • Hero Member
  • *****
  • Posts: 4459
  • I like bugs.
Re: Implementation of IDropTarget
« Reply #9 on: October 29, 2017, 02:19:46 pm »
Exactly like Avra says.
The license is there so people don't have to explicitly ask the author every time.
Please consider putting the sources somewhere and providing the package through OPM.
Mostly Lazarus trunk and FPC 3.2 on Manjaro Linux 64-bit.

six1

  • Full Member
  • ***
  • Posts: 117
Re: Implementation of IDropTarget
« Reply #10 on: October 29, 2017, 03:49:00 pm »
Hi,
the Copyright isn't changed in any way. I put a notice under Copyright from Andres Melander, that i've translated the lib for Lazarus.
(Edit: Anders Melander has agreed to a publication of the Fork. )

Installation:
Extract Zip Content to Folder of your Choice. (i.e. C:\lazarus\components\_own_components\)
Open "DragDropLazarus.lpk" in Subfolder "Source", compile and install it.

For me it works for Lazarus 1.6.4
Notice, that i only tested Part of the whole Components!
Also i only tested a few Demos.

Download: http://forum.lazarus.freepascal.org/index.php/topic,38761.0.html


best, Michael
« Last Edit: October 30, 2017, 03:01:26 pm by six1 »

 

TinyPortal © 2005-2018