以文本方式查看主题

-  曙海教育集团论坛  (http://sun4.cn/bbs/index.asp)
--  WinCE应用开发  (http://sun4.cn/bbs/list.asp?boardid=35)
----  用 C++开发WM应用系列(4)——处理屏幕旋转  (http://sun4.cn/bbs/dispbbs.asp?boardid=35&id=1789)

--  作者:wangxinxin
--  发布时间:2010-11-26 8:48:42
--  用 C++开发WM应用系列(4)——处理屏幕旋转
引言:
这年过得,特别郁闷,感觉回到了经济大萧条时期~~~~好冷清,不过也好有闲情逸致来写博客~嘻嘻。今天呢,就通过一个屏幕旋转处理的小例子,来和大家一起复习一下MFC的使用等基本操作。
图片点击可在新窗口打开查看          图片点击可在新窗口打开查看
正文:
回顾以前几篇文章,我们基本上了解了MFC应用程序向导的用处,今天,我们也不例外,还是打开vs,新建一个c++下的智能设备项目,选用MFC智能设备应用程序模板,我们的项目起名就叫做“ScreenMng”吧,之后是我选用WM5 For PPC的SDK,然后“基于对话框”,最后确认一下,整个项目的框架就搭好了!
然后,打开资源视图窗口,对我们的对话框进行如下设计:
图片点击可在新窗口打开查看
也是非常的简单吧,每个按钮对应了一个角度,待稍侯为他们添加旋转代码时,好辨认。
我们为按钮添加事件处理程序吧,如下图:
图片点击可在新窗口打开查看
这是处理九十度旋转的按钮向导界面,相信大家并不陌生了!我们为四个按钮分别添加他们的"BN_CLICKED"事件。在接下来的内容中,我们要了解两个重要的知识:
1、DEVMODE结构体,这是啥玩意儿呢?他比较重要,从名称大致可以猜出,他和设备的某种模式有关,而在这里,此模式也可以理解成为显示模式,当然,这种解释还不是完全的正确,具体介绍请参看MSDN的链接http://msdn.microsoft.com/en-us/library/dd183565(VS.85).aspx 这里已经详细的告诉了我们,这个结构体中每个属性的作用及用法,这样一来,我们也就解决了大部分主要困难,既然我们可以定义一个结构体来描述设备的显示模式,那么,下一步,当然是告诉设备去根据定义的结构体来切换显示模式了吧~
2、ChangeDisplaySettingsEx函数,这又是我们学到的一个“新”玩意儿,其实,如果你曾经看到过MSDN的这篇文章,相信你就大概明白了!中文内容,我就不多说了,这个函数的使用很简单,配合上面那个结构体,传入定义好的DEVMODE结构体以及其他几个“可Null”参数,我们就可以让设备切换到我们想要的显示模式了!此函数的MSDN说明地址如下:http://msdn.microsoft.com/en-us/library/aa923082.aspx,其实很简单的~~~~
OK,在准备好了这两个知识点后,剩下来的事情就很简单了,首先,为每个按钮函数定义一个特定的结构体,指明单击按钮后,需要设备切换成何种显示模式。其次,使用函数改变当前的显示模式。
主要的函数代码如下,我们以90度按钮为例:

图片点击可在新窗口打开查看图片点击可在新窗口打开查看旋转90度代码void CScreenMngDlg::OnBnClickedButton90()
{
   
// TODO: 在此添加控件通知处理程序代码
    DEVMODE devmode = {0};
    devmode.dmSize
=
sizeof(DEVMODE);
    devmode.dmDisplayOrientation
= DMDO_90; //旋转90度
    devmode.dmFields = DM_DISPLAYORIENTATION;
    ChangeDisplaySettingsEx(NULL,
&devmode, NULL, 0, NULL);  
    PrepScreen();
}



可以看到,还有一个PrepScreen()方法,这个方法其实也就是一个UI更新方法,主要是在一个Static控件上,显示当前的显示模式,代码如下,特简单:

图片点击可在新窗口打开查看图片点击可在新窗口打开查看PrepScreen代码// 准备屏幕公共函数
void CScreenMngDlg::PrepScreen(void)
{
    CString b;
   
//取得当前模式
    DEVMODE devmode = {0};
    devmode.dmSize
=
sizeof(DEVMODE);
    devmode.dmFields
= DM_DISPLAYORIENTATION;
    ChangeDisplaySettingsEx(NULL,
&devmode, 0, CDS_TEST, NULL);
   
switch(devmode.dmDisplayOrientation)
    {
   
case DMDO_0:
        b
=_T("0度/默认模式");
        
break;
   
case DMDO_90:
        b
=_T("90度/水平模式");
        
break;
   
case DMDO_180:
        b
=_T("180度/垂直模式");
        
break;
   
case DMDO_270:
        b
=_T("270度/倒立模式");
        
break;
    }
    State.SetWindowText(b);
}



需要说明的是,那个State变量,是添加在Static1控件上的一个控件变量,你别说不知道如何添加啊~~~汗~~~,在这个函数中,我们也学会了如何取当前显示模式了,对吧!
至此,整个例子接近尾声,在我点击270按钮后,模拟器横屏,证明程序无误,可是,当我关闭程序是,设备还是停留在270显示模式,晕~这个尾巴留大了!于是,我想到OnClose函数,顺其自然地,我为对话框添加了OnClose消息处理程序,方法是:在资源视图中,单击对话框任意一个空白地区,在右侧出现的属性窗口,选择消息图标图片点击可在新窗口打开查看,在找到"WM_OnClose",选择添加OnClose函数,如下图:
图片点击可在新窗口打开查看
然后,回到代码实现文件,把下面这段代码添加进去,我想各位和我想的差不多吧:

图片点击可在新窗口打开查看图片点击可在新窗口打开查看OnClose代码void CScreenMngDlg::OnClose()
{
   
// TODO: 在此添加消息处理程序代码和/或调用默认值
    DEVMODE devmode = {0};
    devmode.dmSize
=
sizeof(DEVMODE);
    devmode.dmDisplayOrientation
= DMDO_0; //回到默认状态
    devmode.dmFields = DM_DISPLAYORIENTATION;
    ChangeDisplaySettingsEx(NULL,
&devmode, NULL, 0, NULL);  
    PrepScreen();

    CDialog::OnClose();
}



但是,现实是残酷的,我测试了一下,这段代码在我关闭窗体时没有任何作用,设备还是横着,于是,我上网查找资料,发现一个有趣的东东:OnClose和OnDestroy,至此,我也收获了不少,看完之后,我又对对话框窗体添加了OnDestroy消息处理函数,把相同的代码从OnClose中拷贝到了OnDestroy中,这才顺利让设备在关闭程序后恢复正常显示:

图片点击可在新窗口打开查看图片点击可在新窗口打开查看OnDestroy代码void CScreenMngDlg::OnDestroy()
{
    CDialog::OnDestroy();

   
// TODO: 在此处添加消息处理程序代码
    DEVMODE devmode = {0};
    devmode.dmSize
=
sizeof(DEVMODE);
    devmode.dmDisplayOrientation
= DMDO_0; //回到默认状态
    devmode.dmFields = DM_DISPLAYORIENTATION;
    ChangeDisplaySettingsEx(NULL,
&devmode, NULL, 0, NULL);  
    PrepScreen();
}



总结:
1、在今天的这篇文章中,我们又复习了一遍建立MFC程序的步骤,添加控件,为控件添加处理程序,添加变量!
2、我们还学习了DEVMODE结构体以及ChangeDisplaySettingsEx函数的简单使用。
3、我们学会了为窗体添加消息处理程序,诸如:OnClose和OnDestroy
4、最后,我们还了解了一下OnClose和OnDestroy的一些区别和联系。
附上本次例子的项目代码:点此查看