In some cases, the application needs to change the screen direction, because some features are designed to run best in a specific mode. One example is "Slide Show" in Microsoft Office PowerPoint: PowerPoint runs in horizontal mode. Even if you are using tablet PC in portrait mode, the application switches to the horizontal direction when you start a slide show. When the user ends the slide show, PowerPoint switches back to the original settings.
You can use two Win32 APIs to change the display settings. Each API has a pointer to the devmode structure, which contains all information related to the display settings:
Use enumdisplaysettings to read the current display settings and enumerate all supported display settings.
Use changedisplaysettings to switch to the new display settings.
Get current display settings
To obtain the current display settings, pass the enum_current_settings constant in the imodenum parameter to the enumdisplaysettings API, as shown in the following C ++ code.
Devmode DM; <br/> // initialize the devmode structure <br/> zeromemory (& DM, sizeof (DM); <br/> DM. dmsize = sizeof (DM); </P> <p> If (0! = Enumdisplaysettings (null, enum_current_settings, & DM )) <br/> {<br/> // inspect the devmode structure to obtain details <br/> // about the display settings such as <br/> //-orientation <br //> //-width and height <br/> //-frequency <br/> //-etc. <br/>}< br/>
Enumerate all supported display settings
To enumerate all display settings supported by the current display device, pass 0 in the imodenum parameter to the enumdisplaysettings API, and then call it with an increasing imodenum value until the function returns zero, see the following C ++ code.
Int Index = 0; <br/> devmode DM; <br/> // initialize the devmode structure <br/> zeromemory (& DM, sizeof (DM )); <br/> DM. dmsize = sizeof (DM); </P> <p> while (0! = Enumdisplaysettings (null, index ++, & DM )) <br/> {<br/> // inspect the devmode structure to obtain details <br/> // about the display settings such as <br/> //-orientation <br //> //-width and height <br/> //-frequency <br/> //-etc. <br/>}
Change display settings
To change the display settings, pass the pointer pointing to the valid devmode structure to the changedisplaysettings API. The following C ++ code shows how to rotate the screen 90 degrees clockwise. Note that this code only applies to devices that support corresponding display settings. It is important to follow the changedisplaysettings API returned values because some operations require a computer restart to work in graphic mode.
Devmode DM; <br/> // initialize the devmode structure <br/> zeromemory (& DM, sizeof (DM); <br/> DM. dmsize = sizeof (DM); </P> <p> If (0! = Enumdisplaysettings (null, enum_current_settings, & DM) <br/>{< br/> // swap height and width <br/> DWORD dwtemp = DM. dmpelsheight; <br/> DM. dmpelsheight = DM. dmpelswidth; <br/> DM. dmpelswidth = dwtemp; </P> <p> // determine new Orientaion <br/> switch (DM. dmdisplayorientation) <br/>{< br/> case dmdo_default: <br/> DM. dmdisplayorientation = dmdo_270; <br/> break; <br/> case dmdo_270: <br/> DM. dmdis Playorientation = dmdo_180; <br/> break; <br/> case dmdo_180: <br/> DM. dmdisplayorientation = dmdo_90; <br/> break; <br/> case dmdo_90: <br/> DM. dmdisplayorientation = dmdo_default; <br/> break; <br/> default: <br/> // unknown orientation value <br/> // Add Exception Handling here <br/> break; <br/>}< br/> long LRET = changedisplaysettings (& DM, 0); <br/> If (disp_change_successful! = LRET) <br/>{< br/> // Add Exception Handling here <br/>}< br/>}
Get and change display settings in managed code
Ing API
To change the display settings in managed code, you must use the platform call service (pinvoke) to call the enumdisplaysettings and changedisplaysettings APIs. In this regard, a good way is to create a class named nativemethods, which can publish public static methods that encapsulate these Apis. This class should contain all the necessary constant definitions for the API. The following code example demonstrates this practice. The complete implementation of this class can be found in the nativemethods. CS file, which is part of the sample application.
Using system. runtime. interopservices; <br/>... <br/> public class nativemethods <br/> {<br/> // pinvoke Declaration for enumdisplaysettings Win32 API <br/> [dllimport ("user32.dll", charset = charset. ANSI)] <br/> Public static extern int enumdisplaysettings (<br/> string lpszdevicename, <br/> int imodenum, <br/> ref devmode lpdevmode ); </P> <p> // pinvoke Declaration for changedisplaysettings Win32 API <br /> [Dllimport ("user32.dll, charset = charset. ANSI ")] <br/> Public static extern int changedisplaysettings (<br/> ref devmode lpdevmode, <br/> int dwflags ); </P> <p> // Add more functions as needed ?? </P> <p> // constants <br/> Public const int enum_current_settings =-1; <br/> Public const int dmdo_default = 0; <br/> Public const int dmdo_90 = 1; <br/> Public const int dmdo_180 = 2; <br/> Public const int dmdo_270 = 3; <br/> // Add more constants as needed ?? <Br/>}
Deving devmode Structure
When you map a devmode structure to a managed structure, pay attention to the following issues:
Because the devmode structure contains union, we must select the members we need.
Arrays mapped to strings in. NET Framework must be enclosed as strings of the same size.
For simplicity, You can flatten the nested structure (for example, replace the pointl structure with two hosted int types .)
[Structlayout (layoutkind. sequential, charset = charset. ANSI)] <br/> public struct devmode <br/> {<br/> [financialas (unmanagedtype. byvaltstr, sizeconst = 32)] <br/> Public String dmdevicename; </P> <p> Public short dmspecversion; <br/> Public short dmdriverversion; <br/> Public short dmsize; <br/> Public short dmdriverextra; <br/> Public int dmfields; <br/> Public int dmpositionx; <br/> Public int dmpositiony; <br/> Public int dmdisplayorientation; <br/> Public int dmdisplayfixedoutput; <br/> Public short dmcolor; <br/> Public short dmduplex; <br/> Public short dmyresolution; <br/> Public short dmttoption; <br/> Public short dmcollate; </P> <p> [managed Alas (unmanagedtype. byvaltstr, sizeconst = 32)] <br/> Public String dmformname; </P> <p> Public short dmlogpixels; <br/> Public short dmbitsperpel; <br/> Public int dmpelswidth; <br/> Public int dmpelsheight; <br/> Public int dmdisplayflags; <br/> Public int dmdisplayfrequency; <br/> Public int dmic1_hod; <br/> Public int dmicmintent; <br/> Public int dmmediatype; <br/> Public int dmdithertype; <br/> Public int dmreserved1; <br/> Public int dmreserved2; <br/> Public int dmpanningwidth; <br/> Public int dmpanningheight; <br/> };
When initializing a new instance with the devmode structure in. NET Framework, make sure that the dmdevicename, dmformname, and dmsize values are set properly. To this end, I added the following method to the nativemethods class of the sample application:
Public static devmode createdevmode () <br/>{< br/> devmode dm = new devmode (); <br/> DM. dmdevicename = new string (New char [32]); <br/> DM. dmformname = new string (New char [32]); <br/> DM. dmsize = (short) Marshal. sizeof (DM); <br/> return DM; <br/>}
Rotate the screen in C #
The following C # code combines the technology discussed above and shows how to rotate the screen clockwise in the hosted code. Note that this code only applies to devices that support corresponding display settings.
// Initialize the devmode structure <br/> devmode dm = new devmode (); <br/> DM. dmdevicename = new string (New char [32]); <br/> DM. dmformname = new string (New char [32]); <br/> DM. dmsize = marshal. sizeof (DM); </P> <p> If (0! = Nativemethods. enumdisplaysettings (<br/> null, <br/> nativemethods. enum_current_settings, <br/> ref DM) <br/>{< br/> // swap width and height <br/> int temp = DM. dmpelsheight; <br/> DM. dmpelsheight = DM. dmpelswidth; <br/> DM. dmpelswidth = temp; </P> <p> // determine new orientation <br/> switch (DM. dmdisplayorientation) <br/>{< br/> case nativemethods. dmdo_default: <br/> DM. dmdisplayorientation = Nat Ivemethods. dmdo_270; <br/> break; <br/> case nativemethods. dmdo_270: <br/> DM. dmdisplayorientation = nativemethods. dmdo_180; <br/> break; <br/> case nativemethods. dmdo_180: <br/> DM. dmdisplayorientation = nativemethods. dmdo_90; <br/> break; <br/> case nativemethods. dmdo_90: <br/> DM. dmdisplayorientation = nativemethods. dmdo_default; <br/> break; <br/> default: <br/> // unknown orientation value <br // Add Exception Handling here <br/> break; <br/>}</P> <p> int iret = nativemethods. changedisplaysettings (ref DM, 0); <br/> If (nativemethods. disp_change_successful! = Iret) <br/>{< br/> // Add Exception Handling here <br/>}< br/>}