GDI精灵显示一段时间后消失

GDI sprite shown some time and disappear

本文关键字:消失 一段时间 显示 精灵 GDI      更新时间:2023-10-16

我正在Visual Studio 2013中与GDI一起学习精灵绘图,C++。我可以使用两个bmp文件,黑色背景的图像和黑色蒙版绘制精灵。但是在程序启动后,子画面显示一段时间(大约 15 秒)并消失。我找不到原因。这是我的代码。

#include <Windows.h>
#include "resource.h"
using namespace std;
LRESULT WINAPI WinProc(HWND hWnd,UINT uMsg,WPARAM wParam,LPARAM lParam);
HWND hWnd = 0;
int WINAPI WinMain(HINSTANCE hInst, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow)
{
    MSG msg;
    ZeroMemory(&msg, sizeof(msg));
    WNDCLASS wc;
    wc.cbClsExtra = 0;
    wc.cbWndExtra = 0;
    wc.hbrBackground = (HBRUSH)GetStockObject(NULL_BRUSH);
    wc.hCursor = LoadCursor(hInst, MAKEINTRESOURCE(IDC_HAND));
    wc.hIcon = LoadIcon(hInst, MAKEINTRESOURCE(IDI_ASTERISK));
    wc.hInstance = hInst;
    wc.lpfnWndProc = WinProc;
    wc.lpszClassName = "ClassName";
    wc.lpszMenuName = 0;
    wc.style = CS_VREDRAW | CS_HREDRAW;
    if (!RegisterClass(&wc))
        MessageBox(0, "Class was not registered!", "Error", 0);
    hWnd=CreateWindow("ClassName", "WindowName", WS_OVERLAPPEDWINDOW, 100, 100, 640, 480, 0, 0, hInst, 0);
    if (hWnd==0)
        MessageBox(0, "Window was not created!", "Error", 0);
    ShowWindow(hWnd, nCmdShow);
    UpdateWindow(hWnd);
    while (msg.message!=WM_QUIT)
    if (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE))
    {
        TranslateMessage(&msg);
        DispatchMessage(&msg);
    }
    else
    {
        HDC hdc = GetDC(hWnd);
        HDC hBuffDC = CreateCompatibleDC(hdc);
        HDC hMemDC = CreateCompatibleDC(hdc);
        HBITMAP hBuffBitmap = CreateCompatibleBitmap(hdc, 640, 480);
        HBITMAP hSpriteBitmap = LoadBitmap(hInst, MAKEINTRESOURCE(IDB_MASK));
        SelectObject(hBuffDC, hBuffBitmap);
        SelectObject(hBuffDC, (HBRUSH)GetStockObject(GRAY_BRUSH));
        Rectangle(hBuffDC, 0, 0, 640, 480);
        SelectObject(hMemDC, hSpriteBitmap);
        BitBlt(hBuffDC, 0, 0, 640, 480, hMemDC, 0, 0, SRCAND);
        hSpriteBitmap = LoadBitmap(hInst, MAKEINTRESOURCE(IDB_SPRITE));
        SelectObject(hMemDC, hSpriteBitmap);
        BitBlt(hBuffDC, 0, 0, 640, 480, hMemDC, 0, 0, SRCPAINT);
        BitBlt(hdc, 0, 0, 640, 480, hBuffDC, 0, 0, SRCCOPY);
        DeleteObject(hBuffBitmap);
        DeleteObject(hSpriteBitmap);
        DeleteDC(hMemDC);
        DeleteDC(hBuffDC);
        ReleaseDC(hWnd, hdc);
    }
    return 0;
}
LRESULT WINAPI WinProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
    switch (uMsg)
    {
    case WM_KEYDOWN:
        switch (wParam)
        {
        case VK_ESCAPE:
            DestroyWindow(hWnd);
            break;
        }
        break;
    case WM_CLOSE:
        DestroyWindow(hWnd);
        break;
    case WM_DESTROY:
        PostQuitMessage(0);
        break;
    }
    return DefWindowProc(hWnd, uMsg, wParam, lParam);
}

图像只是一个带有白色背景(蒙版)的黑色圆圈和带有黑色背景的绿色圆圈。

//Here is corrected code without memory leak and ReleaseDc return 1
#include <Windows.h>
#include "resource.h"
using namespace std;
LRESULT WINAPI WinProc(HWND hWnd,UINT uMsg,WPARAM wParam,LPARAM lParam);
HWND hWnd = 0;
HDC hdc = 0;
int WINAPI WinMain(HINSTANCE hInst, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow)
{
    MSG msg;
    ZeroMemory(&msg, sizeof(msg));
    WNDCLASS wc;
    wc.cbClsExtra = 0;
    wc.cbWndExtra = 0;
    wc.hbrBackground = (HBRUSH)GetStockObject(GRAY_BRUSH);
    wc.hCursor = LoadCursor(hInst, MAKEINTRESOURCE(IDC_HAND));
    wc.hIcon = LoadIcon(hInst, MAKEINTRESOURCE(IDI_ASTERISK));
    wc.hInstance = hInst;
    wc.lpfnWndProc = WinProc;
    wc.lpszClassName = "ClassName";
    wc.lpszMenuName = 0;
    wc.style = CS_VREDRAW | CS_HREDRAW;
    if (!RegisterClass(&wc))
        MessageBox(0, "Class was not registered!", "Error", 0);
    hWnd=CreateWindow("ClassName", "WindowName", WS_OVERLAPPEDWINDOW, 100, 100, 640, 480, 0, 0, hInst, 0);
    if (hWnd==0)
        MessageBox(0, "Window was not created!", "Error", 0);
    ShowWindow(hWnd, nCmdShow);
    UpdateWindow(hWnd);
    hdc = GetDC(hWnd);
    while (msg.message!=WM_QUIT)
    if (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE))
    {
        TranslateMessage(&msg);
        DispatchMessage(&msg);
    }
    else
    {
        HDC hBuffDC = CreateCompatibleDC(hdc);
        HDC hMemDC = CreateCompatibleDC(hdc);
        HBITMAP hBuffBitmap = CreateCompatibleBitmap(hdc, 640, 480);
        HBITMAP hSpriteBitmap = LoadBitmap(hInst, MAKEINTRESOURCE(IDB_SPRITE));
        HBITMAP hMaskBitmap = LoadBitmap(hInst, MAKEINTRESOURCE(IDB_MASK));
        HBITMAP hOldBuffBitmap= (HBITMAP)SelectObject(hBuffDC, hBuffBitmap);
        HBRUSH hOldBrush= (HBRUSH)SelectObject(hBuffDC, (HBRUSH)GetStockObject(GRAY_BRUSH));
        Rectangle(hBuffDC, 0, 0, 640, 480);
        HBITMAP hOldSpriteBitmap= (HBITMAP)SelectObject(hMemDC, hMaskBitmap);
        BitBlt(hBuffDC, 0, 0, 640, 480, hMemDC, 0, 0, SRCAND);
        SelectObject(hMemDC, hSpriteBitmap);
        BitBlt(hBuffDC, 0, 0, 640, 480, hMemDC, 0, 0, SRCPAINT);
        BitBlt(hdc, 0, 0, 640, 480, hBuffDC, 0, 0, SRCCOPY);
        SelectObject(hBuffDC, hOldBuffBitmap);
        SelectObject(hMemDC, hOldSpriteBitmap);
        SelectObject(hBuffDC, hOldBrush);
        DeleteObject(hBuffBitmap);
        DeleteObject(hSpriteBitmap);
        DeleteObject(hMaskBitmap);
        DeleteDC(hMemDC);
        DeleteDC(hBuffDC);
    }
    return 0;
}
LRESULT WINAPI WinProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
    switch (uMsg)
    {
    case WM_KEYDOWN:
        switch (wParam)
        {
        case VK_ESCAPE:
            DestroyWindow(hWnd);
            break;
        }
        return 0;
    case WM_CLOSE:
        DestroyWindow(hWnd);
        return 0;
    case WM_DESTROY:
        int Res = ReleaseDC(hWnd, hdc); //Release main window device context before destroying window
        DWORD err = GetLastError();
        PostQuitMessage(0);
        return 0;
    }
    return DefWindowProc(hWnd, uMsg, wParam, lParam);
}