![]() |
Messages abfangen/mitlesen
Hallo,
ich habe folgendes Problem: ich will/muss eine große Anzahl von bmp-Dateien in jpg-/png-Dateien umwandeln. Das wollte ich in einen Thread auslagern, u.a. um die Forms flüssig laufen zu lassen. Allerdings scheitert das an dem ![]() Also habe ich die Idee, die Berechnung in einem (unsichtbaren) Konsolenprogramm ausführen zu lassen und dieses wiederum über Messages vom Hauptprogramm zu steuern. Den Rumpf stelle ich mir so vor:
Delphi-Quellcode:
Wo/wie kann ich die Messages abfangen?
Program Packer;
{$APPTYPE CONSOLE} {$R *.res} {$DEFINE DEBUG} Uses Winapi.Windows, System.SysUtils, System.Classes, Vcl.Graphics; Var bRet : Integer; Msg : Winapi.Windows.TMsg; Begin While True Do Try // Hier kommt das Laden und Komprimieren des Bitmap Sleep(50); Except On E: Exception Do With TStringList.Create Do Try Try LoadFromFile('Log.txt'); Except End; Append(E.ClassName + ': ' + E.Message); SaveToFile('Log.txt'); Finally Free; End; End; End. Wie das mit dem Message Loop grundsätzlich funktioniert, habe ich anhand diverser Beispiel-Codes gesehen (
Delphi-Quellcode:
,
GetMessage
Delphi-Quellcode:
,
TranslateMessage
Delphi-Quellcode:
). Dann hätte ich die Messages. Allerdings habe ich Test-Code an diversen Stellen eingefügt, ohne dass dieser ausgeführt würde...
DispatchMessage
Gruß, Alex |
AW: Messages abfangen/mitlesen
Da du uns leider deinen Testcode nicht gezeigt hast, zunächst mal eine generelle Info: Um Fensternachrichten (so heissen die) zu empfangen, brauchst du zwingend auch ein Fenster. (Das Konsolenfenster zählt hierbei nicht, da es ja zum Prozess cmd.exe gehört, nicht zu deinem Programm.) Das Fenster kann durchaus unsichtbar sein, das wichtige ist nur, dass du von Windows ein Fenster-Handle bekommst an das die Messages geschickt werden können.
Man kann das natürlich zu Fuß über die WinAPI machen, aber wenn die Größe des Tools jetzt nicht unbedingt wenige kB sein muss, würde ich mir die Gemütlichkeit antun einfach eine VCL-Anwendung draus zu machen. Wenn du bei der Konsole bleiben willst: Mit Konsolenanwendungen kommuniziert man besser mittels ![]() |
AW: Messages abfangen/mitlesen
Warum eine Konsole-Anwendung?
Ein Windowsprogramme mit ShowMainForm:=False wäre doch sicherlich auch möglich. Such mal nach "interprocess communication delphi", da dürfte es zwecks Kommunikation einiges zu lesen geben. cu |
AW: Messages abfangen/mitlesen
Danke für die ausführlich Antwort!
Zitat:
Delphi-Quellcode:
Var
bRet : Integer; Msg : Winapi.Windows.TMsg; Begin { your program logic } // [1] Repeat bRet:= Integer(GetMessage(Msg, 0, 0, 0)); If (bRet = -1) Then Begin // error [2] Break; End Else Begin // [3] TranslateMessage(Msg); // [4] DispatchMessage(Msg); // [5] End // [6] Until (bRet = 0); End.
Aber ich greife den Vorschlag gern auf und es sieht mir auch einfacher aus, es über ein VCL-Programm zu machen, dessen Fenster einfach nicht sichtbar ist. So gesehen eine gut Idee - hätte ich auch selbst drauf kommen können :roll: Von der Theorie her würde mich aber der Weg über ein Konsolen-Programm dennoch interessieren. |
AW: Messages abfangen/mitlesen
Lange nicht mehr gemacht. Aber da fehlt dir die Fenster-Prozedur, an die die Nachricht weitergeleitet und verarbeitet wird. Würde ich jetzt mal so sagen. Das, was du da hast, ist nur die Nachrichtenschleife.
|
AW: Messages abfangen/mitlesen
Naja, das Ding ist halt, dass man mit einer reinen Konsolenanwendung niemals Window-Messages empfangen können wird. Die landen sozusagen überhaupt nicht im Verteiler. Es muss ein Fenster geben, und dieses muss innerhalb seiner so genannten
![]() Man müsste sich also per WinAPI ein Fenster-Handle besogren, und für dieses eine Nachrichtenschleife implementieren (=WndProc). Naja, und im Kern ist das ein wesentlicher Teil dessen, was das VCL TForm für uns kapselt und mundgerecht in Form von Ereignissen serviert. Der Schritt von Konsolenprogramm mit Fenster mit WndProc hin zu einem VCL Programm ist fast schon als nur noch kosmetisch anzusehen. (Ja, die VCL macht einen ganzen Haufen, aber im Kern geht es um "hier hast du Fenster".) |
AW: Messages abfangen/mitlesen
Mir ist das zu aufwendig. Also werde ich den "Packer" auch als (unsichtbares) VCL machen. Ich habe bereits gesucht. Und da ich bloß Strings austauschen will, wurde ich
![]() Ich habe nun versucht, das Ganze in 2 Programm zu splitten. Aber irgendwie kommt immer nur ein leerer String an:
Delphi-Quellcode:
und der Empfänger
const
MY_MESSAGE = WM_USER + 4242; type TForm1 = class(TForm) Edit1: TEdit; Button1: TButton; procedure Button1Click(Sender: TObject); end; var Form1: TForm1; implementation {$R *.dfm} procedure TForm1.Button1Click(Sender: TObject); Var H : HWND; txt : String; begin txt:= Edit1.Text; SendMessage(FindWindow('TForm1', 'Packer'), MY_MESSAGE, 0, DWORD(PChar(txt))); end;
Delphi-Quellcode:
Was mache ich falsch?
Const
MY_MESSAGE = WM_USER + 4242; Type TForm1 = Class(TForm) Memo1 : TMemo; Private Procedure GotMessage(Var Msg: TMessage); Message MY_MESSAGE; End; Var Form1 : TForm1; Implementation {$R *.dfm} Procedure TForm1.GotMessage(Var Msg: TMessage); Var MsgStr : PChar; txt : String; Begin MsgStr:= PChar(msg.lParam); Msg.Result:= 1; ShowMessage(MsgStr); // exakt der gleiche Code - trotzdem leere Zeichenkette With Memo1.Lines Do Try BeginUpdate; txt:= String(MsgStr); Add(txt); Finally EndUpdate; End; End; |
AW: Messages abfangen/mitlesen
Nur mal so als Anregung: Wie wäre es mit Startparametern? Einfach pro Bild das Programm einmal starten. Und fertig. Ggf. als zusätzlichen Parameter noch das Handle deiner Hauptform mit gegeben. Dann kann das "Packer" Programm dein Hauptprogramm noch per Botschaft informieren, wenn es fertig ist. Dürfte einfacher sein und weniger "Angriffsfläche" für Fehler bieten.
|
AW: Messages abfangen/mitlesen
Das wird so nicht funktionieren. Wenn dann mit WM_COPYDATA. Siehe hier:
![]() |
AW: Messages abfangen/mitlesen
Bei dem String versuchst du einen Pointer zwischen zwei Prozessen auszutauschen, aber jeder Prozess hat seinen eigenen Speicherbereich. Das was in einem Programm auf einen gültigen String zeigt, zeigt im anderen auf irgend etwas - höchstwahrscheinlich Müll. Mit der Ausnahme von WM_COPYDATA kann mit Messages immer nur wParam und lParam, also zwei 32 Bit Integer übergeben werden. Und WM_COPYDATA hat auch so seine eigenen kleinen Eigenheiten.
Nur um's noch mal in den Raum zu werfen: ![]() |
Alle Zeitangaben in WEZ +1. Es ist jetzt 23: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