Convert Windows Message IDs to Text

前端 未结 3 791
被撕碎了的回忆
被撕碎了的回忆 2020-12-07 01:48

Is there a hidden/undocumented API call within Windows that will convert a message ID (e.g. WM_COMMAND) into text?

I have seen suggestions on how to achieve this usi

相关标签:
3条回答
  • 2020-12-07 01:58

    Hereafter is code to convert WM_ and other Win32 message codes to text. Includes options to ignore certain messages (eg. WM_MOUSEMOVE) and to dump a list of messages received at the end. (NB: This list only goes up to 1024 (WM_USER) due to the 30K limit on this box. Also there are many duplicates in the list thereafter.)

    // Usage -----
    #include "win_msg.h"
    
    void ShowMessageText(UINT msg)
    {
      wchar_t str[1024];
      wchar_t* win_msgtext = (wchar_t*)GetMessageText(msg);
      if (win_msgtext)
      {
        //printf(L"WndProc: msg = %x (%s)\n", msg, win_msgtext);
        wsprintf(str, L"WndProc: msg = %x (%s)\n", msg, win_msgtext);
        OutputDebugString(str);
      }
    }
    
    To list messages used (and generate an 'ignore' list) call:
      ShowUsedMessages();
    
      
    // win_msg.h file ----------
    #define SHOW_USED_MESSAGES 1
    
    wchar_t* GetMessageText(unsigned int msg);
    
    #ifdef SHOW_USED_MESSAGES
    void ShowUsedMessages(void);
    #endif
    
    // win_msg.cpp -----------
    #include "stdafx.h"
    #include "win_msg.h"
    
    // List here messages to ignore (-1 signifies end of list)
    // if -999 occurs at the start of the list, ALL messages except these are ignored (ie. inverts)
    //int msgs_to_ignore[] = { -1 };
    int msgs_to_ignore[] = {//-999,
      0x20, 0x84, 0xA0, 0x113, 0x200
    };
    // 0x0020 - WM_SETCURSOR (45)
    // 0x0084 - WM_NCHITTEST (26)
    // 0x0113 - WM_TIMER (46)
    // 0x0135 - WM_CTLCOLORBTN (8)
    // 0x0200 - WM_MOUSEFIRST (26)
    
    typedef struct {
      unsigned int code;
      wchar_t* text;
    } XMSGITEM;
    
    // These from https://wiki.winehq.org/List_Of_Windows_Messages
    XMSGITEM xmsglist[] =
    {
      { 0, L"WM_NULL"},
      { 1, L"WM_CREATE" },
      { 2, L"WM_DESTROY" },
      { 3, L"WM_MOVE" },
      { 5, L"WM_SIZE" },
      { 6, L"WM_ACTIVATE" },
      { 7, L"WM_SETFOCUS" },
      { 8, L"WM_KILLFOCUS" },
      { 10, L"WM_ENABLE" },
      { 11, L"WM_SETREDRAW" },
      { 12, L"WM_SETTEXT" },
      { 13, L"WM_GETTEXT" },
      { 14, L"WM_GETTEXTLENGTH" },
      { 15, L"WM_PAINT" },
      { 16, L"WM_CLOSE" },
      { 17, L"WM_QUERYENDSESSION" },
      { 18, L"WM_QUIT" },
      { 19, L"WM_QUERYOPEN" },
      { 20, L"WM_ERASEBKGND" },
      { 21, L"WM_SYSCOLORCHANGE" },
      { 22, L"WM_ENDSESSION" },
      { 24, L"WM_SHOWWINDOW" },
      { 25, L"WM_CTLCOLOR" },
      { 26, L"WM_WININICHANGE" },
      { 27, L"WM_DEVMODECHANGE" },
      { 28, L"WM_ACTIVATEAPP" },
      { 29, L"WM_FONTCHANGE" },
      { 30, L"WM_TIMECHANGE" },
      { 31, L"WM_CANCELMODE" },
      { 32, L"WM_SETCURSOR" },
      { 33, L"WM_MOUSEACTIVATE" },
      { 34, L"WM_CHILDACTIVATE" },
      { 35, L"WM_QUEUESYNC" },
      { 36, L"WM_GETMINMAXINFO" },
      { 38, L"WM_PAINTICON" },
      { 39, L"WM_ICONERASEBKGND" },
      { 40, L"WM_NEXTDLGCTL" },
      { 42, L"WM_SPOOLERSTATUS" },
      { 43, L"WM_DRAWITEM" },
      { 44, L"WM_MEASUREITEM" },
      { 45, L"WM_DELETEITEM" },
      { 46, L"WM_VKEYTOITEM" },
      { 47, L"WM_CHARTOITEM" },
      { 48, L"WM_SETFONT" },
      { 49, L"WM_GETFONT" },
      { 50, L"WM_SETHOTKEY" },
      { 51, L"WM_GETHOTKEY" },
      { 55, L"WM_QUERYDRAGICON" },
      { 57, L"WM_COMPAREITEM" },
      { 61, L"WM_GETOBJECT" },
      { 65, L"WM_COMPACTING" },
      { 68, L"WM_COMMNOTIFY" },
      { 70, L"WM_WINDOWPOSCHANGING" },
      { 71, L"WM_WINDOWPOSCHANGED" },
      { 72, L"WM_POWER" },
      { 73, L"WM_COPYGLOBALDATA" },
      { 74, L"WM_COPYDATA" },
      { 75, L"WM_CANCELJOURNAL" },
      { 78, L"WM_NOTIFY" },
      { 80, L"WM_INPUTLANGCHANGEREQUEST" },
      { 81, L"WM_INPUTLANGCHANGE" },
      { 82, L"WM_TCARD" },
      { 83, L"WM_HELP" },
      { 84, L"WM_USERCHANGED" },
      { 85, L"WM_NOTIFYFORMAT" },
      { 123, L"WM_CONTEXTMENU" },
      { 124, L"WM_STYLECHANGING" },
      { 125, L"WM_STYLECHANGED" },
      { 126, L"WM_DISPLAYCHANGE" },
      { 127, L"WM_GETICON" },
      { 128, L"WM_SETICON" },
      { 129, L"WM_NCCREATE" },
      { 130, L"WM_NCDESTROY" },
      { 131, L"WM_NCCALCSIZE" },
      { 132, L"WM_NCHITTEST" },
      { 133, L"WM_NCPAINT" },
      { 134, L"WM_NCACTIVATE" },
      { 135, L"WM_GETDLGCODE" },
      { 136, L"WM_SYNCPAINT" },
      { 160, L"WM_NCMOUSEMOVE" },
      { 161, L"WM_NCLBUTTONDOWN" },
      { 162, L"WM_NCLBUTTONUP" },
      { 163, L"WM_NCLBUTTONDBLCLK" },
      { 164, L"WM_NCRBUTTONDOWN" },
      { 165, L"WM_NCRBUTTONUP" },
      { 166, L"WM_NCRBUTTONDBLCLK" },
      { 167, L"WM_NCMBUTTONDOWN" },
      { 168, L"WM_NCMBUTTONUP" },
      { 169, L"WM_NCMBUTTONDBLCLK" },
      { 171, L"WM_NCXBUTTONDOWN" },
      { 172, L"WM_NCXBUTTONUP" },
      { 173, L"WM_NCXBUTTONDBLCLK" },
      { 176, L"EM_GETSEL" },
      { 177, L"EM_SETSEL" },
      { 178, L"EM_GETRECT" },
      { 179, L"EM_SETRECT" },
      { 180, L"EM_SETRECTNP" },
      { 181, L"EM_SCROLL" },
      { 182, L"EM_LINESCROLL" },
      { 183, L"EM_SCROLLCARET" },
      { 185, L"EM_GETMODIFY" },
      { 187, L"EM_SETMODIFY" },
      { 188, L"EM_GETLINECOUNT" },
      { 189, L"EM_LINEINDEX" },
      { 190, L"EM_SETHANDLE" },
      { 191, L"EM_GETHANDLE" },
      { 192, L"EM_GETTHUMB" },
      { 193, L"EM_LINELENGTH" },
      { 194, L"EM_REPLACESEL" },
      { 195, L"EM_SETFONT" },
      { 196, L"EM_GETLINE" },
      { 197, L"EM_LIMITTEXT" },
      { 197, L"EM_SETLIMITTEXT" },
      { 198, L"EM_CANUNDO" },
      { 199, L"EM_UNDO" },
      { 200, L"EM_FMTLINES" },
      { 201, L"EM_LINEFROMCHAR" },
      { 202, L"EM_SETWORDBREAK" },
      { 203, L"EM_SETTABSTOPS" },
      { 204, L"EM_SETPASSWORDCHAR" },
      { 205, L"EM_EMPTYUNDOBUFFER" },
      { 206, L"EM_GETFIRSTVISIBLELINE" },
      { 207, L"EM_SETREADONLY" },
      { 209, L"EM_SETWORDBREAKPROC" },
      { 209, L"EM_GETWORDBREAKPROC" },
      { 210, L"EM_GETPASSWORDCHAR" },
      { 211, L"EM_SETMARGINS" },
      { 212, L"EM_GETMARGINS" },
      { 213, L"EM_GETLIMITTEXT" },
      { 214, L"EM_POSFROMCHAR" },
      { 215, L"EM_CHARFROMPOS" },
      { 216, L"EM_SETIMESTATUS" },
      { 217, L"EM_GETIMESTATUS" },
      { 224, L"SBM_SETPOS" },
      { 225, L"SBM_GETPOS" },
      { 226, L"SBM_SETRANGE" },
      { 227, L"SBM_GETRANGE" },
      { 228, L"SBM_ENABLE_ARROWS" },
      { 230, L"SBM_SETRANGEREDRAW" },
      { 233, L"SBM_SETSCROLLINFO" },
      { 234, L"SBM_GETSCROLLINFO" },
      { 235, L"SBM_GETSCROLLBARINFO" },
      { 240, L"BM_GETCHECK" },
      { 241, L"BM_SETCHECK" },
      { 242, L"BM_GETSTATE" },
      { 243, L"BM_SETSTATE" },
      { 244, L"BM_SETSTYLE" },
      { 245, L"BM_CLICK" },
      { 246, L"BM_GETIMAGE" },
      { 247, L"BM_SETIMAGE" },
      { 248, L"BM_SETDONTCLICK" },
      { 255, L"WM_INPUT" },
      { 256, L"WM_KEYDOWN" },
      { 256, L"WM_KEYFIRST" },
      { 257, L"WM_KEYUP" },
      { 258, L"WM_CHAR" },
      { 259, L"WM_DEADCHAR" },
      { 260, L"WM_SYSKEYDOWN" },
      { 261, L"WM_SYSKEYUP" },
      { 262, L"WM_SYSCHAR" },
      { 263, L"WM_SYSDEADCHAR" },
      { 264, L"WM_KEYLAST" },
      { 265, L"WM_UNICHAR" },
      { 265, L"WM_WNT_CONVERTREQUESTEX" },
      { 266, L"WM_CONVERTREQUEST" },
      { 267, L"WM_CONVERTRESULT" },
      { 268, L"WM_INTERIM" },
      { 269, L"WM_IME_STARTCOMPOSITION" },
      { 270, L"WM_IME_ENDCOMPOSITION" },
      { 271, L"WM_IME_COMPOSITION" },
      { 271, L"WM_IME_KEYLAST" },
      { 272, L"WM_INITDIALOG" },
      { 273, L"WM_COMMAND" },
      { 274, L"WM_SYSCOMMAND" },
      { 275, L"WM_TIMER" },
      { 276, L"WM_HSCROLL" },
      { 277, L"WM_VSCROLL" },
      { 278, L"WM_INITMENU" },
      { 279, L"WM_INITMENUPOPUP" },
      { 280, L"WM_SYSTIMER" },
      { 287, L"WM_MENUSELECT" },
      { 288, L"WM_MENUCHAR" },
      { 289, L"WM_ENTERIDLE" },
      { 290, L"WM_MENURBUTTONUP" },
      { 291, L"WM_MENUDRAG" },
      { 292, L"WM_MENUGETOBJECT" },
      { 293, L"WM_UNINITMENUPOPUP" },
      { 294, L"WM_MENUCOMMAND" },
      { 295, L"WM_CHANGEUISTATE" },
      { 296, L"WM_UPDATEUISTATE" },
      { 297, L"WM_QUERYUISTATE" },
      { 306, L"WM_CTLCOLORMSGBOX" },
      { 307, L"WM_CTLCOLOREDIT" },
      { 308, L"WM_CTLCOLORLISTBOX" },
      { 309, L"WM_CTLCOLORBTN" },
      { 310, L"WM_CTLCOLORDLG" },
      { 311, L"WM_CTLCOLORSCROLLBAR" },
      { 312, L"WM_CTLCOLORSTATIC" },
      { 512, L"WM_MOUSEFIRST" },
      { 512, L"WM_MOUSEMOVE" },
      { 513, L"WM_LBUTTONDOWN" },
      { 514, L"WM_LBUTTONUP" },
      { 515, L"WM_LBUTTONDBLCLK" },
      { 516, L"WM_RBUTTONDOWN" },
      { 517, L"WM_RBUTTONUP" },
      { 518, L"WM_RBUTTONDBLCLK" },
      { 519, L"WM_MBUTTONDOWN" },
      { 520, L"WM_MBUTTONUP" },
      { 521, L"WM_MBUTTONDBLCLK" },
      { 521, L"WM_MOUSELAST" },
      { 522, L"WM_MOUSEWHEEL" },
      { 523, L"WM_XBUTTONDOWN" },
      { 524, L"WM_XBUTTONUP" },
      { 525, L"WM_XBUTTONDBLCLK" },
      { 528, L"WM_PARENTNOTIFY" },
      { 529, L"WM_ENTERMENULOOP" },
      { 530, L"WM_EXITMENULOOP" },
      { 531, L"WM_NEXTMENU" },
      { 532, L"WM_SIZING" },
      { 533, L"WM_CAPTURECHANGED" },
      { 534, L"WM_MOVING" },
      { 536, L"WM_POWERBROADCAST" },
      { 537, L"WM_DEVICECHANGE" },
      { 544, L"WM_MDICREATE" },
      { 545, L"WM_MDIDESTROY" },
      { 546, L"WM_MDIACTIVATE" },
      { 547, L"WM_MDIRESTORE" },
      { 548, L"WM_MDINEXT" },
      { 549, L"WM_MDIMAXIMIZE" },
      { 550, L"WM_MDITILE" },
      { 551, L"WM_MDICASCADE" },
      { 552, L"WM_MDIICONARRANGE" },
      { 553, L"WM_MDIGETACTIVE" },
      { 560, L"WM_MDISETMENU" },
      { 561, L"WM_ENTERSIZEMOVE" },
      { 562, L"WM_EXITSIZEMOVE" },
      { 563, L"WM_DROPFILES" },
      { 564, L"WM_MDIREFRESHMENU" },
      { 640, L"WM_IME_REPORT" },
      { 641, L"WM_IME_SETCONTEXT" },
      { 642, L"WM_IME_NOTIFY" },
      { 643, L"WM_IME_CONTROL" },
      { 644, L"WM_IME_COMPOSITIONFULL" },
      { 645, L"WM_IME_SELECT" },
      { 646, L"WM_IME_CHAR" },
      { 648, L"WM_IME_REQUEST" },
      { 656, L"WM_IMEKEYDOWN" },
      { 656, L"WM_IME_KEYDOWN" },
      { 657, L"WM_IMEKEYUP" },
      { 657, L"WM_IME_KEYUP" },
      { 672, L"WM_NCMOUSEHOVER" },
      { 673, L"WM_MOUSEHOVER" },
      { 674, L"WM_NCMOUSELEAVE" },
      { 675, L"WM_MOUSELEAVE" },
      { 768, L"WM_CUT" },
      { 769, L"WM_COPY" },
      { 770, L"WM_PASTE" },
      { 771, L"WM_CLEAR" },
      { 772, L"WM_UNDO" },
      { 773, L"WM_RENDERFORMAT" },
      { 774, L"WM_RENDERALLFORMATS" },
      { 775, L"WM_DESTROYCLIPBOARD" },
      { 776, L"WM_DRAWCLIPBOARD" },
      { 777, L"WM_PAINTCLIPBOARD" },
      { 778, L"WM_VSCROLLCLIPBOARD" },
      { 779, L"WM_SIZECLIPBOARD" },
      { 780, L"WM_ASKCBFORMATNAME" },
      { 781, L"WM_CHANGECBCHAIN" },
      { 782, L"WM_HSCROLLCLIPBOARD" },
      { 783, L"WM_QUERYNEWPALETTE" },
      { 784, L"WM_PALETTEISCHANGING" },
      { 785, L"WM_PALETTECHANGED" },
      { 786, L"WM_HOTKEY" },
      { 791, L"WM_PRINT" },
      { 792, L"WM_PRINTCLIENT" },
      { 793, L"WM_APPCOMMAND" },
      { 856, L"WM_HANDHELDFIRST" },
      { 863, L"WM_HANDHELDLAST" },
      { 864, L"WM_AFXFIRST" },
      { 895, L"WM_AFXLAST" },
      { 896, L"WM_PENWINFIRST" },
      { 897, L"WM_RCRESULT" },
      { 898, L"WM_HOOKRCRESULT" },
      { 899, L"WM_GLOBALRCCHANGE" },
      { 899, L"WM_PENMISCINFO" },
      { 900, L"WM_SKB" },
      { 901, L"WM_HEDITCTL" },
      { 901, L"WM_PENCTL" },
      { 902, L"WM_PENMISC" },
      { 903, L"WM_CTLINIT" },
      { 904, L"WM_PENEVENT" },
      { 911, L"WM_PENWINLAST" },
      { 1024, L"WM_USER" }
    };
    
    // 1003 messages
    #define NUM_XMSGS (sizeof(xmsglist) / sizeof(XMSGITEM))
    bool ignore_msg[NUM_XMSGS];
    static int xmsgs_initialized = 0;
    
    #ifdef SHOW_USED_MESSAGES
    int used_freq[NUM_XMSGS];
    #endif
    
    //-------------------------------------------------
    // returns -1 if not found
    int msgid_to_index(unsigned int msg)
    {
      static unsigned int first, cur, last; //138nS
      //register unsigned int first,cur,last;   //173nS
    
      // Use bchop to find message code
      first = 0;
      last = NUM_XMSGS;
    
      while (1)
      {
        cur = (first + last) / 2;
    
        if (msg < xmsglist[cur].code)
        {
          if (cur == last)
            return (-1);          // not found
          else
            last = cur;
        }
        else
        {
          if (msg == xmsglist[cur].code)  //found
          {
            return (cur);
          }
    
          if (cur == first)
            return (-1);          // not found
          else
            first = cur;
        }
      }
    }
    
    //-------------------------------------------------
    #define MAX_XMIGNORES (sizeof(msgs_to_ignore) / sizeof(int))
    
    void initialise_xmsgs(void)
    {
      int msg,index;
      bool invert = 0;
    
      if (msgs_to_ignore[0] == -999) invert = 1;
    
      for (int i = 0; i < NUM_XMSGS; i++)
      {
        ignore_msg[i] = invert; 
    #ifdef SHOW_USED_MESSAGES
        used_freq[i] = 0;
    #endif
      }
    
      for (int i = 0; i < MAX_XMIGNORES; i++)
      {
        msg = msgs_to_ignore[i];
        if (msg == -1) break;
    
        index = msgid_to_index(msg);
        if (index != -1)
        {
          if (index < NUM_XMSGS)
          {
            ignore_msg[index] = invert ^ 1;
          }
          else
          {
            index = NUM_XMSGS;
          }
        }
      }
      xmsgs_initialized = 1;
    }
    
    //-------------------------------------------------
    wchar_t* GetMessageText(unsigned int msg)
    {
      int index;
    
      // Setup ignore list on first call
      if (!xmsgs_initialized)
      {
        initialise_xmsgs();
      }
    
      index = msgid_to_index(msg);
      if (index == -1) return (NULL);//not found - bad msg id
    
    #ifdef SHOW_USED_MESSAGES
      used_freq[index]++;
    #endif
    
      if (ignore_msg[index])
      {
        return (NULL);
      }
      return (xmsglist[index].text);
    }
    
    //-------------------------------------------------
    #ifdef SHOW_USED_MESSAGES
    void ShowUsedMessages(void)
    {
      wchar_t str[1024];
      wchar_t* p = str;
      int count = 0;
      int lastmsg;
    
      // Find last message - to exclude ',' at end
      for (int i = 0; i < NUM_XMSGS; i++)
      {
        if (used_freq[i]) lastmsg = i;
      }
      
      // Pass 1 - output table for inclusion
      OutputDebugString(L"\nint msgs_to_ignore[] = {\n");
    
      for (int i = 0; i < NUM_XMSGS; i++)
      {
        if (used_freq[i])
        {
          p += wsprintf(p, L"0x%X", xmsglist[i].code);
          count++;
    
          if (i == lastmsg)
            count = 8;
          else
            *p++ = ',';
    
          if (count >= 8)
          {
            *p++ = '\n';
            *p++ = '\0';
            OutputDebugString(str);
            p = str;
            count = 0;
          }
        }
      }
      OutputDebugString(L"};\n");
    
      // Pass 2 - add message text and frequencies
      for (int i = 0; i < NUM_XMSGS; i++)
      {
        if (used_freq[i])
        {
          wsprintf(str, L"// 0x%04X - %s (%d)\n", xmsglist[i].code, xmsglist[i].text, used_freq[i]);
          OutputDebugString(str);
        }
      }
    }
    #endif
    
    0 讨论(0)
  • 2020-12-07 02:02

    In visual studio, you can add uMsg,wm in command window or immediate window to get the string representation of the message ID given by uMsg.

    source : http://www.codeguru.com/cpp/v-s/debug/article.php/c1267/Convert-message-ID-to-a-string.htm (comments section)

    PS: This is same link as mentioned in jack's answer. A user had commented there on the link. This technique has helped me very much in debugging Windows messages (no modification and recompilation of code is required), and therefore merits a separate answer.

    0 讨论(0)
  • 2020-12-07 02:06

    Spy++ has a huge message ID lookup table inside its source.

    0 讨论(0)
提交回复
热议问题