Ошибка WinLamb: недопустимая инициализация члена - PullRequest
0 голосов
/ 11 сентября 2018

Я пытаюсь научиться использовать WinLamb , легкую современную библиотеку C ++ для Win32 API, только заголовки, используя лямбды C ++ 11 для обработки сообщений Windows.Я создал пустой проект Win32 в Visual Studio 2017 и добавил два файла, как в примере вверху статья Codeproject (то же самое на странице Github WinLamb).Единственный включенный файл - <winlamb/window_main.h>.Пытаясь скомпилировать, я получаю следующие ошибки (обе в строке 45 <winlamb/internals/window.h>):

C2614 wl::wli::window <wl::wli::w_thread_capable<LRESULT,0>>::_styler' illegal member initialization: 'styler' is not a base or member а такжеC2512 'wl::wli::styler<wl::wli::window<wl::wli::w_thread_capable<LRESULT,0>>>': no appropriate default constructor available

Весь код этого минимального примера приложения состоит из двух файлов:My_Window.h

#pragma once
#include <winlamb/window_main.h>

class My_Window : public wl::window_main {
public:
    My_Window();
};

и My_Window.cpp

#include "My_Window.h"

RUN(My_Window) // optional, generate WinMain call and instantiate My_Window

My_Window::My_Window()
{
    setup.wndClassEx.lpszClassName = L"SOME_CLASS_NAME"; // class name to be registered
    setup.title = L"This is my window";
    setup.style |= WS_MINIMIZEBOX;

    on_message(WM_CREATE, [this](wl::wm::create p)->LRESULT
    {
        set_text(L"A new title for the window");
        return 0;
    });

    on_message(WM_LBUTTONDOWN, [](wl::wm::lbuttondown p)->LRESULT
    {
        bool isCtrlDown = p.has_ctrl();
        long xPos = p.pos().x;
        return 0;
    });
}

Глядя на файл <winlamb/internals/window.h>, отметим, что он включает в себя следующие заголовки:

#include "w_thread_capable.h"
#include "w_user_control.h"
#include "styler.h"

Кажется, ошибки связаны с классом w_thread_capable.Шаблонный класс w_thread_capable имеет только один (защищенный) конструктор.Я пытался изменить его на общедоступный, но я получил те же ошибки.Вот часть файла <winlamb/internals/window.h>, где я получаю сообщение об ошибке:

template<typename baseT>
class window : public baseT {
// ...
private:

    class _styler final : public wli::styler<window> {
    public:
    // error here:
        explicit _styler(window* pWindow) noexcept : styler(pWindow) { }
    };
// ...  
};

Вот код класса styler (файл: <winlamb/internals/styler.h>):

/**
 * Part of WinLamb - Win32 API Lambda Library
 * https://github.com/rodrigocfd/winlamb
 * Copyright 2017-present Rodrigo Cesar de Freitas Dias
 * This library is released under the MIT License
 */

#pragma once
#include <Windows.h>

namespace wl {
namespace wli {

// Wraps window style changes with Get/SetWindowLongPtr, and allows custom methods.
template<typename wndT>
class styler {
private:
    wndT& _wnd;

protected:
    explicit styler(wndT* target) noexcept : _wnd(*target) { }

public:
    styler(const styler&) = delete;
    styler& operator=(const styler&) = delete; // non-copyable, non-movable

protected:
    HWND  hwnd() const noexcept   { return this->_wnd.hwnd(); }
    wndT& target() const noexcept { return this->_wnd; }

public:
    wndT& set_style(bool addStyle, DWORD styleFlags) noexcept {
        return this->_change_style_flags(false, addStyle, styleFlags);
    }

    wndT& set_style_ex(bool addStyle, DWORD styleFlags) noexcept {
        return this->_change_style_flags(true, addStyle, styleFlags);
    }

    bool has_style(DWORD styleFlags) const noexcept {
        return (GetWindowLongPtrW(this->_wnd.hwnd(), GWL_STYLE) & styleFlags) != 0;
    }

    bool has_style_ex(DWORD styleFlags) const noexcept {
        return (GetWindowLongPtrW(this->_wnd.hwnd(), GWL_EXSTYLE) & styleFlags) != 0;
    }

private:
    wndT& _change_style_flags(bool isEx, bool addStyle, DWORD styleFlags) noexcept {
        LONG_PTR curFlags = GetWindowLongPtrW(this->_wnd.hwnd(), isEx ? GWL_EXSTYLE : GWL_STYLE);
        if (addStyle) {
            curFlags |= static_cast<LONG_PTR>(styleFlags);
        } else {
            curFlags &= ~static_cast<LONG_PTR>(styleFlags);
        }
        SetWindowLongPtrW(this->_wnd.hwnd(), isEx ? GWL_EXSTYLE : GWL_STYLE, curFlags);
        return this->_wnd;
    }
};

}//namespace wli
}//namespace wl

Я, честно говоря, не могу понять этот код.Любое предложение приветствуется.

1 Ответ

0 голосов
/ 11 сентября 2018

Измените определение class _styler в winlamb/internals/window.h, чтобы явно указать полный шаблон класса в базовом инициализаторе.

class _styler final : public wli::styler<window> {
public:
    // Error in VC 2017
    //explicit _styler(window* pWindow) noexcept : styler(pWindow) { }
    // No errors
    explicit _styler(window* pWindow) noexcept : wli::styler<window>(pWindow) { }
};

или

class _styler final : public styler<window> {
public:
    explicit _styler(window* pWindow) noexcept : styler<window>(pWindow) { }
};
...