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

send message to winApp ?

108 views
Skip to first unread message

FHDB

unread,
Nov 4, 2009, 12:30:02 AM11/4/09
to

I have placed thread control logic for worker threads in theApp, declared as
CdualApp : public CWinApp. But my additions to the message map result in the
error: error C2440: 'static_cast' : cannot convert from 'LRESULT (__cdecl
*)(WPARAM,LPARAM)' to 'LRESULT (__thiscall CWnd::* )(WPARAM,LPARAM)'
if declared globally, or similarly if made part of class CdualApp.

The problem appears to be that the message map wants message handlers that
are part of a CWnd derived class. Is there a workaround for this, or do I
need to move all the thread control logic into such a class?

Giovanni Dicanio

unread,
Nov 4, 2009, 4:48:19 AM11/4/09
to
"FHDB" <FH...@discussions.microsoft.com> ha scritto nel messaggio
news:9E8C74B2-01BE-4658...@microsoft.com...

> I have placed thread control logic for worker threads in theApp, declared
> as
> CdualApp : public CWinApp. But my additions to the message map result in
> the
> error: error C2440: 'static_cast' : cannot convert from 'LRESULT (__cdecl
> *)(WPARAM,LPARAM)' to 'LRESULT (__thiscall CWnd::* )(WPARAM,LPARAM)'
> if declared globally, or similarly if made part of class CdualApp.

It would be helpful to read actual code.

However, in general, when you use AfxBeginThread in MFC context to create a
worker thread, you pass as first parameter the address of a function which
can be a *static* member function of a class.
And you can specify as second parameter an LPVOID; you can use this second
parameter to pass the 'this' value associated to the particular instance of
a C++ class.
In this way, the static member function can cast the LPVOID back to 'this'
pointer, and can call a non-static member function.

Joe wrote an interesting essay on worker threads, I think that you will find
it very useful:

http://www.flounder.com/workerthreads.htm

HTH,
Giovanni

Ajay Kalra

unread,
Nov 4, 2009, 7:44:31 AM11/4/09
to

CWinApp is not a window, so you cant really send a message to it.
Since its derived from CWinThread, you can use PostThreadMessage. For
message map, you will need ON_THREAD_MESSAGE.

Also, this object participates in message routing(derived from
CCmdTarget), so it can receive WM_COMMAND types messages as well.

--
Ajay

Joseph M. Newcomer

unread,
Nov 4, 2009, 8:35:26 AM11/4/09
to
Note, however, that if the CWinApp is the CWinApp for a GUI-based app that has windows,
you cannot PostThreadMessage to it!

The error message says explicitly that the type of the function is implemented as

LRESULT function(WPARAM, LPARAM)

when it must be implemented as

LRESULT classname::function(WPARAM, LPARAM)

but more seriously, as pointed out here, the classname can *only* be a CWnd class, so it
can't be in a CWinApp-derived class. ON_MESSAGE and ON_REGISTERED_MESSAGE entries can
only be used in CWnd-derived classes.
joe

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

Ajay Kalra

unread,
Nov 4, 2009, 9:38:12 AM11/4/09
to
On Nov 4, 8:35 am, Joseph M. Newcomer <newco...@flounder.com> wrote:
> Note, however, that if the CWinApp is the CWinApp for a GUI-based app that has windows,
> you cannot PostThreadMessage to it!  
>

Thats very odd. We did it for a GUI without any issue and it has been
in the product for a very long time.

--
Ajay

Tom Serface

unread,
Nov 4, 2009, 10:56:21 AM11/4/09
to
I typically send messages to my mainframe since it *is* a window. You can
call functions in the main app code by using AfxGetApp().

Tom

"FHDB" <FH...@discussions.microsoft.com> wrote in message
news:9E8C74B2-01BE-4658...@microsoft.com...

Scott McPhillips [MVP]

unread,
Nov 4, 2009, 11:24:17 AM11/4/09
to
"Ajay Kalra" <ajay...@yahoo.com> wrote in message
news:2b629084-1edb-4151...@p36g2000vbn.googlegroups.com...


It will fail to process the message if the app is displaying a messge box. I
think it will also fail if the app is displaying a menu. I.e. a modal loop
within Windows does not forward the message, as documented in
PostThreadMessage.

--
Scott McPhillips [VC++ MVP]

Joseph M. Newcomer

unread,
Nov 4, 2009, 11:47:35 AM11/4/09
to
(a) Read the description of PostThreadMessage which explains that it does not work
(b) PostThreadMessage messages will be lost if, at the point of receipt
The GUI thread has a MessageBox up
The GUI thread has a menu up
A window in the main thread is being dragged
A window in the main thread is being resized
...(and probably other situations)

So if it worked "without any issue" it means that you have simply been lucky. The reality
is that it does not work correctly under common scenarios of the main GUI thread.
joe

Joseph M. Newcomer

unread,
Nov 4, 2009, 11:51:33 AM11/4/09
to
I find that the main window is convenient but only under certain restricted scenarios. I
have also discovered that many people post messages to the main window in inappropriate
situations and end up spending a lot of effort figuring out what to do next, and often
this involves having the main window call methods of a document or view, which is really
bad structure. So it is necessary to be careful about how the messaging is structured.
joe

Ajay Kalra

unread,
Nov 4, 2009, 11:58:16 AM11/4/09
to
On Nov 4, 11:47 am, Joseph M. Newcomer <newco...@flounder.com> wrote:
> (a) Read the description of PostThreadMessage which explains that it does not work
> (b) PostThreadMessage messages will be lost if, at the point of receipt
>         The GUI thread has a MessageBox up
>         The GUI thread has a menu up
>         A window in the main thread  is being dragged
>         A window in the main thread is being resized
>         ...(and probably other situations)
>
> So if it worked "without any issue" it means that you have simply been lucky.  The reality
> is that it does not work correctly under common scenarios of the main GUI thread.

Thanks. That explains why. It just happens to be used before the
window is shown.

To elaborate, I didnt implement this; I just found that it was used
this way and was curious(It was also memorable as I still remember it
10 years later). Its also the only use that I have seen this being
used in CWinApp.

--
Ajay

Tom Serface

unread,
Nov 4, 2009, 4:06:29 PM11/4/09
to
I only post messages to "main" if they have to do with something going in
the main window. Otherwise, I'd be more likely to post to a view or a
non-modal dialog or whoever is supposed to do something with the message
(assuming it's GUI related).

Tom

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

David Ching

unread,
Nov 8, 2009, 2:18:27 PM11/8/09
to
"Tom Serface" <t...@camaswood.com> wrote in message
news:F01B3457-0771-4C81...@microsoft.com...

> I only post messages to "main" if they have to do with something going in
> the main window. Otherwise, I'd be more likely to post to a view or a
> non-modal dialog or whoever is supposed to do something with the message
> (assuming it's GUI related).
>

The problem with posting/sending to either the MainFrame or a View is that
it is hard for the posting app to find the window using the classname, since
MFC names these unpredictably. So I create my own top-level hidden window
with a well known classname such as MYAPP_HIDDEN_WINDOW_GUID_xxxxx which
other apps can easily do a FindWindow() to get. Of course, they could
always broadcast a registered window message to all windows and not worry
about finding mine, but that has always seemed wasteful when only my own app
needs to be notified (and not every window on the system).

-- David

Joseph M. Newcomer

unread,
Nov 8, 2009, 7:19:56 PM11/8/09
to
Generally, I never use FindWindow to do this for the reason you point out: you don't know
its class name.

You can always find the main window from
AfxGetApp()->m_pMainWnd
(note that in the main GUI thread, AfxGetMainWnd() [I think that's the name of the
function] does this, but it is not reliable in a secondary thread, while
AfxGetApp()->m_pMainWnd is always reliable.

For views, I explicitly pass in the CWnd* of the view to whatever is supposed to be
sending/posting the message, so there's never a question.

For cross-process messaging, your solution is a real good idea; I always tell my students
that if you broadcast more that one message per run of your program, you are costing
serious system resources. What I usually do is
::PostMessage(HWND_BROADCAST, UWM_HERE_I_AM, (WPARAM)m_hWnd, 0);
or something remarkably similar; yes, it does end up going to every window, but only the
window(s) that recognize the message can respond. Note that the WPARAM in this case is
the window that I want to use to establish communication, so the recipient(s) will respond
with a
::PostMessage((HWND)wParam, UWM_I_SAW_YOU, (WPARAM)m_hWnd, 0);
that is, post back their actual window handle. Now both sender and receiver know each
other's actual window handles, and nobody ever needs to broadcast again. This is
particularly useful for multi-client or multi-server situations where I can have multiple
instances running.

It was not clear from the context of the question if cross-process messaging is involved
at all. Within an app, you should always be told what window to communicate with as part
of the protocol of establishing the "connection" (e.g., passing a window handle in to a
DLL, or as part of the input to a thread).
joe

0 new messages