程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> C語言 >> C >> C語言基礎知識 >> 追蹤鼠標

追蹤鼠標

編輯:C語言基礎知識
很喜歡一些軟件的按鈕:鼠標移進去,就會呈現某種效果(如文字變色、突起顯示等等),移出以
後效果就消失。但是自己動手的時候,卻發現不像自己想象的那樣簡單。其中鼠標移入的效果很容
易實現,使用MouseMove事件就可以了,但是移出呢?要知道Windows裡並沒有鼠標移入移出的消
息呀!(至少我在C++ Builder自帶的Windows API裡翻了遍也沒找著。)以前,我就用了一些取
巧的方法來實現:

  1.比如要讓一個按鈕實現移入變色功能,我就在按鈕本身的MouseMove裡寫一句代碼,讓它的顏
色改變,然後在它的容器控件(如Form, Panel等等)的MouseMove裡寫一句代碼,讓它的顏色還
原。毋需多言,這樣的代碼肯定是很煩瑣的,特別是要控制的控件相當多的時候。

  2.在每個按鈕的MouseMove事件裡設置按鈕狀態。再使用一個定時器,每隔一段較短的時間檢測
狀態,根據狀態設置顏色。這樣做的好處是改變顏色的代碼段只有一段(在定時器事件裡),而不
像第一種方法一樣在許多地方改變顏色。但代碼依然是很煩瑣的,而且還要浪費一個定時器資源。

最重要的是,以上兩種方法都由控件外部來控制,這樣的話,想做一個實現這種功能的控件是不可
能了。那麼,那些第三方控件的這種功能是怎樣實現的呢?

一個偶然的機會,我看到了一個具有鼠標感知能力(注:我們把這種可以感知鼠標是否在自己上面
的能力叫做鼠標感知能力。)的控件的源代碼。於是就細細研究了起來。

在閱讀了一大堆令人目眩的代碼之後,我發現,它的鼠標感知能力是來自兩條消息:
CM_MOUSEENTER和CM_MOUSELEAVE,但是在它的源代碼中並沒有產生這兩個消息的任何語句。在
Window API幫助裡又查不到這兩條消息。奇怪,難道是微軟不想讓我們知道有這兩個消息?該死
的微軟……,等等!我發現CM_這個前綴並不是微軟的標准前綴(看來錯怪微軟了)。CM是……,
對了,是Custom Message的縮寫!好,這個消息不是控件編寫者自己寫的,也不是微軟提供的,
那麼……。不錯,這是Borland提供的一個用戶定義消息。其聲明在controls.hpp中。好,有了
這兩個消息,問題就好解決了。下面是我編寫的一個簡單的控件,為TSpeedButton增加了
EnterFontColor屬性和OnMouseEnter、OnMouseExit兩個事件。

//附:TexSpeedButton控件的關鍵程序段

//exSpeedButton.h
TexSpeedButton::public TSpeedButton
{
  //……………… 
private:
  TColor FEnterFontColor, FOldFontColor;
  TNotifyEvent FOnMouseEnter, FOnMouseExit;

protected:
  virtual void __fastcall WndProc(TMessage &Message);    //重載WndProc方法處理消

 
  virtual void __fastcall MouseEnter(void);              //鼠標感知的處理函數
  virtual void __fastcall MouseExit(void)                //定義成虛以便以後繼承

public:
  //………………

__publish:

  __property TColor EnterFontColor = {read = FEnterFontColor, write 
FEnterFontColor, default = clBlue};
  __property TNotifyEvent OnMouseEnter = {read = FOnMouseEnter, write = 
FOnMouseEnter};
  __property TNotifyEvent OnMouseExit  = {read = FOnMouseExit,  write = 
FOnMouseExit};
};

//exSpeedButton.cpp
TexSpeedButton::TexSpeedButton(TComponent *Owner):public TSpeedButton(Owner)
{
  FEnterColor = clBlue;        //移入顏色缺省為藍色
}

void TexSpeedButton::WndProc(TMessage &Message)
{
  TCustomControl::WndProc(Message);      //調用祖先類的缺省處理(注:這是4.0版的寫法, 5.0中TCustomControl的WndProc方法已經被隱藏,只能用TControl::WndProc)
 
  if (Message.Msg == CM_MOUSEENTER)      //處理CM_MOUSEENTER消息
  {
    MouseEnter();
    Repaint();                          //別忘了刷新界面
  }

  if (Message.Msg == CM_MOUSELEAVE)      //處理CM_MOUSELEAVE消息
  {
    MouseEnter();
    Repaint();                          //同樣別忘了刷新界面
  }
}

void TexSpeedButton::MouseEnter(void)
{
  if(FOnMouseEnter)      //如果事件處理句柄存在(用戶寫了相應事件)
  {
    FOnMouseEnter(this);  //執行用戶定義的事件
  }
  else                    //否則執行缺省處理
  {
    FOldFontColor = Font->Color;
    Font->Color  = FEnterFontColor;
  }
}

void TexSpeedButton::MouseExit(void)
{
  if(FOnMouseEnter)      //如果事件處理句柄存在(用戶寫了相應事件)
  {
    FOnMouseEnter(this);  //執行用戶定義的事件
  }
  else                    //否則執行缺省處理
  {
    Font->Color  = FOldFontColor;
  }
}

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