static int EventArea_DrawWorker(HWND hWnd, HDC hDC) { RECT rc; HFONT hOldFont; GetClientRect(hWnd, &rc); if (g_CluiData.fDisableSkinEngine) sttDrawEventAreaBackground(hWnd, hDC, &rc); else SkinDrawGlyph(hDC, &rc, &rc, "Main,ID=EventArea"); hOldFont = g_clcPainter.ChangeToFont(hDC, NULL, FONTID_EVENTAREA, NULL); SetBkMode(hDC, TRANSPARENT); int iCount = GetMenuItemCount(g_CluiData.hMenuNotify); rc.left += 26; if (g_CluiData.hUpdateContact != 0) { TCHAR *szName = pcli->pfnGetContactDisplayName(g_CluiData.hUpdateContact, 0); int iIcon = cli_GetContactIcon(g_CluiData.hUpdateContact); ske_ImageList_DrawEx(g_himlCListClc, iIcon, hDC, rc.left, (rc.bottom + rc.top - GetSystemMetrics(SM_CYSMICON)) / 2, GetSystemMetrics(SM_CXSMICON), GetSystemMetrics(SM_CYSMICON), CLR_NONE, CLR_NONE, ILD_NORMAL); rc.left += 18; ske_DrawText(hDC, szName, -1, &rc, DT_VCENTER | DT_SINGLELINE); ske_ImageList_DrawEx(g_himlCListClc, (int)g_CluiData.iIconNotify, hDC, 4, (rc.bottom + rc.top - 16) / 2, 16, 16, CLR_NONE, CLR_NONE, ILD_NORMAL); } else if (iCount > 0) { MENUITEMINFO mii = { 0 }; struct NotifyMenuItemExData *nmi; TCHAR *szName; int iIcon; mii.cbSize = sizeof(mii); mii.fMask = MIIM_DATA; GetMenuItemInfo(g_CluiData.hMenuNotify, iCount - 1, TRUE, &mii); nmi = (struct NotifyMenuItemExData *) mii.dwItemData; szName = pcli->pfnGetContactDisplayName(nmi->hContact, 0); iIcon = cli_GetContactIcon(nmi->hContact); ske_ImageList_DrawEx(g_himlCListClc, iIcon, hDC, rc.left, (rc.bottom + rc.top - GetSystemMetrics(SM_CYSMICON)) / 2, GetSystemMetrics(SM_CXSMICON), GetSystemMetrics(SM_CYSMICON), CLR_NONE, CLR_NONE, ILD_NORMAL); rc.left += 18; ske_ImageList_DrawEx(g_himlCListClc, nmi->iIcon, hDC, 4, (rc.bottom + rc.top) / 2 - 8, 16, 16, CLR_NONE, CLR_NONE, ILD_NORMAL); ske_DrawText(hDC, szName, -1, &rc, DT_VCENTER | DT_SINGLELINE); } else { HICON hIcon = (HICON)LoadImage(GetModuleHandle(NULL), MAKEINTRESOURCE(IDI_BLANK), IMAGE_ICON, 16, 16, 0); TCHAR *ptszEvents = TranslateT("No events"); ske_DrawText(hDC, ptszEvents, (int)mir_tstrlen(ptszEvents), &rc, DT_VCENTER | DT_SINGLELINE); ske_DrawIconEx(hDC, 4, (rc.bottom + rc.top - 16) / 2, hIcon, 16, 16, 0, 0, DI_NORMAL | DI_COMPAT); DestroyIcon(hIcon); } ske_ResetTextEffect(hDC); SelectObject(hDC, hOldFont); return 0; }
static LRESULT CALLBACK EventArea_WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) { switch(msg) { case WM_MEASUREITEM: { MEASUREITEMSTRUCT *lpi = (LPMEASUREITEMSTRUCT) lParam; MENUITEMINFOA mii = {0}; mii.cbSize = sizeof(mii); mii.fMask = MIIM_DATA | MIIM_ID; if (GetMenuItemInfoA(g_CluiData.hMenuNotify, lpi->itemID, FALSE, &mii) != 0) { if (mii.dwItemData == lpi->itemData) { lpi->itemWidth = 8 + 16; lpi->itemHeight = 0; return TRUE; } } } break; case WM_DRAWITEM: { LPDRAWITEMSTRUCT dis = (LPDRAWITEMSTRUCT) lParam; if (dis->hwndItem == (HWND) g_CluiData.hMenuNotify) { NotifyMenuItemExData *nmi = 0; MENUITEMINFOA mii = {0}; mii.cbSize = sizeof(mii); mii.fMask = MIIM_DATA; if (GetMenuItemInfoA(g_CluiData.hMenuNotify, (UINT) dis->itemID, FALSE, &mii) != 0) { nmi = (NotifyMenuItemExData *) mii.dwItemData; if (nmi) { int iIcon = cli_GetContactIcon(nmi->hContact); ske_ImageList_DrawEx(g_himlCListClc, nmi->iIcon, dis->hDC, 2, (dis->rcItem.bottom + dis->rcItem.top - GetSystemMetrics(SM_CYSMICON)) / 2, GetSystemMetrics(SM_CXSMICON), GetSystemMetrics(SM_CYSMICON), CLR_NONE, CLR_NONE, ILD_NORMAL); ske_ImageList_DrawEx(g_himlCListClc, iIcon, dis->hDC, 2+GetSystemMetrics(SM_CXSMICON)+2, (dis->rcItem.bottom + dis->rcItem.top - GetSystemMetrics(SM_CYSMICON)) / 2, GetSystemMetrics(SM_CXSMICON), GetSystemMetrics(SM_CYSMICON), CLR_NONE, CLR_NONE, ILD_NORMAL); return TRUE; } } } break; } case WM_LBUTTONUP: if (g_CluiData.bEventAreaEnabled) SendMessage(hwnd, WM_COMMAND, MAKEWPARAM(IDC_NOTIFYBUTTON, 0), 0); break; case WM_COMMAND: if (LOWORD(wParam) == IDC_NOTIFYBUTTON) { int iSelection; MENUITEMINFO mii = {0}; POINT pt; struct NotifyMenuItemExData *nmi = 0; int iCount = GetMenuItemCount(g_CluiData.hMenuNotify); BOOL result; GetCursorPos(&pt); mii.cbSize = sizeof(mii); mii.fMask = MIIM_DATA; if (iCount > 1) iSelection = TrackPopupMenu(g_CluiData.hMenuNotify, TPM_RETURNCMD, pt.x, pt.y, 0, hwnd, NULL); else iSelection = GetMenuItemID(g_CluiData.hMenuNotify, 0); result = GetMenuItemInfo(g_CluiData.hMenuNotify, (UINT) iSelection, FALSE, &mii); if (result != 0) { nmi = (struct NotifyMenuItemExData *) mii.dwItemData; if (nmi) { CLISTEVENT *cle = MyGetEvent(iSelection); if (cle) { CLISTEVENT *cle1 = NULL; CallService(cle->pszService, (WPARAM) NULL, (LPARAM) cle); // re-obtain the pointer, it may already be invalid/point to another event if the // event we're interested in was removed by the service (nasty one...) cle1 = MyGetEvent(iSelection); if (cle1 != NULL) CallService(MS_CLIST_REMOVEEVENT, (WPARAM) cle->hContact, (LPARAM) cle->hDbEvent); } } } break; } break; case WM_SIZE: if (!g_CluiData.fLayered) InvalidateRect(hwnd,NULL,FALSE); return DefWindowProc(hwnd, msg, wParam, lParam); case WM_ERASEBKGND: return 1; case WM_PAINT: if (GetParent(hwnd) == pcli->hwndContactList && g_CluiData.fLayered) CallService(MS_SKINENG_INVALIDATEFRAMEIMAGE,(WPARAM)hwnd,0); else if (GetParent(hwnd) == pcli->hwndContactList && !g_CluiData.fLayered) { HDC hdc, hdc2; HBITMAP hbmp,hbmpo; RECT rc = {0}; GetClientRect(hwnd,&rc); rc.right++; rc.bottom++; hdc = GetDC(hwnd); hdc2 = CreateCompatibleDC(hdc); hbmp = ske_CreateDIB32(rc.right,rc.bottom); hbmpo = (HBITMAP)SelectObject(hdc2,hbmp); ske_BltBackImage(hwnd,hdc2,&rc); EventArea_DrawWorker(hwnd,hdc2); BitBlt(hdc,rc.left,rc.top,rc.right-rc.left,rc.bottom-rc.top, hdc2,rc.left,rc.top,SRCCOPY); SelectObject(hdc2,hbmpo); DeleteObject(hbmp); DeleteDC(hdc2); SelectObject(hdc,GetStockObject(DEFAULT_GUI_FONT)); ReleaseDC(hwnd,hdc); ValidateRect(hwnd,NULL); } else { HDC hdc, hdc2; HBITMAP hbmp, hbmpo; RECT rc; PAINTSTRUCT ps; HBRUSH br = GetSysColorBrush(COLOR_3DFACE); GetClientRect(hwnd,&rc); hdc = BeginPaint(hwnd,&ps); hdc2 = CreateCompatibleDC(hdc); hbmp = ske_CreateDIB32(rc.right,rc.bottom); hbmpo = (HBITMAP)SelectObject(hdc2,hbmp); FillRect(hdc2,&ps.rcPaint,br); EventArea_DrawWorker(hwnd,hdc2); BitBlt(hdc,ps.rcPaint.left,ps.rcPaint.top,ps.rcPaint.right-ps.rcPaint.left,ps.rcPaint.bottom-ps.rcPaint.top, hdc2,ps.rcPaint.left,ps.rcPaint.top,SRCCOPY); SelectObject(hdc2,hbmpo); DeleteObject(hbmp); DeleteDC(hdc2); ps.fErase = FALSE; EndPaint(hwnd,&ps); } default: return DefWindowProc(hwnd, msg, wParam, lParam); } return TRUE; }
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(); }