gpt4 book ai didi

c++ - WndProc 作为类(class)成员,无法退出

转载 作者:行者123 更新时间:2023-11-30 02:47:51 24 4
gpt4 key购买 nike

我想使 WndProc 成为类成员函数,我找到了 this article , 所以我尝试将它应用到最简单的 Win32 程序中,它除了创建一个空白窗口之外什么都不做,这是 Win32 的第一步。

int Myclass::Start(HINSTANCE hInstance, int nCmdShow)
{
if (FAILED(InitWindow(hInstance, nCmdShow)))
return 0;

MSG msg = { 0 };
while (GetMessage(&msg, NULL, 0, 0))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}

return (int)msg.wParam;;
}

LRESULT Myclass::StaticWndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
Myclass* pThis = nullptr;

if (message == WM_NCCREATE) {
LPCREATESTRUCT lpcs = reinterpret_cast<LPCREATESTRUCT>(lParam);
pThis = static_cast<Myclass*>(lpcs->lpCreateParams);

SetWindowLongPtr(hWnd, GWLP_USERDATA, reinterpret_cast<LONG_PTR>(pThis));
}
else {
pThis = reinterpret_cast<Myclass*>(GetWindowLongPtr(hWnd, GWLP_USERDATA));
}

if(pThis)
return pThis->RealWndProc(hWnd, message, wParam, lParam);

return DefWindowProc(hWnd, message, wParam, lParam);
}

LRESULT Myclass::RealWndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
PAINTSTRUCT ps;
HDC hdc;

switch (message)
{
case WM_PAINT:
hdc = BeginPaint(hWnd, &ps);
EndPaint(hWnd, &ps);
break;

case WM_DESTROY:
PostQuitMessage(0);
break;

default:
return DefWindowProc(hWnd, message, wParam, lParam);
}

return 0;
}

它运行良好,但是当我关闭窗口时,程序停留在消息循环中并且不会退出。

我发现 WM_DESTROY 没有传递给 RealWndProc(),所以没有调用 PostQuitMessage()。

如果我插入 if(WM_DESTROY == message) { PostQuitMessage(0);返回 0; } 在 StaticWndProc 的最后一行之前,然后程序退出。但我不确定这是否是一个好方法。

如何让 RealWndProc() 消耗 WM_DESTROY?

最佳答案

我就是这样做的。工作得很好。我在你的代码中能想到的唯一问题是以下两个问题之一:

  • 您错过了 WindowProcedure 的调用约定。
  • 您忘记将“this”传递给 CreateWindowEx。

还有代码:

#include <windows.h>

class Window
{
public:
Window(LPCTSTR Title, LPCTSTR Class, DWORD dwStyleEx = 0, DWORD dwStyle = WS_OVERLAPPEDWINDOW,
POINT Location = {CW_USEDEFAULT, CW_USEDEFAULT}, int Width = CW_USEDEFAULT,
int Height = CW_USEDEFAULT, HWND Parent = HWND_DESKTOP, HMENU Menu = nullptr);

int Loop();

private:
HWND WindowHandle;
static LRESULT __stdcall WindowProcedure(HWND Hwnd, UINT Msg, WPARAM wParam, LPARAM lParam);
LRESULT RealWindowProcedure(HWND Hwnd, UINT Msg, WPARAM wParam, LPARAM lParam);
};

Window::Window(LPCTSTR Title, LPCTSTR Class, DWORD dwStyleEx, DWORD dwStyle, POINT Location, int Width, int Height, HWND Parent, HMENU Menu)
{
WNDCLASSEX WndClass =
{
sizeof(WNDCLASSEX), CS_DBLCLKS, Window::WindowProcedure,
0, 0, GetModuleHandle(nullptr), LoadIcon(nullptr, IDI_APPLICATION),
LoadCursor(nullptr, IDC_ARROW), HBRUSH(COLOR_BACKGROUND),
nullptr, Class, LoadIcon(nullptr, IDI_APPLICATION)
};

if(RegisterClassEx(&WndClass))
{
WindowHandle = CreateWindowEx(dwStyleEx, Class, Title, dwStyle, Location.x, Location.y, Width, Height, Parent, Menu, GetModuleHandle(nullptr), this);
}
}

LRESULT __stdcall Window::WindowProcedure(HWND Hwnd, UINT Msg, WPARAM wParam, LPARAM lParam)
{
Window* Data = nullptr;

switch(Msg)
{
case WM_NCCREATE:
{
CREATESTRUCT* pCreate = reinterpret_cast<CREATESTRUCT*>(lParam);
Data = static_cast<Window*>(pCreate->lpCreateParams);
SetWindowLongPtr(Hwnd, GWLP_USERDATA, reinterpret_cast<LONG_PTR>(Data));
break;
}

default:
{
Data = reinterpret_cast<Window*>(GetWindowLongPtr(Hwnd, GWLP_USERDATA));
break;
}
}

return Data ? Data->RealWindowProcedure(Hwnd, Msg, wParam, lParam) : DefWindowProc(Hwnd, Msg, wParam, lParam);
}

LRESULT Window::RealWindowProcedure(HWND Hwnd, UINT Msg, WPARAM wParam, LPARAM lParam)
{
switch(Msg)
{
case WM_DESTROY:
PostQuitMessage(0);
break;

default:
return DefWindowProc(Hwnd, Msg, wParam, lParam);
}

return 0;
}

int Window::Loop()
{
MSG Messages = {nullptr};
ShowWindow(WindowHandle, SW_SHOW);
while(GetMessage(&Messages, nullptr, 0, 0))
{
TranslateMessage(&Messages);
DispatchMessage(&Messages);
}
return Messages.wParam;
}

int main()
{
Window w("TItle", "Class");
return w.Loop();
}

关于c++ - WndProc 作为类(class)成员,无法退出,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22429039/

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