相信用电脑看过电影的人都会下意识的默认双击一个播放器就会得到全屏播放影片的效果,那这个是怎么做到的呢?其实本人也是不知道的。。当然这篇文章不是到这就完了,而是介绍一种在MFC上全屏显示窗口或者PICTURE控件的方法,用此方法能做到全屏显示图像的效果,当然好坏还是有待考证的。
首先从简单的着手,来看如何实现MFC窗口的全屏显示,废话不说上代码:
在对话框头文件中添加变量:
[cpp] view plain copy
-
- private:
- BOOL bFullScreen;
- CRect rectFullScreen;
- WINDOWPLACEMENT m_struOldWndpl;
添加对话框的鼠标左键双击处理函数,并添加如下代码:
[cpp] view plain copy
- if (!bFullScreen)
- {
-
- int g_iCurScreenWidth = GetSystemMetrics(SM_CXSCREEN);
- int g_iCurScreenHeight = GetSystemMetrics(SM_CYSCREEN);
-
-
- GetWindowPlacement(&m_struOldWndpl);
-
-
- CRect rectWholeDlg;
- CRect rectClient;
- GetWindowRect(&rectWholeDlg);
- RepositionBars(0, 0xffff, AFX_IDW_PANE_FIRST, reposQuery, &rectClient);
- ClientToScreen(&rectClient);
- rectFullScreen.left = rectWholeDlg.left - rectClient.left;
- rectFullScreen.top = rectWholeDlg.top - rectClient.top;
- rectFullScreen.right = rectWholeDlg.right + g_iCurScreenWidth - rectClient.right;
- rectFullScreen.bottom = rectWholeDlg.bottom + g_iCurScreenHeight - rectClient.bottom;
-
-
- WINDOWPLACEMENT struWndpl;
- struWndpl.length = sizeof(WINDOWPLACEMENT);
- struWndpl.flags = 0;
- struWndpl.showCmd = SW_SHOWNORMAL;
- struWndpl.rcNormalPosition = rectFullScreen;
- SetWindowPlacement(&struWndpl);
- bFullScreen = true;
- }
- else
- {
- SetWindowPlacement(&m_struOldWndpl);
- bFullScreen = false;
- }
OK,到处窗口客户区全屏显示就完成一大部分了,运行一下双击窗口就会全屏显示窗口客户区,再双击则返回之前的窗体。
为什么说只是完成一大部分呢?原因在于现在的全屏还不是真正意义上的全屏,在目前的情况下双击全屏会发现底部开始菜单栏和右边一部分屏幕并没有被覆盖,究其原因是因为当窗体做出调整大小之类的操作时Windows会首先发送WM_GETMINMAXINFO消息,该消息在默认的缺省处理中是不允许窗体大小大于屏幕大小的。为此,我们要修改这个消息的响应函数,即主动为窗体添加WM_GETMINMAXINFO消息的处理函数,实现如下:
[cpp] view plain copy
- void CShowPictureInFullScreenDlg::OnGetMinMaxInfo(MINMAXINFO* lpMMI)
- {
-
- if (bFullScreen)
- {
- lpMMI->ptMaxSize.x = rectFullScreen.Width();
- lpMMI->ptMaxSize.y = rectFullScreen.Height();
- lpMMI->ptMaxPosition.x = rectFullScreen.left;
- lpMMI->ptMaxPosition.y = rectFullScreen.top;
- lpMMI->ptMaxTrackSize.x = rectFullScreen.Width();
- lpMMI->ptMaxTrackSize.y = rectFullScreen.Height();
- }
-
- CDialogEx::OnGetMinMaxInfo(lpMMI);
- }
到此,全屏显示窗口客户区的功能就完成了。如果仔细观察了上面所写的代码,会轻易的发现其中最为关键的一句为
[cpp] view plain copy
- SetWindowPlacement(&struWndpl);
如果我们把窗口客户区变为全屏大小之后将PICTURE控件调整大小填满整个客户区并且隐藏掉其他的控件,则可以得到全屏显示的图片。实现如下:
添加一个类变量存储PICTURE控件原位置信息
[cpp] view plain copy
- WINDOWPLACEMENT m_struOldWndpPic;
修改对话框的鼠标左键双击处理函数
[cpp] view plain copy
- if (!bFullScreen)
- {
- bFullScreen = true;
-
-
- int g_iCurScreenWidth = GetSystemMetrics(SM_CXSCREEN);
- int g_iCurScreenHeight = GetSystemMetrics(SM_CYSCREEN);
-
-
- GetWindowPlacement(&m_struOldWndpl);
- GetDlgItem(IDC_STATIC_PICSHOW)->GetWindowPlacement(&m_struOldWndpPic);
-
-
- CRect rectWholeDlg;
- CRect rectClient;
- GetWindowRect(&rectWholeDlg);
- RepositionBars(0, 0xffff, AFX_IDW_PANE_FIRST, reposQuery, &rectClient);
- ClientToScreen(&rectClient);
-
-
- rectFullScreen.left = rectWholeDlg.left - rectClient.left;
- rectFullScreen.top = rectWholeDlg.top - rectClient.top;
- rectFullScreen.right = rectWholeDlg.right + g_iCurScreenWidth - rectClient.right;
- rectFullScreen.bottom = rectWholeDlg.bottom + g_iCurScreenHeight - rectClient.bottom;
-
-
- WINDOWPLACEMENT struWndpl;
- struWndpl.length = sizeof(WINDOWPLACEMENT);
- struWndpl.flags = 0;
- struWndpl.showCmd = SW_SHOWNORMAL;
- struWndpl.rcNormalPosition = rectFullScreen;
- SetWindowPlacement(&struWndpl);
-
-
- GetDlgItem(IDC_STATIC_PICSHOW)->MoveWindow(CRect(0, 0, g_iCurScreenWidth, g_iCurScreenHeight));
- }
- else
- {
- GetDlgItem(IDC_STATIC_PICSHOW)->SetWindowPlacement(&m_struOldWndpPic);
- SetWindowPlacement(&m_struOldWndpl);
- bFullScreen = false;
- }
到此本篇博客希望实现的内容就都完成了,效果如下:
可以在鼠标双击函数中加上鼠标位置判断来实现鼠标双击位置在PICTURE控件内才放大的效果。本篇博客的工程在博客最后的链接中,该工程基于VS2013+OpenCV2.4.9,如有需要可以下载,要自行配置OpenCV方可运行。
工程地址:点击打开链接