C++ - mfc / хочет добавить растровое изображение в cbutton. CButton не имеет члена setBitmap, а BM_SETIMAGE также недоступен для sendMessage

Это мой первый вопрос по stackru, и я надеюсь, что я все делаю правильно:S

Как описано в моем заголовке, я работаю над проектом visual studio(2012) с mfc. Я пытаюсь добавить растровое изображение к моей кнопке, которая была вставлена ​​в представление дизайна в мой диалог.

Все посты, которые я читал об этом, описывают использование setBitmap или sendMessage для этого. Я всегда пытаюсь сделать это в функции onInit() моего диалога. Когда я (пытаюсь) использовать setBitmap() вот так:

m_backButton.Attach (LoadBitmap (AfxGetInstanceHandle(), MAKEINTRESOURCE(IDB_BACK_BUTTON))); //m_backButton is a private CBitmap member of my dialog
CButton* pButton = (CButton* )GetDlgItem(IDC_BUTTON1);
pButton->SetBitmap(m_backButton);

Это приводит к IntelliSense-Error:

IntelliSense: класс "CButton" не имеет члена "setBitmap"

Другой попыткой было использовать sendMessage:

m_backButton.Attach (LoadBitmap (AfxGetInstanceHandle(), MAKEINTRESOURCE(IDB_BACK_BUTTON)));
CButton* pButton = (CButton* )GetDlgItem(IDC_BUTTON1);  
HBITMAP hBitmap = (HBITMAP)m_backButton;
pButton->SendMessage(BM_SETIMAGE,(WPARAM)IMAGE_BITMAP,(LPARAM)hBitmap); 

Сначала я получил еще одну ошибку IntelliSense:

IntelliSense: идентификатор "BM_SETIMAGE" не определен

Как я прочитал в другом посте, я определил "BM_SETIMAGE" своим собственным:

#define BM_SETIMAGE 0x00F7

Теперь код может компилироваться, но кнопка по-прежнему не показывает растровое изображение... Так как каждый пост в Интернете использует одно из этих двух решений, я беспомощен. Кто-нибудь идея, что не так? А если нет, то также спасибо за чтение:)

1 ответ

Решение

Так что я думаю, что нашел решение:) Я думал, что выложу его здесь, чтобы другие тоже могли его использовать. Также я не могу оставить этот вопрос без ответа:S

Мое решение взято с http://www.flounder.com/bitmapbutton.htm и адаптировано к моим потребностям. Теперь его можно использовать с Microsoft Embedded Compact 2013. Спасибо автору!

Моя короткая версия выглядит так:

ImageButton.h

#include "myApp.h" //check the original article if you are missing dependencies
class CImageButton : public CButton
{

public:
    CImageButton(UINT bitmap);
    // Default constructor (required for MFC compatibility)
    CImageButton() {bitmap = 0; }
    virtual void DrawItem(LPDRAWITEMSTRUCT lpDrawItemStruct);
    virtual ~CImageButton();
    void LoadBitmapForButton(UINT bitmap)
          { this->bitmap = bitmap; } 
    void GetBitmaps(UINT &bitmap)
          { bitmap = this->bitmap; }

protected:
    UINT bitmap;

    DECLARE_MESSAGE_MAP()
};

ImageButton.cpp

#include "stdafx.h"
#include "ImageButton.h"

CImageButton::CImageButton(UINT bitmap)
{
 this->bitmap = bitmap;
}

CImageButton::~CImageButton()
{
}


BEGIN_MESSAGE_MAP(CImageButton, CButton)
END_MESSAGE_MAP()

void CImageButton::DrawItem(LPDRAWITEMSTRUCT dis) 
{
     CDC * dc = CDC::FromHandle(dis->hDC);  // Get a CDC we can use
     CRect r(dis->rcItem);                  // Copy the button rectangle
     CBitmap bitmap;                        // Handle to the bitmap we are drawing
     BITMAP bmpval;                         // Parameters of the bitmap

     int saved = dc->SaveDC();              // Save the DC for later restoration

     bitmap.Attach (LoadBitmap (AfxGetInstanceHandle(), MAKEINTRESOURCE(this->bitmap)));

     // Get the bitmap parameters, because we will need width and height
     ::GetObject(bitmap, sizeof(BITMAP), &bmpval);

     // Select the bitmap into a DC
     CDC memDC;
     memDC.CreateCompatibleDC(dc);
     int savemem = memDC.SaveDC();
     memDC.SelectObject(bitmap);

    dc->BitBlt(0, 0,                            // target x, y
           min(bmpval.bmWidth, r.Width() ),     // target width
           min(bmpval.bmHeight, r.Height() ),   // target height
           &memDC,                              // source DC
           0, 0,                                // source x, y
           SRCCOPY);

     memDC.RestoreDC(savemem);

     dc->RestoreDC(saved);
     ::DeleteObject(bitmap);
}

Затем вы можете добавить обычный CButton с помощью редактора ресурсов или динамически (я думаю, не проверял), привести его к ImageButton и загрузить растровое изображение с помощью loadBitmapForButton. Ничья владельца CButton должна быть установлена ​​в true. Это все:)

PS, я не проверял код для правильного освобождения памяти до сих пор... Я сделаю это в ближайшее время, если я обнаружил, что ничего не хватает, я добавлю это в свой пост. Если кто-то еще может помочь в этом вопросе, не стесняйтесь учить меня;)

Другие вопросы по тегам