X-Sharp / XSharpPublic

Public repository for the source code for the XSharp Compiler, Runtime, Project System and Tools.
Apache License 2.0
112 stars 38 forks source link

VOGUI problem with relocating controls and resizing windows when OwnerAlignment is used #1249

Open cpyrgas opened 1 year ago

cpyrgas commented 1 year ago

From Trevor: https://www.xsharp.eu/forum/private-product/3361-vulcan-vo-gui-form#25188

VOMDIApp32.zip

cpyrgas commented 1 year ago

I partially fixed the problem by changing the Control:Origin ASSIGN from

ASSIGN Origin(oPoint)
    IF !IsInstanceOfUsual(oPoint, #Point)
        WCError{#Origin,#Control,__WCSTypeError,oPoint,1}:THROW()
    ENDIF

    IF (hWnd == NULL_PTR)
        SELF:oOrigin := Point{oPoint:X, oPoint:y}
    ELSE
        WCMoveWindow(SELF, oPoint, SELF:Size, TRUE)
    ENDIF

    RETURN

to

ASSIGN Origin(oPoint)
    IF !IsInstanceOfUsual(oPoint, #Point)
        WCError{#Origin,#Control,__WCSTypeError,oPoint,1}:THROW()
    ENDIF

    IF (hWnd == NULL_PTR)
        SELF:oOrigin := Point{oPoint:X, oPoint:y}
    ELSE
        WCMoveWindow(SELF, oPoint, SELF:Size, TRUE)
    ENDIF

    IF !(oFormSurface IS Window) .OR. ! (oParent IS Window)
        RETURN
    ELSEIF oFormSurface IS Window VAR oWin
        oWin:__AdjustAlign(SELF)
    ELSE
        oParent:__AdjustAlign(SELF)
    ENDIF

    RETURN

and similarly added the same code in Control:Size ASSIGN and introduced a new METHOD __AdjustAlign() in the Window class, which updates the owner alignment buffers when a control is manually resized:

METHOD __AdjustAlign(oControl AS Control) AS LOGIC STRICT
        LOCAL dwI, dwCount AS DWORD
        LOCAL sRect        IS _WINRECT
        LOCAL lDelete      AS LOGIC
        LOCAL lOldAlign    AS LOGIC

        dwCount := ALen(aAlignes)
        FOR dwI := 1 UPTO dwCount
            IF aAlignes[dwI, 1] == oControl
                GetWindowRect(oControl:Handle(), @sRect)
                #ifdef __VULCAN__
                    MapWindowPoints(NULL_PTR, SELF:Handle(4), (_winPOINT PTR) @sRect, 2)
                #else
                    MapWindowPoints(NULL_PTR, SELF:Handle(4), @sRect, 2)
                #endif
                aAlignes[dwI, 3] := sRect:left
                aAlignes[dwI, 4] := sRect:top
                aAlignes[dwI, 5] := sRect:right-sRect:left
                aAlignes[dwI, 6] := sRect:bottom-sRect:top
                RETURN TRUE
            ENDIF
        NEXT //dwI

     RETURN FALSE

This does the trick for regular resizing, but the original problem remains for when maximizing the window. Needs further investigation why..

cpyrgas commented 1 year ago

Actually it does work ok also when maximizing...

RobertvanderHulst commented 1 year ago

Chris, This looks good. I would recommend to change this code though:

IF !(oFormSurface IS Window) .OR. ! (oParent IS Window)
        RETURN
    ELSEIF oFormSurface IS Window VAR oWin
        oWin:__AdjustAlign(SELF)
    ELSE
        oParent:__AdjustAlign(SELF)
    ENDIF

You are now checking for the type twice.

IF oFormSurface IS Window VAR oFormWin
    oFormWin:__AdjustAlign(SELF)
ELSEIF oParent is Window  oWindow
    oWindow:__AdjustAlign(SELF)
ELSE
    RETURN
ENDIF

And the check

IF !IsInstanceOfUsual(oPoint, #Point)

should really be changed to (to avoid calling a runtime function)

IF !(oPoint IS Point)

And maybe I should add the IS NOT syntax to the compiler, so we can write IF oPoint IS NOT Point

IS NOT is already in Roslyn, so adding that should be relatively easy.

cpyrgas commented 1 year ago

Robert,

I had just copied/pasted the code from the already existing OwnerAlignment assign:

ASSIGN OwnerAlignment(iNewVal)
    IF !(oFormSurface IS Window) .OR. ! (oParent IS Window)
        RETURN OA_NO
    ELSEIF oFormSurface IS Window VAR oWin
        oWin:__AddAlign(SELF, iNewVal)
    ELSE
        oParent:__AddAlign(SELF, iNewVal)
    ENDIF

As always, I'm afraid of making such code changes in code that has been working for years, as it might introduce a problem we are not thinking of right now. But if you feel adventurous... :)

cpyrgas commented 1 year ago

Hmmm...thinking about it, that was probably your code hehe :)