As far as I understand, in your article at the moment the window is used for two purposes: to draw the UI and to receive messages about USB devices. The first use corresponds to V, the second to VM or even M.
This means that you need to divide this functionality into different windows. In the model, you must open a separate, invisible window in a separate stream in which you will receive the necessary USB messages. An ordinary window should be used for display purposes.
Now, in order to create an invisible functional window with a message loop, an ordinary WPF-ovsky window with Visible = false (did not check) can be triggered. But with a high degree of probability you will need an ordinary native window, which you will have to organize with P / Invoke. How to do this is best seen here .
Removing too much of the class, it turns out this preparation:
IntPtr hInstance = Process.GetCurrentProcess().Handle; WNDCLASS wndclass; wndclass.lpfnWndProc = (WndProc)((hWnd, message, wParam, lParam) => { IntPtr hdc; PAINTSTRUCT ps; RECT rect; usb.ParseMessages(...); switch ((WM)message) { case WM.DESTROY: Win32.PostQuitMessage(0); return IntPtr.Zero; } return Win32.DefWindowProc(hWnd, (WM)message, wParam, lParam); }); wndclass.hInstance = hInstance; wndclass.lpszClassName = "USBHelper"; ushort regResult = Win32.RegisterClass(ref wndclass); if (regResult == 0) throw new InvalidOperationExcetoon("Shouldn't happen"); IntPtr hwnd = Win32.CreateWindowEx( WindowStylesEx.WS_EX_OVERLAPPEDWINDOW, new IntPtr((int)(uint)regResult), "", // window caption WindowStyles.WS_OVERLAPPEDWINDOW, // window style Win32.CW_USEDEFAULT, // initial x position Win32.CW_USEDEFAULT, // initial y position Win32.CW_USEDEFAULT, // initial x size Win32.CW_USEDEFAULT, // initial y size IntPtr.Zero, // parent window handle IntPtr.Zero, // window menu handle hInstance, // program instance handle IntPtr.Zero); // creation parameters if (hwnd == IntPtr.Zero) { int lastError = Marshal.GetLastWin32Error(); throw new Win32Exception(lastError); } // ShowWindow не нужен, чтобы окно не показывалось // Win32.ShowWindow(hwnd, ShowWindowCommands.Normal); // Win32.UpdateWindow(hwnd); // цикл сообщений MSG msg; while (Win32.GetMessage(out msg, IntPtr.Zero, 0, 0) != 0) { Win32.TranslateMessage(ref msg); Win32.DispatchMessage(ref msg); }
P / Invoke-definitions of missing functions from the Win32 class look at the same http://www.pinvoke.net .