C/c++ sous windows sans mfc - tutorial 2 : ecriture dans une fenetre

Soyez le premier à donner votre avis sur cette source.

Snippet vu 16 255 fois - Téléchargée 31 fois

Contenu du snippet

Dans ce tutorial qui fait suite à C/C++ SOUS WINDOWS SANS MFC, nous allons voir comment écrire du texte dans une fenêtre.

Source / Exemple :


//TUTORIAL AFFICHAGE DE TEXTE DANS UNE FENETRE WINDOWS
Dans le tutorial précédent (C/C++ sous Windows sans MFC) il était expliqué comment créer une fenêtre sous Windows, avec une boucle de traitement de messages, et une procédure de traitement de ces messages.
Dans ce tutorial nous allons voir comment écrire du texte dans cette fenêtre, et comment l'afficher.

Dans des programmes écrits dans des langages tels que le Visual Basic, ou encore en C sous DOS, pour afficher du texte, il suffisait d'appeler une fonction d'affichage et de lui indiquer la chaine de caractère à faire apparaitre à l'écran. On pouvait agrémenter cet affichage d'options relatives à la couleur d'écriture, la hauteur des lettres.

Dans Windows, pour afficher du texte dans une fenêtre, c'est un peu différend. On ne va pas se servir de l'affichage direct. On va demander à Windows de redessiner la fenêtre et lors du message de raffraichissement de cette fenêtre, on va demander à ce que soit écrit le texte.

Une fenêtre qui s'affiche à l'écran demande souvent à être redessinée. Cela se produit par exemple lorsqu'une autre fenêtre passe devant, lorsqu'on déplace la fenêtre, lorsqu'on la diminue ou qu'on change ses dimensions. Losque cela se produit, Windows envoie le message WM_PAINT. C'est donc dans WM_PAINT que l'on doit placer tout ce que l'on veut qu'il soit dessiné dans notre fenêtre. A noter que les éléments de fenêtre basiques (boutons de fermeture, cadre...) sont redessinés par Windows lors de WM_PAINT sans que l'on ait besoin de le recoder.

Le message WM_PAINT apparait donc ainsi:
case WM_PAINT:
{
........
}

A l'intérieur, avant d'écrire notre chaine de caractère, il va falloir paramétrer certaines choses.
Tout d'abbord, lorsqu'on dit dessiner dans une fenêtre, il faut comprendre dessiner sur le support prévu à l'écriture de cette fenêtre. C'est comme pour une feuille de papier, n'écrit pas dans la marge par exemple. La partie d'une fenêtre dans laquelle on doit écrire est la partie qui par défaut est blanche. Cette partie ne s'identifie pas par la valeur HWND de la fenêtre mais par une valeur de type HDC. Le HDC est la partie du HWND dans laquelle on peut dessiner, ecrire...

On créé donc en premier lieu une variable hDC
HDC hDC;

Ensuite, on va attribuer à notre hDC la partie dessin de notre fenêtre.
hDC = GetWindowDC(hFenetre);  //hFenetre est de type HWND

Maintenant, on va créer une variable structure PAINTSTRUCT. Il s'agit d'un élément nécessaire pour peindre la zone cliente de notre fenêtre. Il n'est pas nécessaire d'en changer les paramètres

PAINTSTRUCT Ps;

Maintenant que nous disposons de notre fenêtre, de son HDC et de notre élément PAINTSTRUCT, on va commencer à peindre.

Le début du dessin de notre texte va commencer par la fonction suivante : BeginPaint

hDC = BeginPaint( hFenetre, &Ps);

Maintenant, on va placer l'écriture de notre texte avec la fonction TextOut
TextOut (hDC, 10, 10, "Voici notre Phrase", strlen("Voici notre Phrase")); 			
La fonction TextOut va se charger d'écrire aux coordonnées 10,10 de notre fenêtre la phrase "Voici notre Phrase", strlen indique la taille de la chaine.

Enfin, il faut mettre fin à la peinture avec la fonction EndPaint :
EndPaint (hFenetre, &Ps);

voila, notre évènement WM_PAINT est complet. Maintenant, lorqeu la fenêtre aura à être redessinée, notre phrase apparaitra. Il manque néamoins quelque chose. 
On ne veut pas necessairement attendre que notre programme reçoive une demande de redessiner la fenêtre dans 15 ans, lorsque une autre fenêtre passera par dessus par exemple. On veut que notre texte s'affiche tout de suite. Il va falloir indiquer explicitement à Windows qu'on veut que notre fenêtre se redessine tout de suite. Ceci se
fait en indiquant à Windows que la fenêtre n'est pas valide. 
Ainsi, dans la procédure générale de dessin des fenêtres et contrôles, il faut placer la fonction InvalidateRect:
InvalidateRect (hFenetre, 0, FALSE);

Voici ci dessous le programme complet associant le tutorial C/C++ sous Windows sans MFC avec ce qui vient d'être vu:

#include <windows.h>

int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nShowCmd);

LRESULT CALLBACK WinProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam);
bool stop = false; 

int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nShowCmd)
{
HWND hFenetre;
MSG MessagesAEnvoyer;

WNDCLASS Fenetre; 
Fenetre.lpszMenuName =NULL;
Fenetre.cbClsExtra  =0;
Fenetre.cbWndExtra =0;
Fenetre.hInstance = hInstance; 
Fenetre.lpfnWndProc = WinProc;
Fenetre.lpszClassName = "FENETRE DE TYPE A MOI";
Fenetre.style =  CS_VREDRAW | CS_HREDRAW; 
Fenetre.hbrBackground = (HBRUSH) GetStockObject(WHITE_BRUSH);
Fenetre.hIcon =(HICON)  LoadIcon(hInstance, IDI_APPLICATION);
Fenetre.hCursor =(HCURSOR)  LoadCursor(hInstance, IDC_ARROW);

RegisterClass(&Fenetre);

hFenetre = CreateWindow("FENETRE DE TYPE A MOI", "Voici la fenêtre", WS_OVERLAPPEDWINDOW, 200, 200, 300, 250, NULL, NULL, hInstance, NULL);

ShowWindow(hFenetre,nShowCmd);

InvalidateRect(hFenetre, 0, FALSE);

while (GetMessage(&MessagesAEnvoyer, hFenetre, 0, 0))
{ 
	TranslateMessage (&MessagesAEnvoyer); 
	DispatchMessage (&MessagesAEnvoyer);
}

return 0; 
}

LRESULT CALLBACK WinProc (HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
	switch (uMsg)
	{
		case WM_DESTROY:
		{
			stop = true ;
			PostQuitMessage(0);
			return 0;
		}
		case WM_PAINT:
		{
			HDC hDC;
			hDC = GetWindowDC(hWnd);
			PAINTSTRUCT Ps;
			hDC = BeginPaint(hWnd, &Ps);
			TextOut (hDC, 10, 10,"Voici notre Phrase", strlen("Voici note Phrase"));
			EndPaint(hWnd, &Ps);
			return 0;
		}
	}
	return DefWindowProc(hWnd, uMsg, wParam, lParam); 
}
			

Options:
Avant d'écrire le texte avec la procédure TextOut, on peut utiliser diverses options
Par exemple utiliser des couleurs de texte différentes que celles par défaut avec la fonction SetTextColor
SetTextColor (hDC,RGB(255,0,0)); //Ecrit le text des commandes TextOut suivantes en rouge.
SetBkColor(hDC, RGB(255,0,0)); //Ecrit le texte sur un fond rouge.

 ou encore : 

HFONT Font;
Font = CreateFont(20, 30, 50, 50, FW_REGULAR, TRUE, FALSE, FALSE, DEFAULT_CHARSET, OUT_DEFAULT_PRECIS, CLIP_DEFAULT_PRECIS, 												DEFAULT_QUALITY, DEFAULT_PITCH, "Time New Roman");
//Crée une police de type Times News Roman dans laquelle la taille des lettres sera 20,30. Les valeurs TRUE, FALSE, FALSE indique les styles italic non souligné. Je vous invite à voir les autres options sur MSDN (options notament liées à l'orientation du texte correspondant ici aux paramètres 50,50.
SelectObject(hDC, (HGDIOBJ) Font); //Utilise cette font créee pour les TextOut qui suivent.

Voilà pour ce qui est de l'écriture de textes dans une fenêtre avec WM_PAINT. A noter que WM_PAINT sert aussi pour le dessin de tout autre graphique.
Bon courage.

A voir également

Ajouter un commentaire

Commentaires

akadis
Messages postés
2
Date d'inscription
jeudi 22 juillet 2004
Statut
Membre
Dernière intervention
12 octobre 2007

Dans la boucle d'écoute des évènements si on remplace le
while (GetMessage(&MessagesAEnvoyer, hFenetre, 0, 0))
par
while (GetMessage(&MessagesAEnvoyer, NULL, 0, 0))
Ca résoud le problème :)
cs_LaPatoshe
Messages postés
53
Date d'inscription
mercredi 6 août 2003
Statut
Membre
Dernière intervention
19 décembre 2009

Bonsoir, il y a un moment maintenant que j'avais écrit ce code, essaies de voir ce que cela donne en enlevant les return 0 de la partie des traitement des messages.
Ainsi, le retour de boucle se fera en renvoyant les paramètres DefWinProc.
akadis
Messages postés
2
Date d'inscription
jeudi 22 juillet 2004
Statut
Membre
Dernière intervention
12 octobre 2007

Bonjour, je travaille sous Visual C++ et je rencontre aussi ce problème. C'est à dire que lorsque je ferme la fenêtre soit en cliquant sur la croix, soit en cliquant sur l'icône puis en faisant Fermer, la fenêtre disparait mais le processus tourne toujours.
Existe t'il un façon "propre" (sans killer le processus) pour terminer l'application ?
cs_LaPatoshe
Messages postés
53
Date d'inscription
mercredi 6 août 2003
Statut
Membre
Dernière intervention
19 décembre 2009

Bonjour, cela veut il dire que la fenêtre se ferme, mais que le programme tourne toujours et apparait encore de ce fait dans les processus actifs de Windows ?
tennisdev44
Messages postés
1
Date d'inscription
mercredi 17 mai 2006
Statut
Membre
Dernière intervention
15 avril 2007

Bonjour,
Quand je place PostQuitMessage(0) dans WM_DESTROY, le programme ne se ferme pas complètement. Quand je le met dans WM_CLOSE ça ne change rien...
Je travaille sous dev c++ en projet Win 32 GUI


Sauriez vous pourquoi le programme ne se ferme pas complètement?

Vous n'êtes pas encore membre ?

inscrivez-vous, c'est gratuit et ça prend moins d'une minute !

Les membres obtiennent plus de réponses que les utilisateurs anonymes.

Le fait d'être membre vous permet d'avoir un suivi détaillé de vos demandes et codes sources.

Le fait d'être membre vous permet d'avoir des options supplémentaires.