Sorry

here's that bloody newbie again. I tried to write a simple programm that draws a circle to the client area of a window. I wanted that circle to move according to user-input.

But nothing happens. When you would take the time to look at this piece of code I would be very happy. The MessageBox-funktion is just a debugging measure. So I found out that this procedure isn't even executed.

Thank you

Here's the callback-proc


WndProc PROC mhWin :DWORD, uMsg:DWORD, uwParam:DWORD, ulParam:DWORD

LOCAL PS : PAINTSTRUCT
LOCAL hDC : DWORD
LOCAL minx, maxx : DWORD
LOCAL miny, maxy : DWORD
LOCAL CurrentPen : HGDIOBJ

.if uMsg == WM_CHAR
.if uwParam == VK_LEFT
sub circleposx, 5
.elseif uwParam == VK_RIGHT
add circleposx, 5
.elseif uwParam == VK_UP
sub circleposy, 5
.elseif uwParam == VK_DOWN
add circleposy, 5
.endif
invoke UpdateWindow, hWnd
invoke MessageBox, hWnd, ADDR szWindowName, ADDR szClassName, MB_OK
.elseif uMsg == WM_PAINT
invoke BeginPaint, mhWin, ADDR PS
[...]

And here's the MessageLoop


StartMessageLoop:
invoke GetMessage, ADDR msg, NULL, 0,0
cmp eax, 0
je ExitLoop
invoke TranslateMessage, ADDR msg
invoke DispatchMessage, ADDR msg
jmp StartMessageLoop
ExitLoop:
Posted on 2002-05-20 07:01:21 by Compuholic
try to replave WM_CHAR with WM_KEYDOWN
Posted on 2002-05-20 08:33:15 by NEMO
I already tried so,

same result.
Posted on 2002-05-20 08:49:14 by Compuholic
Consider attaching the whole source, it's hard to get an overview of it otherwise, plus the error might lie somewhere else.

Fake
Posted on 2002-05-20 09:09:32 by Fake51
Ok, here's the whole code.
Posted on 2002-05-20 09:52:48 by Compuholic
the problem is not in WM_KEYDOWN but in yoyr WM_PAINT routine -- it does not draw the circle. i want help u with this 'couse i'm not good in GDI but i can assure you that the WM_KEYDWON message is good to process arrow-keys

cya
Posted on 2002-05-20 10:22:56 by NEMO
It's possible that there are some errors in the WM_PAINT-routine (it's my first win32 application) but there must be an error in the WM_KEYDOWN/WM_CHAR-procedure too. Do you see the line:

invoke MessageBox, ... ?

If the code was executed I would see a MessageBox. This is my problem. btw. DefWindowProc seems to be called correctly because I am able to move my window.

Thanks for your help
Posted on 2002-05-20 10:52:21 by Compuholic
Nemo is right, there is no WM_CHAR message sent when an arrow key is pressed. Use WM_KEYDOWN instead. When you receive the message, use GetDC to redraw the screen. This should work :



; Draw the ellipse
DrawScreen PROC hDC:HDC
invoke GetStockObject, BLACK_PEN
mov CurrentPen, eax
invoke SelectObject, hDC, CurrentPen
invoke Ellipse, hDC, circleposx, circleposy
, circleposx, circleposy
invoke SelectObject, hDC, NULL
invoke DeleteObject, CurrentPen

ret
DrawScreen ENDP



WndProc PROC mhWin :DWORD, uMsg:DWORD, uwParam:DWORD, ulParam:DWORD

LOCAL PS : PAINTSTRUCT
LOCAL hDC : DWORD
LOCAL minx, maxx : DWORD
LOCAL miny, maxy : DWORD
LOCAL CurrentPen : HGDIOBJ

; .if uMsg == WM_CHAR
.if uMsg == WM_KEYDOWN

.if uwParam == VK_LEFT
sub circleposx, 5
.elseif uwParam == VK_RIGHT
add circleposx, 5
.elseif uwParam == VK_UP
sub circleposy, 5
.elseif uwParam == VK_DOWN
add circleposy, 5
.endif
;invoke UpdateWindow, hWnd
invoke GetDC, hWnd
mov hDC, eax
invoke DrawScreen, hDC
invoke ReleaseDC, hDC
invoke MessageBox, hWnd,
ADDR szWindowName,
ADDR szClassName, MB_OK
.elseif uMsg == WM_PAINT
invoke BeginPaint, mhWin, ADDR PS
invoke DrawScreen, eax
invoke EndPaint, mhWin, ADDR PS
.endif
invoke DefWindowProc, mhWin, uMsg, uwParam, ulParam
ret

WndProc endp

Posted on 2002-05-20 11:56:28 by Dr. Manhattan
Here's the working code. There were... a few things wrong.

1) Ellipse wasn't drawing the right ellipse
When you do this:
invoke Ellipse, hdc, circleposx-30, circleposx+30, etc

it's not calculating circleposx - 30. it's calculating the *address* circleposx - 30. In the code I just pushed the values manually

2) WM_CHAR will not detect VK_UP, etc. You must use WM_KEYDOWN or WM_KEYUP.

3) you were calling UpdateWindow, but not InvalidateRect after processing WM_CHAR. So the paint message isn't going to do much.

4) be careful how you define msg. You've got it defined as a local DWORD. This should be LOCAL msg:MSG. I'm surprised it never crashed...

5) You should invoke WinMain, and after the call to winMain returns, invoke ExitProcess. I kept having to kill the application after I ran it. Of course, you should also process WM_DESTROY and send the PostQuitMessage too.

6) I wouldn't DeleteObject the stock brush. I don't think that's safe.

--Chorus

PS I changed some of the variable names around as I was editting your source... It just helps me when I'm doing things the way I'm used to (ex. i got rid of hdc cause it's in PS anyways)
Posted on 2002-05-20 12:15:57 by chorus
Thanks @ all
Posted on 2002-05-20 12:31:01 by Compuholic

Here's the working code. There were... a few things wrong.

1) Ellipse wasn't drawing the right ellipse
When you do this:
invoke Ellipse, hdc, circleposx-30, circleposx+30, etc

it's not calculating circleposx - 30. it's calculating the *address* circleposx - 30. In the code I just pushed the values manually

2) WM_CHAR will not detect VK_UP, etc. You must use WM_KEYDOWN or WM_KEYUP.

3) you were calling UpdateWindow, but not InvalidateRect after processing WM_CHAR. So the paint message isn't going to do much.

4) be careful how you define msg. You've got it defined as a local DWORD. This should be LOCAL msg:MSG. I'm surprised it never crashed...

5) You should invoke WinMain, and after the call to winMain returns, invoke ExitProcess. I kept having to kill the application after I ran it. Of course, you should also process WM_DESTROY and send the PostQuitMessage too.

6) I wouldn't DeleteObject the stock brush. I don't think that's safe.


Dangit Chorus :) I was just about to give the exact same mouthful but you beat me to it hehe. Except for a couple of points:

- DeleteObject on a stock object wont hurt anything. The system just ignores it. It *is* a wasted call however.

- You fogot to null term one of the two strings in the data section.

- in the message loop, you should use jle and not je for a proper exit.

- in order to prevent memory leaks I would save the return value from SelectObject and use it to SelectObject it back at the end of the paint routine.

;)
Posted on 2002-05-20 13:35:12 by Graebel
sorry Graebal :)

A few comments:


-DeleteObject on a stock object wont hurt anything. The system just ignores it. It *is* a wasted call however.

- You fogot to null term one of the two strings in the data section.

- in the message loop, you should use jle and not je for a proper exit.

- in order to prevent memory leaks I would save the return value from SelectObject and use it to SelectObject it back at the end of the paint routine.


figured about as much for the DeleteObject.. but hey, better safe than sorry :)

Q: Why jle instead of je? If I'm not mistaken GetMessage will return 0 for WM_QUIT, and possibly -1 for an invalid window. But would you really end your app on -1?

I forgot to mention the selectobject thing, but it's in the code :)

Ciao

--Chorus
Posted on 2002-05-20 14:46:04 by chorus

Q: Why jle instead of je? If I'm not mistaken GetMessage will return 0 for WM_QUIT, and possibly -1 for an invalid window. But would you really end your app on -1?


This is just another example of M$'s shining attention to detail. The return val for GetMessage is listed as BOOL but its actually a Trillian where:

If the function retrieves a message other than WM_QUIT, the return value is TRUE.
If the function retrieves the WM_QUIT, the return value is FALSE.
If there is an error, the return value is -1. For example, the function fails if hWnd is an invalid window handle.

For most considerations, the return is indeed worthless. However I like to give as much information back to the caller as I can. And of course on the off chance that the hWnd (or anything else) failed, it would be nice to exit the loop. I am not positive because I dont feel like reproducing it (heh) but I think ExitProcess wouldnt be called if an error did occure which would tend to keep it in memory.
Posted on 2002-05-20 15:19:12 by Graebel