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

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

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.