News:

Masm32 SDK description, downloads and other helpful links
Message to All Guests
NB: Posting URL's See here: Posted URL Change

Main Menu

Forcing a paint from Window handler?

Started by BlueMR2, September 26, 2014, 09:05:11 AM

Previous topic - Next topic

six_L

Quote from: dedndave on October 17, 2014, 03:14:34 AM
what's the advantage of using WM_KEYDOWN over WM_CHAR ?
WM_CHAR message
Posted to the window with the keyboard focus when a WM_KEYDOWN message is translated by the TranslateMessage function. The WM_CHAR message contains the character code of the key that was pressed.
Because there is not necessarily a one-to-one correspondence between keys pressed and character messages generated, the information in the high-order word of the lParam parameter is generally not useful to applications. The information in the high-order word applies only to the most recent WM_KEYDOWN message that precedes the posting of the WM_CHAR message.
For enhanced 101- and 102-key keyboards, extended keys are the right ALT and the right CTRL keys on the main section of the keyboard; the INS, DEL, HOME, END, PAGE UP, PAGE DOWN and arrow keys in the clusters to the left of the numeric keypad; and the divide (/) and ENTER keys in the numeric keypad. Some other keyboards may support the extended-key bit in the lParam parameter.

WM_KEYDOWN message
Posted to the window with the keyboard focus when a nonsystem key is pressed. A nonsystem key is a key that is pressed when the ALT key is not pressed.
Say you, Say me, Say the codes together for ever.

dedndave

i read the docs
however, i still fail to see an advantage - lol

WM_KEYDOWN seems like a lower-level message
and WM_CHAR seems like a more "cleaned up/processed" version

at any rate - that is not the issue with his code, so it's a minor point

six_L

Quoteat any rate - that is not the issue with his code.
if use the WM_CHAR,his code can't work.
please test it.
.686
.model flat,stdcall
option casemap:none
;¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤
include \masm32\include\windows.inc
include \masm32\include\kernel32.inc
include \masm32\include\user32.inc
include \masm32\include\gdi32.inc
include \masm32\include\masm32.inc

includelib \masm32\lib\kernel32.lib
includelib \masm32\lib\user32.lib
includelib \masm32\lib\gdi32.lib
includelib \masm32\lib\masm32.lib
;¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤
include \masm32\macros\macros.asm
;¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤
WinMain PROTO :DWORD,:DWORD,:DWORD,:DWORD
WndProc PROTO :DWORD,:DWORD,:DWORD,:DWORD
TopXY PROTO :DWORD,:DWORD
;¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤
.data
        szDisplayName db "testt",0
        szClassName   db "testt",0
        dwYpos dd 100
        dwXpos dd 100
;¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤
.data?       
        CommandLine   dd ?
        hWnd          dd ?
        hInstance     dd ?
        hIcon         dd ?
;¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤
.code
;¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤
start:
invoke GetModuleHandle, NULL
mov hInstance, eax

invoke GetCommandLine
mov CommandLine, eax

invoke WinMain,hInstance,NULL,CommandLine,SW_SHOWDEFAULT
invoke ExitProcess,eax
;¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤
WinMain proc hInst:DWORD,hPrevInst:DWORD,CmdLine:DWORD,CmdShow:DWORD
LOCAL wc   :WNDCLASSEX
LOCAL msg  :MSG
LOCAL Wwd  :DWORD
LOCAL Wht  :DWORD
LOCAL Wtx  :DWORD
LOCAL Wty  :DWORD

invoke LoadIcon,hInst,500    ; icon ID
mov hIcon, eax
mov wc.cbSize,sizeof WNDCLASSEX
mov wc.style, CS_HREDRAW or CS_VREDRAW or CS_BYTEALIGNWINDOW
mov wc.lpfnWndProc,offset WndProc
mov wc.cbClsExtra,NULL
mov wc.cbWndExtra,NULL
m2m wc.hInstance,hInst
mov wc.hbrBackground,NULL
mov wc.lpszMenuName,NULL
m2m wc.lpszClassName,offset szClassName
m2m wc.hIcon,hIcon
invoke LoadCursor,NULL,IDC_ARROW
mov wc.hCursor,eax
m2m wc.hIconSm,hIcon

invoke RegisterClassEx, ADDR wc

mov Wwd, 600
mov Wht, 500

invoke GetSystemMetrics,SM_CXSCREEN
invoke TopXY,Wwd,eax
mov Wtx, eax

invoke GetSystemMetrics,SM_CYSCREEN
invoke TopXY,Wht,eax
mov Wty, eax

invoke CreateWindowEx, WS_EX_CLIENTEDGE,ADDR szClassName,ADDR szDisplayName,
                            WS_OVERLAPPEDWINDOW - WS_MAXIMIZEBOX,Wtx,Wty,Wwd,Wht,
                            NULL,NULL,hInst,NULL
mov hWnd,eax

invoke ShowWindow,hWnd,SW_SHOWNORMAL
invoke UpdateWindow,hWnd

.while TRUE
invoke GetMessage, ADDR msg,NULL,0,0
.break .if (!eax)
invoke TranslateMessage, ADDR msg
invoke DispatchMessage, ADDR msg
.endw
mov eax,msg.wParam
ret

WinMain endp
;¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤
WndProc proc hWin:DWORD,uMsg:DWORD,wParam:DWORD,lParam:DWORD
local ps:PAINTSTRUCT
   
.if uMsg == WM_COMMAND
;======== menu commands ========
.elseif uMsg == WM_KEYDOWN
.if     wParam==VK_ESCAPE
invoke  PostMessage,hWnd,WM_SYSCOMMAND,SC_CLOSE,NULL    ; Close full screen window
.elseif wParam==VK_UP
mov eax,dwYpos
sub     eax,5     
mov dwYpos,eax
;dec dwYpos
.elseif wParam==VK_DOWN
mov eax,dwYpos
add     eax,5     
mov dwYpos,eax
;inc dwYpos
.elseif wParam==VK_RIGHT
mov eax,dwXpos
add     eax,5     
mov dwXpos,eax
;inc dwXpos
.elseif wParam==VK_LEFT
mov eax,dwXpos
sub     eax,5     
mov dwXpos,eax
;dec dwXpos
.endif   
;mov     eax, dwXpxos     
;mov     updateregion.left, eax
;mov     updateregion.right, eax
;mov     eax, dwYpos
;mov     updateregion.top, eax
;mov     updateregion.bottom, eax
;invoke  InvalidateRect,hWndMain,offset updateregion,FALSE
invoke  InvalidateRect,hWin,NULL,FALSE
invoke  UpdateWindow,hWin

.elseif uMsg==WM_PAINT

invoke  BeginPaint,hWin,addr ps
invoke  SetPixel,ps.hdc,dwXpos,dwYpos,0FFFF00h
invoke  EndPaint,hWin,addr ps
.elseif uMsg == WM_CLOSE
invoke PostMessage,hWin,WM_DESTROY,0,0

.elseif uMsg == WM_DESTROY
invoke PostQuitMessage,NULL
.else
invoke DefWindowProc,hWin,uMsg,wParam,lParam
ret
.endif
xor eax,eax
ret

WndProc endp
;¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤
TopXY proc wDim:DWORD, sDim:DWORD

shr sDim, 1      ; divide screen dimension by 2
shr wDim, 1      ; divide window dimension by 2
mov eax, wDim    ; copy window dimension into eax
sub sDim, eax    ; sub half win dimension from half screen dimension

mov eax,sDim
ret

TopXY endp
;¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤

end start
Say you, Say me, Say the codes together for ever.

dedndave

that IS an advantage - lol
thanks for the heads up   :t

dedndave


dedndave

i created a "project" out of the source - one thing that means is adding a manifest
under XP, if you call InitCommonControlsEx, you should add a manifest
also, a manifest and revision control block help prevent anti-virus false positives

one change i made was to make the dot 2x2 pixels so i could see it a little better
there are a few ways to do that, but i used MoveToEx and LineTo
that means creating a pen or pens
i created 1 pen (black) to draw the dot, and 1 pen (COLOR_SCROLLBAR) to undraw the dot

in the original code, you attempted to use an update rectangle
i wanted to mention that windows rectangles normally use the following convention:
the left and top coordinates are inclusive
the right and bottom coordinates are exclusive
so, if left = right or if top = bottom, it's an empty rectangle
the convention works so that width = right - left and height = bottom - top

there are a variety of ways to handle the painting
because this program is full-screen and always on top, you get away with certain things
it's probably better to expirement with a normal sizable window, so you learn the issues involved

at any rate, here's the modified program...

BlueMR2

Quote from: six_L on October 17, 2014, 05:24:31 PM
if use the WM_CHAR,his code can't work.

Well, gee, that's interesting!  I totally don't understand why it works.  I tried inserting system exit commands in under the keys and I swear it executed on only the keys I specified it for.  Obviously I'm not understanding something here.  However, I can use it and work with it.  Perhaps understanding will come later.  :-)  Thanks!
My Code Site
https://github.com/BrianKnoblauch

BlueMR2

Quote from: dedndave on October 19, 2014, 12:10:14 AM
i created a "project" out of the source - one thing that means is adding a manifest
under XP, if you call InitCommonControlsEx, you should add a manifest
also, a manifest and revision control block help prevent anti-virus false positives

one change i made was to make the dot 2x2 pixels so i could see it a little better
there are a few ways to do that, but i used MoveToEx and LineTo
that means creating a pen or pens
i created 1 pen (black) to draw the dot, and 1 pen (COLOR_SCROLLBAR) to undraw the dot

in the original code, you attempted to use an update rectangle
i wanted to mention that windows rectangles normally use the following convention:
the left and top coordinates are inclusive
the right and bottom coordinates are exclusive
so, if left = right or if top = bottom, it's an empty rectangle
the convention works so that width = right - left and height = bottom - top

there are a variety of ways to handle the painting
because this program is full-screen and always on top, you get away with certain things
it's probably better to expirement with a normal sizable window, so you learn the issues involved

at any rate, here's the modified program...

Great stuff, thanks!  That also helps a good deal and answers some future questions I suspected I might have.  :-)

I assumed there was some sort of manifest, and I knew the icon stuff was "broken" (but I didn't focus on it since it seemed to be running anyways).  Good to see how it works.

Line and pens was exactly where I'd wanted to go next too.

The update rectangle ranges is very good to know.  I read the docs, but I don't recall it being especially clear on that.  Also, my experimentation lead me away from trying to get fancy stuff like exact update ranges working anyways since my problem seemed to be much more fundamental!  My project initial goal is to do some of my simpler old full-screen DOS style stuff as full-screen Windows.  I'll get to the windowed stuff eventually.  That should provide additional hours of entertainment!  ;-)
My Code Site
https://github.com/BrianKnoblauch

dedndave

as i mentioned earlier, this is a special case because the window is always on top and full screen
what that means is, the only WM_PAINT messages you should receive are those you generate

imagine a normal sizable window - with other windows
the user switches from one to another - perhaps minimizing, restoring, etc
these actions may cause WM_PAINT messages to your window to initiate redraw of part or all of the client area
that doesn't happen in this program, so you can take certain liberties

in this case, we know that a WM_PAINT message means "update the dot"
so, specifying a rectangle is somewhat unnecessary

you may also miss out on issues like flicker, background redraw, and so on
so - if you really want to learn about drawing and painting, a normal window would be better

BlueMR2

Quote from: dedndave on October 23, 2014, 01:07:08 PM
as i mentioned earlier, this is a special case because the window is always on top and full screen
what that means is, the only WM_PAINT messages you should receive are those you generate

imagine a normal sizable window - with other windows
the user switches from one to another - perhaps minimizing, restoring, etc
these actions may cause WM_PAINT messages to your window to initiate redraw of part or all of the client area
that doesn't happen in this program, so you can take certain liberties

in this case, we know that a WM_PAINT message means "update the dot"
so, specifying a rectangle is somewhat unnecessary

you may also miss out on issues like flicker, background redraw, and so on
so - if you really want to learn about drawing and painting, a normal window would be better

Yeah, I see your point.  I'd assume I'd have to be double buffering in that case, so I have something to update from?

Got a few minutes to toy around again with it today finally.  Added support for keyup and reworked it so multiple keys being held down are handled for diagonals.  Very simplistic, but works as long as you don't hold down 3+ keys.  :-)  Also flipped the paint invocations (from myself to myself) to be timer based to make that all work a little smoother (also makes for a rudimentary speed control).
My Code Site
https://github.com/BrianKnoblauch

dedndave

there are several issues (of course)
but, the 2 most obvious are the background redraw and double-buffering

when you InvalidateRect, you get to tell windows whether or not you want the background redrawn
if we are drawing text on an occassional basis, we may want windows to redraw the background to get rid of the old content
for graphics, redrawing the background can cause an objectionable flicker problem

there are a few ways to handle this
one way is to redraw the background, yourself
in fact, what i quite often do is to set WNDCLASSEX.hbrBackground = NULL
QuoteWhen this member is NULL, an application must paint its own
background whenever it is requested to paint in its client area.
then, i have complete control over the background color and how it's drawn
i usually use PatBlt in the WM_PAINT code to fill the desired rectangle before drawing my graphics

the other is double-buffering
there have been several examples in the forum
1. BeginPaint
2. CreateCompatibleDC
3. CreateCompatibleBitmap, and select it into the compatible DC
4. select brushes, pens, modes, etc
5. perform all drawing
6. use BitBlt to copy the desired rectangle into the display DC
7. restore the DC to original context
8. delete the compatible bitmap and DC
9. EndPaint

without double-buffering, steps 2, 3, 6, and 8 are not performed