I am trying to replicate the GUI of the Powershell, Firefox, Word,... with the Win API in C++. We can see that the default title bar is removed and the client area is taking the whole window while keeping the default borders (see screenshot).
I want the window to respond to all functionalities correctly (aerosnap, resize, border colors, ...).
The closest I could get was by using a combination of
MARGINS margins = { 1 };
DwmExtendFrameIntoClientArea(hWnd, &margins);
and
case WM_NCCALCSIZE:
return 0;
But the window does not have the resize handles anymore and the borders are not taking the right color (when "Show accent color on title bars and window borders" is enabled in settings).
Do you know the recipe to get the desired result ?
I read the Firefox source code and found my answer.
All you have to do is create a WS_OVERLAPPEDWINDOW
window and give the client area Rect for each WM_NCCALCSIZE
message (read doc).
case WM_NCCALCSIZE: {
RECT* clientRect =
wParam ? &(reinterpret_cast<NCCALCSIZE_PARAMS*>(lParam))->rgrc[0] : (reinterpret_cast<RECT*>(lParam));
clientRect->top += 0;
clientRect->left += 7;
clientRect->right -= 7;
clientRect->bottom -= 7;
return 0;
}
However, when the window shows up for the first time, there were some rebel pixels near the borders which did not want to be painted with the background color.
The left border appears 1 pixel wider than the bottom one:
I found out that those pixels were painted correctly as soon as the window was resized. So to solve it before the app is visible, I resized the window at start-up in the WM_ACTIVATE
message:
case WM_ACTIVATE: {
static bool startup = true;
if (startup) {
startup = false;
// Change values so that your window increases in all directions
MoveWindow(hWnd, 100, 100, 800, 800, TRUE);
}
return DefWindowProc(hWnd, message, wParam, lParam);
}
Note that you will have to implement the resize logic yourself in the WM_NCHITTEST
message to get the arrow cursor (read doc).
Finally I got a window with default borders only and I am free to paint the client area. Every functionality seems to work.
Result: