 |
AutoHotkey Community Let's help each other out
|
| View previous topic :: View next topic |
| Author |
Message |
Psi-Jack
Joined: 24 Dec 2005 Posts: 7 Location: Austin, TX
|
Posted: Wed Dec 28, 2005 5:27 pm Post subject: Simulated Virtual Keys as Modifiers |
|
|
Hey everyone.
Got another good question I could use some help with.
I just started using Micah's HID support DLL, and I'm trying to do some tricks to get the "most" use out of my media keys. Now that I'm using my keyboard in USB again, since the HID routines themselves are now handling the "extended" keys of my keyboard, which don't send the normal scancodes, I've decided to simulate them instead. A neat way I thought to do it.
What I'm getting, however, isn't what I hoped for..
Here's a code sample I threw out just to test things with:
| Code: |
;
; AutoHotkey Version: 1.x
; Language: English
; Platform: WinXP
; Author: Eric Renfro <erenfro@gmail.com>
;
; Script Function:
; Test Snippet for Logitech Coordless Freedom HID support.
;
Init()
{
HID_DLL=%A_ScriptDir%\AutohotkeyRemoteControl.dll
hModule := DllCall("LoadLibrary", "str", HID_DLL)
OnMessage(0x00FF, "HID_MSG")
DetectHiddenWindows, On
HWND := WinExist(A_ScriptFullPath . " ahk_class AutoHotkey")
HookHID(1, 12, HWND)
SetTimer, UPDATEDSCRIPT, 1000
OnExit, cleanup
Return
}
Init()
vkF8sc03B & y::
MsgBox, 32, Messenger Test, Load Yahoo Messenger,1
Exit
vkF8sc03B & m::
MsgBox, 32, Messenger Test, Load MSN Messenger,1
Exit
vkF8sc03B::
MsgBox, 32, Messenger Test, Load Trillian,1
Exit
Return
HandleHID(Vals)
{
;MsgBox, 32, HandleHID, Vals %Vals%, 1
ifequal, Vals, 485756
kb_Do("Messenger", "Down")
ifequal, Vals, 005756
kb_Do("Messenger", "Up")
ifequal, Vals, 515352
kb_Do("Webcam", "Down")
ifequal, Vals, 005352
kb_Do("Webcam", "Up")
}
ExtractInteger(ByRef pSource, pOffset = 0, pIsSigned = false, pSize = 4)
; pSource is a string (buffer) whose memory area contains a raw/binary integer at pOffset.
; The caller should pass true for pSigned to interpret the result as signed vs. unsigned.
; pSize is the size of PSource's integer in bytes (e.g. 4 bytes for a DWORD or Int).
; pSource must be ByRef to avoid corruption during the formal-to-actual copying process
; (since pSource might contain valid data beyond its first binary zero).
{
SourceAddress := &pSource + pOffset ; Get address and apply the caller's offset.
result := 0 ; Init prior to accumulation in the loop.
Loop %pSize% ; For each byte in the integer:
{
result := result | (*SourceAddress << 8 * (A_Index - 1)) ; Build the integer from its bytes.
SourceAddress += 1 ; Move on to the next byte.
}
if (!pIsSigned OR pSize > 4 OR result < 0x80000000)
return result ; Signed vs. unsigned doesn't matter in these cases.
; Otherwise, convert the value (now known to be 32-bit) to its signed counterpart:
return -(0xFFFFFFFF - result + 1)
}
Return
HookHID(Usage, Page, HWND)
{
nRC := DllCall("AutohotkeyRemoteControl\RegisterDevice", INT, Usage, INT, Page, INT, HWND, "Cdecl UInt")
if (errorlevel <> 0) || (nRC == -1)
{
MsgBox RegisterDevice fehlgeschlagen. Errorcode: %errorlevel%
ExitApp
;goto cleanup
}
}
Return
HID_MSG(wParam, lParam, msg, hwnd)
{
local Vals
DataSize = 5000
VarSetCapacity(RawData, %DataSize%)
nRC := DllCall("AutohotkeyRemoteControl\GetWM_INPUTHIDData", UINT, wParam, UINT, lParam, "UINT *" , DataSize, "UINT *", RawData, "Cdecl UInt")
if (errorlevel <> 0) || (nRC == -1)
{
MsgBox GetWM_INPUTHIDData fehlgeschlagen. Errorcode: %errorlevel%
ExitApp
;goto cleanup
}
loop, %DataSize%
{
Zeichen := ExtractInteger(RawData, A_Index, false, 1)
ifless, Zeichen, 9
{
Zeichen= 0%Zeichen%
}
Vals = %Vals%%Zeichen%
}
HandleHID(Vals)
Vals = ""
}
Return
;reload the script if you changed it with your editor
UPDATEDSCRIPT:
FileGetAttrib,attribs,%A_ScriptFullPath%
IfInString,attribs,A
{
FileSetAttrib,-A,%A_ScriptFullPath%
SplashTextOn,,,Updated script,
Sleep,500
Reload
}
Return
cleanup:
DllCall("FreeLibrary", "UInt", hModule) ; It is best to unload the DLL after using it (or before the script exits).
ExitApp
Return
kb_Do(Key, Direction)
{
;MsgBox, 32, kbDo, Got to kbDo with %Key% and %Direction%, 1
if Key = Messenger
{
If Direction = Down
Send {vkF8sc03B DOWN}
If Direction = Up
Send {vkF8sc03B UP}
;Gosub HotKeyChecks
}
}
Return
|
Now, the problem, here-in lies with this batch of code:
| Code: |
vkF8sc03B & y::
MsgBox, 32, Messenger Test, Load Yahoo Messenger,1
Exit
vkF8sc03B & m::
MsgBox, 32, Messenger Test, Load MSN Messenger,1
Exit
vkF8sc03B::
MsgBox, 32, Messenger Test, Load Trillian,1
Exit
|
With all of them there, autohotkey seems to do absolutely nothing with it. Keep in just the last one, and a popup comes up with Load Trillian. Anyone got any ideas about why this is, or how to fix it?
-- Psi-Jack
PS: Micha, hope you like how I reorganized and functionized your example scripts. I'm not a big fan of the old Gosub or Goto type flows. |
|
| Back to top |
|
 |
not-logged-in-daonlyfreez Guest
|
Posted: Wed Dec 28, 2005 7:14 pm Post subject: |
|
|
| replace the exits with returns? |
|
| Back to top |
|
 |
Laszlo
Joined: 14 Feb 2005 Posts: 4078 Location: Pittsburgh
|
Posted: Wed Dec 28, 2005 7:32 pm Post subject: |
|
|
I don't know the real problem (having no compatible device), but your script is hard to follow. First you define the function Init, then you call it. It means, the autoexecute section starts in the middle of your script. After Init() there is no Return, so the first hotkey is marking the end of the autoexecute section. After the third hotkey, there is a Return, which never gets executed. The hotkey subroutines should probably end with Return, not Exit. Interestingly, these are all allowed, but just bad style.
UPDATEDSCRIPT is annoying if your editor has an autosave function. You have to remember to exit the script, before some editing is started.
You have Send {vkF8sc03B DOWN}, which could cause an infinite cycle, activating hotkeys. Consider adding #UseHook before the hotkey definitions (or a $ prefix). |
|
| Back to top |
|
 |
Psi-Jack
Joined: 24 Dec 2005 Posts: 7 Location: Austin, TX
|
Posted: Wed Dec 28, 2005 11:28 pm Post subject: Simulated Virtual Keys as Modifiers |
|
|
| Laszlo wrote: | | I don't know the real problem (having no compatible device), but your script is hard to follow. First you define the function Init, then you call it. It means, the autoexecute section starts in the middle of your script. After Init() there is no Return, so the first hotkey is marking the end of the autoexecute section. After the third hotkey, there is a Return, which never gets executed. The hotkey subroutines should probably end with Return, not Exit. Interestingly, these are all allowed, but just bad style. |
Heh, what can I say. I'm used to othe programming languages, and "functional" programming, and flow control.
| Laszlo wrote: | | UPDATEDSCRIPT is annoying if your editor has an autosave function. You have to remember to exit the script, before some editing is started. |
That's why I like UltraEdit/32. Best derned ultra-powerful editor there is, in my book.
| Laszlo wrote: | | You have Send {vkF8sc03B DOWN}, which could cause an infinite cycle, activating hotkeys. Consider adding #UseHook before the hotkey definitions (or a $ prefix). |
Well, basically, if you noticed, that vkF8sc03B DOWN, as it's being sent, obviously is the simulated key. You can't get that from the keyboard hook at all. I'm taking the HID input from the keyboard, using Micha's DLL for handling HID responces, and trying to simulate them as keys for autohotkey to trigger on.
-- Psi-Jack |
|
| Back to top |
|
 |
Laszlo
Joined: 14 Feb 2005 Posts: 4078 Location: Pittsburgh
|
Posted: Thu Dec 29, 2005 12:09 am Post subject: |
|
|
| Can you reproduce the problem without simulated virtual keys? If you could modify your script such that it still produces the strange behavior and we can reproduce it w/o the fancy stuff, we might be able to help. (Du kannst die Deutsche Meldungen stehen lassen.) |
|
| Back to top |
|
 |
Micha
Joined: 15 Nov 2005 Posts: 440 Location: Germany
|
Posted: Fri Dec 30, 2005 1:15 pm Post subject: |
|
|
Hi,
I had a short glance on your code.
How does it work after changing everything as the other guys suggested it?
* Good work, functionized my script. I must confess I wrote it quick'n dirty. Looks much better now. I used gosubs, because with my remote control I want to do very different things and if I only call one function, it would have one big if then else if then else .. branch. So I used gosubs to jump to different locations. I will change my examples to look as good as yours
* I think there is a missing return between the end of HandleHID and ExtractInteger
Please post, if your code still doesn't work after all changes
Ciao
Micha |
|
| Back to top |
|
 |
Micha
Joined: 15 Nov 2005 Posts: 440 Location: Germany
|
Posted: Fri Dec 30, 2005 11:34 pm Post subject: |
|
|
Hi,
I've tested your code.
It seems that the y & m - additions are not recognized.
I've tried to write
instead of
and it works sometimes (stange).
I've changed the code to different scancodes and without &m / &y and it works perfect.
Here are my changes:
| Code: |
Init()
return
Init()
{
HID_DLL=%A_ScriptDir%\AutohotkeyRemoteControl.dll
hModule := DllCall("LoadLibrary", "str", HID_DLL)
OnMessage(0x00FF, "HID_MSG")
DetectHiddenWindows, On
HWND := WinExist(A_ScriptFullPath . " ahk_class AutoHotkey")
HookHID(1, 12, HWND)
SetTimer, UPDATEDSCRIPT, 1000
OnExit, cleanup
}
Return
...
...
...
kb_Do(Key, Direction)
{
;MsgBox, 32, kbDo, Got to kbDo with %Key% and %Direction%, 1
if Key = Messenger
{
If Direction = Down
{
MsgBox, 32, kbDo, Got to kbDo with %Key% and %Direction%, 1
Send {vkF8sc03B}
}
If Direction = Up
{
MsgBox, 32, kbDo, Got to kbDo with %Key% and %Direction%, 1
Send {vkF7sc04B}
}
;Gosub HotKeyChecks
}
if Key = webcam
{
If Direction = Down
{
MsgBox, 32, kbDo, WEBWEBWEBWEBWEBWEB Got to kbDo with %Key% and %Direction%, 1
Send {vkF6sc05B}
}
If Direction = Up
{
MsgBox, 32, kbDo, Got to WEBWEBWEBWEBWEBWEB with %Key% and %Direction%, 1
Send {vkF5sc06B}
}
;Gosub HotKeyChecks
}
}
Return
vkF8sc03B::
MsgBox, 32, Messenger Test, Key down 03,1
return
vkF7sc04B::
MsgBox, 32, Messenger Test, Key down 04,1
return
vkF6sc05B::
MsgBox, 32, Messenger Test, Key down 05,1
return
vkF5sc06B::
MsgBox, 32, Messenger Test, Key down 06,1
return
HandleHID(Vals)
{
MsgBox, 32, HandleHID, Vals %Vals%, 1
ifequal, Vals, 49530000
kb_Do("Messenger", "Down")
ifequal, Vals, 49530053
kb_Do("Messenger", "Up")
ifequal, Vals, 48525653
kb_Do("Webcam", "Down")
ifequal, Vals, 005352
kb_Do("Webcam", "Up")
}
return
|
Thus the dllcall and return-values are ok. The problem is the &y which is not recognized.
Am I right that you want to press a special key on your keyboard while holding for example the "m" key?
Perhaps other Autohotkey-Gurus can help you with this.
If you want to test it without an HID-Device:
You can strip of all HID-Codes and try it i.e with mouse-klicks instead of HID-Codes. The result should be the same. The &y &m aren't recognized.
Perhaps I'll have more time tomorrow to find the problem.
Happy new year (only 23:30 h left)
Ciao
Micha |
|
| Back to top |
|
 |
|
|
You can post new topics in this forum You can reply to topics in this forum
|
Powered by phpBB © 2001, 2005 phpBB Group
|