我正在使用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/