Can Autohotkey detect when a KVM switch is activated? - autohotkey

Can Autohotkey detect when a KVM switch is activated? Currently I have:
OnMessage(0x219, "notify_change")
It notifies me when the KVM switch button is pressed, but also when anything else is plugged in or unplugged, plus other times I don't know why. Is there any way to detect just that the switch button was pressed and/or the keyboard, monitor, and mouse switched from one computer to another?

OK, thanks to kindall pointing me in the right direction, I have an answer:
First, get all the functions from here and save them in devicelist.ahk https://www.autohotkey.com/boards/viewtopic.php?t=69380
Then use this code to see if the keyboard is plugged in. If it is not plugged in, that would mean the KVM switch is not turned to this computer.
#include %a_scriptdir%\devicelist.ahk
notify_change(wParam, lParam, msg, hwnd)
{
keyboard := 0
oArray := JEE_DeviceList("`r`n")
for _, oObj in oArray {
for vKey, vValue in oObj {
if (instr(vValue, "Keyboard")) {
keyboard := 1
}
}
}
}

Related

How to integrate Hand Controlle HC1 in my car simulator game

I m building a car simulator game using Unity. For the input I m using Logitheck steering wheel G29. Now I need to use Hand Controller to accelerate or break.
This is my Hand Controller
Hand Controller HC1
Link
Now I can I interpect his input ? This device is recognize by my windows 10 system, but if I try to start the game with this device I cannot accelerate or break the car.
I configured this in my InputController of Unity:
And in my IRDSPlayerControls.cs file I write these lines of code:
if (Input.anyKey)
{
foreach (KeyCode kcode in Enum.GetValues(typeof(KeyCode)))
{
Debug.Log("Joystick pressed " + kcode);
}
}
Debug.Log("Input debug acc: " + Input.GetAxis("Vertical3"));
Debug.Log("Input debug frenata: " + Input.GetAxis("Vertical4"));
In Console of Unity, I can display this:
Input debug acc: -1
Input debug frenata: -1
You can detect a specific button on a specific joystick joystick 1 button 0, joystick 1 button 1, joystick 2 button 0…
or a specific button on any joystick joystick button 0, joystick button 1, joystick button 2…
Check out Input Manager
I can explain this step by step here but it wont be as good as some tutorials online. I recommend this video as a good tutorial to do this.
UPDATE:
I think your hand controller give analog values and the acceleration/brake buttons are not actually buttons but they are analog joy sticks and have a range of values.
to check this use Input.GetJoystickNames :
using UnityEngine;
public class Example : MonoBehaviour
{
// Prints a joystick name if movement is detected.
void Update()
{
// requires you to set up axes "Joy0X" - "Joy3X" and "Joy0Y" - "Joy3Y" in the Input Manager
for (int i = 0; i < 4; i++)
{
if (Mathf.Abs(Input.GetAxis("Joy" + i + "X")) > 0.2 ||
Mathf.Abs(Input.GetAxis("Joy" + i + "Y")) > 0.2)
{
Debug.Log(Input.GetJoystickNames()[i] + " is moved");
}
}
}
}
I will suggest to first check if those inputs are being received with:
if (Input.anyKey)
{
foreach(KeyCode kcode in Enum.GetValues(typeof(KeyCode)))
{
Debug.Log(kcode);
}
}
This way you can know if the game is recognizing the keycodes of your controller, and if it does, which names are assigned to them.
Once you got this, you only need to check keycodes as an usual keyboard!
Not every joystick, steer etc. is mapping it's inputs to the same axis.
There is a unity forum about that topic (and other related problems). And I found that there are some unity plugins, that could probably solve your problem:
https://github.com/speps/XInputDotNet
https://github.com/JISyed/Unity-XboxCtrlrInput
There are some programs that you can use to list all input axis and see which one you are currently affecting. I used one of them but don't remember the name of it. It might help you to see to which axis your break and throttle are mapped to.
Some of them also allow you to remap then, if this is what you want.
The most probable cause is Unity3D does not support this device.
Unity3D uses a mix of XInput, GameInput?, and USB HID processing for its input on Windows.
It is unclear(closed source), if GameInput is used on Windows, it is required on the modern XBOX's.
I cannot provide a definitive answer, since I do not have this controller to test, and the documentation on the controller is sparse.
The best I can do is point you in the right direction.
Does the device exist in Unity3D:
See if the Input System identifies the device when plugged in while running (make sure the game window has focus):
Adapted from https://docs.unity3d.com/Packages/com.unity.inputsystem#1.4/manual/HowDoI.html
InputSystem.onDeviceChange +=
(device, change) =>
{
switch (change)
{
case InputDeviceChange.Added:
// New Device.
Debug.Log("New device added.");
break;
case InputDeviceChange.Disconnected:
// Device got unplugged.
break;
case InputDeviceChange.Connected:
// Plugged back in.
break;
case InputDeviceChange.Removed:
// Remove from Input System entirely; by default, Devices stay in the system once discovered.
break;
default:
// See InputDeviceChange reference for other event types.
break;
}
}
A lack of log output, when plugged in means the device was not identified as a potential input device. Skip to "All else Fails" below.
Identification at this level does not imply support, as it may flag all HID devices.
Look at all low level input events while pressing the buttons:(Also adapted from 4)
var trace = new InputEventTrace(); // Can also give device ID to only
// trace events for a specific device.
trace.Enable();
//…run stuff
var current = new InputEventPtr();
while (trace.GetNextEvent(ref current))
{
Debug.Log("Got some event: " + current);
}
// Trace consumes unmanaged resources. Make sure to dispose.
trace.Dispose();
The chances of getting here with responses(given the edited output) are slim, but if it happens explore the output to find hints to the device associations and fix your mappings accordingly.
All else Fails
Request device support though Unity3D.com website. Highly recommended.
You can write your own support for the device using either the USB HID, may be flagged by virus scanners, and there is limited documentation or implement a custom GameInput interface. The inclusion in Windows Game Controllers makes this the most probable solution.

Using keyboard and external numpad in AutoHotInterception

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?)

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.

SDL 2.0 Quit Event with Multiple Windows

I'm using SDL 2.0, and decided to try out making multiple windows. Unfortunately, now I can't quit out of my program without going back to the IDE and force closing it.
The event handling is as simple as possible, I am only polling for the quit event, and it worked perfectly fine before I added the second window. Is the Quit Event ignored when using multiple windows? If so, how can I turn it back on?
The Quit Event is only sent when the last open window is trying to close, otherwise a window close event is sent.
I also ran into this problem, and the documentation is a little sparse on the topic so I ended up here.
The summary of the problem is:
If you have only one Window, clicking the X button will trigger an SDL_QUIT event.
If you have two or more windows, clicking the X button will trigger an SDL_WINDOWEVENT event, with an internal type of SDL_WINDOWEVENT_CLOSE.
So if your typical code for single-window quit events might look something like this:
SDL_Event e;
while (SDL_PollEvent(&e))
{
if (e.type == SDL_QUIT)
{
// ... Handle close ...
}
}
The multi-window equivalent would be:
SDL_Event e;
while (SDL_PollEvent(&e))
{
if (e.type == SDL_WINDOWEVENT
&& e.window.event == SDL_WINDOWEVENT_CLOSE)
{
// ... Handle window close for each window ...
// Note, you can also check e.window.windowID to check which
// of your windows the event came from.
// e.g.:
if (SDL_GetWindowID(myWindowA) == e.window.windowID)
{
// ... close window A ...
}
}
}
Note that on the last window, you will again receive SDL_QUIT because it's now the only active window - so best to structure your code in a way that correctly handles both depending on the circumstances.
See docs for more info.

Simulate mouse on Mac

I have a virtual trackpad on my iPhone and to move my mouse I'm using :
CGDisplayMoveCursorToPoint(kCGDirectMainDisplay, CGPointMake(((float)aD.msg)+location.x, ((float)aD.msg2)+location.y));
It's working well but this not a real mouse because when I put my mouse on my hidden dock, this one doesn't display it self. I don't understand why.
More over I tried to simulate mouse click with :
case MOUSECLICK:
[self postMouseEventWithButton:0 withType:kCGEventLeftMouseDown andPoint:CGEventGetLocation(CGEventCreate(NULL))];
[self postMouseEventWithButton:0 withType:kCGEventLeftMouseUp andPoint:CGEventGetLocation(CGEventCreate(NULL))];
// *********************
-(void)postMouseEventWithButton:(CGMouseButton)b withType:(CGEventType)t andPoint:(CGPoint)p
{
CGEventRef theEvent = CGEventCreateMouseEvent(NULL, t, p, b);
CGEventSetType(theEvent, t);
CGEventPost(kCGHIDEventTap, theEvent);
CFRelease(theEvent);
}
Is it the good method? Thanks for your help !
CGDisplayMoveCursorToPoint() only moves the image of the cursor, it does not generate any events. You should create and post mouse events of type kCGEventMouseMoved to simulate moving the mouse. Your own method would do it:
[self postMouseEventWithButton:0 withType:kCGEventMouseMoved andPoint:point];
For clicks, you are already doing it the right way, I think. One thing you should also do is set the click count properly on both the mouse down and mouse up events, like so:
CGEventSetIntegerValueField(event, kCGMouseEventClickState, 1);
... because some applications need it.
(See also Simulating mouse clicks on Mac OS X does not work for some applications)
If your code doesn't work, I'm not sure why; it looks OK to me. Try posting to kCGSessionEventTap instead of kCGHIDEventTap and see if it helps. Also, you don't need the CGEventSetType() call since the type is already set in the creation call.