C ++. Я получаю нарушение прав доступа в CreateWindow с помощью метода get для получения строки имени класса - PullRequest
0 голосов
/ 19 марта 2020

(«коды ошибок» скопированы и вставлены внизу)

Я слежу за онлайн-учебником, но у меня также есть 3 книги и я закончил продвинутый курс по С ++ от microsoft @ edX, но понимаю, что я все еще новичок Я упоминаю об этом, чтобы люди не думали, что я учусь, в первую очередь, из-за плохих учебных пособий по YouTube, а не из-за этого.

Эта ошибка изнутри созданного мною класса Windows Window 'Window', который содержит другое класс, 'Windowclass'. Они используются для создания windows, а внутренний синглтон-класс скрывает детали.

Я скопирую код, который мне кажется уместным, из конструктора.

Кажется, проблема может быть в конструктор окна @ hWnd = CreateWindow ( Здесь , name, et c, et c:

Window::Window(int width, int height, const char* name) noexcept

{
    RECT wr;
    wr.left = 100;
    wr.right = width + wr.left;
    wr.top = 100;
    wr.bottom = height + wr.top;
    AdjustWindowRect(&wr, WS_CAPTION | WS_MINIMIZEBOX | WS_SYSMENU, false);
    //create window & get hWnd
    hWnd = CreateWindow(WindowClass::GetName(), name, WS_CAPTION | WS_MINIMIZEBOX | WS_SYSMENU | CW_USEDEFAULT | CW_USEDEFAULT, wr.right, wr.left, wr.bottom, wr.top, nullptr, nullptr, WindowClass::GetInstance(), this);

    ShowWindow(hWnd, SW_SHOWDEFAULT);
}

Если я изменю первый аргумент из CreateWindow на то, что я думаю называется строковым литералом, т. е. «окном» вместо метода получения GetName (), тогда программа, кажется, работает нормально.

здесь приведен код метода получения, обратите внимание, что средство получения работает нормально в другом месте. Например, когда он вызывается при создании окна имя класса

wc.lpszClassName = GetName();

Getter:

const char* Window::WindowClass::GetName() noexcept {

    return wndClassName;
}

, хотя я не хочу копировать слишком много кода, ниже WindowClass который находится в его родительском классе, «Окне».

Обратите также внимание, что мое психическое здоровье не очень хорошее, и кодирование действительно помогает (с большим перерывом в перерыве) в восстановлении моего психического здоровья, аргументах и ​​оскорблениях нет ' т. но счастлив y чтобы получить конструктивную обратную связь.

class WindowClass
{
public:
    static const char* GetName() noexcept;
    static HINSTANCE GetInstance() noexcept;

private:
    WindowClass() noexcept;
    ~WindowClass();
    WindowClass(const WindowClass&) = delete;
    WindowClass& operator=(const WindowClass&) = delete;
    static constexpr const char* wndClassName = "Ryan Direct3d";
    static WindowClass wndClass;
    HINSTANCE hInst;
};

Я ценю все отзывы по этому вопросу, которые имеют отношение. Почему я получаю: Исключение выдается при 0x00000000 в WindowsApp1.exe: 0xC0000005: расположение выполнения нарушения прав доступа 0x00000000. Необработанное исключение в 0x7155CCE0 в WindowsApp1.exe: 0xC000041D: Обнаружено необработанное исключение во время обратного вызова пользователя.

Код для компиляции ниже этой строки


#include <Windows.h>
#include <string>

class Window
{
private:
    //singleton class - manages registration and cleanup / of window  class (unregistered)
    class WindowClass
    {
    public:
        static const char* GetName() noexcept;
        static HINSTANCE GetInstance() noexcept;

    private:
        WindowClass() noexcept;
        ~WindowClass();
        WindowClass(const WindowClass&) = delete;
        WindowClass& operator=(const WindowClass&) = delete;
        //wndClassName called by getter
        static constexpr const char* wndClassName = "Ryan";
        static WindowClass wndClass;
        HINSTANCE hInst;
    };
public:

    Window(int width, int height, const char* name) noexcept;
    ~Window();
    Window(const Window&) = delete;
    Window& operator= (const Window&) = delete;

private:
    int width = 0;
    int height = 0;
    HWND hWnd;
};


//Window Class stuff
Window::WindowClass Window::WindowClass::wndClass; //
Window::WindowClass::WindowClass() noexcept : hInst(GetModuleHandle(nullptr))
{

    WNDCLASSEX wc = { 0 };
    wc.cbSize = sizeof(wc);
    wc.style = CS_OWNDC;
    //wc.lpfnWndProc = WndProc;
    wc.cbClsExtra = 0;
    wc.cbWndExtra = 0;
    wc.hInstance = GetInstance();
    wc.hIcon = nullptr;
    wc.hCursor = nullptr;
    wc.hbrBackground = nullptr;
    wc.lpszMenuName = nullptr;
    wc.lpszClassName = GetName();
    wc.hIconSm = nullptr;
    RegisterClassEx(&wc);

}


const char* Window::WindowClass::GetName() noexcept {

    return wndClassName;
}

HINSTANCE Window::WindowClass::GetInstance() noexcept {

    return wndClass.hInst;

}
Window::WindowClass::~WindowClass()
{
    UnregisterClass(wndClassName, GetInstance());
}


//Window Creation
Window::Window(int width, int height, const char* name) noexcept
{
    RECT wr;
    wr.left = 100;
    wr.right = width + wr.left;
    wr.top = 100;
    wr.bottom = height + wr.top;
    AdjustWindowRect(&wr, WS_CAPTION | WS_MINIMIZEBOX | WS_SYSMENU, false);
    //create window & get hWnd
    hWnd = CreateWindow("Ryan", name, WS_CAPTION | WS_MINIMIZEBOX | WS_SYSMENU | CW_USEDEFAULT | CW_USEDEFAULT, wr.right, wr.left, wr.bottom, wr.top, nullptr, nullptr, WindowClass::GetInstance(), nullptr);
        ShowWindow(hWnd, SW_SHOW);
}


Window::~Window() {

    DestroyWindow(hWnd);
}



//wndprocs
LRESULT CALLBACK WndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
{

    switch (msg) //use a switch because in future we will add / process many kinds of messages
    {
    case WM_KEYUP:
        if (wParam == 'F')
        {
            SetWindowText(hWnd, "Dogmah");
        }
        break;

    case WM_CLOSE:
        PostQuitMessage(69);
        break;
    case WM_KEYDOWN:
        if (wParam == 'F')
        {
            SetWindowText(hWnd, "New Name");
        }
        break;
    case WM_CHAR:
    {
        static std::string title;
        title.push_back((char)wParam);
        SetWindowText(hWnd, title.c_str());
    }
    case WM_LBUTTONDOWN:
    {

    }

    }

    return DefWindowProc(hWnd, msg, wParam, lParam);
}

int CALLBACK WinMain(
    HINSTANCE hInstance,
    HINSTANCE hPrevInstance,
    LPSTR   lpCmdLine,
    int nCmdShow)
{

    Window Ryan(600, 500, "Hey");


    //message pump
    MSG msg;
    BOOL gResult;
    //register custom class for outputting EXTRA msg details

    while ((gResult = GetMessage(&msg, nullptr, 0, 0)) > 0)
    {
        TranslateMessage(&msg);

        DispatchMessage(&msg);
    }

    if (gResult == -1) { return -1; }

    else { return msg.wParam; }

    return 0;
}

1 Ответ

0 голосов
/ 20 марта 2020

Вы прокомментировали назначение WndPro c в WNDCLASSEX:

Window::WindowClass::WindowClass() noexcept : hInst(GetModuleHandle(nullptr))
{

    WNDCLASSEX wc = { 0 };
    wc.cbSize = sizeof(wc);
    wc.style = CS_OWNDC;
    //wc.lpfnWndProc = WndProc;
    ...

Чтобы исправить, просто объявите вашу функцию WndPro c (которая определена ниже). И раскомментируйте.

LRESULT CALLBACK WndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam);

//Window Class stuff
Window::WindowClass Window::WindowClass::wndClass; //
Window::WindowClass::WindowClass() noexcept : hInst(GetModuleHandle(nullptr))
{

    WNDCLASSEX wc = { 0 };
    wc.cbSize = sizeof(wc);
    wc.style = CS_OWNDC;
    wc.lpfnWndProc = WndProc;
    ...

После того, как я сделал это изменение, cra sh исчезнет, ​​и у вас появится окно:

enter image description here

...