plt-scheme : catching mouse click event on canvas - project

I am writing a tic-tac-toe game in plt-scheme as my AI course project.
The idea for gui is a grid with 9 boxes, each with a canvas, using panes ...
When the user click on a canvas, 'X' or 'O' will be drawn accordingly ...
The question is how can I catch mouse click event on canvas?
I found out I need to use on-event, but still don't know how?
Any clues?

Ok, I got it ...
(define canvas-box%
(class canvas%
(define/override (on-event e)
(when (equal? (send e get-event-type) 'left-down) (foobar-callback)))
(super-new)))

I got all mouse and keypad command for uses anywhere
here.
(define my-canvas%
(class canvas%
(define/override (on-event event)
(and
(send test reader (list (number->string (send event get-x))
(number->string (send event get-y)) ))
(send test reader (list (send event get-event-type)))))
(define/override (on-char event)
(define pressed (send event get-key-code))
(if (char? pressed) (send test reader (list (make-string 1 pressed))) '()))
(super-new)))
(define tester%
(class object%
(super-new)
(define command '())
(define/public (reader x)
(and (set! command x)
(display x))
)
(define/public (outer)
command)
))

Related

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?

How to get mouse position properly on keypress with autohotkey Invalid Hotkey Error

For those who find this later, for google reasons or anything, while the comments helped, I largely had to re-do the code from scratch. If you want the CSP equivalent of a private layer in Procreate, or if you want to use CSPs recording features without your reference layers showing up, download autohotkey and this script, then set the following settings.
CTRL and Numpad+ to zoom in
CTRL and Numpad- to zoom out
Middle Mouse button to pan.
Then do the following, put a reference of some sort on both pages, a large checkerboard, a dot with a few lines through it, whatever. Then line up both windows so that they're showing exactly same thing, only use middle mouse button to pan, and CTRL+ and CTRL- to zoom in and out.
This is my first autohotkey script, and I'm trying to link up two different windows of an art program, so that when I pan one canvas, it pans the other. I would like it to be as pixel precise as possible, but I'm getting an error on Line 1 that says it's an invalid hotkey, I've tried removing the variables, and moving the commas around, but I'm not sure what I'm doing wrong.
Here is my code. for purposes, I'll explain the button combinations.
Space + L Mouse Button together lets me pan the canvas, I need to know where the cursor is when I release one or the other.
LCtrl + Numpad5 disables click through on WindowTop which I use to overlay with transparency one window over the other.
LCtrl + Tab switches between the two canvasses in the app
#IfWinActive ahk_exe CLIPStudioPaint.exe
; coordmode
Coordmode, Mouse, Screen
t := 0
;Below line starts script, and declares The Starting Coordinates
WinTitle = 3DLayer
SetTitleMatchMode, 2
^F9::
WinSet,Transparent, Off
^F11::
WinSet, ExStyle, -0x20, % WinTitle
return
^F10::
WinSet, ExStyle, +0x20, % WinTitle
WinSet, Transparent, 128, % WinTitle
return
~MButton::
if (t = 0)
{
MouseGetPos, MouseStartX, MouseStartY
t := 1
}
return
~MButton up::
;When MButton is released, records mouse ending positions
MouseGetpos, MouseEndX, MouseEndY
;Blocks input in case I move mouse or touch keyboard while it's running
BlockInput, On
; switches canvas
Send ^{TAB}
; set window for click through
WinTitle = 3DLayer
SetTitleMatchMode, 2
; Disables Click Through
WinSet, ExStyle, -0x20, % WinTitle
; drag
MouseClickDrag, M, MouseStartX, MouseStartY, MouseEndX, MouseEndY
;Re-enables Click Through
WinSet, ExStyle, +0x20, % WinTitle
Winset, Transparent, 150, % WinTitle
;Turns inputs back on, so that I can resume using the art program
Send ^{TAB}
BlockInput, Off
t := 0
return
~^NumpadAdd::
BlockInput, On
; Get Mouse Position
MouseGetPos, ScrollX, ScrollY
;Block input, then switch canvases
Send ^{Tab}
sleep 50
; Disables Click Through
WinSet, ExStyle, -0x20, % WinTitle
; Move Mouse where it needs to be then scroll
MouseMove, ScrollX, ScrollY
Send ^{NumpadAdd}
;Re-enables Click Through
WinSet, ExStyle, +0x20, % WinTitle
Winset, Transparent, 150, % WinTitle
;Turns inputs back on, so that I can resume using the art program
Send ^{TAB}
BlockInput, Off
return
~^NumpadSub::
BlockInput, On
; Get Mouse Position
MouseGetPos, ScrollX, ScrollY
;Block input, then switch canvases
Send ^{Tab}
sleep 50
; Disables Click Through
WinSet, ExStyle, -0x20, % WinTitle
; Move Mouse where it needs to be then scroll
MouseMove, ScrollX, ScrollY
Send ^{NumpadSub}
;Re-enables Click Through
WinSet, ExStyle, +0x20, % WinTitle
Winset, Transparent, 150, % WinTitle
;Turns inputs back on, so that I can resume using the art program
Send ^{TAB}
BlockInput, Off
return
At this time, the biggest changes I made was replacing
Space UP || LMButton UP::MouseGetPos MouseEndX, MouseEndY
with
while (GetKeyState("LButton", "P") and GetKeyState("Space", "P"))
sleep 50
MouseGetPos MouseEndX, MouseEndY
(since you cannot have nested hotkeys)
I don't actually know if it works as intended since I do not have the software you are using, but feel free to lmk if something isn't working properly.
Update 1:
In order to preserve a key's native function, we can use the ~ modifier.
From the relevant part of the modifier section of the docs:
When the hotkey fires, its key's native function will not be blocked
(hidden from the system).
In order to implement this, we can add the ~ key as a prefix to the hotkey, turning
Space & LButton::
into
~Space & LButton::
Current Code v2:
#IfWinActive ahk_exe CLIPStudioPaint.exe
;Below line starts script, and declares 4 variables with the value 0 to reset the script, to make sure for no reason it uses the old values
~Space & LButton::
;Once variables are declared, it records those variables
MouseGetPos MouseStartX, MouseStartY
;When space or Mouse button release, it uses the 4 recorded variables to move and click on the canvas
while (GetKeyState("LButton", "P") and GetKeyState("Space", "P"))
sleep 50
MouseGetPos MouseEndX, MouseEndY
;Blocks input in case I move mouse or touch keyboard while it's running
BlockInput, On
;Disables Click Through in WindowTop (That's a literal name of the program) by pressing CTRL and Numpad5
Send ^{Numpad5}
;Switches Canvasses to the new canvas (Basically a 2nd tab in the program)
Send ^{TAB}
;Uses the recorded mouse positions to middle mouse button drag the exact same way I had in the previous section
MouseClickDrag, M, MouseStartX, MouseStartY, MouseEndX, MouseEndY
;Re-enables Click Through
Send ^{TAB}
;Switches back too original canvas
Send ^{Numpad5}
;Turns inputs back on, so that I can resume using the art program
BlockInput, Off
return
Space::Space

Autohotkey send shortcut

I want to add some keypresses after a shortcut in Visual Studio.
When pressing the shortcut Ctrl + 0, Ctrl + G it should be executed in Visual Studio and after that 9 Tabs should be pressed.
I came up with this:
^0::
IfWinActive Visual Studio
{
Input, OutputVar, T1 L1
if OutputVar == g
Send, ^0^g
Send, {Tab}
Send, {Tab}
Send, {Tab}
Send, {Tab}
Send, {Tab}
Send, {Tab}
Send, {Tab}
Send, {Tab}
Send, {Tab}
}
return
The check for the shortcut works so far, but sending ^0^g it does nothing
Try this, note the changes made and the links to the documentation for further details.
SetTitleMatchMode, 2
#IfWinActive Visual Studio ; a lot easier to use for context sensitive hotkeys
$^0:: ; for more info on $ see http://ahkscript.org/docs/Hotkeys.htm#Symbols
; Store the character for Ctrl-G in the CtrlG var. (7th letter)
; See doc http://ahkscript.org/docs/commands/Input.htm
Transform, CtrlG, Chr, 7
Input, OutputVar, T1 M L1 ; forgot the M option here
If OutputVar = %CtrlG%
{ ; don't forget the {} block after an if condition http://ahkscript.org/docs/commands/Block.htm
Send, ^0^g
Send, {Tab 9}
}
Return

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

Using auto hotkey to swap Ctrl & Alt and implement Ctrl Tab

While using AutoHotKey I wanted to setup a rule to swap the left alt and left ctrl. I can do this by doing:
LAlt::LCtrl
LCtrl::LAlt
I then wanted to keep the 'alt tab' functionality bound do those physical keys, thus I tried
LCtrl & Tab::AltTab
In addition to the two uptop, yet it won't work. If I put it like so:
LCtrl & Tab::AltTab
LAlt::LCtrl
LCtrl::LAlt
Then the tab will work, however the ctrl alt swap will be broke. Any suggestions?
The hotkey documentation talks about wildcards
Wildcard: Fire the hotkey even if extra modifiers are being held down. This is often used in conjunction with remapping keys or buttons. For example:
*#c::Run Calc.exe ; Win+C, Shift+Win+C, Ctrl+Win+C, etc. will all trigger this hotkey.
*ScrollLock::Run Notepad ; Pressing Scrolllock will trigger this hotkey even when modifer key(s) are down.
So try this
*tab::
{ if(GetKeyState("LAlt", "P"))
{ Send {LControl up}{Alt down}{tab}
KeyWait, tab
}else
{ send {tab}
}
return
}
~LAlt Up::
{ send {lalt up}
return
}
LAlt::LCtrl
LCtrl::LAlt
I improved this slightly to fix shift tab not working, now you can use Shift+tab as expected where as before you couldn't (was frustrating trying to fix indentation(outdent) when coding) I may improve this more and get Shift+Alt+Tab working
*tab::
{
if(GetKeyState("LAlt", "P")){
Send {LControl up}{Alt down}{tab}
KeyWait, tab
} else if(GetKeyState("LShift", "P")){
Send {LShift down}{tab}
KeyWait, tab
}else
{ send {tab}
}
return
}
~LAlt Up::
{ send {lalt up}
return
}
LAlt::LCtrl
LCtrl::LAlt
Just ran into the same problem myself, was looking for a more straightforward solution. If you swap Alt and Ctrl using SharpKeys (or other registry remapping tool) from there it's a simple:
RCtrl & Tab::AltTab