正确确定自定义绘图的复选框状态 [英] Properly determine checkbox state for custom draw
问题描述
介绍及相关信息:
我需要主题公共控件我>但具有不同的文字颜色和透明背景。我遇到了一个问题,这个问题在这个问题 [ ^ ]。
我通过处理 NM_CUSTOMDRAW
取得了一些进展,并决定完成首先是复选框。
问题:
我因确定复选框的状态而陷入困境,所以我无法为传递正确的参数DrawThemeBackground()
。
代码说的多于单词,所以这里是片段:
INTRODUCTION AND RELEVANT INFORMATION:
I need to have themed common controls but with different text color, and transparent background. I have ran into a problem that is well documented in this question[^].
I have made some progress by handling NM_CUSTOMDRAW
and have decided to finish the checkbox first.
PROBLEM:
I got stuck with determining the state of the checkbox, so I can not pass the correct parameter for DrawThemeBackground()
.
Code speaks more than words, so here is the snippet:
case WM_NOTIFY:
{
if( ((LPNMHDR)lParam)->code == NM_CUSTOMDRAW )
{
switch( ((LPNMHDR)lParam)->idFrom )
{
case IDC_CHECK1:
{
switch( ((LPNMCUSTOMDRAW)lParam)->dwDrawStage )
{
case CDDS_PREERASE:
{
HRESULT hr =
DrawThemeParentBackground( (
(LPNMCUSTOMDRAW)lParam)->hdr.hwndFrom,
((LPNMCUSTOMDRAW)lParam)->hdc,
&((LPNMCUSTOMDRAW)lParam)->rc );
if( FAILED(hr) )
{
SetWindowLongPtr( hDlg, DWLP_MSGRESULT,
(LONG_PTR)CDRF_DODEFAULT );
return TRUE;
}
HTHEME hTheme =
OpenThemeData(
((LPNMCUSTOMDRAW)lParam)->hdr.hwndFrom,
L"BUTTON" );
if(!hTheme)
{
CloseThemeData(hTheme);
SetWindowLongPtr( hDlg,
DWLP_MSGRESULT,
(LONG_PTR)CDRF_DODEFAULT );
return TRUE;
}
// draw the state
LRESULT state = SendMessage(
((LPNMCUSTOMDRAW)lParam)->hdr.hwndFrom,
BM_GETSTATE, 0, 0 );
int stateID;
switch( ((LPNMCUSTOMDRAW)lParam)->uItemState )
{
case CDIS_HOT:
{
if( IsDlgButtonChecked( hDlg,
((LPNMCUSTOMDRAW)lParam)->hdr.idFrom ) )
stateID = CBS_CHECKEDHOT;
else
stateID = CBS_UNCHECKEDHOT;
break;
}
case CDIS_DEFAULT:
{
if( IsDlgButtonChecked( hDlg,
((LPNMCUSTOMDRAW)lParam)->hdr.idFrom ) )
stateID = CBS_CHECKEDNORMAL;
else
stateID = CBS_UNCHECKEDNORMAL;
break;
}
case CDIS_FOCUS:
{
if( IsDlgButtonChecked( hDlg,
((LPNMCUSTOMDRAW)lParam)->hdr.idFrom ) )
stateID = CBS_CHECKEDNORMAL;
else
stateID = CBS_UNCHECKEDNORMAL;
break;
}
case CDIS_SELECTED:
{
if( IsDlgButtonChecked( hDlg,
((LPNMCUSTOMDRAW)lParam)->hdr.idFrom ) )
stateID = CBS_CHECKEDPRESSED;
else
stateID = CBS_UNCHECKEDPRESSED;
break;
}
}
RECT r;
SIZE s;
GetThemePartSize( hTheme,
((LPNMCUSTOMDRAW)lParam)->hdc,
BP_CHECKBOX,
stateID,
NULL,
TS_TRUE ,&s );
r.left = ((LPNMCUSTOMDRAW)lParam)->rc.left;
r.top = ((LPNMCUSTOMDRAW)lParam)->rc.top;
r.right = ((LPNMCUSTOMDRAW)lParam)->rc.left + s.cx;
r.bottom = ((LPNMCUSTOMDRAW)lParam)->rc.top + s.cy;
DrawThemeBackground( hTheme,
((LPNMCUSTOMDRAW)lParam)->hdc,
BP_CHECKBOX, stateID,
&r,
NULL );
((LPNMCUSTOMDRAW)lParam)->rc.left += 2 + s.cx;
DrawText( ((LPNMCUSTOMDRAW)lParam)->hdc,
L"Example text",
-1, &((LPNMCUSTOMDRAW)lParam)->rc,
DT_SINGLELINE | DT_VCENTER );
CloseThemeData(hTheme);
SetWindowLongPtr( hDlg, DWLP_MSGRESULT,
(LONG_PTR)CDRF_SKIPDEFAULT );
return TRUE;
}
}
}
break;
}
}
}
break;
文本颜色和文本背景在 WM_CTLCOLORSTATIC
处理程序中设置:
The text color and text background are set in the WM_CTLCOLORSTATIC
handler:
case WM_CTLCOLORSTATIC:
{
SetTextColor( (HDC)wParam, RGB( 255, 0, 0 ) );
SetBkMode( (HDC)wParam, TRANSPARENT );
}
return (INT_PTR)( (HBRUSH)GetStockObject(NULL_BRUSH) );
我在 #pragma comment
和 InitCommonControlsEx()
。
问题:
我现在需要的是为 DrawThemeBackground
传递正确的状态。有人可以帮我这个吗?
编辑:
可以找到满足我需求的解决方案此处 [ ^ ]。
唯一的问题是在行 bool bChecked =(uiItemState& CDIS_CHECKED);
。
它抛出 C4800警告 [ ^ 。
经过多次尝试后,我不得不将进攻线重写为 bool bChecked =(BST_CHECKED == IsDlgButtonChecked(hDlg,((LPNMCUSTOMDRAW)lParam) - > hdr.idFrom));
。
为了让一切正常工作,我还必须重新排列的顺序,如果
语句:
I have included common controls 6 with the #pragma comment
and InitCommonControlsEx()
.
QUESTION:
All I need for now is to pass proper state for the DrawThemeBackground
. Can someone help me with this?
The solution that satisfied my needs can be found here[^].
The only problem was in the line bool bChecked = (uiItemState & CDIS_CHECKED);
.
It threw C4800 warning[^].
After numerous tries I had to rewrite the offensive line to bool bChecked = ( BST_CHECKED == IsDlgButtonChecked( hDlg, ((LPNMCUSTOMDRAW)lParam)->hdr.idFrom ) );
.
In order for everything to work properly I also had to rearrange the order of if
statements :
if (uiItemState & CDIS_SELECTED)
stateID = (bChecked) ? CBS_CHECKEDPRESSED : CBS_UNCHECKEDPRESSED;
else
if (uiItemState & CDIS_HOT)
stateID = (bChecked) ? CBS_CHECKEDHOT : CBS_UNCHECKEDHOT;
else
stateID = (bChecked) ? CBS_CHECKEDNORMAL : CBS_UNCHECKEDNORMAL;
唯一剩下的就是通过绘制焦点矩形来处理键盘焦点,但我在使用正确的颜色方面遇到了麻烦。
编辑结束
谢谢。
祝你好运。
The only thing left is to handle keyboard focus by drawing focus rectangle, but I have trouble in using the correct color.
END OF EDIT
Thank you.
Best regards.
推荐答案
查看 NMCUSTOMDRAW结构 [ ^ ]。您应该检查uItemState
的值。请注意,MSDN条目说:'此值是以下标志的组合。'。这是一个提示,你不应该检查按值...而是(bitmask& value)。
祝福,
-David Delaune
Hi,
Have a look at the NMCUSTOMDRAW structure[^]. You should be checking the value ofuItemState
. Note that the MSDN entry says: 'This value is a combination of the following flags.'. This is a hint that you should not be checking by-value... but rather for (bitmask & value).
Best Wishes,
-David Delaune
这篇关于正确确定自定义绘图的复选框状态的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!