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

Debug ASSERT when CDialog::DoModal() from PreTranslateMessage()

915 views
Skip to first unread message

PeteOlcott

unread,
Feb 6, 2008, 1:01:42 PM2/6/08
to
I am creating and invoking a DialogBox within the
PreTranslateMessage() hander of another DialogBox. If I comment out
the DoModal() invocation, the exception is not thrown. If I leave it
in, the Debug Assertion Failed! message appears. The ASSERT statement
is located within MS Windows void CWnd::AssertValid(). What is going
on here? What can I do to make it work correctly?

David Ching

unread,
Feb 6, 2008, 1:04:21 PM2/6/08
to

"PeteOlcott" <PeteO...@gmail.com> wrote in message
news:144afc43-847a-434a...@v17g2000hsa.googlegroups.com...

Instead of invoking the dialog from PreTranslateMessage(), post a message to
yourself, and in the handler of that message, invoke the dialog. The
message is dispatched to your handler at a safe time to show the dialog.

-- David


PeteOlcott

unread,
Feb 6, 2008, 1:29:12 PM2/6/08
to
On Feb 6, 12:04 pm, "David Ching" <d...@remove-this.dcsoft.com> wrote:
> "PeteOlcott" <PeteOlc...@gmail.com> wrote in message

I tried that and it did not work, I still get the same Debug ASSERT.

David Ching

unread,
Feb 6, 2008, 1:39:10 PM2/6/08
to

"PeteOlcott" <PeteO...@gmail.com> wrote in message
news:1dfbd2a5-aa84-4379...@c23g2000hsa.googlegroups.com...

> I tried that and it did not work, I still get the same Debug ASSERT.

Show the code in PreTranslateMessage(). Under what conditions are you
showing the dialog?

-- David


Doug Harrison [MVP]

unread,
Feb 6, 2008, 1:38:48 PM2/6/08
to
On Wed, 6 Feb 2008 10:01:42 -0800 (PST), PeteOlcott <PeteO...@gmail.com>
wrote:

Doing complicated stuff like showing a secondary dialog inside
PreTranslateMessage is not the best practice in the world, but I see no
reason it shouldn't work. Your best course of action is probably to take a
cue from the function name and translate the message into a WM_COMMAND of
your choosing, which you post to yourself and receive in an ordinary
command handler function. This may well not solve your problem, and in case
it doesn't, and for future reference when dealing with assertions, here are
the questions that come to mind.

What *exactly* does the assertion say? (They're usually at least somewhat
descriptive and come with filename and line number info - for others to
make sense of the latter, you need to state your compiler version.)

When does the assertion occur, before, during, or after DoModal? If after,
are you returning true from PreTranslateMessage, or are you allowing the
dialog to continue processing the message?

When do you call DoModal, before or after the original dialog is displayed?
(More to the point, before or after OnInitDialog?)

What message are you handling in PreTranslateMessage?

Which CWnd is the assertion referring to? The "parent" dialog, or the newly
created one?

Can you invoke the secondary dialog successfully from an ordinary command
message handler, such as that for a button control? (If the answer is no,
you can be certain the PreTranslateMessage issue is a red herring.)

--
Doug Harrison
Visual C++ MVP

Tom Serface

unread,
Feb 6, 2008, 1:37:42 PM2/6/08
to
When you tried David's idea were you careful to use PostMessage() rather
than SendMessage(). Also, is the dialog you want to pop up in the current
resources for the context of the thread? For example, you are not calling
this from a callback on another thread or you did not reset the resource
handle to a different satellite library?

Tom

"PeteOlcott" <PeteO...@gmail.com> wrote in message

news:144afc43-847a-434a...@v17g2000hsa.googlegroups.com...

PeteOlcott

unread,
Feb 6, 2008, 2:53:36 PM2/6/08
to
On Feb 6, 12:38 pm, "Doug Harrison [MVP]" <d...@mvps.org> wrote:
> On Wed, 6 Feb 2008 10:01:42 -0800 (PST), PeteOlcott <PeteOlc...@gmail.com>

> wrote:
>
> >I am creating and invoking a DialogBox within the
> >PreTranslateMessage() hander of another DialogBox. If I comment out
> >the DoModal() invocation, the exception is not thrown. If I leave it
> >in, the Debug Assertion Failed! message appears. The ASSERT statement
> >is located within MS Windows void CWnd::AssertValid(). What is going
> >on here? What can I do to make it work correctly?
>
> Doing complicated stuff like showing a secondary dialog inside
> PreTranslateMessage is not the best practice in the world, but I see no
> reason it shouldn't work. Your best course of action is probably to take a
> cue from the function name and translate the message into a WM_COMMAND of
> your choosing, which you post to yourself and receive in an ordinary
> command handler function. This may well not solve your problem, and in case
> it doesn't, and for future reference when dealing with assertions, here are
> the questions that come to mind.
>
> What *exactly* does the assertion say? (They're usually at least somewhat
> descriptive and come with filename and line number info - for others to
> make sense of the latter, you need to state your compiler version.)

Debug Assertion Failed!
My Program's FullPathName
File: wincore.cpp
Line: 886

>
> When does the assertion occur, before, during, or after DoModal? If after,
> are you returning true from PreTranslateMessage, or are you allowing the
> dialog to continue processing the message?

The Debug Assertion occurs after the original PreTranslateMessage() is
called, it looks like it occurs within this function.


>
> When do you call DoModal, before or after the original dialog is displayed?
> (More to the point, before or after OnInitDialog?)

After InitDialog()

>
> What message are you handling in PreTranslateMessage?

#define SPECIAL_MESSAGE WM_USER + 1

>
> Which CWnd is the assertion referring to? The "parent" dialog, or the newly
> created one?

It looks like it is the parent DialogBox

>
> Can you invoke the secondary dialog successfully from an ordinary command
> message handler, such as that for a button control? (If the answer is no,
> you can be certain the PreTranslateMessage issue is a red herring.)

Yes this has been tested and it works fine. I Invoked another
DialogBox from a button on the original DialogBox.

PeteOlcott

unread,
Feb 6, 2008, 2:55:04 PM2/6/08
to
On Feb 6, 12:37 pm, "Tom Serface" <tom.nos...@camaswood.com> wrote:
> When you tried David's idea were you careful to use PostMessage() rather
> than SendMessage().  Also, is the dialog you want to pop up in the current

Yes.

> resources for the context of the thread?  For example, you are not calling
> this from a callback on another thread or you did not reset the resource
> handle to a different satellite library?

I don't know what this means. All the DialogBoxes were created using
the resource editor.

>
> Tom
>
> "PeteOlcott" <PeteOlc...@gmail.com> wrote in message


>
> news:144afc43-847a-434a...@v17g2000hsa.googlegroups.com...
>
>
>
> >I am creating and invoking a DialogBox within the
> > PreTranslateMessage() hander of another DialogBox. If I comment out
> > the DoModal() invocation, the exception is not thrown. If I leave it
> > in, the Debug Assertion Failed! message appears. The ASSERT statement
> > is located within MS Windows void CWnd::AssertValid(). What is going

> > on here? What can I do to make it work correctly?- Hide quoted text -
>
> - Show quoted text -

Mark Salsbery [MVP]

unread,
Feb 6, 2008, 3:08:14 PM2/6/08
to
"PeteOlcott" <PeteO...@gmail.com> wrote in message
news:33771165-f298-4c98...@d70g2000hsb.googlegroups.com...


You have the source code....what is causing the assertion at that line?

Mark

--
Mark Salsbery
Microsoft MVP - Visual C++

Tom Serface

unread,
Feb 6, 2008, 3:53:02 PM2/6/08
to
I've just had problems in the past when a library (DLL) has created it's own
threads and it calls back into a listener in my UI thread, but the resource
context is wrong. Thus, when it tries to pop up a dialog it has the right
ID, but the resource at that ID is what the DLL wanted, not what I wanted. I
know it's confusing, but worth asking since I don't know exactly what you
are doing.

I guess I was wondering, since it couldn't create a valid window, if the
dialog template was wrong somehow or the instance handle was off for the
application. Showing the code for the PretranslateMessage function might
help, but I'm thinking it's something more than that. If you are not using
any DLLs that have resources or any additional threads that may have ended
you up here then what I'm suggesting wouldn't make any sense.

Tom

"PeteOlcott" <PeteO...@gmail.com> wrote in message

news:c2d6fe6b-e494-4dc6...@i29g2000prf.googlegroups.com...

Doug Harrison [MVP]

unread,
Feb 6, 2008, 4:21:55 PM2/6/08
to
On Wed, 6 Feb 2008 11:53:36 -0800 (PST), PeteOlcott <PeteO...@gmail.com>
wrote:

>> What *exactly* does the assertion say? (They're usually at least somewhat


>> descriptive and come with filename and line number info - for others to
>> make sense of the latter, you need to state your compiler version.)
>
>Debug Assertion Failed!
>My Program's FullPathName
>File: wincore.cpp
>Line: 886

Surely there's more to it than that? I only have VC9 installed right now,
and my line 886 is:

ASSERT(HWND_TOP == NULL); // same as desktop

I seriously doubt you're asserting on that, but the text of any assertion
is reported in the assertion dialog box.

>The Debug Assertion occurs after the original PreTranslateMessage() is
>called, it looks like it occurs within this function.

You should be able to determine the exact context by examining the call
stack in the debugger. That will give you a lot more information than you
currently have. You can visit all the stack frames, examine variables, look
at the code that got you there, and so forth.

>> What message are you handling in PreTranslateMessage?
>
>#define SPECIAL_MESSAGE WM_USER + 1

You shouldn't be using the WM_USER range unless you registered the window
class. Instead, use WM_APP, and either use a const int for C++ or to be
compatible with C, at least use parens around macros:

// C++
const int SPECIAL_MESSAGE = WM_APP+1;

// C
#define SPECIAL_MESSAGE (WM_APP+1)

For more on message ranges, see:

Which message numbers belong to whom?
http://blogs.msdn.com/oldnewthing/archive/2003/12/02/55914.aspx

>> Which CWnd is the assertion referring to? The "parent" dialog, or the newly
>> created one?
>
>It looks like it is the parent DialogBox

It would be very helpful to know what "line 886" corresponds to!

>> Can you invoke the secondary dialog successfully from an ordinary command
>> message handler, such as that for a button control? (If the answer is no,
>> you can be certain the PreTranslateMessage issue is a red herring.)
>
>Yes this has been tested and it works fine. I Invoked another
>DialogBox from a button on the original DialogBox.

By "another", I suppose you mean the one that's giving you trouble. If I
were to make a wild guess, I'd wonder if you were calling
PreTranslateMessage directly from another thread. That could cause an
assertion when AssertValid checks the handle map. Again, it would be
very helpful to know what your "line 886" is!

Peter Olcott

unread,
Feb 6, 2008, 10:26:24 PM2/6/08
to

"David Ching" <d...@remove-this.dcsoft.com> wrote in message
news:l9nqj.12806$EZ3....@nlpi070.nbdc.sbc.com...

Here is a simplified example of the original code. I created
a simply Dialog Application using the default setting and
generated code.

BOOL CTestInsertKeyDlg::PreTranslateMessage(MSG* pMsg)
{
if(pMsg->message==WM_KEYDOWN) {
if ( pMsg->wParam == VK_INSERT )
{
CAboutDlg AboutDlg;
AboutDlg.DoModal();
}
if ( pMsg->wParam == VK_DELETE )
AfxMessageBox("VK_DELETE");
if ( pMsg->wParam== VK_RETURN )
AfxMessageBox("VK_RETURN");
}
return CDialog::PreTranslateMessage(pMsg);
}

Peter Olcott

unread,
Feb 6, 2008, 11:23:15 PM2/6/08
to

"David Ching" <d...@remove-this.dcsoft.com> wrote in message
news:HEmqj.3916$uE....@newssvr22.news.prodigy.net...

I build a test program that involved all of the default
generated code from a simple DialogBox program, and your
suggestion worked in this very simple case. This proves that
your idea solves my problem. Now all I have to do is to
adapt the simple program's solution to the complex real
system.


Joseph M. Newcomer

unread,
Feb 9, 2008, 2:17:46 PM2/9/08
to
It is not surprising that you would find an ASSERT in AssertValid. The problem is that
this is not terribly informative. When you get this kind of assertion, you have to ask
"Who called AssertValid?" and work backward in the stack seeing who calls what and what is
being checked for validity! Otherwise, you have said nothing more than "my program
doesn't work, what's wrong?"

PreTranslateMessage is a dangerous place to try to do something like pop up another
dialog, and I wouldn't be at all surprised that something fails.

You need to provide a whole lot more information to get an answer to this kind of
question.
joe

Joseph M. Newcomer [MVP]
email: newc...@flounder.com
Web: http://www.flounder.com
MVP Tips: http://www.flounder.com/mvp_tips.htm

Joseph M. Newcomer

unread,
Feb 9, 2008, 2:20:48 PM2/9/08
to
WM_USER messages are inappropriate. In fact, WM_USER+1 is actually DM_SETDEFID, so it
would be erroneous for you to send this for any purpose other than setting the ID of the
default button.

Use WM_APP messages, or Registered Window Messages, when you are doing this kind of thing.

Note also that it is Best Practice when you define a constant which is an expression to
define it as

#define UWM_WHATEVER (WM_APP + 3)

that is, parenthesize the expression. This should be a reflexive habit.
joe

Tom Serface

unread,
Feb 9, 2008, 7:21:55 PM2/9/08
to
Putting constant expressions in parentheses is a good idea and I'm surprised
how many people don't think of it. Most often they are ignored, but when it
comes to needing them for precedence I am always glad to have this habit.

Tom

"Joseph M. Newcomer" <newc...@flounder.com> wrote in message
news:24vrq39u9bmlf09qh...@4ax.com...

Joseph M. Newcomer

unread,
Feb 10, 2008, 12:34:15 AM2/10/08
to
We discovered this little feature in 1969 when someone in our compiler group wrote the
equivalent of

#define product(a, b) a*b

and then called with with the equivalent of

product(x + y, w + z) * 2

and of course got the computation

x + y * w + z * 2

The language wasn't C, the macro syntax wasn't #define, but the effect was the same. So
I've had the habit for nearly 40 years, and it is something I teach in one of the slides
of my course.

[For those of you who don't know the trick, the MINIMUM correct representation of the
macro is

#define product(a, b) ( (a) * (b) )

]
joe

0 new messages