static LRESULT CALLBACK ModernSkinButtonWndProc(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam) { ModernSkinButtonCtrl* bct = (msg != WM_NCCREATE) ? (ModernSkinButtonCtrl *)GetWindowLongPtr(hwndDlg, GWLP_USERDATA) : nullptr; if (bct) { if (bct->HandleService && IsBadStringPtrA(bct->HandleService, 255)) bct->HandleService = nullptr; else if (bct->HandleService && ServiceExists(bct->HandleService)) { HandleServiceParams MSG = {}; MSG.hwnd = hwndDlg; MSG.msg = msg; MSG.wParam = wParam; MSG.lParam = lParam; int t = CallService(bct->HandleService, (WPARAM)&MSG, 0); if (MSG.handled) return t; } } switch (msg) { case WM_NCCREATE: SetWindowLongPtr(hwndDlg, GWL_STYLE, GetWindowLongPtr(hwndDlg, GWL_STYLE) | BS_OWNERDRAW); SetWindowLongPtr(hwndDlg, GWLP_USERDATA, 0); if (((CREATESTRUCT *)lParam)->lpszName) SetWindowText(hwndDlg, ((CREATESTRUCT *)lParam)->lpszName); return TRUE; case WM_DESTROY: if (bct == nullptr) break; if (hwndToolTips) { mir_cslock lck(csTips); TOOLINFO ti = { 0 }; ti.cbSize = sizeof(ti); ti.uFlags = TTF_IDISHWND; ti.hwnd = bct->hwnd; ti.uId = (UINT_PTR)bct->hwnd; if (SendMessage(hwndToolTips, TTM_GETTOOLINFO, 0, (LPARAM)&ti)) SendMessage(hwndToolTips, TTM_DELTOOL, 0, (LPARAM)&ti); if (SendMessage(hwndToolTips, TTM_GETTOOLCOUNT, 0, (LPARAM)&ti) == 0) { DestroyWindow(hwndToolTips); hwndToolTips = nullptr; } } mir_free(bct->ID); mir_free(bct->CommandService); mir_free(bct->StateService); mir_free(bct->HandleService); mir_free(bct->Hint); mir_free(bct->ValueDBSection); mir_free(bct->ValueTypeDef); mir_free(bct); SetWindowLongPtr(hwndDlg, GWLP_USERDATA, 0); break; // DONT! fall thru case WM_SETCURSOR: { HCURSOR hCurs1 = LoadCursor(nullptr, IDC_ARROW); if (hCurs1) SetCursor(hCurs1); if (bct) SetToolTip(hwndDlg, bct->Hint); } return 1; case WM_PRINT: if (IsWindowVisible(hwndDlg)) ModernSkinButtonPaintWorker(hwndDlg, (HDC)wParam); break; case WM_PAINT: if (IsWindowVisible(hwndDlg) && !g_CluiData.fLayered) { PAINTSTRUCT ps = {}; BeginPaint(hwndDlg, &ps); ModernSkinButtonPaintWorker(hwndDlg, (HDC)ps.hdc); EndPaint(hwndDlg, &ps); } return DefWindowProc(hwndDlg, msg, wParam, lParam); case WM_CAPTURECHANGED: if (bct) { bct->hover = 0; bct->down = 0; ModernSkinButtonPaintWorker(bct->hwnd, nullptr); } break; case WM_MOUSEMOVE: if (bct) { if (!bct->hover) { SetCapture(bct->hwnd); bct->hover = 1; ModernSkinButtonPaintWorker(bct->hwnd, nullptr); } else { POINT t = UNPACK_POINT(lParam); ClientToScreen(bct->hwnd, &t); if (WindowFromPoint(t) != bct->hwnd) ReleaseCapture(); } } return 0; case WM_LBUTTONDOWN: if (bct) { bct->down = 1; SetForegroundWindow(GetParent(bct->hwnd)); ModernSkinButtonPaintWorker(bct->hwnd, nullptr); if (bct->CommandService && IsBadStringPtrA(bct->CommandService, 255)) bct->CommandService = nullptr; if (bct->fCallOnPress) { if (bct->CommandService) { if (!_CallServiceStrParams(bct->CommandService, nullptr) && (bct->ValueDBSection && bct->ValueTypeDef)) ModernSkinButtonToggleDBValue(bct->ValueDBSection, bct->ValueTypeDef); } bct->down = 0; ModernSkinButtonPaintWorker(bct->hwnd, nullptr); } } return 0; case WM_LBUTTONUP: if (bct && bct->down) { ReleaseCapture(); bct->hover = 0; bct->down = 0; ModernSkinButtonPaintWorker(bct->hwnd, nullptr); if (bct->CommandService && IsBadStringPtrA(bct->CommandService, 255)) bct->CommandService = nullptr; if (bct->CommandService) if (_CallServiceStrParams(bct->CommandService, nullptr)) { } else if (bct->ValueDBSection && bct->ValueTypeDef) ModernSkinButtonToggleDBValue(bct->ValueDBSection, bct->ValueTypeDef); } } return DefWindowProc(hwndDlg, msg, wParam, lParam); }
static LRESULT CALLBACK ToolbarButtonProc(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam) { TBBUTTONDATA *bct = (TBBUTTONDATA*)GetWindowLongPtr(hwndDlg, 0); switch (msg) { case WM_DESTROY: xpt_FreeThemeForWindow(hwndDlg); WindowList_Remove(hButtonWindowList, hwndDlg); break; case WM_SETTEXT: mir_tstrncpy(bct->szText, (TCHAR*)lParam, _countof(bct->szText)); break; case WM_SETFONT: // remember the font so we can use it later bct->hFont = (HFONT)wParam; // maybe we should redraw? bct->nFontID = (int)lParam - 1; break; case BUTTONSETMARGINS: if (!lParam) { RECT nillRect = { 0 }; bct->rcMargins = nillRect; } else bct->rcMargins = *(RECT*)lParam; break; case BUTTONSETID: bct->szButtonID = (char *)lParam; break; case BUTTONDRAWINPARENT: if (IsWindowVisible(hwndDlg)) { PaintWorker(bct, (HDC)wParam, (POINT*)lParam); return 0; } break; case WM_NCPAINT: case WM_PAINT: if (g_CluiData.fDisableSkinEngine) { PAINTSTRUCT ps; HDC hdcPaint = BeginPaint(hwndDlg, &ps); if (hdcPaint) { PaintWorker(bct, hdcPaint, NULL); EndPaint(hwndDlg, &ps); } } ValidateRect(hwndDlg, NULL); return 0; case WM_CAPTURECHANGED: if ((HWND)lParam != bct->hwnd && bct->stateId != PBS_DISABLED) { // don't change states if disabled bct->stateId = PBS_NORMAL; InvalidateParentRect(bct->hwnd, NULL, TRUE); } break; case WM_MOUSELEAVE: case BUTTONSETASPUSHBTN: return 0; case WM_ENABLE: // windows tells us to enable/disable bct->stateId = wParam ? PBS_NORMAL : PBS_DISABLED; InvalidateParentRect(bct->hwnd, NULL, TRUE); return 0; case WM_LBUTTONDOWN: { POINT ptMouse = UNPACK_POINT(lParam); RECT rcClient; GetClientRect(bct->hwnd, &rcClient); if (!PtInRect(&rcClient, ptMouse)) { bct->bHotMark = false; ReleaseCapture(); } else { if (bct->stateId != PBS_DISABLED && bct->stateId != PBS_PRESSED) { bct->stateId = PBS_PRESSED; bct->bHotMark = true; InvalidateParentRect(bct->hwnd, NULL, TRUE); if (bct->bSendOnDown) { SendMessage(GetParent(hwndDlg), WM_COMMAND, MAKELONG(GetDlgCtrlID(hwndDlg), BN_CLICKED), (LPARAM)hwndDlg); bct->stateId = PBS_NORMAL; InvalidateParentRect(bct->hwnd, NULL, TRUE); } } SetCapture(bct->hwnd); } } return 0; case WM_LBUTTONUP: if (GetCapture() == bct->hwnd) { POINT ptMouse = UNPACK_POINT(lParam); RECT rcClient; GetClientRect(bct->hwnd, &rcClient); if (!PtInRect(&rcClient, ptMouse)) { bct->bHotMark = false; ReleaseCapture(); return 0; } if (bct->bIsPushBtn) bct->bIsPushed = !bct->bIsPushed; if (bct->stateId != PBS_DISABLED) { // don't change states if disabled bct->stateId = PBS_HOT; InvalidateParentRect(bct->hwnd, NULL, TRUE); } if (!bct->bSendOnDown) { bct->bHotMark = false; SendMessage(GetParent(hwndDlg), WM_COMMAND, MAKELONG(GetDlgCtrlID(hwndDlg), BN_CLICKED), (LPARAM)hwndDlg); } } else { bct->bHotMark = false; InvalidateParentRect(bct->hwnd, NULL, TRUE); } return 0; case WM_MOUSEMOVE: { BOOL bPressed = (wParam & MK_LBUTTON) != 0; if (bPressed && !bct->bHotMark) break; RECT rc; GetWindowRect(hwndDlg, &rc); POINT pt; GetCursorPos(&pt); BOOL inClient = PtInRect(&rc, pt); if (inClient) { SetCapture(bct->hwnd); if (bct->stateId == PBS_NORMAL) { bct->stateId = PBS_HOT; InvalidateParentRect(bct->hwnd, NULL, TRUE); } } if (!inClient && bct->stateId == PBS_PRESSED) { bct->stateId = PBS_HOT; InvalidateParentRect(bct->hwnd, NULL, TRUE); } else if (inClient && bct->stateId == PBS_HOT && bPressed) { if (bct->bHotMark) { bct->stateId = PBS_PRESSED; InvalidateParentRect(bct->hwnd, NULL, TRUE); } } else if (!inClient && !bPressed) { bct->bHotMark = false; ReleaseCapture(); } } return 0; case WM_NCHITTEST: { LRESULT lr = SendMessage(GetParent(hwndDlg), WM_NCHITTEST, wParam, lParam); if (lr == HTLEFT || lr == HTRIGHT || lr == HTBOTTOM || lr == HTTOP || lr == HTTOPLEFT || lr == HTTOPRIGHT || lr == HTBOTTOMLEFT || lr == HTBOTTOMRIGHT) return HTTRANSPARENT; } break; case BM_SETCHECK: if (!bct->bIsPushBtn) break; if (wParam == BST_CHECKED) bct->bIsPushed = 1; else if (wParam == BST_UNCHECKED) bct->bIsPushed = 0; InvalidateRect(bct->hwnd, NULL, TRUE); return 0; case WM_SETFOCUS: // set keyboard focus and redraw bct->bFocused = true; InvalidateParentRect(bct->hwnd, NULL, TRUE); break; case WM_KILLFOCUS: // kill focus and redraw bct->bFocused = false; InvalidateParentRect(bct->hwnd, NULL, TRUE); break; case WM_ERASEBKGND: return 1; case MBM_SETICOLIBHANDLE: bct->hIcolibHandle = (HANDLE)lParam; bct->hIcon = (bct->hIcolibHandle) ? IcoLib_GetIconByHandle(bct->hIcolibHandle) : NULL; return 1; case MBM_REFRESHICOLIBICON: if (bct->hIcolibHandle) bct->hIcon = IcoLib_GetIconByHandle(bct->hIcolibHandle); else bct->hIcon = NULL; InvalidateRect(hwndDlg, NULL, TRUE); pcli->pfnInvalidateRect(GetParent(GetParent(hwndDlg)), NULL, TRUE); return 1; case MBM_UPDATETRANSPARENTFLAG: LONG_PTR flag = GetWindowLongPtr(hwndDlg, GWL_EXSTYLE); LONG_PTR oldFlag = flag; if (lParam == 2) lParam = (g_CluiData.fDisableSkinEngine) ? 0 : 1; flag &= ~WS_EX_TRANSPARENT; if (lParam) flag |= WS_EX_TRANSPARENT; if (flag != oldFlag) { SetWindowLongPtr(hwndDlg, GWL_EXSTYLE, flag); RedrawWindow(hwndDlg, NULL, NULL, RDW_INVALIDATE | RDW_UPDATENOW); } return 1; } LRESULT res = mir_callNextSubclass(hwndDlg, ToolbarButtonProc, msg, wParam, lParam); if (msg == BM_SETIMAGE) InvalidateParentRect(hwndDlg, NULL, TRUE); return res; }