2016-07-18 63 views
2

我有一个小的WPF应用程序,我总是希望在桌面前显示,但在所有其他应用程序后面。我尝试了几种方法来创建这个窗口,但是窗口最小化(WindKey + D)或者它显示在所有应用程序的前面。C#WPF主窗口始终坐在桌面前

基本上我想在主窗口中运行一个标签。它在桌面上具有透明背景,并且消息文本每周都会更改。 (所有用户的工作场所的安全信息)。

using System.Windows; 



namespace ESLMessage 
{ 
    /// <summary> 
    /// Interaction logic for MainWindow.xaml 
    /// </summary> 
    /// 
public partial class MainWindow : Window 
{ 
    public MainWindow() 
    { 
     InitializeComponent(); 
     InitialiseScreenSettings(); 
     this.ShowInTaskbar = false; 

    } 

    public void InitialiseScreenSettings() 
    { 

     double screenWidth = System.Windows.SystemParameters.PrimaryScreenWidth; 
     double screenHeight = System.Windows.SystemParameters.PrimaryScreenHeight; 
     double windowWidth = this.Width; 
     double windowHeight = this.Height; 
     this.Left = (screenWidth/2) - (windowWidth/2); 
     this.Top = (screenHeight/2) - (windowHeight/2); 
     //this.Width = System.Windows.SystemParameters.PrimaryScreenWidth; 
     //this.Height = System.Windows.SystemParameters.PrimaryScreenHeight; 
     //this.Topmost = true; 

     if (!IsVisible) 
     { 
      Show(); 
     } 

     if (WindowState == WindowState.Minimized) 
     { 
      WindowState = WindowState.Normal; 
     } 
     Activate(); 
     Topmost = true; // important 
     Topmost = false; // important 
     Focus();   // important 
    } 
} 
} 

回答

1

采取尝试下面的代码:

[DllImport("user32.dll")] 
static extern bool SetWindowPos(
    IntPtr hWnd, 
    IntPtr hWndInsertAfter, 
    int X, 
    int Y, 
    int cx, 
    int cy, 
    uint uFlags); 

const UInt32 SWP_NOSIZE = 0x0001; 
const UInt32 SWP_NOMOVE = 0x0002; 

static readonly IntPtr HWND_BOTTOM = new IntPtr(1); 

static void SendWpfWindowBack(Window window) 
{ 
    var hWnd = new WindowInteropHelper(window).Handle; 
    SetWindowPos(hWnd, HWND_BOTTOM, 0, 0, 0, 0, SWP_NOSIZE | SWP_NOMOVE); 
} 

来源:http://www.aeroxp.org/board/lofiversion/index.php?t4983.html

编辑:

对不起。您必须处理MainWindow的加载事件并将其发回。 试试这个:

代码隐藏:

private void MainWindow_OnLoaded(object sender, RoutedEventArgs e) 
{ 
    SendWpfWindowBack(Application.Current.MainWindow); 
} 

的XAML:

Loaded="MainWindow_OnLoaded" 

还是按WIN + d将其隐藏。但它有点类似于你的要求。 如果您想永久性地向您的所有员工显示特定消息,请尝试考虑使用壁纸。您可以为每个人设置相同的壁纸,并禁止员工更改它。

+0

谢谢IDisposable。我尝试了类似的东西,但我不确定如何在InitialiseComponents();之后调用SendWpfWindowBack方法。你能建议吗? –

+0

执行此操作:'SendWpfWindowBack(this);'在InitialiseComponents() – ViVi

+0

我仍然可以使用Windows Key + D将它完全减至最小。第一次运行时,它不会直接返回。 (通过Visual Studio显示)。有任何想法吗? –

0

试试这个,

private KeyboardFilter kbFilter; 

private void MainForm_Activated(object sender, EventArgs e) 
{ 
    kbFilter = new KeyboardFilter(new Keys[] 
    { 
     Keys.LWin | Keys.D, 
     Keys.RWin | Keys.D, 
     Keys.LWin | Keys.X, // if you need 
     Keys.RWin | Keys.X, // if you need 
     Keys.Alt | Keys.F4 // if you need 
    }); 
} 

private void MainForm_Deactivate(object sender, EventArgs e) 
{ 
    kbFilter.Dispose(); 
} 

务必在MainForm_Deactivate事件使用KeyboardFilter.Dispose()

KeyboardFilter类是从Here

using System; 
using System.Collections.Generic; 
using System.Linq; 
using System.Text; 
using System.Runtime.InteropServices; 
using System.Windows.Forms; 
using System.Diagnostics; 
using System.ComponentModel; 

class KeyboardFilter : IDisposable 
{ 
    private Keys[] mFilter; 
    private IntPtr mHook; 
    private readonly LowLevelKeyboardProc mProc; 

    public KeyboardFilter(Keys[] keysToFilter) 
    { 
     // Install hook 
     mFilter = keysToFilter; 
     ProcessModule mod = Process.GetCurrentProcess().MainModule; 
     mProc = KeyboardProc; // Avoid garbage collector problems 
     mHook = SetWindowsHookEx(13, mProc, GetModuleHandle(mod.ModuleName), 0); 
     if (mHook == IntPtr.Zero) throw new Win32Exception(Marshal.GetLastWin32Error(), "Failed to set hook"); 
    } 
    public void Dispose() 
    { 
     Dispose(true); 
     GC.SuppressFinalize(this); 
    } 
    protected virtual void Dispose(bool disposing) 
    { 
     if (disposing) 
     { 
      // Release hook 
      if (mHook != IntPtr.Zero) 
      { 
       UnhookWindowsHookEx(mHook); 
       mHook = IntPtr.Zero; 
      } 
     } 
    } 
    ~KeyboardFilter() 
    { 
     Dispose(false); 
    } 
    private IntPtr KeyboardProc(int nCode, IntPtr wp, IntPtr lp) 
    { 
     // Callback, filter key 
     if (nCode >= 0) 
     { 
      KBDLLHOOKSTRUCT info = (KBDLLHOOKSTRUCT)Marshal.PtrToStructure(lp, typeof(KBDLLHOOKSTRUCT)); 
      foreach (Keys key in mFilter) 
       if ((key & Keys.KeyCode) == info.key && CheckModifier(key)) return (IntPtr)1; 
     } 
     return CallNextHookEx(mHook, nCode, wp, lp); 
    } 
    private static bool CheckModifier(Keys key) 
    { 
     // Check if modifier key in required state 
     if ((key & Keys.Control) == Keys.Control && 
      GetAsyncKeyState(Keys.LControlKey) == 0 && GetAsyncKeyState(Keys.RControlKey) == 0) return false; 
     if ((key & Keys.Shift) == Keys.Shift && 
      GetAsyncKeyState(Keys.LShiftKey) == 0 && GetAsyncKeyState(Keys.RShiftKey) == 0) return false; 
     if ((key & Keys.Alt) == Keys.Alt && 
      GetAsyncKeyState(Keys.LMenu) == 0 && GetAsyncKeyState(Keys.RMenu) == 0) return false; 
     return true; 
    } 

    // P/Invoke declarations 
    [StructLayout(LayoutKind.Sequential)] 
    private struct KBDLLHOOKSTRUCT 
    { 
     public Keys key; 
     public int scanCode; 
     public int flags; 
     public int time; 
     public IntPtr extra; 
    } 
    private delegate IntPtr LowLevelKeyboardProc(int nCode, IntPtr wParam, IntPtr lParam); 
    [DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = true)] 
    private static extern IntPtr SetWindowsHookEx(int id, LowLevelKeyboardProc callback, IntPtr hMod, uint dwThreadId); 
    [DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = true)] 
    private static extern bool UnhookWindowsHookEx(IntPtr hook); 
    [DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = true)] 
    private static extern IntPtr CallNextHookEx(IntPtr hook, int nCode, IntPtr wp, IntPtr lp); 
    [DllImport("kernel32.dll", CharSet = CharSet.Auto, SetLastError = true)] 
    private static extern IntPtr GetModuleHandle(string name); 
    [DllImport("user32.dll", CharSet = CharSet.Auto)] 
    private static extern short GetAsyncKeyState(Keys key); 
} 

+0

谢谢普拉萨德。我得到一个“钥匙无法找到的名字”。我认为这是由于我使用WPF而不是Windows窗体? –