static void sttDrawNonLayeredSkinedBar(HWND hwnd, HDC hdc) { HDC hdc2; HBITMAP hbmp,hbmpo; RECT rc={0}; GetClientRect(hwnd,&rc); rc.right++; rc.bottom++; hdc2=CreateCompatibleDC(hdc); hbmp=ske_CreateDIB32(rc.right,rc.bottom); hbmpo=(HBITMAP)SelectObject(hdc2,hbmp); if (GetParent(hwnd)!=pcli->hwndContactList) { HBRUSH br=GetSysColorBrush(COLOR_3DFACE); FillRect(hdc2,&rc,br); } else ske_BltBackImage(hwnd,hdc2,&rc); SendMessage(hwnd,MTBM_LAYEREDPAINT, (WPARAM)hdc2, 0); 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); mod_DeleteDC(hdc2); SelectObject(hdc,(HFONT)GetStockObject(DEFAULT_GUI_FONT)); ValidateRect(hwnd,NULL); }
static int ModernSkinButtonPaintWorker(HWND hwnd, HDC whdc) { HDC hdc; RECT rc; ModernSkinButtonCtrl* bct = (ModernSkinButtonCtrl *)GetWindowLongPtr(hwnd, GWLP_USERDATA); if (!bct) return 0; if (!IsWindowVisible(hwnd)) return 0; if (!whdc && !g_CluiData.fLayered) InvalidateRect(hwnd, nullptr, FALSE); if (whdc && g_CluiData.fLayered) hdc = whdc; else { //sdc = GetWindowDC(GetParent(hwnd)); hdc = CreateCompatibleDC(nullptr); } GetClientRect(hwnd, &rc); HBITMAP bmp = ske_CreateDIB32(rc.right, rc.bottom); HBITMAP oldbmp = (HBITMAP)SelectObject(hdc, bmp); if (!g_CluiData.fLayered) ske_BltBackImage(bct->hwnd, hdc, nullptr); { MODERNMASK Request = {}; // int res; //HBRUSH br = CreateSolidBrush(RGB(255,255,255)); char * Value = nullptr; { if (bct->ValueDBSection && bct->ValueTypeDef) { char * key; char * section; DWORD defval = 0; char buf[20]; key = mir_strdup(bct->ValueDBSection); section = key; if (bct->ValueTypeDef[0] != 's') defval = (DWORD)atol(bct->ValueTypeDef + 1); do { if (key[0] == '/') { key[0] = '\0'; key++; break; } key++; } while (key[0] != '\0'); switch (bct->ValueTypeDef[0]) { case 's': { Value = db_get_sa(0, section, key); if (!Value) Value = mir_strdup(bct->ValueTypeDef + 1); break; } case 'd': defval = db_get_dw(0, section, key, defval); Value = mir_strdup(_ltoa(defval, buf, _countof(buf))); break; case 'w': defval = db_get_w(0, section, key, defval); Value = mir_strdup(_ltoa(defval, buf, _countof(buf))); break; case 'b': defval = db_get_b(0, section, key, defval); Value = mir_strdup(_ltoa(defval, buf, _countof(buf))); break; } mir_free(section); } } g_clcPainter.AddParam(&Request, mod_CalcHash("Module"), "MButton", 0); g_clcPainter.AddParam(&Request, mod_CalcHash("ID"), bct->ID, 0); g_clcPainter.AddParam(&Request, mod_CalcHash("Down"), bct->down ? "1" : "0", 0); g_clcPainter.AddParam(&Request, mod_CalcHash("Focused"), bct->focus ? "1" : "0", 0); g_clcPainter.AddParam(&Request, mod_CalcHash("Hovered"), bct->hover ? "1" : "0", 0); if (Value) { g_clcPainter.AddParam(&Request, mod_CalcHash("Value"), Value, 0); mir_free(Value); } SkinDrawGlyphMask(hdc, &rc, &rc, &Request); SkinSelector_DeleteMask(&Request); } if (!whdc && g_CluiData.fLayered) { RECT r; SetRect(&r, bct->Left, bct->Top, bct->Right, bct->Bottom); ske_DrawImageAt(hdc, &r); //CallingService to immeadeately update window with new image. } if (whdc && !g_CluiData.fLayered) { RECT r = { 0 }; GetClientRect(bct->hwnd, &r); BitBlt(whdc, 0, 0, r.right, r.bottom, hdc, 0, 0, SRCCOPY); } SelectObject(hdc, oldbmp); DeleteObject(bmp); if (!whdc || !g_CluiData.fLayered) { SelectObject(hdc, GetStockObject(DEFAULT_GUI_FONT)); DeleteDC(hdc); } // if (sdc) // ReleaseDC(GetParent(hwnd),sdc); 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(); }
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 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; }
INT_PTR CALLBACK DlgSkinOpts(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam) { switch (msg) { case WM_DESTROY: if (hPreviewBitmap) ske_UnloadGlyphImage(hPreviewBitmap); break; case WM_INITDIALOG: TranslateDialogDefault(hwndDlg); SetDlgItemText(hwndDlg, IDC_SKINFOLDERLABEL, SkinsFolder); { HTREEITEM it = FillAvailableSkinList(hwndDlg); HWND wnd = GetDlgItem(hwndDlg, IDC_TREE1); TreeView_SelectItem(wnd, it); } return 0; case WM_COMMAND: switch (LOWORD(wParam)) { case IDC_COLOUR_MENUNORMAL: case IDC_COLOUR_MENUSELECTED: case IDC_COLOUR_FRAMES: case IDC_COLOUR_STATUSBAR: SendMessage(GetParent(hwndDlg), PSM_CHANGED, 0, 0); break; case IDC_BUTTON_INFO: { TCHAR Author[255], URL[MAX_PATH], Contact[255], Description[400], text[2000]; SkinListData *sd = NULL; HTREEITEM hti = TreeView_GetSelection(GetDlgItem(hwndDlg, IDC_TREE1)); if (hti == 0) return 0; { TVITEM tvi = { 0 }; tvi.hItem = hti; tvi.mask = TVIF_HANDLE | TVIF_PARAM; TreeView_GetItem(GetDlgItem(hwndDlg, IDC_TREE1), &tvi); sd = (SkinListData*)(tvi.lParam); } if (!sd) return 0; if (sd->File && !_tcschr(sd->File, _T('%'))) { GetPrivateProfileString(_T("Skin_Description_Section"), _T("Author"), TranslateT("( unknown )"), Author, _countof(Author), sd->File); GetPrivateProfileString(_T("Skin_Description_Section"), _T("URL"), _T(""), URL, _countof(URL), sd->File); GetPrivateProfileString(_T("Skin_Description_Section"), _T("Contact"), _T(""), Contact, _countof(Contact), sd->File); GetPrivateProfileString(_T("Skin_Description_Section"), _T("Description"), _T(""), Description, _countof(Description), sd->File); mir_sntprintf(text, TranslateT("%s\n\n%s\n\nAuthor(s):\t %s\nContact:\t %s\nWeb:\t %s\n\nFile:\t %s"), sd->Name, Description, Author, Contact, URL, sd->File); } else { mir_sntprintf(text, TranslateT("%s\n\n%s\n\nAuthor(s): %s\nContact:\t %s\nWeb:\t %s\n\nFile:\t %s"), TranslateT("reVista for Modern v0.5"), TranslateT("This is second default Modern Contact list skin in Vista Aero style"), TranslateT("Angeli-Ka (graphics), FYR (template)"), _T("JID: [email protected]"), _T("fyr.mirandaim.ru"), TranslateT("Inside library")); } MessageBox(hwndDlg, text, TranslateT("Skin information"), MB_OK | MB_ICONINFORMATION); } break; case IDC_BUTTON_APPLY_SKIN: if (HIWORD(wParam) == BN_CLICKED) { SkinListData *sd = NULL; HTREEITEM hti = TreeView_GetSelection(GetDlgItem(hwndDlg, IDC_TREE1)); if (hti == 0) return 0; { TVITEM tvi = { 0 }; tvi.hItem = hti; tvi.mask = TVIF_HANDLE | TVIF_PARAM; TreeView_GetItem(GetDlgItem(hwndDlg, IDC_TREE1), &tvi); sd = (SkinListData*)(tvi.lParam); } if (!sd) return 0; ske_LoadSkinFromIniFile(sd->File, FALSE); ske_LoadSkinFromDB(); pcli->pfnClcBroadcast(INTM_RELOADOPTIONS, 0, 0); Sync(CLUIFrames_OnClistResize_mod, 0, 0); ske_RedrawCompleteWindow(); Sync(CLUIFrames_OnClistResize_mod, 0, 0); { HWND hwnd = pcli->hwndContactList; RECT rc = { 0 }; GetWindowRect(hwnd, &rc); Sync(CLUIFrames_OnMoving, hwnd, &rc); } if (g_hCLUIOptionsWnd) { SendDlgItemMessage(g_hCLUIOptionsWnd, IDC_LEFTMARGINSPIN, UDM_SETPOS, 0, db_get_b(NULL, "CLUI", "LeftClientMargin", SETTING_LEFTCLIENTMARIGN_DEFAULT)); SendDlgItemMessage(g_hCLUIOptionsWnd, IDC_RIGHTMARGINSPIN, UDM_SETPOS, 0, db_get_b(NULL, "CLUI", "RightClientMargin", SETTING_RIGHTCLIENTMARIGN_DEFAULT)); SendDlgItemMessage(g_hCLUIOptionsWnd, IDC_TOPMARGINSPIN, UDM_SETPOS, 0, db_get_b(NULL, "CLUI", "TopClientMargin", SETTING_TOPCLIENTMARIGN_DEFAULT)); SendDlgItemMessage(g_hCLUIOptionsWnd, IDC_BOTTOMMARGINSPIN, UDM_SETPOS, 0, db_get_b(NULL, "CLUI", "BottomClientMargin", SETTING_BOTTOMCLIENTMARIGN_DEFAULT)); } } break; case IDC_BUTTON_RESCAN: if (HIWORD(wParam) == BN_CLICKED) { HTREEITEM it = FillAvailableSkinList(hwndDlg); HWND wnd = GetDlgItem(hwndDlg, IDC_TREE1); TreeView_SelectItem(wnd, it); } } break; case WM_DRAWITEM: if (wParam == IDC_PREVIEW) { //TODO:Draw hPreviewBitmap here int mWidth, mHeight; HBRUSH hbr = CreateSolidBrush(GetSysColor(COLOR_3DFACE)); DRAWITEMSTRUCT *dis = (DRAWITEMSTRUCT *)lParam; mWidth = dis->rcItem.right - dis->rcItem.left; mHeight = dis->rcItem.bottom - dis->rcItem.top; HDC memDC = CreateCompatibleDC(dis->hDC); HBITMAP hbmp = ske_CreateDIB32(mWidth, mHeight); HBITMAP holdbmp = (HBITMAP)SelectObject(memDC, hbmp); RECT workRect = dis->rcItem; OffsetRect(&workRect, -workRect.left, -workRect.top); FillRect(memDC, &workRect, hbr); DeleteObject(hbr); if (hPreviewBitmap) { //variables BITMAP bmp = { 0 }; POINT imgPos = { 0 }; float xScale = 1, yScale = 1; //GetSize GetObject(hPreviewBitmap, sizeof(BITMAP), &bmp); int wWidth = workRect.right - workRect.left; int wHeight = workRect.bottom - workRect.top; if (wWidth < bmp.bmWidth) xScale = (float)wWidth / bmp.bmWidth; if (wHeight < bmp.bmHeight) yScale = (float)wHeight / bmp.bmHeight; xScale = min(xScale, yScale); yScale = xScale; int dWidth = (int)(xScale*bmp.bmWidth); int dHeight = (int)(yScale*bmp.bmHeight); //CalcPosition imgPos.x = workRect.left + ((wWidth - dWidth) >> 1); imgPos.y = workRect.top + ((wHeight - dHeight) >> 1); //DrawImage DrawAvatarImageWithGDIp(memDC, imgPos.x, imgPos.y, dWidth, dHeight, hPreviewBitmap, 0, 0, bmp.bmWidth, bmp.bmHeight, 8, 255); } BitBlt(dis->hDC, dis->rcItem.left, dis->rcItem.top, mWidth, mHeight, memDC, 0, 0, SRCCOPY); SelectObject(memDC, holdbmp); DeleteObject(hbmp); DeleteDC(memDC); } break; case WM_NOTIFY: switch (((LPNMHDR)lParam)->idFrom) { case IDC_TREE1: { NMTREEVIEW * nmtv = (NMTREEVIEW *)lParam; if (nmtv == NULL) return 0; if (nmtv->hdr.code == TVN_SELCHANGED) { SkinListData * sd = NULL; if (hPreviewBitmap) { ske_UnloadGlyphImage(hPreviewBitmap); hPreviewBitmap = NULL; } if (nmtv->itemNew.lParam) { sd = (SkinListData*)nmtv->itemNew.lParam; TCHAR buf[MAX_PATH]; PathToRelativeT(sd->File, buf); SetDlgItemText(hwndDlg, IDC_EDIT_SKIN_FILENAME, buf); TCHAR prfn[MAX_PATH] = { 0 }, imfn[MAX_PATH] = { 0 }, skinfolder[MAX_PATH] = { 0 }; GetPrivateProfileString(_T("Skin_Description_Section"), _T("Preview"), _T(""), imfn, _countof(imfn), sd->File); IniParser::GetSkinFolder(sd->File, skinfolder); mir_sntprintf(prfn, _T("%s\\%s"), skinfolder, imfn); PathToAbsoluteT(prfn, imfn); hPreviewBitmap = ske_LoadGlyphImage(imfn); EnableWindow(GetDlgItem(hwndDlg, IDC_BUTTON_APPLY_SKIN), TRUE); EnableWindow(GetDlgItem(hwndDlg, IDC_BUTTON_INFO), TRUE); if (hPreviewBitmap) InvalidateRect(GetDlgItem(hwndDlg, IDC_PREVIEW), NULL, TRUE); else { //prepare text TCHAR Author[255], URL[MAX_PATH], Contact[255], Description[400], text[2000]; SkinListData* sd2 = NULL; HTREEITEM hti = TreeView_GetSelection(GetDlgItem(hwndDlg, IDC_TREE1)); if (hti == 0) return 0; { TVITEM tvi = { 0 }; tvi.hItem = hti; tvi.mask = TVIF_HANDLE | TVIF_PARAM; TreeView_GetItem(GetDlgItem(hwndDlg, IDC_TREE1), &tvi); sd2 = (SkinListData*)(tvi.lParam); } if (!sd2) return 0; if (sd2->File && !_tcschr(sd2->File, _T('%'))) { GetPrivateProfileString(_T("Skin_Description_Section"), _T("Author"), TranslateT("( unknown )"), Author, _countof(Author), sd2->File); GetPrivateProfileString(_T("Skin_Description_Section"), _T("URL"), _T(""), URL, _countof(URL), sd2->File); GetPrivateProfileString(_T("Skin_Description_Section"), _T("Contact"), _T(""), Contact, _countof(Contact), sd2->File); GetPrivateProfileString(_T("Skin_Description_Section"), _T("Description"), _T(""), Description, _countof(Description), sd2->File); mir_sntprintf(text, TranslateT("Preview is not available\n\n%s\n----------------------\n\n%s\n\nAUTHOR(S):\n%s\n\nCONTACT:\n%s\n\nHOMEPAGE:\n%s"), sd2->Name, Description, Author, Contact, URL); } else { mir_sntprintf(text, TranslateT("%s\n\n%s\n\nAUTHORS:\n%s\n\nCONTACT:\n%s\n\nWEB:\n%s\n\n\n"), TranslateT("reVista for Modern v0.5"), TranslateT("This is second default Modern Contact list skin in Vista Aero style"), TranslateT("graphics by Angeli-Ka\ntemplate by FYR"), _T("JID: [email protected]"), _T("fyr.mirandaim.ru")); } ShowWindow(GetDlgItem(hwndDlg, IDC_PREVIEW), SW_HIDE); ShowWindow(GetDlgItem(hwndDlg, IDC_STATIC_INFO), SW_SHOW); SetDlgItemText(hwndDlg, IDC_STATIC_INFO, text); } } else { //no selected SetDlgItemText(hwndDlg, IDC_EDIT_SKIN_FILENAME, TranslateT("Select skin from list")); EnableWindow(GetDlgItem(hwndDlg, IDC_BUTTON_APPLY_SKIN), FALSE); EnableWindow(GetDlgItem(hwndDlg, IDC_BUTTON_INFO), FALSE); SetDlgItemText(hwndDlg, IDC_STATIC_INFO, TranslateT("Please select skin to apply")); ShowWindow(GetDlgItem(hwndDlg, IDC_PREVIEW), SW_HIDE); } ShowWindow(GetDlgItem(hwndDlg, IDC_PREVIEW), hPreviewBitmap ? SW_SHOW : SW_HIDE); return 0; } else if (nmtv->hdr.code == TVN_DELETEITEM) { mir_free_and_nil(nmtv->itemOld.lParam); return 0; } } break; case 0: switch (((LPNMHDR)lParam)->code) { case PSN_APPLY: pcli->pfnClcBroadcast(INTM_RELOADOPTIONS, 0, 0); NotifyEventHooks(g_CluiData.hEventBkgrChanged, 0, 0); pcli->pfnClcBroadcast(INTM_INVALIDATE, 0, 0); RedrawWindow(GetParent(pcli->hwndContactTree), NULL, NULL, RDW_INVALIDATE | RDW_FRAME | RDW_ALLCHILDREN); } break; } }
static void PaintWorker(TBBUTTONDATA *bct, HDC hdcPaint, POINT *pOffset) { if (!hdcPaint) return; //early exit POINT offset; if (pOffset) offset = *pOffset; else offset.x = offset.y = 0; RECT rcClient; GetClientRect(bct->hwnd, &rcClient); int width = rcClient.right - rcClient.left; int height = rcClient.bottom - rcClient.top; HBITMAP hbmMem = NULL; HBITMAP hbmOld = NULL; HDC hdcMem = pOffset ? hdcPaint : CreateCompatibleDC(hdcPaint); HFONT hOldFont = (HFONT)SelectObject(hdcMem, bct->hFont); if (!pOffset) { hbmMem = ske_CreateDIB32(width, height); hbmOld = (HBITMAP)SelectObject(hdcMem, hbmMem); } else OffsetRect(&rcClient, offset.x, offset.y); if (!g_CluiData.fDisableSkinEngine) { char szRequest[128]; /* painting */ mir_snprintf(szRequest, "Button,ID=%s,Hovered=%s,Pressed=%s,Focused=%s", bct->szButtonID, // ID b2str(bct->stateId == PBS_HOT), // Hovered b2str(bct->stateId == PBS_PRESSED || bct->bIsPushed == TRUE), // Pressed b2str(bct->bFocused)); // Focused SkinDrawGlyph(hdcMem, &rcClient, &rcClient, szRequest); } else if (xpt_IsThemed(bct->hThemeToolbar)) { RECT *rc = &rcClient; int state = IsWindowEnabled(bct->hwnd) ? /*(bct->stateId == PBS_PRESSED || bct->bIsPushed == TRUE) ? PBS_PRESSED :*/ (bct->stateId == PBS_NORMAL && bct->bIsDefault ? PBS_DEFAULTED : bct->stateId) : PBS_DISABLED; xpt_DrawTheme(bct->hThemeToolbar, bct->hwnd, hdcMem, TP_BUTTON, TBStateConvert2Flat(state), rc, rc); } else { HBRUSH hbr = NULL; if (bct->stateId == PBS_PRESSED || bct->stateId == PBS_HOT) hbr = GetSysColorBrush(COLOR_3DLIGHT); else { RECT btnRect; POINT pt = { 0 }; int ret; HWND hwndParent = GetParent(bct->hwnd); HDC dc = CreateCompatibleDC(NULL); HBITMAP memBM, oldBM; GetWindowRect(hwndParent, &btnRect); memBM = ske_CreateDIB32(btnRect.right - btnRect.left, btnRect.bottom - btnRect.top); oldBM = (HBITMAP)SelectObject(dc, memBM); ret = SendMessage(hwndParent, WM_ERASEBKGND, (WPARAM)dc, 0); GetWindowRect(bct->hwnd, &btnRect); ClientToScreen(hwndParent, &pt); OffsetRect(&btnRect, -pt.x, -pt.y); if (ret) BitBlt(hdcMem, 0, 0, btnRect.right - btnRect.left, btnRect.bottom - btnRect.top, dc, btnRect.left, btnRect.top, SRCCOPY); oldBM = (HBITMAP)SelectObject(dc, oldBM); DeleteObject(memBM); DeleteDC(dc); if (!ret) { //WM_ERASEBKG return false need to paint HDC pdc = GetDC(hwndParent); HBRUSH oldBrush = (HBRUSH)GetCurrentObject(pdc, OBJ_BRUSH); hbr = (HBRUSH)SendMessage(hwndParent, WM_CTLCOLORDLG, (WPARAM)pdc, (LPARAM)hwndParent); SelectObject(pdc, oldBrush); ReleaseDC(hwndParent, pdc); } } if (hbr) { FillRect(hdcMem, &rcClient, hbr); DeleteObject(hbr); } if (bct->stateId == PBS_HOT || bct->bFocused) { if (bct->bIsPushed) DrawEdge(hdcMem, &rcClient, EDGE_ETCHED, BF_RECT | BF_SOFT); else DrawEdge(hdcMem, &rcClient, BDR_RAISEDOUTER, BF_RECT | BF_SOFT | BF_FLAT); } else if (bct->stateId == PBS_PRESSED) DrawEdge(hdcMem, &rcClient, BDR_SUNKENOUTER, BF_RECT | BF_SOFT); } RECT rcTemp = rcClient; //content rect bool bPressed = (bct->stateId == PBS_PRESSED || bct->bIsPushed == TRUE); bool bHasText = (bct->szText[0] != '\0'); /* formatter */ if (!g_CluiData.fDisableSkinEngine) { /* correct rect according to rcMargins */ rcTemp.left += bct->rcMargins.left; rcTemp.top += bct->rcMargins.top; rcTemp.bottom -= bct->rcMargins.bottom; rcTemp.right -= bct->rcMargins.right; } /* reposition button items */ RECT rcIcon = rcTemp, rcText = rcTemp; if (bct->hIcon) { if (bHasText) { rcIcon.right = rcIcon.left + 16; /* CXSM_ICON */ rcText.left = rcIcon.right + 2; } else { rcIcon.left += (rcIcon.right - rcIcon.left) / 2 - 8; rcIcon.right = rcIcon.left + 16; } } /* Check sizes*/ if (bct->hIcon && (rcIcon.right > rcTemp.right || rcIcon.bottom > rcTemp.bottom || rcIcon.left < rcTemp.left || rcIcon.top < rcTemp.top)) bct->hIcon = NULL; if (bHasText && (rcText.right > rcTemp.right || rcText.bottom > rcTemp.bottom || rcText.left < rcTemp.left || rcText.top < rcTemp.top)) bHasText = FALSE; if (bct->hIcon) { /* center icon vertically */ rcIcon.top += (rcClient.bottom - rcClient.top) / 2 - 8; /* CYSM_ICON/2 */ rcIcon.bottom = rcIcon.top + 16; /* CYSM_ICON */ /* draw it */ ske_DrawIconEx(hdcMem, rcIcon.left + bPressed, rcIcon.top + bPressed, bct->hIcon, 16, 16, 0, NULL, DI_NORMAL); } if (bHasText) { BOOL bCentered = TRUE; SetBkMode(hdcMem, TRANSPARENT); if (bct->nFontID >= 0) g_clcPainter.ChangeToFont(hdcMem, NULL, bct->nFontID, NULL); RECT TextRequiredRect = rcText; ske_DrawText(hdcMem, bct->szText, -1, &TextRequiredRect, DT_CENTER | DT_VCENTER | DT_CALCRECT | DT_SINGLELINE); if (TextRequiredRect.right - TextRequiredRect.left > rcText.right - rcText.left) bCentered = FALSE; ske_DrawText(hdcMem, bct->szText, -1, &rcText, (bCentered ? DT_CENTER : 0) | DT_VCENTER | DT_SINGLELINE); ske_ResetTextEffect(hdcMem); } if (!pOffset) BitBlt(hdcPaint, 0, 0, width, height, hdcMem, 0, 0, SRCCOPY); // better to use try/finally but looks like last one is Microsoft specific SelectObject(hdcMem, hOldFont); if (!pOffset) { SelectObject(hdcMem, hbmOld); DeleteObject(hbmMem); DeleteDC(hdcMem); } }
void Cache_GetAvatar(struct ClcData *dat, struct ClcContact *contact) { int old_pos=contact->avatar_pos; if (g_CluiData.bSTATE!=STATE_NORMAL || (dat->use_avatar_service && !ServiceExists(MS_AV_GETAVATARBITMAP)) ) // workaround for avatar service and other wich destroys service on OK_TOEXIT { contact->avatar_pos = AVATAR_POS_DONT_HAVE; contact->avatar_data = NULL; return; } if (dat->use_avatar_service && ServiceExists(MS_AV_GETAVATARBITMAP)) { if (dat->avatars_show && !ModernGetSettingByte(contact->hContact, "CList", "HideContactAvatar", 0)) { contact->avatar_data = (struct avatarCacheEntry *)CallService(MS_AV_GETAVATARBITMAP, (WPARAM)contact->hContact, 0); if (contact->avatar_data == NULL || contact->avatar_data->cbSize != sizeof(struct avatarCacheEntry) || contact->avatar_data->dwFlags == AVS_BITMAP_EXPIRED) { contact->avatar_data = NULL; } if (contact->avatar_data != NULL) { contact->avatar_data->t_lastAccess = (DWORD)time(NULL); } } else { contact->avatar_data = NULL; } Cache_ProceedAvatarInList(dat, contact); } else { contact->avatar_pos = AVATAR_POS_DONT_HAVE; if (dat->avatars_show && !ModernGetSettingByte(contact->hContact, "CList", "HideContactAvatar", 0)) { DBVARIANT dbv; if (!ModernGetSettingTString(contact->hContact, "ContactPhoto", "File", &dbv)) { HBITMAP hBmp = (HBITMAP) CallService(MS_UTILS_LOADBITMAPT, 0, (LPARAM)dbv.ptszVal); if (hBmp != NULL) { // Make bounds BITMAP bm; if (GetObject(hBmp,sizeof(BITMAP),&bm)) { // Create data... HDC hdc; HBITMAP hDrawBmp,oldBmp; // Make bounds -> keep aspect radio LONG width_clip; LONG height_clip; RECT rc = {0}; // Clipping width and height width_clip = dat->avatars_maxheight_size; height_clip = dat->avatars_maxheight_size; if (height_clip * bm.bmWidth / bm.bmHeight <= width_clip) { width_clip = height_clip * bm.bmWidth / bm.bmHeight; } else { height_clip = width_clip * bm.bmHeight / bm.bmWidth; } // Create objs hdc = CreateCompatibleDC(dat->avatar_cache.hdc); hDrawBmp = ske_CreateDIB32(width_clip, height_clip); oldBmp=(HBITMAP)SelectObject(hdc, hDrawBmp); SetBkMode(hdc,TRANSPARENT); { POINT org; GetBrushOrgEx(hdc, &org); SetStretchBltMode(hdc, HALFTONE); SetBrushOrgEx(hdc, org.x, org.y, NULL); } rc.right = width_clip - 1; rc.bottom = height_clip - 1; // Draw bitmap 8//8 { HDC dcMem = CreateCompatibleDC(hdc); HBITMAP obmp=(HBITMAP)SelectObject(dcMem, hBmp); StretchBlt(hdc, 0, 0, width_clip, height_clip,dcMem, 0, 0, bm.bmWidth, bm.bmHeight, SRCCOPY); SelectObject(dcMem,obmp); mod_DeleteDC(dcMem); } { RECT rtr={0}; rtr.right=width_clip+1; rtr.bottom=height_clip+1; ske_SetRectOpaque(hdc,&rtr); } hDrawBmp = (HBITMAP)GetCurrentObject(hdc, OBJ_BITMAP); SelectObject(hdc,oldBmp); mod_DeleteDC(hdc); // Add to list if (old_pos >= 0) { ImageArray_ChangeImage(&dat->avatar_cache, hDrawBmp, old_pos); contact->avatar_pos = old_pos; } else { contact->avatar_pos = ImageArray_AddImage(&dat->avatar_cache, hDrawBmp, -1); } DeleteObject(hDrawBmp); } // if (GetObject(hBmp,sizeof(BITMAP),&bm)) DeleteObject(hBmp); } //if (hBmp != NULL) } ModernDBFreeVariant(&dbv); } // Remove avatar if needed if (old_pos >= 0 && contact->avatar_pos == AVATAR_POS_DONT_HAVE) { ImageArray_RemoveImage(&dat->avatar_cache, old_pos); // Update all items ExecuteOnAllContacts(dat, ReduceAvatarPosition, (void *)&old_pos); } if (old_pos==AVATAR_POS_ANIMATED && contact->avatar_pos != AVATAR_POS_ANIMATED) { AniAva_RemoveAvatar( contact->hContact ); } } }
void Cache_ProceedAvatarInList(struct ClcData *dat, struct ClcContact *contact) { struct avatarCacheEntry * ace=contact->avatar_data; int old_pos=contact->avatar_pos; if ( ace==NULL || ace->dwFlags == AVS_BITMAP_EXPIRED || ace->hbmPic == NULL) { //Avatar was not ready or removed - need to remove it from cache if (old_pos>=0) { ImageArray_RemoveImage(&dat->avatar_cache, old_pos); // Update all items ExecuteOnAllContacts(dat, ReduceAvatarPosition, (void *)&old_pos); contact->avatar_pos=AVATAR_POS_DONT_HAVE; return; } } else if (contact->avatar_data->hbmPic != NULL) //Lets Add it { HDC hdc; HBITMAP hDrawBmp,oldBmp; void * pt; // Make bounds -> keep aspect radio LONG width_clip; LONG height_clip; RECT rc = {0}; // Clipping width and height width_clip = dat->avatars_maxwidth_size?dat->avatars_maxwidth_size:dat->avatars_maxheight_size; height_clip = dat->avatars_maxheight_size; if (height_clip * ace->bmWidth / ace->bmHeight <= width_clip) { width_clip = height_clip * ace->bmWidth / ace->bmHeight; } else { height_clip = width_clip * ace->bmHeight / ace->bmWidth; } if (wildcmpi(contact->avatar_data->szFilename,_T("*.gif"))) { int res; if (old_pos==AVATAR_POS_ANIMATED) AniAva_RemoveAvatar(contact->hContact); res=AniAva_AddAvatar(contact->hContact, contact->avatar_data->szFilename, width_clip, height_clip); if (res) { contact->avatar_pos=AVATAR_POS_ANIMATED; contact->avatar_size.cy=HIWORD(res); contact->avatar_size.cx=LOWORD(res); return; } } // Create objs hdc = CreateCompatibleDC(dat->avatar_cache.hdc); hDrawBmp = ske_CreateDIB32Point(width_clip, height_clip,&pt); oldBmp=(HBITMAP)SelectObject(hdc, hDrawBmp); //need to draw avatar bitmap here { RECT real_rc={0,0,width_clip, height_clip}; /* if (ServiceExists(MS_AV_BLENDDRAWAVATAR)) { AVATARDRAWREQUEST adr; adr.cbSize = sizeof(AVATARDRAWREQUEST); adr.hContact = contact->hContact; adr.hTargetDC = hdc; adr.rcDraw = real_rc; adr.dwFlags = 0; adr.alpha = 255; CallService(MS_AV_BLENDDRAWAVATAR, 0, (LPARAM) &adr); } else */ { int w=width_clip; int h=height_clip; if (!g_CluiData.fGDIPlusFail) //Use gdi+ engine { DrawAvatarImageWithGDIp(hdc, 0, 0, w, h,ace->hbmPic,0,0,ace->bmWidth,ace->bmHeight,ace->dwFlags,255); } else { if (!(ace->dwFlags&AVS_PREMULTIPLIED)) { HDC hdcTmp = CreateCompatibleDC(hdc); RECT r={0,0,w,h}; HDC hdcTmp2 = CreateCompatibleDC(hdc); HBITMAP bmo=(HBITMAP)SelectObject(hdcTmp,ace->hbmPic); HBITMAP b2=ske_CreateDIB32(w,h); HBITMAP bmo2=(HBITMAP)SelectObject(hdcTmp2,b2); SetStretchBltMode(hdcTmp, HALFTONE); SetStretchBltMode(hdcTmp2, HALFTONE); StretchBlt(hdcTmp2, 0, 0, w, h, hdcTmp, 0, 0, ace->bmWidth, ace->bmHeight, SRCCOPY); ske_SetRectOpaque(hdcTmp2,&r); BitBlt(hdc, rc.left, rc.top, w, h,hdcTmp2,0,0,SRCCOPY); SelectObject(hdcTmp2,bmo2); SelectObject(hdcTmp,bmo); mod_DeleteDC(hdcTmp); mod_DeleteDC(hdcTmp2); DeleteObject(b2); } else { BLENDFUNCTION bf={AC_SRC_OVER, 0,255, AC_SRC_ALPHA }; HDC hdcTempAv = CreateCompatibleDC(hdc); HBITMAP hbmTempAvOld; hbmTempAvOld = (HBITMAP)SelectObject(hdcTempAv,ace->hbmPic); ske_AlphaBlend(hdc, rc.left, rc.top, w, h, hdcTempAv, 0, 0,ace->bmWidth,ace->bmHeight, bf); SelectObject(hdcTempAv, hbmTempAvOld); mod_DeleteDC(hdcTempAv); } } } } SelectObject(hdc,oldBmp); DeleteDC(hdc); // Add to list if (old_pos >= 0) { ImageArray_ChangeImage(&dat->avatar_cache, hDrawBmp, old_pos); contact->avatar_pos = old_pos; } else { contact->avatar_pos = ImageArray_AddImage(&dat->avatar_cache, hDrawBmp, -1); } if (old_pos==AVATAR_POS_ANIMATED && contact->avatar_pos!=AVATAR_POS_ANIMATED) { AniAva_RemoveAvatar(contact->hContact); } DeleteObject(hDrawBmp); } }
INT_PTR CALLBACK DlgSkinOpts(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam) { switch ( msg ) { case WM_DESTROY: { if ( hPreviewBitmap ) ske_UnloadGlyphImage( hPreviewBitmap ); break; } case WM_INITDIALOG: { HTREEITEM it; TranslateDialogDefault( hwndDlg ); it = FillAvailableSkinList( hwndDlg ); HWND wnd = GetDlgItem( hwndDlg, IDC_TREE1 ); TreeView_SelectItem( wnd, it ); } return 0; case WM_COMMAND: { int isLoad = 0; switch ( LOWORD( wParam ) ) { case IDC_COLOUR_MENUNORMAL: case IDC_COLOUR_MENUSELECTED: case IDC_COLOUR_FRAMES: case IDC_COLOUR_STATUSBAR: SendMessage( GetParent( hwndDlg ), PSM_CHANGED, 0, 0 ); break; case IDC_BUTTON_INFO: { TCHAR Author[255]; TCHAR URL[MAX_PATH]; TCHAR Contact[255]; TCHAR Description[400]; TCHAR text[2000]; SkinListData *sd = NULL; HTREEITEM hti = TreeView_GetSelection( GetDlgItem( hwndDlg, IDC_TREE1 ) ); if ( hti == 0 ) return 0; { TVITEM tvi = {0}; tvi.hItem = hti; tvi.mask = TVIF_HANDLE|TVIF_PARAM; TreeView_GetItem( GetDlgItem( hwndDlg, IDC_TREE1 ), &tvi ); sd = ( SkinListData* )( tvi.lParam ); } if ( !sd ) return 0; if ( sd->File && !_tcschr( sd->File, _T('%') ) ) { GetPrivateProfileString( _T( "Skin_Description_Section" ), _T( "Author" ), TranslateT( "( unknown )" ), Author, SIZEOF( Author ), sd->File ); GetPrivateProfileString( _T( "Skin_Description_Section" ), _T( "URL" ), _T( "" ), URL, SIZEOF( URL ), sd->File ); GetPrivateProfileString( _T( "Skin_Description_Section" ), _T( "Contact" ), _T( "" ), Contact, SIZEOF( Contact ), sd->File ); GetPrivateProfileString( _T( "Skin_Description_Section" ), _T( "Description" ), _T( "" ), Description, SIZEOF( Description ), sd->File ); _sntprintf( text, SIZEOF( text ), TranslateT( "%s\n\n%s\n\nAuthor(s):\t %s\nContact:\t %s\nWeb:\t %s\n\nFile:\t %s" ), sd->Name, Description, Author, Contact, URL, sd->File ); } else { _sntprintf( text, SIZEOF( text ), TranslateT( "%s\n\n%s\n\nAuthor(s): %s\nContact:\t %s\nWeb:\t %s\n\nFile:\t %s" ), TranslateT( "reVista for Modern v0.5" ), TranslateT( "This is second default Modern Contact list skin in Vista Aero style" ), TranslateT( "Angeli-Ka (graphics), FYR (template)" ), _T( "JID: [email protected]" ), _T("fyr.mirandaim.ru"), TranslateT( "Inside library" ) ); } MessageBox( hwndDlg, text, TranslateT( "Skin Information" ), MB_OK|MB_ICONINFORMATION ); } break; case IDC_BUTTON_APPLY_SKIN: if ( HIWORD( wParam ) == BN_CLICKED ) { SkinListData *sd = NULL; HTREEITEM hti = TreeView_GetSelection( GetDlgItem( hwndDlg, IDC_TREE1 ) ); if ( hti == 0 ) return 0; { TVITEM tvi = {0}; tvi.hItem = hti; tvi.mask = TVIF_HANDLE|TVIF_PARAM; TreeView_GetItem( GetDlgItem( hwndDlg, IDC_TREE1 ), &tvi ); sd = ( SkinListData* )( tvi.lParam ); } if ( !sd ) return 0; if ( glSkinWasModified>0 ) { int res = 0; if ( glSkinWasModified == 1 ) res = MessageBox( hwndDlg, TranslateT( "Skin editor contains not stored changes.\n\nAll changes will be lost.\n\n Continue to load new skin?" ), TranslateT( "Warning!" ), MB_OKCANCEL|MB_ICONWARNING|MB_DEFBUTTON2|MB_TOPMOST ); else res = MessageBox( hwndDlg, TranslateT( "Current skin was not saved to file.\n\nAll changes will be lost.\n\n Continue to load new skin?" ), TranslateT( "Warning!" ), MB_OKCANCEL|MB_ICONWARNING|MB_DEFBUTTON2|MB_TOPMOST ); if ( res!= IDOK ) return 0; } ske_LoadSkinFromIniFile( sd->File, FALSE ); ske_LoadSkinFromDB( ); glOtherSkinWasLoaded = TRUE; pcli->pfnClcBroadcast( INTM_RELOADOPTIONS, 0, 0 ); Sync( CLUIFrames_OnClistResize_mod, 0, 0 ); ske_RedrawCompleteWindow( ); Sync( CLUIFrames_OnClistResize_mod, 0, 0 ); { HWND hwnd = pcli->hwndContactList; RECT rc = {0}; GetWindowRect( hwnd, &rc ); Sync( CLUIFrames_OnMoving, hwnd, &rc ); } if ( g_hCLUIOptionsWnd ) { SendDlgItemMessage( g_hCLUIOptionsWnd, IDC_LEFTMARGINSPIN, UDM_SETPOS, 0, ModernGetSettingByte( NULL, "CLUI", "LeftClientMargin", SETTING_LEFTCLIENTMARIGN_DEFAULT ) ); SendDlgItemMessage( g_hCLUIOptionsWnd, IDC_RIGHTMARGINSPIN, UDM_SETPOS, 0, ModernGetSettingByte( NULL, "CLUI", "RightClientMargin", SETTING_RIGHTCLIENTMARIGN_DEFAULT ) ); SendDlgItemMessage( g_hCLUIOptionsWnd, IDC_TOPMARGINSPIN, UDM_SETPOS, 0, ModernGetSettingByte( NULL, "CLUI", "TopClientMargin", SETTING_TOPCLIENTMARIGN_DEFAULT ) ); SendDlgItemMessage( g_hCLUIOptionsWnd, IDC_BOTTOMMARGINSPIN, UDM_SETPOS, 0, ModernGetSettingByte( NULL, "CLUI", "BottomClientMargin", SETTING_BOTTOMCLIENTMARIGN_DEFAULT ) ); } } break; case IDC_BUTTON_LOAD: isLoad = 1; if ( HIWORD( wParam ) == BN_CLICKED ) { { TCHAR str[MAX_PATH] = {0}; OPENFILENAME ofn = {0}; TCHAR filter[512] = {0}; int res = 0; ofn.lStructSize = OPENFILENAME_SIZE_VERSION_400; ofn.hwndOwner = hwndDlg; ofn.hInstance = NULL; mir_sntprintf(filter, SIZEOF(filter), _T("%s (*.msf)%c*.MSF%c%c"), TranslateT("Miranda skin file"), 0, 0, 0); ofn.lpstrFilter = filter; ofn.lpstrFile = str; ofn.Flags = isLoad?( OFN_FILEMUSTEXIST | OFN_HIDEREADONLY ) : ( OFN_OVERWRITEPROMPT|OFN_HIDEREADONLY ) | OFN_DONTADDTORECENT; ofn.nMaxFile = sizeof( str ); ofn.nMaxFileTitle = MAX_PATH; ofn.lpstrDefExt = _T( "msf" ); { DWORD tick = GetTickCount( ); res = GetOpenFileName( &ofn ); if( !res ) if ( GetTickCount( )-tick<100 ) { res = GetOpenFileName( &ofn ); if( !res ) break; } else break; } if ( res ) { HTREEITEM it = AddSkinToListFullName( hwndDlg, ofn.lpstrFile ); TreeView_SelectItem( GetDlgItem( hwndDlg, IDC_TREE1 ), it ); //SendDlgItemMessage( hwndDlg, IDC_SKINS_LIST, LB_SETCURSEL, it, 0 ); //SendMessage( hwndDlg, WM_COMMAND, MAKEWPARAM( IDC_SKINS_LIST, LBN_SELCHANGE ), 0 ); } } } } break; } case WM_DRAWITEM: if ( wParam == IDC_PREVIEW ) { //TODO:Draw hPreviewBitmap here HDC memDC, imgDC; HBITMAP hbmp, holdbmp, imgOldbmp; int mWidth, mHeight; RECT workRect = {0}; HBRUSH hbr = CreateSolidBrush( GetSysColor( COLOR_3DFACE ) ); DRAWITEMSTRUCT *dis = ( DRAWITEMSTRUCT * )lParam; mWidth = dis->rcItem.right-dis->rcItem.left; mHeight = dis->rcItem.bottom-dis->rcItem.top; memDC = CreateCompatibleDC( dis->hDC ); hbmp = ske_CreateDIB32( mWidth, mHeight ); holdbmp = ( HBITMAP )SelectObject( memDC, hbmp ); workRect = dis->rcItem; OffsetRect( &workRect, -workRect.left, -workRect.top ); FillRect( memDC, &workRect, hbr ); DeleteObject( hbr ); if ( hPreviewBitmap ) { //variables BITMAP bmp = {0}; POINT imgPos = {0}; int wWidth, wHeight; int dWidth, dHeight; float xScale = 1, yScale = 1; //GetSize GetObject( hPreviewBitmap, sizeof( BITMAP ), &bmp ); wWidth = workRect.right-workRect.left; wHeight = workRect.bottom-workRect.top; if ( wWidth<bmp.bmWidth ) xScale = ( float )wWidth/bmp.bmWidth; if ( wHeight<bmp.bmHeight ) yScale = ( float )wHeight/bmp.bmHeight; xScale = min( xScale, yScale ); yScale = xScale; dWidth = ( int )( xScale*bmp.bmWidth ); dHeight = ( int )( yScale*bmp.bmHeight ); //CalcPosition imgPos.x = workRect.left+( ( wWidth-dWidth )>>1 ); imgPos.y = workRect.top+( ( wHeight-dHeight )>>1 ); //DrawImage if ( !g_CluiData.fGDIPlusFail ) //Use gdi+ engine { DrawAvatarImageWithGDIp( memDC, imgPos.x, imgPos.y, dWidth, dHeight, hPreviewBitmap, 0, 0, bmp.bmWidth, bmp.bmHeight, 8, 255 ); } else { BLENDFUNCTION bf = {AC_SRC_OVER, 0, 255, AC_SRC_ALPHA }; imgDC = CreateCompatibleDC( dis->hDC ); imgOldbmp = ( HBITMAP )SelectObject( imgDC, hPreviewBitmap ); ske_AlphaBlend( memDC, imgPos.x, imgPos.y, dWidth, dHeight, imgDC, 0, 0, bmp.bmWidth, bmp.bmHeight, bf ); SelectObject( imgDC, imgOldbmp ); mod_DeleteDC( imgDC ); } } BitBlt( dis->hDC, dis->rcItem.left, dis->rcItem.top, mWidth, mHeight, memDC, 0, 0, SRCCOPY ); SelectObject( memDC, holdbmp ); DeleteObject( hbmp ); mod_DeleteDC( memDC ); } break; case WM_NOTIFY: switch ( ( ( LPNMHDR )lParam )->idFrom ) { case IDC_TREE1: { NMTREEVIEW * nmtv = ( NMTREEVIEW * ) lParam; if ( !nmtv ) return 0; if ( nmtv->hdr.code == TVN_SELCHANGEDA || nmtv->hdr.code == TVN_SELCHANGEDW ) { SkinListData * sd = NULL; if ( hPreviewBitmap ) { ske_UnloadGlyphImage( hPreviewBitmap ); hPreviewBitmap = NULL; } if ( nmtv->itemNew.lParam ) { sd = ( SkinListData* )nmtv->itemNew.lParam; { TCHAR buf[MAX_PATH]; CallService( MS_UTILS_PATHTORELATIVET, ( WPARAM )sd->File, ( LPARAM )buf ); SendDlgItemMessage( hwndDlg, IDC_EDIT_SKIN_FILENAME, WM_SETTEXT, 0, ( LPARAM )buf ); } { TCHAR prfn[MAX_PATH] = {0}; TCHAR imfn[MAX_PATH] = {0}; TCHAR skinfolder[MAX_PATH] = {0}; GetPrivateProfileString( _T( "Skin_Description_Section" ), _T( "Preview" ), _T( "" ), imfn, SIZEOF( imfn ), sd->File ); IniParser::GetSkinFolder( sd->File, skinfolder ); _sntprintf( prfn, SIZEOF( prfn ), _T("%s\\%s"), skinfolder, imfn ); CallService( MS_UTILS_PATHTOABSOLUTET, ( WPARAM )prfn, ( LPARAM ) imfn ); char * imfn_ch = mir_t2a( imfn ); hPreviewBitmap = ske_LoadGlyphImage( imfn_ch ); mir_free( imfn_ch ); } EnableWindow( GetDlgItem( hwndDlg, IDC_BUTTON_APPLY_SKIN ), TRUE ); EnableWindow( GetDlgItem( hwndDlg, IDC_BUTTON_INFO ), TRUE ); if ( hPreviewBitmap ) InvalidateRect( GetDlgItem( hwndDlg, IDC_PREVIEW ), NULL, TRUE ); else //prepare text { TCHAR Author[255]; TCHAR URL[MAX_PATH]; TCHAR Contact[255]; TCHAR Description[400]; TCHAR text[2000]; SkinListData* sd = NULL; HTREEITEM hti = TreeView_GetSelection( GetDlgItem( hwndDlg, IDC_TREE1 ) ); if ( hti == 0 ) return 0; { TVITEM tvi = {0}; tvi.hItem = hti; tvi.mask = TVIF_HANDLE|TVIF_PARAM; TreeView_GetItem( GetDlgItem( hwndDlg, IDC_TREE1 ), &tvi ); sd = ( SkinListData* )( tvi.lParam ); } if ( !sd ) return 0; if( sd->File && !_tcschr( sd->File, _T('%') ) ) { GetPrivateProfileString( _T( "Skin_Description_Section" ), _T( "Author" ), TranslateT( "( unknown )" ), Author, SIZEOF( Author ), sd->File ); GetPrivateProfileString( _T( "Skin_Description_Section" ), _T( "URL" ), _T( "" ), URL, SIZEOF( URL ), sd->File ); GetPrivateProfileString( _T( "Skin_Description_Section" ), _T( "Contact" ), _T( "" ), Contact, SIZEOF( Contact ), sd->File ); GetPrivateProfileString( _T( "Skin_Description_Section" ), _T( "Description" ), _T( "" ), Description, SIZEOF( Description ), sd->File ); _sntprintf( text, SIZEOF( text ), TranslateT( "Preview is not available\n\n%s\n----------------------\n\n%s\n\nAUTHOR(S):\n%s\n\nCONTACT:\n%s\n\nHOMEPAGE:\n%s" ), sd->Name, Description, Author, Contact, URL ); } else { _sntprintf( text, SIZEOF( text ), TranslateT( "%s\n\n%s\n\nAUTHORS:\n%s\n\nCONTACT:\n%s\n\nWEB:\n%s\n\n\n" ), TranslateT( "reVista for Modern v0.5" ), TranslateT( "This is second default Modern Contact list skin in Vista Aero style" ), TranslateT( "graphics by Angeli-Ka\ntemplate by FYR" ), _T("JID: [email protected]"), _T("fyr.mirandaim.ru") ); } ShowWindow( GetDlgItem( hwndDlg, IDC_PREVIEW ), SW_HIDE ); ShowWindow( GetDlgItem( hwndDlg, IDC_STATIC_INFO ), SW_SHOW ); SendDlgItemMessage( hwndDlg, IDC_STATIC_INFO, WM_SETTEXT, 0, ( LPARAM )text ); } } else { //no selected SendDlgItemMessage( hwndDlg, IDC_EDIT_SKIN_FILENAME, WM_SETTEXT, 0, ( LPARAM )TranslateT( "Select skin from list" ) ); EnableWindow( GetDlgItem( hwndDlg, IDC_BUTTON_APPLY_SKIN ), FALSE ); EnableWindow( GetDlgItem( hwndDlg, IDC_BUTTON_INFO ), FALSE ); SendDlgItemMessage( hwndDlg, IDC_STATIC_INFO, WM_SETTEXT, 0, ( LPARAM )TranslateT( "Please select skin to apply" ) ); ShowWindow( GetDlgItem( hwndDlg, IDC_PREVIEW ), SW_HIDE ); } ShowWindow( GetDlgItem( hwndDlg, IDC_PREVIEW ), hPreviewBitmap?SW_SHOW:SW_HIDE ); return 0; } else if ( nmtv->hdr.code == TVN_DELETEITEMA || nmtv->hdr.code == TVN_DELETEITEMW ) { if ( nmtv->itemOld.lParam ) mir_free_and_nill( nmtv->itemOld.lParam ); return 0; } break; } case 0: switch ( ( ( LPNMHDR )lParam )->code ) { case PSN_APPLY: { { DWORD tick = GetTickCount( ); pcli->pfnClcBroadcast( INTM_RELOADOPTIONS, 0, 0 ); NotifyEventHooks( g_CluiData.hEventBkgrChanged, 0, 0 ); pcli->pfnClcBroadcast( INTM_INVALIDATE, 0, 0 ); RedrawWindow( GetParent( pcli->hwndContactTree ), NULL, NULL, RDW_INVALIDATE|RDW_FRAME|RDW_ALLCHILDREN ); } return 0; } break; } break; } }