[MFC] Using the SS_OWNERDRAW style on a CStatic control
-
(not really urgent, just a general question) I want to "owner draw" a CStatic to have a custom "GroupBox". The documentation says that I need to add the SS_OWNERDRAW style to the control; The resource editor does not let me change the style (there's no toggle for that). So, I added a variable to my test dialog and tried to use ModifyStyle to add the SS_OWNERDRAW style in the dialog OnInitDialog (after the control is created). I also tried to change the style in custom CStatic's PreSubclassWindow method; but that does not work. Both changes did not work as expected. I tried manually create the control in the dialog OnInitDialog; this is the work-around I am using now.
///...
CRect rect;
GetClientRect(rect);
rect.DeflateRect(10, 10, 10, 10 );
m_CustomGroup.Create(_T(""), SS_OWNERDRAW|WS_CHILD|WS_VISIBLE, rect, this, IDC_CUSTOM_STATIC );
///...This works, but I remove the ability to use the resource editor to manage the custom static. Is this the proper way to do it? Thanks. Max.
I'd rather be phishing!
-
(not really urgent, just a general question) I want to "owner draw" a CStatic to have a custom "GroupBox". The documentation says that I need to add the SS_OWNERDRAW style to the control; The resource editor does not let me change the style (there's no toggle for that). So, I added a variable to my test dialog and tried to use ModifyStyle to add the SS_OWNERDRAW style in the dialog OnInitDialog (after the control is created). I also tried to change the style in custom CStatic's PreSubclassWindow method; but that does not work. Both changes did not work as expected. I tried manually create the control in the dialog OnInitDialog; this is the work-around I am using now.
///...
CRect rect;
GetClientRect(rect);
rect.DeflateRect(10, 10, 10, 10 );
m_CustomGroup.Create(_T(""), SS_OWNERDRAW|WS_CHILD|WS_VISIBLE, rect, this, IDC_CUSTOM_STATIC );
///...This works, but I remove the ability to use the resource editor to manage the custom static. Is this the proper way to do it? Thanks. Max.
I'd rather be phishing!
I had a similar problem a few weeks ago. I solved it by manually editing the resource file containing the dialog box and adding the style that way.
The difficult we do right away... ...the impossible takes slightly longer.
-
(not really urgent, just a general question) I want to "owner draw" a CStatic to have a custom "GroupBox". The documentation says that I need to add the SS_OWNERDRAW style to the control; The resource editor does not let me change the style (there's no toggle for that). So, I added a variable to my test dialog and tried to use ModifyStyle to add the SS_OWNERDRAW style in the dialog OnInitDialog (after the control is created). I also tried to change the style in custom CStatic's PreSubclassWindow method; but that does not work. Both changes did not work as expected. I tried manually create the control in the dialog OnInitDialog; this is the work-around I am using now.
///...
CRect rect;
GetClientRect(rect);
rect.DeflateRect(10, 10, 10, 10 );
m_CustomGroup.Create(_T(""), SS_OWNERDRAW|WS_CHILD|WS_VISIBLE, rect, this, IDC_CUSTOM_STATIC );
///...This works, but I remove the ability to use the resource editor to manage the custom static. Is this the proper way to do it? Thanks. Max.
I'd rather be phishing!
The usual method to switch to ownerdraw style is to use PreSubclassWindow:
void CMyStatic::PreSubclassWindow()
{
// Switch to owner-draw
VERIFY(ModifyStyle(SS_TYPEMASK, SS_OWNERDRAW, 0));
CStatic::PreSubclassWindow();
}Note that
SS_TYPEMASK
should be passed for the flags to be removed because the lower style bits are not ored options but enumerations. If the current style is notSS_LEFT
(which is zero) but set to something else in the resource editor, the resulting style might be not owner draw. The probable reason that this style can't be set in the resource editor is that owner drawn controls must implement theDrawItem
function. This can't be checked by the resource editor. -
The usual method to switch to ownerdraw style is to use PreSubclassWindow:
void CMyStatic::PreSubclassWindow()
{
// Switch to owner-draw
VERIFY(ModifyStyle(SS_TYPEMASK, SS_OWNERDRAW, 0));
CStatic::PreSubclassWindow();
}Note that
SS_TYPEMASK
should be passed for the flags to be removed because the lower style bits are not ored options but enumerations. If the current style is notSS_LEFT
(which is zero) but set to something else in the resource editor, the resulting style might be not owner draw. The probable reason that this style can't be set in the resource editor is that owner drawn controls must implement theDrawItem
function. This can't be checked by the resource editor.Thanks, I tried that, but it does not work, the ModifyStyle "works" (does not fail), but the DrawItem is not called. SS_TYPEMASK is now obsolete, msdn says we should not use it. There are other controls that I can set as Owner draw in the resource editor (for example List box) and will ASSERT when run and the (related) DrawItem is not defined.
I'd rather be phishing!
-
I had a similar problem a few weeks ago. I solved it by manually editing the resource file containing the dialog box and adding the style that way.
The difficult we do right away... ...the impossible takes slightly longer.
I tried modifying the resource manually but the resulting control is not a groupbox and the framework does not call my overridden DrawItem and the resulting control in the dialog is completely wrong. This is my resource definition.
IDD_TESTDIALOG_DIALOG DIALOGEX 0, 0, 320, 200
STYLE DS_SETFONT | DS_MODALFRAME | DS_FIXEDSYS | WS_POPUP | WS_VISIBLE | WS_CAPTION | WS_SYSMENU
EXSTYLE WS_EX_APPWINDOW
CAPTION "testDialog"
FONT 8, "MS Shell Dlg", 0, 0, 0x1
BEGIN
GROUPBOX "Static",IDC_CUSTOM_STATIC,57,7,48,40, SS_OWNERDRAW
ENDvoid CColorGroupBox::PreSubclassWindow()
{
// VERIFY( ModifyStyle(0, SS_OWNERDRAW) ); // this will fail if SS_OWNERDRAW is set in the resources;
__super::PreSubclassWindow();
}void CColorGroupBox::DrawItem(LPDRAWITEMSTRUCT lpDrawItemStruct )
{
CDC dc;
dc. Attach (lpDrawItemStruct->hDC);
CRect rect;
GetClientRect(rect);
rect.DeflateRect(10, 10, 10, 10);CBrush brush( RGB( 255, 0, 0)); dc.FrameRect( rect , &brush ); dc.Detach();
}
Am I missing something ? Thanks Richard, Max.
I'd rather be phishing!
-
Thanks, I tried that, but it does not work, the ModifyStyle "works" (does not fail), but the DrawItem is not called. SS_TYPEMASK is now obsolete, msdn says we should not use it. There are other controls that I can set as Owner draw in the resource editor (for example List box) and will ASSERT when run and the (related) DrawItem is not defined.
I'd rather be phishing!
I have used this method and it works (I have just looked it up in a project but that still uses VS 2003).
SS_TYPEMASK
is used in my example as what it is: A mask to ensure that other bits are cleared to avoid setting a wrong style. You may check the resulting style for a proper value (callGetStyle
after changing the style).