Discussion:
PostThreadMessage to a thread that has a modal dialog shown
(too old to reply)
ultranet
2006-06-08 23:47:01 UTC
Permalink
PostThreadMessage(threadID, ...) returns 1 when modal dialog is shown, but
message appears to be lost, because after i close the modal window, i don't
get the message.

I will code to close modal windows before posting the message, but i find
this very strange. Any feedback is welcome.
William DePalo [MVP VC++]
2006-06-09 00:10:32 UTC
Permalink
Post by ultranet
PostThreadMessage(threadID, ...) returns 1 when modal dialog is shown, but
message appears to be lost, because after i close the modal window, i don't
get the message.
I will code to close modal windows before posting the message, but i find
this very strange. Any feedback is welcome.
It is not lost. It is simply ignored. :-)

Seriously, at the heart of a modal loop is code something like this:

while ( GetMessage(...) )
{
TranslateMessage(...);
DispatchMessage();
}

Thread messages have their hwnd member set to 0; So, your thread message is
gotten, but DispatchMessage(0 has nowhere to send it. To you it looks lost.

For that reason, some programmers maintain the handle to the "main" window
as a global variable. Rather than PostThreadMessage(), they post to the main
window.

A better solution, IMO, is to do this: Put up a thread-specific (not
global!) hook before you show the dialog. Have the hook insert a valid
window handle into the message structure where it is missing. Take down the
hook when the dialog is destroyed.

Regards,
Will
--
Regards,
Will

"I'm not ready to make nice, I'm not ready to back down ..."
ultranet
2006-06-09 00:35:01 UTC
Permalink
Post by William DePalo [MVP VC++]
It is not lost. It is simply ignored. :-)
I wish it was so, but it's a non-window message, for which i don't even try
to call translate-dispatch. I know that it gets lost because the caller waits
for notification of processing, which never happens.
Caller snippet:

CEvent event;
InvokeParams *params = new InvokeParams(event, task);

BOOL result = ::PostThreadMessage(threadID, WM_NATIVE_EVENT_LOOP,
InvokeParams::INVOKE_AND_WAIT, (long)params);
::WaitForSingleObject(event, INFINITE);
// i can't reach this point, but only when a modal window is shown on
threadID thread.
I recall seeing modal windows causing original event loop to be deactivated,
and starting their own event loop. But i don't recall if that new event loop
was running on the same thread or not. From this experience i tend to think
not. Does that mean there is no way for me to queue task above while modal
window is showing? WM_NATIVE_EVENT_LOOP is a user message, registered w/
RegisterWindowMessage.
Igor Tandetnik
2006-06-09 00:45:13 UTC
Permalink
Post by ultranet
Post by William DePalo [MVP VC++]
It is not lost. It is simply ignored. :-)
I wish it was so, but it's a non-window message, for which i don't
even try to call translate-dispatch.
You don't. Modal dialog's message pump does. Understand that when you
put up a modal dialog, it spins its own message pump independent on the
one you wrote. And it does call DispatchMessage on every message in the
queue, even the one posted by PostThreadMessage. The latter cannot be
dispatched, so it's dropped on the floor.
Post by ultranet
I recall seeing modal windows causing original event loop to be
deactivated, and starting their own event loop. But i don't recall if
that new event loop was running on the same thread or not.
It runs on the same thread that created the modal dialog in the first
place.
Post by ultranet
From this
experience i tend to think not. Does that mean there is no way for me
to queue task above while modal window is showing?
Post the message to a specific window with PostMessage, rather than
PostThreadMessage.
--
With best wishes,
Igor Tandetnik

With sufficient thrust, pigs fly just fine. However, this is not
necessarily a good idea. It is hard to be sure where they are going to
land, and it could be dangerous sitting under them as they fly
overhead. -- RFC 1925
ultranet
2006-06-09 00:47:01 UTC
Permalink
Post by ultranet
I recall seeing modal windows causing original event loop to be deactivated,
and starting their own event loop. But i don't recall if that new event loop
was running on the same thread or not. From this experience i tend to think
not. Does that mean there is no way for me to queue task above while modal
window is showing? WM_NATIVE_EVENT_LOOP is a user message, registered w/
RegisterWindowMessage.
I'd settle for the message to be at least processed after the modal window
is closed.
Even if the modal event loop runs on the same thread, i think it has it's
own handler, and effectively overwrites the original event loop. Which would
explain why i don't see the message ever.
Closing the modal windows before sending the message should work for me, but
i'm just trying to understand what's going on.
Alex Blekhman
2006-06-09 09:48:54 UTC
Permalink
Post by ultranet
Post by ultranet
I recall seeing modal windows causing original event
loop to be deactivated, and starting their own event
loop. But i don't recall if that new event loop was
running on the same thread or not. From this experience
i tend to think not. Does that mean there is no way for
me to queue task above while modal window is showing?
WM_NATIVE_EVENT_LOOP is a user message, registered w/
RegisterWindowMessage.
I'd settle for the message to be at least processed after
the modal window is closed.
Even if the modal event loop runs on the same thread, i
think it has it's own handler, and effectively overwrites
the original event loop. Which would explain why i don't
see the message ever.
Closing the modal windows before sending the message
should work for me, but i'm just trying to understand
what's going on.
Closing the modal window will help you in short term while
ignoring the problem in long term. Igor and William already
explained to you that posting messages to threads in GUI
application is bad thing to do since message doesn't have
destination window, so it occasionally dropped by
DispatchMessage or whatever.

Common approach to establish messaging communication between
threads in GUI application is to post/send messages to
windows. It can be the same window, which user sees or it
can be messaging window created for sole purpose of
receiveing messages. See about message only windows here:

"Window Features"
http://msdn.microsoft.com/library/en-us/winui/winui/windowsuserinterface/windowing/windows/windowfeatures.asp

Look in "Message-Only Windows" section.
ultranet
2006-06-09 16:58:02 UTC
Permalink
Post by Alex Blekhman
Closing the modal window will help you in short term while
ignoring the problem in long term. Igor and William already
explained to you that posting messages to threads in GUI
application is bad thing to do since message doesn't have
destination window, so it occasionally dropped by
DispatchMessage or whatever.
Common approach to establish messaging communication between
threads in GUI application is to post/send messages to
windows. It can be the same window, which user sees or it
can be messaging window created for sole purpose of
"Window Features"
http://msdn.microsoft.com/library/en-us/winui/winui/windowsuserinterface/windowing/windows/windowfeatures.asp
Look in "Message-Only Windows" section.
That clears it up, but i'm struggling to find where HWND_MESSAGE is defined.
ultranet
2006-06-09 17:03:01 UTC
Permalink
Post by ultranet
That clears it up, but i'm struggling to find where HWND_MESSAGE is defined.
winuser.h, but need to modify WINVER to x0500.
ultranet
2006-06-09 17:10:02 UTC
Permalink
Post by ultranet
Post by ultranet
That clears it up, but i'm struggling to find where HWND_MESSAGE is defined.
winuser.h, but need to modify WINVER to x0500.
How big of a deal is it to ignore this note?

NOTE: WINVER has been defined as 0x0500 or greater which enables
Windows NT 5.0 and Windows 98 features. When these headers were released,
Windows NT 5.0 beta 1 and Windows 98 beta 2.1 were the current versions.
For this release when WINVER is defined as 0x0500 or greater, you can only
build beta or test applications. To build a retail application,
set WINVER to 0x0400 or visit http://www.microsoft.com/msdn/sdk
to see if retail Windows NT 5.0 or Windows 98 headers are available.
See the SDK release notes for more information.
David Wilkinson
2006-06-09 17:17:59 UTC
Permalink
Post by ultranet
Post by ultranet
Post by ultranet
That clears it up, but i'm struggling to find where HWND_MESSAGE is defined.
winuser.h, but need to modify WINVER to x0500.
How big of a deal is it to ignore this note?
NOTE: WINVER has been defined as 0x0500 or greater which enables
Windows NT 5.0 and Windows 98 features. When these headers were released,
Windows NT 5.0 beta 1 and Windows 98 beta 2.1 were the current versions.
For this release when WINVER is defined as 0x0500 or greater, you can only
build beta or test applications. To build a retail application,
set WINVER to 0x0400 or visit http://www.microsoft.com/msdn/sdk
to see if retail Windows NT 5.0 or Windows 98 headers are available.
See the SDK release notes for more information.
ultranet:

Where is this note? Surely is is obsolete. What vesrion of the PSDK are
you using?

David Wilkinson
ultranet
2006-06-09 18:24:02 UTC
Permalink
Post by David Wilkinson
Where is this note? Surely is is obsolete. What vesrion of the PSDK are
you using?
It's VC6, and i think x400 is the default here.
David Wilkinson
2006-06-09 22:18:35 UTC
Permalink
Post by ultranet
Post by David Wilkinson
Where is this note? Surely is is obsolete. What vesrion of the PSDK are
you using?
It's VC6, and i think x400 is the default here.
ultranet:

I'm still not sure exactly where this message is.

But anyway, I would certainly recommend that you install the latest
version of the PSDK compatible with VC6 (Feb 2003).

David Wilkinson

=================
Alex Blekhman
2006-06-09 22:37:23 UTC
Permalink
Post by David Wilkinson
Post by ultranet
Post by David Wilkinson
Where is this note? Surely is is obsolete. What vesrion
of the PSDK are you using?
It's VC6, and i think x400 is the default here.
I'm still not sure exactly where this message is.
This message is from PSDK that originally distributed with
VC6 ("#pragma message" in some of its headers). When VC6 was
released all platforms with WINVER 0x0500 or greater were in
beta state.
ultranet
2006-06-09 23:19:01 UTC
Permalink
Post by Alex Blekhman
Post by David Wilkinson
I'm still not sure exactly where this message is.
This message is from PSDK that originally distributed with
VC6 ("#pragma message" in some of its headers). When VC6 was
released all platforms with WINVER 0x0500 or greater were in
beta state.
Right. The upgrade here is unlikely soon. Hence the question.

windows.h:
#if(WINVER >= 0x0500)
#pragma message ("")
#pragma message ("NOTE: WINVER has been defined as 0x0500 or greater which
enabl
es")
#pragma message ("Windows NT 5.0 and Windows 98 features. When these headers
wer
e released,")
#pragma message ("Windows NT 5.0 beta 1 and Windows 98 beta 2.1 were the
current
versions.")
#pragma message ("")
#pragma message ("For this release when WINVER is defined as 0x0500 or
greater,
you can only")
#pragma message ("build beta or test applications. To build a retail
applicatio
n,")
#pragma message ("set WINVER to 0x0400 or visit
http://www.microsoft.com/msdn/sd
k")
#pragma message ("to see if retail Windows NT 5.0 or Windows 98 headers are
avai
lable.")
#pragma message ("")
#pragma message ("See the SDK release notes for more information.")
#pragma message ("")
ultranet
2006-06-10 01:27:01 UTC
Permalink
Post by ultranet
Right. The upgrade here is unlikely soon. Hence the question.
#if(WINVER >= 0x0500)
#pragma message ("")
#pragma message ("NOTE: WINVER has been defined as 0x0500 or greater which
enabl
es")
#pragma message ("Windows NT 5.0 and Windows 98 features. When these headers
wer
e released,")
#pragma message ("Windows NT 5.0 beta 1 and Windows 98 beta 2.1 were the
current
versions.")
#pragma message ("")
#pragma message ("For this release when WINVER is defined as 0x0500 or
greater,
you can only")
#pragma message ("build beta or test applications. To build a retail
applicatio
n,")
#pragma message ("set WINVER to 0x0400 or visit
http://www.microsoft.com/msdn/sd
k")
#pragma message ("to see if retail Windows NT 5.0 or Windows 98 headers are
avai
lable.")
#pragma message ("")
#pragma message ("See the SDK release notes for more information.")
#pragma message ("")
I have only 171MB of disk space left, so i don't know whether it's a fluke,
but i'm getting the following error in Debug, when trying to show a modal
window:
HEAP[java.exe]: Invalid Address specified to RtlFreeHeap( 00030000, 0BAB3A20 )
at
NTDLL! 7c901230()
NTDLL! 7c96cd80()
NTDLL! 7c96df66()
NTDLL! 7c94a5d0()
NTDLL! 7c9268ad()
MSVCRT! 77c2c2de()
MFC42! 73e69112()
_DllMainCRTStartup(void * 0x0f1f0000, unsigned long 0, void * 0x00000001)
line 273 + 17 bytes
NTDLL! 7c9011a7()
NTDLL! 7c923f31()
KERNEL32! 7c81ca3e()
KERNEL32! 7c81cab6()
MSVCRT! 77c39d45()
MSVCRT! 77c39e78()
MSVCRT! 77c39e90()
...

It works in Release mode.

I'm gonna clean up my disk and try again.
Alex Blekhman
2006-06-10 08:18:00 UTC
Permalink
Post by ultranet
Post by Alex Blekhman
Post by David Wilkinson
I'm still not sure exactly where this message is.
This message is from PSDK that originally distributed
with VC6 ("#pragma message" in some of its headers).
When VC6 was released all platforms with WINVER 0x0500
or greater were in beta state.
Right. The upgrade here is unlikely soon. Hence the
question.
BTW, you can upgrade PSDK without touching VC. Just install
Feb 2003 PSDK (latest one compatible with VC6) and register
it with Visula Studio. It will put PSDK folders paths in VS
settings.
ultranet
2006-06-12 14:15:02 UTC
Permalink
Post by Alex Blekhman
Post by ultranet
Post by Alex Blekhman
Post by David Wilkinson
I'm still not sure exactly where this message is.
This message is from PSDK that originally distributed
with VC6 ("#pragma message" in some of its headers).
When VC6 was released all platforms with WINVER 0x0500
or greater were in beta state.
Right. The upgrade here is unlikely soon. Hence the
question.
BTW, you can upgrade PSDK without touching VC. Just install
Feb 2003 PSDK (latest one compatible with VC6) and register
it with Visula Studio. It will put PSDK folders paths in VS
settings.
Actually, the crash is happening in a different dll, still same project, but
only in Debug mode when setting a resource handle (other team) for i18n. To
do that, we are linking to some Release-mode libs.

The crash is at wincore.cpp line 3478:
if (!AfxGetThread()->PumpMessage())
{
AfxPostQuitMessage(0);
return -1;
}
because AfxGetThread() ıs NULL.

I wonder if it could be because of Debug and Release dlls running together.
Carl Daniel [VC++ MVP]
2006-06-12 15:10:43 UTC
Permalink
Post by ultranet
I wonder if it could be because of Debug and Release dlls running together.
Very likely, yes. That means you have (at least) two different heaps -
allocating from one and freeing to the other is a Bad Thing.

-cd

William DePalo [MVP VC++]
2006-06-09 00:47:20 UTC
Permalink
Post by ultranet
I wish it was so, but it's a non-window message, for which i don't even try
to call translate-dispatch. I know that it gets lost because the caller waits
for notification of processing, which never happens.
Maybe I misunderstood.

I thought that you said that a modal dialog is running in the receiver. If
that's the case, then the dialog manager is pumping messages. Your message
loop doesn't ever see the message. And the dialog manager does not have a
clue as to what to do with a message with a null handle.

Regards,
Will
Loading...