DispatchMessage vs own function
-
Normally messages are cought into a so called Message Loop and are parsed using the TranslateMessage and DispatchMessage. The DispatchMessage does two things: 1 - it calls the right Window procedure 2 - it posts the return value back to the os Well I want to redesign option 1, but I don't want to redesign option 2, so does anyone know what DispatchMessage really does? Maybe WTL/ATL have also there implementations, so if anyone knows where these are, I would be pleased if anyone tells me where. Sjoerd van Leent LPCTSTR Dutch = TEXT("Double Dutch :-)");
-
Normally messages are cought into a so called Message Loop and are parsed using the TranslateMessage and DispatchMessage. The DispatchMessage does two things: 1 - it calls the right Window procedure 2 - it posts the return value back to the os Well I want to redesign option 1, but I don't want to redesign option 2, so does anyone know what DispatchMessage really does? Maybe WTL/ATL have also there implementations, so if anyone knows where these are, I would be pleased if anyone tells me where. Sjoerd van Leent LPCTSTR Dutch = TEXT("Double Dutch :-)");
If you poke around in the headers you'll see some interesting things. MFC, ATL, and WTL use
#define
s to set up message handling for their window classes. I think you're really wanting to implement your own message handling for your window classes.DispatchMessage()
is a Win32 API that [MSDN] "dispatches a message to a window procedure. It is typically used to dispatch a message retrieved by the GetMessage function." You can't really roll your own version of DispatchMessage. Take a look at this interesting snippet from<atlwin.h>
line 1524:#define BEGIN_MSG_MAP(theClass) \
public: \
BOOL ProcessWindowMessage(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam, LRESULT& lResult, DWORD dwMsgMapID = 0) \
{ \
BOOL bHandled = TRUE; \
hWnd; \
uMsg; \
wParam; \
lParam; \
lResult; \
bHandled; \
switch(dwMsgMapID) \
{ \
case 0:You should probably research it a bit before you implement your own, because you'll have to be tight on processing windows messages using Win32 wrapped by C++. -- ian
"The greatest danger to humanity is humanity without an open mind."
- Ian Mariano
http://www.ian-space.com/ -
If you poke around in the headers you'll see some interesting things. MFC, ATL, and WTL use
#define
s to set up message handling for their window classes. I think you're really wanting to implement your own message handling for your window classes.DispatchMessage()
is a Win32 API that [MSDN] "dispatches a message to a window procedure. It is typically used to dispatch a message retrieved by the GetMessage function." You can't really roll your own version of DispatchMessage. Take a look at this interesting snippet from<atlwin.h>
line 1524:#define BEGIN_MSG_MAP(theClass) \
public: \
BOOL ProcessWindowMessage(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam, LRESULT& lResult, DWORD dwMsgMapID = 0) \
{ \
BOOL bHandled = TRUE; \
hWnd; \
uMsg; \
wParam; \
lParam; \
lResult; \
bHandled; \
switch(dwMsgMapID) \
{ \
case 0:You should probably research it a bit before you implement your own, because you'll have to be tight on processing windows messages using Win32 wrapped by C++. -- ian
"The greatest danger to humanity is humanity without an open mind."
- Ian Mariano
http://www.ian-space.com/imariano wrote: ...you'll have to be tight on processing windows messages using Win32 wrapped by C++. I know about thunking or joining, or storing the this pointer, but I'm just curious, it should be possible... LPCTSTR Dutch = TEXT("Double Dutch :-)");
-
Normally messages are cought into a so called Message Loop and are parsed using the TranslateMessage and DispatchMessage. The DispatchMessage does two things: 1 - it calls the right Window procedure 2 - it posts the return value back to the os Well I want to redesign option 1, but I don't want to redesign option 2, so does anyone know what DispatchMessage really does? Maybe WTL/ATL have also there implementations, so if anyone knows where these are, I would be pleased if anyone tells me where. Sjoerd van Leent LPCTSTR Dutch = TEXT("Double Dutch :-)");
Here is the implementation for DispatchMessage from WINE.
LONG WINAPI DispatchMessageW( const MSG* msg )
{
WND * wndPtr;
LONG retval;
int painting;
WNDPROC winproc;/\* Process timer messages \*/ if ((msg->message == WM\_TIMER) || (msg->message == WM\_SYSTIMER)) { if (msg->lParam) {
/* HOOK_CallHooks32W( WH_CALLWNDPROC, HC_ACTION, 0, FIXME ); */
/\* before calling window proc, verify whether timer is still valid; there's a slim chance that the application kills the timer between GetMessage and DispatchMessage API calls \*/ if (!TIMER\_IsTimerValid(msg->hwnd, (UINT) msg->wParam, (HWINDOWPROC) msg->lParam)) return 0; /\* invalid winproc \*/ return CallWindowProcW( (WNDPROC)msg->lParam, msg->hwnd, msg->message, msg->wParam, GetTickCount() ); } } if (!(wndPtr = WIN\_GetPtr( msg->hwnd ))) { if (msg->hwnd) SetLastError( ERROR\_INVALID\_WINDOW\_HANDLE ); return 0; } if (wndPtr == WND\_OTHER\_PROCESS) { if (IsWindow( msg->hwnd )) ERR( "cannot dispatch msg to other process window %x\\n", msg->hwnd ); SetLastError( ERROR\_INVALID\_WINDOW\_HANDLE ); return 0; } if (!(winproc = wndPtr->winproc)) { WIN\_ReleasePtr( wndPtr ); return 0; } painting = (msg->message == WM\_PAINT); if (painting) wndPtr->flags |= WIN\_NEEDS\_BEGINPAINT; WIN\_ReleasePtr( wndPtr );
/* HOOK_CallHooks32W( WH_CALLWNDPROC, HC_ACTION, 0, FIXME ); */
SPY\_EnterMessage( SPY\_DISPATCHMESSAGE, msg->hwnd, msg->message, msg->wParam, msg->lParam ); retval = CallWindowProcW( winproc, msg->hwnd, msg->message, msg->wParam, msg->lParam ); SPY\_ExitMessage( SPY\_RESULT\_OK, msg->hwnd, msg->message, retval, msg->wParam, msg->lParam ); if (painting && (wndPtr = WIN\_GetPtr( msg->hwnd )) && (wndPtr != WND\_OTHER\_PROCESS)) { BOOL validate = ((wndPtr->flags & WIN\_NEEDS\_BEGINPAINT) && wndPtr->hrgnUpdate); wndPtr->flags &= ~WIN\_NEEDS\_BEGINPAINT; WIN\_ReleasePtr( wndPtr ); if (validate) { ERR( "BeginPaint not called on WM\_PAINT for hwnd %04x!\\n", msg->hwnd ); /\* Validate the update region to avoid infinite WM\_PAINT loop \*/ RedrawWindow( msg->hwnd, NULL, 0, RDW\_NO
-
Here is the implementation for DispatchMessage from WINE.
LONG WINAPI DispatchMessageW( const MSG* msg )
{
WND * wndPtr;
LONG retval;
int painting;
WNDPROC winproc;/\* Process timer messages \*/ if ((msg->message == WM\_TIMER) || (msg->message == WM\_SYSTIMER)) { if (msg->lParam) {
/* HOOK_CallHooks32W( WH_CALLWNDPROC, HC_ACTION, 0, FIXME ); */
/\* before calling window proc, verify whether timer is still valid; there's a slim chance that the application kills the timer between GetMessage and DispatchMessage API calls \*/ if (!TIMER\_IsTimerValid(msg->hwnd, (UINT) msg->wParam, (HWINDOWPROC) msg->lParam)) return 0; /\* invalid winproc \*/ return CallWindowProcW( (WNDPROC)msg->lParam, msg->hwnd, msg->message, msg->wParam, GetTickCount() ); } } if (!(wndPtr = WIN\_GetPtr( msg->hwnd ))) { if (msg->hwnd) SetLastError( ERROR\_INVALID\_WINDOW\_HANDLE ); return 0; } if (wndPtr == WND\_OTHER\_PROCESS) { if (IsWindow( msg->hwnd )) ERR( "cannot dispatch msg to other process window %x\\n", msg->hwnd ); SetLastError( ERROR\_INVALID\_WINDOW\_HANDLE ); return 0; } if (!(winproc = wndPtr->winproc)) { WIN\_ReleasePtr( wndPtr ); return 0; } painting = (msg->message == WM\_PAINT); if (painting) wndPtr->flags |= WIN\_NEEDS\_BEGINPAINT; WIN\_ReleasePtr( wndPtr );
/* HOOK_CallHooks32W( WH_CALLWNDPROC, HC_ACTION, 0, FIXME ); */
SPY\_EnterMessage( SPY\_DISPATCHMESSAGE, msg->hwnd, msg->message, msg->wParam, msg->lParam ); retval = CallWindowProcW( winproc, msg->hwnd, msg->message, msg->wParam, msg->lParam ); SPY\_ExitMessage( SPY\_RESULT\_OK, msg->hwnd, msg->message, retval, msg->wParam, msg->lParam ); if (painting && (wndPtr = WIN\_GetPtr( msg->hwnd )) && (wndPtr != WND\_OTHER\_PROCESS)) { BOOL validate = ((wndPtr->flags & WIN\_NEEDS\_BEGINPAINT) && wndPtr->hrgnUpdate); wndPtr->flags &= ~WIN\_NEEDS\_BEGINPAINT; WIN\_ReleasePtr( wndPtr ); if (validate) { ERR( "BeginPaint not called on WM\_PAINT for hwnd %04x!\\n", msg->hwnd ); /\* Validate the update region to avoid infinite WM\_PAINT loop \*/ RedrawWindow( msg->hwnd, NULL, 0, RDW\_NO
I also looked into atlapp.h of WTL70 there is also another type of function which does this. But do you've also the TranslateMessage function, and other functions which apply to a message loop. I guess that what I really want to do is fading the CALLBACK out of sight. LPCTSTR Dutch = TEXT("Double Dutch :-)");
-
Normally messages are cought into a so called Message Loop and are parsed using the TranslateMessage and DispatchMessage. The DispatchMessage does two things: 1 - it calls the right Window procedure 2 - it posts the return value back to the os Well I want to redesign option 1, but I don't want to redesign option 2, so does anyone know what DispatchMessage really does? Maybe WTL/ATL have also there implementations, so if anyone knows where these are, I would be pleased if anyone tells me where. Sjoerd van Leent LPCTSTR Dutch = TEXT("Double Dutch :-)");
Got this code out of a MSJ from 1997
MS Systems journal example: //================================================= // Matt Pietrek // Microsoft Systems Journal, March 1997 // Pseudocode for ring 3 portion of DispatchMessage //================================================= LONG DispatchMessageA( CONST MSG *lpmsg ) { return DispatchMessageWorker( lpmsg, 1 ); // 0 == UNICODE, 1 = ANSI } LONG DispatchMessageWorker( CONST MSG *lpmsg, BOOL fAnsi ) { if ( lpmsg->message == 0xFFFE0000 ) { _UserSetLastError( ERROR_INVALID_PARAMETER ); return 0; } // If we have a non-null HWND, convert it to a pointer to the user mode // WND structure. We'll use this ptr extensively. if ( lpmsg->hwnd ) { pWnd = @ValidateHwnd( lpmsg->hwnd ); if ( !pWnd ) return 0; } else pWnd = 0; if ( (lpmsg->message != WM_TIMER) && (lpmsg->message != WM_SYSTIMER) ) { begin_normal_message: if ( pWnd == 0 ) // Sanity check. We'd better have a valid window! return 0; DWORD save_wParam = lpmsg->wParam; if ( (lpmsg->message != WM_PAINT) && !(pWnd->someFlags9E & 4) ) { if ( IsWindowUnicode( lpmsg->hwnd ) ) { if ( fAnsi ) RtlMBMessageWParamCharToWCS( lpmsg->message, save_wParam ); else RtlWCSMessageWParamCharToMB( lpmsg->message, save_wParam ); } // Is the high bit in the wndproc address set? If so, this is a // 16 bit window, and pfnWndProc is a 16:16 far address. To get // the real address, turn off the high bit (0x80000000) if ( 0 == (pWnd->pfnWndProc & 0x80000000) ) { pWnd->pfnWndProc( lpmsg->hwnd, lpmsg->message, lpmsg->wParam, lpmsg->lParam ); } else { pfnWowWndProcEx( lpmsg->hwnd, lpmsg->message, save_wParam, lpmsg->lParam, lpmsg->message, pWnd->0x90 ); } } else // WM_PAINT, or something else... { if ( fAnsi ) _RtlMBMessageWParamCharToWCS( lpmsg->message, save_wParam ); _NtUserDispatchMessage( lpmsg ); } lpmsg->wParam
-
Here is the implementation for DispatchMessage from WINE.
LONG WINAPI DispatchMessageW( const MSG* msg )
{
WND * wndPtr;
LONG retval;
int painting;
WNDPROC winproc;/\* Process timer messages \*/ if ((msg->message == WM\_TIMER) || (msg->message == WM\_SYSTIMER)) { if (msg->lParam) {
/* HOOK_CallHooks32W( WH_CALLWNDPROC, HC_ACTION, 0, FIXME ); */
/\* before calling window proc, verify whether timer is still valid; there's a slim chance that the application kills the timer between GetMessage and DispatchMessage API calls \*/ if (!TIMER\_IsTimerValid(msg->hwnd, (UINT) msg->wParam, (HWINDOWPROC) msg->lParam)) return 0; /\* invalid winproc \*/ return CallWindowProcW( (WNDPROC)msg->lParam, msg->hwnd, msg->message, msg->wParam, GetTickCount() ); } } if (!(wndPtr = WIN\_GetPtr( msg->hwnd ))) { if (msg->hwnd) SetLastError( ERROR\_INVALID\_WINDOW\_HANDLE ); return 0; } if (wndPtr == WND\_OTHER\_PROCESS) { if (IsWindow( msg->hwnd )) ERR( "cannot dispatch msg to other process window %x\\n", msg->hwnd ); SetLastError( ERROR\_INVALID\_WINDOW\_HANDLE ); return 0; } if (!(winproc = wndPtr->winproc)) { WIN\_ReleasePtr( wndPtr ); return 0; } painting = (msg->message == WM\_PAINT); if (painting) wndPtr->flags |= WIN\_NEEDS\_BEGINPAINT; WIN\_ReleasePtr( wndPtr );
/* HOOK_CallHooks32W( WH_CALLWNDPROC, HC_ACTION, 0, FIXME ); */
SPY\_EnterMessage( SPY\_DISPATCHMESSAGE, msg->hwnd, msg->message, msg->wParam, msg->lParam ); retval = CallWindowProcW( winproc, msg->hwnd, msg->message, msg->wParam, msg->lParam ); SPY\_ExitMessage( SPY\_RESULT\_OK, msg->hwnd, msg->message, retval, msg->wParam, msg->lParam ); if (painting && (wndPtr = WIN\_GetPtr( msg->hwnd )) && (wndPtr != WND\_OTHER\_PROCESS)) { BOOL validate = ((wndPtr->flags & WIN\_NEEDS\_BEGINPAINT) && wndPtr->hrgnUpdate); wndPtr->flags &= ~WIN\_NEEDS\_BEGINPAINT; WIN\_ReleasePtr( wndPtr ); if (validate) { ERR( "BeginPaint not called on WM\_PAINT for hwnd %04x!\\n", msg->hwnd ); /\* Validate the update region to avoid infinite WM\_PAINT loop \*/ RedrawWindow( msg->hwnd, NULL, 0, RDW\_NO
Never thought to look @ Wine ;) Heheh. Still, quite informative that code snippet, and the psuedocode one below from MSJ...which looks like it still allows for 16-bit (!) thingamadoodles. TranslateMessage allows for "preprocessing" of Virtual key messages into character messages, which are then posted to the calling thread's message queue.
"The greatest danger to humanity is humanity without an open mind."
- Ian Mariano - http://www.ian-space.com/