﻿;-- TIME_STAMP   2021-05-19 11:45:13

#include <WinAPI.au3>
#include <WindowsConstants.au3>
#include <StaticConstants.au3>
#include <StructureConstants.au3>
#include "VKCodeConstants.au3"

Opt('TrayIconHide', 1)
Opt('GUICloseOnESC', 0)

OnAutoItExitRegister("_KeyHookOf")

HotKeySet('^!{F7}', '_Exit') ; Strg+Alt+F7 zum manuellen Beenden

HotKeySet("^-", "_ActivateLayoutSwitch")
; US-Layout:
;~ HotKeySet("^\", "_ActivateLayoutSwitch")

Global $g_hKeyProc, $g_hMod, $g_hHook
Global $g_VK_SHIFT = False		; Shift (RShift or LShift) is down (True/False)
Global $g_user32 = DllOpen("user32.dll")
Global $g_LayoutSwitched = False
Global $g_LayoutIco = "C:\Users\BugFix\Pictures\a_Ä.ico"   ; PFAD ANPASSEN
Global $g_hGuiLayoutMode = GUICreate('', 24, 24, -50, -50)
GUISetIcon($g_LayoutIco, -1, $g_hGuiLayoutMode) ; Icon der nicht sichtbaren GUI ist in der Taskbar sichtbar wenn GUI aktiviert (Skript muss kompiliert sein)

; Starte Tastatur-Hook
_KeyHookOn()

While True
	Sleep(10)
WEnd

Func _Exit()
	Exit
EndFunc

Func _ActivateLayoutSwitch()
	$g_LayoutSwitched = Not $g_LayoutSwitched  ; falls ungewollt aktiviert, wird durch nochmaliges Betätigen der Modus deaktiviert
	If $g_LayoutSwitched Then
		GUISetState(@SW_SHOWNOACTIVATE, $g_hGuiLayoutMode)
	Else
		GUISetState(@SW_HIDE, $g_hGuiLayoutMode)
	EndIf
EndFunc

Func _KeyHookOn()
	; Registrieren der Funktion "_KeyProc" als Callback
	$g_hKeyProc = DllCallbackRegister("_KeyProc", "long", "int;wparam;lparam")

	; Installieren einer eigenen Prozedur zur Verarbeitung der Tastaturereignisse
	$g_hMod = _WinAPI_GetModuleHandle(0)
	$g_hHook = _WinAPI_SetWindowsHookEx($WH_KEYBOARD_LL, DllCallbackGetPtr($g_hKeyProc), $g_hMod)
EndFunc

Func _KeyHookOf()
	; Entfernen der eigenen Key-Prozedur
    _WinAPI_UnhookWindowsHookEx($g_hHook)
    DllCallbackFree($g_hKeyProc)
	; Dll Handle schliessen
	DllClose($g_user32)
EndFunc

Func _KeyProc($_nCode, $_wParam, $_lParam)
    If $_nCode < 0 Then Return _WinAPI_CallNextHookEx($g_hHook, $_nCode, $_wParam, $_lParam)
    Local $tKEYHOOKS, $vkCode, $bCapsLock = False
    $tKEYHOOKS = DllStructCreate($tagKBDLLHOOKSTRUCT, $_lParam)
	$vkCode = $tKEYHOOKS.vkCode

	; Auswerten Status Capslock
	Local $ret = DllCall($g_user32, "long", "GetKeyState", "long", $VK_CAPITAL)
	If $ret[0] Then $bCapsLock = True

	If $_wParam = $WM_KEYDOWN Then
		Switch $vkCode
			Case $VK_LSHIFT, $VK_RSHIFT
				$g_VK_SHIFT = True
			Case $VK_A
				If $g_LayoutSwitched And ($g_VK_SHIFT Or $bCapsLock) Then
					Send('Ä')
					Return -1
				ElseIf $g_LayoutSwitched And (Not $g_VK_SHIFT) And (Not $bCapsLock) Then
					Send('ä')
					Return -1
				EndIf
			Case $VK_O
				If $g_LayoutSwitched And ($g_VK_SHIFT Or $bCapsLock) Then
					Send('Ö')
					Return -1
				ElseIf $g_LayoutSwitched And (Not $g_VK_SHIFT) And (Not $bCapsLock) Then
					Send('ö')
					Return -1
				EndIf
			Case $VK_S
				If $g_LayoutSwitched Then
					Send('ß')
					Return -1
				EndIf
			Case $VK_U
				If $g_LayoutSwitched And ($g_VK_SHIFT Or $bCapsLock) Then
					Send('Ü')
					Return -1
				ElseIf $g_LayoutSwitched And (Not $g_VK_SHIFT) And (Not $bCapsLock) Then
					Send('ü')
					Return -1
				EndIf
		EndSwitch
	ElseIf $_wParam = $WM_KEYUP Then
		Switch $vkCode
			Case $VK_LSHIFT, $VK_RSHIFT
				$g_VK_SHIFT = False
			Case $VK_A, $VK_O, $VK_S, $VK_U
				$g_LayoutSwitched = False
				GUISetState(@SW_HIDE, $g_hGuiLayoutMode)
		EndSwitch
    EndIf
    Return _WinAPI_CallNextHookEx($g_hHook, $_nCode, $_wParam, $_lParam)
EndFunc
