Jump to content

Recommended Posts

Posted

Hi there,

I am using a hotkey to show a small GUI next to the cursor. This is working fine, but I want to have the same behaviour/placement of my GUI as when using Tooltip - meaning the GUI should either be move in X or Y direction to have it in the visible window area.

The problem that I am facing is with multiple montiors.

  • I can get the MousePosition with _WinAPI_GetMousePos
  • I can get the current monitor _WinAPI_MonitorFromPoint
  • I can get the monitor dimension with _WinAPI_GetMonitorInfo

but I am unable to translate the MouseCoordinates from the absolut coordinates of all monitor the absolut coordinates on a specific montir.

Can someone point me in the right direction?

 

Posted (edited)
#include <WinAPIMisc.au3>
#include <WinAPIGdi.au3>

Local $tMousePos = _WinAPI_GetMousePos()

; Get the current monitor
Local $hMonitor = _WinAPI_MonitorFromPoint($tMousePos)
Local $tMonitorInfo = _WinAPI_GetMonitorInfo($hMonitor)

; Calculate the relative coordinates on the specific monitor
; absolute x/y - monitor x/y = relative x/y
Local $iRelativeX = DllStructGetData($tMousePos, 1) - DllStructGetData($tMonitorInfo[0], 1) 
Local $iRelativeY = DllStructGetData($tMousePos, 2) - DllStructGetData($tMonitorInfo[0], 2)

ConsoleWrite("Relative X: " & $iRelativeX & ", Relative Y: " & $iRelativeY & @CRLF)

tested on 3 of my monitors

Edited by sylremo
clarify
Posted (edited)

Here's my implementation that doesn't take into account the taskbar width and height, ofc you can do it yourself, depending on which position it is. _WinAPI_GetMonitorInfo documentation doesn't explain some magic numbers it's using, so take a look at https://learn.microsoft.com/en-us/windows/win32/api/windef/ns-windef-rect.

#NoTrayIcon
#RequireAdmin

#include <GUIConstantsEx.au3>
#include <WindowsConstants.au3>
#include <WinAPIMisc.au3>
#include <WinAPIGdi.au3>

HotKeySet('{esc}', quit)
HotKeySet('{f1}', toggleVisibility)

Local $bToggled = False
Local $tMousePos, $tMonitor, $tMonitorInfo
Local $iGuiX, $iGuiY
Local $iGuiW = 200, $iGuiH = 100
Local $iCurrMonUpperLeftX, $iCurrMonUpperLeftY, $iCurrMonLowerRightX, $iCurrMonLowerRightY

Local $hGui = GUICreate('', $iGuiW, $iGuiH, -1, -1, $WS_POPUP + $WS_CAPTION)

While 1
    Sleep(50)
WEnd

Func quit()
    Exit
EndFunc

Func toggleVisibility()
    $tMousePos = _WinAPI_GetMousePos()
    
    $tMonitor = _WinAPI_MonitorFromPoint($tMousePos)
    $tMonitorInfo = _WinAPI_GetMonitorInfo($tMonitor)
    $iCurrMonUpperLeftX = DllStructGetData($tMonitorInfo[0], 1)
    $iCurrMonUpperLeftY = DllStructGetData($tMonitorInfo[0], 2)
    $iCurrMonLowerRightX = DllStructGetData($tMonitorInfo[0], 3)
    $iCurrMonLowerRightY = DllStructGetData($tMonitorInfo[0], 4)

    ; we can actually omit the subtraction because we will add it back eventually
    $iMouseX = DllStructGetData($tMousePos, 1) - $iCurrMonUpperLeftX
    $iMouseY = DllStructGetData($tMousePos, 2) - $iCurrMonUpperLeftY


    If Not ($bToggled) Then
        If ($iMouseX + $iGuiW > $iCurrMonLowerRightX) Then
            $iGuiX = $iMouseX - $iGuiW - 10
        Else
            $iGuiX = $iMouseX + 10
        EndIf

        If ($iMouseY + $iGuiH > $iCurrMonLowerRightY) Then
            $iGuiY = $iMouseY - $iGuiH - 10
        Else
            $iGuiY = $iMouseY + 10
        EndIf

        WinMove($hGui, '', $iGuiX + $iCurrMonUpperLeftX, $iGuiY + $iCurrMonUpperLeftY)

        GUISetState(@SW_SHOW, $hGui)
    Else
        GUISetState(@SW_HIDE, $hGui)
    EndIf

    $bToggled = Not ($bToggled)
EndFunc
Edited by sylremo

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
  • Recently Browsing   0 members

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