Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Win32/Win64 API (native code) (https://www.delphipraxis.net/17-win32-win64-api-native-code/)
-   -   Delphi SendMessage wartet nicht (https://www.delphipraxis.net/190854-sendmessage-wartet-nicht.html)

Sunlight7 14. Nov 2016 15:25

SendMessage wartet nicht
 
Hallo zusammen!

Im MSDN steht:

Zitat:

The SendMessage function calls the window procedure for the specified window and does not return until the window procedure has processed the message.
Nun habe ich ein Problem damit, von einem Prozess aus wird SendMessage benutzt um zu einem anderen Prozess eine Nachricht zu schicken, dort wird ein Fenster per ShowModal angezeigt und das ModalResult als Result der Message zurück geschickt, dabei sollte der Thread mit SendMessage warten bis die Nachricht abgearbeitet wurde. Tut es aber nicht, SendMessage kehrt nach kurzer Zeit mit 0 als Result zurück. GetLastError meint dazu kein Fehler, also auch 0.

Pseudo Code:
Code:
Prozess 1:
Result:=SendMessage(RemoteWnd, WM_IPC_SHOWFORM, 0, 0);
// Hier gehts mit Result=0 kurz drauf weiter, obwohl Form2 noch nicht geschlossen wurde.


Prozess 2:
procedure TForm1.WndProc(var Message:TMessage);
begin
   Case Message.Msg of
      ...
      WM_IPC_SHOWFORM: begin
         Message.Result:=Form2.ShowModal;
         Exit; <- Hier gehts erst weiter sobald Form2 geschlossen wurde
      end;
   end;
   ...
end;
Warum wartet SendMessage nicht? Habs auch mit SendMessageTimeout versucht bei gleichem Ergebnis

Zacherl 14. Nov 2016 15:27

AW: SendMessage wartet nicht
 
Nimm mal
Delphi-Quellcode:
INFINITE
statt 0 für das Timeout, dann gehts auch :-D Oder halt direkt MSDN-Library durchsuchenSendMessage, wenn du das Timeout nicht benötigst.

Hatte den letzten Satz überlesen.

Verwendest du noch Win2000? MSDN sagt, dass MSDN-Library durchsuchenGetLastError eigentlich
Delphi-Quellcode:
ERROR_TIMEOUT
enthalten sollte:
Zitat:

If the function fails or times out, the return value is 0. To get extended error information, call GetLastError. If GetLastError returns ERROR_TIMEOUT, then the function timed out.

Windows 2000: If GetLastError returns 0, then the function timed out.

Der schöne Günther 14. Nov 2016 15:31

AW: SendMessage wartet nicht
 
Dumme Idee:
Delphi-Quellcode:
ShowModal()
verursacht selber wieder das Senden und Abarbeiten von Messages. Ob der deine Message irgendwie runternimmt, damit nichts anfangen kann und wegwirft? Ich würde es mal nicht an TForm1 binden, sondern generell mit
Delphi-Quellcode:
Application.RegisterWndProc(..)
oder wie das hieß...

Mit dem "SendMessageTimeout" komme ich nicht klar: Die beiden Nullen sind eigentlich WPARAM und LPARAM. Kommt das "Timeout" nur von einem Test? Denn für "SendMessageTimeout" hat der Aufruf zu wenig Parameter...

Zacherl 14. Nov 2016 15:35

AW: SendMessage wartet nicht
 
Zitat:

Zitat von Der schöne Günther (Beitrag 1353609)
Dumme Idee:
Delphi-Quellcode:
ShowModal()
verursacht selber wieder das Senden und Abarbeiten von Messages. Ob der deine Message irgendwie runternimmt, damit nichts anfangen kann und wegwirft?

Au ja, das könnte auch sehr gut sein und würde auch erklären, warum MSDN-Library durchsuchenGetLastError keinen Fehlercode zurückgibt. Dann allerdings wundert mich, dass MSDN-Library durchsuchenSendMessageTimeout 0 liefert ..

Neutral General 14. Nov 2016 15:38

AW: SendMessage wartet nicht
 
Ist ja auch ganz logisch. ShowModal blockiert solange bis dasn Fenster geschlossen wird. Das hat nichts mit SendMessage zu tun.
Dementsprechend kommt er zu dem exit logischerweise auch erst wenn das Fenster geschlossen wurde. Das andere Programm kriegt wohl
vorzeitig eine 0 zurück (Timeout) weil es ansonsten solange hängen würde bis das Fenster wieder geschlossen wird.

Unterm Strich heißt das: ShowModal im WndProc ist keine gute Idee.

Sunlight7 14. Nov 2016 15:50

AW: SendMessage wartet nicht
 
Dann wäre aber die Beschreibung im MSDN falsch.
Auch ein SendMessageTimeOut mit ner Zeit gegeben von einer Stunde wartet nicht solange.

Der schöne Günther 14. Nov 2016 15:52

AW: SendMessage wartet nicht
 
Kontrollierst du bitte nochmal deinen Quellcode? SendMessageTimeout(..) hat nicht vier Parameter, sondern mehr.

Sunlight7 14. Nov 2016 15:54

AW: SendMessage wartet nicht
 
Zitat:

Zitat von Zacherl (Beitrag 1353608)
Verwendest du noch Win2000?

Windows 7

Sunlight7 14. Nov 2016 15:55

AW: SendMessage wartet nicht
 
Zitat:

Zitat von Der schöne Günther (Beitrag 1353623)
Kontrollierst du bitte nochmal deinen Quellcode? SendMessageTimeout(..) hat nicht vier Parameter, sondern mehr.

Das war nur ein Copy & Paste Fehler, sollte nur SendMessage sein

Zacherl 14. Nov 2016 16:12

AW: SendMessage wartet nicht
 
Ok nochmal von vorne :-D Ein Result von 0 bei MSDN-Library durchsuchenSendMessage deutet NICHT auf einen Fehler hin. Ein Result von 0 bei MSDN-Library durchsuchenSendMessageTimeout aber definitiv schon. Ich gehe jetzt einfach mal von MSDN-Library durchsuchenSendMessage aus.

Das Problem hat Günther schon korrekt erkannt:
Delphi-Quellcode:
ShowModal
startet eine eigene Message-Verarbeitung und sorgt deshalb dafür, dass deine eigene Message vom Default Message-Handler abgearbeitet und aus der Queue entfernt wird. Das ist dann der Moment, in dem MSDN-Library durchsuchenSendMessage aufhört zu blocken.

Sunlight7 14. Nov 2016 16:19

AW: SendMessage wartet nicht
 
ShowModal läuft in der 2. Anwendung, was hat das mit dem Blocken in der 1. Anwendung zu tun? Oder verstehe ich da was falsch?

Der schöne Günther 14. Nov 2016 16:25

AW: SendMessage wartet nicht
 
Ich dachte die 1. Anwendung wird nicht geblockt, heißt: Du bekommst einen Rückgabewert obwohl das mit ShowModal() geöffnete Fenster noch offen ist.
Die Erklärung war dass der ShowModal()-Aufruf der Form2 selbst anfängt Nachrichten zu verarbeiten. Dem hast du deinen eigene Nachricht nicht beigebracht. Er wirft sie weg und beantwortet sie mit Null.

Versuche es doch mal so:
Delphi-Quellcode:
// TWindowHook = function (var Message: TMessage): Boolean of object;
function TForm1.handleIpcShowForm(var Message: TMessage): Boolean;
const
   WM_IPC_SHOWFORM = WM_USER + 1;
var
   secondForm: TForm;
begin
   case Message.Msg of
      WM_IPC_SHOWFORM: begin
         secondForm := TForm.Create(nil);
         try
            Message.Result := secondForm.ShowModal();
            Result := True;
         finally
            secondForm.Destroy();
         end;
      end;
   else
      Result := False;
   end;
end;

procedure TForm1.FormCreate(Sender: TObject);
begin
   Application.HookMainWindow(handleIpcShowForm);
end;

hoika 14. Nov 2016 16:28

AW: SendMessage wartet nicht
 
Hallo,
warum gehst du überhaupt über Messages?
Das sind Kanonen auf die armen Spatzen.

Der schöne Günther 14. Nov 2016 16:30

AW: SendMessage wartet nicht
 
Weil er zwei verschiedene Prozesse hat. Ich bin für IPC-Sachen kein Profi, aber für so etwas einfaches wie "Mache ein Fenster auf" hätte ich das wahrscheinlich auch genommen...

Zacherl 14. Nov 2016 16:46

AW: SendMessage wartet nicht
 
Zitat:

Zitat von Sunlight7 (Beitrag 1353633)
ShowModal läuft in der 2. Anwendung, was hat das mit dem Blocken in der 1. Anwendung zu tun? Oder verstehe ich da was falsch?

Der Sender blockt halt nur so lange, bis der Empfänger die Nachricht bearbeitet hat. Du gehst davon aus, dass dies erst nach dem
Delphi-Quellcode:
ShowModal
der Fall ist. Da
Delphi-Quellcode:
ShowModal
die Message aber selbstständig abarbeitet, hört MSDN-Library durchsuchenSendMessage praktisch direkt zeitgleich mit deinem
Delphi-Quellcode:
ShowModal
Aufruf auf zu blockieren.

Sunlight7 14. Nov 2016 17:40

AW: SendMessage wartet nicht
 
Wenn ich also anstatt ein Formular mit ShowModal anzuzeigen eine MessageBox aufrufe funktioniert es, was macht Windows da anders?

Der schöne Günther 14. Nov 2016 17:41

AW: SendMessage wartet nicht
 
Eine Windows-Messagebox ist keine VCL-Anwendung? Hast du die Beiträge hier drüber überhaupt gelesen? :oops:

Sunlight7 14. Nov 2016 17:52

AW: SendMessage wartet nicht
 
Ja ich habe die Beiträge gelesen und bin deswegen vom ShowModal weggegangen und es würde mich weiterhin interessieren, wie Windows sein Modales Fenster realisieren kann ohne den SendMessage Block zu stören. Das Windows nicht Delphi VCL ist bin ich mir ebenfalls bewusst, daher ja der Gedanke, ob ich die Windows Variante nachahmen kann.


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