AutoHotkey Community

It is currently May 27th, 2012, 5:25 am

All times are UTC [ DST ]




Post new topic Reply to topic  [ 7 posts ] 
Author Message
PostPosted: December 28th, 2005, 6:27 pm 
Offline

Joined: December 24th, 2005, 1:27 pm
Posts: 7
Location: Austin, TX
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.


Report this post
Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: December 28th, 2005, 8:14 pm 
replace the exits with returns?


Report this post
Top
  
Reply with quote  
 Post subject:
PostPosted: December 28th, 2005, 8:32 pm 
Offline

Joined: February 14th, 2005, 4:05 pm
Posts: 4710
Location: Boulder, CO
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).


Report this post
Top
 Profile  
Reply with quote  
PostPosted: December 29th, 2005, 12:28 am 
Offline

Joined: December 24th, 2005, 1:27 pm
Posts: 7
Location: Austin, TX
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


Report this post
Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: December 29th, 2005, 1:09 am 
Offline

Joined: February 14th, 2005, 4:05 pm
Posts: 4710
Location: Boulder, CO
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.)


Report this post
Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: December 30th, 2005, 2:15 pm 
Offline

Joined: November 15th, 2005, 11:15 am
Posts: 537
Location: Germany
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


Report this post
Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: December 31st, 2005, 12:34 am 
Offline

Joined: November 15th, 2005, 11:15 am
Posts: 537
Location: Germany
Hi,
I've tested your code.
It seems that the y & m - additions are not recognized.
I've tried to write
Code:
vkF8sc03B&m::

instead of
Code:
vkF8sc03B & m::

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


Report this post
Top
 Profile  
Reply with quote  
Display posts from previous:  Sort by  
Post new topic Reply to topic  [ 7 posts ] 

All times are UTC [ DST ]


Who is online

Users browsing this forum: Exabot [Bot], HotkeyStick, rbrtryn, XstatyK, Yahoo [Bot] and 80 guests


You can post new topics in this forum
You can reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot post attachments in this forum

Search for:
Powered by phpBB® Forum Software © phpBB Group