DUilib是一个轻量级的跨平台UI库,它基于DirectUI技术提供了一套简单易用的消息映射机制。这种机制允许开发者通过发送预定义的消息到特定的对象,来触发对象内部相应的处理函数,即响应事件。DUilib的消息映射通常包含以下几个步骤:
-
消息注册: 开发者需要给控件或者自定义组件注册它们能够接收和处理的消息。这通常是通过设置控件的
OnEventProc
成员函数来完成。 -
消息传递: 当用户操作或系统事件发生时,DUilib会自动将对应的消息传递给相应的对象。例如,点击按钮时,会发送一个
BTN_CLICKED
消息。 -
消息处理: 对象接收到消息后,会检查其是否实现了该消息对应的回调函数(比如
OnBtnClicked()
)。如果存在,则执行相应功能;如果没有,消息可能会默认忽略或向上级容器冒泡。 -
回调函数: 回调函数内可以编写各种业务逻辑,如更新界面状态、数据交互等。
// 程序入口及Duilib初始化部分
int APIENTRY WinMain(HINSTANCE hInstance, HINSTANCE /*hPrevInstance*/, LPSTR /*lpCmdLine*/, int nCmdShow)
{
// 加载资源
DuilibResourceInit::InitInstance(hInstance, UILIB_ZIP, L"");
DuilibResourceInit::Load();
//创建主窗口
TsetControl* pFrame = new TsetControl();
pFrame->Create(NULL, L"example", UI_WNDSTYLE_FRAME^WS_THICKFRAME, WS_EX_WINDOWEDGE);
pFrame->CenterWindow();
pFrame->ShowWindow(true);
CPaintManagerUI::MessageLoop();
return 0;
}
DuiLib的消息渠,也就是所谓的消息循环在CPaintManagerUI::MessageLoop()或者CWindowWnd::ShowModal()中实现。俩套代码的核心基本一致,以MessageLoop为例:
voidCPaintManagerUI::MessageLoop()
{
MSGmsg = { 0 };
while( ::GetMessage(&msg, NULL, 0, 0) ) {
// CPaintManagerUI::TranslateMessage进行消息过滤
if( !CPaintManagerUI::TranslateMessage(&msg) ) {
::TranslateMessage(&msg);
try{
::DispatchMessage(&msg);
} catch(...) {
DUITRACE(_T("EXCEPTION: %s(%d)\n"), __FILET__, __LINE__);
#ifdef_DEBUG
throw"CPaintManagerUI::MessageLoop";
#endif
}
}
}
}
1.发送消息
m_pManager->SendNotify(this, DUI_MSGTYPE_CLICK);
2.注册消息函数
DUI_BEGIN_MESSAGE_MAP(WindowImplBase, CNotifyPump)//CNotifyPump子类,WindowImplBase基类
DUI_ON_MSGTYPE(DUI_MSGTYPE_CLICK,OnClick)
DUI_END_MESSAGE_MAP()
3.消息响应函数
void WindowImplBase::OnClick(TNotifyUI& msg)
{
CDuiString sCtrlName = msg.pSender->GetName();
if( sCtrlName == _T("closebtn") ) {
Close();
return;
}
else if( sCtrlName == _T("minbtn")) {
SendMessage(WM_SYSCOMMAND, SC_MINIMIZE, 0);
return;
}
else if( sCtrlName == _T("maxbtn")) {
SendMessage(WM_SYSCOMMAND, SC_MAXIMIZE, 0);
return;
}
else if( sCtrlName == _T("restorebtn")) {
SendMessage(WM_SYSCOMMAND, SC_RESTORE, 0);
return;
}
return;
}
// Structure for notifications to the outside world结构用于向外部世界发出通知
typedef struct tagTNotifyUI
{
CDuiString sType;//操作类型
CDuiString sVirtualWnd;//虚拟窗口
CControlUI* pSender;//控件发送者
DWORD dwTimestamp;//发送时间
POINT ptMouse;//鼠标位置
WPARAM wParam;//参数1
LPARAM lParam;//参数2
} TNotifyUI;