Jump to content

Detect if Mouse is pushed (mouse move) on screen top corner


MDCT
 Share

Recommended Posts

Hello, guys. Is it possible to detect if mouse is pushed (mouse move) on screen top corner?

Basically, I want to have a gui that would appear when mouse is pushed upward on the top corner, because otherwise, the gui would appear too easy by accident. I could make a timer, but I feel, it would not be productive.

Below is the example, the gui would appear when mouse Y pos is 0, but the gui appears too easy, thus it became problem for me.

#include <GUIConstants.au3>

$gui = GUICreate("", 100, 100, -1, -1,  $WS_POPUP, BitOR($WS_EX_TOPMOST, $WS_EX_NOACTIVATE, $WS_EX_TOOLWINDOW))
GUISetBkColor(0xffff00)
WinSetTrans($gui,"",0)
GUISetState(@SW_SHOWNOACTIVATE, $gui)
$Show=0

While 1
   Sleep(64)
   If MouseGetPos()[1] = 0 Then
      If Not $Show Then
         WinSetTrans($gui,"",255)
         $Show=1
      EndIf
   Else
      If $Show Then
         WinSetTrans($gui,"",0)
         $Show=0
      EndIf
   EndIf
WEnd

Is it possible to detect mouse push (mouse move) on the screen corner? Or maybe there is a better way to prevent accidentally showing the gui?

Thank you.

Edited to clarify, push I meant to push mouse move up, not push mouse button. 

Edited by MDCT
Link to comment
Share on other sites

#include <GUIConstants.au3>

$gui = GUICreate("", 100, 100, -1, -1,  $WS_POPUP, BitOR($WS_EX_TOPMOST, $WS_EX_NOACTIVATE, $WS_EX_TOOLWINDOW))
GUISetBkColor(0xffff00)
WinSetTrans($gui,"",0)
GUISetState(@SW_SHOWNOACTIVATE, $gui)
$Show=0

While 1
    Sleep(64)

    $bLeft_click = False
    $aInfo = GUIGetCursorInfo($gui)
    If IsArray($aInfo) And $aInfo[2] = 1 Then
        $bLeft_click = True
    EndIf

    If $bLeft_click And MouseGetPos()[1] = 0 Then
        If Not $Show Then
            WinSetTrans($gui,"",255)
            $Show=1
        EndIf
    Else
        If $Show Then
            WinSetTrans($gui,"",0)
            $Show=0
        EndIf
    EndIf
WEnd

Next comment should be Func WM_NOTIFY() with test on $NM_CLICK, let's complicate it :D

Edited by pixelsearch
Link to comment
Share on other sites

@MDCT

Win* functions are all those functions which start with Win (WinActive, WinMove...).

Depending of what your goal is, you could detect the click on the Y = 0 (you didn'y specified the X by the way, which could be left corner as well as right one), and then, use WinSetState() to let display your Window or hide it :)

Click here to see my signature:

Spoiler

ALWAYS GOOD TO READ:

 

Link to comment
Share on other sites

@FrancescoDiMuro

Ah, yes. Now I understand what you are talking about. Thank you for the suggestion, I may use that conditions if I cannot solve this problem.

I did not set the x because i want to show the gui only by pushing up (mouse move) on the top corner of the screen, but I started to think x is also important to prevent gui shown by accident.

I may have a solution using Mouse Hook and playing around with x, y, and time to my liking, but I haven't solved it yet. Anyway, thanks again for trying to help!

 

Link to comment
Share on other sites

10 minutes ago, FrancescoDiMuro said:

@MDCT

You could even use HotKeySet() to show/hide your GUI... So, no mouse clicks or anything else more than a key combination :)

It could be an option, but the gui I am going to show is used for task switcher, like a taskbar. So, it would not be productive to press keyboard shortcut, use mouse to chose the task, and click to jump between tasks...it would be an additional action that I want to avoid, actually.  But, thanks for the idea tho.

Link to comment
Share on other sites

Link to comment
Share on other sites

6 hours ago, Nine said:

Another option would be to calculate the time the user is staying at Y = 0.  If he stays there (like) more than 1 secs, then you can show the window.

Yes, I may use x, y, and timer for this to prevent accidental activation. But with timer, it would reduce productivity, I like with y=0 only, as it's fast if I want to switch tasks, but occasion activation became problem in real practice. Thank you for trying to help me! 

Link to comment
Share on other sites

I think I have found a solution to my problem.

I am using Mouse Hook to check X, Y, and timestamp. If timestamp is small and x difference is small it means I am pushing mouse up.

; ~~ Mouse Hook ~~
;For more info, Visit: http://msdn.microsoft.com/en-us/library/ms644986(VS.85).aspx

;Include GUI Consts
#include <GUIConstants.au3> ;for $GUI_EVENT_CLOSE
#Include <WinAPI.au3> ;for HIWORD

;Consts/structs from msdn
Global Const $MSLLHOOKSTRUCT = $tagPOINT & ";dword mouseData;dword flags;dword time;ulong_ptr dwExtraInfo"
;~ Global Const $WH_MOUSE_LL = 14           ;already declared
;~ Global Const $tagPOINT = "int X;int Y"   ;already declared

;Register callback
$hKey_Proc = DllCallbackRegister("_Mouse_Proc", "int", "int;ptr;ptr")
$hM_Module = DllCall("kernel32.dll", "hwnd", "GetModuleHandle", "ptr", 0)
$hM_Hook = DllCall("user32.dll", "hwnd", "SetWindowsHookEx", "int", $WH_MOUSE_LL, "ptr", DllCallbackGetPtr($hKey_Proc), "hwnd", $hM_Module[0], "dword", 0)

Global $X1=0, $X2,  $Time1=0, $Time2, $Time3, $Counter=0 ,$Show=0, $ShowCount=0, $Y=1

While 1
   Sleep(16)
   If $Y>0 Then ContinueLoop
   If $Time1 <> $Time2 Then
      If $Time2 - $Time1 < 70 Then
         $Counter+=1
         If Abs($X2 - $X1) < 3 and $Counter=2 Then
            $Counter=0
            $ShowCount+=1
            ConsoleWrite($ShowCount&@CRLF)
         EndIf
         $X1=$X2
      Else
         $Counter=0
      EndIf
      $Time1 = $Time2
   EndIf
WEnd

Func _Mouse_Proc($nCode, $wParam, $lParam) ;function called for mouse events..
    ;define local vars
    Local $info

    If $nCode < 0 Then ;recommended, see http://msdn.microsoft.com/en-us/library/ms644986(VS.85).aspx
        $ret = DllCall("user32.dll", "long", "CallNextHookEx", "hwnd", $hM_Hook[0], _
                "int", $nCode, "ptr", $wParam, "ptr", $lParam) ;recommended
        Return $ret[0]
    EndIf


    $info = DllStructCreate($MSLLHOOKSTRUCT, $lParam) ;used to get all data in the struct ($lParam is the ptr)
   $X2 = DllStructGetData($info, 1)
    $Y = DllStructGetData($info, 2)
   $Time2 = DllStructGetData($info, 5)


    ;This is recommended instead of Return 0
    $ret = DllCall("user32.dll", "long", "CallNextHookEx", "hwnd", $hM_Hook[0], _
            "int", $nCode, "ptr", $wParam, "ptr", $lParam)
    Return $ret[0]
EndFunc   ;==>_Mouse_Proc

Func OnAutoItExit()
    DllCall("user32.dll", "int", "UnhookWindowsHookEx", "hwnd", $hM_Hook[0])
    $hM_Hook[0] = 0
    DllCallbackFree($hKey_Proc)
    $hKey_Proc = 0
EndFunc   ;==>OnAutoItExit

Now, the problem with Mouse Hook is that when TaskMan is on, it seems the hook is not registered.

I am thinking to use GUIRegisterMsg($WM_MOUSEMOVE, WM_MOUSEMOVE) and put the "mouse detection gui" in upper corner of the screen. But It's not pretty tho.

Oh well...I may just use a simpler solution suggested here. Thank you again guys for trying to help me!

Link to comment
Share on other sites

Here are a couple of methods.

This example toggles the GUI, show/hide, by the position of the mouse.

#include <GUIConstants.au3>
#include <Misc.au3>

Local $gui = GUICreate("", 100, 100, -1, -1, $WS_POPUP, BitOR($WS_EX_TOPMOST, $WS_EX_NOACTIVATE, $WS_EX_TOOLWINDOW))
GUISetBkColor(0xffff00)
;GUISetState(@SW_SHOW)
ToolTip("<- Move mouse here, or," & @CRLF & "      Press Esc to exit", 20, 0)

While 1
    Sleep(50)
    If _IsPressed("1B") Then Exit ; Press "Esc" key to exit

    If MouseGetPos(0) < 20 And MouseGetPos(1) = 0 Then ; True when mouse's 'X' coordinate is less than 20 and mouse's 'Y' coordinate is 0 (@ top of desktop)
        ; ---- Toggle Show/Hide GUI. -----
        If BitAND(WinGetState($gui), 2) Then ; 2 = Window is visible
            GUISetState(@SW_HIDE, $gui)
        Else
            GUISetState(@SW_SHOW, $gui)
        EndIf
        While MouseGetPos(0) < 20 And MouseGetPos(1) = 0 ; Avoids double key bounce
        WEnd
    EndIf
WEnd


This example partly hides the GUI when the mouse is not over the GUI.

#include <GUIConstants.au3>
#include <Misc.au3>
#include <WinAPISysWin.au3>
#include <WinAPIMisc.au3>

Local $gui = GUICreate("", 100, 100, @DesktopWidth / 2, -98, $WS_POPUP, BitOR($WS_EX_TOPMOST, $WS_EX_NOACTIVATE, $WS_EX_TOOLWINDOW))
GUISetBkColor(0xffff00)
GUISetState(@SW_SHOW)
ToolTip("^^Move mouse here ^^, or," & @CRLF & "      Press Esc to exit", @DesktopWidth / 2, 2)

While 1
    Sleep(50)
    If _IsPressed("1B") Then Exit ; Press "Esc" key to exit
    $tPoint = _WinAPI_GetMousePos()
    $hwnd = _WinAPI_WindowFromPoint($tPoint)
    If $hwnd = $gui Then
        ToolTip("")
        WinMove($gui, "", @DesktopWidth / 2, 0, 100, 100, 2)
    Else
        WinMove($gui, "", @DesktopWidth / 2, -98, 100, 100, 2)
    EndIf
WEnd

 

Link to comment
Share on other sites

Thank you for the great examples, Malkey.

I am still working for a light way to detect mouse-move push upward using GUIRegisterMsg, if I found it to be troublesome, I might use your second example.

To summary: I have found a solution to detect mouse is move pushing upward (eventhough y is 0 already) using MouseHook. However, MouseHook wont work if TaskMan is on. So now I'm trying for GUIRegisterMsg on a gui, that detects mouse movement, located on upper corner of screen with height of 1 pixel.

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