News:

Masm32 SDK description, downloads and other helpful links
Message to All Guests

Main Menu

Win32 My First Window

Started by tda0626, April 24, 2024, 11:05:19 AM

Previous topic - Next topic

TimoVJL

#90
Many of us remember this, from Petzold book:
LRESULT CALLBACK WndProc (HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
{
    HDC        hdc ;
    PAINTSTRUCT ps ;
    RECT        rect ;
   
    switch (message)
    {
    case WM_CREATE:
          PlaySound (TEXT ("hellowin.wav"), NULL, SND_FILENAME | SND_ASYNC) ;
          return 0 ;

    case WM_PAINT:
          hdc = BeginPaint (hwnd, &ps) ;
         
          GetClientRect (hwnd, &rect) ;
         
          DrawText (hdc, TEXT ("Hello, Windows 98!"), -1, &rect,
                    DT_SINGLELINE | DT_CENTER | DT_VCENTER) ;
          EndPaint (hwnd, &ps) ;
          return 0 ;
         
    case WM_DESTROY:
          PostQuitMessage (0) ;
          return 0 ;
    }
    return DefWindowProc (hwnd, message, wParam, lParam) ;
}
HelloWin petzold-pw5e
May the source be with you

jj2007

See reply #64, case 2 or 3a:

Quote from: jj2007 on April 28, 2024, 06:40:48 PM2. You return a flag to Windows, e.g. zero: xor eax, eax, then ret. No further processing please.

3a. You want to change something, like painting an emoji, but then Windows must continue with the default processing to finalise the task.

Here it is case 2: no further processing needed. You could use case 3a, though, because DefWindowProc calls BeginPaint internally, and then finds out that there is no update rectangle. So it returns. Lots of cycles wasted but no harm done.

Using 3a, i.e. continuing to DefWindowProc, will save a few bytes (9 with uses esi edi ebx, 6 without uses) because ret is a macro. The downside is some unnecessary processing, which costs around 40 microseconds :cool:

Quote from: TimoVJL on May 02, 2024, 06:41:12 PMcase WM_DESTROY:
          PostQuitMessage (0) ;
          return 0 ;
Same case: you can return zero, but you don't have to. DefWindowProc will do nothing harmful, and you saved 6 or 9 bytes, depending on your uses clause :cool:

NoCforMe

Quote from: jj2007 on May 02, 2024, 06:42:03 PM
Quote from: TimoVJL on May 02, 2024, 06:41:12 PMcase WM_DESTROY:
          PostQuitMessage (0) ;
          return 0 ;
Same case: you can return zero, but you don't have to. DefWindowProc will do nothing harmful, and you saved 6 or 9 bytes, depending on your uses clause :cool:
Yes, you can call DefWindowProc(), but again: why would you want to? Just for the sake of your nice pretty macro-formatted code?

And saving 6 or 9 bytes of code? "Woohoo, my code is 9 bytes smaller! Only, sometimes it does weird things ...".
Assembly language programming should be fun. That's why I do it.

jj2007

Quote from: NoCforMe on May 03, 2024, 04:44:15 AMwhy would you want to?

Why would you not want to, knowing that it's shorter and costs less than 50 microseconds? Why do you insist to return, instead of letting Windows do its job?

And no, it doesn't do weird things. It behaves like any other window, and that's by design.

NoCforMe

Wellll, I don't know about you, but this is one case where if Micro$oft is telling me I should return 0 and not call DefWindowProc(), that's what I'm gonna do. You, of course, are free to do whatever you like.
Assembly language programming should be fun. That's why I do it.

TimoVJL

Everyone are free to make experiments and others decide, what programs they use.
The new world order for programming isn't suitable for everyone.
Of course it's a bit boring to use same program template for all programs and no one tell to you, that you are a genius, but if do the job, what worry about.
A programs are only important, not just a programmer, who wrote them.
May the source be with you

tda0626

Quote from: TimoVJL on May 02, 2024, 06:41:12 PMMany of us remember this, from Petzold book:
LRESULT CALLBACK WndProc (HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
{
    HDC        hdc ;
    PAINTSTRUCT ps ;
    RECT        rect ;
   
    switch (message)
    {
    case WM_CREATE:
          PlaySound (TEXT ("hellowin.wav"), NULL, SND_FILENAME | SND_ASYNC) ;
          return 0 ;

    case WM_PAINT:
          hdc = BeginPaint (hwnd, &ps) ;
         
          GetClientRect (hwnd, &rect) ;
         
          DrawText (hdc, TEXT ("Hello, Windows 98!"), -1, &rect,
                    DT_SINGLELINE | DT_CENTER | DT_VCENTER) ;
          EndPaint (hwnd, &ps) ;
          return 0 ;
         
    case WM_DESTROY:
          PostQuitMessage (0) ;
          return 0 ;
    }
    return DefWindowProc (hwnd, message, wParam, lParam) ;
}
HelloWin petzold-pw5e

Yep, I have a copy of this book and translated his code over to assembler for practice.

Tim

NoCforMe

Quote from: tda0626 on May 03, 2024, 05:34:23 AMYep, I have a copy of this book and translated his code over to assembler for practice.
Care to show us your translation so we can tear it apart and critique it?

Yep, Petzold is good stuff. Old, but timeless.
Assembly language programming should be fun. That's why I do it.

tda0626

Quote from: NoCforMe on May 03, 2024, 05:41:10 AM
Quote from: tda0626 on May 03, 2024, 05:34:23 AMYep, I have a copy of this book and translated his code over to assembler for practice.
Care to show us your translation so we can tear it apart and critique it?

Yep, Petzold is good stuff. Old, but timeless.

Should have been more specific, I translated only the "A Window of ones own", which is attached to post on page 5 I think.

Looked at his text metrics code and besides the custom include file he wants you to import into the program, I have no clue to translating some of his c code in that section. Might just skip that section and come back to it later.

Tim


NoCforMe

Quote from: tda0626 on May 03, 2024, 05:48:47 AMLooked at his text metrics code and besides the custom include file he wants you to import into the program, I have no clue to translating some of his c code in that section.
What program is that exactly? I have his book (yes, actual book, the size of a boat anchor) in front of me. I could take a look at that code.
Assembly language programming should be fun. That's why I do it.

jj2007

Quote from: NoCforMe on May 03, 2024, 04:59:05 AMWellll, I don't know about you, but this is one case where if Micro$oft is telling me I should return 0 and not call DefWindowProc(), that's what I'm gonna do. You, of course, are free to do whatever you like.

You, too :thumbsup:

tda0626

Quote from: NoCforMe on May 03, 2024, 06:58:51 AM
Quote from: tda0626 on May 03, 2024, 05:48:47 AMLooked at his text metrics code and besides the custom include file he wants you to import into the program, I have no clue to translating some of his c code in that section.
What program is that exactly? I have his book (yes, actual book, the size of a boat anchor) in front of me. I could take a look at that code.

In the 5th edition, it is on page 73. The custom include file starts on page 70.

tda0626

So my brother is also learning assembly and practicing on his own and asked me to debug his source code.He wanted to try to convert some C code of a window example on Microsoft's site to see where there were gaps in his knowledge and for practice. Anyway, I looked over his code and caught some little mistakes he did and commented them. But after running it, CreateWindow returns 0 and triggers the error code. I ran it in Ollydbg and didn't see any apparent issues so I thought I would post his source here and see if anyone spotted anything. It is attached to this post.

Last weekend, I went over to his house and we went over a window program together explaining every step in detail while he was the one inputting all the code. He is new to assembler and never really messed with it but he is picking it up alright I think.

sudoku

Check the window class name is correct when calling CreateWindowEx.... you have the wrong string there "szAppName"

should be "szWindowClass"  :icon_idea:

    invoke CreateWindowExA,\
        WS_EX_OVERLAPPEDWINDOW,\
        offset szAppName,\                                ;;;; should be the registered class name
        offset win_caption,\
        WS_OVERLAPPEDWINDOW ,\
        CW_USEDEFAULT,\
        CW_USEDEFAULT,\
        CW_USEDEFAULT,\
        CW_USEDEFAULT,\
        0,\
        0,\
        hInstance,\
        0

mov wcex.lpszClassName, offset szWindowClass  ;;;; the registered class name
Tip: for invoke statements we use 'addr' not 'offset', generally.
also in .data there are a couple variables with '?' ought to be '0' (for initialized data)
and the structures more commonly -->  "ps PAINTSTRUCT <0>"  (where  "ps PAINTSTRUCT {0}" is in your source)
:cool:

tda0626

See that is why I come here, you guys are awesome and fast!  :biggrin:

Thanks Sudoku!