windows自定义消息

Windows 应用程序所要做的每项工作几乎都是基于消息处理的, Windows 系统消息分为常用 Windows 消息,控件通知消息和命令。然而,有时我们需要定义自己的消息来通知程序什么事情发生了,这就是用户自定义消息。 ClassWizard 并没有提供增加用户自定义消息的功能,所以要使用用户自定义消息,必须手工编写代码。然后 ClassWizard 才可以象处理其它消息一样处理你自定义的消息。具体做法如下详解: 

   第一步:定义消息。一个消息实际上是开发 Windows95 应用程序时, Microsoft 推荐用户自定义消息至少是 WM_USER+100 ,因为很多新控件也要使用 WM_USER 消息。 

   第二步:实现消息处理函数。该函数使用 WPRAM 和 LPARAM 参数并返回 LPESULT 。 

   LPESULT CMainFrame::OnMyMessage(WPARAM wParam, LPARAM lParam){// TODO: 处理用户自定义消息 AfxMessageBox(" 处理用户自定义消息 "); return 0;} 

   第三步:在类头文件的 AFX_MSG 块中说明消息处理函数: 
   class CMainFrame:public CMDIFrameWnd{

   ...

   // 一般消息映射函数 

   protected:

   // {{AFX_MSG(CMainFrame)

   afx_msg int OnCreate(LPCREATESTRUCT lpCreateStruct);

   afx_msg void OnTimer(UINT nIDEvent);

   afx_msg LRESULT OnMyMessage(WPARAM wParam, LPARAM lParam);

   //}}AFX_MSG

   DECLARE_MESSAGE_MAP()}


   第四步:在用户类的消息块中,使用 ON_MESSAGE 宏指令将消息映射到消息处理函数中。 
   BEGIN_MESSAGE_MAP(CMainFrame, CMDIFrameWnd)

   //{{AFX_MSG_MAP(CMainFrame)

   ON_WM_CREATE()

   ON_WM_TIMER()

   ON_MESSAGE(WM_MY_MESSAGE, OnMyMessage)

   //}}AFX_MSG_MAPEND_MESSAGE_MAP()


   这样,一个用户自定义消息就可以使用了,如果用户需要一个整个系统唯一的消息,可以调用 SDK 函数 RegisterWindowMessage 并使用 ON_REGISTER_MESSAGE 宏指令取代 ON_MESSAGE 宏指令,其余步骤同上。 

 

现在.cpp文件的顶端
#define WM_MYMESSAGE WM_USER+100
在到.h文件的
//{{AFX_MSG(CMyDlg) //自动生成的
afx_msg void OnMyMessage(); //你要填写的
//}}AFX_MSG         //自动生成的。
在到.cpp文件中
BEGIN_MESSAGE_MAP(CMyDlg, CDialog) //自动生成的
//{{AFX_MSG_MAP(CMyDlg)//自动生成的
ON_MESSAGE(WM_MYMESSAGE, OnMyMessage) //你要填写的
//}}AFX_MSG_MAP//自动生成的
END_MESSAGE_MAP() //自动生成的

然后定义函数
void CMyDlg::OnMyMessage()
{
       AfxMessageBox("this is my message") ;
}

最后就是发消息了,如果不用API
就SendMessage(WM_MYMESSAGE, 0, 0 );
如果用API
就SendMessage(窗口句柄,WM_MYMESSAGE, 0 , 0)

<think>我们正在查询Windows自定义消息的范围。根据引用内容,我们得知: - 系统定义消息的范围是0x0000到0x03FF(即0到WM_USER-1)。 - 用户自定义消息的范围从0x0400(即WM_USER)到0x7FFF(引用[1]中提到0x0400到0x7FFF是为用户保留的)。 另外,引用[3]也提到了WM_USER消息(虽然标注已过时)和WM_APP消息,以及注册窗口消息注册窗口消息可以保证全局唯一,通常使用RegisterWindowMessage函数,其范围在0xC000到0xFFFF之间。 总结: 1. 用户自定义消息的第一种方式:使用WM_USER到0x7FFF的范围。WM_USER定义为0x0400,所以范围是0x0400 (1024) 到 0x7FFF (32767)。 2. 应用程序全局消息(使用RegisterWindowMessage注册):范围从0xC000 (49152) 到 0xFFFF (65535)。这种消息在系统中是唯一的,不同应用程序注册相同的字符串会得到相同的消息值,因此适合进程间通信。 注意:引用[1]提到消息总范围为0x0000到0xFFFF(0-65535),所以自定义消息不能超出这个范围。 因此,回答如下: 在Windows系统中,自定义消息的范围分为两个区域: 1. **应用程序私有消息(WM_USER区域)**: - 范围:`WM_USER` (0x0400) 到 0x7FFF(即1024到32767) - 说明:此范围内的消息由应用程序内部使用,不同应用程序可以重复使用相同的消息值而不会冲突,但仅限于同一应用程序内。 2. **全局注册消息(RegisterWindowMessage区域)**: - 范围:0xC000 到 0xFFFF(即49152到65535) - 说明:通过`RegisterWindowMessage`函数注册消息。该函数接收一个字符串参数,系统会为这个字符串生成一个唯一的消息ID。如果两个应用程序注册相同的字符串,将返回相同的消息ID,因此适合跨进程通信[^3]。 需要避免使用系统消息范围(0x0000到0x03FF)和未定义区域(0x8000到0xBFFF)。 补充示例代码(自定义消息处理): 根据引用[2],在窗口过程中处理自定义消息: ```cpp #define WM_MY_MESSAGE (WM_USER + 100) // 在WM_USER范围内定义 LRESULT CALLBACK WindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam) { switch (uMsg) { case WM_MY_MESSAGE: // 处理自定义消息 printf("Received WM_MY_MESSAGE with parameters: %d, %d\n", wParam, lParam); return 0; // ... 其他消息处理 } return DefWindowProc(hwnd, uMsg, wParam, lParam); } ``` 对于跨进程通信,推荐使用`RegisterWindowMessage`或`WM_COPYDATA`(引用[3]和[4]): ```cpp // 注册全局消息 UINT WM_GLOBAL_MESSAGE = RegisterWindowMessage(TEXT("MyGlobalMessage")); // 发送消息 PostMessage(hWndTarget, WM_GLOBAL_MESSAGE, 0, 0); ``` 注意事项: - 使用`WM_USER`定义的消息仅在同一进程内有效,跨进程发送可能因接收方未定义相同消息而无法处理。 - 使用`RegisterWindowMessage`注册消息ID是动态分配的,因此需要用变量保存,不可硬编码。 相关问题: 1. 如何通过自定义消息实现跨进程通信? 2. 使用`RegisterWindowMessage`注册消息时需要注意什么? 3. 在Windows中,消息处理函数如何安全地处理自定义消息? </think>### Windows自定义消息范围详解 根据引用内容,Windows自定义消息的范围可分为三个主要区域: 1. **WM_USER 消息范围** - 范围:`0x0400` (WM_USER) 到 `0x7FFF` (32767) - 特性: - 应用程序私有范围(每个应用独立) - 通过`#define`宏定义使用,例如: ```cpp #define WM_MY_MESSAGE (WM_USER + 100) // 0x0400 + 100 = 0x0464 ``` - 仅限同一进程内通信[^1][^2] 2. **WM_APP 消息范围** - 范围:`0x8000` (32768) 到 `0xBFFF` (49151) - 特性: - 新版替代WM_USER消息范围 - 允许多模块共享(同一进程内) - 定义示例: ```cpp #define WM_APP_MESSAGE (WM_APP + 200) ``` 3. **注册窗口消息范围** - 范围:`0xC000` (49152) 到 `0xFFFF` (65535) - 特性: - 通过`RegisterWindowMessage()`注册 - 全局唯一(跨进程有效) - 使用字符串标识符保证唯一性[^3]: ```cpp UINT WM_CROSS_PROCESS = RegisterWindowMessage(L"MyAppMessage"); ``` ### 关键区分(图示) ``` 0x0000 ────────┬──────────────┬──────────────┬───────────▶ 0xFFFF │ │ │ │ 系统消息 WM_USER范围 WM_APP范围 注册消息范围 (0-0x03FF) (0x0400-7FFF) (0x8000-BFFF) (0xC000-FFFF) │ │ │ 同一进程内 多模块共享 跨进程通信 ``` ### 使用注意事项 1. **避免冲突** 永远不要使用`0x0000-0x03FF`的系统保留区[^1] 2. **跨进程通信** 优先使用`RegisterWindowMessage`或`WM_COPYDATA`[^3][^4] 3. **消息处理示例** ```cpp // 接收端处理自定义消息 LRESULT CALLBACK WndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam) { switch(msg) { case WM_MY_MESSAGE: // WM_USER范围消息 printf("收到消息参数: %d, %d\n", wParam, lParam); return 1; // 返回值给发送方 ... } return DefWindowProc(hWnd, msg, wParam, lParam); } [^2] ``` > 重要原则: > - **WM_USER**:同一EXE文件内通信 > - **WM_APP**:同一进程内多DLL通信 > - **注册消息**:跨进程/全局通信
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值