Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   GUI-Design mit VCL / FireMonkey / Common Controls (https://www.delphipraxis.net/18-gui-design-mit-vcl-firemonkey-common-controls/)
-   -   Delphi Strings per PostMessage intern weitergeben? (https://www.delphipraxis.net/146568-strings-per-postmessage-intern-weitergeben.html)

schwa226 22. Jan 2010 18:12


Strings per PostMessage intern weitergeben?
 
Hallo,

Ich komme einfach nicht weiter! :cry:

Ich habe einen Thread den ich vom Hauptprogramm Nachrichten schicken will.

Derzeit habe ich es so gemacht, dass der Hauptthread per Postmessage den Thread die Nachrichten schickt.
Der Thread hat mit AllocateHwnd sein eigenes Hwnd.

Nun möchte ich aber auch Strings zu dem Thread schicken.

Hätte versucht eine TStringList zu erstellen und dann den Pointer per Wparam zu übergeben.
Komm aber nicht weiter!
Geht das vielleicht auch viel einfacher?

Finde hier im Board leider keine Lösung.

Danke!

Aphton 22. Jan 2010 20:10

Re: Strings per PostMessage intern weitergeben?
 
Beispielsweise so?
Delphi-Quellcode:
const
  WM_StrRcv = WM_USER + 1;
{...}
    { Public-Deklarationen }
    procedure OnStrRcv(var Msg: TMessage); message WM_StrRcv;
{...}
procedure TForm1.Button1Click(Sender: TObject);
var
  pStr: PString;
begin
  New( pStr );
  pStr^ := Edit1.Text;
  PostMessage( Handle, WM_StrRcv, DWord(pStr), 0 );
end;

procedure TForm1.OnStrRcv(var Msg: TMessage);
var
  pStr: PString;
begin
  pStr := PString( Msg.WParam );
  Memo1.Lines.Add( pStr^ );
  Dispose( pStr );
end;

Bernhard Geyer 22. Jan 2010 22:16

Re: Strings per PostMessage intern weitergeben?
 
Schau dir mal die Windows-Message WM_COPYDATA an. Hier im Forum solltest du genug Beispiele finden.

Luckie 22. Jan 2010 23:07

Re: Strings per PostMessage intern weitergeben?
 
Da die Nachricht nicht über Prozessgrenzen verschickt werden sollen, wird auch kein WM_COPYDATA benötigt. Aber warum arbeitest du mit einem AllocateHwnd[i]? Benutze doch Delphi-Referenz durchsuchenPostThreadMessage.

schwa226 23. Jan 2010 10:20

Re: Strings per PostMessage intern weitergeben?
 
Danke für eure Hilfe!

Werde mir das mit PostThreadMessage noch ansehen.

Ich habe es derweilen so gelößt:

Hauptform gibt dem Thread die Nachricht das eine Stringlist abzuholen ist.
Da holt sich der Thread über Synchronize die TStringlist von der Hauptform ab.

Geht soweit ganz gut!

EDIT:
Habe mir nun PostThreadMessage angesehen.
Mein Thread erhält auch die Nachrichten.

Im Thread habe ich eine Dauerschleife mit while not Terminated

In dieser Schleife werte ich so die Nachrichten aus:
Delphi-Quellcode:
    while not Terminated do
    begin

      if MyIdTCPClient.Connected then begin
        Sleep(10);

        //check first if message got received from mainform:
        Peekmessage(Msg, 0, 0, 0, PM_REMOVE);

        TranslateMessage(Msg);
        DispatchMessage(Msg);

          case Msg.message of
...
..
Nun habe ich das Problem, das meine Nachricht Msg.message zwei mal ansteht.
Wenn ich im Case Msg.message nach erhalt der Nachricht Msg.message := 0 setze geht es.
Warum bekomme ich die Message zwei mal?

sirius 23. Jan 2010 12:40

Re: Strings per PostMessage intern weitergeben?
 
LAss mal das Translate und Dispatchmessaqeg weg, wenn du jetzt sowieso keine Fenster mehr hast.

schwa226 23. Jan 2010 12:59

Re: Strings per PostMessage intern weitergeben?
 
Delphi-Quellcode:
        //TranslateMessage(Msg);
        //DispatchMessage(Msg);

          case Msg.message of
Behebt leider das Problem nicht das sie zwei mal kommt!?

Nur wenn ich es so mache geht es:
Delphi-Quellcode:
        //TranslateMessage(Msg);
        //DispatchMessage(Msg);

          case Msg.message of
             MyMessage : Msg.message := 0;

sirius 23. Jan 2010 13:53

Re: Strings per PostMessage intern weitergeben?
 
Das ist komisch., ich habe erst kürzlich hier ein BEispiel gepostet, was einwandfrei funktioniert (mit PostThreadMEssage)

Wo kommt eigentlich der TCPClient her? Ist der Teil des Threads? (evtl. braucht der Client doch min. ein Dispatchmessage)

schwa226 23. Jan 2010 16:57

Re: Strings per PostMessage intern weitergeben?
 
Die MeinForm schickt es so:
Delphi-Quellcode:
function TFormClient.SendMessageToThread(const Command : Byte) : Boolean;
begin
    if Assigned(ThreadTCPClient) then
    begin
      if ThreadTCPClient.ThreadID <> 0 then
          Result := PostThreadMessage(ThreadTCPClient.ThreadID, SendCommandToServer, 0,Command)
    end;
end;
Der Thread empfängt sie dann so:
Delphi-Quellcode:
  MyIdTCPClient := TIdTCPClient.Create(nil);
    while not Terminated do
    begin

      if MyIdTCPClient.Connected then begin
        Sleep(1);

        //check first if message got received from mainform:
        Peekmessage(Msg, 0, 0, 0, PM_REMOVE);

          case Msg.message of

            SendCommandToServer : begin
                Msg.message := 0;

            end; //SendCommandToServer : begin
          end; //case Msg.message of


        if not MyIdTCPClient.IOHandler.InputBufferIsEmpty then
        begin
          //schau was im Inputpuffer vom Client ist
        end;
      end
      else begin

          MyIdTCPClient.Connect;
        if MyIdTCPClient.Connected then
          fServerConnectionStatus := Connected;
      end;
So geht es, aber wenn ich das Msg.message := 0; rausnehme dann bekomme ich die Meldung 2 mal.

sirius 25. Jan 2010 07:51

Re: Strings per PostMessage intern weitergeben?
 
Peekmessage ist ja nicht blockierend. Wenn beim zweiten Durchlauf keine neue Message anliegt, kommt peekmessage zurück ohne den Record MSg geändert zu haben. Du musst den Rückegabewert von Peekemessage überprüfen, ob überhaupt eine neue Message da ist/war.

Astat 25. Jan 2010 22:19

Re: Strings per PostMessage intern weitergeben?
 
Zitat:

Zitat von schwa226
Ich komme einfach nicht weiter...
Ich habe einen Thread den ich vom Hauptprogramm Nachrichten schicken will.
Geht das vielleicht auch viel einfacher?

Hallo schwa226, ein Klassiker ist, die Daten in einem Threadsaven Buffer zu stellen, und diesen dann von
einem Workerthread, signalled von einem Eventobjekt, aholen zu lassen.
Der Thread wartet dann wieder auf das nächtse Event, usw... und so fort.
Die Verwendung einer Messagequeue und die Sleeps im IndyClient, haben sich die Indy Entwickler sicher nicht so vorgestellt.

Wenn schon sowas, dann eher so.

Delphi-Quellcode:

      if PeekMessage(Msg, 0, 0, 0, PM_REMOVE) then begin

        if Msg.message = WM_QUIT then BREAK;
        DispatchMessage(msg)
      end else WaitMessage;
Die DefProc sieht dann etwa so aus.

Delphi-Quellcode:

  function WindowProc(hWnd, msg, WParam, LParam: LongInt): LongInt; stdcall;
  var
    p Pointer;
  begin
    Result := DefWindowProc(hWnd ,msg, WParam, LParam);
    if Msg = FOO then begin
      BAR
    end;
  end;
lg. Astat

R2009 26. Jan 2010 08:25

Re: Strings per PostMessage intern weitergeben?
 
Hi,
Sirius: Ich nehme an du meinst das Beispiel das du zu meinem Thread gepostest hast.
Das hat bei mir, in deiner Fassung, auch nicht funktioniert.

Ich kann vor der Verwendung von postthreadmessage nur warnen.
Bei uns hier hat das, bei der Kommunikation zwischen Threads und zwischen main, nie zuverlässig funktioniert.
Das ganze Handling ist sehr undurchsichtig. Z.B. muß in jedem Thread, in der mainloop, application.processmessages drinstehen.
Steht das nicht drin funktioniert das Ganze nicht.
Das war auch bei dem Beispiel von Sirius der Fall.
Zunmindest auf unseren Rechnern hier und mit RAD2007 ist das so.

Ich hab das ganze jetzt mit Events gelöst. Geht auch!

Grüsse
Rainer


Alle Zeitangaben in WEZ +1. Es ist jetzt 20:21 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