Page 1 of 1
Get ACTUAL full virtual desktop size?
Posted: Thu May 30, 2024 1:15 pm
by BarryG
It turns out that "GetSystemMetrics_(#SM_CXVIRTUALSCREEN)" and the "CY" version don't actually get the entire desktop area when using multiple monitors. Seen lots of posts on StackOverflow about it.
I need to get the entire actual desktop size, regardless of which monitor is set as the main one.
So I tried adapting this code by Chi ->
viewtopic.php?p=507541#p507541
And here's what I'm testing:
Code: Select all
; Get full real desktop size of all monitors combined.
Global desktop_size_x,desktop_size_y,desktop_size_w,desktop_size_h
Procedure MonitorEnumProc(hMonitor,hdcMonitor,lprcMonitor,dwData) ; http://forums.purebasic.com/english/viewtopic.php?p=507541
*monRect.RECT=lprcMonitor
x=*monRect\left : If x<desktop_size_x : desktop_size_x=x : EndIf
y=*monRect\top : If y<desktop_size_y : desktop_size_y=y : EndIf
w=*monRect\right : If w>desktop_size_w : desktop_size_w=w : EndIf
h=*monRect\bottom : If h>desktop_size_h : desktop_size_h=h : EndIf
ProcedureReturn #True
EndProcedure
Procedure GetDesktopSize()
desktop_size_x=0
desktop_size_y=0
desktop_size_w=0
desktop_size_h=0
EnumDisplayMonitors_(0,0,@MonitorEnumProc(),0)
EndProcedure
GetDesktopSize()
OpenWindow(0,desktop_size_x+10,desktop_size_y+10,desktop_size_w-20,desktop_size_h-20,"",#PB_Window_BorderLess)
SetWindowColor(0,#Yellow)
UpdateWindow_(WindowID(0))
Repeat : WaitWindowEvent(1) : Until GetAsyncKeyState_(#VK_ESCAPE) & $8000 <> 0
When I run this, the yellow window doesn't match the desktop size because monitor 3 on the right is the main one, but it also doesn't work if I set monitor 1 or 2 as the main. Anyone know how to resolve this so that the yellow window fills all 3 monitors? And don't forget to test when all 3 monitors are stacked vertically, too.

Thanks.
Screenshot for reference:

Re: Get ACTUAL full virtual desktop size?
Posted: Thu May 30, 2024 3:53 pm
by Axolotl
I cannot test this, because I only have a single monitor setting.
I know, that the GetSystemMetrics() returns a LONG value, so to get the negative values you should do something like below.
Recently I did
this.
Maybe you can give it a try and a small feedback.
And sorry in advance, because I do things simple i.e. never did this dpi stuff.
Code: Select all
Procedure.l GetSystemMetrics(Index) ; .l is important (works in 64-bit) .. variable can be a .i type, index == i.e. #SM_XVIRTUALSCREEN
ProcedureReturn GetSystemMetrics_(Index) ; return depends on Index, i.e. #SM_XVIRTUALSCREEN
EndProcedure
Macro VirtualScreenX()
GetSystemMetrics(#SM_XVIRTUALSCREEN)
EndMacro
Macro VirtualScreenY()
GetSystemMetrics(#SM_YVIRTUALSCREEN)
EndMacro
Macro VirtualScreenWidth()
GetSystemMetrics(#SM_CXVIRTUALSCREEN)
EndMacro
Macro VirtualScreenHeight()
GetSystemMetrics(#SM_CYVIRTUALSCREEN)
EndMacro
Macro CountMonitors()
GetSystemMetrics(#SM_CMONITORS)
EndMacro
Macro SameDisplayFormat()
GetSystemMetrics(#SM_SAMEDISPLAYFORMAT)
EndMacro
Macro MonitorAsString() ; returns <Number of Monitors> _ <entire width> x <entire height> i.e. '1_1920x1080'
Str(GetSystemMetrics(#SM_CMONITORS)) + "_" + Str(GetSystemMetrics(#SM_CXVIRTUALSCREEN)) + "x" + Str(GetSystemMetrics(#SM_CYVIRTUALSCREEN))
EndMacro
Re: Get ACTUAL full virtual desktop size?
Posted: Thu May 30, 2024 6:20 pm
by ChrisR
I haven't tested it, I only have one monitor at the moment.
It seems that there is confusion in your code between: *monRect\right, bottom and Width, Height
desktop_size.. should be a Rect structure. Not tested and don't know if Windows lets you stretch it over several monitors but try with:
Code: Select all
; Get full real desktop size of all monitors combined.
Global desktopRect.Rect
Procedure MonitorEnumProc(hMonitor,hdcMonitor,*monRect.RECT,dwData) ; https://www.purebasic.fr/english/viewtopic.php?p=507541
If *monRect\left < desktopRect\left : desktopRect\left = *monRect\left : EndIf
If *monRect\top < desktopRect\top : desktopRect\top = *monRect\top : EndIf
If *monRect\right > desktopRect\right : desktopRect\right = *monRect\right : EndIf
If *monRect\bottom > desktopRect\bottom : desktopRect\bottom = *monRect\bottom : EndIf
ProcedureReturn #True
EndProcedure
Procedure GetDesktopSize()
desktopRect\left = 9999
desktopRect\top = 9999
desktopRect\right = 0
desktopRect\bottom = 0
EnumDisplayMonitors_(0,0,@MonitorEnumProc(),0)
EndProcedure
GetDesktopSize()
OpenWindow(0,desktopRect\left+10,desktopRect\top+10,desktopRect\right-desktopRect\left-20,desktopRect\bottom-desktopRect\top-20,"",#PB_Window_BorderLess)
SetWindowColor(0,#Yellow)
UpdateWindow_(WindowID(0))
Repeat : WaitWindowEvent(1) : Until GetAsyncKeyState_(#VK_ESCAPE) & $8000 <> 0
Re: Get ACTUAL full virtual desktop size?
Posted: Fri May 31, 2024 10:02 am
by BarryG
@Axolotl: No, using #SM_CXVIRTUALSCREEN doesn't work when the monitors are re-arranged.
@ChrisR: Yes, that did it! Thank you so much. 
Re: Get ACTUAL full virtual desktop size?
Posted: Fri May 31, 2024 11:15 am
by NicTheQuick
This also works on Linux:
Code: Select all
Structure DesktopRect
left.i
top.i
right.i
bottom.i
EndStructure
Procedure.i min(a.i, b.i)
If a < b: ProcedureReturn a: Else: ProcedureReturn b: EndIf
EndProcedure
Procedure.i max(a.i, b.i)
If a > b: ProcedureReturn a: Else: ProcedureReturn b: EndIf
EndProcedure
Procedure GetDesktopRect(*rect.DesktopRect)
Protected i.i, desktops.i = ExamineDesktops()
With *rect
\left = $7FFFFFFF
\top = $7FFFFFFF
\right = -$80000000
\bottom = -$80000000
For i = 0 To desktops - 1
\left = min(\left, DesktopX(i))
\top = min(\left, DesktopY(i))
\right = max(\right, DesktopX(i) + DesktopWidth(i))
\bottom = max(\bottom, DesktopY(i) + DesktopHeight(i))
Next
EndWith
EndProcedure
Define rect.DesktopRect
GetDesktopRect(rect)
Debug rect\left
Debug rect\top
Debug rect\right
Debug rect\bottom
OpenWindow(0, rect\left, rect\top, rect\right - rect\left, rect\bottom - rect\top, "test", #PB_Window_BorderLess)
Repeat: Until WaitWindowEvent() = #PB_Event_CloseWindow
Or did I miss something?
Re: Get ACTUAL full virtual desktop size?
Posted: Fri May 31, 2024 12:12 pm
by moulder61
@NicTheQuick
Works on my dual monitor Void Linux install except the window opens at what would be 1920,0 rather than 0,0.
The window is sized correctly at 3840,1080, but half of it disappears off the right hand side of the desktop.
I'll check it later in Arch, Devuan and Antix to see if they behave the same?
Moulder.
Re: Get ACTUAL full virtual desktop size?
Posted: Fri May 31, 2024 12:26 pm
by moulder61
@NicTheQuick
If you're interested, Devuan, Arch and Antix all behave the same as Void on my machine re: my previous post.
I don't run a "normal" desktop environment as such. All my installs have the same customised minimal XFWM setup.
Don't know if that would make a difference?
Moulder.
Re: Get ACTUAL full virtual desktop size?
Posted: Sat Jun 01, 2024 11:18 am
by ChrisR
NicTheQuick wrote: Fri May 31, 2024 11:15 am
Or did I miss something?
You haven't missed any thing, it should work fine with the Desktop library.
Well, maybe you forgot to lock Alt-Tab and Ctrl-Alt-Del shortcuts so as not to close this borderless window
