当前位置:网站首页>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 ???
边栏推荐
- Common short chain design methods
- Entity of cesium data visualization (Part 1)
- shake数据库中怎么使用Mongo-shake实现MongoDB的双向同步啊?
- What is MD5
- Unity shader (to achieve a simple material effect with adjustable color attributes only)
- Over 100000 words_ Ultra detailed SSM integration practice_ Manually implement permission management
- Implementation of corner badge of Youmeng message push
- 信息安全实验三 :PGP邮件加密软件的使用
- Leetcode daily questions (2316. count unreachable pairs of nodes in an undirected graph)
- Postman setting environment variables
猜你喜欢
随机推荐
如何使用clipboard.js库实现复制剪切功能
JWT certification used in DRF
十二、排序
Sublime Text4 download the view in bower and set the shortcut key
golang select机制和超时问题怎么解决
DRF defines views and routes
PMP certificate preparation experience sharing
Locust performance test 4 (custom load Policy)
信息安全实验一:DES加密算法的实现
Unity uses mesh to realize real-time point cloud (I)
Mysql database lock learning notes
LeetCode每日一题(2316. Count Unreachable Pairs of Nodes in an Undirected Graph)
Install pyqt5 and Matplotlib module
Full link voltage test of the e-commerce campaign Guide
PMP experience learning and sharing process
Jenkins+ant+jmeter use
Jemter operation
Locust performance test 3 (high concurrency, parameter correlation, assembly point)
Postman interface debugging method
PMP Exam details after the release of the new exam outline