123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444 |
- #include "./skinnedcombo.h"
- #include "./skinnedheader.h"
- #include "../winamp/wa_dlg.h"
- #include "./skinning.h"
- #include "../nu/trace.h"
- #include <windowsx.h>
- #include <strsafe.h>
- #define COMBO_TEXT_MAX 512
- SkinnedCombobox::SkinnedCombobox(void) : SkinnedWnd(FALSE), activeBorder(TRUE)
- {
- }
- SkinnedCombobox::~SkinnedCombobox(void)
- {
- }
- BOOL SkinnedCombobox::Attach(HWND hwndCombo)
- {
- if(!SkinnedWnd::Attach(hwndCombo)) return FALSE;
- SetType(SKINNEDWND_TYPE_COMBOBOX);
- activeBorder = TRUE;
- COMBOBOXINFO cbi;
- ZeroMemory(&cbi, sizeof(COMBOBOXINFO));
- cbi.cbSize = sizeof(COMBOBOXINFO);
- if (GetComboBoxInfo(hwnd, &cbi))
- {
- if (NULL != cbi.hwndItem) SkinWindowEx(cbi.hwndItem, SKINNEDWND_TYPE_EDIT, style);
- if (NULL != cbi.hwndList)
- {
- SkinWindowEx(cbi.hwndList, SKINNEDWND_TYPE_LISTBOX, style);
- }
- }
- SetWindowPos(hwnd, NULL, 0, 0, 0, 0, SWP_NOSIZE | SWP_NOMOVE | SWP_NOZORDER | SWP_NOACTIVATE | SWP_FRAMECHANGED);
- return TRUE;
- }
- BOOL SkinnedCombobox::SetStyle(UINT newStyle, BOOL bRedraw)
- {
- BOOL result = __super::SetStyle(newStyle, bRedraw);
- if (hwnd)
- {
- COMBOBOXINFO cbi;
- ZeroMemory(&cbi, sizeof(COMBOBOXINFO));
- cbi.cbSize = sizeof(COMBOBOXINFO);
- activeBorder = (0 == (SWCBS_TOOLBAR & style));
- if (GetComboBoxInfo(hwnd, &cbi))
- {
- if (NULL != cbi.hwndItem) MLSkinnedWnd_SetStyle(cbi.hwndItem, style);
- if (NULL != cbi.hwndList) MLSkinnedWnd_SetStyle(cbi.hwndList, style);
- }
- }
- return result;
- }
- BOOL SkinnedCombobox::IsButtonDown(DWORD windowStyle)
- {
- if(GetAsyncKeyState((GetSystemMetrics(SM_SWAPBUTTON)) ? VK_RBUTTON : VK_LBUTTON) & 0x8000)
- {
- if (CBS_DROPDOWNLIST == (0x0F & windowStyle))
- {
- POINT pt;
- RECT rc;
- if (hwnd == GetFocus() && GetClientRect(hwnd, &rc))
- {
- GetCursorPos(&pt);
- MapWindowPoints(HWND_DESKTOP, hwnd, &pt, 1);
- return PtInRect(&rc, pt);
- }
- return FALSE;
- }
- COMBOBOXINFO cbi;
- ZeroMemory(&cbi, sizeof(COMBOBOXINFO));
- cbi.cbSize = sizeof(COMBOBOXINFO);
- if (GetComboBoxInfo(hwnd, &cbi))
- {
- //check if in arrow down area
- POINT pt;
- GetCursorPos(&pt);
- MapWindowPoints(HWND_DESKTOP, hwnd, &pt, 1);
- return PtInRect(&cbi.rcButton, pt);
- }
- }
- return FALSE;
- }
- void SkinnedCombobox::DrawButton(HDC hdc, RECT *prcButton, BOOL bPressed, BOOL bActive)
- {
- COLORREF rgbBkOld, rgbBk;
- rgbBk = WADlg_getColor(WADLG_LISTHEADER_BGCOLOR);
- rgbBkOld = SetBkColor(hdc, rgbBk);
- ExtTextOutW(hdc, 0, 0, ETO_OPAQUE, prcButton, NULL, 0, 0);
- if (bActive)
- {
- HPEN pen, penOld;
- pen = (HPEN)MlStockObjects_Get((bPressed) ? HEADERBOTTOM_PEN : HEADERTOP_PEN);
- penOld = (HPEN)SelectObject(hdc, pen);
- MoveToEx(hdc, prcButton->left, prcButton->top, NULL);
- LineTo(hdc, prcButton->right, prcButton->top);
- MoveToEx(hdc, prcButton->left, prcButton->top, NULL);
- LineTo(hdc, prcButton->left, prcButton->bottom);
- if (!bPressed)
- {
- SelectObject(hdc, penOld);
- pen = (HPEN)MlStockObjects_Get(HEADERBOTTOM_PEN);
- penOld = (HPEN)SelectObject(hdc, pen);
- }
- MoveToEx(hdc, prcButton->right - 1, prcButton->top, NULL);
- LineTo(hdc, prcButton->right - 1, prcButton->bottom);
- MoveToEx(hdc, prcButton->right - 1, prcButton->bottom - 1, NULL);
- LineTo(hdc, prcButton->left - 1, prcButton->bottom - 1);
- if (!bPressed)
- {
- SelectObject(hdc, penOld);
- pen = (HPEN)MlStockObjects_Get(HEADERMIDDLE_PEN);
- penOld = (HPEN)SelectObject(hdc, pen);
- MoveToEx(hdc, prcButton->right - 2, prcButton->top + 1, NULL);
- LineTo(hdc, prcButton->right - 2, prcButton->bottom - 2);
- MoveToEx(hdc, prcButton->right - 2, prcButton->bottom - 2, NULL);
- LineTo(hdc, prcButton->left, prcButton->bottom - 2);
- }
- SelectObject(hdc, penOld);
- }
- RECT r;
- DWORD arrowSize = SkinnedHeader::GetSortArrowSize();
- SetRect(&r, 0, 0, GET_X_LPARAM(arrowSize), GET_Y_LPARAM(arrowSize));
- OffsetRect(&r,
- prcButton->left + (prcButton->right - prcButton->left - r.right)/2 + (prcButton->right - prcButton->left - r.right)%2,
- prcButton->top + (prcButton->bottom - prcButton->top - r.bottom)/2);
- if (bPressed) OffsetRect(&r, 1, 1);
- if (r.left > (prcButton->left + 1) && r.top > (prcButton->top + 1))
- {
- SkinnedHeader::DrawSortArrow(hdc, &r, rgbBk, WADlg_getColor(WADLG_LISTHEADER_FONTCOLOR), FALSE);
- }
- SetBkColor(hdc, rgbBkOld);
- }
- void SkinnedCombobox::OnPaint()
- {
- HDC hdc;
- PAINTSTRUCT ps;
- RECT rc;
- COMBOBOXINFO cbi;
- BOOL ctrlActive;
- if (!GetClientRect(hwnd, &rc) || rc.bottom <= rc.top || rc.right <= rc.left) return;
- hdc= BeginPaint(hwnd, &ps);
- if (NULL == hdc) return;
- ctrlActive = (activeBorder /*|| hwnd == GetFocus()*/);
- if (SWCBS_TOOLBAR & style)
- {
- DrawBorder(hdc, &rc, BORDER_FLAT, (HPEN)MlStockObjects_Get(WNDBCK_PEN));
- if (ctrlActive)
- {
- InflateRect(&rc, -1, -1);
- DrawBorder(hdc, &rc, BORDER_FLAT, __super::GetBorderPen());
- }
- }
- else DrawBorder(hdc, &rc, BORDER_FLAT, GetBorderPen());
- InflateRect(&rc, -1, -1);
- ZeroMemory(&cbi, sizeof(COMBOBOXINFO));
- cbi.cbSize = sizeof(COMBOBOXINFO);
- if (GetComboBoxInfo(hwnd, &cbi))
- {
- RECT r;
- DWORD ws = GetWindowLongPtrW(hwnd, GWL_STYLE);
- SetBkMode(hdc, OPAQUE);
- SetBkColor(hdc, WADlg_getColor(WADLG_ITEMBG));
- SetRect(&r, rc.left, rc.top, cbi.rcItem.left, rc.bottom);
- if (r.left < r.right) ExtTextOutW(hdc, 0, 0, ETO_OPAQUE, &r, L"", 0, NULL);
- SetRect(&r, cbi.rcItem.left, rc.top, cbi.rcItem.right, cbi.rcItem.top);
- if (r.top < r.bottom) ExtTextOutW(hdc, 0, 0, ETO_OPAQUE, &r, L"", 0, NULL);
- SetRect(&r, cbi.rcItem.left, cbi.rcItem.bottom, cbi.rcItem.right, rc.bottom);
- if (r.top < r.bottom) ExtTextOutW(hdc, 0, 0, ETO_OPAQUE, &r, L"", 0, NULL);
- if (cbi.rcButton.left != cbi.rcButton.right)
- {
- SetRect(&r, cbi.rcItem.right, rc.top, cbi.rcButton.left, rc.bottom);
- if (r.left < r.right) ExtTextOutW(hdc, 0, 0, ETO_OPAQUE, &r, L"", 0, NULL);
- SetRect(&r, cbi.rcButton.right, rc.top, rc.right, rc.bottom);
- if (r.left < r.right) ExtTextOutW(hdc, 0, 0, ETO_OPAQUE, &r, L"", 0, NULL);
- SetRect(&r, cbi.rcButton.left, rc.top, cbi.rcButton.right, cbi.rcButton.top);
- if (r.top < r.bottom) ExtTextOutW(hdc, 0, 0, ETO_OPAQUE, &r, L"", 0, NULL);
- SetRect(&r, cbi.rcButton.left, cbi.rcButton.bottom, cbi.rcButton.right, rc.bottom);
- if (r.top < r.bottom) ExtTextOutW(hdc, 0, 0, ETO_OPAQUE, &r, L"", 0, NULL);
- DrawButton(hdc, &cbi.rcButton, IsButtonDown(ws), ctrlActive);
- }
- else
- {
- SetRect(&r, cbi.rcItem.right, rc.top, rc.right, rc.bottom);
- if (r.left < r.right) ExtTextOutW(hdc, 0, 0, ETO_OPAQUE, &r, L"", 0, NULL);
- }
- if (CBS_DROPDOWNLIST == (0x0F & ws))
- {
- INT cchText = (INT)SendMessageW(hwnd, WM_GETTEXTLENGTH, 0, 0);
- if (cchText)
- {
- HFONT hFont, hFontOld;
- wchar_t szText[COMBO_TEXT_MAX] = {0};
- SendMessageW(hwnd, WM_GETTEXT, (WPARAM)COMBO_TEXT_MAX, (LPARAM)szText);
- hFont = (HFONT)SendMessage(hwnd, WM_GETFONT, 0, 0L);
- if (!hFont) hFont = (HFONT)MlStockObjects_Get(DEFAULT_FONT);
- hFontOld = (hFont) ? (HFONT)SelectObject(hdc, hFont) : NULL;
- COLORREF rgbText;
- BOOL bFocused = (hwnd == GetFocus() && !SendMessageW(hwnd, CB_GETDROPPEDSTATE, 0, 0L));
- if (bFocused && 0 == (SWCBS_TOOLBAR & style))
- {
- rgbText = WADlg_getColor(WADLG_SELBAR_FGCOLOR);
- SetBkColor(hdc, WADlg_getColor(WADLG_SELBAR_BGCOLOR));
- }
- else rgbText = WADlg_getColor(WADLG_ITEMFG);
- if(!IsWindowEnabled(hwnd))
- {
- COLORREF rgbBack = GetBkColor(hdc);
- rgbText = RGB((GetRValue(rgbText)+GetRValue(rgbBack))/2,
- (GetGValue(rgbText)+GetGValue(rgbBack))/2,
- (GetBValue(rgbText)+GetBValue(rgbBack))/2);
- }
- SetTextColor(hdc, rgbText);
- ExtTextOutW(hdc, 0, 0, ETO_OPAQUE, &cbi.rcItem, L"", 0, NULL);
- if (bFocused &&
- 0 == (0x01/*UISF_HIDEFOCUS*/ & uiState) &&
- 0 == (SWCBS_TOOLBAR & style))
- {
- COLORREF fg, bk;
- fg = SetTextColor(hdc, GetSysColor(COLOR_WINDOWTEXT));
- bk = SetBkColor(hdc, GetSysColor(COLOR_WINDOW));
- DrawFocusRect(hdc, &cbi.rcItem);
- SetTextColor(hdc, fg);
- SetBkColor(hdc, bk);
- }
- InflateRect(&cbi.rcItem, -1, -1);
- DrawTextW(hdc, szText, min(cchText,COMBO_TEXT_MAX), &cbi.rcItem, DT_NOPREFIX | DT_SINGLELINE | DT_VCENTER);
- if (hFontOld) SelectObject(hdc, hFontOld);
- }
- else
- {
- ExtTextOutW(hdc, 0, 0, ETO_OPAQUE, &cbi.rcItem, L"", 0, NULL);
- }
- }
- }
- EndPaint(hwnd, &ps);
- }
- void SkinnedCombobox::OnSkinUpdated(BOOL bNotifyChildren, BOOL bRedraw)
- {
- __super::OnSkinUpdated(bNotifyChildren, bRedraw);
- if (SWS_USESKINFONT & style)
- {
- if (0 == (CBS_OWNERDRAWVARIABLE & GetWindowLongPtrW(hwnd, GWL_STYLE)))
- {
- HDC hdc = GetDCEx(hwnd, NULL, DCX_CACHE | DCX_NORESETATTRS);
- HFONT hf, hfo;
- TEXTMETRIC tm;
- hf = (HFONT)SendMessageW(hwnd, WM_GETFONT, 0, 0L);
- if (NULL == hf) hf = (HFONT)MlStockObjects_Get(DEFAULT_FONT);
- hfo = (HFONT)SelectObject(hdc, hf);
- GetTextMetrics(hdc, &tm);
- SendMessageW(hwnd, CB_SETITEMHEIGHT, -1, tm.tmHeight + 2);
- SendMessageW(hwnd, CB_SETITEMHEIGHT, 0, tm.tmHeight + 2);
- SelectObject(hdc, hfo);
- ReleaseDC(hwnd, hdc);
- }
- }
- }
- INT SkinnedCombobox::OnNcHitTest(POINTS pts)
- {
- INT ht = __super::OnNcHitTest(pts);
- if (ht > 0 && !activeBorder && (SWCBS_TOOLBAR & style) && IsChild(GetActiveWindow(), hwnd))
- {
- TRACKMOUSEEVENT track;
- track.cbSize = sizeof(TRACKMOUSEEVENT);
- track.dwFlags = TME_LEAVE;
- track.hwndTrack = hwnd;
- TrackMouseEvent(&track);
- activeBorder = TRUE;
- InvalidateRect(hwnd, NULL, TRUE);
- UpdateWindow(hwnd);
- }
- return ht;
- }
- void SkinnedCombobox::OnMouseLeave(void)
- {
- if (!activeBorder) return;
- COMBOBOXINFO cbi;
- ZeroMemory(&cbi, sizeof(COMBOBOXINFO));
- cbi.cbSize = sizeof(COMBOBOXINFO);
- if (GetComboBoxInfo(hwnd, &cbi) && IsWindowVisible(cbi.hwndList))
- return;
-
- activeBorder = FALSE;
- if (SWCBS_TOOLBAR & style)
- {
- InvalidateRect(hwnd, NULL, TRUE);
- UpdateWindow(hwnd);
- }
- }
- LRESULT SkinnedCombobox::SilenceMessage(UINT uMsg, WPARAM wParam, LPARAM lParam)
- {
- LRESULT result;
- UpdateWindow(hwnd);
- CallDefWndProc(WM_SETREDRAW, FALSE, 0L);
- result = __super::WindowProc(uMsg, wParam, lParam);
- CallDefWndProc(WM_SETREDRAW, TRUE, 0L);
- InvalidateRect(hwnd, NULL, TRUE);
- return result;
- }
- static HWND hwndPreviousFocus = NULL;
- LRESULT SkinnedCombobox::WindowProc(UINT uMsg, WPARAM wParam, LPARAM lParam)
- {
- if (SWCBS_TOOLBAR & style)
- {
- switch(uMsg)
- {
- case WM_SETFOCUS:
- hwndPreviousFocus = (HWND)wParam;
- break;
- case REFLECTED_COMMAND:
- switch(HIWORD(wParam))
- {
- case CBN_CLOSEUP:
- {
- if (NULL != hwndPreviousFocus && hwnd == GetFocus())
- {
- do
- {
- if (IsWindowVisible(hwndPreviousFocus) && IsWindowEnabled(hwndPreviousFocus))
- {
- SetFocus(hwndPreviousFocus);
- break;
- }
- } while (NULL != (hwndPreviousFocus = GetAncestor(hwndPreviousFocus, GA_PARENT)));
-
- }
- hwndPreviousFocus = NULL;
- }
- break;
- }
- break;
- }
- }
- if (SWS_USESKINCOLORS & style)
- {
- switch(uMsg)
- {
- case WM_PAINT: OnPaint(); return 0;
- case WM_ERASEBKGND: return 0;
- case WM_MOUSELEAVE: OnMouseLeave(); break;
-
- case WM_KILLFOCUS:
- case WM_SETFOCUS:
- case WM_COMMAND:
- case WM_CAPTURECHANGED:
- case 0x0128/*WM_UPDATEUISTATE*/:
- SilenceMessage(uMsg, wParam, lParam);
- return 0;
- case WM_LBUTTONUP:
- if (activeBorder && (SWCBS_TOOLBAR & style))
- {
- TRACKMOUSEEVENT track;
- track.cbSize = sizeof(TRACKMOUSEEVENT);
- track.dwFlags = TME_LEAVE;
- track.hwndTrack = hwnd;
- TrackMouseEvent(&track);
- POINT pt;
- pt.x = GET_X_LPARAM(lParam);
- pt.y = GET_Y_LPARAM(lParam);
- RECT rw;
- if (GetWindowRect(hwnd, &rw))
- {
- MapWindowPoints(hwnd, HWND_DESKTOP, &pt, 1);
- if (!PtInRect(&rw, pt))
- {
- INPUT pi[2];
- ZeroMemory(&pi[0], sizeof(INPUT));
- pi[0].type = INPUT_MOUSE;
- pi[0].mi.dx = pt.x;
- pi[0].mi.dy = pt.y;
- pi[0].mi.dwFlags = MOUSEEVENTF_ABSOLUTE | MOUSEEVENTF_LEFTDOWN;
- CopyMemory(&pi[1], &pi[0], sizeof(INPUT));
- pi[1].mi.dwFlags = MOUSEEVENTF_ABSOLUTE | MOUSEEVENTF_LEFTUP;
- SendInput(2, pi, sizeof(INPUT));
- }
- }
- }
- break;
- case WM_LBUTTONDOWN:
- if (!activeBorder && (SWCBS_TOOLBAR & style))
- {
- TRACKMOUSEEVENT track;
- track.cbSize = sizeof(TRACKMOUSEEVENT);
- track.dwFlags = TME_LEAVE;
- track.hwndTrack = hwnd;
- TrackMouseEvent(&track);
- activeBorder = TRUE;
- }
- break;
- }
- }
- return __super::WindowProc(uMsg, wParam, lParam);
- }
|