IMHO.WS

IMHO.WS (https://www.imho.ws/index.php)
-   Программирование (https://www.imho.ws/forumdisplay.php?f=40)
-   -   Owner Drawn Controls in WinAPI (https://www.imho.ws/showthread.php?t=76020)

chesnok 18.12.2004 20:36

Owner Drawn Controls in WinAPI
 
Недавно занимался сабжем, появился один вопрос:
как обработать WM_DRAWITEM для не только button'ов, но и group box, checkbox, radio button? В MSDN довольно подробно написано по поводу обычных кнопок, но про другие контролы - ни слова. STFW тоже пока ни к чему не привёл...

alexey_ma 19.12.2004 10:21

С точки зрения WinAPI group box, checkbox, radio button тоже являются кнопками. Они все имеют один и тотже оконный класс "Button", у них только различные оконные стили - BS_CHECKBOX ,BS_AUTORADIOBUTTON ,BS_GROUPBOX и т.д. По всей видимости обрабатываются точно также как и обычный button.

chesnok 19.12.2004 10:40

alexey_ma
Это я знаю, но мой обработчик сообщения WM_DRAWITEM изменяет только внешний вид кнопок со стилем BS_PUSHBUTTON, и абсолютно не трогает остальное, хотя написан так, чтоб обрабатывал всё с классом "button".

alexey_ma 19.12.2004 11:00

Код покажи, может чего-нибудь придумаем.

chesnok 19.12.2004 11:38

Часть DialogProc:
Код:

case WM_DRAWITEM:
                {
                        lpdis = (LPDRAWITEMSTRUCT) lParam;
                        DrawOwnControl(lpdis);                       
                       
                        break;
                }

Код:

void DrawOwnControl(LPDRAWITEMSTRUCT lpdis)
{
        HDC hMemDc = CreateCompatibleDC(lpdis->hDC);
        if(lpdis->CtlType == ODT_BUTTON) //its a button
        {
                LONG lStyle = GetWindowLong(lpdis->hwndItem, GWL_STYLE);
                if(lStyle & BS_GROUPBOX)
                {
                        //groupbox
                        LOGBRUSH lb;
                        lb.lbColor = RGB(0, 0, 0);
                        lb.lbStyle = BS_SOLID;
                        lb.lbHatch = NULL;
                        HBRUSH hBlack = CreateBrushIndirect(&lb);
                        SelectObject(lpdis->hDC, hBlack);
                        FloodFill(lpdis->hDC, 1, 1, RGB(125, 125, 125));
                }

                //button
                BOOL bDwnText;
               
                HBITMAP hBmpBtn = LoadBitmap(hInst, MAKEINTRESOURCE(IDB_RAISED_NOFOCUS)); //bitmap for button drawing, default = raised w/o focus
                bDwnText = FALSE;
                switch(lpdis->itemAction)
                {
                case ODA_SELECT:
                        {
                                if(lpdis->itemState & ODS_SELECTED)
                                {
                                        //down
                                        if(lpdis->itemState & ODS_FOCUS)
                                        {
                                                //down focused
                                                hBmpBtn = LoadBitmap(hInst, MAKEINTRESOURCE(IDB_DOWN_FOCUS));
                                                bDwnText = TRUE;
                                        }else
                                        {
                                                //down non-focused
                                                hBmpBtn = LoadBitmap(hInst, MAKEINTRESOURCE(IDB_DOWN_NOFOCUS));
                                                bDwnText = TRUE;
                                        }
                                }
                                break;
                        }
                case ODA_DRAWENTIRE:
                        {
                                if(lpdis->itemState & ODS_DISABLED)
                                {
                                        //grayed
                                        //the only difference is gray text instead of white

                                }
                                break;
                        }
                case ODA_FOCUS:
                        {
                                //raised with focus
                                if(lpdis->itemState & ODS_FOCUS)
                                {
                                        hBmpBtn = LoadBitmap(hInst, MAKEINTRESOURCE(IDB_RAISED_FOCUS));
                                        bDwnText = FALSE;
                                }
                                break;
                        }
                }
                SelectObject(hMemDc, hBmpBtn);
                StretchBlt(lpdis->hDC, lpdis->rcItem.left, lpdis->rcItem.top, lpdis->rcItem.right - lpdis->rcItem.left, lpdis->rcItem.bottom - lpdis->rcItem.top, hMemDc, 0, 0, 91, 26, SRCCOPY);
                uCurTextLen = GetWindowText(lpdis->hwndItem, szCurText, MAX_PATH);
                SetBkColor(lpdis->hDC, RGB(76, 88, 68));
                SetTextColor(lpdis->hDC, RGB(255, 255, 255));                       
                RECT rcForText = lpdis->rcItem;
                rcForText.left += STEAM_TEXT_OFFSET;
                if(bDwnText)
                {
                        //down text
                        rcForText.left += 2;
                        rcForText.top += 2;
                }
                //draw text
                DrawText(lpdis->hDC, szCurText, uCurTextLen, &rcForText, DT_SINGLELINE | DT_VCENTER);

                DeleteDC(hMemDc);
        }else
                if(lpdis->CtlType == ODT_LISTBOX) //listbox
                {
                    //to be done yet
                }
        return;
}

То, что выделено красным - попытка обработать group box, не увенчавшаяся успехом :(

alexey_ma 19.12.2004 12:26

Попробуй вместо WM_DRAWITEM обработать WM_CTLCOLOR -WM_CTLCOLORBTN

chesnok 19.12.2004 12:48

Их я тоже обрабатываю, но они отвечают за цвет текста/фона контрола + режим отображения этого текста и шрифт. А мне нужна именно собственноручная прорисовка всех деталей, а CTLCOLOR*** не позволяют это реализовать...

Вот такое я хочу получить в результате:
http://web.vrn.ru/chesnok/filez/target.GIF
Вот такое получается с помощью WM_CTLCOLOREDIT:
http://web.vrn.ru/chesnok/filez/my.GIF
То есть рамка остаётся дефаултной виндовой, и абсолютно не смотрится в таких цветах :(

alexey_ma 19.12.2004 16:27

group box, checkbox, radio button по всей видимости не посылают WM_DRAWITEM. MFC вообще не дает выставить стиль "Owner Draw" для таких контролов.
Из MSDN :
Код:

The WM_DRAWITEM message is sent to the parent window of an owner-drawn
 button, combo box, list box, or menu when a visual aspect of the button,
combo box, list box, or menu has changed.

Проблему с бордером вокруг контрола можно попытаться решить следующим образом: B обработчике WM_CTLCOLOR получить прямоугольник контрола и обрисовать его прямо по DC нужным тебе цветом.

chesnok 19.12.2004 17:39

Цитата:

Сообщение от alexey_ma
Проблему с бордером вокруг контрола можно попытаться решить следующим образом: B обработчике WM_CTLCOLOR получить прямоугольник контрола и обрисовать его прямо по DC нужным тебе цветом.

Сработало!!! Хотя это и достаточно топорное и нехорошее решение проблемы, но на безрыбье и рак - рыба :)

alexey_ma 19.12.2004 17:42

Согласен. Кривовато малость. Но я просто не знаю как по другому сделать.


Часовой пояс GMT +4, время: 03:58.

Powered by vBulletin® Version 3.8.5
Copyright ©2000 - 2026, Jelsoft Enterprises Ltd.