237 lines
6.3 KiB
ObjectPascal
237 lines
6.3 KiB
ObjectPascal
|
{
|
||
|
Original Code from
|
||
|
(C) 2001 - Peter Windridge
|
||
|
|
||
|
Code in separate unit and some changes
|
||
|
2003 by Bernhard Mayer
|
||
|
|
||
|
Fixed and formatted by Brett Dever
|
||
|
http://editor.nfscheats.com/
|
||
|
|
||
|
simply include this unit in your plugin project and export
|
||
|
functions as needed
|
||
|
}
|
||
|
|
||
|
unit nsis;
|
||
|
|
||
|
interface
|
||
|
|
||
|
uses
|
||
|
windows, SysUtils
|
||
|
{$IFNDEF FPC}
|
||
|
,CommCtrl
|
||
|
{$ENDIF}
|
||
|
{$IF FPC_FULLVERSION < 30000} ; This is probably wrong
|
||
|
,CommCtrl
|
||
|
{$ENDIF}
|
||
|
;
|
||
|
|
||
|
{$IFDEF UNICODE}
|
||
|
type NSISTString = System.WideString; // UnicodeString?
|
||
|
type NSISPTChar = PWideChar;
|
||
|
{$ELSE}
|
||
|
type NSISTString = AnsiString;
|
||
|
type NSISPTChar = PAnsiChar;
|
||
|
{$ENDIF}
|
||
|
|
||
|
type
|
||
|
VarConstants = (
|
||
|
INST_0, // $0
|
||
|
INST_1, // $1
|
||
|
INST_2, // $2
|
||
|
INST_3, // $3
|
||
|
INST_4, // $4
|
||
|
INST_5, // $5
|
||
|
INST_6, // $6
|
||
|
INST_7, // $7
|
||
|
INST_8, // $8
|
||
|
INST_9, // $9
|
||
|
INST_R0, // $R0
|
||
|
INST_R1, // $R1
|
||
|
INST_R2, // $R2
|
||
|
INST_R3, // $R3
|
||
|
INST_R4, // $R4
|
||
|
INST_R5, // $R5
|
||
|
INST_R6, // $R6
|
||
|
INST_R7, // $R7
|
||
|
INST_R8, // $R8
|
||
|
INST_R9, // $R9
|
||
|
INST_CMDLINE, // $CMDLINE
|
||
|
INST_INSTDIR, // $INSTDIR
|
||
|
INST_OUTDIR, // $OUTDIR
|
||
|
INST_EXEDIR, // $EXEDIR
|
||
|
INST_LANG, // $LANGUAGE
|
||
|
__INST_LAST
|
||
|
);
|
||
|
TVariableList = INST_0..__INST_LAST;
|
||
|
|
||
|
type
|
||
|
PluginCallbackMessages = (
|
||
|
NSPIM_UNLOAD, // This is the last message a plugin gets, do final cleanup
|
||
|
NSPIM_GUIUNLOAD // Called after .onGUIEnd
|
||
|
);
|
||
|
TNSPIM = NSPIM_UNLOAD..NSPIM_GUIUNLOAD;
|
||
|
|
||
|
//TPluginCallback = function (const NSPIM: Integer): Pointer; cdecl;
|
||
|
|
||
|
TExecuteCodeSegment = function (const funct_id: Integer; const parent: HWND): Integer; stdcall;
|
||
|
Tvalidate_filename = procedure (const filename: NSISPTChar); stdcall;
|
||
|
TRegisterPluginCallback = function (const DllInstance: HMODULE; const CallbackFunction: Pointer): Integer; stdcall;
|
||
|
|
||
|
pexec_flags_t = ^exec_flags_t;
|
||
|
exec_flags_t = record
|
||
|
autoclose: Integer;
|
||
|
all_user_var: Integer;
|
||
|
exec_error: Integer;
|
||
|
abort: Integer;
|
||
|
exec_reboot: Integer;
|
||
|
reboot_called: Integer;
|
||
|
XXX_cur_insttype: Integer;
|
||
|
plugin_api_version: Integer;
|
||
|
silent: Integer;
|
||
|
instdir_error: Integer;
|
||
|
rtl: Integer;
|
||
|
errlvl: Integer;
|
||
|
alter_reg_view: Integer;
|
||
|
status_update: Integer;
|
||
|
end;
|
||
|
|
||
|
pextrap_t = ^extrap_t;
|
||
|
extrap_t = record
|
||
|
exec_flags: Pointer; // exec_flags_t;
|
||
|
exec_code_segment: TExecuteCodeSegment; // TFarProc;
|
||
|
validate_filename: Pointer; // Tvalidate_filename;
|
||
|
RegisterPluginCallback: Pointer; //TRegisterPluginCallback;
|
||
|
end;
|
||
|
|
||
|
pstack_t = ^stack_t;
|
||
|
stack_t = record
|
||
|
next: pstack_t;
|
||
|
text: NSISPTChar;
|
||
|
end;
|
||
|
|
||
|
var
|
||
|
g_stringsize: integer;
|
||
|
g_stacktop: ^pstack_t;
|
||
|
g_variables: NSISPTChar;
|
||
|
g_hwndParent: HWND;
|
||
|
g_hwndList: HWND;
|
||
|
g_hwndLogList: HWND;
|
||
|
g_extraparameters: pextrap_t;
|
||
|
|
||
|
procedure Init(const hwndParent: HWND; const string_size: integer; const variables: NSISPTChar; const stacktop: pointer; const extraparameters: pointer = nil);
|
||
|
function LogMessage(Msg : String): BOOL;
|
||
|
function Call(NSIS_func : String) : Integer;
|
||
|
function PopString(): NSISTString;
|
||
|
procedure PushString(const str: NSISTString='');
|
||
|
function GetUserVariable(const varnum: TVariableList): NSISTString;
|
||
|
procedure SetUserVariable(const varnum: TVariableList; const value: NSISTString);
|
||
|
procedure NSISDialog(const text, caption: NSISTString; const buttons: integer);
|
||
|
|
||
|
implementation
|
||
|
|
||
|
procedure Init(const hwndParent: HWND; const string_size: integer; const variables: NSISPTChar; const stacktop: pointer; const extraparameters: pointer = nil);
|
||
|
begin
|
||
|
g_stringsize := string_size;
|
||
|
g_hwndParent := hwndParent;
|
||
|
g_stacktop := stacktop;
|
||
|
g_variables := variables;
|
||
|
g_hwndList := FindWindowEx(FindWindowEx(g_hwndParent, 0, '#32770', nil), 0,'SysListView32', nil);
|
||
|
g_extraparameters := extraparameters;
|
||
|
end;
|
||
|
|
||
|
|
||
|
function Call(NSIS_func : String) : Integer;
|
||
|
var
|
||
|
codeoffset: Integer; //The ID of nsis function
|
||
|
begin
|
||
|
Result := 0;
|
||
|
codeoffset := StrToIntDef(NSIS_func, 0);
|
||
|
if (codeoffset <> 0) and (g_extraparameters <> nil) then
|
||
|
begin
|
||
|
codeoffset := codeoffset - 1;
|
||
|
Result := g_extraparameters.exec_code_segment(codeoffset, g_hwndParent);
|
||
|
end;
|
||
|
end;
|
||
|
|
||
|
function LogMessage(Msg : String): BOOL;
|
||
|
var
|
||
|
ItemCount : Integer;
|
||
|
item: TLVItem;
|
||
|
begin
|
||
|
Result := FAlse;
|
||
|
if g_hwndList = 0 then exit;
|
||
|
FillChar( item, sizeof(item), 0 );
|
||
|
ItemCount := SendMessage(g_hwndList, LVM_GETITEMCOUNT, 0, 0);
|
||
|
item.iItem := ItemCount;
|
||
|
item.mask := LVIF_TEXT;
|
||
|
item.pszText := PChar(Msg); // Unicode bug?
|
||
|
ListView_InsertItem(g_hwndList, item);
|
||
|
ListView_EnsureVisible(g_hwndList, ItemCount, not 0);
|
||
|
end;
|
||
|
|
||
|
function PopString(): NSISTString;
|
||
|
var
|
||
|
th: pstack_t;
|
||
|
begin
|
||
|
if NativeUInt(g_stacktop^) <> 0 then begin
|
||
|
th := g_stacktop^;
|
||
|
Result := NSISPTChar(@th.text);
|
||
|
g_stacktop^ := th.next;
|
||
|
GlobalFree(HGLOBAL(th));
|
||
|
end;
|
||
|
end;
|
||
|
|
||
|
procedure PushString(const str: NSISTString='');
|
||
|
var
|
||
|
th: pstack_t;
|
||
|
begin
|
||
|
if NativeUInt(g_stacktop) <> 0 then begin
|
||
|
{$IFDEF UNICODE}
|
||
|
th := pstack_t(GlobalAlloc(GPTR, SizeOf(stack_t) + (g_stringsize * 2)));
|
||
|
lstrcpynW(@th.text, PWideChar(str), g_stringsize);
|
||
|
{$ELSE}
|
||
|
th := pstack_t(GlobalAlloc(GPTR, SizeOf(stack_t) + (g_stringsize )));
|
||
|
lstrcpynA(@th.text, PAnsiChar(str), g_stringsize);
|
||
|
{$ENDIF}
|
||
|
th.next := g_stacktop^;
|
||
|
g_stacktop^ := th;
|
||
|
end;
|
||
|
end;
|
||
|
|
||
|
function GetUserVariable(const varnum: TVariableList): NSISTString;
|
||
|
begin
|
||
|
if (integer(varnum) >= 0) and (integer(varnum) < integer(__INST_LAST)) then
|
||
|
Result := g_variables + integer(varnum) * g_stringsize
|
||
|
else
|
||
|
Result := '';
|
||
|
end;
|
||
|
|
||
|
procedure SetUserVariable(const varnum: TVariableList; const value: NSISTString);
|
||
|
begin
|
||
|
if (integer(varnum) >= 0) and (integer(varnum) < integer(__INST_LAST)) then
|
||
|
{$IFDEF UNICODE}
|
||
|
lstrcpyW(g_variables + integer(varnum) * (g_stringsize), PWideChar(value))
|
||
|
{$ELSE}
|
||
|
lstrcpyA(g_variables + integer(varnum) * (g_stringsize), PAnsiChar(value))
|
||
|
{$ENDIF}
|
||
|
end;
|
||
|
|
||
|
procedure NSISDialog(const text, caption: NSISTString; const buttons: integer);
|
||
|
var
|
||
|
hwndOwner: HWND;
|
||
|
begin
|
||
|
hwndOwner := g_hwndParent;
|
||
|
if not IsWindow(g_hwndParent) then hwndOwner := 0; // g_hwndParent is not valid in NSPIM_[GUI]UNLOAD
|
||
|
{$IFDEF UNICODE}
|
||
|
MessageBoxW(hwndOwner, PWideChar(text), PWideChar(caption), buttons);
|
||
|
{$ELSE}
|
||
|
MessageBoxA(hwndOwner, PAnsiChar(text), PAnsiChar(caption), buttons);
|
||
|
{$ENDIF}
|
||
|
end;
|
||
|
|
||
|
begin
|
||
|
|
||
|
end.
|
||
|
|