-
WM_PAINT my wagon
Hello,
I'm trying to display a bitmap (Well, DIB in Microsoft-speak) in a window using the WM_PAINT message. This works fine when it initially loads up, but if I drag another window over it and then drag it back it gets all corrupted. I'm using:-
Code:
// g_lpData is a pointer to the image data
// g_lpBi is a pointer to the image's BITMAPINFO
// g_iScrollX, g_iScrollY are offsets set by the scroll bars
case WM_PAINT:
{
PAINTSTRUCT ps;
if (g_lpData) // We have something to draw
{
BeginPaint(hwnd, &ps);
ps.rcPaint.right -= ps.rcPaint.left;
ps.rcPaint.bottom -= ps.rcPaint.top;
if (ps.rcPaint.right > g_lpBi->bmiHeader.biWidth)
ps.rcPaint.right = g_lpBi->bmiHeader.biWidth;
if (ps.rcPaint.bottom > -g_lpBi->bmiHeader.biHeight)
ps.rcPaint.bottom = -g_lpBi->bmiHeader.biHeight;
if (ps.rcPaint.left < g_lpBi->bmiHeader.biWidth && ps.rcPaint.top < -g_lpBi->bmiHeader.biHeight)
StretchDIBits(ps.hdc, ps.rcPaint.left, ps.rcPaint.top, ps.rcPaint.right, ps.rcPaint.bottom, ps.rcPaint.left + g_iScrollX, ps.rcPaint.top + g_iScrollY, ps.rcPaint.right, ps.rcPaint.bottom, g_lpData, g_lpBi, DIB_RGB_COLORS, SRCCOPY);
EndPaint(hwnd, &ps);
}
break;
}
I know most people just draw the entire bitmap all at once, but I think that's a bit of a waste doing that every time a window is moved a pixel over the bitmap. Can anyone solve this for me please? :confused:
-
the rect returned by the call to BeginPaint() will contain the update region.
Why are you changing it?
"ps.rcPaint.right -= ps.rcPaint.left;
ps.rcPaint.bottom -= ps.rcPaint.top;"
If the rect is say 1/2 the width to the whole width ie the right half of the screen, then you will draw nothing
ie left = Width/2;
right = Width;
therefore
right -= left -> width - width/2 = width/2
now left and right == width/2
PS
Stretch'ing the image is slow and costly to the quality of the image. It would be better to select the BMP into a temp DC (on init) and use that to BitBlt() the correct area (free on close).
-
I think he's changing it because he wants size of that region (for StretchDIBits()), no?
SMurf, try testing validity of those params you pass to StretchDIBits(), to be sure they are right :). Are your memory buffer & BITMAPINFO still valid when subsequent calls to WM_PAINT happen?
-
novocain, StretchDIBits needs x y width height, not left top right bottom as the RECT is used, so I decrement the right by the left to give the width (And the same with the bottom and top). From your given logic, the DIB would be drawn starting from width/2 to a width of width/2, and there is nothing wrong with that.
I'm not actually stretching the image either, as source width and height are the same as dest width and height. I just didn't want to bother with actual bitmaps and DCs beyond the window's DC (This will be an image editing program, one day...). ;)
lobo, all of the params do seem to be valid, and neither of the pointers change until the program is closed, so the problem doesn't lie there. There must be something about the co-ordinates that differs when redrawing (As I've said, when the invalidated region is the entire window, it draws fine). :confused:
-
Sorry to repeat myself: did you check both src and tgt position and size parameters of StretchDIBIts() call when wrong data were drawn? If whole bitmap is painted fine when entire window region is invalidated, as you said, they must be wrong somehow and best method to see is to output them directly...to log perhaps...or to watch them in debugger.
Ps. is StretchDIBits() call successfull at all??? Try checking returned value, it provides number of lines drawn, i think..
-
OK. Fair enough.
Though I would bewary of modifing the update region in a paint struct, as windows may still use it later in the EndPaint(). (more important in other functions)
ps.rcPaint.left + g_iScrollX,
ps.rcPaint.top + g_iScrollY, // not sure but I would check the scale is correct ie size on screen is same as size in image.
Is g_iScrollX in logical units or a percentage of the scrollable area?
-
Never mind. There appears to be some internal "feature" of DIB functions that prevent them from being used for active redrawing (I changed my code so the DIB was put into a bitmap and then BitBlted and it worked without problems). :rolleyes:
With larger images I could see the redraw with the DIB functions, whereas with BitBlting it was smooth. Oh well.