Windows WinApi c++;windowwon';不出现oop
我正在尝试创建一个演示,其中窗口框架在它自己的类中处理,并在WinMain文件中调用,我有main.cpp和window.h以及window.cpp,代码编译成功,但窗口将不会显示,尽管在系统托盘中弹出窗口标题,我在main.cpp中传递了整个代码: main.cpp:Windows WinApi c++;windowwon';不出现oop,windows,oop,winapi,visual-c++,Windows,Oop,Winapi,Visual C++,我正在尝试创建一个演示,其中窗口框架在它自己的类中处理,并在WinMain文件中调用,我有main.cpp和window.h以及window.cpp,代码编译成功,但窗口将不会显示,尽管在系统托盘中弹出窗口标题,我在main.cpp中传递了整个代码: main.cpp: #include <Windows.h> #include "window.h" window* WinapiInit = new window; int WINAPI WinMain(HINSTANCE hI
#include <Windows.h>
#include "window.h"
window* WinapiInit = new window;
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE PrevhInstance, LPSTR
lpCmdLine, int nCmdShow)
{
WinapiInit->initWindow(hInstance, 800, 600, L"DirectX 12 Demo", nCmdShow);
delete WinapiInit;
return 0;
}
到底是什么原因导致窗口不显示?我是一名面向对象编程的初学者,因此我认为这就是问题所在,但我无法解决它,希望您能提供任何帮助。这里有很多错误,因为您设法使一个简单的应用程序变得非常复杂,因此很难调试 对于您的问题,最关键的是,您使用系统度量SM_CXSCREEN和SM_CYSCREEN初始化m_ScreenPosX和m_ScreenPosY,根据定义,这意味着该窗口位于桌面的可见区域之外 由于这看起来像是一个DirectX应用程序,您可能希望使用0,0作为位置,并使用主显示器的尺寸(在多显示器系统上不是SM_CXSCREEN,SM_CYSCREEN)在主显示器上定位窗口 但在短期内,CW_USEDEFAULT将是用于初始开发的合理仓位值 下一个最关键的错误源是将消息循环作为窗口类的一部分包含在内。大多数(如果不是全部的话)面向对象的windows开发框架将“窗口”与“应用程序”分开,即使只有一个应用程序窗口。这意味着应用程序对象拥有消息循环,并且它从不按hWnd进行过滤:发布到应用程序的消息(如WM_QUIT)不会发送到hWnd,这可能就是WM_DESTROY处理程序也调用ExitProcess的原因。删除对ExitProcess的调用,并删除hWnd筛选,PostQuitMessage()将导致应用程序完全终止 最后,除非您只想存储窗口类的一个单例(因为游戏窗口不太可能导致问题),否则您很快就会对必须将整个窗口类实现为静态方法感到恼火。
通常的方法是使用
SetWindowLongPtr/GetWindowLongPtr
和GWLP\u USERDATA
在静态WndProc中存储和检索这个
指针,这样它就可以调用非静态类方法了。@Dan ok,谢谢大家的指导up@Cody很好,WinapInit是指向窗口类的指针(希望如此)我发布了标题和cpp文件,任何帮助都可以appreciated@Dan:如果您正在使用MFC进行Win32开发,您可以看看Qt。@sergiol您能帮我完成这段代码吗?请不要编辑@Raymond的标题,这是正确的。我们没有添加标题黑客在这里,因为我们有一个成熟的接受系统。如果您看到某人具有较高的代表性,可能值得考虑的是,他们对堆栈溢出的工作原理有很好的了解,因此请在进入编辑战之前使用他们的@handle
ping他们。谢谢
#pragma once
#include <Windows.h>
class window
{
private:
LPCWSTR m_WindowTitle;
const LPCTSTR m_WindowClassName = L"WindowClass1";
int m_WindowWidth;
int m_WindowHeight;
const int m_ScreenPosX = GetSystemMetrics(SM_CXSCREEN);
const int m_ScreenPosY = GetSystemMetrics(SM_CYSCREEN);
HWND hWnd;
WNDCLASSEX wcex;
MSG msg;
public:
void initWindow(HINSTANCE hInstance, int WindowWidth, int WindowHeight,
LPCWSTR WindowTitle, int nCmdShow);
static LRESULT CALLBACK WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM
lParam);
void mainLoop();
};
#include "window.h"
LRESULT window::WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
switch (uMsg)
{
case WM_DESTROY:
PostQuitMessage(0);
ExitProcess(0);
break;
default:
return DefWindowProc(hWnd, uMsg, wParam, lParam);
break;
}
return 0;
}
void window::mainLoop()
{
msg = { 0 };
while (WM_QUIT != msg.message)
{
if (PeekMessage(&msg, hWnd, 0, 0, PM_REMOVE))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
//GAME CODE HERE
//...
}
}
void window::initWindow(const HINSTANCE hInstance, int WindowWidth, int
WindowHeight, LPCWSTR WindowTitle, const int nCmdShow)
{
m_WindowWidth = WindowWidth;
m_WindowHeight = WindowHeight;
m_WindowTitle = WindowTitle;
wcex = { 0 };
wcex.cbSize = sizeof(WNDCLASSEX);
wcex.cbClsExtra = 0;
wcex.cbWndExtra = 0;
wcex.hbrBackground = (HBRUSH)(COLOR_WINDOW + 3);
wcex.hCursor = LoadCursor(NULL, IDC_ARROW);
wcex.hIcon = LoadIcon(hInstance, IDI_APPLICATION);
wcex.hIconSm = LoadIcon(hInstance, IDI_APPLICATION);
wcex.hInstance = hInstance;
wcex.lpfnWndProc = window::WndProc;
wcex.lpszMenuName = nullptr;
wcex.lpszClassName = m_WindowClassName;
wcex.style = CS_HREDRAW | CS_VREDRAW;
if (!RegisterClassEx(&wcex))
{
MessageBox(NULL, L"RegisterClassEx Call Error!", L"ERROR" , MB_OK |
MB_ICONERROR);
}
hWnd = CreateWindowEx(NULL, m_WindowClassName, WindowTitle,
WS_OVERLAPPEDWINDOW, m_ScreenPosX, m_ScreenPosY,
WindowWidth,
WindowHeight, NULL, NULL, hInstance, NULL);
if (!hWnd)
{
MessageBox(NULL, L"CreateWindowEx Call Error!", L"ERROR", MB_OK |
MB_ICONERROR);
}
ShowWindow(hWnd, nCmdShow);
UpdateWindow(hWnd);
mainLoop();
}