Bonsoir,

J'ai un petit problème pour rafraichir la position d'un CButton sur une boite de dialogue...
(Je suis désolé de balancer des gros bouts de code comme ça, je vous assure avoir cherché... et vraiment longtemps, avant de venir vous demander votre aide)

Je m'explique :
J'ai une CDialog dont la méthode OnPaint() est la suivante:
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
16
17
18
19
 
	CPaintDC	      dc(this); 
	CRect			myRect;
	CDC			MemDC;			
	CBitmap			bmp;
	CBrush			lBrush(RGB(221,221,221));
 
	isOnce=false;
	dc.GetWindow()->GetClientRect(&myRect);
	MemDC.CreateCompatibleDC(&dc);
	MemDC.SetBkMode(OPAQUE);
	MemDC.SetBkColor(RGB(221,221,221));
	bmp.CreateCompatibleBitmap(&dc,myRect.Width(),myRect.Height());
	CBitmap *pOldBitmap =MemDC.SelectObject (&bmp); 
	MemDC.SelectObject(&lBrush);
	MemDC.PatBlt(0,0,myRect.Width(),myRect.Height(),PATCOPY); 
	pObject->Draw(&MemDC,20,30,&myRect); //pObject est un autre objet d'une autre classe qui possède une méthode Draw                                                          permettant de dessiner sur un DC
dc.BitBlt(0,0,myRect.Width(),myRect.Height(),&MemDC,0,0,SRCCOPY); 
 	MemDC.SelectObject (pOldBitmap);
Pour éviter le flickering, j'utilise un DC mémoire dans lequel je dessine puis je fais un blit de l'ensemble de la boite de dialogue.

Sur cette boite de dialogue, j'ai un bouton CMyButton qui est une classe dérivée de CButton des MFC. Les boutons CMyButton ont la particularité suivante:
Lorsqu'on clique sur le bouton, le bouton va suivre le mouvement du pointeur de souris. En recliquant sur le bouton, on met fin à ce drag.

J'ai ainsi la méthode suivante:

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
16
17
18
19
20
21
void CMyButton::OnMouseMove(UINT nFlags, CPoint point) 
{
	if (isDrag) //si on est en cours de drag
	{
		CPoint		pointCourant;
		CRect		rectButton;
		NMHDR hdr;
 
		hdr.hwndFrom = GetSafeHwnd();
                hdr.idFrom   = GetDlgCtrlID();
               hdr.code     = BN_MOUSEMOVE;
 
		this->GetWindowRect(&rectButton);
		this->GetParent()->ScreenToClient(&rectButton);
		GetCursorPos(&pointCourant);
		this->GetParent()->ScreenToClient(&pointCourant);
		MoveWindow(pointCourant.x,rectButton.top,20,20,true);
 
		GetParent()->SendMessage(WM_NOTIFY, GetDlgCtrlID(), (LPARAM)&hdr);
 
	}
Cette méthode capture le survol du bouton et si on est en cours de drag & drop, on déplace l'objet (MoveWindow). La fenetre parente (celle qui contient le bouton) en est avertie à l'aide d'un SendMessage.

et dans ma boite de dialogue, j'ai la méthode qui est appelé par ce SendMessage:

Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
void CMyDlg::OnMouseMoveBtn(UINT id,NMHDR* pNMHDR, LRESULT* pResult)
{
       /* ICI, JE MODIFIE LE pObject QUI SE TROUVE DANS LA METHODE ONPAINT. IL FAUT DONC REDESSINER LA FENETRE D'OU LE INVALIDATE*/
 
	Invalidate();
 
	CRect rect;
	m_tabBtn.ElementAt(0)->GetWindowRect(&rect); //m_tabBtn est un bouton CMyButton
	ScreenToClient(&rect);
	ValidateRect(&rect);
 
}
En fait, ds cette méthode, je modifie l'objet pointé par pObject (que je dessine sur la boite de dialogue) => il faut donc redessiner la fenetre (d'où le Invalidate).
Mais en faisant ça, mon bouton est effacé... (par le bitblit). J'essaye donc de valider la zone où se trouve le bouton avec le code:

Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
CRect rect;
m_tabBtn.ElementAt(0)->GetWindowRect(&rect); //m_tabBtn est un bouton CMyButton
ScreenToClient(&rect);
ValidateRect(&rect);
Mais cela ne fonctionne que moyennement (il ne semble pas valider toute la surface du bouton... ).

Et là, c'est le drame.. cela fait plusieurs jours que je lutte sur ce problème..sans succès
Avez vous des idées possibles pour résoudre ce problème? Une autre manière de faire?
En gros, si je savais JUSTE (re)dessiner un bouton d'une boite de dialogue sans à avoir à redessiner la boite entière, ce serait gagné j'imagine... Il suffirait que je fasse ça, après le bitblit dans le OnPaint de la boite...

Merci d'avance!