SOUI中的消息通信¶
Warning
The current page still doesn't have a translation for this language.
You can read it through google translate.
SOUI作为一个基于Win32 SDK的DirectUI框架,提供了多种消息通信机制。本文将详细介绍SOUI中的各种通信方式。
消息通信类型¶
SOUI框架中主要有三种通信机制:
- 真窗口消息通信
- SOUI控件间通信
- 事件机制
真窗口消息通信¶
发送消息¶
可以使用Win32 API向宿主窗口发送消息:
// 发送自定义消息
::SendMessage(hWndHost, WM_MYMSG, wParam, lParam);
// 或使用PostMessage
::PostMessage(hWndHost, WM_MYMSG, wParam, lParam);
处理消息¶
在宿主窗口的消息映射表中处理消息:
// 自定义消息定义
#define WM_MYMSG (WM_USER+100)
// 消息处理函数
LRESULT OnMyMsg(UINT uMsg, WPARAM wp, LPARAM lp, BOOL& bHandled)
{
// 处理消息
return 0;
}
// 消息映射表(WTL风格)
BEGIN_MSG_MAP_EX(CMainDlg)
MESSAGE_HANDLER(WM_MYMSG, OnMyMsg)
MSG_WM_CREATE(OnCreate)
MSG_WM_DESTROY(OnDestory)
CHAIN_MSG_MAP(SHostWnd)
REFLECT_NOTIFICATIONS_EX()
END_MSG_MAP()
SOUI控件间通信¶
发送消息¶
使用SSendMessage
向SOUI窗口发送消息:
// 发送消息到SOUI窗口
pWindow->SSendMessage(uMsg, wParam, lParam);
注意:SOUI不支持PostMessage机制。
处理消息¶
在SOUI窗口的消息映射表中处理消息:
class SMyWindow : public SWindow
{
protected:
void OnPaint(IRenderTarget *pRT);
void OnLButtonDown(UINT nFlags, CPoint pt);
void OnMouseMove(UINT nFlags, CPoint pt);
SOUI_MSG_MAP_BEGIN()
MSG_WM_PAINT_EX(OnPaint)
MSG_WM_LBUTTONDOWN(OnLButtonDown)
MSG_WM_MOUSEMOVE(OnMouseMove)
SOUI_MSG_MAP_END()
};
常用消息映射宏¶
SOUI宏 | Win32消息 | 说明 |
---|---|---|
MSG_WM_PAINT_EX | WM_PAINT | 绘制消息 |
MSG_WM_ERASEBKGND_EX | WM_ERASEBKGND | 擦除背景 |
MSG_WM_SETFONT_EX | WM_SETFONT | 设置字体 |
事件机制¶
事件定义¶
// 自定义事件参数
class EventMyCustom : public TplEventArgs<EventMyCustom>
{
SOUI_CLASS_NAME(EventMyCustom, L"on_my_custom")
public:
EventMyCustom(SObject *pSender) : TplEventArgs<EventMyCustom>(pSender) {}
int eventData; // 事件数据
};
触发事件¶
void SMyWindow::TriggerCustomEvent()
{
EventMyCustom evt(this);
evt.eventData = 100;
FireEvent(evt);
}
处理事件¶
方式1:事件映射表¶
// 事件处理函数
BOOL OnMyCustomEvent(EventMyCustom *pEvt)
{
int data = pEvt->eventData;
return TRUE;
}
// 事件映射
EVENT_MAP_BEGIN()
EVENT_HANDLER(EventMyCustom::EventID, OnMyCustomEvent)
EVENT_MAP_END()
方式2:事件订阅¶
// 订阅特定窗口的事件
pWindow->subscribeEvent(EventMyCustom::EventID,
[](EventArgs *e)->bool{
EventMyCustom *evt = (EventMyCustom*)e;
// 处理事件
return true;
});
最佳实践¶
1. 选择合适的通信方式¶
- 与宿主窗口通信:使用真窗口消息
- SOUI控件间通信:使用SSendMessage
- 控件状态变化通知:使用事件机制
2. 消息处理注意事项¶
- 消息映射
- 使用正确的映射宏
-
注意消息处理顺序
-
参数传递
- 合理使用wParam/lParam
-
避免传递野指针
-
返回值处理
- 正确设置bHandled
- 返回适当的值
3. 事件处理建议¶
- 事件定义
- 合理设计事件参数
-
使用有意义的事件名
-
事件订阅
- 及时取消不需要的订阅
-
避免循环引用
-
性能优化
- 减少不必要的事件触发
- 优化事件处理逻辑
调试技巧¶
- 消息跟踪
- 使用SPyView跟踪消息
-
打印关键消息信息
-
事件调试
- 设置事件断点
-
跟踪事件传播路径
-
常见问题排查
- 消息没有被处理
- 事件没有触发
- 参数传递错误