Модераторы: feodorv, GremlinProg, xvr, Fixin

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> custom button 
:(
    Опции темы
GP1000
Дата 10.4.2009, 18:49 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 27
Регистрация: 2.5.2008

Репутация: нет
Всего: нет



Подскажите пожалуйста как сделать кнопку на основе иконки .
Эта кнопка должна быть прозрачной по отношению к фону на котором она лежит .То есть в нормальном положении это должна быть одна иконка в нажатом положении другая . 
Я пробовал делать так :
Код

BOOL DrawFreeStyleBtn(LPDRAWITEMSTRUCT pis)
{
    POINT pos;
    HICON hIcon = LoadIcon(g_hInstance,MAKEINTRESOURCE(IDI_ICON1));
        
    switch(pis->itemAction)
        {
        case ODA_SELECT:
            if( pis->itemState & ODS_SELECTED){
               hIcon = LoadIcon(g_hInstance,MAKEINTRESOURCE(IDI_ICON2));
            }
            break;
        default:
            break;
        }
        DrawIconEx(pis->hDC,0,0,hIcon,WIDTH,HEIGHT,0,0,DI_NORMAL);
     return TRUE;
    return FALSE;
}
//...где то внутри процедуры окна 
case WM_DRAWITEM:
return DrawFreeStyleBtn( (LPDRAWITEMSTRUCT) lParam );

Иконка отрисовывается ,но кнопочный фон серый все равно остается .
Где и что я не правильно сделал?

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


Это сообщение отредактировал(а) GP1000 - 10.4.2009, 18:49
PM MAIL   Вверх
GremlinProg
Дата 15.4.2009, 17:38 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Комодератор
Сообщений: 2706
Регистрация: 9.8.2005
Где: Тюмень

Репутация: 99
Всего: 106



можно попробовать поиграться со стилем WS_EX_TRANSPARENT
но похоже, все равно придется перехватывать некоторый функционал кнопки, чтобы встроенная процедура окна ее не заливала
тут возможны 2 случая:

1. если фон закрашивается на WM_ERASEBKGND, то достаточно переопределить класс кнопки с нулевой кистьюWNDCLASS::hbrBackground (но я, честно говоря, не припомню, чтобы встроенные классы явно пользовались этим параметром)

2. если фон кнопки закрашивается еще и при рисовании, на WM_PAINT, (а скорее всего так и есть), то можно переопределить класс окна кнопки с заглушками на сообщения WM_ERASEBKGNDWM_PAINT и WM_PRINT, но это, по сути - создание нового класса окна


--------------------
"Гений всегда разумнее, чем умнее. Ум — это машина, разум — водитель этой машины."
PM WWW ICQ   Вверх
Andrey44
Дата 16.4.2009, 07:07 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1501
Регистрация: 4.12.2006
Где: На работе

Репутация: 8
Всего: 26



По моему это только писать самому свой класс для кнопки, по крайней мере я так и делал.
Но можно еще в WM_DRAWITEM рисовать кнопки, но это скажем не очень-то удобно, если кнопок много.


--------------------
????? ??, ??????? ?????.  smile 
PM MAIL WWW ICQ   Вверх
GremlinProg
Дата 16.4.2009, 10:26 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Комодератор
Сообщений: 2706
Регистрация: 9.8.2005
Где: Тюмень

Репутация: 99
Всего: 106



GP1000, через WM_DRAWITEM и рисует


--------------------
"Гений всегда разумнее, чем умнее. Ум — это машина, разум — водитель этой машины."
PM WWW ICQ   Вверх
Andrey44
Дата 16.4.2009, 11:20 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1501
Регистрация: 4.12.2006
Где: На работе

Репутация: 8
Всего: 26



GremlinProg, Я вижу что он рисует и как рисует.
А не выходит у него потому-что рисует в том HDC который приходит в LPDRAWITEMSTRUCT.
А нужно создавать в памяти рисовать в нем а потом выдавать на отрисовку. Я так и делал. 
Но очень неудобно когда много кнопок и много картинок.


--------------------
????? ??, ??????? ?????.  smile 
PM MAIL WWW ICQ   Вверх
GremlinProg
Дата 16.4.2009, 13:00 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Комодератор
Сообщений: 2706
Регистрация: 9.8.2005
Где: Тюмень

Репутация: 99
Всего: 106



Цитата(Andrey44 @  16.4.2009,  13:20 Найти цитируемый пост)
А нужно создавать в памяти рисовать в нем а потом выдавать на отрисовку.

 smile двойная буферизация тут совсем ни при чем, и ошибки тут нет


GP1000, пробовал с WS_EX_TRANSPARENT?


--------------------
"Гений всегда разумнее, чем умнее. Ум — это машина, разум — водитель этой машины."
PM WWW ICQ   Вверх
Andrey44
Дата 16.4.2009, 14:18 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1501
Регистрация: 4.12.2006
Где: На работе

Репутация: 8
Всего: 26



Цитата(GremlinProg @  16.4.2009,  13:00 Найти цитируемый пост)
двойная буферизация тут совсем ни при чем, и ошибки тут нет

А кто говорил об ошибке?
Цитата(GP1000 @  10.4.2009,  18:49 Найти цитируемый пост)
Иконка отрисовывается ,но кнопочный фон серый все равно остается .
Где и что я не правильно сделал?

А надо рисовать то что находится под кнопкой. Правильно?



--------------------
????? ??, ??????? ?????.  smile 
PM MAIL WWW ICQ   Вверх
GremlinProg
Дата 16.4.2009, 14:35 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Комодератор
Сообщений: 2706
Регистрация: 9.8.2005
Где: Тюмень

Репутация: 99
Всего: 106



Цитата(Andrey44 @  16.4.2009,  16:18 Найти цитируемый пост)
А кто говорил об ошибке?

Цитата(Andrey44 @  16.4.2009,  13:20 Найти цитируемый пост)
А не выходит у него потому-что рисует в том HDC который приходит в LPDRAWITEMSTRUCT.


Цитата(Andrey44 @  16.4.2009,  16:18 Найти цитируемый пост)
А надо рисовать то что находится под кнопкой. Правильно?

правильно, но двойной буфер без WS_EX_TRANSPARENT прозрачности не принесет ни коим образом


--------------------
"Гений всегда разумнее, чем умнее. Ум — это машина, разум — водитель этой машины."
PM WWW ICQ   Вверх
Andrey44
Дата 16.4.2009, 14:42 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1501
Регистрация: 4.12.2006
Где: На работе

Репутация: 8
Всего: 26



Цитата(GremlinProg @  16.4.2009,  14:35 Найти цитируемый пост)
без WS_EX_TRANSPARENT прозрачности не принесет ни коим образом 

А причем тут WS_EX_TRANSPARENT? Он по-моему вообще не работает. Хотя не стану утверждать.
А делал я так. Брал HDC родительского окна брал из его битмапа область над которой находится кнопка и рисовал ее на саму кнопку, по-моему все понятно , а вы стали ко мне придираться.


--------------------
????? ??, ??????? ?????.  smile 
PM MAIL WWW ICQ   Вверх
GremlinProg
Дата 16.4.2009, 14:58 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Комодератор
Сообщений: 2706
Регистрация: 9.8.2005
Где: Тюмень

Репутация: 99
Всего: 106



Цитата(Andrey44 @  16.4.2009,  16:42 Найти цитируемый пост)
Брал HDC родительского окна брал из его битмапа область над которой находится кнопка и рисовал ее на саму кнопку, по-моему все понятно , а вы стали ко мне придираться.

я не придираюсь, такой метод будет работать только если родительское окно не отсекает дочерние и это не самый хороший вариант, поскольку накладывает ограничения на родительское окно, а WS_EX_TRANSPARENT заставляет это родительское окно рисовать себя прежде, чем дочернее будет отрисовано, тогда можно гарантировать, что задний фон дочернего уже будет содержать часть родителя, без дополнительных операций


--------------------
"Гений всегда разумнее, чем умнее. Ум — это машина, разум — водитель этой машины."
PM WWW ICQ   Вверх
Andrey44
Дата 16.4.2009, 15:09 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1501
Регистрация: 4.12.2006
Где: На работе

Репутация: 8
Всего: 26



GremlinProg, вы хотите сказать если я кнопке поставлю стиль WS_EX_TRANSPARENT, то она будет прозрачная?


--------------------
????? ??, ??????? ?????.  smile 
PM MAIL WWW ICQ   Вверх
GremlinProg
Дата 16.4.2009, 15:18 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Комодератор
Сообщений: 2706
Регистрация: 9.8.2005
Где: Тюмень

Репутация: 99
Всего: 106



Цитата(Andrey44 @  16.4.2009,  17:09 Найти цитируемый пост)
вы хотите сказать если я кнопке поставлю стиль WS_EX_TRANSPARENT, то она будет прозрачная?

нет, я уже писал что для этого требуется: http://forum.vingrad.ru/index.php?showtopi...t&p=1843435


--------------------
"Гений всегда разумнее, чем умнее. Ум — это машина, разум — водитель этой машины."
PM WWW ICQ   Вверх
Andrey44
Дата 16.4.2009, 15:21 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1501
Регистрация: 4.12.2006
Где: На работе

Репутация: 8
Всего: 26



Хорошо, не будем спорить.
Но я написал то что делал, и все работает.


--------------------
????? ??, ??????? ?????.  smile 
PM MAIL WWW ICQ   Вверх
Emura
Дата 21.4.2009, 15:14 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 102
Регистрация: 7.2.2009

Репутация: 1
Всего: 1



Задам здесь вопрос.

Andrey44
Цитата

А делал я так. Брал HDC родительского окна брал из его битмапа область над которой находится кнопка и рисовал ее на саму кнопку, по-моему все понятно


GremlinProg
Цитата

такой метод будет работать только если родительское окно не отсекает дочерние


Именно WS_CLIPCHILDREN и не дает нормально реализовать прозрачность, подскажите как побороть..



PM   Вверх
GremlinProg
Дата 21.4.2009, 17:05 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Комодератор
Сообщений: 2706
Регистрация: 9.8.2005
Где: Тюмень

Репутация: 99
Всего: 106



ладно, уговорили,
привожу пример использования WS_EX_TRANSPARENT:
Код

// transparency.cpp : Defines the entry point for the application.
//
#define WIN32_LEAN_AND_MEAN             // Exclude rarely-used stuff from Windows headers
#include <windows.h>
#include <stdlib.h>
#include <malloc.h>
#include <memory.h>
#include <tchar.h>
#include <string>

LRESULT CALLBACK    WndProc(HWND, UINT, WPARAM, LPARAM);
LRESULT CALLBACK    TransparencyControl(HWND, UINT, WPARAM, LPARAM);

int APIENTRY _tWinMain(HINSTANCE hInstance,HINSTANCE hPrevInstance,LPTSTR lpCmdLine,int nCmdShow){
    MSG msg;
    WNDCLASSEX wcex;
    HWND hWnd,hWndChild;
    //
    UNREFERENCED_PARAMETER(hPrevInstance);
    UNREFERENCED_PARAMETER(lpCmdLine);
    //
    wcex.cbSize            = sizeof(WNDCLASSEX);
    wcex.style            = CS_HREDRAW | CS_VREDRAW;
    wcex.lpfnWndProc    = WndProc;
    wcex.cbClsExtra        = 0;
    wcex.cbWndExtra        = 0;
    wcex.hInstance        = hInstance;
    wcex.hIcon            = ::LoadIcon(NULL,IDI_APPLICATION);
    wcex.hCursor        = ::LoadCursor(NULL, IDC_ARROW);
    wcex.hbrBackground    = ::GetSysColorBrush(COLOR_BTNFACE);
    wcex.lpszMenuName    = NULL;
    wcex.lpszClassName    = _T("TransparencyControlApplication");
    wcex.hIconSm        = ::LoadIcon(NULL,IDI_APPLICATION);
    if( ::RegisterClassEx(&wcex) ){
        hWnd = ::CreateWindowEx(
            0,
            wcex.lpszClassName,
            _T("пример для флага WS_EX_TRANSPARENT"),
            WS_OVERLAPPEDWINDOW | WS_CLIPCHILDREN,
            CW_USEDEFAULT,0,
            300,300,NULL,NULL,
            hInstance,NULL
        );
        if(!hWnd){
            return FALSE;
        }
        wcex.style            = 0;
        wcex.lpfnWndProc    = TransparencyControl;
        wcex.cbClsExtra        = 0;
        wcex.cbWndExtra        = 0;
        wcex.hInstance        = hInstance;
        wcex.hIcon            = NULL;
        wcex.hCursor        = ::LoadCursor(NULL,IDC_ARROW);
        wcex.hbrBackground    = NULL;
        wcex.lpszMenuName    = NULL;
        wcex.lpszClassName    = _T("TransparencyControl");
        wcex.hIconSm        = NULL;
        if( ::RegisterClassEx(&wcex) ){
            hWndChild    = ::CreateWindowEx(
                WS_EX_TRANSPARENT,
                wcex.lpszClassName,
                _T("Иконка IDI_EXCLAMATION на фоне текста с прозрачным фоном\r\nразноцветные прямоугольники рисуются на родителе"),
                WS_CHILD,0,0,150,150,
                hWnd,NULL,
                hInstance,NULL
                );
            if( hWndChild ){
                ::ShowWindow(hWndChild, nCmdShow);
            }
        }
        ::ShowWindow(hWnd, nCmdShow);
        ::UpdateWindow(hWnd);
    }
    while(::GetMessage(&msg, NULL, 0, 0)){
        ::TranslateMessage(&msg);
        ::DispatchMessage(&msg);
    }
    return(int)msg.wParam;
}
LRESULT CALLBACK TransparencyControl(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam){
    switch( message ){
        case WM_PAINT:{
            PAINTSTRUCT ps;
            RECT rc;
            std::wstring text;
            HGDIOBJ hBrush,hPen;
            HICON hIcon;
            //
            ::GetClientRect(hWnd,&rc);
            ::BeginPaint(hWnd,&ps);
            text.resize( ::GetWindowTextLength(hWnd) );
            hBrush    = ::SelectObject(ps.hdc,::GetStockObject(NULL_BRUSH));
            hPen    = ::SelectObject(ps.hdc,::GetStockObject(DC_PEN));
            ::SetDCPenColor(ps.hdc,RGB(0,255,0));
            ::Rectangle(ps.hdc,rc.left,rc.top,rc.right,rc.bottom);
            if( !text.empty() ){
                ::InflateRect(&rc,-1,-1);
                ::GetWindowTextW(hWnd,&*text.begin(),text.size() + 1);
                ::SetBkMode(ps.hdc,TRANSPARENT);
                ::DrawTextW(ps.hdc,text.c_str(),text.size(),&rc, DT_VCENTER | DT_CENTER | DT_WORDBREAK);
            }
            hIcon    = ::LoadIcon(NULL,IDI_EXCLAMATION);
            ::DrawIconEx(ps.hdc,0,0,hIcon,0,0,0,NULL,DI_NORMAL);
            ::DestroyIcon(hIcon);
            ::SelectObject(ps.hdc,hPen);
            ::SelectObject(ps.hdc,hBrush);
            ::EndPaint(hWnd,&ps);
            break;
        }
    }
    return::DefWindowProc(hWnd,message,wParam,lParam);
}
LRESULT CALLBACK WndProc(HWND hWnd,UINT message,WPARAM wParam,LPARAM lParam){
    switch( message ){
        case WM_PAINT:{
            PAINTSTRUCT ps;
            RECT rc;
            HGDIOBJ hPen;
            //
            ::BeginPaint(hWnd, &ps);
            ::SetRect(&rc,10,10,160,160);
            hPen    = ::SelectObject(ps.hdc,::GetStockObject(DC_PEN));
            for(int i = 10;i--;){
                if(i & 1){
                    ::SetDCPenColor(ps.hdc,RGB(255,0,0));
                }else{
                    ::SetDCPenColor(ps.hdc,RGB(0,0,255));
                }
                ::Rectangle(ps.hdc,rc.left,rc.top,rc.right,rc.bottom);
                ::InflateRect(&rc,-3,-3);
            }
            ::SelectObject(ps.hdc,hPen);
            ::EndPaint(hWnd,&ps);
            break;
        }
        case WM_DESTROY:{
            ::PostQuitMessage(0);
            break;
        }
    }
    return::DefWindowProc(hWnd, message, wParam, lParam);
}

в приложении - скомпилированный exe'шник
как видно, все прозрачно без лишних заморочек

Добавлено через 3 минуты и 3 секунды
Цитата(Emura @  21.4.2009,  17:14 Найти цитируемый пост)
Именно WS_CLIPCHILDREN и не дает нормально реализовать прозрачность, подскажите как побороть..

в пример этот флаг тоже включен

Присоединённый файл ( Кол-во скачиваний: 38 )
Присоединённый файл  transparency.rar 26,87 Kb


--------------------
"Гений всегда разумнее, чем умнее. Ум — это машина, разум — водитель этой машины."
PM WWW ICQ   Вверх
Страницы: (3) Все [1] 2 3 
Ответ в темуСоздание новой темы Создание опроса
Правила форума "C/C++: Системное программирование и WinAPI"
Fixin
GremlinProg
xvr
feodorv
  • Большое количество информации и примеров с использованием функций WinAPI можно найти в MSDN
  • Описание сообщений, уведомлений и примеров с использованием компонент WinAPI (BUTTON, EDIT, STATIC, и т.п.), можно найти в MSDN Control Library
  • Непосредственно, перед созданием новой темы, проверьте заголовок и удостоверьтесь, что он отражает суть обсуждения.
  • После заполнения поля "Название темы", обратите внимание на наличие и содержание панели "А здесь смотрели?", возможно Ваш вопрос уже был решен.
  • Приводите часть кода, в которой предположительно находится проблема или ошибка.
  • Если указываете код, пользуйтесь тегами [code][/code], или их кнопочными аналогами.
  • Если вопрос решен, воспользуйтесь соответствующей ссылкой, расположенной напротив названия темы.
  • Один топик - один вопрос!
  • Перед тем как создать тему - прочтите это .

На данный раздел распространяются Правила форума и Правила раздела С++:Общие вопросы .


Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, Chipset, Step, Fixin, GremlinProg, xvr. feodorv.

 
1 Пользователей читают эту тему (1 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | C/C++: Системное программирование и WinAPI | Следующая тема »


 




[ Время генерации скрипта: 0.0945 ]   [ Использовано запросов: 21 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.