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:
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.
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);
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:
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.
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); }
et dans ma boite de dialogue, j'ai la méthode qui est appelé par ce SendMessage:
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).
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); }
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:
Mais cela ne fonctionne que moyennement (il ne semble pas valider toute la surface du bouton... ).
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);
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!
Partager