Windows MFC 全局模态 实现 (二)

        上一篇 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


工程源码

这种方法最需要改善的地方是对话框的封装:假设有多个需要全局模态的对话框,直接继承某个类,就自动成了具有全局模态特性的对话框,而不需要每个对话框单独写代码弄一次。


Windows MFC 全局模态 实现 (二)

上一篇:DirectX 9.0c游戏开发手记之RPG编程自学日志之十 ——Drawing with DirectX Graphics (用DirectX图形绘图)(第4节)(C)


下一篇:Windows判断是否为管理员