2009-09-22 15 views
2

Je courais ce code suivant,Bitblt noir

HDC hdc; 
HDC hdcMem; 
HBITMAP bitmap; 
RECT c; 
GetClientRect(viewHandle, &c); 
// instead of BeginPaint use GetDC or GetWindowDC 
hdc = GetDC(viewHandle); 
hdcMem = CreateCompatibleDC(hdc); 
// always create the bitmap for the memdc from the window dc 
bitmap = CreateCompatibleBitmap(hdc,c.right-c.left,200); 

SelectObject(hdcMem, bitmap); 

// only execute the code up to this point one time 
// that is, you only need to create the back buffer once 
// you can reuse it over and over again after that 

// draw on hdcMem 
// for example ... 
Rectangle(hdcMem, 126, 0, 624, 400); 

// when finished drawing blit the hdcMem to the hdc 
BitBlt(hdc, 0, 0, c.right-c.left,200, hdcMem, 0, 0, SRCCOPY); 

// note, height is not spelled i before e 

// Clean up - only need to do this one time as well 
DeleteDC(hdcMem); 
DeleteObject(bitmap); 
ReleaseDC(viewHandle, hdc); 

Le code est très bien. Mais je vois de la couleur noire autour de ce rectangle. Pourquoi donc? Here is an example image.

+0

Vous devriez enregistrer le résultat de votre SelectObject et le restaurer avant la suppression, pour éviter les problèmes de Windows, vous évitez peut-être des plantages en raison de la sortie du DC mais d'autres effets secondaires: HBITMAP saveBM; .. saveBM = SelectObject (hdcMem, bitmap); ... SelectObject (hdcMem, saveBM); DeleteObject (bitmap); –

Répondre

4

La bitmap est probablement initialisée pour être entièrement noire. Vous dessinez alors un rectangle blanc entre les coordonnées x 126 et 624. Par conséquent, tout à gauche de x = 126 et à droite de x = 624 reste noir.

Edit: Le documentation for CreateCompatibleBitmap ne dit pas comment le bitmap sera initialisé, vous devez donc initialiser explicitement le bitmap avec une couleur spécifique, comme le suggère Goz, en utilisant FillRect:

RECT rc; 

rc.left=0; 
rc.top=0; 
rc.right=c.right-c.left; 
rc.bottom=200; 

FillRect(hdcMem, &rc, (HBRUSH)GetStockObject(GRAY_BRUSH)); 

Cet exemple remplit le bitmap en gris - vous devrez peut-être utiliser votre propre pinceau si vous avez besoin d'une couleur différente. (N'oubliez pas d'appeler le DeleteObject lorsque vous avez terminé.)

En note, je trouve un peu étrange que votre bitmap soit réglé à une hauteur constante de 200 - la chose normale serait de rendre la hauteur du bitmap égale à la hauteur de la fenêtre (comme c'est le cas pour la largeur).

+0

comment initialiser le bitmap avec une couleur spécifiée? – asyncwait

+0

Modifié la réponse pour montrer comment initialiser le bitmap. –

+0

Merci Martin, ça marche. Est-ce la bonne façon? Je veux comprendre la raison pour laquelle nous devons faire FillRect. Pouvez-vous s'il vous plaît expliquer dans votre réponse. – asyncwait

0

par MSDN http://msdn.microsoft.com/en-us/library/dd162898.aspx:

Le rectangle est décrit à l'aide du stylo en cours et rempli en utilisant le pinceau en cours.

Envisagez d'appeler FillRect à la place, ou sélectionnez un stylo approprié avant d'appeler Rectangle '.

+0

La même chose se produit même si vous tracez une ligne. Je pense que le problème est avec BitBlt – asyncwait

1

Est-ce parce que vous n'avez pas initialisé la zone de mémoire bitmap à une couleur donnée? Essayez FillRect'ing l'arrière-plan à une couleur différente puis dessinez votre rectangle blanc au-dessus et voir ce qui se passe.

0

J'utilisé:

// Fill the background 
    hdcMem->FillSolidRect(c, hdcMem->GetBkColor()); 

Tout comme une note.

+0

c'est MFC, pas pure API Win32 – dns