An AppBar application not working correctly in Windows 8.x/10 (desktop working area does not get reduced for multiple appbars)

大憨熊 提交于 2019-12-08 06:11:19

问题


I have an application that functions as an "Application Desktop Toolbar", or appbar for short. It is implemented in WPF, and appbar functionality is added by following this guideline: https://msdn.microsoft.com/en-us/library/windows/desktop/cc144177(v=vs.85).aspx.

Everything works fine in Windows 7, but in Windows 8.1 (or likely in Windows 8.x) the following happens:

  1. The first appbar docked on a display's side is displayed correctly, and Windows desktop's working area is reduced accordingly, so that the appbar does not overlap any windows.
  2. The second appbar docked on the same side of the display as the first one is displayed in the right position, but Windows desktop's working area is not reduced. So the second appbar is now overlapping other windows.
  3. The third appbar docked on the same side of the display acts identically with the second one
  4. The fourth (and all appbars after it) get placed over/under the previous three, so effectively appbars start to disappear

What happens in step 2 codewise is this (debugged in Windows 8.1):

Calling

SHAppBarMessage((int)ABMsg.ABM_QUERYPOS, ref barData);

returns the correctly adjusted coordinates for the new appbar. But then calling

SHAppBarMessage((int)ABMsg.ABM_SETPOS, ref barData);

does not seem to "go through", meaning that it executes ok, and later the window will be set in the correct position (defined in barData). But the working area is not reduced, which should to my understanding happen by this function call.

What happens in step 4 is, that SHAppBarMessage((int)ABMsg.ABM_QUERYPOS, ref barData) starts to return incorrect coordinates, such that are the same as already existing appbars. The result being that appbars get overlapped with each other.

The same problem occurs in Windows 10, but seems that with more serious side-effects: my appbar application crashes with multiple appbar instances quite quickly, putting the whole Windows OS to a halt for a few minutes.

I have searched the web quite extensively, but have not found a solution. Did find this article though https://github.com/PhilipRieck/WpfAppBar/issues/4 where the symptoms experienced are quite similar to the ones with my app.

Any help would be greatly appreciated. My guess is that this is a bug with the SHAppBarMessage API in Windows 8.x/10. But won't stop looking until it is confirmed to be so, or even better, a fix is found.


回答1:


In windows 8 and windows 10 ABM_QUERYPOS is not always returning the correct position at first call. But, calling ABM_QUERYPOS again, obtains from Windows the correct position. Depending on the number of app bars. As a sample, this code obtains the correct position:

        APPBARDATA abd = new APPBARDATA();
        abd.cbSize = Marshal.SizeOf(abd);
        abd.hWnd = this.Handle;
        abd.uEdge = (int)ABEdge.ABE_TOP;
        abd.rc.left = 0;
        abd.rc.right = SystemInformation.PrimaryMonitorSize.Width;
        abd.rc.top = 0;
        abd.rc.bottom = Size.Height;

        // Query the system for an approved size and position. 
        int top = abd.rc.top;
        for (;;)
        {
            SHAppBarMessage((int)ABMsg.ABM_QUERYPOS, ref abd);
            if (top == abd.rc.top)
                break;
            top = abd.rc.top;
            abd.rc.bottom = abd.rc.top + Size.Height;
        }

Desktop area is not always correctly modified in Windows 8 or Windows 10 as it is in Windows 7. For the moment, the desktop area can be adjusted with the next code. In windows 10 avoid using SPIF_SENDWININICHANGE, is not working.

    private const Int32 SPIF_change = SPIF_UPDATEINIFILE | SPIF_SENDWININICHANGE;

        MoveWindow(abd.hWnd, abd.rc.left, abd.rc.top, 
            abd.rc.right - abd.rc.left, abd.rc.bottom - abd.rc.top, true);


            RECT final_working_area = new RECT();
            result = SystemParametersInfo(SPI_GETWORKAREA,
                                                  0,
                                                  ref final_working_area,
                                                  SPIF_change);
            // Verify working area was adjusted
            if (final_working_area.top < abd.rc.bottom)
            {
                final_working_area.top = abd.rc.bottom;
                result = SystemParametersInfo(SPI_SETWORKAREA,
                                                      0,
                                                      ref final_working_area,
                                                      SPIF_change);
            }


来源:https://stackoverflow.com/questions/36640551/an-appbar-application-not-working-correctly-in-windows-8-x-10-desktop-working-a

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!