There is nothing special about having multiple callbacks:
PHP Code:
/* Note: This is both the NSIS and C++ code in one file. */
#if 0 // NSIS:
Unicode False
!addplugindir "."
RequestExecutionLevel User
Function F1
MessageBox MB_OK "F1 called"
FunctionEnd
Function F2
MessageBox MB_OK "F2 called"
FunctionEnd
Section
GetFunctionAddress $0 F1
CallbackTest::SetCallback1 /NoUnload ; /NoUnload or SetPluginsUnload required
GetFunctionAddress $0 F2
CallbackTest::SetCallback2 ; Requires the plug-in to call RegisterPluginCallback
CallbackTest::Trigger ; Just a simple way to start calling back
SectionEnd
!if 0
#else // C++:
#include <windows.h>
#include <stdlib.h>
#include <tchar.h>
typedef struct {
int*sloppy_hack; // Not using this
int (WINAPI*ExecuteCodeSegment)(int, HWND);
void (WINAPI*validate_filename)(LPTSTR);
int (WINAPI*RegisterPluginCallback)(HINSTANCE, UINT_PTR(__cdecl*f)(int));
} extra_parameters;
typedef struct _stack_t { struct _stack_t *next; TCHAR text[1]; } stack_t;
#define NPPUBEXPORT EXTERN_C __declspec(dllexport) void __cdecl
static char remember_to_fix_unicode_in_nsi_if_you_remove_this[sizeof(OSVERSIONINFO) == sizeof(OSVERSIONINFOA)];
HINSTANCE g_hInst;
int g_CallbackAddr1 = 0;
int g_CallbackAddr2 = 0;
UINT_PTR __cdecl NsisPluginCallback(int Reason)
{
return 0;
}
NPPUBEXPORT SetCallback1(HWND hWndNsis, UINT cchNsis, PTSTR Vars, stack_t **ppST, extra_parameters*pXP, ...)
{
LPTSTR r0 = Vars;
g_CallbackAddr1 = _ttoi(r0);
// Note: Not calling RegisterPluginCallback. The script must use /NoUnload!
}
NPPUBEXPORT SetCallback2(HWND hWndNsis, UINT cchNsis, PTSTR Vars, stack_t **ppST, extra_parameters*pXP, ...)
{
LPTSTR r0 = Vars;
g_CallbackAddr2 = _ttoi(r0);
pXP->RegisterPluginCallback(g_hInst, NsisPluginCallback); // Prevent FreeLibrary
}
NPPUBEXPORT Trigger(HWND hWndNsis, UINT cchNsis, PTSTR Vars, stack_t **ppST, extra_parameters*pXP, ...)
{
for (;;)
{
switch(MessageBox(hWndNsis, TEXT("\"Try Again\" for callback 1\n\n\"Continue\" for callback 2"), TEXT("?"), MB_ICONQUESTION|MB_CANCELTRYCONTINUE))
{
case IDCANCEL:
return;
case IDTRYAGAIN:
if (g_CallbackAddr1) pXP->ExecuteCodeSegment(g_CallbackAddr1 - 1, NULL);
break;
case IDCONTINUE:
if (g_CallbackAddr2) pXP->ExecuteCodeSegment(g_CallbackAddr2 - 1, NULL);
break;
}
}
}
EXTERN_C BOOL WINAPI _DllMainCRTStartup(HINSTANCE hInst, DWORD, void*)
{
g_hInst = hInst;
return TRUE;
}
#if 0
!endif
#endif
#endif
Leave a comment: