以 TrackPopupMenu 呼叫 PopupMenu 可否使用 OwnerDraw? |
答題得分者是:Zard
|
RedSnow
版主 發表:79 回覆:1322 積分:845 註冊:2003-12-15 發送簡訊給我 |
各位好,我在程式中的一個 Panel 的 OnMouseUp 事件中使用了 TrackPopupMenu 來呼叫 PopupMenu,以便在它顯示之前後可以做一些其它的設定 (例如:Timer on/off),原先一切運作都正常,後來因為要處理 PopupMenu 裡的字型變化,因此將 PopupMenu 的 OwnerDraw 屬性設為 true,並將各個 MenuItem 的 OnDrawItem 與 OnMeasureItem 事件設給對應的程序 (OnDrawItem 與 OnMeasureItem 事件的對應程序是原先使用在另一支程式作為繪製 MainMenu 之用,稍加修改後套用到現在寫的程式來),編譯過程很順利並未發生錯誤,結果在程式執行時,呼叫出來的 PopupMenu 是空的,經追蹤的結果,發現在 PopupMenu 顯示時,並未進入 OnDrawItem 與 OnMeasureItem 事件的對應程序,後來我將執行過程避開 TrackPopupMenu 程序 (將透過 TrackPopupMenu 呼叫 PopupMenu 的動作改為直接設定給一個 Panel 物件的 PopupMenu 屬性,並將 AutoPopup 為 true),重新執行的結果是選單項目能正常的顯示。 請問各位先進們,是否使用 TrackPopupMenu 來呼叫 PopupMenu 就無法使用 OwnerDraw 的功能?還是有什麼地方需要額外作一些設定?
|
Zard
尊榮會員 發表:24 回覆:396 積分:539 註冊:2003-11-26 發送簡訊給我 |
其實你猜對了, 直接呼叫TrackPopupMenu無法觸發OwnerDraw事件.
把TPopupMenu的原始碼挖出來看一下就可以知道原因了, TPopupMenu用來處理Popup的函式為 procedure TPopupMenu.Popup(X, Y: Integer); 他最後是用TrackPopupMenu(FItems.Handle, AFlags, X, Y, 0 { reserved }, PopupList.Window, nil); 來彈出選單的, 重點就在PopupList.Window, 這是指定處理彈出選單訊息的Parent Window, 而PopupList在他的訊息迴圈有這麼一段
WM_DRAWITEM: ........... DrawMenuItem(MenuItem, Canvas, rcItem, TOwnerDrawState(LongRec(itemState).Lo)); ........... WM_MEASUREITEM: ...........發現了嗎? 其實PopupList會先攔到WM_MEASUREITEM, WM_DRAWITEM這兩個事件, 攔到WM_DRAWITEM再去呼叫DrawMenuItem, DrawMenuItem呼叫AdvancedDrawItem, AdvancedDrawItem才呼叫你的OnDrawItem事件, WM_MEASUREITEM也是經過類似的步驟, 有興趣你可以去看看Delphi的原始碼. 不過建議你直接呼叫TPopupMenu.Popup(X, Y: Integer); 來取代TrackPopupMenu, 自己做太麻煩了. |
RedSnow
版主 發表:79 回覆:1322 積分:845 註冊:2003-12-15 發送簡訊給我 |
|
Zard
尊榮會員 發表:24 回覆:396 積分:539 註冊:2003-11-26 發送簡訊給我 |
|
RedSnow
版主 發表:79 回覆:1322 積分:845 註冊:2003-12-15 發送簡訊給我 |
Zard 您好: 我大概瞭解您的意思了,當初我查看說明文件時,文件上對 TrackPopupMenu 第六個參數 hWnd 值的說明是 "handle of owner window",而上網搜尋相關範例時也都是直接指向程式本身的 Handle 值,因此都沒能觸發到您所說的那個方向,原先我之所以會使用 TrackPopupMenu 來呼叫 PopupMenu,是因為我需要在 PopupMenu 出現的前/後有個 "暫停等待" 的時機,以便做 Timer off/on 等動作之處理,當我查看 BCB Help 時,TPopupMenu::Popup() 的說明太過簡要,並未讓我瞭解到它也會有 "等待" (以便於在視窗顯示前後做相關設定) 的效果,而讓我最意外的就是您所給予的 "答案" - TrackPopupMenu 會無法觸發 OwnerDraw 的事件,經過您的說明後,我改用 TPopupMenu::Popup() 來處理原先的動作,目前可達到原定需求,對於您所描述的方式,我欠缺相關的經驗,因此暫不去研究您說的自製程序,未來若有進一步需要的話,希望能有機會再向您討教,多謝您的協助與說明。
|
本站聲明 |
1. 本論壇為無營利行為之開放平台,所有文章都是由網友自行張貼,如牽涉到法律糾紛一切與本站無關。 2. 假如網友發表之內容涉及侵權,而損及您的利益,請立即通知版主刪除。 3. 請勿批評中華民國元首及政府或批評各政黨,是藍是綠本站無權干涉,但這裡不是政治性論壇! |