上一篇 Windows MFC 全局模态 实现 介绍了一下第一种方法,但是这个方法有个问题是,即使在对话框外不能点击,框外点击鼠标,当前需要操作的窗口也是失去了焦点的。这样用户体验影响比较严重。而且还有个问题是,如果要适配32位、64位系统,要达到全局模态(禁止鼠标效果)需要32、64位两种库,而且要分别被32、64位系统调用。使用条件限制比较严格。
所以这里记录一下使用透明窗口的实现方法:
1、工程中插入一个对话框
2、设置对话框属性 去掉Title bar的勾
3、增加一个OnInitDialog函数,在这个函数里实现后续调用
4、在OnInitDialog内增加设置对话框全屏
<span style="white-space:pre"> </span>CRect m_FullScreenRect; int nFullWidth=GetSystemMetrics(SM_CXSCREEN); int nFullHeight=GetSystemMetrics(SM_CYSCREEN); m_FullScreenRect.left = 0; m_FullScreenRect.top = 0; m_FullScreenRect.right = m_FullScreenRect.left + nFullWidth; m_FullScreenRect.bottom = m_FullScreenRect.top + nFullHeight; MoveWindow(0,0,m_FullScreenRect.Width(),m_FullScreenRect.Height(),1);
5、在OnInitDialog内增加设置对话框透明
<span style="white-space:pre"> </span>typedef BOOL (WINAPI *lpfnSetLayeredWindowAttributes)(HWND hWnd, COLORREF crKey, BYTE bAlpha, DWORD dwFlags); lpfnSetLayeredWindowAttributes SetLayeredWindowAttributes; //设置成边缘透明 COLORREF maskColor=RGB(0,0,0); HMODULE hUser32 = GetModuleHandle(TEXT("user32.dll")); //加载动态链接库 SetLayeredWindowAttributes = (lpfnSetLayeredWindowAttributes)GetProcAddress(hUser32,"SetLayeredWindowAttributes"); //取得SetLayeredWindowAttributes函数指针 //为窗口加入WS_EX_LAYERED扩展属性 SetWindowLong(this->GetSafeHwnd(), GWL_EXSTYLE, GetWindowLong(GetSafeHwnd(), GWL_EXSTYLE)^WS_EX_LAYERED); //调用SetLayeredWinowAttributes函数 SetLayeredWindowAttributes(this->GetSafeHwnd(), maskColor, 1, LWA_ALPHA); // 至少要设置为1透明度,0表示不存在该对话框 FreeLibrary(hUser32); //释放动态链接库6、在需要模态的对话框的原父窗口调用透明全屏框的DoModal
7、在透明全屏框的OnInitDialog最后增加线程调用需要模态的对话框的DoModal。使用线程调用的原因是为了防止阻塞正常弹出全屏透明框
8、在线程调用需要模态框的DoModal之后,增加透明框的退出代码
over
这种方法最需要改善的地方是对话框的封装:假设有多个需要全局模态的对话框,直接继承某个类,就自动成了具有全局模态特性的对话框,而不需要每个对话框单独写代码弄一次。
原文地址:http://blog.csdn.net/lonelyrains/article/details/39297015