Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

---> Display Settings APIs?

13 views
Skip to first unread message

Mark

unread,
Nov 30, 2003, 8:12:42 PM11/30/03
to
Anyone -

I am trying to write a little macro that will enable me to switch between
dual monitor mode on my laptop to single monitor mode on my laptop. The
scenario is focused around the user undocking from a dual monitor setup and
having to go to :

Desktop->RightClick->Properties->Settings->ClickOnSecondMonitor->Check(orUnC
heck)'ExtendmyWindowsDesktopOntoThisMonitor"->OK

This is very annoying since a lot of my users dock and undock miltiple times
a day and have the dual monitor setup. Is there an API that I can call to to
the above manual setting programmatically?

Sample code or a pointer to a reference would be great. Please help.

Thanks,
Mark


Mike D Sutton

unread,
Nov 30, 2003, 9:25:41 PM11/30/03
to

Use the EnumDisplayDevices() API call to enumerate the display devices on the system and look for those that don't have the
DISPLAY_DEVICE_ATTACHED_TO_DESKTOP flag set (this will include any mirroring devices so not all will be physical displays.)
Once you've found the display device you'll need to get a valid display mode to change it to, you can find this by calling the
EnumDisplaySettingsEx() API call - Generally you'd display all the available modes and allow the user to choose however in your case
it sounds like this may be possible to hard-code and save you an additional step. For the sake of future-proofing your application
though I'd suggest having this easily changeable without having to dig through the source every time, a registry key would be the
obvious choice.
Once you've got that sorted out populate a DevMode display structure with the information about the display positioning (set the
PelsWidth/Height, Position, DisplayFrequency and BitsPerPel properties) then set these flags in the fields member. Finally call
ChangeDisplaySettingsEx() with this settings structure and be sure to send the reset and update registry flags.
That should be all you need, hope this helps,

Mike


- Microsoft Visual Basic MVP -
E-Mail: ED...@mvps.org
WWW: Http://www.mvps.org/EDais/


Mike D Sutton

unread,
Nov 30, 2003, 11:40:47 PM11/30/03
to
Hi Mark,
Try and keep this kind of thing on the groups so everyone benefits. If your query is confidential in nature then you're welcome
to e-mail me directly but otherwise the groups are a preferable medium and are also archived, which creates a great information
resources for this kind of thing!

> Thank you for this information. I am pretty new to VB and wanted to ask you
> some more details about the implemnetaion. I am currentl writting this as
> the onClick action in excel, but am planning to move it out into it's own
> vbs file that can executed when the icon is clicked. Is there a better way
> to develop?

For development practices in Excel you'd probably be best off posting to an Excel VBA group.

> * With regards to that API, do I need to include some library to call it?

You need the API declarations for the functions, here's the one's mentioned if you need any others then either port them from the
platform SDK headers or take a look over on www.allapi.net (I actually recommend the former, you get a far better idea of what's
going on that way, in either case a good read through the multi-monitor second on the MSDN is worthwhile):

'***
Private Declare Function EnumDisplayDevices Lib "User32.dll" _
Alias "EnumDisplayDevicesA" (ByVal lpDevice As String, _
ByVal iDevNum As Long, ByRef lpDisplayDevice As Display_Device, _
ByVal dwFlags As Long) As Long
Private Declare Function EnumDisplaySettingsEx Lib "User32.dll" _
Alias "EnumDisplaySettingsExA" (ByVal lpszDeviceName As String, _
ByVal iModeNum As Long, ByRef lpDevMode As DevMode, _
ByVal dwFlags As Long) As Long
Private Declare Function ChangeDisplaySettingsEx Lib "User32.dll" _
Alias "ChangeDisplaySettingsExA" (ByVal lpszDeviceName As String, _
ByRef lpDevMode As DevMode, ByVal hWnd As Long, _
ByVal dwFlags As Long, ByRef lParam As Any) As Long

Private Const CCHDEVICENAME As Long = 32
Private Const CCHFORMNAME As Long = 32

Private Type Display_Device
cb As Long
DeviceName As String * 32
DeviceString As String * 128
StateFlags As Long
DeviceID As String * 128
DeviceKey As String * 128
End Type

Private Type PointL
X As Long
Y As Long
End Type

Private Type DevMode
dmDeviceName As String * CCHDEVICENAME
dmSpecVersion As Integer
dmDriverVersion As Integer
dmSize As Integer
dmDriverExtra As Integer
dmFields As Long
dmPosition As PointL
dmDisplayOrientation As Long
dmDisplayFixedOutput As Long
dmColor As Integer
dmDuplex As Integer
dmYResolution As Integer
dmTTOption As Integer
dmCollate As Integer
dmFormName(CCHFORMNAME - 1) As Byte
dmLogPixels As Integer
dmBitsPerPel As Long
dmPelsWidth As Long
dmPelsHeight As Long
dmDisplayFlags As Long
dmDisplayFrequency As Long
End Type

Private Const DISPLAY_DEVICE_ATTACHED_TO_DESKTOP As Long = &H1

Private Const DM_POSITION As Long = &H20
Private Const DM_BITSPERPEL As Long = &H40000
Private Const DM_PELSWIDTH As Long = &H80000
Private Const DM_PELSHEIGHT As Long = &H100000
Private Const DM_DISPLAYFLAGS As Long = &H200000
Private Const DM_DISPLAYFREQUENCY As Long = &H400000

Private Const CDS_UPDATEREGISTRY As Long = &H1
Private Const CDS_RESET As Long = &H40000000
'***

> * after enumerating the devices, do I need to store it in some array so that
> I can read the settings?

You can if you want to but it's really an optional step, you could most likely put the display change in the device enumeration
itself since changing the display mode of a device wouldn't affect the system's device count.

> or is there a more general way of doing this in vb?

In general cases a Collection object is an easy way of storing multiple bits of data, however since a UDT cannot be cast to a
Variant (the collection's storage method) it's not applicable in this case, so no.

> * What do you mean by "populate DevMode display structure"?

Set the members of the device/display mode structure, i.e:

'***
Dim DispMode As DevMode

With DispMode ' Assuming structure contains valid display mode
.dmSize = Len(DispMode)
.dmPosition.X = 0
.dmPosition.Y = 0
.dmFields = _
DM_POSITION Or DM_BITSPERPEL Or _
DM_PELSWIDTH Or DM_PELSHEIGHT Or _
DM_DISPLAYFLAGS Or DM_DISPLAYFREQUENCY
End With
'***

> * Doesn't seem that the api you referred to can control the "Extend Windows
> Desktop onto this monitor"? Am I wrong?

Unfortunately the documentation isn't very clear on this topic, however by setting a valid position and display mode it will AFAIK
be enabled and attached to the desktop. If anyone can confirm this or knows different then please post back here, unfortunately I
don't have time to do much testing of this right now.
Hope this helps,

0 new messages