Konverter Windows-meddelelses-id'er til tekst

Indlæg af Hanne Mølgaard Plasc

Problem



Er der et skjult/ikke-dokumenteret API-opkald i Windows, der konverterer et besked-id (f.eks. WM\_COMMAND) til tekst?


Jeg har set forslag til, hvordan man opnår dette ved hjælp af makroer og switch statements (hvilket er lidt af en vittighed!) Men der er sikkert en run-time måde at gøre dette på?


Jeg kan ikke bruge Spy ++ til det scenario, jeg prøver at fejle, og jeg ønsker ikke at oprette et stort bord med kommandoen ID'er og der tekst - selvom det er via en makro. Der skal være en måde at gøre dette på - Sikkert Spy ++ har ikke et stort meddelelses-ID opslagstavle inde i sin kilde ???


Skål
Sparky

Bedste reference


Spy ++ har et stort meddelelses ID opslagstabel inde i sin kilde.

Andre referencer 1


I visuel studie kan du tilføje uMsg,wm i kommandovindue eller direkte vindue for at få strengepræsentationen af ​​meddelelses-id'et givet af uMsg.


kilde: http://www.codeguru.com/cpp/v-s/debug/article.php/c1267/Convert-message-ID-to-a-string.htm (kommentarer sektion) [4]


PS: Dette er samme link som nævnt i jacks svar. En bruger havde kommenteret der på linket. Denne teknik har hjulpet mig meget i debugging Windows-meddelelser (ingen ændring og genkompilering af kode er påkrævet) og fortjener derfor en separat svaret.

Andre referencer 2


Herefter er koden til at konvertere WM\_ og andre Win32-meddelelseskoder til tekst. Inkluderer muligheder for at ignorere visse meddelelser (f.eks. WM\_MOUSEMOVE) og at dumpe en liste over meddelelser modtaget i slutningen. (NB: Denne liste går kun op til 1024 (WM\_USER) på grund af 30K-grænsen på denne boks. Der er også mange duplikater i listen derefter.)


// 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)
", msg, win\_msgtext);
        wsprintf(str, L"WndProc: msg = \%x (\%s)
", 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"
int msgs\_to\_ignore[] = {
");

    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++ = '
';
                *p++ = '';
                OutputDebugString(str);
                p = str;
                count = 0;
            }
        }
    }
    OutputDebugString(L"};
");

    // 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)
", xmsglist[i].code, xmsglist[i].text, used\_freq[i]);
            OutputDebugString(str);
        }
    }
}
#endif