FAQ Win32
FAQ Win32Consultez toutes les FAQ
Nombre d'auteurs : 11, nombre de questions : 72, dernière mise à jour : 16 juin 2021
- Quelle est la différence entre WM_CLOSE et WM_DESTROY ?
- Peut-on détruire une fenêtre (hWnd) avec SendMessage(hWnd, WM_DESTROY, 0, 0) ?
- Comment définir de nouveaux messages ?
- Comment associer une valeur à une fenêtre ?
- Quelle est la différence entre une fenêtre et une boîte de dialogue ?
- Je suis sous XP (ou Vista, etc.) mais mes contrôles ressemblent toujours à ceux de Windows 95 ! Pourquoi ?
- Commment afficher une image ?
WM_CLOSE est envoyé à l'application quand Windows reçoit une demande de fermeture d'une fenêtre de cette application. WM_DESTROY, pour sa part, est envoyé pour indiquer qu'une fenêtre de l'application a été détruite (mais pas encore totalement puisqu'à ce stade, les fenêtres enfants par exemple, s'il y en a, n'ont pas encore été détruites).
Non. Cela indique tout simplement à l'application de se comporter comme si la fenêtre avait été détruite. Pour détruire une fenêtre, il faut appeler DestroyWindow (la "fin" de CreateWindow). A noter que cette fonction est implicitement appelée dans certains cas, par exemple quand on laisse à DefWindowProc le soin de traiter le message WM_CLOSE. Ne pas oublier non plus que DestroyWindow est récursive, c'est-à-dire que la destruction d'une fenêtre entraîne la destruction de toutes ses fenêtres enfants (mais également la destruction du menu, etc.).
Les messages Windows sont ni plus ni moins que des entiers donc n'importe quel entier peut définir un message, par exemple #define WM_MONMESSAGE 0xBFFF. On ne peut pas cependant utiliser vraiment n'importe quelle valeur car certaines sont déjà utilisées par Windows.
Windows garantit que les messages systèmes ont tous des valeurs comprises entre 0 et WM_USER - 1. Les valeurs comprises entre WM_USER et WM_APP - 1 sont réservées à être utilisées par une application pour définir des messages spécifiques d'une classe de fenêtre privée (chaque classe interprète donc
un message à sa façon, c'est-à-dire que X peut avoir un sens pour une classe donnée et un autre ou aucun sens pour une classe). Certaines classes de fenêtre prédéfinies (boîtes de dialogue, contrôles, etc.) utilisent également des messages dans cette plage et enfin, les valeurs comprises entre WM_APP
et 0xBFFF sont réservées à être utilisées par une application pour définir ses propres messages.
Il y a aussi la fonction RegisterWindowMessage qui permet de créer un message possédant une valeur garantie être unique dans tout le système. Cette valeur sera comprise entre 0xC000 et 0xFFFF.
En utilisant SetWindowLong (qui ne doit être utilisée que dans les versions 32 bits) ou SetWindowLongPtr (utilisable aussi bien sous 32 que 64 bits).
Une boîte de dialogue est une fenêtre appartenant à la classe "#32770" bref : une fenêtre, mais une fenêtre n'est pas toujours une boîte de dialogue. Une fenêtre peut être : une fenêtre, un bouton, une boîte de dialogue, un menu, etc.
Vous utilisez les contrôles standards. Pour avoir l'effet attendu, vous devez utiliser les contrôles de votre version de Windows, appelés contrôles communs.
Lien : Les contrôles communs
Si c'est une image bitmap, c'est plutôt trivial avec DrawState ou BitBlt par exemple. Si l'image n'est pas nécessairement un bitmap, il va falloir utiliser une API de plus haut niveau que la GDI. GDI+ par exemple
mais cette API est plutôt destinée aux programmeurs C++. Voici donc une méthode qui peut être utilisée avec n'importe quel langage de programmation sous Windows.
On crée un objet COM encapsulant l'image qu'on veut afficher à l'aide de OleLoadPicture ou OleLoadPicturePath (inclure olectl.h) si l'image sera chargé depuis un fichier puis on appelle la méthode Render de l'interface IPicture de cet objet.
L'image est représentée en interne dans un système de coordonnées dans lequel les axes x et y sont orientés respectivement vers la droite et vers le haut, vu de l'utilisateur.
La méthode la plus naturelle pour copier l'image vers un DC est donc de spécifier les points (x1, y1) et (x2, y2) qui correspondent respectivement au coin inférieur gauche et
au coin supérieur droit du rectangle destiné à contenir l'image. Ainsi, on peut avoir une seule fonction compatible avec tous les modes possibles (MM_TEXT, MM_HIMETRIC, modes personnalisés, etc.).
Le code pour charger une image est le suivant, en supposant qu'on veut charger l'image depuis un fichier (c:\image.jpg) :
IPicture *
pIPicture;
OleLoadPicturePath
(
L"
c:
\\
image.jpg
"
, NULL
, 0
, 0
, &
IID_IPicture, &
pIPicture);
Et pour l'afficher :
void
RenderPicture
(
HDC hDC, LONG x1, LONG y1, LONG x2, LONG y2, IPicture *
pIPicture)
{
OLE_XSIZE_HIMETRIC xsize;
OLE_YSIZE_HIMETRIC ysize;
/* xsize et ysize représentent la taille de l'image. (x1, y1) et (x2, y2) spécifient respécivement */
/* le coin inférieur gauche et le coin supérieur droit du rectangle du DC sur lequel on veut copier */
/* l'image. */
pIPicture->
lpVtbl->
get_Width
(
pIPicture, &
xsize);
pIPicture->
lpVtbl->
get_Height
(
pIPicture, &
ysize);
pIPicture->
lpVtbl->
Render
(
pIPicture, hDC, x1, y1, x2 -
x1, y2 -
y1, 0
, 0
, xsize, ysize, NULL
);
}
Ces codes sont très spécifiques au langage C mais facilement traductible en C++ ou autre langage. N'oubliez pas de mettre CoInitialize(NULL) et CoUninitialize() respectivement en début et en fin de votre
programme car cela est requis par COM. Vous devez également libérer l'objet image avant l'appel de CoUninitialize :
pIPicture->lpVtbl->Release(pIPicture).
Lien : Qu'est-ce que COM ?