我正在使用C ++在Visual Studio 2013中研究GDI的精灵绘图。
我可以使用两个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);
}

关于c++ - GDI Sprite 显示了一段时间并消失了,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/22871509/

10-13 02:44