2016-07-18 125 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窗體? –