2009-06-25 5 views
4

Мы пишем настольные приложения для Windows с использованием C++ и Win32. Наши диалоговые окна имеют уродливый внешний вид с «стилем Windows XP»: фон для статического текста серый. Если фон диалогового окна также серый, это не проблема, но внутри элемента управления вкладки, где фон белый, серый фон для текста очень заметен.Windows XP Стиль: Почему мы получаем темно-серый фон на статических текстовых виджетах?

В прошлом мы сделали много собственных чертежей элементов управления, но в наши дни мы стараемся как можно больше использовать стандартный look'n'feel и избегать как можно большего превышения стандартного поведения.

Мы используем API Win32, который немного устарел, но я думаю, что проблема возникает даже с ATL. Мы создаем DIALOGTEMPLATE. Текст находится в «статическом» элементе управления (0x0082). Единственный флаг, который мы установили для стиля, - «SS_LEFT». Текстовый элемент управления находится внутри элемента управления вкладкой: «SysTabControl32» с только одним флагом: WS_CLIPSIBLINGS, установленным на нем. Я экспериментировал с SS_WHITERECT и WS_EX_TRANSPARENT и другими настройками, но безрезультатно.

Все это нарисовано стандартным обработчиком сообщений диалогового окна Windows. Мой главный вопрос: «Что мы делаем не так?» а не «как я могу обойти это?», хотя я соглашусь на последнее, если никто не сможет помочь мне с первым.

Любые идеи?

+0

Вы не видите, что вы используете файл манифеста для просмотра темы XP? – Rob

+0

Да, мы: #pragma comment (linker, "/ manifestdependency: \" type = 'win32' "\ " name = 'Microsoft.Windows.Common-Controls' "\ " version = '6.0.0.0' "\ " processorArchitecture = '*' "\ " publicKeyToken = '6595b64144ccf1df' "\ " language = '*' \ "") –

ответ

0

Мы не переопределяем сообщение WM_CTLCOLORSTATIC. В нашем исходном коде нет такой строки, и в наших обработчиках сообщений ничего подобного нет.

Мы столкнулись с этой проблемой, переопределив сообщение WM_DRAWITEM для элементов управления вкладками, чтобы нарисовать их содержимое серым фоном (стандартным для диалоговых окон без элементов управления вкладками), а не на белом фоне (стандартный для содержимого элементов управления вкладками) ,

 brush = CreateSolidBrush(GetSysColor(COLOR_MENU)); 
     FillRect(lpdis->hDC, &lpdis->rcItem, brush); 
     SetBkColor(lpdis->hDC, GetSysColor(COLOR_MENU)); 
     wtext = ToWideStrdup(c->u.tabcontrol.Tabs[lpdis->itemID].name); 
     rect = lpdis->rcItem; 
     rect.top += DlgMarginY - 1; 
     rect.bottom += DlgMarginY; 
     DrawTextW(lpdis->hDC, wtext, -1, &rect, DT_CENTER | DT_VCENTER); 
     free(wtext); 
     DeleteObject(brush); 

Это, очевидно, обходной путь, а не правильный ответ на мой вопрос.

Кстати, мы инициализируем «общие элементы управления», из которых, я считаю, элемент управления вкладками один, используя такой код ... Я не думаю, что это связано с проблемой?

#pragma comment(linker, "/manifestdependency:\"type='win32' " \ 
    "name='Microsoft.Windows.Common-Controls' " \ 
    "version='6.0.0.0' " \ 
    "processorArchitecture='*' " \ 
    "publicKeyToken='6595b64144ccf1df' " \ 
    "language='*'\"") 
... 

hCommCtrl = GetModuleHandle("comctl32.dll");` 
if (hCommCtrl) { 
     ptrInit = (TfcInit_fn) GetProcAddress(hCommCtrl, "InitCommonControlsEx"); 
     if (ptrInit) { 
      data.dwSize = sizeof(INITCOMMONCONTROLSEX); 
      data.dwICC = ctrlClass; 
      if (ptrInit(&data)) 
       gCommCtrlsInitialized |= ICC_TAB_CLASSES | ICC_BAR_CLASSES; 
     } 
} 
+2

-1 для неправильного ответа. –

0

У меня есть приложения Win32/MFC с надписями внутри вкладок в диалогах, а цвет фона выглядит хорошо на них (то есть он отражает тему XP-look, а не плоский серый) без какой-либо очевидной специальной обработки ,

Под капотом должно произойти, что метка отправляет сообщение WM_CTLCOLOR его родительскому элементу, которое соответствующим образом устанавливает контекст устройства: обработка по умолчанию в Windows должна устанавливать соответствующий цвет фона, по крайней мере для диалогов и элементов управления вкладками ,

Возможно, вы используете что-то нестандартное при обработке WM_CTLCOLOR: оно перегружено где-то в вашем приложении? Возможно, у вас есть старый код, который устанавливает цвет фона метки таким образом.

(также, как и спрашивает Роб, вы используете манифест, чтобы получить COMCTL32 6.0 в приложение?)

4

Причина, почему фон серый, потому что это по умолчанию.

Чтобы отменить его, вы можете обработать сообщение WM_CTLCOLORSTATIC в родительском окне и вернуть пользовательскую кисть.

+0

Gray является _not_ по умолчанию для содержимого элемента управления вкладки с стилем XP. –

+1

@ Тим: вам не хватает точки. Серый по умолчанию используется для * статических элементов управления *. –

+0

@ Ханс: Я понимаю это. Мы используем цвета по умолчанию для всех элементов управления, но проблема в том, что это выглядит странно, потому что белый является фоном по умолчанию для элементов управления вкладками, но серый является фоном по умолчанию для статических элементов управления. Таким образом, мы получаем фон с пэчворком. –

1

Ваша проблема не в ATL или WinAPI. В MFC существует та же проблема. Настройка управления вкладкой в ​​качестве родительского окна для элементов управления Static. Но я считаю, что переопределение WM_DRAWITEM - более гибкое решение.

6

Обычный способ реализации страниц в вкладке управления требуется для доступа решения МСА этой проблемы: -

Вместо создания отдельных элементов управления на вкладке области, создать немодальную диалог ребенка для каждой страницы и имеет контроль над этим. Создайте диалоги страниц с основным диалогом (а не с вкладкой) в качестве своего родителя, и когда пользователь переключается между вкладками, просто покажите и скройте соответствующий диалог страницы.

В WM_INITDIALOG обработчик для каждой страницы, вызовите UXTheme API EnableThemeDialogTexture

с ETDT_ENABLETAB флагом это автоматически изменяет цвет фона диалогового окна и все его дочерние элементы управления окрасить соответствующим образом на вкладке.

Если у вас есть переопределенные WM_ERASEBKGND или WM_CTLCOLOR* на ваших страницах DialogProc, вам нужно будет вернуться к обработке по умолчанию (возвращать FALSE), так как эти методы там, где код диалога собирается сделать свой тяжелый подъем. Биты стиля должны быть просто настроены так, как если бы страница диалога с дочерней страницей создавалась в обычном диалоговом окне с окнами 9X.

+0

Вы говорите, что использование элемента управления вкладкой «Общие элементы управления» Microsoft-библиотека (ICC_TAB_CLASSES, TabCtrl_SetCurSel) не является «обычным способом» реализации страниц в элементе управления вкладкой? То, что вы предлагаете, звучит как большая часть работы («создайте немодальное дочернее диалоговое окно для каждой страницы»). –

+0

+1, потому что вы, кажется, хорошо осведомлены об этом районе. –

+1

Чтобы упростить сложность элементов управления вкладками, существует API-интерфейс свойств. В листе свойств api реализованы страницы свойств вкладок, как описано в Ive: каждая страница с листами свойств предоставляется в виде отдельного диалога. Класс ICC_TAB_CLASSES используется для рисования (и управления) области вкладок элемента управления вкладки, но область содержимого управляется родительским диалоговым окном, отвечающим на сообщения уведомлений из элемента управления вкладками, скрывая и отображая соответствующий дочерний диалог. –

0

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

Как любитель обнаружил, что самым простым эффективным решением было просто создать дочернее окно класса «Статическое», которое охватывает все окно. Просто еще один уровень исправления взлома: