繁体   English   中英

如何判断屏幕的 WorkingArea 何时发生变化(即任务栏被移动)?

[英]How can I tell when a screen's WorkingArea changes (i.e. task bar is moved)?

我有一些窗口停靠在工作区域的边缘/角落,我需要知道屏幕的 WorkingArea 是否/何时发生变化,以便更新这些窗口的位置。 我记得之前尝试过解决这个问题,但无济于事。

一种方法是将您的窗口注册为应用程序桌面工具栏(AppBar) http://msdn.microsoft.com/en-us/library/bb776821(VS.85).aspx然后系统会在您的窗口时向您发送通知需要重新定位、调整大小等。例如,当发生会影响 AppBar 的大小/位置/可见性等的事情时,AppBar 会从系统接收 ABN_POSCHANGED 通知。

您需要互操作才能做到这一点,这是一篇关于使用 C# 执行此操作的代码项目文章,虽然我只使用 C++ 完成过,所以我不能保证这篇文章,但它应该是一个公平的起点。 http://www.codeproject.com/KB/dotnet/AppBar.aspx

我最终只采用了一种非常简单的方法,即运行一个DispatcherTimer ,它每两秒滴答一次,并简单地检查当前的 WorkingArea 与最后检查的 WorkingArea,如果它们不同,则发送一个事件。

1- 在您的表单中创建一个属性,用于保存工作区或最后一个屏幕的最后位置(如代码示例中所示)。

2- 覆盖表单中的 LocationChanged 以检查表单的新位置是否在新的 WorkingArea 上。 如果是这样,则表单位于新屏幕(工作区)上。

    protected override void OnLocationChanged(EventArgs e)
    {
        base.OnLocationChanged(e);
        WorkingScreen = Screen.AllScreens.ToList().FirstOrDefault(s => s.WorkingArea == Screen.GetWorkingArea(this));
    }

    Screen _WorkingScreen = null;

    Screen WorkingScreen
    {
        get { return _WorkingScreen; }
        set
        {
            if (WorkingScreen != value)
            {
                _WorkingScreen = value;
                // Screen changed or working area changed!!!!
            }
        }
    }

这似乎是一个未记录的功能,但我发现在 WndProc 中监听WM_WININICHANGE会告诉你任务栏何时移动/调整大小。
但是我怀疑其他 AppBar 更改会触发此问题,但也许您不想回应这些。

private rectangle prevWA;
    
protected override void WndProc(ref Message m)
{
    switch (m.Msg)
    {
        case WM_WININICHANGE: // 0x1A
        {
            Debug.Print($"WM_WININICHANGE {m.LParam}");    
            if (m.LParam == IntPtr.Zero)
            {
                var newWA = Screen.FromPoint(this.Location + new Point(this.Width / 2, this.Height / 2)).WorkingArea;
                if (newWA != prevWA)
                {
                    Debug.Print($"Working Area Changed {prevWA}->{newWA}");
                    // code here
                    prewWA = newWA;
                }
            }
            break;
        }
    }
    base.WndProc(m);  // allow form to process this message
}

注意:我并没有真正用 C# 编写代码,所以这可能有错误。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM