Multiple screens/monitors

Just starting out? Need help? Post your questions and find answers here.
User avatar
Lunasole
Addict
Addict
Posts: 1091
Joined: Mon Oct 26, 2015 2:55 am
Location: UA
Contact:

Multiple screens/monitors

Post by Lunasole »

Hi, anyone here has experience of creating 2 different windows on 2 monitors?
Or some code for that ^^

If I'm not wrong generic schema is following:
- enumerate displays
- open each window on X, Y coordinate which corresponds to different monitors

But I have few questions to details (like "is first monitor of enumeration always one which is primary?" or "how it will work if windows opened in fullscreen mode?") and didn't have 2 monitors to check it all for sure
"W̷i̷s̷h̷i̷n̷g o̷n a s̷t̷a̷r"
User avatar
Thunder93
Addict
Addict
Posts: 1788
Joined: Tue Mar 21, 2006 12:31 am
Location: Canada

Re: Multiple screens/monitors

Post by Thunder93 »

If you using ExamineDesktops(), the first one is suppose to be the primary display. Therefore DesktopX() and DesktopY() should give information based on the index, for the specific monitor.
No other information yet.
ʽʽSuccess is almost totally dependent upon drive and persistence. The extra energy required to make another effort or try another approach is the secret of winning.ʾʾ --Dennis Waitley
citystate
Enthusiast
Enthusiast
Posts: 638
Joined: Sun Feb 12, 2006 10:06 pm

Re: Multiple screens/monitors

Post by citystate »

here's a quick and dirty bit of code to give you an idea

Code: Select all

n=ExamineDesktops()
For i=0 To n-1
  x=DesktopX(i)
  y=DesktopY(i)
  w=DesktopWidth(i)
  h=DesktopHeight(i)
  OpenWindow(i,x,y,w,h,"Desktop "+Str(i))
Next

Repeat
Until WaitWindowEvent()=#PB_Event_CloseWindow
there is no sig, only zuul (and the following disclaimer)

WARNING: may be talking out of his hat
User avatar
Lunasole
Addict
Addict
Posts: 1091
Joined: Mon Oct 26, 2015 2:55 am
Location: UA
Contact:

Re: Multiple screens/monitors

Post by Lunasole »

citystate wrote:here's a quick and dirty bit of code to give you an idea
So it will work fine even if OpenWindow used with #PB_Window_Maximize flag?
"W̷i̷s̷h̷i̷n̷g o̷n a s̷t̷a̷r"
User avatar
Thunder93
Addict
Addict
Posts: 1788
Joined: Tue Mar 21, 2006 12:31 am
Location: Canada

Re: Multiple screens/monitors

Post by Thunder93 »

Hi Lunasole. I've had some spare time, and accessibility of two displays. I don't know how far you've got into this but I had went into testing mode.

citystate example in such raw form will give some issues. The Window on the first screen will exceed onto the other screen. The height will go beyond, and so forth. The Window for the second screen will also be all wrong. With the use of the #PB_Window_Maximize flag, both opened Windows are also all wrong. Just giving you my observations.

I've made quickly three examples to have a look at. First one puts a square top-left, top-right, bottom-left, bottom-right of the screen edge, and exactly so for the secondary display using different colour squares.

The second example shows opening up the Windows in full screen, not maximized state. It requires little extra information to have it so for both displays.

The third example shows opening up with Windows in maximized state. Basically this example we don't even care (but we should normally) about the Window height and width, because it should anyways open up in maximized state and properly per display.


First Example:

Code: Select all


Procedure CreateWindow(WinID, x, y, iw, ih, backcolor)
  OpenWindow(WinID, x, y, iw, ih, "", #PB_Window_BorderLess)
  SetWindowColor(WinID, backcolor)
EndProcedure

Procedure.i EnumDisplayMonitorsProc(hMonitor.i, hDC.i, *rect.RECT, Userdata.i)
  Protected mi.MONITORINFOEX, RGB.i
  Protected.l BlockID1, BlockID2, BlockID3, BlockID4
  Static Count.b = 0
      
  If Count = 0
    RGB = RGB(255, 242, 5)
    BlockID1 = 01
    BlockID2 = 02
    BlockID3 = 03
    BlockID4 = 04
  ElseIf Count  = 1
    RGB = RGB(156, 255, 5)
    BlockID1 = 11
    BlockID2 = 12
    BlockID3 = 13
    BlockID4 = 14
  Else
    ProcedureReturn 0    
  EndIf
  

  mi\cbSize=SizeOf(MONITORINFOEX)
  
  GetMonitorInfo_(hMonitor, mi)
  
  Debug PeekS(@mi\szDevice)
  
  If (mi\dwFlags & #MONITORINFOF_PRIMARY) = #MONITORINFOF_PRIMARY
    Debug "  Primary Monitor: Yes"
  Else
    Debug "  Primary Monitor: No"
  EndIf
  
  Debug ""
  Debug "  Display-X: "+mi\rcMonitor\left
  Debug "  Display-Y: "+mi\rcMonitor\top
  Debug "  Display-Width: "+Str(mi\rcMonitor\right-mi\rcMonitor\left)
  Debug "  Display Height: "+Str(mi\rcMonitor\bottom-mi\rcMonitor\top)
  
  Debug ""
  Debug "  Working Area:"
  Debug "   Working-X: "+mi\rcWork\left
  Debug "   Working-Y: "+mi\rcWork\top
  Debug "   Working-Width: "+Str(mi\rcWork\right-mi\rcWork\left)
  Debug "   Working-Height: "+Str(mi\rcWork\bottom-mi\rcWork\top)
  Debug #CRLF$+#CRLF$

  
  ; Color Square Top-Left Corner
  CreateWindow(BlockID1, mi\rcMonitor\left, mi\rcMonitor\top, 30, 30, RGB)
  
  ; Color Square Top-Right Corner
  CreateWindow(BlockID2, mi\rcMonitor\right-30, mi\rcMonitor\top, 30, 30, RGB)
  
  ; Color Square Left-Bottom Corner
  CreateWindow(BlockID3, mi\rcMonitor\left, mi\rcMonitor\bottom-30, 30, 30, RGB)
  
  ; Color Square Right-Bottom Corner
  CreateWindow(BlockID4, mi\rcMonitor\right-30, mi\rcMonitor\bottom-30, 30, 30, RGB)
 
  Count+1
  ProcedureReturn #True
EndProcedure


Define.i hDC
hDC = GetDC_(#Null)
If hDC
  EnumDisplayMonitors_(hDC, #Null, @EnumDisplayMonitorsProc(), 0)
EndIf


Repeat
  Event = WindowEvent()  
Until Event = #PB_Event_CloseWindow

Second Example:

Code: Select all


Procedure CreateWindow(WinID, x, y, iw, ih, backcolor)
  OpenWindow(WinID, x, y, iw, ih, "", #PB_Window_SystemMenu)
  SetWindowColor(WinID, backcolor)
EndProcedure

Procedure.i EnumDisplayMonitorsProc(hMonitor.i, hDC.i, *rect.RECT, Userdata.i)
  Protected mi.MONITORINFOEX, RGB.i
  Protected.l WindowID
  Global.l CXDLGFRAME, CYDLGFRAME
  Static Count.b = 0
    
  If Count = 0
    RGB = RGB(255, 242, 5)
    WindowID = 01
  ElseIf Count  = 1
    RGB = RGB(156, 255, 5)
    WindowID = 11
  Else
    ProcedureReturn 0    
  EndIf
  

  mi\cbSize=SizeOf(MONITORINFOEX)
  
  GetMonitorInfo_(hMonitor, mi)
  
  Debug PeekS(@mi\szDevice)
  
  If (mi\dwFlags & #MONITORINFOF_PRIMARY) = #MONITORINFOF_PRIMARY
    Debug "  Primary Monitor: Yes"
  Else
    Debug "  Primary Monitor: No"
  EndIf
  
  Debug ""
  Debug "  Display-X: "+mi\rcMonitor\left
  Debug "  Display-Y: "+mi\rcMonitor\top
  Debug "  Display-Width: "+Str(mi\rcMonitor\right-mi\rcMonitor\left)
  Debug "  Display Height: "+Str(mi\rcMonitor\bottom-mi\rcMonitor\top)
  
  Debug ""
  Debug "  Working Area:"
  Debug "   Working-X: "+mi\rcWork\left
  Debug "   Working-Y: "+mi\rcWork\top
  Debug "   Working-Width: "+Str(mi\rcWork\right-mi\rcWork\left)
  Debug "   Working-Height: "+Str(mi\rcWork\bottom-mi\rcWork\top)
  Debug #CRLF$+#CRLF$

  
  CreateWindow(WindowID, mi\rcMonitor\left-CXDLGFRAME, mi\rcMonitor\top, mi\rcMonitor\right-mi\rcMonitor\left, mi\rcMonitor\bottom-CYDLGFRAME, RGB)

 
  Count+1
  ProcedureReturn #True
EndProcedure


Define.i hDC
hDC = GetDC_(#Null)
If hDC
   Global CXDLGFRAME.l = GetSystemMetrics_(#SM_CXDLGFRAME)
   Global CYDLGFRAME.l = GetSystemMetrics_(#SM_CYDLGFRAME)
   
  EnumDisplayMonitors_(hDC, #Null, @EnumDisplayMonitorsProc(), 0)
EndIf


Repeat
  Event = WindowEvent()  
Until Event = #PB_Event_CloseWindow

Third Example:

Code: Select all


Procedure CreateWindow(WinID, x, y, iw, ih, backcolor)
  OpenWindow(WinID, x, y, iw, ih, "", #PB_Window_SystemMenu|#PB_Window_MinimizeGadget|#PB_Window_MaximizeGadget|#PB_Window_Maximize)
  SetWindowColor(WinID, backcolor)
EndProcedure

Procedure.i EnumDisplayMonitorsProc(hMonitor.i, hDC.i, *rect.RECT, Userdata.i)
  Protected mi.MONITORINFOEX, RGB.i
  Protected.l WindowID
  Global.l CXDLGFRAME, CYDLGFRAME
  Static Count.b = 0
    
  If Count = 0
    RGB = RGB(255, 242, 5)
    WindowID = 01
  ElseIf Count  = 1
    RGB = RGB(156, 255, 5)
    WindowID = 11
  Else
    ProcedureReturn 0    
  EndIf
  

  mi\cbSize=SizeOf(MONITORINFOEX)
  
  GetMonitorInfo_(hMonitor, mi)
  
  Debug PeekS(@mi\szDevice)
  
  If (mi\dwFlags & #MONITORINFOF_PRIMARY) = #MONITORINFOF_PRIMARY
    Debug "  Primary Monitor: Yes"
  Else
    Debug "  Primary Monitor: No"
  EndIf
  
  Debug ""
  Debug "  Display-X: "+mi\rcMonitor\left
  Debug "  Display-Y: "+mi\rcMonitor\top
  Debug "  Display-Width: "+Str(mi\rcMonitor\right-mi\rcMonitor\left)
  Debug "  Display Height: "+Str(mi\rcMonitor\bottom-mi\rcMonitor\top)
  
  Debug ""
  Debug "  Working Area:"
  Debug "   Working-X: "+mi\rcWork\left
  Debug "   Working-Y: "+mi\rcWork\top
  Debug "   Working-Width: "+Str(mi\rcWork\right-mi\rcWork\left)
  Debug "   Working-Height: "+Str(mi\rcWork\bottom-mi\rcWork\top)
  Debug #CRLF$+#CRLF$
  
  CreateWindow(WindowID, mi\rcMonitor\left-CXDLGFRAME, mi\rcMonitor\top, 0, 0, RGB)

 
  Count+1
  ProcedureReturn #True
EndProcedure


Define.i hDC
hDC = GetDC_(#Null)
If hDC
   Global CXDLGFRAME.l = GetSystemMetrics_(#SM_CXDLGFRAME)
   Global CYDLGFRAME.l = GetSystemMetrics_(#SM_CYDLGFRAME)
   
  EnumDisplayMonitors_(hDC, #Null, @EnumDisplayMonitorsProc(), 0)
EndIf


Repeat
  Event = WindowEvent()  
Until Event = #PB_Event_CloseWindow
ʽʽSuccess is almost totally dependent upon drive and persistence. The extra energy required to make another effort or try another approach is the secret of winning.ʾʾ --Dennis Waitley
User avatar
Lunasole
Addict
Addict
Posts: 1091
Joined: Mon Oct 26, 2015 2:55 am
Location: UA
Contact:

Re: Multiple screens/monitors

Post by Lunasole »

@Thunder93, thanks for those researches ^^

I still have no 2nd monitor for tests (and actually don't need this right now, rather wanted to know how it can be done), but your examples looking nice and doing all OK
"W̷i̷s̷h̷i̷n̷g o̷n a s̷t̷a̷r"
User avatar
blueznl
PureBasic Expert
PureBasic Expert
Posts: 6161
Joined: Sat May 17, 2003 11:31 am
Contact:

Re: Multiple screens/monitors

Post by blueznl »

I've written a small wallpaper tool called WallX. If you take it apart you'll find some multi monitor code. Just search the forum for WallX. (Source included.)
( PB6.00 LTS Win11 x64 Asrock AB350 Pro4 Ryzen 5 3600 32GB GTX1060 6GB)
( The path to enlightenment and the PureBasic Survival Guide right here... )
User avatar
chi
Addict
Addict
Posts: 1028
Joined: Sat May 05, 2007 5:31 pm
Location: Linz, Austria

Re: Multiple screens/monitors

Post by chi »

Lunasole wrote:I still have no 2nd monitor for tests
That's pretty simple to emulate nowadays ;). Just install VirtualBox, setup the OS and choose more than one Monitor (don't forget to install the Extension Pack). If you have a Laptop sitting around somewhere, you could also use TightVNC...
Et cetera is my worst enemy
User avatar
Lunasole
Addict
Addict
Posts: 1091
Joined: Mon Oct 26, 2015 2:55 am
Location: UA
Contact:

Re: Multiple screens/monitors

Post by Lunasole »

chi wrote:That's pretty simple to emulate nowadays ;). Just install VirtualBox, setup the OS and choose more than one Monitor (don't forget to install the Extension Pack). If you have a Laptop sitting around somewhere, you could also use TightVNC...
Thanks, sounds like cool idea 8)
I already have Virtual Box 4, will try to change it to 2 displays (if that will be possible with 4)

blueznl wrote:I've written a small wallpaper tool called WallX. If you take it apart you'll find some multi monitor code. Just search the forum for WallX. (Source included.)
Thanks, I'll check this one (among with some other interesting stuff on your site^^)
"W̷i̷s̷h̷i̷n̷g o̷n a s̷t̷a̷r"
User avatar
Lunasole
Addict
Addict
Posts: 1091
Joined: Mon Oct 26, 2015 2:55 am
Location: UA
Contact:

Re: Multiple screens/monitors

Post by Lunasole »

@blueznl, I've found desktops-related code in your x_lib (from Codecaddy sources), seems that's all which is needed.
Btw really huge library ^^ Maybe it's largest than any other include lib in PB
"W̷i̷s̷h̷i̷n̷g o̷n a s̷t̷a̷r"
User avatar
blueznl
PureBasic Expert
PureBasic Expert
Posts: 6161
Joined: Sat May 17, 2003 11:31 am
Contact:

Re: Multiple screens/monitors

Post by blueznl »

I just hope it will be of any use to you :-)

Note: x_lib stuff is NOT multi threading safe.
( PB6.00 LTS Win11 x64 Asrock AB350 Pro4 Ryzen 5 3600 32GB GTX1060 6GB)
( The path to enlightenment and the PureBasic Survival Guide right here... )
BarryG
Addict
Addict
Posts: 3292
Joined: Thu Apr 18, 2019 8:17 am

Re: Multiple screens/monitors

Post by BarryG »

Thunder93 wrote: Tue Oct 24, 2017 1:33 amIf you using ExamineDesktops(), the first one is suppose to be the primary display.
The manual doesn't say that, though. See here for my test -> viewtopic.php?t=80521
Post Reply