天天看點

IContextMenu第五部分:處理菜單消息

在我們編寫代碼完成上下文菜單的顯示之後,我們留了一個問題。

就是”打開方式”和”發送”這兩個子菜單不能如預期般工作。

這是咋回事?

原因在于,這些子菜單是延遲建立的,這就解釋了為什麼當你嘗試展開這些菜單時,沒有顯示出任何有用的東西。另外有些子菜單是自繪型菜單,也會存在這樣的問題。

這個時候,如果要解決這個問題,就需要使用新的手段了,也就是今天我們要講的:

IContextMenu2::HandleMenuMsg和IContextMenu3::HandleMenuMsg2這兩個方法。

這裡要說一則曆史故事

IContextMenu2::HandleMenuMessage是新增加的IContextMenu2接口的一個方法,我們沒有在原有的IContextMenu接口中直接添加,而是另外派生一個新的接口。主要原因是,IContextMenu是在Windows 95後期開發中加入的,我們覺得新增加一個接口比在原有接口上做變更會更加安全,也盡可能地保持了向後相容,這樣的帶來的好處是開發者不需要重寫它們的外殼擴充代碼。

如果我沒記錯的話,

IContextMenu3::HandleMenuMessage2這個方法被添加到了Internet Explorer 4中,主要是為了支援自繪型上下文菜單鍵盤可通路性而添加的。

在真實程式中,這兩個接口變量應該被定義為視窗類的成員變量,但為了示範目的,我将它們定義成了全局變量。當編寫你自己的程式的時候,請注意,不要使用全局變量,因為當涉及第二個視窗時,它們将導緻大規模混亂。因為這兩個視窗都會嘗試和同一個接口做互動,而實際上在同一時刻,隻會有一個視窗會顯示上下文菜單。

IContextMenu第五部分:處理菜單消息

這兩個接口成員會追蹤目前顯示的上下文菜單,我們需要在調用TrackPopupMenuEx之前或者之後對它們進行初始化或者銷毀,如下圖所示:

IContextMenu第五部分:處理菜單消息

最後,我們需要在視窗過程中調用接口的方法,如下圖所示:

IContextMenu第五部分:處理菜單消息

在上面的代碼中,我們首先檢查接口是否為空,如果不為空,則調用其HandleMenuMsg來處理菜單相關的消息。如果調用成功,則直接傳回,不再進行後續的處理流程。

通過添加上述改動到我們的例子程式中,我們會發現世界變得稍微美好了一些:”打開方式”和”發送”這兩個子菜單現在可以正常工作了。

總結

我真驚了,這IContextMenu裡的小坑還不少。

各位還是小心為上。

最後

最近我寫了個東西

繼續閱讀