The MASM Forum Archive 2004 to 2012

General Forums => The Campus => Topic started by: NoCforMe on April 09, 2012, 01:56:13 AM

Title: Centering a window on another window
Post by: NoCforMe on April 09, 2012, 01:56:13 AM
This is something I do a lot in my programs, so I came up with the following routine to do this:


;============================================
; CenterWindow (winHandle, winWidth, winHeight)
;
; Centers window (by w. & h.) on another window.
;
; Returns:
; ECX = x-position for window
; EDX = y-position
;============================================

CenterWindow PROC winHandle:HWND, winWidth:DWORD, winHeight:DWORD
LOCAL gpRect:RECT

INVOKE GetWindowRect, winHandle, ADDR gpRect

; Calculate X-position of window:
MOV EAX, gpRect.right
SUB EAX, gpRect.left
SUB EAX, winWidth
MOV ECX, EAX
AND ECX, 1 SHL 31 ;Mask for sign bit.
SHR EAX, 1 ;Quick-n-dirty IDIV / 2.
OR EAX, ECX ;Replace sign bit.
ADD EAX, gpRect.left
MOV ECX, EAX ;Stash x-pos.

; Calculate Y-position of window:
MOV EAX, gpRect.bottom
SUB EAX, gpRect.top
SUB EAX, winHeight
MOV EDX, EAX
AND EDX, 1 SHL 31
SHR EAX, 1
OR EAX, EDX
ADD EAX, gpRect.top
MOV EDX, EAX
RET

CenterWindow ENDP


The handle passed in to the subroutine is that of the window you want to center the other window on; the height and width parameters are for the window you want centered. This works whether the window to be centered is larger or smaller than the other window. (To do this, I think my method of doing a "poor-man's IDIV" here is fairly clever: I use SHR 1 to divide by half, but preserve the sign bit beforehand and OR it back into the result afterwards to preserve the sign of the value.)

After calling this, you can pass the values in ECX and EDX directly to SetWindowPos() to center the window.
Title: Re: Centering a window on another window
Post by: dedndave on April 09, 2012, 02:04:02 AM
to restore the sign, you want 2 bits   :P
SAR (shift arithmetic right) takes care of that for you

(http://www.arl.wustl.edu/~lockwood/class/cs306/books/artofasm/Chapter_6/images/ch06a2.gif)
Title: Re: Centering a window on another window
Post by: NoCforMe on April 09, 2012, 02:10:09 AM
Yeah, SAR is certainly easier, isn't it! Dunno how I missed that.

But why do you say "2 bits"? It's just the one bit, the sign bit, no? I don't care about the carry bit here.

Anyhow, here's the simplified code:


; Calculate X-position of window:
MOV EAX, gpRect.right
SUB EAX, gpRect.left
SUB EAX, winWidth
SAR EAX, 1 ;Quick-n-dirty IDIV / 2.
ADD EAX, gpRect.left
MOV ECX, EAX ;Stash x-pos.

; Calculate Y-position of window:
MOV EAX, gpRect.bottom
SUB EAX, gpRect.top
SUB EAX, winHeight
SAR EAX, 1
ADD EAX, gpRect.top
MOV EDX, EAX
RET
Title: Re: Centering a window on another window
Post by: dedndave on April 09, 2012, 02:17:47 AM
2 bits - one is the sign, one is the extension

for bytes...
1abcdefg
becomes
11abcdef

and
0abcdefg
becomes
00abcdef
Title: Re: Centering a window on another window
Post by: NoCforMe on April 09, 2012, 02:33:07 AM
Hmm, don't know what you mean by the "extension". Isn't that just the most significant bit of the (signed) quantity?

In any case, my original code worked fine; it was just needlessly complex.
Title: Re: Centering a window on another window
Post by: dedndave on April 09, 2012, 03:03:17 AM
well - under the right (wrong) conditions, it would have returned incorrect results

let's play....

-10, in hex...

FFFF FFF6

your calculation would have yielded...

DFFF FFFB

but, -10, diviided by 2 should be somewhere near -5   :P

FFFF FFFB

you can plug those values into the str$ macro to see

        mov     eax,0FFFFFFF6h
        print   str$(eax),32
        mov     eax,0DFFFFFFBh
        print   str$(eax),32
        mov     eax,0FFFFFFFBh
        print   str$(eax),13,10
Title: Re: Centering a window on another window
Post by: dedndave on April 09, 2012, 03:24:22 AM
on a different note, here's something you might consider...

;create a structure for your stuff

MyWinStruct STRUCT
  dwWidth     dd ?
  dwHeight    dd ?
  rcRect      RECT <>
;   left        dd ?
;   top         dd ?
;   right       dd ?
;   bottom      dd ?
MyWinStruct ENDS

;define it in the data area

        .DATA?

mws MyWinStruct <>


now, you can use a register to point to the base of the structure
your horizontal values are at offsets 0, 8, 16
your vertical values are at offsets 4, 12, 20

Calc    PROC

        mov     eax,offset mws
        call    Calc00
        mov     ecx,edx
        add     eax,4

Calc00: push    ecx
        mov     edx,[eax].MyWinStruct.rcRect.right
        mov     ecx,[eax].MyWinStruct.rcRect.left
        sub     edx,[eax].MyWinStruct.dwWidth
        sub     edx,ecx
        sar     edx,1
        add     edx,ecx
        pop     ecx
        ret

Calc    ENDP

you could also put the result for each in the structure, if you like
not only that, but if you pass the address of the structure in EAX, you can use it for multiple windows   :P

addressing data with a register and an index is smaller and faster than addressing it directly
"smaller and faster" may not appeal to you - how about "more efficient"
Title: Re: Centering a window on another window
Post by: dedndave on April 09, 2012, 03:35:22 AM
here is what the code looks like
i always like to look at the disassembly to see where i can do better   :P
00000018 Calc    PROC

00000018  B8 00000000 R         mov     eax,offset mws
0000001D  E8 00000005 call    Calc00
00000022  8B CA         mov     ecx,edx
00000024  83 C0 04 add     eax,4

00000027  51         Calc00: push    ecx
00000028  8B 50 10 mov     edx,[eax].MyWinStruct.rcRect.right
0000002B  8B 48 08 mov     ecx,[eax].MyWinStruct.rcRect.left
0000002E  2B 10         sub     edx,[eax].MyWinStruct.dwWidth
00000030  2B D1         sub     edx,ecx
00000032  D1 FA         sar     edx,1
00000034  03 D1         add     edx,ecx
00000036  59 pop     ecx
00000037  C3 ret

00000038 Calc    ENDP

; Calculate X-position of window:
00000038  A1 00000010 R         MOV EAX, mws.rcRect.right
0000003D  2B 05 00000008 R SUB EAX, mws.rcRect.left
00000043  2B 05 00000000 R SUB EAX, mws.dwWidth
00000049  D1 F8         SAR EAX, 1 ;Quick-n-dirty IDIV / 2.
0000004B  03 05 00000008 R ADD EAX, mws.rcRect.left
00000051  8B C8         MOV ECX, EAX ;Stash x-pos.

; Calculate Y-position of window:
00000053  A1 00000014 R         MOV EAX, mws.rcRect.bottom
00000058  2B 05 0000000C R SUB EAX, mws.rcRect.top
0000005E  2B 05 00000004 R SUB EAX, mws.dwHeight
00000064  D1 F8         SAR EAX, 1
00000066  03 05 0000000C R ADD EAX, mws.rcRect.top
0000006C  8B D0         MOV EDX, EAX
0000006E  C3 RET


55 bytes of code vs 32
Title: Re: Centering a window on another window
Post by: NoCforMe on April 09, 2012, 04:48:45 AM
Quote from: dedndave on April 09, 2012, 03:03:17 AM
well - under the right (wrong) conditions, it would have returned incorrect results

let's play....

-10, in hex...

FFFF FFF6

your calculation would have yielded...

DFFF FFFB

I don't see how you get that. Using my code:


MOV EAX, gpRect.right
SUB EAX, gpRect.left
SUB EAX, winWidth
MOV ECX, EAX
AND ECX, 1 SHL 31 ;Mask for sign bit.
SHR EAX, 1 ;Quick-n-dirty IDIV / 2.
OR EAX, ECX ;Replace sign bit.


let's look at the result, using your example of -10:

1. -10 = FFF6 (let's pretend it's a WORD instead of a DWORD to make things easier).
2. Mask (CX, copy of original AND 8000) = 8000
3. FFF6 SHR 1 = 7FFB (AX)
3. Result = AX OR 8000 = FFFB = -5

Q.E.D.: my method works.

But your method (SAR vs SHR) is clearly superior, and I changed my original code. I just mistakenly found a more expensive way to implement SAR is all.
Title: Re: Centering a window on another window
Post by: dedndave on April 09, 2012, 04:50:20 AM
oops !
my mistake
cudda saved us a lot of typing - lol
Title: Re: Centering a window on another window
Post by: NoCforMe on April 09, 2012, 05:00:25 AM
Hey, no harm, no foul.

Of course, I would never make a mistake like that ...
Title: Re: Centering a window on another window
Post by: dedndave on April 09, 2012, 08:15:25 AM
brain fart on my part

when i was younger, i had a full set of registers upstairs - lol
Title: Re: Centering a window on another window
Post by: SteveAsm on April 09, 2012, 02:25:52 PM
FYI guys,
when I see code that looks like this, I can only wonder how confusing that must look to noob programmers.

INVOKE GetWindowRect, winHandle, ADDR gpRect

MOV EAX, gpRect.right
SUB EAX, gpRect.left
SUB EAX, winWidth
MOV ECX, EAX
AND ECX, 1 SHL 31 ;Mask for sign bit.
SHR EAX, 1 ;Quick-n-dirty IDIV / 2.
OR EAX, ECX ;Replace sign bit.
ADD EAX, gpRect.left
MOV ECX, EAX ;Stash x-pos.


The problem appears to be the usage of TABS in your code examples.
Instead, perhaps you could use SPACES:

    INVOKE    GetWindowRect, winHandle, ADDR gpRect

    MOV    EAX, gpRect.right
    SUB    EAX, gpRect.left
    SUB    EAX, winWidth
    MOV    ECX, EAX
    AND    ECX, 1 SHL 31 ;Mask for sign bit.
    SHR    EAX, 1 ;Quick-n-dirty IDIV / 2.
    OR    EAX, ECX ;Replace sign bit.
    ADD    EAX, gpRect.left
    MOV    ECX, EAX ;Stash x-pos.


Whether or not you use TABS in your code, that is up to you.
However, when you post it for all to view, that is another thing.
It makes it very hard to read and (for some, especially new programmers) Assembly Language can be very hard to read to begin with.   :U

Title: Re: Centering a window on another window
Post by: jj2007 on April 09, 2012, 03:55:55 PM
Steve,

Have a look at your own post with Firefox. It looks perfectly "tabbed".
Title: Re: Centering a window on another window
Post by: SteveAsm on April 09, 2012, 04:30:39 PM
Quote from: jj2007 on April 09, 2012, 03:55:55 PM
Have a look at your own post with Firefox. It looks perfectly "tabbed".

I had figured it was an issue with the forum and it still may be.
I'm not surprised.
I've seen other cases where a forum looked one way on one browser and different on another.

SourceForge is an example of that too.
I guess they all use Firefox there.
They were not aware that their forums looked bad on IE, until I informed them of a similar issue.

At any rate, this forum does not display correctly on IE.
I believe it is fixable.

You can't assume everyone uses Firefox or non-IE browsers.
Title: Re: Centering a window on another window
Post by: dedndave on April 09, 2012, 05:24:29 PM
Steve,
for IE, there is a feature called "Compatibility View"
you may have it disabled   :P

i am using XP MCE2005, SP3 with IE8 - Compatibilty View enabled
your post looks the same in Firefox and IE
Title: Re: Centering a window on another window
Post by: jj2007 on April 09, 2012, 05:48:18 PM
Just checked with IE7 (<rant>I'll never understand why the bloody beast points me every single time I start it to runonce, although I always tell it what my homepage is</rant>), and I can confirm that IE does not show the tabs correctly. Looks awful indeed.
Title: Re: Centering a window on another window
Post by: SteveAsm on April 09, 2012, 05:58:31 PM
Quote from: dedndave on April 09, 2012, 05:24:29 PM
for IE, there is a feature called "Compatibility View"
you may have it disabled   :P

i am using XP MCE2005, SP3 with IE8 - Compatibilty View enabled
your post looks the same in Firefox and IE

Dave,
I'm aware of "Compatibility View".
I'm running XP, SP3, IE8 w/Compatibility View enabled.
And this is what I see for many posts with code:

    INVOKEGetWindowRect, winHandle, ADDR gpRect

    MOVEAX, gpRect.right
    SUBEAX, gpRect.left
    SUBEAX, winWidth
    MOVECX, EAX
    ANDECX, 1 SHL 31
    SHREAX, 1
    OREAX, ECX
    ADDEAX, gpRect.left
    MOVECX, EAX

where TABS are used in the code.
Title: Re: Centering a window on another window
Post by: NoCforMe on April 09, 2012, 06:24:50 PM
Dunno why y'all are having problems with IE. I just tried my version (old: v5) and it displayed correctly.

Did Micro$oft break tab rendering in later versions of IE?
Title: Re: Centering a window on another window
Post by: dedndave on April 09, 2012, 06:59:11 PM
ok - i was playing around - lol
you have to disable compatibility view for this site
IE - Tools menu - Compatibility View

i had it disabled for alll websites except those in my list
IE - Tools menu - Compatibility View Settings
Title: Re: Centering a window on another window
Post by: SteveAsm on April 09, 2012, 10:59:25 PM
Quote from: dedndave on April 09, 2012, 06:59:11 PM
ok - i was playing around - lol
you have to disable compatibility view for this site
IE - Tools menu - Compatibility View

i had it disabled for alll websites except those in my list
IE - Tools menu - Compatibility View Settings

Okay, once I removed masm32 from my Compatibility View list, it displayed correctly.
Now, I can't remember why I had it on my list.   :eek
Title: Re: Centering a window on another window
Post by: SteveAsm on April 09, 2012, 11:14:21 PM
Quote from: SteveAsm on April 09, 2012, 10:59:25 PM
Okay, once I removed masm32 from my Compatibility View list, it displayed correctly.
Now, I can't remember why I had it on my list.   :eek

Ohoh!
now I remember.
It has to due with SMF Forums.
SMF Forums, (and masm32 is one of them), has a glitch that pertains to IE-8.
Unless you use Compatibility View, when entering text in the textbox for submitting a post, the textbox becomes unstable.
I remember discussing this in emails with SMF support. It is a well known bug.
Their only solution is to turn Compatibility View ON.
Try it.
Using IE8, Compatibility View turned OFF, enter (or copy) a dozen or so lines of text and at the end of the page, start typing.
It will become unstable.

This raises another issue, tho'.
Now, as I have illustrated, with Compatibility View turned ON, TABS become a problem as text is run together without proper spacing.
Title: Re: Centering a window on another window
Post by: hfheatherfox07 on April 11, 2012, 09:54:14 PM
Hi there this seems to be a good Idea what am I doing wrong invoking the  SetWindowPos ?
... I commented out because It crashes on me  :(
Title: Re: Centering a window on another window
Post by: dedndave on April 11, 2012, 10:09:33 PM
SWP_NOMOVE + SWP_NOSIZE

you should OR constants together, not ADD

SWP_NOMOVE or SWP_NOSIZE

but - that's not the problem

also, the x and y position parameters will be ignored if the SWP_NOMOVE flag is set   :P

but - that's not the problem
Title: Re: Centering a window on another window
Post by: hfheatherfox07 on April 11, 2012, 10:11:05 PM
Quote from: dedndave on April 11, 2012, 10:09:33 PM
SWP_NOMOVE + SWP_NOSIZE

you should OR constants together, not ADD

SWP_NOMOVE or SWP_NOSIZE

but - that's not the problem

also, the x and y position parameters will be ignored if the SWP_NOMOVE flag is set   :P

but - that's not the problem


so what is the problem?
Title: Re: Centering a window on another window
Post by: dedndave on April 11, 2012, 10:14:20 PM
    Call CenterWindow
CenterWindow PROC winHandle:HWND, winWidth:DWORD, winHeight:DWORD
when CenterWindow returns, it POP's 3 dwords off the stack
lemme see - that'd be the stored EBP value, the return address for DlgProc, and the hWnd parm   :bg
no wonder it crashes
then - when you exit the DlgProc routine, it tries to jam the uMsg value into ESP and POP wParam into EBP   :lol
it then proceeds to execute code at the address of whatever lParam is pointing to - probably crashes right there
Title: Re: Centering a window on another window
Post by: hfheatherfox07 on April 11, 2012, 10:16:47 PM
Quote from: dedndave on April 11, 2012, 10:14:20 PM
    Call CenterWindow
CenterWindow PROC winHandle:HWND, winWidth:DWORD, winHeight:DWORD


LOL ...

I don't get it
Title: Re: Centering a window on another window
Post by: Gunner on April 11, 2012, 10:17:44 PM
If you use call, you need to push the parameters then call,  or use invoke and you would see what the error is!
Title: Re: Centering a window on another window
Post by: dedndave on April 11, 2012, 10:20:14 PM
well, first, you have to get the window width and height
i am guessing you want to center it on the desktop, so you can use GetSystemMetrics for those
        INVOKE  CenterWindow,hWnd,width,height
Title: Re: Centering a window on another window
Post by: hfheatherfox07 on April 11, 2012, 10:26:43 PM
woops
Title: Re: Centering a window on another window
Post by: hfheatherfox07 on April 11, 2012, 10:30:03 PM
Quote from: dedndave on April 11, 2012, 10:20:14 PM
well, first, you have to get the window width and height
i am guessing you want to center it on the desktop, so you can use GetSystemMetrics for those
        INVOKE  CenterWindow,hWnd,width,height

I thought this centers the window within another window .....not in the center of the desktop ...I just use poponcenter in the rsrc.rc with MASMeD
Title: Re: Centering a window on another window
Post by: dedndave on April 11, 2012, 11:16:58 PM
oh - well it will center any window in any other window, i think
the desktop is a window   :P
HWND_DESKTOP = 0
Title: Re: Centering a window on another window
Post by: hfheatherfox07 on April 12, 2012, 04:47:05 PM
Quote from: dedndave on April 11, 2012, 10:20:14 PM
well, first, you have to get the window width and height
i am guessing you want to center it on the desktop, so you can use GetSystemMetrics for those
        INVOKE  CenterWindow,hWnd,width,height


I tried all this Last night on the example that I posted above and no go ...the window is not centered on my main window ...and it goes to the upper left corner of the desktop .... also no window just a title bar?????


I have another way that I do this but it does not keep the window proportion with regards to the window size ...you have to set left right top bottom and window height and width....

maybe I think this will do something that It does not..... what I thought this does is.... for the child window to pop up on center in relation to the parent window  even if I move the parent window anywhere on the desktop before I execute the child window
Title: Re: Centering a window on another window
Post by: dedndave on April 12, 2012, 04:49:44 PM
well - show us your example
what you may be dealing with is a coordinate reference issue
i.e., screen coordinates vs client coordinates
Title: Re: Centering a window on another window
Post by: hfheatherfox07 on April 12, 2012, 04:55:06 PM
Quote from: dedndave on April 12, 2012, 04:49:44 PM
well - show us your example
what you may be dealing with is a coordinate reference issue
i.e., screen coordinates vs client coordinates

the example that does not work is the one above that I want to work using this authors way .....  I have no problem with the other one it works great ... I am not at home at my personal PC ...but If you want to see that one let me know and I will grab it with me on a flash drive and upload it ...I have no questions about that one ....
I am trying to make this one work

http://www.masm32.com/board/index.php?PHPSESSID=fc2c702b1f62df3f61be07c96a25b83f&action=dlattach;topic=18662.0;id=10550

I did not re-upload it with the modifications suggested last night
Title: Re: Centering a window on another window
Post by: dedndave on April 12, 2012, 05:02:38 PM
ok
that example doesn't tell us which window you want centered on which other window   :P
remember - the parms for CenterWindow are missing - so we cannot see what you want to do

on another note...
looking again at the code,
it seems logical that the function could be passed 2 window handles, rather than a handle, width, and height
i dunno - a matter of application, i suppose

Heather...
this is a simple thing   :P
if you can handle bitmaps, you should be able to handle this
Title: Re: Centering a window on another window
Post by: hfheatherfox07 on April 12, 2012, 06:51:51 PM
Quote from: dedndave on April 12, 2012, 05:02:38 PM
ok
that example doesn't tell us which window you want centered on which other window   :P
remember - the parms for CenterWindow are missing - so we cannot see what you want to do

on another note...
looking again at the code,
it seems logical that the function could be passed 2 window handles, rather than a handle, width, and height
i dunno - a matter of application, i suppose

Heather...
this is a simple thing   :P
if you can handle bitmaps, you should be able to handle this

LOL the child window ... so say I execute my main window .... than I move it to the button corner of the screen ...I thought this proc makes sure that the child window opens in the center of the parent window
I know that I should be able to handle this but I want to use his proc the way he intended it ...and I do not know how ....
for example my way  the "INVOKE GetWindowRect, winHandle, ADDR gpRect" is not in the proc it gets invoked Like so:

.IF wParam == IDC_WINDOWBUTTON
INVOKE GetWindowRect,hWnd, addr rect
invoke DialogBoxParam,hInstance,IDC_WINDOW,hWnd,addr WindowProc,0

and the rect is not defined LOCAL ....

SO I do not know were to place his "invoke CenterWindow", and were do I place "invoke SetWindowPos"

I just thought I would try his proc that's all  :(
Title: Re: Centering a window on another window
Post by: dedndave on April 12, 2012, 07:05:09 PM
we'll make it fly   :U

gimme a while - i am playing with the enumeration thingy
Title: Re: Centering a window on another window
Post by: dedndave on April 12, 2012, 07:59:36 PM
yah - little snafu with coordinates
GetWindowRect returns screen coordinates
MoveWindow uses client coordinates for child windows, screen coordinates for top-level windows
SetWindowPos uses client coordinates

so - the routine works ok for centering the main window of a program
we can use ScreenToClient to straighten things out, i think
Title: Re: Centering a window on another window
Post by: hfheatherfox07 on April 12, 2012, 08:04:43 PM
Quote from: dedndave on April 12, 2012, 07:59:36 PM
yah - little snafu with coordinates
GetWindowRect returns screen coordinates
MoveWindow and SetWindowPos use client coordinates for child windows, screen coordinates for top-level windows

so - the routine works ok for centering the main window of a program
we can use ScreenToClient to straighten things out, i think

The authors original post said that it does what I thought it would ..????
I have an example that does that .... I just thought he had a better way..... oh well ......
not that important ...... I am sure the author might respond and explain or give a demo of how he uses this proc

look at the first proc  quote "Centers window (by w. & h.) on another window"
Title: Re: Centering a window on another window
Post by: dedndave on April 12, 2012, 08:08:37 PM
maybe i am missing something
at the end of each section in the code, he adds the left or top screen position back onto the result
Title: Re: Centering a window on another window
Post by: hfheatherfox07 on April 12, 2012, 08:11:00 PM
who knows I am sure he will post an example of how he meant this to be used

Thank you for all your help with every thing so far  :bg
Title: Re: Centering a window on another window
Post by: dedndave on April 12, 2012, 08:44:00 PM
ok - i must have misunderstood something or other - lol

give this a try...
Title: Re: Centering a window on another window
Post by: hfheatherfox07 on April 13, 2012, 11:13:45 PM
Quote from: dedndave on April 12, 2012, 08:44:00 PM
ok - i must have misunderstood something or other - lol

give this a try...


Yes that is what I wanted to do :U 
but that is not the way that the author described using the proc .....the original post made it seem like all you have to do is call CenterWindow and than SetWindowPos

I was on this for the most part of the day and still would not get it to work .......
you had to add a bunch of stuff that makes the CenterWindow proc almost irrelevant your way can be  modified so you do not  need to use that proc
It is very similar to an example that I had
As I promised yesterday that I will bring my example on a flash drive and upload it .....  this gives you the ability to Control the final Child window size  and the position

Thank you for all your hard work ... :bg I hope one day that I will be good enough to start helping people too
Title: Re: Centering a window on another window
Post by: dedndave on April 14, 2012, 12:14:06 AM
well - normally, you know what size the inside window will be ahead of time - the height and width would be constants
no need to call GetWindowRect before the CenterWindow call to get the size
that was just some example code i tossed together

for example - you want to center a "standard sized" button in hWin...
        INVOKE  CenterWindow,hWin,86,26
        INVOKE  MoveWindow,hButton,ecx,edx,86,26,TRUE


a trick that Edgar (donkey) taught me a couple years ago...

main window - WM_CREATE handler - create all your controls
the initial sizes and positions can be all 0's
then let the WM_SIZE handler set their sizes and positions   :P
(works especially well for scroll bars and status bars - whose sizes and positions depend on the window size)
Title: Re: Centering a window on another window
Post by: Farabi on April 14, 2012, 07:33:19 AM
Quote from: dedndave on April 09, 2012, 03:35:22 AM
here is what the code looks like
i always like to look at the disassembly to see where i can do better   :P
00000018 Calc    PROC

00000018  B8 00000000 R         mov     eax,offset mws
0000001D  E8 00000005 call    Calc00
00000022  8B CA         mov     ecx,edx
00000024  83 C0 04 add     eax,4

00000027  51         Calc00: push    ecx
00000028  8B 50 10 mov     edx,[eax].MyWinStruct.rcRect.right
0000002B  8B 48 08 mov     ecx,[eax].MyWinStruct.rcRect.left
0000002E  2B 10         sub     edx,[eax].MyWinStruct.dwWidth
00000030  2B D1         sub     edx,ecx
00000032  D1 FA         sar     edx,1
00000034  03 D1         add     edx,ecx
00000036  59 pop     ecx
00000037  C3 ret

00000038 Calc    ENDP

; Calculate X-position of window:
00000038  A1 00000010 R         MOV EAX, mws.rcRect.right
0000003D  2B 05 00000008 R SUB EAX, mws.rcRect.left
00000043  2B 05 00000000 R SUB EAX, mws.dwWidth
00000049  D1 F8         SAR EAX, 1 ;Quick-n-dirty IDIV / 2.
0000004B  03 05 00000008 R ADD EAX, mws.rcRect.left
00000051  8B C8         MOV ECX, EAX ;Stash x-pos.

; Calculate Y-position of window:
00000053  A1 00000014 R         MOV EAX, mws.rcRect.bottom
00000058  2B 05 0000000C R SUB EAX, mws.rcRect.top
0000005E  2B 05 00000004 R SUB EAX, mws.dwHeight
00000064  D1 F8         SAR EAX, 1
00000066  03 05 0000000C R ADD EAX, mws.rcRect.top
0000006C  8B D0         MOV EDX, EAX
0000006E  C3 RET


55 bytes of code vs 32
How'd did you do that? What disassembler did you used?
Title: Re: Centering a window on another window
Post by: dedndave on April 14, 2012, 11:00:50 AM
masm generated that listing with the Fl switch
i sometimes use Sang Cho's simple disassembler if i want another view (he's a prof at CheongJu University)
http://hcilab.cju.ac.kr/
there are numerous more powerful disassemblers out there
Title: Re: Centering a window on another window
Post by: NoCforMe on April 23, 2012, 02:51:20 AM
Quote from: hfheatherfox07 on April 12, 2012, 08:04:43 PM
Quote from: dedndave on April 12, 2012, 07:59:36 PM
yah - little snafu with coordinates
GetWindowRect returns screen coordinates
MoveWindow and SetWindowPos use client coordinates for child windows, screen coordinates for top-level windows

so - the routine works ok for centering the main window of a program
we can use ScreenToClient to straighten things out, i think

The authors original post said that it does what I thought it would ..????
I have an example that does that .... I just thought he had a better way..... oh well ......
not that important ...... I am sure the author might respond and explain or give a demo of how he uses this proc

look at the first proc  quote "Centers window (by w. & h.) on another window"

Yes, I'm the OP (original poster), and yes, it does what you thought I said it did (and what I did say it did, and what in fact does).

It centers one window, whose X- and Y-coordinates are passed in, on another window, whose handle is passed in. For example, the window to be centered could be a pop-up window, and the window you want it centered on could be your main window. Remember (and this may be where some confusion came in) that the X- and Y-coordinates for centering the window are screen coordinates, not client coordinates (i.e., relative to (0,0) of the parent window). This can't be used to center a child window on a parent window, though it could easily be modified to do so.

It works exactly as described. The way to use it is thus:


INVOKE CenterWindow, winHandle, (window width), (window height)
; X- and Y-coords. come back in ECX & EDX
INVOKE CreateWindowEx, WS_EX_OVERLAPPEDWINDOW, (class), (title),
(styles), ECX, EDX, (window width), (window height),
NULL, NULL, InstanceHandle, NULL



Of course, this shows it being used to create another window centered on the main one. You could just as easily use it with an existing window by calling SetWindowPos() to move the window.

And it works whether the window to be centered is larger or smaller than the other window.

Try it sometime!