Extended screens

Discussions related to graphics (2D and 3D), animation and games programming
KenDown
Posts: 327
Joined: Wed 04 Apr 2018, 06:36

Extended screens

Post by KenDown »

Does anyone know of a SYS call (or calls) that would enable me to detect whether there is an additional screen connected to my computer and what size it is? My laptop is 1366x768 but I commonly connect to an extended screen or a projector with the resolution 1920x1080. It would be useful if I could detect the presence and size of this other screen.

Thanks.
Hans
Posts: 1
Joined: Wed 04 Apr 2018, 08:00

Re: Extended screens

Post by Hans »

This is a snippet of code from one of my programs which does what you need:

SYS"GetDeviceCaps", @memhdc%, 88 TO dpi% : REM read dpi of screen
SYS"GetSystemMetrics", 0 TO xscreen% : SYS"GetSystemMetrics", 1 TO yscreen% : REM get size of main monitor in pixels.
SYS"GetSystemMetrics",76 TO m_left% : SYS"GetSystemMetrics",77 TO m_top% : REM Leftmost and topmost pixel on all monitors.
SYS"GetSystemMetrics",78 TO m_width% : SYS"GetSystemMetrics",79 TO m_height% : REM Total width and height of all monitors.
m_right%=m_left%+m_width% : m_bottom%=m_top%+m_height% : REM Rightmost and lowest pixel on all monitors.
SYS"GetSystemMetrics",80 TO monitors% : REM Number of active monitors.
Hated Moron

Re: Extended screens

Post by Hated Moron »

KenDown wrote: Sun 08 Jan 2023, 20:44 Does anyone know of a SYS call (or calls) that would enable me to detect whether there is an additional screen connected to my computer and what size it is?
You don't say whether this is BB4W or BBCSDL, but in the latter you can get the total number of screens with:

Code: Select all

      SYS "SDL_GetNumVideoDisplays" TO ns%
      PRINT "Number of screens = "; ns%
and the size of each screen can be found as follows:

Code: Select all

      DIM rect{x%, y%, w%, h%}
      FOR index% = 0 TO ns% - 1
        SYS "SDL_GetDisplayBounds", index%, rect{}
        PRINT "Size of screen "; index% " is "; rect.w% " x "; rect.h%
      NEXT index%
KenDown
Posts: 327
Joined: Wed 04 Apr 2018, 06:36

Re: Extended screens

Post by KenDown »

Thanks. I'm afraid it is BB4W, not SDL. However your reply did enable me to track down SYS"GetSystemMetrics"

Code: Select all

      SM_CMONITORS = 80
      SYS"GetSystemMetrics",SM_CMONITORS TOnum%
      PRINTnum%
This returns a value of 2 on my dual monitor computer. I'll have to check it on a laptop without a second monitor to see what I get.

However finding the size of the screens does not appear so easy. I've found

Code: Select all

      SM_CXSCREEN = 16
      SM_CYSCREEN = 1
      SYS"GetSystemMetrics",SM_CXSCREEN TOx%
      SYS"GetSystemMetrics",SM_CYSCREEN TOy%
      PRINTx%,y%
which returns the size in pixels of the main screen, but I can't find anything for any other screens.
Leo
Posts: 13
Joined: Tue 03 Apr 2018, 16:45

Re: Extended screens

Post by Leo »

I wrote this program a few years ago - it doesn't do exactly what you want but it does get window sizes, so may give some clues.
When run, the prog displays a small window containing a button and a static box. Clicking the button displays the size of the screen it's in.
Drag the window to another screen and click to find out the size of that one.

Code: Select all

      REM The following line is for compilation
      REM!Window 130,45,client,xpstyle
      REM!WC
      WS_MINIMIZEBOX = &20000
      WM_SETFONT = 48
      GWL_STYLE = -16
      MONITOR_DEFAULTTONEAREST = 2
      SS_CENTER = 1
      WM_SETTEXT = &C
      WS_MAXIMIZEBOX = 65536
      WS_SIZEBOX = &40000

      Width = 130
      Height = 45
      EHeight = 25

      DIM Rect{left%, top%, right%, bottom%}
      DIM MonInfo{cbSize%, rcMonitor{}=Rect{}, rcWork{}=Rect{}, dwFlags%}

      REM Set window style to disallow resizing
      SYS "GetWindowLong", @hwnd%, GWL_STYLE TO ws%
      ws% AND= NOT(WS_SIZEBOX OR WS_MAXIMIZEBOX OR WS_MINIMIZEBOX)
      SYS "SetWindowLong", @hwnd%, GWL_STYLE, ws%

      REM Set window size initially for XP Styles
      VDU 23,22,Width;Height;8,16,16,128
      *FONT Segoe UI,9
      OFF

      hBut% = FN_button("Click on each monitor", 0,0, Width,EHeight, FN_setproc(PROC_Click),0)
      hInf% = FN_staticbox("", 0,EHeight, Width,EHeight, 100, SS_CENTER)

      SYS "SendMessage", hBut%, WM_SETFONT, @vdu.hf%, 0
      SYS "SendMessage", hInf%, WM_SETFONT, @vdu.hf%, 0
      REM The following line seems necessary to make sure the new button font is used immediately
      SYS "InvalidateRect", hBut%,0,1
      REM This also forces repaint: SYS "SendMessage", hBut%, WM_SETTEXT, 0, "Click on each monitor"


      REPEAT
        WAIT 1
      UNTIL 0

      END

      DEF PROC_Click
      LOCAL X%,Y%, handle
      SYS "MonitorFromWindow", @hwnd%, MONITOR_DEFAULTTONEAREST TO handle
      MonInfo.cbSize% = DIM(MonInfo{})
      SYS "GetMonitorInfo", handle, MonInfo{}
      X% = MonInfo.rcWork.right% - MonInfo.rcWork.left%
      Y% = MonInfo.rcWork.bottom% - MonInfo.rcWork.top%
      SYS "SendMessage", hInf%, WM_SETTEXT, 0, STR$(X%) + " X " + STR$(Y%)
      ENDPROC

KenDown
Posts: 327
Joined: Wed 04 Apr 2018, 06:36

Re: Extended screens

Post by KenDown »

Thanks. I'm going to have to study that carefully. (If anyone else wants to try it, you will have to put the line

Code: Select all

INSTALL @lib$+"WinLib5"
near the start of the listing.
KenDown
Posts: 327
Joined: Wed 04 Apr 2018, 06:36

Re: Extended screens

Post by KenDown »

To Hans:
I can't see your reply here, but thank you for it. It looks a very ineresting and useful routine, but it does assume that both monitors are the same size. As I am working with 1366x768 and 1920x1080 I could, of course, assume that the second screen size is 3286-1366 and that the height is the height. However I can see it getting confused when the other day I discovered that I was linked to a projector 1280x800!

Thanks again.