2011-03-10 47 views
0

我有一個相當大的應用程序,顯示許多不同的MFC CDialog派生的對話框窗口。所有的對話都是由中央功能類似於這樣顯示:攔截CDialog創建

void ShowDialog(CDialog& dlg) 
{ 
    dlg.DoModal(); 
} 

現在我需要基本調用一個函數在每一個對話框的OnInitDialog方法。它在技術上並不需要在OnInitDialog中,但最好在對話框可見之前。

蠻力方法是通過代碼並找到每個最後一個對話框,並將函數調用添加到OnInitDialog方法(如果它有一個,如果它沒有,則添加一個)。但它似乎必須有一個更優雅的方式...

請注意,dlg實際上不是一個CDialog,但它是從它派生的東西。

任何想法,技巧或黑客?我沒有修改消息映射,但希望找到更乾淨/更安全的東西。

回答

-1

原來這是很容易做到:

HHOOK gPrevHook = SetWindowsHookEx(WH_CALLWNDPROCRET, HookProc, NULL, myGUIThreadID); 


LRESULT CALLBACK HookProc(int nCode, WPARAM wParam, LPARAM lParam) 
{ 
    if(NULL != wParam) 
    { 
     CWPRETSTRUCT* pS = (CWPRETSTRUCT*)lParam; 
     if(WM_INITDIALOG == pS->message) 
      CallFuncOnWindow(pS->hwnd); 
    } 

    return CallNextHookEx(gPrevHook, nCode, wParam, lParam); 
} 

可能不適合高性能應用做的事,但對於東西是一個簡單的GUI它完美的作品。無需更改其他代碼。

+0

官方稱此爲「技術性債務」 – 2011-03-12 21:55:55

+0

這簡直令人驚訝。以正確的方式做到這一點會更快!你所要做的只是在類上使用正則表達式。* CDialog並用CMyCommonAncestor替換CDialog。 1小時絕對上衣。而且你將永遠受益。 – 2011-03-12 22:02:53

+0

除了不會處理所有沒有實現OnInitDialog的對話框。它不會處理已有基類的對話框,並在它們的OnInitDialog中調用Base :: OnInitDialog。任何錯過的案例都會是bug。這是7行代碼,不會錯過任何東西,不會依賴人類記住從基類中派生將來的代碼等。如果這是一個「攔截框架」,那麼將會有關於它的文章:) – DougN 2011-03-15 18:59:35

1

如果你有一個共同的祖先對所有對話,你似乎暗示你有,那麼你可以簡單地把代碼放在共同的祖先在你選擇的合適的位置。例如OnInitDialog()是虛擬的。

+0

CDialog的是唯一的共同祖先:( – DougN 2011-03-10 19:56:16

+1

@Doug將一個共同的祖先呢。 – 2011-03-10 19:56:59

+0

這不是從蠻力「找到所有的OnInitDialog」的方法非常不同。我希望這樣的事情重定向到WM_INITDIALOG一個單獨的函數(鉤子)或其他一些技巧,所以我不必更改所有其他代碼 – DougN 2011-03-10 21:48:37