Qt 4.8
qwizard_win.cpp
Go to the documentation of this file.
1 /****************************************************************************
2 **
3 ** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies).
4 ** Contact: http://www.qt-project.org/legal
5 **
6 ** This file is part of the QtGui module of the Qt Toolkit.
7 **
8 ** $QT_BEGIN_LICENSE:LGPL$
9 ** Commercial License Usage
10 ** Licensees holding valid commercial Qt licenses may use this file in
11 ** accordance with the commercial license agreement provided with the
12 ** Software or, alternatively, in accordance with the terms contained in
13 ** a written agreement between you and Digia. For licensing terms and
14 ** conditions see http://qt.digia.com/licensing. For further information
15 ** use the contact form at http://qt.digia.com/contact-us.
16 **
17 ** GNU Lesser General Public License Usage
18 ** Alternatively, this file may be used under the terms of the GNU Lesser
19 ** General Public License version 2.1 as published by the Free Software
20 ** Foundation and appearing in the file LICENSE.LGPL included in the
21 ** packaging of this file. Please review the following information to
22 ** ensure the GNU Lesser General Public License version 2.1 requirements
23 ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
24 **
25 ** In addition, as a special exception, Digia gives you certain additional
26 ** rights. These rights are described in the Digia Qt LGPL Exception
27 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
28 **
29 ** GNU General Public License Usage
30 ** Alternatively, this file may be used under the terms of the GNU
31 ** General Public License version 3.0 as published by the Free Software
32 ** Foundation and appearing in the file LICENSE.GPL included in the
33 ** packaging of this file. Please review the following information to
34 ** ensure the GNU General Public License version 3.0 requirements will be
35 ** met: http://www.gnu.org/copyleft/gpl.html.
36 **
37 **
38 ** $QT_END_LICENSE$
39 **
40 ****************************************************************************/
41 
42 #ifndef QT_NO_WIZARD
43 #ifndef QT_NO_STYLE_WINDOWSVISTA
44 
45 #include "qwizard_win_p.h"
46 #include <private/qsystemlibrary_p.h>
47 #include "qwizard.h"
48 #include "qpaintengine.h"
49 #include "qapplication.h"
50 #include <QtGui/QMouseEvent>
51 #include <QtGui/QDesktopWidget>
52 
53 // Note, these tests are duplicates in qwindowsxpstyle_p.h.
54 #ifdef Q_CC_GNU
55 # include <w32api.h>
56 # if (__W32API_MAJOR_VERSION >= 3 || (__W32API_MAJOR_VERSION == 2 && __W32API_MINOR_VERSION >= 5))
57 # ifdef _WIN32_WINNT
58 # undef _WIN32_WINNT
59 # endif
60 # define _WIN32_WINNT 0x0501
61 # include <commctrl.h>
62 # endif
63 #endif
64 
65 #include <uxtheme.h>
66 
68 
69 //DWM related
70 typedef struct { //MARGINS
71  int cxLeftWidth; // width of left border that retains its size
72  int cxRightWidth; // width of right border that retains its size
73  int cyTopHeight; // height of top border that retains its size
74  int cyBottomHeight; // height of bottom border that retains its size
75 } WIZ_MARGINS;
76 typedef struct { //DTTOPTS
77  DWORD dwSize;
78  DWORD dwFlags;
79  COLORREF crText;
80  COLORREF crBorder;
81  COLORREF crShadow;
87  int iStateId;
89  int iGlowSize;
90 } WIZ_DTTOPTS;
91 
92 typedef struct {
93  DWORD dwFlags;
94  DWORD dwMask;
96 
97 #define WIZ_WM_THEMECHANGED 0x031A
98 #define WIZ_WM_DWMCOMPOSITIONCHANGED 0x031E
99 
102 };
103 
104 #define WIZ_WTNCA_NODRAWCAPTION 0x00000001
105 #define WIZ_WTNCA_NODRAWICON 0x00000002
106 
107 #define WIZ_DT_CENTER 0x00000001 //DT_CENTER
108 #define WIZ_DT_VCENTER 0x00000004
109 #define WIZ_DT_SINGLELINE 0x00000020
110 #define WIZ_DT_NOPREFIX 0x00000800
111 
112 enum WIZ_NAVIGATIONPARTS { //NAVIGATIONPARTS
116 };
117 
118 enum WIZ_NAV_BACKBUTTONSTATES { //NAV_BACKBUTTONSTATES
123 };
124 
125 #define WIZ_TMT_CAPTIONFONT (801) //TMT_CAPTIONFONT
126 #define WIZ_DTT_COMPOSITED (1UL << 13) //DTT_COMPOSITED
127 #define WIZ_DTT_GLOWSIZE (1UL << 11) //DTT_GLOWSIZE
128 
129 #define WIZ_WM_NCMOUSELEAVE 674 //WM_NCMOUSELEAVE
130 
131 #define WIZ_WP_CAPTION 1 //WP_CAPTION
132 #define WIZ_CS_ACTIVE 1 //CS_ACTIVE
133 #define WIZ_TMT_FILLCOLORHINT 3821 //TMT_FILLCOLORHINT
134 #define WIZ_TMT_BORDERCOLORHINT 3822 //TMT_BORDERCOLORHINT
135 
136 typedef BOOL (WINAPI *PtrDwmDefWindowProc)(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam, LRESULT *plResult);
137 typedef HRESULT (WINAPI *PtrDwmIsCompositionEnabled)(BOOL* pfEnabled);
138 typedef HRESULT (WINAPI *PtrDwmExtendFrameIntoClientArea)(HWND hWnd, const WIZ_MARGINS* pMarInset);
139 typedef HRESULT (WINAPI *PtrSetWindowThemeAttribute)(HWND hwnd, enum WIZ_WINDOWTHEMEATTRIBUTETYPE eAttribute, PVOID pvAttribute, DWORD cbAttribute);
140 
145 
146 //Theme related
147 typedef bool (WINAPI *PtrIsAppThemed)();
148 typedef bool (WINAPI *PtrIsThemeActive)();
149 typedef HANDLE (WINAPI *PtrOpenThemeData)(HWND hwnd, LPCWSTR pszClassList);
150 typedef HRESULT (WINAPI *PtrCloseThemeData)(HANDLE hTheme);
151 typedef HRESULT (WINAPI *PtrGetThemeSysFont)(HANDLE hTheme, int iFontId, LOGFONTW *plf);
152 typedef HRESULT (WINAPI *PtrDrawThemeTextEx)(HANDLE hTheme, HDC hdc, int iPartId, int iStateId, LPCWSTR pszText, int cchText, DWORD dwTextFlags, LPRECT pRect, const WIZ_DTTOPTS *pOptions);
153 typedef HRESULT (WINAPI *PtrDrawThemeBackground)(HANDLE hTheme, HDC hdc, int iPartId, int iStateId, const RECT *pRect, OPTIONAL const RECT *pClipRect);
154 typedef HRESULT (WINAPI *PtrGetThemePartSize)(HANDLE hTheme, HDC hdc, int iPartId, int iStateId, OPTIONAL RECT *prc, enum THEMESIZE eSize, OUT SIZE *psz);
155 typedef HRESULT (WINAPI *PtrGetThemeColor)(HANDLE hTheme, int iPartId, int iStateId, int iPropId, OUT COLORREF *pColor);
156 
166 
168 bool QVistaHelper::is_vista = false;
170 
171 /******************************************************************************
172 ** QVistaBackButton
173 */
174 
176  : QAbstractButton(widget)
177 {
179 }
180 
182 {
183  ensurePolished();
184  int size = int(QStyleHelper::dpiScaled(32));
185  int width = size, height = size;
186 /*
187  HANDLE theme = pOpenThemeData(0, L"Navigation");
188  SIZE size;
189  if (pGetThemePartSize(theme, 0, WIZ_NAV_BACKBUTTON, WIZ_NAV_BB_NORMAL, 0, TS_TRUE, &size) == S_OK) {
190  width = size.cx;
191  height = size.cy;
192  }
193 */
194  return QSize(width, height);
195 }
196 
198 {
199  if (isEnabled())
200  update();
202 }
203 
205 {
206  if (isEnabled())
207  update();
209 }
210 
212 {
213  QPainter p(this);
214  QRect r = rect();
215  HANDLE theme = pOpenThemeData(0, L"Navigation");
216  //RECT rect;
217  RECT clipRect;
218  int xoffset = QWidget::mapToParent(r.topLeft()).x() - 1;
219  int yoffset = QWidget::mapToParent(r.topLeft()).y() - 1;
220 
221  clipRect.top = r.top() + yoffset;
222  clipRect.bottom = r.bottom() + yoffset;
223  clipRect.left = r.left() + xoffset;
224  clipRect.right = r.right() + xoffset;
225 
226  int state = WIZ_NAV_BB_NORMAL;
227  if (!isEnabled())
228  state = WIZ_NAV_BB_DISABLED;
229  else if (isDown())
230  state = WIZ_NAV_BB_PRESSED;
231  else if (underMouse())
232  state = WIZ_NAV_BB_HOT;
233 
237 
238  pDrawThemeBackground(theme, p.paintEngine()->getDC(), buttonType, state, &clipRect, &clipRect);
239 }
240 
241 /******************************************************************************
242 ** QVistaHelper
243 */
244 
246  : QObject(wizard)
247  , pressed(false)
248  , wizard(wizard)
249  , backButton_(0)
250 {
252  if (instanceCount++ == 0)
254  if (is_vista)
255  backButton_ = new QVistaBackButton(wizard);
256 
257  // Handle diff between Windows 7 and Vista
261 }
262 
264 {
265  --instanceCount;
266 }
267 
269 {
270  bool value = is_vista;
271  if (is_vista) {
272  HRESULT hr;
273  BOOL bEnabled;
274 
275  hr = pDwmIsCompositionEnabled(&bEnabled);
276  value = (SUCCEEDED(hr) && bEnabled);
277  }
278  return value;
279 }
280 
282 {
283  return is_vista && pIsThemeActive();
284 }
285 
287 {
288  if (instanceCount == 0 || cachedVistaState == Dirty)
291  return cachedVistaState;
292 }
293 
295 {
296  if (backButton_) // Leave QStyleSheetStyle's connections on destroyed() intact.
297  backButton_->disconnect(SIGNAL(clicked()));
298 }
299 
301 {
302  DWORD rgb;
303  HANDLE hTheme = pOpenThemeData(QApplication::desktop()->winId(), L"WINDOW");
305  hTheme, WIZ_WP_CAPTION, WIZ_CS_ACTIVE,
307  &rgb);
308  BYTE r = GetRValue(rgb);
309  BYTE g = GetGValue(rgb);
310  BYTE b = GetBValue(rgb);
311  return QColor(r, g, b);
312 }
313 
315 {
316  bool value = false;
317  if (vistaState() == VistaAero) {
318  WIZ_MARGINS mar = {0};
319  if (type == NormalTitleBar)
320  mar.cyTopHeight = 0;
321  else
322  mar.cyTopHeight = titleBarSize() + topOffset();
324  value = SUCCEEDED(hr);
325  }
326  return value;
327 }
328 
330 {
331  HDC hdc = painter->paintEngine()->getDC();
332 
333  if (vistaState() == VistaAero)
334  drawBlackRect(QRect(0, 0, wizard->width(),
335  titleBarSize() + topOffset()), hdc);
337  const int btnTop = backButton_->mapToParent(QPoint()).y();
338  const int btnHeight = backButton_->size().height();
339  const int verticalCenter = (btnTop + btnHeight / 2) - 1;
340 
341  const QString text = wizard->window()->windowTitle();
342  const QFont font = QApplication::font("QWorkspaceTitleBar");
343  const QFontMetrics fontMetrics(font);
344  const QRect brect = fontMetrics.boundingRect(text);
345  int textHeight = brect.height();
346  int textWidth = brect.width();
347  int glowOffset = 0;
348 
349  if (vistaState() == VistaAero) {
350  textHeight += 2 * glowSize();
351  textWidth += 2 * glowSize();
352  glowOffset = glowSize();
353  }
354 
355  const int titleLeft = (wizard->layoutDirection() == Qt::LeftToRight
356  ? titleOffset() - glowOffset
357  : wizard->width() - titleOffset() - textWidth + glowOffset);
358 
360  painter, text,
361  QRect(titleLeft, verticalCenter - textHeight / 2, textWidth, textHeight),
362  hdc);
363 
364  if (!wizard->windowIcon().isNull()) {
365  const int iconLeft = (wizard->layoutDirection() == Qt::LeftToRight
366  ? leftMargin()
367  : wizard->width() - leftMargin() - iconSize());
368 
369  QRect rect(iconLeft, verticalCenter - iconSize() / 2, iconSize(), iconSize());
370  HICON hIcon = wizard->windowIcon().pixmap(iconSize()).toWinHICON();
371  DrawIconEx(hdc, rect.left(), rect.top(), hIcon, 0, 0, 0, NULL, DI_NORMAL | DI_COMPAT);
372  DestroyIcon(hIcon);
373  }
374 }
375 
377 {
378  if (is_vista) {
379  WIZ_WTA_OPTIONS opt;
381  if (visible)
382  opt.dwMask = 0;
383  else
386  }
387 }
388 
389 bool QVistaHelper::winEvent(MSG* msg, long* result)
390 {
391  switch (msg->message) {
392  case WM_NCHITTEST: {
393  LRESULT lResult;
394  // Perform hit testing using DWM
395  if (pDwmDefWindowProc(msg->hwnd, msg->message, msg->wParam, msg->lParam, &lResult)) {
396  // DWM returned a hit, no further processing necessary
397  *result = lResult;
398  } else {
399  // DWM didn't return a hit, process using DefWindowProc
400  lResult = DefWindowProc(msg->hwnd, msg->message, msg->wParam, msg->lParam);
401  // If DefWindowProc returns a window caption button, just return HTCLIENT (client area).
402  // This avoid unnecessary hits to Windows NT style caption buttons which aren't visible but are
403  // located just under the Aero style window close button.
404  if (lResult == HTCLOSE || lResult == HTMAXBUTTON || lResult == HTMINBUTTON || lResult == HTHELP)
405  *result = HTCLIENT;
406  else
407  *result = lResult;
408  }
409  break;
410  }
411  case WM_NCCALCSIZE:
412  if (vistaState() == VistaAero) {
413  NCCALCSIZE_PARAMS* lpncsp = (NCCALCSIZE_PARAMS*)msg->lParam;
414  *result = DefWindowProc(msg->hwnd, msg->message, msg->wParam, msg->lParam);
415  lpncsp->rgrc[0].top -= titleBarSize();
416  } else {
417  return false;
418  }
419  break;
420  default:
421  LRESULT lResult;
422  // Pass to DWM to handle
423  if (pDwmDefWindowProc(msg->hwnd, msg->message, msg->wParam, msg->lParam, &lResult))
424  *result = lResult;
425  // If the message wasn't handled by DWM, continue processing it as normal
426  else
427  return false;
428  }
429 
430  return true;
431 }
432 
434 {
435 #ifndef QT_NO_CURSOR
436  if (rtTop.contains(pos))
438  else
440 #endif
441 }
442 
444 {
445  switch (event->type()) {
446  case QEvent::MouseMove:
447  mouseMoveEvent(static_cast<QMouseEvent *>(event));
448  break;
450  mousePressEvent(static_cast<QMouseEvent *>(event));
451  break;
453  mouseReleaseEvent(static_cast<QMouseEvent *>(event));
454  break;
455  default:
456  break;
457  }
458 }
459 
460 // The following hack ensures that the titlebar is updated correctly
461 // when the wizard style changes to and from AeroStyle. Specifically,
462 // this function causes a Windows message of type WM_NCCALCSIZE to
463 // be triggered.
465 {
466  const int x = wizard->geometry().x(); // ignored by SWP_NOMOVE
467  const int y = wizard->geometry().y(); // ignored by SWP_NOMOVE
468  const int w = wizard->width();
469  const int h = wizard->height();
470  SetWindowPos(wizard->winId(), 0, x, y, w, h, SWP_NOMOVE | SWP_NOZORDER | SWP_FRAMECHANGED);
471 }
472 
473 // The following hack allows any QWidget subclass to access
474 // QWidgetPrivate::topData() without being declared as a
475 // friend by QWidget.
476 class QHackWidget : public QWidget
477 {
478 public:
480  QTLWExtra* topData() { return d_func()->topData(); }
481 };
482 
484 {
485  QTLWExtra *top = ((QHackWidget *)wizard)->d_func()->topData();
486  int x1, y1, x2, y2;
487  top->frameStrut.getCoords(&x1, &y1, &x2, &y2);
488  top->frameStrut.setCoords(x1, 0, x2, y2);
489 }
490 
491 bool QVistaHelper::handleWinEvent(MSG *message, long *result)
492 {
493  if (message->message == WIZ_WM_THEMECHANGED || message->message == WIZ_WM_DWMCOMPOSITIONCHANGED)
495 
496  bool status = false;
498  status = winEvent(message, result);
499  if (message->message == WM_NCCALCSIZE) {
500  if (status)
502  } else if (message->message == WM_NCPAINT) {
503  wizard->update();
504  }
505  }
506  return status;
507 }
508 
510 {
511  Q_UNUSED(event);
512  rtTop = QRect (0, 0, wizard->width(), frameSize());
513  int height = captionSize() + topOffset();
514  if (vistaState() == VistaBasic)
515  height -= titleBarSize();
516  rtTitle = QRect (0, frameSize(), wizard->width(), height);
517 }
518 
520 {
521  Q_UNUSED(event);
522  QPainter painter(wizard);
523  drawTitleBar(&painter);
524 }
525 
527 {
529  event->ignore();
530  return;
531  }
532 
533  QRect rect = wizard->geometry();
534  if (pressed) {
535  switch (change) {
536  case resizeTop:
537  {
538  const int dy = event->pos().y() - pressedPos.y();
539  if ((dy > 0 && rect.height() > wizard->minimumHeight())
540  || (dy < 0 && rect.height() < wizard->maximumHeight()))
541  rect.setTop(rect.top() + dy);
542  }
543  break;
544  case movePosition: {
545  QPoint newPos = event->pos() - pressedPos;
546  rect.moveLeft(rect.left() + newPos.x());
547  rect.moveTop(rect.top() + newPos.y());
548  break; }
549  default:
550  break;
551  }
552  wizard->setGeometry(rect);
553 
554  } else if (vistaState() == VistaAero) {
555  setMouseCursor(event->pos());
556  }
557  event->ignore();
558 }
559 
561 {
562  change = noChange;
563 
564  if (event->button() != Qt::LeftButton || wizard->windowState() & Qt::WindowMaximized) {
565  event->ignore();
566  return;
567  }
568 
569  if (rtTitle.contains(event->pos())) {
571  } else if (rtTop.contains(event->pos()))
573 
574  if (change != noChange) {
575  if (vistaState() == VistaAero)
576  setMouseCursor(event->pos());
577  pressed = true;
578  pressedPos = event->pos();
579  } else {
580  event->ignore();
581  }
582 }
583 
585 {
586  change = noChange;
587  if (pressed) {
588  pressed = false;
589  wizard->releaseMouse();
590  if (vistaState() == VistaAero)
591  setMouseCursor(event->pos());
592  }
593  event->ignore();
594 }
595 
597 {
598  if (obj != wizard)
599  return QObject::eventFilter(obj, event);
600 
601  if (event->type() == QEvent::MouseMove) {
602  QMouseEvent *mouseEvent = static_cast<QMouseEvent*>(event);
603  long result;
604  MSG msg;
605  msg.message = WM_NCHITTEST;
606  msg.wParam = 0;
607  msg.lParam = MAKELPARAM(mouseEvent->globalX(), mouseEvent->globalY());
608  msg.hwnd = wizard->winId();
609  winEvent(&msg, &result);
610  msg.wParam = result;
611  msg.message = WM_NCMOUSEMOVE;
612  winEvent(&msg, &result);
613  } else if (event->type() == QEvent::MouseButtonPress) {
614  QMouseEvent *mouseEvent = static_cast<QMouseEvent*>(event);
615 
616  if (mouseEvent->button() == Qt::LeftButton) {
617  long result;
618  MSG msg;
619  msg.message = WM_NCHITTEST;
620  msg.wParam = 0;
621  msg.lParam = MAKELPARAM(mouseEvent->globalX(), mouseEvent->globalY());
622  msg.hwnd = wizard->winId();
623  winEvent(&msg, &result);
624  msg.wParam = result;
625  msg.message = WM_NCLBUTTONDOWN;
626  winEvent(&msg, &result);
627  }
628  } else if (event->type() == QEvent::MouseButtonRelease) {
629  QMouseEvent *mouseEvent = static_cast<QMouseEvent*>(event);
630 
631  if (mouseEvent->button() == Qt::LeftButton) {
632  long result;
633  MSG msg;
634  msg.message = WM_NCHITTEST;
635  msg.wParam = 0;
636  msg.lParam = MAKELPARAM(mouseEvent->globalX(), mouseEvent->globalY());
637  msg.hwnd = wizard->winId();
638  winEvent(&msg, &result);
639  msg.wParam = result;
640  msg.message = WM_NCLBUTTONUP;
641  winEvent(&msg, &result);
642  }
643  }
644 
645  return false;
646 }
647 
649 {
650  LOGFONT lf = {0};
651 
652  if (!hTheme)
654  else
655  {
656  NONCLIENTMETRICS ncm = {sizeof(NONCLIENTMETRICS)};
657  SystemParametersInfo(SPI_GETNONCLIENTMETRICS, sizeof(NONCLIENTMETRICS), &ncm, false);
658  lf = ncm.lfMessageFont;
659  }
660  return CreateFontIndirect(&lf);
661 }
662 
663 bool QVistaHelper::drawTitleText(QPainter *painter, const QString &text, const QRect &rect, HDC hdc)
664 {
665  bool value = false;
666  if (vistaState() == VistaAero) {
667  HANDLE hTheme = pOpenThemeData(QApplication::desktop()->winId(), L"WINDOW");
668  if (!hTheme) return false;
669  // Set up a memory DC and bitmap that we'll draw into
670  HDC dcMem;
671  HBITMAP bmp;
672  BITMAPINFO dib = {{0}};
673  dcMem = CreateCompatibleDC(hdc);
674 
675  dib.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
676  dib.bmiHeader.biWidth = rect.width();
677  dib.bmiHeader.biHeight = -rect.height();
678  dib.bmiHeader.biPlanes = 1;
679  dib.bmiHeader.biBitCount = 32;
680  dib.bmiHeader.biCompression = BI_RGB;
681 
682  bmp = CreateDIBSection(hdc, &dib, DIB_RGB_COLORS, NULL, NULL, 0);
683 
684  // Set up the DC
685  HFONT hCaptionFont = getCaptionFont(hTheme);
686  HBITMAP hOldBmp = (HBITMAP)SelectObject(dcMem, (HGDIOBJ) bmp);
687  HFONT hOldFont = (HFONT)SelectObject(dcMem, (HGDIOBJ) hCaptionFont);
688 
689  // Draw the text!
690  WIZ_DTTOPTS dto = { sizeof(WIZ_DTTOPTS) };
692  RECT rctext ={0,0, rect.width(), rect.height()};
693 
695  dto.iGlowSize = glowSize();
696 
697  pDrawThemeTextEx(hTheme, dcMem, 0, 0, (LPCWSTR)text.utf16(), -1, uFormat, &rctext, &dto );
698  BitBlt(hdc, rect.left(), rect.top(), rect.width(), rect.height(), dcMem, 0, 0, SRCCOPY);
699  SelectObject(dcMem, (HGDIOBJ) hOldBmp);
700  SelectObject(dcMem, (HGDIOBJ) hOldFont);
701  DeleteObject(bmp);
702  DeleteObject(hCaptionFont);
703  DeleteDC(dcMem);
704  //ReleaseDC(hwnd, hdc);
705  } else if (vistaState() == VistaBasic) {
706  painter->drawText(rect, text);
707  }
708  return value;
709 }
710 
711 bool QVistaHelper::drawBlackRect(const QRect &rect, HDC hdc)
712 {
713  bool value = false;
714  if (vistaState() == VistaAero) {
715  // Set up a memory DC and bitmap that we'll draw into
716  HDC dcMem;
717  HBITMAP bmp;
718  BITMAPINFO dib = {{0}};
719  dcMem = CreateCompatibleDC(hdc);
720 
721  dib.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
722  dib.bmiHeader.biWidth = rect.width();
723  dib.bmiHeader.biHeight = -rect.height();
724  dib.bmiHeader.biPlanes = 1;
725  dib.bmiHeader.biBitCount = 32;
726  dib.bmiHeader.biCompression = BI_RGB;
727 
728  bmp = CreateDIBSection(hdc, &dib, DIB_RGB_COLORS, NULL, NULL, 0);
729  HBITMAP hOldBmp = (HBITMAP)SelectObject(dcMem, (HGDIOBJ) bmp);
730 
731  BitBlt(hdc, rect.left(), rect.top(), rect.width(), rect.height(), dcMem, 0, 0, SRCCOPY);
732  SelectObject(dcMem, (HGDIOBJ) hOldBmp);
733 
734  DeleteObject(bmp);
735  DeleteDC(dcMem);
736  }
737  return value;
738 }
739 
740 #if !defined(_MSC_VER) || _MSC_VER < 1700
741 static inline int getWindowBottomMargin()
742 {
743  return GetSystemMetrics(SM_CYSIZEFRAME);
744 }
745 #else // !_MSC_VER || _MSC_VER < 1700
746 // QTBUG-36192, GetSystemMetrics(SM_CYSIZEFRAME) returns bogus values
747 // for MSVC2012 which leads to the custom margin having no effect since
748 // that only works when removing the entire margin.
749 static inline int getWindowBottomMargin()
750 {
751  RECT rect = {0, 0, 0, 0};
752  AdjustWindowRectEx(&rect, WS_POPUP | WS_CLIPSIBLINGS | WS_CLIPCHILDREN | WS_THICKFRAME | WS_DLGFRAME, FALSE, 0);
753  return qAbs(rect.bottom);
754 }
755 #endif // _MSC_VER >= 1700
756 
758 {
759  return getWindowBottomMargin();
760 }
761 
763 {
764  return GetSystemMetrics(SM_CYCAPTION);
765 }
766 
768 {
769  static bool tried = false;
770  if (!tried) {
771  QSystemLibrary dwmLib(L"dwmapi");
773  (PtrDwmIsCompositionEnabled)dwmLib.resolve("DwmIsCompositionEnabled");
775  pDwmDefWindowProc = (PtrDwmDefWindowProc)dwmLib.resolve("DwmDefWindowProc");
777  (PtrDwmExtendFrameIntoClientArea)dwmLib.resolve("DwmExtendFrameIntoClientArea");
778  }
779  QSystemLibrary themeLib(L"uxtheme");
780  pIsAppThemed = (PtrIsAppThemed)themeLib.resolve("IsAppThemed");
781  if (pIsAppThemed) {
782  pDrawThemeBackground = (PtrDrawThemeBackground)themeLib.resolve("DrawThemeBackground");
783  pGetThemePartSize = (PtrGetThemePartSize)themeLib.resolve("GetThemePartSize");
784  pGetThemeColor = (PtrGetThemeColor)themeLib.resolve("GetThemeColor");
785  pIsThemeActive = (PtrIsThemeActive)themeLib.resolve("IsThemeActive");
786  pOpenThemeData = (PtrOpenThemeData)themeLib.resolve("OpenThemeData");
787  pCloseThemeData = (PtrCloseThemeData)themeLib.resolve("CloseThemeData");
788  pGetThemeSysFont = (PtrGetThemeSysFont)themeLib.resolve("GetThemeSysFont");
789  pDrawThemeTextEx = (PtrDrawThemeTextEx)themeLib.resolve("DrawThemeTextEx");
790  pSetWindowThemeAttribute = (PtrSetWindowThemeAttribute)themeLib.resolve("SetWindowThemeAttribute");
791  }
792  tried = true;
793  }
794 
795  return (
797  && pDwmDefWindowProc != 0
799  && pIsAppThemed != 0
800  && pDrawThemeBackground != 0
801  && pGetThemePartSize != 0
802  && pGetThemeColor != 0
803  && pIsThemeActive != 0
804  && pOpenThemeData != 0
805  && pCloseThemeData != 0
806  && pGetThemeSysFont != 0
807  && pDrawThemeTextEx != 0
809  );
810 }
811 
813 {
814  int iconOffset = wizard ->windowIcon().isNull() ? 0 : iconSize() + textSpacing;
815  return leftMargin() + iconOffset;
816 }
817 
819 {
820  if (vistaState() != VistaAero)
821  return titleBarSize() + 3;
822  static const int aeroOffset =
825  return aeroOffset + titleBarSize();
826 }
827 
829 
830 #endif // QT_NO_STYLE_WINDOWSVISTA
831 
832 #endif // QT_NO_WIZARD
#define WIZ_TMT_CAPTIONFONT
The QAbstractButton class is the abstract base class of button widgets, providing functionality commo...
The QPainter class performs low-level painting on widgets and other paint devices.
Definition: qpainter.h:86
void mouseMoveEvent(QMouseEvent *event)
The QColor class provides colors based on RGB, HSV or CMYK values.
Definition: qcolor.h:67
void mousePressEvent(QMouseEvent *event)
bool setDWMTitleBar(TitleBarChangeType type)
int minimumHeight() const
void mouseReleaseEvent(QMouseEvent *event)
static PtrIsThemeActive pIsThemeActive
QSize sizeHint() const
int type
Definition: qmetatype.cpp:239
#define WIZ_WTNCA_NODRAWCAPTION
int y() const
The QFontMetrics class provides font metrics information.
Definition: qfontmetrics.h:65
#define QT_END_NAMESPACE
This macro expands to.
Definition: qglobal.h:90
QSize size() const
QPointer< QWidget > widget
QRect frameStrut
Definition: qwidget_p.h:180
#define BYTE
void disconnectBackButton()
Qt::WindowStates windowState() const
Returns the current window state.
Definition: qwidget.cpp:3086
static PtrDrawThemeBackground pDrawThemeBackground
void moveLeft(int pos)
Moves the rectangle horizontally, leaving the rectangle&#39;s left edge at the given x coordinate...
Definition: qrect.h:350
void paintEvent(QPaintEvent *event)
QVistaBackButton * backButton_
void ensurePolished() const
Ensures that the widget has been polished by QStyle (i.e., has a proper font and palette).
Definition: qwidget.cpp:10024
static PtrDrawThemeTextEx pDrawThemeTextEx
static VistaState vistaState()
static VistaState cachedVistaState
static PtrDwmDefWindowProc pDwmDefWindowProc
bool(WINAPI * PtrIsAppThemed)()
static bool drawBlackRect(const QRect &rect, HDC hdc)
void resizeEvent(QResizeEvent *event)
virtual void leaveEvent(QEvent *)
This event handler can be reimplemented in a subclass to receive widget leave events which are passed...
Definition: qwidget.cpp:9491
The QWidget class is the base class of all user interface objects.
Definition: qwidget.h:150
bool isDown() const
static PtrGetThemePartSize pGetThemePartSize
int cyBottomHeight
Definition: qwizard_win.cpp:74
WIZ_WINDOWTHEMEATTRIBUTETYPE
int left() const
Returns the x-coordinate of the rectangle&#39;s left edge.
Definition: qrect.h:240
int width() const
Returns the width of the rectangle.
Definition: qrect.h:303
static LibLoadStatus status
Definition: qlocale_icu.cpp:69
static int topOffset()
QColor basicWindowFrameColor()
bool underMouse() const
Returns true if the widget is under the mouse cursor; otherwise returns false.
Definition: qwidget.h:996
HRESULT(WINAPI * PtrGetThemeColor)(HANDLE hTheme, int iPartId, int iStateId, int iPropId, OUT COLORREF *pColor)
void pressed()
This signal is emitted when the button is pressed down.
void setGeometry(int x, int y, int w, int h)
This is an overloaded member function, provided for convenience. It differs from the above function o...
Definition: qwidget.h:1017
enum QVistaHelper::Changes change
int height() const
Returns the height of the rectangle.
Definition: qrect.h:306
static const WinVersion WindowsVersion
the version of the Windows operating system on which the application is run (Windows only) ...
Definition: qglobal.h:1613
bool isActiveWindow() const
int bottom() const
Returns the y-coordinate of the rectangle&#39;s bottom edge.
Definition: qrect.h:249
The QString class provides a Unicode character string.
Definition: qstring.h:83
WIZ_NAVIGATIONPARTS
#define WIZ_DT_SINGLELINE
HRESULT(WINAPI * PtrSetWindowThemeAttribute)(HWND hwnd, enum WIZ_WINDOWTHEMEATTRIBUTETYPE eAttribute, PVOID pvAttribute, DWORD cbAttribute)
#define WIZ_DT_VCENTER
void drawTitleBar(QPainter *painter)
Q_DECL_CONSTEXPR T qAbs(const T &t)
Definition: qglobal.h:1201
#define Q_ASSERT(cond)
Definition: qglobal.h:1823
The QObject class is the base class of all Qt objects.
Definition: qobject.h:111
virtual bool event(QEvent *)
This virtual function receives events to an object and should return true if the event e was recogniz...
Definition: qobject.cpp:1200
int height() const
#define WIZ_TMT_BORDERCOLORHINT
bool(WINAPI * PtrIsThemeActive)()
#define WIZ_DT_CENTER
#define SIZE(large, small, mini)
WizardStyle wizardStyle
the look and feel of the wizard
Definition: qwizard.h:64
#define WIZ_DTT_COMPOSITED
const QPoint & pos() const
Returns the position of the mouse cursor, relative to the widget that received the event...
Definition: qevent.h:95
bool drawTitleText(QPainter *painter, const QString &text, const QRect &rect, HDC hdc)
static PtrCloseThemeData pCloseThemeData
HRESULT(WINAPI * PtrCloseThemeData)(HANDLE hTheme)
static QFont font()
Returns the default application font.
HRESULT(WINAPI * PtrGetThemePartSize)(HANDLE hTheme, HDC hdc, int iPartId, int iStateId, OPTIONAL RECT *prc, enum THEMESIZE eSize, OUT SIZE *psz)
void update()
Updates the widget unless updates are disabled or the widget is hidden.
Definition: qwidget.cpp:10883
QRect boundingRect(QChar) const
Returns the rectangle that is covered by ink if character ch were to be drawn at the origin of the co...
void getCoords(int *x1, int *y1, int *x2, int *y2) const
Extracts the position of the rectangle&#39;s top-left corner to *x1 and *y1, and the position of the bott...
Definition: qrect.h:408
#define SIGNAL(a)
Definition: qobjectdefs.h:227
bool winEvent(MSG *message, long *result)
bool event(QEvent *e)
Reimplemented Function
QIcon windowIcon() const
static int frameSize()
virtual HDC getDC() const
Empty default implementation.
void drawText(const QPointF &p, const QString &s)
Draws the given text with the currently defined text direction, beginning at the given position...
Definition: qpainter.cpp:6231
POINT ptShadowOffset
Definition: qwizard_win.cpp:83
#define QT_BEGIN_NAMESPACE
This macro expands to.
Definition: qglobal.h:89
#define WIZ_WTNCA_NODRAWICON
#define WIZ_DTT_GLOWSIZE
void releaseMouse()
Releases the mouse grab.
#define WIZ_WM_DWMCOMPOSITIONCHANGED
Definition: qwizard_win.cpp:98
bool eventFilter(QObject *obj, QEvent *event)
Filters events if this object has been installed as an event filter for the watched object...
static int titleBarSize()
int width() const
void setTop(int pos)
Sets the top edge of the rectangle to the given y coordinate.
Definition: qrect.h:261
bool isNull() const
Returns true if the icon is empty; otherwise returns false.
Definition: qicon.cpp:769
static PtrIsAppThemed pIsAppThemed
The QResizeEvent class contains event parameters for resize events.
Definition: qevent.h:349
int globalX() const
Returns the global x position of the mouse cursor at the time of the event.
Definition: qevent.h:99
static int iconSize()
#define WIZ_CS_ACTIVE
bool handleWinEvent(MSG *message, long *result)
QVistaHelper(QWizard *wizard)
static bool isThemeActive()
QString windowTitle
the window title (caption)
Definition: qwidget.h:198
#define FALSE
Synonym for false.
Definition: qglobal.h:1019
static bool is_vista
HRESULT(WINAPI * PtrDrawThemeTextEx)(HANDLE hTheme, HDC hdc, int iPartId, int iStateId, LPCWSTR pszText, int cchText, DWORD dwTextFlags, LPRECT pRect, const WIZ_DTTOPTS *pOptions)
QPaintEngine * paintEngine() const
Returns the paint engine that the painter is currently operating on if the painter is active; otherwi...
Definition: qpainter.cpp:1991
void setCursor(const QCursor &)
Definition: qwidget.cpp:5290
void setMouseCursor(QPoint pos)
COLORREF crBorder
Definition: qwizard_win.cpp:80
void * HANDLE
Definition: qnamespace.h:1671
void setCoords(int x1, int y1, int x2, int y2)
Sets the coordinates of the rectangle&#39;s top-left corner to (x1, y1), and the coordinates of its botto...
Definition: qrect.h:416
COLORREF crShadow
Definition: qwizard_win.cpp:81
HRESULT(WINAPI * PtrDwmExtendFrameIntoClientArea)(HWND hWnd, const WIZ_MARGINS *pMarInset)
Qt::MouseButton button() const
Returns the button that caused the event.
Definition: qevent.h:101
QRect rect() const
bool contains(const QPoint &p, bool proper=false) const
Returns true if the given point is inside or on the edge of the rectangle, otherwise returns false...
Definition: qrect.cpp:1101
bool isEnabled() const
Definition: qwidget.h:948
virtual bool eventFilter(QObject *, QEvent *)
Filters events if this object has been installed as an event filter for the watched object...
Definition: qobject.cpp:1375
static PtrSetWindowThemeAttribute pSetWindowThemeAttribute
The QMouseEvent class contains parameters that describe a mouse event.
Definition: qevent.h:85
#define rgb(r, g, b)
Definition: qcolor_p.cpp:130
static QDesktopWidget * desktop()
Returns the desktop widget (also called the root window).
qreal dpiScaled(qreal value)
static bool disconnect(const QObject *sender, const char *signal, const QObject *receiver, const char *member)
Disconnects signal in object sender from method in object receiver.
Definition: qobject.cpp:2895
HANDLE(WINAPI * PtrOpenThemeData)(HWND hwnd, LPCWSTR pszClassList)
struct tagMSG MSG
long HRESULT
int top() const
Returns the y-coordinate of the rectangle&#39;s top edge.
Definition: qrect.h:243
void * resolve(const char *symbol)
HRESULT(WINAPI * PtrDwmIsCompositionEnabled)(BOOL *pfEnabled)
#define WIZ_DT_NOPREFIX
int right() const
Returns the x-coordinate of the rectangle&#39;s right edge.
Definition: qrect.h:246
int x() const
Qt::LayoutDirection layoutDirection() const
static PtrGetThemeSysFont pGetThemeSysFont
HICON toWinHICON() const
Returns the HICON handle.
The QFont class specifies a font used for drawing text.
Definition: qfont.h:64
int y() const
Returns the y-coordinate of the rectangle&#39;s top edge.
Definition: qrect.h:255
WIZ_NAV_BACKBUTTONSTATES
COLORREF crText
Definition: qwizard_win.cpp:79
void paintEvent(QPaintEvent *event)
Reimplemented Function
int globalY() const
Returns the global y position of the mouse cursor at the time of the event.
Definition: qevent.h:100
int x() const
Returns the x-coordinate of the rectangle&#39;s left edge.
Definition: qrect.h:252
BOOL fApplyOverlay
Definition: qwizard_win.cpp:88
void collapseTopFrameStrut()
static PtrDwmExtendFrameIntoClientArea pDwmExtendFrameIntoClientArea
The QPoint class defines a point in the plane using integer precision.
Definition: qpoint.h:53
QPoint mapToParent(const QPoint &) const
Translates the widget coordinate pos to a coordinate in the parent widget.
Definition: qwidget.cpp:4459
QPoint pressedPos
QVistaBackButton(QWidget *widget)
int maximumHeight() const
static PtrGetThemeColor pGetThemeColor
int height() const
Returns the height.
Definition: qsize.h:129
The QRect class defines a rectangle in the plane using integer precision.
Definition: qrect.h:58
void enterEvent(QEvent *event)
This event handler can be reimplemented in a subclass to receive widget enter events which are passed...
#define WIZ_WM_THEMECHANGED
Definition: qwizard_win.cpp:97
static int getWindowBottomMargin()
void leaveEvent(QEvent *event)
This event handler can be reimplemented in a subclass to receive widget leave events which are passed...
#define WIZ_WP_CAPTION
int y() const
Returns the y coordinate of this point.
Definition: qpoint.h:131
QWidget * window() const
Returns the window for this widget, i.e.
Definition: qwidget.cpp:4492
QPixmap pixmap(const QSize &size, Mode mode=Normal, State state=Off) const
Returns a pixmap with the requested size, mode, and state, generating one if necessary.
Definition: qicon.cpp:693
The QSize class defines the size of a two-dimensional object using integer point precision.
Definition: qsize.h:53
bool resolveSymbols()
#define Q_DECLARE_PRIVATE(Class)
Definition: qglobal.h:2467
WId winId() const
Returns the window system identifier of the widget.
Definition: qwidget.cpp:2557
void setWindowPosHack()
int x() const
Returns the x coordinate of this point.
Definition: qpoint.h:128
static int instanceCount
HRESULT(WINAPI * PtrGetThemeSysFont)(HANDLE hTheme, int iFontId, LOGFONTW *plf)
static int captionSize()
void moveTop(int pos)
Moves the rectangle vertically, leaving the rectangle&#39;s top edge at the given y coordinate.
Definition: qrect.h:353
static HFONT getCaptionFont(HANDLE hTheme)
const QRect & geometry() const
The QPaintEvent class contains event parameters for paint events.
Definition: qevent.h:298
QWizard * wizard
The QEvent class is the base class of all event classes.
Definition: qcoreevent.h:56
Type type() const
Returns the event type.
Definition: qcoreevent.h:303
static int glowSize()
#define WIZ_TMT_FILLCOLORHINT
#define Q_UNUSED(x)
Indicates to the compiler that the parameter with the specified name is not used in the body of a fun...
Definition: qglobal.h:1729
void setTitleBarIconAndCaptionVisible(bool visible)
static bool isCompositionEnabled()
#define WS_THICKFRAME
virtual void enterEvent(QEvent *)
This event handler can be reimplemented in a subclass to receive widget enter events which are passed...
Definition: qwidget.cpp:9475
int eTextShadowType
Definition: qwizard_win.cpp:82
HRESULT(WINAPI * PtrDrawThemeBackground)(HANDLE hTheme, HDC hdc, int iPartId, int iStateId, const RECT *pRect, OPTIONAL const RECT *pClipRect)
static PtrOpenThemeData pOpenThemeData
#define text
Definition: qobjectdefs.h:80
BOOL(WINAPI * PtrDwmDefWindowProc)(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam, LRESULT *plResult)
The QWizard class provides a framework for wizards.
Definition: qwizard.h:59
void mouseEvent(QEvent *event)
void setFocusPolicy(Qt::FocusPolicy policy)
Definition: qwidget.cpp:7631
const ushort * utf16() const
Returns the QString as a &#39;\0\&#39;-terminated array of unsigned shorts.
Definition: qstring.cpp:5290
QPoint topLeft() const
Returns the position of the rectangle&#39;s top-left corner.
Definition: qrect.h:288
static PtrDwmIsCompositionEnabled pDwmIsCompositionEnabled