如何有效使用對話方塊之二
譯者:徐景周(原作:Nishant S )
本文是《如何有效使用對話方塊》一文的繼續.
1. 如何有效地使初始視窗不顯示
當我們想讓視窗初始時不顯示時,通常會用ShowWindow(SW_HIDE) ,但實際上還是在啟動是可以看到視窗一閃而過的痕迹。所以,可以使用下面的方法來實現它:
(1.1)先在建構函式中設定布樂變數 visible值為false.
visible = false;
(1.2)重載 WM_WINDOWPOSCHANGING,並添加下面代碼:
void CTest_deleteDlg::OnWindowPosChanging(WINDOWPOS FAR* lpwndpos) { if(!visible) lpwndpos->flags &= ~SWP_SHOWWINDOW; CDialog::OnWindowPosChanging(lpwndpos);}
(1.3)然後設布爾visible變數值為true,並在要顯示視窗時,再用ShowWindow(SW_SHOW)既可。
visible = true;ShowWindow(SW_SHOW);
2. 對話方塊的全螢幕顯示
對話方塊的全螢幕顯示可以在OnInitDialog()中用 SetWindowPos 和 HWND_TOPMOST 來實現對話方塊的重新大小。
BOOL CFullScrDlgDlg::OnInitDialog(){ CDialog::OnInitDialog(); //... int cx, cy; HDC dc = ::GetDC(NULL); cx = GetDeviceCaps(dc,HORZRES) + GetSystemMetrics(SM_CXBORDER); cy = GetDeviceCaps(dc,VERTRES) + GetSystemMetrics(SM_CYBORDER); ::ReleaseDC(0,dc); //去除標題和邊框 SetWindowLong(m_hWnd, GWL_STYLE, GetWindowLong(m_hWnd, GWL_STYLE) & (~(WS_CAPTION | WS_BORDER))); // 置對話方塊為最頂端並擴充到整個螢幕 ::SetWindowPos(m_hWnd, HWND_TOPMOST, -(GetSystemMetrics(SM_CXBORDER)+1), -(GetSystemMetrics(SM_CYBORDER)+1), cx+1,cy+1, SWP_NOZORDER); //... return TRUE; }
3. 如何在2K/xp下使視窗擷取焦點
在2K/XP下我們可以用 AttachThreadInput 和SetForegroundWindow來有效擷取焦點。
//捕捉並設定當前焦點視窗為我們的視窗AttachThreadInput( GetWindowThreadProcessId( ::GetForegroundWindow(),NULL), GetCurrentThreadId(),TRUE);//置我們的為焦點視窗SetForegroundWindow();SetFocus(); //釋放threadAttachThreadInput( GetWindowThreadProcessId( ::GetForegroundWindow(),NULL), GetCurrentThreadId(),FALSE);
4. 使你的對話方塊位於最頂端
可以直接在 OnInitDialog()中用SetWindowPos來實現。
SetWindowPos(&this->wndTopMost,0,0,0,0,SWP_NOMOVE|SWP_NOSIZE);
5. 如何動態放大/縮小對話方塊
還是可以用SetWindowPos或MoveWindow來實現它。
void CTest_deleteDlg::OnMakeSmall() { SetWindowPos(NULL,0,0,200,200,SWP_NOZORDER|SWP_NOMOVE); }void CTest_deleteDlg::OnExpand() { SetWindowPos(NULL,0,0,500,300,SWP_NOZORDER|SWP_NOMOVE); }
或:
//伸、縮在IDC_DYCREDITS和IDC_COPYRIGHT兩STATIC控制項間,做為分隔線BOOL CAbout::OnInitDialog() { CDialog::OnInitDialog();//"關於"對話方塊中對話方塊可收縮效果 CRect Rect1,Rect2; //對話方塊收縮時大小 GetDlgItem(IDC_DYCREDITS)->GetWindowRect(Rect1); GetDlgItem(IDC_COPYRIGHT)->GetWindowRect(Rect2); m_nReducedHeight = Rect1.Height()+(Rect1.top -Rect2.bottom)/2; //收縮後表單高度 dlgRect.bottom -= (Rect1.Height()+(Rect1.top -Rect2.bottom)/2); MoveWindow(&dlgRect); //如果要顯示對話方塊起始動態效果的話,不能使用該句 m_bVertical=false; //預設收縮對話方塊}// ---------------------------------------------------------// 名稱: OnMore// 功能: 是否允許顯示// 變數: 無// 返回: 無// 編寫: 徐景周,2002.4.8// ---------------------------------------------------------void CAbout::OnMore() { m_bVertical = !m_bVertical; if(m_bVertical == FALSE) //不顯示 { SetDlgItemText(ID_MORE,_T("更多>>")); SizeWindow(m_nReducedHeight,true);// m_DyCredits.EndScrolling(); //停止滾動 } else //顯示 { SetDlgItemText(ID_MORE,_T("<<隱藏")); SizeWindow(m_nReducedHeight,false); m_DyCredits.StartScrolling(); //開始滾動 } UpdateWindow(); }// ---------------------------------------------------------// 名稱: SizeWindow// 功能: 伸展或收縮對話方塊 // 變數: ReduceHeight-收縮高度,bExtend-是否伸展// 返回: 無// 編寫: 徐景周,2002.4.8// --------------------------------------------------------- void CAbout::SizeWindow(int ReduceHeight, bool bExtend){ CRect rc; GetWindowRect(&rc); if(bExtend) { for (int i= 0; i < ReduceHeight; i++) { rc.bottom--; MoveWindow(&rc); } } else { for (int i= 0; i < ReduceHeight; i++) { rc.bottom++; MoveWindow(&rc); } }}
6. 如何讓對話方塊回到螢幕中來
當對話方塊被拖離螢幕時,可用下面代碼使其回到螢幕中。
SendMessage(DM_REPOSITION);
註:它必須是頂端視窗且不是child視窗。
7. 如何給對話方塊添加或去掉最大/最小化按鈕
在OnCreate()或OnInitDialog() 改變其顯示風格既可。
int CTest_deleteDlg::OnCreate(LPCREATESTRUCT lpCreateStruct) { if (CDialog::OnCreate(lpCreateStruct) == -1) return -1; // TODO: Add your specialized creation code here SetWindowLong(this->m_hWnd,GWL_STYLE, GetWindowLong(this->m_hWnd,GWL_STYLE) | WS_MINIMIZEBOX | WS_MAXIMIZEBOX); return 0;}
或用:
ModifyStyle (NULL, WS_MAXIMIZEBOX);
8. 改變滑鼠指標
可以在OnSetCursor中實現.
BOOL CTest_deleteDlg::OnSetCursor(CWnd* pWnd, UINT nHitTest, UINT message) { // TODO: Add your message handler code here and/or call default SetCursor(AfxGetApp()->LoadStandardCursor(IDC_UPARROW)); // Now we return instead of calling the base class return 0; // return CDialog::OnSetCursor(pWnd, nHitTest, message);}
9. 改變對話方塊的前景和背景色
可以在InitInstance()中實現。
//紅色背景、綠色前景SetDialogBkColor(RGB(255,0,0),RGB(0,255,0));
10. 在任務條上不顯示表徵圖
先從CWinApp繼承類中建立一個不顯示的最上層視窗.
CFrameWnd *abc=new CFrameWnd();abc->Create(0,0,WS_OVERLAPPEDWINDOW);CNoTaskBarIconDlg dlg(abc);m_pMainWnd = &dlg;int nResponse = dlg.DoModal();if (nResponse == IDOK){}else if (nResponse == IDCANCEL){}delete abc;
在 OnInitDialog中修改顯示風格 WS_EX_APPWINDOW.
BOOL CNoTaskBarIconDlg::OnInitDialog(){ CDialog::OnInitDialog(); ModifyStyleEx(WS_EX_APPWINDOW,0); SetIcon(m_hIcon, TRUE); // Set big icon SetIcon(m_hIcon, FALSE); // Set small icon // TODO: Add extra initialization here return TRUE; // return TRUE unless you set the focus to a control}
11. 加入上、下文協助
在 OnInitDialog 修改顯示風格,加入上、下文HLP協助顯示.
BOOL HelpDialog::OnInitDialog() { ModifyStyleEx(0, WS_EX_CONTEXTHELP); return CDialog::OnInitDialog();}
重載OnHelpInfo(...),用顯示相關協助資訊
BOOL HelpDialog::OnHelpInfo(HELPINFO* pHelpInfo) { short state = GetKeyState (VK_F1); if (state < 0) // F1 key is down, get help for the dialog return CDialog::OnHelpInfo(pHelpInfo); else { // F1 key not down, get help for specific control if (pHelpInfo->dwContextId) WinHelp (pHelpInfo->dwContextId, HELP_CONTEXTPOPUP); return TRUE; }}