This one, like the GoldFish animation, uses a layered window to display a 32-bit PNG
to create a nice splash screen with antialias variable opacity.
to create a nice splash screen with antialias variable opacity.
Code:
'+--------------------------------------------------------------------------+ '| Splash | '| | '| Example of 32-bit layered splash screen | '| | '+--------------------------------------------------------------------------+ '| | '| Author Patrice TERRIER | '| copyright(c) 2008 | '| www.zapsolution.com | '| [email protected] | '| | '+--------------------------------------------------------------------------+ '| Project started on : 09-19-2008 (MM-DD-YYYY) | '| Last revised : 09-20-2008 (MM-DD-YYYY) | '+--------------------------------------------------------------------------+ #COMPILE EXE "Splash.exe" #INCLUDE "Layered.inc" '------------------------------------------------------------------------------------------ ' LOCAL section '----------------------------------------------------------------------------------------- '$IMAGE_FullPathName = "GoldFish.png" '%FRAME_SizeX = 84 '// Must match the animation frame width '%FRAME_SizeY = 84 '// Must match the animation frame height '%FRAME_Count = 20 '// The frame number '%USE_StepX = 3 '// X step value in pixel '%USE_StepY = 1 '// Y step value in pixel $IMAGE_FullPathName = "GDImage.png" %FRAME_SizeX = 512 '// Must match the animation frame width %FRAME_SizeY = 382 '// Must match the animation frame height %FRAME_Count = 1 '// The frame number %USE_StepX = 0 '// X step value in pixel %USE_StepY = 0 '// Y step value in pixel '// Load the GDI+ Dll FUNCTION zGdipStart() AS LONG DIM GpInput AS GdiplusStartupInput GpInput.GdiplusVersion = 1 IF GdiplusStartup(hGDIplus&, GpInput) = 0 THEN FUNCTION = hGDIplus& END FUNCTION '// GDIPLUS unload (unload the GDIPLUS.DLL) SUB zGdipEnd(BYREF hGDIplus AS LONG) ' Unload the GDI+ Dll IF hGDIplus THEN CALL GdiplusShutdown(hGDIplus): hGDIplus = 0 END SUB '// Main entry point FUNCTION WINMAIN (BYVAL hInstance AS LONG, _ BYVAL hPrevInstance AS LONG, _ BYVAL lpCmdLine AS ASCIIZ PTR, _ BYVAL iCmdShow AS LONG) AS LONG LOCAL Msg AS tagMsg LOCAL wc AS WNDCLASSEXA LOCAL zClass AS ASCIIZ * 80 LOCAL dwExStyle AS DWORD LOCAL dwStyle AS DWORD LOCAL rc AS RECT LOCAL x AS LONG LOCAL y AS LONG LOCAL hMutex AS DWORD LOCAL hFound AS DWORD LOCAL hMain AS DWORD ' LOCAL IsInitialized AS LONG LOCAL hGDIplus AS LONG ' GDIPLUS zClass = "ZLAYERED" ' hMutex = CreateMutex(BYVAL %Null, 0, zClass) IF hMutex THEN IF GetLastError = %ERROR_ALREADY_EXISTS THEN DO hFound = FindWindow(zClass, ""): IF hFound THEN EXIT DO WHILE PeekMessage(Msg, %NULL, %NULL, %NULL, %PM_REMOVE): WEND LOOP IF IsIconic(hFound) THEN CALL ShowWindow(hFound, %SW_RESTORE) CALL SetForeGroundWindow(hFound) FUNCTION = 0 EXIT FUNCTION END IF END IF wc.cbSize = SIZEOF(wc) IsInitialized = GetClassInfoEx(GetModuleHandle(""), zClass, wc) IF IsInitialized = 0 THEN wc.cbSize = SIZEOF(wc) wc.style = %CS_HREDRAW OR %CS_VREDRAW OR %CS_DBLCLKS ' OR %CS_DROPSHADOW wc.lpfnWndProc = CODEPTR(WndProc) wc.cbClsExtra = 0 wc.cbWndExtra = 0 wc.hInstance = GetModuleHandle("") wc.hIcon = LoadIcon(wc.hInstance, "PROGRAM") wc.hCursor = LoadCursor(%NULL, BYVAL %IDC_ARROW) wc.hbrBackground = %NULL wc.lpszMenuName = %NULL wc.lpszClassName = VARPTR(zClass) wc.hIconSm = wc.hIcon IF RegisterClassEx(wc) THEN IsInitialized = %TRUE END IF ' IF IsInitialized THEN ' // Init GDIPLUS hGDIplus = zGdipStart() ' Window Extended Style dwExStyle = %WS_EX_LAYERED OR %WS_EX_TOPMOST ' Windows Style, avoid using %WS_CLIPSIBLINGS OR %WS_CLIPCHILDREN with the Skin Engine dwStyle = %WS_POPUP ' OR %WS_CLIPCHILDREN OR %WS_CLIPSIBLINGS ' CALL SetRect(rc, 0, 0, %FRAME_SizeX, %FRAME_SizeY) ' // Note: indeed we don't need AdjustWindowRectEx, because we use do not use a non-client area ' // but it won't hurt anything to keep it, in case we change our mind ;) CALL AdjustWindowRectEx(rc, dwStyle, %FALSE, dwExStyle) ' Adjust Window To True Requested Size ' x = MAX&((GetSystemMetrics(%SM_CXSCREEN) - rc.nRight - rc.nLeft) \ 2, 0) y = MAX&((GetSystemMetrics(%SM_CYSCREEN) - rc.nBottom - rc.nTop) \ 2, 0) ' ' Create The Window MyTitle$ = "Splash" hMain = CreateWindowEx(dwExStyle, _ ' Extended Style For The Window zClass, _ ' Class Name (MyTitle$), _ ' Window Title dwStyle, _ ' Defined Window Style x, y, _ ' Window Position rc.nRight - rc.nLeft, _ ' Calculate Window Width rc.nBottom - rc.nTop, _ ' Calculate Window Height %NULL, _ ' No Parent Window %NULL, _ ' No Menu wc.hInstance, _ ' Instance BYVAL %NULL) ' Dont Pass Anything To WM_CREATE ' IF hMain THEN CALL SetImage(hMain, $IMAGE_FullPathName, 255) CALL ShowWindow(hMain, %SW_SHOW) IF %FRAME_Count > 1 THEN CALL SetTimer(hMain, 1, 50, %NULL) WHILE GetMessage(Msg, %NULL, 0, 0) CALL TranslateMessage(Msg) CALL DispatchMessage(Msg) WEND IF %FRAME_Count > 1 THEN CALL KillTimer(hMain, 1) FUNCTION = msg.wParam END IF ' // UNLOAD GDIPLUS CALL zGdipEnd(hGDIplus) END IF ' IF hMutex THEN CALL CloseHandle(hMutex) ' END FUNCTION '// Main window procedure FUNCTION WndProc(BYVAL hWnd AS LONG, BYVAL Msg AS LONG, BYVAL wParam AS LONG, BYVAL lParam AS LONG) EXPORT AS LONG SELECT CASE LONG Msg CASE %WM_KEYDOWN IF wParam = &H1B& THEN '// VK_ESCAPE CALL DestroyWindow(hWnd) END IF CASE %WM_TIMER CALL SetImage(hWnd, $IMAGE_FullPathName, 255) CASE %WM_NCHITTEST FUNCTION = %HTCAPTION: EXIT FUNCTION CASE %WM_DESTROY CALL PostQuitMessage(0) FUNCTION = 0: EXIT FUNCTION END SELECT FUNCTION = DefWindowProc(hWnd, Msg, wParam, lParam) END FUNCTION SUB SetImage(BYVAL hWnd AS LONG, zFileName AS ASCIIZ, BYVAL alpha AS LONG) LOCAL graphics, DesktopDC, hMemDC, hBmp, OldBmp, Img, imgW, imgH, ImgAttr, x, y, nStepX, nStepY AS LONG LOCAL rw AS RECT, bmp AS BITMAP, bi AS BITMAPINFO LOCAL dwp AS DWORD PTR LOCAL bf AS BLENDFUNCTION LOCAL lp, ptSrc AS POINTAPI LOCAL lpSize AS SIZEL STATIC ToTheRight, nFrame AS LONG CALL GetWindowRect(hWnd, rw) lpSize.Cx = rw.nRight - rw.nLeft: lpSize.Cy = rw.nBottom - rw.nTop RANDOMIZE(TIMER) nStepX = %USE_StepX: nStepY = ((RND - 0.5) * 1.5) * %USE_StepY lp.Y = rw.nTop + nStepY IF ToTheRight THEN IF rw.nRight < GetSystemMetrics(%SM_CXSCREEN) + lpSize.Cx THEN lp.X = rw.nLeft + nStepX ELSE ToTheRight = 0 lp.X = rw.nLeft - nStepX END IF ELSE IF rw.nLeft > - lpSize.Cx THEN lp.X = rw.nLeft - nStepX ELSE ToTheRight = -1 lp.X = rw.nLeft + nStepX END IF END IF INCR nFrame: IF nFrame > %FRAME_Count THEN nFrame = 1 IF GdipLoadImageFromFile((UCODE$(zFileName)), Img) = 0 THEN IF ToTheRight THEN CALL GdipImageRotateFlip(Img, 4) CALL GdipGetImageWidth(Img, imgW) CALL GdipGetImageHeight(Img, imgH) DesktopDC = GetDC(0) '// Draw active frame to new memory DC hMemDC = CreateCompatibleDC(DesktopDC) hBmp = CreateCompatibleBitmap(DesktopDC, imgW, imgH) OldBmp = SelectObject(hMemDC, hBmp) IF GdipCreateFromHDC(hMemDC, graphics) = 0 THEN CALL GdipSetInterpolationMode(graphics, 2) CALL GdipDrawImageRectRectI(graphics, Img, 0, 0, lpSize.Cx, lpSize.Cy, nFrame * lpSize.Cx - lpSize.Cx, 0, lpSize.Cx, lpSize.Cy, 2, ImgAttr) CALL GdipDeleteGraphics(graphics) CALL GdipDisposeImage(Img) END IF CALL GetObject(hBmp, sizeof(bmp), bmp) bf.BlendOp = %AC_SRC_OVER bf.BlendFlags = 0 bf.AlphaFormat = %AC_SRC_ALPHA '// Use source alpha bf.SourceConstantAlpha = alpha CALL UpdateLayeredWindow (hWnd, DesktopDC, lp, lpSize, hMemDC, ptSrc, 0, bf, %ULW_ALPHA) END IF CALL SelectObject(hMemDC, OldBmp) CALL DeleteObject(hBmp) CALL DeleteDC(hMemDC) CALL ReleaseDC(0, DesktopDC) END SUB
Comment