feat: NSIS 中文安装器(年糕历险记-Setup-v0.1.0.exe 实际构建+静默安装验证)、菜单鼠标可见性修复、首页 UI 原版复刻(土质背景/原版按钮/splash/版本角标)、全 goroutine 崩溃兜底
This commit is contained in:
236
tools/nsis/nsis-3.10/Examples/Plugin/nsis.pas
Normal file
236
tools/nsis/nsis-3.10/Examples/Plugin/nsis.pas
Normal file
@@ -0,0 +1,236 @@
|
||||
{
|
||||
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.
|
||||
|
||||
Reference in New Issue
Block a user