Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > C/C++: Системное программирование и WinAPI > Фон элементов управления


Автор: Kostik88 24.7.2008, 20:24
Здравствуйте! Сталкнулся с такой проблемой: закрашиваю клиентскую область окна белой кистью ( WHITE_BTUSH), на закрашиваемом окне имеются элементы управления(две кнопки и один чекбокс), так вот при закраске их фон не меняется(см. прикреплённый файл). Вопрос, какбы можно убрать этот фон не совпадающий с цветом фона окна?

Автор: SABROG 24.7.2008, 21:33
Все элементы управления в программе - отдельные окна со своим фоном.

Автор: mes 24.7.2008, 21:55
есть флаг по использованию родительского контекста, точно не помню как в винапи он будет 
типа (CS_) WS_PARENTDC

Автор: Kostik88 24.7.2008, 22:11
Цитата

Все элементы управления в программе - отдельные окна со своим фоном. 

Это я знаю, вовпрос не в том что все элементы это окна со своим фоном, а в том как этот самый фон изменить. smile 

Автор: mes 24.7.2008, 22:24
Цитата(Kostik88 @  24.7.2008,  22:11 Найти цитируемый пост)

Это я знаю, вовпрос не в том что все элементы это окна со своим фоном, а в том как этот самый фон изменить.

флаг пробовал ставить? 

Автор: Dem_max 25.7.2008, 05:17
Юзай сообщения, и возвращяй нужный цвет.

      case WM_CTLCOLORBTN:
      case WM_CTLCOLORSTATIC:
      {
         SetBkMode((HDC)wParam,TRANSPARENT);
         return (LRESULT) GetSysColorBrush(COLOR_BTNFACE);
      }

Ноя так понял тебя интересует стиль как у винды  ?
то юзай такой код, после создания окна нужно этой функции передать HWND окна (диалога):

Код

//Гдето в заголовке
typedef HRESULT (WINAPI * ETDTProc) (HWND, DWORD);

// Сама функция
BOOL EnableDialogTheme(HWND hwnd)
{
    HMODULE hUXTheme;
    ETDTProc fnEnableThemeDialogTexture;

    hUXTheme = LoadLibrary(_T("uxtheme.dll"));

    if(hUXTheme)
    {
        fnEnableThemeDialogTexture = 
            (ETDTProc)GetProcAddress(hUXTheme, "EnableThemeDialogTexture");

        if(fnEnableThemeDialogTexture)
        {
            fnEnableThemeDialogTexture(hwnd, ETDT_ENABLETAB);

            FreeLibrary(hUXTheme);
            return TRUE;
        }
        else
        {
            FreeLibrary(hUXTheme);
            return FALSE;
        }
    }
    else
    {
        return FALSE;
    }
}

Автор: mes 25.7.2008, 08:45
Цитата(Dem_max @  25.7.2008,  05:17 Найти цитируемый пост)
Ноя так понял тебя интересует стиль как у винды  ?

так ведь в атаче на скриншоте уже установлен ХP-стиль ... smile 

Автор: Kostik88 25.7.2008, 14:30
Цитата

флаг пробовал ставить?  

Пробовал, но результат никакой.

Код

SetClassLong(hBottom,GCL_STYLE,GetClassLong(hBottom,GСL_STYLE) | CS_PARENTDC);

Автор: mes 25.7.2008, 16:00
Цитата(Kostik88 @  25.7.2008,  14:30 Найти цитируемый пост)
Пробовал, но результат никакой.

тогда только как предложил Dem_max- надо перегрузить ответ на дочерний запрос родителю о атрибутах 

Автор: Kostik88 25.7.2008, 17:36
Dem_max, Вот к примеру я пишу обработку сообщения для чекбокса :

Цитата

case WM_CTLCOLORSTATIC: 
         SetBkMode((HDC)GetWindowDC(hChec),TRANSPARENT);
         return (LRESULT) GetSysColorBrush(COLOR_BTNFACE);   
      break;


Только цвет фона  чекбокса не меняется. 0о

Автор: Dem_max 25.7.2008, 17:51
Цитата

так ведь в атаче на скриншоте уже установлен ХP-стиль

Нифига не установлен, ты к к ехе только присобачил манифест, 'nnjlftn возможность отображать контролы в стиле XP, а тему ХР можно задать только через EnableDialogTheme(HWND hwnd)

Автор: Kostik88 25.7.2008, 18:03
Цитата

Нифига не установлен, ты к к ехе только присобачил манифест, 'nnjlftn возможность отображать контролы в стиле XP, а тему ХР можно задать только через EnableDialogTheme(HWND hwnd) 



Чтобы убрать этот фон с элементов управления мне обязательно нужно ставить тему ХР чтоли?

А присобачил манифест Я, а не mes  smile 

Автор: Dem_max 26.7.2008, 14:00
Цитата

Чтобы убрать этот фон с элементов управления мне обязательно нужно ставить тему ХР чтоли?


Не ты функцией активизируешь текущую тему. Текущей может быть стандартная или которая изменяет оформление рабочего стола, ты бы лучше сделал как говорят и не ...... нам мозг.

Автор: Kostik88 26.7.2008, 15:00
Dem_max, меньше всего мне хочется ......., такому как ты, мозг!

Автор: mekhanikus 27.7.2008, 14:45
Цитата(Kostik88 @ 25.7.2008,  17:36)
Dem_max, Вот к примеру я пишу обработку сообщения для чекбокса :

Цитата

case WM_CTLCOLORSTATIC: 
         SetBkMode((HDC)GetWindowDC(hChec),TRANSPARENT);
         return (LRESULT) GetSysColorBrush(COLOR_BTNFACE);   
      break;


Только цвет фона  чекбокса не меняется. 0о

Попробуй сделать так:

Код


case WM_CTLCOLORSTATIC: 
         SetBkMode((HDC)GetWindowDC(hChec),TRANSPARENT);
         return GetSysColorBrush(COLOR_BTNFACE);   
      break;



Функция должна возвращать HBRUSH, а ты возвращаеш LRESULT.

Автор: Kostik88 28.7.2008, 00:03
mekhanikus,  так всё правильно, обработчик события WM_CTLCOLORSTATIC возвращает значения BOOL - го типа и поэтому LRESULT, если ставить значение HBRUSH компилятор просто напросто будет ругаться.

Кому интересно про включение ХP те могут глянуть  сайтик, похожая проблема, такаяже ф-ция.... Но почемуто у меня она отказывается работать.

http://forum.sources.ru/index.php?showtopic=219977

Добавлено через 13 минут и 23 секунды
Просто будет выдаваться ошибка:

'return' : cannot convert from 'HBRUSH' to 'BOOL'

Автор: mes 28.7.2008, 00:33
Цитата(Kostik88 @  25.7.2008,  17:36 Найти цитируемый пост)
Вот к примеру я пишу обработку сообщения для чекбокса :
Код


case WM_CTLCOLORSTATIC: 
         SetBkMode((HDC)GetWindowDC(hChec),TRANSPARENT);
         return (LRESULT) GetSysColorBrush(COLOR_BTNFACE);   
      break;


Во первых где ты ловишь сообщение? у родителя ? приходит или нет?
Во вторых не кажется ли окончание static подозрительным? 
Чекбокс как никак кнопка. Мне кажется, что в данном случае надо использовать WM_CTLCOLORBTN  smile 



Автор: Kostik88 28.7.2008, 00:51
Цитата

Чекбокс как никак кнопка. Мне кажется, что в данном случае надо использовать WM_CTLCOLORBTN  

Я тоже так думаю=) только не шипко помогло(

Цитата

Во первых где ты ловишь сообщение? у родителя ?


Сообщение ловлю у родителя.

Цитата

приходит или нет?



приходит.

Автор: Dem_max 28.7.2008, 06:49
Можно еще так

#include <uxtheme.h>
#pragma comment(lib, "UxTheme.lib")

SetWindowTheme(hwndList, L"Explorer", NULL);

Автор: Kostik88 28.7.2008, 11:40
Вроде бы решил проблему:

для бутонов:

Код

     case WM_CTLCOLORBTN:
{    
         
         return (LRESULT) GetStockObject(WHITE_BRUSH);  
          }


и для чекбокса:

Код

case WM_CTLCOLORSTATIC: 
          {    
                    
         return (LRESULT) GetStockObject(WHITE_BRUSH);  
          }



теперь фон кнопок и чекбоксов меняется.

Добавлено через 2 минуты и 54 секунды
А если хочется поставить любой другой фон то можно воспользоваться ф-цией CreateSolidBrush =)

Автор: mekhanikus 28.7.2008, 15:26
Странно.
Читаем про WM_CTLCOLORSTATIC

Цитата

Return Value

If an application processes this message, the return value is a handle to a brush that the system uses to paint the background of the static control.


Тоже самое про WM_CTLCOLORBTN.

Кинь исходник, если не жалко, самый минимум, как ты кнопки делаешь и красишь.
Интересно самомы скомпилить.

Автор: Kostik88 28.7.2008, 16:14
mekhanikus,  Я не совсем понял что тебя в этих сообщения не устраивает и в чём твое негодование относительно цитаты из msdn?
Код выкладывать не буду ибо там больше 3 тысяч строк кода. Хочешь проверить сделай простой проект прикрепи к нему диалог с помощью Resource View и кинь на него кнопочки и проверь эти сообщения.

Автор: Draeden 28.7.2008, 18:43
Любопытная задачка: нужно поменять значения поля в WNDCLASS созданного ранее через RegisterWindowClass.
Интересно посмотреть, есть ли красивое решение...

Автор: mes 28.7.2008, 23:26
Цитата(Draeden @  28.7.2008,  18:43 Найти цитируемый пост)
Любопытная задачка: нужно поменять значения поля в WNDCLASS созданного ранее через RegisterWindowClass.
Интересно посмотреть, есть ли красивое решение... 

если я правильно понял то Вам нужно SetClassLong

Добавлено через 1 минуту и 44 секунды
также непонятно почему вопрос поместили в этом топике.. в чем связь с темой ?? 

Автор: mekhanikus 29.7.2008, 12:45
Цитата(Kostik88 @ 28.7.2008,  16:14)
в чём твое негодование относительно цитаты из msdn?


Никакого негодования, спокоен как удав.

Просто, у меня был опыт раскрашивания статиков.
При этом в DialogProc сообщения обрабатывались макросами HANDLE_MSG,
с последующим вызовом соответствующих функций.
Так вот функция раскраски статиков возвращала HBRUSH, и все работало.

Сейчас попробовал стелать тоже самое без HANDLE_MSG,
действительно, без (LRESULT) ругается. smile 
Оказывается в HANDLE_MSG сделано тоже самое - преобразование в LRESULT.
Век живи - век учись.  smile 

Кстати PUSHBUTTON у меня нехотят краситься никак.

Автор: Draeden 29.7.2008, 13:57
Цитата(mes @ 28.7.2008,  23:26)
Цитата(Draeden @  28.7.2008,  18:43 Найти цитируемый пост)
Любопытная задачка: нужно поменять значения поля в WNDCLASS созданного ранее через RegisterWindowClass.
Интересно посмотреть, есть ли красивое решение... 

если я правильно понял то Вам нужно SetClassLong

Добавлено @ 23:28
также непонятно почему вопрос поместили в этом топике.. в чем связь с темой ?? 

Цитата(Draeden @  28.7.2008,  18:43 Найти цитируемый пост)
Любопытная задачка: нужно поменять значения поля в WNDCLASS созданного ранее через RegisterWindowClass.
Интересно посмотреть, есть ли красивое решение... 

если я правильно понял то Вам нужно SetClassLong

Добавлено @ 23:28
также непонятно почему вопрос поместили в этом топике.. в чем связь с темой ??

Это не мой вопрос. Автор темы хочет поменять цвет фона для определённого окна, а также для всех его дочерних окон. Цвет фона определяется полем в структуре WNDCLASS которая регистрируется функцией RegisterClass. Таким образом нужно

1. найти все дочерние окна
2. определить классы всех окон - родительского и дочерних ( этот класс возвращается функцией RegisterClass и указывается при вызове CreateWindow )
3. найти структуры WNDCLASS для найденных классов ( я не вижу документированного способа сделать это )
4. изменить соотвтесвующее поля в этой структуре ( кисть фона )
5. обновить родительское окно со всеми дочерними окнами

Проблема - п.3, всё остальное сделать просто.

Автор: Kostik88 29.7.2008, 14:37
Draeden,  если Вы не заметили то вопрос уже решён, кодом в несколько строк.

Автор: mes 29.7.2008, 14:50
Цитата(Draeden @  29.7.2008,  13:57 Найти цитируемый пост)
3. найти структуры WNDCLASS для найденных классов ( я не вижу документированного способа сделать это )


Цитата(Draeden @  29.7.2008,  13:57 Найти цитируемый пост)
Это не мой вопрос. Автор темы хочет поменять цвет фона для определённого окна, а также для всех его дочерних окон. Цвет фона определяется полем в структуре WNDCLASS которая регистрируется функцией RegisterClass. Таким образом нужно

Цвет фона класса окон, а не отдельно взятого окна.  
Цитата(Draeden @  29.7.2008,  13:57 Найти цитируемый пост)
3. найти структуры WNDCLASS для найденных классов ( я не вижу документированного способа сделать это )

Цитата(mes @  28.7.2008,  23:26 Найти цитируемый пост)
... Вам нужно SetClassLong

http://msdn.microsoft.com/en-us/library/ms633588(VS.85).aspx

Автор: Draeden 29.7.2008, 16:07
И то верно, надо MSDN внимательнее читать smile

Автор: Dem_max 30.7.2008, 07:22
Kostik88, 
Цитата

теперь фон кнопок и чекбоксов меняется.
А если хочется поставить любой другой фон то можно воспользоваться ф-цией CreateSolidBrush =)


Ага а ты попробуй Оформление XP поставить на классический вид или оформление другое поставь из сторонних разработчиков и получишь гимморой, и тогда фон будет другим цветом и твои статики будут закрашиваться белым цветом, а подбирать через СreateSolidBrush  у тебя не получится.

А чтою этого небыло используется SetWindowTheme(hwndList, L"Explorer", NULL), которая сама автоматически раскрашивает контролы с установленной цветовой схемой в системе, при этом эта функция вызывается только для родительского окна или для диалога который создается на TabControl/

Автор: Kostik88 30.7.2008, 12:01
Цитата

А чтою этого небыло используется SetWindowTheme(hwndList, L"Explorer", NULL), которая сама автоматически раскрашивает контролы с установленной цветовой схемой в системе, при этом эта функция вызывается только для родительского окна или для диалога который создается на TabControl/ 


Нихрена она не ставится! Говорил же уже!

Добавлено через 2 минуты и 47 секунд
Цитата

Ага а ты попробуй Оформление XP поставить на классический вид или оформление другое поставь из сторонних разработчиков и получишь гимморой, и тогда фон будет другим цветом и твои статики будут закрашиваться белым цветом, а подбирать через СreateSolidBrush  у тебя не получится.


пробовал и всё нормально никокого гимароя не вылезло! манифест тоже не просто так существует!

Добавлено через 8 минут и 20 секунд
И к томуже это для Лист контрола тема SetWindowTheme(hwndList, L"Explorer", NULL)

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