diff --git a/Contrib/AdvSplash/Example.nsi b/Contrib/AdvSplash/Example.nsi index 3337ed17..86603705 100644 --- a/Contrib/AdvSplash/Example.nsi +++ b/Contrib/AdvSplash/Example.nsi @@ -7,25 +7,28 @@ XPStyle on Function .onInit # the plugins dir is automatically deleted when the installer exits InitPluginsDir - File /oname=$PLUGINSDIR\splash.bmp "${NSISDIR}\Contrib\Makensisw\logo.bmp" + File /oname=$PLUGINSDIR\splash.bmp "${NSISDIR}\Contrib\Icons\modern-header.bmp" #optional #File /oname=$PLUGINSDIR\splash.wav "C:\myprog\sound.wav" + MessageBox MB_OK "Fading" + advsplash::show 1000 600 400 -1 $PLUGINSDIR\splash - Pop $0 ; $0 has '1' if the user closed the splash screen early, + Pop $0 ; $0 has '1' if the user closed the splash screen early, ; '0' if everything closed normal, and '-1' if some error occured. - MessageBox MB_OK "Now with transparency" + MessageBox MB_OK "Transparency" + File /oname=$PLUGINSDIR\splash.bmp "${NSISDIR}\Contrib\Makensisw\logo.bmp" + advsplash::show 2000 0 0 0x1856B1 $PLUGINSDIR\splash + Pop $0 - File /oname=$PLUGINSDIR\splash.bmp "${NSISDIR}\Contrib\Icons\modern.bmp" - - advsplash::show 1000 600 400 0xFF00FF $PLUGINSDIR\splash - - Pop $0 ; $0 has '1' if the user closed the splash screen early, - ; '0' if everything closed normal, and '-1' if some error occured. - MessageBox MB_OK "$0" + MessageBox MB_OK "Transparency/Fading" + File /oname=$PLUGINSDIR\splash.bmp "${NSISDIR}\Contrib\Icons\modern-wizard llama.bmp" + advsplash::show 1000 600 400 0x00005B $PLUGINSDIR\splash + Pop $0 + Delete $PLUGINSDIR\splash.bmp FunctionEnd Section diff --git a/Contrib/AdvSplash/advsplash.c b/Contrib/AdvSplash/advsplash.c index 47539e12..c7abc309 100644 --- a/Contrib/AdvSplash/advsplash.c +++ b/Contrib/AdvSplash/advsplash.c @@ -2,80 +2,284 @@ #define _WIN32_WINNT 0x0500 #include -#include "../exdll/exdll.h" +#include +#include "..\exdll\exdll.h" HINSTANCE g_hInstance; -#define RESOLUTION 20 // 50 fps ;) -#define KEYCOLOR_8BIT_RGBSUPPORT 1 // Includes (1) code for - // specifing key color for 8bit images as RGB +#define RESOLUTION 32 // 30 fps ;) (32? I like SHR more than iDIV ;) BITMAP bm; HBITMAP g_hbm; -int g_rv=-1; -int resolution = RESOLUTION; +int g_rv; +int resolution; int sleep_val, fadein_val, fadeout_val, state, timeleft, keycolor, nt50, alphaparam; -int call = -1; +const char classname[4]="_sp"; typedef BOOL (_stdcall *_tSetLayeredWindowAttributesProc)(HWND hwnd, // handle to the layered window COLORREF crKey, // specifies the color key BYTE bAlpha, // value for the blend function DWORD dwFlags // action ); - - _tSetLayeredWindowAttributesProc SetLayeredWindowAttributesProc; static LRESULT CALLBACK WndProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam) { - if (uMsg == WM_CREATE) - { - RECT vp; - - SystemParametersInfo(SPI_GETWORKAREA, 0, &vp, 0); - SetWindowLong(hwnd,GWL_STYLE,0); - SetWindowPos(hwnd,NULL, - vp.left+(vp.right-vp.left-bm.bmWidth)/2, - vp.top+(vp.bottom-vp.top-bm.bmHeight)/2, - bm.bmWidth,bm.bmHeight, - SWP_NOZORDER); - ShowWindow(hwnd,SW_SHOW); - - return 0; - } - if (uMsg == WM_PAINT) - { PAINTSTRUCT ps; RECT r; - - HDC curdc=BeginPaint(hwnd,&ps); - HDC hdc=CreateCompatibleDC(curdc); + HDC curdc = NULL; + HDC hdc; HBITMAP oldbm; - oldbm=(HBITMAP)SelectObject(hdc,g_hbm); - GetClientRect(hwnd,&r); - BitBlt(curdc,r.left,r.top,r.right-r.left,r.bottom-r.top,hdc,0,0,SRCCOPY); + switch (uMsg) + { + case WM_CREATE: + SystemParametersInfo(SPI_GETWORKAREA, 0, &r, 0); + SetWindowLong(hwnd,GWL_STYLE,0); + SetWindowPos(hwnd,NULL, + r.left+(r.right-r.left-bm.bmWidth)/2, + r.top+(r.bottom-r.top-bm.bmHeight)/2, + bm.bmWidth,bm.bmHeight, + SWP_NOZORDER | SWP_SHOWWINDOW); + return 0; + + case WM_PAINT: + curdc=BeginPaint(hwnd,&ps); + hdc=CreateCompatibleDC(curdc); + GetClientRect(hwnd,&r); + + oldbm = SelectObject(hdc, g_hbm); + BitBlt(curdc,r.left,r.top,r.right-r.left,r.bottom-r.top,hdc,0,0, SRCCOPY); - SelectObject(hdc,oldbm); - DeleteDC(hdc); - EndPaint(hwnd,&ps); - return 0; - } - if (uMsg == WM_CLOSE) return 0; - if (uMsg == WM_TIMER || uMsg == WM_LBUTTONDOWN) - { - g_rv=(uMsg == WM_LBUTTONDOWN); - DestroyWindow(hwnd); - } - return DefWindowProc(hwnd,uMsg,wParam,lParam); + SelectObject(hdc,oldbm); + DeleteDC(hdc); + EndPaint(hwnd,&ps); + + case WM_CLOSE: + return 0; + + case WM_TIMER: + case WM_LBUTTONDOWN: + g_rv=(uMsg == WM_LBUTTONDOWN); + DestroyWindow(hwnd); + break; + } + return DefWindowProc(hwnd,uMsg,wParam,lParam); +} + +void SetTransparentRegion(HWND myWnd) +{ + HDC dc; + int x, y; + HRGN region, cutrgn; + BITMAPINFO bmi; + int size = bm.bmWidth * bm.bmHeight*4; + int *bmp = GlobalAlloc(GPTR, size); + bmi.bmiHeader.biBitCount = 32; + bmi.bmiHeader.biCompression = BI_RGB; + bmi.bmiHeader.biHeight = bm.bmHeight; + bmi.bmiHeader.biPlanes = 1; + bmi.bmiHeader.biSize = sizeof(BITMAPINFOHEADER); + bmi.bmiHeader.biWidth = bm.bmWidth; + bmi.bmiHeader.biClrUsed = 0; + bmi.bmiHeader.biClrImportant = 0; + + dc = CreateCompatibleDC(NULL); + SelectObject(dc, g_hbm); + + x = GetDIBits(dc, g_hbm, 0, bm.bmHeight, bmp, &bmi, DIB_RGB_COLORS); + + region = CreateRectRgn(0,0,bm.bmWidth,bm.bmHeight); + + // Search for transparent pixels + for (y = bm.bmHeight-1; y >= 0; y--) + for (x = 0; x < bm.bmWidth; ) + if ((*bmp & 0xFFFFFF) == keycolor) + { + int j = x; + while ((x < bm.bmWidth) && ((*bmp & 0xFFFFFF) == keycolor)) bmp++, x++; + + // Cut transparent pixels from the original region + cutrgn = CreateRectRgn(j, y, x, y+1); + CombineRgn(region, region, cutrgn, RGN_XOR); + DeleteObject(cutrgn); + } else bmp++, x++; + + // Set resulting region. + SetWindowRgn(myWnd, region, TRUE); + DeleteObject(region); + DeleteObject(dc); + GlobalFree(bmp); } BOOL WINAPI _DllMainCRTStartup(HANDLE hInst, ULONG ul_reason_for_call, LPVOID lpReserved) { - g_hInstance=hInst; - return TRUE; + g_hInstance=hInst; + return TRUE; } +void CALLBACK TimeProc( + UINT uID, + UINT uMsg, + DWORD dwUser, + DWORD dw1, + DWORD dw2) +{ + int call = -1; + switch (state) + { + // FadeIN + case 0: if (timeleft == 0) + { + timeleft = sleep_val; + state++; + if (nt50) call = 255; + } else { call = ((fadein_val-timeleft)*255)/fadein_val; break; } + // Sleep + case 1: if (timeleft == 0) + { + timeleft = fadeout_val; + state++; + // fadeout + } else break; + // FadeOUT + case 2: if (timeleft == 0) + { + PostMessage((HWND)dwUser, WM_TIMER, 0, 0); + return; + } else { call = ((timeleft)*255)/fadeout_val; break; } + } + // Transparency value aquired, and could be set... + if ((call >= 0) && nt50) + SetLayeredWindowAttributesProc((HWND)dwUser, keycolor, + call, + alphaparam); + + // Time is running out... + timeleft--; +} + +int myatoi(char *s); + +void __declspec(dllexport) show(HWND hwndParent, int string_size, char *variables, stack_t **stacktop) +{ + DEVMODE dm; + char fn[MAX_PATH]; + char temp[64]; + + g_rv = -1; + resolution = RESOLUTION; + + EXDLL_INIT(); + + popstring(temp); + sleep_val = myatoi(temp); + popstring(temp); + fadein_val = myatoi(temp); + popstring(temp); + fadeout_val = myatoi(temp); + popstring(temp); + keycolor = myatoi(temp); + popstring(fn); + + dm.dmSize = sizeof(DEVMODE); + EnumDisplaySettings(NULL, ENUM_CURRENT_SETTINGS, &dm); + // Check for winXP/2k at 32 bpp transparency + nt50 = (LOBYTE(LOWORD(GetVersion())) >= 5) && !((dm.dmBitsPerPel < 32) && (keycolor != -1)); + if (!nt50) + { + // Fading+transparency is unsupported at old windows versions... + resolution = sleep_val + fadein_val + fadeout_val; + fadeout_val = fadein_val = 0; + sleep_val = 1; + } else + { + // div them by resolution + sleep_val >>= 5; + fadein_val >>= 5; + fadeout_val >>= 5; + + alphaparam = LWA_ALPHA | ((keycolor == -1)?(0):(LWA_COLORKEY)); + keycolor = ((keycolor & 0xFF) << 16) + (keycolor & 0xFF00) + ((keycolor & 0xFF0000) >> 16); + } + + if (fn[0] && ((sleep_val+fadein_val+fadeout_val)>0)) + { + MSG msg; + static WNDCLASS wc; + wc.lpfnWndProc = WndProc; + wc.hInstance = g_hInstance; + wc.hCursor = LoadCursor(NULL,IDC_ARROW); + wc.lpszClassName = classname; + if (RegisterClass(&wc)) + { + char fn2[MAX_PATH]; + lstrcpy(fn2,fn); + lstrcat(fn,".bmp"); + lstrcat(fn2,".wav"); + g_hbm=LoadImage(NULL,fn,IMAGE_BITMAP,0,0,LR_CREATEDIBSECTION|LR_LOADFROMFILE); + if (g_hbm) + { + HWND myWnd; + UINT timerEvent; + + // Get Bitmap Information + GetObject(g_hbm, sizeof(bm), (LPSTR)&bm); + + myWnd = CreateWindowEx(WS_EX_TOOLWINDOW | ((nt50)?(WS_EX_LAYERED):(0)),classname,classname, + 0,0,0,0,0,(HWND)hwndParent,NULL,g_hInstance,NULL); + + // Set transparency / key color + if (nt50) + { + // Get blending proc address + HANDLE user32 = GetModuleHandle("user32"); + SetLayeredWindowAttributesProc = (_tSetLayeredWindowAttributesProc) GetProcAddress(user32, "SetLayeredWindowAttributes"); + // Use win2k method + SetLayeredWindowAttributesProc(myWnd, keycolor, + (fadein_val > 0)?(0):(255), + alphaparam); + } else + if (keycolor != -1) + { + // transparency mode + SetTransparentRegion(myWnd); + } + + PlaySound(fn2,NULL,SND_ASYNC|SND_FILENAME|SND_NODEFAULT); + + // Start up timer... + state = 0; timeleft = fadein_val; + timerEvent = timeSetEvent(resolution, RESOLUTION/4, TimeProc, (DWORD_PTR)myWnd, TIME_PERIODIC); + + while (IsWindow(myWnd) && GetMessage(&msg,myWnd,0,0)) + { + DispatchMessage(&msg); + } + + // Kill the timer... + timeKillEvent(timerEvent); + + // Stop currently playing wave, we want to exit + PlaySound(0,0,0); + + DeleteObject(g_hbm); + } + + // We should UnRegister class, since Windows NT series never does this by itself + UnregisterClass(wc.lpszClassName, g_hInstance); + } + } + wsprintf(temp,"%d",g_rv); + pushstring(temp); +} + +#ifdef _DEBUG +void main() +{ +} +#endif + int myatoi(char *s) { unsigned int v=0; @@ -120,219 +324,3 @@ int myatoi(char *s) } return (int)v; } - -void CALLBACK TimeProc( - UINT uID, - UINT uMsg, - DWORD dwUser, - DWORD dw1, - DWORD dw2) -{ - switch (state) - { - // FadeIN - case 0: if (timeleft == 0) - { - timeleft = sleep_val; - state++; - if (nt50) call = 255; - } else { call = ((fadein_val-timeleft)*255)/fadein_val; break; } - // Sleep - case 1: if (timeleft == 0) - { - timeleft = fadeout_val; - state++; - } else break; - // FadeOUT - case 2: if (timeleft == 0) - { - PostMessage((HWND)dwUser, WM_TIMER, 0, 0); - return; - } else { call = ((timeleft)*255)/fadeout_val; break; } - } - // Transparency value aquired, and could be set... - if ((call >= 0) && nt50) - SetLayeredWindowAttributesProc((HWND)dwUser, keycolor, - call, - alphaparam); - call = -1; - // Time is running out... - timeleft--; -} - -void __declspec(dllexport) show(HWND hwndParent, int string_size, char *variables, stack_t **stacktop) -{ - char fn[MAX_PATH]; - char temp[64]; - char *sleep=temp; - - EXDLL_INIT(); - - popstring(temp); - sleep_val = myatoi(temp) / RESOLUTION; - popstring(temp); - fadein_val = myatoi(temp) / RESOLUTION; - popstring(temp); - fadeout_val = myatoi(temp) / RESOLUTION; - popstring(temp); - keycolor = myatoi(temp); - popstring(fn); - - // Check for winXP/2k - nt50 = (LOBYTE(LOWORD(GetVersion())) >= 5); - if (!nt50) - { - // Fading is unsupported at old windows versions... - resolution = (sleep_val + fadein_val + fadeout_val) * RESOLUTION; - fadeout_val = fadein_val = 0; - sleep_val = 1; - } else alphaparam = LWA_ALPHA | ((keycolor == -1)?(0):(LWA_COLORKEY)); - - if (fn[0] && sleep_val>0) - { - MSG msg; - char classname[4]="_sp"; - static WNDCLASS wc; - wc.lpfnWndProc = WndProc; - wc.hInstance = g_hInstance; - wc.hCursor = LoadCursor(NULL,IDC_ARROW); - wc.lpszClassName = classname; - if (RegisterClass(&wc)) - { - char fn2[MAX_PATH]; - lstrcpy(fn2,fn); - lstrcat(fn,".bmp"); - lstrcat(fn2,".wav"); - g_hbm=LoadImage(NULL,fn,IMAGE_BITMAP,0,0,LR_CREATEDIBSECTION|LR_LOADFROMFILE); - if (g_hbm) - { - HWND myWnd; - UINT timerEvent; - - // Get Bitmap Information - GetObject(g_hbm, sizeof(bm), (LPSTR)&bm); - - myWnd = CreateWindowEx(WS_EX_TOOLWINDOW | ((nt50)?(WS_EX_LAYERED):(0)),classname,classname, - 0,0,0,0,0,(HWND)hwndParent,NULL,g_hInstance,NULL); - - // Set transparency / key color - if (nt50) - { - // Get blending proc address - HANDLE user32 = GetModuleHandle("user32"); - SetLayeredWindowAttributesProc = (_tSetLayeredWindowAttributesProc) GetProcAddress(user32, "SetLayeredWindowAttributes"); - // Use win2k method - SetLayeredWindowAttributesProc(myWnd, keycolor, - (fadein_val > 0)?(0):(255), - alphaparam); - } else - if (keycolor != -1) - { - // Use simpliest region method - int x, y, wdelta; - HRGN region, cutrgn; - BYTE *bmp = bm.bmBits; - - region = CreateRectRgn(0,0,bm.bmWidth,bm.bmHeight); - //region = CreateRectRgn(0,0,0,0); - - if (bm.bmBitsPixel == 8) - { -#if (KEYCOLOR_8BIT_RGBSUPPORT == 1) - HDC hMemDC; - HBITMAP hOldBitmap; - int rgb[256]; - int nColors; - - // Find out how many colors are in the color table - nColors = 1 << bm.bmBitsPixel; - // Create a memory DC and select the DIBSection into it - hMemDC = CreateCompatibleDC(NULL); - hOldBitmap = SelectObject(hMemDC,g_hbm); - // Get the DIBSection's color table - GetDIBColorTable(hMemDC,0,nColors,(RGBQUAD*)rgb); - - // Find our keycolor at palette - if (keycolor < 0x1000000) - { - for (x = 0; x < nColors; x++) - if (rgb[x] == keycolor) { keycolor = x; break; } - } else keycolor &= 0xff; - - // Free used objects - SelectObject(hMemDC,hOldBitmap); - DeleteDC(hMemDC); -#endif - - // Bitmap is DWORD aligned by width - //wdelta = (( bm.bmWidth + 3 ) & ~3) - bm.bmWidth; - wdelta = ((bm.bmWidth + 3) & 3) ^ 3; - // Search for transparent pixels - for (y = bm.bmHeight-1; y >= 0; y--, bmp += wdelta) - for (x = 0; x < bm.bmWidth; ) - if (*bmp == (BYTE) keycolor) - { - int j = x; - while ((x < bm.bmWidth) && (*bmp == (BYTE) keycolor)) x++, bmp++; - - // Cut transparent pixels from the original region - cutrgn = CreateRectRgn(j, y, x, y+1); - CombineRgn(region, region, cutrgn, RGN_XOR); - DeleteObject(cutrgn); - } else bmp++, x++; - } else if (bm.bmBitsPixel == 24) - { - // Bitmap is DWORD aligned by width - wdelta = ((bm.bmWidth*3 + 3 ) & 3) ^ 3; - // Search for transparent pixels - for (y = bm.bmHeight-1; y >= 0; y--, bmp += wdelta) - for (x = 0; x < bm.bmWidth; ) - if ((*(int*)bmp & 0xFFFFFF) == keycolor) - { - int j = x; - while ((x < bm.bmWidth) && ((*(int*)bmp & 0xFFFFFF) == keycolor)) bmp+=3, x++; - - // Cut transparent pixels from the original region - cutrgn = CreateRectRgn(j, y, x, y+1); - CombineRgn(region, region, cutrgn, RGN_XOR); - DeleteObject(cutrgn); - } else bmp += 3, x++; - } - - // Set resulting region. - SetWindowRgn(myWnd, region, TRUE); - } - - PlaySound(fn2,NULL,SND_ASYNC|SND_FILENAME|SND_NODEFAULT); - - // Start up timer... - state = 0; timeleft = fadein_val; - timerEvent = timeSetEvent(resolution, RESOLUTION/4, TimeProc, (DWORD_PTR)myWnd, TIME_PERIODIC); - - while (IsWindow(myWnd) && GetMessage(&msg,myWnd,0,0)) - { - DispatchMessage(&msg); - } - - // Kill the timer... - timeKillEvent(timerEvent); - - // Stop currently playing wave, we want to exit - PlaySound(0,0,0); - - DeleteObject(g_hbm); - } - - // We should UnRegister class, since Windows NT series never does this by itself - UnregisterClass(wc.lpszClassName, g_hInstance); - } - } - wsprintf(temp,"%d",g_rv); - pushstring(temp); -} - -#ifdef _DEBUG -void main() -{ -} -#endif \ No newline at end of file diff --git a/Contrib/AdvSplash/advsplash.txt b/Contrib/AdvSplash/advsplash.txt index ef0094c3..02da65cb 100644 --- a/Contrib/AdvSplash/advsplash.txt +++ b/Contrib/AdvSplash/advsplash.txt @@ -1,6 +1,6 @@ -AdvSplash.exe - small (6.0k), simple plugin that lets you throw +AdvSplash.exe - small (5.5k), simple plugin that lets you throw up a splash screen in NSIS installers with cool fading effects (win2k/xp) -and transparency (24bit/8bit bitmaps). +and transparency. To use: @@ -31,13 +31,9 @@ Calling format Delay - length to show the screen for (in milliseconds) FadeIn - length to show the fadein scene (in ms) (not included in Delay) FadeOut - length to show the fadeout scene (in ms) (not included in Delay) -KeyColor - color used for transparency. For 24 bit bitmaps could be any RGB - value (for ex. R=255 G=100 B=16 -> KeyColor=0xFF6410), for 8 bit bitmaps - could be either RGB value or index of the color at bitmap palette - (if such RGB color present in your image and you'd like to use palette - index, use (0x1000000+index) as KeyColor [you should calculate - this value by yourself]). Use KeyColor=-1 if there is now transparent - color at your image. +KeyColor - color used for transparency, could be any RGB value + (for ex. R=255 G=100 B=16 -> KeyColor=0xFF6410), + use KeyColor=-1 if there is no transparent color at your image. FileName - splash bitmap filename (without the .bmp). The BMP file used will be this parameter.bmp, and the wave file used (if present) will be this parameter.wav. @@ -45,11 +41,11 @@ FileName - splash bitmap filename (without the .bmp). The BMP file used will be (If you already have an .onInit function, put that in it) Note 1: fadein/fadeout supported only on win2k/winxp systems, all other systems -will show simple splash screen with Delay = Delay + FadeIn + FadeOut. +will show simple splash screen with Delay = Delay + FadeIn + FadeOut. Also, I've +noted my winXP uses no transparent color at 16 bpp, so at bpps lower than 32 +for images with transparent color no fading effect will occur. -Note 2: transparency supported only for 24bit and 8bit bitmaps. - -Note 3: the return value of splash is 1 if the user closed the splash +Note 2: the return value of splash is 1 if the user closed the splash screen early (pop it from the stack) -Justin diff --git a/Plugins/advsplash.dll b/Plugins/advsplash.dll index bdaffb92..906d57c6 100644 Binary files a/Plugins/advsplash.dll and b/Plugins/advsplash.dll differ