Borderless Window Covers Taskbar

721 views Asked by At

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

There are 1 answers

3
anachronon On

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.