Windows VC ++ to achieve in a dual display (main screen, extended screen) various operations source projects

        Windows Desktop, right-mouse button -> appears when "Screen Resolution", "change the appearance of the display" box next to achieve the dual function of many operations, such as: the main screen resolution setting, the main screen and the extended screen, direction, screen merger. Actual projects need to achieve by VC ++ code for these functions, with almost a week of events, after several rounds of online search, integration and rewritten, and finally developed a desired function. Cpp source code will be posted to compensate for the lack of information on the Internet in this regard. See the complete engineering resources to upload Dual various settings under Windows VC ++ implementation (complete source code engineering) (developed under VS2010).


// Multi_DisplayDlg.cpp: implementation file
//

#include "stdafx.h"
#include "Multi_Display.h"
#include "Multi_DisplayDlg.h"
#include "afxdialogex.h"

#ifdef _DEBUG
#define new DEBUG_NEW
#endif


// application for CAboutDlg Dialog "About" menu item

class CAboutDlg : public CDialogEx
{
public:
 CAboutDlg();

// dialog data
 enum {IDD = IDD_ABOUTBOX};

 protected:
 virtual void DoDataExchange(CDataExchange* pDX);    // DDX/DDV 支持

@ Achieve
protected:
 DECLARE_MESSAGE_MAP ()
};

CAboutDlg :: CAboutDlg (): CDialogEx (CAboutDlg :: IDD)
{
}

void CAboutDlg::DoDataExchange(CDataExchange* pDX)
{
 CDialogEx::DoDataExchange(pDX);
}

BEGIN_MESSAGE_MAP(CAboutDlg, CDialogEx)
END_MESSAGE_MAP()


// CMulti_DisplayDlg dialog



CMulti_DisplayDlg::CMulti_DisplayDlg(CWnd* pParent /*=NULL*/)
 : CDialogEx(CMulti_DisplayDlg::IDD, pParent)
{
 m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME);
}

void CMulti_DisplayDlg::DoDataExchange(CDataExchange* pDX)
{
 CDialogEx::DoDataExchange(pDX);
}

BEGIN_MESSAGE_MAP(CMulti_DisplayDlg, CDialogEx)
 ON_WM_SYSCOMMAND()
 ON_WM_PAINT()
 ON_WM_QUERYDRAGICON()
 ON_BN_CLICKED(IDOK, &CMulti_DisplayDlg::OnBnClickedOk)
 ON_CBN_SELCHANGE(IDC_COMBO1, &CMulti_DisplayDlg::OnCbnSelchangeCombo1)
 ON_CBN_DROPDOWN(IDC_COMBO1, &CMulti_DisplayDlg::OnCbnDropdownCombo1)
 ON_BN_CLICKED(IDC_BUTTON1, &CMulti_DisplayDlg::OnBnClickedButton1)
 ON_BN_CLICKED(IDC_BUTTON2, &CMulti_DisplayDlg::OnBnClickedButton2)
END_MESSAGE_MAP()


// CMulti_DisplayDlg message handler

:: CMulti_DisplayDlg the OnInitDialog BOOL ()
{
 CDialogEx :: the OnInitDialog ();
 
 // the "About ..." menu item is added to the system menu.

 // IDM_ABOUTBOX command system must be within range.
 The ASSERT ((IDM_ABOUTBOX & 0xFFF0) == IDM_ABOUTBOX);
 the ASSERT (IDM_ABOUTBOX <0xF000);

 CMenu* pSysMenu = GetSystemMenu(FALSE);
 if (pSysMenu != NULL)
 {
  BOOL bNameValid;
  CString strAboutMenu;
  bNameValid = strAboutMenu.LoadString(IDS_ABOUTBOX);
  ASSERT(bNameValid);
  if (!strAboutMenu.IsEmpty())
  {
   pSysMenu->AppendMenu(MF_SEPARATOR);
   pSysMenu->AppendMenu(MF_STRING, IDM_ABOUTBOX, strAboutMenu);
  }
 }

 // Set the icon for this dialog. When the dialog box is not the main application window, the frame will automatically
 // do this
 SetIcon (m_hIcon, TRUE); // set large icons
 SetIcon (m_hIcon, FALSE); // set icon

 // TODO: this additional initialization code
 GetAllMonitors ();
 the comboBox = (the CComboBox *) the GetDlgItem (IDC_COMBO1);
 ComboBox- to> ResetContent ();
 for (int I = 0; I <dev_list.size (); I ++) 
 { 
  CString string1; //; = CString (I);
  string1.Format (_T ( "% D"), I +. 1);
  // ZeroMemory (& string1, the sizeof (string1));
  // sprintf (TEMP, "% D ", I +. 1);
  ComboBox- to> the AddString (string1);
 } 
 ComboBox- to> SetCurSel (0);
 UpdateData (to false);

 return TRUE; // set the focus to the control unless otherwise returns TRUE
}

void CMulti_DisplayDlg::OnSysCommand(UINT nID, LPARAM lParam)
{
 if ((nID & 0xFFF0) == IDM_ABOUTBOX)
 {
  CAboutDlg dlgAbout;
  dlgAbout.DoModal();
 }
 else
 {
  CDialogEx::OnSysCommand(nID, lParam);
 }
}

// If you add a button to minimize the dialog box, you'll need the code below
// to draw the icon. For MFC applications using the document / view model,
// This is done automatically by the framework.

:: CMulti_DisplayDlg the OnPaint void ()
{
 IF (IsIconic ())
 {
  CPaintDC DC (the this); // device context for drawing

  SendMessage(WM_ICONERASEBKGND, reinterpret_cast<WPARAM>(dc.GetSafeHdc()), 0);

  // make the icons in the work area centered rectangle
  int = cxIcon the GetSystemMetrics (SM_CXICON);
  int = cyIcon the GetSystemMetrics (SM_CYICON);
  CRect RECT;
  the GetClientRect (& RECT);
  int X = (rect.width () - + cxIcon. 1) / 2 ;
  int Y = (rect.height () - + cyIcon. 1) / 2;

  // Draw icons
  dc.DrawIcon (X, Y, m_hIcon);
 }
 the else
 {
  CDialogEx :: the OnPaint ();
 }
}

// When the user drags the minimized window system calls the function to obtain the cursor
// display.
:: OnQueryDragIcon CMulti_DisplayDlg HCURSOR ()
{
 return static_cast <HCURSOR> (m_hIcon);
}

void CMulti_DisplayDlg::GetAllMonitors()
{
 std::list<DISPLAY_DEVICE> devices;
 std::list<DEVMODE> modes;
 int devId = 0;
 bool ret = false;
 bool isPrimary = false;

 //list all DisplayDevices (Monitors)
 do
 {
  DISPLAY_DEVICE displayDevice;
  ZeroMemory(&displayDevice, sizeof(DISPLAY_DEVICE));
  displayDevice.cb = sizeof(displayDevice);

  ret = EnumDisplayDevices(NULL, devId, &displayDevice, 0);
  if (ret == true)
  {
   if ((displayDevice.StateFlags & DISPLAY_DEVICE_ATTACHED_TO_DESKTOP) == DISPLAY_DEVICE_ATTACHED_TO_DESKTOP)
   {
    devices.push_back(displayDevice);
    isPrimary = ((displayDevice.StateFlags & DISPLAY_DEVICE_PRIMARY_DEVICE) == DISPLAY_DEVICE_PRIMARY_DEVICE);
    if (isPrimary)
     PrimaryNum = devId;
   }
  }
  devId++;
 } while (ret);
 dev_list = devices;

 std::list<DISPLAY_DEVICE>::iterator it;
 for (it = dev_list.begin(); it != dev_list.end(); it++)
 {
  DEVMODE deviceMode;
  deviceMode.dmSize = sizeof(DEVMODE);
  deviceMode.dmFields = DM_PELSWIDTH | DM_PELSHEIGHT | DM_BITSPERPEL | DM_POSITION | DM_DISPLAYFREQUENCY | DM_DISPLAYFLAGS; // | DM_DISPLAYORIENTATION;

  EnumDisplaySettings(it->DeviceName, (int)ENUM_REGISTRY_SETTINGS, &deviceMode);
  modes.push_back(deviceMode);
 }
 dev_mode_list = modes;

}

void CMulti_DisplayDlg::SwitchPrimaryScreen(int newPrimary, int oldPrimary)
{
 MoveNewPrimary(newPrimary, oldPrimary);
 MoveOldPrimary(newPrimary, oldPrimary);
 CommitChange();
}

void CMulti_DisplayDlg::MoveOldPrimary(int newPrimary, int oldPrimary)
{
 int index = 0;
 std::list<DISPLAY_DEVICE>::iterator it1;
 for (it1 = dev_list.begin(); it1 != dev_list.end(); it1++)
 {
  if (index == oldPrimary)
   break;
  index++;
 }
 index = 0;
 std::list<DEVMODE>::iterator it2;
 for (it2 = dev_mode_list.begin(); it2 != dev_mode_list.end(); it2++)
 {
  if (index == newPrimary)
   break;
  index++;
 }
 index = 0;
 std::list<DEVMODE>::iterator it3;
 for (it3 = dev_mode_list.begin(); it3 != dev_mode_list.end(); it3++)
 {
  if (index == oldPrimary)
   break;
  index++;
 }
 it3->dmPosition.x = it2->dmPelsWidth;
 it3->dmPosition.y = 0;
 DEVMODE deviceMode = *it3;
 int ret = ChangeDisplaySettingsEx(it1->DeviceName, &deviceMode, NULL, CDS_UPDATEREGISTRY | CDS_NORESET, NULL);
}

void CMulti_DisplayDlg::MoveNewPrimary(int newPrimary, int oldPrimary)
{
 int index = 0;
 std::list<DISPLAY_DEVICE>::iterator it1;
 for (it1 = dev_list.begin(); it1 != dev_list.end(); it1++)
 {
  if (index == newPrimary)
   break;
  index++;
 }
 index = 0;
 std::list<DEVMODE>::iterator it2;
 for (it2 = dev_mode_list.begin(); it2 != dev_mode_list.end(); it2++)
 {
  if (index == newPrimary)
   break;
  index++;
 }

 it2->dmPosition.x = 0;
 it2->dmPosition.y = 0;
 DEVMODE deviceMode = *it2;
 
 int ret = ChangeDisplaySettingsEx(it1->DeviceName, &deviceMode, NULL, CDS_SET_PRIMARY | CDS_UPDATEREGISTRY | CDS_NORESET, NULL);
}

void CMulti_DisplayDlg::CommitChange()
{
 ChangeDisplaySettingsEx (NULL, NULL, NULL, 0, NULL);
}

int CMulti_DisplayDlg::GetPrimaryScreen()
{
 return PrimaryNum;
}

int CMulti_DisplayDlg::SetPrimaryScreen(int num)
{
 int oldprimary = GetPrimaryScreen();
 int newPrimary = num;

 if ((num >= dev_list.size()) || (num < 0))
  return -1;

 if (oldprimary == newPrimary)
  return 0;

 SwitchPrimaryScreen(newPrimary, oldprimary);
 PrimaryNum = newPrimary;

 return oldprimary;
}

int CMulti_DisplayDlg::SetCloneView(int mode)
{
 /*UINT32 PathArraySize = 0;  
 UINT32 ModeArraySize = 0;  
 DISPLAYCONFIG_PATH_INFO* PathArray;  
 DISPLAYCONFIG_MODE_INFO* ModeArray;  
 DISPLAYCONFIG_TOPOLOGY_ID CurrentTopology;  

 //Determine the size of the path array that is required to hold all valid paths
 GetDisplayConfigBufferSizes(QDC_ALL_PATHS, &PathArraySize, &ModeArraySize); //retrieve the sizes of the DISPLAYCONFIG_PATH_INFO and DISPLAYCONFIG_MODE_INFO buffers that are required

 //Allocate memory for path and mode information arrays
 PathArray = (DISPLAYCONFIG_PATH_INFO*)malloc(PathArraySize * sizeof(DISPLAYCONFIG_PATH_INFO));  
 memset(PathArray, 0, PathArraySize * sizeof(DISPLAYCONFIG_PATH_INFO));  

 ModeArray = (DISPLAYCONFIG_MODE_INFO*)malloc(ModeArraySize * sizeof(DISPLAYCONFIG_MODE_INFO));  
 ZeroMemory(ModeArray, ModeArraySize * sizeof(DISPLAYCONFIG_MODE_INFO));  
 
 //Request all of the path information
 LONG ret = QueryDisplayConfig(QDC_DATABASE_CURRENT,&PathArraySize, PathArray, &ModeArraySize, ModeArray, &CurrentTopology); //obtain the path and mode information for all posible paths
 // Above CurrentTopology variable will aquire the current display setting (ie Extend, Duplicate etc)  

 free(PathArray);  
 free(ModeArray);  
 */
 //Set the new topology.
 SetDisplayConfig(0,NULL,0,NULL, mode | SDC_APPLY); //change to the clone topology

 return 0;
}

int CMulti_DisplayDlg::ChangeScreenOrientation(int num, int rotation)
{
 int index = 0;
 std::list<DEVMODE>::iterator it;

 for (it = dev_mode_list.begin(); it != dev_mode_list.end(); it++)
 {
  if (index == num)
   break;
  index++;
 }
 DWORD dwTemp = it->dmPelsHeight;
 switch(rotation)
 {
  case 0:
   if(it->dmDisplayOrientation == DMDO_DEFAULT)
    it->dmDisplayOrientation = DMDO_90;
   else if(it->dmDisplayOrientation == DMDO_90)
    it->dmDisplayOrientation = DMDO_DEFAULT;
   it->dmPelsHeight= it->dmPelsWidth;
   it->dmPelsWidth = dwTemp;
   break;
  case 1:
   if(it->dmDisplayOrientation == DMDO_DEFAULT)
    it->dmDisplayOrientation = DMDO_90;
   else if(it->dmDisplayOrientation == DMDO_90)
    it->dmDisplayOrientation = DMDO_DEFAULT;
   it->dmPelsHeight= it->dmPelsWidth;
   it->dmPelsWidth = dwTemp;
   break;
 }

 DEVMODE deviceMode;
 ZeroMemory(&deviceMode, sizeof(deviceMode));
 deviceMode.dmSize = sizeof(deviceMode);
 deviceMode = *it;

 index = 0;
 std::list<DISPLAY_DEVICE>::iterator it1;
 for (it1 = dev_list.begin(); it1 != dev_list.end(); it1++)
 {
  if (index == num)
   break;
  index++;
 }

 //long lRet = ChangeDisplaySettingsEx(it1->DeviceName, &deviceMode, NULL, CDS_UPDATEREGISTRY | CDS_NORESET, NULL);
 //CommitChange();
 long lRet = ChangeDisplaySettingsEx(it1->DeviceName, &deviceMode, NULL, CDS_UPDATEREGISTRY, NULL);

 return lRet;
}

:: OnBnClickedOk CMulti_DisplayDlg void ()
{
 // the TODO: In this addition control notification handler code
 SetPrimaryScreen (selIndex);
 
 // :: CDialogEx the OnOK ();
}

count1 is = 0 int;
void CMulti_DisplayDlg :: OnBnClickedButton1 ()
{
 // the TODO: In this addition control notification handler code
 long lRet;

 selIndex = comboBox->GetCurSel();//取得选中的索引
 if(selIndex < 0 )
  return;
 count1++;
 if(count1 %2)
 {
  lRet = ChangeScreenOrientation(selIndex, 1);
 }
 else
 {
  lRet = ChangeScreenOrientation(selIndex, 0);
 }
}

COUNT = 0 int;
void CMulti_DisplayDlg :: OnBnClickedButton2 ()
{
 // the TODO: In this addition control notification handler code
 COUNT ++;
 IF (COUNT 2%)
 {
  SetCloneView (SDC_TOPOLOGY_CLONE);
  the GetDlgItem (IDC_BUTTON2) -> SetWindowTextW (_T ( " recovery "));
 }
 the else
 {
  SetCloneView (SDC_TOPOLOGY_EXTEND);
  the GetDlgItem (IDC_BUTTON2) -> SetWindowTextW (_T (" screen copy "));
 }
}

:: OnCbnSelchangeCombo1 CMulti_DisplayDlg void ()
{
 // the TODO: In this addition control notification handler code
 // Get the value of the selected
 CString selStr;
 selIndex = ComboBox- to> GetCurSel (); // Get the selected index
 // comboBox-> GetLBText (nIndex, selStr);

 // MessageBox (selStr);
}

:: OnCbnDropdownCombo1 CMulti_DisplayDlg void ()
{
 // the TODO: In this addition control notification handler code
 GetAllMonitors ();
 the comboBox = (the CComboBox *) the GetDlgItem (IDC_COMBO1);
 ComboBox- to> ResetContent ();
 for (int I = 0; I <dev_list.size (); I ++) 
 { 
  CString string1; //; = CString (I);
  string1.Format (_T ( "% D"), I +. 1);
  // ZeroMemory (& string1, the sizeof (string1)) ;
  // sprintf (TEMP, "% D", I +. 1);
  ComboBox- to> the AddString (string1);
 } 

 UpdateData(false);
}



Attach a few useful links:

https://msdn.microsoft.com/en-us/library/ff569533(v=vs.85).aspx


https://msdn.microsoft.com/en-us/library/dd183413(VS.85).aspx





发布了34 篇原创文章 · 获赞 12 · 访问量 8万+

Guess you like

Origin blog.csdn.net/phmatthaus/article/details/50219409