我创建了一个控制台应用程序来监视剪贴板的更改时间。它工作正常,代码显示在下面的控制台代码部分。
我的问题是现在尝试使用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();
}
}