windows mobile 全屏到底用什么API最好

来源:互联网 发布:学生用mp3推荐知乎 编辑:程序博客网 时间:2024/06/10 04:30

http://topic.csdn.net/u/20090630/17/d06d6ed3-84fc-4ac2-b050-dafd26b827ae.html

第一点:全屏到底用什么API最好
在MSDN、网络资料等有一下几种全屏方法:(都是简记
1、SHFullScreen
2、ShowWindow(FindWindow)  利用循环找出所有menuworker等等的窗口
3、EnumWindows(EnumWindowsProc) => EnumWindowsProc{GetClassName;ShowWindow;}

事实上,第2和第3 是一回事,都是通过找窗口 把符合条件的窗口找到然后隐藏,就像我在第5楼说的一样:使用FindWindow是个危险的做法 原因就在于,当用户主动结束掉应用程序,因来不及调用相应的显示而造成屏幕的部分系统级别的窗口缺失,让用户以为出了严重问题,我测试过,当用“运行的程序”结束进程,就会导致这类情况,当然重启WM可以恢复。(第4楼、第6楼就分别采用的这类方法)

然而,SHFullScreen是一个非常好的函数,他的参数是本窗体句柄,也就是说,无论在全屏后遭受如何的打击,即使进程强制关闭,都不会影响到系统整体。我强烈推荐使用SHFullScreen。 甚至如果你太懒,你可以不负责任的不去编写逆全屏代码。当然我还是会编写,因为可能考虑到在程序运行期间的主动退出全屏模式的可能。


第二点 如何隐藏菜单
让我把SHFullScreen的原型写出来:
SHFullScreen
This function can be used to take over certain areas of the screen. It is used to modify the taskbar, Input Panel button, or Start menu icon.
它的相应的宏标志:SHFS_SHOWTASKBAR、SHFS_HIDETASKBAR、SHFS_SHOWSIPBUTTON、SHFS_HIDESIPBUTTON、SHFS_SHOWSTARTICON、SHFS_HIDESTARTICON也只有 “任务栏”、“SIPB(Standard Input Panel Button)”、开始菜单按钮的有效性(即在全屏后,是否可以列出开始菜单,可能的方法是手机硬键盘的windows标记按钮),并没有涉及菜单的标志。

因此,为了隐藏菜单,而且又为了不妨碍系统,就找到了SHFindMenuBar(hwnd)这个函数,它也是控制在本地句柄级别内的。
在用ShowWindow就可以隐藏找到的句柄。注意:SHFindMenuBar只是找出现有可以看到的菜单的句柄,即如果你隐藏了,SHFindMenuBar就找不到了,所以如果你要恢复菜单,那么请你在隐藏前,保存找到的菜单句柄。

但是实际过程中,你会发现,ShowWindow(SHFindMenuBar(hwnd), SW_HIDE)并没有彻底隐藏菜单栏,而是隐藏了你自己的菜单,也就是说如果你执行ShowWindow(SHFindMenuBar(hwnd), SW_HIDE)一次后,会看到屏幕仍旧有一个空的菜单栏,只是原先有字的菜单不见了。 这是为什么呢?
事实上,原因是,一个窗口在没有建立用户自定义菜单时,已经有了一个默认菜单
ShowWindow(SHFindMenuBar(hwnd), SW_HIDE)之后  你再去SHFindMenuBar(hwnd),又会得到一个句柄,你得再把它隐藏掉。当然,如果你没有构造自定义菜单,那只有一个默认菜单。

如果你还需要在退出全屏时,重新显示菜单,那要怎么办呢,以建立了自定义菜单为例,理论上来说,你得把刚才的两次SHFindMenuBar(hwnd)都保存句柄,然后依次ShowWindow(hmenu, SW_SHOW), hmenu有2个。
但是在实测过程中,我发现,没有必要显示默认的菜单栏,因为已经有自定义菜单栏覆盖在上面了。当然出于严谨的态度,我还是打算在最终版本中,将2个句柄都SW_SHOW。以免造成纰漏。
如果没有自定义菜单,只有默认菜单,那只要一次来回就行了。

第三点 注意窗口的移动
由于上述的隐藏只是隐藏,WM不会向积木一样因为缺少了窗口而自动调整,因此在隐藏后的地方,仍旧没有重绘,需要我们自己用
MoveWindow来重新调整窗口位置。
在全屏过程中:SetRect(&SCR_Rect, 0, 0, GetSystemMetrics(SM_CXSCREEN), GetSystemMetrics(SM_CYSCREEN));获得窗口的最大表现。
在逆全屏过程中:SystemParametersInfo(SPI_GETWORKAREA, 0, &WORK_Rect, 0);获取本来面目大小。


第四点 全屏不受干扰
也许,你已经很满意了,这样就可以隐藏界面上所有的乱七八糟的东西了。

但是你会不经意发现,当点击SIPB、或者按了下手机上的照相机按钮等离开窗口时的动作发生后,原先已经全屏的窗口再一次变成了不全屏,也就是在本贴开头的提问, 不过由于没有人回答这个问题,我不得不自己找。

在MFC的窗体类中加入,2个消息ON_WM_SETTINGCHANGE()、ON_WM_ACTIVATE()
并本窗体内重载CDialog的OnSettingChange、OnActivate方法。
将OnSettingChange方法置为空方法{}
ON_WM_SETTINGCHANGE()消息可以被触发如,点击SIPB时,因此当触发时,就不让它做任何事,这样点击SIPB就不会还原,估计CDialog的OnSettingChange方法内部具有还原全凭的代码。

但是这还不够,因为比如按了照相机按钮、短信按钮等,仍旧会让窗体的全屏失效,这时候ON_WM_ACTIVATE()消息就发挥了作用。
在重载的OnActivate方法中,再一次调用全屏代码,就能 即使窗体受到干扰,也能在干扰后“恢复”(其实就是再一次)全屏。

第五点 其他
剩下的就是如何有机的组合各种状态,比如我不隐藏“任务栏”,只隐藏菜单栏,那么窗体移动就要考虑位置问题,不能一味的往屏幕左上(0,0)移动,而是要往WorkArea的左上移动。等等的各类组合,就要自己灵活调整了。

原创粉丝点击