Как сделать размеры кнопок MFC CToolbar более согласованными для приложений с высоким DPI в Windows 7/10 - PullRequest
0 голосов
/ 01 марта 2019

Я работаю над старым приложением C ++ MFC, использующим CToolbar для компиляции его панели инструментов с Visual Studio 2017.

Когда в настройках манифеста для приложения установлено значение «High DPI Aware» (Project / Properties /Свойства конфигурации / Инструмент манифеста / Ввод и вывод / Осведомленность о DPI), как и ожидалось, во время выполнения панель инструментов масштабируется с масштабным коэффициентом DPI основного монитора в Windows 10 и примерно вдвое меньше, чем текст строки меню.

В Windows 7 такого масштабирования не происходит.Панель инструментов имеет ту же высоту, что и текст строки меню при 100% DPI, и остается с той же высотой пикселя при различных настройках DPI.Использование или отсутствие использования масштабирования DPI в стиле XP не имеет значения.

Является ли базовый элемент управления панели инструментов в Windows 7 принципиально менее способным к масштабированию с высоким DPI?Есть ли эффективный способ изменить это и сделать размеры панелей инструментов Windows 7 и Windows 10 более согласованными?

Я могу воспроизвести ту же проблему, запустив образец DFCTOOL MFC, перекомпилированный с High DPI Awareness, в манифесте с использованием Visual Studio 2017.

https://github.com/Microsoft/VCSamples/tree/master/VC2010Samples/MFC/general/docktool

// code excerpts from DOCKTOOL below:
class CMainFrame : public CFrameWnd

{
protected: // create from serialization only
    CMainFrame();
    DECLARE_DYNCREATE(CMainFrame)

    CToolBar    m_wndMainBar;

// Generated message map functions
protected:
    //{{AFX_MSG(CMainFrame)
    afx_msg int OnCreate(LPCREATESTRUCT lpCreateStruct);
    //}}AFX_MSG
    DECLARE_MESSAGE_MAP()
};

int CMainFrame::OnCreate(LPCREATESTRUCT lpCreateStruct)
{
    if (CFrameWnd::OnCreate(lpCreateStruct) == -1)
        return -1;
//....


if (!m_wndMainBar.Create(this, WS_CHILD | WS_VISIBLE | CBRS_SIZE_DYNAMIC |
            CBRS_TOP | ((m_bToolTips)?(CBRS_TOOLTIPS | CBRS_FLYBY):0), IDW_MAIN_BAR) ||
        !m_wndMainBar.LoadBitmap(
            (m_bColor)?IDR_COLOR_MAINBAR:IDR_MONO_MAINBAR) ||
        !m_wndMainBar.SetButtons(MainButtons, sizeof(MainButtons)/sizeof(UINT)))
    {
        TRACE0("Failed to create mainbar\n");
        return -1;      // fail to create
    }

1 Ответ

0 голосов
/ 03 марта 2019

Используйте CToolBar::SetSizes, чтобы назначить новый размер кнопки и размер растрового изображения.Вы должны знать размеры растрового изображения, используемого в ресурсе.

В приведенном ниже примере предполагается, что размер растрового изображения составляет 16 x 15 пикселей.Это увеличит размер кнопок в зависимости от настроек DPI (но не увеличит растровое изображение)

//get DPI scaling 
double fx = GetSystemMetrics(SM_CXSMICON) / 16.0f;
double fy = GetSystemMetrics(SM_CYSMICON) / 16.0f;
if(fx < 1) fx = 1;
if(fy < 1) fy = 1;

CRect temp;
m_wndMainBar.GetItemRect(0, &temp);
temp.MoveToXY(0, 0);
temp.right = int(temp.right * fx);
temp.bottom = int(temp.bottom * fy);

CSize bmp_size(16, 15);
m_wndMainBar.SetSizes(temp.Size(), bmp_size);

Чтобы увеличить растровое изображение, вам нужно перейти в редактор ресурсов и создать отдельное растровое изображение длякаждое масштабирование.

Например, для масштабирования 125% DPI создайте растровое изображение на 25% больше и используйте bmp_size(20, 18) вместо bmp_size(16, 15)

Этот метод может стать очень сложным, поэтому вы можете рассмотреть возможность использования значковс LoadIconWithScaleDown.Таким образом, вы создаете большую иконку, скажем, 150% DPI, и используете эту же иконку для масштабирования 125% и 100% DPI.

...