News:

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

Main Menu

Macro traps

Started by jj2007, February 27, 2017, 12:56:28 AM

Previous topic - Next topic

jj2007

Just stumbled over some oddities, and wanted to share what I learned:include \masm32\include\masm32rt.inc ; pure Masm32

; the real macro is MasmBasic and looks a bit different ;-)
DlgControl MACRO ctrlType, szText, dstyle, posX1, posY1, width, height, ctlID, tooMany
LOCAL dsInt
  ; case A: use original arg and test for equality
  if (dstyle and SS_BITMAP) eq SS_BITMAP or (dstyle and SS_ICON) eq SS_ICON
echo ** A: BITMAP or ICON style set **
  else
echo ** A: BITMAP or ICON style NOT set **
  endif
  ; case B: use original arg and test for combined AND
  if dstyle and (SS_BITMAP or SS_ICON)
echo ** B: BITMAP or ICON style set **
  else
echo ** B: BITMAP or ICON style NOT set **
  endif
  ; case C: use original arg and test for combined AND
  if dstyle and SS_BITMAP or dstyle and SS_ICON
echo ** C: BITMAP or ICON style set **
  else
echo ** C: BITMAP or ICON style NOT set **
  endif
  ; case D: use intermediate variable
  dsInt=dstyle
  if (dsInt and SS_BITMAP) or (dsInt and SS_ICON) ; with or without brackets, same result
echo ** D: BITMAP or ICON style set **
  else
echo ** D: BITMAP or ICON style NOT set **
  endif
  ; case E: use intermediate variable and test for equality (ONLY THIS ONE PRODUCES CORRECT RESULTS)
  dsInt=dstyle
  if (dsInt and SS_BITMAP) eq SS_BITMAP or (dsInt and SS_ICON) eq SS_ICON
echo ** E: BITMAP or ICON style set **
  else
echo ** E: BITMAP or ICON style NOT set **
  endif
ENDM

.code
start:
  IDTime=123

  echo SS_BITMAP set:
  DlgControl dcStatic, 0, SS_LEFTNOWORDWRAP or SS_NOPREFIX or SS_SUNKEN or SS_BITMAP, 2, 0, 105.0, 28, IDTime
  echo

  echo SS_BITMAP NOT set:
  DlgControl dcStatic, 0, SS_NOPREFIX or SS_SUNKEN, 2, 0, 105.0, 28, IDTime
  echo

  echo so far it seems that D+E work find BUT:
  echo

  echo SS_BITMAP NOT set, SS_LEFTNOWORDWRAP set:
  DlgControl dcStatic, 0, SS_LEFTNOWORDWRAP or SS_NOPREFIX or SS_SUNKEN, 2, 0, 105.0, 28, IDTime

  echo
  echo *** only E passes the test...! ***
  echo

  .err <instead of running this snippet, we just look at the echos>
  inkey "ok?"
  exit

end start


The code does not assemble because of the .err, so we can look at the output without going through the whole assemble & link & run process:***********
ASCII build
***********

SS_BITMAP set:
** A: BITMAP or ICON style NOT set **
** B: BITMAP or ICON style set **
** C: BITMAP or ICON style set **
** D: BITMAP or ICON style set **
** E: BITMAP or ICON style set **

SS_BITMAP NOT set:
** A: BITMAP or ICON style NOT set **
** B: BITMAP or ICON style set **
** C: BITMAP or ICON style set **
** D: BITMAP or ICON style NOT set **
** E: BITMAP or ICON style NOT set **

so far it seems that D+E work find BUT:

SS_BITMAP NOT set, SS_LEFTNOWORDWRAP set:
** A: BITMAP or ICON style NOT set **
** B: BITMAP or ICON style set **
** C: BITMAP or ICON style set **
** D: BITMAP or ICON style set **
** E: BITMAP or ICON style NOT set **

*** only E passes the test...! ***

Tmp_File.asm(62) : Error A2114: forced error: instead of running this snippet, we just look at the echos


There are two lessons I learned through this bug:
1. you pass SS_LEFTNOWORDWRAP or SS_NOPREFIX or SS_SUNKEN as a text, not a number
2. Windows has the habit of defining constants bitwise, e.g. 0, 1, 2, 4, 8; don't rely on it!

More specifically, it is necessary to "test for equality" (see above in the macro) because there is a "bit overlap" between SS_LEFTNOWORDWRAP and SS_BITMAP (note the awkward mix of single- and multiple-bit SS_ constants):SS_LEFT                              equ 0h     ; 00000000000000000000000000000000
SS_CENTER                            equ 1h     ; 00000000000000000000000000000001
SS_RIGHT                             equ 2h     ; 00000000000000000000000000000010
SS_ICON                              equ 3h     ; 00000000000000000000000000000011
SS_BLACKRECT                         equ 4h     ; 00000000000000000000000000000100
SS_GRAYRECT                          equ 5h     ; 00000000000000000000000000000101
SS_WHITERECT                         equ 6h     ; 00000000000000000000000000000110
SS_BLACKFRAME                        equ 7h     ; 00000000000000000000000000000111
SS_GRAYFRAME                         equ 8h     ; 00000000000000000000000000001000
SS_WHITEFRAME                        equ 9h     ; 00000000000000000000000000001001
SS_USERITEM                          equ 0Ah    ; 00000000000000000000000000001010
SS_SIMPLE                            equ 0Bh    ; 00000000000000000000000000001011
SS_LEFTNOWORDWRAP                    equ 0Ch    ; 00000000000000000000000000001100
SS_NOPREFIX                          equ 80h    ; 00000000000000000000000010000000
SS_OWNERDRAW            equ 0Dh ; 00000000000000000000000000001101
SS_BITMAP               equ 0Eh ; 00000000000000000000000000001110
SS_ENHMETAFILE          equ 0Fh ; 00000000000000000000000000001111
SS_ETCHEDHORZ           equ 10h ; 00000000000000000000000000010000
SS_ETCHEDVERT           equ 11h ; 00000000000000000000000000010001
SS_ETCHEDFRAME          equ 12h ; 00000000000000000000000000010010
SS_TYPEMASK             equ 1Fh ; 00000000000000000000000000011111
SS_NOTIFY               equ 100h        ; 00000000000000000000000100000000
SS_CENTERIMAGE          equ 200h        ; 00000000000000000000001000000000
SS_RIGHTJUST            equ 400h        ; 00000000000000000000010000000000
SS_REALSIZEIMAGE            equ 800h    ; 00000000000000000000100000000000
SS_SUNKEN               equ 1000h       ; 00000000000000000001000000000000
SS_ENDELLIPSIS          equ 4000h       ; 00000000000000000100000000000000
SS_PATHELLIPSIS             equ 8000h   ; 00000000000000001000000000000000
SS_WORDELLIPSIS             equ 0C000h  ; 00000000000000001100000000000000
SS_ELLIPSISMASK             equ 0C000h  ; 00000000000000001100000000000000


The SS_ constants are pretty old, nowadays M$ would probably be more careful to keep constants single-bit, given the risks of certain bad coding habits:
Quote from: jj2007 on November 19, 2016, 04:39:42 AM
STYLE 0xD0000000+WS_CHILD+DS_CONTROL is a no-no in programming :eusa_naughty:

If you have any doubt about that, have a look at WS_OVERLAPPEDWINDOW
;)

hutch--

Usually ORing the styles together will get you the correct results where adding them sometimes fails. I have absolutely no problems ORRing the styles together and it has been this way since in 3.??.

jj2007

Thank you for confirming what I wrote above, Hutch :icon14: