接受服务接收其他客户端发送的消息 需要传递给对应组件或者界面 因此会出现类库重复引用问题。因为采用消息队列,和数据库中转来传递消息需要每个组件知道太多其他组件的业务,并且耗损性能和时间更多一下因此都被排除掉。最后采用Windows API传递消息
后续如果有更好地办法再继续更新上来
由于项目进程间和线程间需要进行通讯,因此通过api调用windows底层消息传递
[DllImport("User32.dll", EntryPoint = "PostMessage")]
public static extern int PostMessage(IntPtr wnd, int msg, IntPtr wP, IntPtr lP);
因此通过实验和调查实现了WPF调用PostMessage传递消息,并且支持传递结构体(转换概念:现将结构体进行转换为16进制,WinProc接收后在进行转换为结构体) 具体代码如下:
/// <summary>
/// Receive message window form handle 消息接收窗口句柄
/// </summary>
public static IntPtr Handle;
/// <summary>
/// PostMessage Dll Import API方法
/// </summary>
[DllImport("User32.dll", EntryPoint = "PostMessage")]
public static extern int PostMessage(IntPtr wnd, int msg, IntPtr wP, IntPtr lP);
/// <summary>
/// Message Data Struct 结构体
/// </summary>
public struct MessageDataStruct
{
//message对象
public CMessageData messageData;
}
/// <summary>
/// user-defined message no 自定义消息
/// </summary>
public const int USER_MESSAGE = 0x0400;
发送消息
/// <summary>
/// Send mesage data to window message queue
/// </summary>
/// <param name="messageData">message data</param>
public void PostMessageToMessageQueue(MessageDataStruct messageData)
{
//结构体赋值
MessageDataStruct mds = new MessageDataStruct();
mds.messageData = new CMessageData();
LocalClientInfo lci = new LocalClientInfo();
lci.ClientID = "我是客户端id";
lci.ClientIP = "我是客户端ip";
mds.messageData.LocalClientInfo = new LocalClientInfo();
mds.messageData.LocalClientInfo = lci;
IntPtr buffer = Marshal.AllocCoTaskMem(Marshal.SizeOf(mds));
Marshal.StructureToPtr(mds, buffer, false);
PostMessage(Handle, BaseTypeParameters.USER_MESSAGE(等同于消息编号), buffer, IntPtr.Zero);
}
Windows消息接收
调用系统WinProc方法
void win_SourceInitialized(object sender, EventArgs e)
{
if (hwndSource != null)
{
hwndSource.AddHook(new HwndSourceHook(WindowProc));
}
}
{
base.OnSourceInitialized(e);
this.win_SourceInitialized(this, e);
}
private IntPtr WindowProc(IntPtr hwnd, int msg, IntPtr wParam, IntPtr lParam, ref bool handled)
{
IntPtr result = IntPtr.Zero;
{
//WM_DEVICECHANGE,系统硬件改变发出的系统消息
switch (param)
{
//判断是否为自定义消息
case BaseTypeParameters.USER_MESSAGE:
//将消息转换为结构体
MessageBox.Show(mds.messageData.LocalClientInfo.ClientID + "----" + mds.messageData.LocalClientInfo.ClientIP);
break;
}
return result;
}
}
#endregion
//将窗句柄赋值给服务
private void Window_Loaded(object sender, RoutedEventArgs e)
{
ReceiveDataImplement.Handle = new WindowInteropHelper(this).Handle;
}