-
Notifications
You must be signed in to change notification settings - Fork 2
/
Copy pathUseLoadLibMain.pas
162 lines (139 loc) · 4.61 KB
/
UseLoadLibMain.pas
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
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
unit UseLoadLibMain;
interface
uses
Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
StdCtrls, FileCtrl, Buttons, ExtCtrls;
type
TfrmDynDllDemo = class(TForm)
lblFreeBytes: TLabel;
lblFreeMBytes: TLabel;
btnExit: TBitBtn;
cmbDrives: TDriveComboBox;
btnBulbs: TSpeedButton;
procedure cmbDrivesChange(Sender: TObject);
procedure FormCreate(Sender: TObject);
procedure FormDestroy(Sender: TObject);
procedure FormActivate(Sender: TObject);
procedure FormDeactivate(Sender: TObject);
procedure btnBulbsMouseMove(Sender: TObject; Shift: TShiftState; X, Y: Integer);
procedure FormMouseMove(Sender: TObject; Shift: TShiftState; X, Y: Integer);
procedure btnBulbsClick(Sender: TObject);
procedure FormCloseQuery(Sender: TObject; var CanClose: Boolean);
private
// internal flag: have we already turned on the bulb?
OverImage: Boolean;
// handles to the function and resource libraries
DllHandle: HModule;
ResHandle: HModule;
end;
var
frmDynDllDemo: TfrmDynDllDemo;
implementation
uses
NewMsgDlg;
{$R *.DFM}
type
// declare function types that we'll access
TIntToCommaStrFunc = function(Num: Int64; Dest: PChar; MaxLen: Integer): PChar; stdcall;
TFreeBytesFunc = function(Drive: Char): Int64; stdcall;
TFreeMBytesProc = procedure(Drive: Char; var MBytesFree: Double); stdcall;
var
// pointers to the functions we have to assign manually
IntToCommaStr: TIntToCommaStrFunc;
FreeBytes: TFreeBytesFunc;
FreeMBytes: TFreeMBytesProc;
procedure TfrmDynDllDemo.FormCreate(Sender: TObject);
begin
// initialize the DLL handles
DllHandle := 0;
ResHandle := 0;
end;
procedure TfrmDynDllDemo.FormDestroy(Sender: TObject);
begin
// free the function library
if DllHandle <> 0 then
FreeLibrary(DllHandle);
// free the resource library
if ResHandle <> 0 then
FreeLibrary(ResHandle);
end;
procedure TfrmDynDllDemo.FormActivate(Sender: TObject);
const
BitmapLibName = 'BitmapLib.DLL';
var
msg: array[0..50] of Char;
begin
// load the resource library
ResHandle := LoadLibraryEx(PChar(BitmapLibName), 0, Load_Library_As_DataFile);
if ResHandle = 0 then
begin
StrPCopy(msg, 'Could not load ' + BitmapLibName + ': Error ' + IntToStr(GetLastError));
NewMessageDlg(msg , Ord(mtError))
end else
// if loaded, set the "bulb off" glyph
btnBulbs.Glyph.LoadFromResourceName(ResHandle, 'BulbOff');
// initialize the flag
OverImage := False;
end;
procedure TfrmDynDllDemo.FormDeactivate(Sender: TObject);
begin
// free the resource handle
if ResHandle <> 0 then
FreeLibrary(ResHandle);
end;
procedure TfrmDynDllDemo.cmbDrivesChange(Sender: TObject);
const
FuncLibName = 'FunctionLib.DLL';
var
p: array[0..30] of Char;
msg: array[0..50] of Char;
x: Double;
begin
// check to see if the DLL is loaded
if DllHandle = 0 then begin
DllHandle := LoadLibrary(PChar(FuncLibName));
// didn't make it :-(
if DllHandle = 0 then begin
StrPCopy(msg, 'Could not load ' + FuncLibName + ': Error ' + IntToStr(GetLastError));
NewMessageDlg(msg, Ord(mtError));
Exit;
end;
// DLL loaded, assign the functions
@IntToCommaStr := GetProcAddress(DllHandle, 'IntToCommaStr');
@FreeBytes := GetProcAddress(DllHandle, 'FreeBytes');
@FreeMBytes := GetProcAddress(DllHandle, 'FreeMBytes');
end;
// assume it has by here
IntToCommaStr(FreeBytes(cmbDrives.Drive), p, 30);
lblFreeBytes.Caption := StrPas(p) + ' Bytes free';
FreeMBytes(cmbDrives.Drive, x);
lblFreeMBytes.Caption := FloatToStrF(x, ffFixed, 15, 2) + ' MBytes free';
end;
procedure TfrmDynDllDemo.btnBulbsMouseMove(Sender: TObject; Shift: TShiftState; X, Y: Integer);
begin
// if the resource is available and we haven't already turned the bulb on, do it now
if (ResHandle <> 0) and (not OverImage) then begin
btnBulbs.Glyph.LoadFromResourceName(ResHandle, 'BulbOn');
OverImage := True;
end;
end;
procedure TfrmDynDllDemo.FormMouseMove(Sender: TObject; Shift: TShiftState; X, Y: Integer);
begin
// if we think we're still over the button, clear the flag and turn the bulb off
if OverImage then begin
OverImage := False;
btnBulbs.Glyph.LoadFromResourceName(ResHandle, 'BulbOff');
end;
end;
procedure TfrmDynDllDemo.btnBulbsClick(Sender: TObject);
var
msg: array[0..80] of Char;
begin
StrPCopy(msg, 'You should think twice before hitting that Cancel button!');
NewMessageDlg(msg, Ord(mtWarning));
end;
procedure TfrmDynDllDemo.FormCloseQuery(Sender: TObject; var CanClose: Boolean);
begin
CanClose := NewMessageDlg(PChar('Do you REALLY want to leave?'), Ord(mtConfirmation)) = mrOk;
end;
end.