当我打开视觉样式时,常用控件未使用WM_CTLCOLORSTATIC处理程序正确绘制 [英] Common controls are not properly painted with WM_CTLCOLORSTATIC handler when I turn Visual styles on

查看:118
本文介绍了当我打开视觉样式时,常用控件未使用WM_CTLCOLORSTATIC处理程序正确绘制的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

介绍及相关信息:



我有2个对话框通过资源编辑器创建。由于我使用 Microsoft Visual Studio Express版,我必须下载免费资源编辑器 [ ^ ]。在我的程序中,我启用了这样的视觉样式:

INTRODUCTION AND RELEVANT INFORMATION:

I have 2 dialog boxes created via Resource Editor. Since I use Microsoft Visual Studio Express edition, I had to download free resource editor[^]. In my program, I have visual styles enabled like this:

#include <commctrl.h>

#pragma comment( lib, "comctl32.lib")

#pragma comment( linker, "/manifestdependency:\"type='win32' \
        name='Microsoft.Windows.Common-Controls' version='6.0.0.0' \
        processorArchitecture='*' publicKeyToken='6595b64144ccf1df' \
        language='*'\"")



据我所知,复选框单选按钮组合框获取 WM_CTLCOLORSTATIC 用于绘制文本的消息。这是我为第一个对话框编码的


As far as I know, check box, radio button, and group box get WM_CTLCOLORSTATIC message for painting their text. This is what I have coded for the first dialog box:

case WM_CTLCOLORSTATIC:
        {
            SetBkMode( (HDC)wParam, TRANSPARENT );
            SetTextColor( (HDC)wParam, RGB( 0, 0, 0 ) );
            return (INT_PTR)( (HBRUSH)GetStockObject(NULL_BRUSH) );
        }



我只是希望这些控件具有透明文本背景和文本的黑色。



问题:



在Windows XP上 [ ^ ],第一个对话框的结果是复选框,它的文本被正确绘制,但文本背景为黑色。 组合框具有棕色边框,文本背景具有适当的透明色,但文本为蓝色。单选按钮绘制正确。



在Windows 7上 [ ^ ],启动相同程序后,组合框检查box 具有正确的文本颜色,但复选框的文本背景和组框的边框是错误的 - 它们都是白色的。 单选按钮具有正确的文本颜色,但文本背景为灰色。



在我的对话框中,我有静态控件并在 Windows 7 Windows XP 上正确绘制



我努力解决问题:



我浏览过的 StackOverflow 存档,并尝试在 CodeProject 搜索,但没有找到任何我可以用来修改我的 WM_CTLCOLORSTATIC 处理程序。



我从这些控件中找到了一个删除 视觉样式的示例,所以它可以达到预期的效果,但我需要保持视觉样式并使文本的背景透明,因此这个解决方案不能满足我。



查看视觉样式参考和一些实验后,我找到了无线电的解决方法使用以下代码按钮复选框(但不适用于组框):


I just want those controls to have transparent text background and black color of their text.

THE PROBLEM:

On Windows XP[^], the result for first dialog is that check box and it's text are painted properly, but the text background is black. Group box has brown borders, text background has proper transparent color, but text is blue. Radio button is painted properly.

On Windows 7[^], after starting the same program, group box and check box have proper text color, yet text background of the check box and the border of the group box are wrong - they are both white. Radio button has proper text color, but text background is gray.

In my dialog box, I have static controls and they are painted properly both on Windows 7 and Windows XP.

MY EFFORTS TO SOLVE THE PROBLEM:

I have browsed through StackOverflow archive, and tried searching here at CodeProject, but haven't found anything I could use to modify my WM_CTLCOLORSTATIC handler.

I have found an example which removes Visual Styles from those controls, so it can achieve the desired result, but I need to keep the Visual Styles and make the background of the text transparent, thus this solution can not satisfy me.

After looking through Visual Styles reference and a little experimenting, I have found a workaround for radio button and check box ( but not for group box ) with the following code:

case WM_CTLCOLORSTATIC:

     if( (HWND)lParam == GetDlgItem( hwnd, IDC_RADIO1 ) ) 
     {
	 RECT r;
	 GetClientRect( hwnd, &r );
 	 DrawThemeParentBackground( (HWND)lParam, (HDC)wParam, &r );
     }
     else
     {
	 SetTextColor( (HDC)wParam, RGB( 0, 0, 0 ) );
	 SetBkMode( (HDC)wParam, TRANSPARENT );
     }
     return (INT_PTR)( (HBRUSH)GetStockObject(NULL_BRUSH) );





尽管如此,我还是碰到了墙:



在我的对话框中那里是一个 treeview ,一旦我选择节点并按空格键(或其他任何键)对话框的背景位图就在我的静态控件



我注释掉 DrawThemeParentBackground()后,重新编译并重新启动程序一切正常(当我选择树的节点并按空格键),然后我在方形一。



问题:



1.如何修改 WM_CTLCOLORSTATIC 处理程序来修复我的问题?



2.如果上述情况不可能,我可以用<$ c $获得所需的效果c> NM_CUSTOMDRAW ?



注意:



我认为我必须使用 GDI 绘制组合框。如果是这种情况,我也会接受这个解决方案,因为我的主要关注点是复选框单选按钮



谢谢。



祝你好运。



Still, I have "hit the wall" with this:

In my dialog box there is a treeview and once I select node and press spacebar ( or any other key for that matter ) dialog's background bitmap gets on top of my static controls.

After I comment out DrawThemeParentBackground(), recompile and start program again everything works fine ( when I select tree's node and press spacebar ) but then I am "at square one".

THE QUESTION:

1. How can I modify my WM_CTLCOLORSTATIC handler to fix my problem ?

2. If the above is not possible, can I get the desired effect with NM_CUSTOMDRAW ?

NOTE:

I think that I will have to draw group box using GDI. If that is the case, I will accept this solution too, as my main concern is checkbox and radio button.

Thank you.

Best regards.

推荐答案

来自微软的例子



以下C ++示例显示如何设置静态控件的文本前景色和背景色以响应WM_CTLCOLORSTATIC消息。 hbrBkgnd变量是一个静态HBRUSH变量,初始化为NULL,并在对WM_CTLCOLORSTATIC的调用之间存储背景画笔。当不再需要时,必须通过调用DeleteObject函数来销毁画笔,通常是在关联的对话框被销毁时。



创建一个快速的方法ActiveX控件或其他专用控件是子窗口的子类。有关详细信息,请参阅MFC ActiveX控件:对Windows控件进行子类化。



为防止控件的容器接收子类化Windows控件发送的窗口消息,COleControl创建一个反射器窗口来拦截某些窗口消息并将它们发送回控制。然后,控件在其窗口过程中可以通过采取适合ActiveX控件的操作来处理这些反射的消息。



通过控制发送的消息__________________消息反映到控件

WM_CTLCOLORSTATIC________________________OCM_CTLCOLORSTATIC



Examples From Microsoft

The following C++ example shows how to set the text foreground and background colors of a static control in response to the WM_CTLCOLORSTATIC message. The hbrBkgnd variable is a static HBRUSH variable that is initialized to NULL, and stores the background brush between calls to WM_CTLCOLORSTATIC. The brush must be destroyed by a call to the DeleteObject function when it is no longer needed, typically when the associated dialog box is destroyed.

A quick way to create an ActiveX control, or other specialized control, is to subclass a window. For more information, see MFC ActiveX Controls: Subclassing a Windows Control.

To prevent the control's container from receiving the window messages sent by a subclassed Windows control, COleControl creates a "reflector" window to intercept certain window messages and send them back to the control. The control, in its window procedure, can then process these reflected messages by taking actions appropriate for an ActiveX control.

Message Sent By Control__________________Message reflected to the control
WM_CTLCOLORSTATIC________________________OCM_CTLCOLORSTATIC

     static HBRUSH hbrBkgnd = NULL; // If you do this ... 

     case WM_CTLCOLORSTATIC:
     {
         HDC hdcStatic = (HDC) wParam;//Yours didn't have this statement
         SetTextColor(hdcStatic, RGB(255,255,255));//White
         SetBkColor(hdcStatic, RGB(0,0,0));//Black

         if (hbrBkgnd == NULL) //... then this will work.
         {
             hbrBkgnd = CreateSolidBrush(RGB(0,0,0)); //And you really forgot this part.
         }
         return (INT_PTR)hbrBkgnd;
     }
     break;
...........

     DeleteObject hbrBkgnd;// Don't forget this either.





如果控件在Win32系统上运行,有几种类型的WM_CTLCOLOR *它可能收到的消息。有关更多信息,请参阅WM_CTLCOLORBTN,WM_CTLCOLORDLG,WM_CTLCOLOREDIT,WM_CTLCOLORLISTBOX,WM_CTLCOLORMSGBOX,WM_CTLCOLORSCROLLBAR,WM_CTLCOLORSTATIC。



If the control runs on a Win32 system, there are several types of WM_CTLCOLOR* messages it may receive. For more information, see WM_CTLCOLORBTN, WM_CTLCOLORDLG, WM_CTLCOLOREDIT, WM_CTLCOLORLISTBOX, WM_CTLCOLORMSGBOX, WM_CTLCOLORSCROLLBAR, WM_CTLCOLORSTATIC.


	this->GrayCtlColor(HDS hDC, HWND hWnd, UINT nCtlColor, HBRUSH hbrGray, COLORREF clrText);

// implementation of OnCtlColor for default gray backgrounds
//   (works for any window containing controls)
//  return value of FALSE means caller must call DefWindowProc's default
//  TRUE means that 'hbrGray' will be used and the appropriate text
//    ('clrText') and background colors are set.
BOOL PASCAL CWnd::GrayCtlColor(HDC hDC, HWND hWnd, UINT nCtlColor,
	HBRUSH hbrGray, COLORREF clrText)
{
	if (hDC == NULL)
	{
		// sometimes Win32 passes a NULL hDC in the WM_CTLCOLOR message.
		TRACE(traceAppMsg, 0, "Warning: hDC is NULL in CWnd::GrayCtlColor; WM_CTLCOLOR not processed.\n");
		return FALSE;
	}

	if (hbrGray == NULL ||
		nCtlColor == CTLCOLOR_EDIT || nCtlColor == CTLCOLOR_MSGBOX ||
		nCtlColor == CTLCOLOR_SCROLLBAR)
	{
		return FALSE;
	}

	if (nCtlColor == CTLCOLOR_LISTBOX)
	{
		// only handle requests to draw the space between edit and drop button
		//  in a drop-down combo (not a drop-down list)
		if (!_AfxIsComboBoxControl(hWnd, (UINT)CBS_DROPDOWN))
			return FALSE;
	}

	// set background color and return handle to brush
	LOGBRUSH logbrush;
	VERIFY(::GetObject(hbrGray, sizeof(LOGBRUSH), (LPVOID)&logbrush));
	::SetBkColor(hDC, logbrush.lbColor);
	if (clrText == (COLORREF)-1)
		clrText = ::GetSysColor(COLOR_WINDOWTEXT);  // normal text
	::SetTextColor(hDC, clrText);
	return TRUE;
}





我在另一个应用程序中使用它的方式:





The way I used it in another app:

HBRUSH CPlayerView::OnCtlColor(CDC* pDC, CWnd* pWnd, UINT nCtlColor) 
{
    switch (nCtlColor)
    {
        case CTLCOLOR_BTN:
        case CTLCOLOR_STATIC:
        {
            pDC->SetBkMode(TRANSPARENT);
        }
        case CTLCOLOR_DLG:
        {
            CBrush*     back_brush;
            COLORREF    color;
            color = (COLORREF) GetSysColor(COLOR_BTNFACE);
            back_brush = new CBrush(color);
            return (HBRUSH) (back_brush->m_hObject);
        }
    }
    return(CFormView::OnCtlColor(pDC, pWnd, nCtlColor));
}


这篇关于当我打开视觉样式时,常用控件未使用WM_CTLCOLORSTATIC处理程序正确绘制的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆