You do not need all this. You can directly use GDI +:
static Gdiplus::Image *firstImage; static Gdiplus::Image *secondImage; case WM_CREATE: // or WM_INITDIALOG if it dialog { firstImage = new Gdiplus::Image(L"data\\img\\screen.png"); secondImage = new Gdiplus::Image(L"data\\img\\screen2.png"); return 0; } case WM_PAINT: { PAINTSTRUCT ps = { 0 }; HDC hdc = BeginPaint(hwnd, &ps); Gdiplus::Graphics gr(hdc); gr.DrawImage(firstImage, 0, 0); gr.DrawImage(secondImage, 0, 0);//<== this will draw transparently EndPaint(hwnd, &ps); return 0; }
However, this code still draws 2 images back with a possible flicker (for example, your source code). Use double buffering in WM_PAINT to make only one BltBlt . Just change to:
if (msg == WM_PAINT) { PAINTSTRUCT ps = { 0 }; HDC hdc = BeginPaint(hwnd, &ps); RECT rc; GetClientRect(hwnd, &rc); HDC memdc = CreateCompatibleDC(hdc); HBITMAP hbitmap = CreateCompatibleBitmap(hdc, rc.right, rc.bottom); HGDIOBJ oldbmp = SelectObject(memdc, hbitmap); FillRect(memdc, &rc, WHITE_BRUSH); Gdiplus::Graphics gr(memdc); gr.DrawImage(firstImage, 0, 0); gr.DrawImage(secondImage, 0, 0); BitBlt(hdc, 0, 0, rc.right, rc.bottom, memdc, 0, 0, SRCCOPY); SelectObject(memdc, oldbmp); DeleteObject(hbitmap); DeleteDC(memdc); EndPaint(hwnd, &ps); return 0; }
Regarding the source code:
void displayImage(HBITMAP mBmp, HWND mHwnd) { HDC hdc = GetDC(mHwnd); ... }
You must change the function declaration to void displayImage(HBITMAP mBmp, HWND mHwnd, HDC hdc) , then you can transfer hdc directly from WM_PAINT