21

Is it possible to enable a second monitor programatically and extend the Windows Desktop onto it in C#? It needs to do the equivalent of turning on the checkbox in the image below.

alt text

4

5 回答 5

14

MSDN Device Context Functions

What you basically need to do:

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,

DISPLAY_DEVICE structure import using PInvoke

EnumDisplayDevices function import

EnumDisplaySettingsEx function import

etc. the rest of them functions can be found with a simple search by name.

于 2008-10-24T14:44:41.330 回答
12

If you have windows 7, then just start a process:

    private static Process DisplayChanger = new Process
    {
        StartInfo =
        {
            CreateNoWindow = true,
            WindowStyle = ProcessWindowStyle.Hidden,
            FileName = "DisplaySwitch.exe",
            Arguments = "/extend"
        }
    };

then DisplayChanger.Start();

于 2010-06-27T07:38:53.530 回答
2

I don't have the full answer here but I am almost sure that you will have to call out of .Net to do this. You will have to use Pinvoke to call an unmanaged dll. A great resource for this is pinvoke.net.

I did a quick search and found http://www.pinvoke.net/default.aspx/user32/ChangeDisplaySettings.html which probably isn't exactly what you want but you will probably find it somewhere on pinvoke.net

于 2008-10-24T13:46:16.190 回答
2

I am looking for the same solution. I have written the following code to call ChangeDisplaySettingsEx with PInvoke:

DEVMODE dm = new DEVMODE();
dm.dmSize = (short)Marshal.SizeOf(dm);
dm.dmPelsWidth = 1680;
dm.dmPelsHeight = 1050;
dm.dmBitsPerPel = 32;
dm.dmDisplayFrequency = 60;
dm.dmFields = DevModeFields.DM_BITSPERPEL | DevModeFields.DM_PELSWIDTH | 
              DevModeFields.DM_PELSHEIGHT | DevModeFields.DM_DISPLAYFREQUENCY;
int res = ChangeDisplaySettingsEx(@"\\.\DISPLAY2", ref dm, IntPtr.Zero, CDS_RESET | CDS_UPDATEREGISTRY, IntPtr.Zero);
Console.WriteLine("result = " + res.ToString());

If the monitor is already enabled, this changes the resolution successfully. But if the monitor isn't attached to the desktop already, this won't activate it. So does anyone have a code example that works?

于 2009-02-03T14:51:45.303 回答
1

To enable a monitor, set its position to something other than 0,0, like as shown:

POINTL enabledPosition = new POINTL();
enabledPosition.x = -1280;
enabledPosition.y = 0;

dm.dmPosition = enabledPosition;
dm.dmFields = DM.Position;
res = ChangeDisplaySettingsEx(d.DeviceName, ref dm, IntPtr.Zero, (uint) DeviceFlags.CDS_UPDATEREGISTRY, IntPtr.Zero);
于 2011-02-10T20:01:53.120 回答