Win32 API logic error: Code compiles fine but the main window doesn't show up
Win32 API logic error: Code compiles fine but the main window doesn't show up
我正在重写我写的一个软件,因为程序大小和性能问题;代码编译正常,但 window 没有显示。
我已经调查了其他关于此的问题,但 none 解决了我的问题,这就是为什么我要问一个新问题,为了完整起见,请解释代码有什么问题以及如何解决解决问题。
我使用的是 Visual Studio 2013。
这是代码:
WFrame.h
#pragma once
#include <Windows.h>
#include <tchar.h>
#include <wchar.h>
class WFrame
{
public:
WFrame();
WFrame(LPCWSTR szClassName, LPCWSTR szWindowTitle, HINSTANCE hInstance, int nCmdShow, int nX, int nY, int nWidth, int nHeight, DWORD dwStyle = WS_EX_OVERLAPPEDWINDOW);
~WFrame();
void show();
static LRESULT CALLBACK staticWindowProcedure(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam);
virtual LRESULT CALLBACK WindowProcedure(UINT uMsg, WPARAM wParam, LPARAM lParam);
protected:
private:
HWND hWnd;
int cmdShow;
};
WFrame.cpp
#include "WFrame.h"
WFrame::WFrame()
{
}
WFrame::WFrame(LPCWSTR szClassName, LPCWSTR szWindowTitle, HINSTANCE hInstance, int nCmdShow, int nX, int nY, int nWidth, int nHeight, DWORD dwStyle)
{
WNDCLASSEX wClass;
ZeroMemory(&wClass, sizeof(WNDCLASSEX));
wClass.cbClsExtra = NULL;
wClass.cbSize = sizeof(WNDCLASSEX);
wClass.cbWndExtra = NULL;
wClass.hbrBackground = (HBRUSH)COLOR_WINDOW;
wClass.hCursor = LoadCursor(NULL, IDC_ARROW);
wClass.hIcon = NULL;
wClass.hIconSm = NULL;
wClass.hInstance = hInstance;
wClass.lpfnWndProc = (WNDPROC) WFrame::staticWindowProcedure;
wClass.lpszClassName = szClassName;
wClass.lpszMenuName = NULL;
wClass.style = CS_HREDRAW | CS_VREDRAW;
if (!RegisterClassEx(&wClass))
{
int nResult = GetLastError();
MessageBox(NULL,
L"Window class creation failed",
L"Window Class Failed",
MB_ICONERROR);
}
this->hWnd = CreateWindow(
szClassName,
szWindowTitle,
dwStyle,
nX,
nY,
nWidth,
nHeight,
NULL,
NULL,
hInstance,
NULL);
if (!hWnd)
{
int nResult = GetLastError();
MessageBox(NULL,
L"Window creation failed",
L"Window Creation Failed",
MB_ICONERROR);
}
}
WFrame::~WFrame()
{
delete this;
}
void WFrame::show()
{
ShowWindow(this->hWnd, this->cmdShow);
UpdateWindow(this->hWnd);
}
LRESULT CALLBACK WFrame::staticWindowProcedure(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
WFrame* winptr = (WFrame*)GetWindowLongPtr(hWnd, GWLP_USERDATA);
if (winptr == NULL) {
return DefWindowProc(hWnd, uMsg, wParam, lParam);
}
else {
return winptr->WindowProcedure(uMsg, wParam, lParam);
}
}
LRESULT CALLBACK WFrame::WindowProcedure(UINT uMsg, WPARAM wParam, LPARAM lParam)
{
switch (uMsg)
{
case WM_CLOSE:
DestroyWindow(this->hWnd);
break;
case WM_DESTROY:
if (!GetParent(this->hWnd))
PostQuitMessage(0);
break;
}
return DefWindowProc(this->hWnd, uMsg, wParam, lParam);
}
Main.cpp
#include <Windows.h>
#include "WFrame.h"
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow)
{
WFrame * frame = new WFrame(L"Window", L"Window", hInstance, nCmdShow, 0, 0, 1024, 700);
frame->show();
MSG msg;
ZeroMemory(&msg, sizeof(MSG));
while (GetMessage(&msg, NULL, 0, 0))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
return msg.wParam;
}
感谢进一步的回答。
您正在使用 WS_EX_OVERLAPPEDWINDOW
作为 CreateWindow
的 dwStyle
参数。该标志实际上应该用于 CreateWindowEx
的 dwExStyle
参数。请改用 WS_OVERLAPPEDWINDOW
。
完成后别忘了delete frame;
。实际上,您在这里甚至不需要指针。只需在堆栈上实例化 frame
。
此外,对于您处理的 window 条消息,您应该 return 0;
,而不是调用 DefWindowProc
。
我没有看到你给成员变量cmdShow赋值,所以它的默认值为0,也就是SW_HIDE,所以你应该试试下面的代码,看看window可以在 WFrame 初始值设定项中显示或分配 cmdShow。
void WFrame::show()
{
ShowWindow(this->hWnd, SW_SHOW);
UpdateWindow(this->hWnd);
}
我正在重写我写的一个软件,因为程序大小和性能问题;代码编译正常,但 window 没有显示。
我已经调查了其他关于此的问题,但 none 解决了我的问题,这就是为什么我要问一个新问题,为了完整起见,请解释代码有什么问题以及如何解决解决问题。
我使用的是 Visual Studio 2013。 这是代码:
WFrame.h
#pragma once
#include <Windows.h>
#include <tchar.h>
#include <wchar.h>
class WFrame
{
public:
WFrame();
WFrame(LPCWSTR szClassName, LPCWSTR szWindowTitle, HINSTANCE hInstance, int nCmdShow, int nX, int nY, int nWidth, int nHeight, DWORD dwStyle = WS_EX_OVERLAPPEDWINDOW);
~WFrame();
void show();
static LRESULT CALLBACK staticWindowProcedure(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam);
virtual LRESULT CALLBACK WindowProcedure(UINT uMsg, WPARAM wParam, LPARAM lParam);
protected:
private:
HWND hWnd;
int cmdShow;
};
WFrame.cpp
#include "WFrame.h"
WFrame::WFrame()
{
}
WFrame::WFrame(LPCWSTR szClassName, LPCWSTR szWindowTitle, HINSTANCE hInstance, int nCmdShow, int nX, int nY, int nWidth, int nHeight, DWORD dwStyle)
{
WNDCLASSEX wClass;
ZeroMemory(&wClass, sizeof(WNDCLASSEX));
wClass.cbClsExtra = NULL;
wClass.cbSize = sizeof(WNDCLASSEX);
wClass.cbWndExtra = NULL;
wClass.hbrBackground = (HBRUSH)COLOR_WINDOW;
wClass.hCursor = LoadCursor(NULL, IDC_ARROW);
wClass.hIcon = NULL;
wClass.hIconSm = NULL;
wClass.hInstance = hInstance;
wClass.lpfnWndProc = (WNDPROC) WFrame::staticWindowProcedure;
wClass.lpszClassName = szClassName;
wClass.lpszMenuName = NULL;
wClass.style = CS_HREDRAW | CS_VREDRAW;
if (!RegisterClassEx(&wClass))
{
int nResult = GetLastError();
MessageBox(NULL,
L"Window class creation failed",
L"Window Class Failed",
MB_ICONERROR);
}
this->hWnd = CreateWindow(
szClassName,
szWindowTitle,
dwStyle,
nX,
nY,
nWidth,
nHeight,
NULL,
NULL,
hInstance,
NULL);
if (!hWnd)
{
int nResult = GetLastError();
MessageBox(NULL,
L"Window creation failed",
L"Window Creation Failed",
MB_ICONERROR);
}
}
WFrame::~WFrame()
{
delete this;
}
void WFrame::show()
{
ShowWindow(this->hWnd, this->cmdShow);
UpdateWindow(this->hWnd);
}
LRESULT CALLBACK WFrame::staticWindowProcedure(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
WFrame* winptr = (WFrame*)GetWindowLongPtr(hWnd, GWLP_USERDATA);
if (winptr == NULL) {
return DefWindowProc(hWnd, uMsg, wParam, lParam);
}
else {
return winptr->WindowProcedure(uMsg, wParam, lParam);
}
}
LRESULT CALLBACK WFrame::WindowProcedure(UINT uMsg, WPARAM wParam, LPARAM lParam)
{
switch (uMsg)
{
case WM_CLOSE:
DestroyWindow(this->hWnd);
break;
case WM_DESTROY:
if (!GetParent(this->hWnd))
PostQuitMessage(0);
break;
}
return DefWindowProc(this->hWnd, uMsg, wParam, lParam);
}
Main.cpp
#include <Windows.h>
#include "WFrame.h"
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow)
{
WFrame * frame = new WFrame(L"Window", L"Window", hInstance, nCmdShow, 0, 0, 1024, 700);
frame->show();
MSG msg;
ZeroMemory(&msg, sizeof(MSG));
while (GetMessage(&msg, NULL, 0, 0))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
return msg.wParam;
}
感谢进一步的回答。
您正在使用 WS_EX_OVERLAPPEDWINDOW
作为 CreateWindow
的 dwStyle
参数。该标志实际上应该用于 CreateWindowEx
的 dwExStyle
参数。请改用 WS_OVERLAPPEDWINDOW
。
完成后别忘了delete frame;
。实际上,您在这里甚至不需要指针。只需在堆栈上实例化 frame
。
此外,对于您处理的 window 条消息,您应该 return 0;
,而不是调用 DefWindowProc
。
我没有看到你给成员变量cmdShow赋值,所以它的默认值为0,也就是SW_HIDE,所以你应该试试下面的代码,看看window可以在 WFrame 初始值设定项中显示或分配 cmdShow。
void WFrame::show()
{
ShowWindow(this->hWnd, SW_SHOW);
UpdateWindow(this->hWnd);
}