VB中没有鼠标移出事件,请问该用什么方法来实现这样一个功能呢?

解决方案 »

  1.   

    在你想要的vb窗体上通过设置mouseIcon使得在此区域获得独特的鼠标样式,不就得了吗?
      

  2.   

    先取得物件的handle得到他的clientarea
    在物件上層容器中的MOUSEMOVE中判斷範圍去執行你要的程序
      

  3.   

    请楼上明示,,最后给个例子我,谢谢了
    对了,是IMAGE
      

  4.   

    按照我的理解,给你一个简单的例子:
    Private Sub Command1_MouseMove(Button As Integer, Shift As Integer, X As Single, Y As Single)
        Command1.Caption = "鼠标在按钮上"
    End Sub
    Private Sub Form_MouseMove(Button As Integer, Shift As Integer, X As Single, Y As Single)
        Command1.Caption = "鼠标不在按钮上"
    End Sub
      

  5.   

    '捕捉 MouseExit 事件(源程序)  
    Private Declare Function SetCapture Lib "user32" (ByVal hWnd As Long) As Long
    Private Declare Function ReleaseCapture Lib "user32" () As LongPrivate Sub Cmd1_MouseMove(Button As Integer, Shift As Integer, X As Single, Y As Single)  With Cmd1
           
        If (X < 0) Or (Y < 0) Or (X > .Width) Or (Y > .Height) Then
             
          ReleaseCapture
          ' 放入鼠标离开的代码
          .Caption = "Out"
       
        Else
         
          SetCapture .hWnd
          ' 放入鼠标进入的代码
          .Caption = "in"
           
        End If
           
      End With
       
    End Sub
      

  6.   


    这个方法已经用过了,我同一个Form有很多个 image ,用Form的MOVE 事情,太慢了。。
    如果有二十个控件,,
    Private Sub Form_MouseMove(Button As Integer, Shift As Integer, X As Single, Y As Single) 
        Command1.Caption = "鼠标不在按钮上" 
        Command2.Caption = "鼠标不在按钮上" 
        Command3.Caption = "鼠标不在按钮上" 
    ...
        Command20.Caption = "鼠标不在按钮上" End Sub 
    这样效率有点低。
      

  7.   

    换image为picbox,如果不能换,只能靠timer控件来实时监测
      

  8.   

    不可以换成Picbox..
    用timer如何来监测呢。。
      

  9.   

    只能写个大概:
    type pointapi
    x as long
    y as long
    end type引用windowfrompoint和getcursorpos API
    private sub timer1_timer()
    dim hcursorwnd as long,point as pointapi
    getcursorpos point
    hcursorwnd=windowfrompoint(point.x,point.y)
    if point.x and point.y 在commandbutton上 then
    ...
    else
    ...
    end if
    end sub
      

  10.   

    Private Declare Function SetCapture Lib "user32" (ByVal hWnd As Long) As Long
    Private Declare Function ReleaseCapture Lib "user32" () As LongDim obj As ObjectPrivate Sub Form_MouseMove(Button As Integer, Shift As Integer, X As Single, Y As Single)
        If obj Is Nothing Then
            Exit Sub
        End If
        If X < obj.Left Or X > obj.Left + obj.Width Or Y < obj.Top Or Y > obj.Top + obj.Height Then
            ReleaseCapture
            obj.Caption = "离开了"
            Set obj = Nothing
        End If
    End SubPrivate Sub Command1_MouseMove(Button As Integer, Shift As Integer, X As Single, Y As Single)
        SetCapture Me.hWnd
        Set obj = Command1
        Command1.Caption = "进来了"
    End Sub
    Private Sub Frame1_MouseMove(Button As Integer, Shift As Integer, X As Single, Y As Single)
        SetCapture Me.hWnd
        Set obj = Frame1
        Frame1.Caption = "进来了"
    End SubPrivate Sub Label1_MouseMove(Button As Integer, Shift As Integer, X As Single, Y As Single)
        SetCapture Me.hWnd
        Set obj = Label1
        Label1.Caption = "进来了"
    End SubPrivate Sub Label2_MouseMove(Button As Integer, Shift As Integer, X As Single, Y As Single)
        SetCapture Me.hWnd
        Set obj = Label2
        Label2.Caption = "进来了"
    End Sub
    Private Sub Label3_MouseMove(Button As Integer, Shift As Integer, X As Single, Y As Single)
        SetCapture Me.hWnd
        Set obj = Label3
        Label3.Caption = "进来了"
    End Sub
      

  11.   

    重载控件的消息循环(子类化),在WM_MOUSEMOVE消息,调用TrackMouseEvent函数,其中TRACKMOUSEEVENTTYPE结构填充为:
    With tTrackMouse
        .cbSize = Len(tTrackMouse)
        .dwFlags = TME_LEAVE
        .hwndTrack = 控件.hwnd
    End With这样,当鼠标离开该控件,系统会给其发WM_MOUSELEAVE消息,这样就可以得知了。
    注意,需要设置一个标志,避免在WM_MOUSEMOVE里多次调用TrackMouseEvent。
      

  12.   

    路过.IMAGE是轻量控件.......无句柄的.我提供个思路,楼主看看如何吧:同一时间鼠标只能在一个控件上产生MOVE消息.那么,你窗体里定义一个变量,其值为唯一标志每个控件的内容,比如控件NAME & INDEX.然后写一个函数,在每个控件的MOUSEMOVE事件里调用即可:private ControlFlag as stringprivate sub GetMouse(byval theFlag as string)
        if theflag<>controlflag then
            '这里就可以确定上次鼠标所在控件,即鼠标"离开"了哪个控件
            debug.print "离开了:" & controlflag , "进入了:" & theflag
        end if
    end subprivate sub Image1_MouseMove(xxxxxxxxxxxxxxxxxx)
        call getmouse("Image1")      '每个控件的MOUSEMOVE事件里加这一句即可
        '其它内容
    end sub
    这样子结构好些.话又说回来,最多是编码效率低,执行效率不可能因为这几个判断就低下来吧?
      

  13.   

        if theflag<>controlflag then
            '这里就可以确定上次鼠标所在控件,即鼠标"离开"了哪个控件
            debug.print "离开了:" & controlflag , "进入了:" & theflag
           controlflag=theflag       '忘了加这一句
        end if
      

  14.   

    Private Const TME_LEAVE = &H2Private Type TrackMouseEvent
        cbSize As Long
        dwFlags As Long
        hwndTrack As Long
        dwHoverTime As Long
    End Type'当在指定时间内鼠标指针离开或盘旋在一个窗口上时,此函数寄送消息
    Private Declare Function TrackMouseEvent Lib "user32" _
                    (lpEventTrack As TrackMouseEvent) As BooleanPrivate Sub Command1_MouseMove(Button As Integer, Shift As Integer, X As Single, Y As Single)
    Dim tme As TrackMouseEvent
    'initialize   structure
    tme.cbSize = Len(tme)
    tme.hwndTrack = Command1.hwnd
    tme.dwFlags = TME_LEAVE
    'start   the   tracking
    TrackMouseEvent tme
    End SubPrivate Sub Form_Load()
    SubClass Command1.hwnd
    End SubPrivate Sub Form_Unload(Cancel As Integer)
    UnSubClass Command1.hwnd
    End SubOption ExplicitPublic Const GWL_WNDPROC = (-4)
    Private Const WM_MOUSELEAVE = &H2A3
    Private Const WM_MOUSEWHEEL = &H20A
    Declare Function CallWindowProc Lib "user32" Alias "CallWindowProcA" (ByVal lpPrevWndFunc As Long, ByVal hwnd As Long, ByVal Msg As Long, ByVal wParam As Long, ByVal lParam As Long) As Long
    Declare Function GetWindowLong Lib "user32" Alias "GetWindowLongA" (ByVal hwnd As Long, ByVal nIndex As Long) As Long
    Declare Function SetWindowLong Lib "user32" Alias "SetWindowLongA" (ByVal hwnd As Long, ByVal nIndex As Long, ByVal dwNewLong As Long) As Long
    Public prevWndProc As Long
    Dim t As BooleanFunction WndProc1(ByVal hwnd As Long, ByVal Msg As Long, ByVal wParam As Long, ByVal lParam As Long) As Long
        If Msg = WM_MOUSEWHEEL Then
        If wParam > 0 Then
        Form1.Text1.Text = Form1.Text1.Text + 1
        Else
            If Form1.Text1.Text > 0 Then Form1.Text1.Text = Form1.Text1.Text - 1
        End If
        End If
        WndProc = CallWindowProc(prevWndProc, hwnd, Msg, wParam, lParam)
        
    End Function
    Function WndProc(ByVal hwnd As Long, ByVal Msg As Long, ByVal wParam As Long, ByVal lParam As Long) As Long
        If Msg = WM_MOUSELEAVE Then
            Debug.Print "leave", Now
        End If
        WndProc = CallWindowProc(prevWndProc, hwnd, Msg, wParam, lParam)
        
    End Function
    Public Sub SubClass(ByVal hwnd As Long)
    prevWndProc = SetWindowLong(hwnd, GWL_WNDPROC, AddressOf WndProc)
    End SubPublic Sub UnSubClass(ByVal hwnd As Long)
    prevWndProc = SetWindowLong(hwnd, GWL_WNDPROC, prevWndProc)
    End Sub