2016-06-30 117 views
0

我使用和改進了一個名爲FFC的開源MFC工作類庫。有時庫會將錯誤的窗口句柄與對話框對象相關聯,這意味着稍後在查找正確句柄時找不到C++對象。特別是當應用程序打開它的根窗口時發生這種情況,這是一個對話框,它打開時會調用DoModal。捕獲新創建的模式對話框的窗口句柄

在其DoModal函數中,FFC庫使用......「令人驚訝」的方式將句柄附加到對話對象。它將「this」指針存儲在一個全局變量中,並在調用DialogBox函數之前掛鉤一個函數以在所有窗口消息上調用。它在術語中註冊的這個鉤子函數假定它接收到的第一個消息的句柄是全局變量中窗口的句柄,並將該句柄附加到它。

有時候,這是有效的。經常 - 我不知道這是因爲我的工作計算機上的McAfee掃描儀完成了干擾事情,還是因爲我的程序是從控制檯窗口或其他內容開始 - 許多無關的消息將在消息實際上意味着模態對話框會通過。

起初我以爲是因爲FFC沒有確定它看起來的消息是「WM_CREATE」。我添加了這張支票,但沒有解決問題。發現一個或多個虛假消息也是WM_CREATE消息!在它獲得真正的對話框之前,它收到的第一個WM_CREATE是一個帶有空白窗口文本和矩形0,0-0,0的窗口句柄。

那麼,這是真正的正確或規範的方式來獲取模態對話框的句柄?這似乎不可靠。 (請注意,因爲對話框是模態的,所以不能使用CreateWindowEx的返回值,因爲DialogBox函數在關閉模態對話框之前不會返回。)這是MFC真的如此嗎?有沒有更好的辦法?我可以將某些數據與對話框關聯起來,還是查找應與其關聯的數據以確保我擁有正確的窗口句柄? (例如,檢查傳遞給對話框調用的模板參數,如果我可以以某種方式從句柄中獲取它)。

+1

Visual Studio附帶的MFC的源代碼。看看你自己。 – IInspectable

+0

哦,順便說一下,MFC不需要檢查特定的消息。它建立一個鉤子,調用'CreateWindowEx'(或它的一個朋友),讓鉤子回調設置實例指針,並且取消鉤住當前線程。所有這些都允許操作系統按照它認爲合適的順序對消息進行重新排序,並且當第一條消息到達時,MFC的任何指定版本的Windows上可能會有的實例指針都會正確地附加到窗口句柄上。如果您看到虛假消息阻礙,您可能違反了線程關聯性規則:GUI需要是單線程的。 – IInspectable

回答

0

我確定這是在書籍中發佈的,但MFC設置了一個windows鉤子(WH_CBT),然後在掛鉤中查找HCBT_CREATEWND代碼以將C++對象與HWND結婚。