static LRESULT CALLBACK RichUtil_Proc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) { TRichUtil *ru; ru = (TRichUtil *)GetWindowLong(hwnd, GWL_USERDATA); switch(msg) { case WM_THEMECHANGED: case WM_STYLECHANGED: { RichUtil_ClearUglyBorder(ru); break; } case WM_NCPAINT: { LRESULT ret = CallWindowProc(origProc, hwnd, msg, wParam, lParam); if (ru->hasUglyBorder&&MyIsThemeActive()) { HANDLE hTheme = MyOpenThemeData(ru->hwnd, L"EDIT"); if (hTheme) { RECT rcBorder; RECT rcClient; int nState; HDC hdc = GetWindowDC(ru->hwnd); GetWindowRect(hwnd, &rcBorder); rcBorder.right -= rcBorder.left; rcBorder.bottom -= rcBorder.top; rcBorder.left = rcBorder.top = 0; CopyRect(&rcClient, &rcBorder); rcClient.left += ru->rect.left; rcClient.top += ru->rect.top; rcClient.right -= ru->rect.right; rcClient.bottom -= ru->rect.bottom; ExcludeClipRect(hdc, rcClient.left, rcClient.top, rcClient.right, rcClient.bottom); if(MyIsThemeBackgroundPartiallyTransparent(hTheme, EP_EDITTEXT, ETS_NORMAL)) MyDrawThemeParentBackground(hwnd, hdc, &rcBorder); if(!IsWindowEnabled(hwnd)) nState = ETS_DISABLED; else if(SendMessage(hwnd, EM_GETOPTIONS, 0, 0) & ECO_READONLY) nState = ETS_READONLY; else nState = ETS_NORMAL; MyDrawThemeBackground(hTheme, hdc, EP_EDITTEXT, nState, &rcBorder, NULL); MyCloseThemeData(hTheme); ReleaseDC(hwnd, hdc); return 0; } } return ret; } case WM_NCCALCSIZE: { LRESULT ret = CallWindowProc(origProc, hwnd, msg, wParam, lParam); NCCALCSIZE_PARAMS *ncsParam = (NCCALCSIZE_PARAMS*)lParam; if (ru->hasUglyBorder&&MyIsThemeActive()) { HANDLE hTheme = MyOpenThemeData(hwnd, L"EDIT"); if (hTheme) { RECT rcClient; HDC hdc = GetDC(GetParent(hwnd)); ZeroMemory(&rcClient, sizeof(RECT)); if(MyGetThemeBackgroundContentRect(hTheme, hdc, EP_EDITTEXT, ETS_NORMAL, &ncsParam->rgrc[0], &rcClient) == S_OK) { ru->rect.left = rcClient.left-ncsParam->rgrc[0].left; ru->rect.top = rcClient.top-ncsParam->rgrc[0].top; ru->rect.right = ncsParam->rgrc[0].right-rcClient.right; ru->rect.bottom = ncsParam->rgrc[0].bottom-rcClient.bottom; CopyRect(&ncsParam->rgrc[0], &rcClient); MyCloseThemeData(hTheme); ReleaseDC(GetParent(hwnd), hdc); return WVR_REDRAW; } ReleaseDC(GetParent(hwnd), hdc); MyCloseThemeData(hTheme); } } return ret; } case WM_ENABLE: RedrawWindow(hwnd, NULL, NULL, RDW_INVALIDATE|RDW_NOCHILDREN|RDW_UPDATENOW|RDW_FRAME); break; case WM_DESTROY: { LRESULT ret = CallWindowProc(origProc, hwnd, msg, wParam, lParam); if(IsWindow(hwnd)) { if((WNDPROC)GetWindowLong(hwnd, GWL_WNDPROC) == &RichUtil_Proc) SetWindowLong(hwnd, GWL_WNDPROC, (LONG)origProc); } if (ru) free(ru); return ret; } } return CallWindowProc(origProc, hwnd, msg, wParam, lParam); }
static LRESULT CALLBACK RichUtil_Proc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) { TRichUtil *ru; EnterCriticalSection(&csRich); ru = li.List_Find(&sListInt, (TRichUtil*)&hwnd); LeaveCriticalSection(&csRich); if (ru == NULL) return 0; switch(msg) { case WM_CHAR: { HWND hwndMsg = GetDlgItem(GetParent(hwnd), IDC_MESSAGE); if (hwndMsg != hwnd) { SetFocus(hwndMsg); SendMessage(hwndMsg, WM_CHAR, wParam, lParam); } break; } case WM_THEMECHANGED: case WM_STYLECHANGED: { RichUtil_ClearUglyBorder(ru); break; } case WM_NCPAINT: { LRESULT ret = CallWindowProc(ru->origProc, hwnd, msg, wParam, lParam); if (ru->hasUglyBorder && MyIsThemeActive()) { HANDLE hTheme = MyOpenThemeData(ru->hwnd, L"EDIT"); if (hTheme) { RECT rcBorder; RECT rcClient; int nState; HDC hdc = GetWindowDC(ru->hwnd); LONG style = GetWindowLong(hwnd, GWL_STYLE); GetWindowRect(hwnd, &rcBorder); rcBorder.right -= rcBorder.left; rcBorder.bottom -= rcBorder.top; rcBorder.left = rcBorder.top = 0; CopyRect(&rcClient, &rcBorder); rcClient.left += ru->rect.left; rcClient.top += ru->rect.top; rcClient.right -= ru->rect.right; rcClient.bottom -= ru->rect.bottom; ExcludeClipRect(hdc, rcClient.left, rcClient.top, rcClient.right, rcClient.bottom); if (MyIsThemeBackgroundPartiallyTransparent(hTheme, EP_EDITTEXT, ETS_NORMAL)) MyDrawThemeParentBackground(hwnd, hdc, &rcBorder); if (style & WS_DISABLED) nState = ETS_DISABLED; else if (style & ES_READONLY) nState = ETS_READONLY; else nState = ETS_NORMAL; MyDrawThemeBackground(hTheme, hdc, EP_EDITTEXT, nState, &rcBorder, NULL); MyCloseThemeData(hTheme); ReleaseDC(hwnd, hdc); return 0; } } return ret; } case WM_NCCALCSIZE: { LRESULT ret = CallWindowProc(ru->origProc, hwnd, msg, wParam, lParam); NCCALCSIZE_PARAMS *ncsParam = (NCCALCSIZE_PARAMS*)lParam; if (ru->hasUglyBorder && MyIsThemeActive()) { HANDLE hTheme = MyOpenThemeData(hwnd, L"EDIT"); if (hTheme) { RECT rcClient ={0}; HDC hdc = GetDC(GetParent(hwnd)); if (MyGetThemeBackgroundContentRect(hTheme, hdc, EP_EDITTEXT, ETS_NORMAL, &ncsParam->rgrc[0], &rcClient) == S_OK) { ru->rect.left = rcClient.left-ncsParam->rgrc[0].left; ru->rect.top = rcClient.top-ncsParam->rgrc[0].top; ru->rect.right = ncsParam->rgrc[0].right-rcClient.right; ru->rect.bottom = ncsParam->rgrc[0].bottom-rcClient.bottom; ncsParam->rgrc[0] = rcClient; MyCloseThemeData(hTheme); ReleaseDC(GetParent(hwnd), hdc); return WVR_REDRAW; } ReleaseDC(GetParent(hwnd), hdc); MyCloseThemeData(hTheme); } } return ret; } case WM_ENABLE: RedrawWindow(hwnd, NULL, NULL, RDW_INVALIDATE | RDW_NOCHILDREN | RDW_UPDATENOW | RDW_FRAME); break; case WM_GETDLGCODE: return CallWindowProc(ru->origProc, hwnd, msg, wParam, lParam) & ~DLGC_HASSETSEL; case WM_NCDESTROY: { LRESULT ret = CallWindowProc(ru->origProc, hwnd, msg, wParam, lParam); if (IsWindow(hwnd)) { if((WNDPROC)GetWindowLongPtr(hwnd, GWLP_WNDPROC) == &RichUtil_Proc) SetWindowLongPtr(hwnd, GWLP_WNDPROC, (LONG_PTR)ru->origProc); } EnterCriticalSection(&csRich); li.List_RemovePtr(&sListInt, ru); LeaveCriticalSection(&csRich); mir_free(ru); return ret; } } return CallWindowProc(ru->origProc, hwnd, msg, wParam, lParam); }
static void PaintWorker(MButtonCtrl *ctl, HDC hdcPaint) { if (hdcPaint) { HDC hdcMem; HBITMAP hbmMem; HBITMAP hbmOld = 0; RECT rcClient; HFONT hOldFont = 0; int xOffset = 0; GetClientRect(ctl->hwnd, &rcClient); hdcMem = CreateCompatibleDC(hdcPaint); hbmMem = CreateCompatibleBitmap(hdcPaint, rcClient.right - rcClient.left, rcClient.bottom - rcClient.top); hbmOld = SelectObject(hdcMem, hbmMem); hOldFont = SelectObject(hdcMem, ctl->hFont); // If its a push button, check to see if it should stay pressed if (ctl->pushBtn && ctl->pbState) ctl->stateId = PBS_PRESSED; // Draw the flat button if (ctl->flatBtn) { if (ctl->hThemeToolbar && ctl->bThemed) { RECT rc = rcClient; int state = IsWindowEnabled(ctl->hwnd) ? (ctl->stateId == PBS_NORMAL && ctl->defbutton ? PBS_DEFAULTED : ctl->stateId) : PBS_DISABLED; SkinDrawBg(ctl->hwnd, hdcMem); if (MyIsThemeBackgroundPartiallyTransparent(ctl->hThemeToolbar, TP_BUTTON, TBStateConvert2Flat(state))) { MyDrawThemeParentBackground(ctl->hwnd, hdcMem, &rc); } MyDrawThemeBackground(ctl->hThemeToolbar, hdcMem, TP_BUTTON, TBStateConvert2Flat(state), &rc, &rc); } else { HBRUSH hbr; RECT rc = rcClient; if(ctl->buttonItem) { RECT rcParent; POINT pt; HWND hwndParent = pcli->hwndContactList; ImageItem *imgItem = ctl->stateId == PBS_HOT ? ctl->buttonItem->imgHover : (ctl->stateId == PBS_PRESSED ? ctl->buttonItem->imgPressed : ctl->buttonItem->imgNormal); LONG *glyphMetrics = ctl->stateId == PBS_HOT ? ctl->buttonItem->hoverGlyphMetrics : (ctl->stateId == PBS_PRESSED ? ctl->buttonItem->pressedGlyphMetrics : ctl->buttonItem->normalGlyphMetrics); //if(ctl->stateId == PBS_HOT && glyphMetrics[2] <= 1 && glyphMetrics[3] <= 1) // glyphMetrics = ctl->lastGlyphMetrics; GetWindowRect(ctl->hwnd, &rcParent); pt.x = rcParent.left; pt.y = rcParent.top; ScreenToClient(pcli->hwndContactList, &pt); BitBlt(hdcMem, 0, 0, rc.right, rc.bottom, g_CluiData.hdcBg, pt.x, pt.y, SRCCOPY); if(imgItem) DrawAlpha(hdcMem, &rc, 0, 0, 0, 0, 0, 0, 0, imgItem); if(g_glyphItem) { AlphaBlend(hdcMem, (rc.right - glyphMetrics[2]) / 2, (rc.bottom - glyphMetrics[3]) / 2, glyphMetrics[2], glyphMetrics[3], g_glyphItem->hdc, glyphMetrics[0], glyphMetrics[1], glyphMetrics[2], glyphMetrics[3], g_glyphItem->bf); //CopyMemory(ctl->lastGlyphMetrics, glyphMetrics, 4 * sizeof(LONG)); } } else if(ctl->bSkinned) { // skinned RECT rcParent; POINT pt; HWND hwndParent = pcli->hwndContactList; StatusItems_t *item; int item_id; GetWindowRect(ctl->hwnd, &rcParent); pt.x = rcParent.left; pt.y = rcParent.top; ScreenToClient(pcli->hwndContactList, &pt); if(HIWORD(ctl->bSkinned)) item_id = ctl->stateId == PBS_HOT ? ID_EXTBKTBBUTTONMOUSEOVER : (ctl->stateId == PBS_PRESSED ? ID_EXTBKTBBUTTONSPRESSED : ID_EXTBKTBBUTTONSNPRESSED); //GetItemByStatus(ctl->stateId == PBS_HOT ? ID_EXTBKBUTTONSMOUSEOVER : (ctl->stateId == PBS_PRESSED ? ID_EXTBKTBBUTTONSPRESSED : ID_EXTBKTBBUTTONSNPRESSED), &item); else item_id = ctl->stateId == PBS_HOT ? ID_EXTBKBUTTONSMOUSEOVER : (ctl->stateId == PBS_PRESSED ? ID_EXTBKBUTTONSPRESSED : ID_EXTBKBUTTONSNPRESSED); item = &StatusItems[item_id - ID_STATUS_OFFLINE]; //GetItemByStatus(ctl->stateId == PBS_PRESSED ? ID_EXTBKBUTTONSPRESSED : ID_EXTBKBUTTONSNPRESSED, &item); SetTextColor(hdcMem, item->TEXTCOLOR); if(item->IGNORED) { if(pt.y < 10 || g_CluiData.bWallpaperMode) //SkinDrawBg(ctl->hwnd, hdcMem); BitBlt(hdcMem, 0, 0, rc.right, rc.bottom, g_CluiData.hdcBg, pt.x, pt.y, SRCCOPY); else FillRect(hdcMem, &rc, GetSysColorBrush(COLOR_3DFACE)); } else { if(pt.y < 10 || g_CluiData.bWallpaperMode) //SkinDrawBg(ctl->hwnd, hdcMem); BitBlt(hdcMem, 0, 0, rc.right, rc.bottom, g_CluiData.hdcBg, pt.x, pt.y, SRCCOPY); else FillRect(hdcMem, &rc, GetSysColorBrush(COLOR_3DFACE)); rc.top += item->MARGIN_TOP; rc.bottom -= item->MARGIN_BOTTOM; rc.left += item->MARGIN_LEFT; rc.right -= item->MARGIN_RIGHT; DrawAlpha(hdcMem, &rc, item->COLOR, item->ALPHA, item->COLOR2, item->COLOR2_TRANSPARENT, item->GRADIENT, item->CORNER, item->BORDERSTYLE, item->imageItem); } } else { if (ctl->stateId == PBS_PRESSED || ctl->stateId == PBS_HOT) hbr = GetSysColorBrush(COLOR_3DFACE); else { HDC dc; HWND hwndParent; hwndParent = GetParent(ctl->hwnd); dc = GetDC(hwndParent); hbr = (HBRUSH) SendMessage(hwndParent, WM_CTLCOLORDLG, (WPARAM) dc, (LPARAM) hwndParent); ReleaseDC(hwndParent, dc); } if (hbr) { FillRect(hdcMem, &rc, hbr); DeleteObject(hbr); } } if(!ctl->bSkinned && ctl->buttonItem == 0) { if (ctl->stateId == PBS_HOT || ctl->focus) { if (ctl->pbState) DrawEdge(hdcMem, &rc, EDGE_ETCHED, BF_RECT | BF_SOFT); else DrawEdge(hdcMem, &rc, BDR_RAISEDOUTER, BF_RECT | BF_SOFT); } else if (ctl->stateId == PBS_PRESSED) DrawEdge(hdcMem, &rc, BDR_SUNKENOUTER, BF_RECT | BF_SOFT); } } } else { // Draw background/border if (ctl->hThemeButton && ctl->bThemed) { int state = IsWindowEnabled(ctl->hwnd) ? (ctl->stateId == PBS_NORMAL && ctl->defbutton ? PBS_DEFAULTED : ctl->stateId) : PBS_DISABLED; POINT pt; RECT rcParent; GetWindowRect(ctl->hwnd, &rcParent); pt.x = rcParent.left; pt.y = rcParent.top; ScreenToClient(pcli->hwndContactList, &pt); BitBlt(hdcMem, 0, 0, rcClient.right, rcClient.bottom, g_CluiData.hdcBg, pt.x, pt.y, SRCCOPY); if (MyIsThemeBackgroundPartiallyTransparent(ctl->hThemeButton, BP_PUSHBUTTON, state)) { MyDrawThemeParentBackground(ctl->hwnd, hdcMem, &rcClient); } MyDrawThemeBackground(ctl->hThemeButton, hdcMem, BP_PUSHBUTTON, state, &rcClient, &rcClient); } else { UINT uState = DFCS_BUTTONPUSH | ((ctl->stateId == PBS_HOT) ? DFCS_HOT : 0) | ((ctl->stateId == PBS_PRESSED) ? DFCS_PUSHED : 0); if (ctl->defbutton && ctl->stateId == PBS_NORMAL) uState |= DLGC_DEFPUSHBUTTON; DrawFrameControl(hdcMem, &rcClient, DFC_BUTTON, uState); } // Draw focus rectangle if button has focus if (ctl->focus) { RECT focusRect = rcClient; InflateRect(&focusRect, -3, -3); DrawFocusRect(hdcMem, &focusRect); } } // If we have an icon or a bitmap, ignore text and only draw the image on the button if (ctl->hIcon || ctl->hIconPrivate || ctl->iIcon) { int ix = (rcClient.right - rcClient.left) / 2 - (g_cxsmIcon / 2); int iy = (rcClient.bottom - rcClient.top) / 2 - (g_cxsmIcon / 2); HICON hIconNew = ctl->hIconPrivate != 0 ? ctl->hIconPrivate : ctl->hIcon; if (lstrlen(ctl->szText) == 0) { if (ctl->iIcon) ImageList_DrawEx(ctl->hIml, ctl->iIcon, hdcMem, ix, iy, g_cxsmIcon, g_cysmIcon, CLR_NONE, CLR_NONE, ILD_NORMAL); else DrawState(hdcMem, NULL, NULL, (LPARAM) hIconNew, 0, ix, iy, g_cxsmIcon, g_cysmIcon, IsWindowEnabled(ctl->hwnd) ? DST_ICON | DSS_NORMAL : DST_ICON | DSS_DISABLED); ctl->sLabel.cx = ctl->sLabel.cy = 0; } else { GetTextExtentPoint32(hdcMem, ctl->szText, lstrlen(ctl->szText), &ctl->sLabel); if(g_cxsmIcon + ctl->sLabel.cx + 8 > rcClient.right - rcClient.left) ctl->sLabel.cx = (rcClient.right - rcClient.left) - g_cxsmIcon - 8; else ctl->sLabel.cx += 4; ix = (rcClient.right - rcClient.left) / 2 - ((g_cxsmIcon + ctl->sLabel.cx) / 2); if (ctl->iIcon) ImageList_DrawEx(ctl->hIml, ctl->iIcon, hdcMem, ix, iy, g_cxsmIcon, g_cysmIcon, CLR_NONE, CLR_NONE, ILD_NORMAL); else DrawState(hdcMem, NULL, NULL, (LPARAM) hIconNew, 0, ix, iy, g_cxsmIcon, g_cysmIcon, IsWindowEnabled(ctl->hwnd) ? DST_ICON | DSS_NORMAL : DST_ICON | DSS_DISABLED); xOffset = ix + g_cxsmIcon + 4; } } else if (ctl->hBitmap) { BITMAP bminfo; int ix, iy; GetObject(ctl->hBitmap, sizeof(bminfo), &bminfo); ix = (rcClient.right - rcClient.left) / 2 - (bminfo.bmWidth / 2); iy = (rcClient.bottom - rcClient.top) / 2 - (bminfo.bmHeight / 2); if (ctl->stateId == PBS_PRESSED) { ix++; iy++; } DrawState(hdcMem, NULL, NULL, (LPARAM) ctl->hBitmap, 0, ix, iy, bminfo.bmWidth, bminfo.bmHeight, IsWindowEnabled(ctl->hwnd) ? DST_BITMAP : DST_BITMAP | DSS_DISABLED); } if (GetWindowTextLength(ctl->hwnd)) { // Draw the text and optinally the arrow RECT rcText; CopyRect(&rcText, &rcClient); SetBkMode(hdcMem, TRANSPARENT); // XP w/themes doesn't used the glossy disabled text. Is it always using COLOR_GRAYTEXT? Seems so. if(!ctl->bSkinned) SetTextColor(hdcMem, IsWindowEnabled(ctl->hwnd) || !ctl->hThemeButton ? GetSysColor(COLOR_BTNTEXT) : GetSysColor(COLOR_GRAYTEXT)); if (ctl->arrow) DrawState(hdcMem, NULL, NULL, (LPARAM) ctl->arrow, 0, rcClient.right - rcClient.left - 5 - g_cxsmIcon + (!ctl->hThemeButton && ctl->stateId == PBS_PRESSED ? 1 : 0), (rcClient.bottom - rcClient.top) / 2 - g_cysmIcon / 2 + (!ctl->hThemeButton && ctl->stateId == PBS_PRESSED ? 1 : 0), g_cxsmIcon, g_cysmIcon, IsWindowEnabled(ctl->hwnd) ? DST_ICON : DST_ICON | DSS_DISABLED); DrawState(hdcMem, NULL, NULL, (LPARAM) ctl->szText, 0, xOffset + (!ctl->hThemeButton && ctl->stateId == PBS_PRESSED ? 1 : 0), ctl->hThemeButton ? (rcText.bottom - rcText.top - ctl->sLabel.cy) / 2 + 1 : (rcText.bottom - rcText.top - ctl->sLabel.cy) / 2 + (ctl->stateId == PBS_PRESSED ? 1 : 0), ctl->sLabel.cx, ctl->sLabel.cy, IsWindowEnabled(ctl->hwnd) || ctl->hThemeButton ? DST_PREFIXTEXT | DSS_NORMAL : DST_PREFIXTEXT | DSS_DISABLED); } if (hOldFont) SelectObject(hdcMem, hOldFont); BitBlt(hdcPaint, 0, 0, rcClient.right - rcClient.left, rcClient.bottom - rcClient.top, hdcMem, 0, 0, SRCCOPY); SelectObject(hdcMem, hbmOld); DeleteObject(hbmMem); DeleteDC(hdcMem); DeleteObject(hbmOld); } }