Use VC to dynamically change windows display features

Source: Internet
Author: User
For Windows platforms, the display resolution, color count, and refresh rate are very important, especially for multimedia applications and game software. In many cases, the current screen setting of the user is not suitable for the operation of the Software. the common practice of the software is to prompt the user to set the screen to the resolution and color required by the software, restart the software. This will undoubtedly increase the operational burden and difficulties of ordinary users, and reduce the friendliness and ease of use of the software. The ideal practice is to dynamically change the screen settings at the beginning of the software to meet the software running requirements. After the software is running, the screen setting is automatically changed back to the original setting value. All these processes are done without knowing it. This example shows how to dynamically set the system display resolution. You can set the resolution to 1024*768 or 800*600 as long as the system hardware supports it; set the color to 8 bits, 24 bits, and 32 bits. After the program is compiled and run, the interface effect 1 is shown as follows:


Figure 1. Program Interface for setting system resolution

I. programming methods

We know that the display content corresponds to the video memory. The smallest unit on the display is pixel (pixel, here only the logical pixel is taken into account), and the smallest unit of the video memory is bit (BITs ). The main features of the display are the number of colors and resolution. The number of colors displayed by the monitor depends on the number of BITs used by the unit pixel ). In video memory, if the 8-bit video memory (that is, a pixel uses a one-byte video memory) corresponds to a pixel on the display, the number of colors displayed on the monitor is 28 = 256. Similarly, if the current color is 16 bits, the number of colors displayed on the monitor is 216 = 65536 colors. The display resolution refers to the horizontal and vertical resolutions. The commonly referred to as 800x600 means that the number of pixels displayed in the horizontal aspect is 800, the number of pixels displayed in the vertical aspect is 600.

The function changedisplaysettings () for modifying the attributes of a display device (such as a display or printer) is provided in VC (), this function can modify the display device as needed. The prototype of the function is long changedisplaysettings (lpdevmode, DWORD dwflags). The parameter meanings are as follows:

Lpdevmode: a pointer to the devmode data structure. The data structure of the devmode describes the attribute values of the display to be set. Generally, the following member variables are used:
Dmsize: the size of the devmode data structure used (in bytes );
Dmbitsperpel: The number of BITs used for each pixel );
Dmpelswidth: horizontal resolution (points );
Dmpelsheight pixel height: vertical resolution (points );
Dmdisplayfrequency: displays the update rate in Hz;
Dmfields: Generally, different display devices (such as printers) use different devmode data structures. For example, you do not use the dmdisplayfrequency attribute when setting a printer. Therefore, when you use the devmode data structure, you should explain to the system the valid data members you actually use. dmfields is useful here. If you only use dmpelswidth (horizontal resolution) and dmpelsheight (vertical resolution) in the program, the value should be dm_pelswidth | dm_pelsheight.
Dwflags: indicates how the display device is modified. The specific values are as follows: 0: dynamically changing the display device properties; cds_updateregistry: dynamically changing the display device properties and modifying the registry settings. The modifications made next time you start the computer will still be valid; cds_test: test whether the modification is valid.

After the above function is called, the return value is as follows: disp_change_successful: the modification is successful; disp_change_restart: after the modification, it needs to be restarted (select "Restart computer before applying the new color" in the display settings); disp_change_failed: modification failed; disp_change_badmode: the modification mode is incorrect (for example, your monitor is in a monochrome color, but you change it to a 256 color ). If the lpdevmode parameter is null and dwflags is 0 during function calling, the display device uses the current registry value to set the display feature. The above is the most common usage of the changedisplaysettings () function. For more details, see msdn.

For the system's display feature programming, there is also a key API function enumdisplaysettings () used to obtain all the display modes supported by the current display driver. To obtain the current display mode, you can use the following functions:

Bool getcurrentvideosettings (devmode * devmode)
{
Hwnd hwnddesktop = getdomaintopwindow ();
HDC = getdc (hwnddesktop );
Devmode-> dmsize = sizeof (devmode );
Devmode-> dmbitsperpel = getdevicecaps (HDC, bitspixel );
Devmode-> dmpelswidth = getsystemmetrics (sm_cxscreen );
Devmode-> dmpelsheight = getsystemmetrics (sm_cyscreen );
Devmode-> dmfields = dm_bitsperpel | dm_pelswidth | dm_pelsheight;
Return true;
}

The following code shows how to use enumdisplaysettings to obtain all currently supported display modes:

Int modenum, done;
Devmode;
Done = 0;
Modenum = 0;
Do
{
Done =! Enumdisplaysettings (null, modenum, & devmode );
Addtolist (& devmode );
Modenum ++;
} While (! Done );

You can set the display mode as follows:

Rc = changedisplaysettings (& devmode, cds_fullscreen); The devmode here is obtained by using enumdisplaysettings. If the setting is normal, the returned value is disp_change_successful.

Ii. programming steps

1. Start visual c ++ 6.0, generate a project chngdsplymd Based on the dialog box, and place three editing controls in the dialog box. The IDS are named id_edit_width, id_editheight, and id_edit_bits respectively, to describe the edit box control function, place the first two edit box controls in a combo box titled "screen area" and add a static control next to the third edit box control, "caption" is set to "number of pixels ". The "caption" of the two button controls on the dialog box are set to "change resolution" and "close" respectively, and the IDs are defined as idc_change and idok respectively;

2. Use Class Wizard to define the corresponding member variables for the preceding three editing controls:

Uint m_nwidthpixels, uint m_nheightpixels, uint m_nbitsperpixel

3. Compile and run the program by clicking the button in the dialog framework.

 

 

Iii. Implementation Code

//////////////////////////////////////// //// // Chngdsplymddlg. h: header file
# If! Defined (afx_chngdsplymddlg_h1_1d52415e_62de_11d6_8f32_00e04ce762401_encoded _)
# Define afx_chngdsplymddlg_h1_1d52415e_62de_11d6_8f32_00e04ce762401_encoded _
# If _ msc_ver> 1000
# Pragma once
# Endif // _ msc_ver> 1000
Class cchngdsplymddlg: Public cdialog // cchngdsplymddlg Dialog
{
// Construction
Public:
Cchngdsplymddlg (cwnd * pparent = NULL); // standard Constructor
// Dialog data
// {Afx_data (cchngdsplymddlg)
Enum {IDD = idd_chngdsplymd_dialog };
Uint m_nbitsperpixel;
Uint m_nheightpixels;
Uint m_nwidthpixels;
//} Afx_data
// Classwizard generated virtual function overrides
// {Afx_virtual (cchngdsplymddlg)
Protected:
Virtual void dodataexchange (cdataexchange * PDX); // DDX/DDV support
//} Afx_virtual
// Implementation
Protected:
Hicon m_hicon;
// Generated message map Functions
// {Afx_msg (cchngdsplymddlg)
Virtual bool oninitdialog ();
Afx_msg void onsyscommand (uint NID, lparam );
Afx_msg void onpaint ();
Afx_msg hcursor onquerydragicon ();
Afx_msg void onchagne ();
//} Afx_msg
Declare_message_map ()
};
# Endif
//////////////////////////////////////// ///////////////////// Cchngdsplymddlg Dialog
# Include "stdafx. H"
# Include "chngdsplymd. H"
# Include "chngdsplymddlg. H"
# Ifdef _ debug
# Define new debug_new
# UNDEF this_file
Static char this_file [] = _ file __;
# Endif
Cchngdsplymddlg: cchngdsplymddlg (cwnd * pparent/* = NULL */)
: Cdialog (cchngdsplymddlg: IDD, pparent)
{
// {Afx_data_init (cchngdsplymddlg)
M_nbitsperpixel = 32;
M_nwidthpixels = 1024;
M_nheightpixels = 768;
//} Afx_data_init
// Note that loadicon does not require a subsequent destroyicon in Win32
M_hicon = afxgetapp ()-> loadicon (idr_mainframe );
}
Void cchngdsplymddlg: dodataexchange (cdataexchange * PDX)
{
Cdialog: dodataexchange (PDX );
// {Afx_data_map (cchngdsplymddlg)
Ddx_text (PDX, idc_edit_bits, m_nbitsperpixel );
Ddx_text (PDX, idc_edit_height, m_nheightpixels );
Ddx_text (PDX, idc_edit_width, m_nwidthpixels );
//} Afx_data_map
}

Begin_message_map (cchngdsplymddlg, cdialog)
// {Afx_msg_map (cchngdsplymddlg)
On_wm_syscommand ()
On_wm_paint ()
On_wm_querydragicon ()
On_bn_clicked (idc_chagne, onchagne)
//} Afx_msg_map
End_message_map ()
//////////////////////////////////////// /////////////////////////////////////
// Cchngdsplymddlg message handlers
Bool cchngdsplymddlg: oninitdialog ()
{
Cdialog: oninitdialog ();
// Add "about..." menu item to system menu.
// Idm_aboutbox must be in the system command range.
Assert (idm_aboutbox & 0xfff0) = idm_aboutbox );
Assert (idm_aboutbox <0xf000 );
Cmenu * psysmenu = getsystemmenu (false );
If (psysmenu! = NULL)
{
Cstring straboutmenu;
Straboutmenu. loadstring (ids_aboutbox );
If (! Straboutmenu. isempty ())
{
Psysmenu-> appendmenu (mf_separator );
Psysmenu-> appendmenu (mf_string, idm_aboutbox, straboutmenu );
}
}
// Set the icon for this dialog. The framework does this automatically
// When the application's main window is not a dialog
Seticon (m_hicon, true); // set big icon
Seticon (m_hicon, false); // set small icon
// Todo: add extra initialization here
Return true; // return true unless you set the focus to a control
}
Void cchngdsplymddlg: onsyscommand (uint NID, lparam)
{
If (NID & 0xfff0) = idm_aboutbox)
{
Caboutdlg dlgabout;
Dlgabout. domodal ();
}
Else
{
Cdialog: onsyscommand (NID, lparam );
}
}
// If you add a Minimize button to your dialog, you will need the code below
// To draw the icon. For MFC applications using the document/view model,
// This is automatically done for you by the framework.
Void cchngdsplymddlg: onpaint ()
{
If (isiconic ())
{
Cpaintdc DC (this); // device context for painting
Sendmessage (wm_iconerasebkgnd, (wparam) DC. getsafehdc (), 0 );
// Center icon in client rectangle
Int cxicon = getsystemmetrics (sm_cxicon );
Int cyicon = getsystemmetrics (sm_cyicon );
Crect rect;
Getclientrect (& rect );
Int x = (rect. Width ()-cxicon + 1)/2;
Int y = (rect. Height ()-cyicon + 1)/2;
// Draw the icon
DC. drawicon (X, Y, m_hicon );
}
Else
{
Cdialog: onpaint ();
}
}
// The system callthis to obtain the cursor to display while the user drags
// The minimized window.
Hcursor cchngdsplymddlg: onquerydragicon ()
{
Return (hcursor) m_hicon;
}
Void cchngdsplymddlg: onchagne ()
{
Updatedata (true );
Devmode lpdevmode;
Lpdevmode. dmbitsperpel = m_nbitsperpixel;
Lpdevmode. dmpelswidth = m_nwidthpixels;
Lpdevmode. dmpelsheight = m_nheightpixels;
Lpdevmode. dmsize = sizeof (lpdevmode );
Lpdevmode. dmfields = dm_pelswidth | dm_pelsheight | dm_bitsperpel;
Long result = changedisplaysettings (& lpdevmode, 0 );
If (result = disp_change_successful)
{
Afxmessagebox ("modified successfully ");
Changedisplaysettings (& lpdevmode, cds_updateregistry );
// Use cds_updateregistry to indicate that the next modification is persistent,
// And related data is written into the registry
}
Else
{
Afxmessagebox ("modification failed, restore original settings ");
Changedisplaysettings (null, 0 );
}
}

Iv. Summary

The result returned by the changedisplaysettings () function is not analyzed in the above instance code. In actual operation, you can perform changedisplaysettings () to find out the reason for the modification failure. By setting the dmfields member variable of devmode, you can also set the update rate feature of the system. The implementation method is almost the same as above. I believe it is unnecessary to introduce it more.

 

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.