| 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	512SkinnedCombobox::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);}
 |