#include <EditConstants.au3>
#include <GUIConstantsEx.au3>
#include <ListBoxConstants.au3>
#include <WindowsConstants.au3>
#include <GUIListBox.au3>
#Include <WinAPI.au3>
Opt("GUICloseOnESC", 0)
Opt("GuiOnEventMode", 1)
Opt("MustDeclareVars", 1)

Global $show = False, $indexB = -1, $SenseGui, $SenseCtrl, $Macro, $guiBox, $box, $POSSenseGui[2]
Local $aMacro[47] = [ _
'@AppDataCommonDir','@AppDataDir','@AutoItExe','@AutoItVersion','@CommonFilesDir','@ComputerName', _
'@DesktopCommonDir','@DesktopDir','@DocumentsCommonDir','@FavoritesCommonDir','@FavoritesDir','@HomeDrive', _
'@HomePath','@HomeShare','@IPAddress1','@IPAddress2','@IPAddress3','@IPAddress4','@KBLayout','@LogonDNSDomain', _
'@LogonDNSDomain','@LogonDomain','@LogonDomain','@LogonServer','@LogonServer','@MyDocumentsDir','@OSArch', _
'@OSBuild','@OSLang','@OSServicePack','@OSType','@OSVersion','@ProgramFilesDir','@ProgramsCommonDir', _
'@ProgramsDir','@ScriptDir','@ScriptFullPath','@ScriptName','@StartMenuCommonDir','@StartMenuDir', _
'@StartupCommonDir','@StartupDir','@SystemDir','@TempDir','@UserName','@UserProfileDir','@WindowsDir']
$guiBox = GUICreate('', 150, 85, 0, 0, BitOR($WS_SIZEBOX,$WS_POPUP), BitOR($WS_EX_TOPMOST, $WS_EX_TOOLWINDOW))
$box = _GUICtrlListBox_Create($guiBox, '', 0, 0, 150, 86, BitOR($LBS_SORT, 0x00B00002))
For $i = 0 To UBound($aMacro) -1
	_GUICtrlListBox_AddString($box, $aMacro[$i])
Next

GUIRegisterMsg($WM_COMMAND, "MY_WM_COMMAND")
GUIRegisterMsg($WM_MOVE, "_WM_MOVE")
GUIRegisterMsg(0x231, "_WM_ENTERSIZEMOVE")

$SenseGui = GUICreate('Macro Box', 500, 205)
GUISetOnEvent($GUI_EVENT_CLOSE, '_Exit')
GUICtrlCreateLabel('Inhalt', 10, 10, 60)
$Macro = GUICtrlCreateInput('', 10, 30, 480, 21, BitOR($ES_READONLY,$ES_AUTOHSCROLL))
GUICtrlSetBkColor(-1, 0xE0FFFF)
GUICtrlCreateLabel('Makro', 10, 60, 60)
$SenseCtrl = GUICtrlCreateInput('', 10, 80, 480, 21)
GUICtrlSetBkColor(-1, 0xFFFFE0)
GUICtrlCreateButton('Copy To Clipboard', 380, 175, 110, 20)
GUICtrlSetOnEvent(-1, '_Copy')
GUISetState()

Global $Dummy[5]
$Dummy[0] = GUICtrlCreateDummy()
For $i = 1 To 4
    $Dummy[$i] = GUICtrlCreateDummy()
    GUICtrlSetOnEvent(-1, "_Dummy")
Next

Dim $AccelKeys[4][2] = [["{ENTER}", $Dummy[1]],["{ESC}", $Dummy[2]],["{UP}", $Dummy[3]],["{DOWN}", $Dummy[4]]]
GUISetAccelerators($AccelKeys)

While True
    Sleep(100)
WEnd

Func _Exit()
    Exit
EndFunc

Func _Copy()
	ClipPut(GUICtrlRead($Macro))
EndFunc

Func _Dummy()
    If Not $show Then Return
    Switch @GUI_CtrlId - $Dummy[0]
		Case 1
			Local $txt = _GUICtrlListBox_GetText($box, $indexB)
			If $txt Then
				ControlSetText($SenseGui, '', $SenseCtrl, $txt)
				ControlSetText($SenseGui, '', $Macro, Execute($txt))
			Else
				ControlSetText($SenseGui, '', $Macro, '')
			EndIf
            GUISetState(@SW_HIDE, $guiBox)
            $show = False
        Case 2
            GUISetState(@SW_HIDE, $guiBox)
            $show = False
        Case 3
            If $indexB > 0 Then
                $indexB -= 1
                _GUICtrlListBox_SetCurSel($box, $indexB)
				ControlSetText($SenseGui, '', $Macro, Execute(_GUICtrlListBox_GetText($box, $indexB)))
                Sleep(90)
            EndIf
        Case 4
            If $indexB < _GUICtrlListBox_GetCount($box) - 1 Then
                $indexB += 1
                _GUICtrlListBox_SetCurSel($box, $indexB)
				ControlSetText($SenseGui, '', $Macro, Execute(_GUICtrlListBox_GetText($box, $indexB)))
                Sleep(90)
            EndIf
    EndSwitch
EndFunc

Func MY_WM_COMMAND($hWnd, $Msg, $wParam, $lParam)
    Local $nNotifyCode    = BitShift($wParam, 16)
    Local $hCtrl          = $lParam
	Local $hSenseCtrl     = $SenseCtrl
	If Not IsHWnd($hSenseCtrl) Then $hSenseCtrl = GUICtrlGetHandle($hSenseCtrl)
    If ($nNotifyCode = 1024 Or $nNotifyCode = 6)  And $hCtrl = $hSenseCtrl Then
        Local $str = ControlGetText($SenseGui, '', $SenseCtrl)
        $indexB = _GUICtrlListBox_FindString($box, $str)
        _GUICtrlListBox_SetCurSel($box, $indexB)
        Local $caret = _CaretPos()
        If Not @error And Not $show Then
            WinMove($guiBox, '', $caret[0], $caret[1] +25)
            GUISetState(@SW_SHOWNOACTIVATE, $guiBox)
            $show = True
			ControlSetText($SenseGui, '', $Macro, Execute(_GUICtrlListBox_GetText($box, 0)))
        EndIf
    ElseIf $hCtrl = $box And $nNotifyCode = 1 Then
        $indexB = _GUICtrlListBox_GetCurSel($box)
		ControlSetText($SenseGui, '', $SenseCtrl, _GUICtrlListBox_GetText($box, $indexB))
		ControlSetText($SenseGui, '', $Macro, Execute(_GUICtrlListBox_GetText($box, $indexB)))
		GUISetState(@SW_HIDE, $guiBox)
		$show = False
    ElseIf $show And $nNotifyCode = 512 And $hCtrl = $lParam And Not $hCtrl = $box Then
        GUISetState(@SW_HIDE,$guiBox)
        $show = False
    EndIf
	If $show And Not StringLen(GUICtrlRead($SenseCtrl)) Then
        GUISetState(@SW_HIDE,$guiBox)
        $show = False
    EndIf
    Return $GUI_RUNDEFMSG
EndFunc

Func _WM_ENTERSIZEMOVE($hWnd)
    If $hWnd = $SenseGui Then $POSSenseGui = WinGetPos($SenseGui)
EndFunc

Func _WM_MOVE($hWnd)
    If $hWnd = $SenseGui Then
        Local $pos = WinGetPos($guiBox)
        Local $postemp = WinGetPos($SenseGui)
        WinMove($guiBox,"",$pos[0]-($POSSenseGui[0]-$postemp[0]),$pos[1]-($POSSenseGui[1]-$postemp[1]))
        $POSSenseGui = WinGetPos($SenseGui)
    EndIf
EndFunc

Func _CaretPos()
	Local $old = Opt("CaretCoordMode", 0)   ;relative mode
	Local $c = WinGetCaretPos()             ;relative caret coords
	Local $w = WinGetPos("")                ;window's coords
	Local $f = ControlGetFocus("","")       ;text region "handle"
	Local $e = ControlGetPos("", "", $f)    ;text region coords
	Local $h = ControlGetHandle("", "", $f) ;Ctrl-Handle
	Local $t[5]
	If IsArray($c) and IsArray($w) and IsArray($e) Then
		If _WinAPI_IsClassName($SenseCtrl, 'Edit') Then ; Input wird als Edit-Class erkannt
			$t[0] = $c[0] + $w[0] + $e[0]
		ElseIf _WinAPI_IsClassName($SenseCtrl, 'ComboBox') Then
			$t[0] = $w[0] + $e[0]
		EndIf
		$t[1] = $c[1] + $w[1] + $e[1]
		$t[2] = $h
		$t[3] = $w[1]
		$t[4] = $e[1]
		Opt("CaretCoordMode", $old)
		Return $t     ;absolute screen coords of caret cursor
	Else
		Opt("CaretCoordMode", $old)
		SetError(1)
	EndIf
EndFunc

