当前位置:网站首页>Unity3d interface is embedded in WPF interface (mouse and keyboard can respond normally)
Unity3d interface is embedded in WPF interface (mouse and keyboard can respond normally)
2022-07-07 09:26:00 【heater404】
Unity3D Interface embedding WPF In the interface ( The mouse and keyboard can respond normally )
1、 quote System.Windows.Forms.dll and WindowsFormsIntegration.dll
unity3D The interface cannot be directly embedded into WPF Control , But it can be embedded in WinForm Control , So we need to be able to WPF Use in WinForm Control as a carrier . Need to quote the above dll, As shown in the figure below :
And then in Xaml Introduce a namespace into the file to use WinForm Control , for example :
xmlns:wf="clr-namespace:System.Windows.Forms;assembly=System.Windows.Forms"
<WindowsFormsHost Grid.Row="1">
<wf:Panel/>
</WindowsFormsHost>
2、 take Unity3d Embedded in WinForm Control
public class AppContainer
{
private System.Windows.Forms.Panel _hostPanel;
private readonly ManualResetEvent _eventDone = new ManualResetEvent(false);
private Process _process = null;
internal IntPtr _embededWindowHandle;
public AppContainer(System.Windows.Forms.Panel panel)
{
this._hostPanel = panel;
this._hostPanel.Resize += _hostPanel_Resize;
}
private void _hostPanel_Resize(object sender, EventArgs e)
{
SetBounds();
}
public void ActivateWindow()
{
if (_process == null)
return;
if (_process.MainWindowHandle == IntPtr.Zero)
return;
Win32Api.SendMessage(_process.MainWindowHandle, Win32Api.WM_ACTIVATE, Win32Api.WA_ACTIVE, IntPtr.Zero);
}
public void SetBounds()
{
SetBounds(_hostPanel.Width, _hostPanel.Height);
}
public void SetBounds(int width, int height)
{
if (_process == null)
return;
if (_process.MainWindowHandle == IntPtr.Zero)
return;
if (width <= 0 || height <= 0)
return;
Win32Api.MoveWindow(_process.MainWindowHandle, 0, 0, width, height, true);
ActivateWindow();// Activate
}
public bool StartAndEmbedProcess(string processPath)
{
if (null != _process)
return true;
var isStartAndEmbedSuccess = false;
_eventDone.Reset();
// Start the process
ProcessStartInfo info = new ProcessStartInfo(processPath);
info.WindowStyle = ProcessWindowStyle.Maximized;// Default maximization , No pop-up interface .
info.Arguments = $"-popupwindow";//Unity Command line parameters of
_process = Process.Start(info);
if (_process == null)
{
return false;
}
// Wait for process to be created and enter idle condition
_process.WaitForInputIdle();
// Get the main handle
var thread = new Thread(() =>
{
while (true)
{
if (_process.MainWindowHandle != (IntPtr)0)
{
_eventDone.Set();
break;
}
Thread.Sleep(10);
}
});
thread.Start();
// Embedded process
if (_eventDone.WaitOne(10000))
{
isStartAndEmbedSuccess = EmbedApp(_process);
if (!isStartAndEmbedSuccess)
{
CloseApp(_process);
}
}
return isStartAndEmbedSuccess;
}
public bool EmbedExistProcess(Process process)
{
_process = process;
return EmbedApp(process);
}
/// <summary>
/// Embed the external process into the current program
/// </summary>
/// <param name="process"></param>
private bool EmbedApp(Process process)
{
// Whether to embed the success flag , Used as a return value
var isEmbedSuccess = false;
// External process handle
var processHwnd = process.MainWindowHandle;
// Container handle
var panelHwnd = _hostPanel.Handle;
if (processHwnd != (IntPtr)0 && panelHwnd != (IntPtr)0)
{
// Associate this window handle with the target window handle
var setTime = 0;
while (!isEmbedSuccess && setTime < 50)
{
// Put it into this form
isEmbedSuccess = Win32Api.SetParent(processHwnd, panelHwnd) != 0;
Thread.Sleep(10);
setTime++;
}
// Remove border and whatnot
//Win32Api.SetWindowLong(processHwnd, Win32Api.GWL_STYLE, Win32Api.WS_CHILDWINDOW | Win32Api.WS_CLIPSIBLINGS | Win32Api.WS_CLIPCHILDREN | Win32Api.WS_VISIBLE);
SetBounds();
Move the window to overlay it on this window
//Win32Api.MoveWindow(_process.MainWindowHandle, 0, 0, (int)ActualWidth, (int)ActualHeight, true);
}
if (isEmbedSuccess)
{
_embededWindowHandle = _process.MainWindowHandle;
}
return isEmbedSuccess;
}
/// <summary>
/// Close the process
/// </summary>
/// <param name="process"></param>
private void CloseApp(Process process)
{
if (process != null && !process.HasExited)
{
process.Kill();
}
}
public void CloseProcess()
{
CloseApp(_process);
_process = null;
}
}
This is an embedded instance class , The constructor will put WinForm Control is passed in as a parameter , Then this control needs to subscribe Resize event , The event handler did unity3D Reactivation of forms .
Command line parameters are used when the process starts info.Arguments = $"-popupwindow";//Unity Command line parameters of .
Still used Win32Api Set as parent form , Win32Api.SetParent(processHwnd, panelHwnd).
The example code is as follows :
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="auto"/>
<RowDefinition />
</Grid.RowDefinitions>
<Grid Grid.Row="0">
<Button Margin="3" Content="Embed" Click="Button_Click" HorizontalAlignment="Center"/>
</Grid>
<WindowsFormsHost Grid.Row="1">
<wf:Panel x:Name="host"/>
</WindowsFormsHost>
</Grid>
private void Button_Click(object sender, RoutedEventArgs e)
{
AppContainer container = new AppContainer(this.host);
container.StartAndEmbedProcess(@"Child.exe");
}
3、 Effect demonstration
The mouse and keyboard can respond normally .
Last 、 If it helps you , Please pay attention to 、 Ask for one key and three links , thank
4、.NetCore
At present, many projects use .NetCore, Then I found that I can't use the above dll. Then, because the following information needs to be added to the project file :
<PropertyGroup>
<TargetFramework>netcoreapp3.1</TargetFramework>
<UseWPF>true</UseWPF>
<UseWindowsForms>true</UseWindowsForms>
<AssemblyName>SIFP.Core</AssemblyName>
</PropertyGroup>
5、 doubt
take WinForm Embedded in WPF In the after ,WinForm Control can only be overridden in WPF Controls , I don't know if there is a big man who knows how to make WPF Control overrides WinForm On ???
边栏推荐
- Yapi test plug-in -- cross request
- Netease cloud wechat applet
- Jenkins task grouping
- 数据库多表关联查询问题
- 正则匹配以XXX开头的,XXX结束的
- PMP Exam details after the release of the new exam outline
- Locust performance test 2 (interface request)
- Locust performance test 4 (custom load Policy)
- Selenium mouse sliding operation event
- 網易雲微信小程序
猜你喜欢

Error: selenium common. exceptions. WebDriverException: Messag‘geckodriver‘ execute

Regular matching starts with XXX and ends with XXX

Information Security Experiment 1: implementation of DES encryption algorithm

STM32 clock system

JMeter JDBC batch references data as input parameters (the simplest method for the whole website)

Information Security Experiment 2: using x-scanner scanning tool

Jenkins+ant+jmeter use

C language pointer (Part 2)

2021 year end summary

浏览器中如何让视频倍速播放
随机推荐
信息安全实验一:DES加密算法的实现
Leetcode question brushing record (array) combination sum, combination sum II
[cloud native] Devops (I): introduction to Devops and use of code tool
How can I apply for a PMP certificate?
Record of structured interview
Idea development environment installation
Postman interface debugging method
PMP Exam details after the release of the new exam outline
Mysql database transaction learning notes
Huawei hcip datacom core_ 03day
Register address name mapping
章鱼未来之星获得25万美金奖励|章鱼加速器2022夏季创业营圆满落幕
flex弹性布局
Implementation of corner badge of Youmeng message push
shake数据库中怎么使用Mongo-shake实现MongoDB的双向同步啊?
Summary of PMP learning materials
When inputting an expression in the input box, an error is reported: incorrect string value:'\xf0\x9f... ' for column 'XXX' at row 1
Schema-validation: wrong column type encountered in column XXX in table XXX
Final keyword
超十万字_超详细SSM整合实践_手动实现权限管理