main vs winmain

 

 

main

Classiquement, un programme en C doit contenir une procédure main().

Il s'agit de la procédure qui sera lancée automatiquement par le système après chargement du programme correspondant.

 

int main(int argc, char* argv[])

{

...Le code

}

En entrée:

argc contient le nombre de paramètres "dans" argv. Il est positionné au minimum à 1 car il y a au minimum 1 paramètre de passé...

argv[] tableau de pointeurs sur une liste de chaines de caractères (chaines terminées classiquement par 0). Ce tableau s'arrête lorsque vous aurez trouvé dans ce tableau l'élément positionné à 0.

Le premier élément étant toujours existant est contenant le nom de la commande (nom du programme) (d'où argc au minimum à 1).

Les éléments suivant sont les arguments passés au programme.

 

En sortie:

Vous devriez faire un return 0 si tout votre traitement c'est bien déroulé, sinon un code erreur pour préciser le problème.

 

WinMain

Mais évidemment, chez Microsoft, ce point d'entrée est modifié (en tout cas pour les applications Windows), il s'agit de WinMain()

int APIENTRY WinMain(HINSTANCE hInstance,
HINSTANCE hPrevInstance,
LPSTR lpCmdLine,
int nCmdShow)
{

...Le code

}

En entrée:

hInstance est l'instance de votre programme.

hPrevInstance est de nos jours positionnés à 0, dans les versions antérieures de Windows, il s'agissait de l'instance de votre programme lancé avant celui en cours et non terminé. Permettait de savoir si votre programme était la première instance ou non.

lpCmdLine contient la liste des paramètres de votre application. Càd les arguments passés mais contrairement à main(), sans le nom du programme. Les arguments sont séparés par des espaces.

nCmdShow contient la valeur permettant d'indiquer comment doit s'afficher votre fenêtre au lancement de votre programme (iconifié, plein écran, ...)

 

 

Récupérer la ligne de commande

Hormis depuis la procédure WinMain, il sera possible de récupérer la ligne de paramètres via la fonction GetCommandLine:

LPTSTR WINAPI GetCommandLine(void);

Image non trouvée ! Contrairement à lpCmdLine, la fonction va retourner le nom du programme entre guillemets ("nomprog") en plus des paramètres.

En sortie: La fonction retourne un pointeur sur la chaine des paramètres.

 

Image non trouvée !Il existe sous Windows deux manières de stocker une chaîne de caractères: ANSI ou UNICODE. Généralement transparent pour nos petites applications, il peut s'avérer important ici, surtout si vous voulez utiliser la fonction CommandLineToArgvW dont les explications vont suivre:

La fonction GetCommandLine lance en fait GetCommandLineA ou GetCommandLineW suivant que vous êtes en mode ANSI ou UNICODE.

Ce principe de fonction se terminant par A ou W existe un peu partout dans Windows...

Ces fonctions font donc la même chose que GetCommandLine, mais retournent une chaîne de caractères dans le format correspondant. Par défaut il est fort probable que vous soyez en ANSI. Une variable prépo vous l'indiquera, elle se nomme : UNICODE. Si elle n'existe pas vous êtes en ANSI. Vous pouvez la créez vous mêmes, mais il faudra la déclarer avant l'include à windows.h. Ainsi, tous les appels suivants de Windows se feront avec les fonctions équivalentes pour l'UNICODE

 

Un exemple d'appel qui va afficher les paramètres non par lpCmdLine, mais via la fonction GetCommandLine().

#include <windows.h>

int APIENTRY WinMain(HINSTANCE hInstance,
HINSTANCE hPrevInstance,
LPSTR lpCmdLine,
int nCmdShow)
{

LPSTR chaine;

chaine = GetCommandLine ();

MessageBox (NULL,chaine, "Ligne de commande passé", MB_OK);


return 0;

}

 

Transformer lpCmdLine en argv[]

Un fonction permet de convertir lpCmdLine en argv[]. Il s'agit de la fonction CommandLineToArgvW :

LPWSTR* CommandLineToArgvW(
__in LPCWSTR lpCmdLine,
__out int *pNumArgs
);

En entrée:

lpCmdLine provenant simplement de la fonction GetCommandLineW().

pNumArgs : Nombre d'arguments retournés (sachant que la valeur minimale est de 1 car le premier argument est le nom du programme).

Image non trouvée !Si vous passez "" comme paramètre à la place de lpCmdLine, la fonction CommandLineToArgvW() retournera le nom du programme (sans les guillemets car il n'y en a pas dans argv à l'origine).

 

En sortie:

Un tableau sur une liste de pointeurs vers une chaîne de caractères contenant les arguments (chaînes terminées chacunes par 0 pour indiquer la fin de la chaîne). Le dernier élément du tableau étant à 0 afin d'indiquer la fin de la liste des arguments.

Image non trouvée !L'utilisation de lpCmdLine de WinMain n'est pas possible tel quel, puisque ce paramètre ne contient pas le nom du programme. Nom qui est nécessaire dans argv. De plus, la fonction CommandLineToArgvW attend ce paramètre au format unicode, il faut donc utiliser GetCommandLineW().

Image non trouvée !Ces chaînes de caractères sont au format UNICODE (WCHAR sous Windows) et non ANSI ! Le tableau n'est donc pas directement compatible pour des fonctions utilisant argv qui est au format char (ANSI) et non WCHAR de Windows (UNICODE). Il faudra éventuellement les convertir

Image non trouvée !Il sera nécessaire de libérer l'espace alloué en sortie. Vous utiliserez simplement LocalFree(tableau de la liste en sortie)

 

Voici un exemple récapitulant les différentes fonctions

Image non trouvée !

Eventuellement, passez un paramètre à votre programme...