wm_paint problem

I'm trying to draw a polygon but It the polygon is drawn after I resize the window. Can anyone tell what's wrong? I think the error is in this code.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
LRESULT CALLBACK WndProc (HWND hwnd, UINT message, WPARAM wparam, LPARAM lparam)
{
	HDC hdc;
	PAINTSTRUCT ps;

	HBRUSH brush;
	HPEN pen;

	if(message == WM_DESTROY || lparam == VK_ESCAPE){
		PostQuitMessage(0);
		return(0);
	}

    if(message == WM_PAINT){
            hdc = BeginPaint( hwnd, &ps );
			
			brush = CreateSolidBrush(RGB(0, 200, 0));
			pen = CreatePen(PS_SOLID, 3, RGB(0, 0, 0));

			SelectObject(hdc, brush);
			SelectObject(hdc, pen);

            Polygon(hdc, the points, 3);

            EndPaint(hwnd, &ps);
			return(0);
	}
    return DefWindowProc(hwnd, message, wparam, lparam);
}
I don't see anything that would cause it to draw only on resize... but I do spot 3 problems.

1) You are not deleting the objects you are creating (memory leaks)
2) You should not [permanently] modify the screen DC's pens/brushes. Any changes you make should be reverted as soon as you're done:
3) "the points" (with a space) is not a valid identifier. This tells me this code is not a copy/paste of your actual code, and therefore may not accurately represent what you're really doing... so you may not be illustrating the problem to us here.

Fix:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
            hdc = BeginPaint( hwnd, &ps );
			
			brush = CreateSolidBrush(RGB(0, 200, 0));
			pen = CreatePen(PS_SOLID, 3, RGB(0, 0, 0));

			HGDIOBJ oldbrush = SelectObject(hdc, brush);
			HGDIOBJ oldpen = SelectObject(hdc, pen);

            Polygon(hdc, the points, 3);

            SelectObject(hdc,oldbrush);
            SelectObject(hdc,oldpen);
            EndPaint(hwnd, &ps);
            DeleteObject(brush);
            DeleteObject(pen);
Last edited on
I don't understand what you mean by that I should not modify the DC's pens permanently. But that's probably not important. About the stupid triangle, it's like it is drawn in the corner. Here is the whole code

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
#include "stdafx.h"
#include "projection.h"

POINT p[3];

HBRUSH brush;
HPEN pen;

LRESULT CALLBACK WndProc(HWND hwnd, UINT message, WPARAM wparam, LPARAM lparam);
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR szCmdLine, int iCmdShow);

int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR szCmdLine, int iCmdShow){


	WNDCLASS wc;
    wc.cbClsExtra = 0;
    wc.cbWndExtra = 0; 
    wc.hbrBackground = CreateSolidBrush(RGB(200, 0, 0));
    wc.hCursor = LoadCursor( NULL, IDC_ARROW );
    wc.hIcon = LoadIcon( NULL, IDI_APPLICATION );
    wc.hInstance = hInstance;
    wc.lpfnWndProc = WndProc;
    wc.lpszClassName = TEXT("1");

    wc.lpszMenuName = 0;
    wc.style = CS_HREDRAW | CS_VREDRAW;

	RegisterClass( &wc );

	HWND hwnd = CreateWindow(
	TEXT("1"),
	TEXT("2"),
	WS_OVERLAPPEDWINDOW,
    10,
	10,
	200,
	200,
    NULL,
	NULL,
    hInstance,
	NULL ); 
	ShowWindow(hwnd, iCmdShow );
    UpdateWindow(hwnd);

	MSG msg;

	p[0].x = 10;
	p[0].y = 10;

	p[1].x = 110;
	p[1].y = 10;

	p[2].x = 50;
	p[2].y = 100;

	while( GetMessage( &msg, NULL, 0, 0 ) )
    {
        TranslateMessage( &msg );
        DispatchMessage( &msg );
	}
    return msg.wParam;
}

LRESULT CALLBACK WndProc (HWND hwnd, UINT message, WPARAM wparam, LPARAM lparam)
{
	HDC hdc;
	PAINTSTRUCT ps;

	if(message == WM_DESTROY || lparam == VK_ESCAPE){
		PostQuitMessage(0);
		return(0);
	}

    if(message == WM_PAINT){
            hdc = BeginPaint( hwnd, &ps );
			
			brush = CreateSolidBrush(RGB(0, 200, 0));
			pen = CreatePen(PS_SOLID, 3, RGB(0, 0, 0));

			HGDIOBJ oldbrush = SelectObject(hdc, brush);
			HGDIOBJ oldpen = SelectObject(hdc, pen);

            Polygon(hdc, p, 3);
			
            SelectObject(hdc,oldbrush);
            SelectObject(hdc,oldpen);
            EndPaint(hwnd, &ps);
            DeleteObject(brush);
            DeleteObject(pen);

			return(0);
	}
    return DefWindowProc(hwnd, message, wparam, lparam);
}
You are calling ShowWindow before you initialize your 'p' array.

This means the window is drawn before the polygon has been set up. Which means the polygon will only be visible after a redraw is forced (ie: by resizing).

Don't show the window until after 'p' is initialized. Or force a redraw (with InvalidateRect()) after you initialize 'p'.

I don't understand what you mean by that I should not modify the DC's pens permanently.


The screen DC has a designated pen and brush. When you call SelectObject(), you are removing that pen/brush and replacing it with your own. This is fine to do when drawing, but you should not do this long term -- that is, you should revert the screen DC to its original pen/brush when you are done drawing.
Solved it! WndProc runs before I set the Points right. Thanks for the moral support!
Topic archived. No new replies allowed.