Windows Mobile窗口全屏總結

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


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章