The MASM Forum Archive 2004 to 2012

General Forums => The Laboratory => Topic started by: Larry Hammick on November 30, 2009, 01:24:45 AM

Title: A helper routine for WM_SIZE message handlers
Post by: Larry Hammick on November 30, 2009, 01:24:45 AM
When a window contains controls such as a tool bar and a status bar, the program usually needs to do some calculations on their relative locations when the user resizes the window. We can use a local RECT structure for each control, and call GetWindowRect for each one. But often we only need to know the control's size and not its previous location. This little routine gets that information and obviates the local RECT structure as well.

WindowSize:    ;input is eax=window handle, returns eax=height and edx=width
    sub esp,10h    ;sizeof(RECT)
    mov ecx,esp
    invoke GetWindowRect,eax,ecx
    pop edx    ;left
    pop ecx    ;top
    pop eax    ;right
    sub edx,eax
    pop eax    ;bottom
    sub eax,ecx
    ret
Title: Re: A helper routine for WM_SIZE message handlers
Post by: hutch-- on November 30, 2009, 04:45:00 AM
Nice small code Larry.  :U
Title: Re: A helper routine for WM_SIZE message handlers
Post by: jj2007 on November 30, 2009, 06:59:20 AM
Cute indeed :U

I can't test it right now but check if this one works:

Quotemov ecx,esp
    invoke GetWindowRect,eax,esp
Title: Re: A helper routine for WM_SIZE message handlers
Post by: Larry Hammick on November 30, 2009, 10:41:28 AM
On the earliest Intel PC's, the instruction "push sp" would put the /new/ value of sp on the stack. Later chips put the value of sp as it was /before/ the push. I've been superstitious about pushing the stack pointer ever since. :green
Title: Re: A helper routine for WM_SIZE message handlers
Post by: UtillMasm on November 30, 2009, 12:37:23 PM
 :U

sub edx,eax
;sub eax,edx
;mov edx,eax
Title: Re: A helper routine for WM_SIZE message handlers
Post by: dedndave on November 30, 2009, 02:13:39 PM
QuoteOn the earliest Intel PC's, the instruction "push sp" would put the /new/ value of sp on the stack. Later chips put the value of sp as it was /before/ the push.

my understanding of this was that it happened only on a few 8088/8086/80188/80186's and was considered to be an error
i think they got it squared away for anything 80286 and beyond

by the way - you are really dating yourself to be knowing about that one - lol

i don't usually mess with esp on the stack, either
but, if i want to adjust the stack pointer without altering the flags...

        pop     [esp-4]
Title: Re: A helper routine for WM_SIZE message handlers
Post by: FORTRANS on November 30, 2009, 10:59:13 PM
Hi,

   Here is some text taken from a CPU identification program.


;-------------------------------------------------------------------------------+
; Early processor identification: +
; +
;   CPU Method +
; +
;   808x/186+ Shift register by 32. Clears register on 808x and NEC V2/30. +
; This is because later CPUs mask sift/rotate value with 01Fh. +
;   808x/NEC PUSHA; NOP; +
; pusha is executed on V20/30, so we can check if SP has changed. +
; On 808x, pusha executes as a 2-byte nop, so SP is not changed. +
;   808x/80C8x REP ES: MOVSB ; CX = 0FFFFh +
; Test within a loop. If CX is non-zero at the end of a loop, +
; then it is a NMOS chip. If always zero, it is CMOS. +
;   18x/286 PUSH SP +
; On 286 and later, the original value of SP is stored. +
; On 18x and earlier, the new value is stored. +
;   8/16-bit Use self-modifying code (808x/8018x/Vx0) +
; The prefetch queue on 8-bit processors is 4 bytes long. +
; The prefetch queue on 16-bit processors is 6 bytes long. +
; For example, change a NOP to an INC. If executed as INC, we +
; we have an 8-bit processor. +
; ---------------------------------------------------------------- +


   As I read this, I was a bit surprised as I considered the 80186
to be closer to the 80286 than the 8086.  Anyway...

Cheers,

Steve N.
Regards,
Title: Re: A helper routine for WM_SIZE message handlers
Post by: dedndave on November 30, 2009, 11:46:47 PM
i don't think that is entirely accurate, Steve
although he may have used it to discern 186's from 286's, i don't think it applied to all pre-286 chips
btw - 186's can be used in PC's (i think tandy did)
but they will not be very compatible, as many of the 186 internal peripherals are not addressed
to the same I/O map as the PC - IBM chose to ignore some of Intel's original reccomendations in that regard
Title: Re: A helper routine for WM_SIZE message handlers
Post by: jj2007 on November 30, 2009, 11:48:25 PM
Quote from: dedndave on November 30, 2009, 02:13:39 PM

but, if i want to adjust the stack pointer without altering the flags...

        pop     [esp-4]


Hmmm.... lea esp, [esp+4] does the same, but I must admit your version looks more impressive :bg
Title: Re: A helper routine for WM_SIZE message handlers
Post by: dedndave on November 30, 2009, 11:50:47 PM
lol - i bet yours is faster Jochen   :U
at least, you would think so, because there is no memory access
and, here, i thought i was slick - lol
mine may be smaller   :bg
Title: Re: A helper routine for WM_SIZE message handlers
Post by: jj2007 on December 01, 2009, 12:08:49 AM
Quote from: dedndave on November 30, 2009, 11:50:47 PM
mine may be smaller   :bg

Njet - 4 bytes each. Add esp, 4 is 3 bytes but trashes the flags.
Title: Re: A helper routine for WM_SIZE message handlers
Post by: Larry Hammick on December 01, 2009, 08:45:11 AM
Thx UtillMasm. Here's my correction.
WindowSize:   ;input eax=window handle, returns eax=height, edx=width, and ecx=top
    sub esp,10h    ;sizeof(RECT)
    mov ecx,esp
    invoke GetWindowRect,eax,ecx
    pop eax    ;left
    pop ecx    ;top
    pop edx    ;right
    sub edx,eax
    pop eax    ;bottom
    sub eax,ecx
    ret

and while we're at it

WindowClientSize:  ;eax=hWnd, returns eax=client height, edx=client width, and ecx=0
    sub esp,10h
    mov ecx,esp
    invoke GetClientRect,eax,ecx
    pop eax   ;zero
    pop ecx   ;zero
    pop edx
    pop eax
    ret
Title: Re: A helper routine for WM_SIZE message handlers
Post by: hutch-- on December 01, 2009, 12:16:35 PM
Larry,

4 memory read are likely to be a lot faster than 4 unbalanced pops. 4 moves followed by a stack correction. Depends on if you are after speed or size.
Title: Re: A helper routine for WM_SIZE message handlers
Post by: FORTRANS on December 01, 2009, 01:58:49 PM
Hi Dave,

Quote
although he may have used it to discern 186's from 286's, i don't think it applied to all pre-286 chips

   (?)  8088, 8086, 80188, 80186, and the NEC's are all of them
right?

Quote
btw - 186's can be used in PC's (i think tandy did)
but they will not be very compatible, as many of the 186 internal peripherals are not addressed
to the same I/O map as the PC - IBM chose to ignore some of Intel's original reccomendations in that regard

   Actually, my HP 200LX is 80186 based, and quite compatible
with a PC/XT from a user/programmer point of view.  And it
fits into a pocket.  If you have a specific known problem, I
can test for it (timing of instructions aside).  It is a later design
than the Tandy, so they may have just shoe-horned exceptions
into the BIOS based on what was learned along the way.

Regards,

Steve N.
Title: Re: A helper routine for WM_SIZE message handlers
Post by: dedndave on December 01, 2009, 02:15:15 PM
oh - the BIOS can be written to accomodate the differences
but, software that relies on certain devices being at certain I/O addresses may not work properly
the 186/188 are essentially the same CPU as the 86/88
they just added things like the PIC and counter/timers on-chip (a couple others - i don't remember all of them - lol)
the problem lies with IBM, really - they ignored Intel's original recommendations for I/O addressing
so - the peripherals on the PC are not where Intel told them to put them - lol
of course, IBM addresses have become the standard, now
that makes Intel look like the bad guy, in a way
not that Intel cares - as long as they sell chips, they are happy
EDIT- for all i know, Intel may have adopted to the IBM standards by now
i used to work for ADR Ultrasound (bio-med equip) - we used a 80186 to run the scanners
it is a very powerful little chip, really - or, at least, it was back then
in that case, it was great - we had no need to be IBM compatible

sorry for being off-topic, here - lol
Title: Re: A helper routine for WM_SIZE message handlers
Post by: jj2007 on December 01, 2009, 02:31:08 PM
Quote from: Larry Hammick on December 01, 2009, 08:45:11 AM

WindowClientSize:  ;eax=hWnd, returns eax=client height, edx=client width, and ecx=0
    sub esp,10h
    mov ecx,esp
    invoke GetClientRect,eax,ecx
    pop eax   ;zero
    pop ecx   ;zero
    pop edx
    pop eax
    ret


Hutch, I would suggest going for size. GetClientRect in an innermost loop...?
Right now it's 17 bytes, without the mov ecx, esp it's 15, just under one para. Great little routine :thumbu
Title: Re: A helper routine for WM_SIZE message handlers
Post by: hutch-- on December 01, 2009, 03:16:09 PM
JJ,

here is how to wase the space, put an "align 16" in front of the label.  :bg