Здравствуйте
Имеется следующая задача — есть несколько контролов (Button, Radio, Checkbox) с переопределенной отрисовкой (картинка берется из png-файла). Контролы писал не я. Необходимо реализовать функцию отключения custom-отрисовки, что-то типа переключения тем в Windows.
1. Правильно ли следующее решение — завести глобальную переменную g_isNativeTheme, и проверять ее в каждом методе, имеющем отношеие к переопределению контрола. В методах типа DrawItem(), OnMouseMove() я вызывал метод родитеьского класса, примерно так:
if (g_isNativeTheme)
{
CButton::OnMouseMove(nFlags, point);
return;
}
Метода, характерные только для custom-контрола, превращаются в заглушки, например, OnTimer():
if (g_isNativeTheme) return;
2. Вышеуказанное решение работает только при перезапуске приложения. Когда я пытаюсь реализовать флажок Disable All Skins, примеро так:
void CSettingsGenDialog::OnBnClickedCheckSetgenDisskin()
{
UpdateData(TRUE); //считывает из checkbox
g_isNativeTheme = m_disableTheme;//устанавливаем глобальную переменную
//(здесь точно все работает!)
InvalidateRect(NULL);//обновить окно настроек
CWnd* w = AfxGetMainWnd();
w->InvalidateRect(NULL);//обновить главное окно
}
Но контролы не перерисовываются. Если идеи? Если моя ошибка очень грубая и очевидная, не бейте сильно по голове, ОК? Программист я пока очень начинающий
Здравствуйте, Yuri_Ch, Вы писали:
Y_C>1. Правильно ли следующее решение — завести глобальную переменную g_isNativeTheme, и проверять ее в каждом методе, имеющем отношеие к переопределению контрола.
К глобальным переменным вообще у многих людей отношение неоднозначное Я бы лучше создал метод например у объекта приложения:
class CMyApp: public CWinApp { /* ... * };
inline bool CMyApp::UseNativeTheme() {
return m_bUseNativeTheme;
}
Но это конечно не принципиально.
<...>
Y_C>2. Вышеуказанное решение работает только при перезапуске приложения.
Да прям... Пробовал окно развернуть/свернуть?
Y_C>Когда я пытаюсь реализовать флажок Disable All Skins, примеро так:
<...>
Y_C>Но контролы не перерисовываются. Если идеи? Если моя ошибка очень грубая и очевидная, не бейте сильно по голове, ОК? Программист я пока очень начинающий
Ну, что-то прояснилось
Перерисовка при снятии флажка (используется custom-отрисовка) работает! Но обратно вместо контрола отображается пустое окно. Я посмотрел, там изначально во всех классах контролов в OnEraseBkgnd() была заглушка
return TRUE;
может, из-за этого? Только как работало непонятно
И еще, кроме окна настроек и главного окна есть еще окна, там перерисовка тоже не происходит.
Здравствуйте, Yuri_Ch, Вы писали:
Y_C>Перерисовка при снятии флажка (используется custom-отрисовка) работает! Но обратно вместо контрола отображается пустое окно. Я посмотрел, там изначально во всех классах контролов в OnEraseBkgnd() была заглушка Y_C>
Y_C>return TRUE;
Y_C>
Y_C>может, из-за этого? Только как работало непонятно
Это говорит о том, что прорисовка фона по умолчанию не используется (возможно для того чтобы избежать мерцания). Является ли это причиной глюка не знаю, но думаю что если не используется кастомная отрисовка (т.е. когда соответствующий флажок снят), лучше бы не возвращать из этого метода TRUE, а вызывать обработку базового класса:
Другой вариант, не требующий использования списка — использовать EnumWindows (перечисление всех окон верхнего уровня), GetWindowThreadProcessId() (для определения того ,что окно принадлжеит нашему приложению), IsWindowVisible() (нет смысла перерисовывать невидимые окна), CWnd::FromHandle (для получения указателя на объект CWnd), CWnd::RedrawWindow (собственно перерисовка)
... << RSDN@Home 1.1.4 stable SR1 rev. 568>>
It is always bad to give advices, but you will be never forgiven for a good one.
Oscar Wilde