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

AFXMessageBox() doesn't appear (but is active)

410 views
Skip to first unread message

Corey Cooper

unread,
Feb 12, 2000, 3:00:00 AM2/12/00
to
I have a CDialog based app, but when I call either CWnd.MessageBox()
or AfxMessageBox() after the main app window has been created, they
aren't drawn, but they are (invisibly) active! In otherwords, I press a
button that for testing I just wanted to pop up with a message box. I
hit the button, focus is lost by my app, I hear the MessageBox sound,
and anywhere I press on the screen I get a chime, except there is no
messagebox to be seen. If I hit 'Enter', focus is returned to my app.

The AfxMessagBox function works fine in the OnInitDialog() function,
but by the time I get to the OnEraseBkgnd() function (I am using a
bitmap for the background of the Dialog) the MessagBox is invisible. I
tried eliminating the OnEraseBkgnd() handler, that didn't fix anything.

Any ideas?

Corey Cooper.


Corey Cooper

unread,
Feb 13, 2000, 3:00:00 AM2/13/00
to
As an addendum:
It turns out I can't make any dialog apear. I created a dialog
resource and call it with DoModal(), it is also invisible (but active), no
matter where I try and put it in the Z-Order with either SetWindowPos() or
BringWindowToTop().
C.

Johan Rosengren

unread,
Feb 13, 2000, 3:00:00 AM2/13/00
to
Perhaps the message box is behind your app dialog window? Do you set the
m_pMainWnd CWinApp member in your InitInstance?

Johan Rosengren
Responsable Informatique
PACTA S.A.

Corey Cooper <Co...@C-Cooper.com> a écrit dans le message :
38A62D3E...@C-Cooper.com...

Corey Cooper

unread,
Feb 13, 2000, 3:00:00 AM2/13/00
to
I initially created the app with MFC App Wizard, so m_pMainWnd is set in
"Engine.cpp", the app main dialog, and my InitInstance override, is in
"EngineDlg.cpp".

The dialog box might be behind, but I can't resize or move since this is a
borderless app with no resize or move capabilities.

As another experiment, I added
SetWindowPos(&wndBottom,0,0,0,0,SWP_NOMOVE | SWP_NOSIZE); before my DoModal()
call. The only effect seems to be my main window erases, is re-drawn, and
then the 'invisible' modal dialog is activated just like before.
So I tried:
SetWindowPos() with SWP_HIDEWINDOW as one parameter. before my DoModal() call,
followed by a matching SWP_SHOWWINDOW after. Now I can see my dialog box, but
it is a very ugly transition. This seems like a workaround at best, I can't
dump my main app window every time I want to show a simple "OK" Dialog Box.

C.

David Wilkinson

unread,
Feb 13, 2000, 3:00:00 AM2/13/00
to
Corey:

You must be doing something strange. Try creating a brand new dialog-based
application, add a handler for the OK button, and put an AfxMessageBox() call
there. Surely the message box will be shown on top of your dialog, no?
Similarly if you create another modal dialog, surely.

If so, try to figure our what is different in your application.

HTH,

David Wilkinson

======================

Corey Cooper wrote:

> As an addendum:
> It turns out I can't make any dialog apear. I created a dialog
> resource and call it with DoModal(), it is also invisible (but active), no
> matter where I try and put it in the Z-Order with either SetWindowPos() or
> BringWindowToTop().
> C.
>
> Corey Cooper wrote:
>

Corey Cooper

unread,
Feb 13, 2000, 3:00:00 AM2/13/00
to
First a note on Debugging:
To solve this problem, I created a new app with minimal changes from the
standard MFC AppWizard Dialog Based Program, just a single button that
brought up a MessageBox. After proving it worked, I piecemeal added code
from the 'broken' app to the working app, until the working app 'broke'. A
little more work and I identified the problem. This is the standard method
of fixing electronics as well (I hope no one fainted because I mentioned
Hardware!).

The solution!

For various reasons, I need invisible buttons in my app. The way that I
have now found to do this is to sub-class CButton, override the DrawItem
Virtual function, and set the 'Owner Draw' property. Since I am using a
bitmap as the background to my dialog box, I also had to catch the
WM_ERASEBKGND message with OnEraseBkgnd(). For my purpose both of these
functions are empty, (except for return TRUE; in OnEraseBkgnd). In
experimenting with this however, I also caught the WM_PAINT message, which
didn't seem to hurt, and for all I knew helped. The only thing I knew about
this function in this case was the rather cryptic comment Class Wizard
inserted into the function when it created it:
// Do not call CButton::OnPaint() for painting messages
I happily left the function empty like the other two.

Oddly enough, having any button in my app, with an empty OnPaint()
function, prevents all child windows from displaying, but not from
operating!

I would be interested if anyone could explain why, in the meantime, I
hope this might help someone else in the future.

Corey Cooper

sirwi...@my-deja.com

unread,
Feb 14, 2000, 3:00:00 AM2/14/00
to
In article <38A755A3...@C-Cooper.com>,

Co...@C-Cooper.com wrote:
> For various reasons, I need invisible buttons in my app. The way
that I
> have now found to do this is to sub-class CButton, override the
DrawItem
> Virtual function, and set the 'Owner Draw' property.

Very ugly "kludge" for doing something built in. Check out
CWnd::ShowWindow.

> Since I am using a
> bitmap as the background to my dialog box, I also had to catch the
> WM_ERASEBKGND message with OnEraseBkgnd(). For my purpose both of
these
> functions are empty, (except for return TRUE; in OnEraseBkgnd). In
> experimenting with this however, I also caught the WM_PAINT message,
which
> didn't seem to hurt, and for all I knew helped. The only thing I
knew about
> this function in this case was the rather cryptic comment Class Wizard
> inserted into the function when it created it:
> // Do not call CButton::OnPaint() for painting messages
> I happily left the function empty like the other two.

The comment is a little cryptic, but it makes complete sense. When you
handle WM_PAINT, the wizard assumes you're actually going to add
painting code into your handler. In this case your code will call
BeginPaint and EndPaint, usually implicitly done by the CPaintDC
instance created by the wizard. If you were to call the base class's
OnPaint, you'd call BeginPaint twice, which is not allowed. (If you
read that carefully you might realize that there may be valid reasons
to override OnPaint but to still call the base classes which is fine so
long as your handler does NOT do any actual painting.)

What you've done here is the opposite problem. Since you handled
OnPaint and did NOTHING, BeginPaint/EndPaint never get called, leaving
the OS confused about the state of your controls display. For what
ever reason, this is causing the display of other windows to fail as
well. You should be able to simply provided a CPaintDC in the handler
(which will call BeginPaint/EndPaint) and do no actual painting with
it. However, don't forget that this approach is a kludge for
functionality provided for you by CWnd::ShowWindow.

--
William E. Kempf
Software Engineer, MS Windows Programmer


Sent via Deja.com http://www.deja.com/
Before you buy.

Joseph M. Newcomer

unread,
Feb 14, 2000, 3:00:00 AM2/14/00
to
I think the problem is that you can't have an empty OnPaint handler;
you have to at least do a CPaintDC dc(this) declaration to force the
WM_PAINT to be disabled; otherwise what happens is you get an infinite
loop of WM_PAINTs going to your OnPaint handler, which never tells the
system that the area has been validated. By calling the default
OnPaint handler, it creates a Paint DC, which gets you out of the
problem. It will then probably do the wrong thing to your owner-draw
button if you had actually done any drawing.
joe

On Sun, 13 Feb 2000 17:08:51 -0800, Corey Cooper <Co...@C-Cooper.com>
wrote:

> First a note on Debugging:
> To solve this problem, I created a new app with minimal changes from the
>standard MFC AppWizard Dialog Based Program, just a single button that
>brought up a MessageBox. After proving it worked, I piecemeal added code
>from the 'broken' app to the working app, until the working app 'broke'. A
>little more work and I identified the problem. This is the standard method
>of fixing electronics as well (I hope no one fainted because I mentioned
>Hardware!).
>
>The solution!
>

> For various reasons, I need invisible buttons in my app. The way that I
>have now found to do this is to sub-class CButton, override the DrawItem

>Virtual function, and set the 'Owner Draw' property. Since I am using a


>bitmap as the background to my dialog box, I also had to catch the
>WM_ERASEBKGND message with OnEraseBkgnd(). For my purpose both of these
>functions are empty, (except for return TRUE; in OnEraseBkgnd). In
>experimenting with this however, I also caught the WM_PAINT message, which
>didn't seem to hurt, and for all I knew helped. The only thing I knew about
>this function in this case was the rather cryptic comment Class Wizard
>inserted into the function when it created it:
> // Do not call CButton::OnPaint() for painting messages
>I happily left the function empty like the other two.
>

> Oddly enough, having any button in my app, with an empty OnPaint()
>function, prevents all child windows from displaying, but not from
>operating!
>
> I would be interested if anyone could explain why, in the meantime, I
>hope this might help someone else in the future.
>
> Corey Cooper
>
>Corey Cooper wrote:
>
>> I have a CDialog based app, but when I call either CWnd.MessageBox()
>> or AfxMessageBox() after the main app window has been created, they
>> aren't drawn, but they are (invisibly) active! In otherwords, I press a
>> button that for testing I just wanted to pop up with a message box. I
>> hit the button, focus is lost by my app, I hear the MessageBox sound,
>> and anywhere I press on the screen I get a chime, except there is no
>> messagebox to be seen. If I hit 'Enter', focus is returned to my app.
>>
>> The AfxMessagBox function works fine in the OnInitDialog() function,
>> but by the time I get to the OnEraseBkgnd() function (I am using a
>> bitmap for the background of the Dialog) the MessagBox is invisible. I
>> tried eliminating the OnEraseBkgnd() handler, that didn't fix anything.
>>
>> Any ideas?
>>
>> Corey Cooper.

Joseph M. Newcomer [MVP]
email: newc...@flounder.com
Web: http://www3.pgh.net/~newcomer
MVP Tips: http://www3.pgh.net/~newcomer/mvp_tips.htm

Corey Cooper

unread,
Feb 14, 2000, 3:00:00 AM2/14/00
to
>Very ugly "kludge" for doing something built in. Check out
>CWnd::ShowWindow.
No, ShowWindow will disable the button, I want an active button, but one
that is invisible. There are other ways to do this, but I am using the
Leadtools Library to provide some extendd graphics capability. I have a
Lead function doing a couple of 'effects' to bring on a few fancy graphic
window backgrounds all in one shot. Built in to the graphics are several
buttons, which, for esthetic reasons, I didn't want to pop on after the cool
background came up.
The other way to do this that I might try later is to just bring a
graphic button that matches the background in on top of the graphic
background. But the graphics are created dynamically, so I thought this was
an easier way to go (although Lead also provides some extended capability
graphic buttons as well.)

What I didn't realize was that CPaintDC called BeginPaint and EndPaint,
which does make sense. I knew I had to call BeginPaint and EndPaint in a
non-MFC app, I just didn't carry that knowlege to it's logical conclusion.

C.

sirwi...@my-deja.com wrote:

> In article <38A755A3...@C-Cooper.com>,
> Co...@C-Cooper.com wrote:

> > For various reasons, I need invisible buttons in my app. The way
> that I
> > have now found to do this is to sub-class CButton, override the
> DrawItem
> > Virtual function, and set the 'Owner Draw' property.
>

> Very ugly "kludge" for doing something built in. Check out
> CWnd::ShowWindow.
>

> > Since I am using a
> > bitmap as the background to my dialog box, I also had to catch the
> > WM_ERASEBKGND message with OnEraseBkgnd(). For my purpose both of
> these
> > functions are empty, (except for return TRUE; in OnEraseBkgnd). In
> > experimenting with this however, I also caught the WM_PAINT message,
> which
> > didn't seem to hurt, and for all I knew helped. The only thing I
> knew about
> > this function in this case was the rather cryptic comment Class Wizard
> > inserted into the function when it created it:
> > // Do not call CButton::OnPaint() for painting messages
> > I happily left the function empty like the other two.
>

sirwi...@my-deja.com

unread,
Feb 15, 2000, 3:00:00 AM2/15/00
to
In article <38A8CF62...@C-Cooper.com>,

Co...@C-Cooper.com wrote:
> >Very ugly "kludge" for doing something built in. Check out
> >CWnd::ShowWindow.
> No, ShowWindow will disable the button

No, ShowWindow hides/shows a window. EnableWindow will enable/disable
the window.

>, I want an active button, but one
> that is invisible.

Do you mean you want an invisible button, but one that can still be
clicked on? Why on God's green earth would you want something like
this? It makes no sense. How will a user know to click on it if they
can't see it?

> There are other ways to do this, but I am using the
> Leadtools Library to provide some extendd graphics capability. I
have a
> Lead function doing a couple of 'effects' to bring on a few fancy
graphic
> window backgrounds all in one shot. Built in to the graphics are
several
> buttons, which, for esthetic reasons, I didn't want to pop on after
the cool
> background came up.

This makes no sense to me.

> The other way to do this that I might try later is to just bring a
> graphic button that matches the background in on top of the graphic
> background. But the graphics are created dynamically, so I thought
this was
> an easier way to go (although Lead also provides some extended
capability
> graphic buttons as well.)

It *sounds* like what you're really after is a "clickable image", where
when the user clicks on the image something happens according to the
area of the image they clicked on. There are MUCH better ways to do
this then using a transparent button (the proper term for what you've
done).

Corey Cooper

unread,
Feb 17, 2000, 3:00:00 AM2/17/00
to
Do you enjoy being unpleasant? You read one sentance, respond to it,
with things like "makes no sense", then the next sentance explans what you
didn't understand, but you push right on like a bull in a china shop, again
being insulting.
As I said myself, there are other ways to do what I was describing, but
all of the way's I know of leave something to be desired. This way I have
24 simple 'transparent' buttons, all of identical size, that when pressed,
draw a box around the item pressed and play a sound as further feedback.
In the future "sir", read an entire message, then comment. And if you
have a "MUCH" better way to do something, why don't you explain your idea,
instead of just being insulting. After all this is a forum for exchanging
information, not berating others.

c.

0 new messages