News:

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

Main Menu

Problems with MapWindowPoints

Started by Ar0n, August 10, 2015, 04:55:57 PM

Previous topic - Next topic

jj2007

Quote from: rrr314159 on August 11, 2015, 05:46:32 AMI'm with jj2007, thought simply Rect2.top might do it, but the value is way off. Curious why, will look into it when I get to it ... or just wait for him to figure it out :biggrin:

Same for Win XP and Win7-64: Works without client edge. I thought of adding a manifest but it didn't help.

Ar0n

@dedndave, you did it so simple  :biggrin: I was starting to play with GetWindowRect and GetClientRect to get the size of the border. Thank you!

Quote from: rrr314159 on August 11, 2015, 05:46:32 AM
Quote from: ArOnGuys, at this point, I'm not sure if I'm implying my problem ... :-P

- I'm glad u fixed your problem, assuming you're happy without the "clientedge" (works on my system also). I'm with jj2007, thought simply Rect2.top might do it, but the value is way off. Curious why, will look into it when I get to it ... or just wait for him to figure it out :biggrin:
yeah, it's weird for me too.

thanks guys for your time. :icon_exclaim:

HSE

It's not processing WM_SIZING :eusa_naughty: , but WM_SIZE  :t

Regards. HSE
Equations in Assembly: SmplMath

jj2007

Quote from: HSE on August 12, 2015, 02:18:40 AM
It's not processing WM_SIZING :eusa_naughty: , but WM_SIZE  :t

Same problem with client edge. The only difference is that the move downwards is slower, of course.

dedndave

WM_SIZE has some very important values in wParam and lParam
i see a lot of code that totally ignores them, too - lol

WM_SIZE, wParam values

SIZE_RESTORED  EQU 0
The window has been resized, but neither the SIZE_MINIMIZED nor SIZE_MAXIMIZED value applies.

SIZE_MINIMIZED EQU 1
The window has been minimized.

SIZE_MAXIMIZED EQU 2
The window has been maximized.

SIZE_MAXSHOW   EQU 3
Message is sent to all pop-up windows when some other window has been restored to its former size.

SIZE_MAXHIDE   EQU 4
Message is sent to all pop-up windows when some other window is maximized.


you typically want to perform some adjustments for SIZE_RESTORED and SIZE_MAXIMIZED, and do nothing for the other values
lParam holds the new client dimensions
what i sometimes do, is to store the new values in a global _SIZE structure
that way, i don't have to call GetClientRect during WM_PAINT (or other places)

    mov     eax,uMsg
    .if eax==WM_SIZE
        .if !(wParam&(NOT SIZE_MAXIMIZED))                            ;perform if SIZE_RESTORED or if SIZE_MAXIMIZED
            mov     edx,lParam
            movzx   ecx,dx
            shr     edx,16
            mov     sizeClient.x,ecx
            mov     sizeClient.y,edx
        .endif
        xor     eax,eax                                               ;return 0


in this particular case, Aron could do a similar thing with the position of the child window
i.e., store the Y postition in a global variable, and only calculate the X position when SIZE_RESTORED or SIZE_MAXIMIZED

HSE

Hi JJ. I'am in the original "center" problem (in Win 7-32).

Good trick Dave!! I think something close to that, but I don't resolve the problem with maximized windows.



Equations in Assembly: SmplMath

dedndave

it's not an issue of "resolving a problem with maximized windows"

when the window is maximized, you still want to update the client _SIZE structure   :t

jj2007

I wonder if lparam of WM_SIZE really solves the problem, which is the wrong rc.top value...

dedndave

well - he wants to center the child window (or control) horizontally
so - having the client width handy means you don't have to call GetClientRect to get it
not that it's a slow function, really
but you also don't have to create a local RECT to get it   :P

rrr314159

Here's another way to do it, which works with WS_EX_CLIENTEDGE - on my machine. Unfortunately it uses a "magic number" which may not work on your machine.

Rect2.top has the textbox in screen coords, so we need the window's top in screen coords also, and subtract them. So, after computing ecx in CenterHorizontal call GetWindowRect for the parent (instead of GetClientRect) and subtract its top from the textbox. Then adjust by the "magic number" 26h which is the thickness of the window's title bar. So CenterHorizontal becomes:

CenterHorizontal proc Child:HWND
    LOCAL Parent:HWND
    LOCAL Rect1:RECT
    LOCAL Rect2:RECT
   
    invoke GetParent, Child
    mov Parent, eax
    invoke GetClientRect, Parent, addr Rect1
    invoke GetWindowRect, Child, addr Rect2
;    invoke GetYRelativeToParent, Child   ; this technique is alternative to MapWindowPoints
    mov ecx, Rect1.right
    add ecx, Rect2.left
    sub ecx, Rect2.right
    sar ecx,1

push ecx ; could rearrange to make it cleaner and avoid this push
    invoke GetWindowRect, Parent, addr Rect1
pop ecx

    mov edx, Rect2.top
    sub edx, Rect1.top
    sub edx, 26h

    invoke SetWindowPos, Child, 0, ecx, edx, 0, 0, SWP_NOZORDER or SWP_NOSIZE
    ret

CenterHorizontal endp


The code could be cleaner, of course. I think u can skip the GetClientRect call to Parent and subtract its GetWindowRect coords (right-left) to get the value which is in Rect1.right, for instance.

This works with or without WS_EX_CLIENTEDGE. The problem is, I doubt you can count on that "26h" for the title bar. On different systems and with different styles it may change. In fact that's exactly the problem MapWindowPoints is supposed to handle. But (for some reason) it doesn't work with clientedge ... Anyway this resolves (IMHO) the issue with Rect2.top, FWIW.
I am NaN ;)

jj2007

Quote from: rrr314159 on August 12, 2015, 06:56:18 AMthe "magic number" 26h which is the thickness of the window's title bar.

include \masm32\include\masm32rt.inc
.code
start: MsgBox 0, str$(rv(GetSystemMetrics, SM_CYCAPTION)), "Height of your window title bars:", MB_OK
exit
end start

rrr314159

The call to GetSystemMetrics probably can make this approach portable and more or less equivalent to using MapWindowPoints - except for clientedge. The question is, why does MapWindowPoints have problem with clientedge?
I am NaN ;)

dedndave

you can use system metrics to get the border width, as well
i think it's SM_BORDER
double it, of course
you have to do that for the caption bar height, anyways
the caption bar includes a border

TouEnMasm

#28
The GetSystemMetrics function have not the SM_BORDER
https://msdn.microsoft.com/en-us/library/aa929225.aspx
Must be an old name

Answer is SM_CXBORDER, SM_CYBORDER
But SM_CXEDGE, SM_CYEDGE make things a little more difficult to use.
The better way stay a substract between the getwindowrect,getclientrect

Fa is a musical note to play with CL