2009-04-09 97 views

回答

3

你需要考慮它是什麼意思是模態窗口 - 基本上,窗口的父項被禁用。這樣做的唯一自動方法(我知道)是調用DialogBox()創建一個模態對話框。但是,由於您想使用CreateWindow(),所以您只需手動禁用父窗口即可。理想情況下,最好是去對話框路由(因爲操作系統確切地知道必須做什麼才能創建一個模式窗口),但是如果你必須使用它,我想這個選項是存在的。

12

Modality, part 1: UI-modality vs code-modality解釋如何做到這一點,爲什麼你可能不希望。

+6

作爲一個規則,我投票的所有舊新事物的參考。 – Aardvark 2009-04-09 15:38:15

+0

舊的新事物引用是偉大的,但太糟糕了,這是一個鏈接唯一的答案。您可能需要用自己的文字重新翻譯文章中的某些內容。 – jrh 2017-12-28 16:55:35

16

確保在CreateWindow設置hwndParent和使用​​顯示彈出窗口後,禁用父。然後在彈出窗口關閉後啓用EnableWindow(hwndParent, TRUE)

2

你也可以運行一個「二級消息循環」,這一直不活躍的父窗口,直到您的工作與「模式」對話框完成。

0

好吧我只是自己與這個相同的問題摔跤。我需要一個快速的對話框,如果我使用DialogBox(),但我不想爲我正在使用的特定項目創建模板。

我發現那是什麼,如果你禁用對話框的父窗口也關閉對話框。如果不重新啓用父對話框,則無法啓用該對話框。所以這種方法將無法工作。

我還發現,你不能使用SetCapture()/ ReleaseCapture(),因爲隨後的對話框的子窗口不會得到的消息。

我沒有找到一個可行的解決方案:使用本地消息泵,方法是的PeekMessage()或GetMessage函數()驅動。這裏是爲我工作的代碼:

while (!m_bFinished) 
    { 
    BOOL bEat; 

    if (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE)) 
    { 
     if (msg.message == WM_CHAR) 
     { 
      if (msg.wParam == VK_ESCAPE) 
      { 
       m_bFinished = TRUE; 
       continue; 
      } 
     } 

     bEat = FALSE; 

     if (msg.message >= WM_MOUSEFIRST && 
      msg.message <= WM_MOUSELAST) 
     { 
      RECT rectMe; 

      pcMe->GetWindowRect(&rectMe); 
      if (!::PtInRect(&rectMe, msg.pt)) 
       bEat = TRUE; 
     } 

     if (!bEat) 
     { 
      ::TranslateMessage(&msg); 
      ::DispatchMessage(&msg); 
     } 
    } 
    } 

這是什麼做有效的是「吃」是的窗口傳遞到應用程序的所有消息的客戶區以外的任何鼠標消息。它不禁止在應用程序外單擊,只需單擊不在「模式」窗口的客戶區內的應用程序內的任何地方。如果您在消息中添加MessageBeep(),則會獲得與實際模式對話框完全相同的行爲。

m_bFinished是類的BOOL成員,如果在「對話框」上以及在此代碼片段範圍之外的某些其他條件下訪問了「確定」或「取消」按鈕,它將被設置。

相關問題