nsis.pas 6.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236
  1. {
  2. Original Code from
  3. (C) 2001 - Peter Windridge
  4. Code in separate unit and some changes
  5. 2003 by Bernhard Mayer
  6. Fixed and formatted by Brett Dever
  7. http://editor.nfscheats.com/
  8. simply include this unit in your plugin project and export
  9. functions as needed
  10. }
  11. unit nsis;
  12. interface
  13. uses
  14. windows, SysUtils
  15. {$IFNDEF FPC}
  16. ,CommCtrl
  17. {$ENDIF}
  18. {$IF FPC_FULLVERSION < 30000} ; This is probably wrong
  19. ,CommCtrl
  20. {$ENDIF}
  21. ;
  22. {$IFDEF UNICODE}
  23. type NSISTString = System.WideString; // UnicodeString?
  24. type NSISPTChar = PWideChar;
  25. {$ELSE}
  26. type NSISTString = AnsiString;
  27. type NSISPTChar = PAnsiChar;
  28. {$ENDIF}
  29. type
  30. VarConstants = (
  31. INST_0, // $0
  32. INST_1, // $1
  33. INST_2, // $2
  34. INST_3, // $3
  35. INST_4, // $4
  36. INST_5, // $5
  37. INST_6, // $6
  38. INST_7, // $7
  39. INST_8, // $8
  40. INST_9, // $9
  41. INST_R0, // $R0
  42. INST_R1, // $R1
  43. INST_R2, // $R2
  44. INST_R3, // $R3
  45. INST_R4, // $R4
  46. INST_R5, // $R5
  47. INST_R6, // $R6
  48. INST_R7, // $R7
  49. INST_R8, // $R8
  50. INST_R9, // $R9
  51. INST_CMDLINE, // $CMDLINE
  52. INST_INSTDIR, // $INSTDIR
  53. INST_OUTDIR, // $OUTDIR
  54. INST_EXEDIR, // $EXEDIR
  55. INST_LANG, // $LANGUAGE
  56. __INST_LAST
  57. );
  58. TVariableList = INST_0..__INST_LAST;
  59. type
  60. PluginCallbackMessages = (
  61. NSPIM_UNLOAD, // This is the last message a plugin gets, do final cleanup
  62. NSPIM_GUIUNLOAD // Called after .onGUIEnd
  63. );
  64. TNSPIM = NSPIM_UNLOAD..NSPIM_GUIUNLOAD;
  65. //TPluginCallback = function (const NSPIM: Integer): Pointer; cdecl;
  66. TExecuteCodeSegment = function (const funct_id: Integer; const parent: HWND): Integer; stdcall;
  67. Tvalidate_filename = procedure (const filename: NSISPTChar); stdcall;
  68. TRegisterPluginCallback = function (const DllInstance: HMODULE; const CallbackFunction: Pointer): Integer; stdcall;
  69. pexec_flags_t = ^exec_flags_t;
  70. exec_flags_t = record
  71. autoclose: Integer;
  72. all_user_var: Integer;
  73. exec_error: Integer;
  74. abort: Integer;
  75. exec_reboot: Integer;
  76. reboot_called: Integer;
  77. XXX_cur_insttype: Integer;
  78. plugin_api_version: Integer;
  79. silent: Integer;
  80. instdir_error: Integer;
  81. rtl: Integer;
  82. errlvl: Integer;
  83. alter_reg_view: Integer;
  84. status_update: Integer;
  85. end;
  86. pextrap_t = ^extrap_t;
  87. extrap_t = record
  88. exec_flags: Pointer; // exec_flags_t;
  89. exec_code_segment: TExecuteCodeSegment; // TFarProc;
  90. validate_filename: Pointer; // Tvalidate_filename;
  91. RegisterPluginCallback: Pointer; //TRegisterPluginCallback;
  92. end;
  93. pstack_t = ^stack_t;
  94. stack_t = record
  95. next: pstack_t;
  96. text: NSISPTChar;
  97. end;
  98. var
  99. g_stringsize: integer;
  100. g_stacktop: ^pstack_t;
  101. g_variables: NSISPTChar;
  102. g_hwndParent: HWND;
  103. g_hwndList: HWND;
  104. g_hwndLogList: HWND;
  105. g_extraparameters: pextrap_t;
  106. procedure Init(const hwndParent: HWND; const string_size: integer; const variables: NSISPTChar; const stacktop: pointer; const extraparameters: pointer = nil);
  107. function LogMessage(Msg : String): BOOL;
  108. function Call(NSIS_func : String) : Integer;
  109. function PopString(): NSISTString;
  110. procedure PushString(const str: NSISTString='');
  111. function GetUserVariable(const varnum: TVariableList): NSISTString;
  112. procedure SetUserVariable(const varnum: TVariableList; const value: NSISTString);
  113. procedure NSISDialog(const text, caption: NSISTString; const buttons: integer);
  114. implementation
  115. procedure Init(const hwndParent: HWND; const string_size: integer; const variables: NSISPTChar; const stacktop: pointer; const extraparameters: pointer = nil);
  116. begin
  117. g_stringsize := string_size;
  118. g_hwndParent := hwndParent;
  119. g_stacktop := stacktop;
  120. g_variables := variables;
  121. g_hwndList := FindWindowEx(FindWindowEx(g_hwndParent, 0, '#32770', nil), 0,'SysListView32', nil);
  122. g_extraparameters := extraparameters;
  123. end;
  124. function Call(NSIS_func : String) : Integer;
  125. var
  126. codeoffset: Integer; //The ID of nsis function
  127. begin
  128. Result := 0;
  129. codeoffset := StrToIntDef(NSIS_func, 0);
  130. if (codeoffset <> 0) and (g_extraparameters <> nil) then
  131. begin
  132. codeoffset := codeoffset - 1;
  133. Result := g_extraparameters.exec_code_segment(codeoffset, g_hwndParent);
  134. end;
  135. end;
  136. function LogMessage(Msg : String): BOOL;
  137. var
  138. ItemCount : Integer;
  139. item: TLVItem;
  140. begin
  141. Result := FAlse;
  142. if g_hwndList = 0 then exit;
  143. FillChar( item, sizeof(item), 0 );
  144. ItemCount := SendMessage(g_hwndList, LVM_GETITEMCOUNT, 0, 0);
  145. item.iItem := ItemCount;
  146. item.mask := LVIF_TEXT;
  147. item.pszText := PChar(Msg); // Unicode bug?
  148. ListView_InsertItem(g_hwndList, item);
  149. ListView_EnsureVisible(g_hwndList, ItemCount, not 0);
  150. end;
  151. function PopString(): NSISTString;
  152. var
  153. th: pstack_t;
  154. begin
  155. if NativeUInt(g_stacktop^) <> 0 then begin
  156. th := g_stacktop^;
  157. Result := NSISPTChar(@th.text);
  158. g_stacktop^ := th.next;
  159. GlobalFree(HGLOBAL(th));
  160. end;
  161. end;
  162. procedure PushString(const str: NSISTString='');
  163. var
  164. th: pstack_t;
  165. begin
  166. if NativeUInt(g_stacktop) <> 0 then begin
  167. {$IFDEF UNICODE}
  168. th := pstack_t(GlobalAlloc(GPTR, SizeOf(stack_t) + (g_stringsize * 2)));
  169. lstrcpynW(@th.text, PWideChar(str), g_stringsize);
  170. {$ELSE}
  171. th := pstack_t(GlobalAlloc(GPTR, SizeOf(stack_t) + (g_stringsize )));
  172. lstrcpynA(@th.text, PAnsiChar(str), g_stringsize);
  173. {$ENDIF}
  174. th.next := g_stacktop^;
  175. g_stacktop^ := th;
  176. end;
  177. end;
  178. function GetUserVariable(const varnum: TVariableList): NSISTString;
  179. begin
  180. if (integer(varnum) >= 0) and (integer(varnum) < integer(__INST_LAST)) then
  181. Result := g_variables + integer(varnum) * g_stringsize
  182. else
  183. Result := '';
  184. end;
  185. procedure SetUserVariable(const varnum: TVariableList; const value: NSISTString);
  186. begin
  187. if (integer(varnum) >= 0) and (integer(varnum) < integer(__INST_LAST)) then
  188. {$IFDEF UNICODE}
  189. lstrcpyW(g_variables + integer(varnum) * (g_stringsize), PWideChar(value))
  190. {$ELSE}
  191. lstrcpyA(g_variables + integer(varnum) * (g_stringsize), PAnsiChar(value))
  192. {$ENDIF}
  193. end;
  194. procedure NSISDialog(const text, caption: NSISTString; const buttons: integer);
  195. var
  196. hwndOwner: HWND;
  197. begin
  198. hwndOwner := g_hwndParent;
  199. if not IsWindow(g_hwndParent) then hwndOwner := 0; // g_hwndParent is not valid in NSPIM_[GUI]UNLOAD
  200. {$IFDEF UNICODE}
  201. MessageBoxW(hwndOwner, PWideChar(text), PWideChar(caption), buttons);
  202. {$ELSE}
  203. MessageBoxA(hwndOwner, PAnsiChar(text), PAnsiChar(caption), buttons);
  204. {$ENDIF}
  205. end;
  206. begin
  207. end.