Using keyboard and external numpad in AutoHotInterception - autohotkey

What I need is to map my keys from external numpad to keys on my keyboard. I've decided to use the AutoHotInterception program from evilC. The overall goal is to be able to use windows mouse keys with my keyboard. I have come to the point where program registers both inputs from my numpad and keyboard and I can type numbers with my keyboard but it doesn't really affect the windows mouse keys.
This is what I have so far:
#SingleInstance force
#Persistent
#include Lib\AutoHotInterception.ahk
AHI := new AutoHotInterception()
keyboardId := AHI.GetKeyboardId(0x04D9, 0x8008)
numPadId := AHI.GetKeyboardId(0x0C45, 0x7663)
AHI.SubscribeKeyboard(numPadId, true, Func("KeyEvent"))
AHI.SubscribeKeyboard(keyboardId, true, Func("KeyEvent"))
return
KeyEvent(code, state){
ToolTip % "Keyboard Key - Code: " code ", State: " state
if (state) & (code=30)
{
Send, {NumpadUp}
}
}
^Esc::
ExitApp

The main problem is that you need to send input at hardware driver level to trigger WMK.
Then I'd like to say that your questions seems quite weird. It seems to contradict itself?
You want to remap keys from the external keyboard, but then you also say that you just want to use the numpad with your main keyboard? So what is the external keyboard for actually?
In any case, Here's some advise and a revised script you can probably adapt for your own use. So firstly there's really no need to subscribe to the whole keyboard. Just subscribe to the keys you want.
And since I'm quite unclear on what it is you're actually trying to do, I'll just show an example of how you'd remap A, S and D to Numpad1, Numpad2 and Numpad3 at hardware driver level.
#include Lib\AutoHotInterception.ahk
AHI := new AutoHotInterception()
;kind of optional
;if you don't switch up stuff, you'll always have the same id
keyboardId := AHI.GetKeyboardId(..., ...)
;binding arguments to the function object to make use of the same function over and over
;so don't need to define a new function for each key
AHI.SubscribeKey(keyboardId, GetKeySC("a"), true, Func("KeyEvent").Bind(GetKeySC("numpad1")))
AHI.SubscribeKey(keyboardId, GetKeySC("s"), true, Func("KeyEvent").Bind(GetKeySC("numpad2")))
AHI.SubscribeKey(keyboardId, GetKeySC("d"), true, Func("KeyEvent").Bind(GetKeySC("numpad3")))
return
;the key argument will be the argument we bound to the function object above
;the AHI library takes care of passing in the state argument
KeyEvent(key, state)
{
global keyboardId
AHI.SendKeyEvent(keyboardId, key, state)
}
^Esc::ExitApp
Sending input is documented here here.
(Side question, any chance you're doing this for OSRS?)

Related

How to make transparent Form get mouse enter events?

I want to create a Delphi application that does something interesting when the user moves his mouse over the top-left corner of the screen. I thought about it and plan to do it with the following strategy:
Create a very small 3x3 Form and make it transparent and always on top. Also make it with no title bar or border.
Define mouse enter event for the Form.
I use the following code for step 1:
procedure TopLeftForm.FormCreate(Sender: TObject);
begin
FormStyle := fsStayOnTop;
self.TransparentColor := true;
self.TransparentColorValue := self.Color;
self.BorderStyle := bsNone;
end;
The problem is that I found that when the Form is transparent, it can't capture mouse enter events. I could make the Form not transparent in order to get mouse enter events, but that way users can see the Form at the top-left screen corner, which is not what I want.
What's your suggestions to my problem?
What you want is a 'Hook' that can give you information about mouse events without the events being intended for your program. It's too big a topic to be able to give you a how-to in one go, but these two links should be helpful:
Understanding how to use Windows Hooks
Mouse Hook Tutorial with Delphi codes
Why use a Windows Hook?
The Windows environment is designed around messages being passed around. Typically, a program is only interested in messages that are sent directly to its own windows. Trying to make sure that your application has a window that will get the messages blocks other applications from receiving those messages when they are in the same location under yours, and if another window is over yours then you won't get the messages. If you want to know about activity that's happening that wouldn't normally be sent to you - for example, a mouse click outside of your application's window. To enable applications to have visibility of events that are not destined for itself, a windows hook can be used.
There are different types of hooks, depending on what you want to access. A mouse hook is appropriate for what you have specified here. The system maintains a 'Hook Chain' for all of the hooks that have been installed - it will be your responsibility to pass the messages on down the chain, and to uninstall yourself from the chain.
To access the messages, your hook function will look something like this (code taken from the 2nd link above and adapted):
function MouseHookHandler(ACode: Integer; WParam: WParam; LParam: LParam): LResult; stdcall;
var
vMouseInfo: PMouseHookStruct;
begin
if ACode < 0 then
Result := CallNextHookEx(Data^.MouseHook, ACode, WParam, LParam)
else
begin
vMouseInfo := PMouseHookStruct(Pointer(LParam));
PostMessage(Data^.AppHandle, WM_CUSTOM_MOUSE, vMouseInfo^.pt.X, vMouseInfo^.pt.Y);
// we dont want to block the mouse messages
Result := CallNextHookEx(nil, ACode, WParam, LParam);
end;
end;
In your hook function:
ACode is dependent on the type of hook and indicates the event
wParam and lParam have a meaning specific to the event
To pass the message on, you should call CallNextHookEx - however for some hooks, the message will always be passed on regardless.
Hooks can be installed as Global hooks - meaning they intercept messages on all threads running in the same Desktop / WinStation as the calling thread. So, if you have multiple users connected via RD, for example, the hook is specific to one of those desktops only.

Simple way to *wait* for a key press, and get its martrix or PETSCII code?

I have found a few BASIC and KERNAL functions and memory addresses related to getting a key press/line, but how can I simply wait for a key press, and get its code? I want to pause execution, and resume once a key is pressed. I do not want them to be queued up during execution.
The principle is to use a non-blocking call, and keep calling it until you get a key.
In assembler you can use the KERNAL function GETIN at $FFE4
WAIT_KEY
jsr $FFE4 ; Calling KERNAL GETIN
beq WAIT_KEY ; If Z, no key was pressed, so try again.
; The key is in A
In BASIC you can use GET
10 GET A$:IF A$="" GOTO 10:REM WAIT FOR KEY
20 PRINT A$
Above I used spaces to make it more readable, but spaces are not necessary (they use memory and take time to process. It could be written as:
10 GETA$:IFA$=""GOTO10
20 PRINTA$

How to detect whether a "text/writeable" field is focused

How do I detect whether a text/writable field is focussed?
By text/writable field, I mean e.g. notepad; this SO-text field; the address-bar of Chrome, etc. Basically anything that you are supposed to write into.
Sounds like you want ControlGetFocus, it lets you get which control of a target window that has input focus. What kind of window will really make a difference, IE is pretty doable, Notepad++ also doable, Chrome would require special code for example: https://autohotkey.com/board/topic/103178-how-to-get-the-current-url-in-google-chrome/#entry637687.
Example of getting the control of the active window that works pretty well:
!z::
activeWindow := WinExist("A")
ControlGetFocus, focusedControl, ahk_id %activeWindow%
if(ErrorLevel) {
MsgBox, Couldn't get focusedControl
} else {
ControlGetText, focusText, %focusedControl%
if(ErrorLevel) {
ControlGetText, focusText,, ahk_id %activeWindow%
Msgbox, Focused window text: %focusText%
} else {
Msgbox, Focused control text: %focusText%
}
}
return
So you would want to find out the identifier of what ever field you were interested in and check if it has focus when you want to know, or maybe regularly with SetTimer.

Configure dwm (Linux) to peek when MODKEY is held

I just installed dwm on Arch and am loving it. However, I found that I have no use for the status bar except when I'm switching tags, so I thought a useful feature would be to only display it while MODKEY is pressed.
I know that MODKEY+b toggles the bar, but I'd like to be able to peek at it while MODKEY's being held down. I'd also prefer that this doesn't consume the event, so I'll still be able to chain additional keys onto the sequence.
The only thing I found online about this was a post from Lokichaos (https://warosu.org/g/thread/24122078):
I split the difference with "peek" behavior. When I hold down Mod4 (my main dwm modkey) it shows the bar (but does not reserve space for it). The bar also auto-shows when there is an urgent client waiting (so I can see the highlighted tag). [...]
Is there any way I could implement this with my config.h file, or would I need to get into the nitty-gritty dwm.c? Any ideas as to how this could be done in an organized fashion so that I could bind other actions to key presses and releases?
Thanks for your help!
--EDIT--
This patch allows you to listen to release events, (they even show you how to toggle the bar with pressing/releasing MODKEY+b), but I'm only able to listen to presses and releases on non-mod keys. Again, my goal is to have the bar display when I press MODKEY, and disappear again when I release it.
Here are the three things I've tried in config.h:
type modifier key function argument
{ KeyRelease,MODKEY, 0, togglebar, {0} },
{ KeyRelease,MODKEY, NULL, togglebar, {0} },
{ KeyRelease,MODKEY, XK_Super_L, togglebar, {0} },
...to no avail.
You may try holdbar patch to serve your purpose. I am using this and it is working seamlessly without any errors.
Note that after using this, togglebar will not work any more and bar will be always hidden. Also you cannot map HOLDKEY to simply MODKEY as it takes keysym bindings. You can get them by running xev and pressing the required key. It's keysym value in hexadecimal will be displayed. I use the Super (Windows) key and it's keysym value is 0xffeb. I have applied the same patch. If you want to see, you can view it on Github.

Alternative of ControlSend() function of AutoIT in Perl

ControlSend() works in a similar way to Send() but it can send key strokes directly to a window/control, rather than just to the active window. It takes the window/control hwnd as a parameter with keystrokes.
I have used
SendMessage($_,WM_KEYDOWN, VK_RETURN, 0);
SendMessage($_,WM_KEYUP, VK_RETURN, 0);
and
SendMessage($Ctrls5,WM_CHAR, VK_RETURN, 0);
I have also used SendKeys("{ENTER}"); but it wants the window to be present in foreground.
Help me in solving this.
If you are sending the Enter key for carriage return in text box then you have no function for that.
But if you want to send enter key on a button or any other control(to click on it) then you can do so by the function
PushChildById(Parent_HWND ,ctrl_Hwnd);
PushChildButton(Parent_HWND , Ctrl_regex);