![]() |
GUI-Anwendung mit Konsolenausgabe
Hallo zusammen!
Viele Windows-Programme kann man per Befehlszeilenparameter steuern, das ist ja nichts ungewöhnliches. Bei manchen kann man auch den Parameter "/?" oder "/help" angeben und bekommt dann ein Programm-About. Mir ist bei einigen Microsoft-GUI-Anwendungen aufgefallen dass diese das About nicht als GUI-Window öffnen sondern auf der Befehlszeile ausgeben (sprich wenn man das Ding in der DOS-Box aufruft). Nur scheint es bei Delphi gar nicht so einfach zu sein, einen Hybriden aus GUI-Anwendung mit Befehlszeilenausgabe zu realisieren. Gibts da einen Trick? Ein WriteLn in der .DPR vor dem Application.Initialize bringt jedenfalls eine E/A-Exception. Grüße Cody |
AW: GUI-Anwendung mit Konsolenausgabe
Lies dir mal
![]() Zitat:
|
AW: GUI-Anwendung mit Konsolenausgabe
Falls du etwas halbwegs einfaches findest, wäre ich auch am Ergebnis interessiert. Aber letztlich sagt der Link von Uli ja alles: eigentlich geht es nicht so richtig. Als mich damit mal vor 2-3 Jahren aus dem gleichen Grund wie du beschäftigt habe, kam ich letztlich zum Ergebnis, dass mir das alles viel zu abgefahren war, um nur einen Hilfstext für "/?" auszugeben. Letztlich habe ich mich dann dazu entschieden, den Hilfstext doch in einem MessageDlg anzuzeigen - gefiel mir zwar nicht so dolle, habe ich aber auch schon bei vielen - auch Microsoft- - Programmen gesehen.
Ist jetzt zwar keine wirkliche Hilfe, aber vielleicht doch mal ein kleiner Erfahrungsbericht als Feedback zu dem Thema. Bis denn Bommel |
AW: GUI-Anwendung mit Konsolenausgabe
Ich unterstreiche/stütze Bommels Beitrag.
|
AW: GUI-Anwendung mit Konsolenausgabe
Also,
- auch eine GUI-Anwendung kann man mit Parametern starten. - erstellt man eine Konsolenanwendung, dann kann man darin auch ganz einfach Fenster dynamisch erstellen. - oder man erstellt eine GUI-Anwendung und sagt dem Compiler/Windows es wäre eine Konsolenanwendung (dafür einfach den Kompilerschalter, welchen ihr in einer Konsolen-DPR findet in die GUI-DPR reinmachen) - oder man erstellt ene GUI-Anwendung und erstellt zur Laufzeit eine Console ( ![]() PS: mein ![]() und irgendwo existiert auch ein Thread, wo es um das gleicher Thema geht PPS: In meiner Anwendung findet ihr auch, wie man rausbekommt, ob die Ein-/Ausgaben der Anwendung mit einer Konsole verknüpft sind ... dementsprechend könnte man dann entweder in der Konsole oder über einen Dialog die Ausgaben machen. |
AW: GUI-Anwendung mit Konsolenausgabe
![]() ![]() |
AW: GUI-Anwendung mit Konsolenausgabe
Moin :hi:
... oder eine GUI-Anwendung mit Konsole als Kindfenster? Da bin ich zur Zeit bei. Ich habe mein Turbo Pascal-Programm als Konsolenanwendung konvertiert und nun möchte ich das in die Fenstervariante einbinden. Das ist schon etwas aufwändig. Stefan |
AW: GUI-Anwendung mit Konsolenausgabe
So, ich habs derweil mal hinbekommen. Das Kernproblem war bei mir mehrschichtig. Zum einen arbeite ich noch mit Delphi 5 und 7, da gabs noch nicht alle Imports aus der Kernel32.dll. Zum zweiten muss man sich erstmal das Handle der aufrufenden Konsoleninstanz holen. Andernfalls öffnet sich ein neues Konsolenfenster, gibt den Text aus und schließt sich wieder. Auf aktuellen Rechnern geht das so flott dass man das kaum bis gar nicht mehr mitbekommt. Leider gibt es die API AttachConsole erst ab XP aufwärts, aber das sollte ja im Moment ohnehin das Minimum sein.
Delphi-Quellcode:
// Konstante definieren ATTACH_PARENT_PROCESS = DWord(-1); // API einbinden function AttachConsole(dwProcessId: DWord): Boolean; stdcall; external 'kernel32.dll' name 'AttachConsole'; // Hier beginnt das About (innerhalb der .DPR vor dem Application.Initialize) if Pos('/?', CmdLine) > 0 then begin if AttachConsole(ATTACH_PARENT_PROCESS) then begin try WriteLn(#13#10 + 'About'); finally FreeConsole; end; Exit; end else begin ShowMessage('About'); Exit; end; end; |
AW: GUI-Anwendung mit Konsolenausgabe
Krass, soll das wirklich alles gewesen sein? :shock: Irgendwie hatte ich das (wie oben geschrieben) viel komplizierter in Erinnerung bei den Lösungen, die ich damals gefunden habe.
Ein Problem habe ich allerdings noch bei einem Test festgestellt: Wenn das Programm mit dem "/?" gestartet wird, gibt es den Text brav auf der Konsole aus, nach dem Ende des Programms wird dann aber kein Prompt angezeigt. D.h.: der Cursor blinkt, die Konsole nimmt auch Befehle entgegen, aber für den Benutzer sieht das nicht so aus, da er das Prompt nicht sieht. Irgendwelche Ideen, wie man das noch lösen kann? Meine Komplettlösung sieht dann übrigens so aus:
Delphi-Quellcode:
Bis denn
program GUIcons;
uses Forms, windows, Dialogs, main in 'main.pas' {Form1}; const // Konstante definieren ATTACH_PARENT_PROCESS = DWord(-1); // API einbinden function AttachConsole(dwProcessId: DWord): Boolean; stdcall; external 'kernel32.dll' name 'AttachConsole'; {$R *.res} begin // Hier beginnt das About (innerhalb der .DPR vor dem Application.Initialize) if paramstr(1)='/?' then begin if AttachConsole(ATTACH_PARENT_PROCESS) then begin try WriteLn(#13#10 + 'About'); writeln; finally FreeConsole; end; end else begin ShowMessage('About'); end; end else begin Application.Initialize; Application.MainFormOnTaskbar := True; Application.CreateForm(TForm1, Form1); Application.Run; end; end. Bommel |
AW: GUI-Anwendung mit Konsolenausgabe
Zitat:
Zitat:
Delphi-Quellcode:
nach dem FreeConsole einfügen, dann klappt das :-)
KEYBD_EVENT(VK_RETURN,0,0,0);
|
AW: GUI-Anwendung mit Konsolenausgabe
(1) Unter Delphi7 funktioniert die Anweisung "if AttachConsole(ATTACH_PARENT_PROCESS) then" nicht bzw. gibt immer den Wert FALSE zurück.
Die Verwendung von "if Windows.AllocConsole then" funktioniert dagegen schon. (2) Man kann mit
Code:
einen künstlichen Prompt anzeigen, die Eingabe in die Variable abfangen und diese zielgerichtet auswerten.
Write('>');
ReadLn(Parameter); (3) Sollte man unbedingt entweder mit einem Mutex oder per GlobalFindAtom() arbeiten, um den sonst möglichen Start mehrfacher Instanzen des Programms zu blockieren und so insbesondere das Kuddelmuddel einer evt. gleichzeitigen Präsenz von GUI- und Konsolen-Ausgabe separater Instanzen des Programms zu verhindern (4) Deshalb Vorschlag:
Code:
Eine grundsätzliche Frage ist aber, wozu denn überhaupt der Klimmzug mit der Konsolenausgabe sinnvoll sein soll, wenn man die gleiche Information problemlos und diese viel besser und ansprechender noch vor der Initialisierung der Mainform mittels Showmessage() anzeigen kann, ohne ggf. zwangsläufig dann die Mainform öffnen zu müssen.
program GUIcons;
uses windows, Sysutils, Forms, Unit1 in 'Unit1.pas' {Form1}; {$R *.res} const AppTitle = 'GUIcons'; // irgendetwas Spezifisches als Titel var Mutex: THandle; ConsoleForm: TForm1; Parameter: shortstring; begin Mutex := CreateMutex(nil, True, AppTitle); if (Mutex = 0) or (GetLastError = ERROR_ALREADY_EXISTS) then begin // Reaktiviere die bereits laufende 1.Programminstanz SendMessage(HWND_BROADCAST, RegisterWindowMessage(AppTitle), 0, 0); // und beende sofort die neu gestartete (2.) Programminstanz end else try Parameter:=''; // gff. eine spezifische Parameteranalyse if paramcount = 0 then begin if Windows.AllocConsole then try ConsoleForm := TForm1.Create(nil); WriteLn; // irgendeine sinnvolle Information, z.B.: WriteLn('Usage: GUIcons <Parameter>'); WriteLn('Fortsetzung mit <ENTER>'); write('> '); readln(Parameter); finally ConsoleForm.Free; FreeConsole; end; end else parameter:=paramstr(1); // ggf. prüfen, ob doch noch benötigter Parameter eingegeben wurde, // z.B. Parameter "/open" if Uppercase(Parameter)='/OPEN' then begin Application.Initialize; Application.CreateForm(TForm1, Form1); Application.Run; end finally CloseHandle(Mutex); end; end. |
Alle Zeitangaben in WEZ +1. Es ist jetzt 03:51 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