IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Windows Discussion :

GetPixel() ne marche pas. . .


Sujet :

Windows

  1. #1
    Membre régulier Avatar de kidpaddle2
    Inscrit en
    Avril 2006
    Messages
    430
    Détails du profil
    Informations forums :
    Inscription : Avril 2006
    Messages : 430
    Points : 95
    Points
    95
    Par défaut GetPixel() ne marche pas. . .
    Bonjour,

    J'aimerais récupérer la couleur RGB d'un pixel situé aux coordonnées déterminées par la variable "point" (donc à ses champrs 'x' et 'y') dans un bitmap chargé. Pour cela, je dois utiliser GetPixel(), qui requiert un DC dessus. Or, je ne sais pas trop quoi mettre... sachant que le bitmap n'est pas affiché, servant juste d'"information". Voici le code :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    bool Button::isUnder(LPARAM coordinates, HBITMAP mouseMask)
    {
        //Début de la zone à risque : je ne sais pas quoi récupérer comme DC...
        HDC mouseDc = CreateCompatibleDC(GetDC(_parent));
        SelectObject(mouseDc, mouseMask);
        //Fin
    
        POINTS point;
        point = MAKEPOINTS(coordinates);
    
        if(GetPixel(mouseDc, point.x, point.y) == _color)
           return true;
        else
            return false;
    }
    Pourriez-vous m'aider ?

    Merci d'avance.

  2. #2
    Expert éminent sénior
    Avatar de Médinoc
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2005
    Messages
    27 382
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 40
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2005
    Messages : 27 382
    Points : 41 590
    Points
    41 590
    Par défaut
    Eh bien, normalement ça devrait marcher...
    1. Vérifie les valeurs retournées (erreurs etc.)
    2. Vérifie tes coordonnées : Elles doivent être relatives à l'origine du bitmap
    3. Vérifie que la valeur retournée est bien une des valeurs possibles et non pas une valeur "intermédiaire" ou "proche"...
    4. Pense à tout désallouer à la fin: Re-SelectObject(), ReleaseDC(), DeleteDC()...

  3. #3
    Membre régulier Avatar de kidpaddle2
    Inscrit en
    Avril 2006
    Messages
    430
    Détails du profil
    Informations forums :
    Inscription : Avril 2006
    Messages : 430
    Points : 95
    Points
    95
    Par défaut
    En fait, j'ai trouvé... je travaille sur un ordi qui n'est pas le mien, et en faisant quelques tests il s'est avéré que les couleurs d'affichage étaient en 16 bits. Après changement en 32, ça marche parfaitement. Merci quand même ^^

  4. #4
    Expert éminent sénior
    Avatar de Médinoc
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2005
    Messages
    27 382
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 40
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2005
    Messages : 27 382
    Points : 41 590
    Points
    41 590
    Par défaut
    Ce qui signifie que tu as fait CreateCompatibleBitmap() au lieu de CreateDIBSection() pour ta bitmap "souris".

    Mon conseil : Corrige ça. Le bitmap souris n'est jamais affiché, il a donc tout intéret à être complètement coupé du matériel...

  5. #5
    Membre régulier Avatar de kidpaddle2
    Inscrit en
    Avril 2006
    Messages
    430
    Détails du profil
    Informations forums :
    Inscription : Avril 2006
    Messages : 430
    Points : 95
    Points
    95
    Par défaut
    Je n'ai même pas fait de CreateCompatibleBitmap()... juste un LoadBitmap() des ressources, et le code donné.

  6. #6
    Expert éminent sénior
    Avatar de Médinoc
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2005
    Messages
    27 382
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 40
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2005
    Messages : 27 382
    Points : 41 590
    Points
    41 590
    Par défaut
    LoadBitmap() crée un bitmap "Compatible" également.
    Tu peux toujours copier le bitmap chargé vers un bitmap "Device-Independent" créé avec CreateDIBSection()...

  7. #7
    Membre régulier Avatar de kidpaddle2
    Inscrit en
    Avril 2006
    Messages
    430
    Détails du profil
    Informations forums :
    Inscription : Avril 2006
    Messages : 430
    Points : 95
    Points
    95
    Par défaut
    Allons bon... maintenant que j'ai intégré la possibilité de bouger le lecteur (avec WM_NCHITTEST), les coordonnées sont faussées, sûrement à cause des coordonnées à partir de l'écran. Donc, il faut que je crée un device-independent bitmap, comme tu le dis non ?

    Bref, tout ce que j'ai à faire, c'est CreateDIBSection()... seulement, je ne vois pas trop quoi faire, du fait du nombre de paramètres que je trouve inutiles à mon cas. Aurais-tu une idée de l'appel que je dois effectuer à partir de mon code ?

  8. #8
    Expert éminent sénior
    Avatar de Médinoc
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2005
    Messages
    27 382
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 40
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2005
    Messages : 27 382
    Points : 41 590
    Points
    41 590
    Par défaut
    Pour un bitmap en 24 ou 32 bits, tu as rarement besoin de grand-chose.
    Il te suffit d'une bète structure BITMAPINFO (en 24 ou 32bits, tu n'as même pas besoin de l'allouer dynamiquement, et peut-être même que c'est aussi le cas en 16bits, mais je n'en suis pas sûr).

    Normalement, il suffit d'un truc de ce genre-là (je n'ai pas testé) :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    BITMAPINFO bi = {{sizeof(bi),largeur,hauteur,1,32,BI_RGB,0,0,0,0,0}, {0,0,0,0}};
    LPVOID pPixels = NULL;
    HBITMAP hBmp = CreateDIBSection(NULL, &bi, DIB_RGB_COLORS, &pPixels, NULL, 0);

  9. #9
    Membre régulier Avatar de kidpaddle2
    Inscrit en
    Avril 2006
    Messages
    430
    Détails du profil
    Informations forums :
    Inscription : Avril 2006
    Messages : 430
    Points : 95
    Points
    95
    Par défaut
    Merci. Et hBmp désigne le bitmap déjà chargé avec LoadBitmap(), ou bien un nouveau, d'abord vide, qui recevra celui chargé ?

  10. #10
    Expert éminent sénior
    Avatar de Médinoc
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2005
    Messages
    27 382
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 40
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2005
    Messages : 27 382
    Points : 41 590
    Points
    41 590
    Par défaut
    C'est une déclaratio, c'est donc un nouveau handle de bitmap, qu'on initialise avec le DIB créé.

  11. #11
    Membre régulier Avatar de kidpaddle2
    Inscrit en
    Avril 2006
    Messages
    430
    Détails du profil
    Informations forums :
    Inscription : Avril 2006
    Messages : 430
    Points : 95
    Points
    95
    Par défaut
    Ca aurait pu être pour illustrer.

    Donc, c'est le bitmap qui va recevoir le HBITMAP du masque de souris, après avoir été chargé en ressources, non ?

    Edit: Non, ça fait pareil... voici mon code :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    BITMAPINFO bi = {{sizeof(bi),257,436,1,32,BI_RGB,0,0,0,0,0}, {0,0,0,0}};
    LPVOID pPixels = NULL;
    
    _mouseMask = CreateDIBSection(NULL, &bi, DIB_RGB_COLORS, &pPixels, NULL, 0);
    _mouseMask = LoadBitmap(instance, "mouseMask");
    Avec :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    bool Button::isUnder(LPARAM coordinates, HBITMAP mouseMask)
    {
        static HDC mouseDc = CreateCompatibleDC(NULL);
        SelectObject(mouseDc, mouseMask);
    
        POINTS point;
        point = MAKEPOINTS(coordinates);
    
        if(GetPixel(mouseDc, point.x, point.y) == _color)
            return true;
        else
            return false;
    }
    ReEdit : j'ai une autre question... j'ai fait un type de slot, étant un pointeur de fonction, avec :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    typedef void (*Slot)();
    Seulement, j'oubliais qu'il s'agissait de méthodes de ma classe Player. Donc, je ne peux pas les passer en paramètre avec ce typedef. Que dois-je mettre pour pouvoir indiquer une méthode ?

    Merci d'avance.

  12. #12
    Expert éminent sénior
    Avatar de Médinoc
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2005
    Messages
    27 382
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 40
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2005
    Messages : 27 382
    Points : 41 590
    Points
    41 590
    Par défaut
    Ben non, ce n'est pas ça.
    D'ailleurs, ton code leake le DIB qu'on s'est donné tant de mal à créer...

    De plus, normalement, tu n'as pas qu'un seul masque. Tu as un masque chargé par bouton, et un masque "global" qui cumule les autres, et qui est généré.

    En fait, un truc de ce genre-là (non-testé, non-compilé) :
    Code C++ : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    //Classe utilitaire
    class BitmapDC
    {
    public:
    	BitmapDC(HBITMAP hBmp;)
    	{
    		m_hDC = CreateCompatibleDC(NULL);
    		m_hOld = SelectObject(m_hDC, hBmp);
    	}
    	~BitmapDC()
    	{
    		SelectObject(m_hDC, m_hOld);
    		DeleteDC(m_hDC);
    	}
    	HDC m_hDC;
    private:
    	HGDIOBJ m_hOld;
    };
     
     
    //Classe mère de ta hiérarchie de classes de fenêtres
    class Wnd
    {
    	//HWND, WindowProc virtuelle + GetWindowLong(), etc.
    	//On en a déjà parlé, n'est-ce pas ?
    };
     
    //Classe mère de ta hiérarchie de contrôles WindowLess
    class WindowLessControl //n'hérite pas de Wnd
    {
    public:
    	//Obtenir le masque: Cette implémentation le charge à chaque appel, 
    	//mais tu peux aussi le charger dans le constructeur et le stocker en interne...
    	HBITMAP GetMask()
    	{ return LoadBitmap(GetMaskName()); }
    	void ReleaseMask(HBITMAP hBmp);
    	{ DeleteObject(hBmp); }
    protected:	
    	virtual LPCTSTR GetMaskName() = 0;
    };
     
    //Contrôle hôte des contrôles WindowLess :
    //C'est cette classe qui contient le bitmap souris,
    //et qui appelle les méthodes de dessin des contrôles, etc.
    class WindowLessControlHost : public Wnd
    {
    	//WindowProc virtuelle, etc.
     
    protected:
    	struct ControlInfo
    	{
    		int x;
    		int y;
    		COLORREF color;
    		WindowLessControl *pCtl;
    	};
     
    	//Je n'ai pas le code sous les yeux, 
    	//(à modifier, voir le lien dans l'aide de TransparentBlt(), on en a déjà parlé)
    	static HBITMAP GetColorMask(HBITMAP hMask, COLORREF color);
     
    	HBITMAP m_hMouseDIBmp;
    	std::map< COLORREF, ControlInfo * > m_controlInfoByColor;
    	std::map< WindowLessControl *, ControlInfo * > m_controlInfoByControl;
    };
     
    ////////////////////////////////////////////////////////////////////////////:
    // Implémentation
     
    //Fonction de départ : Ici, j'ai juste mis la création du bitmap souris
    void WindowLessControlHost::Initialize()
    {
    	//Recup dimensions de la zone contenant les contrôles WindowLess
    	RECT r;
    	GetClientRect(m_hWnd, &r);
     
    	BITMAPINFO bi = {{sizeof(bi),r.right,r.bottom,1,32,BI_RGB,0,0,0,0,0}, {0,0,0,0}};
    	LPVOID pPixels = NULL;
    	m_hMouseDIBmp = CreateDIBSection(NULL, &bi, DIB_RGB_COLORS, &pPixels, NULL, 0);
     
    	//Remplit l'image de blanc
    	{
    		BitmapDC dc(m_hMouseDIBmp);
    		FillRect(dc.m_hDC, &r, GetStockObject(WHITE_BRUSH));
    	}
    }
     
    //Fonction d'ajout d'un contrôle : ajoute son masque au masque
    void WindowLessControlHost::AddControl(WindowLessControl *pCtl, int x, int y)
    {
    	ControlInfo *pInfo = new ControlInfo(x, y, GetNewColor(), pCtl);
    	m_controlInfoByColor.add(pInfo->color, pInfo);
    	m_controlInfoByControl.add(pInfo->pCtl, pInfo);
     
    	//Charge le masque du contrôle et le dessine dans le masque de souris de l'hote
    	{
    		HBITMAP hCtlMask = pCtl->GetMask();
    		HBITMAP hMask = GetColorMask(hCtlMask, pInfo->color);
    		BITMAP mask;
    		GetObject(hMask, sizeof(mask), &mask);
    		{
    			BitmapDC maskDC(hMask);
    			BitmapDC mouseDC(m_hMouseDIBmp);
     
    			BitBlt(mouseDC.m_hDC, x, y, mask.bmWidth, mask.bmHeight, maskDC.m_hDC, 0, 0);
    		}
    		DeleteObject(hMask);
    		pCtl->ReleaseMask(hCtlMask);
    	}
    }
     
    WindowLessControlHost::ControlInfo * WindowLessControlHost::GetControlByMouse(int x, int y) const
    {
    	BitmapDC dc(hMouseDIBmp);
    	COLORREF color = GetPixel(dc.m_hDC, x, y);
    	return m_controlInfoByColor[color];
    }

  13. #13
    Membre régulier Avatar de kidpaddle2
    Inscrit en
    Avril 2006
    Messages
    430
    Détails du profil
    Informations forums :
    Inscription : Avril 2006
    Messages : 430
    Points : 95
    Points
    95
    Par défaut
    Oulala, je n'ai pas du tout fait comme cela... en fait, j'ai fait un masque global avec une couleur de fond valant -blanc-, et des formes de couleur unie représentant les contrôles (à leur place), avec une couleur unique pour chacun. Ensuite, je passe au constructeur du bouton la couleur que je lui assigne, afin qu'il puisse vérifier, lors d'un évèenement souris, s'il est survolé ou non.

    Je ne sais pas si tu accepterais, mais j'aimerais te montrer mon code pour que tu puisse m'aider au mieux. De plus, j'aurais besoin de conseils de pros, puisque j'ai des problèmes d'optimisation.

    Seulement... j'ai quelques fuites. Je garde jalousement mon projet au chaud en attendant sa sortie (et sa licence correspondante), ayant déjà subi une appropriation de programme. Pourrais-tu me donner ton adresse e-mail, si tu accepte, que je puisse t'envoyer le paquet ?

    Merci beaucoup de ton aide.

    Edit: J'ai activé la réception des emails... au cas où tu veuille bien m'envoyer par email ton adresse (ou autre) pour que je puisse te répondre (c'est pour que personne ne voie ton email, je suppose que ce n'est pas pour rien qu'elle est cachée )

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. 'SHOW TABLES' marche pas sous postgresql !?
    Par fet dans le forum PostgreSQL
    Réponses: 4
    Dernier message: 13/05/2004, 10h28
  2. Maximiser fenêtre ne marche pas
    Par sandrinec dans le forum Composants VCL
    Réponses: 2
    Dernier message: 12/06/2003, 13h02
  3. Réponses: 9
    Dernier message: 07/05/2003, 13h57
  4. [GifDecoder] marche pas dans applet avec IE
    Par formentor dans le forum Applets
    Réponses: 2
    Dernier message: 06/05/2003, 11h43
  5. Sysdate qui marche pas ??
    Par StouffR dans le forum Langage SQL
    Réponses: 4
    Dernier message: 28/08/2002, 14h23

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo