程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> C語言 >> VC >> 關於VC++ >> 再談客戶區對話框拖動操作

再談客戶區對話框拖動操作

編輯:關於VC++

《無標題對話框的拖動》,示范了如何用鼠標點擊窗口或對話框背景(即客戶區)進行拖動操作,文章中提供的解決方法在沒有上下文菜單的情況下運行很正常,一旦有上下文菜單時,文中所提供的方法便顯現出了缺陷——上下文菜單無法顯示出來。本文將針對這個問題對前一篇提出的方法進行改進。

當初實現拖動的基本思路是改寫 OnNcHitTest 例程,讓鼠標在客戶區中的點擊始終返回 HTCAPTION 而不是 HTCLIENT,從而誘使 Windows 實現拖動操作。沒想到這樣做使上下文菜單的操作出現了混亂,原因是如果強制 OnNcHitTest 在客戶區返回 HTCAPTION,Windows 不會發送 WM_CONTEXTMENU 消息。有一個解決是調用 GetKeyState 函數,在返回 HTCAPTION 之前檢查鼠標右鍵狀態。這個方法要求跟蹤鼠標左右鍵的交換操作。 也就是要自己處理虛擬鍵,而且如果用戶是個左撇子的話,這個方法是否還靈呢?如果有興趣,自己試試吧!除此之外,還有一個方案可以考慮,思路是當 Windows 得到 WM_NCHITTEST 消息時,鼠標按鍵已經釋放。我查閱了 MSDN 有關鼠標消息處理的資料,利用這一間隙,可以通過改寫 OnNcRButtonUp 例程對 WM_NCRBUTTONUP 消息進行處理: // OnNcRButtonUp 函數代碼
void CMyDialog::OnNcRButtonUp(UINT nHitTest, CPoint pt)
{
   if (nHitTest==HTCAPTION && PtInClientRect(pt))
  SendMessage(WM_CONTEXTMENU, (WPARAM)m_hWnd, MAKELPARAM(pt.x,pt.y));
   else
  CDialog::OnNcRButtonUp(nHitTest, pt);
}

從代碼中不難看出,如果鼠標命中代碼所反映的鼠標位置為標題欄,而實際位置是在客戶區裡,那麼你必須自己發送 WM_CONTEXTMENU 消息。此為解決問題的關鍵,代碼既要在 OnNcHitTest 中誘使 Windows 把 HTCLIENT 當作 HTCAPTION 處理來實現拖動,又要判斷右鍵發出單擊操作時是否處在客戶區。如果是,則發送 WM_CONTEXTMENU 消息。注意當用戶在標題欄上單擊右鍵時,仍然要顯示系統菜單,這時讓 OnNcRButtonUp 做默認處理即可。下面是本文例子程序運行畫面:

圖一 例子程序運行畫面

詳細的處理細節請下載源代碼。

最後,大家身體健康,編程愉快!

本文配套源碼

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved