Affichage conditionnel de bitmap

Résolu
mouloudhab - 12 avril 2013 à 08:10
 mouloudhab - 22 avril 2013 à 13:54
Bonjour la communauté,
Je développe un petit programme (win32) sous VC++6, avec un hook sur les clics de souris.
L’idée est la suivante :
Aucun bouton actif : une image1 qui s’affiche.
Bouton gauche pressé : image2, et bouton droit pressé : image3
J’ai inséré un fichier log, pour être sûr que mon programme se déroule bien.

Le programme de hook (une dll) fonctionne bien. Les messages parviennent à mon programme.

Dans la procédure de traitement du hook, j’ai mis un UINT que j’initialise à une valeur en fonction du bouton de souris.

Je récupère cet entier dans OnPaint pour sélectionner l’image à afficher et cela ne marche pas (je ne comprends pas ce qui ne fonctionne pas)

Extraits du programme :
J'ai essayé autant que possible de réduire l'extrait, tout en étant clair dans l'exposé de mon problème.
Merci pour votre patience à tous, et merci pour toute aide!
LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
if(message == m_MsgMouseHook)
return MsgMouseHook(wParam, lParam);
// en fonction du message
switch(message)
{
case WM_CREATE		: return MsgCreate		(hWnd, wParam, lParam);
// ici création des objets bitmap
case WM_PAINT		: return OnPaint(); 
case WM_DESTROY		: return MsgDestroy		(wParam, lParam);

default				: 
return DefWindowProc(hWnd, message, wParam, lParam);
}
}


La fonction WM_CREATE:
LRESULT MsgCreate(HWND hWnd, WPARAM wParam, LPARAM lParam)
{

// récupération taille de la zone cliente
RECT rcClient;
GetClientRect(hWnd, &rcClient);
int cx = rcClient.right - rcClient.left;
int cy = rcClient.bottom - rcClient.top;

// chargement des bitmaps
s_hBmpImg1 = LoadBitmap(m_hAppInstance, MAKEINTRESOURCE(IDB_IMG1));
s_hBmpImg2 = LoadBitmap(m_hAppInstance, MAKEINTRESOURCE(IDB_IMG2));
s_hBmpImg3 = LoadBitmap(m_hAppInstance, MAKEINTRESOURCE(IDB_IMG3));

// création de DCs pour ces bitmap
HDC hdc = GetDC(hWnd);
s_hDCImg1 = CreateCompatibleDC(hdc);
s_hDCImg2 = CreateCompatibleDC(hdc);
s_hDCImg3 = CreateCompatibleDC(hdc);
ReleaseDC(hWnd, hdc);

// sélection des bitmaps dans les DCs et savegarde des anciens
s_hOldBmpImg1 = (HBITMAP) SelectObject(s_hDCImg1, s_hBmpImg1);
s_hOldBmpImg2 = (HBITMAP) SelectObject(s_hDCImg2, s_hBmpImg2);
s_hOldBmpImg3 = (HBITMAP) SelectObject(s_hDCImg3, s_hBmpImg3);

// récupération de la taille des bitmaps
BITMAP bmpInfo;
GetObject(s_hBmpImg1, sizeof(BITMAP), &bmpInfo);
s_SizeBmpImg1.cx = bmpInfo.bmWidth;
s_SizeBmpImg1.cy = bmpInfo.bmHeight;
GetObject(s_hBmpImg2, sizeof(BITMAP), &bmpInfo);
s_SizeImg2.cx = bmpInfo.bmWidth;
s_SizeImg2.cy = bmpInfo.bmHeight;
GetObject(s_hBmpImg3, sizeof(BITMAP), &bmpInfo);
s_SizeImg3.cx = bmpInfo.bmWidth;
s_SizeImg3.cy = bmpInfo.bmHeight;

// création réussie
return 0;
}

La fonction sortie de programme:
LRESULT MsgDestroy(WPARAM wParam, LPARAM lParam)
{
// sélection des anciens bitmaps dans les DCs
SelectObject(s_hDCImg1, s_hOldBmpImg1);
SelectObject(s_hDCImg2, s_hOldBmpImg2);
SelectObject(s_hDCImg3, s_hOldBmpImg3);

// destruction des DCs
DeleteDC(s_hDCImg1);
DeleteDC(s_hDCImg2);
DeleteDC(s_hDCImg3);

// destruction des bitmaps
DeleteObject(s_hOldBmpImg1);
DeleteObject(s_hOldBmpImg2);
DeleteObject(s_hOldBmpImg3);
// on quitte l'application
PostQuitMessage(0);
return 0;
}


et enfin, la fonction qui permet l'affichage condionnel. La variable m_ButtonLabel est bien initialisée par le Hook!
LRESULT OnPaint()
{
// début du dessin
PAINTSTRUCT ps;
HDC hdc = BeginPaint(m_hWndMainFrame, &ps);

// taille zone cliente
RECT rcClient;
GetClientRect(m_hWndMainFrame, &rcClient);
int cxClient = rcClient.right-rcClient.left;
int cyClient = rcClient.bottom-rcClient.top;

// création de bitmaps et DCs pour l'affichage final et les opérations
// intermédiaires
HDC hDCFinal = CreateCompatibleDC(hdc);
HDC hDCTemp = CreateCompatibleDC(hdc);
HBITMAP hBmpFinal = CreateCompatibleBitmap(hdc, cxClient, cyClient);
HBITMAP hBmpTemp = CreateCompatibleBitmap(hdc, s_SizeBmpImg1.cx, s_SizeBmpImg1.cy);
HBITMAP hOldBmpFinal = (HBITMAP) SelectObject(hDCFinal, hBmpFinal);
HBITMAP hOldBmpTemp = (HBITMAP) SelectObject(hDCTemp, hBmpTemp);

// effacement du fond du DC final
HBRUSH hWhiteBrush = CreateSolidBrush(RGB(0xFF, 0xFF, 0xFF));
FillRect(hDCFinal, &rcClient, hWhiteBrush);
DeleteObject(hWhiteBrush);

// en fonction du message de MsgMouseHook
if(m_ButtonLabel == 1)
{
BitBlt(hDCFinal, 0, 0, s_SizeImg3.cx, s_SizeImg3.cy, s_hDCImg3, 0, 0, SRCCOPY);
BitBlt(hdc, 0, 0, cxClient, cyClient, hDCFinal, 0, 0, SRCCOPY);
EndPaint(m_hWndMainFrame, &ps);
}
else if (m_ButtonLabel == 2)
{
BitBlt(hDCFinal, 0, 0, s_SizeImg2.cx, s_SizeImg2.cy, s_hDCImg2, 0, 0, SRCCOPY);
BitBlt(hdc, 0, 0, cxClient, cyClient, hDCFinal, 0, 0, SRCCOPY);
EndPaint(m_hWndMainFrame, &ps);	
}
else
{
BitBlt(hDCFinal, 0, 0, s_SizeBmpImg1.cx, s_SizeBmpImg1.cy, s_hDCImg1, 0, 0, SRCCOPY);
BitBlt(hdc, 0, 0, cxClient, cyClient, hDCFinal, 0, 0, SRCCOPY);
EndPaint(m_hWndMainFrame, &ps);
}

// libération des ressources
SelectObject(hDCFinal, hOldBmpFinal);
SelectObject(hDCTemp, hOldBmpTemp);
DeleteDC(hDCFinal);
DeleteDC(hDCTemp);
DeleteObject(hBmpFinal);
DeleteObject(hBmpTemp);

// fin du dessin
return 0;
}

2 réponses

yann_lo_san Messages postés 1137 Date d'inscription lundi 17 novembre 2003 Statut Membre Dernière intervention 23 janvier 2016 26
12 avril 2013 à 20:30
Salut,

je ne vois pas le code qui provoque le WM_PAINT !
Es ce que tu fais un RedrawWindow() ou un Invalidate() dans MsgMouseHook() ?

Si c'est le cas, il faut que tu utilises le HDC & le PaintStruct de la WNDPROC :

case WM_PAINT:
PAINTSTRUCT ps;
HDC hdcTemp;
hdcTemp = BeginPaint(hWnd, &ps); 
OnPaint(hdcTemp, &ps); //<------------- ICI
EndPaint(hWnd, &ps);
break;

LRESULT OnPaint(HDC hdc, PAINTSTRUCT* pps)
{
    // Contexte de dessin
    HDC hMemDC = CreateCompatibleDC(hdc);
    HBITMAP hBmp = CreateCompatibleBitmap(hdc, BITMAP_SX, BITMAP_SY);
    HBITMAP hBmpOld = (HBITMAP)SelectObject(hMemDC, hBmp);
    
    switch( quelleImg )
    {
        case 1: SelectObject(hMemDC, s_hBmpImg1);
            break;
    }

    BitBlt(hdc, 0, 0, BITMAP_SX, BITMAP_SY, hMemDC, 0, 0, SRCCOPY);
    SelectObject(hMemDC, hBmpOld);
    DeleteDC(hMemDC);
    DeleteObject(hBmp);
}



bye...
3
Merci beaucoup,
Formidable, ça marche merveilleusement bien!

Merci yann_lo_san
3
Rejoignez-nous