Screen dimensions

Discussions related to mouse, keyboard and Graphical User Interface
KenDown
Posts: 52
Joined: Wed 04 Apr 2018, 06:36

Screen dimensions

Post by KenDown » Fri 18 Jan 2019, 21:54

Does anyone know how to read screen dimensions in BBC BASIC, please? There is a routine provided somewhere (Help?) which successfully read the current screen, but if you have two screens of different sizes, how can you find the dimensions of the second?

I have a laptop running at 1400x800 and it is linked to a monitor 1920x1080, set up as extended monitor with the larger one being the main display. I would like to read the size of the laptop screen so that my program can create the appropriate window, bearing in mind that I have another laptop 1366x768 and a very old on 1280x840.

Thanks.

Zaphod
Posts: 63
Joined: Sat 23 Jun 2018, 15:51

Re: Screen dimensions

Post by Zaphod » Sat 19 Jan 2019, 17:06

I have not done this but this link might help.
https://stackoverflow.com/questions/310 ... nd-monitor

Z

DDRM
Administrator
Posts: 110
Joined: Mon 02 Apr 2018, 18:04

Re: Screen dimensions

Post by DDRM » Sun 20 Jan 2019, 15:06

Hi Kendall,

Not sure if this helps, but I think the piece you are remembering is under "using the entire screen" in the manual. The relevant commands are
SYS "GetSystemMetrics", 0 TO xscreen%
SYS "GetSystemMetrics", 1 TO yscreen%
which will give you the horizontal and vertical dimensions (in pixels) of the PRIMARY display - in this case presumably the big one.

Is the idea to set up a second window on the laptop screen? There's an MSDN page that might help:
https://docs.microsoft.com/en-us/window ... t-displays
It looks like you would need to set up a second device context for it, and then get the characteristics of that.

Hope that helps...

D

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

Re: Screen dimensions

Post by KenDown » Mon 28 Jan 2019, 14:45

Yes, those are the calls I am using to find the size of the primary screen. It's the second (and smaller) screen whose size I need to read.

I don't really understand what you mean by "set up a second device context" but I'll look up the URL you give and see if that enlightens me.

Sorry to be a bear of such very little brain.

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

Re: Screen dimensions

Post by KenDown » Mon 28 Jan 2019, 20:34

Hmmmm. No, it doesn't help. I tried following the instructions and ended up with this:

DIMcb%4
DIMdevicename%32
DIMdevicestring%128
DIMstateflags%4
DIMdeviceid%128
DIMdevicekey%128
DIMdisplaydeviceA{cb%,devicename%,devicestring%,stateflags%,deviceid%,devicekey%}
!cb%=4+32+128+4+128+128

FORi%=0TO2
SYS"EnumDisplayDevicesA",0,i%,displaydeviceA{},1TOsuccess%

PRINTsuccess%
PRINTdisplaydeviceA.devicename%
PRINTdisplaydeviceA.devicestring%
PRINTdisplaydeviceA.deviceid%
PRINTdisplaydeviceA.stateflags%
PRINT
NEXT
END

I have two monitors and the success% flag duly returns 1 when I call EnumDisplayDevicesA with 0 or 1 and returns 0 when I call with 2, so something is working, but the other values printed out below are the same - 0 in every case. Any advice is appreciated.

p_m21987
Posts: 120
Joined: Mon 02 Apr 2018, 21:51

Re: Screen dimensions

Post by p_m21987 » Tue 29 Jan 2019, 02:23

You should put code in tags when you post it on the forum.

Code: Select all

Like this

DDRM
Administrator
Posts: 110
Joined: Mon 02 Apr 2018, 18:04

Re: Screen dimensions

Post by DDRM » Tue 29 Jan 2019, 15:20

Hi Kendall,

Does this get you any further? I've modified your code a bit: notably
1) to put the value for cb% in the relevant structure element
2) To get the device name to print as an indirected string
3) For some reason the FOR i%...loop was throwing a "no such variable" error on the second monitor, so I have taken it out and hard-coded it.

Code: Select all

      DIMcb%4
      DIMdevicename%32
      DIMdevicestring%128
      DIMstateflags%4
      DIMdeviceid%128
      DIMdevicekey%128
      DIMdisplaydeviceA{cb%,devicename%,devicestring%,stateflags%,deviceid%,devicekey%}
      displaydeviceA.cb%=4+32+128+4+128+128

      SYS"EnumDisplayDevicesA",0,0,displaydeviceA{},1 TO success%

      PRINTsuccess%
      PRINT$$^displaydeviceA.devicename%
      PRINT $$^displaydeviceA.devicestring%
      PRINTdisplaydeviceA.deviceid%
      PRINTdisplaydeviceA.stateflags%
      PRINT

      SYS"EnumDisplayDevicesA",0,1,displaydeviceA{},1 TO success%

      PRINTsuccess%
      PRINT$$^displaydeviceA.devicename%
      PRINT $$^displaydeviceA.devicestring%
      PRINTdisplaydeviceA.deviceid%
      PRINTdisplaydeviceA.stateflags%
      PRINT

      END
With those changes I get different results from the two runs (encouragingly, the devicestrings read "DISPLAY1" and "DISPLAY2").

However, I'm not sure it gets you any closer to the info you need.

It looks like you might be able to do it using GetMonitorInfoA, but to do that you need to the handle of the monitor. You might be able to get that from MonitorFromWindow, if you put an output window (at least mostly) on the relevant monitor - is that possible? for example, if your accessory monitor is mapped to the left of the primary monitor, moving the BASIC window to a negative x coordinate with SetWindowPos?

Don't have time to play with this now, but if you can't get it to work, spell out how the monitors are arranged, and I'll have another think.

Best wishes,

D

Zaphod
Posts: 63
Joined: Sat 23 Jun 2018, 15:51

Re: Screen dimensions

Post by Zaphod » Tue 29 Jan 2019, 18:01

Not sure it gives any more information but I think that could be written a little more concisely using structures.

Code: Select all

            DISPLAY_DEVICE_ATTACHED_TO_DESKTOP=1
      DIM displaydeviceA{cb%,devicename&(31),devicestring&(127),stateflags%,deviceid&(127),devicekey&(127)}
      displaydeviceA.cb%=DIM(displaydeviceA{})
      DIM buf% 33
      REPEAT
        SYS"EnumDisplayDevicesA",0,I%,displaydeviceA{},1 TO success%
        I%+=1
        IF displaydeviceA.stateflags% AND DISPLAY_DEVICE_ATTACHED_TO_DESKTOP=1 THEN
          PRINT displaydeviceA.devicename&()
          PRINT displaydeviceA.devicestring&()
          PRINT displaydeviceA.stateflags%
          $$buf%=displaydeviceA.devicename&()
          SYS"EnumDisplayDevicesA",buf%,0,displaydeviceA{},1 TO success%
          PRINT displaydeviceA.devicestring&()
          PRINT
        ENDIF
      UNTIL success%=FALSE


Zaphod
Posts: 63
Joined: Sat 23 Jun 2018, 15:51

Re: Screen dimensions

Post by Zaphod » Sun 03 Feb 2019, 14:24

I had a play trying various ways to achieve what you were after but without success.
Win 32 calls to MonitorFromPoint always failed. Calls to MonitorFromRect always gave the handle of the primary monitor no mater what Rect coordinates were given. So I could never get a handle to the second monitor, which would allow me to determine its size, but even then I am not sure that would help.
I tried just writing a simple dialog to a position I knew was on the second monitor. It always put it the at the far edge of the primary rather than onto the secondary monitor.
Whether any of that is related to Windows 10 or the Nvidia drivers I can't say. Perhaps it was that I was running from the IDE that constrains things.
Edit: It relates to the way Windows works and it places things on the monitor that contains the primary window by default.
Z
Last edited by Zaphod on Sat 09 Feb 2019, 13:47, edited 1 time in total.

User avatar
hellomike
Posts: 17
Joined: Sat 09 Jun 2018, 09:47

Re: Screen dimensions

Post by hellomike » Tue 05 Feb 2019, 19:27

Hi,

Actually I don't understand how the modification done by DDRM does give a reasonable output and not a crash since the structure doesn't seem in the correct format.

DIM displaydeviceA{cb%,devicename%,devicestring%,stateflags%,deviceid%,devicekey%}

defines a structure of 4+4+4+4+4+4=24 bytes, while the call to the EnumDisplayDevicesA function expects a structure in memory of 4+32+128+4+128+128 bytes. Would the call not overwrite byte 5 - 23 (and beyond) with the actual characters in Device Name?

How come that after the SYS call like e.g.

^displaydeviceA.devicename%

points to a printable string?

I understand Zaphod's program and structure declaration but not the other.

Thanks

Mike

Post Reply