Clearing the client area
No, this is not "How do I clear the screen?" question. See my problem is I want a "new" option in my menu, which I have. The code of it just invalidates the client area and that works fine but it repaints the entir window(in the client area) including the menus and title bar. I used to accomplish the effect of clearing the screen with SendMessage and sending WM_PAINT but I recently switched to using a FrameBuffer so that option wont work anymore. Any suggestions?
PS..The code for my Invalidation is:
InvalidateRect (hwnd, &rectClient, TRUE) ;
and rectClient is already set to be the size fof the client area
So is it like a picture drawing thing?
Maybe you should send a message making every pixel white.
acturally its a geometric graphing program (I solidify both my geometry and my coding :-) so I cant make every pixel white or it will take out my graph which it is spose to keep and just get rid of any drawings that were done.
It may be in your WM_PAINT handler.
If your not using the PAINTSTRUCT (filled with the BeginPaint() call) in your cooresponding BitBlt() call, then I'd say that's the problem.
Or are you already doing that? That's all I can think.
The BitBlt works fine its just the client area is redrawn using the wrong parts of the screen.
What is the RECT* param that you are setting with InvalidateRect? You could try just invalidating the area without the menu and what do you don't want repainted.
[EDIT] Actually, you musn't be invalidating the menu because it is "doubling" it. What does your WM_PAINT handling look like? Post the code. You might be repainting the toolbar and menu there. That's all I can think of.[/EDIT]
&rectClient is already initilized to only hold the client area no menus or titlebars. And its only redrawing that section but with the wrong section of screen in it.
Post your handling of WM_PAINT. There is no other explanation than you are either repainting the menu and toolbar.
is that what you wanted?
hdc = BeginPaint (hwnd, &ps) ;
marks = CreatePen (PS_INSIDEFRAME, 1, 0) ; // create pen for drawing the marks
axis = CreatePen (PS_SOLID, 4, 0) ; // create pen for drawing axis
SelectObject (hdc, marks) ;
xspace = cxClient/20 ;//to find spacing on x axis
yspace = cyClient/20 ;//to find spacing on the X axis
n = 1 ;
xmarks = xspace * n ; //calculate the position of x marks
ymarks = yspace * n ; // calculate the position of y marks
MoveToEx(hdc, xmarks, 0, NULL) ;//move to starting point of x marks
LineTo(hdc, xmarks, cyClient) ;//draw x marks
MoveToEx(hdc, 0, ymarks, NULL) ;//move to starting point of y marks
LineTo(hdc, cxClient, ymarks) ;//draw y marks
SelectObject (hdc, axis) ;
yaxis = cyClient/2 ; //to find half the hieght
xaxis = cxClient/2 ; //to find half the width
MoveToEx(hdc, xaxis, 0, NULL) ; //to move to top of Y axis
LineTo(hdc, xaxis, cyClient) ; //to draw y axis
MoveToEx(hdc, 0, yaxis, NULL) ; //to move to left of X axis
LineTo(hdc, cxClient, yaxis) ; //to draw X axis
SelectObject (hdc, NULL) ;
BitBlt(hdc, 0, 0, clientWidth, clientHeight, memhdc, 0, 0, SRCCOPY) ;
EndPaint (hwnd, &ps) ;
First, watch the SelectObject() as you may be loosing a brush / pen per paint.
Second try to get all the drawing functions out of the paint, much quicker and easier to debug.
Third you set up a HDC, returned from paint (hdc), and then BitBlt() memhdc over the top, wiping hdc out.
This could be the problem, how did you create memdc?
Is it the Window rect or Client rect?
On style not functionality,
I would create a function that only drew the axis given a HDC and RECT.
Also function that clears the HDC given a HDC and RECT, use BitBlt() and WHITENESS as the type of drawing (last param).
A function that graphs the data given a HDC, RECT and a pointer to the data.
If the user calls for a clear call the functions to do the drawing.
This is where having multiple HDC is a help, once you get used to them.
Create a DC for the axis, one for the actual graph and another for, if I understand correctly the user's drawings all exactly the same (an array).
The idea is that you redraw the entire graph, calc the axis ect. Then BitBlt() all the components (line, axis ect) to one HDC, the FrameBuffer.
Then call a paint with InvalidateRect().
In paint the FrameBuffer is only BitBlt()ed to the HDC returned from BeginPaint(), NOTHING more. If Windows calls for a paint only the FrameBuffer will be redrawn.
In other words try to have all the drawing finished BEFORE calling paint.
Your saying that I should do the drawing before WM_PAINT but eh only message that would accomedate that would be WM_CREATE. I tried moving the recently functionized(is that a word??) axis and marks drawing into WM_CREATE but I came out with a blank screen. Any suggestions?
BTW... if the functions are called from WM_PAINT they work fine. Am I mistaken about the order of messages but that wouldn't make sense, right?
Hard to describe as I do not know what / how your app works. Will tell you how mine does.
In WM_CREATE I have a StartUp function that does all the Start up things.
This includes creating two HDC's, with BMP's, compatible with the screen and the same size as the client area. These are the MAIN and FRAMEBUFFER. A small function BitBlt's them white (this will be used to clear the HDC's again later) .
These are released / deleted in my WM_CLOSE handling function.
When the user calls data (clicks a ctrl) from the server and asks for a graph I draw to one HDC (MAIN).
Small functions to do one of the following are called;
Clear HDC (as at start
Assemble data (convert to axis scales, POINT array)
Now I have the graph drawn, I BitBlt MAIN to the unused HDC (framebuffer) and call a paint (InvalidateRect ect). The framebuffer is used to BitBlt to the BeginPaint() hdc. The main never gets drawn to the screen (or goes near the paint function).
Now if Windows calls a paint the framebuffer is drawn, it contains the last graph (until the new graph is finished).
This gives good control over the drawing and is easier to debug (you can't put a break point in the paint as it generates a paint call itself).
How do you know to draw a new graph?