QB64 Phoenix Edition
$RESIZE questions - Printable Version

+- QB64 Phoenix Edition (https://qb64phoenix.com/forum)
+-- Forum: QB64 Rising (https://qb64phoenix.com/forum/forumdisplay.php?fid=1)
+--- Forum: Code and Stuff (https://qb64phoenix.com/forum/forumdisplay.php?fid=3)
+---- Forum: Help Me! (https://qb64phoenix.com/forum/forumdisplay.php?fid=10)
+---- Thread: $RESIZE questions (/showthread.php?tid=2781)



$RESIZE questions - TerryRitchie - 06-06-2024

With $RESIZE:ON I've noticed that _WIDTH and _HEIGHT will not update when the screen is resized (which I assume is correct behavior).

_RESIZEWIDTH and _RESIZEHEIGHT do however as detailed in the Wiki.

Without $RESIZE:ON in the code I've noticed that _RESIZEWIDTH and _RESIZEHEIGHT report the same as _WIDTH and _HEIGHT. According to the Wiki the RESIZE command set should not be available without $RESIZE:ON.

Is _RESIZEWIDTH and _RESIZEHEIGHT reporting values without $RESIZE:ON a bug or is this expected behavior?

If this is not expected behavior and will get fixed (a bug) how can I detect when a program is allowed to resize? I would need to know to use _WIDTH and _HEIGHT when a window has a fixed size or use _RESIZEWIDTH and _RESIZEHEIGHT when a window is allowed to resize. I need to be able to incorporate this detection into libraries.

If this is expected behavior then why use _WIDTH and _HEIGHT at all? _RESIZEWIDTH and _RESIZEHEIGHT will always report the correct client _WIDTH and _HEIGHT whether $RESIZE:ON is present or not.

Any insights?


RE: $RESIZE questions - SMcNeill - 06-06-2024

(06-06-2024, 09:09 PM)TerryRitchie Wrote: Without $RESIZE:ON in the code I've noticed that _RESIZEWIDTH and _RESIZEHEIGHT report the same as _WIDTH and _HEIGHT.

It's not something I'm seeing when I run the little code here below:

Code: (Select All)
DO
    x = _RESIZEWIDTH
    y = _RESIZEHEIGHT
    PRINT _WIDTH, _HEIGHT, x, y
    _LIMIT 10
LOOP UNTIL x _ANDALSO y

This prints us a couple of zeros on the screen, followed by the values 640, 400, for the x/y values above.

What you're seeing is basically the default settings for everything.  This doesn't have any screen statement, so it's going to be a default SCREEN 0 screen.  The _WIDTH and _HEIGHT are determined basically when the screen starts to initialize itself and get created.  That _RESIZEWIDTH and _RESIZEHEIGHT basically gets set to the default SCREEN width and height, once the window/screen is finally created and registered.

For a few cycles there, the screen isn't fully created/registered, so those values aren't updated. 

Now, as far as I know, with RESIZE OFF (or not in your code), those values will only update when the SCREEN itself changes (and they always seem to lag a bit behind before they update), as illustrated below:

Code: (Select All)
DO
    x = _RESIZEWIDTH
    y = _RESIZEHEIGHT
    PRINT _WIDTH, _HEIGHT, x, y
    _LIMIT 10
LOOP UNTIL x _ANDALSO y

SCREEN _NEWIMAGE(720, 400, 32)
DO
    x = _RESIZEWIDTH
    y = _RESIZEHEIGHT
    PRINT _WIDTH, _HEIGHT, x, y
    _LIMIT 10
LOOP UNTIL x <> 640

Once again, we report the old size of 640, 400 twice on my machine, before we finally swap over to 720, 400 as the finilized size.

That screen has to be finished with it's whole process, before those values update to the default values.



Now, the question becomes, "What should those default values be?"

0 and 0?
Just toss an ERROR?
Some negative values?  -32000, -32000?

Basically, Galleon decided back in the day that the best way to handle these was just to have them default to the current screen's starting size.

So basically, with no $RESIZE ON anywhere in your code, the value is always going to be the pixel value of your screen's width and height.  (Maybe after a few cycles to update settings after a screen change or WIDTH change.)

If that's useful information for you, then make use of it.  Personally though, I think I'd rather just stick to _WIDTH and _HEIGHT in most cases, as it's just less typing.  Smile


RE: $RESIZE questions - TerryRitchie - 06-07-2024

I don't know why this crazy stuff happens to me. I'm getting 640x480 using _RESIZEWIDTH and _RESIZEHEIGHT with no $RESIZE:ON directive in the following code.

Change _NEWIMAGE to 800 and 600 and you'll see _RESIZEWIDTH and _RESIZEHEIGHT reflect that too.

Code: (Select All)

OPTION _EXPLICIT

TYPE TYPE_IPOINT
    x AS LONG
    y AS LONG
END TYPE

TYPE TYPE_RECT
    left AS LONG
    top AS LONG
    right AS LONG
    bottom AS LONG
END TYPE



DECLARE DYNAMIC LIBRARY "user32"
    'get current mouse x/y position
    'http://allapi.mentalis.org/apilist/GetCursorPos.shtml
    FUNCTION GetCursorPos% (lpPoint AS TYPE_IPOINT)
    'system window metrics in pixels
    'https://learn.microsoft.com/en-us/windows/win32/api/winuser/nf-winuser-getsystemmetrics
    FUNCTION GetSystemMetrics% (BYVAL nIndex AS INTEGER)
    '
    '-  4: Window caption height
    '-  5: Window border width
    '-  6: Window border height
    '- 32: The width of the sizing border around the perimeter of a window that can be resized
    '- 33: The height of the sizing border around the perimeter of a window that can be resized
    '
    'To get actual border width : 32 - 5
    'To get actual border height: 33 - 6

    FUNCTION GetWindowRect% (BYVAL hWnd AS _INTEGER64, lpRect AS TYPE_RECT) ' returns desktop coordinates (_SCREENX, _SCREENY)-(x2, y2)
    '
    ' The rectangle returned
    '    - .left  : desktop left  x coordinate
    '    - .top    : desktop top    y coordinate
    '    - .right  : desktop right  x coordinate + 1
    '    - .bottom : desktop bottom y coordinate + 1


    FUNCTION GetClientRect% (BYVAL hWnd AS _INTEGER64, lpRect AS TYPE_RECT) ' returns (0, 0)-(_WIDTH, _HEIGHT)

    FUNCTION IsZoomed% (BYVAL hWnd AS _INTEGER64) ' reports a maximized window (_FULLSCREEN)

END DECLARE


TYPE TYPE_WINDOWAREA '          WINDOW AREA PROPERTIES
    Rect AS TYPE_RECT '          area coordinates
    Width AS INTEGER '          area width
    Height AS INTEGER '          area height
    Border AS INTEGER '          area border
END TYPE

TYPE TYPE_PROGRAMWINDOW '        PROGRAM WINDOW PROPERTIES
    Main AS TYPE_WINDOWAREA '    main  window coordinates, width, height (absolute to desktop)
    Client AS TYPE_WINDOWAREA '  client  area coordinates, width, height (absolute to desktop)
    Caption AS TYPE_WINDOWAREA ' caption area coordinates, width, height (absolute to desktop)
END TYPE

DIM Program AS TYPE_PROGRAMWINDOW ' program window properties
DIM Success AS INTEGER

SCREEN _NEWIMAGE(640, 480, 32)

DO
    _LIMIT 60
    LOCATE 1, 1
    PRINT _RESIZEWIDTH, _RESIZEHEIGHT
    IF _RESIZE THEN
        BEEP
        CLS
        PRINT
        IF ProgramWindowUpdate THEN
            PRINT " Program Width  :"; ProgramWidth
            PRINT " Program Height :"; ProgramHeight
            PRINT " Program Left  :"; ProgramLeft
            PRINT " Program Top    :"; ProgramTop
            PRINT " Program Right  :"; ProgramRight
            PRINT " Program Bottom :"; ProgramBottom
            PRINT " Program Border :"; ProgramBorder
            PRINT
            PRINT " Client Width  :"; ClientWidth
            PRINT " Client Height  :"; ClientHeight
            PRINT " Client Left    :"; ClientLeft
            PRINT " Client Top    :"; ClientTop
            PRINT " Client Right  :"; ClientRight
            PRINT " Client Bottom  :"; ClientBottom
            PRINT " Client Border  :"; ClientBorder
            PRINT
            PRINT " Caption Width  :"; CaptionWidth
            PRINT " Caption Height :"; CaptionHeight
            PRINT " Caption Left  :"; CaptionLeft
            PRINT " Caption Top    :"; CaptionTop
            PRINT " Caption Right  :"; CaptionRight
            PRINT " Caption Bottom :"; CaptionBottom
        ELSE
            PRINT " There was an error retrieveing the program window properties."
        END IF
    END IF
LOOP




FUNCTION ProgramWindowUpdate% ()

    SHARED Program AS TYPE_PROGRAMWINDOW ' program window properties
    DIM Rect AS TYPE_RECT '                rectangle structure
    DIM Success AS INTEGER '              0 if API call failed, non zero otherwise

    _DELAY .1 ' LOOK ------------------------------------------------------------------>  this delay may need to be longer
    Success = GetWindowRect(_WINDOWHANDLE, Rect) '                                        get program window desktop coordinates
    IF Success THEN '                                                                    were the coordinates gotten successfully?
        Program.Client.Border = GetSystemMetrics(5) '                                    yes, client area border width/height
        Program.Main.Width = Rect.right - Rect.left '                                    width of main program window
        Program.Main.Height = Rect.bottom - Rect.top '                                    height of main program window
        Program.Main.Rect.left = Rect.left '                                              desktop left  x coordinate of main program window (_SCREENX)
        Program.Main.Rect.top = Rect.top '                                                desktop top    y coordinate of main program window (_SCREENY)
        Program.Main.Rect.right = Rect.right - 1 '                                        desktop right  x coordinate of main program window
        Program.Main.Rect.bottom = Rect.bottom - 1 '                                      desktop bottom y coordinate of main program window
        Program.Main.Border =      (Program.Main.Width - _WIDTH(0)) \ 2 - _
                                  Program.Client.Border '                                main program window border width/height
        Program.Client.Height = _HEIGHT '                                                height of client area
        Program.Caption.Height =  Program.Main.Height - Program.Client.Height - _
                                  Program.Main.Border * 2 - Program.Client.Border * 2 '  caption area height
        Program.Client.Width = _WIDTH '                                                  width of client area
        Program.Client.Rect.left = Program.Main.Rect.left + Program.Main.Border + _
                                  Program.Client.Border '                                desktop left  x coordinate of client area
        Program.Client.Rect.top =  Program.Main.Rect.top + Program.Main.Border + _
                                  Program.Caption.Height + Program.Client.Border '      desktop top    y coordinate of client area
        Program.Client.Rect.right = Program.Client.Rect.left + _WIDTH - 1 '              desktop right  x coordinate of client area
        Program.Client.Rect.bottom = Program.Client.Rect.top + _HEIGHT - 1 '              desktop bottom y coordinate of client area
        Program.Caption.Width = Program.Client.Width '                                    width of caption area
        Program.Caption.Rect.left = Program.Client.Rect.left '                            desktop left x coordinate of caption area
        Program.Caption.Rect.top = Program.Main.Border + Program.Client.Border '          desktop top y coordinate of caption area
        Program.Caption.Rect.right = Program.Client.Rect.right '                          desktop right x coordinate of caption area
        Program.Caption.Rect.bottom = Program.Caption.Rect.top + Program.Caption.Height ' desktop bottom y coordinate of caption area
        ProgramWindowUpdate% = Success '                                                  return success status of operation
    END IF

END FUNCTION


FUNCTION ProgramWidth% ()

    SHARED Program AS TYPE_PROGRAMWINDOW ' program window properties

    ProgramWidth% = Program.Main.Width '  yes, return the set value

END FUNCTION

FUNCTION ProgramHeight% ()

    SHARED Program AS TYPE_PROGRAMWINDOW ' program window properties

    ProgramHeight% = Program.Main.Height

END FUNCTION

FUNCTION ProgramLeft% ()

    ' Note: Same as _SCREENX

    SHARED Program AS TYPE_PROGRAMWINDOW ' program window properties

    ProgramLeft% = Program.Main.Rect.left

END FUNCTION

FUNCTION ProgramTop% ()

    ' Note: Same as _SCREENY

    SHARED Program AS TYPE_PROGRAMWINDOW ' program window properties

    ProgramTop% = Program.Main.Rect.top

END FUNCTION

FUNCTION ProgramRight% ()

    SHARED Program AS TYPE_PROGRAMWINDOW ' program window properties

    ProgramRight% = Program.Main.Rect.right

END FUNCTION

FUNCTION ProgramBottom% ()

    SHARED Program AS TYPE_PROGRAMWINDOW ' program window properties

    ProgramBottom% = Program.Main.Rect.bottom

END FUNCTION

FUNCTION ProgramRect% (ReturnRect AS TYPE_RECT)

    SHARED Program AS TYPE_PROGRAMWINDOW ' program window properties

    ReturnRect = Program.Main.Rect

END FUNCTION

FUNCTION ProgramBorder% ()

    SHARED Program AS TYPE_PROGRAMWINDOW ' program window properties

    ProgramBorder% = Program.Main.Border

END FUNCTION

FUNCTION ClientWidth% ()

    SHARED Program AS TYPE_PROGRAMWINDOW ' program window properties

    ClientWidth% = Program.Client.Width

END FUNCTION

FUNCTION ClientHeight% ()

    SHARED Program AS TYPE_PROGRAMWINDOW ' program window properties

    ClientHeight% = Program.Client.Height

END FUNCTION

FUNCTION ClientLeft% ()

    SHARED Program AS TYPE_PROGRAMWINDOW ' program window properties

    ClientLeft% = Program.Client.Rect.left

END FUNCTION

FUNCTION ClientTop% ()

    SHARED Program AS TYPE_PROGRAMWINDOW ' program window properties

    ClientTop% = Program.Client.Rect.top

END FUNCTION

FUNCTION ClientRight% ()

    SHARED Program AS TYPE_PROGRAMWINDOW ' program window properties

    ClientRight% = Program.Client.Rect.right

END FUNCTION

FUNCTION ClientBottom% ()

    SHARED Program AS TYPE_PROGRAMWINDOW ' program window properties

    ClientBottom% = Program.Client.Rect.bottom

END FUNCTION

FUNCTION ClientRect% (ReturnRect AS TYPE_RECT)

    SHARED Program AS TYPE_PROGRAMWINDOW ' program window properties

    ReturnRect = Program.Client.Rect

END FUNCTION

FUNCTION ClientBorder% ()

    SHARED Program AS TYPE_PROGRAMWINDOW ' program window properties

    ClientBorder% = Program.Client.Border

END FUNCTION

FUNCTION CaptionWidth% ()

    SHARED Program AS TYPE_PROGRAMWINDOW ' program window properties

    CaptionWidth% = Program.Caption.Width

END FUNCTION

FUNCTION CaptionHeight% ()

    SHARED Program AS TYPE_PROGRAMWINDOW ' program window properties

    CaptionHeight% = Program.Caption.Height

END FUNCTION

FUNCTION CaptionLeft% ()

    SHARED Program AS TYPE_PROGRAMWINDOW ' program window properties

    CaptionLeft% = Program.Caption.Rect.left

END FUNCTION

FUNCTION CaptionTop% ()

    SHARED Program AS TYPE_PROGRAMWINDOW ' program window properties

    CaptionTop% = Program.Caption.Rect.top

END FUNCTION

FUNCTION CaptionRight% ()

    SHARED Program AS TYPE_PROGRAMWINDOW ' program window properties

    CaptionRight% = Program.Caption.Rect.right

END FUNCTION

FUNCTION CaptionBottom% ()

    SHARED Program AS TYPE_PROGRAMWINDOW ' program window properties

    CaptionBottom% = Program.Caption.Rect.bottom

END FUNCTION

FUNCTION CaptionRect% (ReturnRect AS TYPE_RECT)

    SHARED Program AS TYPE_PROGRAMWINDOW ' program window properties

    ReturnRect = Program.Caption.Rect

END FUNCTION



RE: $RESIZE questions - SMcNeill - 06-07-2024

When you call the SCREEN _NEWIMAGE(640, 480, 32), that sets the _RESIZEWIDTH and _RESIZEHEIGHT default values to the screen Width and Height.  It's only when you grab the edge of the screen and change that window size, that those figures will change.

As far as I can tell, it's doing as expected.  What values/behavior are you expecting to see here?


RE: $RESIZE questions - TerryRitchie - 06-07-2024

Ok, I misread your reply. This is what is supposed to happen.

Ugh. I need a break.

Damn Steve that was a quick reply. You beat mine stating that I misread your post. Smile


RE: $RESIZE questions - SMcNeill - 06-07-2024

(06-07-2024, 12:38 AM)TerryRitchie Wrote: Ok, I misread your reply. This is what is supposed to happen.

Ugh. I need a break.

Damn Steve that was a quick reply. You beat mine stating that I misread your post. Smile

It may take a cycle or two to update the values after a SCREEN change, but it'll eventually get there for you.  Smile


RE: $RESIZE questions - TerryRitchie - 06-07-2024

(06-07-2024, 12:40 AM)SMcNeill Wrote:
(06-07-2024, 12:38 AM)TerryRitchie Wrote: Ok, I misread your reply. This is what is supposed to happen.

Ugh. I need a break.

Damn Steve that was a quick reply. You beat mine stating that I misread your post. Smile

It may take a cycle or two to update the values after a SCREEN change, but it'll eventually get there for you.  Smile
Is there a reason why _WIDTH and _HEIGHT can't update when the screen size changes? Why the need for separate _RESIZEWIDTH and _RESIZEHEIGHT?


RE: $RESIZE questions - SMcNeill - 06-07-2024

(06-07-2024, 04:37 AM)TerryRitchie Wrote: Is there a reason why _WIDTH and _HEIGHT can't update when the screen size changes? Why the need for separate _RESIZEWIDTH and _RESIZEHEIGHT?

Try this:

Code: (Select All)
SCREEN _NEWIMAGE(640, 480, 32) 'let's set the screen to a nice size that we know exactly what it'll be
_DELAY .5 'make certain everything has time to do its stuff
PRINT _WIDTH, _HEIGHT, _RESIZEWIDTH, _RESIZEHEIGHT 'now, all these numbers should match.
SLEEP 'give you time to check the screen to make certain they do
_DELAY .2
_KEYCLEAR
$RESIZE:SMOOTH
DO
    CLS
    PRINT "Grab any corner and drag the screen to resize it, please!"
    PRINT _WIDTH, _HEIGHT, _RESIZEWIDTH, _RESIZEHEIGHT
    _LIMIT 30
    _DISPLAY
LOOP UNTIL _KEYHIT

Now, as you can see when you grab the corner of that window and drag it, the _WIDTH and _HEIGHT don't change.  Your SCREEN is still 640 x 480 pixels in size -- but look at the SIZE of those pixels!  If you drag the screen to 1280 x 960, those pixels are all now TWICE as large as they were before.

The _WIDTH and _HEIGHT of the SCREEN didn't change.
The _RESIZEWIDTH and _RESIZEHEIGHT of the WINDOW did. 

Two completely different things.  One relates to the SCREEN coordinates.  The other relates to the WINDOW size.



Now, try it with $RESIZE:ON

Code: (Select All)
$COLOR:32
SCREEN _NEWIMAGE(640, 480, 32) 'let's set the screen to a nice size that we know exactly what it'll be
_DELAY .5 'make certain everything has time to do its stuff
PRINT _WIDTH, _HEIGHT, _RESIZEWIDTH, _RESIZEHEIGHT 'now, all these numbers should match.
SLEEP 'give you time to check the screen to make certain they do
_DELAY .2
_KEYCLEAR
$RESIZE:ON
DO
CLS , White
PRINT "Grab any corner and drag the screen to resize it, please!"
PRINT _WIDTH, _HEIGHT, _RESIZEWIDTH, _RESIZEHEIGHT
_LIMIT 30
_DISPLAY
LOOP UNTIL _KEYHIT

Run the above, get to the white screen, and then grab a corner and drag.

Your screen stays the same size of 640 x 480. It never changes.

If you grab the right corner and drag it to the right, the _RESIZEWIDTH will increase, and there'll be a black gap of nothing to the right side of your program screen (kinda like the black bars you often see on TVs when a 16:9 widescreen show tries to show on a 4:3 old standard TV).

Resize:On requires the programmer to decide what to do with things manually. Do you want to stretch the pixels like RESIZE:STRETCH does? Do you want to resize the program to fit the new Window, like the QB64PE IDE does? Do you want to maintain aspect ratio, like most video players would? Or can you just drag one side to make the screen wider, without affecting the height?

Your program SCREEN and thus its WIDTH and HEIGHT doesn't change one bit, until you manually process and decide what to do with that _RESIZE event.

And it's _RESIZEWIDTH and _RESIZEHEIGHT that gives you the information back so you can do that.


RE: $RESIZE questions - TerryRitchie - 06-07-2024

Ah, I didn't even take that into account. Yep, makes sense.