1

I'm trying to position my Win32 API window alongside (e.g. left-sided vertical) taskbar. My display has 2560x1600 resolution and 144 DPI. I had some problems with DPI-aware apps previously, so maybe I still don't undestand some DPI-related things. For example, now I set DPI-awarness both programmatically - setting the DPI_AWARENESS_CONTEXT_PER_MONITOR_AWARE_V2 option through the Win32 API, and adding two lines (to support Windows 7-10) to the project's manifest file:

<dpiAware xmlns="http://schemas.microsoft.com/SMI/2005/WindowsSettings">True/PM</dpiAware>
<dpiAwareness xmlns="http://schemas.microsoft.com/SMI/2016/WindowsSettings">PerMonitorV2</dpiAwareness>

Here is a code snippet, that shows how I'm setting a window's position:

RECT taskbarRect = {0, 0, 0, 0};
HWND taskbarHandle = FindWindow(L"Shell_TrayWnd", NULL);
if (taskbarHandle) {
    GetWindowRect(taskbarHandle, &taskbarRect);
} else {...}
RECT notificationWindowRect; // Here is the RECT for window, I'm trying to reposition.
GetWindowRect(notificationWindowHandle, &notificationWindowRect);
LONG newX = 0;
LONG newY = 0;
bool taskbarIsVertical = (taskbarRect.Height() > taskbarRect.Width());
if (taskbarRect.left == 0 && taskbarIsVertical) { // left vertical taskbar
    newX = taskbarRect.right;
    newY = taskbarRect.bottom - notificationWindowRect.Height();
} else {...}

SetWindowPos(notificationWindowHandle, NULL, newX, newY, 0, 0, SWP_NOSIZE | SWP_NOZORDER | SWP_NOACTIVATE);

When system scaling is set to 100%, it's almost working - taskbarRect has a width of 63, but still there is a gap of a few pixels between the taskbar's right side and my window's left side. Note, that my window has the popup style and has no borders.

However, the main problem happens, when I set Windows' scaling to 150%. From the one hand, the taskbarRect's width becomes equal to 94, which I suppose is correct because 63 * 1.5 == 94. On the other hand, my window becomes hidden a little bit from the left side by the taskbar. To handle that, I need to add 65 pixels:

newX = taskbarRect.right + 65;

I don't understand where this 65-pixel shift appears from, and why it is exactly 65 pixels.

Remy Lebeau
  • 555,201
  • 31
  • 458
  • 770
qloq
  • 689
  • 1
  • 5
  • 15
  • 1
    Windows have invisible borders these days, trying to align two windows is quite difficult and varies between OS versions and (as you've seen) different DPIs. Black magic basically. – Jonathan Potter Jun 29 '22 at 08:04
  • 2
    Don't use Shell_TrayWnd, use the monitor work area. – Anders Jun 29 '22 at 11:01
  • 1
    To get the _visual_ size (i. e. without the drop shadow) of a window, call `DwmGetWindowAttribute()` with `DWMWA_EXTENDED_FRAME_BOUNDS`. This API has been available since Windows Vista. – zett42 Jun 30 '22 at 16:43
  • Your code looks like it should work *to some extent* (see below). And I cannot reproduce the issue. Your code *perfecly* (no gap) positions a `WS_POPUP` window on my system with a left taskbar on 150% dpi (also *no gap* on 100%). Some guesses: Do you have multiple monitors? Maybe something gets confused -- this is also why Shell_TrayWnd is a bad idea - multiple monitors means multiple taskbars, do what @Anders suggested. Or maybe you are running that code in the wrong place, maybe it's too early and then accidentally some other code repositions the window? – dialer Jun 30 '22 at 20:27
  • @dialer. No, I don't use multiple monitors now. Maybe I will test it after this, more simple, case will be solved. There is no code for reposition after code, that I mentioned in the first post. However I found new problems - something automatically resizes my window to minimize gaps between controls and window' borders, so I need to insert dummy controls to keep those gaps. Maybe I have some fundamental bugs in my code, e.g. in `CreateWindow` or `RegisterClassEx`. – qloq Jul 01 '22 at 18:45
  • You can get the size of padding for the shadow around window using [`GetSystemMetrics(SM_CXPADDEDBORDER)`](https://learn.microsoft.com/en-us/windows/win32/api/winuser/nf-winuser-getsystemmetrics), subtract this value from the appropriate coordinate. – Alexey Ivanov Nov 21 '22 at 23:50

0 Answers0