﻿;-- TIME_STAMP   2019-01-23 21:29:09   v 0.1

#include-once
#include "SciTE_Constants.au3"
#include <WinAPIConv.au3>
#include <WinAPIConstants.au3>
#include <SendMessage.au3>

#cs  The actions understood by SciTE are:
askfilename: 								Return the name of the file being edited.
askproperty:<key> 							Return the value of a property.
close: 										Close the current file.
closing: 									Director is closing - SciTE closes if it was started by the director.
currentmacro:<string> 						Set the current macro to name.
cwd: 										Change the working directory.
enumproperties:dyn|local|user|base|embed 	Enumerate all the properties in the argument set.
exportashtml:<path> 						Save the document in HTML format as the indicated file.
exportasrtf:<path> 							Save the document in RTF format as the indicated file.
exportaspdf:<path> 							Save the document in PDF format as the indicated file.
exportaslatex:<path> 						Save the document in LaTeX format as the indicated file.
exportasxml:<path> 							Save the document in XML format as the indicated file.
extender:<command> 							Call the extension interface with the given command.
find:<string> 								Search for a string, select and show it.
goto:<lineNumber>[,<columnNumber>] 			Move caret to a particular line and make it visible.
											If there is a column number then select the word at that column number or move the caret there if no word is present.
identity:<hwndDirector> 					Sets the director window handle to which SciTE sends messages. The argument is in decimal.
insert:<value> 								Display the value in the editor pane replacing the selection.
loadsession:<path>	 						Load a session as given by the indicated file.
macrocommand:<command> 						Execute a macro command. See the SciTE source code for the syntax of the command argument.
macroenable:<enable> 						If enable, display menu commands in SciTE for recording and playing macros.
macrolist:<list> 							Display a list for the user to choose from.
menucommand:<cmd> 							Execute a menu command based on numeric ID.
open:<path> 								Open the indicated file.
output:<value> 								Display the value in the output pane replacing the selection.
property:<key>=<value> 						Set a property to a value.
quit: 										Shut down SciTE.
reloadproperties: 							Reload properties from files.
replaceall:<search>\000<replace> 			Replace all instances of he search string in the document with the replace string.
saveas:<path> 								Save the document as the indicated file.
savesession:<path> 							Save a session as given by the indicated file.
#ce  The actions understood by SciTE are:

Global $g_SciTECmd
GUIRegisterMsg(74, "MY_WM_COPYDATA")  ; $WM_COPYDATA = 74

;===============================================================================
; Function Name....: _GetCurrentTabNumber
; Description......: Gibt die Nummer des aktuell aktiven Tab im Editor zurück
; Parameter(s).....: keine
; Return Value(s)..: TabNumber
; Author(s)........: Bitnugger ( bitnugger@autoit.de )
;===============================================================================
Func _GetCurrentTabNumber()
	Local Const $TCM_GETCURSEL = 0x1300 + 11
	Local $hTab = ControlGetHandle(WinGetHandle('[ACTIVE]'), '', '[CLASS:SciTeTabCtrl; INSTANCE:1]')
	If IsHWnd($hTab) Then Return _SendMessage($hTab, $TCM_GETCURSEL)
EndFunc  ;==>_GetCurrentTabNumber

;===============================================================================
; Function Name....: _SetCurrentTabNumber
; Description......: Aktiviert den angegebenen Tab im Editor
; Parameter(s).....: TabNumber
; Return Value(s)..: none
; Author(s)........: Bitnugger ( bitnugger@autoit.de )
;===============================================================================
Func _SetCurrentTabNumber($iTabNumber)
	If $iTabNumber = _GetCurrentTabNumber() Then Return
	Local $aResult = DllCall("user32.dll", "int", "GetClassNameW", "hwnd", WinGetHandle('[ACTIVE]'), "wstr", "", "int", 4096)
	If Not @error And $aResult[2] = 'SciTEWindow' Then
		Send('!F' & $iTabNumber) ; Menü "Fenster", EN = !W' & $iTabNumber
		Sleep(500) ; Damit stellen wir sicher, dass die Message von SciTE verarbeitet wurde, bevor wir die Funktion verlassen!
	EndIf
EndFunc  ;==>_SetCurrentTabNumber

;===============================================================================
; Function Name....: _GetLineCount
; Description......: Gibt die Anzahl der Zeilen im aktiven Tab im Editor zurück
; Parameter(s).....: keine
; Return Value(s)..: LineCount
; Author(s)........: Bitnugger ( bitnugger@autoit.de )
;===============================================================================
Func _GetLineCount()
	Local Const $SCI_GETLINECOUNT = 2154
	Local $hActive = WinGetHandle('[ACTIVE]')
	Local $aResult = DllCall("user32.dll", "int", "GetClassNameW", "hwnd", $hActive, "wstr", "", "int", 4096)
	If Not @error And $aResult[2] = 'SciTEWindow' Then
		Local $hEditor = ControlGetHandle($hActive, '', '[CLASS:Scintilla; INSTANCE:1]')
		Return _SendMessage($hEditor, $SCI_GETLINECOUNT, 0, 0)
	EndIf
EndFunc  ;==>_GetLineCount

;===============================================================================
; Function Name....: _GetCurrentFile
; Description......: Gibt den Pfad der aktuell im Editor geöffneten Datei zurück
; Parameter(s).....: keine
; Return Value(s)..: Dateipfad
; Author(s)........: BugFix ( bugfix@autoit.de )
;===============================================================================
Func _GetCurrentFile()
	SendSciTE_Command("askfilename:", 1)
	Return StringReplace(StringTrimLeft(_WinAPI_MultiByteToWideChar(String($g_SciTECmd), 65001, $MB_PRECOMPOSED, True), StringInStr($g_SciTECmd, ':', 1, 1)), '\\', '\')
EndFunc  ;==>_GetCurrentFile

;===============================================================================
; Function Name....: _GetProperty
; Description......: Gibt den Wert für eine Property zurück
; Parameter(s).....: Property
; Return Value(s)..: Wert der Property
; Docu.............: http://www.scintilla.org/SciTEDoc.html od. "SciTE-Hilfe" --> "SciTE Documentation"
; Author(s)........: BugFix ( bugfix@autoit.de )
;===============================================================================
Func _GetProperty($_sProperty)
	SendSciTE_Command("askproperty:" & $_sProperty, 1)
;~ 	Return StringTrimLeft($g_SciTECmd, StringInStr($g_SciTECmd, ':', 1, 4))
	Return _WinAPI_MultiByteToWideChar(StringTrimLeft($g_SciTECmd, StringInStr($g_SciTECmd, ':', 1, 4)), 65001, $MB_PRECOMPOSED, True)
EndFunc  ;==>_GetProperty

;===============================================================================
; Function Name....: _CloseCurrentFile
; Description......: Schließt die aktuell offene Datei im Editor
; Parameter(s).....: keine
; Return Value(s)..: keine
; Author(s)........: BugFix ( bugfix@autoit.de )
;===============================================================================
Func _CloseCurrentFile()
	SendSciTE_Command("close:")
EndFunc  ;==>_CloseCurrentFile

;===============================================================================
; Function Name....: _FindString
; Description......: Sucht nach einem übergebenen String und selektiert ihn, wenn
; .................: gefunden (erstes Vorkommen)
; Parameter(s).....: Suchstring
; Return Value(s)..: keine
; Author(s)........: BugFix ( bugfix@autoit.de )
;===============================================================================
Func _FindString($_sString)
	SendSciTE_Command("find:" & _WinAPI_WideCharToMultiByte(String($_sString), 65001))
EndFunc  ;==>_FindString

;===============================================================================
; Function Name....: _GoToLineCol
; Description......: Setzt den Cursor auf die übergebene Zeilen und (optional)
; .................: Spaltenposition. Zeile: 1-basiert, Spalte: 0-basiert
; .................: Ist an dieser Position ein Wort, wird es selektiert
; Parameter(s).....: Zeile, optional Spalte
; Return Value(s)..: keine
; Author(s)........: BugFix ( bugfix@autoit.de )
;===============================================================================
Func _GoToLineCol($_iLine, $_iCol = -1)
	Local $iCol = ""
	If $_iCol > -1 Then $iCol = "," & $_iCol
	SendSciTE_Command("goto:" & $_iLine & $iCol)
EndFunc  ;==>_GoToLineCol

;===============================================================================
; Function Name....: _InsertValue
; Description......: Fügt an aktueller Cursorposition od. Selektion den übergebenen
; .................: wert ein
; Parameter(s).....: Einfügestring
; Return Value(s)..: keine
; Author(s)........: BugFix ( bugfix@autoit.de )
;===============================================================================
Func _InsertValue($_vValue)
	SendSciTE_Command("insert:" & _WinAPI_WideCharToMultiByte(String($_vValue), 65001))
EndFunc  ;==>_InsertValue

;===============================================================================
; Function Name....: _MenuCmd
; Description......: Führt einen Menübefehl aus
; Parameter(s).....: Command-ID
; Requirement(s)...: SciTE_Constants.au3
; Return Value(s)..: keine
; Docu.............: http://www.scintilla.org/CommandValues.html
; Author(s)........: BugFix ( bugfix@autoit.de )
;===============================================================================
Func _MenuCmd($_CmdID)
	SendSciTE_Command("menucommand:" & $_CmdID)
EndFunc  ;==>_MenuCmd

;===============================================================================
; Function Name....: _FileOpen
; Description......: Öffnet eine Datei im Editor
; Parameter(s).....: Dateipfad
; Return Value(s)..: keine
; Author(s)........: BugFix ( bugfix@autoit.de )
;===============================================================================
Func _FileOpen($_sPath)
	SendSciTE_Command("open:" & StringReplace(_WinAPI_WideCharToMultiByte($_sPath, 65001), '\', '\\'))
EndFunc  ;==>_FileOpen

;===============================================================================
; Function Name....: _OutputToConsole
; Description......: Gibt einen Wert in die Konsole aus
; Parameter(s).....: auszugebender Wert, Zeilenumbruch mit "\n", Tab mit "\t"
; Return Value(s)..: keine
; Author(s)........: BugFix ( bugfix@autoit.de )
;===============================================================================
Func _OutputToConsole($_vValue)
	SendSciTE_Command("output:" & _WinAPI_WideCharToMultiByte(String($_vValue), 65001))
EndFunc  ;==>_OutputToConsole

;===============================================================================
; Function Name....: _SetProperty
; Description......: Setzt den Wert einer Property
; Parameter(s).....: Property und Wert
; Return Value(s)..: keine
; Author(s)........: BugFix ( bugfix@autoit.de )
;===============================================================================
Func _SetProperty($_sProperty, $_sValue)
	SendSciTE_Command("property:" & $_sProperty & "=" & _WinAPI_WideCharToMultiByte(StringReplace($_sValue, '\', '\\'), 65001))
EndFunc  ;==>_SetProperty

;===============================================================================
; Function Name....: _ReloadProperties
; Description......: Lädt die Properties neu
; Parameter(s).....: keine
; Return Value(s)..: keine
; Author(s)........: BugFix ( bugfix@autoit.de )
;===============================================================================
Func _ReloadProperties()
	SendSciTE_Command("reloadproperties:")
EndFunc  ;==>_ReloadProperties

;===============================================================================
; Function Name....: _ReplaceAll
; Description......: Ersetzt alle Vorkommen eines Suchbegriffs
; Parameter(s).....: Suchwort und Ersetzung
; Return Value(s)..: keine
; Author(s)........: BugFix ( bugfix@autoit.de )
;===============================================================================
Func _ReplaceAll($_sSearch, $_sReplace)
	SendSciTE_Command(_WinAPI_WideCharToMultiByte(String("replaceall:" & $_sSearch & "\000" & $_sReplace), 65001))
EndFunc  ;==>_ReplaceAll

;===============================================================================
; Function Name....: _FileSaveAs
; Description......: Datei unter angegebenem Pfad speichern
; Parameter(s).....: Dateipfad
; Return Value(s)..: keine
; Author(s)........: BugFix ( bugfix@autoit.de )
;===============================================================================
Func _FileSaveAs($_sPath)
	SendSciTE_Command("saveas:" & _WinAPI_WideCharToMultiByte(StringReplace($_sPath, '\', '\\'), 65001))
EndFunc  ;==>_FileSaveAs

; by BugFix
Func _GetHwndDirectorExtension()
	Local $hActive = WinGetHandle('[ACTIVE]')
	Local $PIDActive = WinGetProcess($hActive)
	Local $aExtension = WinList("DirectorExtension")
	Local $PIDExt
	For $i = 1 To $aExtension[0][0]
		$PIDExt = WinGetProcess($aExtension[$i][1])
		If $PIDExt = $PIDActive Then Return $aExtension[$i][1]
	Next
EndFunc  ;==>_GetHwndDirectorExtension

; by Jos
Func SendSciTE_Command($_sCmd, $Wait_For_Return_Info = 0)
	Local Static $My_Hwnd = GUICreate("AutoIt3-SciTE interface") ; Create GUI to receive SciTE info
	Local Static $My_Dec_Hwnd = Dec(StringTrimLeft($My_Hwnd, 2)) ; Convert my Gui Handle to decimal
	Local Const $SCI_GETLINE      = 0x0869 ;  2153
	Local Const $WM_COPYDATA      = 0x004A ;    74
	Local Const $WM_GETTEXT       = 0x000D ;    13
	Local Const $WM_GETTEXTLENGTH = 0xE224 ; 57892
;~ 	Local $Scite_hwnd = WinGetHandle("DirectorExtension") ; Get SciTE DIrector Handle
	Local $Scite_hwnd = _GetHwndDirectorExtension() ; Get SciTE DIrector Handle
	$_sCmd = ":" & $My_Dec_Hwnd & ":" & $_sCmd              ; Add dec my gui handle to commandline to tell SciTE where to send the return info
	Local $CmdStruct = DllStructCreate('CHAR[' & StringLen($_sCmd) + 1 & ']')
	DllStructSetData($CmdStruct, 1, $_sCmd)
	Local $COPYDATA = DllStructCreate('ULONG_PTR;DWORD;PTR')
	DllStructSetData($COPYDATA, 1, 1)
	DllStructSetData($COPYDATA, 2, StringLen($_sCmd) + 1)
	DllStructSetData($COPYDATA, 3, DllStructGetPtr($CmdStruct))
	$g_SciTECmd = ""
	DllCall('User32.dll', 'None', 'SendMessage', _
			'HWnd', $Scite_hwnd, _
			'Int', $WM_COPYDATA, _
			'HWnd', $My_Hwnd, _
			'Ptr', DllStructGetPtr($COPYDATA))
;~ 	GUIDelete($My_Hwnd)
	If $Wait_For_Return_Info Then
		For $x = 1 To 10
			If $g_SciTECmd <> "" Then ExitLoop
			Sleep(20)
		Next
		$g_SciTECmd = StringTrimLeft($g_SciTECmd, StringLen(":" & $My_Dec_Hwnd & ":"))
		$g_SciTECmd = StringReplace($g_SciTECmd, "macro:stringinfo:", "")
		Return $g_SciTECmd
	EndIf
EndFunc  ;==>SendSciTE_Command

;~ https://docs.microsoft.com/en-us/windows/desktop/api/Winuser/ns-winuser-tagcopydatastruct
;~ typedef struct tagCOPYDATASTRUCT {
;~   ULONG_PTR dwData; --> ULONG_PTR
;~   DWORD     cbData; --> DWORD
;~   PVOID     lpData; --> PTR
;~ } COPYDATASTRUCT, *PCOPYDATASTRUCT;
Func MY_WM_COPYDATA($hWnd, $msg, $wParam, $lParam)
	Local $COPYDATA = DllStructCreate('ULONG_PTR;DWORD;PTR', $lParam)
	Local $SciTECmdLen = DllStructGetData($COPYDATA, 2)
	Local $CmdStruct = DllStructCreate('CHAR[255]', DllStructGetData($COPYDATA, 3))
	$g_SciTECmd = StringLeft(DllStructGetData($CmdStruct, 1), $SciTECmdLen)
EndFunc  ;==>MY_WM_COPYDATA

