当前位置:网站首页>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 ???
边栏推荐
- ComputeShader
- Skill review of test engineer before interview
- 信息安全实验三 :PGP邮件加密软件的使用
- stm32和电机开发(从单机版到网络化)
- C language pointer (Part 1)
- Where is the answer? action config/Interceptor/class/servlet
- 章鱼未来之星获得25万美金奖励|章鱼加速器2022夏季创业营圆满落幕
- PMP Exam details after the release of the new exam outline
- 網易雲微信小程序
- NVIC interrupt priority management
猜你喜欢
四、机器学习基础
C language pointer (exercises)
JMeter JDBC batch references data as input parameters (the simplest method for the whole website)
Locust performance test 3 (high concurrency, parameter correlation, assembly point)
二叉树高频题型
Difference between interface iterator and iteratable
Unity shader (basic concept)
Loxodonframework quick start
What are the conditions for applying for NPDP?
MongoDB怎么实现创建删除数据库、创建删除表、数据增删改查
随机推荐
Idea development environment installation
What is the use of PMP certificate?
Information Security Experiment 1: implementation of DES encryption algorithm
C language pointer (exercises)
Information Security Experiment 3: the use of PGP email encryption software
Yapi test plug-in -- cross request
Pick up the premise idea of programming
Implementation of corner badge of Youmeng message push
DRF authentication, permissions, and flow restrictions (only for views in DRF)
Over 100000 words_ Ultra detailed SSM integration practice_ Manually implement permission management
4、 Fundamentals of machine learning
网易云微信小程序
NVIC interrupt priority management
章鱼未来之星获得25万美金奖励|章鱼加速器2022夏季创业营圆满落幕
Schema-validation: wrong column type encountered in column XXX in table XXX
The configuration and options of save actions are explained in detail, and you won't be confused after reading it
Redis common commands
Unity shader (basic concept)
2021 year end summary
Regular matching starts with XXX and ends with XXX