summaryrefslogtreecommitdiff
path: root/plugins/modernb/modern_aniavatars.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'plugins/modernb/modern_aniavatars.cpp')
-rw-r--r--plugins/modernb/modern_aniavatars.cpp1315
1 files changed, 0 insertions, 1315 deletions
diff --git a/plugins/modernb/modern_aniavatars.cpp b/plugins/modernb/modern_aniavatars.cpp
deleted file mode 100644
index 5e060c2028..0000000000
--- a/plugins/modernb/modern_aniavatars.cpp
+++ /dev/null
@@ -1,1315 +0,0 @@
-/**************************************************************************\
-
-Miranda IM: the free IM client for Microsoft* Windows*
-
-Copyright 2000-2008 Miranda ICQ/IM project,
-all portions of this codebase are copyrighted to the people
-listed in contributors.txt.
-
-This program is free software; you can redistribute it and/or
-modify it under the terms of the GNU General Public License
-as published by the Free Software Foundation; either version 2
-of the License, or (at your option) any later version.
-
-This program is distributed in the hope that it will be useful,
-but WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-GNU General Public License for more details.
-
-You should have received a copy of the GNU General Public License
-along with this program; if not, write to the Free Software
-Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
-
-****************************************************************************
-
-Created: Mar 9, 2007
-
-Author: Artem Shpynov aka FYR: ashpynov@gmail.com
-
-****************************************************************************
-
-File contains implementation of animated avatars in contact list
-
-\**************************************************************************/
-
-#include "hdr/modern_commonheaders.h"
-
-#define IMMEDIATE_DRAW (!AniAva.bSeparateWindow)
-
-void GDIPlus_ExtractAnimatedGIF(TCHAR * szName, int width, int height, HBITMAP * pBmp, int ** pframesDelay, int * pframesCount, SIZE * sizeAvatar);
-BOOL GDIPlus_IsAnimatedGIF(TCHAR * szName);
-
-/* Next is module */
-#define ANIAVAWINDOWCLASS _T("MirandaModernAniAvatar")
-#define aacheck if (!AniAva.bModuleStarted) return
-#define aalock EnterCriticalSection(&AniAva.CS)
-#define aaunlock LeaveCriticalSection(&AniAva.CS)
-
-#define AAO_HAS_BORDER 0x01
-#define AAO_ROUND_CORNERS 0x02
-#define AAO_HAS_OVERLAY 0x04
-#define AAO_OPAQUE 0x08
-//messages
-enum {
- AAM_FIRST = WM_USER,
- AAM_SETAVATAR , //sync WPARAM: TCHAR * filename, LPARAM: SIZE * size, RESULT: actual size
- AAM_SETPOSITION, //async LPARAM: pointer to set pos info - the handler will empty it, RESULT: 0
- AAM_REDRAW, //async
- AAM_STOP, //async stops animation, timer, hide window - prepeare for deleting
- AAM_PAUSE, //sync keep timer and window, but do not process painting -need before graphics change
- AAM_RESUME, //async remobe previous flag. repaints if required
- AAM_REMOVEAVATAR, //sync WPARAM: if y more then wParam, LPARAM: shift up to lParam( remove if values is same)
- AAM_SETPARENT, //async WPARAM: handle of new parent window
- AAM_SELFDESTROY, //sync
- AAM_RENDER, //sync
- AAM_LAST,
-};
-
-typedef struct _tagAniAva_Object
-{
- HANDLE hContact;
- HWND hWindow;
- BOOL bInvalidPos;
- BOOL bToBeDeleted;
- DWORD dwAvatarUniqId;
- SIZE ObjectSize;
-} ANIAVA_OBJECT;
-
-typedef struct _tagAniAva_Info
-{
- DWORD dwAvatarUniqId;
- TCHAR * tcsFilename;
- int nRefCount;
- int nStripTop;
- int nFrameCount;
- int * pFrameDelays;
- SIZE FrameSize;
-} ANIAVA_INFO;
-
-typedef struct _tagAniAva_WindowInfo
-{
- HWND hWindow;
- RECT rcPos;
- SIZE sizeAvatar;
- BOOL StopTimer;
- int TimerId;
- int nFramesCount;
- int * delaysInterval;
- int currentFrame;
-
- POINT ptFromPoint;
-
- BOOL bPlaying;
- int overlayIconIdx;
- BYTE bAlpha;
- BOOL bOrderTop;
-
- BOOL bPaused; // was request do not draw
- BOOL bPended; // till do not draw - was painting - need to be repaint
-} ANIAVA_WINDOWINFO;
-typedef struct _tagAniAva_PosInfo
-{
- RECT rcPos;
- int idxOverlay;
- BYTE bAlpha;
-} ANIAVA_POSINFO;
-typedef struct _tagAniAvaSyncCallItem
-{
- WPARAM wParam;
- LPARAM lParam;
- INT_PTR nResult;
- HANDLE hDoneEvent;
- PSYNCCALLBACKPROC pfnProc;
-} ANIAVA_SYNCCALLITEM;
-typedef struct _tagAniAvatarImageInfo
-{
- POINT ptImagePos;
- int nFramesCount;
- int * pFrameDelays;
- SIZE szSize;
-} ANIAVATARIMAGEINFO;
-
-//main structure to handle global
-typedef struct _tagAniAva
-{
- //protection
- BOOL bModuleStarted;
- CRITICAL_SECTION CS;
- //options
- BYTE bFlags; // 0x1 has border, 0x2 has round corners, 0x4 has overlay, 0x8 background color
- COLORREF borderColor;
- BYTE cornerRadius;
- COLORREF bkgColor;
- HIMAGELIST overlayIconImageList;
- //animations
- HDC hAniAvaDC;
- HBITMAP hAniAvaBitmap;
- HBITMAP hAniAvaOldBitmap;
- int width;
- int height;
- SortedList * AniAvatarList;
- DWORD AnimationThreadID;
- HANDLE AnimationThreadHandle;
- HANDLE hExitEvent;
- //Objects
- SortedList * Objects;
- BOOL bSeparateWindow;
-} ANIAVA;
-
-//module static declarations
-static void __AniAva_DebugRenderStrip();
-
-static void _AniAva_DestroyAvatarWindow( HWND hwnd);
-static void _AniAva_Clear_ANIAVA_WINDOWINFO(ANIAVA_WINDOWINFO * pavwi );
-static void _AniAva_RenderAvatar(ANIAVA_WINDOWINFO * dat, HDC hdcParent = NULL, RECT * rcInParent = NULL );
-static void _AniAva_PausePainting();
-static void _AniAva_ResumePainting();
-static void _AniAva_LoadOptions();
-static void _AniAva_ReduceAvatarImages(int startY, int dY, BOOL bDestroyWindow);
-static void _AniAva_AnimationTreadProc(HANDLE hExitEvent);
-static void _AniAva_RemoveAniAvaDC(ANIAVA * pAniAva);
-static void _AniAva_RealRemoveAvatar(DWORD UniqueID);
-static int _AniAva_LoadAvatarFromImage(TCHAR * szFileName, int width, int height, ANIAVATARIMAGEINFO * pRetAII);
-static int _AniAva_SortAvatarInfo(void * first, void * last);
-static BOOL _AniAva_GetAvatarImageInfo(DWORD dwAvatarUniqId, ANIAVATARIMAGEINFO * avii);
-static HWND _AniAva_CreateAvatarWindowSync(TCHAR *szFileName);
-
-static LRESULT CALLBACK _AniAva_WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam);
-
-//module variables
-static ANIAVA AniAva={0};
-
-/// IMPLEMENTATION
-
-
-int _AniAva_OnModulesUnload(WPARAM wParam,LPARAM lParam)
-{
- SetEvent(AniAva.hExitEvent);
- return 0;
-}
-
-
-// Init AniAva module
-int AniAva_InitModule()
-{
- memset(&AniAva,0,sizeof(AniAva));
- if (g_CluiData.fGDIPlusFail) return 0;
- if (!( ModernGetSettingByte(NULL,"CList","AvatarsAnimated",(ServiceExists(MS_AV_GETAVATARBITMAP)&&!g_CluiData.fGDIPlusFail))
- && ModernGetSettingByte(NULL,"CList","AvatarsShow",SETTINGS_SHOWAVATARS_DEFAULT) ) ) return 0;
- {
- WNDCLASSEX wc;
- ZeroMemory(&wc, sizeof(wc));
- wc.cbSize = sizeof(wc);
- wc.lpszClassName = ANIAVAWINDOWCLASS;
- wc.lpfnWndProc = _AniAva_WndProc;
- wc.hCursor = LoadCursor(NULL, IDC_ARROW);
- wc.cbWndExtra = sizeof(ANIAVA_WINDOWINFO*);
- wc.hbrBackground = 0;
- wc.style = CS_GLOBALCLASS;
- RegisterClassEx(&wc);
- }
- InitializeCriticalSection(&AniAva.CS);
- AniAva.Objects=li.List_Create(0,2);
- AniAva.AniAvatarList=li.List_Create(0,1);
- AniAva.AniAvatarList->sortFunc=_AniAva_SortAvatarInfo;
- AniAva.bModuleStarted=TRUE;
- AniAva.hExitEvent=CreateEvent(NULL,FALSE,FALSE,NULL);
- AniAva.AnimationThreadID=(DWORD)mir_forkthread(_AniAva_AnimationTreadProc, (void*)AniAva.hExitEvent);
- ModernHookEvent(ME_SYSTEM_PRESHUTDOWN, _AniAva_OnModulesUnload);
-
- _AniAva_LoadOptions();
-
- return 1;
-}
-
-// Unload AniAva module
-int AniAva_UnloadModule()
-{
- aacheck 0;
- aalock;
- {
- int i;
- AniAva.bModuleStarted=FALSE;
- for (i=0; i<AniAva.Objects->realCount; i++)
- {
- if (AniAva.Objects->items[i])
- {
- _AniAva_DestroyAvatarWindow(((ANIAVA_OBJECT*)AniAva.Objects->items[i])->hWindow);
- }
- mir_free(AniAva.Objects->items[i]);
- }
- li.List_Destroy(AniAva.Objects);
- mir_free(AniAva.Objects);
-
- for (i=0; i<AniAva.AniAvatarList->realCount; i++)
- {
- ANIAVA_INFO * aai=(ANIAVA_INFO *)AniAva.AniAvatarList->items[i];
- if (aai->tcsFilename) mir_free(aai->tcsFilename);
- if (aai->pFrameDelays) free(aai->pFrameDelays);
- mir_free(aai);
- }
- li.List_Destroy(AniAva.AniAvatarList);
- mir_free(AniAva.AniAvatarList);
- _AniAva_RemoveAniAvaDC(&AniAva);
- SetEvent(AniAva.hExitEvent);
- CloseHandle(AniAva.hExitEvent);
- }
- aaunlock;
- DeleteCriticalSection(&AniAva.CS);
- return 1;
-}
-// Update options
-int AniAva_UpdateOptions()
-{
- BOOL bReloadAvatars=FALSE;
- BOOL bBeEnabled=(!g_CluiData.fGDIPlusFail
- && ModernGetSettingByte(NULL,"CList","AvatarsAnimated",(ServiceExists(MS_AV_GETAVATARBITMAP)&&!g_CluiData.fGDIPlusFail))
- && ModernGetSettingByte(NULL,"CList","AvatarsShow",SETTINGS_SHOWAVATARS_DEFAULT) );
- if (bBeEnabled && !AniAva.bModuleStarted)
- {
- AniAva_InitModule();
- bReloadAvatars=TRUE;
- }
- else if (!bBeEnabled && AniAva.bModuleStarted)
- {
- AniAva_UnloadModule();
- bReloadAvatars=TRUE;
- }
- BOOL oldSeparate = AniAva.bSeparateWindow;
- _AniAva_LoadOptions();
- if ( oldSeparate != AniAva.bSeparateWindow )
- {
- AniAva_InvalidateAvatarPositions(NULL);
- AniAva_RemoveInvalidatedAvatars();
- }
- if ( bReloadAvatars ) PostMessage(pcli->hwndContactTree,INTM_AVATARCHANGED,0,0);
- else AniAva_RedrawAllAvatars(TRUE);
- return 0;
-}
-// adds avatars to be displayed
-int AniAva_AddAvatar(HANDLE hContact, TCHAR * szFilename, int width, int heigth)
-{
- int res=0;
- aacheck 0;
- if (!GDIPlus_IsAnimatedGIF(szFilename))
- return 0;
- aalock;
- {
- //first try to find window for contact avatar
- HWND hwnd=NULL;
- int i;
- ANIAVA_OBJECT * pavi;
- ANIAVATARIMAGEINFO avii={0};
- SIZE szAva={ width, heigth };
- for (i=0; i<AniAva.Objects->realCount; i++)
- {
- pavi=(ANIAVA_OBJECT *)AniAva.Objects->items[i];
- if (pavi->hContact==hContact)
- {
- if (pavi->ObjectSize.cx==width && pavi->ObjectSize.cy==heigth)
- {
- hwnd=pavi->hWindow;
- break;
- }
- else
- {
-
- _AniAva_DestroyAvatarWindow(pavi->hWindow);
- pavi->hWindow=NULL;
- _AniAva_RealRemoveAvatar(pavi->dwAvatarUniqId);
- pavi->dwAvatarUniqId=0;
- break;
- }
- }
- }
- if (i==AniAva.Objects->realCount)
- {
- pavi = (ANIAVA_OBJECT *) mir_calloc( sizeof(ANIAVA_OBJECT) );
- pavi->hWindow = NULL;
- pavi->hContact = hContact;
- pavi->bInvalidPos = 0;
- li.List_Insert( AniAva.Objects, pavi, AniAva.Objects->realCount);
- }
- //change avatar
- pavi->bToBeDeleted=FALSE;
- pavi->bInvalidPos = 0;
- // now CreateAvatar
- if (pavi->dwAvatarUniqId)
- _AniAva_GetAvatarImageInfo(pavi->dwAvatarUniqId,&avii);
- else
- pavi->dwAvatarUniqId=_AniAva_LoadAvatarFromImage(szFilename, width, heigth, &avii);
- if (hwnd)
- SendMessage(hwnd, AAM_SETAVATAR, (WPARAM)&avii, (LPARAM) 0);
- pavi->ObjectSize=avii.szSize;
- res=MAKELONG(avii.szSize.cx, avii.szSize.cy);
- }
- aaunlock;
- return res;
-}
-
-// call windows to set they parent in order to ensure valid zorder
-void AniAva_UpdateParent()
-{
- aacheck;
- aalock;
- {
- int i;
- HWND parent = fnGetAncestor(pcli->hwndContactList,GA_PARENT);
- for (i=0; i<AniAva.Objects->realCount; i++)
- {
- ANIAVA_OBJECT * pai=(ANIAVA_OBJECT *)AniAva.Objects->items[i];
- SendMessage(pai->hWindow, AAM_SETPARENT, (WPARAM)parent,0);
- }
- }
- aaunlock;
-}
-ANIAVA_OBJECT * FindAvatarByContact( HANDLE hContact )
-{
- for ( int i=0; i<AniAva.Objects->realCount; i++)
- {
- ANIAVA_OBJECT * pai=((ANIAVA_OBJECT *)AniAva.Objects->items[i]);
- if (pai->hContact==hContact)
- return pai;
- }
- return NULL;
-}
-
-int AniAva_RenderAvatar( HANDLE hContact, HDC hdcMem, RECT * rc )
-{
- aacheck 0;
- aalock;
- ANIAVA_OBJECT * pai=FindAvatarByContact( hContact );
- if ( pai )
- SendMessage(pai->hWindow, AAM_RENDER, (WPARAM)hdcMem, (LPARAM) rc);
- aaunlock;
- return 0;
-}
-// update avatars pos
-int AniAva_SetAvatarPos(HANDLE hContact, RECT * rc, int overlayIdx, BYTE bAlpha)
-{
- aacheck 0;
- aalock;
- if (AniAva.CS.LockCount>0)
- {
- aaunlock;
- return 0;
- }
- {
- ANIAVA_OBJECT * pai=FindAvatarByContact( hContact );
- if ( pai )
- {
- ANIAVA_POSINFO * api=(ANIAVA_POSINFO *)malloc(sizeof(ANIAVA_POSINFO));
- if (!pai->hWindow)
- {
- HWND hwnd;
- HWND parent;
- ANIAVATARIMAGEINFO avii={0};
- //not found -> create window
- char szName[150] = "AniAvaWnd_";
- TCHAR * tszName;
- _itoa((int)hContact,szName+10,16);
-#ifdef _DEBUG
- {
- char *temp;
- PDNCE pdnce=(PDNCE)pcli->pfnGetCacheEntry(hContact);
-
- if ( pdnce && pdnce->m_cache_tcsName )
- {
- temp=mir_t2a(pdnce->m_cache_tcsName);
- strcat(szName,"_");
- strcat(szName,temp);
- mir_free(temp);
- }
- }
-#endif
- tszName = mir_a2t( szName );
- hwnd=_AniAva_CreateAvatarWindowSync(tszName);
- mir_free( tszName );
- parent=fnGetAncestor(pcli->hwndContactList,GA_PARENT);
- pai->hWindow=hwnd;
- SendMessage(hwnd,AAM_SETPARENT,(WPARAM)parent,0);
- if (_AniAva_GetAvatarImageInfo(pai->dwAvatarUniqId,&avii))
- SendMessage(pai->hWindow, AAM_SETAVATAR, (WPARAM)&avii, (LPARAM) 0);
- }
- api->bAlpha=bAlpha;
- api->idxOverlay=overlayIdx;
- api->rcPos=*rc;
- SendNotifyMessage(pai->hWindow, AAM_SETPOSITION, (WPARAM)0, (LPARAM) api);
- // the AAM_SETPOSITION is responsible to destroy memory under api
- pai->bInvalidPos=FALSE;
- pai->bToBeDeleted=FALSE;
- }
- }
- aaunlock;
- return 1;
-}
-// remove avatar
-int AniAva_RemoveAvatar(HANDLE hContact)
-{
- aacheck 0;
- aalock;
- {
- int i;
- for (i=0; i<AniAva.Objects->realCount; i++)
- {
- ANIAVA_OBJECT * pai=(ANIAVA_OBJECT *)AniAva.Objects->items[i];
- if (pai->hContact == hContact)
- {
- pai->bToBeDeleted=TRUE;
- break;
- }
- }
- }
- aaunlock;
- return 1;
-}
-// reset positions of avatars to be drawn (still be painted at same place)
-int AniAva_InvalidateAvatarPositions(HANDLE hContact)
-{
- int i;
- aacheck 0;
- aalock;
- for (i=0; i<AniAva.Objects->realCount; i++)
- {
- ANIAVA_OBJECT * pai=(ANIAVA_OBJECT *)AniAva.Objects->items[i];
- if (pai->hContact==hContact || !hContact)
- {
- pai->bInvalidPos++;
- if (hContact) break;
- }
- }
- aaunlock;
- return 1;
-}
-// all avatars without validated position will be stop painted and probably removed
-int AniAva_RemoveInvalidatedAvatars()
-{
- BOOL keepAvatar=FALSE;
- aacheck 0;
- aalock;
-
- {
- int i;
- for (i=0; i<AniAva.Objects->realCount; i++)
- {
- ANIAVA_OBJECT * pai=(ANIAVA_OBJECT *)AniAva.Objects->items[i];
- if (pai->hWindow && (pai->bInvalidPos) )
- {
- SendMessage(pai->hWindow,AAM_STOP,0,0);
- if (pai->bInvalidPos)//>3)
- {
- //keepAvatar=TRUE;
- //pai->bToBeDeleted=TRUE;
- pai->bInvalidPos=0;
- _AniAva_DestroyAvatarWindow(pai->hWindow);
- pai->hWindow=NULL;
- }
- }
- if (pai->bToBeDeleted)
- {
- if (pai->hWindow) _AniAva_DestroyAvatarWindow(pai->hWindow);
- pai->hWindow=NULL;
- if (!keepAvatar) _AniAva_RealRemoveAvatar(pai->dwAvatarUniqId);
- mir_free(pai);
- li.List_Remove(AniAva.Objects,i);
- i--;
- }
- }
- }
- aaunlock;
- return 1;
-}
-
-// repaint all avatars at positions (eg on main window movement)
-int AniAva_RedrawAllAvatars(BOOL updateZOrder)
-{
- int i;
- aacheck 0;
- aalock;
- updateZOrder=1;
- for (i=0; i<AniAva.Objects->realCount; i++)
- {
- ANIAVA_OBJECT * pai=(ANIAVA_OBJECT *)AniAva.Objects->items[i];
- if (updateZOrder)
- SendMessage(pai->hWindow,AAM_REDRAW,(WPARAM)updateZOrder,0);
- else
- SendNotifyMessage(pai->hWindow,AAM_REDRAW,(WPARAM)updateZOrder,0);
- }
- aaunlock;
- return 1;
-}
-
-//Static procedures
-static void CALLBACK _AniAva_SyncCallerUserAPCProc(DWORD_PTR dwParam)
-{
- ANIAVA_SYNCCALLITEM* item = (ANIAVA_SYNCCALLITEM*) dwParam;
- item->nResult = item->pfnProc(item->wParam, item->lParam);
- SetEvent(item->hDoneEvent);
-}
-static INT_PTR _AniAva_CreateAvatarWindowSync_Worker(WPARAM tszName, LPARAM lParam)
-{
- HWND hwnd=CreateWindowEx( WS_EX_TOPMOST | WS_EX_TRANSPARENT | WS_EX_NOPARENTNOTIFY,ANIAVAWINDOWCLASS,(TCHAR*)tszName,WS_POPUP,
- 0,0,1,1,pcli->hwndContactList, NULL, pcli->hInst, NULL );
- return (INT_PTR)hwnd;
-}
-
-static HWND _AniAva_CreateAvatarWindowSync(TCHAR *szFileName)
-{
- ANIAVA_SYNCCALLITEM item={0};
- int res=0;
- if (!AniAva.AnimationThreadHandle) return NULL;
- if (AniAva.AnimationThreadID==0) return NULL;
- item.wParam = (WPARAM) szFileName;
- item.lParam = 0;
- item.pfnProc = _AniAva_CreateAvatarWindowSync_Worker;
- item.hDoneEvent = CreateEvent(NULL, FALSE, FALSE, NULL);
- if (GetCurrentThreadId()!=AniAva.AnimationThreadID)
- QueueUserAPC(_AniAva_SyncCallerUserAPCProc, AniAva.AnimationThreadHandle, (DWORD_PTR) &item);
- else
- _AniAva_SyncCallerUserAPCProc((DWORD_PTR) &item);
- WaitForSingleObject(item.hDoneEvent, INFINITE);
- CloseHandle(item.hDoneEvent);
- return (HWND)item.nResult;
-}
-
-static void _AniAva_RealRemoveAvatar(DWORD UniqueID)
-{
- int j,k;
- for (j=0; j<AniAva.AniAvatarList->realCount; j++)
- {
- ANIAVA_INFO * aai=(ANIAVA_INFO *) AniAva.AniAvatarList->items[j];
- if (aai->dwAvatarUniqId==UniqueID)
- {
- aai->nRefCount--;
- if (aai->nRefCount==0)
- {
- _AniAva_PausePainting();
- #ifdef _DEBUG
- __AniAva_DebugRenderStrip();
- #endif
- if (aai->tcsFilename) mir_free(aai->tcsFilename);
- if (aai->pFrameDelays) free(aai->pFrameDelays);
- _AniAva_ReduceAvatarImages(aai->nStripTop,aai->FrameSize.cx*aai->nFrameCount, FALSE);
- for (k=0; k<AniAva.AniAvatarList->realCount; k++)
- if (k!=j) {
- ANIAVA_INFO * taai=(ANIAVA_INFO *) AniAva.AniAvatarList->items[k];
- if (taai->nStripTop>aai->nStripTop)
- taai->nStripTop-=aai->FrameSize.cx*aai->nFrameCount;
- }
- if (AniAva.AniAvatarList->realCount>0)
- {
- //lets create hNewDC
- HDC hNewDC;
- HBITMAP hNewBmp, hNewOldBmp;
-
- int newWidth=AniAva.width-aai->FrameSize.cx*aai->nFrameCount;
- int newHeight=0;
- int i;
- for (i=0; i<AniAva.AniAvatarList->realCount; i++)
- if (i!=j)
- {
- newHeight=max(newHeight,((ANIAVA_INFO *) AniAva.AniAvatarList->items[i])->FrameSize.cy);
- }
-
- hNewDC=CreateCompatibleDC(NULL);
- hNewBmp=ske_CreateDIB32(newWidth,newHeight);
- hNewOldBmp=(HBITMAP)SelectObject(hNewDC,hNewBmp);
- // copy from old and from new strip
- if (aai->nStripTop>0)
- BitBlt(hNewDC,0,0,aai->nStripTop,newHeight,AniAva.hAniAvaDC,0,0, SRCCOPY);
- if (aai->nStripTop+aai->FrameSize.cx*aai->nFrameCount<AniAva.width)
- BitBlt(hNewDC,aai->nStripTop,0,AniAva.width-(aai->nStripTop+aai->FrameSize.cx*aai->nFrameCount),newHeight,AniAva.hAniAvaDC,aai->nStripTop+aai->FrameSize.cx*aai->nFrameCount,0, SRCCOPY);
-
- _AniAva_RemoveAniAvaDC(&AniAva);
- AniAva.hAniAvaDC =hNewDC;
- AniAva.hAniAvaBitmap =hNewBmp;
- AniAva.hAniAvaOldBitmap =hNewOldBmp;
- AniAva.width =newWidth;
- AniAva.height =newHeight;
-
- }
- else
- {
- _AniAva_RemoveAniAvaDC(&AniAva);
- }
- #ifdef _DEBUG
- __AniAva_DebugRenderStrip();
- #endif
- li.List_Remove(AniAva.AniAvatarList, j);
- mir_free(aai);
- _AniAva_ResumePainting();
- break;
- }
- }
- }
-}
-static void _AniAva_RemoveAniAvaDC(ANIAVA * pAniAva)
-{
- if(pAniAva->hAniAvaDC)
- {
- SelectObject(pAniAva->hAniAvaDC, pAniAva->hAniAvaOldBitmap);
- DeleteObject(pAniAva->hAniAvaBitmap);
- DeleteDC(pAniAva->hAniAvaDC);
- pAniAva->hAniAvaDC=NULL;
- pAniAva->height=0;
- pAniAva->width=0;
- pAniAva->hAniAvaBitmap=NULL;
- }
-};
-
-static void _AniAva_DestroyAvatarWindow( HWND hwnd)
-{
- SendMessage(hwnd,AAM_SELFDESTROY,0,0);
-}
-static int _AniAva_LoadAvatarFromImage(TCHAR * szFileName, int width, int height, ANIAVATARIMAGEINFO * pRetAII)
-{
- ANIAVA_INFO aai={0};
- ANIAVA_INFO * paai=NULL;
- BOOL fNeedInsertToList=FALSE;
- int idx=0;
- aai.tcsFilename=szFileName;
- aai.FrameSize.cx=width;
- aai.FrameSize.cy=height;
-
- if (!li.List_GetIndex(AniAva.AniAvatarList,(void*)&aai,&idx)) idx=-1;
- if (idx==-1) //item not present in list
- {
- HBITMAP hBitmap=NULL;
- HDC hTempDC;
- HBITMAP hOldBitmap;
- HDC hNewDC;
- HBITMAP hNewBmp;
- HBITMAP hNewOldBmp;
- int newWidth;
- int newHeight;
-
- paai=(ANIAVA_INFO *)mir_calloc(sizeof(ANIAVA_INFO));
- paai->tcsFilename=mir_tstrdup(szFileName);
- paai->dwAvatarUniqId=rand();
- fNeedInsertToList=TRUE;
- //get image strip
- GDIPlus_ExtractAnimatedGIF(szFileName, width, height, &hBitmap, &(paai->pFrameDelays), &(paai->nFrameCount), &(paai->FrameSize));
-
- //copy image to temp DC
- hTempDC=CreateCompatibleDC(NULL);
- hOldBitmap=(HBITMAP)SelectObject(hTempDC,hBitmap);
-
- //lets create hNewDC
- /*
- newWidth=max(paai->FrameSize.cx*paai->nFrameCount,AniAva.width);
- newHeight=AniAva.height+paai->FrameSize.cy;
- */
- newWidth=AniAva.width+paai->FrameSize.cx*paai->nFrameCount;
- newHeight=max(paai->FrameSize.cy,AniAva.height);
-
- hNewDC=CreateCompatibleDC(NULL);
- hNewBmp=ske_CreateDIB32(newWidth,newHeight);
- hNewOldBmp=(HBITMAP)SelectObject(hNewDC,hNewBmp);
-
- _AniAva_PausePainting();
- GdiFlush();
- // copy from old and from new strip
- BitBlt(hNewDC,0,0,AniAva.width,AniAva.height,AniAva.hAniAvaDC,0,0, SRCCOPY);
- BitBlt(hNewDC,AniAva.width,0,paai->FrameSize.cx*paai->nFrameCount,paai->FrameSize.cy,hTempDC,0,0, SRCCOPY);
-
- paai->nStripTop=AniAva.width;
-
- GdiFlush();
- //remove temp DC
- SelectObject(hTempDC,hOldBitmap);
- DeleteObject(hNewBmp);
- DeleteDC(hTempDC);
- DeleteObject(hBitmap);
-
-
- //delete old
- _AniAva_RemoveAniAvaDC(&AniAva);
- //setNewDC;
- AniAva.hAniAvaDC =hNewDC;
- AniAva.hAniAvaBitmap =hNewBmp;
- AniAva.hAniAvaOldBitmap =hNewOldBmp;
- AniAva.width =newWidth;
- AniAva.height =newHeight;
- GdiFlush();
- _AniAva_ResumePainting();
- }
- else
- {
- paai=(ANIAVA_INFO *)AniAva.AniAvatarList->items[idx];
- }
- if (paai)
- {
- paai->nRefCount++;
- pRetAII->nFramesCount=paai->nFrameCount;
- pRetAII->pFrameDelays=paai->pFrameDelays;
- pRetAII->ptImagePos.x=paai->nStripTop;
- pRetAII->ptImagePos.y=0;
- pRetAII->szSize=paai->FrameSize;
- if (fNeedInsertToList)
- {
- //add to list
- int idx=AniAva.AniAvatarList->realCount;
- li.List_GetIndex(AniAva.AniAvatarList, paai,&idx);
- li.List_Insert(AniAva.AniAvatarList, (void*)paai, idx);
- }
- return paai->dwAvatarUniqId;
- }
- return 0;
-}
-static BOOL _AniAva_GetAvatarImageInfo(DWORD dwAvatarUniqId, ANIAVATARIMAGEINFO * avii)
-{
- int j;
- BOOL res=FALSE;
- for (j=0; j<AniAva.AniAvatarList->realCount; j++)
- {
- ANIAVA_INFO * aai=(ANIAVA_INFO *) AniAva.AniAvatarList->items[j];
- if (aai->dwAvatarUniqId==dwAvatarUniqId)
- {
- avii->nFramesCount=aai->nFrameCount;
- avii->pFrameDelays=aai->pFrameDelays;
- avii->ptImagePos.x=aai->nStripTop;
- avii->ptImagePos.y=0;
- avii->szSize=aai->FrameSize;
- res=TRUE;
- break;
- }
- }
- return res;
-}
-static void _AniAva_Clear_ANIAVA_WINDOWINFO(ANIAVA_WINDOWINFO * pavwi )
-{
- pavwi->delaysInterval=NULL;
- pavwi->nFramesCount=0;
- KillTimer(pavwi->hWindow,2);
- pavwi->bPlaying =FALSE;
- pavwi->TimerId=0;
-}
-static void __AniAva_DebugRenderStrip()
-{
- return;
- #ifdef _DEBUG
- {
- HDC hDC_debug=GetDC(NULL);
- BitBlt(hDC_debug,0,0,AniAva.width, AniAva.height,AniAva.hAniAvaDC,0,0,SRCCOPY);
- DeleteDC(hDC_debug);
- }
- #endif
-}
-
-static void _AniAva_RenderAvatar(ANIAVA_WINDOWINFO * dat, HDC hdcParent /* = NULL*/, RECT * rcInParent /* = NULL */ )
-{
- if (dat->bPaused>0) { dat->bPended=TRUE; return; }
- else dat->bPended=FALSE;
-
- if ( IMMEDIATE_DRAW && hdcParent == NULL ) return;
- GdiFlush();
-#ifdef _DEBUG
- __AniAva_DebugRenderStrip();
-#endif
- if (dat->bPlaying && IsWindowVisible(dat->hWindow))
- {
- POINT ptWnd={0};
- SIZE szWnd={dat->rcPos.right-dat->rcPos.left,dat->rcPos.bottom-dat->rcPos.top};
- BLENDFUNCTION bf={AC_SRC_OVER, 0,g_CluiData.bCurrentAlpha*dat->bAlpha/256, AC_SRC_ALPHA };
- POINT pt_from={0,0};
- HDC hDC_animation=GetDC(NULL);
- HDC copyFromDC;
- RECT clistRect;
- HDC tempDC=NULL;
- HBITMAP hBmp;
- HBITMAP hOldBmp;
-
- /*
- int x=bf.SourceConstantAlpha;
- x=(49152/(383-x))-129;
- x=min(x,255); x=max(x,0);
- bf.SourceConstantAlpha=x;
- */
- if ( AniAva.bFlags == 0 ) //simple and fastest method - no borders, round corners and etc. just copy
- {
- pt_from.x=dat->ptFromPoint.x+dat->currentFrame*dat->sizeAvatar.cx;
- pt_from.y=dat->ptFromPoint.y;
- copyFromDC=AniAva.hAniAvaDC;
- }
- else
- {
- // ... need to create additional hDC_animation
- HRGN hRgn=NULL;
- int cornerRadius= AniAva.cornerRadius;
- tempDC = CreateCompatibleDC( NULL );
- hBmp = ske_CreateDIB32( szWnd.cx, szWnd.cy );
- hOldBmp = (HBITMAP)SelectObject(tempDC,hBmp);
- if ( AniAva.bFlags & AAO_ROUND_CORNERS )
- {
- if (!cornerRadius) //auto radius
- cornerRadius = min(szWnd.cx, szWnd.cy )/5;
- }
- if ( AniAva.bFlags & AAO_HAS_BORDER )
- {
- // if has borders - create region (round corners) and fill it, remember internal as clipping
- HBRUSH hBrush = CreateSolidBrush( AniAva.borderColor );
- HBRUSH hOldBrush = (HBRUSH)SelectObject( tempDC, hBrush );
- HRGN rgnOutside = CreateRoundRectRgn( 0, 0, szWnd.cx+1, szWnd.cy+1, cornerRadius<<1, cornerRadius<<1);
- hRgn=CreateRoundRectRgn( 1, 1, szWnd.cx, szWnd.cy, cornerRadius<<1, cornerRadius<<1);
- CombineRgn( rgnOutside,rgnOutside,hRgn,RGN_DIFF);
- FillRgn( tempDC, rgnOutside, hBrush);
- ske_SetRgnOpaque( tempDC, rgnOutside, TRUE);
- SelectObject(tempDC, hOldBrush);
- DeleteObject(hBrush);
- DeleteObject(rgnOutside);
- }
- else if ( cornerRadius > 0 )
- {
- // else create clipping area (round corners)
- hRgn=CreateRoundRectRgn(0, 0, szWnd.cx+1, szWnd.cy+1, cornerRadius<<1, cornerRadius<<1);
- }
- else
- {
- hRgn=CreateRectRgn(0, 0, szWnd.cx+1, szWnd.cy+1);
- }
- // select clip area
- if ( hRgn )
- ExtSelectClipRgn(tempDC, hRgn, RGN_AND);
-
- if ( AniAva.bFlags & AAO_OPAQUE)
- {
- // if back color - fill clipping area
- HBRUSH hBrush = CreateSolidBrush( AniAva.bkgColor );
- HBRUSH hOldBrush = (HBRUSH)SelectObject( tempDC, hBrush );
- FillRgn( tempDC, hRgn, hBrush );
- ske_SetRgnOpaque( tempDC, hRgn, TRUE );
- }
- // draw avatar
- if ( !(AniAva.bFlags & AAO_OPAQUE) )
- BitBlt(tempDC,0, 0, szWnd.cx, szWnd.cy , AniAva.hAniAvaDC , dat->ptFromPoint.x+dat->sizeAvatar.cx*dat->currentFrame, dat->ptFromPoint.y, SRCCOPY);
- else
- {
- BLENDFUNCTION abf={AC_SRC_OVER, 0, 255, AC_SRC_ALPHA };
- ske_AlphaBlend(tempDC,0, 0, szWnd.cx, szWnd.cy , AniAva.hAniAvaDC, dat->ptFromPoint.x+dat->sizeAvatar.cx*dat->currentFrame, dat->ptFromPoint.y, szWnd.cx, szWnd.cy, abf);
- }
- // reset clip area
- if ( hRgn )
- {
- DeleteObject(hRgn);
- hRgn = CreateRectRgn(0, 0, szWnd.cx, szWnd.cy);
- SelectClipRgn(tempDC, hRgn);
- DeleteObject(hRgn);
- }
-
- if ( ( AniAva.bFlags & AAO_HAS_OVERLAY )
- && ( dat->overlayIconIdx != -1 )
- && ( AniAva.overlayIconImageList ) )
- {
- // if overlay - draw overlay icon
- // position - on avatar
- int x=szWnd.cx-ICON_WIDTH;
- int y=szWnd.cy-ICON_HEIGHT;
- ske_ImageList_DrawEx(AniAva.overlayIconImageList,
- dat->overlayIconIdx&0xFFFF,
- tempDC, x, y, ICON_WIDTH, ICON_HEIGHT,
- CLR_NONE, CLR_NONE, ILD_NORMAL);
- }
- copyFromDC=tempDC;
- }
- // intersect visible area
- // update layered window
- GetWindowRect(pcli->hwndContactTree, &clistRect);
- if (dat->rcPos.top<0)
- {
- pt_from.y+=-dat->rcPos.top;
- szWnd.cy+=dat->rcPos.top;
- }
- if (dat->rcPos.bottom>clistRect.bottom-clistRect.top)
- {
- szWnd.cy-=(dat->rcPos.bottom-(clistRect.bottom-clistRect.top));
- }
- ptWnd.x=dat->rcPos.left+clistRect.left;
- ptWnd.y=(dat->rcPos.top>0 ? dat->rcPos.top :0)+clistRect.top;
- if (szWnd.cy>0)
- {
- if ( hdcParent && rcInParent && IMMEDIATE_DRAW )
- {
- if ( AniAva.bFlags & AAO_OPAQUE )
- BitBlt( hdcParent, rcInParent->left, rcInParent->top, szWnd.cx, szWnd.cy, copyFromDC, pt_from.x, pt_from.y, SRCCOPY);
- else
- {
- BLENDFUNCTION abf={AC_SRC_OVER, 0, 255, AC_SRC_ALPHA };
- ske_AlphaBlend( hdcParent, rcInParent->left, rcInParent->top, szWnd.cx, szWnd.cy, copyFromDC, pt_from.x, pt_from.y, szWnd.cx, szWnd.cy, abf);
- }
- }
- else if (!g_proc_UpdateLayeredWindow(dat->hWindow, hDC_animation, &ptWnd, &szWnd, copyFromDC, &pt_from, RGB(0,0,0), &bf, ULW_ALPHA ))
- {
- LONG exStyle;
- exStyle=GetWindowLong(dat->hWindow,GWL_EXSTYLE);
- exStyle|=WS_EX_LAYERED;
- SetWindowLong(dat->hWindow,GWL_EXSTYLE,exStyle);
- if ( !IMMEDIATE_DRAW )
- SetWindowPos( pcli->hwndContactTree, dat->hWindow, 0, 0, 0, 0, SWP_ASYNCWINDOWPOS | SWP_NOSIZE | SWP_NOMOVE | SWP_NOACTIVATE | SWP_NOSENDCHANGING );
- g_proc_UpdateLayeredWindow(dat->hWindow, hDC_animation, &ptWnd, &szWnd, copyFromDC, &pt_from, RGB(0,0,0), &bf, ULW_ALPHA );
- }
-
- g_CluiData.fAeroGlass = false;
- CLUI_UpdateAeroGlass();
- }
- else
- {
- dat->bPlaying=FALSE;
- }
- ReleaseDC(NULL,hDC_animation);
- if (tempDC)
- {
- SelectObject(tempDC, hOldBmp);
- DeleteObject(hBmp);
- DeleteDC(tempDC);
- }
- }
- if (!dat->bPlaying)
- {
- ShowWindow(dat->hWindow, SW_HIDE);
- KillTimer(dat->hWindow,2); //stop animation till set pos will be called
- }
- GdiFlush();
-}
-static void _AniAva_PausePainting()
-{
- int i;
- for (i=0; i<AniAva.Objects->realCount; i++)
- {
- ANIAVA_OBJECT * pai=(ANIAVA_OBJECT *)AniAva.Objects->items[i];
- SendMessage(pai->hWindow,AAM_PAUSE,0,0);
- }
-}
-static void _AniAva_ResumePainting()
-{
- int i;
- for (i=0; i<AniAva.Objects->realCount; i++)
- {
- ANIAVA_OBJECT * pai=(ANIAVA_OBJECT *)AniAva.Objects->items[i];
- SendNotifyMessage(pai->hWindow,AAM_RESUME,0,0);
- }
-}
-
-static void _AniAva_ReduceAvatarImages(int startY, int dY, BOOL bDestroyWindow)
-{
- int i;
- for (i=0; i<AniAva.Objects->realCount; i++)
- {
- ANIAVA_OBJECT * pai=(ANIAVA_OBJECT *)AniAva.Objects->items[i];
- int res=SendMessage(pai->hWindow,AAM_REMOVEAVATAR,(WPARAM)startY,(LPARAM)dY);
- if (res==0xDEAD && bDestroyWindow)
- {
- _AniAva_DestroyAvatarWindow(pai->hWindow);
- mir_free(pai);
- li.List_Remove(AniAva.Objects,i);
- i--;
- }
- }
-}
-
-
-static void _AniAva_LoadOptions()
-{
- aacheck;
- aalock;
- {
- AniAva.bFlags= (ModernGetSettingByte(NULL,"CList","AvatarsDrawBorders",SETTINGS_AVATARDRAWBORDER_DEFAULT)? AAO_HAS_BORDER :0) |
- (ModernGetSettingByte(NULL,"CList","AvatarsRoundCorners",SETTINGS_AVATARROUNDCORNERS_DEFAULT)? AAO_ROUND_CORNERS :0) |
- (ModernGetSettingByte(NULL,"CList","AvatarsDrawOverlay",SETTINGS_AVATARDRAWOVERLAY_DEFAULT)? AAO_HAS_OVERLAY :0) |
- ( (0) ? AAO_OPAQUE :0);
-
- if (AniAva.bFlags & AAO_HAS_BORDER)
- AniAva.borderColor=(COLORREF)ModernGetSettingDword(NULL,"CList","AvatarsBorderColor",SETTINGS_AVATARBORDERCOLOR_DEFAULT);;
- if (AniAva.bFlags & AAO_ROUND_CORNERS)
- AniAva.cornerRadius=ModernGetSettingByte(NULL,"CList","AvatarsUseCustomCornerSize",SETTINGS_AVATARUSECUTOMCORNERSIZE_DEFAULT)? ModernGetSettingWord(NULL,"CList","AvatarsCustomCornerSize",SETTINGS_AVATARCORNERSIZE_DEFAULT) : 0;
- if (AniAva.bFlags & AAO_HAS_OVERLAY)
- {
- //check image list
- BYTE type=ModernGetSettingByte(NULL,"CList","AvatarsOverlayType",SETTINGS_AVATAROVERLAYTYPE_DEFAULT);
- switch(type)
- {
- case SETTING_AVATAR_OVERLAY_TYPE_NORMAL:
- AniAva.overlayIconImageList=hAvatarOverlays;
- break;
- case SETTING_AVATAR_OVERLAY_TYPE_PROTOCOL:
- case SETTING_AVATAR_OVERLAY_TYPE_CONTACT:
- AniAva.overlayIconImageList=g_himlCListClc;
- break;
- default:
- AniAva.overlayIconImageList=NULL;
- }
- }
- if (AniAva.bFlags & AAO_OPAQUE)
- AniAva.bkgColor=0;
- AniAva.bSeparateWindow = ModernGetSettingByte(NULL,"CList","AvatarsInSeparateWnd",SETTINGS_AVATARINSEPARATE_DEFAULT);
-
- }
- aaunlock;
-}
-static void _AniAva_AnimationTreadProc(HANDLE hExitEvent)
-{
- //wait forever till hExitEvent signalled
- DWORD rc;
- HANDLE hThread=0;
- DuplicateHandle(GetCurrentProcess(),GetCurrentThread(),GetCurrentProcess(),&hThread,0,FALSE,DUPLICATE_SAME_ACCESS);
- AniAva.AnimationThreadHandle=hThread;
- SetThreadPriority(hThread,THREAD_PRIORITY_LOWEST);
- for (;;)
- {
- if ( fnMsgWaitForMultipleObjectsEx )
- rc = fnMsgWaitForMultipleObjectsEx(1,&hExitEvent, INFINITE, QS_ALLINPUT, MWMO_ALERTABLE);
- else
- rc = MsgWaitForMultipleObjects(1,&hExitEvent, FALSE, INFINITE, QS_ALLINPUT);
-
- ResetEvent(hExitEvent);
- if ( rc == WAIT_OBJECT_0 + 1 )
- {
- MSG msg;
- while ( PeekMessage(&msg, NULL, 0, 0, PM_REMOVE) )
- {
- if ( IsDialogMessage(msg.hwnd, &msg) ) continue;
- TranslateMessage(&msg);
- DispatchMessage(&msg);
- }
- }
- else if ( rc==WAIT_OBJECT_0 )
- {
- break;
- }
- }
- CloseHandle(AniAva.AnimationThreadHandle);
- AniAva.AnimationThreadHandle=NULL;
-}
-
-static int _AniAva_SortAvatarInfo(void * first, void * last)
-{
- int res=0;
- ANIAVA_INFO * aai1=(ANIAVA_INFO *)first;
- ANIAVA_INFO * aai2=(ANIAVA_INFO *)last;
- if (aai1 && aai1->tcsFilename &&
- aai2 && aai2->tcsFilename)
- {
- res=_tcsicmp(aai2->tcsFilename, aai1->tcsFilename);
- }
- else
- {
- int a1=(aai1 && aai1->tcsFilename)? 1:0;
- int a2=(aai2 && aai2->tcsFilename)? 1:0;
- res=a1-a2;
- }
-
- if (res==0)
- {
- if ( aai1->FrameSize.cx==aai2->FrameSize.cx && aai1->FrameSize.cy==aai2->FrameSize.cy )
- return 0;
- else
- return 1;
- }
- else
- return res;
-}
-
-void _AniAva_InvalidateParent(ANIAVA_WINDOWINFO * dat)
-{
- if ( !IMMEDIATE_DRAW ) return;
- HWND hwndParent = pcli->hwndContactTree;
- RECT rcPos = dat->rcPos;
- pcli->pfnInvalidateRect( hwndParent, &rcPos, FALSE );
-}
-
-static LRESULT CALLBACK _AniAva_WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
-{
- ANIAVA_WINDOWINFO * dat=NULL;
- if (msg==WM_TIMER || msg==WM_DESTROY || (msg>AAM_FIRST && msg<AAM_LAST) )
- dat=(ANIAVA_WINDOWINFO *)GetWindowLongPtr(hwnd, GWLP_USERDATA);
-
- switch (msg)
- {
- case AAM_REMOVEAVATAR:
- if (dat->ptFromPoint.x==(int)wParam) return 0xDEAD; //need to destroy window
- else if (dat->ptFromPoint.x>(int)wParam) dat->ptFromPoint.x-=(int)lParam;
- return 0;
-
- case AAM_PAUSE:
- dat->bPaused++;
- return 0;
-
- case AAM_RESUME:
- dat->bPaused--;
- if (dat->bPaused) return 0;
- if (dat->bPended)
- {
- if ( !IMMEDIATE_DRAW )
- _AniAva_RenderAvatar(dat);
- }
- dat->bPended=FALSE;
- return 0;
-
- case AAM_STOP:
- if (dat->bPlaying)
- {
- dat->bPlaying=FALSE;
- KillTimer(hwnd,2);
- ShowWindow(hwnd, SW_HIDE);
- }
- return 0;
-
- case AAM_SETAVATAR:
- {
- ANIAVATARIMAGEINFO *paaii=(ANIAVATARIMAGEINFO*)wParam;
- _AniAva_Clear_ANIAVA_WINDOWINFO(dat);
- dat->nFramesCount=paaii->nFramesCount;
- dat->delaysInterval=paaii->pFrameDelays;
- dat->sizeAvatar=paaii->szSize;
- dat->ptFromPoint=paaii->ptImagePos;
- dat->currentFrame=0;
- dat->bPlaying=FALSE;
- return MAKELONG(dat->sizeAvatar.cx,dat->sizeAvatar.cy);
- }
-
- case AAM_SETPOSITION:
- {
- ANIAVA_POSINFO * papi=(ANIAVA_POSINFO *)lParam;
- if (!dat->delaysInterval) return 0;
- if (!papi) return 0;
- dat->rcPos=papi->rcPos;
- dat->overlayIconIdx=papi->idxOverlay;
- dat->bAlpha=papi->bAlpha;
- free(papi);
- if (!dat->bPlaying)
- {
- dat->bPlaying=TRUE;
- ShowWindow(hwnd,SW_SHOWNA);
- dat->currentFrame=0;
- KillTimer(hwnd,2);
- SetTimer(hwnd,2,dat->delaysInterval[0],NULL);
- }
- if ( !IMMEDIATE_DRAW )
- _AniAva_RenderAvatar(dat);
- return 0;
- }
- case AAM_SETPARENT:
- if ( IMMEDIATE_DRAW ) return 0;
- dat->bOrderTop=((HWND)wParam!=GetDesktopWindow());
- SetParent(hwnd,(HWND)wParam);
- if (dat->bOrderTop)
- {
- SetWindowPos(hwnd,HWND_TOP,0,0,0,0,SWP_NOSIZE|SWP_NOMOVE|SWP_NOACTIVATE|SWP_ASYNCWINDOWPOS);
- }
- else
- {
- LONG exStyle;
- exStyle=GetWindowLong(pcli->hwndContactList,GWL_EXSTYLE);
- SetWindowPos(pcli->hwndContactList,hwnd,0,0,0,0,SWP_NOSIZE|SWP_NOMOVE|SWP_NOACTIVATE/*|SWP_ASYNCWINDOWPOS*/);
- if (!(exStyle&WS_EX_TOPMOST))
- SetWindowPos(pcli->hwndContactList,HWND_NOTOPMOST,0,0,0,0,SWP_NOSIZE|SWP_NOMOVE|SWP_NOACTIVATE/*|SWP_ASYNCWINDOWPOS*/);
- }
- return 0;
-
- case AAM_REDRAW:
- if ( IMMEDIATE_DRAW )
- return 0;
- if ( wParam )
- {
- if (dat->bOrderTop)
- {
- SetWindowPos(hwnd,HWND_TOP,0,0,0,0,SWP_NOSIZE|SWP_NOMOVE|SWP_NOACTIVATE|SWP_ASYNCWINDOWPOS);
- }
- else
- {
- LONG exStyle;
- exStyle=GetWindowLong(pcli->hwndContactList,GWL_EXSTYLE);
- SetWindowPos(pcli->hwndContactList,hwnd,0,0,0,0,SWP_NOSIZE|SWP_NOMOVE|SWP_NOACTIVATE/*|SWP_ASYNCWINDOWPOS*/);
- if (!(exStyle&WS_EX_TOPMOST))
- SetWindowPos(pcli->hwndContactList,HWND_NOTOPMOST,0,0,0,0,SWP_NOSIZE|SWP_NOMOVE|SWP_NOACTIVATE/*|SWP_ASYNCWINDOWPOS*/);
- }
- }
-
- _AniAva_RenderAvatar( dat );
- return 0;
-
-
- case AAM_RENDER:
- {
- HDC hdc = ( HDC )wParam;
- RECT* rect = ( RECT* )lParam;
- _AniAva_RenderAvatar( dat, hdc, rect );
- }
- return 0;
-
- case AAM_SELFDESTROY:
- return DestroyWindow(hwnd);
-
- case WM_CREATE:
- {
- LONG exStyle;
- ANIAVA_WINDOWINFO * dat = (ANIAVA_WINDOWINFO *) mir_calloc(sizeof (ANIAVA_WINDOWINFO));
- SetWindowLongPtr(hwnd,GWLP_USERDATA,(LONG_PTR)dat);
- dat->hWindow=hwnd;
- //ShowWindow(dat->hWindow,SW_SHOW);
- //change layered mode
- exStyle=GetWindowLongPtr(dat->hWindow,GWL_EXSTYLE);
- exStyle|=WS_EX_LAYERED;
- SetWindowLong(dat->hWindow,GWL_EXSTYLE,exStyle);
- exStyle=GetWindowLong(dat->hWindow,GWL_STYLE);
- exStyle&=~WS_POPUP;
- exStyle|=WS_CHILD;
- SetWindowLong(dat->hWindow,GWL_STYLE,exStyle);
- break;
- }
- case WM_TIMER:
- {
- if (!IsWindowVisible(hwnd))
- {
- DestroyWindow(hwnd);
- return 0;
- }
- dat->currentFrame++;
- if (dat->currentFrame>=dat->nFramesCount)
- dat->currentFrame=0;
-
- if ( !IMMEDIATE_DRAW )
- _AniAva_RenderAvatar( dat );
- else
- _AniAva_InvalidateParent( dat );
-
- KillTimer(hwnd,2);
- SetTimer(hwnd,2,dat->delaysInterval[dat->currentFrame]+1,NULL);
- return 0;
- }
- case WM_DESTROY:
- {
- _AniAva_Clear_ANIAVA_WINDOWINFO(dat);
- mir_free(dat);
- SetWindowLongPtr(hwnd,GWLP_USERDATA,(LONG_PTR)NULL);
- break;
- }
-
- }
- return DefWindowProc(hwnd, msg, wParam, lParam);
-}
-
-#undef aacheck
-#undef aalock
-#undef aaunlock
-
-/////////////////////////////////////////////////////////////////
-// some stub
-
-HWND WINAPI MyGetAncestor( HWND hWnd, UINT option )
-{
- if ( option == GA_PARENT )
- return GetParent( hWnd );
-
- if ( option == GA_ROOTOWNER ) {
- HWND result = hWnd;
- while( true ) {
- HWND hParent = GetParent( result );
- if ( !hParent )
- return result;
-
- result = hParent;
- }
- }
-
- return NULL;
-}