Кнопка изображения MFC с прозрачностью - PullRequest
2 голосов
/ 15 февраля 2012

Я обновляю диалог MFC с несколькими кнопками на нем.

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

Очевидно, было бы намного проще, если бы изображения можно было создавать в основном прозрачными, поэтомуфон просвечивает автоматически.Однако я не могу понять, как заставить MFC правильно отображать прозрачные изображения в этом случае.

Я понимаю, что мне может потребоваться другой класс, чем CBitmapButton, или мне нужно написать собственный подкласс;это хорошо, но я не знаю с чего начать.Было бы неплохо поддерживать 32-битный BMP или PNG с альфа-каналом, но я бы согласился на тип «указанный цвет должен быть прозрачным».

1 Ответ

1 голос
/ 16 февраля 2012

Возможно, это не лучший способ сделать это, но я бы создал собственный производный класс CButton (при условии, что вы фактически используете остальную часть функциональности CButton), а затем переопределил функцию DrawItem для установкиВаш собственный код для рисования.

Для самого изображения я бы использовал объект Bitmap GDI + (который позволит вам загружать BMP или PNG с альфа-каналами), а затем использовал обычную функцию DrawImage для рисования растрового изображения.

Если вы собираетесь помещать PNG-файлы в свой файл ресурсов, то вам нужно поместить их как тип "PNG".Когда вы смотрите в коде файла ресурсов, что запись выглядит как

IDB_PNG1 PNG "C: \ temp \ test.png"

, и не пытайтесь рассматривать ее как BITMAPресурс, иначе у вас возникнут проблемы с их загрузкой.

Редактировать

Разместите мой ответ здесь, чтобы я мог опубликовать код.Да, я хотел получить собственный класс из CButton, а затем добавить переменную-член Gdiplus :: Bitmap.Вот примерно то, что вам нужно сделать, чтобы заставить его работать, хотя я не проверял, что код на самом деле компилируется и работает, но, надеюсь, вы поймете идею.Это не самый эффективный способ сделать это, но если вы раньше не делали много пользовательских рисунков, то оно имеет преимущество в простоте!

void CMyButton::LoadImage(const int resourceID)
{
    m_pBitmap = Gdiplus::Bitmap::FromResource(NULL, MAKEINTRESOURCE(resourceID));
    ASSERT(m_pBitmap);
}

void CMyButton::DrawItem(LPDRAWITEMSTRUCT lpDrawItemStruct) 
{
    ASSERT(lpDrawItemStruct->CtlType == ODT_BUTTON);

    CRect rcClient;
    GetClientRect(&rcClient);
    if (lpDrawItemStruct->itemState & ODS_SELECTED)
    {
        // If you want to do anything special when the button is pressed, do it here
        // Maybe offset the rect to give the impression of the button being pressed?
        rcClient.OffsetRect(1,1);
    }
    Graphics gr(lpDrawItemStruct->hDC);
    gr.DrawImage(m_pBitmap, rcClient.left, rcClient.top);
}
...