[c/win32] bouton bitmap - subclassing

Soyez le premier à donner votre avis sur cette source.

Vue 9 053 fois - Téléchargée 697 fois

Description

Un Boutton custom à base d'images BMP avec effet "MouseOver".

Fait sous Dev-Cpp mais compilable sous VS.

Source / Exemple :


//Code complet, environ 80 lignes de code:

#include <windows.h>

HINSTANCE hInst; // Instance application

BOOL CALLBACK DlgProc(HWND, UINT, WPARAM, LPARAM); 

//Couleur de fond de la feuille

HDC hDC;

HBRUSH couleur_fond; //brush à la couleur RGB

// Bouttton bitmap

HWND hBtn;          // Handle du boutton bitmap (contrôle)

HBITMAP hBitmap;    // handle du bitmap         (image)

WNDPROC OldBtnProc; // Déclaration proto fonction subclassing boutton

BOOL ButtonIsOver;  // TRUE quand souris est dessus

/* -----------------------------------------------------------------------------

   Point d'entrée

------------------------------------------------------------------------------*/

int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, PSTR szCmdLine, int iCmdShow){

    hInst=hInstance; //on met de côté le handle de l' appli

	return DialogBoxParam(hInstance, (char*)100, 0, &DlgProc, 0);

}

/* -----------------------------------------------------------------------------

   Procédure de sous-classement du boutton

------------------------------------------------------------------------------*/

LRESULT CALLBACK BtnProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)

{

    switch(message){

      case WM_LBUTTONDOWN: // on clique: charge bitmap "cliqué"

             hBitmap=LoadImage(hInst,(LPCSTR)"imgdown",IMAGE_BITMAP,0,0,LR_CREATEDIBSECTION);

             SendMessage(hBtn,STM_SETIMAGE,IMAGE_BITMAP,(LPARAM)(HBITMAP)hBitmap);        

             return TRUE;

      case WM_LBUTTONUP:

             hBitmap=LoadImage(hInst,(LPCSTR)"imgnorm",IMAGE_BITMAP,0,0,LR_CREATEDIBSECTION);

             SendMessage(hBtn,STM_SETIMAGE,IMAGE_BITMAP,(LPARAM)(HBITMAP)hBitmap);

             PostQuitMessage(0); //fermeture!

             return TRUE;

      case WM_MOUSEMOVE:

             hBitmap=LoadImage(hInst,(LPCSTR)"imgover",IMAGE_BITMAP,0,0,LR_CREATEDIBSECTION);

             SendMessage(hBtn,STM_SETIMAGE,IMAGE_BITMAP,(LPARAM)(HBITMAP)hBitmap);        

             ButtonIsOver=TRUE;

             return TRUE;

   }

    // et retour à la procédure originale

    return CallWindowProc(OldBtnProc, hWnd, message, wParam, lParam);

}

/* -----------------------------------------------------------------------------

   Callback fenêtre

------------------------------------------------------------------------------*/

BOOL CALLBACK DlgProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam){

    int x,y;

	switch (uMsg){

	  case WM_INITDIALOG:

            // définit variables fenêtre

               couleur_fond = CreateSolidBrush(RGB(148,183,197)); // bleu foncé

               SetWindowText(hWnd, "Boutton Bitmap"); //titre taskbar

		    // centre la fenêtre

               x = (GetSystemMetrics(SM_CXSCREEN)-200)/2;

               y = (GetSystemMetrics(SM_CYSCREEN)-200)/2;

               MoveWindow(hWnd,x,y,200,160,0);

            // subclassing du boutton: appel de la fonction de sous-classement

            hBtn = GetDlgItem(hWnd, 101); //met de côté le handle

            OldBtnProc=(WNDPROC) SetWindowLong(hBtn,GWL_WNDPROC,(LPARAM)BtnProc);

		    break;

      case WM_MOUSEMOVE:

           if (ButtonIsOver){

             hBitmap=LoadImage(hInst,(LPCSTR)"imgnorm",IMAGE_BITMAP,0,0,LR_CREATEDIBSECTION);

             SendMessage(hBtn,STM_SETIMAGE,IMAGE_BITMAP,(LPARAM)(HBITMAP)hBitmap);        

             ButtonIsOver=FALSE;

             return TRUE;

           } break;

	  case WM_CTLCOLORDLG:return(LRESULT)couleur_fond;

      case WM_CTLCOLORSTATIC:

 			hDC = (HDC)wParam;

		    SetBkMode(hDC, TRANSPARENT);

            SetTextColor (hDC, RGB(215,236,253));//bleu clair

            return(LRESULT)couleur_fond;

	  case WM_CLOSE:

            DeleteObject(hBitmap);

		    DeleteObject(couleur_fond);

		    DeleteObject(hDC);            

		    EndDialog(hWnd,0);

	}

	return 0;

}

Conclusion :


Dans cet exemple le boutton ferme l'application.

Codes Sources

A voir également

Ajouter un commentaire

Commentaires

Messages postés
2
Date d'inscription
dimanche 22 mai 2005
Statut
Membre
Dernière intervention
31 août 2008

Trés bien
Messages postés
13
Date d'inscription
vendredi 13 août 2004
Statut
Membre
Dernière intervention
20 février 2006

salut katsankat, j'apprend doucement le win 32 et je trouve ton code vraiment bien je pense qu'il est utile et tres simple, c cool surtout quand on debute.......;)
merci
Mat1eu
Messages postés
13
Date d'inscription
vendredi 13 août 2004
Statut
Membre
Dernière intervention
20 février 2006

salut katsankat, j'apprend doucement le win 32 et je trouve ton code vraiment bien je pense qu'il est utile et tres simple, c cool surtout quand on debute.......;)
merci
Mat1eu
Messages postés
458
Date d'inscription
jeudi 4 décembre 2003
Statut
Membre
Dernière intervention
19 décembre 2008
10
Je suis pa d'accord.
Si pour chaque bouton que tu souhaites rajouter tu dois recréer une fonction de traitement des messages on en finit plus.
Tu peux ne garder qu'une seule fonction de traitement des messages pour tous tes boutons, il fautjuste ue tu donnes à chaque bouton les handles ou chemin d'accès des bitmpas qu'il doit utiliser, ce qui est faisable avec SetWindowLong.

1.-Création du bouton (CreateWindow)
2.-Association des images au bouton (SetWindowLong avec GWL_USERDATA + passage d'un pointeur sur une structure contenant handle ou chemin d'accès aux bmp)
3.-Association de la fonction de sous classement (SetWindowLong avec GWL_WNDPROC)

Il ne reste plus qu'à modifier un peu la fonction de sous classement pour récupérer les infos qu'on a passé au bouton par l'intermédiaire de GetWindowLong.
Normalement avec ca, tu peux créer autant de boutons que tu veux avec une seule fonction de sous classement.
Messages postés
571
Date d'inscription
vendredi 30 décembre 2005
Statut
Membre
Dernière intervention
12 juillet 2012
3
Pour plusieurs boutton, il faut ajouter le nouveau dans le fichier rc (en remplaçant celui qui sert à rien ;) après faut rajouter le prototype de la fonction:
WNDPROC 2mebouttonProc;
Puis écrire cette fonction en recopiant l'autre, et l' appeler dans WM_INITDIALOG. Et ne pas oublier de supprimer l' objet bitmap quand l' appli ferme.

La question n'est pas de savoir si l' idée est bonne ou pas mauvaise, mais comment récupérer le mousemove et le click sur un contrôle statique autrement que par subclassing! Si quelqu'un trouve on est preneur.

C'est du C, pas du C++.
Afficher les 9 commentaires

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.