概述
在做界面程序的过程中,我们经常会遇到模态对话框(这个名词没必要在解释了吧,不懂就别看这篇文章了)。因此这点还是很有必要拿出来说明下的,不然不知道怎么实现,说不清其原理还是挺可悲的。
在windows中,使用DialogBoxParam显示的对话框就是模态的,ATL中也用了该函数进行了封装。虽然模态对话框在windows中很普遍,但是并没有SDK级别的API,可以将一个窗口变为模态显示。
我们知道windows系统是依靠windows消息分发与响应来驱动UI交互的。有一种想法就是能够让代码停留在Domodal()中,同时不相关的窗口消息也不会被阻塞,这样就能简易的实现模态了。有什么方法可以实现上面的方案呢?答案就是接管默认的消息循环。即在DoModal()内部实现一个自己的GetMessage循环,这样直到模态框退出了才能够进入默认的消息循环继续分发消息。另外还要注意一点,弹出的模态窗口的父窗口hParent也需要对应设置。
下面就按照我们上面的阻塞的思路给出一种实现。
class ModelWindow : public XWindowImpl<ModelWindow>
{
XButton m_btn;
bool m_bClose;
public:
DECLARE_XWNDCLASS(L"ModelWindow")
public:
ModelWindow()
{
m_bClose = false;
}
public:
LRESULT ProcessXWndMessage(UINT uMsg, WPARAM wParam, LPARAM lParam)
{
switch(uMsg)
{
case WM_CLOSE:
DestroyWindow();
m_bClose = true;
break;
default:
return ::DefWindowProc(this->m_hWnd, uMsg, wParam, lParam);
}
return 0;
}
public:
void DoModal(HWND hParent)
{
ShowWindow(SW_SHOW);
UpdateWindow();
// disable掉父窗口,让其不再接受消息
HWND hParentWnd = hParent;
while(hParentWnd != NULL)
{
EnableWindow(hParentWnd, FALSE);
hParentWnd = GetParent(hParentWnd);
}
// 主消息循环:
MSG msg;
while (GetMessage(&msg, NULL, 0, 0))
{
if (m_bClose)
{
break;
}
TranslateMessage(&msg);
DispatchMessage(&msg);
}
// 恢复父窗口enable状态
hParentWnd = hParent;
while(hParentWnd != NULL)
{
EnableWindow(hParentWnd, TRUE);
hParentWnd = GetParent(hParentWnd);
}
}
};
SimpleWindow窗口按钮响应的地方可以创建一个模态窗口:
case WM_COMMAND:
if (wParam == 2013)
{
ModelWindow simWnd2;
simWnd2.Create(L"模态窗口",&rc, m_hWnd);
simWnd2.DoModal(m_hWnd);
HDC dc = ::GetDC(m_hWnd);
CString strInfo(L"You have pushed the button");
TextOut(dc,20,100,strInfo, strInfo.GetLength());
}
运行结果发现基本上满足了我们的需求。
最后
以上就是碧蓝导师为你收集整理的跟我一起学Windows界面封装(六) 之 模态对话框原理的全部内容,希望文章能够帮你解决跟我一起学Windows界面封装(六) 之 模态对话框原理所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
发表评论 取消回复