DYTSrouce/src/ui/FramelessDelegateWin.h

265 lines
6.4 KiB
C
Raw Normal View History

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