我的问题是当我想创建一个子窗口时,我从
GetLastError()
: 得到错误代码 1406
ERROR_TLW_WITH_WSCHILD
1406 (0x57E)
无法创建顶级子窗口。
有人能告诉我为什么会出现这个奇怪的错误吗?
这是消息.h
class IMessage
{
protected:
virtual void Create(
DWORD,
const std::wstring&,
DWORD, int, int, int, int,
HWND, HWND, HMENU
) = 0;
virtual Event TranslateMessage(HWND, UINT, WPARAM, LPARAM, Element*) = 0;
};
template<typename Elem>
class Message : IMessage
{
public:
static LRESULT CALLBACK WindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
Elem* pElem = nullptr;
if (uMsg == WM_NCCREATE)
{
LPCREATESTRUCT pCreate = reinterpret_cast<LPCREATESTRUCT>(lParam);
pElem = static_cast<Elem*>(pCreate->lpCreateParams);
pElem->m_hWnd = hwnd;
SetWindowLongPtr(hwnd, GWLP_USERDATA, reinterpret_cast<LONG_PTR>(pElem));
}
else
{
pElem = reinterpret_cast<Elem*>(GetWindowLongPtr(hwnd, GWLP_USERDATA));
}
if (pElem)
{
return pElem->HandleMessage(uMsg, wParam, lParam);
}
return DefWindowProc(hwnd, uMsg, wParam, lParam);
}
void Create(
DWORD dwExStyles,
const std::wstring& windowName,
DWORD dwStyles, int X, int Y, int nWidth, int nHeight, HWND hwnd, HWND hWndParent = nullptr, HMENU hMenu = nullptr
) override
{
WNDCLASS wndClass = { 0 };
wndClass.style = CS_HREDRAW | CS_VREDRAW | CS_PARENTDC;
wndClass.lpfnWndProc = WindowProc;
wndClass.hInstance = GetModuleHandle(nullptr);
wndClass.lpszClassName = GetName().c_str();
if (!RegisterClass(&wndClass))
{
throw GSGUI_ELEMENT_LAST_EXCEPT();
}
if (!(m_hWnd = CreateWindowEx(
dwExStyles,
GetName().c_str(),
windowName.c_str(),
dwStyles,
X, Y, nWidth, nHeight,
hWndParent,
hMenu,
GetModuleHandle(nullptr),
this
)))
{
throw GSGUI_ELEMENT_LAST_EXCEPT();
}
else
{
hwnd = m_hWnd;
}
}
Event TranslateMessage(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam, Element* target) override
{
Event event;
event.Target = target;
return event;
}
protected:
HWND m_hWnd;
virtual const std::wstring& GetName() const = 0;
virtual LRESULT HandleMessage(UINT, WPARAM, LPARAM) = 0;
};
这是窗口.h
class GSGUI_API IWindow
{
protected:
virtual bool Running() = 0;
virtual void Show() = 0;
virtual void Restore() = 0;
virtual void Maximize() = 0;
virtual void Minimize() = 0;
virtual void OnDestroy(Event e) = 0;
};
class GSGUI_API Window : public Message<Window>, public Element, IWindow
{
public:
Window(const std::wstring& content, const Style& style);
bool Running() override;
void Show() override;
void Restore() override;
void Maximize() override;
void Minimize() override;
const std::wstring& GetName() const override;
// Event handling
void OnPaint(Event e) override;
void OnDestroy(Event e) override;
// Event handling
public:
GSGUI_BEGIN_MSG_MAP
GSGUI_HANDLE_MSG(WM_PAINT, OnPaint)
GSGUI_HANDLE_MSG(WM_CLOSE, OnDestroy)
GSGUI_END_MSG_MAP
};
窗口.cpp
Window::Window(const std::wstring& content, const Style& style)
{
m_ClassName = L"GSguiWindow";
m_Content = content;
m_Style = style;
Create(
0,
content,
WS_OVERLAPPEDWINDOW,
m_Style.Margin.top, m_Style.Margin.left, m_Style.Width, m_Style.Height,
m_Handle
);
}
bool Window::Running()
{
MSG msg = { 0 };
while (PeekMessage(&msg, nullptr, 0, 0, PM_REMOVE))
{
if (msg.message == WM_QUIT)
return false;
::TranslateMessage(&msg);
DispatchMessage(&msg);
Sleep(1);
}
return true;
}
void Window::Show()
{
if (ShowWindow(m_hWnd, SW_SHOW))
{
throw GSGUI_ELEMENT_LAST_EXCEPT();
}
}
void Window::Restore()
{
if (ShowWindow(m_hWnd, SW_RESTORE))
{
throw GSGUI_ELEMENT_LAST_EXCEPT();
}
}
void Window::Maximize()
{
if (ShowWindow(m_hWnd, SW_MAXIMIZE))
{
throw GSGUI_ELEMENT_LAST_EXCEPT();
}
}
void Window::Minimize()
{
if (ShowWindow(m_hWnd, SW_MINIMIZE))
{
throw GSGUI_ELEMENT_LAST_EXCEPT();
}
}
const std::wstring& Window::GetName() const { return m_ClassName; }
void Window::OnDestroy(Event e)
{
PostQuitMessage(0);
}
void Window::OnPaint(Event e)
{
PAINTSTRUCT ps;
HDC hdc = BeginPaint(m_hWnd, &ps);
wprintf(L"%s", e.Target->GetContent().c_str());
FillRect(hdc, &ps.rcPaint, CreateSolidBrush(0xffffff));
EndPaint(m_hWnd, &ps);
}
Style.h
struct GSGUI_API Style
{
public:
Style() = default;
Style(const Style& other);
Style& operator=(const Style& other);
public:
int Width = 0;
int Height = 0;
Margin Margin;
};
样式.cpp
Style::Style(const Style& other)
{
operator=(other);
}
Style& Style::operator=(const Style& other)
{
Width = other.Width;
Height = other.Height;
Margin = other.Margin;
return *this;
}
main.cpp
class PushButton : public Message<PushButton>, public Element
{
public:
PushButton(const std::wstring& content, const Style& style, Element parent)
{
m_ClassName = L"PushButton";
m_Content = content;
m_Style = style;
Create(
0,
content,
WS_CHILD | WS_VISIBLE,
m_Style.Margin.left, m_Style.Margin.top, m_Style.Width, m_Style.Height,
m_Handle,
static_cast<HWND>(parent.GetElementHandle().GetHandle())
);
parent.AddChildRef(*this);
}
const std::wstring& GetName() const override { return m_ClassName; }
void OnPaint(Event e) override
{
PAINTSTRUCT ps;
HDC hdc = BeginPaint(m_hWnd, &ps);
FillRect(hdc, &ps.rcPaint, CreateSolidBrush(0));
EndPaint(m_hWnd, &ps);
}
public:
GSGUI_BEGIN_MSG_MAP
GSGUI_HANDLE_MSG(WM_PAINT, OnPaint)
GSGUI_END_MSG_MAP
};
int main()
{
Style wndStyle;
wndStyle.Width = 800;
wndStyle.Height = 600;
wndStyle.Margin = { 100, 100 };
Window window(L"Test", wndStyle);
window.Show();
try
{
Style btnStyle;
btnStyle.Width = 100;
btnStyle.Height = 30;
PushButton* btn = new PushButton(L"Click", btnStyle, window);
}
catch (const Element::Exception& err)
{
std::wcout << err.What() << "\n";
}
while (window.Running())
{
}
return 0;
}
宏:
#define GSGUI_BEGIN_MSG_MAP \
LRESULT HandleMessage(UINT uMsg, WPARAM wParam, LPARAM lParam) override \
{ \
GS::UI::Event event = TranslateMessage(m_hWnd, uMsg, wParam, lParam, this); \
switch (uMsg) \
{ \
case WM_NULL: \
return 0;
#define GSGUI_HANDLE_MSG(wm_msg, handler) \
case wm_msg: \
{ \
handler(event); \
} \
return 0;
#define GSGUI_END_MSG_MAP \
} \
return DefWindowProc(m_hWnd, uMsg, wParam, lParam); \
}
我认为这就是您需要知道的一切。如果需要有关代码的更多信息,请告诉我。
最后,请原谅我在编辑这个问题之前占用了您的时间。