Code: Select all
ScrollLock::
if (flag := !flag) {
MouseGetPos, , , hwnd
Gui Cursor:+Owner%hwnd%
BlockInput MouseMove
DllCall("ShowCursor", Int,0)
} else {
BlockInput MouseMoveOff
DllCall("ShowCursor", Int,1)
}
Return
Code: Select all
ScrollLock::
if (flag := !flag) {
MouseGetPos, , , hwnd
Gui Cursor:+Owner%hwnd%
BlockInput MouseMove
DllCall("ShowCursor", Int,0)
} else {
BlockInput MouseMoveOff
DllCall("ShowCursor", Int,1)
}
Return
Hitaku wrote:[...] but I was hoping to have it work without having to press any keys [...]
As far as I can say you've to use SetTimer to do checks against the window itself (+ ControlGetFocus/CoordMode/...) to get this done.#IfWinActive / #IfWinExist
Creates context-sensitive hotkeys and hotstrings. Such hotkeys perform a different action (or none at all) depending on the type of window that is active or exists.
Code: Select all
#Persistent
SetTitleMatchMode, 2
SetTimer, Painter, 100
Return
Painter:
WinGetTitle, Title, A
If InStr(Title,"Paint")
WinGetPos, X, Y, Width, Height, A
<now you've to create a condition based on the current mouse position and its position within the target windows frame>
Return
Code: Select all
SetBatchLines, -1
Return ; end of auto-execute section
;-------------------------------------------------------------------------------
Watchdog(wParam, lParam := "") { ; monitor activating windows
;-------------------------------------------------------------------------------
static init := DllCall("RegisterShellHookWindow", Ptr, A_ScriptHwnd)
, MsgNum := DllCall("RegisterWindowMessage", Str, "SHELLHOOK")
, neglect := OnMessage(MsgNum, "Watchdog")
, CleanUp := {base: {__Delete: "Watchdog"}}
If Not IsObject(CleanUp) {
OnMessage(MsgNum, "")
DllCall("DeregisterShellHookWindow", Ptr, A_ScriptHwnd)
}
If (wParam = 1) ; HSHELL_WINDOWCREATED
Or (wParam = 4) ; HSHELL_WINDOWACTIVATED
Or (wParam = 32772) ; HSHELL_RUDEAPPACTIVATED
Guard(lParam) ; alert the guard about a new active window
}
;-------------------------------------------------------------------------------
Guard(hActive) { ; toggle mouse on/off if a certain window is active
;-------------------------------------------------------------------------------
WinGetTitle, Title, ahk_id %hActive%
If InStr(Title, "Notepad") { ; toggle mouse off
MouseGetPos,,, hwnd
Gui, Cursor: +Owner%hwnd%
BlockInput, MouseMove
DllCall("ShowCursor", Int,0)
}
Else { ; toggle mouse on
BlockInput, MouseMoveOff
DllCall("ShowCursor", Int,1)
}
}
wolf_II wrote:There is another way with SHELLHOOK that allows you to monitor (and respond to) the active window.
Forum user SvenBent explains the benefits of SHELLHOOK over SetTimer here: https://autohotkey.com/boards/viewtopic ... 26#p109226
It works like this: Put a Watchdog function in your script and have it alert the Guard whenever the active window changes.
Example with notepad: (Paint does not play nicely with hiding cursor)Code: Select all
SetBatchLines, -1 Return ; end of auto-execute section ;------------------------------------------------------------------------------- Watchdog(wParam, lParam := "") { ; monitor activating windows ;------------------------------------------------------------------------------- static init := DllCall("RegisterShellHookWindow", Ptr, A_ScriptHwnd) , MsgNum := DllCall("RegisterWindowMessage", Str, "SHELLHOOK") , neglect := OnMessage(MsgNum, "Watchdog") , CleanUp := {base: {__Delete: "Watchdog"}} If Not IsObject(CleanUp) { OnMessage(MsgNum, "") DllCall("DeregisterShellHookWindow", Ptr, A_ScriptHwnd) } If (wParam = 1) ; HSHELL_WINDOWCREATED Or (wParam = 4) ; HSHELL_WINDOWACTIVATED Or (wParam = 32772) ; HSHELL_RUDEAPPACTIVATED Guard(lParam) ; alert the guard about a new active window } ;------------------------------------------------------------------------------- Guard(hActive) { ; toggle mouse on/off if a certain window is active ;------------------------------------------------------------------------------- WinGetTitle, Title, ahk_id %hActive% If InStr(Title, "Notepad") { ; toggle mouse off MouseGetPos,,, hwnd Gui, Cursor: +Owner%hwnd% BlockInput, MouseMove DllCall("ShowCursor", Int,0) } Else { ; toggle mouse on BlockInput, MouseMoveOff DllCall("ShowCursor", Int,1) } }
I think there is a way, but I don't like it very much. I had to get rid of your very elegant Gui Cursor and DllCall, and use a separate function to show/hide the mouse cursor.Hitaku wrote:Is there a fix to that?
I take this one, thanks (I change BlankCursor to be static and make it only once though.)wolf_II wrote:Code: Select all
ShowMouse()
Code: Select all
;-------------------------------------------------------------------------------
show_Mouse(bShow := True) { ; show/hide the mouse cursor
;-------------------------------------------------------------------------------
; WINAPI: SystemParametersInfo, CreateCursor, CopyImage, SetSystemCursor
; https://msdn.microsoft.com/en-us/library/windows/desktop/ms724947.aspx
; https://msdn.microsoft.com/en-us/library/windows/desktop/ms648385.aspx
; https://msdn.microsoft.com/en-us/library/windows/desktop/ms648031.aspx
; https://msdn.microsoft.com/en-us/library/windows/desktop/ms648395.aspx
;---------------------------------------------------------------------------
static BlankCursor
static CursorList := "32512, 32513, 32514, 32515, 32516, 32640, 32641"
. ",32642, 32643, 32644, 32645, 32646, 32648, 32649, 32650, 32651"
local ANDmask, XORmask, CursorHandle
If bShow ; shortcut for showing the mouse cursor
Return, DllCall("SystemParametersInfo"
, "UInt", 0x57 ; UINT uiAction (SPI_SETCURSORS)
, "UInt", 0 ; UINT uiParam
, "Ptr", 0 ; PVOID pvParam
, "UInt", 0) ; UINT fWinIni
If Not BlankCursor { ; create BlankCursor only once
VarSetCapacity(ANDmask, 32 * 4, 0xFF)
VarSetCapacity(XORmask, 32 * 4, 0x00)
BlankCursor := DllCall("CreateCursor"
, "Ptr", 0 ; HINSTANCE hInst
, "Int", 0 ; int xHotSpot
, "Int", 0 ; int yHotSpot
, "Int", 32 ; int nWidth
, "Int", 32 ; int nHeight
, "Ptr", &ANDmask ; const VOID *pvANDPlane
, "Ptr", &XORmask) ; const VOID *pvXORPlane
}
; set all system cursors to blank, each needs a new copy
Loop, Parse, CursorList, `,, %A_Space%
{
CursorHandle := DllCall("CopyImage"
, "Ptr", BlankCursor ; HANDLE hImage
, "UInt", 2 ; UINT uType (IMAGE_CURSOR)
, "Int", 0 ; int cxDesired
, "Int", 0 ; int cyDesired
, "UInt", 0) ; UINT fuFlags
DllCall("SetSystemCursor"
, "Ptr", CursorHandle ; HCURSOR hcur
, "UInt", A_Loopfield) ; DWORD id
}
}
This is my preference, mostly due to syntax highligthing. I checked with DebugVars, omitting the quotes doesn't seem to create any Int variable. Also, having a global variable Int:="somethingIncorrectForDllCall" doesn't seem to affect the dllcall either."Int" over Int and so on, since omitting the quotes seems to create variables named Int and so on.
That is correct."HCURSOR" to "Ptr"
DebugVars does show them, and ListVars does. Please check the following stand-alone script. Int is listed under global vars.Helgef wrote:omitting the quotes doesn't seem to create any Int variable
Code: Select all
;-------------------------------------------------------------------------------
; this example hides the mouse cursor for 5 seconds, then shows it again
;-------------------------------------------------------------------------------
show_Mouse(False)
Sleep, 5000
show_Mouse(True)
ExitApp ; end of auto-execute section
;-------------------------------------------------------------------------------
show_Mouse(bShow := True) { ; show/hide the mouse cursor
;-------------------------------------------------------------------------------
; WINAPI: SystemParametersInfo, CreateCursor, CopyImage, SetSystemCursor
; https://msdn.microsoft.com/en-us/library/windows/desktop/ms724947.aspx
; https://msdn.microsoft.com/en-us/library/windows/desktop/ms648385.aspx
; https://msdn.microsoft.com/en-us/library/windows/desktop/ms648031.aspx
; https://msdn.microsoft.com/en-us/library/windows/desktop/ms648395.aspx
;---------------------------------------------------------------------------
static BlankCursor
static CursorList := "32512, 32513, 32514, 32515, 32516, 32640, 32641"
. ",32642, 32643, 32644, 32645, 32646, 32648, 32649, 32650, 32651"
local ANDmask, XORmask, CursorHandle
ListVars ; debug/demo
MsgBox ; debug/demo
If bShow ; shortcut for showing the mouse cursor
Return, DllCall("SystemParametersInfo"
, "UInt", 0x57 ; UINT uiAction (SPI_SETCURSORS)
, "UInt", 0 ; UINT uiParam
, "Ptr", 0 ; PVOID pvParam
, "UInt", 0 ; UINT fWinIni
, "Cdecl Int") ; return BOOL
If Not BlankCursor { ; create BlankCursor only once
VarSetCapacity(ANDmask, 32 * 4, 0xFF)
VarSetCapacity(XORmask, 32 * 4, 0x00)
BlankCursor := DllCall("CreateCursor"
, "Ptr", 0 ; HINSTANCE hInst
, Int , 0 ; int xHotSpot
, Int , 0 ; int yHotSpot
, Int , 32 ; int nWidth
, Int , 32 ; int nHeight
, "Ptr", &ANDmask ; const VOID *pvANDPlane
, "Ptr", &XORmask ; const VOID *pvXORPlane
, "Cdecl Ptr") ; return HCURSOR
}
; set all system cursors to blank, each needs a new copy
Loop, Parse, CursorList, `,, %A_Space%
{
CursorHandle := DllCall("CopyImage"
, "Ptr", BlankCursor ; HANDLE hImage
, "UInt", 2 ; UINT uType (IMAGE_CURSOR)
, Int , 0 ; int cxDesired
, Int , 0 ; int cyDesired
, "UInt", 0 ; UINT fuFlags
, "Cdecl Ptr") ; return HANDLE
DllCall("SetSystemCursor"
, "Ptr", CursorHandle ; HCURSOR hcur
, "UInt", A_Loopfield ; DWORD id
, "Cdecl Int") ; return BOOL
}
}
Users browsing this forum: peter_ahk and 169 guests