当前位置导航:炫浪网>>网络学院>>编程开发>>C++教程>>C++ Builder教程

c++builder里四种处理“鼠标离开窗体”事件的方法

在处理窗体消息的时候,我想不少人都会碰到鼠标离开窗体的消息(下面称之为MouseLeave)。在C++ Builder里,并没有直接提供处理这种消息的方法,需要我们自己动手来做。通过参考一些资料,我发现在C++ Builder里面处理MouseLeave,不外乎以下四种方法,现写出来供大家参考。如果有什么不对之处,请指正。

(一)、笨拙的Timer

       每每提到捕捉鼠标离开窗体的消息的时候,也许有人就会马上想到用Timer来处理。不错,这种方法很简单,也确实有效。只须在Timer的OnTimer事件中判断鼠标所处位置的坐标是否在窗体内就可以了,详细代码如下:

void __fastcall TForm1::Timer1Timer(TObject *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,

共2页 首页 上一页 1 2 下一页 尾页 跳转到
相关内容
赞助商链接