mike2k12
mike2k12

Reputation: 23

Displaying BMP Image in Window (C/C++) - Image Disappears

I am trying to display a BMP image inside a window I create, and to some degree am succeeding. The window is created and the image is displayed properly, but when I leave the window and open it again, the image has disappeared. For example if I click the minimize button on my window and then open it again, the image is gone. If I just stay in the window, the image stays on the screen.

I feel like there is an issue with my use the the BeginPaint function to create a device context in the window, but I couldn't find another way without using things like CClientDC and other objects that I do not want to use. So there are 2 relevant functions here, the first being my function to 1) create the window 2) draw the BMP in it. Here is that function:

bool Func()
{

// Register class
char ClassName[] = "ClassName";
WNDCLASSEX wc;
HWND hWnd;
wc.lpszClassName = ClassName;
wc.lpfnWndProc = fnWndProc;
wc.cbSize = sizeof(WNDCLASSEX);
wc.style = CS_DBLCLKS;
wc.hIcon = LoadIcon(NULL, IDI_APPLICATION);
wc.hInstance = NULL;
wc.hIconSm = LoadIcon(NULL, IDI_SHIELD);
wc.hCursor = LoadCursor(NULL, IDC_ARROW);
wc.hbrBackground = (HBRUSH)COLOR_BTNSHADOW;
wc.cbWndExtra = 0;
wc.cbClsExtra = 0;
wc.lpszMenuName = NULL;
RegisterClassEx(&wc);

// Get screen size
const HWND Desktop = GetDesktopWindow();
RECT dDimensions;
GetWindowRect(Desktop, &dDimensions);

// Create window and begin message loop
hWnd = CreateWindowEx(WS_EX_TOPMOST, ClassName, "Hi", WS_OVERLAPPEDWINDOW, 0, 0,   dDimensions.right, dDimensions.bottom, HWND_DESKTOP, 0, NULL, 0);
ShowWindow(hWnd, SW_SHOW);

// Set up device context
PAINTSTRUCT Paint;
HDC dContext = BeginPaint(hWnd, &Paint);
if (dContext == NULL) {
    MessageBox(NULL, "Failed to call BeginPaint", "", 0);
    return false;
}

// Load image
HBITMAP hBM = (HBITMAP)LoadImage(NULL, "image.bmp", IMAGE_BITMAP, 0, 0, LR_LOADFROMFILE);
if (hBM == NULL) {
    char Buffer[MAX_PATH];
    sprintf(Buffer, "Failed to call LoadImage. Error %ld", GetLastError());
    MessageBox(NULL, Buffer, "Failed", 0);
    return false;
}

// Create new, compatible device context
HDC LocalDC = CreateCompatibleDC(dContext);
if (LocalDC == NULL) {
    MessageBox(NULL, "Failed to call CreateCompatibleDC", "", 0);
    return false;
}

// Get BMP params
BITMAP BM;
if (!GetObject(hBM, sizeof(BITMAP), &BM)) {
    MessageBox(NULL, "Failed to call GetObject", "", 0);
    return false;
}

// Select bitmap
HBITMAP OldBM = (HBITMAP)SelectObject(LocalDC, hBM);
if (OldBM == NULL) {
    MessageBox(NULL, "Failed to call SelectObject", "", 0);
    return false;
}

// Calculate values of where to place image. We want it to be centered.
int XOffset;
int YOffset;
// If the screen is bigger than the image...
if (dDimensions.right > BM.bmWidth && dDimensions.bottom > BM.bmHeight) {
    XOffset = (dDimensions.right - BM.bmWidth) / 2;
    YOffset = (dDimensions.bottom - BM.bmHeight) / 2;
}
// If image is bigger than screen, do best to center
else {
    XOffset = -1 * ((BM.bmWidth - dDimensions.right) / 2);
    YOffset = -1 * ((BM.bmHeight - dDimensions.left) / 2);
}

// Copy the image
if (!BitBlt(dContext, XOffset, YOffset, BM.bmWidth, BM.bmHeight, LocalDC, 0, 0, SRCCOPY)) {
    printf("Failed to call BlitBlt. Error %ld", GetLastError());
    getchar();
    return false;
}

MSG messages;
while (GetMessage(&messages, NULL, 0, 0))
{
    TranslateMessage(&messages);
    DispatchMessage(&messages);
}

DeleteObject(hBM);
return true;
}

Second relevant function is the window procedure used to handle messages to the window. The window procedure referenced doesn't do anything in particular, since I'm really only interested in displaying the image. Perhaps my error is here? Anyways, here is the window procedure function:

long __stdcall fnWndProc(HWND hwnd, unsigned int msg, WPARAM wParam, LPARAM lParam)
{
switch (msg)
{
    break;
}
return (DefWindowProc(hwnd, msg, wParam, lParam));
}

So my problem is that when I minimize the window and re-open it, the image is gone. The window itself is still there, but the image is gone. Can someone please point out where the error in my function logic is? Thanks heaps.

Upvotes: 1

Views: 940

Answers (1)

mike2k12
mike2k12

Reputation: 23

I had to move my code to draw the BMP into the WM_PAINT case of the message switch. Every time the window is minimized and re-maximized, Windows is likely calling RedrawWindow or a similar API (causing the window to become blank again). Thanks for the answers, working fine now.

Upvotes: 1

Related Questions