wpf应用程序mvvm监视器剪贴板

时间:2018-09-19 17:26:45

标签: c# .net wpf

我创建了一个控制台应用程序来监视剪贴板的更改时间。它工作正常,代码显示在下面的控制台代码部分。

我的问题是现在尝试使用MVVM对WPF应用程序执行此操作。我想我需要将MainWindow传递给我的视图模型,这是MVVM的正确方法吗?

更新

这是我创建窗口的尝试。我读到我需要实现HwndHost,这在我的类MyFirstWindow中已经完成。我不确定如何隐藏窗口吗?

我假设在ClipboardManager下的其他类中,我需要创建MyFirstWindow的实例。但是我不确定要传递什么HandleRef?

db.collection.dropIndex({ "name.short": 1 })

我在WPF应用程序中下面创建了ClipboardManager类。

 class MyFirstWindow : HwndHost
{

    IntPtr hwndHost;

    protected override HandleRef BuildWindowCore(HandleRef hwndParent)
    {
        hwndHost = IntPtr.Zero;
        hwndHost = CreateWindowEx(0, "static", "", WS_CHILD,
            0, 0, 50, 50, hwndParent.Handle,
            (IntPtr)HOST_ID,
            IntPtr.Zero, 0);

        return new HandleRef(this, hwndHost);
    }

    protected override void DestroyWindowCore(HandleRef hwnd)
    {            
        DestroyWindow(hwnd.Handle);
    }

    internal const int
      WS_CHILD = 0x40000000,
      WS_VISIBLE = 0x10000000,
      LBS_NOTIFY = 0x00000001,
      HOST_ID = 0x00000002,
      LISTBOX_ID = 0x00000001,
      WS_VSCROLL = 0x00200000,
      WS_BORDER = 0x00800000;

    [DllImport("user32.dll", EntryPoint = "CreateWindowEx", CharSet = CharSet.Unicode)]
    internal static extern IntPtr CreateWindowEx(int dwExStyle,
                                          string lpszClassName,
                                          string lpszWindowName,
                                          int style,
                                          int x, int y,
                                          int width, int height,
                                          IntPtr hwndParent,
                                          IntPtr hMenu,
                                          IntPtr hInst,
                                          [MarshalAs(UnmanagedType.AsAny)] object pvParam);

    [DllImport("user32.dll", EntryPoint = "DestroyWindow", CharSet = CharSet.Unicode)]
    internal static extern bool DestroyWindow(IntPtr hwnd);
}

赢得32堂课

class ClipboardManager : IDisposable
{
    #region variable declaration
    /// <summary>
    /// Next clipboard viewer window 
    /// </summary>
    private IntPtr _hWndNextViewer;
    /// <summary>
    /// The <see cref="HwndSource"/> for this window.
    /// </summary>
    private HwndSource _hWndSource;
    private string _clipboardContent;
    #endregion

    #region property declaration
    public string ClipboardContent
    {
        get
        {
            return _clipboardContent;
        }
        set
        {
            _clipboardContent = value;
        }
    }
    #endregion

    public ClipboardManager()
    {
        hwnd = new MyFirstWindow();
        InitCBViewer();
    }

    private void InitCBViewer(System.Windows.Window wnd)
    {
        WindowInteropHelper wih = new WindowInteropHelper(wnd);
        _hWndSource = HwndSource.FromHwnd(wih.Handle);

        _hWndSource.AddHook(WinProc);   // start processing window messages
        _hWndNextViewer = Win32.SetClipboardViewer(_hWndSource.Handle);   // set this window as a viewer

    }

    private void CloseCBViewer()
    {
        // remove this window from the clipboard viewer chain
        Win32.ChangeClipboardChain(_hWndSource.Handle, _hWndNextViewer);

        _hWndNextViewer = IntPtr.Zero;
        _hWndSource.RemoveHook(this.WinProc);
    }

    private IntPtr WinProc(IntPtr hwnd, int msg, IntPtr wParam, IntPtr lParam, ref bool handled)
    {
        switch (msg)
        {
            case Win32.WM_CHANGECBCHAIN:
                if (wParam == _hWndNextViewer)
                {
                    // clipboard viewer chain changed, need to fix it.
                    _hWndNextViewer = lParam;
                }
                else if (_hWndNextViewer != IntPtr.Zero)
                {
                    // pass the message to the next viewer.
                    Win32.SendMessage(_hWndNextViewer, msg, wParam, lParam);
                }
                break;

            case Win32.WM_DRAWCLIPBOARD:
                // clipboard content changed
                if (Clipboard.ContainsText())
                {
                    ClipboardContent = Clipboard.GetText();
                }

                // pass the message to the next viewer.
                Win32.SendMessage(_hWndNextViewer, msg, wParam, lParam);
                break;
        }

        return IntPtr.Zero;
    }

    public void Dispose()
    {
        CloseCBViewer();
    }
}

0 个答案:

没有答案