current desktop?

Just starting out? Need help? Post your questions and find answers here.
Damion12
User
User
Posts: 81
Joined: Tue Oct 30, 2012 1:39 am

current desktop?

Post by Damion12 »

In a multi monitor environment, how can I tell which monitor (or desktop) is in use? (currently has input focus?)

related, but not the same:
How can I tell which monitor/desktop 'my application' is displayed in?

I can enumerate them but not determine the one a specific window (of my application) is on?

Something like: DesktopWindow( #win_Main )
User avatar
Lunasole
Addict
Addict
Posts: 1091
Joined: Mon Oct 26, 2015 2:55 am
Location: UA
Contact:

Re: current desktop?

Post by Lunasole »

Looks like you can't to this using PB built-in functions.

Try something like following using WinAPI:

Code: Select all

EnableExplicit

; Create window
Define mWnd = OpenWindow(#PB_Any, 0, 0, 100, 200, "")

; MonitorFromWindow returns handle to a display on which MOST of your window area is located
Define hCurrentDisplay =  MonitorFromWindow_(WindowID(mWnd), #MONITOR_DEFAULTTONEAREST)

; Getting info about that display
Define Display.MONITORINFO
Display\cbSize = SizeOf(MONITORINFO)
If GetMonitorInfo_(hCurrentDisplay, Display)
	Debug "Main part of your window located on some display with following resolution:"
	Debug Str(Display\rcMonitor\right - Display\rcMonitor\left) + "x" + Str(Display\rcMonitor\bottom - Display\rcMonitor\top)
EndIf
"W̷i̷s̷h̷i̷n̷g o̷n a s̷t̷a̷r"
Damion12
User
User
Posts: 81
Joined: Tue Oct 30, 2012 1:39 am

Re: current desktop?

Post by Damion12 »

but how can I tell which desktop that is? If I have 3 monitors and they are all the same resolution, can't tell which is which....
Hmm. I think I will be able to use this with rcMonitor and rcWork to determine which one it falls in.
thanks.
User avatar
ts-soft
Always Here
Always Here
Posts: 5756
Joined: Thu Jun 24, 2004 2:44 pm
Location: Berlin - Germany

Re: current desktop?

Post by ts-soft »

How can I tell which monitor/desktop 'my application' is displayed in?
Crossplattform!

Code: Select all

Procedure DesktopFromPoint(x, y)
  Protected Count = ExamineDesktops()
  Protected i, dx, dy, dw, dh
  
  For i = 0 To Count - 1
    dx = DesktopX(i)
    dy = DesktopY(i)
    dw = DesktopWidth(i)
    dh = DesktopHeight(i)

    If x >= dx And x <= dx + dw And y >= dy And y <= dy + dh
      ProcedureReturn i
    EndIf 
  Next i 
 
  ProcedureReturn -1 ; point is outside of all monitors
EndProcedure
PureBasic 5.73 | SpiderBasic 2.30 | Windows 10 Pro (x64) | Linux Mint 20.1 (x64)
Old bugs good, new bugs bad! Updates are evil: might fix old bugs and introduce no new ones.
Image
User avatar
Lunasole
Addict
Addict
Posts: 1091
Joined: Mon Oct 26, 2015 2:55 am
Location: UA
Contact:

Re: current desktop?

Post by Lunasole »

Damion12 wrote: Hmm. I think I will be able to use this with rcMonitor and rcWork to determine which one it falls in.
thanks.
Also returned monitor handle is different and unique for every display (hCurrentDisplay variable).
That handle probably can be used with other API to get misc monitor info (like vendor, etc), but I didn't tried go so far.

UPD: There is extended structure which also provides display string name, here modified example:

Code: Select all

EnableExplicit
; Create window and get moninor handle, where MOST of window area is located
Define mWnd = OpenWindow(#PB_Any, 0, 0, 100, 200, "")
Define hCurrentDisplay =  MonitorFromWindow_(WindowID(mWnd), #MONITOR_DEFAULTTONEAREST)

; Info about that display
Define Display.MONITORINFOEX
Display\szDevice = Space(#CCHDEVICENAME)
Display\cbSize = SizeOf(MONITORINFO) + #CCHDEVICENAME * SizeOf(Character) ; PB has incorrect MONITORINFOEX structure for unicode mode
If GetMonitorInfo_(hCurrentDisplay, Display)
	Debug "Main part of window is located on some display with following resolution: " + Str(Display\rcMonitor\right - Display\rcMonitor\left) + "x" + Str(Display\rcMonitor\bottom - Display\rcMonitor\top)
	Debug "Also display system name is: " + Display\szDevice
EndIf
"W̷i̷s̷h̷i̷n̷g o̷n a s̷t̷a̷r"
User avatar
TI-994A
Addict
Addict
Posts: 2751
Joined: Sat Feb 19, 2011 3:47 am
Location: Singapore
Contact:

Re: current desktop?

Post by TI-994A »

Damion12 wrote:...how can I tell which monitor (or desktop) is in use? (currently has input focus?)

...

How can I tell which monitor/desktop 'my application' is displayed in? ...
Technically, in a multi-monitor setup, all activated displays would have the "input focus".

This little cross-platform routine determines:
1. the main desktop
2. the mouse position
3. the desktop that the mouse is hovering on, and
4. the desktop that the app is positioned in

Code: Select all

;===========================================================
;
;   getDesktopInfo() returns various metrics
;   regarding the mouse, app, and desktops
;
;   tested & working with PureBasic v5.5 (x64) on:
;   - Windows 8.1 and Windows 10
;   - Mac OSX 10.7.5
;   - Windows XP SP3 with PureBasic v5.41 (x86)
;
;   by TI-994A - free to use, improve, share...
;
;   5th December 2016
;
;===========================================================

Structure desktop
  CompilerIf #PB_Compiler_OS = #PB_OS_Windows
    app.POINT
    mouse.POINT
  CompilerElseIf #PB_Compiler_OS = #PB_OS_MacOS
    app.CGPOINT
    mouse.CGPOINT  
  CompilerEndIf
  appDesktop.i
  mouseDesktop.i
  mainDesktop.i
  appWin.i
  desktop.i
EndStructure

;just drop this routine into any application (requires the desktop structure above)
;and simply poll the relevant elements to determine the required desktop metrics
;
Procedure getDesktopInfo(*ds.desktop)
  Protected desktops = ExamineDesktops()
  Protected i, dx, dy, dw, dh
  
  With *ds
    
    \mouse\x = DesktopMouseX()
    \mouse\y = DesktopMouseY()
    \app\x = WindowX(\appWin)
    \app\y = WindowY(\appWin)
    
    For i = 0 To desktops -1
      dx = DesktopX(i)
      dy = DesktopY(i)
      dw = DesktopWidth(i)
      dh = DesktopHeight(i)
      
      If \mouse\x >= dx And \mouse\x <= dx + dw And 
         \mouse\y >= dy And \mouse\y <= dy + dh
        \mouseDesktop = i
        If dx = 0 And dy = 0
          \mainDesktop = i
        EndIf
        If \app\x >= dx And \app\x <= dx + dw And 
           \app\y >= dy And \app\y <= dy + dh
          \appDesktop = i
        EndIf
        Break
      EndIf 
    Next i 
    
  EndWith
  
EndProcedure

;demo
;
desktop.desktop

LoadFont(0, "Arial", 16)
SetGadgetFont(#PB_Default, FontID(0)) 

wFlags = #PB_Window_SystemMenu | #PB_Window_ScreenCentered
mainWin = OpenWindow(#PB_Any, #PB_Ignore, #PB_Ignore, 
                     500, 300, "Active Desktops", wFlags)
desktopInfo = TextGadget(#PB_Any, 50, 50, 400, 50, "")
mousePos = TextGadget(#PB_Any, 50, 120, 400, 50, "")
appPos = TextGadget(#PB_Any, 50, 190, 400, 50, "")
AddWindowTimer(mainWin, 0, 100)

Repeat
  Select WaitWindowEvent()
    Case #PB_Event_CloseWindow
      appQuit = 1
      
    Default
      desktop\appWin = mainWin
      getDesktopInfo(@desktop)
      With desktop
        SetGadgetText(desktopInfo, "Desktop " + 
                                   Str(\mainDesktop) + " is the main desktop")
        SetGadgetText(mousePos, "The mouse is at " + Str(\mouse\x) + ", " + 
                                Str(\mouse\y) + " on desktop " + Str(\mouseDesktop))
        SetGadgetText(appPos, "The app is on desktop " + Str(\appDesktop))
      EndWith
  EndSelect
Until appQuit = 1
The timer induces a call through the event loop every 1/10th of a second to poll the mouse position when it's outside of the app window. This could also be achieved by setting the WaitWindowEvent() timeout value to the same.

Hope it helps! :wink:
Texas Instruments TI-99/4A Home Computer: the first home computer with a 16bit processor, crammed into an 8bit architecture. Great hardware - Poor design - Wonderful BASIC engine. And it could talk too! Please visit my YouTube Channel :D
Damion12
User
User
Posts: 81
Joined: Tue Oct 30, 2012 1:39 am

Re: current desktop?

Post by Damion12 »

Thanks ! I appreciate your help & code examples.
BarryG
Addict
Addict
Posts: 4219
Joined: Thu Apr 18, 2019 8:17 am

Re: current desktop?

Post by BarryG »

Damion12 wrote: Sat Dec 03, 2016 9:46 pmHow can I tell which monitor/desktop 'my application' is displayed in?
I had a similar problem, but I needed to know which monitor a third-party window (like Notepad) was in. I came up with this from Lunasole's code. Can someone check that it's correct? It appears to be. Thanks!

Code: Select all

hWnd=FindWindow_(0,"Untitled - Notepad")

hCurrentDisplay=MonitorFromWindow_(hWnd,#MONITOR_DEFAULTTONEAREST)

Display.MONITORINFO\cbSize=SizeOf(MONITORINFO)
If GetMonitorInfo_(hCurrentDisplay,Display)
  Debug "Main part of hWnd is in this monitor's area:"
  Debug "Monitor X = "+Str(Display\rcMonitor\left)
  Debug "Monitor Y = "+Str(Display\rcMonitor\top)
  Debug "Monitor W = "+Str(Display\rcMonitor\right-Display\rcMonitor\left)
  Debug "Monitor H = "+Str(Display\rcMonitor\bottom-Display\rcMonitor\top)
EndIf
User avatar
skywalk
Addict
Addict
Posts: 4242
Joined: Wed Dec 23, 2009 10:14 pm
Location: Boston, MA

Re: current desktop?

Post by skywalk »

This does not work for multiple monitors.
I get the same results no matter where Notepad resides.
The nice thing about standards is there are so many to choose from. ~ Andrew Tanenbaum
BarryG
Addict
Addict
Posts: 4219
Joined: Thu Apr 18, 2019 8:17 am

Re: current desktop?

Post by BarryG »

skywalk wrote: Mon Sep 16, 2024 2:35 pm This does not work for multiple monitors.
I get the same results no matter where Notepad resides.
What? I tested it with 3 monitors (in VirtualBox) and the X/Y/W/H values were different for all 3 monitors when Notepad was placed in each one.

So the debug output for you is the SAME no matter which monitor Notepad is in when you run it?
User avatar
skywalk
Addict
Addict
Posts: 4242
Joined: Wed Dec 23, 2009 10:14 pm
Location: Boston, MA

Re: current desktop?

Post by skywalk »

My bad, I thought FindWindow_() would catch "like" window captions.
The code works if exact 'Untitled - Notepad' window exists.
Else, no window is found and the debugs are all the same.
The nice thing about standards is there are so many to choose from. ~ Andrew Tanenbaum
BarryG
Addict
Addict
Posts: 4219
Joined: Thu Apr 18, 2019 8:17 am

Re: current desktop?

Post by BarryG »

skywalk wrote: Tue Sep 17, 2024 9:10 pmThe code works if exact 'Untitled - Notepad' window exists.
Yeah, that's what I meant. One single new Notepad that you open, put it in one monitor, run the code, see the output. Then move that same Notepad to the other monitors and do the same. All debug outputs should be different and show each monitor's X/Y/W/H attributes.
User avatar
idle
Always Here
Always Here
Posts: 6026
Joined: Fri Sep 21, 2007 5:52 am
Location: New Zealand

Re: current desktop?

Post by idle »

windows you can do this I suppose, I don't have multiple monitors anymore though

Code: Select all

Procedure getActiveDesktop() 
  
 Protected i, dx, dy, dw, dh,cx,cy 
 Protected  rc.rect, hwnd,count  
   
  hwnd = GetForegroundWindow_() 
  GetWindowRect_(hwnd,@rc) 
  cx = rc\right - rc\left 
  cy = rc\bottom - rc\top  
   
  count = ExamineDesktops() 
  
  For i = 0 To Count - 1
    dx = DesktopX(i)
    dy = DesktopY(i)
    dw = DesktopWidth(i)
    dh = DesktopHeight(i)
        
    If cx >= dx And cx <= dx + dw And cy >= dy And cy <= dy + dh
      ProcedureReturn i
    EndIf 
  Next i 
 
  ProcedureReturn -1 ; point is outside of all monitors
EndProcedure

For a = 0 To 10  

Debug getActiveDesktop() 

Delay(1000) 

Next 
BarryG
Addict
Addict
Posts: 4219
Joined: Thu Apr 18, 2019 8:17 am

Re: current desktop?

Post by BarryG »

Thanks, Idle. :)
Post Reply