Jump to content

Problems with mouse events in Windows 7


R0cc0
 Share

Recommended Posts

You said you could not get a ControlClick to work, it does work.

waive your Autoit cock around as much as you like, I'm done here you absolute fucking cock end.

Over and out.

Thank you for the professional response. I also left out that it still does not work on my system (Windows 7 Ultimate x64) unless I also activate the window to receive events. That's 2 errors in your answer, but who's counting?

Link to comment
Share on other sites

  • Developers

You said you could not get a ControlClick to work, it does work.

waive your Autoit cock around as much as you like, I'm done here you absolute fucking cock end.

Over and out.

What about you control your own emotions for a change and walk away if you dont like what is asked.

You started to move this thread into excalation mode due to your perception and I expect members that are here longer to know how it works in our forums. Maybe you are right and maybe not, but let us do our work and judge that.

This is now the second time i am addresing you on something like this and dont particularly like to have to do that.

Hope this setles it,

Jos

Edited by Jos

SciTE4AutoIt3 Full installer Download page   - Beta files       Read before posting     How to post scriptsource   Forum etiquette  Forum Rules 
 
Live for the present,
Dream of the future,
Learn from the past.
  :)

Link to comment
Share on other sites

There is a problem with conrolclick() in Autoit 3.3.6.1.

Did you tried Autoit Beta 3.3.7.21 ?

It's worth a shot. I got nothing right now.

But unless there is a change in the functions which Autoit calls for mouse events, I do not expect to see any different results on my system. That is, having to activate all windows which receive mouse events.

Link to comment
Share on other sites

No difference. Here is the example script with comments explaining what is happening:

#include <Misc.au3> ; needed for _IsPressed()
#include <WindowsConstants.au3> ; needed for $WS_POPUP
#region "my code"
$x = (@DesktopWidth/2)-50
$y = (@DesktopHeight/2)-50
;create 4 identical guis 50 pixels apart with a button
$gui1 = GUICreate("gui1", 50, 50, $x, $y, $WS_POPUP)
GUISetBkColor(0xFF0000)
$btn1 = GUICtrlCreateButton("btn1", 5, 15, 40, 20)
GUISetState()
$gui2 = GUICreate("gui2", 50, 50, $x + 50, $y, $WS_POPUP)
GUISetBkColor(0xFF0000)
$btn2 = GUICtrlCreateButton("btn2", 5, 15, 40, 20)
GUISetState()
$gui3 = GUICreate("gui3", 50, 50, $x, $y + 50, $WS_POPUP)
GUISetBkColor(0xFF0000)
$btn3 = GUICtrlCreateButton("btn3", 5, 15, 40, 20)
GUISetState()
$gui4 = GUICreate("gui4", 50, 50, $x + 50, $y + 50, $WS_POPUP)
GUISetBkColor(0xFF0000)
$btn4 = GUICtrlCreateButton("btn4", 5, 15, 40, 20)
GUISetState()
; press esc to quit
HotKeySet("{ESC}", "Quit")
; set mouse coords relative to the active window
Opt("MouseCoordMode", 0)
; set mouse coords relative to the client area of the active window
; Opt("MouseCoordMode", 2)
While 1
; if the left mouse button is press then
If _IsPressed(Hex(1)) Then

  ; get mouse position within the active gui
  $pos = MouseGetPos()
  ConsoleWrite("X: " & $pos[0] & @LF & "Y: " & $pos[1] & @LF)

  ; activate the target gui
  WinActivate($gui2); <-- causes both ControlClick to fail but report success if this is commented out

  ; click btn2 on gui2
  $ret = ControlClick($gui2, '', $btn2, "left", 1); <-- only fails if the window is not activated - pressing any button will press btn2
  ;$ret = ControlClick($gui2, '', '', "left", 1, $pos[0], $pos[1]) <-- fails but reports success unless btn2 is actually clicked

  ;check return value for error
  If $ret = 0 Then ConsoleWrite("ControlClick failed" & @LF)
  If $ret = 1 Then ConsoleWrite("ControlClick successful" & @LF)

  ;sleep until the mouse button is released
  While _IsPressed(Hex(1))
   Sleep(10)
  WEnd

EndIf
; check for gui events
$msg = GUIGetMsg()
Select
Case $msg = $btn4
  ConsoleWrite("btn4 pressed" & @LF)
Case $msg = $btn3
  ConsoleWrite("btn3 pressed" & @LF)
Case $msg = $btn2
  ConsoleWrite("btn2 pressed" & @LF)
Case $msg = $btn1
  ConsoleWrite("btn1 pressed" & @LF)
EndSelect
Sleep(10)
WEnd
Func Quit()
Exit
EndFunc
#endregion "my code"

This works on my system as it is, but not how I want it to work. I still have to activate the window "capturing" the mouse event. Also, unless a control ID is supplied then ControlClick will fail unless the actual mouse click originated on gui2.

I also still cannot do mouse drags with ControlClick even if it worked 100% as intended.

Link to comment
Share on other sites

R0cc0,

In your message loop are you not supposed to check for control within gui. None of your gui's contain all of the controls but you are treating it as such.

kylomas

If you are referring to using ControlClick without supplying a control ID; I could be mistaken, but I was under the assumption that it used to be possible to send clicks to a background window (i.e. not activated) at x/y position using ControlClick in this fashion. I say "used to" because it obviously isn't working for me right now.

However, I never used ControlClick for that since I usually needed to control the up and down clicks independently. That just isn't possible, and has never been possible, with ControlClick. The same situation is here. Even if it works like it's supposed to, I cannot send mouse events to a background window, let alone any controls, unless that window is activated. No matter what language I have tried.

Link to comment
Share on other sites

R0cc0,

I don't know what is wrong with the way you are using "controlclick", if anything. However, I believe your message loop is incorrect. This may or may not have anything to do with your problem, but it would be better to eliminate it as a possible problem.

The msg loop should be something like (not tested):

while 1
   $a10 = guigetmsg(1)
       switch $a10[1]
           case $gui1
              if $btn1 then .....
           case $gui2
              if $btn2 then ...
      endswitch
wend

kylomas

Forum Rules         Procedure for posting code

"I like pigs.  Dogs look up to us.  Cats look down on us.  Pigs treat us as equals."

- Sir Winston Churchill

Link to comment
Share on other sites

sec, I missed something... will edit in a sec.

I think you're on to something. It seems to work just fine like this: (Although it registers a lot more times than once per click, I'll have to iron that out.)

#include <Misc.au3> ; needed for _IsPressed()
#include <WindowsConstants.au3> ; needed for $WS_POPUP
#region "my code"
$x = (@DesktopWidth/2)-50
$y = (@DesktopHeight/2)-50
;create 4 identical guis 50 pixels apart with a button
$gui1 = GUICreate("gui1", 50, 50, $x, $y, $WS_POPUP)
GUISetBkColor(0xFF0000)
$btn1 = GUICtrlCreateButton("btn1", 5, 15, 40, 20)
GUISetState()
$gui2 = GUICreate("gui2", 50, 50, $x + 50, $y, $WS_POPUP)
GUISetBkColor(0xFF0000)
$btn2 = GUICtrlCreateButton("btn2", 5, 15, 40, 20)
GUISetState()
$gui3 = GUICreate("gui3", 50, 50, $x, $y + 50, $WS_POPUP)
GUISetBkColor(0xFF0000)
$btn3 = GUICtrlCreateButton("btn3", 5, 15, 40, 20)
GUISetState()
$gui4 = GUICreate("gui4", 50, 50, $x + 50, $y + 50, $WS_POPUP)
GUISetBkColor(0xFF0000)
$btn4 = GUICtrlCreateButton("btn4", 5, 15, 40, 20)
GUISetState()
; press esc to quit
HotKeySet("{ESC}", "Quit")
; set mouse coords relative to the active window
Opt("MouseCoordMode", 0)
; set mouse coords relative to the client area of the active window
; Opt("MouseCoordMode", 2)
While 1
; if the left mouse button is press then
If _IsPressed(Hex(1)) Then
 
  ; get mouse position within the active gui
  $pos = MouseGetPos()
  ConsoleWrite("X: " & $pos[0] & @LF & "Y: " & $pos[1] & @LF)
 
  ; activate the target gui
  ;WinActivate($gui2); <-- causes both ControlClick to fail but report success if this is commented out
 
  ; click btn2 on gui2
  ;$ret = ControlClick($gui2, '', $btn2, "left", 1); <-- only fails if the window is not activated - pressing any button will press btn2
  $ret = ControlClick($gui2, '', '', "left", 1, $pos[0], $pos[1]); <-- fails but reports success unless btn2 is actually clicked
 
  ;check return value for error
  If $ret = 0 Then ConsoleWrite("ControlClick failed" & @LF)
  If $ret = 1 Then ConsoleWrite("ControlClick successful" & @LF)
 
  ;sleep until the mouse button is released
  While _IsPressed(Hex(1))
   Sleep(10)
  WEnd
 
EndIf
$a10 = guigetmsg(1)
switch $a10[1]
case $gui1
if $btn1 then ConsoleWrite("btn1 pressed" & @LF)
case $gui2
if $btn2 then ConsoleWrite("btn2 pressed" & @LF)
case $gui3
if $btn3 then ConsoleWrite("btn3 pressed" & @LF)
case $gui4
if $btn4 then ConsoleWrite("btn4 pressed" & @LF)
endswitch
#cs Old method for detecting events
; check for gui events
$msg = GUIGetMsg(1)
Select
Case $msg[0] = $btn4
  ConsoleWrite("btn4 pressed" & @LF)
Case $msg[0] = $btn3
  ConsoleWrite("btn3 pressed" & @LF)
Case $msg[0] = $btn2
  ConsoleWrite("btn2 pressed" & @LF)
Case $msg[0] = $btn1
  ConsoleWrite("btn1 pressed" & @LF)
EndSelect
#CE
Sleep(10)
WEnd
Func Quit()
Exit
EndFunc
#endregion "my code"

I'm going to have to experiment around some more to see why my clicks are failing in my source script (I use OnEvent mode). Then I'll worry about picking apart ControlClick in the old source code (assuming that part hasn't changed) to see how I can make the up and down clicks independent if I can't solve it in my script.

Edited by R0cc0
Link to comment
Share on other sites

r0cc0,

Your origional problem was that your script was working under XP and not under 7. Then you posted a re-producer that was not only tecnically incorrect but fundamentally different (event VS message loop mode). I think that you will have better luck getting the level of help you need if you post the actual script (or parts of it) that are failing.

Good Luck,

kylomas

Forum Rules         Procedure for posting code

"I like pigs.  Dogs look up to us.  Cats look down on us.  Pigs treat us as equals."

- Sir Winston Churchill

Link to comment
Share on other sites

r0cc0,

Your origional problem was that your script was working under XP and not under 7. Then you posted a re-producer that was not only tecnically incorrect but fundamentally different (event VS message loop mode). I think that you will have better luck getting the level of help you need if you post the actual script (or parts of it) that are failing.

Good Luck,

kylomas

The example was giving a false positive. It wasn't really clicking the button, only registering the click in the thread. My program cannot access another application's message thread with GUIGetMsg(). Therefore the application must receive a real simulated click, if that makes sense.

Here is an example using MSPaint, which much more closely resembles what I am working with:

#include <Misc.au3> ; needed for _IsPressed()
#region "my code"
$x = (@DesktopWidth/2)-500
$y = (@DesktopHeight/2)-250
$hWnd1 = Run(@WindowsDir & "system32mspaint.exe")
WinWaitActive("[Class:MSPaintApp]", '', 10)
$title1 = "Window 1"
WinSetTitle("[Class:MSPaintApp]", '', $title1)
WinMove($title1, '', $x, $y, 500, 500)
$hWnd2 = Run(@WindowsDir & "system32mspaint.exe")
WinWaitActive("[Class:MSPaintApp]", '', 10)
$title2 = "Window 2"
WinSetTitle("[Class:MSPaintApp]", '', $title2)
WinMove($title2, '', $x + 500, $y, 500, 500)
; press esc to quit
HotKeySet("{ESC}", "Quit")
; set mouse coords relative to the active window
;Opt("MouseCoordMode", 0)
; set mouse coords relative to the client area of the active window
Opt("MouseCoordMode", 2)
While WinExists($title1) And WinExists($title2);exit script if either window closes
;if the primary mouse button is pressed then
If _IsPressed(Hex(1)) And Winactive($title1) Then
 
  ; get mouse position within the active window
  $pos = MouseGetPos()
  ConsoleWrite("X: " & $pos[0]-1 & @LF & "Y: " & $pos[1]-147 & @LF);I'm guestimating the position since it's off? (it's close enough for me)
 
  ; activate the target gui
  WinActivate($title2); <-- both ControlClick fail if this is commented, but report success in the console
 
  ;$ret = ControlClick($title2, '', '[CLASS:Afx:630000:8; INSTANCE:1]', 'Primary', 1, $pos[0], $pos[1]); <-- fails no matter what, also reports failure
  $ret = ControlClick($title2, '', '', 'Primary', 1, $pos[0]-1, $pos[1]-147)
 
  ;check return value for error
  If $ret = 0 Then ConsoleWrite("ControlClick failed on Window 2" & @LF)
  If $ret = 1 Then ConsoleWrite("ControlClick successful on Window 2" & @LF)
 
  WinActivate($title1)
 
  ;sleep until the mouse button is released
  While _IsPressed(Hex(1))
   Sleep(10)
  WEnd
 
ElseIf _IsPressed(Hex(1)) And Winactive($title2) Then
 
  ; get mouse position within the active window
  $pos = MouseGetPos()
  ConsoleWrite("X: " & $pos[0]-1 & @LF & "Y: " & $pos[1]-147 & @LF)
 
  ; activate the target gui
  WinActivate($title1)
 
  ;$ret = ControlClick($title1, '', '[CLASS:Afx:630000:8; INSTANCE:1]', 'Primary', 1, $pos[0], $pos[1])
  $ret = ControlClick($title1, '', '', 'Primary', 1, $pos[0]-1, $pos[1]-147)
 
  ;check return value for error
  If $ret = 0 Then ConsoleWrite("ControlClick failed on Window 1" & @LF)
  If $ret = 1 Then ConsoleWrite("ControlClick successful on Window 1" & @LF)
 
  WinActivate($title2)
 
  ;sleep until the mouse button is released
  While _IsPressed(Hex(1))
   Sleep(10)
  WEnd
 
EndIf
Sleep(10)
WEnd
Func Quit()

WinClose($title1)
WinClose($title2)

Exit

EndFunc
#endregion "my code"

This works for me, until I comment out the WinActivate() functions. Then it fails miserably and also reports the failure in the console. So... back to the original problem. The OS is blocking the input when the window is not active.

Link to comment
Share on other sites

r0cc0,

Your origional problem was that your script was working under XP and not under 7. Then you posted a re-producer that was not only tecnically incorrect but fundamentally different (event VS message loop mode). I think that you will have better luck getting the level of help you need if you post the actual script (or parts of it) that are failing.

Good Luck,

kylomas

Posting any of the source code in any form is a violation of the license agreement under which the application was designed. This forum is supposed to be "against" illegal activity the last time I checked, and violating a copyright is illegal. There is much more involved than a few mouse events. The mouse event functions only account for about 1% of a 15,000 line script. But I would have to post over half of the script for someone to be able to follow what is going on. That would also mean parsing about 8000 lines of code. If I can't get help without the source, then I just can't get help. That's how is has to be.

The example above will suffice. If that example will work without window activation on my system, so will the source application. The old example was flawed because I slapped it together real quick without really thinking about what I was putting out. The new example was thought out.

Anyway, I guess it's time to move on. Either nobody here knows how to correct this issue, or they don't want to share. I will try to stop by to check on the thread from time to time if the issue still persists. But I'm focusing my efforts in other places since this issue is much bigger than Autoit alone.

Thanks to all for their time.

Link to comment
Share on other sites

  • 2 weeks later...

R0cc0,

Good Luck !!!

kylomas

Thanks!

I found my solution and figured I would point others in a good direction if they happen to be facing this issue. There may be other ways to accomplish this as well, but I haven't found them yet.

My solution involved using hooks and dll injection. I'm new to hooks, but it was time well spent.

Basically, the hook functions must be in a dll, the dll gets injected into the target process, and the dll is called from your exe.

The more detailed response will require some Google. :)

Link to comment
Share on other sites

  • 1 month later...

I take it my reference to J.R. was most helpful? He was good, no? :)

Injection is the ultimate backstage pass. Once properly injected, you can do anything to any process as if you own it. I hope you didn't use hooks to inject? That is the most common method used maliciously since it is the easiest method to use. So most anti-virus will throw a false positive even if your program is not a virus. I know yours isn't, but... I prefer to create a remote thread.

Anti-detection is another matter, if that's a potential issue... ;)

Drop me a line if you get this.

Link to comment
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
 Share

  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...