# resize problems

• 11-14-2001
Isometric
resize problems
I am trying to figure out how to make a coordinate plane. I figure it mostly out except for two problems:
1. I cant figure out how to stop the program from drawing the "marks" on the axis. I tried using 2 while statements(one for each axis) inside the while that makes the "marks" but that just put the marks on the top and left sides. Any ideas whats wrong?

2. The second problem is that whenever the user resizes the window it keeps the axis but the "marks" disappear. What can I do to fix this?

The code for the WM_SIZE and WM_PAINT is posted below:

Code:

```case WM_SIZE:           cxClient = LOWORD (lParam) ;//to calculate width           cyClient = HIWORD (lParam) ;//to calculate height           return 0 ;               case WM_PAINT:           hdc = BeginPaint (hwnd, &ps) ;           axis = CreatePen (PS_SOLID, 2, 0);           marks = CreatePen (PS_DOT, 1, 0);           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, marks);                     xspace=cxClient/10;//to find a point on the Y axis           yspace=cyClient/10;//to find a point on the X axis                     while(n<20){           xmarks = xspace * n;           ymarks = yspace * n;                                                     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                                                            n++;           }                                        EndPaint (hwnd, &ps) ;           return 0 ;```
• 11-14-2001
novacain
1. When dealing with GDI resources eg Pens, brushes ect, you must be very careful to replace any GDI's you SelectObject(). In your code you create two pens each time you get a repaint. Both of these are never released with DeleteObject(). This will cost memory. Eventually your PC will not be able to redraw.

When you use SelectObject() the return is the HGDIOBJ in the HDC. Catch this and hold until you have finished.

Code:

```hSysPen=SelectObject(hdc,hPen); /do drawing SelectObject(hdc,hsysPen); DeleteObject(hPen);```
2. Are the variables from the resize static? If not they will have 'lost' the value from the WM_SIZE before you get the WM_PAINT. The while loop counter n is also not initialised in the code. Are you resetting/defined it as zero?

You need a framebufferHDC/screenHDC to do all the drawing to. Will help in speed and ease of update. The framebuffer is an exact copy of the screen HDC eg have two HDC's (you have none). The new axis are drawn to the framebuffer when the user resizes. When all the drawing is done BitBlt() the framebuffer to the screen HDC. Then you call for a paint with InvalidateRect().
In the paint function the screen HDC is BitBlt() to the one you are getting from the PAINTSTRUCT (could also use ps.hdc)

There is a Paint function code and code to create the HDC's in the thread

3. I would use break; rather than return 0; but same result most of the time.
• 11-14-2001
DutchStud
Try this...
Code:

```case WM_SIZE:           cxClient = LOWORD (lParam) ;//to calculate width           cyClient = HIWORD (lParam) ;//to calculate height           n=0;  //This will set n to zero so it will redraw ticks           InvalidateRect(hwnd, NULL, true); //This will call wm_paint again.           break ;```
• 11-15-2001
DutchStud
for the tick problem...
Quote:

1. I cant figure out how to stop the program from drawing the "marks" on the axis. I tried using 2 while statements(one for each axis) inside the while that makes the "marks" but that just put the marks on the top and left sides. Any ideas whats wrong?

Try initializing n to -20 or something like that, maybe that will help.
• 11-16-2001
Isometric
I got the resize thing to stop but it still always makes those marks on the axis. Any suggestions for that one?
I already tried all of these none worked. Especially the -20 thing because of the division code it didnt would of given me some really wierd displays.
• 11-18-2001
novacain
Have you created a framebuffer and a screen HDC? If not your drawing will be very slow if you want to actually graph something.

Doing all that paint in the WM_PAINT msg will slow your program down and it will 'lock' on PC's with slow graphics cards. Too much code in the callback.

Have you 'watched' the values generated in the while loop for xmarks and ymarks? Then compared them to the client area?

Have you tried a for loop instead? (As you know the number of loops needed) Use two, based on the x and y cood.
Code:

```#define    NUM_MARKS      20 GetClientRect(hWnd,&Rect); xMarks=(Rect.right-Rect.left)/NUM_MARKS; for(x=Rect.left;x<Rect.right;x+=xMarks) //do x drawing```
With this one it does not matter if the user has resized the screen as long as you call a WM_PAINT in response to the WM_SIZE msg (find the one that tells you it has finished sizing/moving).
• 11-18-2001
Isometric
The latest code is posted below. How do I do a framebuffer? Also how should i lessen the code in WM_PAINT and still have the same effect?
One last question is there anyway to reverse the effects of teh 4:3 visual ration on monitors?
• 11-19-2001
novacain

There is code for both the paint function and to create a HDC.

Create TWO HDC's exactly the same.
Compatible with the HWND from the area you want to draw too and the same size as this area. [GetWindow() for the HWND and GetClientRect() for the size]. If in doubt create them the size of the screen.

One is FrameBufferHDC. This is the HDC to which you will do all the drawing. Create the axis on this one, graph to this one and write text to this one.

When ALL the drawing is finished, call a function that copies the FrameBufferHDC to the ScreenHDC. Do this with BitBlt() or if the screen has changed size, StretchBlt(). [I would get the BitBlt() then go on to the StretchBlt() later]. You will have an area, usually a rectangle that has been redrawn, get this to repaint by calling InvalidateRect(). This will send the WM_PAINT msg.

Call the function [Repaint()] in response to a WM_PAINT msg.
The HDC passed to it should be your ScreenHDC.

As all the drawing is done to one HDC and the repaint from another you can be redrawing the graph AND repainting the screen at the same time.
The paint contains NO calculations and ONE BitBlt() for speed. [BitBlt() is faster and much better than StretchBlt)]

I use a factor, aprox 1.17, to correct the yScale, as the pixcells on the monitor are not square but rectangular. Remember that the Y screen cood go DOWN and the Y scale usually goes UP.

PS make your HINSTANCE a global.
• 11-21-2001
Isometric
I understand the Screenbuffer thing but how do I use the factor? should I devide the xspace by 1.7 to square it?
• 11-21-2001
novacain
The y dimension of the pixcels is smaller than the x.

Look at your output and see if you need to multi the y cood by the factor (approx 1.17) before/during calculating the screen cood.
• 11-21-2001
Isometric
I multiplied ymarks by1.7 and still have a 3:4 ratio(3/10ths of a inch high by 4/10ths of a inch wide on a 17" monitor)
• 11-22-2001
novacain
Draw a lines with a known slope ie 1,2 ect and see if it draws correctly. Adjust as needed. (is your 1.7 a typo as I said 1.17)

Only use the correction if you see you need it from incorrect looking graphs.