Custom Window Border
Unsolved
General and Desktop
-
Hello,
I currently try to create a QMainWindow with an custom window border on Windows. My current code is:
bool MainWindow::nativeEvent(const QByteArray &eventType, void *msg, long *result) { auto win_msg = static_cast<MSG*>(msg); auto message = win_msg->message; auto wParam = win_msg->wParam; auto lParam = win_msg->lParam; if (message == WM_CREATE) int i = 0; if (message == WM_CREATE || message == WM_ACTIVATE || message == WM_NCCALCSIZE || message == WM_NCHITTEST) { auto forward = true; auto win_result = (LRESULT)0; auto hwnd = (HWND)winId(); auto dwm_enabled = (BOOL)FALSE; auto hr = DwmIsCompositionEnabled(&dwm_enabled); if (SUCCEEDED(hr)) { forward = !DwmDefWindowProc(hwnd, message, wParam, lParam, &win_result); switch (message) { case WM_CREATE: { RECT rcClient; GetWindowRect(hwnd, &rcClient); // Inform application of the frame change. SetWindowPos(hwnd, NULL, rcClient.left, rcClient.top, rcClient.right - rcClient.left, rcClient.bottom - rcClient.top, SWP_FRAMECHANGED); forward = true; win_result = 0; break; } case WM_ACTIVATE: { MARGINS margins; margins.cxLeftWidth = 0; margins.cxRightWidth = 0; margins.cyBottomHeight = 0; margins.cyTopHeight = 0; hr = DwmExtendFrameIntoClientArea(hwnd, &margins); if (!SUCCEEDED(hr)) { // Handle error. } forward = true; win_result = 0; break; } case WM_NCCALCSIZE: { if (wParam == TRUE) { NCCALCSIZE_PARAMS *params = reinterpret_cast<NCCALCSIZE_PARAMS*>(lParam); params->rgrc[0].left = params->rgrc[0].left + 5; params->rgrc[0].top = params->rgrc[0].top + 0; params->rgrc[0].right = params->rgrc[0].right - 5; params->rgrc[0].bottom = params->rgrc[0].bottom - 5; forward = false; win_result = 0; } break; } case WM_NCHITTEST: { if (win_result == 0) { auto mouse_pos = POINT{ LOWORD(lParam), HIWORD(lParam) }; RECT window_rect; GetWindowRect(hwnd, &window_rect); RECT frame_rect = { 0 }; AdjustWindowRectEx(&frame_rect, WS_OVERLAPPEDWINDOW & ~WS_CAPTION, FALSE, NULL); auto row = (USHORT)1; auto col = (USHORT)1; auto resize_border = false; if (mouse_pos.y >= window_rect.top && mouse_pos.y < window_rect.top + 30) { resize_border = (mouse_pos.y < (window_rect.top - frame_rect.top)); row = 0; } else if (mouse_pos.y < window_rect.bottom && mouse_pos.y >= window_rect.bottom) row = 2; if (mouse_pos.x >= window_rect.left && mouse_pos.x < window_rect.left) col = 0; else if (mouse_pos.x < window_rect.right && mouse_pos.x >= window_rect.right) col = 2; LRESULT result_map[3][3] = { { HTTOPLEFT, resize_border ? HTTOP : HTCAPTION, HTTOPRIGHT }, { HTLEFT, HTNOWHERE, HTRIGHT }, { HTBOTTOMLEFT, HTBOTTOM, HTBOTTOMRIGHT }, }; win_result = result_map[row][col]; if (win_result != HTNOWHERE) forward = false; } break; } } } if (!forward) { *result = win_result; return true; } } return QWidget::nativeEvent(eventType, msg, result); } void MainWindow::paintEvent(QPaintEvent *event) { QPainter p(this); p.setPen(Qt::NoPen); p.setBrush(QBrush(QColor("#bbdefb"))); p.drawRect(0, 0, geometry().width(), geometry().height()); p.setBrush(QBrush(QColor("#2196f3"))); p.drawRect(0, 0, geometry().width(), 30); QMainWindow::paintEvent(event); }
The problem is, them main winow then looks like this:
So it seems, that the sizes of the drawing area are not calculated correctly given the customizations I made.
Does anybody know a solution to this?Regards
-
Hi, and welcome. The image upload function on our forum is broken, the uploaded images might be visible to you, but they aren't to anyone else. See this thread for a workaround.