winform 将untiy程序嵌入到一个panel里

核心脚本

using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Runtime.InteropServices;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.Windows.Forms;namespace SimulationTraining
{public class ExetowinformClass//将应用程序嵌入winform {EventHandler appIdleEvent = null;//这个事件是程序处于空闲时触发 这里用于出发当程序加载完成后要做的事public Form ParentForm = null;string strGUID = "";#region 属性//标识内嵌程序是否已经启动public Process m_AppProcess = null;public bool IsStarted { get { return (this.m_AppProcess != null); } }#endregion 属性public ExetowinformClass(string Titlestr){appIdleEvent = new EventHandler(Application_Idle);strGUID = Titlestr;}//将属性AppFilename指向的应用程序打开并嵌入此容器public IntPtr Start(string FileNameStr, string arg){if (m_AppProcess != null){Stop();}try{ProcessStartInfo info = new ProcessStartInfo(FileNameStr);info.UseShellExecute = true;info.WindowStyle = ProcessWindowStyle.Minimized;info.Arguments = arg;m_AppProcess = System.Diagnostics.Process.Start(info);m_AppProcess.WaitForInputIdle();Application.Idle += appIdleEvent;}catch{if (m_AppProcess != null){if (!m_AppProcess.HasExited) m_AppProcess.Kill();m_AppProcess = null;}}return m_AppProcess.Handle;}//程序加载完成时要做的事  private void Application_Idle(object sender, EventArgs e){if (this.m_AppProcess == null || this.m_AppProcess.HasExited){this.m_AppProcess = null;Application.Idle -= appIdleEvent;return;}//Thread.Sleep(300); //这里加阻塞,时间可以大些Application.DoEvents();if (m_AppProcess.MainWindowHandle == IntPtr.Zero) return;Application.Idle -= appIdleEvent;//EmbedProcess(panel_play);}//将属性AppFilename指向的应用程序关闭public void Stop(){if (m_AppProcess != null){try{if (!m_AppProcess.HasExited)m_AppProcess.Kill();}catch (Exception){}m_AppProcess = null;}}//将指定的程序嵌入指定的控件  这一步会真正嵌入到winform里public void EmbedProcess(Control control){if (m_AppProcess == null || m_AppProcess.MainWindowHandle == IntPtr.Zero || control == null) return;try{//put it into this formShowWindow(m_AppProcess.MainWindowHandle, 0);//先将窗体隐藏,避免闪烁 SetParent(m_AppProcess.MainWindowHandle, control.Handle);}catch (Exception){ }try{//Remove border and whatnotSetWindowLong(new HandleRef(this, m_AppProcess.MainWindowHandle), GWL_STYLE, WS_VISIBLE);SendMessage(m_AppProcess.MainWindowHandle, WM_SETTEXT, IntPtr.Zero, strGUID);}catch (Exception){ }try{//Move the window to overlay it on this windowMoveWindow(m_AppProcess.MainWindowHandle, 0, 0, control.Width, control.Height, true);ShowWindow(m_AppProcess.MainWindowHandle, 3);//窗体显示并最大化}catch (Exception){ }}#region Win32 API[DllImport("user32.dll", EntryPoint = "GetWindowThreadProcessId", SetLastError = true,CharSet = CharSet.Unicode, ExactSpelling = true,CallingConvention = CallingConvention.StdCall)]private static extern long GetWindowThreadProcessId(long hWnd, long lpdwProcessId);[DllImport("user32.dll", SetLastError = true)]private static extern IntPtr FindWindow(string lpClassname, string lpWindowName);[DllImport("user32.dll", SetLastError = true)]private static extern long SetParent(IntPtr hWndChild, IntPtr hWndNewParent);[DllImport("user32.dll", EntryPoint = "GetWindowLongA", SetLastError = true)]private static extern long GetWindowLong(IntPtr hwnd, int nIndex);[DllImport("user32.dll", EntryPoint = "SetWindowLong", CharSet = CharSet.Auto)]public static extern IntPtr SetWindowLongPtr32(HandleRef hWnd, int nIndex, int dwNewLong);[DllImport("user32.dll", EntryPoint = "SetWindowLongPtr", CharSet = CharSet.Auto)]public static extern IntPtr SetWindowLongPtr64(HandleRef hWnd, int nIndex, int dwNewLong);public static IntPtr SetWindowLong(HandleRef hWnd, int nIndex, int dwNewLong){if (IntPtr.Size == 4){return SetWindowLongPtr32(hWnd, nIndex, dwNewLong);}return SetWindowLongPtr64(hWnd, nIndex, dwNewLong);}[DllImport("user32.dll", SetLastError = true)]private static extern long SetWindowPos(IntPtr hwnd, long hWndInsertAfter, long x, long y, long cy, long wFlags);[DllImport("user32.dll", SetLastError = true)]private static extern bool MoveWindow(IntPtr hwnd, int x, int y, int cx, int cy, bool repaint);[DllImport("user32.dll", EntryPoint = "PostMessageA", SetLastError = true)]private static extern bool PostMessage(IntPtr hwnd, uint Msg, uint wParam, uint lParam);[DllImport("user32.dll", SetLastError = true)]private static extern IntPtr GetParent(IntPtr hwnd);[DllImport("user32.dll", EntryPoint = "ShowWindow", SetLastError = true)]static extern bool ShowWindow(IntPtr hWnd, int nCmdShow);[DllImport("user32.dll", EntryPoint = "SendMessage")]private static extern int SendMessage(IntPtr hWnd, int Msg, IntPtr wParam, string lParam);private const int SWP_NOOWNERZORDER = 0x200;private const int SWP_NOREDRAW = 0x8;private const int SWP_NOZORDER = 0x4;private const int SWP_SHOWWINDOW = 0x0040;private const int WS_EX_MDICHILD = 0x40;private const int SWP_FRAMECHANGED = 0x20;private const int SWP_NOACTIVATE = 0x10;private const int SWP_ASYNCWINDOWPOS = 0x40;private const int SWP_NOMOVE = 0x2;private const int SWP_NOSIZE = 0x1;private const int GWL_STYLE = (-16);private const int WS_VISIBLE = 0x10000000;private const int WM_CLOSE = 0x10;private const int WS_CHILD = 0x40000000;private const int SW_HIDE = 0;//{隐藏,并且任务栏也没有最小化图标}private const int SW_SHOWNORMAL = 1;//{用最近的大小和位置显示,激活}private const int SW_NORMAL = 1;//{同 SW_SHOWNORMAL}private const int SW_SHOWMINIMIZED = 2;//{最小化,激活}private const int SW_SHOWMAXIMIZED = 3;//{最大化,激活}private const int SW_MAXIMIZE = 3;//同 SW_SHOWMAXIMIZED}private const int SW_SHOWNOACTIVATE = 4;//{用最近的大小和位置显示,不激活}private const int SW_SHOW = 5;//{同SW_SHOWNORMAL}private const int SW_MINIMIZE = 6;//最小化,不激活private const int SW_SHOWMINNOACTIVE = 7;//同 SW_MINIMIZEprivate const int SW_SHOWNA = 8;//同 SW_SHOWNOACTIVATEprivate const int SW_RESTORE = 9;//同 SW_SHOWNORMALprivate const int SW_SHOWDEFAULT = 10;//同 SW_SHOWNORMALprivate const int SW_MAX = 10;//同 SW_SHOWNORMALconst int WM_SETTEXT = 0x000C;private const int WM_COPYDATA = 0x004A;//接收外部消息#endregion Win32 API}
}

使用方法:

//伪代码unityExeManager = new ExetowinformClass("");//参数是窗口的标题名unityExeManager.Start(exeFullPath, "");//参数2 启动参数
//我用了一个timer和ProcessBar,Untiy程序以最小化启动,等进度条wiform的processBar执行完成后,再将unity嵌入panel,并最大化Unity,这么做是为了不让用户看到madewithunity
//等timer执行完毕后嵌入panelunityExeManager.EmbedProcess(panel_play);//如果不需要进度条,那么可以直接在ExetowinformClass的Application_Idle方法里,取消注释//EmbedProcess(panel_play);来自动嵌入,注意这里panel_play只是演示用的参数,取消注释后需要稍微修改一下代码才能正确执行

//这一部分是timer的代码,仅供参考

  private void timer_UnityLoad_Tick(object sender, EventArgs e)//itmer事件{progressBar_UnityLoad.Value += 1;//timer每0.1秒执行一次,一秒钟为进度条填充10个单位,我们希望他能执行5-7秒if (progressBar_UnityLoad.Value == progressBar_UnityLoad.Maximum){panel_progressBar.Visible = false;//隐藏进度条面板GameApp.Interface.SendEvent(new OnEmbedExe_unityManager(playPanel));timer_UnityLoad.Stop();}}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/web/54140.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Java Web应用升级故障案例解析

在一次Java Web应用程序的优化升级过程中,从Tomcat 7.0.109版本升级至8.5.93版本后,尽管在预发布环境中验证无误,但在灰度环境中却发现了一个令人困惑的问题:新日志记录神秘“失踪”。本文深入探讨了这一问题的排查与解决过程&…

Android常用C++特性之std::chrono

声明:本文内容生成自ChatGPT,目的是为方便大家了解学习作为引用到作者的其他文章中。 std::chrono 是 C11 引入的标准库中的时间处理工具,提供了以多种精度进行时间测量、处理和操作的功能。它允许开发者处理时间点(time_point&am…

C++随心记

C随心记 C中的 CONST C中的const是表示不可修改 int main() {/* 对于变量而言 */// 不可修改的常量const int A 10;// 不可修改的指针指向const int* pointer_0 nullptr;int const* poniter_1 nullptr;// 不可修改指针指向的内容int* const poniter_2 nullptr; }const也…

【湖南步联科技身份证】 身份证读取与酒店收银系统源码整合———未来之窗行业应用跨平台架构

一、html5 <!DOCTYPE html> <html><head><meta http-equiv"Content-Type" content"text/html; charsetutf-8" /><script type"text/javascript" src"http://51.onelink.ynwlzc.net/o2o/tpl/Merchant/static/js…

pip外部管理环境错误处理方法

error: externally-managed-environment This environment is externally managed ╰─> To install Python packages system-wide, try apt install python3-xyz, where xyz is the package you are trying to install. sudo mv /usr/lib/python3.x/EXTERNALLY-MANAGED …

onload_tcpdump命令抓包报错Onload stack [7,] already has tcpdump process

最近碰到Onload 不支持同时运行多个 tcpdump 进程的报错&#xff0c;实际上使用了ps查询当时系统中并没有tcpdump相关进程存在。需要重启服务器本机使用onload加速的相关进程后才能使用onload_tcpdump正常抓包&#xff0c;很奇怪&#xff0c;之前确实没遇到这样的问题&#xff…

Golang | Leetcode Golang题解之第450题删除二叉搜索树的节点

题目&#xff1a; 题解&#xff1a; func deleteNode(root *TreeNode, key int) *TreeNode {var cur, curParent *TreeNode root, nilfor cur ! nil && cur.Val ! key {curParent curif cur.Val > key {cur cur.Left} else {cur cur.Right}}if cur nil {retur…

Django Nginx+uwsgi 安装配置

Django Nginx+uwsgi 安装配置 本文将详细介绍如何在Linux环境下安装和配置Django应用程序,使用Nginx作为Web服务器和uwsgi作为应用程序服务器。我们将覆盖以下主题: 安装Python和相关库安装和配置Django安装Nginx安装和配置uwsgi配置Nginx以使用uwsgi测试和调试1. 安装Pytho…

金镐开源组织成立,增加最新KIT技术,望能为开源添一把火

国内做开源的很多&#xff0c;知名的若依、芋道源码、Pig、Guns等&#xff0c;可谓是百花齐放&#xff0c;虽然比不上Apache&#xff0c;但也大大提高了国内的生产力。经过多年的发展&#xff0c;一些开源项目逐渐也都开始商业化。基于这样的背景&#xff0c;我拉拢了三个技术人…

【重学 MySQL】三十九、Having 的使用

【重学 MySQL】三十九、Having 的使用 基本语法示例示例 1&#xff1a;使用 HAVING 过滤分组示例 2&#xff1a;HAVING 与 WHERE 的结合使用 注意点WHERE 与 HAVING 的对比基本定义与用途主要区别示例对比总结 在 MySQL 中&#xff0c;HAVING 子句主要用于对 GROUP BY 语句产生…

使用powershell的脚本报错:因为在此系统中禁止执行脚本

1.添加powershell功能环境&#xff1a; 2.启动powershell的执行策略 因为在此系统中禁止执行脚本。 set-executionpolicy unrestricted

【计算机视觉】ch1-Introduction

相机模型与成像 1. 世界坐标系 (World Coordinate System) 世界坐标系是指物体在真实世界中的位置和方向的表示方式。在计算机视觉和图像处理领域&#xff0c;世界坐标系通常是一个全局坐标系统&#xff0c;描述了摄像机拍摄到的物体在实际三维空间中的位置。它是所有其他坐标…

刷题day11 栈与队列下【逆波兰表达式求值】【滑动窗口最大值】【前 K 个高频元素】

⚡刷题计划day11 栈与队列继续&#xff0c;可以点个免费的赞哦~ 往期可看专栏&#xff0c;关注不迷路&#xff0c; 您的支持是我的最大动力&#x1f339;~ 目录 ⚡刷题计划day11 栈与队列继续&#xff0c;可以点个免费的赞哦~ 往期可看专栏&#xff0c;关注不迷路&#xf…

无心剑七绝《华夏中兴》

七绝华夏中兴 长空万里尽春声 治世群英喜纵横 一代雄才华夏梦 中兴日月照前程 2024年10月1日 平水韵八庚平韵 无心剑的七绝《华夏中兴》通过对自然景观和国家景象的描绘&#xff0c;展现了一种恢弘的气势和对未来的美好愿景。 意境开阔&#xff1a;首句“长空万里尽春声”以广阔…

MATLAB数字水印系统

课题介绍 本课题为基于MATLAB的小波变换dwt和离散余弦dct的多方法对比数字水印系统。带GUI交互界面。有一个主界面GUI&#xff0c;可以调用dwt方法的子界面和dct方法的子界面。流程包括&#xff0c;读取宿主图像和水印图像&#xff0c;嵌入&#xff0c;多种方法的攻击&#xf…

跳台阶问题

剑指offer的一道简单题目。 描述 一只青蛙一次可以跳上1级台阶&#xff0c;也可以跳上2级。求该青蛙跳上一个 n 级的台阶总共有多少种跳法&#xff08;先后次序不同算不同的结果&#xff09;。 数据范围&#xff1a;1≤n≤40 要求&#xff1a;时间复杂度&#xff1a;O(n) &a…

C#和Python共享内存技术

我这里做一个简单的示例 1.C#写入内存的方法&#xff0c;FileName是内存共享的名字 t是内存size public static void SaveGluePLYToMemory(string FileName, string msg){try{ long t 100;// SetMemorySize(msg);// 100;//# 创建内存块&#xff0c;test1,其他语言利用这个内存…

sysbench 命令:跨平台的基准测试工具

一、命令简介 sysbench 是一个跨平台的基准测试工具&#xff0c;用于评估系统性能&#xff0c;包括 CPU、内存、文件 I/O、数据库等性能。 ‍ 比较同类测试工具 bench.sh 在上文 bench.sh&#xff1a;Linux 服务器基准测试中介绍了 bench.sh 一键测试脚本&#xff0c;它对…

Python库pandas之一

Python库pandas之一 基本数据结构Series构造器属性属性应用函数函数应用 基本数据结构 Pandas提供了两种类型的类来处理数据&#xff1a; Series&#xff1a;保存任何类型数据的一维数组。例如整数、字符串、Python对象等。DataFrame&#xff1a;一种二维数据结构&#xff0c…

ip是可以从能够上网的设备提取吗

是的&#xff0c;IP地址可以从能够上网的设备提取。以下是如何从不同设备提取IP地址的具体方法&#xff1a; 在电脑上提取IP地址 Windows: 打开命令提示符&#xff08;按下 Win R&#xff0c;输入 cmd&#xff0c;按回车&#xff09;。 输入命令 ipconfig&#xff0c;按回车。…