Mbee Posted March 11, 2018 Share Posted March 11, 2018 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? Link to comment Share on other sites More sharing options...
BatMan22 Posted March 11, 2018 Share Posted March 11, 2018 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 Link to comment Share on other sites More sharing options...
Mbee Posted March 11, 2018 Author Share Posted March 11, 2018 (edited) 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 March 11, 2018 by Mbee Link to comment Share on other sites More sharing options...
Bilgus Posted March 11, 2018 Share Posted March 11, 2018 (edited) #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 March 25, 2018 by Bilgus Link to comment Share on other sites More sharing options...
Bilgus Posted March 11, 2018 Share Posted March 11, 2018 (edited) With you extra requirements you'll need to change it a bit scancode list https://msdn.microsoft.com/en-us/library/aa299374(v=vs.60).aspx Vkcode list https://msdn.microsoft.com/en-us/library/windows/desktop/dd375731(v=vs.85).aspx You should be able to only use vkcodes Edited March 25, 2018 by Bilgus Link to comment Share on other sites More sharing options...
Bilgus Posted March 12, 2018 Share Posted March 12, 2018 (edited) 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.. expandcollapse popup#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 March 25, 2018 by Bilgus Link to comment Share on other sites More sharing options...
InnI Posted March 12, 2018 Share Posted March 12, 2018 9 hours ago, Mbee said: if the user presses Control+Up, I want to translate that into the "Home" key. And likewise for the Control+Down = "End" key HotKeySet("^{up}", "Home") HotKeySet("^{down}", "End") While Sleep(111) WEnd Func Home() Send("{home}") EndFunc Func End() Send("{end}") EndFunc Link to comment Share on other sites More sharing options...
Recommended Posts
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 accountSign in
Already have an account? Sign in here.
Sign In Now