;-- TIME_STAMP   2020-09-10 06:22:31   v 0.1

Opt('MustDeclareVars', 1)

#include <GUIConstantsEx.au3>  ; $GUI_EVENT_CLOSE
#include <Array.au3>           ; _ArraySearch, _ArrayAdd
#include <Date.au3>            ; _NowCalc, _Date_Time_GetTickCount
#include <GuiEdit.au3>         ; _GUICtrlEdit_AppendText
#include <String.au3>          ; _StringRepeat
#include <WinAPIConv.au3>      ; _WinAPI_HashString
#include <WinAPISys.au3>       ; _WinAPI_ComputeCrc32, _WinAPI_GetClassName
;~ #include <WinAPISysWin.au3> ; _WinAPI_GetClassName
#include <Crypt.au3>           ; _Crypt_HashData, _Crypt_HashFile, _Crypt_*

Global Const $g_aAlgIDs = [[$CALG_MD2, '$CALG_MD2 (128bit)'], [$CALG_MD4, '$CALG_MD4 (128bit)'], [$CALG_MD5, '$CALG_MD5 (128bit)'], [$CALG_SHA1, '$CALG_SHA1 (160bit)'], [$CALG_SHA_256, '$CALG_SHA_256'], [$CALG_SHA_384, '$CALG_SHA_384'], [$CALG_SHA_512, '$CALG_SHA_512']]

Global Enum $eString = 1, $eFile

Global $g_hGUI, $g_idEdit, $g_hEdit, $g_sClassName = 'AutoIt v3 GUI', $g_Hash, $g_sSpacer = _StringRepeat('-', 194)

_Crypt_Startup() ; To optimize performance start the crypt library.
OnAutoItExitRegister('_Exit')

Example1() ; Hash and _WinGetHandle

Func Example1()
	$g_hGUI = GUICreate('')
	GUISetFont(11, 800, 0, 'Courier New')
;~ 	$g_sClassName = _WinAPI_GetClassName($g_hGUI)
	GUISetState(@SW_SHOWMAXIMIZED, $g_hGUI)
	Local $aClientSize = WinGetClientSize($g_hGUI)
	$g_idEdit = GUICtrlCreateEdit('', 0, 0, $aClientSize[0], $aClientSize[1])
	GUIctrlSetBkColor(-1, 0x318CE7)
	GUIctrlSetColor(-1, 0xEEE9D5)
	$g_hEdit = GUICtrlGetHandle(-1)
	_Memo($g_sSpacer & @CRLF & '! Example1()' & @CRLF & $g_sSpacer & @CRLF & @CRLF)
	_Memo('! $g_hGUI       = ' & $g_hGUI & @CRLF)
	_Memo('! $g_sClassName = ' & $g_sClassName & @CRLF & @CRLF)

	$g_Hash = _GetCrc32(@ScriptFullPath) ; or @ScriptName, or "Any string of characters"
	_SetWinTitle()
	_WinGetHandle('.+' & $g_Hash, $g_sClassName, 1)
	$g_Hash = _GetCrc32(@ScriptFullPath, $eFile)
	_SetWinTitle()
	_WinGetHandle('.+' & $g_Hash, $g_sClassName, 1)

	_Memo(@CRLF)

	$g_Hash = _GetHashString(@ScriptFullPath) ; or @ScriptName, or "Any string of characters"
	_SetWinTitle()
	_WinGetHandle('.+' & $g_Hash, $g_sClassName, 1)
	$g_Hash = _GetHashString(@ScriptFullPath, $eFile)
	_SetWinTitle()
	_WinGetHandle('.+' & $g_Hash, $g_sClassName, 1)

	_Memo(@CRLF)

	For $i = 0 To UBound($g_aAlgIDs) - 1 Step 1
		$g_Hash = _GetHashData(@ScriptFullPath, $g_aAlgIDs[$i][0])
		If @error Then Exit @error
		_SetWinTitle()
		_WinGetHandle('.+' & $g_Hash, $g_sClassName, 1)
	Next

	_Memo(@CRLF)

	For $i = 0 To UBound($g_aAlgIDs) - 1 Step 1
		$g_Hash = _GetHashFile(@ScriptFullPath, $g_aAlgIDs[$i][0])
		If @error Then Exit @error
		_SetWinTitle()
		_WinGetHandle('.+' & $g_Hash, $g_sClassName, 1)
	Next

	_Memo(@CRLF & $g_sSpacer & @CRLF & '! Press ESC to EXIT' & @CRLF & $g_sSpacer & @CRLF & @CRLF)

	Do
		_SetWinTitle()
	Until GUIGetMsg() = $GUI_EVENT_CLOSE
	GUIDelete($g_hGUI)
EndFunc   ;==>Example1

Func _GetCrc32($sString, $iType = $eString)
	Local $sType = $iType = $eString ? '$eString' : $iType = $eFile ? '$eFile' : 'Undefined $iType!'
	_Memo('> _GetCrc32("' & $sString & '", ' & $sType & ')' & @CRLF)
	$sString = _GetType($sString, $iType)
	If @error Then Return SetError(1, 0, '')
	Local $iLength = StringLen($sString), $tCrc32 = DllStructCreate('char Crc32[' & $iLength & ']')
	If @error Then Return SetError(2, 0, '')
	DllStructSetData($tCrc32, 'Crc32', $sString)
	Local $pMemory = DllStructGetPtr($tCrc32)
	Local $iCrc32 = _WinAPI_ComputeCrc32($pMemory, $iLength)
	_Memo('- $iCrc32        = ' & $iCrc32 & @CRLF)
	Return $iCrc32 ? $iCrc32 : SetError(3, 0, '')
EndFunc   ;==>_GetCrc32

;~ _WinAPI_HashString($sString)
Func _GetHashString($sString, $iType = $eString)
	Local $sType = $iType = $eString ? '$eString' : $iType = $eFile ? '$eFile' : 'Undefined $iType!'
	_Memo('> _GetHashString("' & $sString & '", ' & $sType & ')' & @CRLF)
	$sString = _GetType($sString, $iType)
	If @error Then Return SetError(1, 0, '')
	Local $bHashString = _WinAPI_HashString($sString)
	_Memo('- $bHashString   = ' & $bHashString & @CRLF)
	Return $bHashString ? $bHashString : SetError(2, 0, '')
EndFunc   ;==>_GetHashString

;~ _Crypt_HashData ( $vData, $iAlgID [, $bFinal = True [, $hCryptHash = 0]] )
Func _GetHashData($vData, $iAlgID = $CALG_MD2)
	Local $iIndex = _ArraySearch($g_aAlgIDs, $iAlgID)
	_Memo('> _GetHashData("' & $vData & '", 0x' & Hex($iAlgID) & ') ; ' & ($iIndex = -1 ? 'No Hashing algorithm!' : $g_aAlgIDs[$iIndex][1]) & @CRLF)
	If $vData = '' Then Return SetError(1, 0, '')
	If $iIndex = -1 Then Return SetError(2, 0, '')
	Local $bHashData = _Crypt_HashData($vData, $iAlgID), $iError = @error
	_Memo('- $bHashData     = ' & $bHashData & @CRLF)
	Return $iError ? SetError($iError, 0, '') : $bHashData
EndFunc   ;==>_GetHashData

;~ _Crypt_HashFile ( $sFilePath, $iAlgID )
Func _GetHashFile($sFilePath, $iAlgID = $CALG_MD2)
	Local $iIndex = _ArraySearch($g_aAlgIDs, $iAlgID)
	_Memo('> _GetHashFile("' & $sFilePath & '", 0x' & Hex($iAlgID) & ') ; ' & ($iIndex = -1 ? 'No Hashing algorithm!' : $g_aAlgIDs[$iIndex][1]) & @CRLF)
	If $iIndex = -1 Then Return SetError(2)
	Local $bHashFile = _Crypt_HashFile($sFilePath, $iAlgID), $iError = @error
	_Memo('- $bHashFile  = ' & $bHashFile & @CRLF)
	Return $iError ? SetError($iError, 0, '') : $bHashFile
EndFunc   ;==>_GetHashFile

Func _GetType($sString, $iType)
	If $sString = '' Then Return SetError(1, 0, '')
	Switch $iType
		Case $eString
			Return $sString
		Case $eFile
			Return FileExists($sString) ? FileRead($sString) : SetError(2, 0, '')
		Case Else
			Return SetError(3, 0, '')
	EndSwitch
EndFunc   ;==>_GetType

Func _SetWinTitle()
	Local $sTitle = @ScriptName & ' ' & _NowCalc() & ' TickCount:' & _Date_Time_GetTickCount() & ' ' & $g_Hash
;~ 	_Memo('> WinSetTitle(' & $g_hGUI & ', "", "' & $sTitle & '")' & @CRLF)
	WinSetTitle($g_hGUI, '', $sTitle)
	Return $sTitle
EndFunc

; Total Commander Ultima Prime: ' Total Commander Ultima Prime 7.3 :: CPU: 022% (3,2 GHz) :: RAM: 078% (6,0 GB) :: C: 50% :: 09.09.2020 - 02:46:22 :: 03:07:43 ::'    <<== 1. Instanz
; Total Commander Ultima Prime: '[2] Total Commander Ultima Prime 7.3 :: CPU: 022% (3,2 GHz) :: RAM: 078% (6,0 GB) :: C: 50% :: 09.09.2020 - 02:46:22 :: 03:07:43 ::' <<== 2. Instanz
; Notepad++                   : 'F:\Eigene Dateien\TxT\ToDo.txt - Notepad++'
; SciTE                       : 'C:\Program Files (x86)\AutoIt3\Include\Misc.au3 - SciTE [20 von 20]'

;~ _WinGetHandle('^(\[\d+\])? Total Commander Ultima Prime.*', 'TTOTAL_CMD', 1) ; Titel beginnt bei der ersten Instanz mit einem Leerzeichen, bei weiteren mit '[n] '!
;~ _WinGetHandle('^(\[\d+\])? Total Commander Ultima Prime.*', 'TTOTAL_CMD')
;~ _WinGetHandle('.+( - Notepad++)', 'Notepad++')
;~ _WinGetHandle('.+( - SciTE).*', 'SciTEWindow')
;~ _WinGetHandle('.+( - SciTE).*', 'SciTE Window') ; Fehler, weil $sClassName falsch
;~ _WinGetHandle('.+( - SciTE).*')

Func _WinGetHandle($sTitle, $sClassName = '', $iInstance = -1) ; -1 = alle suchen (Array, wenn mehr als 1 Treffer), 1 = nur zuletzt aktives
	Local $sPattern, $hWnd, $aWnd[0], $sFullTitle, $iLoop = $iInstance

	_Memo('> _WinGetHandle("' & $sTitle & '", "' & $sClassName & '", ' & $iInstance & ')' & @CRLF)
	If $iInstance < 1 Then $iInstance = 1

	While 1
		$sPattern = '[REGEXPTITLE:' & $sTitle & ($sClassName ? '; CLASS:' & $sClassName : '') & '; INSTANCE:' & $iInstance & ']'
		_Memo('+ $sPattern   = ' & $sPattern & @CRLF)
		$hWnd = WinGetHandle($sPattern)
		_Memo((IsHWnd($hWnd) ? '- ' : '! ') & '$hWnd       = ' & $hWnd & @CRLF)
		If Not IsHWnd($hWnd) Then ExitLoop
		_ArrayAdd($aWnd, $hWnd)
		If $sClassName = '' Then $sClassName = _WinAPI_GetClassName($hWnd)
		_Memo('- $sClassName = ' & $sClassName & @CRLF)
		Local $sFullTitle = WinGetTitle($hWnd)
		_Memo('- $sFullTitle = ' & $sFullTitle & @CRLF)
		If $iLoop > 0 Then ExitLoop
		$iInstance += 1
	WEnd
	_Memo($g_sSpacer & @CRLF & @CRLF)
	If UBound($aWnd) > 1 Then _ArrayDisplay($aWnd, '$aWnd', '', 0, Default, $sClassName)
	Return UBound($aWnd) > 1 ? $aWnd : IsHWnd($hWnd) ? $hWnd : SetError(1, 0, '')
EndFunc   ;==>_WinGetHandle

Func _Memo($sText)
	If IsHWnd($g_hEdit) Then _GUICtrlEdit_AppendText($g_hEdit, $sText)
EndFunc

Func _Exit()
	_Crypt_Shutdown() ; Shutdown the crypt library.
EndFunc
