目前最通用的客户端调用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. 基于Hexo+Github Pages搭建的博客

    概念 Github Pages可以被认为是用户编写的.托管在github上的静态网页.使用Github Pages可以为你提供一个免费的服务器,免去了自己搭建服务器和写数据库的麻烦.此外还可以绑定自己 ...

  2. Spatial Analyst Tools(Spatial Analyst 工具)

    Spatial Analyst Tools 1.区域分析 # Process: 以表格显示分区几何统计 arcpy.gp.ZonalGeometryAsTable_sa("", & ...

  3. SpringBoot入门03-转发到Thymeleaf

    前言 Spring Boot不提倡使用jsp和用View层,而是使用Thymeleaf代替jsp,因为性能可以得到提升. 使用Thymeleaf要加入依赖 Thymeleaf不能直接被访问,它严格遵守 ...

  4. Fikker 管理平台弱口令

    官网:www.fikker.com 应用介绍:Fikker 是一款面向 CDN/站长 的专业级网站缓存(Webcache)和反向代理服务器软件(Reverse Proxy Server). 发现过程: ...

  5. Flask 易错点

    1.With上下文管理器 常用: with open("file_name","wb") as f: f.write("hello flask&quo ...

  6. Java:并发笔记-05

    Java:并发笔记-05 说明:这是看了 bilibili 上 黑马程序员 的课程 java并发编程 后做的笔记 4. 共享模型之内存 本章内容 上一章讲解的 Monitor 主要关注的是访问共享变量 ...

  7. 第1次 Beta Scrum Meeting

    本次会议为Beta阶段第1次Scrum Meeting会议 会议概要 会议时间:2021年5月29日 会议地点:「腾讯会议」线上进行 会议时长:0.5小时 会议内容简介:本次会议为Beta阶段第1次会 ...

  8. the Agiles Scrum Meeting 2

    会议时间:2020.4.10 21:00 1.每个人的工作 今天已完成的工作 yjy:debug:班级创建了个人项目不能访问班级:教师窗口的前端bug. issues:Bug:教师创建博客时显示项目为 ...

  9. 8.18考试总结[NOIP模拟43]

    又挂了$80$ 好气哦,但要保持优雅.(草 T1 地衣体 小小的贪心:每次肯定从深度较小的点向深度较大的点转移更优. 模拟一下,把边按链接点的子树最大深度排序,发现实际上只有上一个遍历到的点是对当前考 ...

  10. NavigationView使用简介

    Android支持直接创建带有NavigationView的Activity,这里主要介绍NavigationView的逻辑. NavigationView通常是跟DrawerLayout一起使用.D ...