diff --git a/Contrib/Banner/Banner.c b/Contrib/Banner/Banner.c index 3f670ef6..bd24aaaa 100644 --- a/Contrib/Banner/Banner.c +++ b/Contrib/Banner/Banner.c @@ -14,28 +14,75 @@ HINSTANCE hInstance; HWND hwBanner; +HANDLE hThread; char buf[1024]; unsigned int myatoi(char *s); -BOOL CALLBACK bannerProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam) +BOOL CALLBACK BannerProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam) { if (uMsg == WM_INITDIALOG) { + int iMainStringSet = 0; + popstring(buf); - while (*(int*)buf == CHAR4_TO_DWORD('/','s','e','t')) { + while (*(int*)buf == CHAR4_TO_DWORD('/','s','e','t') && !buf[4]) + { unsigned int id; popstring(buf); id = myatoi(buf); popstring(buf); - SetDlgItemText(hwndDlg,id,buf); + SetDlgItemText(hwndDlg, id, buf); popstring(buf); + + if (id == IDC_STR) + iMainStringSet++; } - SetWindowText(hwndDlg,buf); - SetDlgItemText(hwndDlg,IDC_STR,buf); - ShowWindow(hwndDlg,SW_SHOW); + + SetWindowText(hwndDlg, buf); + if (!iMainStringSet) + SetDlgItemText(hwndDlg, IDC_STR, buf); + + if (!*buf) + SetWindowLong(hwndDlg, GWL_EXSTYLE, GetWindowLong(hwndDlg, GWL_EXSTYLE) | WS_EX_TOOLWINDOW); } + if (uMsg == WM_CLOSE) + { + DestroyWindow(hwndDlg); + } + return 0; +} + +DWORD WINAPI BannerThread(LPVOID lpParameter) +{ + HWND hwndParent = (HWND) lpParameter; + HWND lhwBanner; + MSG msg; + //BOOL bRet; + + lhwBanner = CreateDialog( + GetModuleHandle(0), + MAKEINTRESOURCE(IDD_VERIFY), + hwndParent, + BannerProc + ); + + while (IsWindow(lhwBanner)) + { + if (PeekMessage(&msg, lhwBanner, 0, 0, PM_REMOVE)) + { + DispatchMessage(&msg); + } + else + { + hwBanner = lhwBanner; + WaitMessage(); + } + } + + hwBanner = NULL; + return 0; } @@ -43,21 +90,72 @@ void __declspec(dllexport) show(HWND hwndParent, int string_size, char *variable { EXDLL_INIT(); - hwBanner = CreateDialog( - GetModuleHandle(0), - MAKEINTRESOURCE(IDD_VERIFY), - hwndParent, - bannerProc - ); + { + DWORD dwThreadId; + + hwBanner = NULL; + + hThread = CreateThread(0, 0, BannerThread, (LPVOID) hwndParent, 0, &dwThreadId); + + // wait for the window to initalize and for the stack operations to finish + while (hThread && !hwBanner) + { + Sleep(10); + } + + CloseHandle(hThread); + + ShowWindow(hwBanner, SW_SHOW); + } } void __declspec(dllexport) destroy(HWND hwndParent, int string_size, char *variables, stack_t **stacktop) { - DestroyWindow(hwBanner); + if (!hwBanner) + return; + + PostMessage(hwBanner, WM_CLOSE, 0, 0); + + if (!hwndParent) + { + // create a dummy window on the thread the NSIS window will be created on and set it + // as the foreground window so this thread will return to be the foreground window + HWND hwTemp; + + AttachThreadInput(GetWindowThreadProcessId(hwndParent, 0), GetCurrentThreadId(), TRUE); + + hwTemp = CreateWindowEx( + WS_EX_TOOLWINDOW, + "STATIC", + "", + WS_VISIBLE | WS_POPUP, + -1, + -1, + 1, + 1, + 0, + 0, + hInstance, + 0 + ); + SetForegroundWindow(hwTemp); + DestroyWindow(hwTemp); + + AttachThreadInput(GetWindowThreadProcessId(hwndParent, 0), GetCurrentThreadId(), FALSE); + } + + // Wait for the thread to finish + while (hwBanner) + Sleep(25); } BOOL WINAPI _DllMainCRTStartup(HANDLE hInst, ULONG ul_reason_for_call, LPVOID lpReserved) { + hInstance = hInst; + if (hwBanner && ul_reason_for_call == DLL_PROCESS_DETACH) + { + destroy(0, 0, 0, 0); + } return TRUE; } diff --git a/Contrib/Banner/Banner.dsp b/Contrib/Banner/Banner.dsp index 84b7ff41..1762caff 100644 --- a/Contrib/Banner/Banner.dsp +++ b/Contrib/Banner/Banner.dsp @@ -54,7 +54,7 @@ BSC32=bscmake.exe # ADD BSC32 /nologo LINK32=link.exe # ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /machine:I386 -# ADD LINK32 kernel32.lib user32.lib gdi32.lib comdlg32.lib advapi32.lib shell32.lib /nologo /entry:"_DllMainCRTStartup" /dll /machine:I386 /nodefaultlib /out:"../../Plugins/Banner.dll" /opt:nowin98 +# ADD LINK32 kernel32.lib user32.lib gdi32.lib comdlg32.lib advapi32.lib shell32.lib /nologo /entry:"_DllMainCRTStartup" /dll /map /machine:I386 /nodefaultlib /out:"../../Plugins/Banner.dll" /opt:nowin98 # SUBTRACT LINK32 /pdb:none !ELSEIF "$(CFG)" == "Banner - Win32 Debug" diff --git a/Contrib/Banner/Readme.txt b/Contrib/Banner/Readme.txt index d6bf2b09..74393a47 100644 --- a/Contrib/Banner/Readme.txt +++ b/Contrib/Banner/Readme.txt @@ -30,4 +30,16 @@ Example: Banner::show /NOUNLOAD /set 76 "bah #1" /set 54 "bah #2" "Normal text" -The second parameter for /set is the ID of the control. \ No newline at end of file +The second parameter for /set is the ID of the control. + +Some More Tricks +---------------- + +If you use /set to set the main string (IDC_STR, 1030) you can specify a different string for the window's caption and for the main string. + +If you use an empty string as the main string (Banner::show /NOUNLOAD "") the banner window will not show on the taskbar. + +Credits +------- + +A joint effort of brainsucker and kichik in honor of the messages dropped during the battle \ No newline at end of file diff --git a/Plugins/Banner.dll b/Plugins/Banner.dll index 3137dacd..34fce603 100644 Binary files a/Plugins/Banner.dll and b/Plugins/Banner.dll differ