Настройка CMFCPropertySheet как RTL

Я видел несколько подобных вопросов по этому вопросу, но я могу решить его.

Например, в CodeProject:

https://www.codeproject.com/Messages/2873837/Re-How-to-set-RTL-layout-for-a-CPropertySheet.aspx

И на ТАК:

проблема с макетом RTL для страниц свойств (MFC)

Итак, у меня есть CMFCPropertySheet, которое является моим главным окном приложения, и при запуске программы оно установлено на арабский язык:

Арабское окно

Проблема, как и в случае с другими пользователями, заключается в том, что хотя страницы правильно настроены на макет справа налево, лист — нет.

Как правильно заставить лист отображать RTL?

Я пытался использовать PreCreateWindow, и это не имело никакого значения. Я тоже пытался использовать SetProcessDefaultLayout. Нет радости.


person Andrew Truckle    schedule 09.12.2018    source источник


Ответы (1)


В идеале стиль окна должен быть изменен в OnNcCreate до того, как окно начнет создавать и размещать свои дочерние элементы управления. Таким образом, дочерняя вкладка, а также дочерние кнопки будут расположены соответствующим образом (кнопка OK/Отмена/Применить также будет выровнена по левому краю).

Пример:

BEGIN_MESSAGE_MAP(...)
    ON_WM_NCCREATE()
    ...
END_MESSAGE_MAP()

BOOL CMyPropertySheet::OnNcCreate(LPCREATESTRUCT pc)
{
    BOOL res = CMFCPropertySheet::OnNcCreate(pc);

    SetWindowLongPtr(m_hWnd, GWL_EXSTYLE,
            WS_EX_LAYOUTRTL | GetWindowLongPtr(m_hWnd, GWL_EXSTYLE));

    return res;
}

В качестве альтернативы, сделайте это в OnInitDialog, используйте ::FindWindowEx(m_hWnd, 0, WC_TABCONTROL, 0), чтобы найти дескриптор элемента управления вкладкой и изменить его стиль. Таким образом, кнопки не переставляются. Пример:

BOOL CMyPropertySheet::OnInitDialog()
{
    BOOL res = CMFCPropertySheet::OnInitDialog();

    SetWindowLongPtr(m_hWnd, GWL_EXSTYLE,
        WS_EX_LAYOUTRTL | GetWindowLongPtr(m_hWnd, GWL_EXSTYLE));

    HWND htabctrl = ::FindWindowEx(m_hWnd, 0, WC_TABCONTROL, 0);
    SetWindowLongPtr(htabctrl, GWL_EXSTYLE,
        WS_EX_LAYOUTRTL | GetWindowLongPtr(htabctrl, GWL_EXSTYLE));

    return res;
}

Примечание:

Вы также можете вызвать SetProcessDefaultLayout(LAYOUT_RTL) в начале процесса (например, в CMyWinApp::InitInstance). Затем измените макет в зависимости от результата от GetProcessDefaultLayout. Чтобы вы не забыли случайно изменить стиль на латинскую версию...

person Barmak Shemirani    schedule 09.12.2018
comment
Я понимаю, что для SetProcessDefaultLayout мне нужно связать user32.lib и включить windows.h и winuser.h. - person Andrew Truckle; 10.12.2018
comment
Когда бы вы вызвали SetProcessDefaultLayout? Когда загружаются языковые ресурсы? - person Andrew Truckle; 10.12.2018
comment
Я думаю, что излишне усложнил это, говоря о SetProcessDefaultLayout. Тебе это совсем не нужно. Смотрите редактировать... - person Barmak Shemirani; 10.12.2018