OVH Cloud OVH Cloud

Dialog et WM_PAINT

8 réponses
Avatar
lgloub
Encore moi :(

Je voudrais afficher une image en fond d'une dialog (créée par DialogBox).
Sur le WM_PAINT de la callback dialog, j'entame un BeginPaint, bref le
truc classique, mais l'image n'apparaît pas.
Le WM_PAINT d'une callback dialog est-il différent du WM_PAINT d'une
wndProc ? Dois-je sous-classer la dialog ?

8 réponses

Avatar
Christian ASTOR
lgloub wrote:

Je voudrais afficher une image en fond d'une dialog (créée par DialogBox).
Sur le WM_PAINT de la callback dialog, j'entame un BeginPaint, bref le
truc classique, mais l'image n'apparaît pas.
Le WM_PAINT d'une callback dialog est-il différent du WM_PAINT d'une
wndProc ? Dois-je sous-classer la dialog ?



Non, c'est pareil.
Une des petites différences est juste que le style de la classe de Dlg
par défaut (#32770) n'a pas des flags comme CS_HREDRAW, CS_VREDRAW, ce
qui fait que le WM_PAINT n'est pas appelé qd on resize (soit
subclassing, soit SetClassLong() ds ce cas)
Avatar
lgloub
> Non, c'est pareil.
Une des petites différences est juste que le style de la classe de Dlg
par défaut (#32770) n'a pas des flags comme CS_HREDRAW, CS_VREDRAW, ce
qui fait que le WM_PAINT n'est pas appelé qd on resize (soit
subclassing, soit SetClassLong() ds ce cas)



Merci pour ces précisions.
Mais alors je comprends pas pourquoi l'image s'affiche pas :

case WM_PAINT:{

if(g_hBmDlgBack != NULL){
BITMAP bm;
PAINTSTRUCT ps;

HDC hdc = BeginPaint(hWnd, &ps);
HDC hdcMem = CreateCompatibleDC(hdc);
HBITMAP hbmOld = SelectObject(hdcMem, g_hBmDlgBack);
GetObject(g_hBmDlgBack, sizeof(bm), &bm);
BitBlt(hdc, 0, 0, bm.bmWidth, bm.bmHeight, hdcMem, 0,
0, SRCCOPY);
SelectObject(hdcMem, hbmOld);
DeleteDC(hdcMem);
EndPaint(hWnd, &ps);
return(TRUE);
}
}
break;

Apparemment il n'y a pas de WM_CREATE sur une dialog. J'ai donc essayé
de charger la bitmap à d'autres endroits (WM_INITDIALOG, WM_PAINT,
WM_CREATE de la winmain), mais rien ne marche.
if(g_hBmDlgBack == NULL)
g_hBmDlgBack = LoadBitmap(g_hInstance,
MAKEINTRESOURCE(ID_BTM_DLGBACK));

Doit y avoir une erreur dans mon WM_PAINT ?
Avatar
Christian ASTOR
lgloub wrote:

Doit y avoir une erreur dans mon WM_PAINT ?



Non, il est correct (à part return TRUE au lieu de FALSE, mais pas grave)
Si je le copie tel quel ds 1 de mes Dlg, ça marche très bien.
(s'assurant que g_hBmDlgBack est bien renseigné, ds le WM_INITDIALOG)
Sorry, pas d'autres idées sans plus d'éléments...
Avatar
lgloub
> Non, il est correct (à part return TRUE au lieu de FALSE, mais pas grave)
Si je le copie tel quel ds 1 de mes Dlg, ça marche très bien.
(s'assurant que g_hBmDlgBack est bien renseigné, ds le WM_INITDIALOG)
Sorry, pas d'autres idées sans plus d'éléments...



Effectivement, la ressource veut un bmp, j'avais mis un jpg... :(
Autre question : je dois apparemment utiliser DeleteObject pour libérer
la bitmap. Je le fais sur le WM_CLOSE, ou le mot-clé DISCARDABLE assure
la libération ?

En tout cas merci pour ta constante aide ;)
Avatar
lgloub
Christian ASTOR wrote:
DISCARDABLE est un reliquat 16-bits, gardé pour compatibilité ascendante.
On libère ds le WM_DESTROY ou WM_NCDESTROY.



ok, merci.
Avatar
Christian ASTOR
lgloub wrote:

Autre question : je dois apparemment utiliser DeleteObject pour libérer
la bitmap. Je le fais sur le WM_CLOSE, ou le mot-clé DISCARDABLE assure
la libération ?



DISCARDABLE est un reliquat 16-bits, gardé pour compatibilité ascendante.
On libère ds le WM_DESTROY ou WM_NCDESTROY.
Avatar
Vincent Burel
"lgloub" wrote in message
news:3fa4fd20$0$255$
> Non, c'est pareil.
> Une des petites différences est juste que le style de la classe de Dlg
> par défaut (#32770) n'a pas des flags comme CS_HREDRAW, CS_VREDRAW, ce
> qui fait que le WM_PAINT n'est pas appelé qd on resize (soit
> subclassing, soit SetClassLong() ds ce cas)

Merci pour ces précisions.
Mais alors je comprends pas pourquoi l'image s'affiche pas :

case WM_PAINT:{

if(g_hBmDlgBack != NULL){
BITMAP bm;
PAINTSTRUCT ps;

HDC hdc = BeginPaint(hWnd, &ps);
HDC hdcMem = CreateCompatibleDC(hdc);
HBITMAP hbmOld = SelectObject(hdcMem, g_hBmDlgBack);
GetObject(g_hBmDlgBack, sizeof(bm), &bm);
BitBlt(hdc, 0, 0, bm.bmWidth, bm.bmHeight, hdcMem, 0,
0, SRCCOPY);
SelectObject(hdcMem, hbmOld);
DeleteDC(hdcMem);
EndPaint(hWnd, &ps);
return(TRUE);
}
}
break;



si c'est un fond, on le fait généralement sur le
WM_ERASEBKGND
la dc est fournit par le WPARAM.

cela permet notamment des optim avec InvalidateRect provocant ou non le
ré-affichage du background : le décord(WM_ERASEBKGND) ou seulement de
l'affichage significatif (WM_PAINT)

VB
Avatar
lgloub
> si c'est un fond, on le fait généralement sur le
WM_ERASEBKGND
la dc est fournit par le WPARAM.

cela permet notamment des optim avec InvalidateRect provocant ou non le
ré-affichage du background : le décord(WM_ERASEBKGND) ou seulement de
l'affichage significatif (WM_PAINT)



Merci. Une précision qui me sera précieuse ;)