目前最通用的客户端调用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. break和continue关键字

    什么是break break 跳出最里层的循环,并且继续执行该循环下面的语句 就是强制退出循环 示例 package struct; public class ForDemo05 { public s ...

  2. Apache ShardingSphere 元数据加载剖析

    唐国城 小米软件工程师,主要负责 MIUI 浏览器服务端研发工作.热爱开源,热爱技术,喜欢探索,热衷于研究学习各种开源中间件,很高兴能参与到 ShardingSphere 社区建设中,希望在社区中努力 ...

  3. Linux查找运行程序主目录

    1.查看程序所在PID netstat -lntup 2.根据PID查找程序所在目录 ll /proc/PID/exe 3.查找程序配置路径 /proc/PID/exe -t

  4. 题解 [HNOI/AHOI2018]毒瘤

    题目传送门 题目大意 给出一个 \(n\) 个点 \(m\) 条边的无向图,问有多少个点集满足点集中任意两点均不存在边相连. \(n\le 10^5,m-n\le 10\),答案对 \(9982443 ...

  5. 虚拟机Parallels Desktop 17 (PD17)支持M1 自己动手制作启动器解锁

    个人博客:xzajyjs.cn 如果自己有能力的话,直接查看这个视频即可.点此 前段时间刚出pd17,作为mac上最最强(没有之一)的虚拟机,版本17更是更进一步,性能提升极大,更是支持了Monter ...

  6. C11 (GNU Dialect) -std=gnu11 和 -std=c11

    C11 (GNU Dialect) -std=gnu11 和 -std=c11 C11 (GNU Dialect) -std=gnu11 和 -std=c11 用于 IntelliSense 的 C ...

  7. dubbo注册中心占位符无法解析问题(二)

    dubbo注册中心占位符无法解析问题 前面分析了dubbo注册中心占位符无法解析的问题. 并给出了2种解决办法: 降低mybatis-spring的版本至2.0.1及以下 自定义MapperScann ...

  8. 微服务网关Ocelot加入IdentityServer4鉴权-.NetCore(.NET5)中使用

    Consul+Ocelot+Polly在.NetCore中使用(.NET5)-Consul服务注册,服务发现 Consul+Ocelot+Polly在.NetCore中使用(.NET5)-网关Ocel ...

  9. webRTC中语音降噪模块ANS细节详解(二)

    上篇(webRTC中语音降噪模块ANS细节详解(一))讲了维纳滤波的基本原理.本篇先给出webRTC中ANS的基本处理过程,然后讲其中两步(即时域转频域和频域转时域)中的一些处理细节. ANS的基本处 ...

  10. 【UE4 调试】C++ 常见编译 warnnings/errors

    error LNK2019: unresolved external symbol "" referenced in function 描述 Link错误.无法解析的外部符号 解决 ...