Convert Windows Message IDs to Text

☆樱花仙子☆ 提交于 2019-12-30 18:49:14

问题


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 using macros and switch statements (which is a bit of a joke!) but surely there is a run-time means of doing this?

I can't use Spy++ for the scenario I'm trying to debug and I don't want to create a huge table of command IDs and there text - even if it is via a macro. There must be a way to do this - surely Spy++ doesn't have a huge message ID lookup table inside its source???

Cheers Sparky


回答1:


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




回答2:


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.




回答3:


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


来源:https://stackoverflow.com/questions/7252398/convert-windows-message-ids-to-text

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!