想在 Windows Mobile 系統中實現全屏效果,需要考慮兩個方面.
如所示的 Mobile 系統介面,需要隱藏螢幕上部的工作列,下部的功能表列.
隱藏工作列的方法有兩種,一種是徹底隱藏,另一種是利用api調整工作列的顯示.
1.徹底隱藏工作列:
// 隱藏工作列
CWnd* pWndTask = FindWindow( _T("HHTaskBar"), NULL );
if ( pWndTask )
{
pWndTask->ShowWindow(SW_HIDE);
}
CRect rc;
SetRect( &rc, 0, 0, GetSystemMetrics( SM_CXSCREEN ), GetSystemMetrics( SM_CYSCREEN ) );
MoveWindow( rc );
使用這種方法的時候記得在程式退出的時候必須將工作列還原,否則工作列是不會自動出現的.
2.利用 SHFullScreen 隱藏工作列:
SetForegroundWindow();
DWORD dwState = ( SHFS_HIDETASKBAR | SHFS_HIDESTARTICON | SHFS_HIDESIPBUTTON );
::SHFullScreen( m_hWnd, dwState );
CRect rc;
SetRect( &rc, 0, 0, GetSystemMetrics( SM_CXSCREEN ), GetSystemMetrics( SM_CYSCREEN ) );
MoveWindow( rc );
這種方法隱藏工作列,在程式退出的時候不需要做什麼特殊處理.但是在對 CWnd, CFrameWnd 一類的視窗做處理的時候一定要先 SetForegroundWindow 一次,而 CDialog 類型的視窗則不需要這一步.
另外在對 CWnd, CFrameWnd 類型視窗做處理的時候,還必須響應 WM_ACTIVATE 訊息,在其中做同樣的處理才能做到完全的隱藏工作列效果.
由於此訊息在程式退出及視窗切換的時候也被調用,因此直接在其中響應訊息,會導致程式退出之後工作列的重新整理問題,及程式視窗無法切出.解決辦法是設定成員變數判斷程式是否退出,並檢測此訊息的參數來判斷是否切換視窗.相關代碼如下:
void CMainFrame::OnActivate(UINT nState, CWnd* pWndOther, BOOL bMinimized)
{
CFrameWnd::OnActivate(nState, pWndOther, bMinimized);
if( !nState && !pWndOther )
return;
if( !m_bExit )
{
// 全屏視窗
SetForegroundWindow();
DWORD dwState = ( SHFS_HIDETASKBAR | SHFS_HIDESTARTICON | SHFS_HIDESIPBUTTON );
::SHFullScreen( m_hWnd, dwState );
CRect rc;
SetRect( &rc, 0, 0, GetSystemMetrics( SM_CXSCREEN ), GetSystemMetrics( SM_CYSCREEN ) );
MoveWindow( rc );
}
}
隱藏下方的功能表列基本只有一種方法,同上面隱藏工作列的第一種方法類似:
// 隱藏IME欄
CWnd* pWndSIP = FindWindow( _T("menu_worker"), NULL );
if ( pWndSIP )
{
pWndSIP->ShowWindow(SW_HIDE);
}
在程式退出的時候也必須將該視窗還原,否則此欄將不會自動出現.
在很多時候,我們僅需要隱藏工作列,而對下方的IME欄並不需要隱藏,如手機QQ的做法.但是在這個時候,彈出IME軟鍵盤的時候,螢幕上視窗將會自動向下收縮並露出上方被隱藏工作列的地區.解決方案是在主視窗裡響應 WM_WININICHANGE 訊息即可,不需要在裡面添加自訂代碼,如下:
// 按動IME時不自動彈出工作列
void CMainFrame::OnWinIniChange(LPCTSTR lpszSection)
{
CFrameWnd::OnWinIniChange(lpszSection);
// TODO: 在此處添加訊息處理常式代碼
}