Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

CWnd::ModifyStyle

562 views
Skip to first unread message

Oliver Regenfelder

unread,
Nov 9, 2010, 4:43:28 PM11/9/10
to
Hello,

I am having some puzzling moments with CWnd::ModifyStyle.

First some prerequisites:

CMyWindow is derived from CWnd. It does painting representing
some data in its OnPaint handler. It also needs a vertical
scrollbar as the drawing is rather long.

What I do is

> m_cProtocolDebugDisplay.Create(NULL, _T(""), WS_VISIBLE | WS_VSCROLL,
> debug_display_rectangle, this, 1);

to create the window in the OnInit handler of the dialog it is placed
in.
Style question: Should I enforce the scrollbar in the CMyWindow::Create
method or should the caller deside whether he wants the scrollbar or
not?

But now to the main question:

I wanted a border around the CMyWindow so I did the following

> m_cProtocolDebugDisplay.Create(NULL, _T(""), WS_VISIBLE | WS_VSCROLL
> | WS_BORDER, debug_display_rectangle, this, 1);

everything works. I have the border, I have the vertical scroll bar and
all my custom painting is only done in the client area.

But, on my first try I used CWnd::ModifyStyle and failed horribly:

> m_cProtocolDebugDisplay.Create(.... WS_VISIBLE | WS_VSCROLL, ...);
> m_cProtocolDebugDisplay.ModifyStyle(0, WS_BORDER);

What happens is that a border is drawn, but the scrollbar doesn't
respect the border and any painting in OnPaint just overwrites the
border. So it seems that the border is attached but the client area
doesn't get updated :-(.

I know that the first version works, but I would be glad for anyone
who can point out why the second version doesn't.

Even worse happens with
> m_cProtocolDebugDisplay.Create(.... WS_VISIBLE, ...);
> m_cProtocolDebugDisplay.ModifyStyle(0, WS_BORDER | WS_VSCROLL);

The vertical scroll bar is never drawn.

A Invalidate doesn't help.

Best regards,

Oliver

David Lowndes

unread,
Nov 9, 2010, 5:54:30 PM11/9/10
to
>But, on my first try I used CWnd::ModifyStyle and failed horribly:
>
> > m_cProtocolDebugDisplay.Create(.... WS_VISIBLE | WS_VSCROLL, ...);
> > m_cProtocolDebugDisplay.ModifyStyle(0, WS_BORDER);
>
>What happens is that a border is drawn, but the scrollbar doesn't
>respect the border and any painting in OnPaint just overwrites the
>border. So it seems that the border is attached but the client area
>doesn't get updated :-(.

Oliver,

Sometimes controls only take the style into account when the control
is created. The "Window Styles" topic on MSDN notes:

"The following styles can be specified wherever a window style is
required. After the control has been created, these styles cannot be
modified, except as noted.
"

In your initial case, you may have needed to specify some addition
flag such as SWP_DRAWFRAME) in the ModifyStyle call.

As far as I'm aware there's no definitive documentation on what works
and what doesn't. As you've found, it's often best to specify the
style on creation.

Dave

Oliver Regenfelder

unread,
Nov 10, 2010, 6:20:32 AM11/10/10
to
Hello,

On 09.11.2010 23:54, David Lowndes wrote:
>> But, on my first try I used CWnd::ModifyStyle and failed horribly:
>>
>>> m_cProtocolDebugDisplay.Create(.... WS_VISIBLE | WS_VSCROLL, ...);
>>> m_cProtocolDebugDisplay.ModifyStyle(0, WS_BORDER);
>>
>> What happens is that a border is drawn, but the scrollbar doesn't
>> respect the border
>

> Sometimes controls only take the style into account when the control
> is created. The "Window Styles" topic on MSDN notes:
>

> In your initial case, you may have needed to specify some addition
> flag such as SWP_DRAWFRAME) in the ModifyStyle call.

Thanks, using SWP_DRAWFRAME or SWP_FRAMECHANGED solved the problem.

m_cProtocolDebugDisplay.ModifyStyle(0, WS_BORDER, SWP_DRAWFRAME);

It also correctly updates the client area size of the window.

Best regards,

Oliver

Joseph M. Newcomer

unread,
Nov 12, 2010, 8:12:30 PM11/12/10
to
See below...

On Tue, 09 Nov 2010 22:43:28 +0100, Oliver Regenfelder <oliver.re...@gmx.at> wrote:

>Hello,
>
>I am having some puzzling moments with CWnd::ModifyStyle.
>
>First some prerequisites:
>
>CMyWindow is derived from CWnd. It does painting representing
>some data in its OnPaint handler. It also needs a vertical
>scrollbar as the drawing is rather long.
>
>What I do is
>
> > m_cProtocolDebugDisplay.Create(NULL, _T(""), WS_VISIBLE | WS_VSCROLL,
> > debug_display_rectangle, this, 1);
>
>to create the window in the OnInit handler of the dialog it is placed
>in.

****
There is something deeply wrong here. Why are you doing a Create? Where did the magical
rectangle debug_display_rectangle get set, and what did it get set to? And why did "1"
materialize as if it were a meaningful value? Have you never heard of #define?
****


>Style question: Should I enforce the scrollbar in the CMyWindow::Create
>method or should the caller deside whether he wants the scrollbar or
>not?

****
It depends.

Do you WANT the user to specify if the scrollbar is there? What if it isn't and the
window has more lines than can be shown? If the user is going to specify it, what is the
mechanism you are going to provide the user to do this specification? Don't ask us, ask
your users!
****


>
>But now to the main question:
>
>I wanted a border around the CMyWindow so I did the following
>
> > m_cProtocolDebugDisplay.Create(NULL, _T(""), WS_VISIBLE | WS_VSCROLL
> > | WS_BORDER, debug_display_rectangle, this, 1);
>
>everything works. I have the border, I have the vertical scroll bar and
>all my custom painting is only done in the client area.
>
>But, on my first try I used CWnd::ModifyStyle and failed horribly:
>
> > m_cProtocolDebugDisplay.Create(.... WS_VISIBLE | WS_VSCROLL, ...);
> > m_cProtocolDebugDisplay.ModifyStyle(0, WS_BORDER);

****
First, many styles apply ONLY at creation time and CANNOT be changed once the window is
created. It is entirely possible the WS_BORDER is one of these.

Some styles require that you use SetWindowPos to force a redrawing.
****


>
>What happens is that a border is drawn, but the scrollbar doesn't
>respect the border and any painting in OnPaint just overwrites the
>border. So it seems that the border is attached but the client area
>doesn't get updated :-(.

****
Sounds unsurprising. See the above note. If you change the style after the wndow is
created, there is no guarantee that it will work. Perhaps if you do
wnd.SetWIndowPos(NULL, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE | SWP_NOZORDER
| SWP_FRAMECHANGED);
this *might* recompute the client area, and it would be the first thing I would try.

But if that doesn't work, then you will have to supply the border state with the Create
and not in a ModifyStyle.
****


>
>I know that the first version works, but I would be glad for anyone
>who can point out why the second version doesn't.
>
>Even worse happens with
> > m_cProtocolDebugDisplay.Create(.... WS_VISIBLE, ...);
> > m_cProtocolDebugDisplay.ModifyStyle(0, WS_BORDER | WS_VSCROLL);
>
>The vertical scroll bar is never drawn.

****
What are the parameters of the scrollbar? In general, if the scrollbar has 0 size, it
will not be drawn. Where do you set the scrollbar size? Note that if you have a nonempty
scrollbar, then GetClientRect will give one set of values, and if you change the
parameters so the scrollbar is empty, and it disappears, GetClientRect will give you a
different set of values.
****


>
>A Invalidate doesn't help.

****
It wouldn't. Invalidate() only invalidates the client area, and the border and scrollbar
are in the non-client area. SetWindowPos with SWP_DRAWFRAME will redraw the frame.
****
>
>Best regards,
>
>Oliver
Joseph M. Newcomer [MVP]
email: newc...@flounder.com
Web: http://www.flounder.com
MVP Tips: http://www.flounder.com/mvp_tips.htm

0 new messages