Entwickler-Ecke

Windows API - Application.processmessages in DLL


Yasso - Mo 04.12.06 11:06
Titel: Application.processmessages in DLL
hallo,

ich brauche das "application.processmessages" oder ähnliches in einer DLL.

Ich könnte z.b. eine Funktion/procedure in der DLL schreiben, die ungefähr so aussieht:


Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
...
var application : TApplication;
...
procedure Init(apphandle : THandle);
begin
  application.handle := apphandle;
end;

procedure proc2;
begin
  ...
  application.processmessages;
  ...
end;


Das Problem ist aber, daß ich das application.handle vom Hauptprogramm nicht wie oben übergeben will, sondern diese soll in der DLL ermitteln werden.
z.b.


Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
...
var application : TApplication;
...
procedure Init;
var apphandle : THandle;
begin
  apphandle := hier soll das application.handle des Hauptprogramm ermittelt werden.
  application.handle := apphandle;
end;

procedure proc2;
begin
  ...
  application.processmessages;
  ...
end;



ist sowas möglich??


Danke
Yasso

Moderiert von user profile iconGausi: Delphi-Tags hinzugefügt


Narses - Mo 04.12.06 11:12

Moin!

Was auch immer du vor hast :nixweiss:, die VCL ist eh nicht threadsave, so dass ein Abarbeiten der MessageLoop aus einem anderen Thread als dem Haupt-Thread der Anwendung dir sowieso nicht weiter hilft... :mahn: (sondern vermutlich eher Fehler produziert) :|

cu
Narses


Stefan.Buchholtz - Mo 04.12.06 11:54

Das ist so meines Wissens nicht möglich. Das Application.ProcessMessages sollte vom Application-Objekt das Hauptprogramms ausgeführt werden, damit die Nachrichten richtig verarbeitet werden können.

Ich würde der DLL eine Callback-Funktion ins Hauptprogramm übergeben, die im Hauptprogramm dann Application.ProcessMessages aufruft.

Das sieht dann in etwas so aus:

Hauptprogramm:


Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
type 
  TOnProcessMessages = procedurestdcall;

...

procedure OnProcessPessages;
begin
  Application.ProcessMessages;
end;

  ...
  // DLL-Aufruf
  DLLProc(@OnProcessMessages, ...);

  ...

DLL:


Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
type 
  TOnProcessMessages = procedurestdcall;

procedure DLLProc(AOnProcessMessages: TOnProcessMessages; ...); stdcall;
begin
  ...
  if Assigned(AOnProcessMessages) then
    AOnProcessMessages;
  ...
end;


Stefan


Yasso - Mo 04.12.06 11:54

danke.

ich habe in der DLL eine Komponente implmentiert, die z.b. über UDP Daten senden und empfangen kann.
Mit Hilfe einer Funktion kann ich Daten über UDP senden. Und über z.b. (event)OnDataAvailable(..) werden die Daten/Rückmeldung empfangen.

z.B.

Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
...
var IsBusy : Boolean;
    RetValue : Byte; 

Function SendData(daten..) : Byte; stdcall;
begin
  IsBusy := true;
  udp1.send(daten);
  repeat
    application.processmessages;  // d.h. solange warten bis Rückmeldung empfangen wurde.
  until IsBusy = false;
  ...
  Result := RetValue;
  ...
end;

procedure udp1.OnDataAvailable(...);
begin
  ...
  //Daten lesen und auswerten.
  RetValue := xx;
  ...
  IsBusy := false;  // wieder frei
end;

function GetIsBusy : Boolean; stdcall;
begin
  Result := IsBusy;
end;


Mein Hauptprogramm soll auf den Rückgabewert der Funktion "Senddata" warten.
Dabei müssen aber alle Messages des Hauptprogramms weiter abgearbeitet werden. Sonst würde das Hauptprogramm auf nichts mehr reagieren, erst bis die Rückmeldung empfangen wurde.


Danke
Yasso


Narses - Mo 04.12.06 12:01

Moin!

user profile iconYasso hat folgendes geschrieben:
Mein Hauptprogramm soll auf den Rückgabewert der Funktion "Senddata" warten.
Dabei müssen aber alle Messages des Hauptprogramms weiter abgearbeitet werden.

Immer das gleiche, "ereignisorientiert warten"... :roll: ;) :arrow: FAQ-Beitrag [http://www.delphi-library.de/viewtopic.php?p=408843#408843] dazu!

Mach es dann doch gleich richtig und definiere ein entsprechendes Ereignis, dass du z.B. über PostMessage aus der DLL der Hauptanwendung "zustellst". Die Hauptanwendung wiederum muss als Zustandsautomat mit entsprechenden Zuständen (Warten auf Rückmeldung, Senden von Anfrage, Warten auf Benutzereingabe, etc.) umgehen können.

cu
Narses


Yasso - Mo 04.12.06 12:08

Zitat:
Immer das gleiche, "ereignisorientiert warten"...

das habe ich bisher immer so gemacht.
Es ist aber leider so, dass ich jetzt oft warten MUSS!


Narses - Mo 04.12.06 12:15

Moin!

user profile iconYasso hat folgendes geschrieben:
Zitat:
Immer das gleiche, "ereignisorientiert warten"...

das habe ich bisher immer so gemacht.

Das macht eine Polling-Schleife in einer ereignisorientierten Umgebung aber nicht "besser"... :D

cu
Narses


Yasso - Mo 04.12.06 13:29

wenn es möglich wäre das Application.Handle irgendwie in der DLL zu ermitteln,
dann würde ich das ganze testen.
Ob gut oder schlecht das lässt sich dann feststellen.



Danke


Yasso - Mo 04.12.06 19:46

ich habe bis jetzt nichts brauchbares gefunden.

Ist es echt nicht möglich das "Application.Handle" der Hauptanwendung in einer dll zu ermitteln!

Ich bin seit eine Woche daran, und bis jetzt leider kein Erfolg!

Gruß
Yasso


Yasso - Mo 04.12.06 20:52

ich habe jetzt folgendes gemacht:

das Unit "Forms" in der DLL deklariert.

und für Application.ProcessMessages habe ich Forms.Application.ProcessMessages geschrieben. So funktioniert es.

Warum es so funktioniert weis ich nicht! Hat jemand Ahnung?
Könnte dadurch Probleme geben?

Gruss
Yasso


Narses - Mo 04.12.06 21:28

Moin!

Warum du den DLL-Funktionen nicht einfach das Handle mitgibst, hab ich immer noch nicht verstanden, aber nun gut... :nixweiss:

Du kriegst nur dann definitiv Probleme, wenn du Application.ProcessMessages NICHT aus dem Kontext des Haupt-Threads aufrust, der Rest sollte AFAIK egal sein.

cu
Narses


Reinhard Kern - Di 05.12.06 07:56

user profile iconYasso hat folgendes geschrieben:
ich habe jetzt folgendes gemacht:

das Unit "Forms" in der DLL deklariert.

und für Application.ProcessMessages habe ich Forms.Application.ProcessMessages geschrieben. So funktioniert es.

Warum es so funktioniert weis ich nicht! Hat jemand Ahnung?
Könnte dadurch Probleme geben?

Gruss
Yasso


Hallo,

vermutlich hast du jetzt in der DLL eine neue Variable Application definiert. Die kann zwar ProcessMessages ausführen, aber es ist denke ich nicht die Application deines Hauptprogramms, daher wird sie mit den Messages nichts anfangen können; sie kriegt aber wahrscheinlich auch keine, die für dein Hauptprogramm bestimmt waren.

Grundsätzlich ist eine DLL ja auch eine EXE, die für andere Programme Prozeduren ausführt - und sonst nichts. Ausserdem kann das eigentlich schon deshalb nicht funktionieren, weil eine DLL genauso mit C/C++ und andern Programmen funktionieren muss, die von Delphis Application überhaupt nichts wissen.

Ich schätze also, du hast da eine Dummy Application, die eigentlich nichts tut. Das reicht aber möglicherweise, um den Windows Scheduler aufzurufen.

Gruss Reinhard


Yasso - Sa 09.12.06 17:36

Hi,

Zitat:

vermutlich hast du jetzt in der DLL eine neue Variable Application definiert.


nein, das habe ich nicht getan.
Ich habe nur das Unit Forms deklariert.
und da kann ich das Procedure Forms.Application.ProcessMessages auch verwenden.
Es schein gut zu funktionieren.

Gruß
Yasso


Sinspin - Sa 09.12.06 19:19

Hast du jetzt einmal probiert ob wirklich die Ereignisse in deinem Hauptprogramm weiter verarbeitet werden wenn du in deiner DLL Funktion auf etwas wartest? Lass mal 30 Sekunden warten und schau dabei nach ob du deine Anwendung noch beutzen kannst. Es würde mich etwas wundern wenn dem so wäre.