Assigning a Hotkey in Autoit - autoit

I want to use space bar to "click" a specific button in a window with autoit (without focusing the program?), like a "start" button in a game.
I tried to use ControlClick function but It's doing nothing by the way. I think i'm doing something wrong.
HotKeySet( "{space}", "MyFunction")
Func MyFunction()
ControlClick ( "title", "text", controlID [, button = "left" [, clicks = 1 [, x [, y]]]] )
EndFunc
Is it something like that?

Your way doing it is good. You are missing the title and the controlID of the ControlClick function. The 1st and 3rd parameter should be set to the title of the window and the control ID of the control.
To get those use the AutoIt tool that comes with autoit installation.
Set those properly and the code should work.

U can use it like this.
First start AutoIt info program to get desired coordinates ( place where u want to click ), use finder tool to get coorinates of mouse and edit it in a script.
So when u run ur script it will do nothing untill u press Spacebar, then it will run function MyFunction 1 time.
So it move mouse on given position, make pause of half second then left click on desired position $x and $y 1 time and srcipt stop untill u press space again then he make same procedure.
I added exit function so u can turn it off by just press ESC key.
HotKeySet( "{SPACE}", "MyFunction")
HotKeySet( "{ESC}", "CloseScript")
Global $x = 519 ; x is first value of mouse position
Global $y = 900 ; y is second value of mouse position
While 1
sleep(10)
Wend
Func MyFunction()
MouseMove($x, $y, 2) ; moves the mouse pointer do mouse position with speed 2
Sleep(500) ; wait 500 ms half of second ( delay )
MouseClick("left", $x, $y, 1, 2) ; now click left mouse key on mouse position, 1 click with speed 2
EndFunc
Func CloseScript()
Exit
EndFunc

Related

how do I make a button only print once if it is pressed (I'm using micropython with raspberry pi pico)

I have a mechanical switch to a pin and this is what the code looks like: BUTTON_ONE = Pin(0, Pin.IN, Pin.PULL_DOWN) i have it so when the value of the button is "1" then it prints the button name. I want it to only print once but when u press a button and hold it down it keeps printing (i know that is how buttons work but I want to know how to stop that)
AKA: a button that is toggleable
def button_input():
global is_pressed
global current_chain
current_chain=[]
while not is_pressed:
for x in BUTTONS:
if x["pin"].value()==1:
is_pressed = True
while is_pressed:
if x["pin"].value()==0:
is_pressed =False
lcd.putstr(x["pin_number"])
current_chain.append(x["pin_number"])
check_psw()
else: continue
else: continue

Scilab: How to use cbmenu in xclick()

I do not understand the explanation of the output argument cbmenu in the Scilab documentation of xclick.
It says:
cbmenu: String: callback associated to a menu if xclick returns due to a click on a menu.
I did not find any example in the web so I ask here. I have coded a snippet which lumps together the elements which may be relevant for cbmenu. The snippet does nothing, when I click on CLICK. Could anyone alter/complement/revise the code so that it does something - whatever it is to give me a clue what could be done with cbmenu?
xdel()
x=[-1 +1];
cf=figure(0);
plot(x,x)
m=uimenu(cf,'label','CLICK','callback','two=1+1');
[ibutton,xcoord,yxcoord,iwin,cbmenu]=xclick();
Kind regards
Rosestock
This is a minimal script which explains what the 5th output argument of xclick() can do:
xdel()
x=[-1 +1];
winnum=1; win=string(winnum);
cf=figure(winnum);
plot(x,x)
C=["Green" "Red" "Abort"];//case name strings
addmenu(winnum, C(1)); C1="execstr("+C(1)+"_"+win+"(1))";
addmenu(winnum, C(2)); C2="execstr("+C(2)+"_"+win+"(1))";
addmenu(winnum, C(3)); C3="execstr("+C(3)+"_"+win+"(1))";
while %t
[!,!,!,!,cbmenu]=xclick();
//Get the clicked option by cbmenu
if cbmenu==C1, cf.background=3; end
if cbmenu==C2, cf.background=5; end
if cbmenu==C3, break, end
end
If I get your intentions right, you want to create a custom menu. Here is a small demo, how to bulid custom menu elements, and also how to use locate to get back coordinates (but you don't need xclick to sense menu clicking). This code does not use explicitly cbmenu, but it is not necessary to get it work. If you run the code, first click the "Select range" menu, then click two times on the graph. Then the "Regression" menu is activated, and you can choose "Linear regession". By clicking "Exit program", the execution aborts. Not all nenu functions are implemented, they are there only to demonstrate a multilayer structure. I hope it helps!
//Interactive menu demo
// Scilab 5.5.2
// 2016.12.20. Attila Eredics
//
//Attention!
//Do not close the graphic window with the original x symbol
// while the program is running,
// because the program will run infinitely!
// But you can stop it in the Consol with: Ctrl+C and then typing: abort
clc;
clear;
lines(0);
//artificial data vectors
row = 100;
t=gsort(rand(row,1),'r','i'); //time
c=10*t+8; //concentration
c=c+rand(c); //add some noise
//graphic window
scf(0); clf(0);
w=gcf(); //get current figure
//new menu elements
m3=uimenu(w,"Label","Select range","Callback","m=3");
m4=uimenu(w,"Label","Regression","Enable","off","ForegroundColor","0.5|0.5|0.5");
m41=uimenu(m4,"Label","Linear","Callback","m=41","Enable","on");
m42=uimenu(m4,"Label","Nonlinear","Callback","m=42","Enable","on");
m5=uimenu(w,"Label","Save results","Callback","m=5");
m6=uimenu(w,"Label","Exit program","Callback","abort","ForegroundColor","1|0|0");
plot2d(t,c,style=-5,frameflag=6); //plot the data
xtitle("","time","concentration"); //axis labels
while %T //infinite loop
//-------------wait for user action (click on a menu)-------
m=0;
while m<1
xpause(1e4); //pause 10ms
end
//------------------the menu actions-------------------------
if m==3 then //Select range
mprintf("\nChoose 2 points (click on the graph)!");
coord=locate(2); //locate two clicks
disp(coord); //coord: according to the axes
//Select range in t vector
for i=1:row-1
if coord(1,1)>=t(i) & coord(1,1)<t(i+1) then //t(i) <= 1st click < t(i+1)
i1=i;
end
if coord(1,2)>=t(i) & coord(1,2)<t(i+1) then //t(i) <= 2nd click < t(i+1)
i2=i;
end
end
//selected range
clear tt;
clear cc;
tt=t(i1:i2);
cc=c(i1:i2);
plot2d(tt,cc,style=-5); //plot selected points
h2=gce();
h2.children.mark_foreground=3; //green
m4.Enable="on"; //enable Regression menu
m4.ForegroundColor="0|0|0"
m3.Enable="off"; //Disable selection menu
m3.ForegroundColor="0.5|0.5|0.5"
elseif m==41 then //linear regression of the selected points
mprintf("\nLinear regression");
[a,b,sig]=reglin(tt',cc');
plot2d([tt(1),tt($)],a*[tt(1),tt($)]+b,style=2); //blue line
m41.Enable="off"; //disable Linear regression menu
m41.ForegroundColor="0.5|0.5|0.5"
elseif m==42 then //Nonlinear regression
mprintf("\nNot implemented yet!");
elseif m==5 then //Save
mprintf("\nNot implemented yet!");
end
end

Change mouse cursor across environment with AutoIt

I'm hoping this is feasible... I made a program using AutoIt that resides in the system tray. One of the tray items runs a function that waits for the user to click on a window to get the window title (it can be any window, not necessarily one made from AutoIt. This part works flawlessly.
I would like for the function to change the mouse cursor to the cross while waiting for the user's click. I have tried using GUISetCursor(3), but from my understanding this only changes the cursor for an AutoIt GUI window.
How could I go about changing the mouse cursor for the user's environment, not just for an AutoIt window?
You can do it so:
#include <Misc.au3>
#include <WindowsConstants.au3>
GetTitleByClick()
Func GetTitleByClick()
Local $hCursor = GUICreate('', 48, 48, -1, -1, $WS_POPUP, $WS_EX_TOPMOST)
WinSetTrans($hCursor, '', 10)
GUISetCursor(3, 1, $hCursor)
GUISetState(#SW_SHOW, $hCursor)
; get title bar position
Local $pos
Do
$pos = MouseGetPos()
WinMove($hCursor, '', $pos[0]-24, $pos[1]-24)
Sleep(10)
Until _IsPressed('01')
GUIDelete($hCursor)
; block mouse
_MouseTrap($pos[0], $pos[1], $pos[0]+1, $pos[0]+1)
; click position - activates the window
MouseClick('left', $pos[0], $pos[1])
; unblock mouse
_MouseTrap()
; get the title of the active window
Local $sTitle = WinGetTitle('[ACTIVE]')
Return MsgBox(0, 'TITLE', $sTitle)
EndFunc
Thatnks to Richard's comment, and a reply in the AutoIt forums that linked me to AutoIt's _WinAPI_SetSystemCursor function, I was able to get this working.
I copied the cross cursor I wanted from %SystemRoot%\Cursors (specifically, I copied cross_i.cur) to put in my script's source directory.
Then, in the function that executes the brute of the program, I added the following lines:
Func FuncName()
;backs up the user's arrow cursor
Local $hPrev = _WinAPI_CopyCursor(_WinAPI_LoadCursor(0, 32512))
;backs up the user's ibeam cursor
Local $iPrev = _WinAPI_CopyCursor(_WinAPI_LoadCursor(0, 32513))
;changes the user's arrow cursor
_WinAPI_SetSystemCursor(_WinAPI_LoadCursorFromFile(#ScriptDir & "\cross.cur"),32512)
;changes the user's ibeam cursor
_WinAPI_SetSystemCursor(_WinAPI_LoadCursorFromFile(#ScriptDir & "\cross.cur"),32513)
; Do the code you want to execute
;restores the user's default cursor
_WinAPI_SetSystemCursor($hPrev,32512)
;restores the user's ibeam cursor
_WinAPI_SetSystemCursor($iPrev,32513)
EndFunc
This allowed me to accomplish what I needed.

How to expand a tree view using AutoIt

The UI is as following:
The tool "AutoIt Window Info" can only locate the elements in red (red rectangle area), the sub items can not be located.
So how can I expand or operate these items?
Usually Windows controls can be accessed using keystrokes as well.
In the screen-dump the Farmtt element is selected. That would be your starting point.
You may try:
Send("{DOWN}") Move down an element.
Send("{TAB}") Navigate to next control (button, checkbox, etc)
Send("{NumPadMult}") Recursively expands folders in a SysTreeView32.
Send("{ENTER}") ENTER key on the main keyboard
etc.
Reference:
https://www.autoitscript.com/autoit3/docs/appendix/SendKeys.htm
There are two things over here:
1) Use the following code snippet:
;Gets the handle for the text
Func readFirstlevelTreeNodes($hWndCtrl)
Local $firstItemHandle = _GUICtrlTreeView_GetFirstItem ($hWndCtrl)
Local $iCount = _GUICtrlTreeView_GetSiblingCount( $hWndCtrl, $firstItemHandle )
Dim $aRet[$iCount]
$aRet[0] = $firstItemHandle
For $index = 1 To $iCount - 1
$aRet[$index] = _GUICtrlTreeView_GetNextSibling ( $hWndCtrl, $firstItemHandle )
$firstItemHandle = $aRet[$index]
Next
getTreeNodeTextList($hWndCtrl,$aRet)
EndFunc
; Gets the text for given sibling node handle lists
Func getTreeNodeTextList($hWndCtrl,$aRet)
ConsoleWrite("Tree Node first level list"&#CRLF)
For $index = 0 To Ubound($aRet) -1
ConsoleWrite(_GUICtrlTreeView_GetText ( $hWndCtrl, $aRet[$index] )&#CRLF)
Next
EndFunc
You may see the output for the first level tree nodes.
2) If you still dont see the output then please verify the control handle values and window handles. If they are correct and it still doesnt show the first level tree nodes then try running your sciTE editor as administrator.
I think this should help.

Sticky key activation (shift 5 times) doesn't work by hotkey ::Send {LShift 5}

I would like to activate sticky keys by pressing 1 button, instead of pressing shift 5 times, which is the default way.
If I were to do
F9::Send {LShift 5}
pressing F9 will yield nothing.
I also tried
F9::
Send {LShift}
sleep 50
Send {LShift}
sleep 50
Send {LShift}
sleep 50
Send {LShift}
sleep 50
Send {LShift}
sleep 50
return
Are there any reasons as to why it's not working?
While there is most likely a way to do a dll call or something complicated, it is also possibly to program similar functionality using AutoHotkey. This would also avoid the sticky keys prompt, and you can do a traytip instead.
stickykeys = 0
F9::
stickykeys:=!stickykeys
Traytip, Sticky Keys, % (stickykeys) ? "On" : "Off"
return
#If stickykeys
*$Shift::
key = 0
Input, key, L1 M
SendInput {Shift Down}{%key%}{Shift Up}
return
*$Ctrl::
key = 0
Input, key, L1 M
SendInput {Ctrl Down}{%key%}{Ctrl Up}
Return
*$Alt::
key = 0
Input, key, L1 M
SendInput {Alt Down}{%key%}{Alt Up}
Return
#If
F9 simply toggles sticky keys on and off.
Note: This is using AHK_L which supports #If
SPI_GETSTICKYKEYS:=0x003A
SPI_SETSTICKYKEYS:=0x003B
SKF_STICKYKEYSON:=0x1
VarSetCapacity(STICKYKEYS,8) ; DWORD cbSize;DWORD dwFlags;
NumPut(8,&STICKYKEYS,"UInt")
F9::
DllCall("SystemParametersInfo","UInt",SPI_GETSTICKYKEYS,"UInt",8,"PTR",&STICKYKEYS,"UInt",0)
dwFlags:=NumGet(&STICKYKEYS,4,"Uint")
If (dwFlags & SKF_STICKYKEYSON)
dwFlags-=SKF_STICKYKEYSON
else dwFlags|=SKF_STICKYKEYSON
ToolTip % "STICKYKEYS are " (dwFlags & SKF_STICKYKEYSON ? "ON" : "OFF")
SetTimer,ToolTipOff,-1000
NumPut(dwFlags,&STICKYKEYS,4,"UInt")
DllCall("SystemParametersInfo","UInt",SPI_SETSTICKYKEYS,"UInt",8,"PTR",&STICKYKEYS,"UInt",0)
Return
ToolTipOff:
The code is from the Autohotkey forums at http://www.autohotkey.com/community/viewtopic.php?f=1&t=93650
A note for anyone wanting to use the code: I think you have to put it at the top of your script for it to work. In my script of hotkeys, placing it in the middle, and pressing F9 to activate sticky keys caused some weird things to happen: The cursor jumped around, some folders were launched, the script exited, etc. I'm guessing that it activated other hotkeys nearby?

Resources