source: trunk/src/comctl32/animate.cpp@ 2912

Last change on this file since 2912 was 2875, checked in by cbratschi, 26 years ago

C -> C++, WINE animate, treeview WM_VSCROLL fixed

File size: 23.0 KB
Line 
1/* $Id: animate.cpp,v 1.1 2000-02-23 17:09:40 cbratschi Exp $ */
2/*
3 * Animation control
4 *
5 * Copyright 1998, 1999 Eric Kohl
6 * 1999 Eric Pouech
7 * Copyright 1999 Achim Hasenmueller
8 * Copyright 1999 Christoph Bratschi
9 *
10 * Status: complete
11 * Version: 5.00
12 */
13
14#include "winbase.h"
15#include "commctrl.h"
16#include "comctl32.h"
17#include "driver.h"
18#include "mmsystem.h"
19#include "ccbase.h"
20#include "animate.h"
21
22#define ANIMATE_GetInfoPtr(hwnd) ((ANIMATE_INFO*)getInfoPtr(hwnd))
23
24static BOOL ANIMATE_LoadRes(ANIMATE_INFO *infoPtr,HINSTANCE hInst,LPWSTR lpName,BOOL unicode)
25{
26 HRSRC hrsrc;
27 MMIOINFO mminfo;
28 LPVOID lpAvi;
29
30 if (unicode)
31 hrsrc = FindResourceW(hInst,lpName,(LPWSTR)L"AVI");
32 else
33 hrsrc = FindResourceA(hInst,(LPCSTR)lpName,"AVI");
34 if (!hrsrc) return FALSE;
35
36 infoPtr->hRes = LoadResource(hInst, hrsrc);
37 if (!infoPtr->hRes)
38 return FALSE;
39
40 lpAvi = LockResource (infoPtr->hRes);
41 if (!lpAvi) return FALSE;
42
43 memset(&mminfo, 0, sizeof(mminfo));
44 mminfo.fccIOProc = FOURCC_MEM;
45 mminfo.pchBuffer = (LPSTR)lpAvi;
46 mminfo.cchBuffer = SizeofResource(hInst, hrsrc);
47 infoPtr->hMMio = mmioOpenA(NULL, &mminfo, MMIO_READ);
48
49 if (!infoPtr->hMMio) {
50 GlobalFree((HGLOBAL)lpAvi);
51 return FALSE;
52 }
53
54 return TRUE;
55}
56
57static BOOL ANIMATE_LoadFile(ANIMATE_INFO *infoPtr,LPWSTR lpName,BOOL unicode)
58{
59 if (unicode)
60 infoPtr->hMMio = mmioOpenW(lpName,NULL,MMIO_ALLOCBUF | MMIO_READ | MMIO_DENYWRITE);
61 else
62 infoPtr->hMMio = mmioOpenA((LPSTR)lpName,NULL,MMIO_ALLOCBUF | MMIO_READ | MMIO_DENYWRITE);
63
64 if (!infoPtr->hMMio)
65 return FALSE;
66
67 return TRUE;
68}
69
70static LRESULT ANIMATE_DoStop(ANIMATE_INFO *infoPtr)
71{
72 EnterCriticalSection(&infoPtr->cs);
73
74 /* should stop playing */
75 if (infoPtr->hThread)
76 {
77 infoPtr->stopThread = TRUE;
78 infoPtr->hThread = 0;
79 }
80 if (infoPtr->uTimer) {
81 KillTimer(infoPtr->hWnd, infoPtr->uTimer);
82 infoPtr->uTimer = 0;
83 }
84
85 LeaveCriticalSection(&infoPtr->cs);
86
87 sendCommand(infoPtr->hWnd,ACN_STOP);
88
89 return TRUE;
90}
91
92
93static void ANIMATE_Free(ANIMATE_INFO *infoPtr)
94{
95 if (infoPtr->hMMio) {
96 ANIMATE_DoStop(infoPtr);
97 mmioClose(infoPtr->hMMio, 0);
98 if (infoPtr->hRes) {
99 FreeResource(infoPtr->hRes);
100 infoPtr->hRes = 0;
101 }
102 if (infoPtr->lpIndex) {
103 HeapFree(GetProcessHeap(), 0, infoPtr->lpIndex);
104 infoPtr->lpIndex = NULL;
105 }
106 if (infoPtr->hic) {
107 (infoPtr->fnICClose)(infoPtr->hic);
108 infoPtr->hic = 0;
109 }
110 if (infoPtr->inbih) {
111 HeapFree(GetProcessHeap(), 0, infoPtr->inbih);
112 infoPtr->inbih = NULL;
113 }
114 if (infoPtr->outbih) {
115 HeapFree(GetProcessHeap(), 0, infoPtr->outbih);
116 infoPtr->outbih = NULL;
117 }
118 HeapFree(GetProcessHeap(), 0, infoPtr->indata);
119 HeapFree(GetProcessHeap(), 0, infoPtr->outdata);
120 infoPtr->indata = infoPtr->outdata = NULL;
121 infoPtr->hWnd = 0;
122 infoPtr->hMMio = 0;
123 memset(&infoPtr->mah, 0, sizeof(infoPtr->mah));
124 memset(&infoPtr->ash, 0, sizeof(infoPtr->ash));
125 infoPtr->nFromFrame = infoPtr->nToFrame = infoPtr->nLoop = infoPtr->currFrame = 0;
126 }
127}
128
129
130static LRESULT ANIMATE_PaintFrame(ANIMATE_INFO* infoPtr, HDC hDC)
131{
132 if (!hDC || !infoPtr->inbih)
133 return TRUE;
134 if (infoPtr->hic)
135 StretchDIBits(hDC, 0, 0, infoPtr->outbih->biWidth, infoPtr->outbih->biHeight,
136 0, 0, infoPtr->outbih->biWidth, infoPtr->outbih->biHeight,
137 infoPtr->outdata, (LPBITMAPINFO)infoPtr->outbih, DIB_RGB_COLORS,
138 SRCCOPY);
139 else
140 StretchDIBits(hDC, 0, 0, infoPtr->inbih->biWidth, infoPtr->inbih->biHeight,
141 0, 0, infoPtr->inbih->biWidth, infoPtr->inbih->biHeight,
142 infoPtr->indata, (LPBITMAPINFO)infoPtr->inbih, DIB_RGB_COLORS,
143 SRCCOPY);
144
145 return TRUE;
146}
147
148static LRESULT ANIMATE_DrawFrame(ANIMATE_INFO* infoPtr)
149{
150 HDC hDC;
151
152 //TRACE("Drawing frame %d (loop %d)\n", infoPtr->currFrame, infoPtr->nLoop);
153
154 EnterCriticalSection(&infoPtr->cs);
155
156 mmioSeek(infoPtr->hMMio, infoPtr->lpIndex[infoPtr->currFrame], SEEK_SET);
157 mmioRead(infoPtr->hMMio, (HPSTR)infoPtr->indata, infoPtr->ash.dwSuggestedBufferSize);
158
159 if (infoPtr->hic &&
160 (infoPtr->fnICDecompress)(infoPtr->hic, 0, infoPtr->inbih, infoPtr->indata,
161 infoPtr->outbih, infoPtr->outdata) != ICERR_OK) {
162 LeaveCriticalSection(&infoPtr->cs);
163 //WARN("Decompression error\n");
164 return FALSE;
165 }
166
167 if ((hDC = GetDC(infoPtr->hWnd)) != 0) {
168 ANIMATE_PaintFrame(infoPtr, hDC);
169 ReleaseDC(infoPtr->hWnd, hDC);
170 }
171
172 if (infoPtr->currFrame++ >= infoPtr->nToFrame) {
173 infoPtr->currFrame = infoPtr->nFromFrame;
174 if (infoPtr->nLoop != -1) {
175 if (--infoPtr->nLoop == 0) {
176 ANIMATE_DoStop(infoPtr);
177 }
178 }
179 }
180 LeaveCriticalSection(&infoPtr->cs);
181
182 return TRUE;
183}
184
185static DWORD ANIMATE_ThreadFunc(LPDWORD lpdwParam)
186{
187 HWND hwnd = (HWND)lpdwParam;
188 ANIMATE_INFO* infoPtr = ANIMATE_GetInfoPtr(hwnd);
189
190 while (IsWindow(hwnd) && !infoPtr->stopThread)
191 {
192 EnterCriticalSection(&infoPtr->cs);
193 ANIMATE_DrawFrame(infoPtr);
194 LeaveCriticalSection(&infoPtr->cs);
195 Sleep(infoPtr->delay);
196 }
197
198 return 0;
199}
200
201static LRESULT ANIMATE_Play(HWND hWnd, WPARAM wParam, LPARAM lParam)
202{
203 ANIMATE_INFO *infoPtr = ANIMATE_GetInfoPtr(hWnd);
204
205 /* nothing opened */
206 if (!infoPtr->hMMio)
207 return FALSE;
208
209 if (infoPtr->hThread || infoPtr->uTimer) {
210 //FIXME("Already playing ? what should I do ??\n");
211 ANIMATE_DoStop(infoPtr);
212 }
213
214 infoPtr->nFromFrame = (INT)LOWORD(lParam);
215 infoPtr->nToFrame = (INT)HIWORD(lParam);
216 infoPtr->nLoop = (INT)wParam;
217
218 if (infoPtr->nToFrame == 0xFFFF)
219 infoPtr->nToFrame = infoPtr->mah.dwTotalFrames - 1;
220
221 //TRACE("(repeat=%d from=%d to=%d);\n",
222 // infoPtr->nLoop, infoPtr->nFromFrame, infoPtr->nToFrame);
223
224 if (infoPtr->nFromFrame >= infoPtr->nToFrame ||
225 infoPtr->nToFrame >= infoPtr->mah.dwTotalFrames)
226 return FALSE;
227
228 infoPtr->currFrame = infoPtr->nFromFrame;
229
230 if (GetWindowLongA(hWnd, GWL_STYLE) & ACS_TIMER) {
231 //TRACE("Using a timer\n");
232 /* create a timer to display AVI */
233 infoPtr->uTimer = SetTimer(hWnd, 1, infoPtr->mah.dwMicroSecPerFrame / 1000, NULL);
234 } else
235 {
236 DWORD id;
237
238 //TRACE("Using the service thread\n");
239 infoPtr->stopThread = FALSE;
240 infoPtr->delay = infoPtr->mah.dwMicroSecPerFrame+500;
241 infoPtr->hThread = CreateThread(NULL,0,(LPTHREAD_START_ROUTINE)ANIMATE_ThreadFunc,(LPVOID)hWnd,0,&id);
242 }
243
244 sendCommand(infoPtr->hWnd,ACN_START);
245
246 return TRUE;
247}
248
249
250static BOOL ANIMATE_GetAviInfo(ANIMATE_INFO *infoPtr)
251{
252 MMCKINFO ckMainRIFF;
253 MMCKINFO mmckHead;
254 MMCKINFO mmckList;
255 MMCKINFO mmckInfo;
256 DWORD numFrame;
257 DWORD insize;
258
259 if (mmioDescend(infoPtr->hMMio, &ckMainRIFF, NULL, 0) != 0) {
260 //WARN("Can't find 'RIFF' chunk\n");
261 return FALSE;
262 }
263
264 if ((ckMainRIFF.ckid != FOURCC_RIFF) ||
265 (ckMainRIFF.fccType != mmioFOURCC('A', 'V', 'I', ' '))) {
266 //WARN("Can't find 'AVI ' chunk\n");
267 return FALSE;
268 }
269
270 mmckHead.fccType = mmioFOURCC('h', 'd', 'r', 'l');
271 if (mmioDescend(infoPtr->hMMio, &mmckHead, &ckMainRIFF, MMIO_FINDLIST) != 0) {
272 //WARN("Can't find 'hdrl' list\n");
273 return FALSE;
274 }
275
276 mmckInfo.ckid = mmioFOURCC('a', 'v', 'i', 'h');
277 if (mmioDescend(infoPtr->hMMio, &mmckInfo, &mmckHead, MMIO_FINDCHUNK) != 0) {
278 //WARN("Can't find 'avih' chunk\n");
279 return FALSE;
280 }
281
282 mmioRead(infoPtr->hMMio, (LPSTR)&infoPtr->mah, sizeof(infoPtr->mah));
283 //TRACE("mah.dwMicroSecPerFrame=%ld\n", infoPtr->mah.dwMicroSecPerFrame);
284 //TRACE("mah.dwMaxBytesPerSec=%ld\n", infoPtr->mah.dwMaxBytesPerSec);
285 //TRACE("mah.dwPaddingGranularity=%ld\n", infoPtr->mah.dwPaddingGranularity);
286 //TRACE("mah.dwFlags=%ld\n", infoPtr->mah.dwFlags);
287 //TRACE("mah.dwTotalFrames=%ld\n", infoPtr->mah.dwTotalFrames);
288 //TRACE("mah.dwInitialFrames=%ld\n", infoPtr->mah.dwInitialFrames);
289 //TRACE("mah.dwStreams=%ld\n", infoPtr->mah.dwStreams);
290 //TRACE("mah.dwSuggestedBufferSize=%ld\n", infoPtr->mah.dwSuggestedBufferSize);
291 //TRACE("mah.dwWidth=%ld\n", infoPtr->mah.dwWidth);
292 //TRACE("mah.dwHeight=%ld\n", infoPtr->mah.dwHeight);
293 mmioAscend(infoPtr->hMMio, &mmckInfo, 0);
294
295 mmckList.fccType = mmioFOURCC('s', 't', 'r', 'l');
296 if (mmioDescend(infoPtr->hMMio, &mmckList, &mmckHead, MMIO_FINDLIST) != 0) {
297 //WARN("Can't find 'strl' list\n");
298 return FALSE;
299 }
300
301 mmckInfo.ckid = mmioFOURCC('s', 't', 'r', 'h');
302 if (mmioDescend(infoPtr->hMMio, &mmckInfo, &mmckList, MMIO_FINDCHUNK) != 0) {
303 //WARN("Can't find 'strh' chunk\n");
304 return FALSE;
305 }
306
307 mmioRead(infoPtr->hMMio, (LPSTR)&infoPtr->ash, sizeof(infoPtr->ash));
308 //TRACE("ash.fccType='%c%c%c%c'\n", LOBYTE(LOWORD(infoPtr->ash.fccType)),
309 // HIBYTE(LOWORD(infoPtr->ash.fccType)),
310 // LOBYTE(HIWORD(infoPtr->ash.fccType)),
311 // HIBYTE(HIWORD(infoPtr->ash.fccType)));
312 //TRACE("ash.fccHandler='%c%c%c%c'\n", LOBYTE(LOWORD(infoPtr->ash.fccHandler)),
313 // HIBYTE(LOWORD(infoPtr->ash.fccHandler)),
314 // LOBYTE(HIWORD(infoPtr->ash.fccHandler)),
315 // HIBYTE(HIWORD(infoPtr->ash.fccHandler)));
316 //TRACE("ash.dwFlags=%ld\n", infoPtr->ash.dwFlags);
317 //TRACE("ash.wPriority=%d\n", infoPtr->ash.wPriority);
318 //TRACE("ash.wLanguage=%d\n", infoPtr->ash.wLanguage);
319 //TRACE("ash.dwInitialFrames=%ld\n", infoPtr->ash.dwInitialFrames);
320 //TRACE("ash.dwScale=%ld\n", infoPtr->ash.dwScale);
321 //TRACE("ash.dwRate=%ld\n", infoPtr->ash.dwRate);
322 //TRACE("ash.dwStart=%ld\n", infoPtr->ash.dwStart);
323 //TRACE("ash.dwLength=%ld\n", infoPtr->ash.dwLength);
324 //TRACE("ash.dwSuggestedBufferSize=%ld\n", infoPtr->ash.dwSuggestedBufferSize);
325 //TRACE("ash.dwQuality=%ld\n", infoPtr->ash.dwQuality);
326 //TRACE("ash.dwSampleSize=%ld\n", infoPtr->ash.dwSampleSize);
327 //TRACE("ash.rcFrame=(%d,%d,%d,%d)\n", infoPtr->ash.rcFrame.top, infoPtr->ash.rcFrame.left,
328 // infoPtr->ash.rcFrame.bottom, infoPtr->ash.rcFrame.right);
329 mmioAscend(infoPtr->hMMio, &mmckInfo, 0);
330
331 mmckInfo.ckid = mmioFOURCC('s', 't', 'r', 'f');
332 if (mmioDescend(infoPtr->hMMio, &mmckInfo, &mmckList, MMIO_FINDCHUNK) != 0) {
333 //WARN("Can't find 'strh' chunk\n");
334 return FALSE;
335 }
336
337 infoPtr->inbih = (BITMAPINFOHEADER*)HeapAlloc(GetProcessHeap(), 0, mmckInfo.cksize);
338 if (!infoPtr->inbih) {
339 //WARN("Can't alloc input BIH\n");
340 return FALSE;
341 }
342
343 mmioRead(infoPtr->hMMio, (LPSTR)infoPtr->inbih, mmckInfo.cksize);
344 //TRACE("bih.biSize=%ld\n", infoPtr->inbih->biSize);
345 //TRACE("bih.biWidth=%ld\n", infoPtr->inbih->biWidth);
346 //TRACE("bih.biHeight=%ld\n", infoPtr->inbih->biHeight);
347 //TRACE("bih.biPlanes=%d\n", infoPtr->inbih->biPlanes);
348 //TRACE("bih.biBitCount=%d\n", infoPtr->inbih->biBitCount);
349 //TRACE("bih.biCompression=%ld\n", infoPtr->inbih->biCompression);
350 //TRACE("bih.biSizeImage=%ld\n", infoPtr->inbih->biSizeImage);
351 //TRACE("bih.biXPelsPerMeter=%ld\n", infoPtr->inbih->biXPelsPerMeter);
352 //TRACE("bih.biYPelsPerMeter=%ld\n", infoPtr->inbih->biYPelsPerMeter);
353 //TRACE("bih.biClrUsed=%ld\n", infoPtr->inbih->biClrUsed);
354 //TRACE("bih.biClrImportant=%ld\n", infoPtr->inbih->biClrImportant);
355 mmioAscend(infoPtr->hMMio, &mmckInfo, 0);
356
357 mmioAscend(infoPtr->hMMio, &mmckList, 0);
358
359#if 0
360 /* an AVI has 0 or 1 video stream, and to be animated should not contain
361 * an audio stream, so only one strl is allowed
362 */
363 mmckList.fccType = mmioFOURCC('s', 't', 'r', 'l');
364 if (mmioDescend(infoPtr->hMMio, &mmckList, &mmckHead, MMIO_FINDLIST) == 0) {
365 //WARN("There should be a single 'strl' list\n");
366 return FALSE;
367 }
368#endif
369
370 mmioAscend(infoPtr->hMMio, &mmckHead, 0);
371
372 /* no need to read optional JUNK chunk */
373
374 mmckList.fccType = mmioFOURCC('m', 'o', 'v', 'i');
375 if (mmioDescend(infoPtr->hMMio, &mmckList, &ckMainRIFF, MMIO_FINDLIST) != 0) {
376 //WARN("Can't find 'movi' list\n");
377 return FALSE;
378 }
379
380 /* FIXME: should handle the 'rec ' LIST when present */
381
382 infoPtr->lpIndex = (DWORD*)HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY,
383 infoPtr->mah.dwTotalFrames * sizeof(DWORD));
384 if (!infoPtr->lpIndex) {
385 //WARN("Can't alloc index array\n");
386 return FALSE;
387 }
388
389 numFrame = insize = 0;
390 while (mmioDescend(infoPtr->hMMio, &mmckInfo, &mmckList, 0) == 0 &&
391 numFrame < infoPtr->mah.dwTotalFrames) {
392 infoPtr->lpIndex[numFrame] = mmckInfo.dwDataOffset;
393 if (insize < mmckInfo.cksize)
394 insize = mmckInfo.cksize;
395 numFrame++;
396 mmioAscend(infoPtr->hMMio, &mmckInfo, 0);
397 }
398 if (numFrame != infoPtr->mah.dwTotalFrames) {
399 //WARN("Found %ld frames (/%ld)\n", numFrame, infoPtr->mah.dwTotalFrames);
400 return FALSE;
401 }
402 if (insize > infoPtr->ash.dwSuggestedBufferSize) {
403 //WARN("insize=%ld suggestedSize=%ld\n", insize, infoPtr->ash.dwSuggestedBufferSize);
404 infoPtr->ash.dwSuggestedBufferSize = insize;
405 }
406
407 infoPtr->indata = HeapAlloc(GetProcessHeap(), 0, infoPtr->ash.dwSuggestedBufferSize);
408 if (!infoPtr->indata) {
409 //WARN("Can't alloc input buffer\n");
410 return FALSE;
411 }
412
413 return TRUE;
414}
415
416
417static BOOL ANIMATE_GetAviCodec(ANIMATE_INFO *infoPtr)
418{
419 DWORD outSize;
420
421 /* check uncompressed AVI */
422 if (infoPtr->ash.fccHandler == mmioFOURCC('D', 'I', 'B', ' ')) {
423 infoPtr->hic = 0;
424 return TRUE;
425 }
426
427 /* try to get a decompressor for that type */
428 infoPtr->hic = (infoPtr->fnICOpen)(ICTYPE_VIDEO,
429 infoPtr->ash.fccHandler,
430 ICMODE_DECOMPRESS);
431 if (!infoPtr->hic) {
432 //WARN("Can't load codec for the file\n");
433 return FALSE;
434 }
435
436 outSize = (infoPtr->fnICSendMessage)(infoPtr->hic,
437 ICM_DECOMPRESS_GET_FORMAT,
438 (DWORD)infoPtr->inbih, 0L);
439 infoPtr->outbih = (BITMAPINFOHEADER*)HeapAlloc(GetProcessHeap(), 0, outSize);
440 if (!infoPtr->outbih) {
441 //WARN("Can't alloc output BIH\n");
442 return FALSE;
443 }
444
445 if ((infoPtr->fnICSendMessage)(infoPtr->hic, ICM_DECOMPRESS_GET_FORMAT,
446 (DWORD)infoPtr->inbih,
447 (DWORD)infoPtr->outbih) != ICERR_OK) {
448 //WARN("Can't get output BIH\n");
449 return FALSE;
450 }
451
452 infoPtr->outdata = HeapAlloc(GetProcessHeap(), 0, infoPtr->outbih->biSizeImage);
453 if (!infoPtr->outdata) {
454 //WARN("Can't alloc output buffer\n");
455 return FALSE;
456 }
457
458 if ((infoPtr->fnICSendMessage)(infoPtr->hic, ICM_DECOMPRESS_BEGIN,
459 (DWORD)infoPtr->inbih,
460 (DWORD)infoPtr->outbih) != ICERR_OK) {
461 //WARN("Can't begin decompression\n");
462 return FALSE;
463 }
464
465 return TRUE;
466}
467
468static LRESULT ANIMATE_Open(HWND hWnd, WPARAM wParam, LPARAM lParam,BOOL unicode)
469{
470 ANIMATE_INFO *infoPtr = ANIMATE_GetInfoPtr(hWnd);
471 HINSTANCE hInstance = (HINSTANCE)wParam;
472
473 ANIMATE_Free(infoPtr);
474
475 if (!lParam) {
476 //TRACE("Closing avi!\n");
477 return TRUE;
478 }
479
480 if (!hInstance)
481 hInstance = GetWindowLongA(hWnd, GWL_HINSTANCE);
482
483 if (HIWORD(lParam)) {
484 //TRACE("(\"%s\");\n", (LPSTR)lParam);
485
486 if (!ANIMATE_LoadRes(infoPtr, hInstance, (LPWSTR)lParam,unicode)) {
487 //TRACE("No AVI resource found!\n");
488 if (!ANIMATE_LoadFile(infoPtr, (LPWSTR)lParam,unicode)) {
489 //WARN("No AVI file found!\n");
490 return FALSE;
491 }
492 }
493 } else {
494 //TRACE("(%u);\n", (WORD)LOWORD(lParam));
495
496 if (!ANIMATE_LoadRes(infoPtr,hInstance,unicode ? MAKEINTRESOURCEW((INT)lParam):(LPWSTR)MAKEINTRESOURCEA((INT)lParam),unicode)) {
497 //WARN("No AVI resource found!\n");
498 return FALSE;
499 }
500 }
501
502 if (!ANIMATE_GetAviInfo(infoPtr)) {
503 //WARN("Can't get AVI information\n");
504 ANIMATE_Free(infoPtr);
505 return FALSE;
506 }
507
508 if (!ANIMATE_GetAviCodec(infoPtr)) {
509 //WARN("Can't get AVI Codec\n");
510 ANIMATE_Free(infoPtr);
511 return FALSE;
512 }
513
514 if (GetWindowLongA(hWnd, GWL_STYLE) & ACS_CENTER) {
515 //FIXME("ACS_CENTER: NIY\n");
516 } else {
517 /* MoveWindow(hWnd, 0, 0, infoPtr->mah.dwWidth, infoPtr->mah.dwHeight, FALSE);*/
518 SetWindowPos(hWnd, 0, 0, 0, infoPtr->mah.dwWidth, infoPtr->mah.dwHeight,
519 SWP_NOACTIVATE | SWP_NOMOVE | SWP_NOZORDER);
520 }
521
522 if (GetWindowLongA(hWnd, GWL_STYLE) & ACS_TRANSPARENT) {
523 //FIXME("ACS_TRANSPARENT: NIY\n");
524 }
525
526 if (GetWindowLongA(hWnd, GWL_STYLE) & ACS_AUTOPLAY) {
527 return ANIMATE_Play(hWnd, -1, (LPARAM)MAKELONG(0, infoPtr->mah.dwTotalFrames-1));
528 }
529
530 return TRUE;
531}
532
533static LRESULT ANIMATE_Stop(HWND hWnd, WPARAM wParam, LPARAM lParam)
534{
535 ANIMATE_INFO *infoPtr = ANIMATE_GetInfoPtr(hWnd);
536
537 /* nothing opened */
538 if (!infoPtr->hMMio)
539 return FALSE;
540
541 ANIMATE_DoStop(infoPtr);
542 return TRUE;
543}
544
545
546static LRESULT ANIMATE_NCCreate(HWND hWnd, WPARAM wParam, LPARAM lParam)
547{
548 ANIMATE_INFO* infoPtr;
549 HMODULE hModule = LoadLibraryA("msvfw32.dll");
550
551 if (!hModule)
552 return FALSE;
553
554 /* allocate memory for info structure */
555 infoPtr = (ANIMATE_INFO*)initControl(hWnd,sizeof(ANIMATE_INFO));
556 if (!infoPtr) {
557 //ERR("could not allocate info memory!\n");
558 return 0;
559 }
560
561 /* Temporary hack until we get dllglue up and running */
562 *(VOID**)&infoPtr->fnICOpen = (VOID*)GetProcAddress(hModule, "ICOpen");
563 *(VOID**)&infoPtr->fnICClose = (VOID*)GetProcAddress(hModule, "ICClose");
564 *(VOID**)&infoPtr->fnICSendMessage = (VOID*)GetProcAddress(hModule, "ICSendMessage");
565 *(VOID**)&infoPtr->fnICDecompress = (VOID*)GetProcAddress(hModule, "ICDecompress");
566
567 //TRACE("Animate style=0x%08lx, parent=%08lx\n", GetWindowLongA(hWnd, GWL_STYLE), (DWORD)GetParent(hWnd));
568
569 /* store crossref hWnd <-> info structure */
570 infoPtr->hWnd = hWnd;
571
572 InitializeCriticalSection(&infoPtr->cs);
573 //RegisterDebugptr(&infoPtr->cs, "Animate infoPtr->cs");
574
575 return DefWindowProcA(hWnd,WM_NCCREATE,wParam,lParam);
576}
577
578static LRESULT ANIMATE_NCHitTest(HWND hwnd,WPARAM wParam,LPARAM lParam)
579{
580 return HTTRANSPARENT;
581}
582
583static LRESULT ANIMATE_Timer(HWND hWnd,WPARAM wParam,LPARAM lParam)
584{
585 return ANIMATE_DrawFrame(ANIMATE_GetInfoPtr(hWnd));
586}
587
588static LRESULT ANIMATE_Paint(HWND hWnd,WPARAM wParam,LPARAM lParam)
589{
590 if (wParam)
591 {
592 ANIMATE_PaintFrame(ANIMATE_GetInfoPtr(hWnd), (HDC)wParam);
593 } else
594 {
595 PAINTSTRUCT ps;
596 HDC hDC = BeginPaint(hWnd, &ps);
597
598 ANIMATE_PaintFrame(ANIMATE_GetInfoPtr(hWnd), hDC);
599 EndPaint(hWnd, &ps);
600 }
601
602 return 0;
603}
604
605static LRESULT ANIMATE_Destroy(HWND hWnd, WPARAM wParam, LPARAM lParam)
606{
607 ANIMATE_INFO *infoPtr = ANIMATE_GetInfoPtr(hWnd);
608
609
610 /* free avi data */
611 ANIMATE_Free(infoPtr);
612
613 /* free animate info data */
614 doneControl(hWnd);
615
616 return DefWindowProcA(hWnd,WM_DESTROY,wParam,lParam);
617}
618
619
620static LRESULT ANIMATE_EraseBackground(HWND hWnd, WPARAM wParam, LPARAM lParam)
621{
622 RECT rect;
623
624 GetClientRect(hWnd, &rect);
625#if 0
626 HBRUSH hBrush = CreateSolidBrush(infoPtr->clrBk);
627
628 FillRect((HDC)wParam, &rect, hBrush);
629 DeleteObject(hBrush);
630#else
631 FillRect((HDC)wParam, &rect, GetSysColorBrush(COLOR_WINDOW));
632#endif
633 return TRUE;
634}
635
636static LRESULT WINAPI ANIMATE_Close(HWND hWnd, WPARAM wParam, LPARAM lParam)
637{
638 ANIMATE_Free(ANIMATE_GetInfoPtr(hWnd));
639 return TRUE;
640}
641
642static LRESULT WINAPI ANIMATE_Size(HWND hWnd, WPARAM wParam, LPARAM lParam)
643{
644 ANIMATE_INFO *infoPtr = ANIMATE_GetInfoPtr(hWnd);
645
646 if (GetWindowLongA(hWnd, GWL_STYLE) & ACS_CENTER) {
647 //FIXME("NIY\n");
648 if (infoPtr->hMMio) {
649 /* centers the animation in the control, invalidates the control
650 */
651 }
652 InvalidateRect(hWnd, NULL, TRUE);
653 }
654 return DefWindowProcA(hWnd,WM_SIZE,wParam,lParam);
655}
656
657static LRESULT ANIMATE_StyleChanged(HWND hwnd,WPARAM wParam,LPARAM lParam)
658{
659 //CB: todo
660
661 return 0;
662}
663
664static LRESULT WINAPI ANIMATE_WindowProc (HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
665{
666 switch (uMsg)
667 {
668 case ACM_OPENA:
669 return ANIMATE_Open(hwnd,wParam,lParam,FALSE);
670
671 case ACM_OPENW:
672 return ANIMATE_Open(hwnd,wParam,lParam,TRUE);
673
674 case ACM_PLAY:
675 return ANIMATE_Play (hwnd, wParam, lParam);
676
677 case ACM_STOP:
678 return ANIMATE_Stop (hwnd, wParam, lParam);
679
680 case WM_CLOSE:
681 return ANIMATE_Close(hwnd,wParam,lParam);
682
683 case WM_NCCREATE:
684 return ANIMATE_NCCreate(hwnd,wParam,lParam);
685
686 case WM_DESTROY:
687 return ANIMATE_Destroy (hwnd, wParam, lParam);
688
689 case WM_ERASEBKGND:
690 return ANIMATE_EraseBackground (hwnd, wParam, lParam);
691
692 case WM_NCHITTEST:
693 return ANIMATE_NCHitTest(hwnd,wParam,lParam);
694
695 case WM_PAINT:
696 return ANIMATE_Paint(hwnd,wParam,lParam);
697
698 case WM_SIZE:
699 return ANIMATE_Size(hwnd,wParam,lParam);
700
701 case WM_STYLECHANGED:
702 return ANIMATE_StyleChanged(hwnd,wParam,lParam);
703
704 case WM_TIMER:
705 return ANIMATE_Timer(hwnd,wParam,lParam);
706
707 default:
708// if (uMsg >= WM_USER)
709// ERR (animate, "unknown msg %04x wp=%08x lp=%08lx\n",
710// uMsg, wParam, lParam);
711 return defComCtl32ProcA (hwnd, uMsg, wParam, lParam);
712 }
713
714 return 0;
715}
716
717
718VOID
719ANIMATE_Register (VOID)
720{
721 WNDCLASSA wndClass;
722
723 ZeroMemory (&wndClass, sizeof(WNDCLASSA));
724 wndClass.style = CS_GLOBALCLASS | CS_DBLCLKS;
725 wndClass.lpfnWndProc = (WNDPROC)ANIMATE_WindowProc;
726 wndClass.cbClsExtra = 0;
727 wndClass.cbWndExtra = sizeof(ANIMATE_INFO *);
728 wndClass.hCursor = LoadCursorA (0, IDC_ARROWA);
729 wndClass.hbrBackground = (HBRUSH)(COLOR_BTNFACE + 1);
730 wndClass.lpszClassName = ANIMATE_CLASSA;
731
732 RegisterClassA (&wndClass);
733}
734
735
736VOID
737ANIMATE_Unregister (VOID)
738{
739 UnregisterClassA (ANIMATE_CLASSA, (HINSTANCE)NULL);
740}
741
Note: See TracBrowser for help on using the repository browser.