tcStyleToolDialog.cpp
#include "tcStyleToolDialog.h"#include "ui_tcStyleToolDialog.h"#include <QDesktopWidget>#include <QMouseEvent>#include <QPainter>#include <qt_windows.h>#include <windowsx.h>#include <QDebug>void TcStyleToolDialog::paintShadow(QWidget* widget, int shadowWidth){QPainterPath path;path.setFillRule(Qt::WindingFill);path.addRoundedRect(shadowWidth, shadowWidth, widget->width()-shadowWidth*2, widget->height()-shadowWidth*2,shadowWidth, shadowWidth);QPainter painter(widget);painter.setRenderHint(QPainter::Antialiasing, true);painter.fillPath(path, QBrush(Qt::white));QColor color(0, 0, 0, 250);for(int i=0; i<shadowWidth; ++i){QPainterPath path;path.setFillRule(Qt::WindingFill);path.addRoundedRect(shadowWidth -i,shadowWidth -i,widget->width()-(shadowWidth -i)*2,widget->height()-(shadowWidth -i)*2,shadowWidth, shadowWidth, Qt::AbsoluteSize);color.setAlpha((shadowWidth*24) / (i+1)); //- qSqrt(i)*50);painter.setPen(color);painter.drawPath(path);}}bool TcStyleToolDialog::resizeEvent(const QByteArray&, void* msg, long* result, const QRect& wndRect){bool ret = false;MSG* message = (MSG*) msg;switch(message->message){case WM_NCHITTEST:int xPos = GET_X_LPARAM(message->lParam) - wndRect.x();int yPos = GET_Y_LPARAM(message->lParam) - wndRect.y();//if ( childAt(xPos, yPos) == ? ) // ? 为桌面控件名,即可实现拖动,但无法双击缩放//{// // 移动// *result = HTCAPTION;//}else//{// return false;//}ret = true;if ( abs(xPos) <= 5 && abs(yPos) <= 5 ){*result = HTTOPLEFT;}elseif ( abs(xPos-wndRect.width()) <= 5 && abs(yPos) <= 5 ){*result = HTTOPRIGHT;}elseif ( abs(xPos) <= 5 && abs(yPos-wndRect.height()) <= 5 ){*result = HTBOTTOMLEFT;}elseif ( abs(xPos-wndRect.width()) <= 5 && abs(yPos-wndRect.height()) <= 5 ){*result = HTBOTTOMRIGHT;}elseif ( abs(xPos) <= 3 ){*result = HTLEFT;}elseif ( abs(xPos-wndRect.width()) <= 3 ){*result = HTRIGHT;}elseif ( abs(yPos) <= 3 ){*result = HTTOP;}elseif ( abs(yPos-wndRect.height()) <= 3 ){*result = HTBOTTOM;}else{ret = false;}}return ret;}bool TcStyleToolDialog::sorptionEvent(const QByteArray&, void* msg, long*, int shadowWidth){MSG* message = (MSG*) msg;if ( message->message == WM_MOVING ){LPRECT prc = (LPRECT)message->lParam;int wndWidth = prc->right - prc->left;int wndHeight = prc->bottom - prc->top;const int distance = 16;static bool sorptionX = false;static bool sorptionY = false;static int startX;static int startY;if ( abs(prc->left) <= distance ){prc->left = -shadowWidth;prc->right = wndWidth-shadowWidth;if ( ! sorptionX ){sorptionX = true;startX = QCursor::pos().x();}}if ( abs(prc->right - qApp->desktop()->availableGeometry().right()) <= distance ){prc->left = qApp->desktop()->availableGeometry().right() - wndWidth + shadowWidth;prc->right = qApp->desktop()->availableGeometry().right() + shadowWidth;if ( ! sorptionX ){sorptionX = true;startX = QCursor::pos().x();}}if ( abs(prc->top) <= distance ){prc->top = -shadowWidth;prc->bottom = wndHeight-shadowWidth;if ( ! sorptionY ){sorptionY = true;startY = QCursor::pos().y();}}if ( abs(prc->bottom - qApp->desktop()->availableGeometry().bottom()) <= distance ){prc->top = qApp->desktop()->availableGeometry().bottom() - wndHeight + shadowWidth;prc->bottom = qApp->desktop()->availableGeometry().bottom() + shadowWidth;if ( ! sorptionY ){sorptionY = true;startY = QCursor::pos().y();}}if ( sorptionX ){int newX = QCursor::pos().x() - startX;if ( abs(newX) > distance ){prc->left = prc->left + newX - shadowWidth;prc->right = prc->left + wndWidth;sorptionX = false;}}if ( sorptionY ){int newY = QCursor::pos().y() - startY;if ( abs(newY) > distance ){prc->top = prc->top + newY - shadowWidth;prc->bottom = prc->top + wndHeight;sorptionY = false;}}}return false;}TcStyleToolDialog::TcStyleToolDialog(QWidget* parent): QDialog(parent), ui(new Ui::TcStyleToolDialog), m_dialogResize(false){ui->setupUi(this);setWindowFlags( windowFlags() | Qt::FramelessWindowHint );ui->DialogWidget->setAttribute(Qt::WA_TranslucentBackground, true);//QMargins shadowMargins = ui->dialogLayout->contentsMargins();m_shadowWidth = 0; //(shadowMargins.left()+shadowMargins.top()+shadowMargins.right()+shadowMargins.bottom())/4;}TcStyleToolDialog::~TcStyleToolDialog(){delete ui;}QLayout* TcStyleToolDialog::clientLayout(){return ui->clientLayout;}void TcStyleToolDialog::setShadowWidth(int shadowWidth){m_shadowWidth = shadowWidth;setContentsMargins(0,0,0,0);ui->dialogLayout->setContentsMargins(shadowWidth, shadowWidth, shadowWidth, shadowWidth);setAttribute(Qt::WA_TranslucentBackground, shadowWidth >0);}void TcStyleToolDialog::initClient(QWidget* widget){widget->setParent(ui->DialogWidget);ui->clientLayout->addWidget(widget);move((qApp->desktop()->availableGeometry().bottomRight()- QPoint(geometry().size().width(), geometry().size().height())) /2);}void TcStyleToolDialog::paintEvent(QPaintEvent*){if ( m_shadowWidth >0 ){paintShadow(this, m_shadowWidth);}}bool TcStyleToolDialog::nativeEvent(const QByteArray& eventType, void* msg, long* result){MSG* message = (MSG*) msg;switch(message->message){case WM_NCHITTEST:int xPos = GET_X_LPARAM(message->lParam) - geometry().x();int yPos = GET_Y_LPARAM(message->lParam) - geometry().y();if ( isMoveBar(childAt(xPos, yPos)) ){*result = HTCAPTION;return true;}elseif ( m_dialogResize ){return resizeEvent(eventType, msg, result, QRect(geometry().x()+m_shadowWidth,geometry().y()+m_shadowWidth,geometry().width()-m_shadowWidth-m_shadowWidth,geometry().height()-m_shadowWidth-m_shadowWidth));}}return QDialog::nativeEvent(eventType, msg, result);}
tcStyleToolDialog.h
#pragma once#ifndef TIANCHI_TCSTYLETOOLDIALOG_H#define TIANCHI_TCSTYLETOOLDIALOG_H#include <QDialog>#include <QPixmap>#include <QVBoxLayout>#ifndef TIANCHI_API#define TIANCHI_API#endifnamespace Ui {class TcStyleToolDialog;}class TIANCHI_API TcStyleToolDialog : public QDialog{typedef QDialog inherited;Q_OBJECTpublic:static void paintShadow(QWidget* widget, int shadowWidth=3);static bool resizeEvent(const QByteArray&, void* msg, long* result, const QRect& wndRect);static bool sorptionEvent(const QByteArray&, void* msg, long*, int shadowWidth=0);explicit TcStyleToolDialog(QWidget* parent=0);~TcStyleToolDialog();protected:Ui::TcStyleToolDialog* ui;inline void setDialogResize(bool value) { m_dialogResize = value; }void setShadowWidth(int shadowWidth);QLayout* clientLayout();void initClient(QWidget* widget);virtual bool isMoveBar(QWidget* moveBar) const { Q_UNUSED(moveBar); return false; }virtual void paintEvent(QPaintEvent*) override;virtual bool nativeEvent(const QByteArray& eventType, void* msg, long* result) override;private:bool m_dialogResize;int m_shadowWidth;};#define TC_PAINTSHADOW(w) \virtual void paintEvent(QPaintEvent*) override \{ TcStyleToolDialog::paintShadow(this, w); }#define TC_WINDOWRESIZE(widget) \virtual bool nativeEvent(const QByteArray& eventType, void* msg, long* result) override \{ return TcStyleToolDialog::resizeEvent(eventType, msg, result, widget->geometry()); }#endif // TIANCHI_TCSTYLETOOLDIALOG_H