Solved

GetCursorPos(...) in Access

Posted on 2007-04-09
31
843 Views
Last Modified: 2008-02-01
I have this code to move the mouse pointer to a desired location on a form (I think):

Private Declare Function SetCursorPos Lib "user32" (ByVal x As Long, ByVal y As Long) As Long
using:

Call SetCursorPos 100,45 ' for example.

Now, I need similar function to return X, and Y value of the mouse pointer where ever it might be on the form. I am looking for GetCursorPos(...)

Thanks.
0
Comment
Question by:Mike Eghtebas
  • 18
  • 7
  • 3
  • +2
31 Comments
 
LVL 65

Accepted Solution

by:
rockiroads earned 200 total points
Comment Utility
something like this perhaps?
http://www.freevbcode.com/ShowCode.Asp?ID=1120

Option Explicit

Private Type POINTAPI
    X As Long
    Y As Long
End Type

Private Declare Function GetCursorPos Lib "user32" (lpPoint As POINTAPI) As Long

Public Function GetXCursorPos() As Long
   Dim pt As POINTAPI
   GetCursorPos pt
   GetXCursorPos = pt.X
End Function

Public Function GetYCursorPos() As Long
   Dim pt As POINTAPI
   GetCursorPos pt
   GetYCursorPos = pt.Y
End Function


0
 
LVL 33

Author Comment

by:Mike Eghtebas
Comment Utility
Now, I guess all I need to do is:

Debug.Print  "x= " & GetXCursorPos()  & ", y= " & GetYCursorPos

I am testing although your solution don't need to be tested.

Mike
0
 
LVL 85

Assisted Solution

by:Mike Tomlinson
Mike Tomlinson earned 200 total points
Comment Utility
"I have this code to move the mouse pointer to a desired location on a form"

When using GetCursorPos() and SetCursorPos(), remember that you are working with SCREEN coordinates.

If you need convert Form cooordinates to Screen coords then use:

    Private Declare Function ClientToScreen Lib "user32" (ByVal hwnd As Long, lpPoint As POINTAPI) As Long

and the oppositie would be:

    Private Declare Function ScreenToClient Lib "user32" Alias "ScreenToClient" (ByVal hwnd As Long, lpPoint As POINTAPI) As Long
0
 
LVL 33

Author Comment

by:Mike Eghtebas
Comment Utility
Idle_Mind,

What a pleasure to hear from you. Year 2004, I learned a lot from you with my VB questions.

Conversion issue was one of the points I was strugling with just now.  your post will be helpfull in that regard.

Another issue I am dealing with is to find left position of the form. In VB, I have used me.left but it seems not working in Access.

FYI: What I am tying to do to detect (in the form timer event) if the user has the cursor on a certain button:

    If (GetXCursorPos >= cmdStop.Left And GetXCursorPos <= (cmdStop.Left + cmdStop.Width)) Then And _
    (GetYCursorPos <= cmdStop.Top And GetYCursorPos >= (cmdStop.Top + cmdStop.Height)) Then
        bolStop = True
        cmdStop.SetFocus
    Else
        bolStop = False
    End If

Of course, I need yet to include form's .left and .top property in the code.

Thank you to both my favorite experts.

Mike
0
 
LVL 33

Author Comment

by:Mike Eghtebas
Comment Utility
Background: variable bolStop is set to control the code used to print files. By holding/clicking cmdStop, user is able to stop print process.

At a later question I will post, I would try to send a commant to the printer to cancle all print jobs from a specific user (to cancle all print jobs qued to be printed). I am not sure whether such action is possible or not.

Regards,

Mike
0
 
LVL 26

Expert Comment

by:EDDYKT
Comment Utility
? should you just trap the mousemove event?
0
 
LVL 65

Expert Comment

by:rockiroads
Comment Utility
Hi Mike, I went offline after I posted but I see what you are trying to do

idle mind, I didnt know about that api, now I do, thanks

If u just want to capture the position of a mouse to see if its over a certain control then I think the answer from EDDYKT would solve that for you

cmdstop_mousemove  is called whenever the mouse is moved over that button
u may want to handle users using the keyboard as well? so perhaps u also need to check for cmdstop_gotfocus as well
0
 
LVL 33

Author Comment

by:Mike Eghtebas
Comment Utility
re:> ? should you just trap the mousemove event?

Maybe. I am not sure. The reason for my uncertainty is while cpu is engaged running the print routine, why all of sudden a mouse move would be recognized (fire) in middle the print routine. I suspect it will come to it when the print routine is finished which to late then.

I am not even sure the print routine would allow timer to fire either. Then again I could test it to see how each behaves.

brb,

Mike
0
 
LVL 65

Expert Comment

by:rockiroads
Comment Utility
your print job, surely its just a case of you issuing it. You dont wait for that proces to end surely. One would assume u issue the command and revert focus back to access.
U could disable any buttons prior to call to print and renable them after print if that is what u are worried about
0
 
LVL 65

Expert Comment

by:rockiroads
Comment Utility
no, its stop print u want eh
oh
0
 
LVL 33

Author Comment

by:Mike Eghtebas
Comment Utility
Test results:


Timer event fires: 4/10/2007 8:57:18 AM
Timer event fires: 4/10/2007 8:57:19 AM
Timer event fires: 4/10/2007 8:57:19 AM
Timer event fires: 4/10/2007 8:57:20 AM

Print started at: 4/10/2007 8:57:20 AM

Timer event fires: 4/10/2007 8:57:20 AM
Timer event fires: 4/10/2007 8:57:21 AM
Timer event fires: 4/10/2007 8:57:21 AM
Timer event fires: 4/10/2007 8:57:22 AM

Print finished at: 4/10/2007 8:57:31 AM

Although I clicked on cmdStop quickly right after clicking on cmdStop, it kept these two events (cmdStop_MouseMove and cmdStop_GotFocus) to fire after it was done printing.

cmdStop_MouseMove fires at: 4/10/2007 8:57:31 AM
cmdStop_GotFocus fires at: 4/10/2007 8:57:31 AM
cmdStop_MouseMove fires at: 4/10/2007 8:57:31 AM
Timer event fires: 4/10/2007 8:57:31 AM
Timer event fires: 4/10/2007 8:57:32 AM

But timer event fired without DoEvents or something else.

This is the reason why I though I have to use timer to check if the pointer is within cmdStop's boundry.

Mike
0
 
LVL 33

Author Comment

by:Mike Eghtebas
Comment Utility
correction...

Although I clicked on cmdStop quickly right after clicking on cmdPrint, it kept these two events (cmdStop_MouseMove and cmdStop_GotFocus) to fire after it was done printing.
0
 
LVL 33

Author Comment

by:Mike Eghtebas
Comment Utility
re:> your print job, surely its just a case of you issuing it. You dont wait for that proces to end surely.

My code cycles through files selected and prints them one at a time. If I have 12 files selected and the timer sets bolStop = True and my print routine has:

If bolStop = True Then
   now print
Else
  MsgBox "Print job is cancled by user."
  Exit Sub
End If

Mike
0
 
LVL 33

Author Comment

by:Mike Eghtebas
Comment Utility
I am not sure how to apply code from Idle_Mind:

Private Declare Function ClientToScreen Lib "user32" (ByVal hwnd As Long, lpPoint As POINTAPI) As Long

Private Declare Function ScreenToClient Lib "user32" Alias "ScreenToClient" (ByVal hwnd As Long, lpPoint As POINTAPI) As Long

to my code:

Private Sub Form_Timer()

    Dim intX As Long        ' x-position of the cursor
    Dim intY As Long        ' y-position of the cursor
   
    Dim intLeft As Long     ' left of smdStop
    Dim intRight As Long    ' right of smdStop
   
    Dim intTop As Long      ' top of smdStop
    Dim intBottom As Long   ' bottom of smdStop
   
    intX = GetXCursorPos
    intY = GetYCursorPos
   
    intLeft = cmdStop.Left
    intRight = cmdStop.Left + cmdStop.Width
   
    intTop = cmdStop.Top
    intBottom = cmdStop.Top + cmdStop.Height
   
    If (intX >= intLeft And intX <= intRight) And _
       (intY <= intTop And intY >= intBottom) Then
       
            bolStop = True
            cmdStop.SetFocus
            DoEvents
    Else
        bolStop = False
    End If

End Sub

to make it work. Also I am not quite sure about:

...  (intY <= intTop And intY >= intBottom) Then

portion.

Thank you,

Mike
0
 
LVL 34

Assisted Solution

by:jefftwilley
jefftwilley earned 100 total points
Comment Utility
Hey Mike...

Read this thread over. I helped this guy with positioning his mouse.

http://www.experts-exchange.com/Microsoft/Development/MS_Access/Access_Coding-Macros/Q_22452987.html
0
Better Security Awareness With Threat Intelligence

See how one of the leading financial services organizations uses Recorded Future as part of a holistic threat intelligence program to promote security awareness and proactively and efficiently identify threats.

 
LVL 33

Author Comment

by:Mike Eghtebas
Comment Utility
jefftwilley,

I have a good solution here. What I need a bit help to make it work that is if you have a moment to make sense of my last post.

Mike
0
 
LVL 34

Expert Comment

by:jefftwilley
Comment Utility
No time tonight...let me tackle it again in the morning.
J
0
 
LVL 33

Author Comment

by:Mike Eghtebas
Comment Utility
Thanks.
0
 
LVL 34

Expert Comment

by:jefftwilley
Comment Utility
Mike,
I've had time this morning to read through your posts...and here's what I think.

I also have a process...mine involves importing and exporting though...but I'm still simply looping through and starting processes. There can be up to 20 or 30 of them. I use a method similar to this one

If bolStop = True Then
   now print
Else
  MsgBox "Print job is cancled by user."
  Exit Sub
End If

However...because the button click itself isn't actually recognized until my process finishes and tries to start the next item in the loop...I too am forced to wait for that ONE import/export to finish.

While designing and testing this particular process, I too thought there had to be a way to stop it immediately...and issuing a BREAK did at times cancel the process....but often times, that had unpredictable results.

I understand that you're trying to create a predictive process...where by you are relying on a big assumption, that IF your user's mouse is hovering over the CANCEL button, then he must be about to press it. I don't think that's good practice.

In theory, you can issue your mouse to move...you can gain it's coordinates in a timer event, but you're still within a process, that when cancelled, could quite possibly error out and bypass your exit routine within your code.

This can...will leave recordsets open, file handles open, etc...and probably orphan a print job that you'll have to manually cancel.

Convince me that my points have all been taken into consideration, and that you have it under control, and I too would love to have this function that handles a situation I too have been in....and opted for a more Code friendly answer to.

I'll play with this..get it working...but I won't know how to apply it to cancel your print job. I'm assuming you have that handled?
J
0
 
LVL 65

Expert Comment

by:rockiroads
Comment Utility
Mike, instead of worrying about the cursor position, what if u used a global variable (well global to the form) and the mousemove events of detail and cmdStop

dim m_bOnStopBtn as boolean

private sub form_load()
    m_bOnStopBtn = False
end sub

Private Sub Detail_MouseMove(Button As Integer, Shift As Integer, X As Single, Y As Single)
    m_bOnStopBtn = False
end sub

Private Sub cmdStop_MouseMove(Button As Integer, Shift As Integer, X As Single, Y As Single)
    m_bOnStopBtn = True
end sub


then perhaps use m_bOnStopBtn to determine whether to kick off other events or not

eg

private sub form_timer()
    if m_bOnStopBtn = True then
          'do what u need to if cursor on stopbtn
    else
          'etc
    end if
end sub
0
 
LVL 33

Author Comment

by:Mike Eghtebas
Comment Utility
rockiroads,

I guess you haven't read one of my earlier post on "Test results:"


Timer event fires: 4/10/2007 8:57:18 AM
Timer event fires: 4/10/2007 8:57:19 AM
Timer event fires: 4/10/2007 8:57:19 AM
Timer event fires: 4/10/2007 8:57:20 AM

If you do, you would see mouse move cannot be activated (fired) during the print process.

Please help me with my last post which starts with:

"I am not sure how to apply code from Idle_Mind:

Private Declare Function ClientToScreen Lib "user32" (ByVal hwnd As Long, lpPoint As POINTAPI) As Long

Private Declare Function ScreenToClient Lib "user32" Alias "ScreenToClient" (ByVal hwnd As Long, lpPoint As POINTAPI) As Long
.
."

Thanks.

Now, I am reading the posts from Jeff.

Mike

0
 
LVL 33

Author Comment

by:Mike Eghtebas
Comment Utility
jefftwilley,

In my case, the Timer is able to fire and change the value of bolStop from True to False and visa versa. And, my print routine involves reading some file names from a list box. Using the code below:

If bolStop = True Then
   now print
Else
  MsgBox "Print job is cancled by user."
  Exit Sub
End If

if bolStop = True it will print. And once the print code is executed there is no way to undo it (at least for now. I will discuss this further later on with you).

So, there will be no files left open or orphan. The only point is I am dealing with buton left, form left and cursor position using code from Idle_Mind.

Unfortunately, I am not how to bring all together. But, I will eventually will be able to accomplish this task.
=======
Future quest:
Scenario: 10 files are sent to the printer and at this moment the printer is printing file 3 of 10.

User moves the mouse to Panic or Stop Print button. Usere resets bolStop to True when the next file (the 11th file) is being processed.

If bolStop = True Then
   now print
Else
  MsgBox "Print job is cancled by user."
  CancelAllPrintJobsInThePrinter
  Exit Sub
End If

Routine like "CancelAllPrintJobsInThePrinter" might be possible may be not.

If we have only 10 files to print, means now after 10th file is available to be clicked on and it responds to mouse move also.

Now, the idea is to accomplish the first phase of it (post starting:

"I am not sure how to apply code from Idle_Mind:

Private Declare Function ClientToScreen Lib "user32" (ByVal hwnd As Long, lpPoint As POINTAPI) As Long

Private Declare Function ScreenToClient Lib "user32" Alias "ScreenToClient" (ByVal hwnd As Long, lpPoint As POINTAPI) As Long
.
.")

Mike

0
 
LVL 85

Expert Comment

by:Mike Tomlinson
Comment Utility
Working...standby.
0
 
LVL 33

Author Comment

by:Mike Eghtebas
Comment Utility
Thank you very much.

Mike
0
 
LVL 65

Expert Comment

by:rockiroads
Comment Utility
Mike, I tried to get this going but couldnt quite get the right coordinates
Its almost perfect for X (top) but I couldnt quite get left (Y) working

this is the module code

Private Type POINTAPI
    X As Long
    Y As Long
End Type

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

Public Function GetXCursorPos(ByVal lHwnd As Long) As Long
   Dim pt As POINTAPI
   GetCursorPos pt
   ScreenToClient lHwnd, pt
   GetXCursorPos = pt.X
End Function

Public Function GetYCursorPos(ByVal lHwnd As Long) As Long
   Dim pt As POINTAPI
   GetCursorPos pt
   ScreenToClient lHwnd, pt
   GetYCursorPos = pt.Y
End Function


and in the form, I call GetXCursorPos/GetYCursorPos by passing in Me.hwnd
eg
GetXCursorPos(Me.hwnd)
GetYCursorPos(Me.hwnd)

I created a sample form, one button (cmdStop), two labels (lblCurrPos, lblCmdPos)
lblCmdPos shows values of cmdStop (left,top,height,width)
lblCurrPos shows current cursor position

i.e.

Private Sub Form_Load()
    Me.lblCmdPos.Caption = "T=" & cmdStop.Top & ", L=" & cmdStop.Left & ", W=" & cmdStop.width & ", H=" & cmdStop.height
End Sub

Private Sub cmdStop_MouseMove(Button As Integer, Shift As Integer, X As Single, Y As Single)
    Me.lblCurrPos.Caption = "on mouse"
End Sub

Private Sub Detail_MouseMove(Button As Integer, Shift As Integer, X As Single, Y As Single)
    Me.lblCurrPos.Caption = "X=" & GetXCursorPos(Me.hwnd) & ", Y=" & GetYCursorPos(Me.hwnd)
End Sub

Private Sub Form_MouseMove(Button As Integer, Shift As Integer, X As Single, Y As Single)
    Me.lblCurrPos.Caption = "X=" & GetXCursorPos(Me.hwnd) & ", Y=" & GetYCursorPos(Me.hwnd)
End Sub



But Im thinking about this and still not sure if these events can also be captured during the print process. Is it because the print process has all the cpu time, not sure.
0
 
LVL 65

Expert Comment

by:rockiroads
Comment Utility
Im gonna have another play, try to match coordinates correctly. Will have to do this 2morrow now
0
 
LVL 33

Author Comment

by:Mike Eghtebas
Comment Utility
Thank you rockiroads for the time.

Re:>Is it because the print process has all the cpu time, not sure.

By looking to my test resluts from the previous posts, despit the fact print process (or better to say print process of may small files) starts at:

Print started at: 4/10/2007 8:57:20 AM

the form timer fires after print has started:

Timer event fires: 4/10/2007 8:57:20 AM

and befor print finishes at:

Print finished at: 4/10/2007 8:57:31 AM
============
Now, when the user moves the mouse to Panic or Stop Print button while code is in the process of printing the value of bolStop will change to True according my test results.  If the code is in the process of printing say 100 files one at a time and before printing each file checks the value of bolStop:

If bolStop = True Then
   'continue printing current file
Else
  MsgBox "Print job is cancled by the user."
  CancelAllPrintJobsInThePrinter
  Exit Sub
End If

Routine like "CancelAllPrintJobsInThePrinter" might be possible may be not. It is considered possibly to chase the print jobs to the printer and cancled these qued files inside the printer waiting to be printed.

As I said, this is the overkill I am hoping to address later on. Plan A is to stop sending to the printer when user moves the cursor over the panic button (or cmdStop). Plan B is to develope routine like CancelAllPrintJobsInThePrinter to stop print jobs already in the printer.

Regards,

Mike
0
 
LVL 33

Author Comment

by:Mike Eghtebas
Comment Utility
rockiroads,

I coppied your code and created what you have described in your last post. For clarity, I cahnged following code only:

Private Sub Form_Load()
    Me.lblCmdPos.Caption = "Y1=" & cmdStop.Top & ", Y2=" & cmdStop.Top + cmdStop.Height & " , X1=" & cmdStop.Left & ", X2=" & cmdStop.Left + cmdStop.Width
End Sub

It works now!  I need still study it a bit but it works.

Thank you.

Mike
0
 
LVL 33

Author Comment

by:Mike Eghtebas
Comment Utility
rockiroads and Idle_Mind,

Rocky's code on the test form (when no printing taking places) work fine, but it doesn't let Time fire. I move the form's MouseMove event to:

Private Sub Form_Timer()
' this event never fires
    Me.lblCurrPos.Caption = "X=" & GetXCursorPos(Me.hwnd) & ", Y=" & GetYCursorPos(Me.hwnd)
    DoEvents
    Me.Repaint
   ' this never takes place----v
   If lblCurrPos.Caption = "on mouse" Then
        bolStop = True
   Else
        'bolStop = False
   End If

End Sub
=========
Is there a way we avoid to use such a indirect response:

If lblCurrPos.Caption = "on mouse" Then

In direct because lblCurrPos first need to be set to "on mouse" and then our code have some chance to works.

Or, instead of setting its caption to "on mouse", why we cannot set bolStop to True?

Mike
0
 
LVL 33

Author Comment

by:Mike Eghtebas
Comment Utility
I gave up.

Thank you to all.  My last atempt was to create another Panic.mdb with a single button (cmdStop) to change the value of TestVal (yes/no field) in a table tTest in this database. And, include the following code in the print module mdb. It read the setting from Panic.mdb okay but it doesn't fire when it is printing (despit my earlier test results). Here is the code:

Private Sub Form_Timer()
   
    If bolStop = False Then
        DoEvents
        Dim dbsNorthwind As Database
        Dim conPubs As Connection
        Dim rstTemp As Recordset
       
        Set dbsNorthwind = Workspaces(0).OpenDatabase("Panic.mdb")
       
        Set rstTemp = dbsNorthwind.OpenRecordset( _
        "tTest", dbOpenForwardOnly)
        If rstTemp.RecordCount > 0 Then
        'rstTemp.MoveFirst
        bolStop = rstTemp!TestVal
        End If
       
        rstTemp.Close
        dbsNorthwind.Close
       
        lblTest.Caption = bolStop
        Me.Repaint
        DoEvents
    End If

End Sub


Mike
0
 
LVL 33

Author Comment

by:Mike Eghtebas
Comment Utility
Please see "Stop/Cancel Print Job..." at

http://www.experts-exchange.com/Microsoft/Development/MS_Access/Q_22509816.html

to handle it in a different manner. Any help is appreciated.

Mike
0

Featured Post

Find Ransomware Secrets With All-Source Analysis

Ransomware has become a major concern for organizations; its prevalence has grown due to past successes achieved by threat actors. While each ransomware variant is different, we’ve seen some common tactics and trends used among the authors of the malware.

Join & Write a Comment

Most everyone who has done any programming in VB6 knows that you can do something in code like Debug.Print MyVar and that when the program runs from the IDE, the value of MyVar will be displayed in the Immediate Window. Less well known is Debug.Asse…
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…
Learn how to number pages in an Access report over each group. Activate two pass printing by referencing the pages property: Add code to the Page Footers OnFormat event to capture the pages as there occur for each group. Use the pages property to …
Basics of query design. Shows you how to construct a simple query by adding tables, perform joins, defining output columns, perform sorting, and apply criteria.

762 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

9 Experts available now in Live!

Get 1:1 Help Now