小鸟又来了.小鸟这次马不停蹄,立刻奉上全屏篇,解决 "小鸟在MFC下的OpenGL学习笔记(一)"中遗留的问题.不过,这也可以独立来看,这篇与OpenGL是完全没有关系的.
MFC下的全屏,其原理很简单,其实就是根据全屏后屏幕显示区的位置,得到窗口的位置,然后设置就可以了.如果窗口有标题栏的话,就让标题栏到屏幕之外去.总之一句话,让你的显示区域恰好充满整个屏幕就可以了.
首先在DlG类中加入以下变量申明:
CRect mFullSreen; // 全屏幕尺寸
CRect WndRect; // 非全屏幕时屏幕尺寸
小鸟本人还是挺懒的,就暂时用MFC的WM_KEYUP来响应键盘时间吧.哎..................我会很快奉上高精度键盘响应篇的.
在OnKeyUp函数中加入以下代码:
... {
// TODO: Add your message handler code here and/or call default
switch(nChar)
...{
case 'f':
case 'F':
...{
if(m_bFullSreen) //若正处于全屏模式,则不处理
break;
int cx,cy;
cx = GetSystemMetrics(SM_CXSCREEN); //屏幕像素宽度
cy = GetSystemMetrics(SM_CYSCREEN); //屏幕像素高度
this->GetWindowRect(&WndRect); //存储当前非全屏下的窗口尺寸
CRect CliRect; //显示区域的尺寸
this->GetClientRect(&CliRect);
ClientToScreen(&CliRect); //转换成屏幕尺寸
mFullSreen.left = WndRect.left - CliRect.left; //计算全屏幕后窗口尺寸的left值
mFullSreen.top = WndRect.top - CliRect.top; //计算全屏幕后窗口尺寸的top值
mFullSreen.right = WndRect.right - CliRect.right + cx;//计算全屏幕后窗口尺寸的right值
mFullSreen.bottom = WndRect.bottom - CliRect.bottom + cy;//计算全屏幕后窗口尺寸的bottom值
m_bFullSreen = TRUE; //设置全屏标志为真
//重新设置窗口位置
this->SetWindowPos(&wndTopMost,mFullSreen.left,mFullSreen.top,mFullSreen.Width(),mFullSreen.Height()
,SWP_SHOWWINDOW);
break;
}
case 'b':
case 'B':
...{
//若正处于全屏模式下
if (m_bFullSreen)
...{
m_bFullSreen = FALSE;//设置全屏标志为真
//重新设置窗口位置,尺寸为存储的非全屏幕时的大小
this->SetWindowPos(&wndTopMost,WndRect.left,WndRect.top,WndRect.Width(),WndRect.Height()
,SWP_SHOWWINDOW);
}
break;
}
}
CDialog::OnKeyUp(nChar, nRepCnt, nFlags);
}
到这里,按说应该就可以了吧.但是小鸟今天全屏的时候高度一直不对.不关我全屏的时候高度设置多大(我设置了2000多),但程序的高度最大只能到768左右.小鸟推测,CDialog类默认限制了窗口的最大尺寸.至于这个尺寸是多少,小鸟也不得而知了.小鸟继续在网上寻找,终于给我找到了WM_MINMAXINFO消息.Windows系统要向将要改变大小和位置的窗口发送WM_GETMINMAXINFO消息,并且可以在响应函数中更改窗口的最大尺寸.不过到这里,小鸟就很恨了.在SDI或者MDI中,可以在类向导中直接填加CMainFrame的WM_GETMINMAXINFO响应函数.但是在对话框程序中不能在类向导填加,必须得自己写的.还好,至少对话框程序支持WM_GETMINMAXINFO响应,要不我都不知道该怎么办了.
在Dlg中加入函数申明:
这是消息响应函数,加在那里不用小鸟细说了吧.
在Dlg的消息映射中加入:
ON_WM_GETMINMAXINFO();
这里不得不BS下CSDN的插入代码功能.怎么我插一行代码的时候经常会插不了呢?插多行的时候怪好的.
啥?问我消息映射在哪??不就是在APP的.在APP中找到如下形式的代码吧.
// {{AFX_MSG_MAP(CLesson1Dlg)
/**/ ///
消息映射/
//
// }}AFX_MSG_MAP
END_MESSAGE_MAP()
小鸟要晕了...代码又插入成功了......................
最后,就是函数的实现部分了.代码来了...
... {
// TODO: Add your message handler code here and/or call default
if (m_bFullSreen)
...{
//改变最大TRACK尺寸
lpMMI->ptMaxTrackSize.x = mFullSreen.Width();
lpMMI->ptMaxTrackSize.y = mFullSreen.Height();
}
CWnd ::OnGetMinMaxInfo(lpMMI);
}
哎,这么简单的代码,小鸟也不是太了解.小鸟有个习惯,就是懒.如果不是必须的话,小鸟很不喜欢去刨根揪地.要扯原理的话,又要很多口水了.大家还是自己去找找这个函数的意思,还有MINMAXINFO FAR* lpMMI结构的意义.知道了别忘了告诉我.
大工告成.试一下吧,F键全屏,B键还原.知道了原理,大家也能开发更实用的程序了.