![]() |
Text in ein DBRichEdit einfügen per SendMessage()
Hallo zusammen,
ich versuche nun schon länger einen Text per SendMessage() in ein DBRichEdit einzufügen. Das Handle habe ich und es ist auch korrekt. Es passiert aber nichts. Der DB-Navigator zeigt keinerlei Änderung und demzufolge steht im DBRichEdit auch nicht mein Text. Versucht habe ich einiges. U.a. das hier:
Delphi-Quellcode:
Mit Notepad z.B. funktioniert es.
s := 'Test, Test, Test';
FOR i := 1 TO Length( s ) DO SendMessage( my_HWnd, WM_CHAR, Word( s[i] ), 0 ); // Simulate Return Key. PostMessage( my_HWnd, WM_KEYDOWN, VK_RETURN, 0 ); // Simulate Space. PostMessage( my_HWnd, WM_KEYDOWN, VK_SPACE, 0 ); Hat jemand eine wertvollen Tipp für mich? Vielen Dank schon mal vorab! |
AW: Text in ein DBRichEdit einfügen per SendMessage()
Hallo,
ist das DataSet im EditMode? |
AW: Text in ein DBRichEdit einfügen per SendMessage()
Ja.
Ich weiß nicht ob es wichtig ist: es ist eine Fremdanwendung. |
AW: Text in ein DBRichEdit einfügen per SendMessage()
Eine Möglichkeit wäre noch
WM_PASTE |
AW: Text in ein DBRichEdit einfügen per SendMessage()
WM_COPYDATA
Aber keine gewähr ob die andere Anwendung diese Message behandelt. |
AW: Text in ein DBRichEdit einfügen per SendMessage()
Es liegt an der Fremdanwendung. Bei anderen Anwendungen funktioniert es. Da kann man wohl nichts machen.
|
AW: Text in ein DBRichEdit einfügen per SendMessage()
Hallo,
Zitat:
Zitat:
Klappt es denn über die Windows-Zwischenablage? Dann wäre das obige WM_PASTE eine Überlegung wert. Du kopierst deine Daten in die Zwischenablage und schickst dem Fenster ein WM_PASTE. |
AW: Text in ein DBRichEdit einfügen per SendMessage()
Gute Morgen,
über WinSpy kann ich sehen welches Control es ist. Allerdings ist es kein Standardcontrol von Delphi, sondern ein abgeleitetes Control von DBRichEdit. (die Fremdanwendung ist auch in Delphi geschrieben) Die Zwischenablage wollte ich nicht zerstören, da das Ganze recht häufig angewendet werden soll. Im Prinzip sollte es ein Ersatz für PhraseExpress werden. Also pro globalem Hotkey einen bestimmten Textbaustein am Mauscursor einfügen. |
AW: Text in ein DBRichEdit einfügen per SendMessage()
Notepad ist ein Memo. (Wordpad ist das RichEdit)
WM_KEYDOWN alleine: Wenn man eine Taste drückt, dann muß man sie auch wieder loslassen!!! WM_CHAR alleine reicht nicht immer aus. Eine Tastendruck besteht aus einem/mehreren WM_KEYDOWN, einem WM_CHAR und einem/mehreren WM_KEYUP. Rate mal, warum es mehrere Versuche von SndKey/SendKey/... gibt. Tipp: EM_REPLACESEL (TCustomComboBox.SetSelText) |
AW: Text in ein DBRichEdit einfügen per SendMessage()
Hmm...
Zitat:
wie in diesem Tread aus 2018: ![]() Das Testtool macht etwas ähnliches.. Es wartet auf einen (Hot-) Key und schickt einen Text als KeyEvent. Musst jetzt nur eigenen Keys definieren und statt des Memos von Dir vorgegebene Texte schicken. |
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 17:51 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