Hi:

There was one last thing to resolve with the 2 earlier code posts.

The Animated Icon WAS NOT transparent.

After searching Microsoft I found that WS_EX_TRANSPARENT does not function for
re-drawing the window and apparently was never intended for this purpose. It
is considered a short lived modification to Windows GUI.

To fix this problem I modified the WM_PAINT section to pick up the background
pixel color under the icon before the first draw. This is stored in cvBackPix in the
ANIICON_INFO structure.

To achieve this the value is check for NULL which is a most unlikely window
background (BLACK).

Before drawing the icon the procedure now sets all pixels to the cvBackPix value
using a loop (faster and simpler than BitBlt).

In addition I found than the FrameChange .IF was redundant so all lines referencing
it have been removed.

I have tested all conbinations of DialogBox and Icon/Cursor Resource or File
and windows under the same conditions and am working on a complete sample.

But for those many who seem interested in the code I include the final ANNIICON_INFO structure and the complete AniWndProc.
ANIICON_INFO   Struct

pResInfo DWORD ?
hWndIcon DWORD ?
hImage DWORD ?
TimerID DWORD ?
cFrames DWORD ?
cFrameRate DWORD ?
FrameNumber DWORD ?
RateCount DWORD ?
cvBackPix DWORD ?
ANIICON_INFO Ends


AniIconWndProc Proc hWnd:HWND, uMsg:UINT, wParam:WPARAM, lParam:LPARAM
LOCAL pResInfo:DWORD, pIconInfo:DWORD
LOCAL wWidth:DWORD, wHeight:DWORD, vBaseUnits:DWORD
LOCAL IRect:RECT, IPoint:POINT, hWndParent:DWORD
LOCAL ps:PAINTSTRUCT, hDC:HDC, hpDC:HDC
LOCAL vWidthCount:DWORD, vHeightCount:DWORD
LOCAL vPixelColRef:DWORD

push edi
push esi

.IF uMsg == WM_NCCREATE
mov esi, lParam
ASSUME esi:PTR CREATESTRUCT
;
; Get the Resource ID or Name from the Title field
; Save it to a global variable and replace it with NULL
;
mov ebx, [esi].lpszName
.IF ebx == NULL
invoke GetWindowLong, hWnd, GWL_ID
mov AniWndProcResID, eax
.ELSE
mov eax, [esi].lpszName
mov bl, [eax]
.IF bl == NULL
invoke GetWindowLong, hWnd, GWL_ID
mov AniWndProcResID, eax
.ELSE
mov ebx, [esi].lpszName
mov AniWndProcResID, ebx
mov [esi].lpszName, NULL
.ENDIF
.ENDIF
invoke SetWindowLong, hWnd, GWL_STYLE, WS_CHILD
ASSUME esi:NOTHING
mov eax, TRUE
ret

.ELSEIF uMsg == WM_CLOSE
invoke DestroyWindow, hWnd

.ELSEIF uMsg == WM_DESTROY
invoke GetWindowLong, hWnd, GWL_USERDATA
.IF eax != NULL
mov esi, eax
ASSUME esi:PTR ANIICON_INFO
.IF [esi].hImage != NULL
invoke DestroyCursor, [esi].hImage
.ENDIF
.IF [esi].pResInfo != NULL
invoke GlobalFree, [esi].pResInfo
.ENDIF
.IF [esi].TimerID != NULL
invoke KillTimer, [esi].hWndIcon, [esi].TimerID
.ENDIF
invoke GlobalFree, esi
.ENDIF

.ELSEIF uMsg == WM_CREATE
invoke SetWindowLong, hWnd, GWL_USERDATA, NULL
invoke GlobalAlloc, GPTR, SIZEOF ANIICON_INFO
mov pIconInfo, eax
.IF eax == NULL
invoke SendMessage, hWnd, WM_CLOSE, NULL, NULL
jmp AniIconWndProc_Exit
.ENDIF
invoke SetWindowLong, hWnd, GWL_USERDATA, pIconInfo
mov esi, pIconInfo
ASSUME esi:PTR ANIICON_INFO
invoke GlobalAlloc, GPTR, SIZEOF ANIRESOURCE_INFO
mov pResInfo, eax
.IF eax == NULL
invoke SendMessage, hWnd, WM_CLOSE, NULL, NULL
jmp AniIconWndProc_Exit
.ENDIF
mov [esi].pResInfo, eax
mov eax, hWnd
mov [esi].hWndIcon, eax
;
; Load as Cursor first and then Icon to allow for varied use
;
mov edi, pResInfo
ASSUME edi:PTR ANIRESOURCE_INFO
invoke LoadAnimatedResource, hInstance, pResInfo, AniWndProcResID
.IF eax == TRUE
mov eax, [edi].hRAnimated
mov [esi].hImage, eax
mov eax, [edi].cFrames
mov [esi].cFrames, eax
mov eax, [edi].cFrameRate
mov [esi].cFrameRate, eax
mov [esi].RateCount, eax
and [esi].FrameNumber, NULL
and [esi].cvBackPix, NULL
.ELSE
and [esi].hImage, NULL
invoke SendMessage, hWnd, WM_CLOSE, NULL, NULL
jmp AniIconWndProc_Exit
.ENDIF
;
; Now Create the Timer
;
inc AniTimerCount
invoke SetTimer, hWnd, AniTimerCount, 11h, NULL
mov eax, AniTimerCount
mov [esi].TimerID, eax
;
; Mow resize the window to 20 dialog units square
;
invoke GetWindowRect, hWnd, ADDR IRect
invoke GetDialogBaseUnits
mov vBaseUnits, eax
and eax, 0000FFFFh
push edx
xor edx, edx
push ecx
mov ecx, 16
mul ecx
mov ecx, 4
div ecx
mov wWidth, eax
xor edx, edx
mov eax, vBaseUnits
shr eax, 10h
mov ecx, 16
mul ecx
mov ecx, 8
div ecx
mov wHeight, eax
pop ecx
pop edx
mov eax, IRect.left
mov IPoint.x, eax
mov eax, IRect.top
mov IPoint.y, eax
invoke GetWindowLong, hWnd, GWL_HWNDPARENT
mov hWndParent, eax
invoke ScreenToClient, hWndParent, ADDR IPoint
invoke MoveWindow, hWnd, IPoint.x, IPoint.y, wWidth, wHeight, TRUE

.ELSEIF uMsg == WM_PAINT
invoke GetWindowLong, hWnd, GWL_USERDATA
mov esi, eax
ASSUME esi:PTR ANIICON_INFO
.IF [esi].cvBackPix == NULL
invoke GetWindowRect, hWnd, ADDR IRect
mov eax, IRect.left
mov IPoint.x, eax
mov eax, IRect.right
mov IPoint.y, eax
invoke GetWindowLong, hWnd, GWL_HWNDPARENT
mov hWndParent, eax
invoke ScreenToClient, hWndParent, ADDR IPoint
;
; Move down 1 and right 1 only if not zero
;
inc IPoint.x
inc IPoint.y
;
; Get a device context
;
invoke GetDC, hWndParent
mov hpDC, eax
invoke GetPixel, hpDC, IPoint.x, IPoint.y
mov [esi].cvBackPix, eax
invoke ReleaseDC, hWndParent, hpDC
.ENDIF
invoke BeginPaint, hWnd, ADDR ps
mov hDC, eax
invoke GetClientRect, hWnd, ADDR IRect
mov eax, [esi].cvBackPix
mov vPixelColRef, eax
push esi
and vHeightCount, NULL
mov ebx, vHeightCount
.WHILE ebx < IRect.bottom
and vWidthCount, NULL
mov eax, vWidthCount
.WHILE eax < IRect.right
invoke SetPixel, hDC, vWidthCount, vHeightCount, vPixelColRef
inc vWidthCount
mov eax, vWidthCount
.ENDW
inc vHeightCount
mov ebx, vHeightCount
.ENDW
pop esi

invoke DrawIconEx, hDC, 0, 0, [esi].hImage, NULL, NULL, [esi].FrameNumber, NULL, DI_NORMAL
invoke EndPaint, hWnd, ADDR ps

.ELSEIF uMsg == WM_TIMER
invoke GetWindowLong, hWnd, GWL_USERDATA
mov esi, eax
ASSUME esi:PTR ANIICON_INFO
mov eax, wParam
.IF eax == [esi].TimerID
dec [esi].RateCount
.IF [esi].RateCount == 0
inc [esi].FrameNumber
mov eax, [esi].FrameNumber
.IF eax == [esi].cFrames
mov [esi].FrameNumber, NULL
.ENDIF
mov eax, [esi].cFrameRate
mov [esi].RateCount, eax
invoke InvalidateRect, hWnd, NULL, TRUE
.ENDIF
.ENDIF
.ELSE
invoke DefWindowProc,hWnd,uMsg,wParam,lParam
ret
.ENDIF
AniIconWndProc_Exit:
ASSUME esi:NOTHING
ASSUME edi:NOTHING
pop esi
pop edi
xor eax,eax
ret
AniIconWndProc Endp


Enjoy,
Norm

Posted on 2003-07-07 18:10:59 by ngc2501ca
Looks interesting.. i look forward to your example.

:NaN:
Posted on 2003-07-24 18:13:08 by NaN
Hi NaN:

The thread with my link for the example is no longer on the board??

So here it is:

http://www.geocities.com/ngc2501ca/

Norm :)
Posted on 2003-07-26 17:15:50 by ngc2501ca