c++ - mfc/想要将位图添加到 cbutton.CButton 没有成员 setBitmap 并且 BM_SETIMAGE 也不能用于 sendMessage

2022-01-12 00:00:00 visual-c++ mfc cbutton cbitmap

这是我关于 stackoverflow 的第一个问题,我希望我做的一切都是正确的:S

this is my first question on stackoverflow and i hope i do everything right:S

正如我的标题中所述,我正在与 mfc 合作进行视觉工作室(2012)项目.我尝试向我的 cbutton 添加一个位图,该位图被插入到我的对话框的设计视图中.

As described in my titel i am working on a visual studio(2012) project with mfc. I try to add a bitmap to my cbutton, which was inserted in the design view to my dialog.

我读过的所有帖子都描述了使用 setBitmap 或 sendMessage 来做到这一点.我总是尝试在对话框的 onInit() 函数中执行此操作.当我(尝试)像这样使用 setBitmap() 时:

All post i've read about this, describe to use setBitmap or sendMessage to do so. I always try to do this in the onInit()-function of my dialog. When i (try to) use setBitmap() like this:

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 错误:

It results in an IntelliSense-Error:

IntelliSense:类CButton"没有成员setBitmap"

IntelliSense: class "CButton" has no member "setBitmap"

另一个尝试是使用 sendMessage:

Another try was to use 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 错误:

First i got another IntelliSense-Error:

IntelliSense:标识符BM_SETIMAGE"未定义

IntelliSense: identifier "BM_SETIMAGE" is undefined

就像我在另一篇文章中读到的那样,我自己定义了BM_SETIMAGE":

Like i've read in another post, i defined "BM_SETIMAGE" by my own:

#define BM_SETIMAGE 0x00F7

现在代码可以编译了,但是按钮仍然没有显示位图...由于互联网上的每个帖子都使用这两种解决方案之一,我很无奈.有人知道有什么问题吗?如果没有,也感谢您的阅读:)

Now the code is able to compile, but the button still shows no bitmap... Since every post in the internet uses one of this two solutions i'm helpless. Anybody an idea whats wrong? And if not, also thank you for reading:)

推荐答案

所以我想我找到了解决方案:)我想我把它贴在这里,其他人也可能使用它.我也不能不回答这个问题:S

So i think i found a solution:) I thought i post it here, that other may have use of it too. Also i cannot let this question be unansweared:S

我的解决方案来自 http://www.flounder.com/bitmapbutton.htm并适应我的需要.它现在可以与 Microsoft Embedded Compact 2013 一起使用.感谢作者!

My solution is from http://www.flounder.com/bitmapbutton.htm and adapted to fit my needs. It now can be used with Microsoft Embedded Compact 2013. Thx to the autor!

我的简短版本如下所示:

My short version looks like this:

ImageButton.h

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

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 的属性 owner-draw 必须设置为 true.就是这样:)

Than you can add a normal CButton with ressource editor or dynamically(i think, not tested), cast it to ImageButton and load the bitmap with loadBitmapForButton. The property owner-draw of the CButton must be set to true. Thats all:)

PS,直到现在我还没有检查过正确的内存释放代码...我会尽快检查,如果我发现某些东西丢失了,我会在我的帖子中添加这个.如果其他人可以在这一点上提供帮助,请随时教我;)

PS, i did not checked the code for correct memory deallocation until now...I will do so soon, if i found sth missing i will add this in my post. If someone else can help in this point, feel free to teach me;)

相关文章