FAQ DelphiConsultez toutes les FAQ
Nombre d'auteurs : 124, nombre de questions : 933, dernière mise à jour : 28 septembre 2024 Ajouter une question
Cette FAQ a été réalisée à partir des questions fréquemment posées sur les forums Delphi et Delphi et bases de données de www.developpez.com et de l'expérience personnelle des auteurs.
Nous tenons à souligner que cette FAQ ne garantit en aucun cas que les informations qu'elle propose soient correctes. Les auteurs font le maximum, mais l'erreur est humaine. Cette FAQ ne prétend pas non plus être complète. Si vous souhaitez y apporter des corrections ou la compléter, contactez un responsable (lien au bas de cette page).
Nous espérons que cette FAQ saura répondre à vos attentes. Nous vous en souhaitons une bonne lecture.
L'équipe Delphi de Developpez.com.
- Qu'est-ce qu'une application console ?
- Comment ajouter les informations de version dans une application console ?
- Comment utiliser les redirections dans une application console ?
- Comment associer un handle à une console ?
- Comment demander à l'utilisateur d'appuyer sur une touche ?
- Comment déterminer si la sortie standard est redirigée ?
- Comment mettre des couleurs dans une console ?
- Comment intercepter la fin d'un programme console ?
- Comment exécuter une application extérieure et rediriger les entrées/sorties ?
- Comment cacher la fenêtre d'une application console ?
- Comment faire un "clear screen" dans une application console ?
- Comment basculer un programme console en mode plein écran ?
- Comment avoir une icône personnalisée dans une application console ?
- Comment obtenir le handle de fenêtre d'une application console ?
Une application console est une application Windows sans interface graphique. L'interface utilisateur est réduite à une fenêtre texte affiché par Windows au moment du lancement de l'application. Les fichiers texte standard Input et Output sont automatiquement associés à cette fenêtre.
Bien qu'il n'y ai pas de partie graphique, une application console n'est pas une application DOS. Elle doit être lancée sous Windows comme n'importe quelle autre application.
La création d'un nouveau projet de type Application console ne propose pas d'origine la possibilité de lier des informations de version à l'exécutable.
L'ajout la directive {$R *.RES} le permet.
Une fois le projet Application console créé, la fenêtre d'édition contient :
Code delphi : | Sélectionner tout |
1 2 3 4 5 6 7 | program Project1; {$APPTYPE CONSOLE} uses sysutils; begin // Insérer le code utilisateur ici end. |
Code delphi : | Sélectionner tout |
1 2 3 4 5 6 7 8 9 | program Project1; {$APPTYPE CONSOLE} uses sysutils; {$R *.RES} // Ligne à ajouter begin // Insérer le code utilisateur ici end. |
Cliquer sur oui pour confirmer sa création.
Une fois ceci fait, il vous reste à cocher l'option "Inclure les informations de version au projet" en utilisant le menu Projet->Option-> onglet "Information de version".
Renseigner ces informations et enfin recompiler votre projet.
Il s'agit de créer une application console qui puisse gérer les redirections et ce sans passer par les API.
Cela permet de créer et d'utiliser des routines spécialisées dans des scripts NT.
L'utilisation de INPUT et OUTPUT est "un héritage" du turbo pascal mais reste valide sous Delphi 3-4-5.
Code delphi : | Sélectionner tout |
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 30 | program Upper; {$APPTYPE CONSOLE} // Redirection de type 'PIPE', comportement similaire au programme FIND.EXE ou SORT.EXE // Renvoie une chaîne reçue en entrée ( input) en majuscules sur la sortie (output) uses sysutils; Var Chaine: String; procedure CloseFile; begin Close(INPUT); Close(OUTPUT); end; Begin try Assign(INPUT,''); { Entrée standard } Reset(INPUT); { Le fichier existe; reset en lecture seule} Assign(OUTPUT,''); { Sortie standard} Rewrite(OUTPUT); { Le fichier n'existe pas ; rewrite en écriture seule} While not(Eof) Do Begin Readln(INPUT,Chaine); Writeln(OUTPUT,UpperCase(chaine)); end Finally CloseFile; end; end. |
Code batch : | Sélectionner tout |
1 2 3 | @echo off rem Convertir en majuscule le contenu du fichier minuscule.txt Type Minuscule.txt|Upper>Majuscule.txt |
Une redirection en sortie permet d'enregistrer les données obtenues en résultat d'une commande dans un fichier ou de les diriger vers un périphérique, tel qu'une imprimante, au lieu de les afficher dans la fenêtre de l'invite de commandes.
Code : | Sélectionner tout |
Dir> résultat.txt
Code : | Sélectionner tout |
Ftp<Send.txt
Un PIPE ou filtre permet de lire les données obtenues en sortie d'une commande et de les écrire en tant que données d'entrée dans une autre commande.
Code : | Sélectionner tout |
Echo.|Time
Afin d'utiliser dans une application console les API Windows, nous devons d'abord récupérer un des handles de la console.
Pour cela, on peut utiliser le code source suivant :
Code delphi : | Sélectionner tout |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 | program Project1; {$APPTYPE CONSOLE} uses sysutils, Windows; var Han: THandle; begin Han := GetStdHandle(STD_OUTPUT_HANDLE); if (Han <> INVALID_HANDLE_VALUE) then begin // Insérer le code utilisateur ici end else begin Write('Erreur lors de l''initialisation de l''application !'); ReadLn; end; end. |
Le handle récupéré pouvant être :
- STD_INPUT_HANDLE : handle de l'entrée standard (CONIN$).
- STD_OUTPUT_HANDLE : handle de la sortie standard (CONOUT$).
- STD_ERROR_HANDLE : handle de la sortie d'erreur standard. (permet par exemple de rediriger les erreurs/Log dans un fichier spécifique.)
Il faut utiliser l'API Windows ReadConsoleInput, après avoir récupéré le handle de la console.
Code delphi : | Sélectionner tout |
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 | program Project1; {$APPTYPE CONSOLE} uses SysUtils, Windows; var han: THandle; dw: DWord; buf: TInputRecord; begin han := GetStdHandle(STD_INPUT_HANDLE); Write('Continuer [O/N] ?'); repeat FlushConsoleInputBuffer(han); dw := 0; ReadConsoleInput(han, buf, 1, dw); until (buf.EventType = KEY_EVENT) and (buf.Event.KeyEvent.AsciiChar in ['o','O','n','N']); WriteLn(buf.Event.KeyEvent.AsciiChar); case buf.Event.KeyEvent.AsciiChar of 'o','O': WriteLn('OUI !!'); 'n','N': WriteLn('NON !!'); end; ReadLn; end. |
Il est parfois utile de savoir si l'exécution d'une application console redirige ou non ses entrée/sortie standard.
Pour déterminer si c'est le cas, nous utiliserons la fonction Getfiletype, elle renvoie le type du fichier du handle passé en paramètre:
Code delphi : | Sélectionner tout |
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 | program TestIO; {$APPTYPE CONSOLE} uses sysutils, Windows; var ConsoleHandle : THandle; Function GetHandleType(Handle:THandle): String; begin case GetFileType(Handle)of FILE_TYPE_UNKNOWN : Result:='type inconnu ou erreur.'; FILE_TYPE_DISK : Result:='fichier disque.'; FILE_TYPE_CHAR : Result:='fichier caractère.'; FILE_TYPE_PIPE : Result:='socket, un pipe nommé, ou un pipe anonyme.'; //FILE_TYPE_REMOTE inutilisé end; end; begin ConsoleHandle := GetStdHandle(STD_OUTPUT_HANDLE); WriteLn('Sortie standard : '+ GetHandleType(ConsoleHandle)); Readln; ConsoleHandle := GetStdHandle(STD_INPUT_HANDLE); WriteLn('Entrée standard : '+ GetHandleType(ConsoleHandle)); end. |
- FILE_TYPE_CHAR : signale un type de fichier caractère, typiquement une imprimante ou la console .
- FILE_TYPE_DISK : signale un type de fichier disque.
- FILE_TYPE_PIPE : signale un type de fichier socket, un pipe nommé, ou pipe anonymous.
- FILE_TYPE_REMOTE : inutilisé
- FILE_TYPE_UNKNOWN : Soit le type de fichier est inconnu soit la fonction a échouée.
Le script suivant vous permettra de visualiser les différents cas de figure :
Code batch : | Sélectionner tout |
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 30 31 | @Echo Off Set DirPrgName= Set PrgName=%DirPrgName%TestIO.exe Rem Différent cas de figure Echo Test avec : %PrgName% %PrgName% pause&Echo. Echo Test avec : %PrgName%^>Result1.txt %PrgName%>Result1.txt Type Result1.txt pause&Echo. Echo Test avec : %PrgName%^|more %PrgName%|more pause&Echo. Echo Test avec : %PrgName%^|more^>Result2.txt %PrgName%|more>Result2.txt Type Result2.txt pause&Echo. Echo Test avec : %PrgName%^>Result1.txt %PrgName%<Result1.txt pause&Echo. Echo Test avec : %PrgName%^<Result1.txt^>Result3.txt %PrgName%<Result1.txt>Result3.txt Type Result3.txt pause&Echo. |
Après avoir récupéré le handle d'une console, on peut y mettre des couleurs ! Pour cela, on utilise l'API SetConsoleTextAttribute. On peut alors combiner les couleurs d'avant et d'arrière plan…
Code delphi : | Sélectionner tout |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 | program Test1Console; {$APPTYPE CONSOLE} uses sysutils, Windows; var ConsoleHandle: THandle; ConsoleScreenBufferInfo: _CONSOLE_SCREEN_BUFFER_INFO; begin ConsoleHandle := GetStdHandle(STD_OUTPUT_HANDLE); GetConsoleScreenBufferInfo(ConsoleHandle,ConsoleScreenBufferInfo); // Afficher le texte en bleu : SetConsoleTextAttribute(ConsoleHandle,FOREGROUND_BLUE); WriteLn('Ce texte est Bleu !!!'); // Afficher le texte en jaune (Avec Luminosité + Rouge + Vert = Jaune) : SetConsoleTextAttribute(ConsoleHandle,FOREGROUND_GREEN or FOREGROUND_RED or FOREGROUND_INTENSITY); ReadLn; // Rétabli les couleurs d'origine SetConsoleTextAttribute(ConsoleHandle,ConsoleScreenBufferInfo.wAttributes); end. |
Dans une application console le code de la section Finalization est exécuté si l'application se termine normalement. Par contre si l'utilisateur quitte la console en cliquant sur la croix de fermeture de fenêtre par exemple, le code de la section Finalization n'est pas exécuté.
L'utilisation de l'API SetConsoleCtrlHandler remédie à ce problème. On déportera dans ce cas le code de finalisation dans la fonction mise en place.
Code delphi : | Sélectionner tout |
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 30 31 | program console; {$APPTYPE CONSOLE} uses Windows, SysUtils; function ConProc(CtrlType : DWord) : Bool; stdcall; far; var S : String; begin case CtrlType of CTRL_C_EVENT : S := 'CTRL_C_EVENT'; CTRL_BREAK_EVENT : S := 'CTRL_BREAK_EVENT'; CTRL_CLOSE_EVENT : S := 'CTRL_CLOSE_EVENT'; CTRL_LOGOFF_EVENT : S := 'CTRL_LOGOFF_EVENT'; CTRL_SHUTDOWN_EVENT : S := 'CTRL_SHUTDOWN_EVENT'; else S := 'UNKNOWN_EVENT'; end; // Code de finalisation MessageBox(0, PChar(S + ' détecté'), 'Win32 Console', MB_OK); Result := True; end; begin SetConsoleCtrlHandler(@ConProc, True); Writeln('entrée pour terminer'); Readln; // Désactive le Handler // SetConsoleCtrlHandler(@ConProc, False); end. |
Il est parfois utile d'exécuter un programme console et de récupérer les informations résultantes sous Delphi.
On peut ainsi réutiliser facilement des programmes spécialisés tel que NET.EXE qui permet de récupérer un nombre important d'informations sur le poste local et les postes du réseau.
L'utilisation de la redirection des entrées/sorties d'une application console se fait via l'API CreateProcess en ayant pris soin de créer 2 handles de fichier avant son Appel.
Le process ne lira plus les informations en entrées à partir du clavier mais à partir du fichier hInputFile et écrira les résultats dans le fichier hOutputFile et pas sur l'écran.
Dans cet exemple on récupère les informations en fin d'exécution de l'application externe.
Le composant TDosCommand permet de rediriger la sortie standard d'une application console vers un TMEMO par exemple. Il affiche le résultat au fur et à mesure de l'exécution et non pas en fin de process.
Sous W9x et NT on utilise la fonction ShowWindow en association avec la fonction FindWindows de l'API. ShowWindow dans ce cas cache la fenêtre de la console à l'écran, dans la barre de tâche et dans le gestionnaire de tâches.
Dans un environnement NT utilisant les stratégies (policies) cela suffit pour éviter qu'un utilisateur puisse supprimer cette application console.
Code delphi : | Sélectionner tout |
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 | Var NouveauTitre : String; AncienTitre : Array[0..512]of char; begin // Mémorise le titre courant de la fenêtre GetConsoleTitle(PChar(@AncienTitre),SizeOf(AncienTitre)); // Construit un nom unique NouveauTitre:=Format('%d%d', [GetTickCount,GetCurrentProcessId]); // On donne un titre unique à la console SetConsoleTitle(Pchar(NouveauTitre)); Writeln('masque la fenêtre'); // Délai pour s'assurer que le titre est bien mis à jour. Au minimum Sleep(40 ) Sleep(2000); // Masque la fenêtre // FindWindows obtient le handle. Cet appel retourne le handle ou NIL si l'opération échoue. ShowWindow( FindWindow(NIL, PChar(NouveauTitre)),SW_HIDE); Writeln('Affiche la fenêtre'); Sleep(2000); // Affiche la fénêtre précédemment masquée ShowWindow( FindWindow(NIL,PChar(NouveauTitre) ),SW_SHOW); // Réattribue le titre originel SetConsoleTitle(PChar(@AncienTitre)); end. |
Code delphi : | Sélectionner tout |
1 2 3 4 5 6 7 8 9 10 11 | Function GetConsoleWindow:HWnd;Stdcall; external 'Kernel32.dll'; Var Titre : Array[0..512]of char; begin // Mémorise le titre courant de la fenêtre GetConsoleTitle(PChar(@Titre),SizeOf(Titre)); ... ShowWindow(GetConsoleWindow, SW_HIDE); ... end. |
Remplacez uniquement en début de fichier source la directive {$APPTYPE CONSOLE} par {$APPTYPE GUI}, c'est tout.
Noter que dans ce cas les handles standards utilisés par les fonctions Write et Read ne sont plus accessibles.
Leur utilisation provoquera des erreurs à l'exécution.
Code testé sous Windows 98 SE, NT, W2K et XP.
Il n'est pas possible dans une application console d'effacer l'écran comme le faisait la procédure clrstr de Turbo Pascal. La procédure cls ci-dessous explique comment le faire :
Code delphi : | Sélectionner tout |
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 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 | program consolecls; {$APPTYPE CONSOLE} uses SysUtils, Windows; procedure cls(hConsole : THandle); const coordScreen: TCoord=(X:0;Y:0); // Position d'origine du curseur var cCharsWritten: DWord; csbi: TConsoleScreenBufferInfo; dwConSize : DWord; begin // Obtient le nombre de caractères contenu dans le buffer courant if not GetConsoleScreenBufferInfo(hConsole, csbi ) then exit; dwConSize:=csbi.dwSize.X * csbi.dwSize.Y; // remplit la totalité de l'écran avec des espaces. if not FillConsoleOutputCharacter( hConsole,#32,dwConSize, coordScreen, cCharsWritten ) then exit; // Obtient l'attribut courant du texte. if not GetConsoleScreenBufferInfo( hConsole, csbi ) then Exit; // Affecte les attributs du buffer en conséquence. if not FillConsoleOutputAttribute( hConsole, csbi.wAttributes,dwConSize, coordScreen, cCharsWritten ) then exit; // Place le curseur aux coordonnées d'origine. SetConsoleCursorPosition( hConsole, coordScreen ); end; var HandleConsole : THandle; begin HandleConsole := GetStdHandle(STD_OUTPUT_HANDLE); if (HandleConsole <> INVALID_HANDLE_VALUE) then Cls(HandleConsole) else Write('Erreur lors de l''initialisation de l''application !'); |
Pour modifier l'affichage d'un programme console on utilise l'API SetConsoleDisplayMode.
Code delphi : | Sélectionner tout |
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 30 31 32 33 34 35 36 37 38 39 | program Fullscreen; //Bascule un programme console en mode plein écran. {$APPTYPE CONSOLE} uses SysUtils, Windows; const CONSOLE_FULLSCREEN_MODE = 1; // Mode plein écran CONSOLE_WINDOWED_MODE = 2; // Mode console ('fenêtré'). Function SetConsoleDisplayMode(ConsoleOutput : THandle; Flags : DWORD; NewScreenBufferDimensions : PCoord):BOOL; stdcall; external 'kernel32.dll'; Function SetConsoleScreen(Mode:Byte):Boolean; var ConsoleHandle: THandle; begin Result:=False; ConsoleHandle :=GetStdHandle(STD_OUTPUT_HANDLE); if ConsoleHandle <> INVALID_HANDLE_VALUE then Result:=SetConsoleDisplayMode(ConsoleHandle,Mode,Nil)=False end; Function SetFullScreen:Boolean; begin Result:=SetConsoleScreen(CONSOLE_FULLSCREEN_MODE); end; begin Writeln('Mode fenetre '); Readln; if SetFullScreen then Writeln('Mode plein ecran'); Readln; end. |
Il faut tout d'abord créer un fichier .rc (avec le bloc-note par exemple) et y écrire la ligne suivante:
Code other : | Sélectionner tout |
MAINICON ICON "[FichierIcone].ico"
Code other : | Sélectionner tout |
[RépertoireDelphi]\bin\brcc32.exe [MonFichierRessource].rc
Une fois ce fichier .res créé, il suffit alors de l'utiliser dans la source du projet en écrivant :
Code delphi : | Sélectionner tout |
{$R *.res}
Pour obtenir le handle de la fenêtre d'une application console, on peut modifier temporairement le titre de la fenêtre, puis utiliser la fonction FindWindow. On rétablit ensuite le titre initial de la fenêtre.
Code delphi : | Sélectionner tout |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 | function GetConsoleHwnd : HWND; var NewWindowTitle : string; OldWindowTitle : string; begin SetLength(NewWindowTitle, 1024); // Récupère le titre courant. GetConsoleTitle(PChar(OldWindowTitle), 1024); NewWindowTitle := Format('%d/%d', [GetTickCount, GetCurrentProcessId]); // Change le titre. SetConsoleTitle(PChar(NewWindowTitle)); // Attend pour que le titre de la fenêtre soit changé. Sleep(40); // Cherche le nouveau titre. Result := FindWindow(nil, PChar(NewWindowTitle)); // Restaure le titre original. SetConsoleTitle(PChar(OldWindowTitle)); end; |
Proposer une nouvelle réponse sur la FAQ
Ce n'est pas l'endroit pour poser des questions, allez plutôt sur le forum de la rubrique pour çaLes sources présentées sur cette page sont libres de droits et vous pouvez les utiliser à votre convenance. Par contre, la page de présentation constitue une œuvre intellectuelle protégée par les droits d'auteur. Copyright © 2024 Developpez Developpez LLC. Tous droits réservés Developpez LLC. Aucune reproduction, même partielle, ne peut être faite de ce site et de l'ensemble de son contenu : textes, documents et images sans l'autorisation expresse de Developpez LLC. Sinon vous encourez selon la loi jusqu'à trois ans de prison et jusqu'à 300 000 € de dommages et intérêts.