我想在我的 WPF 应用程序中托管一个外部进程的窗口。我是这样推导的HwndHost:
class HwndHostEx : HwndHost
{
[DllImport("user32.dll")]
static extern IntPtr SetParent(IntPtr hWndChild, IntPtr hWndNewParent);
private IntPtr ChildHandle = IntPtr.Zero;
public HwndHostEx(IntPtr handle)
{
this.ChildHandle = handle;
}
protected override System.Runtime.InteropServices.HandleRef BuildWindowCore(System.Runtime.InteropServices.HandleRef hwndParent)
{
HandleRef href = new HandleRef();
if (ChildHandle != IntPtr.Zero)
{
SetParent(this.ChildHandle, hwndParent.Handle);
href = new HandleRef(this, this.ChildHandle);
}
return href;
}
protected override void DestroyWindowCore(System.Runtime.InteropServices.HandleRef hwnd)
{
}
}
Run Code Online (Sandbox Code Playgroud)
并像这样使用它:
HwndHostEx host = new HwndHostEx(handle);
this.PART_Host.Child = host;
Run Code Online (Sandbox Code Playgroud)
handle我想托管的外部窗口的句柄在哪里,是PART_Host我的 WPF …
C代码:
// Device description structure
struct DeviceInfo
{
unsigned short deviceID;
unsigned short productID;
unsigned short versionNumber;
wchar_t* deviceName;
};
void __cdecl GetAttachedDevices(
int* count,
DeviceInfo* deviceInfoList
);
Run Code Online (Sandbox Code Playgroud)
以及使用此 C DLL 的 PInvoke C# 代码:
public struct DeviceInfo
{
public ushort deviceID;
public ushort productID;
public ushort versionNumber;
public IntPtr deviceName;
};
[DllImport("Native.dll", CallingConvention=CallingConvention.Cdecl)]
public static extern void GetAttachedDevices(ref int count, ref DeviceInfo deviceInfoList);
Run Code Online (Sandbox Code Playgroud)
当我使用这个 C# 代码时:
int count = 0;
DeviceInfo dev = new DeviceInfo();
GetAttachedDevices(ref count, ref dev); …Run Code Online (Sandbox Code Playgroud) 这是我的C代码:
LIBRARY_API bool __cdecl Initialize(void (*FirstScanForDevicesDoneFunc)(void));
Run Code Online (Sandbox Code Playgroud)
这是使用此DLL的C#PINvoke代码:
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
public delegate void FirstScanForDevicesDoneFunc();
[DllImport("Native.dll", CallingConvention=CallingConvention.Cdecl)]
public static extern bool Initialize(FirstScanForDevicesDoneFunc);
Run Code Online (Sandbox Code Playgroud)
当我这样调用这个方法时:
static public void Init() {
Initialize(FirstScanForDevicesDone);
}
static public void FirstScanForDevicesDone() {
//do something
}
Run Code Online (Sandbox Code Playgroud)
在Init()回调结束时,我得到NullReferenceException.所以我使用Thread来保持它并且一切正常,但我对这个解决方案不满意:
static public bool Working = true;
static public void Init() {
new Thread(() =>
{
Thread.CurrentThread.IsBackground = true;
Initialize(FirstScanForDevicesDone);
while (Working)
{
Thread.Sleep(1000);
}
}).Start();
}
Run Code Online (Sandbox Code Playgroud)
是否有更复杂的方法来保持这种工作?