# AppContainer
Embed an exe application into the panel control. make it feels like you own this exe application.
http://www.cnblogs.com/bitzhuwei/archive/2012/05/24/SmileWei_EmbeddedApp.html
<p>这是最近在做的一个项目中提到的需求,把一个现有的窗体应用程序界面嵌入到自己开发的窗体中来,看起来就像自己开发的一样(实际上……跟自己开发的还是有一点点区别的,就是内嵌程序和宿主程序的窗口激活状态问题)。</p>
<p>在codeproject找到了一篇相关的文章(<a title="Hosting EXE Applications in a WinForm project" href="http://www.codeproject.com/Articles/9123/Hosting-EXE-Applications-in-a-WinForm-project" target="_blank">http://www.codeproject.com/Articles/9123/Hosting-EXE-Applications-in-a-WinForm-project</a>),虽然可用,但是很不方便,于是重新设计编写了一个类库,用一个控件完成内嵌其它应用程序的功能。</p>
<p>直接上图先:</p>
<p> <a href="http://images.cnblogs.com/cnblogs_com/bitzhuwei/201205/201205241831233469.png"><img style="display: inline; border-width: 0px;" title="嵌入QQ影音" src="http://images.cnblogs.com/cnblogs_com/bitzhuwei/201205/201205241831247863.png" alt="嵌入QQ影音" width="365" height="254" border="0" /></a> <a href="http://images.cnblogs.com/cnblogs_com/bitzhuwei/201205/201205241831258877.png"><img style="display: inline; border-width: 0px;" title="嵌入Windows Live Writer" src="http://images.cnblogs.com/cnblogs_com/bitzhuwei/201205/201205241831258287.png" alt="嵌入Windows Live Writer" width="327" height="254" border="0" /></a></p>
<p><a href="http://images.cnblogs.com/cnblogs_com/bitzhuwei/201205/20120524183127630.png"><img style="display: inline; border-width: 0px;" title="嵌入photoshop" src="http://images.cnblogs.com/cnblogs_com/bitzhuwei/201205/201205241831279169.png" alt="嵌入photoshop" width="389" height="254" border="0" /></a> <a href="http://images.cnblogs.com/cnblogs_com/bitzhuwei/201205/201205241831289103.png"><img style="display: inline; border-width: 0px;" title="嵌入Adobe Reader" src="http://images.cnblogs.com/cnblogs_com/bitzhuwei/201205/201205241831288513.png" alt="嵌入Adobe Reader" width="355" height="254" border="0" /></a></p>
<p>从打开Adobe Reader那张图片可以看出来所谓的“内嵌程序和宿主程序的窗口激活状态问题”。当内嵌程序窗口激活时,表面上将其包裹起来的宿主窗口却处于非激活的状态。想隐藏这一点的话,把窗口的FormBorderStyle属性设为None吧,然后自己在窗口上画关闭、最大化、最小化按钮好了。</p>
<p> </p>
<p>原作者的实现思路更能暴露本质,所以这里用原作者的代码段解释一下实现过程。</p>
<p>1、启动要嵌入的应用程序进程</p>
<div class="cnblogs_code">
<pre><span style="color: #008080;"> 1</span> Process p = <span style="color: #0000ff;">null</span><span style="color: #000000;">;
</span><span style="color: #008080;"> 2</span> <span style="color: #0000ff;">try</span>
<span style="color: #008080;"> 3</span> <span style="color: #000000;">{
</span><span style="color: #008080;"> 4</span> <span style="color: #008000;">//</span><span style="color: #008000;"> Start the process </span>
<span style="color: #008080;"> 5</span> p = System.Diagnostics.Process.Start(<span style="color: #0000ff;">this</span><span style="color: #000000;">.exeName);
</span><span style="color: #008080;"> 6</span>
<span style="color: #008080;"> 7</span> <span style="color: #008000;">//</span><span style="color: #008000;"> Wait for process to be created and enter idle condition </span>
<span style="color: #008080;"> 8</span> <span style="color: #000000;"> p.WaitForInputIdle();
</span><span style="color: #008080;"> 9</span>
<span style="color: #008080;">10</span> <span style="color: #008000;">//</span><span style="color: #008000;"> Get the main handle</span>
<span style="color: #008080;">11</span> appWin =<span style="color: #000000;"> p.MainWindowHandle;
</span><span style="color: #008080;">12</span> <span style="color: #000000;">}
</span><span style="color: #008080;">13</span> <span style="color: #0000ff;">catch</span><span style="color: #000000;"> (Exception ex)
</span><span style="color: #008080;">14</span> <span style="color: #000000;">{
</span><span style="color: #008080;">15</span> MessageBox.Show(<span style="color: #0000ff;">this</span>, ex.Message, <span style="color: #800000;">"</span><span style="color: #800000;">Error</span><span style="color: #800000;">"</span><span style="color: #000000;">);
</span><span style="color: #008080;">16</span> }</pre>
</div>
<p>2、调用Windows API将启动的应用程序窗口嵌入自定义的控件(作者用的是Panel控件)</p>
<div class="cnblogs_code">
<pre><span style="color: #008080;">1</span> <span style="color: #008000;">//</span><span style="color: #008000;"> Put it into this form</span>
<span style="color: #008080;">2</span> SetParent(appWin, <span style="color: #0000ff;">this</span><span style="color: #000000;">.Handle);//<span style="color: #008000;">this在这里是Panel控件<br /><br /></span>
</span><span style="color: #008080;">3</span>
<span style="color: #008080;">4</span> <span style="color: #008000;">//</span><span style="color: #008000;"> Remove border and whatnot</span>
<span style="color: #008080;">5</span> <span style="color: #000000;">SetWindowLong(appWin, GWL_STYLE, WS_VISIBLE);
</span><span style="color: #008080;">6</span>
<span style="color: #008080;">7</span> <span style="color: #008000;">//</span><span style="color: #008000;"> Move the window to overlay it on this window</span>
<span style="color: #008080;">8</span> MoveWindow(appWin, <span style="color: #800080;">0</span>, <span style="color: #800080;">0</span>, <span style="color: #0000ff;">this</span>.Width, <span style="color: #0000ff;">this</span>.Height, <span style="color: #0000ff;">true</span>);</pre>
</div>
<p>3、设置被嵌入的窗体大小随宿主窗体改变</p>
<div class="cnblogs_code">
<pre><span style="color: #008080;">1</span> <span style="color: #0000ff;">protected</span> <span style="color: #0000ff;">override</span> <span style="color: #0000ff;">void</span><span style="color: #000000;"> OnResize(EventArgs e)
</span><span style="color: #008080;">2</span> <span style="color: #000000;">{
</span><span style="color: #008080;">3</span> <span style="color: #0000ff;">if</span> (<span style="color: #0000ff;">this</span>.appWin !=<span style="color: #000000;"> IntPtr.Zero)
</span><span style="color: #008080;">4</span> <span style="color: #000000;"> {
</span><span style="color: #008080;">5</span> MoveWindow(appWin, <span style="color: #800080;">0</span>, <span style="color: #800080;">0</span>, <span style="color: #0000ff;">this</span>.Width, <span style="color: #0000ff;">this</span>.Height, <span style="color: #0000ff;">true</span><span style="color: #000000;">);
</span><span style="color: #008080;">6</span> <span style="color: #000000;"> }
</span><span style="color: #008080;">7</span> <span style="color: #0000ff;">base</span><span style="color: #000000;">.OnResize (e);
</span><span style="color: #008080;">8</span> }</pre>
</div>
<p>4、设置被嵌入的窗体应用程序在宿主程序关闭时也关闭</p>
<div class="cnblogs_code">
<pre><span style="color: #008080;"> 1</span> <span style="color: #0000ff;">protected</span> <span style="color: #0000ff;">override</span> <span style="color: #0000ff;">void</span><span style="color: #000000;"> OnHandleDestroyed(EventArgs e)
</span><span style="color: #008080;"> 2</span> <span style="color: #000000;">{
</span><span style="color: #008080;"> 3</span> <span style="color: #008000;">//</span><span style="color: #008000;"> Stop the application</span>
<span style="color: #008080;"> 4</span> <span style="color: #0000ff;">if</span> (appWin !=<span style="color: #000000;"> IntPtr.Zero)
</span><span style
评论6