What am i doing wrong?

Pages: 12
Hi, i have this:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
case WM_PAINT:
				
HICON hIcon;
hIcon = LoadIcon(hInstance, MAKEINTRESOURCE(IDI_ICON1));
HDC handleDeviceContext; 
PAINTSTRUCT PaintSt;
handleDeviceContext = BeginPaint(hWnd, &PaintSt);
DrawIcon(handleDeviceContext, X, Y, hIcon);
EndPaint(hWnd, &PaintSt);
break;
			
case WM_LBUTTONDOWN:

switch(wParam)

case MK_LBUTTON:
	X += 750;
	Y += 750;
	UpdateWindow(hWnd);

	break;


Im trying to make the icon on screen move when i press the left mouse button.
I get the icon to display on screen, but no movement.
Did you declare X and Y as static? Show some more 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
LRESULT CALLBACK MessageProcedure(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
int X = 250;
int Y = 250;
HINSTANCE hInstance;
hInstance = LoadLibrary (TEXT("Application01.exe"));

switch(message)
{
case WM_PAINT:
				
HICON hIcon;
		
hIcon = LoadIcon(hInstance, MAKEINTRESOURCE(IDI_ICON1));
				
HDC handleDeviceContext; 
				
PAINTSTRUCT PaintSt;
				
handleDeviceContext = BeginPaint(hWnd, &PaintSt);
				
DrawIcon(handleDeviceContext, X, Y, hIcon);
				
EndPaint(hWnd, &PaintSt);
				
break;
			

case WM_LBUTTONDOWN:

switch(wParam)

case MK_LBUTTON:
X += 750;
Y += 750;
UpdateWindow(hWnd);

break;
Since you did not declare the X and Y variables as static, they get reset every time. Add the static keyword to them and it should work OK.
Thanks, the icon is now moving, but to get it to move I have to click in the display area and then resize the window to update the area, how can i get the display area to update without having to resize the window? I thought UpdateWindow() would have done the trick.
msdn wrote:
The function sends a WM_PAINT message directly to the window procedure of the specified window, bypassing the application queue. If the update region is empty, no message is sent.

http://msdn.microsoft.com/en-us/library/dd145167(v=vs.85).aspx

Consider using InvalidateRect instead.
http://msdn.microsoft.com/en-us/library/dd145002(v=vs.85).aspx
http://msdn.microsoft.com/en-us/library/dd145005(v=vs.85).aspx
It has worked, but i dont understand why it has worked, and why exactly UpdateWindow() did not work (even from reading the links you posted), could you try and explain ths please.
I'm only guessing too, as I've not done much with WinAPI.
MSDN wrote:
The UpdateWindow function updates the client area of the specified window by sending a WM_PAINT message to the window if the window's update region is not empty.


I should think your problem was that the update region was empty, so no WM_PAINT message was dispatched. On the other hand, the InvalidateRect() marks the specified region as pending update, and
MSDN wrote:
The system sends a WM_PAINT message to a window whenever its update region is not empty and there are no other messages in the application queue for that window.


Perhaps someone else better versed in the Windows API can tidy up my answer.
Last edited on
The update region was empty? It was not because the icon was displaying in the update region?

:)
Perhaps you are confusing client area with update region. The client area is the window minus the border and titlebar. The update region is a portion of the client area which has been marked as 'needing to be redrawn'.
Ah ok, thanks for your help! It is helpful :)

Im not 100% sure on how i go about setting the update region?
You can use InvalidateRect. The second parameter is a pointer to a RECT structure which specifies the area of the window to add to the update region. If you pass NULL (or 0) as this argument, the whole window is added. It's all in the documentation ;)
Ok, just wondering though, how would I set the update region if i were not to use InvalidateRect(), i mean, how was the update region empty before when i was using UpdateWindow()
Well the update region represents the part of the window needing redrawing, so suppose part of the window which was previously covered by another window were revealed. Then it would need to be drawn so that part of the window would be added to the update region. Similarly, parts would need to be redrawn if the window were resized.

In you example, I think you have to use something such as InvalidateRect to manually set the update region. Think about it. As far as the window and operating system are concerned, why should a mouse event cause invalidation of a window area?

Again, I am deducing this from the documentation with the help of some logical thinking. I may not be entirely correct, and perhaps someone can confirm what I've said.
Ah ok, so your saying I basically had to update region set to 0? I wernt sure whether I had already set the update region.
Also, how exactly do UpdateWindow() and InvalidateRect () differ?
InvaldiateRect() adds a rectangle to the update region. It does not in itself dispatch a WM_PAINT event. The reason this still works is as I said above:
MSDN wrote:
The system sends a WM_PAINT message to a window whenever its update region is not empty and there are no other messages in the application queue for that window.


UpdateWindow() dispatches a WM_PAINT event provided the update region is non empty. It doesn't change the update region (although, of course, the paint event probably will [after updating the window]).
InvalidateRect() erases and then redraws the specified rectangle within the window itself, assuming you've WM_PAINT or other such functions to do the redraw.

UpdateWindow() merely updates the window attributes and corroborating sysmtem parameters.

In other words, each deals with a completely different object.

If you haven't read Petzold's 5th edition of Programming Windows, you need to buy it. He deals with these kinids of things pretty extensively.
Last edited on
So is it the InvaldiateRect function which is actually creating the update region?
Pages: 12