![]() |
AW: Text in ein DBRichEdit einfügen per SendMessage()
Liste der Anhänge anzeigen (Anzahl: 1)
Hallo Holger,
vielen Dank, lieb gemeint. U. a. hatte ich es auch so probiert wie in deinem Source. Aber es funktioniert einfach nicht. Es muss an der Fremd-Anwendung liegen. Ich habe zig Varianten durch probiert und es klappt einfach nicht. Mit anderen Anwendungen hatte ich kein Problem. Das Handle ist auch immer korrekt, das DBRichEdit ist im Editmodus, es wird aber kein Text übernommen. WinSpy zeigt mir auch an, dass es wohl eine Midi-Anwendung ist. Ob es damit was zu tun haben könnte? Ich bin da echt ratlos. Lt. Debugger wird alles korrekt ausgeführt. @himitsu, leider war mein Code-Ausschnitt unvollständig. Ich hatte das alles ausprobiert, auch mit WM_KEYUP. In Zukunft muss ich da etwas genauer den Code-Ausschnitt aufbereiten. Was meintest du mit Zitat:
|
AW: Text in ein DBRichEdit einfügen per SendMessage()
Wie gesagt, siehe
![]() ![]() oder eben ![]()
Delphi-Quellcode:
.
RichEdit.SelText := '...';
Hat das Programm, bzw. das RichEdit den Eingabefocus? |
AW: Text in ein DBRichEdit einfügen per SendMessage()
@himitsu,
dank dir für deine Mühe! Ich habe deine Tipps auch probiert, aber selbes Ergebnis: Die Showmessage wird aufgerufen und zeigt das richtige Handle an, aber im DBRichEdit der Fremdanwendung passiert absolut nichts. Das DBRichEdit im Fremdprogramm hat immer den Fokus (Cursor blinkt im DBRichEdit), jeweils einmal im Editiermodus getestet und einmal ohne. Wie kann ich denn in einem Fremdprogramm Zitat:
Hier mal einer meiner Tests:
Delphi-Quellcode:
PROCEDURE Tfrm_Main.WMHotKey( VAR Msg: TWMHotKey );
VAR s: STRING; copyDataStruct: TCopyDataStruct; BEGIN gc_my_DBRichEdit_Handle := Handle_DBRichEdit_ermitteln { Return Handle-ID }; TRY IF ( Msg.HotKey = Hotkey_id ) AND ( gc_my_DBRichEdit_Handle > 0 ) THEN BEGIN s := 'Das ist ein Test'; copyDataStruct.cbData := 1 + ( Length( s ) * SizeOf( Char ) ); // !!! copyDataStruct.lpData := PChar( s ); Keybd_Event( VK_RETURN, 0, 0, 0 ); // Taste drücken Keybd_Event( VK_RETURN, 0, KEYEVENTF_KEYUP, 0 ); // Taste loslassen SendMessage( gc_my_DBRichEdit_Handle, EM_REPLACESEL, 0, LPARAM( @copyDataStruct ) ); Sleep( 2000 ); ShowMessage( s + ' Handle-ID=' + IntToStr( gc_my_DBRichEdit_Handle ) ); END; FINALLY // gc_my_DBRichEdit_Handle := 0; { TODO 2 -oJS -cnoch zu erledigen : Nach den Tests ist das zu aktivieren, damit die Variable nach jedem Aufruf auch initialisiert ist } END; END; |
AW: Text in ein DBRichEdit einfügen per SendMessage()
Ein CopyDataStruct für was Anderes verwenden zu wollen, als für WM_COPYDATA ... naja :zwinker:
Hier bissl Was zum Abgucken und Ideenholen:
Delphi-Quellcode:
Und natürlich auch beim Hersteller nachzulesen.
procedure TCustomEdit.SetSelTextBuf(Buffer: PChar);
begin SendMessage(Handle, EM_REPLACESEL, 0, LPARAM(Buffer)); end; // oder besser procedure TCustomEdit.DoSetTextHint(const Value: string); begin ... SendTextMessage(Handle, EM_SETCUEBANNER, 0, Value); end; ![]() ![]() PS, auch wenn es hier keine Lösung werden wird: Selbst wenn es so funktioniert hätte, dann wäre aber die Größe dennoch falsch geworden. Zitat:
Erst (Length+1) und dann das *. |
AW: Text in ein DBRichEdit einfügen per SendMessage()
@himitsu,
danke für die Hinweise. Es hilft alles nichts, noch nie hat das DBRichEdit aus der Fremdanwendung überhaupt mal reagiert. Es scheint keine Messages von "außen" anzunehmen. Da bin ich mir ziemlich sicher. Da kann man wohl nichts machen. Was als Q&D ginge, wäre den Text über Clipboard einzufügen, das funktioniert. Aber das will ich nicht. Ich mach da jetzt nichts mehr. Gute N8! :dp: |
AW: Text in ein DBRichEdit einfügen per SendMessage()
Hallo zusammen,
also, ich weiß inzwischen, dass es nicht so einfach ist einen Text an ein RichEdit zu senden. Ich taste mich nun so langsam ran, erst mal mit dem RichEdit von WordPad. Das Handle zu ermitteln wenn Wordpad im Vordergrund ist, ist kein Problem. Ich habe folgenden Source der prinzipiell einen Text an ein RichEdit innerhalb meiner eigenen Anwendung sendet:
Delphi-Quellcode:
Ich weiß nun nicht, wie ich es hinbekomme, dass ich einen Text an ein RichEdit einer Fremd-Anwendung (Wordpad) gesendet bekomme. :oops:
// Source von Dr. Peter Below
TYPE TMyRichEdit = TRichEdit; TYPE TEditStreamCallBack = FUNCTION( dwCookie: Longint; pbBuff: PByte; cb: Longint; VAR pcb: Longint ): DWORD; STDCALL; TEditStream = RECORD dwCookie: Longint; dwError: Longint; pfnCallback: TEditStreamCallBack; END; FUNCTION EditStreamInCallback( dwCookie: Longint; pbBuff: PByte; cb: Longint; VAR pcb: Longint ): DWORD; STDCALL; VAR theStream: TStream; dataAvail: LongInt; BEGIN theStream := TStream( dwCookie ); WITH theStream DO BEGIN dataAvail := Size - Position; Result := 0; { assume everything is ok } IF dataAvail <= cb THEN BEGIN pcb := READ( pbBuff^, dataAvail ); IF pcb <> dataAvail THEN // couldn't read req. amount of bytes result := 0; // E_FAIL; END ELSE BEGIN pcb := READ( pbBuff^, cb ); IF pcb <> cb THEN result := 0; // E_FAIL; END; END; END; FUNCTION EditStreamOutCallback( dwCookie: Longint; pbBuff: PByte; cb: Longint; VAR pcb: Longint ): DWORD; STDCALL; VAR theStream: TStream; BEGIN theStream := TStream( dwCookie ); WITH theStream DO BEGIN IF cb > 0 THEN pcb := WRITE( pbBuff^, cb ); Result := 0; END; END; PROCEDURE GetRTFSelection( aRichEdit: TRichEdit; intoStream: TStream ); VAR editstream: TEditStream; BEGIN WITH editstream DO BEGIN dwCookie := Longint( intoStream ); dwError := 0; pfnCallback := EditStreamOutCallBack; END; aRichedit.Perform( EM_STREAMOUT, SF_RTF OR SFF_SELECTION, longint( @editstream ) ); END; PROCEDURE PutRTFSelection( aRichEdit: TRichEdit; sourceStream: TStream ); VAR editstream: TEditStream; BEGIN WITH editstream DO BEGIN dwCookie := Longint( sourceStream ); dwError := 0; pfnCallback := EditStreamInCallBack; END; aRichedit.Perform( EM_STREAMIN, SF_RTF OR SFF_SELECTION, longint( @editstream ) ); END; Die Frage ist, wie ich das Control in der Fremd-Anwendung ansprechen kann. Das was ich habe ist das Handle dieses Controls. Die Procedure PutRTFSelection erwartet ein RichEdit.
Delphi-Quellcode:
PROCEDURE Tfrm_Main.WMHotKey( VAR Msg: TWMHotKey );
VAR SS: TStringStream; FUNCTION WORDPAD_finden_TEST: THandle; VAR Len: LongInt; Title: STRING; Main_Wnd, wndChild: THandle; BEGIN Result := 0; Main_Wnd := GetForegroundWindow; IF Main_Wnd <> 0 THEN BEGIN Len := GetWindowTextLength( Main_Wnd ) + 1; SetLength( Title, Len ); GetWindowText( Main_Wnd, PChar( Title ), Len ); IF ( Pos( 'wordpad', LowerCase( Title ) ) > 0 ) THEN BEGIN IF Main_Wnd <> 0 THEN BEGIN wndChild := FindWindowEx( Main_Wnd, 0, 'RICHEDIT50W', NIL ); IF wndChild <> 0 THEN BEGIN Result := wndChild; END; END; END; END; END; BEGIN TRY gc_my_DBRichEdit_Handle := WORDPAD_finden_TEST; IF ( Msg.HotKey = Hotkey_id ) AND ( gc_my_DBRichEdit_Handle > 0 ) THEN BEGIN SS := TStringStream.Create ( '{\rtf1\ansi\ansicpg1252\deff0\deflang2055{\fonttbl{\f0\fswiss\fprq2\fcharset0 Arial;}{\f1\fnil MS Sans Serif;}}\viewkind4\uc1\pard\ul\b\f0\fs24 Test\ulnone\b0\f1\fs16\par}' ); TRY PutRTFSelection( RICHEDIT1, SS ); // <==== wie komme ich hier das Control von Wordpad angesprochen (RICHEDIT50W), anstelle meinem RichEdit1 FINALLY SS.Free; END; ShowMessage( 'Handle-ID=' + IntToStr( gc_my_DBRichEdit_Handle ) ); END; FINALLY // END; END; Vielen Dank für Hinweise! |
AW: Text in ein DBRichEdit einfügen per SendMessage()
Ich bin mir fast sicher, dass du EM_STREAMIN nur innerhalb deiner Anwendung nutzen darfst.
Um es an einen anderen Prozeess schicken zu können, müsstest du deinen Code von EditStreamInCallback/EditStreamOutCallback erst in diesen Prozess injizieren, denn was will das andere Programm mit einem Pointer für deinen Speicher, wenn es seinen eigenen Speicher hat und an jener Stelle nichts oder sonstwas liegen wird. Zitat:
UIntPtr oder NativeUInt bzw. IntPtr oder NativeInt Aber auch TEditStream, TEditStreamCallBack, EditStreamInCallback und EditStreamOutCallback sind falsch deklariert. DWORD_PTR -> ![]() Es gibt nur eine Message, welche "irgendeinen" Speicher selbstständig in den Zielprozess kopiert. (WM_COPYDATA) Zusätzlich machen das auch noch die bekannten Text-Messages ala WM_SETTEXT. Selbst wenn EM_STREAMIN/EM_STREAMOUT den Speicher von EDITSTREAM/TEditStream rüberkopiert, dann bleibt dennoch deine Funktion, und das von ihr Verwendete, bei dir. Hast mal geschaut, ob es eine Variante mit IStream gibt? (z.B. beim Clippboard gibt es Schnittstellen, welche damit auch prozesssübergreifend funktionieren) ![]() Zitat:
![]() |
Alle Zeitangaben in WEZ +1. Es ist jetzt 00:03 Uhr. |
Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024-2025 by Thomas Breitkreuz