2012-05-14 68 views
2

我有Windows事件值,例如DefWindowsProc()獲得 - 即hWnd, MsgId, wParam, lParam是否有可能(從一些其他的或可能)區分WM_COMMAND事件與通知代碼BN_CLICKED是否到來從從複選框按鈕,或如何區分Windows上的按鈕和複選框消息?

動機:我正在重寫更大的應用程序中的GUI實現和消息處理。最終目標是wxWidgets,但我必須逐步完成。我確實模仿了宏和相關的EVT_BUTTON,EVT_CHECKBOX(...,EVT_SIZE,EVT_PAINT等)。我也模仿wxCommandEvent這樣的課程,我想將其類型設置爲wxEVT_COMMAND_BUTTON_CLICKEDwxEVT_COMMAND_CHECKBOX_CLICKED,當事件被原始代碼捕獲時。

例如:我有這樣

#define EVT_CHECKBOX(id, func) \ 
    if (uMsg == WM_COMMAND && id == LOWORD(wParam)) \ 
    { \ 
     CAppCommandEvent evt(hWnd, uMsg, wParam, lParam); \ 
     ATLASSERT(evt.GetEventType() == appEVT_COMMAND_CHECKBOX_CLICKED); \ 
     func(evt); \ 
     lResult = evt.GetLResult(); \ 
     if (!evt.GetSkipped()) \ 
      return TRUE; \ 
    } 

wxEVT_COMMAND_CHECKBOX_CLICKED宏有意重命名爲appEVT_...。我希望能夠檢查EVT_CHECKBOX宏是否沒有被用於(錯誤地)按鈕。如果是,則assert命令必須使該程序的調試版本可見。

回答

4

消息中沒有任何內容可以幫助您識別按鈕的類型。但是,理論上你應該能夠間接地找到它。 lParam爲您提供了控件的窗口句柄,您可以使用它與GetWindowLong一起獲取button style

LONG style = ::GetWindowLong(lParam, GWL_STYLE); 
if (style & BS_CHECKBOX) { 
    // It's a checkbox 
} 
+0

我想我們在這裏有一個贏家。好好考慮那個。 – chris

+0

雖然我沒有設置方便的測試來確認它的工作原理。這就是我在理論上說的原因。所以,牢記這一點。 – irobot

+1

我必須說的唯一的事情就是'GetWindowLong'在x64的'GetWindowLongPtr'中被棄用。它在文章的頂部。 – chris

0

「重寫GUI實現和消息在一個更大的應用程序處理。最終目標是wxWidgets的,但我必須要逐步做到這一點。」

真的嗎?恕我直言,你瘋了。使用wxWidgets重寫你的應用程序會比使用一些奇怪的一半的wxWidgets,半個你自己創建的原生Windows API更加容易,快捷,無限少。我能看到的唯一優勢是工作安全,因爲沒有人能夠維護你正在創建的這個怪物。

但是,要回答你的問題:wxWidgets區分這兩個事件。 wxEVT_COMMAND_CHECKBOX_CLICKED由複選框生成,wxEVT_COMMAND_BUTTON_CLICKED由按鈕生成。 wxWidgets代碼是開放的,並且有很好的文檔記錄,所以請看看它們是如何實現的。

+0

謝謝。看來你很快判斷。你會嘗試用自制的動態佈局管理用250 + k行代碼重寫所有內容嗎?首先,我需要使它與wxWidgets儘可能相似。我確實在看過wxWidget源。如果您向我展示源文件和解決Windows問題的線路,我會對此評論加註。 – pepr

+0

是的,我會的。有兩種可能性。你的代碼庫是正確組織的,只有實現GUI的小部分需要重寫,所以最簡單的部分需要重寫。或者你的代碼組織得非常糟糕,以至於GUI實現被分散在整個250K中,因此很難重寫它來修復一個可怕的混亂。 – ravenspoint

+0

我們可以在別處討論它。但是你是否認爲案件介於兩者之間的可能性,並且還有一部分GUI必須重寫?坦率地說,我不想效仿被完全改寫的Netscape Navigator的案例。 – pepr