The MASM Forum

General => The Campus => Topic started by: BlueMR2 on September 26, 2014, 09:05:11 AM

Title: Forcing a paint from Window handler?
Post by: BlueMR2 on September 26, 2014, 09:05:11 AM
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.  :-)
Title: Re: Forcing a paint from Window handler?
Post by: dedndave on September 26, 2014, 09:55:25 AM
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)
Title: Re: Forcing a paint from Window handler?
Post by: dedndave on September 26, 2014, 10:02:12 AM
you can use this thread for flicker related problems, as well   :biggrin:
Title: Re: Forcing a paint from Window handler?
Post by: Zen on September 27, 2014, 04:41:31 AM
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:
Title: Re: Forcing a paint from Window handler?
Post by: dedndave on September 27, 2014, 05:21:25 AM
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
Title: Re: Forcing a paint from Window handler?
Post by: fearless on September 27, 2014, 09:04:24 AM
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
Title: Re: Forcing a paint from Window handler?
Post by: dedndave on September 27, 2014, 09:47:12 AM
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
Title: Re: Forcing a paint from Window handler?
Post by: BlueMR2 on October 07, 2014, 05:29:34 AM
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?
Title: Re: Forcing a paint from Window handler?
Post by: dedndave on October 07, 2014, 06:09:56 AM
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
Title: Re: Forcing a paint from Window handler?
Post by: jj2007 on October 07, 2014, 06:44:40 AM
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
Title: Re: Forcing a paint from Window handler?
Post by: Zen on October 07, 2014, 06:55:01 AM
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,...
Title: Re: Forcing a paint from Window handler?
Post by: Gunther on October 07, 2014, 08:45:13 AM
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
Title: Re: Forcing a paint from Window handler?
Post by: BlueMR2 on October 16, 2014, 11:43:58 AM
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
Title: Re: Forcing a paint from Window handler?
Post by: six_L on October 16, 2014, 10:19:14 PM
.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

Title: Re: Forcing a paint from Window handler?
Post by: dedndave on October 17, 2014, 03:14:34 AM
Six_L - what's the advantage of using WM_KEYDOWN over WM_CHAR ?
Title: Re: Forcing a paint from Window handler?
Post by: six_L on October 17, 2014, 02:06:27 PM
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.
Title: Re: Forcing a paint from Window handler?
Post by: dedndave on October 17, 2014, 02:15:33 PM
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
Title: Re: Forcing a paint from Window handler?
Post by: six_L on October 17, 2014, 05:24:31 PM
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
Title: Re: Forcing a paint from Window handler?
Post by: dedndave on October 17, 2014, 06:27:39 PM
that IS an advantage - lol
thanks for the heads up   :t
Title: Re: Forcing a paint from Window handler?
Post by: dedndave on October 17, 2014, 06:41:58 PM
etch-a-sketch
Title: Re: Forcing a paint from Window handler?
Post by: 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...
Title: Re: Forcing a paint from Window handler?
Post by: BlueMR2 on October 23, 2014, 11:34:29 AM
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!
Title: Re: Forcing a paint from Window handler?
Post by: BlueMR2 on October 23, 2014, 11:43:59 AM
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!  ;-)
Title: Re: Forcing a paint from Window handler?
Post by: 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
Title: Re: Forcing a paint from Window handler?
Post by: BlueMR2 on November 03, 2014, 09:53:05 AM
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).
Title: Re: Forcing a paint from Window handler?
Post by: dedndave on November 04, 2014, 01:47:52 AM
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