forked from lmbelo/python4delphi
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathDynamicDLLWithVersion.pas
More file actions
133 lines (117 loc) · 3.42 KB
/
Copy pathDynamicDLLWithVersion.pas
File metadata and controls
133 lines (117 loc) · 3.42 KB
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
unit DynamicDLLWithVersion;
interface
uses
SysUtils, Classes, DynamicDLL;
type
TDynamicDLLWithVersion = class(TDynamicDLL)
protected
DLL_VersionsSupported: TList;
DLL_VersionsSpeculated: TList;
DLL_VersionsFallback: TList;
DLL_Base_Name: String;
DLL_Version_MajorMod: Integer;
public
DLL_Version: Integer;
PrefereFallback: Boolean;
IsEssential: Boolean;
constructor Create(AOwner: TComponent); override;
destructor Destroy; override;
function LoadDll: Boolean; override;
function LoadDllByVersion(Versions: TList; CurrentIsEssential: Boolean=False): Boolean;
function GetDLL_Version_Major(v: Integer): Integer; virtual;
function GetDLL_Version_Minor(v: Integer): Integer; virtual;
protected
procedure BeforeLoad; override;
function ResolvePaths: Boolean; virtual;
function GetDllNameByVersion(v: Integer): String; virtual;
end;
implementation
uses Windows;
{ TDynamicDLLWithVersion }
constructor TDynamicDLLWithVersion.Create(AOwner: TComponent);
begin
inherited;
DLL_Base_Name := '';
DLL_Version := 0;
DLL_VersionsSupported := TList.Create;
DLL_VersionsSpeculated := TList.Create;
DLL_VersionsFallback := TList.Create;
PrefereFallback := False;
DLL_Version_MajorMod := 100;
IsEssential := True;
FatalAbort := False;
end;
destructor TDynamicDLLWithVersion.Destroy;
begin
DLL_VersionsSpeculated.Free;
DLL_VersionsSupported.Free;
DLL_VersionsFallback.Free;
inherited;
end;
function TDynamicDLLWithVersion.GetDllNameByVersion(v: Integer): String;
begin
Result := DLL_Base_Name + IntToStr(v) + '.dll';
end;
function TDynamicDLLWithVersion.GetDLL_Version_Major(v: Integer): Integer;
begin
Result := v div DLL_Version_MajorMod;
end;
function TDynamicDLLWithVersion.GetDLL_Version_Minor(v: Integer): Integer;
begin
Result := v mod DLL_Version_MajorMod;
end;
procedure TDynamicDLLWithVersion.BeforeLoad;
begin
inherited;
ResolvePaths;
end;
function TDynamicDLLWithVersion.LoadDll: Boolean;
var
LastError: String;
begin
if DllName <> '' then begin
Result := Inherited;
end else begin
if PrefereFallback then begin
Result := LoadDllByVersion(DLL_VersionsFallback);
if not Result then
Result := LoadDllByVersion(DLL_VersionsSupported);
end else begin
Result := LoadDllByVersion(DLL_VersionsSupported);
if not Result then
Result := LoadDllByVersion(DLL_VersionsFallback);
end;
if not Result then
Result := LoadDllByVersion(DLL_VersionsSpeculated);
if not Result and IsEssential then begin
LastError := Format('Error %d: Could not open Dll "%s" (any supported version)',[GetLastError, DLL_Base_Name]);
MessageBox( GetActiveWindow, PChar(LastError), 'Error', MB_TASKMODAL or MB_ICONSTOP );
end;
end;
end;
function TDynamicDLLWithVersion.LoadDllByVersion(Versions: TList; CurrentIsEssential: Boolean): Boolean;
var
i, v: Integer;
ThisIsEssential: Boolean;
begin
Result := False;
for i := 0 to Versions.Count-1 do begin
v := Integer(Versions[i]);
ThisIsEssential := CurrentIsEssential and (i=Versions.Count-1);
FatalMsgDlg := ThisIsEssential;
DllName := GetDllNameByVersion(v);
Result := inherited LoadDll;
if Result then begin
DLL_Version := v;
break;
end
else begin
DllName := '';
end;
end;
end;
function TDynamicDLLWithVersion.ResolvePaths: Boolean;
begin
Result := (DllPath<>'') and FileExists(DllFullFileName);
end;
end.