From a488b6295051b298171ddf9b510d50701e4d5102 Mon Sep 17 00:00:00 2001 From: kichik Date: Fri, 12 Sep 2003 16:45:22 +0000 Subject: [PATCH] New and improved banner: - No more crashes - Responds to messages (and thus redraws itself) - Doesn't put the main window on the background - Some new /set tricks by brainsucker git-svn-id: https://svn.code.sf.net/p/nsis/code/NSIS/trunk@2909 212acab6-be3b-0410-9dea-997c60f758d6 --- Contrib/Banner/Banner.c | 124 ++++++++++++++++++++++++++++++++++---- Contrib/Banner/Banner.dsp | 2 +- Contrib/Banner/Readme.txt | 14 ++++- Plugins/Banner.dll | Bin 2560 -> 4096 bytes 4 files changed, 125 insertions(+), 15 deletions(-) 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 3137dacd0fdc08f018e0d5e4898ec36ac5a8df20..34fce60331db5a13f6ca6f4259709eb77dec31fd 100644 GIT binary patch literal 4096 zcmeHKZ)_7~7=JptS>ZO0WldNjdc$fU;=H@^#{tuhwT#6fb?t7Oz@W63wYBRl?Og^q z<8Usz)FG06(L{7CN=!8FgCD>I(rkz!W(I=>6B8w9Vv|mTAx!yT&fk0O7=D1nFNTCY z&F`M~`8|K$=Y8(dUbjDggccEz9WYIzlh8~&*7eSp3vgFF^mzq+cK>wENn6WwO)wfu z3%x0=I~D2?!l7hR(}jJikTQ}&EGc+*1cV+fqSls|FLo76|NQa#FHcN&jLxHTbON^P zi_+2K(AR#Cj(!N;@!Kv-x5mOz7JIwS{63-UejEb$O! zYg1}M3lmK+280z?!HjwF5N(;a7FKuD1fDz8@8WnHQTx)N_t4m2#AT;In{q}FiC1zT zfXb{81>!qTm*G*!Zy2a|!9&JICHFdF-X% zZhBq(p?X&EiL|Qgr!)Po zHdtM|r^eXcihFj`xuvfjWp_)7vqSBIw@!CCj01tT_Dp>hOSPGoGAlZ;@?+DBna6`{ zX?~}e>sGNEO5BEz88@RSb0k`Yj-&Wq;G+YuO{bql4|`q9O=k<1n0!^?_FxQFL6q9F zduQGeuP(G+Jj&Issf^cUA7^{GvvsAcU%j%;og-h6_v2EZ#DBLrmwV(8z-P*9lbC5IqRUfCtzHbO3gMNk8-(z%gI~m;}BB zt^l(@*-D~HU=^?)XaTx_6mS?|^1fgx>yktc!OjA6atv|8E%qGG^#9S{bz4(H+ZRe~ zO{pr;sYQvjo(lIKXdvpdHL3b`En+0pZJ}f&p@OTW#)OtG+SI%#kWkfLicw=q4e4qy z3Kb!Gie)w$sg#=33tThUXMC;C`dZv_Z6tx0fVau3Vk_-Hdn_5z`sn47fT|bPEn2c0 zdnH+we=$SzF+u#|Bc_!x-b8n^uJ#nD>5}$POy91i)1hva#>g8>_lERvw8$XGwE0!_ zg?alETXVYD1ho}U;*Et8TDL!hS2<+7RT7A5eRDAi+jFayQoB={k&G1Sy~WIe>D%8x zOQ=EDL*Zy~0?A%Orx)kXRG|GSEsS2-d~79tEj`ycc5MszTIZ%U|5VJq+s)v)v4Jir z;(OSafgJGTGNK;fPpnOVMQ*_hshYB8A1Mr;(l``z-m?-2HUyg+@7d!o931}@*#D7g z@e$E2#>IZ|u=uX{k$74>FJ2LI;x(~cs+I)lQK?R9l6FXKQdlyim!u)-sPv9>Tsk3r wDxH$fNav+*q)XCI(sju$SIE`!!}11sv)m-N%DZG;J}AE?zbP*a`|g{-KWSnNivR!s delta 804 zcmah{O=uHA6n?X$A+4c~r71yM-P9!(Ea_mYP-rkJHeSBiJ}+$>HCQqho>hKvX(Y&I7BqaY_zl% zJ6P9NsoArI*@+Y=O&jVu2TQ26nAd!T%&n}yQFw@sLGCh-vfZrPJg4;8P}WuO>}c^B zQx^^7IvEz(ub3-rr|-H9RT%=9^sfbo0>1c!F#%DtVG#vSn>nC3o5Qj!0LU)Kg04Jd z<{aa>tCuwg$Bq}yM56k0RS+N1tCOh7r!;rI!>tm3(UX}nzIv-ipz77Pa-9uoTGbEl z+M-jp46QwCz1OSV5c>Uck5S!t7qwii=++Zt{z2%pj?%9O7Wa~I> zLr31O&oay9K)$y;UI7A?d{A>FDS?0IC6YBk&5dEsQmp|&GM%K70~yPOQ{%&ys~uEQ z`-oSp{gNz~3Z=3zZ&%pRZI$Q&a08I`MkV?PRDs_B_fXB^@ay(e`hX#M(^S-P6(`&I z{~gVBN8k3tq3}>>uy>y?o=OoFlt?0-9hp8GPiM`?jb5{*sZGB{!KsXKK7DCJr)VS; zt~b=@)*o65^BF{Wl@c+;r+@^ohKKS5$imNg%+F1C_9Buu(=2w0uox3*aYft|cg4JT YCdy)2tcX?dMSK%K#V@h2&G~`-0mR3<5C8xG