Пользуясь AutoIt3, там есть отличная функция "Send", которая в окна может выслать текст, выслать горячую клавишу, поддерживает текстовые названия модификаторов индивидуально нажатие и отпуск и переключение. Решил посмотреть если она в PureAutoIt и оказалось есть, там её код на 500 строк и вычленить всю я вначале хотел в отдельный pbi, но решил что код слишком длинный, а в моих целях требовался только хоткей для выделения текста в окне ввода, копирования и вставки. Решил упростить вычленив только нужное и получилось.

Код:
EnableExplicit

Global SendKeyDelay = 5
Global SendKeyDownDelay = 5

EnumerationBinary
	#MOD_LALT      = #MOD_ALT
	#MOD_LCONTROL  = #MOD_CONTROL
	#MOD_LSHIFT    = #MOD_SHIFT
	#MOD_LWIN      = #MOD_WIN
	#MOD_RALT
	#MOD_RCONTROL
	#MOD_RSHIFT
	#MOD_RWIN
EndEnumeration

#KEYEVENTF_UNICODE = 4

Macro IIf(expr, truepart)
	If expr
    truepart
	EndIf
EndMacro

Procedure keybd_event_send(vk.a, flag.l, extra.i = 0)
	Protected input.INPUT
	input\type = #INPUT_KEYBOARD
	input\ki\wVk = vk
	input\ki\wScan = MapVirtualKey_(vk, #MAPVK_VK_TO_VSC)
	input\ki\dwFlags = flag
	input\ki\dwExtraInfo = extra
	SendInput_(1, @input, SizeOf(INPUT))
EndProcedure

; Only left shift, left ctrl, and left alt don't need EXTENDEDKEY
Procedure SendModifier(modifier.u, type.l = 0)
	Macro SendModifierNoExt(vk)
    keybd_event_send(vk, type)
    Delay(SendKeyDelay)
	EndMacro
	
	Macro SendModifierExt(vk)
    keybd_event_send(vk, type | #KEYEVENTF_EXTENDEDKEY)
    Delay(SendKeyDelay)
	EndMacro
	
	IIf(modifier & #MOD_LSHIFT, SendModifierNoExt(#VK_LSHIFT))
	IIf(modifier & #MOD_RSHIFT, SendModifierExt(#VK_RSHIFT))
	IIf(modifier & #MOD_LCONTROL, SendModifierNoExt(#VK_LCONTROL))
	IIf(modifier & #MOD_RCONTROL, SendModifierExt(#VK_RCONTROL))
	IIf(modifier & #MOD_LALT, SendModifierNoExt(#VK_LMENU))
	IIf(modifier & #MOD_RALT, SendModifierExt(#VK_RMENU))
	IIf(modifier & #MOD_LWIN, SendModifierExt(#VK_LWIN))
	IIf(modifier & #MOD_RWIN, SendModifierExt(#VK_RWIN))
EndProcedure

Procedure SendKey(vk.a, modifier.u, extend = 0)
	
	SendModifier(modifier, 0)

	keybd_event_send(vk, extend)
	Delay(SendKeyDownDelay)
	keybd_event_send(vk, #KEYEVENTF_KEYUP | extend)
	Delay(SendKeyDelay)
	
	SendModifier(modifier, #KEYEVENTF_KEYUP)
EndProcedure

Ранее я использвал keybd_event_() и это работало жутко, не понимал в чём была проблема. Потом нашёл код с использованием SendInput_() тут, стало работать нормально, но теперь точно буду использовать AutoIt3-вариант кода. Здесь можно выслать с модификатором или одиночное нажатие клавиши, без необходимости городить последовательности нажатий клавиш и отпуска.

Пример

Код:
XIncludeFile "SendKey.pbi"

Global g_Key.INPUT
g_Key\type = #INPUT_KEYBOARD

Procedure ReleaseKey()
	While GetAsyncKeyState_(#VK_SHIFT)
    g_Key\ki\wVk = #VK_SHIFT
    g_Key\ki\dwFlags = #KEYEVENTF_KEYUP
    SendInput_( 1, @g_Key, SizeOf(INPUT))
    Delay(10)
	Wend
	While GetAsyncKeyState_(#VK_CONTROL)
    g_Key\ki\wVk = #VK_CONTROL
    g_Key\ki\dwFlags = #KEYEVENTF_KEYUP
    SendInput_( 1, @g_Key, SizeOf(INPUT))
    Delay(10)
	Wend
	While GetAsyncKeyState_(#VK_MENU)
    g_Key\ki\wVk = #VK_MENU
    g_Key\ki\dwFlags = #KEYEVENTF_KEYUP
    SendInput_( 1, @g_Key, SizeOf(INPUT))
    Delay(10)
	Wend
EndProcedure


ReleaseKey()
SendKey(#VK_LEFT, #MOD_LCONTROL | #MOD_LSHIFT)

Функцию ReleaseKey() я сделал из предыдущего варианта и не стал переделывать. Она посылает отпуск клавиш перед тем как выслать, так как Send иногда вызывает заливание клавиш модификаторов, поэтому всегда сначала проверить отпущены ли они и если нет, и если нет посылать отпуск пока не отпустит.

Отредактировано AZJIO (20.02.2022 20:17:32)