c++ builder裡四種處理“滑鼠離開窗體”事件的方法 (轉)
在處理窗體訊息的時候,我想不少人都會碰到滑鼠離開窗體的訊息(下面稱之為MouseLeave)。在C++ Builder裡,並沒有直接提供處理這種訊息的方法,需要我們自己動手來做。透過參考一些資料,我發現在C++ Builder裡面處理MouseLeave,不外乎以下四種方法,現寫出來供大家參考。如果有什麼不對之處,請指正。
(一)、笨拙的Timer
每每提到捕捉滑鼠離開窗體的訊息的時候,也許有人就會馬上想到用Timer來處理。不錯,這種方法很簡單,也確實有效。只須在Timer的OnTimer事件中判斷滑鼠所處位置的座標是否在窗體內就可以了,詳細程式碼如下:
void __fastcall TForm1::Timer1Timer(T *Sender)
{
POINT pt;
GetCursorPos(&pt); //得到滑鼠的座標
RECT rect;
GetWindowRect(Handle,&rect); //得到窗體的矩形範圍
if(!PtInRect(rect,pt)) //判斷滑鼠的座標是否在窗體的矩形範圍內
Caption="out";
else
Caption="in";
}
為什麼我要說是笨拙的Timer呢?原因有二:其一、OnTimer是優先順序別比較低的訊息,從嚴格意義上講,上面這種做法並不精準。如果正在處理一大堆級別比較高的訊息,那我們就無法及時獲得MouseLeave訊息。其二、Timer是比較寶貴的系統資源,用在MouseLeave上面似乎有些浪費了,因為我們還有更好的方法來做同樣的事情。
(二)、霸道的SetCapture()
SetCapture()可以讓指定的窗體捕獲所有滑鼠訊息,當然也包括MouseLeave了:
void __fastcall TForm1::FormMouseMove(TObject *Sender, TShiftState Shift,
int X, int Y)
{
Caption="in";
SetCapture(Handle);
TPoint pt(X,Y);
TRect rect;
rect=GetClientRect();
if (!PtInRect(rect,pt))
{
ReleaseCapture();
Caption="out";
}
}
不過這種方法太過於霸道了,因為SetCapture()將所有的滑鼠訊息據為己有。雖然在捕獲了MouseLeave以後已經ReleaseCapture了,但是在捕獲過程中,你卻無法對其他的滑鼠訊息做出反應。不信?你不妨在窗體在多放一個Button,再執行點點看?:)
(三)、受限的TrackMouseEvent()
MSDN上面說,TrackMouseEvent()可以讓指定的窗體接受WM_MOUSELEAVE訊息。但是在接受訊息以後如果還要繼續接受WM_MOUSELEAVE訊息,必須重新TrackMouseEvent():
//---------------------------------------------------------------------------
__fastcall TForm1::TForm1(TComponent* Owner)
: TForm(Owner)
{
MouseTrack=false; //TForm1的私有變數,檢測滑鼠是否已經被Track
}
//---------------------------------------------------------------------------
void __fastcall TForm1::WndProc(TMessage& Message) //過載WndProc
{
if (Message.Msg==WM_MOUSELEAVE) //在這裡捕獲WM_MOUSELEAVE訊息
{
Caption="out";
MouseTrack=false; //滑鼠Track已經完成
}
TForm::WndProc(Message);
}
//---------------------------------------------------------------------------
void __fastcall TForm1::FormMouseMove(TObject *Sender, TShiftState Shift,
int X, int Y)
{
Caption="in";
if (!MouseTrack)
{
TRACKMOUSEEVENT tt;
tt.cbSize=sizeof(tt);
tt.dwFlags=TME_LEAVE;
tt.hwndTrack=Handle;
TrackMouseEvent(&tt);
MouseTrack=true; //開始滑鼠Track
}
}
//---------------------------------------------------------------------------
這種方法很好用,唯一的缺點是可能不支援(具體支不支援我也沒有做過實驗,哪位兄弟有Win98的幫我測試一下)。在的環境下,我推薦用這種方法,:)
(四)、未知的CM_MOUSELEAVE
在CSDN論壇裡經常看到有人說可以透過捕獲CM_MOUSELEAVE訊息來達到同樣的效果。不過根據我的測試,CM_MOUSELEAVE在控制元件上面工作得很好,可以用來捕獲滑鼠離開控制元件的訊息。但用在窗體上似乎就不靈驗了,可能我自己沒有做對吧。如果有哪位大蝦知道該怎麼用,請告知小弟一聲,我將感激不盡。
以上程式碼均在 Professional+bcb6.0環境中編譯成功。
來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/10752043/viewspace-993083/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- 處理滑鼠離開視窗的訊息 (WM_MOUSELEAVE) (轉)
- C++ BUILDER 訊息處理的深入探索 (轉)C++UI
- C#窗體--滑鼠事件C#事件
- wx處理滑鼠事件事件
- C#視窗事件處理初探 (轉)C#事件
- 在C++ Builder中定義事件 (轉)C++UI事件
- 處理記憶體洩漏的一種MFC方法 (轉)記憶體
- JavaScript和JQuery的滑鼠mouse事件冒泡處理JavaScriptjQuery事件
- Simple WPF: WPF 透明窗體和滑鼠事件穿透事件穿透
- 一種高效的 vector 四則運算處理方法
- android的視窗機制分析------事件處理Android事件
- WIN32 SDK - 捕獲滑鼠離開和滯留等事件 (轉)Win32事件
- Flink處理函式實戰之四:視窗處理函式
- 處理字串的方法都在這裡字串
- Qt Creator中滑鼠鍵盤事件的處理實現自定義滑鼠指標QT事件指標
- 控制檯程式的事件處理 (轉)事件
- SQLite 併發的四種處理方式SQLite
- 關於Android的幾種事件處理Android事件
- 四種利用社交媒體推進事件的方法–資料資訊圖事件
- Automation In C++ Builder (轉)C++UI
- Windows系統資源不足的七種處理方法(轉)Windows
- 印表機離線如何處理 印表機離線的方法
- [轉] Scala 中的非同步事件處理非同步事件
- c++異常處理 (轉)C++
- C++中的預處理(上) (轉)C++
- C++中的預處理(下) (轉)C++
- 四種IT治理方法(轉載)
- 對比程式語言的四種錯誤處理方法,哪種才是最優方案?
- C++的另一種錯誤處理策略C++
- 'library cache lock'等待事件的處理方法事件
- c++ builder中的ado使用 (轉)C++UI
- Borland C++ Builder的API後門 (轉)C++UIAPI
- 處理物件的多種狀態及其相互轉換——狀態模式(四)物件模式
- 各種報錯處理方法
- 也說說c++builder中的不規則窗體的實現 (轉)C++UI
- Javascript事件處理程式的5種方式(相容寫法)JavaScript事件
- C++開發必看四種強制型別轉換的總結C++型別
- 事件處理事件