1
0
mirror of https://github.com/jaredtao/TaoQuick.git synced 2025-02-06 21:48:24 +08:00

158 lines
5.2 KiB
C++
Raw Normal View History

2019-12-18 13:26:44 +08:00
#include "TaoView.h"
2020-06-14 13:28:35 +08:00
2020-07-02 23:57:46 +08:00
#include <QCursor>
2020-07-02 23:13:54 +08:00
#include <QGuiApplication>
2020-06-14 00:57:36 +08:00
#include <QQmlContext>
2019-07-18 10:17:02 +08:00
#include <QQmlEngine>
#include <QQuickItem>
2020-07-05 02:12:59 +08:00
#include <QScreen>
2020-07-18 00:07:18 +08:00
2020-07-02 23:13:54 +08:00
#if WIN32
#include <WinUser.h>
#include <dwmapi.h>
#include <objidl.h> // Fixes error C2504: 'IUnknown' : base class undefined
#include <windows.h>
#include <windowsx.h>
#pragma comment(lib, "Dwmapi.lib") // Adds missing library, fixes error LNK2019: unresolved external symbol __imp__DwmExtendFrameIntoClientArea
#pragma comment(lib, "user32.lib")
#endif
2020-07-02 23:57:46 +08:00
2020-08-07 10:58:37 +08:00
#ifdef WIN32
static long hitTest(RECT winrect, long x, long y, int borderWidth)
{
// 鼠标区域位于窗体边框,进行缩放
if ((x >= winrect.left) && (x < winrect.left + borderWidth) && (y >= winrect.top) && (y < winrect.top + borderWidth)) {
return HTTOPLEFT;
} else if (x < winrect.right && x >= winrect.right - borderWidth && y >= winrect.top && y < winrect.top + borderWidth) {
return HTTOPRIGHT;
} else if (x >= winrect.left && x < winrect.left + borderWidth && y < winrect.bottom && y >= winrect.bottom - borderWidth) {
return HTBOTTOMLEFT;
} else if (x < winrect.right && x >= winrect.right - borderWidth && y < winrect.bottom && y >= winrect.bottom - borderWidth) {
return HTBOTTOMRIGHT;
} else if (x >= winrect.left && x < winrect.left + borderWidth) {
return HTLEFT;
} else if (x < winrect.right && x >= winrect.right - borderWidth) {
return HTRIGHT;
} else if (y >= winrect.top && y < winrect.top + borderWidth) {
return HTTOP;
} else if (y < winrect.bottom && y >= winrect.bottom - borderWidth) {
return HTBOTTOM;
} else {
return 0;
}
}
#endif
static bool isMaxWin(QWindow *win)
{
return win->windowStates() & Qt::WindowMaximized;
}
static bool isFullWin(QQuickView *win)
{
return win->windowStates() & Qt::WindowFullScreen;
}
2020-07-02 23:57:46 +08:00
2020-08-07 10:58:37 +08:00
TaoView::TaoView(QWindow *parent)
2020-07-02 23:13:54 +08:00
: QQuickView(parent)
2019-07-18 10:17:02 +08:00
{
2020-07-11 00:37:07 +08:00
setFlags(Qt::Window | Qt::FramelessWindowHint | Qt::WindowMinMaxButtonsHint);
2019-07-18 10:17:02 +08:00
setResizeMode(SizeRootObjectToView);
setColor(QColor(Qt::transparent));
2020-08-07 10:58:37 +08:00
setMinimumSize({1440, 960});
resize(1440, 960);
2020-07-02 23:13:54 +08:00
#if WIN32
DWORD style = ::GetWindowLong(HWND(winId()), GWL_STYLE);
style |= WS_MINIMIZEBOX | WS_THICKFRAME | WS_CAPTION;
::SetWindowLong(HWND(winId()), GWL_STYLE, style);
#endif
2020-08-07 10:58:37 +08:00
setIsMax(isMaxWin(this));
connect(this, &QWindow::windowStateChanged, this, [&](Qt::WindowState state) { setIsMax(state == Qt::WindowMaximized); });
2019-07-18 10:17:02 +08:00
}
2020-08-07 10:58:37 +08:00
TaoView::~TaoView() {}
2019-07-18 10:17:02 +08:00
2019-08-03 17:47:27 +08:00
void TaoView::moveToScreenCenter()
{
2020-08-07 10:58:37 +08:00
auto geo = screen()->availableGeometry();
int w = width();
int h = height();
auto pos = QPoint{ geo.x() + (geo.width() - w) / 2, geo.y() + (geo.height() - h) / 2 };
setPosition(pos.x(), pos.y());
update();
2019-08-03 17:47:27 +08:00
}
2020-07-02 23:57:46 +08:00
2020-07-03 00:21:44 +08:00
void TaoView::setIsMax(bool isMax)
2020-07-02 23:57:46 +08:00
{
2020-07-03 00:21:44 +08:00
if (m_isMax == isMax)
return;
2020-07-02 23:57:46 +08:00
2020-07-03 00:21:44 +08:00
m_isMax = isMax;
emit isMaxChanged(m_isMax);
2020-07-02 23:57:46 +08:00
}
2020-07-02 23:13:54 +08:00
#if WIN32
2020-07-18 00:07:18 +08:00
const long border_width = 6;
2020-08-27 09:19:56 +08:00
#if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0)
bool TaoView::nativeEvent(const QByteArray &eventType, void *message, qintptr *result)
#else
2020-08-07 10:58:37 +08:00
bool TaoView::nativeEvent(const QByteArray &eventType, void *message, long *result)
2020-08-27 09:19:56 +08:00
#endif
2020-07-02 23:13:54 +08:00
{
2020-08-07 10:58:37 +08:00
if (!result) {
return false;
}
MSG *msg = reinterpret_cast<MSG *>(message);
if (!msg || (msg && !msg->hwnd)) {
return false;
}
2020-07-02 23:13:54 +08:00
switch (msg->message) {
2020-08-07 10:58:37 +08:00
case WM_NCCALCSIZE: {
const auto mode = static_cast<BOOL>(msg->wParam);
*result = mode ? WVR_REDRAW : 0;
const auto clientRect = mode ? &(reinterpret_cast<LPNCCALCSIZE_PARAMS>(msg->lParam)->rgrc[0]) : reinterpret_cast<LPRECT>(msg->lParam);
if (!isMaxWin(this) && !isFullWin(this)) {
if (clientRect->top != 0)
clientRect->top -= 1;
} else if (IsMaximized(HWND(winId()))) {
const int bw = ::GetSystemMetrics(SM_CXSIZEFRAME) + ::GetSystemMetrics(SM_CXPADDEDBORDER);
const int bh = ::GetSystemMetrics(SM_CYSIZEFRAME) + ::GetSystemMetrics(SM_CXPADDEDBORDER);
clientRect->top += bh;
clientRect->bottom -= bh;
clientRect->left += bw;
clientRect->right -= bw;
}
return true;
2020-07-02 23:13:54 +08:00
}
2020-08-07 10:58:37 +08:00
case WM_NCHITTEST: {
*result = 0;
2020-07-02 23:13:54 +08:00
2020-08-07 10:58:37 +08:00
RECT winrect;
GetWindowRect(HWND(winId()), &winrect);
2020-07-02 23:13:54 +08:00
2020-08-07 10:58:37 +08:00
long x = GET_X_LPARAM(msg->lParam);
long y = GET_Y_LPARAM(msg->lParam);
2020-07-02 23:13:54 +08:00
2020-08-07 10:58:37 +08:00
*result = 0;
if (!isMaxWin(this) && !isFullWin(this)) { //非最大化、非全屏时,进行命中测试,处理边框拖拽
*result = hitTest(winrect, x, y, border_width);
if (0 != *result) {
return true;
}
2020-07-02 23:13:54 +08:00
}
2020-08-07 10:58:37 +08:00
double dpr = qApp->devicePixelRatio();
QPoint pos = mapFromGlobal(QPoint(x / dpr, y / dpr));
QRect titleRect(border_width, border_width, width() * 0.8, 50);
if (titleRect.contains(pos)) {
*result = HTCAPTION;
return true;
2020-07-02 23:13:54 +08:00
}
2020-08-07 10:58:37 +08:00
return false;
} //end case WM_NCHITTEST
2020-07-02 23:13:54 +08:00
}
return QQuickView::nativeEvent(eventType, message, result);
}
#endif