Posts: 1,277
Threads: 120
Joined: Apr 2022
Reputation:
100
06-06-2024, 09:09 PM
(This post was last modified: 06-06-2024, 09:10 PM by TerryRitchie.)
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?
New to QB64pe? Visit the QB64 tutorial to get started.
QB64 Tutorial
Posts: 2,698
Threads: 327
Joined: Apr 2022
Reputation:
217
(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.
Posts: 1,277
Threads: 120
Joined: Apr 2022
Reputation:
100
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
New to QB64pe? Visit the QB64 tutorial to get started.
QB64 Tutorial
Posts: 2,698
Threads: 327
Joined: Apr 2022
Reputation:
217
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?
Posts: 1,277
Threads: 120
Joined: Apr 2022
Reputation:
100
06-07-2024, 12:38 AM
(This post was last modified: 06-07-2024, 12:40 AM by TerryRitchie.)
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.
New to QB64pe? Visit the QB64 tutorial to get started.
QB64 Tutorial
Posts: 2,698
Threads: 327
Joined: Apr 2022
Reputation:
217
(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.
It may take a cycle or two to update the values after a SCREEN change, but it'll eventually get there for you.
Posts: 1,277
Threads: 120
Joined: Apr 2022
Reputation:
100
(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.
It may take a cycle or two to update the values after a SCREEN change, but it'll eventually get there for you. Is there a reason why _WIDTH and _HEIGHT can't update when the screen size changes? Why the need for separate _RESIZEWIDTH and _RESIZEHEIGHT?
New to QB64pe? Visit the QB64 tutorial to get started.
QB64 Tutorial
Posts: 2,698
Threads: 327
Joined: Apr 2022
Reputation:
217
(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.
Posts: 1,277
Threads: 120
Joined: Apr 2022
Reputation:
100
Ah, I didn't even take that into account. Yep, makes sense.
New to QB64pe? Visit the QB64 tutorial to get started.
QB64 Tutorial
|