Custom Window Border
Unsolved
General and Desktop
-
wrote on 5 Mar 2017, 15:49 last edited by
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
-
wrote on 5 Mar 2017, 19:17 last edited by
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.
2/2