无法创建顶级子窗口。 Win32 api [关闭]

问题描述 投票:0回答:0

我的问题是当我想创建一个子窗口时,我从

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); \
    }

我认为这就是您需要知道的一切。如果需要有关代码的更多信息,请告诉我。

最后,请原谅我在编辑这个问题之前占用了您的时间。

c++ winapi
© www.soinside.com 2019 - 2024. All rights reserved.