代码之家  ›  专栏  ›  技术社区  ›  mHelpMe

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

  •  0
  • mHelpMe  · 技术社区  · 6 年前

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

    我现在的问题是,如何使用MVVM为WPF应用程序实现这一点。我想我需要将主窗口传递给我的视图模型,这是MVVM的正确方式吗?

    使现代化

    这是我创建窗口的尝试。我已经读到我需要实现HwndHost,这是我在我的类MyFirstWindow中完成的。不过我不知道怎么把窗户藏起来?

    我假设在ClipboardManager下面的另一个类中,我需要创建MyFirstWindow的一个实例。然而,我不确定要通过什么样的HandleRef?

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

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

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

    赢得32级

     internal static class Win32
    {
        /// <summary>
        /// The WM_DRAWCLIPBOARD message notifies a clipboard viewer window that 
        /// the content of the clipboard has changed. 
        /// </summary>
        internal const int WM_DRAWCLIPBOARD = 0x0308;
    
        /// <summary>
        /// A clipboard viewer window receives the WM_CHANGECBCHAIN message when 
        /// another window is removing itself from the clipboard viewer chain.
        /// </summary>
        internal const int WM_CHANGECBCHAIN = 0x030D;
    
        [DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = true)]
        internal static extern IntPtr SetClipboardViewer(IntPtr hWndNewViewer);
    
        [DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = true)]
        internal static extern bool ChangeClipboardChain(IntPtr hWndRemove, IntPtr hWndNewNext);
    
        [DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = true)]
        internal static extern IntPtr SendMessage(IntPtr hWnd, int Msg, IntPtr wParam, IntPtr lParam);
    }
    
    0 回复  |  直到 6 年前