I've found nice examples using C++ (http://www.codeproject.com/KB/tips/resswitch.aspx), but not in C#.
Can someone help, please?
Edit:
The exact function that list the video modes is:
BOOL CVideoModes::GetAvailableVideoModes(CAvailableVideoModes& modes)
{
modes.SetSize(0, 5);
int i=0;
DEVMODE dm;
while (EnumDisplaySettings(NULL, i, &dm))
{
CVideoMode thismode(dm.dmBitsPerPel, dm.dmPelsWidth,
dm.dmPelsHeight, dm.dmDisplayFrequency);
modes.SetAtGrow(i, thismode);
++i;
}
modes.FreeExtra();
return (i>0);
}
But sincerelly I cannot understand that C++ code. Where I can find that "thismode" function?
If you mean video modes are available resolutions, try to invoke EnumDisplaySettingsEx
details can be found here:
http://msdn.microsoft.com/en-us/library/dd162612(VS.85).aspx
small program that lists available resolutions:
using System;
using System.Linq;
using System.Runtime.InteropServices;
using System.Windows.Forms;
namespace ListResolutions
{
class Program
{
[DllImport("user32.dll")]
public static extern bool EnumDisplaySettings(
string deviceName, int modeNum, ref DEVMODE devMode);
const int ENUM_CURRENT_SETTINGS = -1;
const int ENUM_REGISTRY_SETTINGS = -2;
[StructLayout(LayoutKind.Sequential)]
public struct DEVMODE
{
private const int CCHDEVICENAME = 0x20;
private const int CCHFORMNAME = 0x20;
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 0x20)]
public string dmDeviceName;
public short dmSpecVersion;
public short dmDriverVersion;
public short dmSize;
public short dmDriverExtra;
public int dmFields;
public int dmPositionX;
public int dmPositionY;
public ScreenOrientation dmDisplayOrientation;
public int dmDisplayFixedOutput;
public short dmColor;
public short dmDuplex;
public short dmYResolution;
public short dmTTOption;
public short dmCollate;
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 0x20)]
public string dmFormName;
public short dmLogPixels;
public int dmBitsPerPel;
public int dmPelsWidth;
public int dmPelsHeight;
public int dmDisplayFlags;
public int dmDisplayFrequency;
public int dmICMMethod;
public int dmICMIntent;
public int dmMediaType;
public int dmDitherType;
public int dmReserved1;
public int dmReserved2;
public int dmPanningWidth;
public int dmPanningHeight;
}
static void Main(string[] args)
{
DEVMODE vDevMode = new DEVMODE();
int i = 0;
while (EnumDisplaySettings(null, i, ref vDevMode))
{
Console.WriteLine("Width:{0} Height:{1} Color:{2} Frequency:{3}",
vDevMode.dmPelsWidth,
vDevMode.dmPelsHeight,
1 << vDevMode.dmBitsPerPel, vDevMode.dmDisplayFrequency
);
i++;
}
}
}
}
Related
I'm trying to use win32 EnumDisplaySettings to get all available resolutions and refresh rates. But when printing dmDisplayFrequency I always get 0 which means that it cannot get it. Is there any alternatives to enumDisplaySettings ? If windows is able to provide a list in display setting window then there must be another way ?
using System;
using System.Linq;
using System.Runtime.InteropServices;
namespace ListResolutions
{
class Program
{
[DllImport("user32.dll")]
public static extern bool EnumDisplaySettings(
string deviceName, int modeNum, ref DEVMODE devMode);
const int ENUM_CURRENT_SETTINGS = -1;
const int ENUM_REGISTRY_SETTINGS = -2;
[StructLayout(LayoutKind.Sequential)]
public struct DEVMODE
{
private const int CCHDEVICENAME = 0x20;
private const int CCHFORMNAME = 0x20;
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 0x20)]
public string dmDeviceName;
public short dmSpecVersion;
public short dmDriverVersion;
public short dmSize;
public short dmDriverExtra;
public int dmFields;
public int dmPositionX;
public int dmPositionY;
public int dmDisplayFixedOutput;
public short dmColor;
public short dmDuplex;
public short dmYResolution;
public short dmTTOption;
public short dmCollate;
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 0x20)]
public string dmFormName;
public short dmLogPixels;
public int dmBitsPerPel;
public int dmPelsWidth;
public int dmPelsHeight;
public int dmDisplayFlags;
public int dmDisplayFrequency;
public int dmICMMethod;
public int dmICMIntent;
public int dmMediaType;
public int dmDitherType;
public int dmReserved1;
public int dmReserved2;
public int dmPanningWidth;
public int dmPanningHeight;
}
static void Main(string[] args)
{
DEVMODE vDevMode = new DEVMODE();
int i = 0;
while (EnumDisplaySettings(null, i, ref vDevMode))
{
Console.WriteLine("Width:{0} Height:{1} Color:{2} Frequency:{3}",
vDevMode.dmPelsWidth,
vDevMode.dmPelsHeight,
1 << vDevMode.dmBitsPerPel, vDevMode.dmDisplayFrequency
);
i++;
}
}
}
}
I have error in this code:
intPtr = Marshal.AllocHGlobal(Marshal.SizeOf<Win32API.OBJECT_BASIC_INFORMATION>(object_BASIC_INFORMATION));
Win32API.NtQueryObject(zero, 0, intPtr, Marshal.SizeOf<Win32API.OBJECT_BASIC_INFORMATION>(object_BASIC_INFORMATION), ref num);
object_BASIC_INFORMATION = (Win32API.OBJECT_BASIC_INFORMATION)Marshal.PtrToStructure(intPtr, object_BASIC_INFORMATION.GetType());
Marshal.FreeHGlobal(intPtr);
intPtr2 = Marshal.AllocHGlobal(object_BASIC_INFORMATION.TypeInformationLength);
num = object_BASIC_INFORMATION.TypeInformationLength;
This line:
intPtr = Marshal.AllocHGlobal(Marshal.SizeOf<Win32API.OBJECT_BASIC_INFORMATION>(object_BASIC_INFORMATION));
What am I doing wrong?
OBJECT_BASIC_INFORMATION:
public struct OBJECT_BASIC_INFORMATION
{
public int Attributes;
public int GrantedAccess;
public int HandleCount;
public int PointerCount;
public int PagedPoolUsage;
public int NonPagedPoolUsage;
public int Reserved1;
public int Reserved2;
public int Reserved3;
public int NameInformationLength;
public int TypeInformationLength;
public int SecurityDescriptorLength;
public System.Runtime.InteropServices.ComTypes.FILETIME CreateTime;
}
Error:
CS0308 C# The non-generic method cannot be used with type arguments
I have the below code to change my 2nd display screen resolution. It all works fine and changes as expected. However once it has been changed my mouse/cursor is offset. eg the active location is not where the pointer shows on the screen.
Thoughts?
using System;
using System.Windows;
using System.Runtime.InteropServices;
using System.Windows.Forms;
using System.Drawing;
[StructLayout(LayoutKind.Sequential)]
public struct DEVMODE1
{
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 32)]
public string dmDeviceName;
public short dmSpecVersion;
public short dmDriverVersion;
public short dmSize;
public short dmDriverExtra;
public int dmFields;
public short dmOrientation;
public short dmPaperSize;
public short dmPaperLength;
public short dmPaperWidth;
public short dmScale;
public short dmCopies;
public short dmDefaultSource;
public short dmPrintQuality;
public short dmColor;
public short dmDuplex;
public short dmYResolution;
public short dmTTOption;
public short dmCollate;
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 32)]
public string dmFormName;
public short dmLogPixels;
public short dmBitsPerPel;
public int dmPelsWidth;
public int dmPelsHeight;
public int dmPosition;
public int dmDisplayFlags;
public int dmDisplayFrequency;
public int dmICMMethod;
public int dmICMIntent;
public int dmMediaType;
public int dmDitherType;
public int dmReserved1;
public int dmReserved2;
public int dmPanningWidth;
public int dmPanningHeight;
};
class User_32
{
[DllImport("user32.dll")]
public static extern int EnumDisplaySettings(string deviceName, int modeNum, ref DEVMODE1 devMode);
[DllImport("user32.dll")]
public static extern int ChangeDisplaySettings(ref DEVMODE1 devMode, int flags);
[DllImport("user32.dll")]
public static extern int ChangeDisplaySettingsEx(string lpszDeviceName, ref DEVMODE1 lpDevMode, IntPtr hwnd, ChangeDisplaySettingsFlags dwflags, IntPtr lParam);
public const int ENUM_CURRENT_SETTINGS = -1;
public const int CDS_UPDATEREGISTRY = 0x01;
public const int CDS_TEST = 0x02;
public const int DISP_CHANGE_SUCCESSFUL = 0;
public const int DISP_CHANGE_RESTART = 1;
public const int DISP_CHANGE_FAILED = -1;
[Flags()]
public enum ChangeDisplaySettingsFlags : uint{
CDS_NONE = 0,
CDS_UPDATEREGISTRY = 0x00000001,
CDS_TEST = 0x00000002,
CDS_FULLSCREEN = 0x00000004,
CDS_GLOBAL = 0x00000008,
CDS_SET_PRIMARY = 0x00000010,
CDS_VIDEOPARAMETERS = 0x00000020,
CDS_ENABLE_UNSAFE_MODES = 0x00000100,
CDS_DISABLE_UNSAFE_MODES = 0x00000200,
CDS_RESET = 0x40000000,
CDS_RESET_EX = 0x20000000,
CDS_NORESET = 0x10000000
}
}
namespace Resolution
{
class CResolution
{
public CResolution(int iWidth, int iHeight)
{
DEVMODE1 dm = new DEVMODE1();
dm.dmFormName = new String(new char[32]);
dm.dmSize = (short)Marshal.SizeOf(dm);
dm.dmPosition = 2;
if (0 != User_32.EnumDisplaySettings(null, User_32.ENUM_CURRENT_SETTINGS, ref dm))
{
dm.dmPelsWidth = iWidth;
dm.dmPelsHeight = iHeight;
long result = User_32.ChangeDisplaySettingsEx("\\\\.\\DISPLAY2", ref dm, IntPtr.Zero, User_32.ChangeDisplaySettingsFlags.CDS_UPDATEREGISTRY, IntPtr.Zero);
}
}
}
}
-
static void Main(string[] args)
{
Resolution.CResolution ChangeRes = new Resolution.CResolution(2560, 1600);
}
I can switch between Landsacpe and Portrait mode in one screen by using the following code (That I have done this morning). And the problem is I have two screens in a computer. And I want the screen 1 is LANDSCAPE mode, and the screen 2 is PORTRAIT mode. But I don't know how to modify the code to make it work. (Sorry about my English)
class ModeSetting
{
public const int LANDSCAPE = 0;
public const int PORTRAIT = 1;
public static bool ChangeMode(int screenID, int modeID)
{
//I'm not using screenID here. Let me know how to do that. How to get screenID
//Or anything that help me.
DEVMODE dm = new DEVMODE();
dm.dmDeviceName = new string(new char[32]);
dm.dmFormName = new string(new char[32]);
//dm.dmSize = Marshal.SizeOf(dm);
if (modeID != PORTRAIT) modeID = LANDSCAPE;
if (0 != NativeMethods.EnumDisplaySettings(
null,
NativeMethods.ENUM_CURRENT_SETTINGS,
ref dm))
{
int temp = dm.dmPelsHeight;
dm.dmPelsHeight = dm.dmPelsWidth;
dm.dmPelsWidth = temp;
dm.dmDisplayOrientation = modeID;
int iRet = NativeMethods.ChangeDisplaySettings(ref dm, 0);
Console.WriteLine(iRet);
if (NativeMethods.DISP_CHANGE_SUCCESSFUL != iRet)
{
return false;
}
return true;
}
return false;
}
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi)]
public struct DEVMODE
{
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 32)]
public string dmDeviceName;
public short dmSpecVersion;
public short dmDriverVersion;
public short dmSize;
public short dmDriverExtra;
public int dmFields;
public int dmPositionX;
public int dmPositionY;
public int dmDisplayOrientation;
public int dmDisplayFixedOutput;
public short dmColor;
public short dmDuplex;
public short dmYResolution;
public short dmTTOption;
public short dmCollate;
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 32)]
public string dmFormName;
public short dmLogPixels;
public short dmBitsPerPel;
public int dmPelsWidth;
public int dmPelsHeight;
public int dmDisplayFlags;
public int dmDisplayFrequency;
public int dmICMMethod;
public int dmICMIntent;
public int dmMediaType;
public int dmDitherType;
public int dmReserved1;
public int dmReserved2;
public int dmPanningWidth;
public int dmPanningHeight;
}
internal class NativeMethods
{
// PInvoke declaration for EnumDisplaySettings Win32 API
[DllImport("user32.dll", CharSet = CharSet.Ansi)]
public static extern int EnumDisplaySettings(
string lpszDeviceName,
int iModeNum,
ref DEVMODE lpDevMode);
// PInvoke declaration for ChangeDisplaySettings Win32 API
[DllImport("user32.dll", CharSet = CharSet.Ansi)]
public static extern int ChangeDisplaySettings(
ref DEVMODE lpDevMode,
int dwFlags);
// constants
public const int ENUM_CURRENT_SETTINGS = -1;
public const int DMDO_DEFAULT = 0;
public const int DMDO_90 = 1;
public const int DMDO_180 = 2;
public const int DMDO_270 = 3;
public const int DISP_CHANGE_SUCCESSFUL = 0;
}
}
And I can switch between LANDSCAPE and PORTRAIT mode by using:
ModeSetting.ChangeMode(0, ModeSetting.LANDSCAPE);//0 here is screen ID that I cannot do when two screens
ModeSetting.ChangeMode(0, ModeSetting.PORTRAIT);
How can I get the supported screen resolutions in XNA? Like when you change the screen resolution in windows, and instead of giving you a list of all the possible choices, it gives you just a few of them.
Just use this:
foreach (DisplayMode mode in GraphicsAdapter.DefaultAdapter.SupportedDisplayModes) {
//mode.whatever (and use any of avaliable information)
}
But it will give you few duplicates, because it also takes into accound refrash rate, so you might include that aswel, or do some filtering.
I'm not that up-to-date with XNA, but I didn't think there was a quick and easy function. There is a way using the old WinForms API, but as I personally don't want to link against that in other applications the easiest way is to use the native functions.
First, define the native struct that will be used:
[StructLayout(LayoutKind.Sequential)]
internal struct DEVMODE
{
private const int CCHDEVICENAME = 0x20;
private const int CCHFORMNAME = 0x20;
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 0x20)]
public string dmDeviceName;
public short dmSpecVersion;
public short dmDriverVersion;
public short dmSize;
public short dmDriverExtra;
public int dmFields;
public int dmPositionX;
public int dmPositionY;
public int dmDisplayOrientation;
public int dmDisplayFixedOutput;
public short dmColor;
public short dmDuplex;
public short dmYResolution;
public short dmTTOption;
public short dmCollate;
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 0x20)]
public string dmFormName;
public short dmLogPixels;
public int dmBitsPerPel;
public int dmPelsWidth;
public int dmPelsHeight;
public int dmDisplayFlags;
public int dmDisplayFrequency;
public int dmICMMethod;
public int dmICMIntent;
public int dmMediaType;
public int dmDitherType;
public int dmReserved1;
public int dmReserved2;
public int dmPanningWidth;
public int dmPanningHeight;
}
We also need to define the two native functions we will use:
[DllImport("user32.dll")]
private static extern bool EnumDisplaySettings(string lpszDeviceName, int iModeNum, ref DEVMODE lpDevMode);
[DllImport("user32.dll")]
private static extern int GetSystemMetrics(int nIndex);
And last, our functions to list all screen resolutions and one to get the current screen resolution:
public static List<string> GetScreenResolutions()
{
var resolutions = new List<string>();
try
{
var devMode = new DEVMODE();
int i = 0;
while (EnumDisplaySettings(null, i, ref devMode))
{
resolutions.Add(string.Format("{0}x{1}", devMode.dmPelsWidth, devMode.dmPelsHeight));
i++;
}
resolutions = resolutions.Distinct(StringComparer.InvariantCulture).ToList();
}
catch (Exception ex)
{
Console.WriteLine("Could not get screen resolutions.");
}
return resolutions;
}
public static string GetCurrentScreenResolution()
{
int width = GetSystemMetrics(0x00);
int height = GetSystemMetrics(0x01);
return string.Format("{0}x{1}", width, height);
}