Code : Tout sélectionner
#include <GUIConstantsEx.au3>
#Include <WindowsConstants.au3>
#include <Constants.au3>
#include <WinAPI.au3>
#include <WinAPISys.au3>
#include <ComboConstants.au3>
#include <GuiComboBoxEx.au3>
HotKeySet("#{F6}", "_toggle")
HotKeySet("#{F7}", "_SelectChrFromUI")
HotKeySet("#{esc}", "_Exit")
Local $BDEBUG = False
Local $bToggle=False, $str = ""
Global $pStub_KeyProc = DllCallbackRegister("_KeyProc", "int", "int;ptr;ptr")
Global $hHookKeyboard = _WinAPI_SetWindowsHookEx($WH_KEYBOARD_LL, DllCallbackGetPtr($pStub_KeyProc), _WinAPI_GetModuleHandle(0), 0)
While 1
Switch GUIGetMsg()
Case $GUI_EVENT_CLOSE
ToolTip('', 0, 0)
Exit
EndSwitch
WEnd
Func _toggle()
$bToggle = not $bToggle
if $bToggle Then
ToolTip('Win F6 is set', 0, 0)
Else
ToolTip('Win F6 is not set, Win Esc to quit', 0, 0)
EndIf
Sleep(100)
EndFunc
Func _KeyProc($nCode, $wParam, $lParam)
If $nCode < 0 Then Return _WinAPI_CallNextHookEx($hHookKeyboard, $nCode, $wParam, $lParam)
Local $KBDLLHOOKSTRUCT = DllStructCreate("dword vkCode;dword scanCode;dword flags;dword time;ptr dwExtraInfo", $lParam)
Local $vkCode = DllStructGetData($KBDLLHOOKSTRUCT, "vkCode")
Switch $wParam
Case $WM_KEYDOWN, $WM_SYSKEYDOWN
Switch $vkCode
case 0
;do nothing
Case 0x60 to 0x69
If $bToggle And GetNumLockState() = 1 Then ; this will only work if numlock is on.
if $BDEBUG Then ConsoleWrite("toggle is true")
DllCall('user32.dll', 'int', 'keybd_event', 'int', "", 'int', 0, 'int', 0, 'ptr', 0) ;send a null keystroke
;$str &= ChrW($vkCode) ;Chr(_WinAPI_MapVirtualKey($vkCode, $MAPVK_VK_TO_CHAR))
$str &= Chr(_WinAPI_MapVirtualKey($vkCode, $MAPVK_VK_TO_CHAR))
If StringLen($str) = 4 Then
if $BDEBUG Then ConsoleWrite(@CRLF & ChrW($str))
;write the character
Send(chrw($str))
$bToggle = False
ToolTip('Win F6 is not set', 0, 0)
$str = ""
Else
if $BDEBUG Then ConsoleWrite(@CRLF & "str=" & $str & "; strlen=" & stringlen($vkCode) & "; chr = " & ChrW($vkCode))
EndIf
Return -1
Else
if $BDEBUG Then ConsoleWrite("toggle is false")
EndIf
case 45, 35, 40, 34, 37, 12, 39, 36, 38, 33 ; I don't want to worry if the numlock is on or off, so this code will do the same with numlock off
If $bToggle And GetNumLockState() = 0 Then
if $BDEBUG Then ConsoleWrite("toggle is true")
DllCall('user32.dll', 'int', 'keybd_event', 'int', "", 'int', 0, 'int', 0, 'ptr', 0) ;send a null keystroke
Local $NewNumChar = NumCharFromPadKey($vkCode)
$str &= $NewNumChar
If StringLen($str) = 4 Then
if $BDEBUG Then ConsoleWrite(@CRLF & ChrW($str))
;write the character
Send(chrw($str))
$bToggle = False
ToolTip('Win F6 is not set', 0, 0)
$str = ""
Else
if $BDEBUG Then ConsoleWrite(@CRLF & "str=" & $str & "; strlen=" & stringlen($vkCode) & "; chr = " & ChrW($vkCode))
EndIf
Return -1
EndIf
case 48 to 57 ; this will work if the non-keypad numbers are used. On a laptop or a tablet keyboard, there is no numeric pad.
If $bToggle Then
if $BDEBUG Then ConsoleWrite("toggle is true")
DllCall('user32.dll', 'int', 'keybd_event', 'int', "", 'int', 0, 'int', 0, 'ptr', 0) ;send a null keystroke
Local $NewNumChar = NumCharFromPadKey($vkCode)
$str &= chr($vkCode)
If StringLen($str) = 4 Then
if $BDEBUG Then ConsoleWrite(@CRLF & ChrW($str))
;write the character
Send(chrw($str))
$bToggle = False
ToolTip('Win F6 is not set', 0, 0)
$str = ""
Else
if $BDEBUG Then ConsoleWrite(@CRLF & "str=" & $str & "; strlen=" & stringlen($vkCode) & "; chr = " & ChrW($vkCode))
EndIf
Return -1
EndIf
Case Else
$bToggle = False
if $BDEBUG Then ConsoleWrite(@CRLF & "old str=" & $str & "; just received non numeric code '" & $vkCode & "'" & ", skipping; char = " & ChrW($vkCode))
ToolTip('Win F6 is not set', 0, 0)
$str = ""
EndSwitch
EndSwitch
_WinAPI_CallNextHookEx($hHookKeyboard, $nCode, $wParam, $lParam)
EndFunc
Func GetNumLockState()
Const $VK_NUMLOCK = 0x90
Local $ret
$ret = DllCall("user32.dll","long","GetKeyState","long",$VK_NUMLOCK)
Return $ret[0]
EndFunc
Func NumCharFromPadKey($NumCode)
Switch($NumCode)
case 45
Return "0"
case 35
Return "1"
case 40
Return "2"
case 34
Return "3"
case 37
Return "4"
case 12
Return "5"
case 39
Return "6"
case 36
Return "7"
case 38
Return "8"
case 33
Return "9"
EndSwitch
EndFunc
Func _Exit()
DllCallbackFree($pStub_KeyProc)
_WinAPI_UnhookWindowsHookEx($hHookKeyboard)
Exit
EndFunc
Func _SelectChrFromUI()
$bToggle = false
ToolTip('Win F6 is not set', 0, 0)
Dim $sRegKey = "HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Fonts"
Local $CharList, $CharListDisplay = 0
GUICreate("Test", 400, 350)
Local $ArialNdx = 0
$cLabel = GUICtrlCreateLabel("Font list:", 30, 10, 185, 20)
$cCombo_Font = GUICtrlCreateCombo("", 110, 10, 200, 20, Bitor($CBS_SORT,$CBS_DROPDOWN,$CBS_AUTOHSCROLL,$WS_VSCROLL))
GUICtrlSetData($cCombo_Font, _RegEnumVal($sRegKey), "Arial")
GUICtrlSetFont($cLabel, 10, Default, Default, "Arial")
$CharListDisplay = GUICtrlCreateEdit("", 10, 50, 380, 300)
$CharList = getcharlist()
GUICtrlSetData($CharListDisplay, $CharList)
GUISetState()
While 1
$msg = GUIGetMsg()
Switch $msg
Case $GUI_EVENT_CLOSE
Return
Case $cCombo_Font
GUICtrlSetFont($cLabel, 10, Default, Default, GUICtrlRead($cCombo_Font))
GUICtrlSetFont($CharListDisplay, 10, Default, Default, GUICtrlRead($cCombo_Font))
$CharList = getcharlist()
GUICtrlSetData($CharListDisplay, $CharList)
EndSwitch
WEnd
EndFunc
Func getcharlist()
Local $CharacterList
for $i = 161 to 255
if Mod($i - 1160, 8)=0 And $i>162 Then
$CharacterList &= chrW("0" & $i) & @CRLF
Else
$CharacterList &= chrW("0" & $i) & @TAB
EndIf
Next
Return $CharacterList
EndFunc
Func _RegEnumVal($sKey)
Local $i = 1, $sVal, $sResult
While 1
$sVal = RegEnumVal($sKey, $i)
If @error Then ExitLoop
$i += 1
$sResult &= $sVal & "|"
WEnd
Return StringRegExpReplace($sResult, " \(.*?\)", "") ;get rid of " (TrueType") etc
EndFunc