问题
I have a custom-made borderless window. When maximized, it covers the taskbar. This is not what I want. I have played with the WM_GETMINMAXINFO
message. But, I have found that Windows 10 will then leave an extra 8-pixel gap along both the bottom and right side. It is an all-or-nothing proposition. Here is the first code that I tried:
case WM_GETMINMAXINFO:
PMINMAXINFO pmm;
pmm = (PMINMAXINFO)lParam;
pmm->ptMaxSize.x = GetSystemMetrics(SM_CXSCREEN);
pmm->ptMaxSize.y = GetSystemMetrics(SM_CYSCREEN);
return 0;
The result of this is identical to what I had, without hooking the WM_GETMINMAXINFO
message. So, I knocked two pixels off of the bottom, so I could access the taskbar (which is in "autohide" mode":
case WM_GETMINMAXINFO:
PMINMAXINFO pmm;
pmm = (PMINMAXINFO)lParam;
pmm->ptMaxSize.x = GetSystemMetrics(SM_CXSCREEN);
pmm->ptMaxSize.y = GetSystemMetrics(SM_CYSCREEN)-2;
return 0;
Suddenly, I have a 10-pixel gap on the bottom, and a new 8-pixel gap on the right side! this appears to be a Windows 10 thing, as this never happened with Win7. I have also tried SystemParametersInfo
, calling SPI_GETWORKAREA
(instead of GetSystemMetrics()
). This yields the same results.
From what I gather, the problem is not with WM_GETMINMAXINFO
. Instead, I need to put a command into my code, to keep the taskbar on top. I have searched through the windows styles. But, I have found nothing of help there.
Does anyone know how to fix this critical problem.
回答1:
Well, I found the answer in a most unlikely place. Someone was trying to manipulate borders with Python code. From their attempt, I was able to devise a solution for a borderless window, in C++. Here is the result:
To start, I created a window with the WS_OVERLAPPEDWINDOW | WS_VISIBLE
style, to enable all Windows functions. I then handled the WM_NCCALCSIZE
message with this code:
case WM_NCCALCSIZE:
{
WINDOWPLACEMENT wp;
LPNCCALCSIZE_PARAMS szr;
wp.length = sizeof(WINDOWPLACEMENT);
GetWindowPlacement(hWnd, &wp);
szr = LPNCCALCSIZE_PARAMS(lParam);
if (wp.showCmd == SW_SHOWMAXIMIZED) szr->rgrc[0].bottom -= (WFRAME+2);
return 0;
}
In the code above, I subtracted the width of the border from the bottom of the first rectangle. The extra 2 pixels were added, to expose the bit of the auto-hidden taskbar. The maximized window now acts as it should, allowing access to the taskbar.
To create my virtual client area in this borderless window, I added this bit of code to both the WM_CREATE
and WM_SIZE
handlers:
WINDOWPLACEMENT wp;
GetWindowRect(hWnd, &rWnd);
GetClientRect(hWnd, &rClient);
wp.length = sizeof(WINDOWPLACEMENT);
GetWindowPlacement(hWnd, &wp);
rClient.left += WFRAME; rClient.right -= WFRAME; rClient.top += (WFRAME+cyMenu);
if (wp.showCmd == SW_SHOWNORMAL) rClient.bottom -= WFRAME;
cxClient = rClient.right-rClient.left;
cyClient = rClient.bottom-rClient.top;
The element cyMenu
is a space reserved for my virtual menu bar. It will contain a series of buttons, simulating the menu and min/max/close buttons.
来源:https://stackoverflow.com/questions/64518580/borderless-window-covers-taskbar