简体   繁体   English

在窗口(C / C ++)中显示BMP图像-图像消失

[英]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. 我试图在我创建的窗口中显示BMP图像,并且在某种程度上成功了。 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 . 我感觉使用BeginPaint函数在窗口中创建设备上下文存在问题,但是如果不使用CClientDC和其他我不想使用的对象之类的东西,我找不到其他方法。 So there are 2 relevant functions here, the first being my function to 1) create the window 2) draw the BMP in it. 因此,这里有2个相关功能,第一个是我的功能:1)创建窗口2)在其中绘制BMP。 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. 谢谢堆。

I had to move my code to draw the BMP into the WM_PAINT case of the message switch. 我不得不移动代码以将BMP绘制到消息开关的WM_PAINT案例中。 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). 每次最小化和重新最大化窗口时,Windows都可能调用RedrawWindow或类似的API(导致窗口再次变为空白)。 Thanks for the answers, working fine now. 感谢您的回答,现在可以正常工作。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM