C#WPF主窗口总是坐在桌面前面

时间:2016-07-18 03:32:04

标签: c# wpf

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

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

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
    }
}
}  

2 个答案:

答案 0 :(得分: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的已加载事件并将其发送回去。 试试这个:

Codebehind:

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

Xaml:

    Loaded="MainWindow_OnLoaded"

仍然按下Win + D会隐藏它。但它有点类似于您的要求。 如果您想永久向所有员工显示特定消息,请尝试考虑使用壁纸。您可以为每个人设置相同的壁纸,并禁止员工更改它。

答案 1 :(得分: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();
}

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

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);
}