Je partage avec vous un exemple montrant comment créer une animation temps réel à partir d'une image PNG 32-bit avec opacité variable et anti-aliasing.
J'ai écrit ce projet pour voir jusqu'où l'on pouvait aller dans l'utilisation de l'API bas niveau avec WinDev. Il n'y a donc aucun appel aux fonctions du w-langage, et tout le code est contenu dans la section "code source du projet".
Ce qui permet de réduire le framework WinDev aux 2 seules WD120VM.DLL et WD12STD.DLL lorsqu'on "compile" le projet.
Il existe une version de GoldFish codée en code managé sous C#, écrite par Davidwu (www.cnpopsoft.com).
La version que je vous propose est basée uniquement sur la FLAT API, elle ne nécessite donc pas le framework DotNET pour fonctionner.
La seule fonction qui m'a posé un problème sous windev est la gestion du code UNICODE lors de l'utilisation de l'API GDIPLUS "GdipLoadImageFromFile", pour laquelle je me suis servi de la fonction équivalente "zLoadImageFromFile" (GDImage).
Note: Afin de faciliter la conversion de ce code, celui-ci est écrit en anglais afin de ressembler au langage "BASIC" dont la syntaxe est très proche.
CODE D'INITIALISATION DU PROJET
CONSTANT
MAX_PATH = 260
ERROR_ALREADY_EXISTS = 183
AC_SRC_OVER = 0x00
AC_SRC_ALPHA = 0x01
SW_SHOW = 5
SW_RESTORE = 9
WM_DESTROY = 0x0002
WM_NCHITTEST = 0x0084
WM_KEYDOWN = 0x0100
WM_TIMER = 0x0113
HTCAPTION = 2
WS_POPUP = 0x80000000
WS_EX_TOPMOST = 0x00000008
WS_EX_LAYERED = 0x00080000
CS_VREDRAW = 0x0001
CS_HREDRAW = 0x0002
CS_DBLCLKS = 0x0008
PM_REMOVE = 0x0001
ULW_ALPHA = 0x00000002
SM_CXSCREEN = 0
SM_CYSCREEN = 1
IDC_ARROW = 32512
GDI32 = "GDI32"
USER32 = "USER32"
GDIPLUS = "GDIPLUS"
GDIMAGE = "GDIMAGE"
END
POINTAPI is structure
x is int
y is int
END
SIZEL is structure
cx is int
cy is int
END
RECT is structure
nLeft is int
nTop is int
nRight is int
nBottom is int
END
SECURITY_ATTRIBUTES is structure
nLength is int
lpSecurityDescriptor is int
bInheritHandle is int
END
TagMSG is structure
hWnd is int
nMessage is int
wParam is int
lParam is int
nTime is int
pt is POINTAPI
END
BITMAP is structure
bmType is int
bmWidth is int
bmHeight is int
bmWidthBytes is int
bmPlanes is 2-byte int
bmBitsPixel is 2-byte int
bmBits is int
END
BLENDFUNCTION is structure
BlendOp is 1-byte int
BlendFlags is 1-byte int
SourceConstantAlpha is 1-byte int
AlphaFormat is 1-byte int
END
WNDCLASSEXA is structure
cbSize is unsigned int
style is unsigned int
lpfnWndProc is int
cbClsExtra is int
cbWndExtra is int
hInstance is int
hIcon is int
hCursor is int
hbrBackground is int
lpszMenuName is int
lpszClassName is int
hIconSm is int
END
BITMAPINFOHEADER is structure
biSize is int
biWidth is int
biHeight is int
biPlanes is 2-byte int
biBitCount is 2-byte int
biCompression is int
biSizeImage is int
biXPelsPerMeter is int
biYPelsPerMeter is int
biClrUsed is int
biClrImportant is int
END
RGBQUAD is structure
bBlue is 1-byte int
bGreen is 1-byte int
bRed is 1-byte int
bReserved is 1-byte int
END
BITMAPINFO_API is structure
bmiHeader is BITMAPINFOHEADER
bmiColors is RGBQUAD
END
GdiplusStartupInput is structure
GdiplusVersion is int
DebugEventCallback is int
SuppressBackgroundThread is int
SuppressExternalCodecs is int
END
gnToTheRight, gnFrame are int
gsIMAGE_FullPathName is string = CompleteDir(fExeDir()) + "GoldFish.png"
gnFRAME_SizeX is int = 84
gnFRAME_SizeY is int = 84
gnFRAME_Count is int = 20
gnUSE_StepX is int = 3
gnUSE_StepY is int = 1
LOCAL
IF LoadDLL(GDIMAGE) THEN
nRet, x, y are int
wc is WNDCLASSEXA
zClass is string ASCIIZ on 16 = "ZANIMATION"
wcStyle is int = CS_HREDRAW + CS_VREDRAW
IsInitialized is int = API(USER32, "GetClassInfoExA", Instance, &zClass, &wc)
IF IsInitialized = 0 THEN
wc:cbSize = Dimension(wc)
wc:style = wcStyle
wc:lpfnWndProc = &WndProc
wc:cbClsExtra = 0
wc:cbWndExtra = 0
wc:hInstance = Instance
wc:hIcon = API(USER32, "LoadImageA", Null, "GoldFish.ico", 1, 0, 0, 0x00000010 + 0x00000040)
wc:hCursor = API(USER32, "LoadCursorA", Null, IDC_ARROW)
wc:hbrBackground = Null
wc:lpszMenuName = Null
wc:lpszClassName = &zClass
wc:hIconSm = Null
IF API(USER32, "RegisterClassExA", &wc) THEN IsInitialized = True
END
IF IsInitialized THEN
x = Max((API(USER32, "GetSystemMetrics", SM_CXSCREEN) - gnFRAME_SizeX) / 2, 0)
y = Max((API(USER32, "GetSystemMetrics", SM_CYSCREEN) - gnFRAME_SizeY) / 2, 0)
hMain is int = API(USER32, "CreateWindowExA", ...
WS_EX_LAYERED, ...
zClass, ...
"GoldFish", ...
WS_POPUP + WS_EX_TOPMOST, ...
x, ...
y, ...
gnFRAME_SizeX, ...
gnFRAME_SizeY, ...
Null, ...
0, ...
Instance, ...
0)
IF hMain THEN
Msg is TagMSG
SetImage(hMain, gsIMAGE_FullPathName, 255)
API(USER32,"ShowWindow", hMain, SW_SHOW)
IF gnFRAME_Count > 1 THEN API(USER32, "SetTimer", hMain, 1, 50, Null)
WHILE API(USER32, "GetMessageA", &Msg, Null, 0, 0)
API(USER32, "TranslateMessage", &Msg)
API(USER32, "DispatchMessageA", &Msg)
END
IF gnFRAME_Count > 1 THEN API(USER32,"KillTimer", hMain, 1)
nRet = Msg:wParam
END
END
END
PROCEDURES GLOBALES
Procedure SetImage(LOCAL hWnd is int, LOCAL sFileName is string, LOCAL alpha is int)
graphics, desktopDC, hMemDC, hBmp, OldBmp, Img, nImgW, nImgH, ImgAttr, x, y, nStepX, nStepY, nOrientation are int
rw is RECT
Bmp is BITMAP
bi is BITMAPINFO_API
nDwp is unsigned int
bf is BLENDFUNCTION
lp, ptSrc are POINTAPI
lpSize is SIZEL
API(USER32,"GetWindowRect", hWnd, &rw)
lpSize:cx = rw:nRight - rw:nLeft; lpSize:cy = rw:nBottom - rw:nTop
InitRandom()
nStepX = gnUSE_StepX; nStepY = ((Random() - 0.5) * 1.5) * gnUSE_StepY
lp:y = rw:nTop + nStepY
IF gnToTheRight THEN
IF rw:nRight < API(USER32, "GetSystemMetrics", SM_CXSCREEN) + lpSize:cx THEN
lp:x = rw:nLeft + nStepX
ELSE
gnToTheRight = 0
lp:x = rw:nLeft - nStepX
END
ELSE
IF rw:nLeft > - lpSize:cx THEN
lp:x = rw:nLeft - nStepX
ELSE
gnToTheRight = -1
lp:x = rw:nLeft + nStepX
END
END
IF gnToTheRight THEN nOrientation = 4 ELSE nOrientation = 0
gnFrame++; IF gnFrame > gnFRAME_Count THEN gnFrame = 1
Img = API(GDIMAGE, "zLoadImageFromFile", (sFileName), &nImgW, &nImgH, nOrientation)
IF Img THEN
desktopDC = API(USER32, "GetDC", 0)
hMemDC = API(GDI32, "CreateCompatibleDC", desktopDC)
hBmp = API(GDI32, "CreateCompatibleBitmap", desktopDC, nImgW, nImgH)
OldBmp = API(GDI32, "SelectObject", hMemDC, hBmp)
IF API(GDIPLUS, "GdipCreateFromHDC", hMemDC, &graphics) = 0 THEN
API(GDIPLUS, "GdipDrawImageRectRectI", graphics, Img, 0, 0, lpSize:cx, lpSize:cy, gnFrame * lpSize:cx - lpSize:cx, 0, lpSize:cx, lpSize:cy, 2, ImgAttr, 0, 0)
API(GDIPLUS, "GdipDeleteGraphics", graphics)
API(GDIPLUS, "GdipDisposeImage", Img)
END
API(GDI32, "GetObjectA", hBmp, Dimension(Bmp), &Bmp)
bf:BlendOp = AC_SRC_OVER
bf:BlendFlags = 0
bf:AlphaFormat = AC_SRC_ALPHA
bf:SourceConstantAlpha = alpha
API(USER32, "SetWindowPos", hWnd, -1, 0, 0, 0, 0, 3)
API(USER32, "UpdateLayeredWindow", hWnd, desktopDC, &lp, &lpSize, hMemDC, &ptSrc, 0, &bf, ULW_ALPHA)
END
API(GDI32, "SelectObject", hMemDC, OldBmp)
API(GDI32, "DeleteObject", hBmp)
API(GDI32, "DeleteDC", hMemDC)
API(USER32, "ReleaseDC", 0, desktopDC)
Procedure WndProc(LOCAL hWnd is int, LOCAL Msg is int, LOCAL wParam is int, LOCAL lParam is int)
nRet is int
SWITCH Msg
CASE WM_KEYDOWN
IF wParam = 0x1B THEN
API(USER32, "DestroyWindow", hWnd)
END
CASE WM_TIMER
SetImage(hWnd, gsIMAGE_FullPathName, 255)
CASE WM_NCHITTEST
nRet = HTCAPTION; GOTO ExitFunction
CASE WM_DESTROY
API(USER32, "PostQuitMessage", 0)
nRet = 0; GOTO ExitFunction
END
nRet = API(USER32, "DefWindowProcA", hWnd, Msg, wParam, lParam)
ExitFunction :
RESULT nRet
Procedure WndProc(LOCAL hWnd is int, LOCAL Msg is int, LOCAL wParam is int, LOCAL lParam is int)
nRet is int
SWITCH Msg
CASE WM_KEYDOWN
IF wParam = 0x1B THEN
API(USER32, "DestroyWindow", hWnd)
END
CASE WM_TIMER
SetImage(hWnd, gsIMAGE_FullPathName, 255)
CASE WM_NCHITTEST
nRet = HTCAPTION; GOTO ExitFunction
CASE WM_DESTROY
API(USER32, "PostQuitMessage", 0)
nRet = 0; GOTO ExitFunction
END
nRet = API(USER32, "DefWindowProcA", hWnd, Msg, wParam, lParam)
ExitFunction :
RESULT nRet
Et maintenant le plus facile, le lien pour télécharger le projet complet :
http://www.zapsolution.com/windev/GoldFish.zip
Dans un prochain article, je vous montrerai comment créer un splash-screen sur le même principe.
Patrice Terrier
http://www.zapsolution.com/newwindev/FR/index.html