Bonjour
J'ai retrouvé un extrait du livre de Paul sur Delphi 7.
Dans le chapitre sur les DLL, il propose un système simple de plugin dans une DLL.
J'ai voulu reprendre le code pour en voir le comportement exact.
Voilà le code que j'ai repris mot à mot.
Le fichier commun au programme d'appel et à la DLL :
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59 unit Plugins; interface uses Winapi.Windows, System.Classes, System.SysUtils; type TPluginOptions = record Caption: PChar; OnClick: procedure; stdcall; ShortCut: TShortCut; Bitmap: THandle; end; TInitPlugin = procedure(var Options: TPluginOptions); stdcall; TPlugin = class private fHandle : THandle; fInit : TInitPlugin; fOptions: TPluginOptions; public Constructor Create(Filename: string); Destructor Destroy; override; procedure DoClick; property Caption: PChar read fOptions.Caption; property ShortCut: TShortCut read fOptions.ShortCut; property Bitmap: THandle read fOptions.Bitmap; end; implementation { TPlugin } constructor TPlugin.Create(Filename: string); begin fHandle := LoadLibrary(PChar(Filename)); if @fHandle = nil then raise Exception.Create('Error loading DLL'); fInit := GetProcAddress(fHandle, 'InitPlugin'); if @fInit = nil then raise Exception.Create('Not a plugin'); fInit(fOptions); end; destructor TPlugin.Destroy; begin if fHandle <> 0 then FreeLibrary(fHandle); inherited; end; procedure TPlugin.DoClick; begin if @fOptions.OnClick <> nil then fOptions.OnClick; end; end.
un exemple de plugin :
Le programme principal qui utilise la DLL de plugin.
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34 library Lister; uses System.SysUtils, System.Classes, Vcl.Menus, Vcl.Dialogs, Plugins in '..\..\Commun\Plugins.pas'; {$R *.res} procedure PluginClick; stdcall; begin ShowMessage('Lister'); end; procedure InitPlugin(var Options: TPluginOptions); stdcall; begin with Options do begin Caption := 'Lister dans DLL'; OnClick := @PluginClick; ShortCut := TextToShortCut('Ctrl+b'); Bitmap := 0; end; end; exports InitPlugin; begin end.
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69 unit Unit13; interface uses Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, System.IOUtils, Vcl.Graphics, Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Vcl.StdCtrls, Vcl.Menus; type TForm13 = class(TForm) MainMenu1: TMainMenu; ListBox1: TListBox; PluginsMenu: TMenuItem; procedure FormCreate(Sender: TObject); procedure FormDestroy(Sender: TObject); private PluginList: TList; procedure PluginsClick(Sender: TObject); end; var Form13: TForm13; implementation {$R *.dfm} uses Plugins; procedure TForm13.FormCreate(Sender: TObject); var F : string; Plugin: TPlugin; Menu : TMenuItem; begin PluginList := TList.Create; for F in TDirectory.GetFiles(TPath.GetDirectoryName(Application.ExeName), '*.dll') do begin ListBox1.Items.Append(F); try Plugin := TPlugin.Create(F); Menu := NewItem(Plugin.Caption, Plugin.ShortCut, False, True, PluginsClick, 0, ''); Menu.Tag := PluginList.Add(Plugin); Menu.Bitmap.Handle := Plugin.Bitmap; PluginsMenu.Add(Menu); except on E: Exception do ListBox1.Items.Append(E.Message); end; end; end; procedure TForm13.FormDestroy(Sender: TObject); var I: Integer; begin for I := 0 to PluginList.Count - 1 do TPlugin(PluginList[I]).Free; PluginList.Free; end; procedure TForm13.PluginsClick(Sender: TObject); begin TPlugin(PluginList[TMenuItem(Sender).Tag]).DoClick; // <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< end; end.
Dans le code du bouquin, la procédure TForm13.PluginsClick n'est pas renseignée en terme de code.
Dans ce cas, les menus sont bien chargés mais la procédure ne fait rien.
Pour que ça fonctionne, j'ai du ajouter la ligne qui appelle la procédure DoClick en me basant sur le Tag du menu.
Et là j'ai 2 possibliltés :
- Un oubli de Paul dans son bouquin, ce qui m'étonnerait beaucoup.
- Une connerie de ma part, ce qui semble plus logique.
Problème, je ne vois pas du tout ce que j'ai pu louper même après plusieurs relectures de l'original par rapport à ce que j'ai recopié.
Partager