1 /* -*- tab-width: 8; c-basic-offset: 4 -*- */
5 * Copyright 1998, 1999 Eric Kohl
9 * I will only improve this control once in a while.
10 * Eric <ekohl@abo.rhein-zeitung.de>
13 * - check for the 'rec ' list in some AVI files
14 * - implement some missing flags (ACS_TRANSPARENT and ACS_CENTER)
15 * - protection between service thread and wndproc messages handling
16 * concurrent access to infoPtr
26 #include "debugtools.h"
28 DEFAULT_DEBUG_CHANNEL(animate
)
30 #define ANIMATE_GetInfoPtr(hWnd) ((ANIMATE_INFO *)GetWindowLongA(hWnd, 0))
32 static void ANIMATE_Notify(ANIMATE_INFO
* infoPtr
, UINT notif
)
34 SendMessageA(GetParent(infoPtr
->hWnd
), WM_COMMAND
,
35 MAKEWPARAM(GetDlgCtrlID(infoPtr
->hWnd
), notif
),
36 (LPARAM
)infoPtr
->hWnd
);
39 static BOOL
ANIMATE_LoadResA(ANIMATE_INFO
*infoPtr
, HINSTANCE hInst
, LPSTR lpName
)
45 hrsrc
= FindResourceA(hInst
, lpName
, "AVI");
49 infoPtr
->hRes
= LoadResource(hInst
, hrsrc
);
53 lpAvi
= LockResource(infoPtr
->hRes
);
57 memset(&mminfo
, 0, sizeof(mminfo
));
58 mminfo
.fccIOProc
= FOURCC_MEM
;
59 mminfo
.pchBuffer
= (LPSTR
)lpAvi
;
60 mminfo
.cchBuffer
= SizeofResource(hInst
, hrsrc
);
61 infoPtr
->hMMio
= mmioOpenA(NULL
, &mminfo
, MMIO_READ
);
63 if (!infoPtr
->hMMio
) {
64 GlobalFree((HGLOBAL
)lpAvi
);
72 static BOOL
ANIMATE_LoadFileA(ANIMATE_INFO
*infoPtr
, LPSTR lpName
)
74 infoPtr
->hMMio
= mmioOpenA((LPSTR
)lpName
, NULL
,
75 MMIO_ALLOCBUF
| MMIO_READ
| MMIO_DENYWRITE
);
84 static void ANIMATE_Free(ANIMATE_INFO
*infoPtr
)
87 mmioClose(infoPtr
->hMMio
, 0);
89 FreeResource(infoPtr
->hRes
);
92 if (infoPtr
->lpIndex
) {
93 HeapFree(GetProcessHeap(), 0, infoPtr
->lpIndex
);
94 infoPtr
->lpIndex
= NULL
;
97 (infoPtr
->fnICClose
)(infoPtr
->hic
);
100 if (infoPtr
->inbih
) {
101 HeapFree(GetProcessHeap(), 0, infoPtr
->inbih
);
102 infoPtr
->inbih
= NULL
;
104 if (infoPtr
->outbih
) {
105 HeapFree(GetProcessHeap(), 0, infoPtr
->outbih
);
106 infoPtr
->outbih
= NULL
;
108 HeapFree(GetProcessHeap(), 0, infoPtr
->indata
);
109 HeapFree(GetProcessHeap(), 0, infoPtr
->outdata
);
110 infoPtr
->indata
= infoPtr
->outdata
= NULL
;
113 memset(&infoPtr
->mah
, 0, sizeof(infoPtr
->mah
));
114 memset(&infoPtr
->ash
, 0, sizeof(infoPtr
->ash
));
115 infoPtr
->nFromFrame
= infoPtr
->nToFrame
= infoPtr
->nLoop
= infoPtr
->currFrame
= 0;
120 static LRESULT
ANIMATE_DoStop(ANIMATE_INFO
*infoPtr
)
122 /* should stop playing */
123 if (infoPtr
->hService
) {
124 SERVICE_Delete(infoPtr
->hService
);
125 infoPtr
->hService
= 0;
127 if (infoPtr
->uTimer
) {
128 KillTimer(infoPtr
->hWnd
, infoPtr
->uTimer
);
132 ANIMATE_Notify(infoPtr
, ACN_STOP
);
137 static LRESULT
ANIMATE_PaintFrame(ANIMATE_INFO
* infoPtr
, HDC hDC
)
140 StretchDIBits(hDC
, 0, 0, infoPtr
->outbih
->biWidth
, infoPtr
->outbih
->biHeight
,
141 0, 0, infoPtr
->outbih
->biWidth
, infoPtr
->outbih
->biHeight
,
142 infoPtr
->outdata
, (LPBITMAPINFO
)infoPtr
->outbih
, DIB_RGB_COLORS
,
148 static LRESULT
ANIMATE_DrawFrame(ANIMATE_INFO
* infoPtr
)
152 TRACE("Drawing frame %d (loop %d)\n", infoPtr
->currFrame
, infoPtr
->nLoop
);
154 EnterCriticalSection(&infoPtr
->cs
);
156 mmioSeek(infoPtr
->hMMio
, infoPtr
->lpIndex
[infoPtr
->currFrame
], SEEK_SET
);
157 mmioRead(infoPtr
->hMMio
, infoPtr
->indata
, infoPtr
->ash
.dwSuggestedBufferSize
);
159 if ((infoPtr
->fnICDecompress
)(infoPtr
->hic
, 0, infoPtr
->inbih
, infoPtr
->indata
,
160 infoPtr
->outbih
, infoPtr
->outdata
) != ICERR_OK
) {
161 LeaveCriticalSection(&infoPtr
->cs
);
162 WARN("Decompression error\n");
166 if ((hDC
= GetDC(infoPtr
->hWnd
)) != 0) {
167 ANIMATE_PaintFrame(infoPtr
, hDC
);
168 ReleaseDC(infoPtr
->hWnd
, hDC
);
171 if (infoPtr
->currFrame
++ >= infoPtr
->nToFrame
) {
172 infoPtr
->currFrame
= infoPtr
->nFromFrame
;
173 if (infoPtr
->nLoop
!= -1) {
174 if (--infoPtr
->nLoop
== 0) {
175 ANIMATE_DoStop(infoPtr
);
179 LeaveCriticalSection(&infoPtr
->cs
);
184 static void CALLBACK
ANIMATE_ServiceCallback(ULONG_PTR ptr_
)
186 ANIMATE_INFO
* infoPtr
= (ANIMATE_INFO
*)ptr_
;
188 EnterCriticalSection(&infoPtr
->cs
);
189 ANIMATE_DrawFrame(infoPtr
);
190 LeaveCriticalSection(&infoPtr
->cs
);
193 static LRESULT
ANIMATE_Play(HWND hWnd
, WPARAM wParam
, LPARAM lParam
)
195 ANIMATE_INFO
*infoPtr
= ANIMATE_GetInfoPtr(hWnd
);
201 if (infoPtr
->hService
|| infoPtr
->uTimer
) {
202 FIXME("Already playing ? what should I do ??\n");
203 ANIMATE_DoStop(infoPtr
);
206 infoPtr
->nFromFrame
= (INT
)LOWORD(lParam
);
207 infoPtr
->nToFrame
= (INT
)HIWORD(lParam
);
208 infoPtr
->nLoop
= (INT
)wParam
;
210 if (infoPtr
->nToFrame
== 0xFFFF)
211 infoPtr
->nToFrame
= infoPtr
->mah
.dwTotalFrames
- 1;
213 TRACE("(repeat=%d from=%d to=%d);\n",
214 infoPtr
->nLoop
, infoPtr
->nFromFrame
, infoPtr
->nToFrame
);
216 if (infoPtr
->nFromFrame
>= infoPtr
->nToFrame
||
217 infoPtr
->nToFrame
>= infoPtr
->mah
.dwTotalFrames
)
220 infoPtr
->currFrame
= infoPtr
->nFromFrame
;
222 if (GetWindowLongA(hWnd
, GWL_STYLE
) & ACS_TIMER
) {
223 TRACE("Using a timer\n");
224 /* create a timer to display AVI */
225 infoPtr
->uTimer
= SetTimer(hWnd
, 1, infoPtr
->mah
.dwMicroSecPerFrame
/ 1000, NULL
);
227 TRACE("Using the service thread\n");
229 infoPtr
->hService
= SERVICE_AddTimer(infoPtr
->mah
.dwMicroSecPerFrame
,
230 ANIMATE_ServiceCallback
, (DWORD
)infoPtr
);
233 ANIMATE_Notify(infoPtr
, ACN_START
);
239 static BOOL
ANIMATE_GetAviInfo(ANIMATE_INFO
*infoPtr
)
248 if (mmioDescend(infoPtr
->hMMio
, &ckMainRIFF
, NULL
, 0) != 0) {
249 WARN("Can't find 'RIFF' chunk\n");
253 if ((ckMainRIFF
.ckid
!= FOURCC_RIFF
) ||
254 (ckMainRIFF
.fccType
!= mmioFOURCC('A', 'V', 'I', ' '))) {
255 WARN("Can't find 'AVI ' chunk\n");
259 mmckHead
.fccType
= mmioFOURCC('h', 'd', 'r', 'l');
260 if (mmioDescend(infoPtr
->hMMio
, &mmckHead
, &ckMainRIFF
, MMIO_FINDLIST
) != 0) {
261 WARN("Can't find 'hdrl' list\n");
265 mmckInfo
.ckid
= mmioFOURCC('a', 'v', 'i', 'h');
266 if (mmioDescend(infoPtr
->hMMio
, &mmckInfo
, &mmckHead
, MMIO_FINDCHUNK
) != 0) {
267 WARN("Can't find 'avih' chunk\n");
271 mmioRead(infoPtr
->hMMio
, (LPSTR
)&infoPtr
->mah
, sizeof(infoPtr
->mah
));
272 TRACE("mah.dwMicroSecPerFrame=%ld\n", infoPtr
->mah
.dwMicroSecPerFrame
);
273 TRACE("mah.dwMaxBytesPerSec=%ld\n", infoPtr
->mah
.dwMaxBytesPerSec
);
274 TRACE("mah.dwPaddingGranularity=%ld\n", infoPtr
->mah
.dwPaddingGranularity
);
275 TRACE("mah.dwFlags=%ld\n", infoPtr
->mah
.dwFlags
);
276 TRACE("mah.dwTotalFrames=%ld\n", infoPtr
->mah
.dwTotalFrames
);
277 TRACE("mah.dwInitialFrames=%ld\n", infoPtr
->mah
.dwInitialFrames
);
278 TRACE("mah.dwStreams=%ld\n", infoPtr
->mah
.dwStreams
);
279 TRACE("mah.dwSuggestedBufferSize=%ld\n", infoPtr
->mah
.dwSuggestedBufferSize
);
280 TRACE("mah.dwWidth=%ld\n", infoPtr
->mah
.dwWidth
);
281 TRACE("mah.dwHeight=%ld\n", infoPtr
->mah
.dwHeight
);
282 mmioAscend(infoPtr
->hMMio
, &mmckInfo
, 0);
284 mmckList
.fccType
= mmioFOURCC('s', 't', 'r', 'l');
285 if (mmioDescend(infoPtr
->hMMio
, &mmckList
, &mmckHead
, MMIO_FINDLIST
) != 0) {
286 WARN("Can't find 'strl' list\n");
290 mmckInfo
.ckid
= mmioFOURCC('s', 't', 'r', 'h');
291 if (mmioDescend(infoPtr
->hMMio
, &mmckInfo
, &mmckList
, MMIO_FINDCHUNK
) != 0) {
292 WARN("Can't find 'strh' chunk\n");
296 mmioRead(infoPtr
->hMMio
, (LPSTR
)&infoPtr
->ash
, sizeof(infoPtr
->ash
));
297 TRACE("ash.fccType='%c%c%c%c'\n", LOBYTE(LOWORD(infoPtr
->ash
.fccType
)),
298 HIBYTE(LOWORD(infoPtr
->ash
.fccType
)),
299 LOBYTE(HIWORD(infoPtr
->ash
.fccType
)),
300 HIBYTE(HIWORD(infoPtr
->ash
.fccType
)));
301 TRACE("ash.fccHandler='%c%c%c%c'\n", LOBYTE(LOWORD(infoPtr
->ash
.fccHandler
)),
302 HIBYTE(LOWORD(infoPtr
->ash
.fccHandler
)),
303 LOBYTE(HIWORD(infoPtr
->ash
.fccHandler
)),
304 HIBYTE(HIWORD(infoPtr
->ash
.fccHandler
)));
305 TRACE("ash.dwFlags=%ld\n", infoPtr
->ash
.dwFlags
);
306 TRACE("ash.wPriority=%d\n", infoPtr
->ash
.wPriority
);
307 TRACE("ash.wLanguage=%d\n", infoPtr
->ash
.wLanguage
);
308 TRACE("ash.dwInitialFrames=%ld\n", infoPtr
->ash
.dwInitialFrames
);
309 TRACE("ash.dwScale=%ld\n", infoPtr
->ash
.dwScale
);
310 TRACE("ash.dwRate=%ld\n", infoPtr
->ash
.dwRate
);
311 TRACE("ash.dwStart=%ld\n", infoPtr
->ash
.dwStart
);
312 TRACE("ash.dwLength=%ld\n", infoPtr
->ash
.dwLength
);
313 TRACE("ash.dwSuggestedBufferSize=%ld\n", infoPtr
->ash
.dwSuggestedBufferSize
);
314 TRACE("ash.dwQuality=%ld\n", infoPtr
->ash
.dwQuality
);
315 TRACE("ash.dwSampleSize=%ld\n", infoPtr
->ash
.dwSampleSize
);
316 TRACE("ash.rcFrame=(%d,%d,%d,%d)\n", infoPtr
->ash
.rcFrame
.top
, infoPtr
->ash
.rcFrame
.left
,
317 infoPtr
->ash
.rcFrame
.bottom
, infoPtr
->ash
.rcFrame
.right
);
318 mmioAscend(infoPtr
->hMMio
, &mmckInfo
, 0);
320 mmckInfo
.ckid
= mmioFOURCC('s', 't', 'r', 'f');
321 if (mmioDescend(infoPtr
->hMMio
, &mmckInfo
, &mmckList
, MMIO_FINDCHUNK
) != 0) {
322 WARN("Can't find 'strh' chunk\n");
326 infoPtr
->inbih
= HeapAlloc(GetProcessHeap(), 0, mmckInfo
.cksize
);
327 if (!infoPtr
->inbih
) {
328 WARN("Can't alloc input BIH\n");
332 mmioRead(infoPtr
->hMMio
, (LPSTR
)infoPtr
->inbih
, mmckInfo
.cksize
);
333 TRACE("bih.biSize=%ld\n", infoPtr
->inbih
->biSize
);
334 TRACE("bih.biWidth=%ld\n", infoPtr
->inbih
->biWidth
);
335 TRACE("bih.biHeight=%ld\n", infoPtr
->inbih
->biHeight
);
336 TRACE("bih.biPlanes=%d\n", infoPtr
->inbih
->biPlanes
);
337 TRACE("bih.biBitCount=%d\n", infoPtr
->inbih
->biBitCount
);
338 TRACE("bih.biCompression=%ld\n", infoPtr
->inbih
->biCompression
);
339 TRACE("bih.biSizeImage=%ld\n", infoPtr
->inbih
->biSizeImage
);
340 TRACE("bih.biXPelsPerMeter=%ld\n", infoPtr
->inbih
->biXPelsPerMeter
);
341 TRACE("bih.biYPelsPerMeter=%ld\n", infoPtr
->inbih
->biYPelsPerMeter
);
342 TRACE("bih.biClrUsed=%ld\n", infoPtr
->inbih
->biClrUsed
);
343 TRACE("bih.biClrImportant=%ld\n", infoPtr
->inbih
->biClrImportant
);
344 mmioAscend(infoPtr
->hMMio
, &mmckInfo
, 0);
346 mmioAscend(infoPtr
->hMMio
, &mmckList
, 0);
349 /* an AVI has 0 or 1 video stream, and to be animated should not contain
350 * an audio stream, so only one strl is allowed
352 mmckList
.fccType
= mmioFOURCC('s', 't', 'r', 'l');
353 if (mmioDescend(infoPtr
->hMMio
, &mmckList
, &mmckHead
, MMIO_FINDLIST
) == 0) {
354 WARN("There should be a single 'strl' list\n");
359 mmioAscend(infoPtr
->hMMio
, &mmckHead
, 0);
361 /* no need to read optional JUNK chunk */
363 mmckList
.fccType
= mmioFOURCC('m', 'o', 'v', 'i');
364 if (mmioDescend(infoPtr
->hMMio
, &mmckList
, &ckMainRIFF
, MMIO_FINDLIST
) != 0) {
365 WARN("Can't find 'movi' list\n");
369 /* FIXME: should handle the 'rec ' LIST when present */
371 infoPtr
->lpIndex
= HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
,
372 infoPtr
->mah
.dwTotalFrames
* sizeof(DWORD
));
373 if (!infoPtr
->lpIndex
) {
374 WARN("Can't alloc index array\n");
378 numFrame
= insize
= 0;
379 while (mmioDescend(infoPtr
->hMMio
, &mmckInfo
, &mmckList
, 0) == 0 &&
380 numFrame
< infoPtr
->mah
.dwTotalFrames
) {
381 infoPtr
->lpIndex
[numFrame
] = mmckInfo
.dwDataOffset
;
382 if (insize
< mmckInfo
.cksize
)
383 insize
= mmckInfo
.cksize
;
385 mmioAscend(infoPtr
->hMMio
, &mmckInfo
, 0);
387 if (numFrame
!= infoPtr
->mah
.dwTotalFrames
) {
388 WARN("Found %ld frames (/%ld)\n", numFrame
, infoPtr
->mah
.dwTotalFrames
);
391 if (insize
> infoPtr
->ash
.dwSuggestedBufferSize
) {
392 WARN("insize=%ld suggestedSize=%ld\n", insize
, infoPtr
->ash
.dwSuggestedBufferSize
);
393 infoPtr
->ash
.dwSuggestedBufferSize
= insize
;
396 infoPtr
->indata
= HeapAlloc(GetProcessHeap(), 0, infoPtr
->ash
.dwSuggestedBufferSize
);
397 if (!infoPtr
->indata
) {
398 WARN("Can't alloc input buffer\n");
406 static BOOL
ANIMATE_GetAviCodec(ANIMATE_INFO
*infoPtr
)
410 infoPtr
->hic
= (infoPtr
->fnICOpen
)(ICTYPE_VIDEO
,
411 infoPtr
->ash
.fccHandler
,
414 WARN("Can't load codec for the file\n");
418 outSize
= (infoPtr
->fnICSendMessage
)(infoPtr
->hic
,
419 ICM_DECOMPRESS_GET_FORMAT
,
420 (DWORD
)infoPtr
->inbih
, 0L);
421 infoPtr
->outbih
= HeapAlloc(GetProcessHeap(), 0, outSize
);
422 if (!infoPtr
->outbih
) {
423 WARN("Can't alloc output BIH\n");
427 if ((infoPtr
->fnICSendMessage
)(infoPtr
->hic
, ICM_DECOMPRESS_GET_FORMAT
,
428 (DWORD
)infoPtr
->inbih
,
429 (DWORD
)infoPtr
->outbih
) != ICERR_OK
) {
430 WARN("Can't get output BIH\n");
434 infoPtr
->outdata
= HeapAlloc(GetProcessHeap(), 0, infoPtr
->outbih
->biSizeImage
);
435 if (!infoPtr
->outdata
) {
436 WARN("Can't alloc output buffer\n");
440 if ((infoPtr
->fnICSendMessage
)(infoPtr
->hic
, ICM_DECOMPRESS_BEGIN
,
441 (DWORD
)infoPtr
->inbih
,
442 (DWORD
)infoPtr
->outbih
) != ICERR_OK
) {
443 WARN("Can't begin decompression\n");
450 static LRESULT
ANIMATE_OpenA(HWND hWnd
, WPARAM wParam
, LPARAM lParam
)
452 ANIMATE_INFO
*infoPtr
= ANIMATE_GetInfoPtr(hWnd
);
453 HINSTANCE hInstance
= (HINSTANCE
)wParam
;
455 ANIMATE_Free(infoPtr
);
458 TRACE("Closing avi!\n");
463 hInstance
= GetWindowLongA(hWnd
, GWL_HINSTANCE
);
465 if (HIWORD(lParam
)) {
466 TRACE("(\"%s\");\n", (LPSTR
)lParam
);
468 if (!ANIMATE_LoadResA(infoPtr
, hInstance
, (LPSTR
)lParam
)) {
469 TRACE("No AVI resource found!\n");
470 if (!ANIMATE_LoadFileA(infoPtr
, (LPSTR
)lParam
)) {
471 WARN("No AVI file found!\n");
476 TRACE("(%u);\n", (WORD
)LOWORD(lParam
));
478 if (!ANIMATE_LoadResA(infoPtr
, hInstance
,
479 MAKEINTRESOURCEA((INT
)lParam
))) {
480 WARN("No AVI resource found!\n");
485 if (!ANIMATE_GetAviInfo(infoPtr
)) {
486 WARN("Can't get AVI information\n");
487 ANIMATE_Free(infoPtr
);
491 if (!ANIMATE_GetAviCodec(infoPtr
)) {
492 WARN("Can't get AVI Codec\n");
493 ANIMATE_Free(infoPtr
);
497 if (GetWindowLongA(hWnd
, GWL_STYLE
) & ACS_CENTER
) {
498 FIXME("ACS_CENTER: NIY\n");
500 /* MoveWindow(hWnd, 0, 0, infoPtr->mah.dwWidth, infoPtr->mah.dwHeight, FALSE);*/
501 SetWindowPos(hWnd
, 0, 0, 0, infoPtr
->mah
.dwWidth
, infoPtr
->mah
.dwHeight
,
502 SWP_NOACTIVATE
| SWP_NOMOVE
| SWP_NOZORDER
);
505 if (GetWindowLongA(hWnd
, GWL_STYLE
) & ACS_TRANSPARENT
) {
506 FIXME("ACS_TRANSPARENT: NIY\n");
509 if (GetWindowLongA(hWnd
, GWL_STYLE
) & ACS_AUTOPLAY
) {
510 return ANIMATE_Play(hWnd
, -1, (LPARAM
)MAKELONG(0, infoPtr
->mah
.dwTotalFrames
-1));
517 /* << ANIMATE_Open32W >> */
519 static LRESULT
ANIMATE_Stop(HWND hWnd
, WPARAM wParam
, LPARAM lParam
)
521 ANIMATE_INFO
*infoPtr
= ANIMATE_GetInfoPtr(hWnd
);
527 ANIMATE_DoStop(infoPtr
);
533 static LRESULT
ANIMATE_Create(HWND hWnd
, WPARAM wParam
, LPARAM lParam
)
535 ANIMATE_INFO
* infoPtr
;
536 HMODULE hModule
= LoadLibraryA("msvfw32.dll");
541 /* allocate memory for info structure */
542 infoPtr
= (ANIMATE_INFO
*)COMCTL32_Alloc(sizeof(ANIMATE_INFO
));
544 ERR("could not allocate info memory!\n");
548 /* Temporary hack until we get dllglue up and running */
549 infoPtr
->fnICOpen
= (void*)GetProcAddress(hModule
, "ICOpen");
550 infoPtr
->fnICClose
= (void*)GetProcAddress(hModule
, "ICClose");
551 infoPtr
->fnICSendMessage
= (void*)GetProcAddress(hModule
, "ICSendMessage");
552 infoPtr
->fnICDecompress
= (void*)GetProcAddress(hModule
, "ICDecompress");
554 TRACE("Animate style=0x%08lx, parent=%08lx\n", GetWindowLongA(hWnd
, GWL_STYLE
), (DWORD
)GetParent(hWnd
));
556 /* store crossref hWnd <-> info structure */
557 SetWindowLongA(hWnd
, 0, (DWORD
)infoPtr
);
558 infoPtr
->hWnd
= hWnd
;
560 InitializeCriticalSection(&infoPtr
->cs
);
566 static LRESULT
ANIMATE_Destroy(HWND hWnd
, WPARAM wParam
, LPARAM lParam
)
568 ANIMATE_INFO
*infoPtr
= ANIMATE_GetInfoPtr(hWnd
);
572 ANIMATE_Free(infoPtr
);
574 /* free animate info data */
575 COMCTL32_Free(infoPtr
);
581 static LRESULT
ANIMATE_EraseBackground(HWND hWnd
, WPARAM wParam
, LPARAM lParam
)
585 GetClientRect(hWnd
, &rect
);
587 HBRUSH hBrush
= CreateSolidBrush(infoPtr
->clrBk
);
589 FillRect((HDC
)wParam
, &rect
, hBrush
);
590 DeleteObject(hBrush
);
592 FillRect((HDC
)wParam
, &rect
, GetSysColorBrush(COLOR_WINDOW
));
597 static LRESULT WINAPI
ANIMATE_Size(HWND hWnd
, WPARAM wParam
, LPARAM lParam
)
599 ANIMATE_INFO
*infoPtr
= ANIMATE_GetInfoPtr(hWnd
);
601 if (GetWindowLongA(hWnd
, GWL_STYLE
) & ACS_CENTER
) {
603 if (infoPtr
->hMMio
) {
604 /* centers the animation in the control, invalidates the control
607 InvalidateRect(hWnd
, NULL
, TRUE
);
612 static LRESULT WINAPI
ANIMATE_WindowProc(HWND hWnd
, UINT uMsg
, WPARAM wParam
, LPARAM lParam
)
617 return ANIMATE_OpenA(hWnd
, wParam
, lParam
);
619 /* case ACM_OPEN32W: FIXME!! */
620 /* return ANIMATE_Open32W(hWnd, wParam, lParam); */
623 return ANIMATE_Play(hWnd
, wParam
, lParam
);
626 return ANIMATE_Stop(hWnd
, wParam
, lParam
);
629 ANIMATE_Create(hWnd
, wParam
, lParam
);
630 return DefWindowProcA(hWnd
, uMsg
, wParam
, lParam
);
633 return HTTRANSPARENT
;
636 ANIMATE_Destroy(hWnd
, wParam
, lParam
);
637 return DefWindowProcA(hWnd
, uMsg
, wParam
, lParam
);
640 ANIMATE_EraseBackground(hWnd
, wParam
, lParam
);
643 /* case WM_STYLECHANGED: FIXME shall we do something ?? */
646 return ANIMATE_DrawFrame(ANIMATE_GetInfoPtr(hWnd
));
649 ANIMATE_Free(ANIMATE_GetInfoPtr(hWnd
));
654 ANIMATE_PaintFrame(ANIMATE_GetInfoPtr(hWnd
), (HDC
)wParam
);
657 HDC hDC
= BeginPaint(hWnd
, &ps
);
658 ANIMATE_PaintFrame(ANIMATE_GetInfoPtr(hWnd
), hDC
);
664 ANIMATE_Size(hWnd
, wParam
, lParam
);
665 return DefWindowProcA(hWnd
, uMsg
, wParam
, lParam
);
669 ERR("unknown msg %04x wp=%08x lp=%08lx\n", uMsg
, wParam
, lParam
);
671 return DefWindowProcA(hWnd
, uMsg
, wParam
, lParam
);
677 void ANIMATE_Register(void)
681 if (GlobalFindAtomA(ANIMATE_CLASSA
)) return;
683 ZeroMemory(&wndClass
, sizeof(WNDCLASSA
));
684 wndClass
.style
= CS_GLOBALCLASS
| CS_DBLCLKS
;
685 wndClass
.lpfnWndProc
= (WNDPROC
)ANIMATE_WindowProc
;
686 wndClass
.cbClsExtra
= 0;
687 wndClass
.cbWndExtra
= sizeof(ANIMATE_INFO
*);
688 wndClass
.hCursor
= LoadCursorA(0, IDC_ARROWA
);
689 wndClass
.hbrBackground
= (HBRUSH
)(COLOR_BTNFACE
+ 1);
690 wndClass
.lpszClassName
= ANIMATE_CLASSA
;
692 RegisterClassA(&wndClass
);
696 void ANIMATE_Unregister(void)
698 if (GlobalFindAtomA(ANIMATE_CLASSA
))
699 UnregisterClassA(ANIMATE_CLASSA
, (HINSTANCE
)NULL
);