2025-01-04 04:12:51 +00:00
|
|
|
#pragma once
|
|
|
|
|
|
|
|
|
|
#include <Windows.h>
|
2025-01-07 14:47:07 +00:00
|
|
|
|
2025-01-04 04:12:51 +00:00
|
|
|
#if __cplusplus >= 201703L
|
|
|
|
|
#include <optional>
|
|
|
|
|
#else
|
2025-01-07 14:47:07 +00:00
|
|
|
#include <stdexcept>
|
2025-01-04 04:12:51 +00:00
|
|
|
namespace std {
|
|
|
|
|
struct nullopt_t { // no-value state indicator
|
|
|
|
|
struct _Tag {
|
|
|
|
|
};
|
|
|
|
|
constexpr explicit nullopt_t(_Tag) {}
|
|
|
|
|
};
|
2025-03-13 00:42:41 +00:00
|
|
|
constexpr nullopt_t nullopt{ nullopt_t::_Tag{} };
|
2025-01-04 04:12:51 +00:00
|
|
|
|
2025-03-13 00:42:41 +00:00
|
|
|
class bad_optional_access : public std::exception
|
|
|
|
|
{
|
|
|
|
|
public:
|
|
|
|
|
const char* what() const noexcept override
|
|
|
|
|
{
|
|
|
|
|
return "bad optional access";
|
|
|
|
|
}
|
|
|
|
|
};
|
2025-01-04 04:12:51 +00:00
|
|
|
|
2025-03-13 00:42:41 +00:00
|
|
|
template <class T>
|
2025-01-04 04:12:51 +00:00
|
|
|
class optional {
|
|
|
|
|
public:
|
2025-03-13 00:42:41 +00:00
|
|
|
constexpr optional() noexcept : _engaged(false) {}
|
|
|
|
|
constexpr optional(nullopt_t) noexcept : _engaged(false) {}
|
2025-01-04 04:12:51 +00:00
|
|
|
|
2025-03-13 00:42:41 +00:00
|
|
|
optional(const optional& other) : _engaged(other._engaged) {
|
|
|
|
|
if (other._engaged) {
|
|
|
|
|
new (_storage) T(*other);
|
|
|
|
|
}
|
2025-01-04 04:12:51 +00:00
|
|
|
}
|
|
|
|
|
|
2025-03-13 00:42:41 +00:00
|
|
|
optional(optional&& other) noexcept : _engaged(other._engaged) {
|
|
|
|
|
if (other._engaged) {
|
|
|
|
|
new (_storage) T(std::move(*other));
|
|
|
|
|
other._engaged = false;
|
2025-01-04 04:12:51 +00:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2025-03-13 00:42:41 +00:00
|
|
|
optional& operator=(const optional& other)
|
|
|
|
|
{
|
|
|
|
|
if(this == &other)
|
|
|
|
|
return *this;
|
|
|
|
|
if(_engaged && other._engaged)
|
|
|
|
|
{
|
|
|
|
|
**this = *other;
|
|
|
|
|
}
|
|
|
|
|
else if(other._engaged)
|
|
|
|
|
{
|
|
|
|
|
new (_storage) T(*other);
|
|
|
|
|
_engaged = true;
|
|
|
|
|
} else if(_engaged)
|
|
|
|
|
{
|
|
|
|
|
reset();
|
2025-01-04 04:12:51 +00:00
|
|
|
}
|
2025-03-13 00:42:41 +00:00
|
|
|
|
|
|
|
|
return *this;
|
|
|
|
|
|
2025-01-04 04:12:51 +00:00
|
|
|
}
|
|
|
|
|
|
2025-03-13 00:42:41 +00:00
|
|
|
optional& operator=(optional&& other) noexcept
|
|
|
|
|
{
|
|
|
|
|
if(this == &other)
|
|
|
|
|
return *this;
|
|
|
|
|
if(_engaged && other._engaged)
|
|
|
|
|
{
|
|
|
|
|
**this = std::move(*other);
|
|
|
|
|
|
|
|
|
|
} else if (other._engaged)
|
|
|
|
|
{
|
|
|
|
|
new(_storage) T(std::move(*other));
|
|
|
|
|
_engaged = true;
|
|
|
|
|
|
|
|
|
|
} else if(_engaged)
|
|
|
|
|
{
|
|
|
|
|
reset();
|
|
|
|
|
}
|
|
|
|
|
other._engaged = false;
|
|
|
|
|
return *this;
|
2025-01-04 04:12:51 +00:00
|
|
|
}
|
|
|
|
|
|
2025-03-13 00:42:41 +00:00
|
|
|
optional(const T& value) : _engaged(true) {
|
|
|
|
|
new (_storage) T(value);
|
2025-01-04 04:12:51 +00:00
|
|
|
}
|
|
|
|
|
|
2025-03-13 00:42:41 +00:00
|
|
|
optional(T&& value) : _engaged(true) {
|
|
|
|
|
new (_storage) T(std::move(value));
|
2025-01-04 04:12:51 +00:00
|
|
|
}
|
|
|
|
|
|
2025-03-13 00:42:41 +00:00
|
|
|
~optional() {
|
|
|
|
|
reset();
|
2025-01-04 04:12:51 +00:00
|
|
|
}
|
|
|
|
|
|
2025-03-13 00:42:41 +00:00
|
|
|
void reset() noexcept {
|
|
|
|
|
if (_engaged) {
|
|
|
|
|
reinterpret_cast<T*>(_storage)->~T();
|
|
|
|
|
_engaged = false;
|
2025-01-04 04:12:51 +00:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2025-03-13 00:42:41 +00:00
|
|
|
constexpr bool has_value() const noexcept
|
|
|
|
|
{
|
|
|
|
|
return _engaged;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
T& operator*() &
|
|
|
|
|
{
|
|
|
|
|
if(!_engaged)
|
|
|
|
|
throw std::bad_optional_access();
|
|
|
|
|
return *reinterpret_cast<T*>(_storage);
|
|
|
|
|
}
|
|
|
|
|
const T& operator*() const&
|
|
|
|
|
{
|
|
|
|
|
if(!_engaged)
|
|
|
|
|
throw std::bad_optional_access();
|
|
|
|
|
return *reinterpret_cast<const T*>(_storage);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
T&& operator*() &&
|
|
|
|
|
{
|
|
|
|
|
if(!_engaged)
|
|
|
|
|
throw std::bad_optional_access();
|
|
|
|
|
return std::move(*reinterpret_cast<T*>(_storage));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
const T&& operator*() const&&
|
|
|
|
|
{
|
|
|
|
|
if(!_engaged)
|
|
|
|
|
throw std::bad_optional_access();
|
|
|
|
|
return std::move(*reinterpret_cast<T*>(_storage));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
T* operator->() {
|
|
|
|
|
return reinterpret_cast<T*>(_storage);
|
|
|
|
|
}
|
|
|
|
|
const T* operator->() const {
|
|
|
|
|
return reinterpret_cast<const T*>(_storage);
|
2025-01-04 04:12:51 +00:00
|
|
|
}
|
|
|
|
|
|
2025-03-13 00:42:41 +00:00
|
|
|
explicit operator bool() const noexcept {
|
|
|
|
|
return _engaged;
|
2025-01-04 04:12:51 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private:
|
2025-03-13 00:42:41 +00:00
|
|
|
bool _engaged;
|
|
|
|
|
char _storage[sizeof(T)];
|
2025-01-04 04:12:51 +00:00
|
|
|
};
|
|
|
|
|
|
2025-03-13 00:42:41 +00:00
|
|
|
|
|
|
|
|
//
|
|
|
|
|
// template<typename T>
|
|
|
|
|
// class optional {
|
|
|
|
|
// public:
|
|
|
|
|
// optional() : has_value_(false) {}
|
|
|
|
|
// optional(const T& value) : has_value_(true), value_(value) {}
|
|
|
|
|
// optional(T&& value) : has_value_(true), value_(std::move(value)) {}
|
|
|
|
|
// optional(nullopt_t) : has_value_(false) {}
|
|
|
|
|
//
|
|
|
|
|
// bool has_value() const {
|
|
|
|
|
// return has_value_;
|
|
|
|
|
// }
|
|
|
|
|
//
|
|
|
|
|
// T& value() {
|
|
|
|
|
// if (!has_value_) {
|
|
|
|
|
// throw std::runtime_error("optional has no value");
|
|
|
|
|
// }
|
|
|
|
|
// return value_;
|
|
|
|
|
// }
|
|
|
|
|
//
|
|
|
|
|
// const T& value() const {
|
|
|
|
|
// if (!has_value_) {
|
|
|
|
|
// throw std::runtime_error("optional has no value");
|
|
|
|
|
// }
|
|
|
|
|
// return value_;
|
|
|
|
|
// }
|
|
|
|
|
//
|
|
|
|
|
// T& operator*() {
|
|
|
|
|
// return value();
|
|
|
|
|
// }
|
|
|
|
|
//
|
|
|
|
|
// const T& operator*() const {
|
|
|
|
|
// return value();
|
|
|
|
|
// }
|
|
|
|
|
//
|
|
|
|
|
// T* operator->() {
|
|
|
|
|
// return &value();
|
|
|
|
|
// }
|
|
|
|
|
//
|
|
|
|
|
// const T* operator->() const {
|
|
|
|
|
// return &value();
|
|
|
|
|
// }
|
|
|
|
|
//
|
|
|
|
|
// bool operator==(const optional& other) const {
|
|
|
|
|
// if (has_value_ && other.has_value_) {
|
|
|
|
|
// return value_ == other.value_;
|
|
|
|
|
// }
|
|
|
|
|
// return has_value_ == other.has_value_;
|
|
|
|
|
// }
|
|
|
|
|
//
|
|
|
|
|
// bool operator!=(const optional& other) const {
|
|
|
|
|
// return !(*this == other);
|
|
|
|
|
// }
|
|
|
|
|
//
|
|
|
|
|
// bool operator!() const {
|
|
|
|
|
// return !has_value();
|
|
|
|
|
// }
|
|
|
|
|
//
|
|
|
|
|
// private:
|
|
|
|
|
// bool has_value_;
|
|
|
|
|
// T value_;
|
|
|
|
|
// };
|
|
|
|
|
|
2025-01-04 04:12:51 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
#include "FramelessDelegate.h"
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
class FramelessDelegateWin : public FramelessDelegate {
|
|
|
|
|
Q_OBJECT
|
|
|
|
|
|
|
|
|
|
public:
|
|
|
|
|
FramelessDelegateWin(QWidget* parent);
|
|
|
|
|
~FramelessDelegateWin() override;
|
|
|
|
|
|
|
|
|
|
#if QT_VERSION < QT_VERSION_CHECK(6, 0, 0)
|
|
|
|
|
bool nativeEvent(const QByteArray& eventType, void* message, long* result) override;
|
|
|
|
|
#else
|
|
|
|
|
bool nativeEvent(const QByteArray& eventType, void* message, qintptr* result) override;
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
protected:
|
|
|
|
|
void OnShow() override;
|
|
|
|
|
void OnHide() override;
|
|
|
|
|
void OnClose() override;
|
|
|
|
|
void OnScreenChangeInternaal() override;
|
|
|
|
|
void AddMoveBar(QWidget* moveWidget) override;
|
|
|
|
|
|
|
|
|
|
private:
|
|
|
|
|
double DpiScale(double value);
|
|
|
|
|
double UnDpiScale(double value);
|
|
|
|
|
void CheckMonitorChanged();
|
|
|
|
|
|
|
|
|
|
void ShowSystemMenu(const QPoint& pos);
|
|
|
|
|
|
|
|
|
|
void SetNativeWindowLong();
|
|
|
|
|
|
|
|
|
|
#if QT_VERSION < QT_VERSION_CHECK(6, 0, 0)
|
|
|
|
|
bool OnNCTitTest(MSG* msg, long* result);
|
|
|
|
|
#else
|
|
|
|
|
bool OnNCTitTest(MSG* msg, qintptr* result);
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
private:
|
|
|
|
|
bool firstShow_{ true };
|
|
|
|
|
std::optional<QRect> workRect_;
|
|
|
|
|
HMONITOR monitor_{ nullptr };
|
|
|
|
|
WINDOWPLACEMENT wndPlaceMent_{ 0, 0, 0, {0, 0}, {0, 0}, {0, 0, 0, 0} };
|
|
|
|
|
};
|