1

I started to study MFC. So I made a simple program. I want to set the background bitmap image on a dialog, but the code is not working. The compiler does not output any error. Execution is also good, however, the dialog is empty. Please help me...

IMPLEMENT_DYNAMIC(Works, CDialogEx)

Works::Works(CWnd* pParent /*=NULL*/)
    : CDialogEx(IDD_WORKS, pParent)
{

}

BOOL Works::OnInitDialog()
{
    CDialogEx::OnInitDialog();


    return TRUE;  // return TRUE unless you set the focus to a control
}

void Works::OnPaint()
{
    CPaintDC dc(this);

    UINT tBG_IMAGE_ID = IDB_BG;
    CRect tRect;
    GetClientRect(&tRect);

    CBitmap tBitmap, *pOldBitmap;
    CDC tMemdc;

    BOOL test = tBitmap.LoadBitmap(IDB_BG);

    tMemdc.CreateCompatibleDC(&dc);

    pOldBitmap = tMemdc.SelectObject(&tBitmap);

    dc.BitBlt(0, 0, tRect.Width(), tRect.Height(), &tMemdc, 0, 0, SRCCOPY);

    BOOL test = tBitmap.LoadBitmap(tBG_IMAGE_ID);

    tMemdc.SelectObject(pOldBitmap);
    tBitmap.DeleteObject();
    tMemdc.DeleteDC();
}

Works::~Works()
{

}

void Works::DoDataExchange(CDataExchange* pDX)
{
    CDialogEx::DoDataExchange(pDX);
}


BEGIN_MESSAGE_MAP(Works, CDialogEx)
END_MESSAGE_MAP()
Andrew Komiagin
  • 6,446
  • 1
  • 13
  • 23
Diana
  • 405
  • 1
  • 5
  • 13
  • Nothing wrong with that code. Show the rest of your window or dialog class. Or test to see if bitmap is loaded `BOOL test = tBitmap.LoadBitmap(tBG_IMAGE_ID);` – Barmak Shemirani Oct 22 '16 at 16:29
  • @BarmakShemirani Thanks! I test this code, Result is true. And I add dialog class in my question. – Diana Oct 22 '16 at 17:34
  • 1
    Add `ON_WM_PAINT()` after `BEGIN_MESSAGE_MAP(Works, CDialogEx)`, otherwise `void Works::OnPaint()` is never called. – Barmak Shemirani Oct 22 '16 at 17:40
  • @BarmakShemirani Huh? I get error 'WM_ON_PAINT() is not defined.'. – Diana Oct 22 '16 at 17:41
  • I had typo, please see edited comment – Barmak Shemirani Oct 22 '16 at 17:42
  • @BarmakShemirani Wowww! It is successful! Thank you very much:) – Diana Oct 22 '16 at 17:46
  • Possible duplicate of [I have added an OnPaint() function to my dialog class but its not getting called after dlg.DoModal()](http://stackoverflow.com/questions/37722069/i-have-added-an-onpaint-function-to-my-dialog-class-but-its-not-getting-called) – Barmak Shemirani Oct 22 '16 at 17:48
  • 1
    May be there is a better approach for you to do what you want. Loading a bitmap image every time the method `OnPaint()` is called seems not a good idea to me. – sergiol Oct 22 '16 at 21:24
  • @sergiol It's a resource bitmap, it is loaded very quickly. There is no need to keep the bitmap in memory unless this is for a game or something which needs to update faster than usual. – Barmak Shemirani Oct 23 '16 at 16:35
  • 1
    @BarmakShemirani: It's not just loading the bitmap (which may indeed be somewhat speedy). It's also about creating an off-screen memory DC on every paint cycle. It may not have a huge impact by itself, but if you promote this as the standard way to go about rendering a background image, it will start to show, when you add more visuals to your application, and keep applying this wasteful technique. – IInspectable Oct 23 '16 at 18:14
  • @IInspectable `CreateCompatibleDC` returns very fast (it take a few microseconds). The main culprits are `BitBlt` and `LoadBitmap` which move a lot of bytes and are relatively slow. `BitBlt` has to be there, so the only optimization is for `LoadBitmap`. For a large image `LoadBitmap` takes a few milliseconds, depending on image size. For a game you certainly want to avoid reloading the bitmap. For other applications I think it's not necessary unless it's a large bitmap or there are many bitmap controls... – Barmak Shemirani Oct 24 '16 at 01:08
  • @BarmakShemirani: Your analysis is wrong. `CreateCompatibleDC` **is** the most costly operation. `BitBlt` is hardware accelerated (unless you're using an inappropriate bitmap format), and `LoadBitmap` operates on memory, that's already mapped into the address space (for a bitmap resource). – IInspectable Oct 24 '16 at 01:11
  • @IInspectable I think this [SO topic](http://stackoverflow.com/q/33472482/4603670) is more relevant, I added an answer there. I am sure I did the test right. Surprisingly loading the image from resource is relatively slow, I just assumed it would be fast. – Barmak Shemirani Oct 24 '16 at 06:58
  • @BarmakShemirani: I'm sorry, I was wrong. `CreateCompatibleDC` is indeed a fairly cheap function. It's just a rendering abstraction object (plus a 1x1 monochrome bitmap) after all. I was confusing this with `CreateCompatibleBitmap` (which can be costly). Still, though, I wouldn't create the device context on every update. – IInspectable Oct 24 '16 at 15:33

0 Answers0