Advanced Caps Lock remap

Page 2 of 3 FirstFirst 123 LastLast

  1. Posts : 10
    Windows 7 Home Premium 64-bit / Debian Sid 64-bit
    Thread Starter
       #11

    Ok so I've looked into this a bit more and I'm currently porting the BASH script to AHK, stay tuned for a quick and dirty test version

    Edit:
    If you want to have a sneak-peek, this is the script I started out with:
    http://www.shellperson.net/quickly-c...ail-with-bash/
    It has evolved quite a bit since I found it but I want to make sure I don't forget to give him proper credit for the whole "detect new mail"-part :)

    Edit2:
    I'm stuck at trying to make the script detect new mail properly (currently hangs if I have new mail) and the keyboard LEDs doesn't seem to be working properly for me as they all stay blank. It's also getting a bit too late here (approx. 3:50 AM local time) so I'll post what I have so far and keep going tomorrow (I must say for someone who's used to C and BASH the syntax of AHK feels kind of awkward to work with).

    Code:
    KeyboardLED(4,"on")
    InputBox, Username, Username, Enter username for mail.google.com
    InputBox, Password, Password, Enter password for mail.google.com, hide
    KeyboardLED(4,"off")
    
    loop
    {
    	; Thanks to aMailuhr for this line at http://www.autohotkey.com/forum/topic4486.html
    	urldownloadtofile, https://%Username%:%Password%@mail.google.com/mail/feed/atom, temp.txt
    
    	i := 0
    	loop, read, temp.txt
    	{
    		if (++i == 5)
    		{
    			if (A_LoopReadLine != "<fullcount>0</fullcount>")
    			{
    				Capslock::Run mail.google.com
    				MsgBox, New mail
    				KeyboardLED(4,"on")
    			}
    			else
    			{
    				;Capslock::Run www.google.com ;Throws an error at me for remaping the key twice, fatal limitation?
    				MsgBox, %A_LoopReadLine%
    				KeyboardLED(4,"off")
    			}
    			sleep 5000
    		}
    	}
    }
    
    ; Thanks to evl, Shimanov, Peter and JGR for the KeyboardLED function at http://www.autohotkey.com/forum/topic10532.html
    KeyboardLED(LEDvalue, Cmd)  ; LEDvalue: ScrollLock=1, NumLock=2, CapsLock=4 ; Cmd = on/off/switch 
    { 
      Static h_device 
      If ! h_device ; initialise 
        { 
        device =\Device\KeyBoardClass0 
        SetUnicodeStr(fn,device) 
        h_device:=NtCreateFile(fn,0+0x00000100+0x00000080+0x00100000,1,1,0x00000040+0x00000020,0) 
        } 
    
      VarSetCapacity( output_actual, 4, 0 ) 
      input_size = 4 
      VarSetCapacity( input, input_size, 0 ) 
    
      If Cmd= switch  ;switches every LED according to LEDvalue 
       KeyLED:= LEDvalue 
      If Cmd= on  ;forces all choosen LED's to ON (LEDvalue= 0 ->LED's according to keystate) 
       KeyLED:= LEDvalue | (GetKeyState("ScrollLock", "T") + 2*GetKeyState("NumLock", "T") + 4*GetKeyState("CapsLock", "T")) 
      If Cmd= off  ;forces all choosen LED's to OFF (LEDvalue= 0 ->LED's according to keystate) 
        { 
        LEDvalue:= LEDvalue ^ 7 
        KeyLED:= LEDvalue & (GetKeyState("ScrollLock", "T") + 2*GetKeyState("NumLock", "T") + 4*GetKeyState("CapsLock", "T")) 
        } 
      ; EncodeInteger( KeyLED, 1, &input, 2 ) ;input bit pattern (KeyLED): bit 0 = scrolllock ;bit 1 = numlock ;bit 2 = capslock 
      input := Chr(1) Chr(1) Chr(KeyLED) 
      input := Chr(1) 
      input= 
      success := DllCall( "DeviceIoControl" 
                  , "uint", h_device 
                  , "uint", CTL_CODE( 0x0000000b     ; FILE_DEVICE_KEYBOARD 
                            , 2 
                            , 0             ; METHOD_BUFFERED 
                            , 0  )          ; FILE_ANY_ACCESS 
                  , "uint", &input 
                  , "uint", input_size 
                  , "uint", 0 
                  , "uint", 0 
                  , "uint", &output_actual 
                  , "uint", 0 ) 
    } 
    
    CTL_CODE( p_device_type, p_function, p_method, p_access ) 
    { 
      Return, ( p_device_type << 16 ) | ( p_access << 14 ) | ( p_function << 2 ) | p_method 
    } 
    
    
    NtCreateFile(ByRef wfilename,desiredaccess,sharemode,createdist,flags,fattribs) 
    { 
      VarSetCapacity(fh,4,0) 
      VarSetCapacity(objattrib,24,0) 
      VarSetCapacity(io,8,0) 
      VarSetCapacity(pus,8) 
      uslen:=DllCall("lstrlenW","str",wfilename)*2 
      InsertInteger(uslen,pus,0,2) 
      InsertInteger(uslen,pus,2,2) 
      InsertInteger(&wfilename,pus,4) 
      InsertInteger(24,objattrib,0) 
      InsertInteger(&pus,objattrib,8) 
      status:=DllCall("ntdll\ZwCreateFile","str",fh,"UInt",desiredaccess,"str",objattrib,"str",io,"UInt",0,"UInt",fattribs 
                      ,"UInt",sharemode,"UInt",createdist,"UInt",flags,"UInt",0,"UInt",0, "UInt") 
      return % ExtractInteger(fh) 
    } 
    
    
    SetUnicodeStr(ByRef out, str_) 
    { 
      VarSetCapacity(st1, 8, 0) 
      InsertInteger(0x530025, st1) 
      VarSetCapacity(out, (StrLen(str_)+1)*2, 0) 
      DllCall("wsprintfW", "str", out, "str", st1, "str", str_, "Cdecl UInt") 
    } 
    
    
    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). 
    { 
      Loop %pSize%  ; Build the integer by adding up its bytes. 
        result += *(&pSource + pOffset + A_Index-1) << 8*(A_Index-1) 
      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) 
    } 
    
    
    InsertInteger(pInteger, ByRef pDest, pOffset = 0, pSize = 4) 
    ; The caller must ensure that pDest has sufficient capacity.  To preserve any existing contents in pDest, 
    ; only pSize number of bytes starting at pOffset are altered in it. 
    { 
      Loop %pSize%  ; Copy each byte in the integer into the structure as raw binary data. 
        DllCall("RtlFillMemory", "UInt", &pDest + pOffset + A_Index-1, "UInt", 1, "UChar", pInteger >> 8*(A_Index-1) & 0xFF) 
    }
    Last edited by Djhg2000; 14 Mar 2011 at 21:53.
      My Computer


  2. jav
    Posts : 713
    Windows 7 Ultimate x86 SP1
       #12

    ok, I changed it a bit and tried it.

    *Without LED lights
    *I used direct username and Password
    *It appears we need if/else arguments inside the Hotkey, to eliminate duplicate hotkey error.
    Code:
    loop
    {
    	; Thanks to aMailuhr for this line at http://www.autohotkey.com/forum/topic4486.html
    	urldownloadtofile, https://Username:Password@mail.google.com/mail/feed/atom, temp.txt
    
    	i := 0
    	loop, read, temp.txt
    	{
    		if (++i == 5)
    		{
    Capslock::
    			if (A_LoopReadLine != "<fullcount>0</fullcount>")
    			{
    
    
    Run https://mail.google.com
    				
    			}
    			else 
    			{
    				
    
    Run https://www.google.com
    			}
    			sleep 5000
    return
    		}
    	}
    }
    The problem is, that "A_LoopReadLine" is doing something wrong as in this script case it always open gmail.
    However you can test that if/else argument is working, by changing
    Code:
    A_LoopReadLine != "<fullcount>0</fullcount>
    to
    Code:
    A_LoopReadLine = "<fullcount>0</fullcount>
    In this case it will always open google...
    Thus it means that mail fetch script always reporting as:
    Code:
     A_LoopReadLine != "<fullcount>0</fullcount>

    P.S. sorry for bad formating. had to work with notepad...
      My Computer


  3. Posts : 10
    Windows 7 Home Premium 64-bit / Debian Sid 64-bit
    Thread Starter
       #13

    Here you go, an initial sort of working test version.

    Known issues:
    The main loop is broken, stops after binding the key (but the key is properly bound according to inbox status)
    LED indication may not work, feedback needed (Windows version and desktop/laptop)

    I'm starting to think C or some flavor of it would suit the task better, this script is definitely massive compared to the BASH script...

    Edit:
    I still haven't been able to figure out why it hangs after configuring the hotkey, any ideas?
    I looked into creating a native C app to work around the LED issue by hooking the keyboard and essentially disable Caps Lock by simulating the user holding Shift when pressing a-z while the LED is lit and it seems to involve creating a DLL, risking system stability and a lot of work. I'm fine with the work bit if that's the way it has to be done but I definitely don't want to risk system stability.

    Suddenly I get the impression that doing this properly in Sid (or any Linux distro) is a lot easier than in 7, especially since the LED is hard coded to Caps Lock at the keyboard driver level. Since I don't intend to write a keyboard driver I think the only reasonable way to notify the user of new mail is through a balloon tip (is it still called that?). Any other ideas?
    Advanced Caps Lock remap Attached Files
    Last edited by Djhg2000; 15 Mar 2011 at 23:03.
      My Computer


  4. Posts : 3
    Windows 2000/XP/7 Ultimate 32bit/7 Enterprise 64bit
       #14

    Djhg2000 said:
    Actually I found this:
    Keyboard Remapping: CAPSLOCK to Ctrl and Beyond - Scancode Map, registry, keyboard, WM_APPCOMMAND, Flip3D, 3dFlip, Win7, Vista, dwmApi

    With a registry hack you can reassign the Caps Lock key to, say, VK_BROWSER_HOME which has the scancode "E0 32". This means the binary key "HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Keyboard Layout\Scancode Map" should contain this:
    Code:
    00 00 00 00 00 00 00 00 02 00 00 00 E0 32 3A 00 00 00 00 00
    Now, it so happens [.....]
    If you want that to work, the code in the registry should be 32 E0, not E0 32. The registry swaps the bytes around. So, the code would have to read:
    Code:
    00 00 00 00 00 00 00 00 02 00 00 00 32 E0 3A 00 00 00 00 00
    in order to work.

    Cheers!
      My Computer


  5. Posts : 10
    Windows 7 Home Premium 64-bit / Debian Sid 64-bit
    Thread Starter
       #15

    skagon said:
    Djhg2000 said:
    Actually I found this:
    Keyboard Remapping: CAPSLOCK to Ctrl and Beyond - Scancode Map, registry, keyboard, WM_APPCOMMAND, Flip3D, 3dFlip, Win7, Vista, dwmApi

    With a registry hack you can reassign the Caps Lock key to, say, VK_BROWSER_HOME which has the scancode "E0 32". This means the binary key "HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Keyboard Layout\Scancode Map" should contain this:
    Code:
    00 00 00 00 00 00 00 00 02 00 00 00 E0 32 3A 00 00 00 00 00
    Now, it so happens [.....]
    If you want that to work, the code in the registry should be 32 E0, not E0 32. The registry swaps the bytes around. So, the code would have to read:
    Code:
    00 00 00 00 00 00 00 00 02 00 00 00 32 E0 3A 00 00 00 00 00
    in order to work.

    Cheers!
    Thanks, it works now!

    Unfortunately for us, I discovered that many browsers themselves claim both VK_BROWSER_HOME and VK_LAUNCH_MAIL for themselves (the latter isn't really the browsers business anyway in my opinion, but that's how it is) which means I had to find another key to use.

    The best candidate so far seems to be VK_LAUNCH_APP2 which none of the browsers I tested claimed, the downside is if you have a multimedia keyboard you'll loose the functionality of any Calculator key if it's bound to VK_LAUNCH_APP2 (I'd imagine at least most generic ones does this). The second drawback is that the ShellExecute registry key for APPCOMMAND_LAUNCH_APP2 can't seem to handle parameters, which has an easy fix (batch script) but still worth noting.

    Current status:
    • I'll abandon the AutoHotkey script for now in favor of a native batch script port of the BASH script
    • It will require a few extra binaries in the PATH environment variable, but they won't conflict with any existing binaries and are pretty useful anyway
    • Current dependencies are curl or wget (tries in order of fastest implementation, only done once per execution of the script in daemon mode)

      My Computer


  6. Posts : 3
    Windows 2000/XP/7 Ultimate 32bit/7 Enterprise 64bit
       #16

    You can get any damn key you want... Personally, I've remapped a shitload of my Apple keyboard's extra keys through the registry, put [Alt] keys where they should be, moved Caps Lock to F13 (big key right above backspace) and renamed Caps Lock to F13, so I can do whatever I want with it...
    The same goes for you. Choose some key nobody's using, even a key that doesn't exist in most keyboards, and you're done. You can even get an F25 key... If you search a bit, you will see that there are scancodes available for F-keys above 12, which nobody's using, since they just don't exist in 99.9999999% of the keyboards out there.
    Cheers mate!
      My Computer


  7. Posts : 10
    Windows 7 Home Premium 64-bit / Debian Sid 64-bit
    Thread Starter
       #17

    skagon said:
    You can get any damn key you want... Personally, I've remapped a shitload of my Apple keyboard's extra keys through the registry, put [Alt] keys where they should be, moved Caps Lock to F13 (big key right above backspace) and renamed Caps Lock to F13, so I can do whatever I want with it...
    The same goes for you. Choose some key nobody's using, even a key that doesn't exist in most keyboards, and you're done. You can even get an F25 key... If you search a bit, you will see that there are scancodes available for F-keys above 12, which nobody's using, since they just don't exist in 99.9999999% of the keyboards out there.
    Cheers mate!
    Thanks again, but I need a key which is mapped to one of the AppKey handlers (apparently defined in Winuser.h) for it to have the right functionality, though if you have any trick for this too I'd be happy to hear about that as well.

    While writing this post I discovered the dark truth about the APPCOMMAND_LAUNCH_APP2 key binding... in addition to launching the specified command it also triggers Ctrl+Alt+L for some reason, which is definitely an undesirable effect.

    At least in theory, only F49 and above are safe to map because they don't correspond to F1-F12 with any modifier keys (such as Shift+F1 which equals F13, better explained in this UnixWare manual page).

    Anyway, I'm now experimenting with a different approach, set Caps Lock to one of the "dead" F keys and set up a shortcut to the command I want to run on the desktop and bind my key to it.

    Edit:
    That didn't work, back to Calculator key...
      My Computer


  8. Posts : 3
    Windows 2000/XP/7 Ultimate 32bit/7 Enterprise 64bit
       #18

    Mate, why would you care what UNIX specs are? The F-keys above F12 in Windows have nothing to do with CTRL or SHIFT or whatever. They have their own scancodes, and you can see that in this document.
    Sorry I don't have any tricks up my sleeve, but I never wanted to do what you want. On the other hand, you can just write a short script with AutoHotKey, like the other guys said, and do what you want easily. No need to write your own programme.
      My Computer


  9. Posts : 10
    Windows 7 Home Premium 64-bit / Debian Sid 64-bit
    Thread Starter
       #19

    skagon said:
    Mate, why would you care what UNIX specs are? The F-keys above F12 in Windows have nothing to do with CTRL or SHIFT or whatever. They have their own scancodes, and you can see that in this document.
    Sorry I don't have any tricks up my sleeve, but I never wanted to do what you want. On the other hand, you can just write a short script with AutoHotKey, like the other guys said, and do what you want easily. No need to write your own programme.
    Seems like you where right, just thought Windows did the F13-F24 thing too.

    Like stated above, I tried to make an AutoHotkey script but couldn't figure out how to get past the hanging hotkey assignment to proceed with the infinite loop. Other than that, the script works as intended (my conclusion is that Windows 7 broke the LED feature).

    The batch script port is coming along nicely anyway, porting from BASH isn't as painful as I thought it would be (but extra binaries are still needed).
      My Computer


  10. jav
    Posts : 713
    Windows 7 Ultimate x86 SP1
       #20

    I tested the script.
    I am getting the same problems, LED and loop is not working.

    As I have said I am not really good with coding.
    If you want to go with AHK your best bet will be asking help from AHK community itself.

    I am sure they can easily solve loop and LED problem.

    Forums: AutoHotkey Community - Mouse and Keyboard Macros and Hotkeys
    Or drop by to their IRC: freenode Web IRC (qwebirc)

    I hope you will find the solution somehow.
      My Computer


 
Page 2 of 3 FirstFirst 123 LastLast

  Related Discussions
Our Sites
Site Links
About Us
Windows 7 Forums is an independent web site and has not been authorized, sponsored, or otherwise approved by Microsoft Corporation. "Windows 7" and related materials are trademarks of Microsoft Corp.

© Designer Media Ltd
All times are GMT -5. The time now is 04:39.
Find Us