用C++代码更改系统分辨率

由于工作需要,我需要制作一个小工具来更改系统分辨率。

小工具需要支持多显示器,每个显示器要能分别设置分辨率

功能很简单,由于不需要做的好看,只要功能可用即可,使用了MFC(只是为了方便)

乱七八糟的逻辑不说,只说几个关键函数:

1.枚举系统显示器

void CDisplaySettingsDlg::FillDeviceCombo()
{
	m_comboDevices.Clear();
	m_comboDevices.ResetContent();
	DWORD dwAdaptorIndex = 0;
	DISPLAY_DEVICE ddv;
	ZeroMemory(&ddv, sizeof(DISPLAY_DEVICE));
	ddv.cb = sizeof(DISPLAY_DEVICE);

	while (EnumDisplayDevices(NULL, dwAdaptorIndex++, &ddv, 0))
	{
		if (!(ddv.StateFlags&DISPLAY_DEVICE_MIRRORING_DRIVER)
			&& (ddv.StateFlags & DISPLAY_DEVICE_ATTACHED_TO_DESKTOP))
		{
			m_comboDevices.AddString(ddv.DeviceName);
		}

		ZeroMemory(&ddv, sizeof(DISPLAY_DEVICE));
		ddv.cb = sizeof(DISPLAY_DEVICE);
	}
	m_comboDevices.SetCurSel(0);
}

2.枚举显示器支持的分辨率

void CDisplaySettingsDlg::RefreshSettingsCombo()
{
    ClearSettingsCombo();
    CString strDeviceName;
    CString strAdd;
    m_comboDevices.GetWindowText(strDeviceName);
    int currentCX = 0;
    int currentCY = 0;
    {
        DEVMODE dev;
        ZeroMemory(&dev, sizeof(dev));
        dev.dmSize = sizeof(dev);
        if (EnumDisplaySettings(strDeviceName, ENUM_CURRENT_SETTINGS, &dev))
        {
            currentCX = dev.dmPelsWidth;
            currentCY = dev.dmPelsHeight;
        }
    }
    LPDISPLAYOPTION pOptionPre = NULL;
    int iModeNum = 0;
    while (true)
    {
        DEVMODE dev;
        ZeroMemory(&dev, sizeof(dev));
        dev.dmSize = sizeof(dev);
        if (EnumDisplaySettings(strDeviceName, iModeNum, &dev))
        {
            int cx = dev.dmPelsWidth;
            int cy = dev.dmPelsHeight;
            if (pOptionPre && pOptionPre->IsLike(cx, cy))
            {
                iModeNum++;
                continue;
            }
            LPDISPLAYOPTION pNew = new DISPLAYOPTION(cx, cy);
            m_vecOptions.push_back(pNew);
            pOptionPre = pNew;

        }
        else
        {
            break;
        }
        iModeNum++;
    }
    std::sort(m_vecOptions.begin(), m_vecOptions.end(), DISPLAYOPTION::biggerWidth);
    int curSel = 0;
    int index = 0;
    for (auto opt : m_vecOptions)
    {
        strAdd.Format(L"%d * %d", opt->cx, opt->cy);
        if (opt->cx == currentCX && opt->cy == currentCY)
        {
            curSel = index;
        }
        if (index == 0)
        {
            strAdd += L"(推荐)";
        }
        m_comboSettings.SetItemDataPtr(m_comboSettings.AddString(strAdd), opt);
        index++;
    }
    m_comboSettings.SetCurSel(curSel);
}

你可能会看到sort函数,这个就是为了让分辨率从大到小排序,默认的枚举顺序是从小到大,如果正好是你需要的,你就干掉sort和那个把条目存到vector的逻辑。 我存到vector然后sort仅仅是为了排序。

3.应用用户选择的分辨率

void CDisplaySettingsDlg::OnCbnSelchangeComboSettings()
{
    int curSel = m_comboSettings.GetCurSel();
    CString strDeviceName;
    m_comboDevices.GetWindowText(strDeviceName);
    if (curSel >= 0)
    {
        LPDISPLAYOPTION pData = (LPDISPLAYOPTION)m_comboSettings.GetItemDataPtr(curSel);
        if (pData)
        {
            DEVMODE dev;
            ZeroMemory(&dev, sizeof(dev));
            dev.dmSize = sizeof(dev);
            dev.dmFields = DM_PELSWIDTH | DM_PELSHEIGHT;
            dev.dmPelsWidth = pData->cx;
            dev.dmPelsHeight = pData->cy;
            ChangeDisplaySettingsEx(strDeviceName, &dev, NULL,
                CDS_GLOBAL | CDS_UPDATEREGISTRY, NULL);
        }
    }
}

 

这些代码都是直接摘抄自我的工程的,直接跑应该有问题,不过只看关键函数就够了

  • 1
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值