Solved

UserControl and Mouse

Posted on 1998-08-27
12
642 Views
Last Modified: 2012-06-27
I've developed a usercontrol that realy needs to know wend the mouse is no longer over it.

I'm using a timer to do so, but as we all know, timers are very hungry for resources.

I've tried hooking the control but no message was received wend the mouse is outside the control, Hooking the parent is no soluction cos it could be a picture or something else of the same size of the control, so no mouse move event will fire!!

HELP!!!
0
Comment
Question by:PedroMVGomes
  • 4
  • 4
  • 2
  • +2
12 Comments
 
LVL 3

Expert Comment

by:a111a111a111
ID: 1431403
I think this will help you.


Option Explicit
'When outside the form or...
Private Declare Function GetActiveWindow Lib "user32" () As Long

Private Type tagRect
   lngLeft As Long
   lngTop As Long
   lngRight As Long
   lngBottom As Long
End Type

' Two different declarations for the same API function.
Private Declare Sub ClipCursor Lib "user32" _
 (typRect As tagRect)
Private Declare Sub ClipCursorClear Lib "user32" _
 Alias "ClipCursor" (ByVal param As Any)

Private Declare Sub GetWindowRect Lib "user32" _
 (ByVal hWnd As Long, typRect As tagRect)

Private Sub cmdClip_Click()
   Dim typRect As tagRect
   Static sstrCaption As String
   Dim hWnd As Long
   Dim X
   Dim OldName
   Dim NewName
   Dim MyFile
   Static fClip As Boolean
     
   Name OldName As NewName ' Rename file.
           
   If fClip Then
      Call ClipCursorClear(vbNullString)
      cmdClip.Caption = sstrCaption
   Else
      hWnd = GetActiveWindow()
      sstrCaption = cmdClip.Caption
      cmdClip.Caption = "Free the Mouse!"
      Name NewName As OldName   ' Rename file.
      Call GetWindowRect(hWnd, typRect)
      Call ClipCursor(typRect)
     
   End If
   fClip = Not fClip
End Sub

Private Sub Form_Load()
   Call ClipCursorClear(vbNullString)
   KeyPreview = True
End Sub

shay@hili.com
0
 
LVL 3

Expert Comment

by:a111a111a111
ID: 1431404
Correction to some element that not needed in the first code

==============start============

Option Explicit
'When outside the form or...
Private Declare Function GetActiveWindow Lib "user32" () As Long

Private Type tagRect
   lngLeft As Long
   lngTop As Long
   lngRight As Long
   lngBottom As Long
End Type

' Two different declarations for the same API function.
Private Declare Sub ClipCursor Lib "user32" _
 (typRect As tagRect)
Private Declare Sub ClipCursorClear Lib "user32" _
 Alias "ClipCursor" (ByVal param As Any)

Private Declare Sub GetWindowRect Lib "user32" _
 (ByVal hWnd As Long, typRect As tagRect)

Private Sub cmdClip_Click()
   Dim typRect As tagRect
   Static sstrCaption As String
   Dim hWnd As Long
   Static fClip As Boolean
           
   If fClip Then
      Call ClipCursorClear(vbNullString)
      cmdClip.Caption = sstrCaption
   Else
      hWnd = GetActiveWindow()
      sstrCaption = cmdClip.Caption
      cmdClip.Caption = "Free the Mouse!"
     
      Call GetWindowRect(hWnd, typRect)
      Call ClipCursor(typRect)
     
   End If
   fClip = Not fClip
End Sub

 =====================end==============
0
 
LVL 1

Expert Comment

by:redbaron082997
ID: 1431405
I am not sure if the above answer is what you are looking for: Try this idea, create an event in your usercontrol call MouseOver. Then in your usercontrol_mousemove event, raiseEvent MouseOver.

In Program, where the control is placed, create the procedure:
private sub Control_MouseOver()
  MouseInControl = true
end sub
private sub form_mouseMove()
  mouseincontrol = false
end sub

MouseInControl is a public variable, that you can test anytime you need to find where the mouse is. If you need more details, let me know. I have this working on a control, and it does work.
0
 
LVL 3

Expert Comment

by:a111a111a111
ID: 1431406
Okay I am working on modification and will send you the code ASAP.
0
 
LVL 3

Expert Comment

by:a111a111a111
ID: 1431407
Okay here is the mouse over proj.

you need : Label1 and  Timer1 .


=========== start ================

Option Explicit

Dim highlighted As Boolean

Private Type POINTAPI
    x As Long
    y As Long
End Type
Private Declare Function ScreenToClient Lib "user32" (ByVal hwnd As Long, lpPoint As POINTAPI) As Long
Private Declare Function GetCursorPos Lib "user32" (lpPoint As POINTAPI) As Long

' Highlight the control.
Private Sub Label1_MouseMove(Button As Integer, Shift As Integer, x As Single, y As Single)
    If highlighted Then Exit Sub
    highlighted = True
    Label1.ForeColor = vbRed
    Timer1.Enabled = True
End Sub

' See if we should unhighlight the control.
Private Sub Timer1_Timer()
Dim pt As POINTAPI

    ' See where the cursor is.
    GetCursorPos pt
   
    ' Translate into window coordinates.
    ScreenToClient hwnd, pt

    ' See if we're still within the control.
    If pt.x < Label1.Left Or pt.y < Label1.Top Or _
       pt.x > Label1.Left + Label1.Width Or _
       pt.y > Label1.Top + Label1.Height _
    Then
        highlighted = False
        Label1.ForeColor = vbBlack
        Timer1.Enabled = False
    End If
End Sub

================ end ===============

shay@hili.com

0
 
LVL 1

Expert Comment

by:redbaron082997
ID: 1431408
Again, I question this, since in the question, PedroMVGomes states that he is using a timer. The function I gave doesn't require the amount of resources, and yields the same results.
PedroMVGomes - What are your thoughts?
0
Do You Know the 4 Main Threat Actor Types?

Do you know the main threat actor types? Most attackers fall into one of four categories, each with their own favored tactics, techniques, and procedures.

 
LVL 1

Expert Comment

by:redbaron082997
ID: 1431409
Again, I question this, since in the question, PedroMVGomes states that he is using a timer. The function I gave doesn't require the amount of resources, and yields the same results.
PedroMVGomes - What are your thoughts?
0
 
LVL 2

Author Comment

by:PedroMVGomes
ID: 1431410
i would like if you explian me what does your answer do cos i'm not uderstanding
0
 
LVL 1

Expert Comment

by:redbaron082997
ID: 1431411
By not using a timer control at all, you free up resourses. In main form code body, declare a variable like this:

DIM bMouseInControl as boolean.

Then handle the event MouseOver like this:

private sub Control_MouseOver()
  MouseInControl = true
end sub

Private Sub Form1_MouseMove(Button As Integer, Shift As Integer, x As Single, y As Single)
    MouseInControl = False
End Sub

Also, handle the event for the forms mousemove, so that when the form is over the form, not the Usercontrol, it sets the varibale to false. You will have to handle this for each control on the form as well


MouseOver is an event that you create in your custom control, and that you call in the controls MouseMove Event.
Ex: (This code goes in custom control)

Private Sub UserControl_MouseMove(Button As Integer, Shift As Integer, x As Single, y As Single)
    RaiseEvent MouseMove(Button, Shift, x, y)
    RaiseEvent MouseOver
End Sub



Let me know if you need clarification.

Ronnie
0
 
LVL 2

Author Comment

by:PedroMVGomes
ID: 1431412
I do not consider that as an answer, a user control must be independent, as and ActiveX it can be in many places (including a web Page) and it isn't anyway possible to intruct the user of the control to do such coding, the control must provide itself in a way to detect that the mouse is no longer in it.

I've build it with a timer, and searching a way to do it without the timer, not a way to force the control user to do it
0
 
LVL 1

Expert Comment

by:jf26028
ID: 1431413
You dont need a timer at all.  You can just use the mousemove command with an api call.  If you are not going to give the points to anyone else, I can post this code for you.
0
 
LVL 2

Accepted Solution

by:
wj7ster earned 150 total points
ID: 1431414
You need to do the following (using Windows API calls, don't worry, they are easy ones...)

Copy the following into the general declaration section of your UserControl:
' ----------------------------------------------------------
Private Declare Function SetCapture Lib "user32" Alias "SetCapture" (ByVal hwnd As Long) As Long
Private Declare Function ReleaseCapture Lib "user32" Alias "ReleaseCapture" () As Long

Private MouseOver       As Boolean
Private MouseDown       As Boolean
Private MouseCaptured   As Boolean

Private Sub UserControl_MouseDown(Button As Integer, Shift As Integer, X As Single, Y As Single)

    MouseDown = True
    UserControl_MouseMove Button, Shift, X, Y
   
End Sub

Private Sub UserControl_MouseMove(Button As Integer, Shift As Integer, X As Single, Y As Single)
   
    If X > 0 And X < UserControl.Width And Y > 0 And Y < UserControl.Height Then
        MouseOver = True
        SetCapture UserControl.hwnd
        MouseCaptured = True
        ' Here you can redraw the control, if needed, to indicate that the mouse is over it.
    Else
        If Not MouseDown then
            MouseOver = False
            ReleaseCapture
            MouseCaptured = False
            ' some code when the mouse has been released etc.
        Else
            ' some more code etc...
        End If
    End If
   
End Sub

Private Sub UserControl_MouseUp(Button As Integer, Shift As Integer, X As Single, Y As Single)
   
    MouseDown = False
    UserControl_MouseMove Button, Shift, X, Y
   
End Sub
' ----------------------------------------------------------

With this code you can even detect when the mouse is up or down and decide not to release when the mouse button is down and not over the control (This is standard Windows behaviour, by the way)  This code does not require a timer and is very simple to implement.
0

Featured Post

6 Surprising Benefits of Threat Intelligence

All sorts of threat intelligence is available on the web. Intelligence you can learn from, and use to anticipate and prepare for future attacks.

Join & Write a Comment

Enums (shorthand for ‘enumerations’) are not often used by programmers but they can be quite valuable when they are.  What are they? An Enum is just a type of variable like a string or an Integer, but in this case one that you create that contains…
Background What I'm presenting in this article is the result of 2 conditions in my work area: We have a SQL Server production environment but no development or test environment; andWe have an MS Access front end using tables in SQL Server but we a…
Get people started with the utilization of class modules. Class modules can be a powerful tool in Microsoft Access. They allow you to create self-contained objects that encapsulate functionality. They can easily hide the complexity of a process from…
Show developers how to use a criteria form to limit the data that appears on an Access report. It is a common requirement that users can specify the criteria for a report at runtime. The easiest way to accomplish this is using a criteria form that a…

705 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

18 Experts available now in Live!

Get 1:1 Help Now