返回
软件
分类

在消息映射中,通常使用WM

日期: 2019-11-14 15:57 浏览次数 : 73

VC++ WINDOWS自定义消息范围,vc自定义

WINDOWS自定义消息WM_USER和WM_APP

WM_USER常量是Windows帮助应用程序定义私有窗口类里的私有消息,通常使用WM_USER+一个整数值,但总值不能超过0x7FFF(十进制:32767)。

#define WM_USER       0x0400                  -->1024

WM_APP常量是Windows帮助应用程序定义私有消息,通常使用WM_APP+一个整数值,但总值不能超过0xBFFF(十进制:49151)。

#define WM_APP       0x8000                    -->32768

这两个都定义在WinUser.h中。

范围                                  表示

0 ~ WM_USER–1               操作系统保留的消息。

WM_USER ~  0x7FFF         私有窗口类用的整数型消息。 

WM_APP  ~  0xBFFF           应用程序用的消息。

0xC000 ~ 0xFFFF              应用程序用的字符串消息。

0xFFFF ~                          操作系统保留的消息。

MFC在afxres.h中预定义了一些常用的控制条

#define AFX_在消息映射中,通常使用WM。IDW_TOOLBAR                     0xE800 // main Toolbar for window

#define AFX_IDW_必赢备用网址 ,STATUS_BAR               0xE801 // Status bar window

#define AFX_IDW_PREVIEW_BAR             0xE802 // PrintPreview Dialog Bar

#define AFX_IDW_RESIZE_BAR                0xE803 // OLE in-place resize bar

#define AFX_IDW_REBAR                         0xE804 // COMCTL32 "rebar" Bar

#define AFX_IDW_DIALOGBAR                 0xE805 // CDialogBar

WINDOWS自定义消息范围,vc自定义 WINDOWS自定义消息WM_USER和WM_APP WM_USER常量是Windows帮助应用程序定义私有窗口类里的私有消息,通常使用...

在开发Windows桌面程序,经常会碰到需要使用自定义消息来实现某种功能。通常我们会这样定义一个Windows消息:

各种控件的通知消码和控制消息可由
MSDN-> Platform SDK-> User Interface Services->Windows User Interface->Controls 查得。

这里,我们定义了一个自定义消息WM_CUSTOM_JOB_DONE,该消息用于通知指定的窗口工作已经完成。

Delphi里的Windows消息(一共227个基本消息)

有朋友可能会问了,为什么不是使用WM_USER呢?

  WM_NULL             = $0000;
  WM_CREATE           = $0001;
  WM_DESTROY          = $0002;
  WM_MOVE             = $0003;
  WM_SIZE             = $0005;
  WM_ACTIVATE         = $0006;
  WM_SETFOCUS         = $0007;
  WM_KILLFOCUS        = $0008;
  WM_ENABLE           = $000A;
  WM_SETREDRAW        = $000B;
  WM_SETTEXT          = $000C;
  WM_GETTEXT          = $000D;
  WM_GETTEXTLENGTH    = $000E;
  WM_PAINT            = $000F;
  WM_CLOSE            = $0010;
  WM_QUERYENDSESSION  = $0011;
  WM_QUIT             = $0012;
  WM_QUERYOPEN        = $0013;
  WM_ERASEBKGND       = $0014;
  WM_SYSCOLORCHANGE   = $0015;
  WM_ENDSESSION       = $0016;
  WM_SYSTEMERROR      = $0017;
  WM_SHOWWINDOW       = $0018;
  WM_CTLCOLOR         = $0019;
  WM_WININICHANGE     = $001A;
  WM_SETTINGCHANGE = WM_WININICHANGE;
  WM_DEVMODECHANGE    = $001B;
  WM_ACTIVATEAPP      = $001C;
  WM_FONTCHANGE       = $001D;
  WM_TIMECHANGE       = $001E;
  WM_CANCELMODE       = $001F;
  WM_SETCURSOR        = $0020;
  WM_MOUSEACTIVATE    = $0021;
  WM_CHILDACTIVATE    = $0022;
  WM_QUEUESYNC        = $0023;
  WM_GETMINMAXINFO    = $0024;
  WM_PAINTICON        = $0026;
  WM_ICONERASEBKGND   = $0027;
  WM_NEXTDLGCTL       = $0028;
  WM_SPOOLERSTATUS    = $002A;
  WM_DRAWITEM         = $002B;
  WM_MEASUREITEM      = $002C;
  WM_DELETEITEM       = $002D;
  WM_VKEYTOITEM       = $002E;
  WM_CHARTOITEM       = $002F;
  WM_SETFONT          = $0030;
  WM_GETFONT          = $0031;
  WM_SETHOTKEY        = $0032;
  WM_GETHOTKEY        = $0033;
  WM_QUERYDRAGICON    = $0037;
  WM_COMPAREITEM      = $0039;
  WM_GETOBJECT        = $003D;
  WM_COMPACTING       = $0041;
  WM_WINDOWPOSCHANGING = $0046;
  WM_WINDOWPOSCHANGED = $0047;
  WM_POWER            = $0048;
  WM_COPYDATA         = $004A;
  WM_CANCELJOURNAL    = $004B;
  WM_NOTIFY           = $004E;
  WM_INPUTLANGCHANGEREQUEST = $0050;
  WM_INPUTLANGCHANGE  = $0051;
  WM_TCARD            = $0052;
  WM_HELP             = $0053;
  WM_USERCHANGED      = $0054;
  WM_NOTIFYFORMAT     = $0055;
  WM_CONTEXTMENU      = $007B;
  WM_STYLECHANGING    = $007C;
  WM_STYLECHANGED     = $007D;
  WM_DISPLAYCHANGE    = $007E;
  WM_GETICON          = $007F;
  WM_SETICON          = $0080;
  WM_NCCREATE         = $0081;
  WM_NCDESTROY        = $0082;
  WM_NCCALCSIZE       = $0083;
  WM_NCHITTEST        = $0084;
  WM_NCPAINT          = $0085;
  WM_NCACTIVATE       = $0086;
  WM_GETDLGCODE       = $0087;


  WM_NCMOUSEMOVE      = $00A0;
  WM_NCLBUTTONDOWN    = $00A1;
  WM_NCLBUTTONUP      = $00A2;
  WM_NCLBUTTONDBLCLK  = $00A3;
  WM_NCRBUTTONDOWN    = $00A4;
  WM_NCRBUTTONUP      = $00A5;
  WM_NCRBUTTONDBLCLK  = $00A6;
  WM_NCMBUTTONDOWN    = $00A7;
  WM_NCMBUTTONUP      = $00A8;
  WM_NCMBUTTONDBLCLK  = $00A9;
  WM_NCXBUTTONDOWN    = $00AB;
  WM_NCXBUTTONUP      = $00AC;
  WM_NCXBUTTONDBLCLK  = $00AD;


  WM_INPUT            = $00FF;
  WM_KEYFIRST         = $0100;
  WM_KEYDOWN          = $0100;
  WM_KEYUP            = $0101;
  WM_CHAR             = $0102;
  WM_DEADCHAR         = $0103;
  WM_SYSKEYDOWN       = $0104;
  WM_SYSKEYUP         = $0105;
  WM_SYSCHAR          = $0106;
  WM_SYSDEADCHAR      = $0107;
  WM_KEYLAST          = $0108;

  WM_INITDIALOG       = $0110;
  WM_COMMAND          = $0111;
  WM_SYSCOMMAND       = $0112;
  WM_TIMER            = $0113;
  WM_HSCROLL          = $0114;
  WM_VSCROLL          = $0115; 

  WM_INITMENU         = $0116;
  WM_INITMENUPOPUP    = $0117;
  WM_MENUSELECT       = $011F;
  WM_MENUCHAR         = $0120;
  WM_ENTERIDLE        = $0121;
  WM_MENURBUTTONUP    = $0122;
  WM_MENUDRAG         = $0123;
  WM_MENUGETOBJECT    = $0124;
  WM_UNINITMENUPOPUP  = $0125;
  WM_MENUCOMMAND      = $0126;

  WM_CHANGEUISTATE    = $0127;
  WM_UPDATEUISTATE    = $0128;
  WM_QUERYUISTATE     = $0129;

  WM_CTLCOLORMSGBOX   = $0132;
  WM_CTLCOLOREDIT     = $0133;
  WM_CTLCOLORLISTBOX  = $0134;
  WM_CTLCOLORBTN      = $0135;
  WM_CTLCOLORDLG      = $0136;
  WM_CTLCOLORSCROLLBAR= $0137;
  WM_CTLCOLORSTATIC   = $0138;

  WM_MOUSEFIRST       = $0200;
  WM_MOUSEMOVE        = $0200;
  WM_LBUTTONDOWN      = $0201;
  WM_LBUTTONUP        = $0202;
  WM_LBUTTONDBLCLK    = $0203;
  WM_RBUTTONDOWN      = $0204;
  WM_RBUTTONUP        = $0205;
  WM_RBUTTONDBLCLK    = $0206;
  WM_MBUTTONDOWN      = $0207;
  WM_MBUTTONUP        = $0208;
  WM_MBUTTONDBLCLK    = $0209;
  WM_MOUSEWHEEL       = $020A;
  WM_MOUSELAST        = $020A;

  WM_PARENTNOTIFY     = $0210;
  WM_ENTERMENULOOP    = $0211;
  WM_EXITMENULOOP     = $0212;
  WM_NEXTMENU         = $0213;

  WM_SIZING           = 532;
  WM_CAPTURECHANGED   = 533;
  WM_MOVING           = 534;
  WM_POWERBROADCAST   = 536;
  WM_DEVICECHANGE     = 537;

  WM_IME_STARTCOMPOSITION        = $010D;
  WM_IME_ENDCOMPOSITION          = $010E;
  WM_IME_COMPOSITION             = $010F;
  WM_IME_KEYLAST                 = $010F;
  WM_IME_SETCONTEXT              = $0281;
  WM_IME_NOTIFY                  = $0282;
  WM_IME_CONTROL                 = $0283;
  WM_IME_COMPOSITIONFULL         = $0284;
  WM_IME_SELECT                  = $0285;
  WM_IME_CHAR                    = $0286;
  WM_IME_REQUEST                 = $0288;
  WM_IME_KEYDOWN                 = $0290;
  WM_IME_KEYUP                   = $0291;

  WM_MDICREATE        = $0220;
  WM_MDIDESTROY       = $0221;
  WM_MDIACTIVATE      = $0222;
  WM_MDIRESTORE       = $0223;
  WM_MDINEXT          = $0224;
  WM_MDIMAXIMIZE      = $0225;
  WM_MDITILE          = $0226;
  WM_MDICASCADE       = $0227;
  WM_MDIICONARRANGE   = $0228;
  WM_MDIGETACTIVE     = $0229;
  WM_MDISETMENU       = $0230;

  WM_ENTERSIZEMOVE    = $0231;
  WM_EXITSIZEMOVE     = $0232;
  WM_DROPFILES        = $0233;
  WM_MDIREFRESHMENU   = $0234;

  WM_MOUSEHOVER       = $02A1;
  WM_MOUSELEAVE       = $02A3;
  WM_NCMOUSEHOVER     = $02A0;
  WM_NCMOUSELEAVE     = $02A2;
  WM_WTSSESSION_CHANGE = $02B1;

  WM_TABLET_FIRST     = $02C0;
  WM_TABLET_LAST      = $02DF;

  WM_CUT              = $0300;
  WM_COPY             = $0301;
  WM_PASTE            = $0302;
  WM_CLEAR            = $0303;
  WM_UNDO             = $0304;
  WM_RENDERFORMAT     = $0305;
  WM_RENDERALLFORMATS = $0306;
  WM_DESTROYCLIPBOARD = $0307;
  WM_DRAWCLIPBOARD    = $0308;
  WM_PAINTCLIPBOARD   = $0309;
  WM_VSCROLLCLIPBOARD = $030A;
  WM_SIZECLIPBOARD    = $030B;
  WM_ASKCBFORMATNAME  = $030C;
  WM_CHANGECBCHAIN    = $030D;
  WM_HSCROLLCLIPBOARD = $030E;
  WM_QUERYNEWPALETTE  = $030F;
  WM_PALETTEISCHANGING= $0310;
  WM_PALETTECHANGED   = $0311;
  WM_HOTKEY           = $0312;
  WM_PRINT            = 791;
  WM_PRINTCLIENT      = 792;
  WM_APPCOMMAND       = $0319;
  WM_THEMECHANGED     = $031A;

  WM_HANDHELDFIRST    = 856;
  WM_HANDHELDLAST     = 863;

  WM_PENWINFIRST      = $0380;
  WM_PENWINLAST       = $038F;

  WM_COALESCE_FIRST   = $0390;
  WM_COALESCE_LAST    = $039F;

  WM_DDE_FIRST        = $03E0;
  WM_DDE_INITIATE     = WM_DDE_FIRST + 0;
  WM_DDE_TERMINATE    = WM_DDE_FIRST + 1;
  WM_DDE_ADVISE       = WM_DDE_FIRST + 2;
  WM_DDE_UNADVISE     = WM_DDE_FIRST + 3;
  WM_DDE_ACK          = WM_DDE_FIRST + 4;
  WM_DDE_DATA         = WM_DDE_FIRST + 5;
  WM_DDE_REQUEST      = WM_DDE_FIRST + 6;
  WM_DDE_POKE         = WM_DDE_FIRST + 7;
  WM_DDE_EXECUTE      = WM_DDE_FIRST + 8;
  WM_DDE_LAST         = WM_DDE_FIRST + 8;

  WM_APP = $8000;
  WM_USER             = $0400;

我们先来看看WM_USER和WM_APP的区别:

 

WM_USER:Used to define private messages for use by private window classes.

WM_NULL---0X0000:表示无操作,在消息映射中,如果应用程序试图使接收器对其投递的消息实行忽略处理,则发送WM_NULL类型消息,如果窗体的消息处理函数WindowProc接收到WM_NULL类型消息,则忽略掉。
0X0001----0X0087:窗口消息,例如WM_SIZE、WM_PAINT、WM_ERASEBKGND等。
0X00A0----0X00A9:非客户区消息,例如WM_NCMOUSEMOVE、WM_NCLBUTTONDBLCLK、WM_NCRBUTTONUP等。
0X0100----0X0108:键盘消息,例如WM_KEYDOWN、WM_KEYFIRST、WM_CHAR、WM_SYSCHAR等。
0X0111----0X0112:菜单命令,例如WM_COMMAND、WM_SYSCOMMAND。0X0132----0x0132----0x0138:颜色控制消息,例如WM_CTLCOLORMSGBOX、WM_CTLCOLORLISTBOX、WM_CTLCOLORDLG等。
0X0200----0X020A:鼠标消息,例如WM_LBUTTONUP、WM_RBUTTONUP等。
0X0211----0X0213:菜单循环消息,例如WM_ENTERMENULOOP、WM_EXITMENULOOP等。
0X0220----0X0230:多文档消息,例如WM_MDICREATE、WM_MDIDESTROY等。
0X03E0----0X03E8:DDE消息,例如WM_PASTE、WM_CLEAR、WM_UNDO等。
0X0400:用户自定义消息的起点,WM_USER,以WM_USER + N形式出现。
0X8000:用户自定义消息的起点,WM_APP,以WM_APP + N形式出现。附属控件的专用消息

WM_APP: Used to define private messages.

参考:

好像区别还是不明显。但是,MSDN中有这样一句话:

  BN_CLICKED       = 0;
  BN_PAINT         = 1;
  BN_HILITE        = 2;
  BN_UNHILITE      = 3;
  BN_DISABLE       = 4;
  BN_DOUBLECLICKED = 5;
  BN_PUSHED = BN_HILITE;
  BN_UNPUSHED = BN_UNHILITE;
  BN_DBLCLK = BN_DOUBLECLICKED;
  BN_SETFOCUS = 6;
  BN_KILLFOCUS = 7;

  BM_GETCHECK = $00F0;
  BM_SETCHECK = $00F1;
  BM_GETSTATE = $00F2;
  BM_SETSTATE = $00F3;
  BM_SETSTYLE = $00F4;
  BM_CLICK    = $00F5;
  BM_GETIMAGE = $00F6;
  BM_SETIMAGE = $00F7;

  LBN_ERRSPACE  = (-2);
  LBN_SELCHANGE = 1;
  LBN_DBLCLK    = 2;
  LBN_SELCANCEL = 3;
  LBN_SETFOCUS  = 4;
  LBN_KILLFOCUS = 5;

  LB_ADDSTRING            = $0180;
  LB_INSERTSTRING         = $0181;
  LB_DELETESTRING         = $0182;
  LB_SELITEMRANGEEX       = $0183;
  LB_RESETCONTENT         = $0184;
  LB_SETSEL               = $0185;
  LB_SETCURSEL            = $0186;
  LB_GETSEL               = $0187;
  LB_GETCURSEL            = $0188;
  LB_GETTEXT              = $0189;
  LB_GETTEXTLEN           = $018A;
  LB_GETCOUNT             = $018B;
  LB_SELECTSTRING         = $018C;
  LB_DIR                  = $018D;
  LB_GETTOPINDEX          = $018E;
  LB_FINDSTRING           = $018F;
  LB_GETSELCOUNT          = $0190;
  LB_GETSELITEMS          = $0191;
  LB_SETTABSTOPS          = $0192;
  LB_GETHORIZONTALEXTENT  = $0193;
  LB_SETHORIZONTALEXTENT  = $0194;
  LB_SETCOLUMNWIDTH       = $0195;
  LB_ADDFILE              = $0196;
  LB_SETTOPINDEX          = $0197;
  LB_GETITEMRECT          = $0198;
  LB_GETITEMDATA          = $0199;
  LB_SETITEMDATA          = $019A;
  LB_SELITEMRANGE         = $019B;
  LB_SETANCHORINDEX       = $019C;
  LB_GETANCHORINDEX       = $019D;
  LB_SETCARETINDEX        = $019E;
  LB_GETCARETINDEX        = $019F;
  LB_SETITEMHEIGHT        = $01A0;
  LB_GETITEMHEIGHT        = $01A1;
  LB_FINDSTRINGEXACT      = $01A2;
  LB_SETLOCALE            = $01A5;
  LB_GETLOCALE            = $01A6;
  LB_SETCOUNT             = $01A7;
  LB_INITSTORAGE          = $01A8;
  LB_ITEMFROMPOINT        = $01A9;
  LB_MSGMAX               = 432;

  CBN_ERRSPACE   = (-1);
  CBN_SELCHANGE  = 1;
  CBN_DBLCLK     = 2;
  CBN_SETFOCUS   = 3;
  CBN_KILLFOCUS  = 4;
  CBN_EDITCHANGE = 5;
  CBN_EDITUPDATE = 6;
  CBN_DROPDOWN   = 7;
  CBN_CLOSEUP    = 8;
  CBN_SELENDOK   = 9;
  CBN_SELENDCANCEL = 10;

  CB_GETEDITSEL            = $0140;
  CB_LIMITTEXT             = $0141;
  CB_SETEDITSEL            = $0142;
  CB_ADDSTRING             = $0143;
  CB_DELETESTRING          = $0144;
  CB_DIR                   = $0145;
  CB_GETCOUNT              = $0146;
  CB_GETCURSEL             = $0147;
  CB_GETLBTEXT             = $0148;
  CB_GETLBTEXTLEN          = $0149;
  CB_INSERTSTRING          = $014A;
  CB_RESETCONTENT          = $014B;
  CB_FINDSTRING            = $014C;
  CB_SELECTSTRING          = $014D;
  CB_SETCURSEL             = $014E;
  CB_SHOWDROPDOWN          = $014F;
  CB_GETITEMDATA           = $0150;
  CB_SETITEMDATA           = $0151;
  CB_GETDROPPEDCONTROLRECT = $0152;
  CB_SETITEMHEIGHT         = $0153;
  CB_GETITEMHEIGHT         = $0154;
  CB_SETEXTENDEDUI         = $0155;
  CB_GETEXTENDEDUI         = $0156;
  CB_GETDROPPEDSTATE       = $0157;
  CB_FINDSTRINGEXACT       = $0158;
  CB_SETLOCALE             = 345;
  CB_GETLOCALE             = 346;
  CB_GETTOPINDEX           = 347;
  CB_SETTOPINDEX           = 348;
  CB_GETHORIZONTALEXTENT   = 349;
  CB_SETHORIZONTALEXTENT   = 350;
  CB_GETDROPPEDWIDTH       = 351;
  CB_SETDROPPEDWIDTH       = 352;
  CB_INITSTORAGE           = 353;
  CB_MSGMAX                = 354;

  EN_SETFOCUS  = $0100;
  EN_KILLFOCUS = $0200;
  EN_CHANGE    = $0300;
  EN_UPDATE    = $0400;
  EN_ERRSPACE  = $0500;
  EN_MAXTEXT   = $0501;
  EN_HSCROLL   = $0601;
  EN_VSCROLL   = $0602;

  EM_GETSEL              = $00B0;
  EM_SETSEL              = $00B1;
  EM_GETRECT             = $00B2;
  EM_SETRECT             = $00B3;
  EM_SETRECTNP           = $00B4;
  EM_SCROLL              = $00B5;
  EM_LINESCROLL          = $00B6;
  EM_SCROLLCARET         = $00B7;
  EM_GETMODIFY           = $00B8;
  EM_SETMODIFY           = $00B9;
  EM_GETLINECOUNT        = $00BA;
  EM_LINEINDEX           = $00BB;
  EM_SETHANDLE           = $00BC;
  EM_GETHANDLE           = $00BD;
  EM_GETTHUMB            = $00BE;
  EM_LINELENGTH          = $00C1;
  EM_REPLACESEL          = $00C2;
  EM_GETLINE             = $00C4;
  EM_LIMITTEXT           = $00C5;
  EM_CANUNDO             = $00C6;
  EM_UNDO                = $00C7;
  EM_FMTLINES            = $00C8;
  EM_LINEFROMCHAR        = $00C9;
  EM_SETTABSTOPS         = $00CB;
  EM_SETPASSWORDCHAR     = $00CC;
  EM_EMPTYUNDOBUFFER     = $00CD;
  EM_GETFIRSTVISIBLELINE = $00CE;
  EM_SETREADONLY         = $00CF;
  EM_SETWORDBREAKPROC    = $00D0;
  EM_GETWORDBREAKPROC    = $00D1;
  EM_GETPASSWORDCHAR     = $00D2;
  EM_SETMARGINS          = 211;
  EM_GETMARGINS          = 212;
  EM_SETLIMITTEXT        = EM_LIMITTEXT;    //win40 Name change
  EM_GETLIMITTEXT        = 213;
  EM_POSFROMCHAR         = 214;
  EM_CHARFROMPOS         = 215;
  EM_SETIMESTATUS        = 216;
  EM_GETIMESTATUS        = 217;

  SBM_SETSCROLLINFO = 233;
  SBM_GETSCROLLINFO = 234;

  DM_GETDEFID = (WM_USER+0);
  DM_SETDEFID = (WM_USER+1);
  DM_REPOSITION = (WM_USER+2);

  PSM_PAGEINFO = (WM_USER+100);
  PSM_SHEETINFO = (WM_USER+101);

Message numbers in the second range (WM_USER through 0x7FFF) can be defined and used by an application to send messages within a private window class. These values cannot be used to define messages that are meaningful throughout an application because some predefined window classes already define values in this range.For example, predefined control classes such as BUTTON, EDIT, LISTBOX, and COMBOBOX may use these values.

// 消息定义

也即,虽然可以使用WM_USER定义消息,但是只能用于私有的窗口,而不可以使用它在整个应用程序范围下定义具有明确含义(比如系统已经预定义的)的消息。因为一些系统控件会使用它定义它们需要的一些消息。

用户自定义的消息, 对于其范围有如下规定: 
WM_USER: 0x0400-0x7FFF      (ex. WM_USER+10) 
WM_APP(winver> 4.0): 0x8000-0xBFFF (ex.WM_APP+4) 
RegisterWindowMessage: 0xC000-0xFFFF

而WM_APP呢,此消息就是用来区分应用程序消息和系统消息的,使用WM_APP可以确保定义的消息不会和系统消息冲突。所以,以上的WM_CUSTOM_JOB_DONE定义中,我们使用了WM_APP。

接下来,第二个问题:我们可能会定义很多自定义消息,比如:

必赢备用网址 1

我们需要手动的对新定义消息自增1,有没有一种自动化的方法呢?有!

感谢强大的boost preprocessor库为我们提供了一个自增宏BOOST_PP_COUNTER。我们可以像如下的方式将消息定义自动化起来:

必赢备用网址 2

这样,我们每次新增一个新消息,只需要复制2行,然后修改消息名称就可以了,不再需要对每个消息手动自增1了。

另外请注意,使用以上方法定义消息,需要添加对boost库的counter_include.hpp头文件的引用。

再次感谢boost!终于可以愉快的定义Windows消息了。