Does anyone know how to detect the names of connected screens (e.g. “Built-in Retina Display”, or “Thunderbolt Display”)? I am currently referring to them in my app as “Display 1”, “Display 2”, etc., but I’d like to present the user with something more useful. I haven’t found anything in the MBS suite with this ability. Cheers.
And just for reference and for those who don’t want or can’t use a Plugin:
Dim sScreenLocalizedNames() As String
#If TargetMacOS Then
Declare Function NSClassFromString Lib "Foundation" (className As CFStringRef) As Ptr
Declare Function getScreens Lib "AppKit" selector "screens" (ptrToNSScreenClass As Ptr) As Ptr
Declare Function getLocalizedName Lib "AppKit" selector "localizedName" (ptrToNSScreenInstance As Ptr) As CFStringRef
Declare Function NSArrayCount Lib "Foundation" selector "count" (ptrToNSArray As Ptr) As UInteger
Declare Function NSArrayObjectAtIndex Lib "Foundation" selector "objectAtIndex:" (ptrToNSArray As Ptr, index As UInteger) As Ptr
Dim ptrNSScreenClass As Ptr = NSClassFromString("NSScreen")
Dim ptrScreensArray As Ptr = getScreens(ptrNSScreenClass)
Dim iScreensArrayCount As UInteger = NSArrayCount(ptrScreensArray)
For i As Integer = 0 To iScreensArrayCount - 1
Dim ptrToNSScreen As Ptr = NSArrayObjectAtIndex(ptrScreensArray, i)
sScreenLocalizedNames.Append(getLocalizedName(ptrToNSScreen))
Next
#EndIf
Me.Text = Join(sScreenLocalizedNames, ", ")
Note: This code is just to get an idea which Declares are involved. Could need more error checking.
Also the function localizedName
is macOS 10.15 or newer. I was looking for such a thing a couple of years ago and the amount of code required to this was a lot!
Thanks for the replies, that was exactly what I was looking for. I guess that I can live with it being Catalina and up, I’ll just default back to the old nomenclature for older systems. Cheers.
You should use [NSObject respondsToSelector:]
to figure out if it is supported, at least that is what Apple recommends you do as opposed to checking for the OS version.
#if targetMacOS and targetDesktop then
Dim s as integer = NSWindowScreen( self.handle )
if NSObjectRespondsToSelector( s, NSSelectorFromString( "localizedName" ) ) then
// --- Do thing with screen name
else
// --- Get screen name it the old long winded way.
end if
#elseif targetWindows then
// --- Do Windows thang...
#endIf
Good point. Luckily this is a macOS only utility, so less to worry about. Thanks Sam.
Not just to determine if this is running on a Mac or not, but also to determine that this function is available on a Mac.
In the recent years with Apple’s rabid pace of change, I have seen API that was only valid for one version of the OS, with it being deprecated the year after it was introduced.
I second the check for ability, as Sam’s thought is right in removing things.
This one uses CGDisplayMBS class and may work on older macOS versions:
Dim DisplayList() As CGDisplayMBS = CGDisplayMBS.GetActiveDisplayList()
For Each display As CGDisplayMBS In DisplayList
Dim dict As Dictionary = display.Info
Dim names As Dictionary = dict.Lookup( "DisplayProductName", Nil )
If names <> Nil Then
Dim name As String = names.Lookup("en_US", "?")
MsgBox name+" "+display.PixelsWide.ToString+"x"+display.PixelsHigh.ToString
end if
Next