Windows Mobile窗口全屏总结

TO:ALL
经过细致研究和严格测试 负责任的给出《史上最全面的Windows Mobile窗口全屏总结》
开发和测试环境: VC2005 智能MFC
测试样机:dopod E616
-------------------------------------------------------------------
第一点:全屏到底用什么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的左上移动。等等的各类组合,就要自己灵活调整了。

读完此帖,应该可以解决基本上的所有全屏涉及的杂7杂8的问题了。没有语句检查,最恨技术贴有理解性的笔误,如果发现,留言。

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

 

在做了几个项目之后,终于找到了一个比较好的实现全屏的方法,之前做全屏的时候,在网上找了很多的实现方法,总结了下大致就2种(其他的大同小异):
1、         SetForegroundWindow();
        SHFullScreen(m_hWnd, SHFS_HIDESIPBUTTON);
        SHFullScreen(m_hWnd, SHFS_HIDETASKBAR);
        SHFullScreen(m_hWnd, SHFS_HIDESTARTICON);

2、        CWnd* pWndSIP = FindWindow( _T("menu_worker"), 0 );
        if ( pWndSIP )
        {
                pWndSIP->SetWindowPos(&wndBottom , 0, 0, 0, 0, SWP_NOMOVE + SWP_NOSIZE);
                pWndSIP->ShowWindow(SW_HIDE);
        }
        pWndSIP = FindWindow( _T("MS_SIPBUTTON"), 0 );
        if ( pWndSIP )
        {
                pWndSIP->SetWindowPos(&wndBottom , 0, 0, 0, 0, SWP_NOMOVE + SWP_NOSIZE);
                pWndSIP->ShowWindow(SW_HIDE);
        }
        pWndSIP = FindWindow( _T("HHTaskBar"), 0 );
        if ( pWndSIP )
        {
                pWndSIP->SetWindowPos(&wndBottom , 0, 0, 0, 0, SWP_NOMOVE + SWP_NOSIZE);
                pWndSIP->ShowWindow(SW_HIDE);
        }

这2种方法其实都可以实现窗口的全屏,但是在某些时候或者某些机器上,并不能成功,或者是开始是成功的,但是在某种情况下就跑出来了,而且之后一直就因此不了了,具体的原因我跟了下,因为Mobile自己带了很多系统的功能条,而且类名都是一样的,所以当时隐藏的可能只是其中的一个,并没有全部隐藏,当某些情况触发的时候就会将另外一个系统条弹出来,而且很难隐藏。

我找到的方法是,在程序启动的时候,或者是你需要隐藏的时候调用系统的EnumWindows函数去枚举所有的系统窗口,然后用GetClassName(hwnd,szClassName,256);函数去根据窗口的名字去获取这个窗口的类名,然后根据你需要隐藏的类名去隐藏窗口,例如:
        if (!wcscmp(szClassName,L"HHTaskBar"))
        {
                ShowWindow(hwnd, SW_HIDE);
                //return FALSE;
        }
        if (!wcscmp(szClassName,L"menu_worker"))
        {
                //EnableWindow(hwnd, FALSE);
                ShowWindow(hwnd, SW_HIDE);

                //return FALSE;
        }
        if (!wcscmp(szClassName,L"MS_SIPBUTTON"))
        {
                //EnableWindow(hwnd, FALSE);
                ShowWindow(hwnd, SW_HIDE);
                //return FALSE;
        }
这样就可以保证所有的系统条都被隐藏了。

当然还有一点很重要,这样的函数执行了以后,一定要在你退出你的程序的时候写个逆隐藏函数,将之前隐藏的都显示出来(只需要将ShowWindow(hwnd, SW_HIDE);改为ShowWindow(hwnd, SW_SHOW);),否则,退出你的程序之后可是什么都看不到了哦

MS_SIPBUTTON:下方中间的拼字那个窗口
menu_worker:下方的带颜色的长条,不算中间的拼字
HHTaskBar:上方的任务条

from:http://hi.baidu.com/whexyil/blog/item/5487753f8d4455f3828b13bf.html

你可能感兴趣的:(Windows Mobile窗口全屏总结)