Solved

UserControl and Mouse

Posted on 1998-08-27
12
667 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
[X]
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
  • 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
Independent Software Vendors: We Want Your Opinion

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

 
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
 
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

SharePoint Admin?

Enable Your Employees To Focus On The Core With Intuitive Onscreen Guidance That is With You At The Moment of Need.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Suggested Solutions

When designing a form there are several BorderStyles to choose from, all of which can be classified as either 'Fixed' or 'Sizable' and I'd guess that 'Fixed Single' or one of the other fixed types is the most popular choice. I assume it's the most p…
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…
Get people started with the process of using Access VBA to control Excel using automation, Microsoft Access can control other applications. An example is the ability to programmatically talk to Excel. Using automation, an Access application can laun…
This lesson covers basic error handling code in Microsoft Excel using VBA. This is the first lesson in a 3-part series that uses code to loop through an Excel spreadsheet in VBA and then fix errors, taking advantage of error handling code. This l…

739 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