Jump to content
Mbee

Can I use Send() to the System rather than specific window or process?

Recommended Posts

Mbee

Using the Send() function is easy if you want to target the active window (even if you have to activate it first), but is it possible to send a keystroke more generally, such as to the System as a whole or to every process simultaneously?  I'm trying to remap some keys to that the remapping applies everywhere for all windows and processes.

I thought about sending to Explorer.exe, but there may be dozens of Explorer processes (I set my systems up to run all explorer windows as a separate process).

Any ideas, please?

Share this post


Link to post
Share on other sites
BatMan22

I'm genuinely confused as to what you mean by send to the system.. It sounds like perhaps you're trying to do something to every open folder or something? Can we get some more info about what you're trying to do exactly..? Send is a dumb function, so it sends the keys as if you're just hitting the keys on the keyboard.. so the text/keys effect whatever screen is in 'focus'.. If you want to do something that effects multiple windows, that is possible but you need to do it in a loop. aka something like what  the WinList example I modified below (Warning: the example below closes your active windows - be careful). 

 

#include <MsgBoxConstants.au3>

Example()

Func Example()
    ; Retrieve a list of window handles.
    Local $aList = WinList()

    ; Loop through the array displaying only visable windows with a title.
    For $i = 1 To $aList[0][0]
        If $aList[$i][0] <> "" And BitAND(WinGetState($aList[$i][1]), 2) Then
            WinActivate ($aList[$i][0])
            Send("^w") ; Warning will close your explorer windows.
        EndIf
    Next
EndFunc   ;==>Example

 

Share this post


Link to post
Share on other sites
Mbee

Thanks for your reply, BatMan22.  You write: "so the text/keys effect whatever screen is in 'focus'"  Did you really mean "screen" there, or did you mean "window"?

Here's what I'm trying to do: No matter which window has focus and no matter which process is associated with that active window, if the user presses Control+Up, I want to translate that into the "Home" key.  And likewise for the Control+Down = "End" key.  That's because one of my systems has a small keyboard that doesn't include Home or End.

But I think I've got at least part of the solution. In the handlers for each of those keys, get the active window no matter what application raised it, and send the translation there.  The only remaining issue is what to do if there are NO active windows (i.e., nothing but the desktop is visible).  But I think in that case I'll find the active window to belong to Explorer.exe, so I can send the translations there...

Edited by Mbee

Share this post


Link to post
Share on other sites
Bilgus

 

#include <MsgBoxConstants.au3>
#include <StructureConstants.au3>
#include <WinAPI.au3>
#include <WindowsConstants.au3>

Func SendKeyLL($hDll, $sKey)
    ;You need to check for shift ctrl and alt if you want to send them
    ;0x100 = shift
    ;0x200 = ctrl
    ;0x400 = alt
    ConsoleWrite("SendKeyLL " & $sKey & @CRLF)
    Local Const $KEYEVENTF_EXTENDEDKEY = 0x0001
    Local Const $KEYEVENTF_KEYUP = 0x0002
    Local Const $iScanCode = 0x45
    Local $aRet = DllCall($hDll, 'short', 'VkKeyScan', 'ushort', AscW($sKey))
    If IsArray($aRet) Then
        Local $vk = BitAND($aRet[0], 0xFF) ;Only Low Order byte

        If BitAND($aRet[0], 0x0100) = 0x100 Then ;ShiftKey
            DllCall($hDll, 'int', 'keybd_event', 'byte', 0xA0, 'dword', 0x2A, 'dword', 0x0, 'int', 0) ;keydn
        EndIf

        DllCall($hDll, 'int', 'keybd_event', 'byte', $vk, 'dword', $iScanCode, 'dword', 0x0, 'int', 0) ;keydn
        DllCall($hDll, 'int', 'keybd_event', 'byte', $vk, 'dword', $iScanCode, 'dword', $KEYEVENTF_KEYUP, 'int', 0) ;keyup

        If BitAND($aRet[0], 0x0100) = 0x100 Then ;ShiftKey
            DllCall($hDll, 'int', 'keybd_event', 'byte', 0xA0, 'dword', 0x2A, 'dword', $KEYEVENTF_KEYUP, 'int', 0) ;keydn
        EndIf
    EndIf
EndFunc   ;==>SendKeyLL

 

Edited by Bilgus

Share this post


Link to post
Share on other sites
Bilgus

And Here is one that does the ctrl key

Do Note I changed SendKeyLL to take flags for alt and ctrl keys and also made it so you don't strictly have to pass it a handle to user32

although in this case since we call it a lot it is advisable..

#include <MsgBoxConstants.au3>
#include <StructureConstants.au3>
#include <WinAPI.au3>
#include <WindowsConstants.au3>

Func SendKeyLL($sKey, $bCtrl = False, $bAlt = False, $vDLL = 'user32.dll')
    ;0x100 = shift
    ;0x200 = ctrl
    ;0x400 = alt
    ConsoleWrite("SendKeyLL " & $sKey & @CRLF)
    Local Const $KEYEVENTF_EXTENDEDKEY = 0x0001
    Local Const $KEYEVENTF_KEYUP = 0x0002
    Local Const $iSCANCODE = 0x03
    Local $hDll = IsString($vDLL) ? DllOpen($vDLL) : $vDLL
    Local $aRet = DllCall($vDLL, 'short', 'VkKeyScan', 'ushort', AscW($sKey))

    If IsArray($aRet) Then
        Local $vk = BitAND($aRet[0], 0xFF) ;Only Low Order byte

        If $bCtrl Then ;CtrlKey
            DllCall($hDll, 'int', 'keybd_event', 'byte', 0xA2, 'dword', 0x1D, 'dword', 0x0, 'int', 0) ;keydn
            DllCall($hDll, 'int', 'keybd_event', 'byte', 0xA3, 'dword', 0x1D, 'dword', 0x0, 'int', 0) ;keydn
        EndIf

        If $bAlt Then ;AltKey
            DllCall($hDll, 'int', 'keybd_event', 'byte', 0x12, 'dword', 0x38, 'dword', 0x0, 'int', 0) ;keydn
        EndIf

        If BitAND($aRet[0], 0x0100) = 0x100 Then ;ShiftKey
            DllCall($hDll, 'int', 'keybd_event', 'byte', 0xA0, 'dword', 0x2A, 'dword', 0x0, 'int', 0) ;keydn
        EndIf

        DllCall($hDll, 'int', 'keybd_event', 'byte', $vk, 'dword', $iSCANCODE, 'dword', 0x0, 'int', 0) ;keydn
        DllCall($hDll, 'int', 'keybd_event', 'byte', $vk, 'dword', $iSCANCODE, 'dword', $KEYEVENTF_KEYUP, 'int', 0) ;keyup

        If BitAND($aRet[0], 0x0100) = 0x100 Then ;ShiftKey
            DllCall($hDll, 'int', 'keybd_event', 'byte', 0xA0, 'dword', 0x2A, 'dword', $KEYEVENTF_KEYUP, 'int', 0) ;keyup
        EndIf

        If $bAlt Then ;AltKey
            DllCall($hDll, 'int', 'keybd_event', 'byte', 0x12, 'dword', 0x38, 'dword', $KEYEVENTF_KEYUP, 'int', 0) ;keyup
        EndIf

        If $bCtrl Then ;CtrlKey
            DllCall($hDll, 'int', 'keybd_event', 'byte', 0xA2, 'dword', 0x1D, 'dword', $KEYEVENTF_KEYUP, 'int', 0) ;keyup
            DllCall($hDll, 'int', 'keybd_event', 'byte', 0xA3, 'dword', 0x1D, 'dword', $KEYEVENTF_KEYUP, 'int', 0) ;keyup
        EndIf
    EndIf
    If IsString($vDLL) Then DllClose($vDLL)
EndFunc   ;==>SendKeyLL

 

Edited by Bilgus

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

×