├── .gitattributes ├── DrawBorderPixmapWidget.cpp ├── DrawBorderPixmapWidget.h ├── MakePixmapWidget.cpp ├── MakePixmapWidget.h ├── NoShadowWidget.cpp ├── NoShadowWidget.h ├── README.md ├── ShadowEffectWidget.cpp ├── ShadowEffectWidget.h ├── ShadowWidget.pro ├── ShadowWidget.pro.user ├── ShadowWidget.pro.user.4.8-pre1 ├── WinAPIShadowWidget.cpp ├── WinAPIShadowWidget.h ├── WindWMAPI.cpp ├── WindWMAPI.h ├── client-shadow.png ├── img.qrc ├── main.cpp └── samples ├── sample1.png ├── sample2.png ├── sample3.png └── sample4.png /.gitattributes: -------------------------------------------------------------------------------- 1 | *.cpp linguist-language=Qt -------------------------------------------------------------------------------- /DrawBorderPixmapWidget.cpp: -------------------------------------------------------------------------------- 1 | /** 2 | * 去掉标题之后添加边框阴影 3 | * 4 | * DrawBorderPixmapWidget.cpp 5 | * 使用Qt的qDrawBorderPixmap函数来实现阴影边框的实现cpp文件。 6 | * 7 | * FlyWM_ 8 | * GitHub: https://github.com/FlyWM 9 | * CSDN: https://blog.csdn.net/a844651990 10 | * 11 | */ 12 | 13 | #include 14 | #include 15 | #include 16 | #include 17 | #include 18 | #include "DrawBorderPixmapWidget.h" 19 | 20 | DrawBorderPixmapWidget::DrawBorderPixmapWidget(QWidget *parent) 21 | : QWidget(parent) 22 | { 23 | resize(400, 300); 24 | setWindowFlags(Qt::FramelessWindowHint); 25 | setAttribute(Qt::WA_TranslucentBackground); 26 | } 27 | 28 | void DrawBorderPixmapWidget::paintEvent(QPaintEvent *e) 29 | { 30 | Q_UNUSED(e) 31 | 32 | QPainter painter(this); 33 | QPixmap pixmap(":/client-shadow.png"); 34 | qDrawBorderPixmap(&painter, this->rect(), QMargins(8, 8, 8, 8), pixmap); 35 | // 绘制中心区域的背景色(不然会是透明的) 36 | QRect rect(this->rect().x()+8, this->rect().y()+8, this->rect().width()-16, this->rect().height()-16); 37 | painter.fillRect(rect, QColor(255, 255, 255)); 38 | } 39 | 40 | -------------------------------------------------------------------------------- /DrawBorderPixmapWidget.h: -------------------------------------------------------------------------------- 1 | /** 2 | * 去掉标题之后添加边框阴影 3 | * 4 | * DrawBorderPixmapWidget.h 5 | * 使用Qt的qDrawBorderPixmap函数来实现阴影边框的头文件。 6 | * 7 | * FlyWM_ 8 | * GitHub: https://github.com/FlyWM 9 | * CSDN: https://blog.csdn.net/a844651990 10 | * 11 | */ 12 | 13 | #ifndef DRAWBORDERPIXMAPWIDGET_H 14 | #define DRAWBORDERPIXMAPWIDGET_H 15 | 16 | #include 17 | 18 | class DrawBorderPixmapWidget : public QWidget 19 | { 20 | Q_OBJECT 21 | public: 22 | explicit DrawBorderPixmapWidget(QWidget *parent = nullptr); 23 | 24 | virtual void paintEvent(QPaintEvent *e); 25 | 26 | signals: 27 | 28 | public slots: 29 | }; 30 | 31 | #endif // DRAWBORDERPIXMAPWIDGET_H 32 | -------------------------------------------------------------------------------- /MakePixmapWidget.cpp: -------------------------------------------------------------------------------- 1 | /** 2 | * 去掉标题之后添加边框阴影 3 | * 4 | * MakePixmapWidget.cpp 5 | * 构造出边框阴影QImage方法的cpp文件。 6 | * 7 | * FlyWM_ 8 | * GitHub: https://github.com/FlyWM 9 | * CSDN: https://blog.csdn.net/a844651990 10 | * 11 | */ 12 | 13 | #include 14 | #include 15 | #include "MakePixmapWidget.h" 16 | 17 | inline unsigned char MakeAlpha(int i, double f, int nSize) 18 | { 19 | if (i == nSize) 20 | f *= 1.2; 21 | // 22 | 23 | double f2 = 1 - cos((double)i / nSize * 3.14 / 2); 24 | // 25 | return int(fabs((i * f) * f2)); 26 | } 27 | QImage MakeShadowImage(int shadowSize, bool activated) 28 | { 29 | int size = shadowSize * 2 + 10; 30 | QImage image(size, size, QImage::Format_ARGB32); 31 | image.fill(QColor(Qt::black)); 32 | // 33 | double f = activated ? 4.0 : 1.0; 34 | // 35 | QSize szImage = image.size(); 36 | // 37 | //left 38 | for (int y = shadowSize; y < szImage.height() - shadowSize; y++) { 39 | for (int x = 0; x < shadowSize; x++) { 40 | int i = x + 1; 41 | int alpha = MakeAlpha(i, f, shadowSize); 42 | image.setPixelColor(x, y, QColor(0, 0, 0, alpha)); 43 | } 44 | } 45 | //right 46 | for (int y = shadowSize; y < szImage.height() - shadowSize; y++) { 47 | for (int x = szImage.width() - shadowSize - 1; x < szImage.width(); x++) { 48 | int i = szImage.width() - x; 49 | int alpha = MakeAlpha(i, f, shadowSize); 50 | image.setPixelColor(x, y, QColor(0, 0, 0, alpha)); 51 | } 52 | } 53 | //top 54 | for (int y = 0; y < shadowSize; y++) { 55 | int i = y + 1; 56 | for (int x = shadowSize; x < szImage.width() - shadowSize; x++) { 57 | int alpha = MakeAlpha(i, f, shadowSize); 58 | image.setPixelColor(x, y, QColor(0, 0, 0, alpha)); 59 | } 60 | // 61 | } 62 | //bottom 63 | for (int y = szImage.height() - shadowSize - 1; y < szImage.height(); y++) { 64 | int i = szImage.height() - y; 65 | for (int x = shadowSize; x < szImage.width() - shadowSize; x++) { 66 | int alpha = MakeAlpha(i, f, shadowSize); 67 | image.setPixelColor(x, y, QColor(0, 0, 0, alpha)); 68 | } 69 | } 70 | // 71 | int parentRoundSize = 3; 72 | // 73 | for (int x = 0; x < shadowSize + parentRoundSize; x++) { 74 | for (int y = 0; y < shadowSize + parentRoundSize; y++) { 75 | int xx = (shadowSize + parentRoundSize) - x; 76 | int yy = (shadowSize + parentRoundSize) - y; 77 | int i = int(sqrt(double(xx * xx + yy * yy))); 78 | i = std::min(shadowSize + parentRoundSize, i); 79 | i -= parentRoundSize; 80 | i = shadowSize - i; 81 | // 82 | int alpha = MakeAlpha(i, f, shadowSize); 83 | image.setPixelColor(x, y, QColor(0, 0, 0, alpha)); 84 | } 85 | } 86 | // 87 | for (int x = szImage.width() - shadowSize - parentRoundSize; x < szImage.width(); x++) { 88 | for (int y = 0; y < shadowSize + parentRoundSize; y++) { 89 | int xx = (shadowSize + parentRoundSize) - (szImage.width() - x); 90 | int yy = (shadowSize + parentRoundSize) - y; 91 | int i = int(sqrt(double(xx * xx + yy * yy))); 92 | i = std::min(shadowSize + parentRoundSize, i); 93 | i -= parentRoundSize; 94 | i = shadowSize - i; 95 | // 96 | int alpha = MakeAlpha(i, f, shadowSize); 97 | image.setPixelColor(x, y, QColor(0, 0, 0, alpha)); 98 | } 99 | } 100 | // 101 | for (int x = 0; x < shadowSize + parentRoundSize; x++) { 102 | for (int y = szImage.height() - shadowSize - parentRoundSize; y < szImage.height(); y++) { 103 | int xx = (shadowSize + parentRoundSize) - x; 104 | int yy = (shadowSize + parentRoundSize) - (szImage.height() - y); 105 | int i = int(sqrt(double(xx * xx + yy * yy))); 106 | i = std::min(shadowSize + parentRoundSize, i); 107 | i -= parentRoundSize; 108 | i = shadowSize - i; 109 | // 110 | int alpha = MakeAlpha(i, f, shadowSize); 111 | image.setPixelColor(x, y, QColor(0, 0, 0, alpha)); 112 | } 113 | } 114 | // 115 | for (int x = szImage.width() - shadowSize - parentRoundSize; x < szImage.width(); x++) { 116 | for (int y = szImage.height() - shadowSize - parentRoundSize; y < szImage.height(); y++) { 117 | int xx = (shadowSize + parentRoundSize) - (szImage.width() - x); 118 | int yy = (shadowSize + parentRoundSize) - (szImage.height() - y); 119 | int i = int(sqrt(double(xx * xx + yy * yy))); 120 | i = std::min(shadowSize + parentRoundSize, i); 121 | i -= parentRoundSize; 122 | i = shadowSize - i; 123 | // 124 | int alpha = MakeAlpha(i, f, shadowSize); 125 | image.setPixelColor(x, y, QColor(0, 0, 0, alpha)); 126 | } 127 | } 128 | // 129 | int borderR = 165; 130 | int borderG = 165; 131 | int borderB = 165; 132 | // 133 | if (activated) { 134 | borderR = 68; 135 | borderG = 138; 136 | borderB = 255; 137 | // borderR = 0; 138 | // borderG = 0; 139 | // borderB = 0; 140 | } 141 | // 142 | int borderSize = 1; 143 | //left 144 | for (int i = 0; i < borderSize; i++) { 145 | for (int y = shadowSize - 1; y < szImage.height() - shadowSize + 1; y++) { 146 | int x = shadowSize - i - 1; 147 | image.setPixelColor(x, y, QColor(borderR, borderG, borderB, 255)); 148 | } 149 | } 150 | //right 151 | for (int i = 0; i < borderSize; i++) { 152 | for (int y = shadowSize - 1; y < szImage.height() - shadowSize + 1; y++) { 153 | int x = szImage.width() - shadowSize - 1 + i + 1; 154 | image.setPixelColor(x, y, QColor(borderR, borderG, borderB, 255)); 155 | } 156 | } 157 | //top 158 | for (int i = 0; i < borderSize; i++) { 159 | for (int x = shadowSize; x < szImage.width() - shadowSize; x++) { 160 | int y = shadowSize - i - 1; 161 | image.setPixelColor(x, y, QColor(borderR, borderG, borderB, 255)); 162 | } 163 | } 164 | //bottom 165 | for (int i = 0; i < borderSize; i++) { 166 | for (int x = shadowSize; x < szImage.width() - shadowSize; x++) { 167 | int y = szImage.height() - shadowSize - 1 + i + 1; 168 | image.setPixelColor(x, y, QColor(borderR, borderG, borderB, 255)); 169 | } 170 | } 171 | // 172 | return image; 173 | } 174 | 175 | bool Skin9GridImage::clear() 176 | { 177 | if (!m_img.isNull()) { 178 | m_img = QImage(); 179 | } 180 | return true; 181 | } 182 | 183 | bool Skin9GridImage::splitRect(const QRect &rcSrc, QPoint ptTopLeft, QRect *parrayRect, int nArrayCount) 184 | { 185 | Q_ASSERT(nArrayCount == 9); 186 | // 187 | QRect* arrayRect = parrayRect; 188 | // 189 | int nWidth = rcSrc.width(); 190 | int nHeight = rcSrc.height(); 191 | // 192 | if (ptTopLeft.x() <= 0) 193 | return false; 194 | if (ptTopLeft.y() <= 0) 195 | return false; 196 | if (ptTopLeft.x() >= nWidth / 2) 197 | return false; 198 | if (ptTopLeft.y() >= nHeight / 2) 199 | return false; 200 | // 201 | int x1 = rcSrc.left() + 0; 202 | int x2 = rcSrc.left() + ptTopLeft.x(); 203 | int x3 = rcSrc.left() + nWidth - ptTopLeft.x(); 204 | int x4 = rcSrc.left() + nWidth; 205 | // 206 | int y1 = rcSrc.top() + 0; 207 | int y2 = rcSrc.top() + ptTopLeft.y(); 208 | int y3 = rcSrc.top() + nHeight - ptTopLeft.y(); 209 | int y4 = rcSrc.top() + nHeight; 210 | // 211 | arrayRect[0] = QRect(QPoint(x1, y1), QPoint(x2, y2)); 212 | arrayRect[1] = QRect(QPoint(x2 + 1, y1), QPoint(x3, y2)); 213 | arrayRect[2] = QRect(QPoint(x3 + 1, y1), QPoint(x4, y2)); 214 | 215 | arrayRect[3] = QRect(QPoint(x1, y2 + 1), QPoint(x2, y3)); 216 | arrayRect[4] = QRect(QPoint(x2 + 1, y2 + 1), QPoint(x3, y3)); 217 | arrayRect[5] = QRect(QPoint(x3 + 1, y2 + 1), QPoint(x4, y3)); 218 | 219 | arrayRect[6] = QRect(QPoint(x1, y3 + 1), QPoint(x2, y4)); 220 | arrayRect[7] = QRect(QPoint(x2 + 1, y3 + 1), QPoint(x3, y4)); 221 | arrayRect[8] = QRect(QPoint(x3 + 1, y3 + 1), QPoint(x4, y4)); 222 | // 223 | return true; 224 | } 225 | 226 | bool Skin9GridImage::setImage(const QImage &image, QPoint ptTopLeft) 227 | { 228 | clear(); 229 | // 230 | m_img = image; 231 | // 232 | int nImageWidth = m_img.width(); 233 | int nImageHeight = m_img.height(); 234 | // 235 | return splitRect(QRect(0, 0, nImageWidth, nImageHeight), ptTopLeft, m_arrayImageGrid, 9); 236 | } 237 | 238 | void Skin9GridImage::drawBorder(QPainter *p, QRect rc) const 239 | { 240 | QRect arrayDest[9]; 241 | // 242 | splitRect(rc, m_arrayImageGrid[0].bottomRight(), arrayDest, 9); 243 | // 244 | for (int i = 0; i < 9; i++) { 245 | if (i == 4) 246 | continue; 247 | // 248 | const QRect& rcSrc = m_arrayImageGrid[i]; 249 | const QRect& rcDest = arrayDest[i]; 250 | // 251 | p->drawImage(rcDest, m_img, rcSrc); 252 | } 253 | } 254 | 255 | 256 | ShadowWidget::ShadowWidget(int shadowSize, QWidget *parent) 257 | : m_shadowSize(shadowSize) 258 | , QWidget(parent) 259 | , m_shadow(new Skin9GridImage()) 260 | { 261 | setAttribute(Qt::WA_TranslucentBackground); 262 | setWindowFlag(Qt::FramelessWindowHint); 263 | setMouseTracking(true); 264 | // 265 | QImage image = MakeShadowImage(shadowSize, true); 266 | m_shadow->setImage(image, QPoint(shadowSize + 1, shadowSize + 1)); 267 | } 268 | 269 | void ShadowWidget::paintEvent(QPaintEvent *e) 270 | { 271 | Q_UNUSED(e) 272 | QPainter painter(this); 273 | m_shadow->drawBorder(&painter, rect()); 274 | } 275 | 276 | MakePixmapWidget::MakePixmapWidget(QWidget *parent) 277 | : QWidget(parent) 278 | { 279 | resize(400, 300); 280 | setAttribute(Qt::WA_TranslucentBackground); 281 | setWindowFlags(Qt::FramelessWindowHint); 282 | setContentsMargins(0, 0, 0, 0); 283 | 284 | QVBoxLayout *pLayout = new QVBoxLayout(this); 285 | pLayout->setContentsMargins(0, 0, 0, 0); 286 | pLayout->setSpacing(0); 287 | int shadowSize = 20; 288 | ShadowWidget *pShadowWidget = new ShadowWidget(shadowSize, this); 289 | pShadowWidget->setContentsMargins(shadowSize, shadowSize, shadowSize, shadowSize); 290 | pLayout->addWidget(pShadowWidget); 291 | 292 | QLayout* rootLayout = new QBoxLayout(QBoxLayout::TopToBottom); 293 | pShadowWidget->setLayout(rootLayout); 294 | rootLayout->setContentsMargins(0, 0, 0, 0); 295 | rootLayout->setSpacing(0); 296 | 297 | QWidget* shadowClientWidget = new QWidget(pShadowWidget); 298 | rootLayout->addWidget(shadowClientWidget); 299 | // 300 | QVBoxLayout* shadowClientLayout = new QVBoxLayout(); 301 | shadowClientLayout->setContentsMargins(0, 0, 0, 0); 302 | shadowClientLayout->setSpacing(0); 303 | shadowClientWidget->setLayout(shadowClientLayout); 304 | shadowClientWidget->setAutoFillBackground(true); 305 | shadowClientWidget->setCursor(QCursor(Qt::ArrowCursor)); 306 | 307 | // 308 | QWidget *clientWidget = new QWidget(shadowClientWidget); 309 | shadowClientLayout->addWidget(clientWidget); 310 | 311 | // 312 | QVBoxLayout *clientLayout = new QVBoxLayout(); 313 | clientWidget->setLayout(clientLayout); 314 | // 315 | clientLayout->setSpacing(0); 316 | clientLayout->setContentsMargins(0, 0, 0, 0); 317 | } 318 | 319 | 320 | 321 | 322 | 323 | 324 | -------------------------------------------------------------------------------- /MakePixmapWidget.h: -------------------------------------------------------------------------------- 1 | /** 2 | * 去掉标题之后添加边框阴影 3 | * 4 | * MakePixmapWidget.h 5 | * 构造出边框阴影QImage方法的头文件。 6 | * 7 | * FlyWM_ 8 | * GitHub: https://github.com/FlyWM 9 | * CSDN: https://blog.csdn.net/a844651990 10 | * 11 | */ 12 | 13 | #ifndef MAKEPIXMAPWIDGET_H 14 | #define MAKEPIXMAPWIDGET_H 15 | 16 | #include 17 | 18 | class QPainter; 19 | class QLineEdit; 20 | class QLabel; 21 | 22 | class Skin9GridImage 23 | { 24 | protected: 25 | QImage m_img; 26 | QRect m_arrayImageGrid[9]; 27 | // 28 | bool clear(); 29 | public: 30 | static bool splitRect(const QRect& rcSrc, QPoint ptTopLeft, QRect* parrayRect, int nArrayCount); 31 | // bool setImage(const CString& strImageFileName, QPoint ptTopLeft); 32 | bool setImage(const QImage& image, QPoint ptTopLeft); 33 | // // 34 | // void draw(QPainter* p, QRect rc, int nAlpha) const; 35 | void drawBorder(QPainter* p, QRect rc) const; 36 | // bool valid() const; 37 | // // 38 | // QSize actualSize() const { return m_img.size(); } 39 | }; 40 | 41 | 42 | class ShadowWidget : public QWidget 43 | { 44 | Q_OBJECT 45 | public: 46 | explicit ShadowWidget(int shadowSize, QWidget *parent = nullptr); 47 | 48 | virtual void paintEvent(QPaintEvent *e); 49 | 50 | private: 51 | Skin9GridImage* m_shadow; 52 | int m_shadowSize; 53 | }; 54 | 55 | class MakePixmapWidget : public QWidget 56 | { 57 | Q_OBJECT 58 | public: 59 | explicit MakePixmapWidget(QWidget *parent = nullptr); 60 | 61 | signals: 62 | 63 | public slots: 64 | }; 65 | 66 | #endif // MAKEPIXMAPWIDGET_H 67 | -------------------------------------------------------------------------------- /NoShadowWidget.cpp: -------------------------------------------------------------------------------- 1 | /** 2 | * 去掉标题之后添加边框阴影 3 | * 4 | * NoShadowWidget.cpp 5 | * 去掉标题栏之后无边框阴影的cpp文件。 6 | * 7 | * FlyWM_ 8 | * GitHub: https://github.com/FlyWM 9 | * CSDN: https://blog.csdn.net/a844651990 10 | * 11 | */ 12 | #include "NoShadowWidget.h" 13 | 14 | NoShadowWidget::NoShadowWidget(QWidget *parent) 15 | : QWidget(parent) 16 | { 17 | setWindowFlags(Qt::FramelessWindowHint); 18 | } 19 | -------------------------------------------------------------------------------- /NoShadowWidget.h: -------------------------------------------------------------------------------- 1 | /** 2 | * 去掉标题之后添加边框阴影 3 | * 4 | * NoShadowWidget.h 5 | * 去掉标题栏之后无边框阴影的头文件。 6 | * 7 | * FlyWM_ 8 | * GitHub: https://github.com/FlyWM 9 | * CSDN: https://blog.csdn.net/a844651990 10 | * 11 | */ 12 | 13 | #ifndef NOSHADOWWIDGET_H 14 | #define NOSHADOWWIDGET_H 15 | 16 | #include 17 | 18 | class NoShadowWidget : public QWidget 19 | { 20 | Q_OBJECT 21 | public: 22 | explicit NoShadowWidget(QWidget *parent = nullptr); 23 | 24 | signals: 25 | 26 | public slots: 27 | }; 28 | 29 | #endif // NOSHADOWWIDGET_H 30 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # ShadowWidget 2 | 基于Qt5的去掉标题栏之后添加边框阴影的解决方案 3 | ### 调用Windows相关API 4 | ![image](https://github.com/FlyWM/ShadowWidget/blob/master/samples/sample1.png) 5 | ### 使用Qt的QGraphicsDropShadowEffect类来实现 6 | ![image](https://github.com/FlyWM/ShadowWidget/blob/master/samples/sample2.png) 7 | ### 使用Qt的qDrawBorderPixmap函数来实现 8 | ![image](https://github.com/FlyWM/ShadowWidget/blob/master/samples/sample3.png) 9 | ### 构造出边框阴影QImage并绘制 10 | ![image](https://github.com/FlyWM/ShadowWidget/blob/master/samples/sample4.png) 11 | -------------------------------------------------------------------------------- /ShadowEffectWidget.cpp: -------------------------------------------------------------------------------- 1 | /** 2 | * 去掉标题之后添加边框阴影 3 | * 4 | * ShadowEffectWidget.cpp 5 | * 使用Qt的QGraphicsDropShadowEffect类来实现边框阴影cpp文件。 6 | * 7 | * FlyWM_ 8 | * GitHub: https://github.com/FlyWM 9 | * CSDN: https://blog.csdn.net/a844651990 10 | * 11 | */ 12 | 13 | #include 14 | #include 15 | #include "ShadowEffectWidget.h" 16 | 17 | ShadowEffectWidget::ShadowEffectWidget(QWidget *parent) 18 | : QWidget(parent) 19 | { 20 | resize(400, 300); 21 | setWindowFlags(windowFlags() | Qt::FramelessWindowHint); 22 | setAttribute(Qt::WA_TranslucentBackground); 23 | QWidget *pCentralWidget = new QWidget(this); 24 | pCentralWidget->setStyleSheet("background-color: white"); 25 | QHBoxLayout *pLayout = new QHBoxLayout(this); 26 | pLayout->addWidget(pCentralWidget); 27 | pLayout->setContentsMargins(20, 20, 20, 20); 28 | 29 | QGraphicsDropShadowEffect *pEffect = new QGraphicsDropShadowEffect(pCentralWidget); 30 | pEffect->setOffset(0, 0); 31 | pEffect->setColor(QColor(QStringLiteral("black"))); 32 | pEffect->setBlurRadius(30); 33 | pCentralWidget->setGraphicsEffect(pEffect); 34 | } 35 | -------------------------------------------------------------------------------- /ShadowEffectWidget.h: -------------------------------------------------------------------------------- 1 | /** 2 | * 去掉标题之后添加边框阴影 3 | * 4 | * ShadowEffectWidget.h 5 | * 使用Qt的QGraphicsDropShadowEffect类来实现边框阴影的头文件。 6 | * 7 | * FlyWM_ 8 | * GitHub: https://github.com/FlyWM 9 | * CSDN: https://blog.csdn.net/a844651990 10 | * 11 | */ 12 | 13 | #ifndef SHADOWEFFECTWIDGET_H 14 | #define SHADOWEFFECTWIDGET_H 15 | 16 | #include 17 | 18 | class ShadowEffectWidget : public QWidget 19 | { 20 | Q_OBJECT 21 | public: 22 | explicit ShadowEffectWidget(QWidget *parent = nullptr); 23 | 24 | signals: 25 | 26 | public slots: 27 | }; 28 | 29 | #endif // SHADOWEFFECTWIDGET_H 30 | -------------------------------------------------------------------------------- /ShadowWidget.pro: -------------------------------------------------------------------------------- 1 | #------------------------------------------------- 2 | # 3 | # Project created by QtCreator 2018-12-09T09:35:40 4 | # 5 | #------------------------------------------------- 6 | 7 | QT += core gui 8 | 9 | greaterThan(QT_MAJOR_VERSION, 4): QT += widgets 10 | 11 | TARGET = ShadowWidget 12 | TEMPLATE = app 13 | 14 | # The following define makes your compiler emit warnings if you use 15 | # any feature of Qt which has been marked as deprecated (the exact warnings 16 | # depend on your compiler). Please consult the documentation of the 17 | # deprecated API in order to know how to port your code away from it. 18 | DEFINES += QT_DEPRECATED_WARNINGS 19 | 20 | # You can also make your code fail to compile if you use deprecated APIs. 21 | # In order to do so, uncomment the following line. 22 | # You can also select to disable deprecated APIs only up to a certain version of Qt. 23 | #DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000 # disables all the APIs deprecated before Qt 6.0.0 24 | 25 | 26 | SOURCES += \ 27 | main.cpp \ 28 | ShadowEffectWidget.cpp \ 29 | WinAPIShadowWidget.cpp \ 30 | WindWMAPI.cpp \ 31 | DrawBorderPixmapWidget.cpp \ 32 | MakePixmapWidget.cpp \ 33 | NoShadowWidget.cpp 34 | 35 | HEADERS += \ 36 | ShadowEffectWidget.h \ 37 | WinAPIShadowWidget.h \ 38 | WindWMAPI.h \ 39 | DrawBorderPixmapWidget.h \ 40 | MakePixmapWidget.h \ 41 | NoShadowWidget.h 42 | 43 | FORMS += 44 | 45 | RESOURCES += \ 46 | img.qrc 47 | -------------------------------------------------------------------------------- /ShadowWidget.pro.user: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | EnvironmentId 7 | {b421c875-f58e-47cc-b9c9-699e8c2f5a5d} 8 | 9 | 10 | ProjectExplorer.Project.ActiveTarget 11 | 0 12 | 13 | 14 | ProjectExplorer.Project.EditorSettings 15 | 16 | true 17 | false 18 | true 19 | 20 | Cpp 21 | 22 | CppGlobal 23 | 24 | 25 | 26 | QmlJS 27 | 28 | QmlJSGlobal 29 | 30 | 31 | 2 32 | UTF-8 33 | false 34 | 4 35 | false 36 | 80 37 | true 38 | true 39 | 1 40 | true 41 | false 42 | 0 43 | true 44 | true 45 | 0 46 | 8 47 | true 48 | 0 49 | true 50 | true 51 | true 52 | false 53 | 54 | 55 | 56 | ProjectExplorer.Project.PluginSettings 57 | 58 | 59 | -fno-delayed-template-parsing 60 | 61 | true 62 | 63 | 64 | 65 | ProjectExplorer.Project.Target.0 66 | 67 | Desktop Qt 5.12.0 MSVC2015 64bit 68 | Desktop Qt 5.12.0 MSVC2015 64bit 69 | qt.qt5.5120.win64_msvc2015_64_kit 70 | 0 71 | 0 72 | 0 73 | 74 | E:/myOpenSource/github/build-ShadowWidget-Desktop_Qt_5_12_0_MSVC2015_64bit-Debug 75 | 76 | 77 | true 78 | qmake 79 | 80 | QtProjectManager.QMakeBuildStep 81 | true 82 | 83 | false 84 | false 85 | false 86 | 87 | 88 | true 89 | Make 90 | 91 | Qt4ProjectManager.MakeStep 92 | 93 | false 94 | 95 | 96 | false 97 | 98 | 2 99 | Build 100 | 101 | ProjectExplorer.BuildSteps.Build 102 | 103 | 104 | 105 | true 106 | Make 107 | 108 | Qt4ProjectManager.MakeStep 109 | 110 | true 111 | clean 112 | 113 | false 114 | 115 | 1 116 | Clean 117 | 118 | ProjectExplorer.BuildSteps.Clean 119 | 120 | 2 121 | false 122 | 123 | Debug 124 | Debug 125 | Qt4ProjectManager.Qt4BuildConfiguration 126 | 2 127 | true 128 | 129 | 130 | E:/myOpenSource/github/build-ShadowWidget-Desktop_Qt_5_12_0_MSVC2015_64bit-Release 131 | 132 | 133 | true 134 | qmake 135 | 136 | QtProjectManager.QMakeBuildStep 137 | false 138 | 139 | false 140 | false 141 | true 142 | 143 | 144 | true 145 | Make 146 | 147 | Qt4ProjectManager.MakeStep 148 | 149 | false 150 | 151 | 152 | false 153 | 154 | 2 155 | Build 156 | 157 | ProjectExplorer.BuildSteps.Build 158 | 159 | 160 | 161 | true 162 | Make 163 | 164 | Qt4ProjectManager.MakeStep 165 | 166 | true 167 | clean 168 | 169 | false 170 | 171 | 1 172 | Clean 173 | 174 | ProjectExplorer.BuildSteps.Clean 175 | 176 | 2 177 | false 178 | 179 | Release 180 | Release 181 | Qt4ProjectManager.Qt4BuildConfiguration 182 | 0 183 | true 184 | 185 | 186 | E:/myOpenSource/github/build-ShadowWidget-Desktop_Qt_5_12_0_MSVC2015_64bit-Profile 187 | 188 | 189 | true 190 | qmake 191 | 192 | QtProjectManager.QMakeBuildStep 193 | true 194 | 195 | false 196 | true 197 | true 198 | 199 | 200 | true 201 | Make 202 | 203 | Qt4ProjectManager.MakeStep 204 | 205 | false 206 | 207 | 208 | false 209 | 210 | 2 211 | Build 212 | 213 | ProjectExplorer.BuildSteps.Build 214 | 215 | 216 | 217 | true 218 | Make 219 | 220 | Qt4ProjectManager.MakeStep 221 | 222 | true 223 | clean 224 | 225 | false 226 | 227 | 1 228 | Clean 229 | 230 | ProjectExplorer.BuildSteps.Clean 231 | 232 | 2 233 | false 234 | 235 | Profile 236 | Profile 237 | Qt4ProjectManager.Qt4BuildConfiguration 238 | 0 239 | true 240 | 241 | 3 242 | 243 | 244 | 0 245 | 部署 246 | 247 | ProjectExplorer.BuildSteps.Deploy 248 | 249 | 1 250 | Deploy Configuration 251 | 252 | ProjectExplorer.DefaultDeployConfiguration 253 | 254 | 1 255 | 256 | 257 | false 258 | false 259 | 1000 260 | 261 | true 262 | 263 | false 264 | false 265 | false 266 | false 267 | true 268 | 0.01 269 | 10 270 | true 271 | 1 272 | 25 273 | 274 | 1 275 | true 276 | false 277 | true 278 | valgrind 279 | 280 | 0 281 | 1 282 | 2 283 | 3 284 | 4 285 | 5 286 | 6 287 | 7 288 | 8 289 | 9 290 | 10 291 | 11 292 | 12 293 | 13 294 | 14 295 | 296 | 2 297 | 298 | ShadowWidget 299 | 300 | Qt4ProjectManager.Qt4RunConfiguration:E:/myOpenSource/github/ShadowWidget/ShadowWidget.pro 301 | ShadowWidget.pro 302 | 303 | 3768 304 | false 305 | true 306 | true 307 | false 308 | false 309 | true 310 | 311 | E:/myOpenSource/github/build-ShadowWidget-Desktop_Qt_5_12_0_MSVC2015_64bit-Debug 312 | 313 | 1 314 | 315 | 316 | 317 | ProjectExplorer.Project.Target.1 318 | 319 | Desktop Qt 5.12.0 MinGW 64-bit 320 | Desktop Qt 5.12.0 MinGW 64-bit 321 | qt.qt5.5120.win64_mingw73_kit 322 | 0 323 | 0 324 | 0 325 | 326 | E:/myOpenSource/github/build-ShadowWidget-Desktop_Qt_5_12_0_MinGW_64_bit-Debug 327 | 328 | 329 | true 330 | qmake 331 | 332 | QtProjectManager.QMakeBuildStep 333 | true 334 | 335 | false 336 | false 337 | false 338 | 339 | 340 | true 341 | Make 342 | 343 | Qt4ProjectManager.MakeStep 344 | 345 | false 346 | 347 | 348 | false 349 | 350 | 2 351 | Build 352 | 353 | ProjectExplorer.BuildSteps.Build 354 | 355 | 356 | 357 | true 358 | Make 359 | 360 | Qt4ProjectManager.MakeStep 361 | 362 | true 363 | clean 364 | 365 | false 366 | 367 | 1 368 | Clean 369 | 370 | ProjectExplorer.BuildSteps.Clean 371 | 372 | 2 373 | false 374 | 375 | Debug 376 | Debug 377 | Qt4ProjectManager.Qt4BuildConfiguration 378 | 2 379 | true 380 | 381 | 382 | E:/myOpenSource/github/build-ShadowWidget-Desktop_Qt_5_12_0_MinGW_64_bit-Release 383 | 384 | 385 | true 386 | qmake 387 | 388 | QtProjectManager.QMakeBuildStep 389 | false 390 | 391 | false 392 | false 393 | true 394 | 395 | 396 | true 397 | Make 398 | 399 | Qt4ProjectManager.MakeStep 400 | 401 | false 402 | 403 | 404 | false 405 | 406 | 2 407 | Build 408 | 409 | ProjectExplorer.BuildSteps.Build 410 | 411 | 412 | 413 | true 414 | Make 415 | 416 | Qt4ProjectManager.MakeStep 417 | 418 | true 419 | clean 420 | 421 | false 422 | 423 | 1 424 | Clean 425 | 426 | ProjectExplorer.BuildSteps.Clean 427 | 428 | 2 429 | false 430 | 431 | Release 432 | Release 433 | Qt4ProjectManager.Qt4BuildConfiguration 434 | 0 435 | true 436 | 437 | 438 | E:/myOpenSource/github/build-ShadowWidget-Desktop_Qt_5_12_0_MinGW_64_bit-Profile 439 | 440 | 441 | true 442 | qmake 443 | 444 | QtProjectManager.QMakeBuildStep 445 | true 446 | 447 | false 448 | true 449 | true 450 | 451 | 452 | true 453 | Make 454 | 455 | Qt4ProjectManager.MakeStep 456 | 457 | false 458 | 459 | 460 | false 461 | 462 | 2 463 | Build 464 | 465 | ProjectExplorer.BuildSteps.Build 466 | 467 | 468 | 469 | true 470 | Make 471 | 472 | Qt4ProjectManager.MakeStep 473 | 474 | true 475 | clean 476 | 477 | false 478 | 479 | 1 480 | Clean 481 | 482 | ProjectExplorer.BuildSteps.Clean 483 | 484 | 2 485 | false 486 | 487 | Profile 488 | Profile 489 | Qt4ProjectManager.Qt4BuildConfiguration 490 | 0 491 | true 492 | 493 | 3 494 | 495 | 496 | 0 497 | 部署 498 | 499 | ProjectExplorer.BuildSteps.Deploy 500 | 501 | 1 502 | Deploy Configuration 503 | 504 | ProjectExplorer.DefaultDeployConfiguration 505 | 506 | 1 507 | 508 | 509 | false 510 | false 511 | 1000 512 | 513 | true 514 | 515 | false 516 | false 517 | false 518 | false 519 | true 520 | 0.01 521 | 10 522 | true 523 | 1 524 | 25 525 | 526 | 1 527 | true 528 | false 529 | true 530 | valgrind 531 | 532 | 0 533 | 1 534 | 2 535 | 3 536 | 4 537 | 5 538 | 6 539 | 7 540 | 8 541 | 9 542 | 10 543 | 11 544 | 12 545 | 13 546 | 14 547 | 548 | 2 549 | 550 | ShadowWidget 551 | 552 | Qt4ProjectManager.Qt4RunConfiguration:E:/myOpenSource/github/ShadowWidget/ShadowWidget.pro 553 | ShadowWidget.pro 554 | 555 | 3768 556 | false 557 | true 558 | true 559 | false 560 | false 561 | true 562 | 563 | E:/myOpenSource/github/build-ShadowWidget-Desktop_Qt_5_12_0_MinGW_64_bit-Debug 564 | 565 | 1 566 | 567 | 568 | 569 | ProjectExplorer.Project.TargetCount 570 | 2 571 | 572 | 573 | ProjectExplorer.Project.Updater.FileVersion 574 | 20 575 | 576 | 577 | Version 578 | 20 579 | 580 | 581 | -------------------------------------------------------------------------------- /ShadowWidget.pro.user.4.8-pre1: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | EnvironmentId 7 | {b421c875-f58e-47cc-b9c9-699e8c2f5a5d} 8 | 9 | 10 | ProjectExplorer.Project.ActiveTarget 11 | 0 12 | 13 | 14 | ProjectExplorer.Project.EditorSettings 15 | 16 | true 17 | false 18 | true 19 | 20 | Cpp 21 | 22 | CppGlobal 23 | 24 | 25 | 26 | QmlJS 27 | 28 | QmlJSGlobal 29 | 30 | 31 | 2 32 | UTF-8 33 | false 34 | 4 35 | false 36 | 80 37 | true 38 | true 39 | 1 40 | true 41 | false 42 | 0 43 | true 44 | true 45 | 0 46 | 8 47 | true 48 | 0 49 | true 50 | true 51 | true 52 | false 53 | 54 | 55 | 56 | ProjectExplorer.Project.PluginSettings 57 | 58 | 59 | 60 | ProjectExplorer.Project.Target.0 61 | 62 | Desktop Qt 5.9.6 MinGW 32bit 63 | Desktop Qt 5.9.6 MinGW 32bit 64 | qt.596.win32_mingw53_kit 65 | 0 66 | 0 67 | 0 68 | 69 | E:/projects/test/build-ShadowWidget-Desktop_Qt_5_9_6_MinGW_32bit-Debug 70 | 71 | 72 | true 73 | qmake 74 | 75 | QtProjectManager.QMakeBuildStep 76 | true 77 | 78 | false 79 | false 80 | false 81 | 82 | 83 | true 84 | Make 85 | 86 | Qt4ProjectManager.MakeStep 87 | 88 | false 89 | 90 | 91 | 92 | 2 93 | Build 94 | 95 | ProjectExplorer.BuildSteps.Build 96 | 97 | 98 | 99 | true 100 | Make 101 | 102 | Qt4ProjectManager.MakeStep 103 | 104 | true 105 | clean 106 | 107 | 108 | 1 109 | Clean 110 | 111 | ProjectExplorer.BuildSteps.Clean 112 | 113 | 2 114 | false 115 | 116 | Debug 117 | Debug 118 | Qt4ProjectManager.Qt4BuildConfiguration 119 | 2 120 | true 121 | 122 | 123 | E:/projects/test/build-ShadowWidget-Desktop_Qt_5_9_6_MinGW_32bit-Release 124 | 125 | 126 | true 127 | qmake 128 | 129 | QtProjectManager.QMakeBuildStep 130 | false 131 | 132 | false 133 | false 134 | false 135 | 136 | 137 | true 138 | Make 139 | 140 | Qt4ProjectManager.MakeStep 141 | 142 | false 143 | 144 | 145 | 146 | 2 147 | Build 148 | 149 | ProjectExplorer.BuildSteps.Build 150 | 151 | 152 | 153 | true 154 | Make 155 | 156 | Qt4ProjectManager.MakeStep 157 | 158 | true 159 | clean 160 | 161 | 162 | 1 163 | Clean 164 | 165 | ProjectExplorer.BuildSteps.Clean 166 | 167 | 2 168 | false 169 | 170 | Release 171 | Release 172 | Qt4ProjectManager.Qt4BuildConfiguration 173 | 0 174 | true 175 | 176 | 177 | E:/projects/test/build-ShadowWidget-Desktop_Qt_5_9_6_MinGW_32bit-Profile 178 | 179 | 180 | true 181 | qmake 182 | 183 | QtProjectManager.QMakeBuildStep 184 | true 185 | 186 | false 187 | true 188 | false 189 | 190 | 191 | true 192 | Make 193 | 194 | Qt4ProjectManager.MakeStep 195 | 196 | false 197 | 198 | 199 | 200 | 2 201 | Build 202 | 203 | ProjectExplorer.BuildSteps.Build 204 | 205 | 206 | 207 | true 208 | Make 209 | 210 | Qt4ProjectManager.MakeStep 211 | 212 | true 213 | clean 214 | 215 | 216 | 1 217 | Clean 218 | 219 | ProjectExplorer.BuildSteps.Clean 220 | 221 | 2 222 | false 223 | 224 | Profile 225 | Profile 226 | Qt4ProjectManager.Qt4BuildConfiguration 227 | 0 228 | true 229 | 230 | 3 231 | 232 | 233 | 0 234 | 部署 235 | 236 | ProjectExplorer.BuildSteps.Deploy 237 | 238 | 1 239 | 部署设置 240 | 241 | ProjectExplorer.DefaultDeployConfiguration 242 | 243 | 1 244 | 245 | 246 | false 247 | false 248 | 1000 249 | 250 | true 251 | 252 | false 253 | false 254 | false 255 | false 256 | true 257 | 0.01 258 | 10 259 | true 260 | 1 261 | 25 262 | 263 | 1 264 | true 265 | false 266 | true 267 | valgrind 268 | 269 | 0 270 | 1 271 | 2 272 | 3 273 | 4 274 | 5 275 | 6 276 | 7 277 | 8 278 | 9 279 | 10 280 | 11 281 | 12 282 | 13 283 | 14 284 | 285 | 2 286 | 287 | ShadowWidget 288 | 289 | Qt4ProjectManager.Qt4RunConfiguration:E:/projects/test/ShadowWidget/ShadowWidget.pro 290 | true 291 | 292 | ShadowWidget.pro 293 | false 294 | 295 | 296 | 3768 297 | false 298 | true 299 | false 300 | false 301 | true 302 | 303 | 1 304 | 305 | 306 | 307 | ProjectExplorer.Project.TargetCount 308 | 1 309 | 310 | 311 | ProjectExplorer.Project.Updater.FileVersion 312 | 18 313 | 314 | 315 | Version 316 | 18 317 | 318 | 319 | -------------------------------------------------------------------------------- /WinAPIShadowWidget.cpp: -------------------------------------------------------------------------------- 1 | /** 2 | * 去掉标题之后添加边框阴影 3 | * 4 | * WinAPIShadowWidget.cpp 5 | * 调用Windows相关AP来实现边框阴影的cpp文件。 6 | * 7 | * FlyWM_ 8 | * GitHub: https://github.com/FlyWM 9 | * CSDN: https://blog.csdn.net/a844651990 10 | * 11 | */ 12 | 13 | #include "WinAPIShadowWidget.h" 14 | #include "windwmapi.h" 15 | #pragma comment(lib, "user32.lib") 16 | WinAPIShadowWidget::WinAPIShadowWidget(QWidget *parent) 17 | : QWidget(parent) 18 | { 19 | resize(400, 300); 20 | setWindowFlags(windowFlags() | Qt::FramelessWindowHint); 21 | HWND hwnd = (HWND)this->winId(); 22 | DWORD style = ::GetWindowLong(hwnd, GWL_STYLE); 23 | 24 | // 此行代码可以带回Aero效果,同时也带回了标题栏和边框,在nativeEvent()会再次去掉标题栏 25 | ::SetWindowLong(hwnd, GWL_STYLE, style | WS_MAXIMIZEBOX | WS_THICKFRAME | WS_CAPTION); 26 | //we better left 1 piexl width of border untouch, so OS can draw nice shadow around it 27 | const MARGINS shadow = { 1, 1, 1, 1 }; 28 | WinDwmapi::instance()->DwmExtendFrameIntoClientArea(HWND(winId()), &shadow); 29 | } 30 | 31 | bool WinAPIShadowWidget::nativeEvent(const QByteArray &eventType, void *message, long *result) 32 | { 33 | MSG* msg = (MSG *)message; 34 | switch (msg->message) 35 | { 36 | case WM_NCCALCSIZE: 37 | { 38 | // this kills the window frame and title bar we added with WS_THICKFRAME and WS_CAPTION 39 | *result = 0; 40 | return true; 41 | } 42 | default: 43 | return QWidget::nativeEvent(eventType, message, result); 44 | } 45 | } 46 | 47 | 48 | -------------------------------------------------------------------------------- /WinAPIShadowWidget.h: -------------------------------------------------------------------------------- 1 | /** 2 | * 去掉标题之后添加边框阴影 3 | * 4 | * WinAPIShadowWidget.h 5 | * 调用Windows相关AP来实现边框阴影的头文件。 6 | * 7 | * FlyWM_ 8 | * GitHub: https://github.com/FlyWM 9 | * CSDN: https://blog.csdn.net/a844651990 10 | * 11 | */ 12 | 13 | #ifndef WINAPISHADOWWIDGET_H 14 | #define WINAPISHADOWWIDGET_H 15 | 16 | #include 17 | 18 | class WinAPIShadowWidget : public QWidget 19 | { 20 | Q_OBJECT 21 | public: 22 | explicit WinAPIShadowWidget(QWidget *parent = nullptr); 23 | 24 | bool nativeEvent(const QByteArray &eventType, void *message, long *result); 25 | 26 | public slots: 27 | }; 28 | 29 | #endif // WINAPISHADOWWIDGET_H 30 | -------------------------------------------------------------------------------- /WindWMAPI.cpp: -------------------------------------------------------------------------------- 1 | /** 2 | * 去掉标题之后添加边框阴影 3 | * 4 | * windwmapi.cpp 5 | * 封装windows api的cpp文件。 6 | * 7 | * FlyWM_ 8 | * GitHub: https://github.com/FlyWM 9 | * CSDN: https://blog.csdn.net/a844651990 10 | * 11 | */ 12 | 13 | #include "windwmapi.h" 14 | 15 | WinDwmapi::WinDwmapi() 16 | : dwmapi_dll_(LoadLibraryW(L"dwmapi.dll")) 17 | , dwm_is_composition_enabled_(NULL) 18 | { 19 | if (dwmapi_dll_) { 20 | dwm_is_composition_enabled_ = \ 21 | reinterpret_cast(GetProcAddress(dwmapi_dll_, "DwmIsCompositionEnabled")); 22 | dwm_extendframe_into_client_area_ = \ 23 | reinterpret_cast(GetProcAddress(dwmapi_dll_, "DwmExtendFrameIntoClientArea")); 24 | } 25 | } 26 | 27 | WinDwmapi::~WinDwmapi() 28 | { 29 | if (dwmapi_dll_) { 30 | FreeLibrary(dwmapi_dll_); 31 | } 32 | } 33 | 34 | HRESULT WinDwmapi::DwmIsCompositionEnabled(BOOL *pfEnabled) const 35 | { 36 | if (dwm_is_composition_enabled_) { 37 | return dwm_is_composition_enabled_(pfEnabled); 38 | } 39 | 40 | return E_NOTIMPL; 41 | } 42 | 43 | HRESULT WinDwmapi::DwmExtendFrameIntoClientArea(HWND hWnd, const MARGINS *pMarInset) const 44 | { 45 | if (dwm_extendframe_into_client_area_) { 46 | return dwm_extendframe_into_client_area_(hWnd, pMarInset); 47 | } 48 | 49 | return E_NOTIMPL; 50 | } 51 | 52 | const WinDwmapi *WinDwmapi::instance() 53 | { 54 | static const WinDwmapi s_dwmapi; 55 | return &s_dwmapi; 56 | } 57 | -------------------------------------------------------------------------------- /WindWMAPI.h: -------------------------------------------------------------------------------- 1 | /** 2 | * 去掉标题之后添加边框阴影 3 | * 4 | * windwmapi.h 5 | * 封装windows api的头文件。 6 | * 7 | * FlyWM_ 8 | * GitHub: https://github.com/FlyWM 9 | * CSDN: https://blog.csdn.net/a844651990 10 | * 11 | */ 12 | 13 | #ifndef WINDWMAPI_H 14 | #define WINDWMAPI_H 15 | 16 | #include 17 | 18 | typedef struct _MARGINS 19 | { 20 | int cxLeftWidth; // width of left border that retains its size 21 | int cxRightWidth; // width of right border that retains its size 22 | int cyTopHeight; // height of top border that retains its size 23 | int cyBottomHeight; // height of bottom border that retains its size 24 | } MARGINS, *PMARGINS; 25 | 26 | class WinDwmapi 27 | { 28 | public: 29 | WinDwmapi(); 30 | ~WinDwmapi(); 31 | 32 | typedef HRESULT (WINAPI* DwmIsCompositionEnabledPtr)(BOOL* pfEnabled); 33 | typedef HRESULT (WINAPI* DwmExtendFrameIntoClientAreaPtr)(HWND hWnd, const MARGINS *pMarInset); 34 | 35 | HRESULT DwmIsCompositionEnabled(BOOL* pfEnabled) const; 36 | HRESULT DwmExtendFrameIntoClientArea(HWND hWnd, const MARGINS *pMarInset) const; 37 | 38 | static const WinDwmapi* instance(); 39 | 40 | private: 41 | DwmIsCompositionEnabledPtr dwm_is_composition_enabled_; 42 | DwmExtendFrameIntoClientAreaPtr dwm_extendframe_into_client_area_; 43 | HMODULE dwmapi_dll_; 44 | }; 45 | 46 | #endif // WINDWMAPI_H 47 | -------------------------------------------------------------------------------- /client-shadow.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/FlyWM/ShadowWidget/391e77b0df9eee82596a65df5ff5393393962195/client-shadow.png -------------------------------------------------------------------------------- /img.qrc: -------------------------------------------------------------------------------- 1 | 2 | 3 | client-shadow.png 4 | 5 | 6 | -------------------------------------------------------------------------------- /main.cpp: -------------------------------------------------------------------------------- 1 | /** 2 | * 去掉标题之后添加边框阴影 3 | * 4 | * main.cpp 5 | * 入口函数文件。 6 | * 7 | * FlyWM_ 8 | * GitHub: https://github.com/FlyWM 9 | * CSDN: https://blog.csdn.net/a844651990 10 | * 11 | */ 12 | 13 | #include 14 | #include "ShadowEffectWidget.h" 15 | #include "WinAPIShadowWidget.h" 16 | #include "DrawBorderPixmapWidget.h" 17 | #include "MakePixmapWidget.h" 18 | #include "NoShadowWidget.h" 19 | 20 | int main(int argc, char *argv[]) 21 | { 22 | QApplication a(argc, argv); 23 | 24 | WinAPIShadowWidget w; 25 | w.show(); 26 | 27 | return a.exec(); 28 | } 29 | -------------------------------------------------------------------------------- /samples/sample1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/FlyWM/ShadowWidget/391e77b0df9eee82596a65df5ff5393393962195/samples/sample1.png -------------------------------------------------------------------------------- /samples/sample2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/FlyWM/ShadowWidget/391e77b0df9eee82596a65df5ff5393393962195/samples/sample2.png -------------------------------------------------------------------------------- /samples/sample3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/FlyWM/ShadowWidget/391e77b0df9eee82596a65df5ff5393393962195/samples/sample3.png -------------------------------------------------------------------------------- /samples/sample4.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/FlyWM/ShadowWidget/391e77b0df9eee82596a65df5ff5393393962195/samples/sample4.png --------------------------------------------------------------------------------