I'm hung up with something that should be easy, but continues to elude me. My key handling section of the window handler gets called as appropriate. I then adjust some variables used by my paint handler. However, the paint handler never gets called again. I'm guessing I have to send some sort of signal to let windows know that I need to repaint. Is that even the correct approach? I've tried a number of things and while they all assemble fine, none of them seem to do anything. :-)
there are a couple ways to cause it to update, but first....
windows keeps track of what is called an "update region"
if some other window is on top of yours, let's say, in the lower right corner,
then that window is removed or minimized, the portion of your window that needs to be repainted is set into the update region
other things can cause the update region to change, as well
when windows sees that a window has no other (higher priority) messages in the queue,
and the update region is not NULL, it sends a WM_PAINT message
there is a RECT structure inside the PAINTSTRUCT that tells you what portion requires update
the simple way is to cause it to add the entire client area to the update region
INVOKE InvalidateRect,hWnd,NULL,<background_flag>
the first argument is the window handle
the second is a pointer to a client coordinate rectangle describing the region to add (NULL = entire client)
the third one is TRUE if you want the background redrawn, FALSE if not
http://msdn.microsoft.com/en-us/library/dd145002%28v=vs.85%29.aspx (http://msdn.microsoft.com/en-us/library/dd145002%28v=vs.85%29.aspx)
in the left pane of that page, you'll see a few other functions
InvalidateRgn is similar (regions are irregular or non-rectangular areas)
ValidateRect and ValidateRgn are related
and, RedrawWindow may also be used to force a redraw (often used to redraw the entire window)
you can use this thread for flicker related problems, as well :biggrin:
BLUEMR2,
As always,...DAVE (above) is correct.
If you need an immediate Repaint of the client area, just call: UpdateWindow (http://msdn.microsoft.com/en-us/library/dd145167(v=vs.85).aspx).
I usually call this in tandem with: ShowWindow (http://msdn.microsoft.com/en-us/library/windows/desktop/ms633548(v=vs.85).aspx).
This NEVER fails and is totally foolproof,...:icon_eek:
true enough - you may see the two functions used together
INVOKE InvalidateRect,hWnd,NULL,TRUE
INVOKE UpdateWindow,hWnd
InvalidateRect adds some area to the update region
but, the operating system treats WM_PAINT messages as a low priority
the message loop queue will only dispatch WM_PAINT to WndProc when no other messages are in the queue
UpdateWindow, on the other hand, causes the WM_PAINT message to be sent immediately, bypassing the queue
however - it only does so if the update region is not empty :P
http://msdn.microsoft.com/en-us/library/dd145167%28v=vs.85%29.aspx
The RedrawWindow function seems to be quite useful for forcing updates. Useful for containers that have children and you dont want to enumerate them all before calling invalidrect/updatewindow.
Invoke RedrawWindow, hWin, NULL, NULL, RDW_UPDATENOW + RDW_INVALIDATE + RDW_ALLCHILDREN
i was using RedrawWindow for a while - thinking it worked great
but, it may have a nasty side-effect
when calling RedrawWindow for several windows (children, etc), it seems to cause the desktop to refresh
this is particularly noticable when you first open the app
RedrawWindow may be a necessary call if you change the appearance of the non-client area (borders, etc)
otherwise, i stopped using it for general-purpose updates
Well, gee, I'm really at a loss then. Great information, but I'm still not able to get it working. I know the right part of the key handler is called, I can insert an exit app function call in there and it happens. However, when I have code there that updates the location variables for my graphics, I never see anything change on-screen. I've tried limiting the update region to just the area affected and I've also tried it as the full window (via NULL). I tried tracing it through with Ollydbg, but with my single screen machine here that doesn't work terribly well and I end up having to force a shutdown of Ollydbg.
I do an initial set of the variables based on the WM_CREATE message. Is that ever called after the initial creation of the window? Perhaps I misunderstand how that message works and I'm repeatedly overwriting my changes with the defaults?
maybe this example will help - you can ignore the Bezier spline stuff, and just look at InvalidateRect, WM_PAINT, WM_TIMER, etc
http://masm32.com/board/index.php?topic=1969.msg20895#msg20895 (http://masm32.com/board/index.php?topic=1969.msg20895#msg20895)
WM_CREATE is sent only once
the window is created, but not displayed at that time (as i remember)
the CreateWindowEx call does not exit until WM_CREATE has returned
Quote from: BlueMR2 on October 07, 2014, 05:29:34 AMI tried tracing it through with Ollydbg
That won't work, too much stuff happening in parallel.
Attached an example that uses the deb macro to display all messages in a console, with the exception of a few frequent but irrelevant ones, such WM_MOUSEMOVE. Plug in your code in the appropriate handlers and watch which messages are of interest. You can insert an extra
deb (http://www.webalice.it/jj2006/MasmBasicQuickReference.htm#Mb1019) wherever you need it - see Other WM_COMMAND in the source. Below a typical output. You can see that the first WM_PAINT comes late in the process, as msg #33. The edit control's ID is 103.
msg chg:msgCount 1 uMsg = Start monitoring
msg chg:msgCount 2 uMsg = WM_GETMINMAXINFO
msg chg:msgCount 3 uMsg = WM_NCCREATE
msg chg:msgCount 4 uMsg = WM_NCCALCSIZE
msg chg:msgCount 5 uMsg = WM_CREATE
msg chg:msgCount 6 uMsg = WM_WINDOWPOSCHANGING
msg chg:msgCount 7 uMsg = WM_NCCALCSIZE
msg chg:msgCount 8 uMsg = WM_WINDOWPOSCHANGED
msg chg:msgCount 9 uMsg = WM_MOVE
msg chg:msgCount 10 uMsg = WM_SIZE
msg chg:msgCount 11 uMsg = WM_PARENTNOTIFY
msg chg:msgCount 12 uMsg = WM_WINDOWPOSCHANGING
msg chg:msgCount 13 uMsg = WM_ACTIVATEAPP
msg chg:msgCount 14 uMsg = WM_NCACTIVATE
msg chg:msgCount 15 uMsg = WM_ACTIVATE
msg chg:msgCount 16 uMsg = WM_IME_SETCONTEXT
msg chg:msgCount 17 uMsg = WM_IME_NOTIFY
msg chg:msgCount 18 uMsg = WM_SETFOCUS
msg chg:msgCount 19 uMsg = WM_KILLFOCUS
msg chg:msgCount 20 uMsg = WM_IME_SETCONTEXT
Other WM_COMMAND
eax 103
edx 256
lParam 199984
msg chg:msgCount 21 uMsg = WM_COMMAND
msg chg:msgCount 22 uMsg = WM_SHOWWINDOW
msg chg:msgCount 23 uMsg = WM_WINDOWPOSCHANGING
msg chg:msgCount 24 uMsg = WM_NCPAINT
msg chg:msgCount 25 uMsg = WM_GETTEXT
msg chg:msgCount 26 uMsg = WM_ERASEBKGND
msg chg:msgCount 27 uMsg = WM_WINDOWPOSCHANGED
msg chg:msgCount 28 uMsg = WM_SIZE
msg chg:msgCount 32 uMsg = WM_MOVE
msg chg:msgCount 33 uMsg = WM_PAINT
msg chg:msgCount 34 uMsg = WM_CTLCOLOREDIT
msg chg:msgCount 35 uMsg = WM_CTLCOLOREDIT
msg chg:msgCount 36 uMsg = WM_NCACTIVATE
msg chg:msgCount 37 uMsg = WM_GETTEXT
msg chg:msgCount 38 uMsg = WM_ACTIVATE
msg chg:msgCount 39 uMsg = WM_ACTIVATEAPP
Other WM_COMMAND
eax 103
edx 512
lParam 199984
Hi, BLUEMR2,
This one has me mystified too. Like you stated in the first post, it should be simple.
Is this a normal windows app, or is it a DirectX app ?
If it is a DirectX app, you should be polling for the key down actions, and not waiting for the normal Windows message.
...Also, you can define your own windows message identifiers (http://msdn.microsoft.com/en-us/library/windows/desktop/ms644931(v=vs.85).aspx),...and, then call SendMessage (http://msdn.microsoft.com/en-us/library/windows/desktop/ms644950(v=vs.85).aspx) to send them to your window. It's FUN. I often do this for testing purposes,...and, if you eventually post your source code here on the MASM Forum,...it confuses other assembly programmers,...yes, sometimes even DAVE,...
Here is: About Messages and Message Queues, MSDN (http://msdn.microsoft.com/en-us/library/windows/desktop/ms644927(v=vs.85).aspx), which you have no doubt already read.
Here is: Keyboard Input, MSDN (http://msdn.microsoft.com/en-us/library/windows/desktop/ms645530(v=vs.85).aspx), which you undoubtedly have already read.
And, here's more: GetAsyncKeyState, MSDN (http://msdn.microsoft.com/en-us/library/windows/desktop/ms646293(v=vs.85).aspx),...again, I'm certain you have already read this,...
But, really,...what I'm wondering is: Why don't you show us some code ??? MASM Forum residents LOVE source code,...
Quote from: Zen on October 07, 2014, 06:55:01 AM
But, really,...what I'm wondering is: Why don't you show us some code ??? MASM Forum residents LOVE source code,...
Excellent point, Zen. :t
Gunther
OK, I'll try to trim it down to the bare essentials. Here's an example based heavily (like 98%) :-) on Dave's "display a dot" code, but theoretically, the dot should move with various keypresses. I've commented out some extra code that I tried that also does nothing.
I'll be going through the code recently attached above, as well as the referenced links again. I appreciate all the help, whatever I'm missing is probably something really simple and silly...
Also, sorry for the big gaps in time between posts, but lately I only get an hour or 2 every couple of weeks to play on my computer at home... :-(
.686
option casemap:none
include \masm32\include\masm32rt.inc
FSWnd PROTO :HWND,:UINT,:WPARAM,:LPARAM
.data
icc INITCOMMONCONTROLSEX <sizeof INITCOMMONCONTROLSEX,0>
wc WNDCLASSEX <sizeof WNDCLASSEX,NULL,FSWnd,0,0,?,?,?,COLOR_SCROLLBAR+1,NULL,szClassName,?>
szAppName db 'ProjectCQB',0
szClassName db 'ProjectCQBClass',0
.data?
hwndMain HWND ?
dwXpos dd ?
dwYpos dd ?
msg MSG <>
updateregion RECT <> ; Left, Top, Right, Bottom
.code
start:
call main
invoke ExitProcess,eax
FSPaint PROC hWnd:HWND
local ps :PAINTSTRUCT
invoke BeginPaint,hWnd,addr ps
invoke SetPixel,ps.hdc,dwXpos,dwYpos,0
invoke EndPaint,hWnd,addr ps
ret
FSPaint ENDP
FSWnd PROC hWnd:HWND,uMsg:UINT,wParam:WPARAM,lParam:LPARAM
mov eax,uMsg
.if eax==WM_PAINT
invoke FSPaint,hWnd
xor eax,eax
.elseif eax==WM_CREATE
invoke GetSystemMetrics,SM_CYSCREEN
mov edx,eax
push eax
shr edx,1
mov dwYpos,edx
invoke GetSystemMetrics,SM_CXSCREEN
mov edx,eax
shr edx,1
mov dwXpos,edx
pop ecx
mov edx,hWnd
mov hwndMain,edx
invoke SetWindowPos,edx,HWND_TOPMOST,0,0,eax,ecx,0
xor eax,eax
.elseif eax==WM_CHAR
.if wParam==VK_ESCAPE
invoke PostMessage,hWnd,WM_SYSCOMMAND,SC_CLOSE,NULL ; Close full screen window
.elseif wParam==VK_UP
dec dwYpos
.elseif wParam==VK_DOWN
inc dwYpos
.elseif wParam==VK_RIGHT
inc dwXpos
.elseif wParam==VK_LEFT
dec dwXpos
.endif
;mov eax, dwXpos
;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,hWnd,NULL,FALSE
invoke UpdateWindow,hWnd
xor eax,eax
.elseif eax==WM_CLOSE
invoke DestroyWindow,hWnd
xor eax,eax
.elseif eax==WM_DESTROY
invoke PostQuitMessage,NULL
xor eax,eax
.else
invoke DefWindowProc,hWnd,uMsg,wParam,lParam
.endif
ret
FSWnd ENDP
main PROC
invoke InitCommonControlsEx,offset icc ;initialize common controls
;register the window class
xor edi,edi ;EDI = 0
mov esi,offset wc ;ESI = offset wc
invoke GetModuleHandle,edi
mov [esi].WNDCLASSEX.hInstance,eax
xchg eax,ebx ;EBX = wc.hInstance
invoke LoadIcon,ebx,501
mov [esi].WNDCLASSEX.hIcon,eax
mov [esi].WNDCLASSEX.hIconSm,eax
invoke LoadCursor,edi,IDC_ARROW
mov [esi].WNDCLASSEX.hCursor,eax
invoke RegisterClassEx,esi
;create the window
invoke CreateWindowEx,edi,offset szClassName,offset szAppName,
WS_POPUP or WS_VISIBLE or WS_CLIPCHILDREN,
CW_USEDEFAULT,SW_SHOWNORMAL,edi,edi,edi,edi,ebx,edi
invoke UpdateWindow,eax
;message loop
mov esi,offset msg ;ESI = msg structure address
jmp short mLoop1
mLoop0: invoke TranslateMessage,esi
invoke DispatchMessage,esi
mLoop1: invoke GetMessage,esi,edi,edi,edi
inc eax ;exit only
shr eax,1 ;if 0 or -1
jnz mLoop0 ;otherwise, we loop
mov eax,[esi].MSG.wParam
ret
main ENDP
end start
.data
dwYpos dd 100
dwXpos dd 100
.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
Six_L - what's the advantage of using WM_KEYDOWN over WM_CHAR ?
Quote from: dedndave on October 17, 2014, 03:14:34 AM
what's the advantage of using WM_KEYDOWN over WM_CHAR ?
WM_CHAR messagePosted 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 messagePosted 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.
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
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
that IS an advantage - lol
thanks for the heads up :t
etch-a-sketch
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...
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!
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! ;-)
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
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).
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