目前最通用的客户端调用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 action 自动构建(多种形式)

    已经使用HEXO正常构建GitHub页面 根据github action 给hexo配置自动部署github page 前往墨抒颖的个人网站查看纯净版 1. 为仓库设置访问密钥 第一步先生成密钥,打开 ...

  2. Java(36)IO流案例与总结

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

  3. CORS+XSS的漏洞利用payload

    之前有人问我有没有CORS+XSS的利用姿势,翻了一下国内貌似都没有利用姿势于是就写了这篇文章!!! 首先找到一个反射xss,然后使用xss加载javascript代码达到跨域劫持目的payload如 ...

  4. 关于 我的博客和Git-hub

    欢迎大家到我的GitHub 热烈讨论 https://github.com/ljj-19951010 由于另一个博客忘了怎么登陆了,换用此博客(仅供个人学习使用,请勿传播) 如果想看 特别详细的教程请 ...

  5. CQL和SQL的CRUD操作比较

    数据进行CRUD操作时,CQL语句和SQL语句的异同之处. 1.建表 2.CRUD语句比较 3.总结 1.建表 在此之前先分别创建两张表,插入数据,用来测试然后进行比较 在SQL数据库里面创建表 在C ...

  6. 四万字32图,Kafka知识体系保姆级教程宝典

    本文目录: 一.消息队列 Apache Pulsar Pulsar 与 Kafka 对比 二.Kafka基础 三.Kafka架构及组件 四.Kafka集群操作 五.Kafka的JavaAPI操作 六. ...

  7. [对对子队]会议记录4.11(Scrum Meeting 2)

    今天已完成的工作 何瑞 ​ 工作内容:完成指令的衔接:完成合成指南界面的制作:初步实现成本系统 ​ 相关issue:实现用户指令编辑系统的逻辑 马嘉 ​ 工作内容:完成游戏内暂停界面 ​ 相关issu ...

  8. PCB电路板元器件布局的一般原则*(转)

    PCB电路板元器件布局的一般原则: 设计人员在PCB电路板布局过程中需要遵循的一般原则如下. (1)元器件最好单面放置.如果需要双面放置元器件,在底层(Bottom Layer)放置插针式元器件, ) ...

  9. [源码解析] PyTorch 分布式(1)------历史和概述

    [源码解析] PyTorch 分布式(1)------历史和概述 目录 [源码解析] PyTorch 分布式(1)------历史和概述 0x00 摘要 0x01 PyTorch分布式的历史 1.1 ...

  10. sudo user1账号获得管理员root的权限

    user1虽然有sudo权限,但不是真正的root权限,修改内核参数之类的就做不了 但是有sudo权限就可以添加账号,以下添加了admin账号与root账号一样的权限 useradd -u 0   - ...