早上好。
我正在使用Managing Application State中使用的BaseWindow
类创建应用程序
一切正常,该应用程序是一个带有一些按钮和列表视图的单个窗口,现在我想添加另一个窗口以将其用作“报告”窗口,该窗口将通过菜单命令创建。
问题是报告窗口在HWND中返回0,该类被注册而没有任何问题,我使用了GetLastError()
,返回值为0(“一切正常”)。永远不会创建报告窗口。
这是对我所做工作的快速回顾:
BaseClass<MainWindow>
继承MainWindow并创建
MainWindow-好的BaseClass<ReportWindow>
继承ReportWindow-确定其他都可以,这是代码:
Main.cpp
// other not related code
MainWindow win;
char szTitle[MainWindow::nMaxLoadString];
LoadString(hInst, IDS_APPTITLE, szTitle, MainWindow::nMaxLoadString);
win.Create(szTitle, WS_OVERLAPPEDWINDOW, 0, CW_USEDEFAULT, CW_USEDEFAULT, 542, 343);
win.Show(SW_SHOWDEFAULT);
// other not related code
ReportWindow.h
#pragma once
#include "BaseWindow.h"
class ReportWindow : public BaseWindow<ReportWindow>
{
public:
ReportWindow() : BaseWindow<ReportWindow>(){}
LPCSTR ClassName() const override { return "AdminLockerRpt"; }
LRESULT HandleMessage(UINT uMsg, WPARAM wParam, LPARAM lParam) override;
private:
};
ReportWindow.cpp
#include "ReportWindow.h"
LRESULT ReportWindow::HandleMessage(UINT uMsg, WPARAM wParam, LPARAM lParam)
{
switch (uMsg)
{
case WM_CLOSE:
DestroyWindow(hWnd);
break;
}
return 0;
}
MainWindow.h
#pragma once
#pragma comment(linker,"\"/manifestdependency:type='win32' \
name='Microsoft.Windows.Common-Controls' version='6.0.0.0' \
processorArchitecture='*' publicKeyToken='6595b64144ccf1df' language='*'\"")
#include "BaseWindow.h"
#include "ReportWindow.h"
class MainWindow : public BaseWindow<MainWindow>
{
public:
MainWindow();
public:
LPCSTR ClassName() const override { return szClassName; }
LRESULT HandleMessage(UINT uMsg, WPARAM wParam, LPARAM lParam) override;
// other not related code
Private:
ReportWindow rpt;
// other not related code
};
MainWindow.cpp
#pragma once
#include "MainWindow.h"
MainWindow::MainWindow()
: BaseWindow<MainWindow>()
{
// other not related code
}
LRESULT MainWindow::HandleMessage(UINT uMsg, WPARAM wParam, LPARAM lParam)
{
switch (uMsg)
{
case WM_CREATE:
{
// other not related code
}
break;
case WM_COMMAND:
if(HIWORD(wParam) == BN_CLICKED)
// other not related code
// Here is the error, rpt.Create() returns 0, as its HWND is 0
// I use GetLastError() inmediately after this and I get 0 as return value
// I also tried to get the last error at the BaseWindow class, with the same results
// I only get error 1401 if I use a number as the HMENU parameter of the Create function
// ReportWindow doesn't get created :(
rpt.Create("Report", WS_OVERLAPPEDWINDOW);
DWORD dwLastError = GetLastError(); // returns 0, "Everything is ok"
rpt.Show(SW_SHOWDEFAULT);
return 0;
case WM_DESTROY:
PostQuitMessage(0);
return 0;
default:
return DefWindowProc(hWnd, uMsg, wParam, lParam);
}
return 0;
}
我希望您能对此有所帮助。预先感谢您的宝贵时间!
以防万一,我包括了BaseWindow类的代码:
BaseWindow.h
#pragma once
#include "stdafx.h"
#include "Resource.h"
#include <cassert>
template <class DERIVED_T>
class BaseWindow
{
public:
BaseWindow() : hWnd(nullptr), hInst(GetModuleHandle(nullptr)), wcx({0}) {}
BOOL Create(LPCSTR lpWindowName, DWORD dwStyle, DWORD dwExStyle = 0,
int x = CW_USEDEFAULT, int y = CW_USEDEFAULT, int width_in = CW_USEDEFAULT, int height_in = CW_USEDEFAULT,
HWND hWndParent = nullptr, HMENU hMenu = nullptr)
{
RECT wr = {0};
wr.left = x;
wr.right = width_in + x;
wr.top = y;
wr.bottom = height_in + y;
AdjustWindowRect(&wr, dwStyle, TRUE);
width = wr.right - wr.left;
height = wr.bottom - wr.top;
wcx.cbSize = sizeof(wcx);
wcx.hInstance = hInst;
wcx.lpszClassName = ClassName();
wcx.lpfnWndProc = DERIVED_T::WndProc;
wcx.hbrBackground = (HBRUSH)(COLOR_WINDOW+1);
wcx.hCursor = LoadCursor(nullptr, IDC_ARROW);
wcx.hIcon = LoadIcon(hInst, MAKEINTRESOURCE(IDI_MAINICON));
ATOM aResult = RegisterClassEx(&wcx);
assert(aResult != 0);
hWnd = CreateWindowEx(
dwExStyle, ClassName(), lpWindowName, dwStyle,
x, y, width, height,
hWndParent, hMenu, hInst, this
);
assert(hWnd != 0);
return (hWnd ? TRUE : FALSE);
}
void Show(int nCmdShow) { ShowWindow(hWnd, nCmdShow); }
HWND Window() const { return hWnd; }
protected:
virtual LPCSTR ClassName() const = 0;
virtual LRESULT HandleMessage(UINT uMsg, WPARAM wParam, LPARAM lParam) = 0;
public:
static constexpr int nMaxLoadString = 100;
protected:
HWND hWnd;
HINSTANCE hInst;
char szClassName[nMaxLoadString];
int width;
int height;
WNDCLASSEX wcx;
public:
static LRESULT CALLBACK WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
DERIVED_T* pThis = nullptr;
if (uMsg == WM_NCCREATE)
{
CREATESTRUCT* pCreate = (CREATESTRUCT*)lParam;
pThis = (DERIVED_T*)pCreate->lpCreateParams;
SetWindowLongPtr(hWnd, GWLP_USERDATA, (LONG_PTR)pThis);
pThis->hWnd = hWnd;
}
else
{
pThis = (DERIVED_T*)GetWindowLongPtr(hWnd, GWLP_USERDATA);
}
if (pThis)
{
return pThis->HandleMessage(uMsg, wParam, lParam);
}
else
{
return DefWindowProc(hWnd, uMsg, wParam, lParam);
}
}
};