News:

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

Main Menu

Dialog box programming considerations

Started by kkurkiewicz, October 23, 2023, 02:18:34 AM

Previous topic - Next topic

kkurkiewicz

#60
Quote from: NoCforMe on November 13, 2023, 11:05:23 AMNo. That only applies to tabbing behavior within the dialog, and not to any special handling of tabs. In other words, WS_TABSTOP when applied to a control in a dialog just tells the dialog manager that that control should be moved to in sequence when the user presses the Tab key. It doesn't allow for any other function of the tab key.

All I want to do is to modify the prog1 version of the dialog so that it is modeless and enable the buttons to be tabbed to with the tabulator key, but please note that in the prog2 program, all the buttons also specify mnemonics—they don't work either. It seems to me that I just need to enable the system-provided dialog box keyboard interface, but there's simply something wrong with it (I even tried creating a custom control class).
Kamil

kkurkiewicz

And regarding the style of the code, I'm just not that used to programming in pure assembly as I am to using disassemblers.
Kamil

_japheth


I got prog2 to work with tab navigation by moving variable NEWHWND to another place:

    HFONT     DD 0
    HINST     DD 0               ; Application descriptor
    NEWHWND   DD 0
    KEY       DB 19 DUP (?)
    LG        LOGFONT <?>
    MSG       MSGSTRUCT <?>
    NEXT      DD 0
    NFONT     DB 'Lucida Console', 0

I didn't elaborate the problem further - perhaps the MSGSTRUCT structure you've defined is too short?
Dummheit, gepaart mit Dreistigkeit - eine furchtbare Macht.

NoCforMe

#63
Quote from: kkurkiewicz on November 14, 2023, 04:27:44 AMAnd regarding the style of the code, I'm just not that used to programming in pure assembly as I am to using disassemblers.

I understand; one does what one is used to doing. But I think you'd benefit greatly from changing your style just a little bit. Not only would we be able to understand your code better, you yourself would as well. And it would be much more maintainable (just imagine coming back to something you wrote a year or two ago and trying to make heads or tails of what it does).
Code disassembly is a terrible template for a coding style. And coding has changed from, say, 20 years ago:

Old style                                    New style

PUSH    TheOther
PUSH    That
PUSH    This
CALL    Function
               
INVOKE    Function, This, That, TheOther

MOV    [ESP+24], EAX          MOV    Variable, EAX

MOV    [Variable], EAX    MOV    Variable, EAX

(This was my attempt to use this forum's "table" formatting tag. Conclusion: it sucks.)

Oh, and one more thing: I noticed you had to define a bunch of Win32 constants in your code:

; Selects a range of characters in an edit control
EM_SETSEL EQU 0B1h

; Tells the target window to shut down
WM_CLOSE EQU 10h

WM_COMMAND EQU 111h

; Sent to an edit control to copy the current selection to the clipboard
WM_COPY EQU 301h

WM_INITDIALOG EQU 110h

; Used to set the font that is to be used when displaying text
WM_SETFONT EQU 30h

WM_SETTEXT EQU 0Ch

etc., etc. This is totally pointless and needless work on your part. All of these constants as well as (almost) all of the structures and other elements used in Win32 are already defined in the MASM32 project (most of it in a file called windows.inc). People have toiled and slaved for years to distill all this stuff out of all those C header files; why not take advantage of it, instead of totally reinventing the wheel as you're doing here?
Assembly language programming should be fun. That's why I do it.

Greenhorn

Quote from: _japheth on November 14, 2023, 06:13:52 AMI didn't elaborate the problem further - perhaps the MSGSTRUCT structure you've defined is too short?


Yes, it is. Should look like this:
; Message structure
MSGSTRUCT STRUC
    MSHWND    DD ?
    MSMESSAGE DD ?
    MSWPARAM  DD ?
    MSLPARAM  DD ?
    MSTIME    DD ?
    MSPT      DQ ?
    LRSVD     DD ?
MSGSTRUCT ENDS


And prog2 is the way to go. With calling CreateDialogParam the function returns a window handle and you can create and execute a message loop.

In prog1 you call DialogBoxParam which not returns before closing the Diallog Box. So, here a message loop would be useless.
Kole Feut un Nordenwind gift en krusen Büdel un en lütten Pint.

lingo

QuoteNovember 13, 2023, 11:09:02 AM
Quote from: jj2007 on November 13, 2023, 11:05:00 AM
I am not eager to read code that makes no use of the invoke macro, but don't take that personally, please :thup:

Quote from: NoCforMe
What JJ said. That was my reaction on glancing at your code.
Please learn to use INVOKE instead of push-push-call.
It makes your code SO much more readable and generates exactly the same code.
(And likewise, no disrespect intended.)


I recommend using clean and fast assembly code without the annoying and incomprehensible macros written at a "high" level.
This is according to the new MS rules for working without macros for masm64.

If you want to share code with Masm32 people like JJ or NoCforMe who don't want and can't accept the new rules, add the version with "invoke" as a comment.

Example:

 
mov    qword ptr [rsp+10*8],0
mov    qword ptr [rsp+9*8], 0
mov    qword ptr [rsp+8*8], FILE_SYNCHRONOUS_IO_NONALERT or FILE_NON_DIRECTORY_FILE
mov    qword ptr [rsp+7*8], FILE_OVERWRITE_IF
mov    qword ptr [rsp+6*8], FILE_SHARE_READ or FILE_SHARE_WRITE 
mov    qword ptr [rsp+5*8], FILE_ATTRIBUTE_NORMAL 
mov    qword ptr [rsp+4*8], 0 
lea    r9,  sb
lea    r8,  oa
mov    edx, FILE_GENERIC_WRITE or SYNCHRONIZE or FILE_GENERIC_READ or FILE_NO_INTERMEDIATE_BUFFERING
lea    rcx, hFileWW  ; invoke NtCreateFile, addr hFileWW, FILE_GENERIC_WRITE or SYNCHRONIZE or FILE_GENERIC_READ or  \ 
call   NtCreateFile  ; FILE_NO_INTERMEDIATE_BUFFERING, addr oa, addr sb, 0, FILE_ATTRIBUTE_NORMAL, FILE_SHARE_READ or  \
                     ; FILE_SHARE_WRITE, FILE_OVERWRITE_IF,FILE_SYNCHRONOUS_IO_NONALERT or FILE_NON_DIRECTORY_FILE, 0, 0

or

 
mov    eax, rcNum.bottom
mov    rcx, numDC
mov    qword ptr [rsp+8*8], SRCCOPY
mov    qword ptr[rsp+7*8], 0
mov    qword ptr[rsp+6*8], 0
mov    [rsp+5*8], rcx
mov    [rsp+4*8], rax
mov    r9d, rcNum.right
xor    r8d, r8d
xor    edx, edx
mov    rcx, hdc
call   BitBlt        ; invoke BitBlt, hdc, 0, 0, rcNum.right, rcNum.bottom, numDC, 0, 0, SRCCOPY


The old has a hard time accepting the new... :badgrin:  :biggrin:


Quid sit futurum cras fuge quaerere.

jj2007

Quote from: lingo on November 14, 2023, 12:34:27 PMI recommend using clean and fast assembly code without the annoying and incomprehensible macros written at a "high" level.
This is according to the new MS rules for working without macros for masm64.

Lingo, you forgot the irony tags :bgrin:

One "advantage" of the 64-bit ABI is that people who cannot count to 12 (CreateWindowEx) or to 14 (CreateFontA) are not immediately being punished with an imbalanced stack; so the crash may happen a bit later :bgrin:

Quote from: _japheth on November 14, 2023, 06:13:52 AMperhaps the MSGSTRUCT structure you've defined is too short?

Good find. What the OP wanted is the MSG structure...

His version:
MSGSTRUCT STRUC
    MSHWND    DD ?
    MSMESSAGE DD ?
    MSWPARAM  DD ?
    MSLPARAM  DD ?
    MSTIME    DD ?
    MSPT      DD ?
MSGSTRUCT ENDS

Masm32 SDK version (Windows.inc):
MSG STRUCT
  hwnd      DWORD      ?
  message  DWORD      ?
  wParam    DWORD      ?
  lParam    DWORD      ?
  time      DWORD      ?
  pt        POINT      <>
MSG ENDS

A POINT is composed of two DWORDs.

Btw there is no MSGSTRUCT in the Windows documentation, but it pops up in an old TASM post; and it's wrong, with a dd instead of the POINT:
QuoteI have been trying to make the switch from Dos to Win32 asm. I am using
Barry Kauler's Win32 asm book and Tom Swan's Mastering Turbo Asm. I am
working with the Whello.asm example in MTA. When I assemble using tasm32,
I get  'Symbol already different kind: MSGSTRUCT' then an error for each
use of msg saying it is an undefined symbol.
The MSGSTRUCT looks like this in WINDOWS.inc
MSGSTRUCT       struc
msHWND          dw      ?
msMESSAGE       dw      ?
msWPARAM        dw      ?
msLPARAM        dd      ?
msTIME          dd      ?
msPT            dd      ?
MSGSTRUCT       ends

NoCforMe

Quote from: lingo on November 14, 2023, 12:34:27 PMIf you want to share code with Masm32 people like JJ or NoCforMe who don't want and can't accept the new rules, add the version with "invoke" as a comment.

Wait, wut? What are the "new rules"?

Must admit your irony is kinda whizzing several levels over my head. Must be a slow day.
Assembly language programming should be fun. That's why I do it.

NoCforMe

Quote from: jj2007 on November 14, 2023, 12:45:05 PMMasm32 SDK version (Windows.inc):
MSG STRUCT
  hwnd      DWORD      ?
  message  DWORD      ?
  wParam    DWORD      ?
  lParam    DWORD      ?
  time      DWORD      ?
  pt        POINT      <>
MSG ENDS

Gotta admit I much prefer our (MASM32) versions like this one you posted, since they match (for the most part **) what you'll find on what's now called "Microsoft Learn", the big document repository. You can just copy the names directly out of the web pages without having to retype them. The folks who created these took pains to use the same names you'd find in a .h header file.

** With a couple exceptions where names had to be changed because they conflicted with MASM keywords.
Assembly language programming should be fun. That's why I do it.

lingo

JJ,

QuoteOne "advantage" of the 64-bit ABI is that people who cannot count to 12 (CreateWindowEx) or to 14 (CreateFontA) are not immediately being punished with an imbalanced stack; so the crash may happen a bit later :bgrin:

The big advantage is that at the beginning of the program I free enough space on the stack for the arguments of the functions via sub rsp,256 and before the end of the program I restore the stack by add rsp, 256.
This is enough to forget about the stack when calling a functions with more arguments.

JJ, you forgot the irony tags :bgrin:

You'd be better off stopping with masm32 examples and moving to masm64 if you want to stay up to date.
Soon masm32 will be only history just like 16 bit DOS Programming.

I use:

MSG64 STRUCT
   hwnd    QWORD ?
   message QWORD ?
   wParam  QWORD ?
   lParam  QWORD ?
   time    DWORD ?
   ptX     DWORD ?
   ptY     DWORD ?
           DWORD ?   ; Align to 8 struc MSG64
MSG64   ENDS

Total: 4*8 + 4*4 = 48 bytes

from MS:

typedef struct tagMSG { HWND hwnd;
UINT  message;
WPARAM wParam;
LPARAM lParam;
DWORD  time;
POINT  pt;
DWORD  lPrivate;       !!!
} MSG, *PMSG, *NPMSG, *LPMSG;

POINT STRUCT
     x  DWORD ?
     y  DWORD ?
  POINT ENDS
:skrewy:  :biggrin:

Quid sit futurum cras fuge quaerere.

TimoVJL

#70
x64 MSG
POINT struct
  x                dd      ?
  y                dd      ?
POINT ends

MSG struct     
  hwnd              dq      ?
  message          dd      ?
  padding1          dd      ?      ; padding
  wParam            dq      ?
  lParam            dq      ?
  time              dd      ?
  pt                POINT  <>
  padding2          dd      ?      ; padding
MSG ends
/*
 * Message structure
 */
typedef struct tagMSG {
    HWND        hwnd;
    UINT        message;
    WPARAM      wParam;
    LPARAM      lParam;
    DWORD      time;
    POINT      pt;
#ifdef _MAC
    DWORD      lPrivate;
#endif
} MSG, *PMSG, NEAR *NPMSG, FAR *LPMSG;
:biggrin: 9/5/2012  :biggrin:
MSG structure



Applies to: desktop apps | Windows Store apps

Contains message information from a thread's message queue.


Syntax


typedef struct tagMSG {
  HWND  hwnd;
  UINT  message;
  WPARAM wParam;
  LPARAM lParam;
  DWORD  time;
  POINT  pt;
} MSG, *PMSG, *LPMSG;

       

Members

hwnd
   
Type: HWND

   
A handle to the window whose window procedure receives the message. This member is NULL when the message is a thread message.

message
   
Type: UINT

   
The message identifier. Applications can only use the low word; the high word is reserved by the system.

wParam
   
Type: WPARAM

   
Additional information about the message. The exact meaning depends on the value of the message member.

lParam
   
Type: LPARAM

   
Additional information about the message. The exact meaning depends on the value of the message member.

time
   
Type: DWORD

   
The time at which the message was posted.

pt
   
Type: POINT

   
The cursor position, in screen coordinates, when the message was posted.



Requirements


Minimum supported client
Windows 2000 Professional

Minimum supported server
Windows 2000 Server

Header
Winuser.h (include Windows.h)



See also

Reference
GetMessage
PeekMessage
PostThreadMessage
Conceptual
Messages and Message Queues

 

 

Send comments about this topic to Microsoft

Build date: 9/5/2012

:biggrin:  :biggrin:  :biggrin:
MSG structure (winuser.h)
Article
11/19/2022
In this article
Syntax
Members
Requirements
See also
Contains message information from a thread's message queue.

Syntax
C++

Copy
typedef struct tagMSG {
  HWND   hwnd;
  UINT   message;
  WPARAM wParam;
  LPARAM lParam;
  DWORD  time;
  POINT  pt;
  DWORD  lPrivate;
} MSG, *PMSG, *NPMSG, *LPMSG;
MSG structure (winuser.h)
May the source be with you

jj2007

Quote from: lingo on November 14, 2023, 03:06:29 PMJJ,

QuoteOne "advantage" of the 64-bit ABI is that people who cannot count to 12 (CreateWindowEx) or to 14 (CreateFontA) are not immediately being punished with an imbalanced stack; so the crash may happen a bit later :bgrin:

The big advantage is that at the beginning of the program I free enough space on the stack for the arguments of the functions via sub rsp,256 and before the end of the program I restore the stack by add rsp, 256.
This is enough to forget about the stack when calling a functions with more arguments.

JJ, you forgot the irony tags :bgrin:

You'd be better off stopping with masm32 examples and moving to masm64 if you want to stay up to date.

You are confused, Lingo :biggrin:

No sane programmer does a sub rsp, 256 just for fun. The PROLOGUE macro can handle that perfectly.

Truth is, however, that MASM handles the MSG structure wrongly:
WinMain proc
LOCAL before, msg:MSG, after
  Print Str$("MSG=%i bytes\n", MSG)

44 bytes with a recent (2021) ML64.exe, despite the /Zp8 option set. UAsm and AsmC do it correctly, with 48 bytes.

Re the lPrivate member, see WinUser.h:
typedef struct tagMSG {
    HWND        hwnd;
    UINT        message;
    WPARAM      wParam;
    LPARAM      lParam;
    DWORD      time;
    POINT      pt;
#ifdef _MAC
    DWORD      lPrivate;
#endif
} MSG, *PMSG, NEAR *NPMSG, FAR *LPMSG;

It's an old MacIntosh thing, and if Micros*t ever decided to let Windows write to that member (what for?), it would break tons of "professional" software, including MS Office.

lingo

JJ asks:
QuoteOne "advantage" of the 64-bit ABI is that people who cannot count to 12 (CreateWindowEx) or to 14 (CreateFontA) are not immediately being punished with an imbalanced stack; so the crash may happen a bit later :bgrin:
JJ answers himself:
QuoteNo sane programmer does a sub rsp, 256 just for fun. The PROLOGUE macro can handle that perfectly.

Your confused answers are just blah,blah... and not related to the main question of switching from masm32 to masm64 and to use clean code without macros :sad:
Quid sit futurum cras fuge quaerere.

kkurkiewicz

It works!!

Thank you, _japheth - I'm obliged :winking:
Kamil

NoCforMe

Quote from: lingo on November 14, 2023, 03:06:29 PMYou'd be better off stopping with masm32 examples and moving to masm64 if you want to stay up to date.
Soon masm32 will be only history just like 16 bit DOS Programming.

One small thing, and this is admittedly a side issue: like the song says, it ain't necessarily so (what you said about the obsolescence of 32-bit programming).

Specific example: I worked for two companies that sold media-conversion systems for PCs. One thing they both offered were 8-inch floppy systems, so you could read, f'rinstance, a disk from a Wang word processor on your PC. (I wonder how many folks here remember those big ol' floppies, or even the later 5-1/4" ones?)

The conventional wisdom in the industry was that these disks would become totally obsolete somewhere in the early 1990s. Guess what? We were still selling those systems well into the 2000s. (Some of the biggest users were video production houses that were still using DEC PDP-11 systems for their edit lists, stored on 8" floppy.)

We also sold lots of 9-track tape systems for PC well into the 2000s.

So be careful when you claim that something is about to become a dinosaur ...

I remember one thing about those 8" floppies was just how bulletproof they were. Once when we were doing development on a system we wanted to see how the disk drive would respond to read errors. My job was to take a floppy and mutilate it. I put it on the carpet and ran the casters of my office chair over it a bunch of times. When we went to read it, there were still zero errors. Those things were amazing. (Probably because they were so low density compared to later floppies.)
Assembly language programming should be fun. That's why I do it.