Exemplo n.º 1
0
static void PaintWorker(MButtonCtrl *ctl, HDC hdcPaint)
{
	if (hdcPaint) {
		HDC hdcMem;
		HBITMAP hbmMem;
		HDC hOld;
		RECT rcClient;

		GetClientRect(ctl->hwnd, &rcClient);
		hdcMem = CreateCompatibleDC(hdcPaint);
		hbmMem = CreateCompatibleBitmap(hdcPaint, rcClient.right-rcClient.left, rcClient.bottom-rcClient.top);
		hOld = ( HDC )SelectObject(hdcMem, hbmMem);

		// 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) {
				int state = IsWindowEnabled(ctl->hwnd)?(ctl->stateId==PBS_NORMAL&&ctl->defbutton?PBS_DEFAULTED:ctl->stateId):PBS_DISABLED;
				if (isThemeBackgroundPartiallyTransparent(ctl->hThemeToolbar, TP_BUTTON, TBStateConvert2Flat(state))) {
					drawThemeParentBackground(ctl->hwnd, hdcMem, &rcClient);
				}
				drawThemeBackground(ctl->hThemeToolbar, hdcMem, TP_BUTTON, TBStateConvert2Flat(state), &rcClient, &rcClient);
			}
			else {
				HBRUSH hbr;

				if (ctl->stateId==PBS_PRESSED||ctl->stateId==PBS_HOT)
					hbr = GetSysColorBrush(COLOR_3DLIGHT);
				else {
					HWND hwndParent = GetParent(ctl->hwnd);
					HDC dc = GetDC(hwndParent);
					HBRUSH oldBrush = (HBRUSH)GetCurrentObject( dc, OBJ_BRUSH );
					hbr = (HBRUSH)SendMessage(hwndParent, WM_CTLCOLORDLG, (WPARAM)dc, (LPARAM)hwndParent);
					SelectObject(dc,oldBrush);
					ReleaseDC(hwndParent,dc);
				}
				if (hbr) {
					FillRect(hdcMem, &rcClient, hbr);
					DeleteObject(hbr);
				}
				if (ctl->stateId==PBS_HOT||ctl->focus) {
					if (ctl->pbState)
						DrawEdge(hdcMem,&rcClient, EDGE_ETCHED,BF_RECT|BF_SOFT);
					else DrawEdge(hdcMem,&rcClient, BDR_RAISEDOUTER,BF_RECT|BF_SOFT|BF_FLAT);
				}
				else if (ctl->stateId==PBS_PRESSED)
					DrawEdge(hdcMem, &rcClient, BDR_SUNKENOUTER,BF_RECT|BF_SOFT);
			}
		}
		else {
			// Draw background/border
			if (ctl->hThemeButton) {
				int state = IsWindowEnabled(ctl->hwnd)?(ctl->stateId==PBS_NORMAL&&ctl->defbutton?PBS_DEFAULTED:ctl->stateId):PBS_DISABLED;
				if (isThemeBackgroundPartiallyTransparent(ctl->hThemeButton, BP_PUSHBUTTON, state)) {
					drawThemeParentBackground(ctl->hwnd, hdcMem, &rcClient);
				}
				drawThemeBackground(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) {
			int ix = (rcClient.right-rcClient.left)/2 - (GetSystemMetrics(SM_CXSMICON)/2);
			int iy = (rcClient.bottom-rcClient.top)/2 - (GetSystemMetrics(SM_CYSMICON)/2);
			if (ctl->stateId == PBS_PRESSED) {
				ix++;
				iy++;
			}
			{
				HIMAGELIST hImageList;
				HICON hIconNew;

				hImageList = ImageList_Create(GetSystemMetrics(SM_CXSMICON),GetSystemMetrics(SM_CYSMICON), IsWinVerXPPlus()? ILC_COLOR32 | ILC_MASK : ILC_COLOR16 | ILC_MASK, 1, 0);
				ImageList_AddIcon(hImageList, ctl->hIcon);
				hIconNew = ImageList_GetIcon(hImageList, 0, ILD_NORMAL);
				DrawState(hdcMem,NULL,NULL,(LPARAM)hIconNew,0,ix,iy,GetSystemMetrics(SM_CXSMICON),GetSystemMetrics(SM_CYSMICON),IsWindowEnabled(ctl->hwnd)?DST_ICON|DSS_NORMAL:DST_ICON|DSS_DISABLED);
				ImageList_RemoveAll(hImageList);
				ImageList_Destroy(hImageList);
				DestroyIcon(hIconNew);
			}
		}
		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);
		}
		else if (GetWindowTextLength(ctl->hwnd)) {
			// Draw the text and optinally the arrow
			TCHAR szText[MAX_PATH];
			SIZE sz;
			RECT rcText;
			HFONT hOldFont;

			CopyRect(&rcText, &rcClient);
			GetWindowText(ctl->hwnd, szText, SIZEOF(szText));
			SetBkMode(hdcMem, TRANSPARENT);
			hOldFont = (HFONT)SelectObject(hdcMem, ctl->hFont);
			// XP w/themes doesn't used the glossy disabled text.  Is it always using COLOR_GRAYTEXT?  Seems so.
			SetTextColor(hdcMem, IsWindowEnabled(ctl->hwnd)||!ctl->hThemeButton?GetSysColor(COLOR_BTNTEXT):GetSysColor(COLOR_GRAYTEXT));
			GetTextExtentPoint32(hdcMem, szText, lstrlen(szText), &sz);
			if (ctl->cHot) {
				SIZE szHot;

				GetTextExtentPoint32 (hdcMem, _T("&"), 1, &szHot);
				sz.cx -= szHot.cx;
			}
			if (ctl->arrow) {
				DrawState(hdcMem,NULL,NULL,(LPARAM)ctl->arrow,0,rcClient.right-rcClient.left-5-GetSystemMetrics(SM_CXSMICON)+(!ctl->hThemeButton&&ctl->stateId==PBS_PRESSED?1:0),(rcClient.bottom-rcClient.top)/2-GetSystemMetrics(SM_CYSMICON)/2+(!ctl->hThemeButton&&ctl->stateId==PBS_PRESSED?1:0),GetSystemMetrics(SM_CXSMICON),GetSystemMetrics(SM_CYSMICON),IsWindowEnabled(ctl->hwnd)?DST_ICON:DST_ICON|DSS_DISABLED);
			}
			SelectObject(hdcMem, ctl->hFont);
			DrawState(hdcMem,NULL,NULL,(LPARAM)szText,0,(rcText.right-rcText.left-sz.cx)/2+(!ctl->hThemeButton&&ctl->stateId==PBS_PRESSED?1:0),ctl->hThemeButton?(rcText.bottom-rcText.top-sz.cy)/2:(rcText.bottom-rcText.top-sz.cy)/2-(ctl->stateId==PBS_PRESSED?0:1),sz.cx,sz.cy,IsWindowEnabled(ctl->hwnd)||ctl->hThemeButton?DST_PREFIXTEXT|DSS_NORMAL:DST_PREFIXTEXT|DSS_DISABLED);
			SelectObject(hdcMem, hOldFont);
		}
		BitBlt(hdcPaint, 0, 0, rcClient.right-rcClient.left, rcClient.bottom-rcClient.top, hdcMem, 0, 0, SRCCOPY);
		SelectObject(hdcMem, hOld);
		DeleteObject(hbmMem);
		DeleteDC(hdcMem);

	}
}
Exemplo n.º 2
0
static LRESULT CALLBACK HyperlinkWndProc(HWND hwnd,UINT msg,WPARAM wParam,LPARAM lParam)
{
	struct HyperlinkWndData *dat=(struct HyperlinkWndData*)GetWindowLongPtr(hwnd,0);
	switch(msg) {
		case WM_NCCREATE:
			dat=(struct HyperlinkWndData*)mir_calloc(sizeof(struct HyperlinkWndData));
			if(dat==NULL) return FALSE; /* fail creation */
			SetWindowLongPtr(hwnd,0,(LONG_PTR)dat); /* always succeeds */
			/* fall thru */
		case WM_SYSCOLORCHANGE:
			if(!(dat->flags&HLKF_HASENABLECOLOR)) {
				if(GetSysColorBrush(COLOR_HOTLIGHT)==NULL) dat->enableColor=RGB(0,0,255);
				else dat->enableColor=GetSysColor(COLOR_HOTLIGHT);
				dat->focusColor = RGB(GetRValue(dat->enableColor) / 2, GetGValue(dat->enableColor) / 2, GetBValue(dat->enableColor) / 2);
			}
			if(!(dat->flags&HLKF_HASDISABLECOLOR))
				dat->disableColor=GetSysColor(COLOR_GRAYTEXT);
			break;

		case WM_SETFOCUS:
		case WM_KILLFOCUS:
			RedrawWindow(hwnd, NULL, NULL, RDW_INVALIDATE);
			break;
		case WM_MOUSEACTIVATE:
			SetFocus(hwnd);
			return MA_ACTIVATE;
		case WM_GETDLGCODE:
		{
			if (lParam)
			{
				MSG *msg = (MSG *) lParam;
				if (msg->message == WM_KEYDOWN)
				{
					if (msg->wParam == VK_TAB)
						return 0;
					if (msg->wParam == VK_ESCAPE)
						return 0;
				} else
				if (msg->message == WM_CHAR)
				{
					if (msg->wParam == '\t')
						return 0;
					if (msg->wParam == 27)
						return 0;
				}
			}
			return DLGC_WANTMESSAGE;
		}

		case WM_KEYDOWN:
		{
			switch (wParam)
			{
			case VK_SPACE:
			case VK_RETURN:
				SendMessage(GetParent(hwnd),WM_COMMAND,MAKEWPARAM(GetDlgCtrlID(hwnd),STN_CLICKED),(LPARAM)hwnd);
				break;
			}
			return 0;
		}

		case WM_LBUTTONDOWN:
		{	POINT pt;
			POINTSTOPOINT(pt,MAKEPOINTS(lParam));
			if(!PtInRect(&dat->rcText,pt)) break;
			SendMessage(GetParent(hwnd),WM_COMMAND,MAKEWPARAM(GetDlgCtrlID(hwnd),STN_CLICKED),(LPARAM)hwnd);
			return 0;
		}
		case WM_SETFONT:
		{	LOGFONT lf;
			HFONT hFont;
			if((HFONT)wParam==NULL) { /* use default system color */
				dat->hEnableFont=dat->hDisableFont=NULL;
				return 0;
			}
			if(GetObject((HFONT)wParam,sizeof(lf),&lf)) {
				lf.lfUnderline=1;
				hFont=CreateFontIndirect(&lf);
				if(hFont!=NULL) {
					dat->hEnableFont=hFont;
					dat->hDisableFont=(HFONT)wParam;
					if(LOWORD(lParam)) SendMessage(hwnd,HLK_INVALIDATE,0,0);
					SendMessage(hwnd,HLK_MEASURETEXT,0,0);
				}
			}
			return 0;
		}
		case WM_ERASEBKGND:
			return TRUE;
		case WM_ENABLE:
		case HLK_INVALIDATE:
		{	RECT rcWnd;
			POINT pt;
			HWND hwndParent;
			if(!GetWindowRect(hwnd,&rcWnd)) break;
			pt.x=rcWnd.left;
			pt.y=rcWnd.top;
			hwndParent=GetParent(hwnd);
			if(hwndParent==NULL) hwndParent=hwnd;
			if(!ScreenToClient(hwndParent,&pt)) break;
			rcWnd.right=pt.x+(rcWnd.right-rcWnd.left);
			rcWnd.bottom=pt.y+(rcWnd.bottom-rcWnd.top);
			rcWnd.left=pt.x;
			rcWnd.top=pt.y;
			InvalidateRect(hwndParent,&rcWnd,TRUE);
			return 0;
		}
		case WM_GETFONT:
			return (LRESULT)dat->hDisableFont;
		case WM_CREATE:
		case HLK_MEASURETEXT:
		{	TCHAR szText[256];
			if(!GetWindowText(hwnd,szText,SIZEOF(szText))) return 0;
			lParam=(LPARAM)szText;
			/* fall thru */
		case WM_SETTEXT:
		{	HFONT hPrevFont = NULL;
			SIZE textSize;
			RECT rc;
			HDC hdc;
			LONG style;
			BOOL fMeasured=FALSE;
			hdc=GetDC(hwnd);
			if(hdc==NULL) return 0; /* text change failed */
			if(dat->hEnableFont!=NULL) hPrevFont=(HFONT)SelectObject(hdc,dat->hEnableFont);
			if(dat->hEnableFont==NULL || hPrevFont!=NULL) /* select failed? */
				if(GetTextExtentPoint32(hdc,(TCHAR*)lParam,lstrlen((TCHAR*)lParam),&textSize))
					if(GetClientRect(hwnd,&rc)) {
						dat->rcText.top=0;
						dat->rcText.bottom=dat->rcText.top+textSize.cy;
						style=GetWindowLongPtr(hwnd,GWL_STYLE);
						if(style&SS_CENTER) dat->rcText.left=(rc.right-textSize.cx)/2;
						else if(style&SS_RIGHT) dat->rcText.left=rc.right-textSize.cx;
						else dat->rcText.left=0;
						dat->rcText.right=dat->rcText.left+textSize.cx;
						fMeasured=TRUE;
					}
			if(dat->hEnableFont!=NULL && hPrevFont!=NULL) SelectObject(hdc,hPrevFont);
			ReleaseDC(hwnd,hdc);
			if(!fMeasured) return 0; /* text change failed */
			SendMessage(hwnd,HLK_INVALIDATE,0,0);
			break;
		}}
		case WM_SETCURSOR:
		{	POINT pt;
			HCURSOR hCursor;
			if(!GetCursorPos(&pt)) return FALSE;
			if(!ScreenToClient(hwnd,&pt)) return FALSE;
			if(PtInRect(&dat->rcText,pt)) {
				hCursor=(HCURSOR)GetClassLongPtr(hwnd,GCLP_HCURSOR);
				if(hCursor==NULL) hCursor=LoadCursor(NULL,IDC_HAND); /* Win2000+ */
			}
			else hCursor=LoadCursor(NULL,IDC_ARROW);
			SetCursor(hCursor);
			return TRUE;
		}
		case HLK_SETENABLECOLOUR:
		{	COLORREF prevColor=dat->enableColor;
			dat->enableColor=(COLORREF)wParam;
			dat->focusColor = RGB(GetRValue(dat->enableColor) / 2, GetGValue(dat->enableColor) / 2, GetBValue(dat->enableColor) / 2);
			dat->flags|=HLKF_HASENABLECOLOR;
			return (LRESULT)prevColor;
		}
		case HLK_SETDISABLECOLOUR:
		{	COLORREF prevColor=dat->disableColor;
			dat->disableColor=(COLORREF)wParam;
			dat->flags|=HLKF_HASDISABLECOLOR;
			return (LRESULT)prevColor;
		}
		case WM_NCPAINT:
			return 0;
		case WM_PAINT:
		{	HFONT hPrevFont;
			RECT rc;
			TCHAR szText[256];
			UINT alignFlag;
			COLORREF textColor;
			PAINTSTRUCT ps;
			HDC hdc;
			
			hdc=BeginPaint(hwnd,&ps);
			if(hdc!=NULL) {
				if(IsWindowEnabled(hwnd)) {
					hPrevFont=(HFONT)SelectObject(hdc,dat->hEnableFont);
					textColor = (GetFocus() == hwnd) ? dat->focusColor : dat->enableColor;
				} else {
					hPrevFont=(HFONT)SelectObject(hdc,dat->hDisableFont);
					textColor=dat->disableColor;
				}
				if(GetClientRect(hwnd,&rc) && GetWindowText(hwnd,szText,SIZEOF(szText))) {
					if (drawThemeParentBackground && IsWinVerXPPlus())
					{
						BOOL fSmoothing;
						UINT fSmoothingType;
						SystemParametersInfo(SPI_GETFONTSMOOTHING, 0, &fSmoothing, 0);
						SystemParametersInfo(SPI_GETFONTSMOOTHINGTYPE, 0, &fSmoothingType, 0);
						if (fSmoothing && fSmoothingType == FE_FONTSMOOTHINGCLEARTYPE)
							drawThemeParentBackground(hwnd, hdc, &rc);
					}
					SetBkMode(hdc,TRANSPARENT);
					SetTextColor(hdc,textColor);
					alignFlag=(GetWindowLongPtr(hwnd,GWL_STYLE)&(SS_CENTER|SS_RIGHT|SS_LEFT));
					DrawText(hdc,szText,-1,&rc,alignFlag|DT_NOPREFIX|DT_SINGLELINE|DT_TOP);
				}
				if(hPrevFont!=NULL) SelectObject(hdc,hPrevFont);
				EndPaint(hwnd,&ps);
			}
			return 0;
		}
		case WM_NCDESTROY:			
			if(dat->hEnableFont!=NULL) DeleteObject(dat->hEnableFont);
			mir_free(dat);			
			break;
	}
	return DefWindowProc(hwnd,msg,wParam,lParam);
}