Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • World
  • Users
  • Groups
Skins
  • Light
  • Cerulean
  • Cosmo
  • Flatly
  • Journal
  • Litera
  • Lumen
  • Lux
  • Materia
  • Minty
  • Morph
  • Pulse
  • Sandstone
  • Simplex
  • Sketchy
  • Spacelab
  • United
  • Yeti
  • Zephyr
  • Dark
  • Cyborg
  • Darkly
  • Quartz
  • Slate
  • Solar
  • Superhero
  • Vapor

  • Default (No Skin)
  • No Skin
Collapse
Code Project
  1. Home
  2. General Programming
  3. C / C++ / MFC
  4. DispatchMessage vs own function

DispatchMessage vs own function

Scheduled Pinned Locked Moved C / C++ / MFC
c++visual-studioquestion
7 Posts 3 Posters 0 Views 1 Watching
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • S Offline
    S Offline
    S van Leent
    wrote on last edited by
    #1

    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 :-)");

    I P S 3 Replies Last reply
    0
    • S S van Leent

      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 :-)");

      I Offline
      I Offline
      ian mariano
      wrote on last edited by
      #2

      If you poke around in the headers you'll see some interesting things. MFC, ATL, and WTL use #defines 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/

      S 1 Reply Last reply
      0
      • I ian mariano

        If you poke around in the headers you'll see some interesting things. MFC, ATL, and WTL use #defines 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/

        S Offline
        S Offline
        S van Leent
        wrote on last edited by
        #3

        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 :-)");

        1 Reply Last reply
        0
        • S S van Leent

          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 :-)");

          P Offline
          P Offline
          Paul M Watt
          wrote on last edited by
          #4

          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
          
          S I 2 Replies Last reply
          0
          • P Paul M Watt

            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
            
            S Offline
            S Offline
            S van Leent
            wrote on last edited by
            #5

            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 :-)");

            1 Reply Last reply
            0
            • S S van Leent

              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 :-)");

              S Offline
              S Offline
              S van Leent
              wrote on last edited by
              #6

              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

              1 Reply Last reply
              0
              • P Paul M Watt

                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 Offline
                I Offline
                ian mariano
                wrote on last edited by
                #7

                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/

                1 Reply Last reply
                0
                Reply
                • Reply as topic
                Log in to reply
                • Oldest to Newest
                • Newest to Oldest
                • Most Votes


                • Login

                • Don't have an account? Register

                • Login or register to search.
                • First post
                  Last post
                0
                • Categories
                • Recent
                • Tags
                • Popular
                • World
                • Users
                • Groups