AutoHotKey not finding image on a window - automation

I recently discovered AutoHotKey, this scripting language seemed to be amazing !
Unfortunately, I can't manage to make my script find an image on a window (BlueStacks in my case).
Can someone please help me, my script is :
CoordMode, Pixel, screen
CoordMode, Mouse, screen
*ESC::ExitApp
ImgFound := false
while(ImgFound = false)
{
ImageSearch, ButtonX, ButtonY, 0, 0, A_ScreenWidth, A_ScreenHeight, *50 C:\Users\...\Documents\...\test.png
if (ErrorLevel = 2)
{
MsgBox Could not execute script.
ExitApp
}
else if (ErrorLevel = 1)
{
ImgFound := false
}
else
{
MsgBox Found.
click, %ButtonX%, %ButtonY%
ImgFound := true
}
}

Your while loop is unreachable code.
The code execution stops when the first hotkey label is encountered. This is called the Auto-execute Section.
Move your hotkey definition to be at the very bottom.
(All hotkeys always defined by hotkeys labels get always created regardless of being in the auto-execute section or not)

Related

Jetpack Compose - ModalBottomSheet comes up with soft keyboard

I have a problem with ModalBottomSheet and it's on my work computer so I can't record it to you right now. So basically, after I give focus to one of my TextFields, my keyboard comes up and pushes all the content upwards so I can see the TextField that I'm writing to. When I'm hiding my keyboard I can see that my ModalBottomSheet hides too, but I never set it to come up.
So if you are familiar with this bug, please let me know your solutions.
My coworker, so he inserted a boolean that checks if keyboard is up or not and if it is, dont put ap modal bottom sheet.
You can use this method until this problem is fixed with an additional update.
You can use LaunchedEffect for this. Here is an example for you.
The important thing here is to disable the ModalBottomSheetDialog when the keyboard is opened and re-enable it half a second after the keyboard is closed.
You can trigger the required function by assigning a value to this variable when the keyboard is turned on, and then changing and checking this value when the keyboard is closed.
/*Change this value to "keyboard_on" when the keyboard is turned on and "keyboard_off" when the keyboard is closed again. You can give different names for different usage areas. That's why we're using a string, not a Boolean.*/
var taskCodeValue = remember { mutableStateOf("keyboard_off") }
var sheetOpener by remember { mutableStateOf(true) }
if (taskCodeValue.value == "keyboard_off"){
LaunchedEffect(taskCodeValue.value == "keyboard_off"){
delay(500)
sheetOpener = true
}
}else {
sheetOpener = false
}
/*
By adding the Scaffold, which includes ModalBottomSheet and other compose
elements, into a box, we enable them to work independently of each other.
*/
Box(modifier = Modifier.fillMaxSize()) {
Scaffold(
content = {}
)
if (sheetOpener){
ModalBottomSheetLayout(
sheetState = sheetState,
sheetContent = {}
) {}
}
}

Java FX Dialog "appears" with no size

I'm using JFX 11 on Fedora 33 (GNU/Linux) with the Xorg GUI server (v 1.20.11), creating a dialog thus (kotlin):
fun YNdialog (txt : String) : Boolean {
val dlog = Dialog<ButtonType>()
dlog.dialogPane.apply {
contentText = txt
buttonTypes.apply {
add(ButtonType.OK)
add(ButtonType.CANCEL)
}
minWidth = 200.0
minHeight = 100.0
}
dlog.initOwner(theStage.scene.window)
val r = dlog.showAndWait()
return r.isPresent && r.get() == ButtonType.OK
}
This is called from an EventHandler<ActionEvent> associated with a Button:
if (YNdialog("hello world")) ...
There does seem to be a window created. If I remove the initOwner() call, an icon for it appears in the desktop taskbar (KDE), allowing me to do things like move it, but "maximize" and "resize" are greyed out, and the mouse cursor appears to be dragging nothing, ie., it has no width or height.
With the initOwner() it does much the same thing, except it gets no taskbar icon. Also, there is a visible vertical line one or two pixels thick where it should be (centered over the main window). What's more interesting is a second close button appears in the titlebar of the main window:
This is not part of the javafx interface, but I've never seen the window manager (?) do this before.
Occasionally (maybe one in five or ten times) the dialog does appear, and curiously,
the close button there is offset with space for a second one:
When this happens and I can dismiss the dialog window, the second close button on the main window disappears.
Using Alert
Replacing that function, etc. with:
Alert(Alert.AlertType.CONFIRMATION, "hello world").showAndWait()
.filter { res -> res == ButtonType.OK }
.ifPresent { _ -> log.msg("ok!") }
The result is identical to the YNdialog with initOwner().
Am I missing something here? I got all of this pretty much straight from the docs. I have done custom popup windows (instantiated via FXMLLoader) and have not had any problem with that. Does this experience imply the dialog hierarchy is glitchy in this context and I should roll my own?

AutoHotkey - Perform action based on clicked menu item

I looked around the AHK forums, google, and here on stack overflow and could not find any method for pulling this off, so thanks BIG TIME in advance if you can figure this one out. I am using notepad in my examples, but I'm writing this script for a complicated Point Of Sale program.
I want to do something almost exactly like this, but using the application menus as described below instead of a button.
I would like to have a script that performs an action if a certain menu item is clicked. It does not matter whether that is determined by menu position, label or otherwise. Cursor position, however, is probably not viable for my needs.
A simple example of this would be to open a MsgBox when File-Open is selected with the mouse in notepad.
I have implemented a few techniques that enabled me to pull variables out of most control objects following a left click (buttons, drop-down menus, etc), but when I use the application menu (for example, in notepad: file-save or file-open) It returns a blank string. For example:
#z::
MouseGetPos,,,,Ctrl,2
ControlGetText, Text,,ahk_id %Ctrl%
MouseClick, left
Sleep 2500
MsgBox, %Text%
(Note that I used windows-z so as to not return a MsgBox after every left-click.)
Will return 'cancel' if the cancel button was pressed in the 'file-save as' dialogue of notepad, but returns nothing if I activate it while selecting anything from the application menus (file, edit, format, etc.)
I know that these menus are accessible to AHK, as you can do the following do activate 'File-Save' from the notepad menu:
WinMenuSelectItem, Untitled - Notepad,File,Save
But when I use window spy, I see the objects behind the menu, rather than strings that are actually in the menu.
Are these menus actually separate windows that I need to switch to active to read? Or am I trying to do something impossible?
Big thanks in advance, this is something that's been driving me crazy!
Menus are not that easy to get info from, at least not with autohotkeys built-in commands, you will need to use DllCall's to get the info you need.
I have made you an example that works with notepad for me on win7 64b
What i did in the example is look for notepad run it if its not there then get the ID (hWnd) of the notepad window
When you press ctrl + LButton a DllCall to GetMenu using the ID of the notepad window is used to get a menu handle.
After that more DllCall's are used to get things like GetMenuItemCount, GetSubMenu and GetMenuItemInfo.
What this does is it lets us loop over the menu items one by one and getting info about them, in this example we're getting the state of the items, specifically the highlight state.
When an item is found that has the highlight state the script stores the indexs of the item and breaks the loops.
As this is only an example all it does is display a string message with the index numbers and sends a LButton press
Example:
ifWinNotExist, ahk_class Notepad
{
Run, notepad.exe
WinWait, ahk_class Notepad
}
WinGet, hWnd, ID,
^Lbutton::
hMenu :=DllCall("GetMenu", "Uint", hWnd)
loop % (count := DllCall("GetMenuItemCount", "ptr", hMenu))
{
menu_index := A_index
; Note that menu item positions are zero-based.
hSubMenu := DllCall("GetSubMenu", "Uint", hMenu, "int", (A_index-1))
; Set the capacity of mii to sizeof(MENUITEMINFO)
VarSetCapacity(mii, A_PtrSize=8 ? (Size:=80) : (Size:=48), 0)
; Set the cbSize field to sizeof(MENUITEMINFO)
NumPut(Size, mii, 0)
; Set the mask to whatever you want to retrieve.
; In this case I set it to MIIM_STATE=1.
NumPut(1, mii, 4)
loop % (subCount := DllCall("GetMenuItemCount", "ptr", hSubMenu))
{
Sub_index := A_index
; Note that menu item positions are zero-based.
DllCall("GetMenuItemInfo", "UInt", hSubMenu, "UInt", (A_index-1), "UInt", 1, "UInt", &mii)
; Get the state field out of the struct.
fState := NumGet(mii, 12)
if (fState & 0x80) ; 0x80 MFS_HILITE | 0x8 MFS_CHECKED
{
MenuString := "Found in top #" menu_index " Sub pos #" Sub_index
break 2
}
}
}
if (MenuString)
{
Tooltip % MenuString
}
else
{
tooltip no menu item highlighted
}
send {Lbutton}
return
I hope that helps you get an idea of what is needed to do what your trying to do, other possible DllCalls to Look at are MenuItemFromPoint, GetMenuString.
This can take time to get right, but with the Dllcalls i have shown in this example, I hope that you can find other examples of how to use them with autohotkey on the forums.
This AutoHotkey script should do what you require.
It has been tested on Notepad (Windows 7), and should be readily adaptable to other programs that use the standard context menus still used in the vast majority of software. Although many programs use custom menu bars, the context menus are often still standard context menus.
I have provided two scripts, one will show a ToolTip and block triggering a menu item, whenever any menu item is pressed, which is useful for understanding and for diagnostic purposes.
The second script will show a ToolTip and block triggering any menu item if its text string starts with 'Open'.
Note: the text of the Notepad menu item is
Open... Ctrl+O (Open...[tab]Ctrl+O) and not simply 'Open'.
-
;==================================================
;tested on Notepad (Windows 7)
;block any clicks on any menu items when notepad is the active window
;note: to bypass this and click an item anyway, use ctrl+click
;note: requires Acc.ahk library in AutoHotkey\Lib folder
;https://github.com/Drugoy/Autohotkey-scripts-.ahk/blob/master/Libraries/Acc.ahk
;on right of screen right-click Raw, Save target as...
#IfWinActive, ahk_class Notepad
;LButton::
CoordMode, Mouse, Screen
MouseGetPos, , , hWnd
WinGetClass, vWinClass, ahk_id %hWnd%
if vWinClass in #32768
{
vCount++ ;your code here
ToolTip blocked %vCount%, 500, 200 ;your code here
Return
}
SendInput {LButton Down}
KeyWait, LButton
MouseGetPos, vPosX, vPosY, hWnd
WinGetClass, vWinClass, ahk_id %hWnd%
if vWinClass in #32768
{
ControlSend, Dummy, {Click, 0, 0}, ahk_class Notepad
vCount++ ;your code here
ToolTip blocked %vCount%, 500, 200 ;your code here
Return
}
SendInput {LButton Up}
Return
#IfWinActive
;==================================================
;tested on Notepad (Windows 7)
;block any clicks on the 'open' menu item when notepad is the active window
;note: to bypass this and click an item anyway, use ctrl+click
;note: requires Acc.ahk library in AutoHotkey\Lib folder
;https://github.com/Drugoy/Autohotkey-scripts-.ahk/blob/master/Libraries/Acc.ahk
;on right of screen right-click Raw, Save target as...
#IfWinActive, ahk_class Notepad
LButton::
CoordMode, Mouse, Screen
MouseGetPos, , , hWnd
WinGetClass, vWinClass, ahk_id %hWnd%
if vWinClass in #32768
{
vItemText := ""
oAcc := Acc_Get("Object", "1", 0, "ahk_id " hWnd)
Loop, % oAcc.accChildCount
if (oAcc.accState(A_Index) & 0x80) ;MF_HILITE := 0x80
if (1, vItemText := oAcc.accName(A_Index))
break
if (SubStr(vItemText, 1, 4) = "Open")
{
vCount++ ;your code here
ToolTip blocked %vCount%, 500, 200 ;your code here
Return
}
}
SendInput {LButton Down}
KeyWait, LButton
MouseGetPos, vPosX, vPosY, hWnd
WinGetClass, vWinClass, ahk_id %hWnd%
if vWinClass in #32768
{
ControlSend, Dummy, {Click, 0, 0}, ahk_class Notepad
vItemText := ""
oAcc := Acc_Get("Object", "1", 0, "ahk_id " hWnd)
Loop, % oAcc.accChildCount
if (oAcc.accState(A_Index) & 0x80) ;MF_HILITE := 0x80
if (1, vItemText := oAcc.accName(A_Index))
break
if (SubStr(vItemText, 1, 4) = "Open")
{
vCount++ ;your code here
ToolTip blocked %vCount%, 500, 200 ;your code here
Return
}
}
SendInput {LButton Up}
Return
#IfWinActive
;==================================================
Note:
The code samples posted in the two links below, achieve related goals.
Is it possible to catch the close button and minimize the window instead? AutoHotKey
AutoHotKey: Run code on Window Event (Close)
Note:
The function JEE_MenuIsActive, link below, can be used to check whether
the menu bar/sysmenu bar is active
in order to distinguish title bar menus from right-click context menus.
GUI COMMANDS: COMPLETE RETHINK - AutoHotkey Community
https://autohotkey.com/boards/viewtopic.php?f=5&t=25893

resetting flexslider on element click

I am currently building a site which utilises multiple flexsliders. The concept is that when the user clicks a specific button, it shows a flexslider with featured content relevant to the button pressed, which is all pretty simple stuff.
The problem i am having is at the moment, the flexsliders are firing on the click of a button, however whenever a user clicks on a different button, the slider is not reset.
I want to try and make the slider reset to slide 0 on each button click. I have tried using .stop() and some of the callback features within the plugin, but i have had no luck as of yet. Was wondering if anybody else had ever faced this before? (and won..)
the code in the footer.php is pretty standard issue at the moment:
$('.button').click(function() {
$('.flexslider').flexslider({
controlNav: true,
directionNav: false,
slideToStart: 0,
pauseOnHover: true,
});
});
I know it's been long since this question was posted, but it might help somebody.
I actually faced the same problem. After some poking around I managed to get it working using the following code:
// Catch the flexslider context
var slider = $(".flexslider").data("flexslider");
// Unset the animating flag so we can move back to the first slide quickly
slider.animating = false;
// Move to the first slide and stop the slideshow there
slider.flexAnimate(0, true, true);
If you want to return at the first slide, but don't want the animation to stop, just replace the last line with slider.flexAnimate(0);
I believe that the slider.stop() method doesn't unset the animating flag. In my opinion it should, because this flag is used in the flexAnimate() function to check whether to actually slide or not. If the flag is set to false, then the flexAnimate() function will suddenly return.
think the answer might lie in the start callback function. Try something like this (untested)
$('.button').click(function() {
$('.flexslider').flexslider({
controlNav: true,
directionNav: false,
slideToStart: 0,
pauseOnHover: true,
start: function(slider) {
if (slider.currentSlide != 0) {
slider.flexAnimate(0)//move the slider to the first slide (Unless the slider is also already on the first slide);
}
}
});
});
use the new api at line 1056 in flexslider like
' startAt: 0,
//Integer: The slide that the slider should start on. Array notation (0 = first slide)'

Placing a window near the system tray

I am writing a program that needs to set a window just above/below the traybar for gtk. I have tried using the 2 approaches that failed. One was using the gtk_status_icon_position_menu function and placing the window in the point where the user clicks (in the tray bar). The problem is that these solutions work in gnome(Linux) but not in Windows. In Linux they work because the window manager doesn't seem to allow placement of windows in the tray panel, honoring the closest possible. In Windows this doesn't happen and the window can go "out" of the screen which understandably is not desired.
With this said i went out for a work around. My idea was to set the window in the location of mouse click and get the x and y coordinates of a normal window placement and with it's size check if it would be within the screen boundaries. If it was not make the correction. I have came up with the functions needed but for some reason the gdk_drawable_get_size(window->window ,&WindowWidth, &WindowHeight) and other similar functions only give the correct size value after the second run of the signal function. The result of the first run is just 1 to both size and width. (I have read the issue of X11 not giving correct results, but i think this is not it)
event_button = (GdkEventButton *) event;
if (event_button->button == 1)
{
if (active == 0)
{
gboolean dummy;
gint WindowHeight, WindowWidth, WindowPosition[2];
GdkScreen *screen;
gint ScreenHeight, ScreenWidth;
dummy = FALSE;
gtk_widget_show_all(window);
gtk_window_present(GTK_WINDOW(window));
gtk_status_icon_position_menu(menu, &pos[X], &pos[Y], &dummy, statusicon);
gtk_window_move(GTK_WINDOW(window), pos[X],pos[Y]);
gdk_drawable_get_size(window->window ,&WindowWidth, &WindowHeight);
screen = gtk_status_icon_get_screen(statusicon);
ScreenWidth = gdk_screen_get_width(screen);
ScreenHeight = gdk_screen_get_height(screen);
g_print("Screen: %d, %d\nGeometry: %d, %d\n",ScreenWidth, ScreenHeight, WindowWidth, window->allocation.height);
gtk_entry_set_text(GTK_ENTRY(entry),"");
active = 1;
return TRUE;
}
How can i do what i want in a portable way?
I think gtk_status_icon_position_menu should work fine, as i used it for the same purpose.
Are you trying this stuff with X11, What is the actual result you are getting.