定位和最大化在后台任务中运行的窗口

本文关键字:运行 窗口 后台任务 最大化 定位 | 更新日期: 2023-09-27 18:33:00

好的,以下问题:

我在一台PC上最多10个屏幕上有一些窗口。其中一些应该在后台任务中运行。它是一个WPF应用程序,但对于屏幕定位等,我使用WinForms的某些部分。为此,我使用以下行:

foreach (List<string> myStrings in Screen.AllScreens.Select(myScreen => _xml.GetScreenConfigs(i)))
{
  Thread newWindowThread = new Thread(() =>
  {
    Marketing myMarketing = new Marketing(i, myStrings[0]);
    myMarketing.Show();
    Dispatcher.Run();
  });
  newWindowThread.SetApartmentState(ApartmentState.STA);
  newWindowThread.IsBackground = true;
  newWindowThread.Start();
}

在此窗口中,我使用以下方法来定位它:

[DllImport("user32.dll")]
private static extern IntPtr GetActiveWindow();
...
Left = Convert.ToInt32(screenArray[screenNumber].Bounds.Left);
Top = Convert.ToInt32(screenArray[screenNumber].Bounds.Top);
var active = GetActiveWindow();
var singleOrDefault = Application.Current.Windows.OfType<Window>()
  .SingleOrDefault(window => new WindowInteropHelper(window).Handle == active);
if (singleOrDefault == null) return;
singleOrDefault.Title = "Monitor" + screenNumber;
singleOrDefault.Name = "Monitor" + screenNumber;
singleOrDefault.WindowState = WindowState.Maximized;

但是当我到达"var singleOrDefault"行时,我收到一个错误,说它无法更改对象Application.Current.Windows,因为它由另一个线程拥有。所以我的问题如下:

"我能做什么,在不同的线程中使用此窗口并定位和最大化它?"

定位和最大化在后台任务中运行的窗口

1)你写道:在此窗口中,我使用以下方法来定位它:... Application.Current.Windows.OfType<Window>..

您无法从任务内部对互操作进行操作。将其放在"主"窗口中。这解释了线程异常。

2)如果在修改 UIElemetns 时不使用窗口的调度程序,则可能会收到另一个线程异常。这就是"船长"回答的想法。但是Title NameWindowstate似乎不依赖于调度程序,因为这些应该是win32道具。

设置或获取 UI 元素的属性时,必须在元素的调度程序线程上调用代码。

简而言之,试试这个:

Application.Current.Dispatcher.Invoke(() =>
{
    var singleOrDefault = Application.Current.Windows.OfType<Window>()
            .SingleOrDefault(window => new WindowInteropHelper(window).Handle == active);
    if (singleOrDefault == null) return;
    singleOrDefault.Title = "Monitor" + screenNumber;
    singleOrDefault.Name = "Monitor" + screenNumber;
    singleOrDefault.WindowState = WindowState.Maximized;
});

希望这有帮助...

好的,我(经过多次尝试和错误)得到了其中一个问题的小解决方案:清除左=...和顶部=...并填写窗口状态 = 窗口状态.最大化;然后它最大化。所以只剩下一个问题了:有时(不是每次启动)应用程序在启动时在 Marketing.xaml 中的"InitializeComponent();"行崩溃.cs然后有时一切正常。有时带有 null-reference-异常,有时它说已经有一个使用此名称声明的组件。有人在这里知道那可能是什么?必须对线程执行一些操作,因为这是我第一次收到这些错误。

[编辑]我找到了它:我必须使用lock(),所以现在我只需要找出如何使用它。有人有过这些经验吗?

好的,这是我近两天搜索的答案:

对于最大化:清除左=...和顶部=...并填写窗口状态 = 窗口状态.最大化;然后它最大化。

对于异常错误:在调用的窗口内放置一个static readonly object _locker = new object();和一个 lock (_locker) { InitializeComponent(); }

在窗口内调用。感谢您的所有帮助,我会投票给您的所有帖子,但我没有这样做的声誉。