目前最通用的客户端调用3D的方式,就是WPF程序通过Process启动Unity3D的exe进程,直接上代码:

 //开启3D进程
internal void Create3DProcess(string processUri)
{
if (string.IsNullOrWhiteSpace(processUri) || !File.Exists(processUri))
{
return;
//throw new Exception("Unable to find Unity window,File was not exit");
}
var handle = Panel.Handle;
this.Dispatcher.InvokeAsync(() =>
{
try
{ //判断当前要启动的进程是否还在启动,如果还在启动,先关闭进程再创建进程
CheckProcessByName(processUri); if (process != null)
{
process.Close();
} process = new Process();
process.StartInfo.Arguments = "-parentHWND " + handle.ToInt32() + " " + Environment.CommandLine + " " + Unity3DProcessArges.Replace("AutoWidth",Panel.Width.ToString()).Replace("AutoHeight",Panel.Height.ToString());
process.StartInfo.FileName = processUri;
process.StartInfo.WorkingDirectory = System.IO.Path.GetDirectoryName(processUri);
process.StartInfo.UseShellExecute = true;
process.StartInfo.CreateNoWindow = true;
process.Start();
process.WaitForInputIdle();
EnumChildWindows(handle, WindowEnum, IntPtr.Zero);
}
catch (Exception ex)
{
LogHelper.Error(ex.ToString());
}
}); } [DllImport("user32.dll")]
public static extern bool EnumChildWindows(IntPtr hwnd, WindowEnumProc func, IntPtr lParam);

启动进程后,在做WPF应用上的交互,比如点击了WPF上的一个按钮,当前的鼠标的焦点会被WPF程序捕获到,如果3D程序进程没有做键盘或者鼠标焦点的获取,就会出现键盘和鼠标事件无法触发!

大概的解决思路:在WPF程序上,获取鼠标滑动的窗体的句柄,判断当前鼠标停留的窗体的句柄如果跟3D程序的窗体句柄一样,则激活3D窗体程序(需要用到user32的API),直接上代码:

 1    private IntPtr unityHWND = IntPtr.Zero; //3D窗体的句柄
2 /// <summary>
3 /// 发送消息,触发激活当前窗体
4 /// </summary>
5 internal void ActiveWindows()
6 {
7
8 if (unityHWND!=IntPtr.Zero)
9 {
10 SendMessage(unityHWND, WM_ACTIVATE, WA_ACTIVE, IntPtr.Zero);
11 }
12 }
13
14 /// <summary>
15 /// 解除激活窗体
16 /// </summary>
17 internal void UnActiveWindows()
18 {
19 if (unityHWND!=IntPtr.Zero)
20 {
21 SendMessage(unityHWND, WM_ACTIVATE, WA_INACTIVE, IntPtr.Zero);
22 }
23 }
24
25
26 //检测窗体句柄
27 private void CheckWindowsActive()
28 {
29 actionTime = new DispatcherTimer();
30 actionTime.Interval = new TimeSpan(TimeSpan.TicksPerMillisecond * 300);
31 actionTime.Tick += ActionTime_Tick;
32 actionTime.Start();
33 }
34
35 IntPtr lastIntprt = IntPtr.Zero; //获取上一次的鼠标指向的句柄,为了指向相同的位置,避免重复给窗体发送消息
36 private void ActionTime_Tick(object sender, EventArgs e)
37 {
38 try
39 {
40 POINT pOINT;
41 bool isSuccess = GetCursorPos(out pOINT);
42 var intptr = WindowFromPoint(pOINT);
43 if (isSuccess && unityHWND != IntPtr.Zero && lastIntprt != intptr)//判断当前句柄跟上一次的句柄是否一样,如果一样就不再触发
44 {
45 if (intptr == unityHWND)
46 {
47 ActiveWindows();
48 }
49 else
50 {
51 UnActiveWindows();
52 }
53
54 }
55 lastIntprt = intptr;
56
57 }
58 catch (Exception ex)
59 {
60 LogHelper.Error(ex.ToString());
61 }
62 }
63
64 [DllImport("user32.dll", CharSet = CharSet.Auto)]
65 public static extern IntPtr SendMessage(IntPtr hWnd, UInt32 Msg, IntPtr wParam, IntPtr lParam);
66
67 [DllImport("user32.dll", CharSet = CharSet.Auto)]
68 public static extern bool GetCursorPos(out POINT pt);
69
70 [DllImport("user32.dll")]
71 public static extern IntPtr WindowFromPoint(POINT Point);
72
73 public struct POINT
74 {
75 public int X;
76 public int Y;
77 public POINT(int x, int y)
78 {
79 this.X = x;
80 this.Y = y;
81 }
82 }

WPF嵌入Unity3D之后,unity3D程序的键盘和鼠标事件无法触发(3D程序的焦点无法激活)的解决方案的更多相关文章

  1. WPF之路-键盘与鼠标事件 - 简书

    原文:WPF之路-键盘与鼠标事件 - 简书 键盘事件 事件类型分为以下几个类型 生命周期事件:在元素加载与卸载的时候发生 鼠标事件:鼠标动作 键盘事件:键盘动作 手写笔事件:适用于win7以上的系统 ...

  2. winform中键盘和鼠标事件的捕捉和重写(转)

    在 编写winform应用程序时,有时需要无论在哪个控件获取焦点时,对某一个键盘输入或者鼠标事件都进行同样的操作.比如编写一个处理图片的应用程序时, 希望无论当前哪个控件获得焦点,当用户按上.下.左. ...

  3. winform中键盘和鼠标事件的捕捉和重写

    在编写winform应用程序时,有时需要无论在哪个控件获取焦点时,对某一个键盘输入或者鼠标事件都进行同样的操作.比如编写一个处理图片的应用程序时,希望无论当前哪个控件获得焦点,当用户按上.下.左.右键 ...

  4. cocos2d-x 键盘和鼠标事件

    出了菜单可以响应用户事件外,cocos2d中的层(Layer)也可以响应事件.层能够自动响应窗口事件,这些事件主要是键盘和鼠标事件,cocos2d中事件处理是通过Pyglet的事件处理完成的. 1.键 ...

  5. 第六章 Windows应用程序对键盘与鼠标的响应 P121 6-8

    基于键盘与鼠标应用的程序设计 一.实验目的 1.掌握键盘与鼠标在应用程序中的消息响应机制.   二.实验内容及步骤 实验任务 1.熟悉键盘的消息响应: 2.熟悉鼠标的消息响应: 实验内容 设计一个窗口 ...

  6. Selenium2+python自动化12-操作元素(键盘和鼠标事件)

    前言 在前面的几篇中重点介绍了一些元素的到位方法,到位到元素后,接下来就是需要操作元素了.本篇总结了web页面常用的一些操作元素方法,可以统称为行为事件 有些web界面的选项菜单需要鼠标悬停在某个元素 ...

  7. 自动化测试-8.selenium操作元素之键盘和鼠标事件

    前言 在前面的几篇中重点介绍了一些元素的定位方法,定位到元素后,接下来就是需要操作元素了.本篇总结了web页面常用的一些操作元素方法,可以统称为行为事件 有些web界面的选项菜单需要鼠标悬停在某个元素 ...

  8. tkinter 对键盘和鼠标事件的处理

    鼠标事件 <ButtonPress-n> <Button-n> <n> 鼠标按钮n被按下,n为1左键,2中键,3右键 <ButtonRelease-n> ...

  9. C# 采用钩子捕获键盘和鼠标事件-验证是否处于无人操作状态

    原文地址:https://www.cnblogs.com/gc2013/p/4036414.html 全局抽象类定义 using System; using System.Collections.Ge ...

随机推荐

  1. JVM学习笔记——GC算法

    GC 算法 GC 即 Garbage Collection 垃圾回收.JVM 中的 GC 99%发生在堆中,而 Java 堆中采用的垃圾回收机制为分代收集算法.即将堆分为新生代和老年代,根据不同的区域 ...

  2. Java(33)IO流的介绍&字节流

    作者:季沐测试笔记 原文地址:https://www.cnblogs.com/testero/p/15228446.html 博客主页:https://www.cnblogs.com/testero ...

  3. 什么是js事件,冒泡机制,事件捕获,默认行为

    js事件: javascript使我们能够有能力创建动态页面,事件就是可以被js侦测到的行为,网页中每个元素都可以产生某些触发js函数的事件. 例如我们可以在用户点击某个按钮时产生一个click事件来 ...

  4. javascript-jquery的基本方法

    1.去除字符串中两端的空格$.trim(str) var str1=" 123 " $.trim(str1);//123 2.遍历对象的数据并进行操作$.each(obj,func ...

  5. Flink Yarn的2种任务提交方式

    Flink Yarn的2种任务提交方式 Pre-Job模式介绍 每次使用flink run运行任务的时候,Yarn都会重新申请Flink集群资源(JobManager和TaskManager),任务执 ...

  6. 40个Python入门小程序

    有不少同学学完Python后仍然很难将其灵活运用.我整理 37 个Python入门的小程序.在实践中应用Python会有事半功倍的效果. 分享 Github 项目,里面收集了 Python 学习资料 ...

  7. HttpClient使用GET方式通过代理服务器读取页面的例子

    import java.io.BufferedReader;import java.io.InputStreamReader;import org.apache.http.HttpEntity;imp ...

  8. [no code][scrum meeting] Beta 4

    例会时间:5月16日11:30,主持者:伦泽标 下次例会时间:5月18日11:30,主持者:叶开辉 一.工作汇报 人员 昨日完成任务 明日要完成的任务 乔玺华 完成整体框架设计与登录逻辑 与后端对接 ...

  9. Noip模拟76 2021.10.14

    T1 洛希极限 上来一道大数据结构或者单调队列优化$dp$ 真就没分析出来正解复杂度 正解复杂度$O(q+nm)$,但是据说我的复杂度是假的 考虑一个点转移最优情况是从它上面的一个反$L$形转移过来 ...

  10. dinic板子

    loj上偷学长的( 注意几点: id初值赋1才能让正向弧反向弧对应起来 很多题要拆点,一定保证空间 dfs里rest=0的终止条件不能放在for循环里 #include<cstdio> # ...