gpt4 book ai didi

c++ - 重绘窗口问题

转载 作者:行者123 更新时间:2023-11-30 03:10:53 24 4
gpt4 key购买 nike

#include "stdafx.h"

// Mario Headers
#include "GameMain.h"

#define MAX_LOADSTRING 100

// Global Variables:
HINSTANCE hInst; // current instance
TCHAR szTitle[MAX_LOADSTRING]; // The title bar text
TCHAR szWindowClass[MAX_LOADSTRING]; // the main window class name

// Mario global variables =================
CGameMain* gGameMain;
HWND hWnd;
PAINTSTRUCT ps;
// ========================================



// Forward declarations of functions included in this code module:
ATOM MyRegisterClass(HINSTANCE hInstance);
BOOL InitInstance(HINSTANCE, int);
LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);
INT_PTR CALLBACK About(HWND, UINT, WPARAM, LPARAM);

// My unprocess function =====================================
void OnCreate(HWND hWnd)
{
}
void OnKeyUp(WPARAM wParam)
{
switch (wParam) {
case VK_LEFT:
gGameMain->KeyReleased(LEFT);
break;
case VK_UP:
gGameMain->KeyReleased(UP);
break;
case VK_RIGHT:
gGameMain->KeyReleased(RIGHT);
break;
case VK_DOWN:
gGameMain->KeyReleased(DOWN);
break;
}
}
void OnKeyDown(HWND hWnd,WPARAM wParam)
{
switch (wParam) {
case VK_LEFT:
gGameMain->KeyPressed(LEFT);
break;
case VK_UP:
gGameMain->KeyPressed(UP);
break;
case VK_RIGHT:
gGameMain->KeyPressed(RIGHT);
break;
case VK_DOWN:
gGameMain->KeyPressed(DOWN);
break;
}
}
void OnPaint(HWND hWnd)
{
HDC hdc = BeginPaint(hWnd,&ps);

RECT rect;
GetClientRect(hWnd,&rect);

HDC hdcDouble = CreateCompatibleDC(hdc);
HBITMAP hdcBitmap = CreateCompatibleBitmap(hdc,rect.right,rect.bottom);
HBITMAP bmOld = (HBITMAP)SelectObject(hdcDouble, hdcBitmap);

gGameMain->SetHDC(&hdcDouble);
gGameMain->SendMessage(MESSAGE_PAINT);

BitBlt(hdc,0,0,rect.right,rect.bottom,hdcDouble,0,0,SRCCOPY);
SelectObject(hdcDouble,bmOld);
DeleteDC(hdcDouble);
DeleteObject(hdcBitmap);
DeleteDC(hdc);
}

void OnDestroy()
{
gGameMain->isPlaying = false;
EndPaint(hWnd,&ps);
}
// My unprocess function =====================================

ATOM MyRegisterClass(HINSTANCE hInstance)
{
WNDCLASSEX wcex;

wcex.cbSize = sizeof(WNDCLASSEX);

wcex.style = CS_HREDRAW | CS_VREDRAW;
wcex.lpfnWndProc = WndProc;
wcex.cbClsExtra = 0;
wcex.cbWndExtra = 0;
wcex.hInstance = hInstance;
wcex.hIcon = LoadIcon(hInstance, MAKEINTRESOURCE(IDI_GDIMARIO));
wcex.hCursor = LoadCursor(NULL, IDC_ARROW);
wcex.hbrBackground = (HBRUSH)(COLOR_WINDOW+1);
wcex.lpszMenuName = MAKEINTRESOURCE(IDC_GDIMARIO);
wcex.lpszClassName = szWindowClass;
wcex.hIconSm = LoadIcon(wcex.hInstance, MAKEINTRESOURCE(IDI_SMALL));

return RegisterClassEx(&wcex);
}

BOOL InitInstance(HINSTANCE hInstance, int nCmdShow)
{

hInst = hInstance; // Store instance handle in our global variable

hWnd = CreateWindow(szWindowClass, szTitle, WS_OVERLAPPEDWINDOW,
CW_USEDEFAULT, CW_USEDEFAULT, WIDTH, HEIGHT, 0, NULL, hInstance, NULL);
if (!hWnd)
{
return FALSE;
}

// ---------------- Start gdiplus ------------------
GdiplusStartup(&gdiToken,&gdiStartInput,NULL);
// -------------------------------------------------

// Init GameMain
gGameMain = new CGameMain();

ShowWindow(hWnd, nCmdShow);
UpdateWindow(hWnd);

return TRUE;
}

LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
int wmId, wmEvent;
switch (message)
{
case WM_COMMAND:
wmId = LOWORD(wParam);
wmEvent = HIWORD(wParam);
// Parse the menu selections:
switch (wmId)
{
case IDM_ABOUT:
DialogBox(hInst, MAKEINTRESOURCE(IDD_ABOUTBOX), hWnd, About);
break;

case IDM_EXIT:
DestroyWindow(hWnd);
break;

default:
return DefWindowProc(hWnd, message, wParam, lParam);
}
break;
case WM_KEYDOWN:
OnKeyDown(hWnd,wParam);
break;
case WM_KEYUP:
OnKeyUp(wParam);
break;
case WM_CREATE:
OnCreate(hWnd);
break;
case WM_PAINT:
OnPaint(hWnd);
break;
case WM_DESTROY:
OnDestroy();
PostQuitMessage(0);
break;
default:
return DefWindowProc(hWnd, message, wParam, lParam);
}
return 0;
}

// Message handler for about box.
INT_PTR CALLBACK About(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)

{
UNREFERENCED_PARAMETER(lParam);
switch (message)
{
case WM_INITDIALOG:
return (INT_PTR)TRUE;

case WM_COMMAND:
if (LOWORD(wParam) == IDOK || LOWORD(wParam) == IDCANCEL)
{
EndDialog(hDlg, LOWORD(wParam));
return (INT_PTR)TRUE;
}
break;
}
return (INT_PTR)FALSE;
}
int APIENTRY _tWinMain(HINSTANCE hInstance,HINSTANCE hPrevInstance,LPTSTR lpCmdLine,int nCmdShow)
{
UNREFERENCED_PARAMETER(hPrevInstance);
UNREFERENCED_PARAMETER(lpCmdLine);

// TODO: Place code here.
MSG msg;
HACCEL hAccelTable;

// Initialize global strings
LoadString(hInstance, IDS_APP_TITLE, szTitle, MAX_LOADSTRING);
LoadString(hInstance, IDC_GDIMARIO, szWindowClass, MAX_LOADSTRING);
MyRegisterClass(hInstance);

// Perform application initialization:
if (!InitInstance (hInstance, nCmdShow))
{
return FALSE;
}

hAccelTable = LoadAccelerators(hInstance, MAKEINTRESOURCE(IDC_GDIMARIO));

// Main message loop:
// GameLoop

PeekMessage(&msg,NULL,0,0,PM_NOREMOVE);

while (gGameMain->isPlaying)
{
while (PeekMessage(&msg,NULL,0,0,PM_REMOVE)) {
if (msg.message == WM_QUIT)
break;

TranslateMessage(&msg);
DispatchMessage(&msg);
}
if (gGameMain->enterNextState) {
gGameMain->SendMessage(MESSAGE_ENTER);
gGameMain->enterNextState = false;
}

gGameMain->SendMessage(MESSAGE_UPDATE);
InvalidateRect(hWnd,NULL,FALSE);
/*if (gGameMain->exitCurrentState) {
gGameMain->SendMessage(MESSAGE_EXIT);
gGameMain->enterNextState = true;
gGameMain->exitCurrentState = false;
}*/
::Sleep(gGameMain->timer);
// Do your game stuff here
}

GdiplusShutdown(gdiToken); // Shut down gdiplus token

return (int) msg.wParam;
}

我使用 InvalidateRect(hWnd,NULL,FALSE);对于重绘窗口,但我遇到的问题是当我重绘时没有对 Game struct 进行任何更改。

第一次它很好地绘制了我的 Logo ,第二次(只需调用 InvalidateRect(hWnd,NULL,FALSE); 没有 gGameMain->SendMessage(MESSAGE_ENTER); 这是初始化一些用于绘制的变量。感谢您阅读本文:)

最佳答案

您在每个 wm_paint 消息中调用 BeginPaint(),但在 wm_paint 消息处理程序中没有对应的 EndPaint() 调用。每个 BeginPaint() 必须与相应的 EndPaint() 匹配。您在 OnDestroy 中的 EndPaint() 调用没有用。

此外,不要删除 BeginPaint() 返回的 DC。它是借来的,不是拥有的。

其他注意事项:尽量避免在每个 wm_paint 消息上分配一个新的位图。当窗口改变大小时分配位图,并保留它以供多个 wm_paint channel 重用。

另请注意,您并未优化绘制以仅绘制剪辑矩形中已无效的内容。您正在绘制所有内容,blitting 所有内容,并依靠 GDI 仅获取实际位于剪辑矩形中的一小部分位图。随着窗口/位图大小的增加以及屏幕上运行的对象/ Sprite 数量的增加,这将成为一个性能问题。你应该只绘制可见的和 cliprect 内的东西。

关于c++ - 重绘窗口问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2821557/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com