简体   繁体   English

克隆屏幕后,如何在C#的顶部放置一个全屏窗口?

[英]How do I put a full screen window on top in C# after screen is cloned?

I am working on a C# WPF application that uses two screens. 我正在使用两个屏幕的C#WPF应用程序。 In the application the user is able to clone or extend the screen depending on what the user want to do. 在应用程序中,用户可以根据用户想要的操作来克隆或扩展屏幕。 This is done in windows 7 and is using the following code: 这是在Windows 7中完成的,并使用以下代码:

[DllImport("user32.dll", CharSet = System.Runtime.InteropServices.CharSet.Unicode)]
private static extern long SetDisplayConfig(uint numPathArrayElements, IntPtr pathArray, uint    numModeArrayElements, IntPtr modeArray, uint flags);

UInt32 SDC_TOPOLOGY_INTERNAL = 0x00000001;
UInt32 SDC_TOPOLOGY_CLONE = 0x00000002;
UInt32 SDC_TOPOLOGY_EXTEND = 0x00000004;
UInt32 SDC_TOPOLOGY_EXTERNAL = 0x00000008;
UInt32 SDC_APPLY = 0x00000080;

public void CloneDisplays()
{
    SetDisplayConfig(0, IntPtr.Zero, 0, IntPtr.Zero, (SDC_APPLY | SDC_TOPOLOGY_CLONE));
}
public void ExtendDisplays()
{
    SetDisplayConfig(0, IntPtr.Zero, 0, IntPtr.Zero, (SDC_APPLY | SDC_TOPOLOGY_EXTEND));
}

Now to my problem. 现在到我的问题。 When using the above code I manage to clone/extend the screen. 使用上面的代码时,我设法克隆/扩展屏幕。 However, after this is done the taskbar at the bottom of the screen is in front of the full screen application which should not be the case. 但是,完成此操作后,屏幕底部的任务栏将位于全屏应用程序的前面,而事实并非如此。 How do i put the application window back at the top? 如何将应用程序窗口放回顶部?

Additional information: When I start the application it starts in fullscreen with the taskbar behind the application. 附加信息:启动应用程序时,它将以全屏模式启动,并且任务栏位于应用程序后面。 This is done by setting the following: 这是通过设置以下内容来完成的:

WindowState="Maximized"
WindowStyle="None"

And this is what I want after the clone/extend has been done. 这就是克隆/扩展完成后我想要的。 Thanks 谢谢

Edit: I have noticed that after I clone/extend the screen and sleep for say 5 seconds everything works as it should. 编辑:我注意到,在克隆/扩展屏幕并休眠5秒钟后,一切正常。 However, as soon as the 5 seconds is over and the function exits the taskbar gets on top. 但是,一旦5秒钟结束并且函数退出,任务栏就会位于顶部。 Therefore it seems that I can not change something right after the clone/extend because the taskbar will always get on top in the end. 因此,似乎无法在克隆/扩展之后立即更改某些内容,因为任务栏始终总是排在最后。 So somehow I have to figure out how to stop the taskbar to behave like this, instead of changing the property of the window. 因此,我必须以某种方式找出如何停止任务栏以使其表现为这种行为,而不是更改窗口的属性。

Try setting the width and height of the WPF window as follows, You could set this within window constructor. 尝试如下设置WPF窗口的宽度和高度。您可以在窗口构造函数中进行设置。

Width = System.Windows.SystemParameters.PrimaryScreenWidth;
Height = System.Windows.SystemParameters.PrimaryScreenWidth;

To hide the taskbar try setting, 隐藏任务栏尝试设置,

Width = System.Windows.SystemParameters.FullPrimaryScreenWidth;
Height = System.Windows.SystemParameters.FullPrimaryScreenHeight;

I'm already doing full-screen mode within my winforms applications, but i think you can do it more or less the same within WPF: 我已经在Winforms应用程序中进行了全屏模式,但是我认为您可以在WPF中或多或少地做到这一点:

(this has to be different but similar in WPF): (这必须有所不同,但在WPF中类似):

form.WindowState = FormWindowState.Normal;
form.FormBorderStyle = FormBorderStyle.None;
form.Bounds = Screen.GetBounds(form);

Then the next step is to hide the task-bar if your application is on the primary screen: 然后,如果您的应用程序在主屏幕上,则下一步是隐藏任务栏:

if (Screen.PrimaryScreen.Equals(Screen.FromRectangle(Screen.GetBounds(form))))
{
    ShowWindowsToolbar(false);
}

And the method ShowWindowsToolbar() is implemented as follows: 并且ShowWindowsToolbar()方法的实现如下:

[DllImport("user32.dll")]
private static extern int FindWindow(string lpszClassName, string lpszWindowName);
[DllImport("user32.dll")]
private static extern int ShowWindow(int hWnd, int nCmdShow);
private const int SW_HIDE = 0;
private const int SW_SHOW = 1;

public void WindowsToolbar(bool visible)
{
    int hWnd = FindWindow("Shell_TrayWnd", "");
    ShowWindow(hWnd, visible ? SW_SHOW : SW_HIDE);
}

That's the way, how most of the tools out there support this kind of stuff. 这样,现有的大多数工具如何支持这种东西。 Also note, that this mode can mostly entered/leaved by pressing F11 . 另请注意,此模式通常可以通过按F11进入/ 退出 So it would be good, if you also support this keystroke. 因此,如果您也支持此击键,那就太好了。

Turns out all I have to do is update the dispatcher queue and force it to do the update right after the clone/extend has been done. 事实证明,我要做的就是更新调度程序队列,并在克隆/扩展完成后立即强制其执行更新。 Then I can update the window properties. 然后,我可以更新窗口属性。

public void ExtendDisplays()
{
    SetDisplayConfig(0, IntPtr.Zero, 0, IntPtr.Zero, (SDC_APPLY | SDC_TOPOLOGY_EXTEND));
    this.Dispatcher.Invoke(DispatcherPriority.Background, new ThreadStart(delegate { })); //Force update
    current_window.hide();
    current_window.show();
}

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

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