API Windows en C

Les boîtes de dialogue communes Choix de couleurs

CGI

- Titre : API Windows en C

- Auteur : CGI

- Parution : 5 juin 2005

- Licence : Copyright 2002-2020 CGi - Tous droits réservés CGi. Toutes reproduction, utilisation ou diffusion de ce document par quelque moyen que ce soit autre que pour un usage personnel doit faire l'objet d'une autorisation écrite de la part de l'auteur, propriétaire des droits intellectuels. Les codes sources de ce document sont fournis en l'état. L'utilisateur les utilise à ses risques et périls, sans garantie d'aucune sorte de la part de l'auteur. L'auteur n'est responsable d'aucun dommage subi par l'utilisateur pouvant résulter de l'utilisation ou de la distribution des codes sources de ce document. De la même façon, l'auteur n'est en aucun cas responsable d'une quelconque perte de revenus ou de profits, ou de données, ou de tous dommages directs ou indirects, susceptibles de survenir du fait de l'utilisation des codes sources de ce document, quand bien même l'auteur aurait été averti de la possibilité de tels dommages. L'utilisation des codes sources de ce document vaut acceptation par l'utilisateur des termes de la licence ci-dessus.

Sommaire

- I. Introduction

- II. Préparation de l'exemple

- III. La boîte de dialogue de choix couleur

- IV. Code complet

I - Introduction

En annexe au chapitre : « Les boîtes de dialogue communes », voici une mise en application de la boîte de dialogue de choix de couleur.

II - Préparation de l'exemple

Sur la base du même exemple. Nous ajoutons une option avec le texte « Couleur du texte… » au sous-menu. L'option « Couleur du texte… » sera identifiée par la constante IDM_TEXTCOLOR :

#define IDM_QUIT 1
#define IDM_OPEN 2
#define IDM_TEXTCOLOR 3

/*...       */

hSousMenu = CreateMenu();
AppendMenu(hSousMenu, MF_STRING, IDM_OPEN, "Ouvrir...");
AppendMenu(hSousMenu, MF_STRING, IDM_TEXTCOLOR, "Couleur du texte...");
AppendMenu(hSousMenu, MF_SEPARATOR, 0, NULL);
AppendMenu(hSousMenu, MF_STRING, IDM_QUIT, "Quitter");

Nous nous en servirons pour changer la couleur du texte du contrôle d'édition multiligne.

Pour changer cette couleur, nous emploierons la fonction SetTextColor. Elle reçoit comme paramètre un handle de contexte de périphérique et une couleur.

Mais, comment obtenir un contexte de périphérique pour le contrôle d'édition ?

Windows avant d'effectuer le dessin des contrôles envoie un message à sa fenêtre parent : WM_CTLCOLOREDIT pour le contrôle d'édition et y joint son handle de contexte de périphérique (HDC) dans le paramètre wParam et son handle de fenêtre dans le paramètre lParam.

case WM_CTLCOLOREDIT:
if((HWND)lParam == hEdit)
{
SetTextColor((HDC)wParam, TextColor);
SetBkColor((HDC)wParam, BkEditcolor);
return EditBrush;
}
return DefWindowProc(hwnd, uMsg, wParam, lParam);

Quand on traite ce message, on doit retourner un pinceau. Dans l'exemple si l'on est en train de traiter ce message pour notre contrôle d'édition, nous changeons la couleur de son texte, de son fond et retournons un pinceau de la même couleur que le fond. Ce pinceau ayant été initialisé à la création de la fenêtre principale :

static HBRUSH EditBrush;
static COLORREF BkEditcolor;
static COLORREF TextColor = 0;

/*...       */
case WM_CREATE:
{
BkEditcolor = GetSysColor(COLOR_WINDOW);
EditBrush = CreateSolidBrush(BkEditcolor);

Si nous ne traitons pas le message WM_CTLCOLOREDIT, c'est DefWindowProc qui met les valeurs par défaut pour le contrôle.

III - La boîte de dialogue de choix couleur

Comme toutes les boîtes de dialogue communes, on utilise une structure (CHOOSECOLOR) pour l'initialiser :

static COLORREF TextColor = 0;

/*...       */

CHOOSECOLOR cc;
static COLORREF acrCustClr[16];

ZeroMemory(&cc, sizeof(CHOOSECOLOR));
cc.lStructSize = sizeof(CHOOSECOLOR);
cc.hwndOwner = hwnd;
cc.lpCustColors = NULL;
cc.lpCustColors = (LPDWORD) acrCustClr;
cc.rgbResult = TextColor;
cc.Flags = CC_FULLOPEN | CC_RGBINIT;

Puis on appelle la fonction ChooseColor pour ouvrir la boîte de dialogue :

if (ChooseColor(&cc)==TRUE)
{
TextColor = cc.rgbResult;
PostMessage(hEdit,WM_SETREDRAW,TRUE,0);
}

Elle retourne la couleur choisie dans le champ rgbResult de la variable de type CHOOSECOLOR qu'elle a reçue comme paramètre. Nous nous en servons pour affecter la variable TextColor. La même que l'on avait utilisée pour changer la couleur du contrôle précédemment.

IV - Code complet

#include <windows.h>

#define IDM_QUIT 1
#define IDM_OPEN 2
#define IDM_TEXTCOLOR 3

HINSTANCE hinst;

LRESULT CALLBACK MainWndProc(HWND, UINT, WPARAM, LPARAM);

int WINAPI WinMain(HINSTANCE hinstance, HINSTANCE hPrevInstance,
LPSTR lpCmdLine, int nCmdShow)
{
HWND hwnd;
MSG msg;
WNDCLASS wc;
HMENU hMenu, hSousMenu;

hinst = hinstance;

wc.style = 0 ;
wc.lpfnWndProc = MainWndProc;
wc.cbClsExtra = 0;
wc.cbWndExtra = 0;
wc.hInstance = hinstance;
wc.hIcon = NULL;
wc.hCursor = LoadCursor(NULL, IDC_ARROW);
wc.hbrBackground = NULL;
wc.lpszMenuName =  NULL;
wc.lpszClassName = "MaWinClass";

if(!RegisterClass(&wc)) return FALSE;

hSousMenu = CreateMenu();
AppendMenu(hSousMenu, MF_STRING, IDM_OPEN, "Ouvrir...");
AppendMenu(hSousMenu, MF_STRING, IDM_TEXTCOLOR, "Couleur du texte...");
AppendMenu(hSousMenu, MF_SEPARATOR, 0, NULL);
AppendMenu(hSousMenu, MF_STRING, IDM_QUIT, "Quitter");
hMenu  = CreateMenu();
AppendMenu(hMenu,MF_POPUP,(UINT)hSousMenu,"Fichier");

hwnd = CreateWindow("MaWinClass", "Titre", WS_OVERLAPPEDWINDOW,
CW_USEDEFAULT, CW_USEDEFAULT, 640, 300,
NULL, hMenu, hinstance, NULL);
if (!hwnd)  return FALSE;

ShowWindow(hwnd, nCmdShow);

while (GetMessage(&msg, NULL, 0, 0))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
return msg.wParam;
}

/******************************************************************************/

LRESULT CALLBACK MainWndProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
static HWND hEdit;
static HBRUSH EditBrush;
static COLORREF BkEditcolor;
static BOOL EditNotChg = TRUE;
static COLORREF TextColor = 0;

switch (uMsg)
{
case WM_CREATE:
{
HFONT hFont;

hEdit = CreateWindow("edit", "Texte", WS_CHILD | WS_VISIBLE |
ES_MULTILINE | ES_WANTRETURN | WS_VSCROLL,
0, 0, 0, 0, hwnd, NULL, hinst, NULL);

BkEditcolor = GetSysColor(COLOR_WINDOW);
EditBrush = CreateSolidBrush(BkEditcolor);
hFont = (HFONT)GetStockObject(ANSI_FIXED_FONT);
SendMessage(hEdit,WM_SETFONT,(UINT)hFont,TRUE);
SendMessage(hEdit, EM_SETMARGINS, EC_LEFTMARGIN | EC_RIGHTMARGIN,
MAKELONG(5, 5));
return 0;
}

case WM_CLOSE:
if(EditNotChg ||
MessageBox(hwnd,"Le texte a été modifié.\r\nEtes vous sûr de \
vouloir fermer l'application ?"
,"Question ?",MB_YESNO | MB_ICONQUESTION ) == IDYES)
DestroyWindow(hwnd);
return 0;

case WM_COMMAND:
if(LOWORD(wParam) == IDM_OPEN)
{
OPENFILENAME ofn;
CHAR szFile[256]={0};

ZeroMemory(&ofn, sizeof(OPENFILENAME));
ofn.lStructSize = sizeof(OPENFILENAME);
ofn.hwndOwner = hwnd;
ofn.lpstrFile = szFile;
ofn.nMaxFile = sizeof(szFile);
ofn.lpstrFilter =
"Fichier source C\0*.c\0Fichier source CPP\0*.cpp\0";
ofn.nFilterIndex = 1;
ofn.Flags =
OFN_PATHMUSTEXIST | OFN_FILEMUSTEXIST | OFN_HIDEREADONLY;

if (GetOpenFileName(&ofn)==TRUE)
{
HANDLE hf;
DWORD FileSize,nbcharRead ;
char *buffer;

hf = CreateFile(szFile, GENERIC_READ, 0,NULL,
OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
FileSize = GetFileSize(hf, NULL);
buffer = (char*)LocalAlloc(LMEM_FIXED, FileSize+1);
ReadFile(hf, buffer, FileSize, &nbcharRead, NULL) ;
buffer[FileSize] = 0;
SendMessage(hEdit, WM_SETTEXT, 0, (LPARAM)buffer);
LocalFree(buffer);
CloseHandle(hf);
}
} /*if IDM_OPEN*/

if(LOWORD(wParam) == IDM_TEXTCOLOR)
{
CHOOSECOLOR cc;
static COLORREF acrCustClr[16];

ZeroMemory(&cc, sizeof(CHOOSECOLOR));
cc.lStructSize = sizeof(CHOOSECOLOR);
cc.hwndOwner = hwnd;
cc.lpCustColors = NULL;
cc.lpCustColors = (LPDWORD) acrCustClr;
cc.rgbResult = TextColor;
cc.Flags = CC_FULLOPEN | CC_RGBINIT;
if (ChooseColor(&cc)==TRUE)
{
TextColor = cc.rgbResult;
PostMessage(hEdit,WM_SETREDRAW,TRUE,0);
}
} /*if IDM_TEXTCOLOR*/

if(LOWORD(wParam) == IDM_QUIT) PostMessage(hwnd, WM_CLOSE,0,0);
if(HIWORD(wParam) == EN_CHANGE) EditNotChg = FALSE;
return 0;

case WM_CTLCOLOREDIT:
if((HWND)lParam == hEdit)
{
SetTextColor((HDC)wParam, TextColor);
SetBkColor((HDC)wParam, BkEditcolor);
return EditBrush;
}
break;

case WM_SIZE:
MoveWindow(hEdit, 0, 0, LOWORD(lParam), HIWORD(lParam), TRUE);
return 0;

case WM_DESTROY:
DeleteObject(EditBrush);
PostQuitMessage(0);
return 0;
}

return DefWindowProc(hwnd, uMsg, wParam, lParam);
}

J'ai testé les compilations avec C++ Builder et DevC++.

À vos PC.

CGi

Retour au sommaire.