#include <Timers.au3>
#include <GuiStatusBar.au3>
#include <GuiMenu.au3>
#include <MenuConstants.au3>
Global $oRegisteredGUI = ObjCreate('Scripting.Dictionary') ; Dectionary für GUIHandles
Global $oRegisteredMenuItem = ObjCreate('Scripting.Dictionary') ; Dectionary für StatusbarTexte
Global $oRegisteredStatusClock = ObjCreate('Scripting.Dictionary') ; Dectionary für GUIHandle
Global $oRegisteredMenuClock = ObjCreate('Scripting.Dictionary') ; Dectionary für GUIHandle
Global Const $UDF_WM_MENUSELECT = 0x011F
Global $iShowMenuText = False
Global $iMenuClockId = 10000


; #FUNCTION# =====================================================================================================================================================================
; Name...........: _GUICtrlMenu_InitStatusbar
; Description ...: Initialisiert die UDF
; Syntax.........: _GUICtrlMenu_InitStatusbar($bState = True)
; Parameters ....: $bState      - True startet die Notifyauswertung der UDF, False beendet die UDF
;
; Return values .: Success -  1
;                  Failure - -1, sets @error to:
;                  |1 - Übergebener State ist nicht vom Typ Boolean
;
;; Author ........: Raupi @ Autoit.de
; Modified.......:
; Remarks .......:
; ================================================================================================================================================================================
Func _GUICtrlMenu_InitStatusbar($bState = True)
	Local $ColKeys, $strKey
	If Not IsBool($bState) Then Return SetError(1, 0, -1)
	If $bState = True Then
		GUIRegisterMsg($UDF_WM_MENUSELECT, "WM_MENUSELECT")
		Return 1
	Else
		GUIRegisterMsg($UDF_WM_MENUSELECT, "")
		Return 1
		$ColKeys = $oRegisteredStatusClock.Keys
		For $strKey In $ColKeys
			Local $aItem = StringSplit($oRegisteredStatusClock.Item($strKey), "|", 2)
			_Timer_KillTimer(HWnd($strKey), Number($aItem[1]))
		Next
	EndIf
EndFunc   ;==>_GUICtrlMenu_InitStatusbar

; #FUNCTION# =====================================================================================================================================================================
; Name...........: _GUICtrlMenu_SetStatusText
; Description ...: Registriert einen Text zur Anzeige in der Statusbar
; Syntax.........: _GUICtrlMenu_SetStatusText($iCtrlID, $sText)
; Parameters ....: $iCtrlID     - ControlId des Menüeintrages oder Command ID eines Menüeintrages (GUIMenu.au3)
;                  $sText       - Text der beim Selektiern des Menüeintrage in der Statuszeile angezeigt werden soll. Wenn leer wird die Registrierung des Textes gelöscht.
; Return values .: Success -  1
;                  Failure - -1, sets @error to:
;                  |1 - $iCtrlID ist keine Zahl (ConrolID´s und Command ID´s müssen eine Zahl sein)
;                  |2 - Übergebene ControlId oder Command Id sind nicht registriert und werden deshalb nicht gelöscht
; Author ........: Raupi @ Autoit.de
; Modified.......:
; Remarks .......: Wenn zu einem ControlId oder Command Id ein Hilfetext registriert wurde, wir dieser bei Inaktivität ($Gui_Disabled) nicht angezeigt
;                  Hilfetexte können nur zu MenüItems und nicht zu Untermenüs angezeigt werden
; ================================================================================================================================================================================
Func _GUICtrlMenu_SetStatusText($iCtrlID, $sText)
	If Not IsInt($iCtrlID) Then Return SetError(1, 0, -1);Übergebener Parameter ist keine Zahl
	If Not $oRegisteredMenuItem.Exists($iCtrlID) Then
		If $sText = "" Then Return SetError(2, 0, -1)
		$oRegisteredMenuItem.Add($iCtrlID, $sText)
		Return 1
	ElseIf $oRegisteredMenuItem.Exists($iCtrlID) Then
		$oRegisteredMenuItem.Remove($iCtrlID)
		If $sText = "" Then
			Return 1
		Else
			$oRegisteredMenuItem.Add($iCtrlID, $sText)
			Return 1
		EndIf
	EndIf
EndFunc   ;==>_GUICtrlMenu_SetStatusText

; #FUNCTION# =====================================================================================================================================================================
; Name...........: _GUICtrlMenu_RegisterStatusbar
; Description ...: Registriert eine Gui und des dazugehörigen StatusbarHandles  (Es können Mehrere GUIS und dazugehörige StatusbarHandles registriert werden
; Syntax.........: _GUICtrlMenu_RegisterStatusbar($hGui, $hStatus)
; Parameters ....: $hGui       - FensterHandle der zu registrierenden GUI
;                  $hStatus    - Handle des Statusbars
; Return values .: Success -  1
;                  Failure - -1, sets @error to:
;                  |1 - $hGui ist kein Fensterhandle
;                  |2 - $hStatus ist kein Handle
; Author ........: Raupi @ Autoit.de
; Modified.......:
; Remarks .......:
;
; ================================================================================================================================================================================
Func _GUICtrlMenu_RegisterStatusbar($hGui, $hStatus)
	If Not IsHWnd($hGui) Then Return SetError(1, 0, -1)
	If Not IsHWnd($hStatus) Then Return SetError(2, 0, -1)
	If Not $oRegisteredGUI.Exists(String($hGui)) Then
		$oRegisteredGUI.Add(String($hGui), String($hStatus))
		Return 1
	ElseIf $oRegisteredGUI.Exists(String($hGui)) Then
		$oRegisteredGUI.Remove(String($hGui))
		$oRegisteredGUI.Add(String($hGui), String($hStatus))
		Return 1
	Else
	EndIf
EndFunc   ;==>_GUICtrlMenu_RegisterStatusbar

; #FUNCTION# =====================================================================================================================================================================
; Name...........:  _GUICtrlStatusBar_SetClock
; Description ...:  Anzeigen einer Uhr in der StatusBar
; Syntax.........: _GUICtrlStatusBar_SetClock($hWnd, $hStatus, $iPart = 1, $bState = True)
; Parameters ....: $hGui       - FensterHandle der zu registrierenden GUI
;                  $hStatus    - Handle des Statusbars
;                  $iPart      - Tab des Statusbar in der die Uhr angezeigt werden soll (Index 1 basierend)
;                  $bState     - True zeigt die Uhr an, False löscht die Uhr
; Return values .: Success -  1
;                  Failure - -1, sets @error to:
;                  |1 - $hGui ist kein Fensterhandle
;                  |2 - $hStatus ist kein Handle
;                  |3 - $iParts ist keine Zahl
;                  |4 - $bState ist nicht vom Typ Boolean
; Author ........: Raupi @ Autoit.de
; Modified.......:
; Remarks .......:
;
; ================================================================================================================================================================================
Func _GUICtrlStatusBar_SetClock($hWnd, $hStatus, $iPart = 1, $bState = True)
	If Not IsHWnd($hWnd) Then Return SetError(1, 0, -1)
	If Not IsHWnd($hStatus) Then Return SetError(2, 0, -1)
	If Not IsNumber($iPart) Then Return SetError(3, 0, -1)
	If Not IsBool($bState) Then Return SetError(4, 0, -1)
	If $iPart > 0 Then
		Local $iParts = _GUICtrlStatusBar_GetCount($hStatus)
		If $iParts = 1 Then
			$iPart = 1
		ElseIf $iParts < $iPart Then
			$iPart = $iParts
		EndIf
	Else
		$iPart = 1
	EndIf
	If $oRegisteredStatusClock.Exists(String($hWnd)) And $bState = True Then Return 1
	If $oRegisteredStatusClock.Exists(String($hWnd)) And $bState = False Then
		Local $aItem = StringSplit($oRegisteredStatusClock.Item(String($hWnd)), "|", 2)
		_GUICtrlStatusBar_SetText(HWnd($aItem[0]), "        ", $aItem[2] - 1)
		_Timer_KillTimer($hWnd, Number($aItem[1]))
		$oRegisteredStatusClock.Remove(String($hWnd))
		Return 1
	Else
		Local $iTimer = _Timer_SetTimer($hWnd, 1000, "_UpdateStatusBarClock")
		ConsoleWrite("Bar Timer " & $iTimer & @CRLF)
		Local $sItem = String($hStatus) & "|" & String($iTimer) & "|" & String($iPart)
		$oRegisteredStatusClock.Add(String($hWnd), $sItem)
		Return 1
	EndIf
EndFunc   ;==>_GUICtrlStatusBar_SetClock

; #FUNCTION# =====================================================================================================================================================================
; Name...........:  _GUICtrlMenu_SetClock
; Description ...:  Anzeigen einer Uhr in der Menüzeile
; Syntax.........: _GUICtrlMenu_SetClock($hWnd, $bState = True)
; Parameters ....: $hGui       - FensterHandle der zu registrierenden GUI
;                  $bState     - True zeigt die Uhr an, False löscht die Uhr
; Return values .: Success -  1
;                  Failure - -1, sets @error to:
;                  |1 - $hGui ist kein Fensterhandle
;                  |2 - $bState ist nicht vom Typ Boolean
; Author ........: Raupi @ Autoit.de
; Modified.......:
; Remarks .......:Wenn die registrierte GUI kein Menü enthällt, wird dieses hinzugefügt
;
; ================================================================================================================================================================================

Func _GUICtrlMenu_SetClock($hWnd, $bState = True)
	Local $NewMenu = 0
	If Not IsHWnd($hWnd) Then Return SetError(1, 0, -1); GuiHandle ungültig
	Local $hMenu = _GUICtrlMenu_GetMenu($hWnd)
	If Not IsBool($bState) Then Return SetError(2, 0, -1); 3. Parameter ist nicht vom Typ Boolean
	If $oRegisteredMenuClock.Exists(String($hWnd)) And $bState = True Then Return 1
	If $oRegisteredMenuClock.Exists(String($hWnd)) And $bState = False Then
		Local $aItem = StringSplit($oRegisteredMenuClock.Item(String($hWnd)), "|", 2)
		_Timer_KillTimer($hWnd, Number($aItem[1]))
		$oRegisteredMenuClock.Remove(String($hWnd))
		_GUICtrlMenu_DeleteMenu($hMenu, _GUICtrlMenu_GetItemCount($hMenu) - 1, True)
		_GUICtrlMenu_SetMenu($hWnd, $hMenu)
		_GUICtrlMenu_DrawMenuBar($hWnd)
		If $aItem[3] = "1" Then _GUICtrlMenu_SetMenu($hWnd, 0);Menü wurde von _GUICtrlMenu_SetClock erstellt und wird deshalb gelöscht
		Return 1
	Else
		If $hMenu = 0 Then; Wenn GUI kein Menü hat, Menü einfügen
			ConsoleWrite("Menü wird erstellt" & @CRLF)
			$hMenu = _GUICtrlMenu_CreateMenu()
			$NewMenu = 1;Menü wurde von _GUICtrlMenu_SetClock erstellt
			_GUICtrlMenu_SetMenu($hWnd, $hMenu)
		EndIf
		$iMenuClockId += 1;Neue MenüID hinzufügen
		_GUICtrlMenu_AddMenuItem($hMenu, StringFormat("%02d:%02d:%02d", @HOUR, @MIN, @SEC), $iMenuClockId)
		Local $iMenuCnt = _GUICtrlMenu_GetItemCount($hMenu)
		_GUICtrlMenu_SetItemType($hMenu, ($iMenuCnt - 1), $MFT_RIGHTJUSTIFY, True)
		Local $iTimer = _Timer_SetTimer($hWnd, 1000, "_UpdateMenuClock"); create timer
		ConsoleWrite("timer " & $iTimer & @CRLF)
		$oRegisteredMenuClock.Add(String($hWnd), String($hWnd) & "|" & String($iTimer) & "|" & String($iMenuClockId) & "|" & String($NewMenu))
		Return 1
	EndIf
EndFunc   ;==>_GUICtrlMenu_SetClock

Func WM_MENUSELECT($hWnd, $iMsg, $iwParam, $ilParam)
	If Not $oRegisteredGUI.Exists(String($hWnd)) Then Return 'GUI_RUNDEFMSG'; Gui wurde nicht registriert
	Local $menuId, $hStatus
	$hStatus = HWnd($oRegisteredGUI.Item(String($hWnd)));Handle der Statusbar
	_GUICtrlStatusBar_SetSimple($hStatus, True);Statusbar Simple Anzeige einschalten
	$iShowMenuText = True
	$menuId = BitAND($iwParam, 0xFFFF);LoWord aus wParam
	If $menuId = 0 And $ilParam = 0x000000 Then;Kein Menüeintrag selektiert und Menü geschlossen
		_GUICtrlStatusBar_SetSimple($hStatus, False);Ursprüngliche Statusbar wieder herstellen.
		$iShowMenuText = False
		Return 'GUI_RUNDEFMSG'
	ElseIf $oRegisteredMenuItem.Exists($menuId) Then ;Eintrag gefunden, in Statusbar anzeigen
		If BitAND(BitShift($iwParam, 16), 0x01) Then ;Menüeintrag ist grayed
			_GUICtrlStatusBar_SetText($hStatus, "")
			Return 'GUI_RUNDEFMSG'
		Else
			_GUICtrlStatusBar_SetText($hStatus, $oRegisteredMenuItem.Item($menuId))
			Return 'GUI_RUNDEFMSG'
		EndIf
	Else
		_GUICtrlStatusBar_SetText($hStatus, "");Menü ist geöffnet aber kein Hilfetext gesetzt
		Return 'GUI_RUNDEFMSG'
	EndIf
EndFunc   ;==>WM_MENUSELECT

Func _UpdateMenuClock($hWnd, $msg, $iIDTimer, $dwTime)
	ConsoleWrite("test" & @CRLF)
	#forceref $hWnd, $Msg, $iIDTimer, $dwTime
	If Not $oRegisteredMenuClock.Exists(String($hWnd)) Then Return
	Local $strItem, $aSplit
	Local $colItems = $oRegisteredMenuClock.Items
	For $strItem In $colItems
		$aSplit = StringSplit($strItem, "|", 2)
		Local $hMenu = _GUICtrlMenu_GetMenu(HWnd($aSplit[0]))
		_GUICtrlMenu_SetItemText($hMenu, Number($aSplit[2]), StringFormat("%02d:%02d:%02d", @HOUR, @MIN, @SEC), False)
		_GUICtrlMenu_DrawMenuBar(HWnd($aSplit[0]))
	Next
EndFunc   ;==>_UpdateMenuClock

Func _UpdateStatusBarClock($hWnd, $msg, $iIDTimer, $dwTime)
	#forceref $hWnd, $Msg, $iIDTimer, $dwTime
	If Not $oRegisteredStatusClock.Exists(String($hWnd)) Then Return
	Local $strItem, $aSplit
	Local $colItems = $oRegisteredStatusClock.Items
	For $strItem In $colItems
		$aSplit = StringSplit($strItem, "|", 2)
		If $iShowMenuText = True Then Return
		_GUICtrlStatusBar_SetText(HWnd($aSplit[0]), StringFormat("%02d:%02d:%02d", @HOUR, @MIN, @SEC), $aSplit[2] - 1)
	Next
EndFunc   ;==>_UpdateStatusBarClock
