Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Programmieren allgemein (https://www.delphipraxis.net/40-programmieren-allgemein/)
-   -   Delphi String via Sendmessage unvollständig (https://www.delphipraxis.net/186864-string-via-sendmessage-unvollstaendig.html)

Ajintaro 7. Okt 2015 17:25

String via Sendmessage unvollständig
 
Hallo DP,

ich nutze auf meiner Hauptanwendung idHttp und sende POST requests an einen Server. Obwohl ich idAntiFreeze benutze, friert die Anwendung regelmäßig ein, ganz besonders wenn die Internetverbindung etwas langsamer ist. Dadurch sind die anderen Funktionen der Anwendung kaum nutzbar und deshalb möchte ich den POST request eine andere Applikation erledigen lassen.

Dazu habe ich eine neue Formularanwendung erstellt, die
  1. über meine Hauptanwendung bei Bedarf gestartet wird und
  2. via Sendmessage mit der Hauptanwendung kommuniziert

Die Hauptanwendung muss lediglich die URL an die Sekundäranwendung übermitteln, damit diese den POST request absetzen kann. Sobald ein Ergebnis vorliegt, meldet die Sekundäranwendung den Status an die Hauptanwendung. Mein Problem ist, dass der String per SendMessage nicht mehr als 6 Zeichen verträgt:

Sender Code:
Delphi-Quellcode:
procedure TForm1.Button1Click(Sender: TObject);
  var DataStruct : CopyDataStruct;
begin
  DataStruct.dwData := 0;
  DataStruct.cbData := length(Edit1.Text)+1;
  DataStruct.lpData := pchar(Edit1.Text);

  SendMessage(FindWindow('TForm1', 'Recipient'),
                          WM_CopyData, Form1.handle, integer(@DataStruct));

end;
Empfänger Code:
Delphi-Quellcode:
    procedure CopyData(var Msg: TWMCopyData); message wm_CopyData;
:
procedure TForm1.CopyData(var Msg: TWmCopyData);
var sMsg: String;
begin
  if IsIconic(Application.Handle) then
    Application.Restore;
  sMsg := PChar(Msg.CopyDataStruct.lpData);
  lbMsg.Caption := sMsg;
end;
Leider sind die Ergebnisse alle unvollständig und es gibt unterschiedliche String-Längen. Hier ein paar Beispiele:
String 1234567890 wird zu 123456
String Edit1 wird zu Edi
String www.test.de wird zu www.te
String Delphipraxis wird zu Delphip

Habt ihr eine Ahnung warum das so ist?

hathor 7. Okt 2015 17:34

AW: String via Sendmessage unvollständig
 
The SendMessage returns an integer value assigned by the code that handled the WM_CopyData message.
http://delphi.about.com/od/windowssh...m_copydata.htm

Ausserdem: PChar: PANSICHAR, PWIDECHAR...???

Info:
http://michael-puff.de/Programmierun...COPYDATA.shtml

Captnemo 7. Okt 2015 17:40

AW: String via Sendmessage unvollständig
 
Probiert mal statt
Code:
  DataStruct.cbData := length(Edit1.Text)+1;
Code:
  DataStruct.cbData := SizeOf(Edit1.Text)+1;
Oder schau mal Hier

Sir Rufo 7. Okt 2015 17:40

AW: String via Sendmessage unvollständig
 
Ich habe schon mal keine Ahnung, warum du das in einer Sekundäranwendung auslagerst.

Delphi-Quellcode:
TIdAntiFreeze
ist Kindergarten. Dort wird nur ein
Delphi-Quellcode:
Application.ProcessMessages
ausgeführt, wenn ein Datenblock übertragen wurde. Darum verschlechtert sich auch das Verhalten bei einer langsamen Leitung.

Lagere den Versand in einen Thread aus und alles wird schön.

r.koch 7. Okt 2015 20:56

AW: String via Sendmessage unvollständig
 
Zwei voneinander unahängige VCL-Anwendungen lassen sich mit den jeweiligen Fremdkomponenten recht schnell zusammenklicken.

Danach schickt man von der einen Nachrichten an die andere, um die Andere fernzusteuern. Und von der Anderen schickt man Nachrichten zwecks Kontrolle zurück an die eine.

Wenn und falls das problemlos klappt, ist man sehr glücklich über seine beiden kommunizierenden VCL-Anwendungen!

Wie man aus den zwei VCL-Anwendungen nun nur noch eine mit Threads macht, sollte abhängig von der verwendeten Delphi-Version nicht ganz so trivial oder simpel sein, wenn die beiden VCL-Anwendungen bisher ihre Ausgaben auf dem Bildschirm darstellten.

Der ferngesteuerten Anwendung ihre Bildschirmausgaben wegzunehmen, um sie in einen Thread auszulagern, dürfte nicht ganz so einfach werden.

Insofern habe ich vollstes Verständnis für Sekundäranwendungen.

Welchen Vorteil hätte eigentlich ein Hauptprogramm mit zusätzlichem Thread, wenn der Thread abschmiert gegenüber zwei Programmen, die miteinander kommunizieren?

Sir Rufo 7. Okt 2015 21:13

AW: String via Sendmessage unvollständig
 
Zitat:

Zitat von r.koch (Beitrag 1317955)
Welchen Vorteil hätte eigentlich ein Hauptprogramm mit zusätzlichem Thread, wenn der Thread abschmiert gegenüber zwei Programmen, die miteinander kommunizieren?

Ähm, wir sprechen hier von einem simplen HTTP-Request der in einem Thread ausgeführt werden sollte. Was soll dir denn da um die Ohren fliegen?

Wenn schon paranoid, dann doch auch bitte konsequent und die Sekundäranwendung auf einem separaten Rechner (im klimageregelten Tresor) laufen lassen. Der Austausch der Daten dann per MSMQ/ActiveMQ (transaktionsbasiert) damit auch ja nichts verloren gehen kann. Und dann noch die Reset-Taste des Rechners mit der Sekundäranwendung an das Netzwerk(*) anschliessen - man kann ja nie sicher sein, dass der sich nicht festfrisst.

Gut, man fragt eigentlich nur ein paar Daten von einem Webserver ab ... also etwas, das jeden Tag von Millionen von Menschen mit einem Rechner und einer Anwendung tausendfach passiert ... aber man kann ja nicht vorsichtig (paranoid) genug sein ... :mrgreen:

(*) Um diesen Reset-Taster per Netzwerk anzusprechen, reicht ein simpler HTTP-Request aus ... ;)

Sir Rufo 7. Okt 2015 23:06

AW: String via Sendmessage unvollständig
 
Wenn der Server nicht erreichbar ist, dann bekommt man eine Exception und gut ist.

Davon schmiert weder die Anwendung noch der Thread ab. Die Exception geht einfach ihren kontrollierten Weg, den man auch noch beeinflussen kann.

Luckie 8. Okt 2015 00:48

AW: String via Sendmessage unvollständig
 
Bitte unterlasst es eure persönlichen Abneigungen hier öffentlich auszutragen.

Davon abgesehen halte ich einen zweiten Prozess für einen HTML Request auch für Overkill und unsinnig. Genau dafür sind Threads da, um Aufgaben im Hintergrund zu erledigen. Ein zweiter Prozess geht natürlich auch, aber da gestaltet sich die Interprozesskommunikation doch schon erheblich schwieriger. Ist der erste Prozess noch da? Kann er meine Nachricht empfangen oder ist er beschäftigt? Wie übermittele ich komplexe Daten? Bei einem Thread liegt alles im gleichen Prozessraum und ist einfach erreichbar. Und der "Auftraggeber" bestimmt wie was läuft.

Daniel 8. Okt 2015 06:18

AW: String via Sendmessage unvollständig
 
Ich habe hier die Antworten, die mich sprachlos machten, entfernt.
Das Grundproblem ist ja, dass die Anwendung einfriert, wenn die Daten zu langsam kommen. Die fachlich gängige Lösung sind hier nunmal Threads.

Zitat:

Aber er überfordert sehr oft meinen Pascal-Horizont mit seinen aktuellen XE/Seatle Vereinfachungen.
Das ist in Ordnung, wir haben diese Plattform, um voneinander und miteinander etwas lernen zu können. Wenn man eine Lösung nicht versteht, sollte man nachfragen und nicht schimpfen.

Neutral General 8. Okt 2015 07:54

AW: String via Sendmessage unvollständig
 
Ernsthaft? So viele Antworten und noch keiner konnte eine richtige und klare Antwort auf das hier zustande bringen? :roll:

Das Problem ist, dass in XE6 (genauer: Ab Delphi 2009) die Chars in deinen Strings 2 Byte groß sind und DataStruct.cbData die Anzahl der zu sendenden Bytes möchte und nicht die Anzahl der Zeichen.
Von daher:
Delphi-Quellcode:
DataStruct.cbData := Length(Edit1.Text)*SizeOf(Char);

Darum werden deine Strings auch ziemlich genau ab der Hälfte abgeschnitten.

Zitat:

Zitat von Captnemo (Beitrag 1317937)
Probiert mal statt
Code:
  DataStruct.cbData := length(Edit1.Text)+1;
Code:
  DataStruct.cbData := SizeOf(Edit1.Text)+1;

SizeOf(Edit1.Text) gibt immer SizeOf(String) = SizeOf(Pointer) zurück. Also 4 in 32-Bit und 8 in 64-Bit Anwendungen.

Ajintaro 8. Okt 2015 12:46

AW: String via Sendmessage unvollständig
 
Hallo DP,

:| ein Foren-thread voller Emotionen... ich hoffe ich habe mti meinem Beitrag niemanden provoziert.
Bezüglich der Kernfrage, wieso der übermittelte String abgeschnitten wird wurde ich auf die richtige Spur gebracht:
Folgender code übertragt den String korrekt:

Sender:
Delphi-Quellcode:
DataStruct.cbData := 1 + (Length(Fmain.edit4.Text) * SizeOf(Char));
DataStruct.lpData := PWideChar(Fmain.edit4.Text);
Empfänger:
Delphi-Quellcode:
sMsg := PWideChar(Msg.CopyDataStruct.lpData);

Natürlich wären threads die klar bessere Lösung. Ich habe auch zuerst versucht, eine thread-basierte Lösung zu schreiben. Allerdings muss ich zugeben, dass das über meinem aktuellen (Delphi) Know-How ist. Es gibt unzählige Beitrage und Beispiele zu diesem Thema, aber ich konnte bisher keinen funktionierenden Code zustande bringen der einen POST request thread basiert absetzt.

hathor 8. Okt 2015 15:58

AW: String via Sendmessage unvollständig
 
Inter-process communication (IPC)
In computing, Inter-process communication (IPC) is a set of techniques for the exchange of data among multiple threads in one or more processes. Processes may be running on one or more computers connected by a network. IPC techniques are divided into methods for message passing, synchronization, shared memory, and remote procedure calls (RPC). The method of IPC used may vary based on the bandwidth and latency of communication between the threads, and the type of data being communicated.
http://www.delphibasics.info/home/de...scommunication
.
IPC
Description Source Code: Source of program show how to create a component for communication between processes. Allows the exchange of information between the 32 and 64 bit processes, services, and isolated process (Low Level Integrity).
http://4coder.org/delphi-source-code/1009/

EWeiss 8. Okt 2015 16:25

AW: String via Sendmessage unvollständig
 
Zitat:

Die fachlich gängige Lösung sind hier nunmal Threads.
Wirklich?

Ich mache es über eine Callback.. da benötige ich keine Threads.

gruss

TBx 8. Okt 2015 16:31

AW: String via Sendmessage unvollständig
 
Zitat:

Zitat von hathor (Beitrag 1318063)
Inter-process communication (IPC)...
IPC...

Und was bitte soll uns nun diese lieblos dahingeworfene Linksammlung sagen?

Daniel 8. Okt 2015 16:40

AW: String via Sendmessage unvollständig
 
Zitat:

Zitat von EWeiss (Beitrag 1318067)
Zitat:

Die fachlich gängige Lösung sind hier nunmal Threads.
Wirklich?
Ich mache es über eine Callback.. da benötige ich keine Threads.
gruss

Es gibt ganz viele Wege nach Rom. Und jeder soll die Lösung wählen, die ihn glücklich macht.
Eines der im ersten Beitrag genannten Probleme war eben das Einfrieren der Anwendung, wenn das Internet mal wieder ein wenig braucht. Und da hilft allein ein Callback ja auch nicht, solange der bremsende Request im Main-Thread läuft.

EWeiss 8. Okt 2015 16:58

AW: String via Sendmessage unvollständig
 
Zitat:

Es gibt ganz viele Wege nach Rom.
Würde eher nach RIO plädieren. :lol:

Zitat:

Es gibt ganz viele Wege nach Rom. Und jeder soll die Lösung wählen, die ihn glücklich macht.
Richtig. ;)
Deshalb habe ich auch meine Herangehensweise mitgeteilt.
Aber gut wie du sagst jeder wie er will.

gruss

Daniel 8. Okt 2015 17:02

AW: String via Sendmessage unvollständig
 
Aber es würde mich interessieren, wie Du das Einfrieren des Main-Threads verhinderst (sei es in Rom oder Rio).

Ajintaro 9. Okt 2015 12:36

AW: String via Sendmessage unvollständig
 
Zitat:

Zitat von TBx (Beitrag 1318068)
Zitat:

Zitat von hathor (Beitrag 1318063)
Inter-process communication (IPC)...
IPC...

Und was bitte soll uns nun diese lieblos dahingeworfene Linksammlung sagen?

Hallo nochmal,

das Problem der String Übertragung wurde wie gesagt gelöst, wobei das Einfrieren auch die Sekundäranwendung betrifft im Fall von SendMessage.
Dieser Artikel war dabei sehr hilfreich: Windows Messages Tutorial

Ich habe mir das IPC Beispiel mal angesehen und es würde all meine Probleme lösen, ich habe nur Schwierigkeiten es komplett zu verstehen. Ich bin euch für eure Unterstützung sehr dankbar!

Habt alle ein schönes Wochenende!

BUG 9. Okt 2015 12:58

AW: String via Sendmessage unvollständig
 
Zitat:

Zitat von Daniel (Beitrag 1318073)
Aber es würde mich interessieren, wie Du das Einfrieren des Main-Threads verhinderst (sei es in Rom oder Rio).

Mit einem Event-getriebenen/asynchronem Programmierstil kann man auch ohne Threads "reaktive" Anwendungenen schreiben und das Verhungern der Benutzeroberfläche verhindern. Dafür würde man alle Aufgaben in kleine Happen zerteilen und nur asynchrone Systemcalls machen. Der oft zitierte IdleWorker ist afaik ein Schritt in diese Richtung.

Das ordentlich hinzugekommen ist aber nicht wirklich einfacher als Threads zu benutzen :wink:

mkinzler 9. Okt 2015 13:14

AW: String via Sendmessage unvollständig
 
Statt eines Autos kann man auch eine Porsche nehmen. :mrgreen:

Daniel 9. Okt 2015 13:27

AW: String via Sendmessage unvollständig
 
Aber ist ein HTTP-Request, der z.B. 2 oder 3 Sekunden lang braucht, nicht ein Monolith?

BUG 9. Okt 2015 13:46

AW: String via Sendmessage unvollständig
 
Nonblocking/overlapping/asynchrone Socket-Operationen sind die Lösung. Wie genau das mit der WinAPI geht, habe ich noch nicht ganz durchschaut*; aber die Socket-Doku macht deutlich dass das unterstützt wird.
Im Prinzip würde man immer das in einen Puffer lesen was gerade da ist und dann später noch mal nachgucken (Busy Waiting, vielleicht kann man sich das auch irgendwie signalisieren lassen).

* zu viel Arbeit nur für den Spaß, wenn man sonst mit *nix arbeitet

Daniel 9. Okt 2015 14:25

AW: String via Sendmessage unvollständig
 
Okay - technisch geht's aber es macht - aus meiner Sicht - deutlich, warum sich viele Entwickler da lieber an Threads halten. :mrgreen:

hathor 9. Okt 2015 15:56

AW: String via Sendmessage unvollständig
 
Liste der Anhänge anzeigen (Anzahl: 4)
Zitat:

Zitat von Ajintaro (Beitrag 1318152)
Ich habe mir das IPC Beispiel mal angesehen und es würde all meine Probleme lösen, ich habe nur Schwierigkeiten es komplett zu verstehen.

Auch SCHÖNES WCHENENDE !

Im Anhang das erweiterte IPC-Beispiel:

Ajintaro 19. Okt 2015 16:29

AW: String via Sendmessage unvollständig
 
Hi DP,

ich war im Urlaub und antworte deshalb so spät.

Zitat:

Zitat von hathor (Beitrag 1318198)
Im Anhang das erweiterte IPC-Beispiel:

Vielen lieben Dank für die Mühe hathor, das hat mir sehr geholfen! :thumb:


Alle Zeitangaben in WEZ +1. Es ist jetzt 07:29 Uhr.

Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz