static LRESULT CALLBACK TSButtonWndProc(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam) { MButtonCtrl *bct = (MButtonCtrl *) GetWindowLongPtr(hwndDlg, 0); switch(msg) { case WM_NCCREATE: { SetWindowLong(hwndDlg, GWL_STYLE, GetWindowLong(hwndDlg, GWL_STYLE) | BS_OWNERDRAW); bct = reinterpret_cast<MButtonCtrl *>(malloc(sizeof(MButtonCtrl))); if(bct == NULL) return FALSE; bct->hwnd = hwndDlg; bct->stateId = PBS_NORMAL; bct->focus = 0; bct->hFont = reinterpret_cast<HFONT>(GetStockObject(DEFAULT_GUI_FONT)); bct->arrow = NULL; bct->defbutton = 0; bct->hIcon = bct->hIconPrivate = 0; bct->iIcon = 0; bct->hIml = 0; bct->hBitmap = NULL; bct->pushBtn = 0; bct->pbState = 0; bct->hThemeButton = NULL; bct->hThemeToolbar = NULL; bct->cHot = 0; bct->flatBtn = 0; bct->bThemed = FALSE; bct->bSkinned = bct->bSendOnDown = 0; bct->buttonItem = NULL; LoadTheme(bct); SetWindowLongPtr(hwndDlg, 0, (LONG_PTR) bct); if(((CREATESTRUCTA *) lParam)->lpszName) SetWindowText(hwndDlg, ((CREATESTRUCT *) lParam)->lpszName); return TRUE; } case WM_DESTROY: { if(bct) { if(hwndToolTips) { TOOLINFO ti; ZeroMemory(&ti, sizeof(ti)); 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 = NULL; } } if(bct->hIconPrivate) DestroyIcon(bct->hIconPrivate); DestroyTheme(bct); free(bct); } SetWindowLongPtr(hwndDlg, 0, 0); break; // DONT! fall thru } case WM_SETTEXT: { bct->cHot = 0; if((char*) lParam) { char *tmp = (char *) lParam; while(*tmp) { if(*tmp == '&' && *(tmp + 1)) { bct->cHot = tolower(*(tmp + 1)); break; } tmp++; } InvalidateRect(bct->hwnd, NULL, TRUE); lstrcpyn(bct->szText, (wchar_t *)lParam, 127); bct->szText[127] = 0; } break; } case WM_SYSKEYUP: if(bct->stateId != PBS_DISABLED && bct->cHot && bct->cHot == tolower((int) wParam)) { if(bct->pushBtn) { if(bct->pbState) bct->pbState = 0; else bct->pbState = 1; InvalidateRect(bct->hwnd, NULL, TRUE); } if(!bct->bSendOnDown) SendMessage(GetParent(hwndDlg), WM_COMMAND, MAKELONG(GetDlgCtrlID(hwndDlg), BN_CLICKED), (LPARAM) hwndDlg); return 0; } break; case WM_THEMECHANGED: { if(bct->bThemed) LoadTheme(bct); InvalidateRect(bct->hwnd, NULL, TRUE); // repaint it break; } case WM_SETFONT: { bct->hFont = (HFONT) wParam; // maybe we should redraw? break; } case WM_PAINT: { PAINTSTRUCT ps; HDC hdcPaint; hdcPaint = BeginPaint(hwndDlg, &ps); if(hdcPaint) { PaintWorker(bct, hdcPaint); EndPaint(hwndDlg, &ps); } break; } case BM_GETIMAGE: if(wParam == IMAGE_ICON) return (LRESULT)(bct->hIconPrivate ? bct->hIconPrivate : bct->hIcon); break; case BM_SETIMAGE: if(!lParam) break; bct->hIml = 0; bct->iIcon = 0; if(wParam == IMAGE_ICON) { ICONINFO ii = {0}; BITMAP bm = {0}; if(bct->hIconPrivate) { DestroyIcon(bct->hIconPrivate); bct->hIconPrivate = 0; } GetIconInfo((HICON) lParam, &ii); GetObject(ii.hbmColor, sizeof(bm), &bm); if(bm.bmWidth > CXSMICON || bm.bmHeight > CYSMICON) { HIMAGELIST hImageList; hImageList = ImageList_Create(CXSMICON, CYSMICON, ILC_COLOR32 | ILC_MASK, 1, 0); ImageList_AddIcon(hImageList, (HICON) lParam); bct->hIconPrivate = ImageList_GetIcon(hImageList, 0, ILD_NORMAL); ImageList_RemoveAll(hImageList); ImageList_Destroy(hImageList); bct->hIcon = 0; } else { bct->hIcon = (HICON) lParam; bct->hIconPrivate = 0; } DeleteObject(ii.hbmMask); DeleteObject(ii.hbmColor); bct->hBitmap = NULL; InvalidateRect(bct->hwnd, NULL, TRUE); } else if(wParam == IMAGE_BITMAP) { bct->hBitmap = (HBITMAP) lParam; if(bct->hIconPrivate) DestroyIcon(bct->hIconPrivate); bct->hIcon = bct->hIconPrivate = NULL; InvalidateRect(bct->hwnd, NULL, TRUE); } break; case BM_SETPRIVATEICON: bct->hIml = 0; bct->iIcon = 0; { if(bct->hIconPrivate) DestroyIcon(bct->hIconPrivate); bct->hIconPrivate = DuplicateIcon(g_hInst, (HICON) lParam); bct->hIcon = 0; break; } case BM_SETIMLICON: { if(bct->hIconPrivate) DestroyIcon(bct->hIconPrivate); bct->hIml = (HIMAGELIST) wParam; bct->iIcon = (int) lParam; bct->hIcon = bct->hIconPrivate = 0; InvalidateRect(bct->hwnd, NULL, TRUE); break; } case BM_SETSKINNED: bct->bSkinned = (DWORD)lParam; bct->bThemed = bct->bSkinned ? FALSE : bct->bThemed; InvalidateRect(bct->hwnd, NULL, TRUE); break; case BM_SETBTNITEM: bct->buttonItem = (TButtonItem *)lParam; break; case BM_SETASMENUACTION: bct->bSendOnDown = wParam ? TRUE : FALSE; return 0; case BM_SETCHECK: if(!bct->pushBtn) break; if(wParam == BST_CHECKED) { bct->pbState = 1; bct->stateId = PBS_PRESSED; } else if(wParam == BST_UNCHECKED) { bct->pbState = 0; bct->stateId = PBS_NORMAL; } InvalidateRect(bct->hwnd, NULL, TRUE); break; case BM_GETCHECK: if(bct->pushBtn) { return bct->pbState ? BST_CHECKED : BST_UNCHECKED; } return 0; case BUTTONSETARROW: // turn arrow on/off if(wParam) { if(!bct->arrow) bct->arrow = (HICON) LoadImage(g_hInst, MAKEINTRESOURCE(IDI_MINIMIZE), IMAGE_ICON, CXSMICON, CYSMICON, 0); } else { if(bct->arrow) { DestroyIcon(bct->arrow); bct->arrow = NULL; } } InvalidateRect(bct->hwnd, NULL, TRUE); break; case BUTTONSETDEFAULT: bct->defbutton = wParam ? 1 : 0; InvalidateRect(bct->hwnd, NULL, TRUE); break; case BUTTONSETASPUSHBTN: bct->pushBtn = 1; InvalidateRect(bct->hwnd, NULL, TRUE); break; case BUTTONSETASFLATBTN: bct->flatBtn = lParam == 0 ? 1 : 0; InvalidateRect(bct->hwnd, NULL, TRUE); break; case BUTTONSETASFLATBTN + 10: bct->bThemed = lParam ? TRUE : FALSE; bct->bSkinned = bct->bThemed ? 0 : bct->bSkinned; break; case BUTTONADDTOOLTIP: { TOOLINFO ti; if(!(char*) wParam) break; if(!hwndToolTips) { hwndToolTips = CreateWindowEx(WS_EX_TOPMOST, TOOLTIPS_CLASS, _T(""), WS_POPUP, 0, 0, 0, 0, NULL, NULL, GetModuleHandle(NULL), NULL); SetWindowPos(hwndToolTips, HWND_TOPMOST, 0, 0, 0, 0, SWP_NOSIZE | SWP_NOMOVE); } ZeroMemory(&ti, sizeof(ti)); 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); } ti.uFlags = TTF_IDISHWND | TTF_SUBCLASS; ti.uId = (UINT_PTR) bct->hwnd; ti.lpszText = (wchar_t *) wParam; SendMessage(hwndToolTips, TTM_ADDTOOL, 0, (LPARAM) &ti); break; } case WM_SETFOCUS: // set keybord focus and redraw bct->focus = 1; InvalidateRect(bct->hwnd, NULL, TRUE); break; case WM_KILLFOCUS: // kill focus and redraw bct->focus = 0; InvalidateRect(bct->hwnd, NULL, TRUE); break; case WM_WINDOWPOSCHANGED: InvalidateRect(bct->hwnd, NULL, TRUE); break; case WM_ENABLE: { bct->stateId = wParam ? PBS_NORMAL : PBS_DISABLED; InvalidateRect(bct->hwnd, NULL, TRUE); break; } case WM_MOUSELEAVE: { if(bct->stateId != PBS_DISABLED) { // don't change states if disabled bct->stateId = PBS_NORMAL; InvalidateRect(bct->hwnd, NULL, TRUE); } break; } case WM_LBUTTONDOWN: { if(bct->stateId != PBS_DISABLED && bct->stateId != PBS_PRESSED) { bct->stateId = PBS_PRESSED; InvalidateRect(bct->hwnd, NULL, TRUE); if(bct->bSendOnDown) { SendMessage(GetParent(hwndDlg), WM_COMMAND, MAKELONG(GetDlgCtrlID(hwndDlg), BN_CLICKED), (LPARAM) hwndDlg); bct->stateId = PBS_NORMAL; InvalidateRect(bct->hwnd, NULL, TRUE); } } break; } case WM_LBUTTONUP: { if(bct->pushBtn) { if(bct->pbState) bct->pbState = 0; else bct->pbState = 1; } if(bct->stateId != PBS_DISABLED) { // don't change states if disabled if(msg == WM_LBUTTONUP) bct->stateId = PBS_HOT; else bct->stateId = PBS_NORMAL; InvalidateRect(bct->hwnd, NULL, TRUE); } if(!bct->bSendOnDown) SendMessage(GetParent(hwndDlg), WM_COMMAND, MAKELONG(GetDlgCtrlID(hwndDlg), BN_CLICKED), (LPARAM) hwndDlg); break; } case WM_MOUSEMOVE: if(bct->stateId == PBS_NORMAL) { bct->stateId = PBS_HOT; InvalidateRect(bct->hwnd, NULL, TRUE); } // Call timer, used to start cheesy TrackMouseEvent faker SetTimer(hwndDlg, BUTTON_POLLID, BUTTON_POLLDELAY, NULL); break; 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 WM_TIMER: { if(wParam == BUTTON_POLLID) { RECT rc; POINT pt; GetWindowRect(hwndDlg, &rc); GetCursorPos(&pt); if(!PtInRect(&rc, pt)) { // mouse must be gone, trigger mouse leave PostMessage(hwndDlg, WM_MOUSELEAVE, 0, 0L); KillTimer(hwndDlg, BUTTON_POLLID); } } break; } case WM_ERASEBKGND: return 1; } 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; }
static LRESULT CALLBACK TSButtonWndProc(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam) { MButtonCtrl* bct = (MButtonCtrl *)GetWindowLongPtr(hwndDlg, 0); switch (msg) { case WM_NCCREATE: { SetWindowLongPtr(hwndDlg, GWL_STYLE, GetWindowLongPtr(hwndDlg, GWL_STYLE) | BS_OWNERDRAW); bct = (MButtonCtrl *)malloc(sizeof(MButtonCtrl)); if (bct == NULL) return FALSE; ZeroMemory(bct, sizeof(MButtonCtrl)); bct->hwnd = hwndDlg; bct->stateId = PBS_NORMAL; bct->hFont = (HFONT)GetStockObject(DEFAULT_GUI_FONT); LoadTheme(bct); SetWindowLongPtr(hwndDlg, 0, (LONG_PTR)bct); if (((CREATESTRUCT *)lParam)->lpszName) SetWindowText(hwndDlg, ((CREATESTRUCT *)lParam)->lpszName); return TRUE; } case WM_DESTROY: { if (bct) { EnterCriticalSection(&csTips); if (hwndToolTips) { TOOLINFO ti; ZeroMemory(&ti, sizeof(ti)); 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 = NULL; } } if (bct->hIconPrivate) DestroyIcon(bct->hIconPrivate); LeaveCriticalSection(&csTips); DestroyTheme(bct); } break; // DONT! fall thru } case WM_NCDESTROY: free(bct); SetWindowLongPtr(hwndDlg, 0, (LONG_PTR)NULL); break; case WM_SETTEXT: { bct->cHot = 0; if ((TCHAR *)lParam) { TCHAR *tmp = (TCHAR *)lParam; while (*tmp) { if (*tmp == (TCHAR)'&' && *(tmp + 1)) { bct->cHot = _totlower(*(tmp + 1)); break; } tmp++; } InvalidateRect(bct->hwnd, NULL, TRUE); } break; } case WM_KEYUP: if (bct->stateId != PBS_DISABLED && wParam == VK_SPACE && !(GetKeyState(VK_CONTROL) & 0x8000) && !(GetKeyState(VK_SHIFT) & 0x8000)) { if (bct->pushBtn) { if (bct->pbState) bct->pbState = 0; else bct->pbState = 1; InvalidateRect(bct->hwnd, NULL, TRUE); } SendMessage(GetParent(hwndDlg), WM_COMMAND, MAKELONG(GetDlgCtrlID(hwndDlg), BN_CLICKED), (LPARAM)hwndDlg); return 0; } break; case WM_SYSKEYUP: if (bct->stateId != PBS_DISABLED && bct->cHot && bct->cHot == tolower((int)wParam)) { if (bct->pushBtn) { if (bct->pbState) bct->pbState = 0; else bct->pbState = 1; InvalidateRect(bct->hwnd, NULL, TRUE); } SendMessage(GetParent(hwndDlg), WM_COMMAND, MAKELONG(GetDlgCtrlID(hwndDlg), BN_CLICKED), (LPARAM)hwndDlg); return 0; } break; case WM_THEMECHANGED: { // themed changed, reload theme object if (bct->bThemed) LoadTheme(bct); InvalidateRect(bct->hwnd, NULL, TRUE); // repaint it break; } case WM_SETFONT: { // remember the font so we can use it later bct->hFont = (HFONT)wParam; // maybe we should redraw? break; } case WM_NCPAINT: return(0); case WM_PAINT: { PAINTSTRUCT ps; HDC hdcPaint; hdcPaint = BeginPaint(hwndDlg, &ps); if (hdcPaint) { if(bct->sitem) bct->sitem->RenderThis(hdcPaint); else PaintWorker(bct, hdcPaint); EndPaint(hwndDlg, &ps); } return(0); } case BM_SETIMAGE: if (wParam == IMAGE_ICON) { ICONINFO ii; BITMAP bm; if (bct->hIconPrivate) DestroyIcon(bct->hIconPrivate); GetIconInfo((HICON)lParam, &ii); GetObject(ii.hbmColor, sizeof(bm), &bm); if (bm.bmWidth != PluginConfig.m_smcxicon || bm.bmHeight != PluginConfig.m_smcyicon) { HIMAGELIST hImageList; hImageList = ImageList_Create(PluginConfig.m_smcxicon, PluginConfig.m_smcyicon, PluginConfig.m_bIsXP ? ILC_COLOR32 | ILC_MASK : ILC_COLOR16 | ILC_MASK, 1, 0); ImageList_AddIcon(hImageList, (HICON)lParam); bct->hIconPrivate = ImageList_GetIcon(hImageList, 0, ILD_NORMAL); ImageList_RemoveAll(hImageList); ImageList_Destroy(hImageList); bct->hIcon = 0; } else { bct->hIcon = (HICON)lParam; bct->hIconPrivate = 0; } DeleteObject(ii.hbmMask); DeleteObject(ii.hbmColor); bct->hBitmap = NULL; InvalidateRect(bct->hwnd, NULL, TRUE); } else if (wParam == IMAGE_BITMAP) { bct->hBitmap = (HBITMAP)lParam; if (bct->hIconPrivate) DestroyIcon(bct->hIconPrivate); bct->hIcon = bct->hIconPrivate = NULL; InvalidateRect(bct->hwnd, NULL, TRUE); } break; case BM_SETCHECK: if (!bct->pushBtn) break; if (wParam == BST_CHECKED) { bct->pbState = 1; bct->stateId = PBS_PRESSED; } else if (wParam == BST_UNCHECKED) { bct->pbState = 0; bct->stateId = PBS_NORMAL; } InvalidateRect(bct->hwnd, NULL, TRUE); break; case BM_GETCHECK: if (bct->pushBtn) { return bct->pbState ? BST_CHECKED : BST_UNCHECKED; } return 0; case BUTTONSETARROW: // turn arrow on/off bct->arrow = (HICON)wParam; InvalidateRect(bct->hwnd, NULL, TRUE); break; case BUTTONSETDEFAULT: bct->defbutton = wParam ? 1 : 0; InvalidateRect(bct->hwnd, NULL, TRUE); break; case BUTTONSETASPUSHBTN: bct->pushBtn = 1; InvalidateRect(bct->hwnd, NULL, TRUE); break; case BUTTONSETASFLATBTN: bct->flatBtn = lParam == 0 ? 1 : 0; InvalidateRect(bct->hwnd, NULL, TRUE); break; case BUTTONSETASFLATBTN + 10: bct->bThemed = lParam ? TRUE : FALSE; break; case BUTTONSETASFLATBTN + 11: bct->dimmed = lParam ? TRUE : FALSE; break; case BUTTONSETASFLATBTN + 12: bct->pContainer = (struct TContainerData *)lParam; break; case BUTTONSETASFLATBTN + 13: bct->bTitleButton = TRUE; break; case BUTTONSETASFLATBTN + 14: bct->stateId = (wParam) ? PBS_NORMAL : PBS_DISABLED; InvalidateRect(bct->hwnd, NULL, FALSE); break; case BUTTONSETASFLATBTN + 15: return bct->stateId; case BUTTONSETASTOOLBARBUTTON: bct->bToolbarButton = lParam; break; case BUTTONSETASSIDEBARBUTTON: bct->sitem = reinterpret_cast<CSideBarButton *>(lParam); break; case BUTTONSETOVERLAYICON: bct->overlay = (HICON)lParam; break; case BUTTONADDTOOLTIP: { TOOLINFO ti; if (!(char*)wParam) break; EnterCriticalSection(&csTips); if (!hwndToolTips) { hwndToolTips = CreateWindowEx(WS_EX_TOPMOST, TOOLTIPS_CLASS, _T(""), WS_POPUP, 0, 0, 0, 0, NULL, NULL, GetModuleHandle(NULL), NULL); } ZeroMemory(&ti, sizeof(ti)); 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); } ti.uFlags = TTF_IDISHWND | TTF_SUBCLASS; ti.uId = (UINT_PTR)bct->hwnd; ti.lpszText = (TCHAR *)wParam; SendMessage(hwndToolTips, TTM_ADDTOOL, 0, (LPARAM)&ti); SendMessage(hwndToolTips, TTM_SETMAXTIPWIDTH, 0, 300); LeaveCriticalSection(&csTips); break; } case WM_SETFOCUS: // set keybord focus and redraw bct->focus = 1; InvalidateRect(bct->hwnd, NULL, TRUE); break; case WM_KILLFOCUS: // kill focus and redraw bct->focus = 0; InvalidateRect(bct->hwnd, NULL, TRUE); break; case WM_ENABLE: { // windows tells us to enable/disable bct->stateId = wParam ? PBS_NORMAL : PBS_DISABLED; InvalidateRect(bct->hwnd, NULL, TRUE); break; } case WM_MOUSELEAVE: { // faked by the WM_TIMER if (bct->stateId != PBS_DISABLED) { // don't change states if disabled bct->stateId = PBS_NORMAL; InvalidateRect(bct->hwnd, NULL, TRUE); } break; } case WM_CONTEXTMENU: if(bct->sitem) bct->sitem->invokeContextMenu(); break; case WM_MBUTTONUP: if(bct->sitem) { if(bct->sitem->getDat()) SendMessage(bct->sitem->getDat()->hwnd, WM_CLOSE, 1, 0); } break; case WM_LBUTTONDOWN: { RECT rc; if(bct->sitem) { if(bct->sitem->testCloseButton() != -1) return(TRUE); bct->stateId = PBS_PRESSED; InvalidateRect(bct->hwnd, NULL, TRUE); bct->sitem->activateSession(); } if (bct->arrow) { GetClientRect(bct->hwnd, &rc); if (LOWORD(lParam) < rc.right - 12 && bct->stateId != PBS_DISABLED) bct->stateId = PBS_PRESSED; else if(LOWORD(lParam) > rc.right - 12) { if(GetDlgCtrlID(hwndDlg) == IDOK || bct->stateId != PBS_DISABLED) { WORD w = (WORD)((int)bct->arrow & 0x0000ffff); SendMessage(GetParent(hwndDlg), WM_COMMAND, MAKELONG(w, BN_CLICKED), (LPARAM)hwndDlg); } } InvalidateRect(bct->hwnd, NULL, TRUE); } else if (bct->stateId != PBS_DISABLED) { bct->stateId = PBS_PRESSED; InvalidateRect(bct->hwnd, NULL, TRUE); } break; } case WM_LBUTTONUP: { int showClick = 0; if (bct->sitem) { if(bct->sitem->testCloseButton() != -1) { SendMessage(bct->sitem->getDat()->hwnd, WM_CLOSE, 1, 0); return(TRUE); } } if (bct->pushBtn) { if (bct->pbState) bct->pbState = 0; else bct->pbState = 1; } if (bct->stateId != PBS_DISABLED) { // don't change states if disabled if(bct->stateId == PBS_PRESSED) showClick = 1; if (msg == WM_LBUTTONUP) bct->stateId = PBS_HOT; else bct->stateId = PBS_NORMAL; InvalidateRect(bct->hwnd, NULL, TRUE); } if(showClick) SendMessage(GetParent(hwndDlg), WM_COMMAND, MAKELONG(GetDlgCtrlID(hwndDlg), BN_CLICKED), (LPARAM)hwndDlg); break; } case WM_MOUSEMOVE: if (bct->stateId == PBS_NORMAL) { bct->stateId = PBS_HOT; InvalidateRect(bct->hwnd, NULL, TRUE); } else if (bct->arrow && bct->stateId == PBS_HOT) { InvalidateRect(bct->hwnd, NULL, TRUE); } // Call timer, used to start cheesy TrackMouseEvent faker SetTimer(hwndDlg, BUTTON_POLLID, BUTTON_POLLDELAY, NULL); if(bct->sitem) { if(bct->sitem->testCloseButton() != -1) { if(bct->sitem->m_sideBar->getHoveredClose() != bct->sitem) { bct->sitem->m_sideBar->setHoveredClose(bct->sitem); InvalidateRect(hwndDlg, 0, FALSE); } } else { bct->sitem->m_sideBar->setHoveredClose(0); InvalidateRect(hwndDlg, 0, FALSE); } } break; case WM_TIMER: { // use a timer to check if they have did a mouseout if (wParam == BUTTON_POLLID) { RECT rc; POINT pt; GetWindowRect(hwndDlg, &rc); GetCursorPos(&pt); if (!PtInRect(&rc, pt)) { // mouse must be gone, trigger mouse leave PostMessage(hwndDlg, WM_MOUSELEAVE, 0, 0L); KillTimer(hwndDlg, BUTTON_POLLID); if(bct->sitem) { bct->sitem->m_sideBar->setHoveredClose(0); InvalidateRect(hwndDlg, 0, FALSE); } } } break; } case WM_ERASEBKGND: return(1); } return DefWindowProc(hwndDlg, msg, wParam, lParam); }
static LRESULT CALLBACK MButtonWndProc(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam) { MButtonCtrl* bct = (MButtonCtrl *)GetWindowLongPtr(hwndDlg, 0); switch(msg) { case WM_NCCREATE: SetWindowLongPtr(hwndDlg, GWL_STYLE, GetWindowLongPtr(hwndDlg, GWL_STYLE) | BS_OWNERDRAW); bct = ( MButtonCtrl* )mir_calloc(sizeof(MButtonCtrl)); if (bct==NULL) return FALSE; bct->hwnd = hwndDlg; bct->stateId = PBS_NORMAL; bct->hFont = ( HFONT )GetStockObject(DEFAULT_GUI_FONT); LoadTheme(bct); if (SUCCEEDED(CoCreateInstance(CLSID_AccPropServices, NULL, CLSCTX_SERVER, IID_IAccPropServices, (void**)&bct->pAccPropServices))) { // Annotating the Role of this object to be PushButton SetHwndPropInt(bct, OBJID_CLIENT, CHILDID_SELF, PROPID_ACC_ROLE, ROLE_SYSTEM_PUSHBUTTON); } else bct->pAccPropServices = NULL; SetWindowLongPtr(hwndDlg, 0, (LONG_PTR)bct); if (((CREATESTRUCT *)lParam)->lpszName) SetWindowText(hwndDlg, ((CREATESTRUCT *)lParam)->lpszName); return TRUE; case WM_DESTROY: if (bct) { if (bct->pAccPropServices) { bct->pAccPropServices->Release(); bct->pAccPropServices = NULL; } if (bct->hwndToolTips) { TOOLINFO ti = {0}; ti.cbSize = sizeof(ti); ti.uFlags = TTF_IDISHWND; ti.hwnd = bct->hwnd; ti.uId = (UINT_PTR)bct->hwnd; if (SendMessage(bct->hwndToolTips, TTM_GETTOOLINFO, 0, (LPARAM)&ti)) { SendMessage(bct->hwndToolTips, TTM_DELTOOL, 0, (LPARAM)&ti); } if ( SendMessage(bct->hwndToolTips, TTM_GETTOOLCOUNT, 0, (LPARAM)&ti) == 0 ) { int idx; TTooltips tt; tt.ThreadId = GetCurrentThreadId(); EnterCriticalSection(&csTips); if ( List_GetIndex( &lToolTips, &tt, &idx ) ) { mir_free( lToolTips.items[idx] ); List_Remove( &lToolTips, idx ); DestroyWindow( bct->hwndToolTips ); } LeaveCriticalSection(&csTips); bct->hwndToolTips = NULL; } } if (bct->arrow) IconLib_ReleaseIcon(bct->arrow, 0); DestroyTheme(bct); } break; // DONT! fall thru case WM_NCDESTROY: mir_free(bct); break; case WM_SETTEXT: bct->cHot = 0; if ( lParam != 0 ) { TCHAR *tmp = ( TCHAR* )lParam; while (*tmp) { if (*tmp=='&' && *(tmp+1)) { bct->cHot = _tolower(*(tmp+1)); break; } tmp++; } InvalidateRect(bct->hwnd, NULL, TRUE); } break; case WM_KEYUP: if (bct->stateId!=PBS_DISABLED && wParam == VK_SPACE) { if (bct->pushBtn) { if (bct->pbState) { bct->pbState = 0; bct->stateId = PBS_NORMAL; } else { bct->pbState = 1; bct->stateId = PBS_PRESSED; } InvalidateRect(bct->hwnd, NULL, TRUE); } SendMessage(GetParent(hwndDlg), WM_COMMAND, MAKELONG(GetDlgCtrlID(hwndDlg), BN_CLICKED), (LPARAM)hwndDlg); return 0; } break; case WM_SYSKEYUP: if (bct->stateId!=PBS_DISABLED && bct->cHot && bct->cHot == tolower((int)wParam)) { if (bct->pushBtn) { if (bct->pbState) { bct->pbState = 0; bct->stateId = PBS_NORMAL; } else { bct->pbState = 1; bct->stateId = PBS_PRESSED; } InvalidateRect(bct->hwnd, NULL, TRUE); } SendMessage(GetParent(hwndDlg), WM_COMMAND, MAKELONG(GetDlgCtrlID(hwndDlg), BN_CLICKED), (LPARAM)hwndDlg); return 0; } break; case WM_THEMECHANGED: // themed changed, reload theme object LoadTheme(bct); InvalidateRect(bct->hwnd, NULL, TRUE); // repaint it break; case WM_SETFONT: // remember the font so we can use it later bct->hFont = (HFONT)wParam; // maybe we should redraw? break; case WM_NCPAINT: case WM_PAINT: { PAINTSTRUCT ps; HDC hdcPaint; hdcPaint = BeginPaint(hwndDlg, &ps); if (hdcPaint) { PaintWorker(bct, hdcPaint); EndPaint(hwndDlg, &ps); } break; } case BM_SETIMAGE: { HGDIOBJ hnd = NULL; if (bct->hIcon) hnd = bct->hIcon; else if (bct->hBitmap) hnd = bct->hBitmap; if (wParam == IMAGE_ICON) { bct->hIcon = (HICON)lParam; bct->hBitmap = NULL; InvalidateRect(bct->hwnd, NULL, TRUE); } else if (wParam == IMAGE_BITMAP) { bct->hBitmap = (HBITMAP)lParam; bct->hIcon = NULL; InvalidateRect(bct->hwnd, NULL, TRUE); } return (LRESULT)hnd; } case BM_GETIMAGE: if (bct->hIcon) return (LRESULT)bct->hIcon; else if (bct->hBitmap) return (LRESULT)bct->hBitmap; else return 0; case BM_SETCHECK: if (!bct->pushBtn) break; if (wParam == BST_CHECKED) { bct->pbState = 1; bct->stateId = PBS_PRESSED; } else if (wParam == BST_UNCHECKED) { bct->pbState = 0; bct->stateId = PBS_NORMAL; } InvalidateRect(bct->hwnd, NULL, TRUE); break; case BM_GETCHECK: if (bct->pushBtn) { return bct->pbState?BST_CHECKED:BST_UNCHECKED; } return 0; case BUTTONSETARROW: // turn arrow on/off if (wParam) { if (!bct->arrow) { bct->arrow = LoadSkinIcon(SKINICON_OTHER_DOWNARROW); SetHwndPropInt(bct, OBJID_CLIENT, CHILDID_SELF, PROPID_ACC_ROLE, ROLE_SYSTEM_BUTTONDROPDOWN); } } else { if (bct->arrow) { IconLib_ReleaseIcon(bct->arrow, 0); bct->arrow = NULL; SetHwndPropInt(bct, OBJID_CLIENT, CHILDID_SELF, PROPID_ACC_ROLE, ROLE_SYSTEM_PUSHBUTTON); } } InvalidateRect(bct->hwnd, NULL, TRUE); break; case BUTTONSETDEFAULT: bct->defbutton = wParam?1:0; InvalidateRect(bct->hwnd, NULL, TRUE); break; case BUTTONSETASPUSHBTN: bct->pushBtn = 1; InvalidateRect(bct->hwnd, NULL, TRUE); break; case BUTTONSETASFLATBTN: bct->flatBtn = 1; InvalidateRect(bct->hwnd, NULL, TRUE); break; case BUTTONADDTOOLTIP: if ( wParam ) { TOOLINFO ti = {0}; if ( !bct->hwndToolTips ) { int idx; TTooltips tt; tt.ThreadId = GetCurrentThreadId(); EnterCriticalSection(&csTips); if ( List_GetIndex( &lToolTips, &tt, &idx )) { bct->hwndToolTips = ((TTooltips*)lToolTips.items[idx])->hwnd; } else { TTooltips *ptt = ( TTooltips* )mir_alloc( sizeof(TTooltips) ); ptt->ThreadId = tt.ThreadId; ptt->hwnd = CreateWindowEx(WS_EX_TOPMOST, TOOLTIPS_CLASS, _T(""), TTS_ALWAYSTIP, 0, 0, 0, 0, NULL, NULL, hMirandaInst, NULL); List_Insert( &lToolTips, ptt, idx ); bct->hwndToolTips = ptt->hwnd; } LeaveCriticalSection(&csTips); } ti.cbSize = sizeof(ti); ti.uFlags = TTF_IDISHWND; ti.hwnd = bct->hwnd; ti.uId = (UINT_PTR)bct->hwnd; if (SendMessage(bct->hwndToolTips, TTM_GETTOOLINFO, 0, (LPARAM)&ti)) SendMessage(bct->hwndToolTips, TTM_DELTOOL, 0, (LPARAM)&ti); ti.uFlags = TTF_IDISHWND|TTF_SUBCLASS; ti.uId = (UINT_PTR)bct->hwnd; #if defined( _UNICODE ) if ( lParam & BATF_UNICODE ) ti.lpszText = mir_wstrdup( TranslateW(( WCHAR* )wParam )); else ti.lpszText = LangPackPcharToTchar(( char* )wParam ); #else ti.lpszText = Translate(( char* )wParam ); #endif if (bct->pAccPropServices) { wchar_t *tmpstr = mir_t2u(ti.lpszText); bct->pAccPropServices->SetHwndPropStr(bct->hwnd, OBJID_CLIENT, CHILDID_SELF, PROPID_ACC_DESCRIPTION, tmpstr); mir_free(tmpstr); } SendMessage( bct->hwndToolTips, TTM_ADDTOOL, 0, (LPARAM)&ti); #if defined( _UNICODE ) mir_free( ti.lpszText ); #endif } break; case WM_SETFOCUS: // set keybord focus and redraw bct->focus = 1; InvalidateRect(bct->hwnd, NULL, TRUE); break; case WM_KILLFOCUS: // kill focus and redraw bct->focus = 0; InvalidateRect(bct->hwnd, NULL, TRUE); break; case WM_WINDOWPOSCHANGED: InvalidateRect(bct->hwnd, NULL, TRUE); break; case WM_ENABLE: // windows tells us to enable/disable bct->stateId = wParam?PBS_NORMAL:PBS_DISABLED; InvalidateRect(bct->hwnd, NULL, TRUE); break; case WM_MOUSELEAVE: // faked by the WM_TIMER if (bct->stateId!=PBS_DISABLED) { // don't change states if disabled bct->stateId = PBS_NORMAL; InvalidateRect(bct->hwnd, NULL, TRUE); } break; case WM_LBUTTONDOWN: if (bct->stateId!=PBS_DISABLED) { // don't change states if disabled bct->stateId = PBS_PRESSED; InvalidateRect(bct->hwnd, NULL, TRUE); } break; case WM_LBUTTONUP: { int showClick = 0; if (bct->pushBtn) { if (bct->pbState) bct->pbState = 0; else bct->pbState = 1; } if (bct->stateId!=PBS_DISABLED) { // don't change states if disabled if (bct->stateId==PBS_PRESSED) showClick = 1; if (msg==WM_LBUTTONUP) bct->stateId = PBS_HOT; else bct->stateId = PBS_NORMAL; InvalidateRect(bct->hwnd, NULL, TRUE); } if (showClick) // Tell your daddy you got clicked. SendMessage(GetParent(hwndDlg), WM_COMMAND, MAKELONG(GetDlgCtrlID(hwndDlg), BN_CLICKED), (LPARAM)hwndDlg); break; } case WM_MOUSEMOVE: if (bct->stateId == PBS_NORMAL) { bct->stateId = PBS_HOT; InvalidateRect(bct->hwnd, NULL, TRUE); } // Call timer, used to start cheesy TrackMouseEvent faker SetTimer(hwndDlg,BUTTON_POLLID,BUTTON_POLLDELAY,NULL); break; case WM_TIMER: // use a timer to check if they have did a mouseout if (wParam == BUTTON_POLLID) { RECT rc; POINT pt; GetWindowRect(hwndDlg,&rc); GetCursorPos(&pt); if(!PtInRect(&rc,pt)) { // mouse must be gone, trigger mouse leave PostMessage(hwndDlg,WM_MOUSELEAVE,0,0L); KillTimer(hwndDlg,BUTTON_POLLID); } } break; case WM_ERASEBKGND: return 1; } return DefWindowProc(hwndDlg, msg, wParam, lParam); }
static LRESULT CALLBACK TollbarButtonProc(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam) { TBBUTTONDATA *lpSBData = (TBBUTTONDATA *) GetWindowLongPtr(hwndDlg, 0); switch (msg) { case WM_NCCREATE: { SetWindowLong(hwndDlg, GWL_STYLE, GetWindowLong(hwndDlg, GWL_STYLE) | BS_OWNERDRAW); lpSBData = (TBBUTTONDATA *)malloc(sizeof(TBBUTTONDATA)); if (lpSBData == NULL) return FALSE; memset(lpSBData,0,sizeof(TBBUTTONDATA)); //I prefer memset to guarantee zeros lpSBData->hWnd = hwndDlg; lpSBData->nStateId = PBS_NORMAL; lpSBData->fFocused = FALSE; lpSBData->hFont = (HFONT)GetStockObject(DEFAULT_GUI_FONT); lpSBData->hIconPrivate = NULL; lpSBData->cHot = '\0'; lpSBData->szText[0] = '\0'; lpSBData->szButtonID[0] = '?'; lpSBData->szButtonID[1] = '\0'; lpSBData->pushBtn = FALSE; lpSBData->pbState = 0; lpSBData->fSendOnDown = FALSE; lpSBData->fHotMark = FALSE; lpSBData->nFontID = -1; SetWindowLongPtr(hwndDlg, 0, (LONG_PTR) lpSBData); if (((CREATESTRUCTA *) lParam)->lpszName) SetWindowText(hwndDlg, ((CREATESTRUCT *) lParam)->lpszName); lpSBData->hThemeButton = xpt_AddThemeHandle(lpSBData->hWnd, L"BUTTON"); lpSBData->hThemeToolbar = xpt_AddThemeHandle(lpSBData->hWnd, L"TOOLBAR"); WindowList_Add(hButtonWindowList, hwndDlg, NULL); return TRUE; } case WM_DESTROY: { /* #ifdef _DEBUG if (GetWindowLong(hwndButton, GWL_USERDATA)) DebugBreak(); #endif */ xpt_FreeThemeForWindow(hwndDlg); WindowList_Remove(hButtonWindowList, hwndDlg); if (lpSBData) { if (hwndToolTips) { TOOLINFO ti; ZeroMemory(&ti, sizeof(ti)); ti.cbSize = sizeof(ti); ti.uFlags = TTF_IDISHWND; ti.hwnd = lpSBData->hWnd; ti.uId = (UINT_PTR) lpSBData->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 = NULL; } } if (lpSBData->hIconPrivate) DestroyIcon(lpSBData->hIconPrivate); free(lpSBData); // lpSBData was malloced by native malloc } SetWindowLong(hwndDlg, 0, (LONG) NULL); break; // DONT! fall thru } case WM_SETTEXT: { lpSBData->cHot = 0; if ((TCHAR*) lParam) { TCHAR *tmp = (TCHAR *) lParam; while (*tmp) { if (*tmp == '&' && *(tmp + 1)) { lpSBData->cHot = (char)tolower(*(tmp + 1)); break; } tmp++; } InvalidateParentRect(lpSBData->hWnd, NULL, TRUE); lstrcpyn(lpSBData->szText, (TCHAR *)lParam, SIZEOF(lpSBData->szText)-1); lpSBData->szText[SIZEOF(lpSBData->szText)-1] = '\0'; } break; } case WM_SYSKEYUP: if (lpSBData->nStateId != PBS_DISABLED && lpSBData->cHot && lpSBData->cHot == tolower((int) wParam)) { if (lpSBData->pushBtn) { if (lpSBData->pbState) lpSBData->pbState = 0; else lpSBData->pbState = 1; InvalidateParentRect(lpSBData->hWnd, NULL, TRUE); } if(!lpSBData->fSendOnDown) SendMessage(GetParent(hwndDlg), WM_COMMAND, MAKELONG(GetDlgCtrlID(hwndDlg), BN_CLICKED), (LPARAM) hwndDlg); return 0; } break; case WM_SETFONT: { // remember the font so we can use it later lpSBData->hFont = (HFONT) wParam; // maybe we should redraw? lpSBData->nFontID = (int) lParam - 1; break; } case BUTTONSETSENDONDOWN: { lpSBData->fSendOnDown = (BOOL) lParam; break; } case BUTTONSETMARGINS: { if (lParam) lpSBData->rcMargins=*(RECT*)lParam; else { RECT nillRect={0}; lpSBData->rcMargins=nillRect; } return 0; } case BUTTONSETID: { lstrcpynA(lpSBData->szButtonID, (char *)lParam, SIZEOF(lpSBData->szButtonID)-1); lpSBData->szButtonID[SIZEOF(lpSBData->szButtonID)-1] = '\0'; return 0; } case BUTTONDRAWINPARENT: { if (IsWindowVisible(hwndDlg)) PaintWorker(lpSBData, (HDC) wParam, (POINT*) lParam); return 0; } case WM_NCPAINT: case WM_PAINT: { PAINTSTRUCT ps; HDC hdcPaint; if (g_CluiData.fDisableSkinEngine) { hdcPaint = BeginPaint(hwndDlg, &ps); if (hdcPaint) { PaintWorker(lpSBData, hdcPaint, NULL); EndPaint(hwndDlg, &ps); } } ValidateRect(hwndDlg,NULL); return 0; } case BUTTONADDTOOLTIP: { TOOLINFO ti; if (!(char*) wParam) break; if (!hwndToolTips) { hwndToolTips = CreateWindowEx(WS_EX_TOPMOST, TOOLTIPS_CLASS, _T(""), WS_POPUP, 0, 0, 0, 0, NULL, NULL, GetModuleHandle(NULL), NULL); SetWindowPos(hwndToolTips, HWND_TOPMOST, 0, 0, 0, 0, SWP_NOSIZE | SWP_NOMOVE); } ZeroMemory(&ti, sizeof(ti)); ti.cbSize = sizeof(ti); ti.uFlags = TTF_IDISHWND; ti.hwnd = lpSBData->hWnd; ti.uId = (UINT_PTR) lpSBData->hWnd; if (SendMessage(hwndToolTips, TTM_GETTOOLINFO, 0, (LPARAM) &ti)) { SendMessage(hwndToolTips, TTM_DELTOOL, 0, (LPARAM) &ti); } ti.uFlags = TTF_IDISHWND | TTF_SUBCLASS; ti.uId = (UINT_PTR) lpSBData->hWnd; ti.lpszText = (TCHAR *) wParam; SendMessage(hwndToolTips, TTM_ADDTOOL, 0, (LPARAM) &ti); break; } case BUTTONSETASPUSHBTN: { if (lParam==0) lpSBData->pushBtn=1; else { lpSBData->pushBtn=wParam; lpSBData->pbState = (lParam&2) ? TRUE : FALSE; } return 0; } case WM_SETFOCUS: { // set keyboard focus and redraw lpSBData->fFocused = TRUE; InvalidateParentRect(lpSBData->hWnd, NULL, TRUE); break; } case WM_KILLFOCUS: { // kill focus and redraw lpSBData->fFocused = FALSE; InvalidateParentRect(lpSBData->hWnd, NULL, TRUE); break; } case WM_WINDOWPOSCHANGED: InvalidateParentRect(lpSBData->hWnd, NULL, TRUE); break; case WM_ENABLE: // windows tells us to enable/disable { lpSBData->nStateId = wParam ? PBS_NORMAL : PBS_DISABLED; InvalidateParentRect(lpSBData->hWnd, NULL, TRUE); break; } /*case WM_MOUSELEAVE: { // faked by the WM_TIMER if (lpSBData->nStateId != PBS_DISABLED) { // don't change states if disabled lpSBData->nStateId = PBS_NORMAL; InvalidateParentRect(lpSBData->hWnd, NULL, TRUE); } break; } */ case WM_CAPTURECHANGED: { if ( (HWND)lParam != lpSBData->hWnd && lpSBData->nStateId != PBS_DISABLED) { // don't change states if disabled lpSBData->nStateId = PBS_NORMAL; InvalidateParentRect(lpSBData->hWnd, NULL, TRUE); } break; } case WM_LBUTTONDOWN: { int xPos=( ( int )( short ) LOWORD( lParam ) ); int yPos=( ( int )( short ) HIWORD( lParam ) ); POINT ptMouse = { xPos, yPos }; RECT rcClient; GetClientRect( lpSBData->hWnd, &rcClient ); if ( !PtInRect( &rcClient, ptMouse ) ) { lpSBData->fHotMark = FALSE; ReleaseCapture(); break; } if (lpSBData->nStateId != PBS_DISABLED && lpSBData->nStateId != PBS_PRESSED) { lpSBData->nStateId = PBS_PRESSED; lpSBData->fHotMark = TRUE; InvalidateParentRect(lpSBData->hWnd, NULL, TRUE); if(lpSBData->fSendOnDown) { SendMessage(GetParent(hwndDlg), WM_COMMAND, MAKELONG(GetDlgCtrlID(hwndDlg), BN_CLICKED), (LPARAM) hwndDlg); lpSBData->nStateId = PBS_NORMAL; InvalidateParentRect(lpSBData->hWnd, NULL, TRUE); } } SetCapture( lpSBData->hWnd ); break; } case WM_LBUTTONUP: if ( GetCapture() == lpSBData->hWnd ) { int xPos=( ( int )( short ) LOWORD( lParam ) ); int yPos=( ( int )( short ) HIWORD( lParam ) ); POINT ptMouse = { xPos, yPos }; RECT rcClient; GetClientRect( lpSBData->hWnd, &rcClient ); if ( !PtInRect( &rcClient, ptMouse ) ) { lpSBData->fHotMark = FALSE; ReleaseCapture(); break; } if (lpSBData->pushBtn) { if (lpSBData->pbState) lpSBData->pbState = FALSE; else lpSBData->pbState = TRUE; } if (lpSBData->nStateId != PBS_DISABLED) { // don't change states if disabled if (msg == WM_LBUTTONUP) lpSBData->nStateId = PBS_HOT; else lpSBData->nStateId = PBS_NORMAL; InvalidateParentRect(lpSBData->hWnd, NULL, TRUE); } if(!lpSBData->fSendOnDown && lpSBData->fHotMark) SendMessage(GetParent(hwndDlg), WM_COMMAND, MAKELONG(GetDlgCtrlID(hwndDlg), BN_CLICKED), (LPARAM) hwndDlg); lpSBData->fHotMark = FALSE; break; } case WM_MOUSEMOVE: { RECT rc; POINT pt; BOOL bPressed = (wParam & MK_LBUTTON) != 0; if ( bPressed && !lpSBData->fHotMark ) break; GetWindowRect(hwndDlg, &rc); GetCursorPos(&pt); BOOL inClient = PtInRect(&rc, pt); if ( inClient ) { SetCapture( lpSBData->hWnd ); if ( lpSBData->nStateId == PBS_NORMAL ) { lpSBData->nStateId = PBS_HOT; InvalidateParentRect(lpSBData->hWnd, NULL, TRUE); } } if ( !inClient && lpSBData->nStateId == PBS_PRESSED ) { lpSBData->nStateId = PBS_HOT; InvalidateParentRect(lpSBData->hWnd, NULL, TRUE); } else if ( inClient && lpSBData->nStateId == PBS_HOT && bPressed ) { if( lpSBData->fHotMark ) { lpSBData->nStateId = PBS_PRESSED; InvalidateParentRect(lpSBData->hWnd, NULL, TRUE); } } else if ( !inClient && !bPressed) { lpSBData->fHotMark = FALSE; ReleaseCapture(); } } // else { //KillTimer(hwndDlg, BUTTON_POLLID); //CLUI_SafeSetTimer(hwndDlg, BUTTON_POLLID, BUTTON_POLLDELAY, NULL); } // Call timer, used to start cheesy TrackMouseEvent faker break; 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 WM_TIMER: // use a timer to check if they have did a mouse out { if (wParam == BUTTON_POLLID) { HWND hwnd=GetCapture(); if ( hwnd == lpSBData->hWnd ) { //KillTimer(hwndDlg, BUTTON_POLLID); break; } RECT rc; POINT pt; GetWindowRect(hwndDlg, &rc); GetCursorPos(&pt); BOOL bInside = ( PtInRect( &rc, pt ) && ( WindowFromPoint( pt ) == lpSBData->hWnd) ); if ( !bInside ) { // mouse must be gone, trigger mouse leave PostMessage(hwndDlg, WM_MOUSELEAVE, 0, 0L); KillTimer(hwndDlg, BUTTON_POLLID); } } break; } */ case WM_ERASEBKGND: { return 1; } case MBM_SETICOLIBHANDLE: { if (lpSBData->hIconPrivate) { DestroyIcon(lpSBData->hIconPrivate); lpSBData->hIconPrivate = 0; } lpSBData->hIcolibHandle=(HANDLE)lParam; if (lpSBData->hIcolibHandle) lpSBData->hIcon=(HICON)CallService(MS_SKIN2_GETICONBYHANDLE, 0 , (LPARAM) lpSBData->hIcolibHandle); else lpSBData->hIcon=NULL; return 1; } case MBM_REFRESHICOLIBICON: { if (lpSBData->hIconPrivate) { DestroyIcon(lpSBData->hIconPrivate); lpSBData->hIconPrivate = 0; } if (lpSBData->hIcolibHandle) lpSBData->hIcon=(HICON)CallService(MS_SKIN2_GETICONBYHANDLE, 0 , (LPARAM) lpSBData->hIcolibHandle); else lpSBData->hIcon=NULL; InvalidateRect(hwndDlg,NULL,TRUE); pcli->pfnInvalidateRect(GetParent(GetParent(hwndDlg)),NULL,TRUE); return 1; } case MBM_UPDATETRANSPARENTFLAG: { LONG flag=GetWindowLong(hwndDlg,GWL_EXSTYLE); LONG oldFlag=flag; if (lParam==2) lParam=(g_CluiData.fDisableSkinEngine)?0:1; flag&=~WS_EX_TRANSPARENT; if (lParam) flag|=WS_EX_TRANSPARENT; if (flag!=oldFlag) { SetWindowLong(hwndDlg,GWL_EXSTYLE,flag); RedrawWindow(hwndDlg,NULL,NULL,RDW_INVALIDATE|RDW_UPDATENOW); } return 0; } case BM_GETIMAGE: { if(wParam == IMAGE_ICON) return (LRESULT)(lpSBData->hIconPrivate ? lpSBData->hIconPrivate : lpSBData->hIcon); break; } case BM_SETIMAGE: { if(!lParam) break; if (wParam == IMAGE_ICON) { ICONINFO ii = {0}; BITMAP bm = {0}; if (lpSBData->hIconPrivate) { DestroyIcon(lpSBData->hIconPrivate); lpSBData->hIconPrivate = 0; } GetIconInfo((HICON) lParam, &ii); GetObject(ii.hbmColor, sizeof(bm), &bm); if (bm.bmWidth > 16 || bm.bmHeight > 16) { HIMAGELIST hImageList; hImageList = ImageList_Create(16, 16, IsWinVerXPPlus() ? ILC_COLOR32 | ILC_MASK : ILC_COLOR16 | ILC_MASK, 1, 0); ImageList_AddIcon(hImageList, (HICON) lParam); lpSBData->hIconPrivate = ImageList_GetIcon(hImageList, 0, ILD_NORMAL); ImageList_RemoveAll(hImageList); ImageList_Destroy(hImageList); lpSBData->hIcon = 0; } else { lpSBData->hIcon = (HICON) lParam; lpSBData->hIconPrivate = NULL; } DeleteObject(ii.hbmMask); DeleteObject(ii.hbmColor); InvalidateParentRect(lpSBData->hWnd, NULL, TRUE); } else if (wParam == IMAGE_BITMAP) { if (lpSBData->hIconPrivate) DestroyIcon(lpSBData->hIconPrivate); lpSBData->hIcon = lpSBData->hIconPrivate = NULL; InvalidateParentRect(lpSBData->hWnd, NULL, TRUE); return 0; // not supported } break; } } return DefWindowProc(hwndDlg, msg, wParam, lParam); }