Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > Visual C++/MFC/WTL > Изменить стили уже существующего окна


Автор: 0x07L 20.7.2006, 15:37
Вот, собственно, код, который ничего не делает:
Код

void CMainDialog::On_ListSettings_Button_Apply()
{
    // TODO: Add your control notification handler code here
    
    ULONG_PTR Style = GetWindowLongPtr(List.m_hWnd, GWL_STYLE);
    /*ULONG_PTR NewValues = 0;
    
    if (IsDlgButtonChecked(IDC_LISTSETTINGS_CHECK_NOHIDESCROLLBAR))
    {
        NewValues |= LBS_DISABLENOSCROLL;
    }

    if (IsDlgButtonChecked(IDC_LISTSETTINGS_CHECK_BORDER))
    {
        NewValues |= WS_BORDER;
    }*/

    SetWindowLongPtr(List.m_hWnd, GWL_STYLE, Style ^ LBS_DISABLENOSCROLL);//Style ^ ((Style ^ NewValues) & (LBS_DISABLENOSCROLL | WS_BORDER)));
    List.SetWindowPos(0, 0, 0, 0, 0, SWP_NOZORDER | SWP_NOMOVE | SWP_NOSIZE | SWP_FRAMECHANGED | SWP_DRAWFRAME | SWP_NOSENDCHANGING);

    Style = GetWindowLongPtr(List.m_hWnd, GWL_STYLE);
}

В MSDN по поводу SetWindowLongPtr сказано, что, дескать, "Certain window data is cached, so changes you make using SetWindowLongPtr will not take effect until you call the SetWindowPos function.". Вот я и пробую этот самый SetWindowPos и ничего не происходит...

Изначально код предназначался для изменения атрибутов окна согласно состоянию CheckBox'ов, но в ходе поиска рабочего варианта я, как видите, часть его закомментировал и он теперь должен только удалять стиль LBS_DISABLENOSCROLL, однако и этого он не делает.

Что интересно, в последней строчке в переменную Style записывается значение без LBS_DISABLENOSCROLL, т.е. значение все-таки меняется, но не изменяется внешний вид окна... Может, надо что-то добавить во флажки SetWindowPos?

Примечание: окно, которое я мучаю, - это ListBox, пока не содержащий элементов.
Еще примечание: после этого я перерисовываю окно и оно рисуется, как прежде, с отключенной (disabled) полосой прокрутки.  

Автор: xTr1m 20.7.2006, 22:47
Может я конечно и путаю, но для элементов есть очень простая функция изменения стиля : ModifyStyle(какие_стили_убрать, какие_добавить)

m_btn->ModifyStyle(WS_VISIBLE, 0 ) и кнопка исчезает =)) 

Автор: Earnest 21.7.2006, 07:52
1) Действительно, удобнее пользоваться CWnd::ModifyStyle - она вызывает тот же SetWindowLong, но сама определяет что куда
2) При изменении стиля обычно достаточно флагов SWP_NOZORDER | SWP_NOMOVE | SWP_NOSIZE | SWP_FRAMECHANGED 
3) Изменился стиль или нет - удобнее проверять при помощи Spy.
4) Попробуй с другим стилем - тем же WS_BORDER. 

Автор: 0x07L 21.7.2006, 09:02
1) Про ModifyStyle я знаю. Пробовал его до SetWindowLongPtr. Результаты те же.
2) Проверял изменение стилей с помощью Spy. Действительно, стиля LBS_DISABLENOSCROLL больше нет, но окно по-прежнему отображается как раньше.
3) С WS_BORDER действует... 

Автор: 0x07L 21.7.2006, 21:14
Ладно, будем считать, что никому после создания окна не нужно менять стиль WS_DISABLENOSCROLL  smile А WS_BORDER - нужно  smile  

Автор: 0x07L 22.7.2006, 13:16
Если же говорить честно, то дело, видимо, в том, что реализация стиля WS_BORDER (рисование рамки) осуществляется системой (если говорить конкретнее, функцией DefWindowProc), а реализация WS_DISABLENOSCROLL возложена на функцию элемента управления и DefWindowProc этот стиль игнорирует. ListBox стиль WS_DISABLENOSCROLL во время создания окна сохраняет где-то у себя и во время выполнения пользуется сохраненным значением и игнорирует стиль WS_DISABLENOSCROLL в стилях окна, хотя последний может изменяться. Плохо, что в MSDN об этом не сказано... 

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)