123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179 |
- #include "WindowsFramelessDialog.h"
- #include "WindowsWindowEffect.h"
- #include "titlebar/TitleBar.h"
- #include "utils/Win32Utils.h"
- #include <QWindow>
- #include <QtWin>
- #include <QApplication>
- #include <QCloseEvent>
- #include <QScreen>
- constexpr int BORDER_WIDTH = 5;
- WindowsFramelessDialog::WindowsFramelessDialog(QWidget *parent) : QDialog(parent)
- {
- Q_INIT_RESOURCE(qframelesswindow);
- windowEffect = new WindowsWindowEffect(this);
- titleBar = new TitleBar(this);
- isResizeEnabled = true;
- // remove window border
- if (!Win32Utils::isWin7()) {
- setWindowFlags(this->windowFlags() | Qt::FramelessWindowHint);
- } else {
- setWindowFlags(Qt::FramelessWindowHint | Qt::WindowMinMaxButtonsHint);
- }
- // add DWM shadow and window animation
- windowEffect->addWindowAnimation((HWND)this->winId());
- if (effectType() == "AcrylicWindow") {
- windowEffect->addShadowEffect((HWND)this->winId());
- }
- connect(this->windowHandle(), &QWindow::screenChanged, this, &WindowsFramelessDialog::onScreenChanged);
- resize(500, 500);
- titleBar->raise();
- }
- void WindowsFramelessDialog::setTitleBar(TitleBar *tBar)
- {
- if (tBar != titleBar) {
- titleBar->deleteLater();
- titleBar = tBar;
- titleBar->setParent(this);
- titleBar->raise();
- }
- }
- void WindowsFramelessDialog::setResizeEnabled(bool isEnabled)
- {
- isResizeEnabled = isEnabled;
- }
- bool WindowsFramelessDialog::getResizeEnabled() const
- {
- return isResizeEnabled;
- }
- WindowsWindowEffect *WindowsFramelessDialog::getWindowEffect() const
- {
- return windowEffect;
- }
- TitleBar *WindowsFramelessDialog::getTitleBar() const
- {
- return titleBar;
- }
- void WindowsFramelessDialog::onScreenChanged(QScreen * /*screen*/)
- {
- HWND hWnd = (HWND)this->windowHandle()->winId();
- SetWindowPos(hWnd, NULL, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE | SWP_FRAMECHANGED);
- }
- void WindowsFramelessDialog::resizeEvent(QResizeEvent *event)
- {
- QWidget::resizeEvent(event);
- titleBar->resize(this->width(), titleBar->height());
- }
- /// Handle the Windows message
- bool WindowsFramelessDialog::nativeEvent(const QByteArray &eventType, void *message, long *result)
- {
- MSG *msg = static_cast<MSG *>(message);
- if (!msg->hwnd) {
- return QWidget::nativeEvent(eventType, message, result);
- }
- switch (msg->message) {
- case WM_NCHITTEST: {
- if (isResizeEnabled) {
- QPoint pos = QCursor::pos();
- int xPos = pos.x() - this->x();
- int yPos = pos.y() - this->y();
- int w = this->width();
- int h = this->height();
- bool lx = (xPos < BORDER_WIDTH);
- bool rx = (xPos > w - BORDER_WIDTH);
- bool ty = (yPos < BORDER_WIDTH);
- bool by = (yPos > h - BORDER_WIDTH);
- if (lx && ty) {
- *result = HTTOPLEFT;
- return true;
- } else if (rx && by) {
- *result = HTBOTTOMRIGHT;
- return true;
- } else if (rx && ty) {
- *result = HTTOPRIGHT;
- return true;
- } else if (lx && by) {
- *result = HTBOTTOMLEFT;
- return true;
- } else if (ty) {
- *result = HTTOP;
- return true;
- } else if (by) {
- *result = HTBOTTOM;
- return true;
- } else if (lx) {
- *result = HTLEFT;
- return true;
- } else if (rx) {
- *result = HTRIGHT;
- return true;
- }
- }
- } break;
- case WM_NCCALCSIZE: {
- RECT rc;
- if (msg->wParam) {
- rc = ((LPNCCALCSIZE_PARAMS)msg->lParam)->rgrc[0];
- } else {
- rc = *(LPRECT)msg->lParam;
- }
- bool isMax = Win32Utils::isMaximized(msg->hwnd);
- bool isFull = Win32Utils::isFullScreen(msg->hwnd);
- // adjust the size of client rect
- if (isMax && !isFull) {
- int ty = Win32Utils::getResizeBorderThickness(msg->hwnd, false);
- rc.top += ty;
- rc.bottom -= ty;
- int tx = Win32Utils::getResizeBorderThickness(msg->hwnd, true);
- rc.left += tx;
- rc.right -= tx;
- }
- // handle the situation that an auto-hide taskbar is enabled
- if ((isMax || isFull) && Win32Utils::Taskbar::isAutoHide()) {
- Win32Utils::Taskbar::Position position = Win32Utils::Taskbar::getPosition(msg->hwnd);
- if (position == Win32Utils::Taskbar::TOP) {
- rc.top += Win32Utils::Taskbar::AUTO_HIDE_THICKNESS;
- } else if (position == Win32Utils::Taskbar::BOTTOM) {
- rc.bottom -= Win32Utils::Taskbar::AUTO_HIDE_THICKNESS;
- } else if (position == Win32Utils::Taskbar::LEFT) {
- rc.left += Win32Utils::Taskbar::AUTO_HIDE_THICKNESS;
- } else if (position == Win32Utils::Taskbar::RIGHT) {
- rc.right -= Win32Utils::Taskbar::AUTO_HIDE_THICKNESS;
- }
- }
- if (!msg->wParam) {
- *result = 0;
- } else {
- *result = WVR_REDRAW;
- }
- return true;
- } break;
- }
- return QWidget::nativeEvent(eventType, message, result);
- }
|