1. 程式人生 > 實用技巧 >一些方便的對話方塊技巧,提示和解決方法

一些方便的對話方塊技巧,提示和解決方法

介紹 這些是我在使用過程中發現的一些技巧 非對話方塊和基於對話方塊的應用程式中的對話方塊。的一些 可能看起來很幼稚,但卻非常方便。我想我應該分享一些 技巧與你在一起時的感覺。 啟動一個模態對話方塊隱藏 你經常聽到人們抱怨,儘管在裡面放了一個ShowWindow(SW_HIDE) 他們的OnInitDialog他們的模態對話方塊仍然在顯示狀態下啟動。的 這裡的問題是,當CDialog::OnInitDialog()完成時,它將呼叫 顯示視窗(SW_SHOW)。這樣,您的對話方塊再次可視。但是,就是這樣 可以預料的是,人們已經開始解決這個問題了。這是你需要做的。 在對話方塊類中新增一個BOOL成員,並將其命名為可視。 現在在你的對話方塊建構函式設定可見為假。 隱藏,複製Code

visible = false;

現在你需要重寫wm_windowposchange。你可能需要改變你的 在類嚮導中顯示此訊息的訊息過濾選項。 隱藏,複製Code

void CTest_deleteDlg::OnWindowPosChanging(WINDOWPOS FAR* lpwndpos) 
{
    if(!visible)
        lpwndpos->flags &= ~SWP_SHOWWINDOW;

    CDialog::OnWindowPosChanging(lpwndpos);
}

就是這樣。現在你的模態對話方塊實際上以隱藏狀態啟動。和 如果你想讓它可見,這就是你需要做的。 隱藏,複製Code

visible = true;
ShowWindow(SW_SHOW);

全屏對話方塊 有時你可能覺得需要做一個全屏對話方塊-意味著 對話方塊,填充整個監視器。這很容易做到。 你需要刪除標題和邊框,這是通過刪除隱藏來實現的。複製Code

WS_CAPTION

和WS_BORDER樣式。然後我們叫隱藏用HWND_TOPMOST複製Code

SetWindowPos

並調整對話方塊大小以填充 整個螢幕。只需將以下程式碼放入OnInitDialog中 函式。 隱藏,收縮,複製Code

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); 

    // Remove caption and border
    SetWindowLong(m_hWnd, GWL_STYLE, 
        GetWindowLong(m_hWnd, GWL_STYLE) & 
    (~(WS_CAPTION | WS_BORDER))); 

    // Put window on top and expand it to fill screen
    ::SetWindowPos(m_hWnd, HWND_TOPMOST, 
        -(GetSystemMetrics(SM_CXBORDER)+1), 
        -(GetSystemMetrics(SM_CYBORDER)+1), 
        cx+1,cy+1, SWP_NOZORDER); 

    //...

    return TRUE; 
}

如何把注意力轉移到2K/XP上 我敢打賭,有時你會懷念過去的日子,當一個簡單的場景擺在窗前 讓你的對話更有焦點。嘆息!現在2K/XP有了一些改變 因此,如果您嘗試一個簡單的SetForegroundWindow,您最終會重新整理 工作列圖標出現了幾次(我從來沒有數過,但有東西告訴我它在閃爍 三次)。這不是你想做的,對吧?幸運的是,我們有辦法 您的對話方塊到前景。 技巧是使用AttachThreadInput附加以下執行緒 擁有當前執行緒的前臺視窗,然後呼叫Hide複製Code

SetForegroundWindow

,然後分離附加的執行緒,再次使用 AttachThreadInput。酷,不是嗎? 隱藏,複製Code

//Attach foreground window thread
//to our thread
AttachThreadInput(
    GetWindowThreadProcessId(
        ::GetForegroundWindow(),NULL),
    GetCurrentThreadId(),TRUE);

//Do our stuff here ;-)
SetForegroundWindow();
SetFocus(); //Just playing safe

//Detach the attached thread
AttachThreadInput(
    GetWindowThreadProcessId(
        ::GetForegroundWindow(),NULL),
    GetCurrentThreadId(),FALSE);

使你的對話保持在頂部 你沒見過有“永遠呆在頂部”選項的節目嗎?好吧, 令人難以置信的是,你可以讓你的對話方塊停留在頂端 行程式碼。只需在您的對話方塊類中放入以下程式碼行即可 OnInitDialog()函式。 隱藏,複製Code

SetWindowPos(&this->wndTopMost,0,0,0,0,SWP_NOMOVE|SWP_NOSIZE);

基本上,我們所做的是使用SetWindowPos函式來更改 對話方塊的z順序。我們讓我們的對話保持在所有其他對話之上 將其移動到z順序的頂部。即使你激活了一些 其他視窗,我們的視窗會在上面。但我建議你一定要確定 當你這樣做的時候,要確切地知道你在做什麼,因為如果你這樣做的話,可能會惹惱別人 當他們想把你的窗戶移開的時候,他們是無法做到的。 展開和收縮對話方塊 我敢打賭,你一定見過有對話方塊的程式,以一個大小開始。 它們會有一個按鈕叫"展開檢視"或者叫 “高階”,當你點選那個按鈕時,對話方塊會漂亮地展開 揭示了一些迄今為止隱藏的兒童控制元件。它們也可能有一些按鈕 叫做"隱藏細節",當你點選它,它會收縮回 原來更小的尺寸隱藏了額外的控制元件,在擴充套件時被揭示。 使用SetWindowPos可以很容易地實現這一點,正如您所看到的,這是一個相當好的方法 有用的函式。 假設你有兩個按鈕,“MakeSmall”和“Expand”。那麼這就是 您需要放入它們的單擊處理程式函式。當然,你需要更換 cx和cy引數與您自己的值。 隱藏,複製Code

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);		
}

還記得在你的對話方塊中呼叫OnMakeSmall() 函式的作用是:使您的對話方塊視窗在合同中開始 大小。相反,您可以通過呼叫OnExpand()來展開它 OnInitDialog()。有時你想使用相同的按鈕,改變 按鈕標題,並使用布林標誌來決定何時展開 以及何時簽約。 順便說一下,這是Thomas Freudenberg的另一個建議。這是 事實上,即使在收縮之後,隱藏的控制仍然是 可通過鍵盤訪問,因此您可能想禁用這些控制元件使用 EnableWindow。我要感謝托馬斯的建議: 你錯過了一些關於“擴充套件和收縮你的對話”的內容 盒子”。似乎你更喜歡使用滑鼠而不是鍵盤(你是一個 所謂的Mausschubser(德文的意思)老鼠《好色客》)如果一個對話方塊 簡約,你仍然可以使用tab鍵去控制之外 的對話方塊。我建議叫EnableWindow (fExtracted)合適 控制。 讓你的對話方塊到桌面 有時使用者可能移動對話方塊螢幕直到部分 在桌面。你可能會想把回的對話方塊 完整的檢視。還可能存在這樣一種情況你的發展 更高的解析度和在您的機器上是漂亮的和完整的,但最後 使用者可能會使用螢幕解析度較低,因此對話方塊的一部分 螢幕。再一次你真的想確保對話方塊 完全可見。信不信由你,這個可以只有一個來完成 行程式碼。 隱藏,複製Code

SendMessage(DM_REPOSITION);

順利是嗎?記住,這個訊息只適用於高層對話方塊 和孩子對話方塊不會工作。 最小化、最大化按鈕新增到對話方塊 如果你想做這個在設計時,所有你需要做的就是設定 相應的屬性。但是如果因為某些原因你在執行時需要這樣做 這是你需要做什麼。覆蓋OnCreate()和新增此程式碼。 請注意,把這段程式碼在OnInitDialog()有一個奇怪的副作用。 按鈕會顯示,最大化和最小化;但是他們是假的, 這意味著他們不正確的函式。我的猜測是,OnInitDialog () 晚一個地方改變對話方塊的風格。 隱藏,複製Code

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;
}

還要注意比原始CREATESTRUCT lpCreateStruct只有一份 過去了。因此改變風格位沒有影響。和一些令人費解的 (至少對我來說)原因,PreCreateWindow永遠不會要求一個模態對話方塊 因此我們不能改變風格也,我們可能會做一個檢視 視窗或框架視窗。 改變滑鼠游標——從安德魯和平 嗯,我想感謝安德魯和平這個建議。有時你可能 覺得需要改變預設的滑鼠游標在一個對話方塊。你需要做什麼 覆蓋OnSetCursor,設定一個新的游標沒有呼叫然後返回 基類函式如下顯示。我試過,因為我一直失敗 呼叫基類。再次感謝安德魯和平指向我 正確的方向。 隱藏,複製Code

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);
}

改變對話方塊的背景和控制文字顏色 有一個問題經常CWinApp成員函式,SetDialogBkColor, 讓我們做到這一點。這個函式接受兩個colorref作為其引數。 第一個是對話方塊的背景色。也就是說第二 靜態的顏色,檢查和無線電控制。它不會影響編輯和 按鈕控制元件。所有對話方塊和訊息盒子裡長大的 全球應用程式將使用這些顏色。把這段程式碼CWinApp 派生類的InitInstance()。記得要呼叫這個函式之前你 例項化CDialog-derived物件。 隱藏,複製Code

//Red background with Green colored controls
SetDialogBkColor(RGB(255,0,0),RGB(0,255,0)); 

這個函式是現在過時了!它甚至可能不工作!我將更新本文 用正確的方法在未來的更新! 刪除你的基於對話方塊的應用程式工作列圖示 有時候您可能想要建立隱形對話方塊應用程式等等 的原因。他們不會隱形自對話方塊將在適當的意義上 可見。但是讓我們假設你不希望他們有工作列圖示等等 的原因。這是如何實現這一點。我們首先建立一個看不見的 水平框架視窗。這是程式碼放入CWinApp-derived 類只; 隱藏,複製Code

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;

現在我們需要修改對話方塊的風格。所以你把這段程式碼 CDialog-derived類的OnInitDialog。我們需要刪除 WS_EX_APPWINDOW風格。 隱藏,複製Code

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
}

上下文敏感的幫助- P J阿倫茲 本文從皮特·阿倫茲向您展示如何獲得上下文敏感的幫助你 對話方塊。你需要做的第一件事是確保對話方塊 有問號的標題欄。你需要這樣做 OnInitDialog如下所示。 隱藏,複製Code

BOOL HelpDialog::OnInitDialog() 
{
    //blah blah blah
    //blah blah blah
    ModifyStyleEx(0, WS_EX_CONTEXTHELP);
    return CDialog::OnInitDialog();
}

OnHelpInfo(…)可以在兩種不同的情況下被呼叫。第一個 當用戶按下F1鍵。這通常應該開啟 主要幫助視窗對話方塊。另一種情況是當用戶點選 問號,然後點選單個控制對話方塊。 或者使用者也可以右鍵點選“控制和選擇 從彈出選單?”選項。當然你必須處理出現的 自己的選單。因此我們需要處理這兩種情況如下所示。 隱藏,複製Code

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;
    }
}

記住控制必須有一個幫助ID相關聯的。這可以 通過採取[屬性——General選項卡——幫助ID複選框)。當然 你還需要寫他lp檔案為您的程式。謝謝。 主對話方塊消失後顯示訊息框 有時,您需要顯示某種型別的訊息框 在基於對話方塊的應用程式中的主對話方塊被駁回後。但 您將注意到您的訊息框從未顯示。有趣的是,如果你放一個休息 在這裡,程式在除錯時確實會中斷。這裡的問題是, 在基於對話方塊的應用程式中,CWinThread::m_pMainWnd是 對話方塊本身,當對話方塊被解除時,主視窗是 被銷燬,程式退出。解決方案是註釋掉其中的行 m_pMainWnd被設定為對話方塊視窗。 隱藏,收縮,複製Code

BOOL CTestApp::InitInstance()
{

    // ....

    CTestDlg dlg;

    /* Comment out the following line */
    //m_pMainWnd = &dlg;

    int nResponse = dlg.DoModal();
    if (nResponse == IDOK)
    {
        // TODO: Place code here to handle 
        // when the dialog is
        //  dismissed with OK
    }
    else if (nResponse == IDCANCEL)
    {
        // TODO: Place code here to handle 
        // when the dialog is
        //  dismissed with Cancel
    }

    
    MessageBox(NULL,"Some message","Title",0);
        
    return FALSE;
}

當然,你不能從你的任何地方呼叫AfxGetMainWnd 應用程式。因為AfxGetMainWnd盲目返回隱藏複製CWinApp派生類的Code

m_pMainWnd

成員。否則 你能做的是把你的CDialog*儲存到一些其他成員 變數,說m_pMainWnd2然後寫一個函式AfxGetMainWnd2 它簡單地返回m_pMainWnd2,如果你想要使用 AfxGetMainWnd。 最後一次更新 由於我經常更新這篇文章,所以我沒有維護一個完整的 歷史,但我將在這裡提到上次更新的資訊。以下 在2002年9月18日的最新更新中增加了一個或多個提示。 全屏對話方塊如何竊取焦點2K/XP 本文轉載於:http://www.diyabc.com/frontweb/news5039.html