Delphi-PRAXiS
Seite 1 von 4  1 23     Letzte »    

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Algorithmen, Datenstrukturen und Klassendesign (https://www.delphipraxis.net/78-algorithmen-datenstrukturen-und-klassendesign/)
-   -   PostMessage mit WndProc oder WMCopyData/Record aus Thread für GUI-Aktualisierung? (https://www.delphipraxis.net/194260-postmessage-mit-wndproc-oder-wmcopydata-record-aus-thread-fuer-gui-aktualisierung.html)

Glados 3. Nov 2017 14:15


PostMessage mit WndProc oder WMCopyData/Record aus Thread für GUI-Aktualisierung?
 
Vor einiger Zeit war es noch OK, dass ich mit PostMessage Daten aus einem Thread an WndProc geschickt habe. Funktioniert wunderbare und ich bin Synchronize() losgeworden.

Ich stelle mir jetzt aber ein paar Kernfragen:
Synchronize aus einem Thread heraus Sychronisiert mit dem Hauptthread. Grob gesagt kann ich dann den zweiten Thread auch komplett weglassen wenn doch eh synchronisiert wird.

Wie sieht das aus, wenn man PostMessage verwendet und die Daten in WndProc (andere Unit) auswertet und dort die GUI aktualisiert.
Wird dann auch mit dem Hauptthread synchronisiert bzw. IST DAS überhaupt besser? Synchronize ist weg, das war mein Ziel.

Ich möchte nun gerne auch Zeichen ketten schicken können.
Dafür würde ich bei PostMessage bleiben, aber WndProc durch WMCopyData(var msg: TWMCopyData); austauschen, sodass ich Records schicken kann und flexibler bin.
Hat das gravierende Nachteile? Wenn ja, wie sonst Daten aus einem Thread heraus schicken, sodass man die GUI aktualisieren kann ohne Synchronize verwenden zu müssen?

EWeiss 3. Nov 2017 14:40

AW: PostMessage mit WndProc oder WMCopyData/Record aus Thread heraus?
 
Zitat:

aber WndProc durch WMCopyData(var msg: TWMCopyData); austauschen
Aha wie geht das?

gruss

Glados 3. Nov 2017 14:44

AW: PostMessage mit WndProc oder WMCopyData/Record aus Thread heraus?
 
Ich weiß nicht ob deine Frage ernst gemeint ist.
Wenn nicht und es Ironie ist, ignoriere ich sie einfach mehr oder weniger gekonnt.

EWeiss 3. Nov 2017 14:46

AW: PostMessage mit WndProc oder WMCopyData/Record aus Thread heraus?
 
Zitat:

Zitat von Glados (Beitrag 1384995)
Ich weiß nicht ob deine Frage ernst gemeint ist.
Wenn nicht und es Ironie ist, ignoriere ich sie einfach mehr oder weniger gekonnt.

Kannst du gerne tun.
Ja sie ist ernst gemeint.

WM_COPYDATA:
WM_COPYDATA ist ein Message die in der Winproc ausgewertet wird aber du möchtest die WinProc entfernen bzw. damit austauschen?
Wie geht das.

gruss

Glados 3. Nov 2017 14:54

AW: PostMessage mit WndProc oder WMCopyData/Record aus Thread heraus?
 
Wie wärs denn so? Ich kapiere noch immer nicht wieso du diese Frage gerade stellst.

Delphi-Quellcode:
type
 TPostMessageData = record
  sString: string;
  sInt: Integer;
 end;
 PPostMessageData = ^TPostMessageData;

Button1Click(Sender: TObject);
var
 CopyData: TPostMessageData;
begin
 CopyData.sString := 'String test';
 CopyData.sInt := 99;

 SendMessage(Handle, WM_COPYDATA, 0, Integer(@CopyData));
end;

procedure TFormReceiver.WMCopyData(var msg: TWMCopyData);
begin
 ShowMessage(PPostMessageData(msg.CopyDataStruct).sString);
end;
So kann ich senden was ich will. Nur frage ich mich: besser das unflexible WndProc-Event nutzen oder das deutlich flexiblere WMCopyData (ersteres mit PostMessage, letzteres mit SendMessage).
Aus einem Thread heraus.

Wenn ich das richtig verstanden habe, blockiert SendMessage den Thread erst einmal. Auch wenn es nicht lange ist. PostMessage, da asynchron, macht das wohl nicht.

EWeiss 3. Nov 2017 14:57

AW: PostMessage mit WndProc oder WMCopyData/Record aus Thread heraus?
 
Zitat:

Zitat von Glados (Beitrag 1385001)
Wie wärs denn so? Ich kapiere noch immer nicht wieso du diese Frage gerade stellst.

Delphi-Quellcode:
type
 TPostMessageData = record
  sString: string;
  sInt: Integer;
 end;
 PPostMessageData = ^TPostMessageData;

Button1Click(Sender: TObject);
var
 CopyData: TPostMessageData;
begin
 CopyData.sString := 'String test';
 CopyData.sInt := 99;

 SendMessage(Handle, WM_COPYDATA, 0, Integer(@CopyData));
end;

procedure TFormReceiver.WMCopyData(var msg: TWMCopyData);
begin
 ShowMessage(PPostMessageData(msg.CopyDataStruct).sString);
end;

Du hast geschrieben das du die Winproc ersetzen\austauschen willst.
Das ist schlicht weg falsch und nicht möglich.

Du kannst deine eigene Message Queue aus dieser ableiten aber die Winproc austauschen vergiss es.
Lese doch einfach mal was du geschrieben hast.
Zitat:

blockiert SendMessage den Thread erst einmal.
Nö.
Sendmessage wartet auf die Rückgabe PostMessage eben nicht!

Bin raus!

gruss

Glados 3. Nov 2017 15:03

AW: PostMessage mit WndProc oder WMCopyData/Record aus Thread heraus?
 
Zitat:

Sendmessage wartet auf die Rückgabe PostMessage eben nicht!
SendMessage wartet auf die Rückgabe, also wird blockiert oder bin ich jetzt neben der Spur?
Ich muss auf keine Rückgabe warten. Ich möchte einfach nur die GUI aus einem Thread heraus aktualisieren ohne Synchronize verwenden zu müssen :P

WndProc zusammen mit Record und PostMessage:
Delphi-Quellcode:

procedure TForm1.Button1Click(Sender: TObject);
var
 CopyData: PPostMessageData;
begin
 CopyData := New(PPostMessageData);
 CopyData.sString := 'String test';
 CopyData.sInt := 99;

 PostMessage(Handle, 50, 0, Integer(CopyData));
end;

procedure TForm1.WndProc(var msg: TMessage);
begin
 case msg.msg of
  50:
   begin
    ShowMessage('WndProc: ' + PPostMessageData(msg.LParam)^.sString);
   end;
 end;

 inherited;
end;
Was ist denn davon zu halten einen ganzen Record zu übergeben und immer mit New einen anzulegen?

Zacherl 3. Nov 2017 15:16

AW: PostMessage mit WndProc oder WMCopyData/Record aus Thread heraus?
 
Zitat:

Zitat von Glados (Beitrag 1384979)
Vor einiger Zeit war es noch OK, dass ich mit PostMessage Daten aus einem Thread an WndProc geschickt habe. Funktioniert wunderbare und ich bin Synchronize() losgeworden.

Hatte das
Delphi-Quellcode:
Synchronize
irgendwelche Probleme bereitet, oder warum wolltest du das loswerden?

Zitat:

Zitat von Glados (Beitrag 1384979)
Synchronize aus einem Thread heraus Sychronisiert mit dem Hauptthread. Grob gesagt kann ich dann den zweiten Thread auch komplett weglassen wenn doch eh synchronisiert wird.

Du synchronisierst ja nicht alle Aktionen des 2. Threads, sondern nur exakt die Stellen, die auf die VCL/GUI zugreifen. Alle anderen Berechnungen laufen dann ja trotzdem parallel ab.

Zitat:

Zitat von Glados (Beitrag 1384979)
Wie sieht das aus, wenn man PostMessage verwendet und die Daten in WndProc (andere Unit) auswertet und dort die GUI aktualisiert.
Wird dann auch mit dem Hauptthread synchronisiert bzw. IST DAS überhaupt besser? Synchronize ist weg, das war mein Ziel.

Die MessageQueue läuft auch im Hauptthread. Bei Verwendung von MSDN-Library durchsuchenPostMessage, würde ich das Verhalten allerdings eher mit
Delphi-Quellcode:
TThread.Queue
vergleichen (hierbei läuft der aufrufende Thread auch weiter; anders als beim
Delphi-Quellcode:
TThread.Synchronize
).

Glados 3. Nov 2017 15:23

AW: PostMessage mit WndProc oder WMCopyData/Record aus Thread heraus?
 
Zitat:

Hatte das Synchronize irgendwelche Probleme bereitet, oder warum wolltest du das loswerden?
Irgendwann hat man es schon gemerkt und die Anwendung wurde tatsächlich träge.
Nachdem ich sehr viel in WndProc ausgelagert habe und PostMessage verwende, ist der Unterschied deutlich spürbar.

Zitat:

Die MessageQueue läuft auch im Hauptthread. Bei Verwendung von MSDN-Library durchsuchenPostMessage, würde ich das Verhalten allerdings eher mit TThread.Queue vergleichen (hierbei läuft der aufrufende Thread auch weiter; anders als beim TThread.Synchronize ).
ist es demnach korrekt-er WndProc (oder was anderes) zu verwenden statt Synchronize;

Mein Ziel ist es, alle Synchronize und Queue aus den Threads zu bekommen.

Daher habe ich mir das da oben mal zusammengestrickt. Record > PostMessage > WndProc. Frage ist nur, ob das in Ordnung ist?

Zacherl 3. Nov 2017 15:28

AW: PostMessage mit WndProc oder WMCopyData/Record aus Thread heraus?
 
Zitat:

Zitat von Glados (Beitrag 1385011)
Zitat:

Die MessageQueue läuft auch im Hauptthread. Bei Verwendung von MSDN-Library durchsuchenPostMessage, würde ich das Verhalten allerdings eher mit TThread.Queue vergleichen (hierbei läuft der aufrufende Thread auch weiter; anders als beim TThread.Synchronize ).
ist es demnach korrekt-er WndProc (oder was anderes) zu verwenden statt Synchronize;

Mein Ziel ist es, alle Synchronize und Queue aus den Threads zu bekommen.

Daher habe ich mir das da oben mal zusammengestrickt. Record > PostMessage > WndProc. Frage ist nur, ob das in Ordnung ist?

Bei vielen deiner Fragen denke ich an klassisches "Overengineering" :stupid:

WndProc und MSDN-Library durchsuchenPostMessage ist der native WinAPI Weg für solche Dinge. Delphi ist nunmal eine höhere Programmiersprache, welche einige Abstraktionen bereitstellt. Ich kann dir hier nur meine persönliche Meinung sagen, aber ich würde in 99% aller Fälle bei
Delphi-Quellcode:
TThread.Synchronize
bzw.
Delphi-Quellcode:
TThread.Queue
bleiben. Probier es mal mit Letzterem und beachte zusätzlich, dass du wirklich nur die erforderlichen Codestellen synchronisierst. Auch hilfreich kann sein, die GUI Aktualisierung nicht nach jedem Rechenschritt auszuführen. Wenn du z.b. eh nur eine ProgressBar updatest, kannst du das ja ggfls. auch ohne Probleme nur alle 1000 Iterationen oder so durchführen, ohne dass man als Mensch davon etwas mitbekommt.

In Ordnung ist deine Methode vermutlich auch, bloß machst du es dir dadurch unnötig schwer und reduzierst zudem wahrscheinlich auch die Lesbarkeit deines Codes.


Alle Zeitangaben in WEZ +1. Es ist jetzt 17:30 Uhr.
Seite 1 von 4  1 23     Letzte »    

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