1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158
| #include "XWidget.h" #include "ui_XWidget.h"
#include <windowsx.h> #include <dwmapi.h> #include <windows.h>
XWidget::XWidget(QWidget *parent) : QWidget(parent), ui(new Ui::XWidget) { ui->setupUi(this); setWindowFlag(Qt::Window); setWindowTitle(u8"无边框窗口测试"); setGeometry(400, 400, 800, 500); HWND hWnd = (HWND)winId(); SetWindowPos(hWnd, 0, 0, 0, 0, 0, SWP_FRAMECHANGED | SWP_NOSIZE | SWP_NOMOVE); }
XWidget::~XWidget() { delete ui; }
bool XWidget::nativeEvent(const QByteArray &, void *message, long *result) { MSG* msg = (MSG*)message; switch (msg->message) { case WM_NCCALCSIZE: if (msg->wParam == TRUE) { NCCALCSIZE_PARAMS* params = reinterpret_cast<NCCALCSIZE_PARAMS*>(msg->lParam); adjustRectIfMaximized(msg->hwnd, params->rgrc[0]); *result = 0; return true; } break; case WM_NCHITTEST: { *result = hitTest(msg->hwnd, { GET_X_LPARAM(msg->lParam), GET_Y_LPARAM(msg->lParam) }); return true; } break; case WM_NCACTIVATE: if (!isCompositionEnabled()) { *result = TRUE; return true; } break; default: break; } return false; }
long XWidget::hitTest(HWND hWnd, POINT cursor) const { const int borderX = GetSystemMetrics(SM_CXFRAME) + GetSystemMetrics(92); const int borderY = GetSystemMetrics(SM_CYFRAME) + GetSystemMetrics(92);
RECT window; if (!GetWindowRect(hWnd, &window)) { return HTNOWHERE; }
POINT localCursor = { cursor.x, cursor.y }; ScreenToClient(hWnd, &localCursor);
QPoint qCursor(localCursor.x, localCursor.y); QRect topWidgetRect = ui->contentWidget->geometry().adjusted(4, 4, -4, -4); if (topWidgetRect.contains(qCursor)) { return HTCLIENT; }
enum RegionMask { CLIENT = 0b0000, LEFT = 0b0001, RIGHT = 0b0010, TOP = 0b0100, BOTTOM = 0b1000, };
int result = CLIENT; if (localCursor.x < (borderX)) result |= LEFT; if (localCursor.x >= (window.right - window.left - borderX)) result |= RIGHT; if (localCursor.y < (borderY)) result |= TOP; if (localCursor.y >= (window.bottom - window.top - borderY)) result |= BOTTOM;
if (result == CLIENT) return HTCAPTION; if (result & LEFT && result & TOP) return HTTOPLEFT; if (result & LEFT && result & BOTTOM) return HTBOTTOMLEFT; if (result & RIGHT && result & TOP) return HTTOPRIGHT; if (result & RIGHT && result & BOTTOM) return HTBOTTOMRIGHT; if (result & LEFT) return HTLEFT; if (result & RIGHT) return HTRIGHT; if (result & TOP) return HTTOP; if (result & BOTTOM) return HTBOTTOM;
return HTNOWHERE; }
bool XWidget::isCompositionEnabled() { BOOL res = FALSE; if ( DwmIsCompositionEnabled(&res) == S_OK ) { return res; } return false; }
void XWidget::adjustRectIfMaximized(HWND window, RECT &rect) { if (!isMaximized(window)) { return; } auto monitor = MonitorFromWindow(window, MONITOR_DEFAULTTONULL); if (!monitor) { return; } MONITORINFO monitor_info = { 0 }; monitor_info.cbSize = sizeof(monitor_info); if (GetMonitorInfo(monitor, &monitor_info)) { rect.left = monitor_info.rcWork.left - 6; rect.top = monitor_info.rcWork.top - 6; rect.right = monitor_info.rcWork.right + 6; rect.bottom = monitor_info.rcWork.bottom + 6; } }
bool XWidget::isMaximized(HWND hwnd) { WINDOWPLACEMENT placement; if (GetWindowPlacement(hwnd, &placement)) { return placement.showCmd == SW_MAXIMIZE; } return false; }
|