Seite 1 von 1

IDE - Send Message an Scintilla

Verfasst: 10.08.2011 19:13
von STARGÅTE
Tachchen,

ich möchte gerne meine Tools etwas aufbessernund wollte deswegen in das ScintillaGadget der IDE direkt einschreiben.
An die Adresse komme ich ja über die Umgebungsvariable, wenn ich es als Werkzeug starte.
Leider funktioniert aber das einfügen von Text nicht:

Code: Alles auswählen

*Address = Val(GetEnvironmentVariable("PB_TOOL_Scintilla"))
Global Text.s = "Hallo Welt!"
SendMessage_(*Address, #SCI_ADDTEXT, Len(Text), @Text)
Wenn ich dann das Werkzeug ausführe bekomme ich:
Bild

PS: Die Befehle scheinen richtig anzukommen (z.B. Funktioniert SCI_CLEARALL ohne Probleme), aber irgendwie ist der String immer leer.
Was mache ich Falsch? Kann PB vielleicht nicht auf den String von meinem Programm zugreifen?
Wenn das der fall wäre, wie könnte ich das zulassen?

Re: IDE - Send Message an Scintilla

Verfasst: 10.08.2011 19:22
von Danilo
STARGÅTE hat geschrieben:Leider funktioniert aber das einfügen von Text nicht:

Code: Alles auswählen

*Address = Val(GetEnvironmentVariable("PB_TOOL_Scintilla"))
Global Text.s = "Hallo Welt!"
SendMessage_(*Address, #SCI_ADDTEXT, Len(Text), @Text)
Wenn ich dann das Werkzeug ausführe bekomme ich:
Bild

PS: Die Befehle scheinen richtig anzukommen (z.B. Funktioniert SCI_CLEARALL ohne Probleme), aber irgendwie ist der String immer leer.
Was mache ich Falsch? Kann PB vielleicht nicht auf den String von meinem Programm zugreifen?
Wenn das der fall wäre, wie könnte ich das zulassen?
Sieht nach Unicode aus. Konvertier mal nach UTF8, siehe AddLine

Re: IDE - Send Message an Scintilla

Verfasst: 10.08.2011 19:23
von ts-soft

Code: Alles auswählen

Procedure GetSCI()
  ProcedureReturn Val(GetEnvironmentVariable("PB_TOOL_Scintilla"))
EndProcedure

Procedure GetProcessFromWindow(hwnd)
  Protected pid, result
 
  If GetWindowThreadProcessId_(hwnd, @pid)
    result = OpenProcess_(#PROCESS_ALL_ACCESS, #False, pid)
  EndIf
 
  ProcedureReturn result
EndProcedure

Procedure PasteText(buffer.s)
  Protected hProc, mem, bW, hsci, len
  
  hsci = GetSCI()
  hProc = GetProcessFromWindow(hsci)
 
  If hProc
   
    len = Len(buffer)
    mem = VirtualAllocEx_(hProc, 0, len, #MEM_RESERVE | #MEM_COMMIT, #PAGE_EXECUTE_READWRITE)
   
    If mem
      WriteProcessMemory_(hProc, mem, @buffer, len, @bW)
      SendMessage_(hsci, #SCI_ADDTEXT, len, mem)
      VirtualFreeEx_(hProc, mem, len, #MEM_RELEASE)
    EndIf
   
    CloseHandle_(hProc)
  EndIf
 
EndProcedure

Re: IDE - Send Message an Scintilla

Verfasst: 10.08.2011 19:52
von STARGÅTE
Erst mal danke, aber ich musste den Code noch anpassen:

Der zu sendende String muss erst in einen Zwischenpuffer geschrieben werden,
damit man einerseits das Tool als Ascii oder Unicode kompilieren kann und
andererseits der Editor entweder in UTF8 oder Ascii sein kann.
Dazu lese ich vorher noch das #SCI_GETCODEPAGE aus:

Code: Alles auswählen

Procedure GetProcessFromWindow(WindowID.i)
	Protected ProcessID.i
	If GetWindowThreadProcessId_(WindowID, @ProcessID)
		ProcedureReturn OpenProcess_(#PROCESS_ALL_ACCESS, #False, ProcessID)
	EndIf
EndProcedure

Procedure SendText(Text.s)
	Protected ScintillaID.i = Val(GetEnvironmentVariable("PB_TOOL_Scintilla"))
	Protected ProcessID.i = GetProcessFromWindow(ScintillaID)
	Protected Length.i
	Protected *MemoryID, *Buffer, Format.i
	If ProcessID
		Select SendMessage_(ScintillaID, #SCI_GETCODEPAGE, #Null, #Null)
			Case 0     : Format = #PB_Ascii
			Case 65001 : Format = #PB_UTF8
		EndSelect
		Length.i = StringByteLength(Text, Format)
		*Buffer = AllocateMemory(Length+SizeOf(Character))
		If *Buffer
			PokeS(*Buffer, Text, #PB_Default, Format)
			*MemoryID = VirtualAllocEx_(ProcessID, #Null, Length, #MEM_RESERVE|#MEM_COMMIT, #PAGE_EXECUTE_READWRITE)
			If *MemoryID
				WriteProcessMemory_(ProcessID, *MemoryID, *Buffer, Length, #Null)
				SendMessage_(ScintillaID, #SCI_ADDTEXT, Length, *MemoryID)
				VirtualFreeEx_(ProcessID, *MemoryID, Length, #MEM_RELEASE)
			EndIf
			FreeMemory(*Buffer)
		EndIf
		CloseHandle_(ProcessID)
	EndIf
EndProcedure

SendText("Schöner Spaß")
Ist sicher auch für andere von Interesse :wink:

So nun gehts ans Werkzeuge schreiben ^^

Re: IDE - Send Message an Scintilla

Verfasst: 10.08.2011 19:58
von ts-soft
>> aber ich musste den Code noch anpassen:
Das war mir fast klar, aber da Danilos einwand direkt über meinem Posting ist, habe ich mir gedacht,
was ja auch hingehauen hat, das Du das selbst ergänzt :mrgreen:

Re: IDE - Send Message an Scintilla

Verfasst: 02.02.2013 12:11
von Josh
@ ts-soft + STARGÅTE
Muss mich wieder mal als Leichenschänder betätigen, aber laut MSDN muss bei VirtualFreeEx / MEM_RELEASE die Größe mit 0 angegeben werden.

@ STARGÅTE
Nach meiner Meinung ist der folgende Code nicht richtig:

Code: Alles auswählen

*Buffer = AllocateMemory(Length+SizeOf(Character))
Mit SizeOf holst du hier die Charactergröße von deinem Code, obwohl hier die Charaktergröße des Scintillagadgets benötigt würde.

Re: IDE - Send Message an Scintilla

Verfasst: 02.02.2013 13:28
von edel
Josh hat geschrieben: @ STARGÅTE
Nach meiner Meinung ist der folgende Code nicht richtig:

Code: Alles auswählen

*Buffer = AllocateMemory(Length+SizeOf(Character))
Mit SizeOf holst du hier die Charactergröße von deinem Code, obwohl hier die Charaktergröße des Scintillagadgets benötigt würde.
Nein, da es sich hier um Platz fuer die 0 handelt. Hat also nichts mit Scintilla zu tun.

Re: IDE - Send Message an Scintilla

Verfasst: 02.02.2013 13:38
von STARGÅTE
Genau, und das Format lese ich ja vorher über #SCI_GETCODEPAGE aus, und schreibe dann entweder mit #PB_UTF8 oder #PB_Ascii und PokeS() in den Speicher, und PokeS() macht am ende noch das #NUL-Zeichen.