通过 WIN32 API 实现嵌入程序窗体

写了一个不使用 COM, 而是通过 WIN32 API 实现的示例, 它把写字板程序嵌在了自己的一个面板中. 

这么做可能没有实际意义, 因为两个程序之前没有进行有价值的交互, 这里仅仅是为了演示这么做到, 以下是详细注释过的主要源代码.

我把它封装到一个类中:

 

[csharp] view plaincopy
  1. using System;  
  2. using System.Collections.Generic;  
  3. using System.Linq;  
  4. using System.Text;  
  5. using System.Diagnostics;  
  6. using System.Runtime.InteropServices;  
  7. using System.Windows.Forms;  
  8. namespace System.Windows.Forms  
  9. {  
  10.     class InsertWindow  
  11.     {  
  12.         /// <summary>  
  13.         /// 将程序嵌入窗体  
  14.         /// </summary>  
  15.         /// <param name="pW">容器</param>  
  16.         /// <param name="appname">程序名</param>  
  17.         public InsertWindow(Panel pW,string appname)  
  18.         {  
  19.             this.pan = pW;  
  20.             this.LoadEvent(appname);  
  21.             pane();  
  22.         }  
  23.   
  24.         ~InsertWindow()  
  25.         {  
  26.             if (m_innerProcess!=null)  
  27.             {  
  28.                 m_innerProcess.Dispose();  
  29.             }  
  30.         }  
  31.  
  32.         #region  函数和变量声明  
  33.         /* 
  34.         * 声明 Win32 API 
  35.         */  
  36.   
  37.         [DllImport("user32.dll")]  
  38.         static extern IntPtr SetParent(IntPtr hWndChild,  
  39.             IntPtr hWndNewParent  
  40.         );  
  41.   
  42.         [DllImport("user32.dll")]  
  43.         static extern Int32 GetWindowLong(IntPtr hWnd,  
  44.             Int32 nIndex  
  45.         );  
  46.   
  47.         [DllImport("user32.dll")]  
  48.         static extern Int32 SetWindowLong(IntPtr hWnd,  
  49.             Int32 nIndex,  
  50.             Int32 dwNewLong  
  51.         );  
  52.   
  53.         [DllImport("user32.dll")]  
  54.         static extern Int32 SetWindowPos(IntPtr hWnd,  
  55.             IntPtr hWndInsertAfter,  
  56.             Int32 X,  
  57.             Int32 Y,  
  58.             Int32 cx,  
  59.             Int32 cy,  
  60.             UInt32 uFlags  
  61.         );  
  62.   
  63.         /* 
  64.          * 定义 Win32 常数 
  65.          */  
  66.         const Int32 GWL_STYLE = -16;  
  67.         const Int32 WS_BORDER = (Int32)0x00800000L;  
  68.         const Int32 WS_THICKFRAME = (Int32)0x00040000L;  
  69.   
  70.         const Int32 SWP_NOMOVE = 0x0002;  
  71.         const Int32 SWP_NOSIZE = 0x0001;  
  72.         const Int32 SWP_NOZORDER = 0x0004;  
  73.         const Int32 SWP_FRAMECHANGED = 0x0020;  
  74.   
  75.         const Int32 SW_MAXIMIZE = 3;  
  76.         IntPtr HWND_NOTOPMOST = new IntPtr(-2);  
  77.   
  78.         // 目标应用程序的进程.  
  79.         Process m_innerProcess = null;  
  80.         #endregion  
  81.  
  82.         #region  容器  
  83.         private Panel pan = null;  
  84.         public Panel panel1  
  85.         {  
  86.             set { pan = value; }  
  87.             get { return pan; }  
  88.         }  
  89.         private void pane()  
  90.         {  
  91.             panel1.Anchor = AnchorStyles.Left | AnchorStyles.Top |  
  92.              AnchorStyles.Right | AnchorStyles.Bottom;  
  93.             panel1.Resize += new EventHandler(panel1_Resize);  
  94.         }  
  95.         private void panel1_Resize(object sender, EventArgs e)  
  96.         {  
  97.             // 设置目标应用程序的窗体样式.  
  98.   
  99.             IntPtr innerWnd = m_innerProcess.MainWindowHandle;  
  100.             SetWindowPos(innerWnd, IntPtr.Zero, 0, 0,  
  101.                 panel1.ClientSize.Width, panel1.ClientSize.Height,  
  102.                 SWP_NOZORDER);  
  103.         }  
  104.         #endregion  
  105.  
  106.         #region  相应事件  
  107.         private void LoadEvent(string appFile)  
  108.         {  
  109.   
  110.             // 启动目标应用程序.  
  111.             m_innerProcess = Process.Start(appFile);  
  112.             m_innerProcess.StartInfo.WindowStyle = ProcessWindowStyle.Hidden; //隐藏  
  113.             // 等待, 直到那个程序已经完全启动.   
  114.             m_innerProcess.WaitForInputIdle();  
  115.   
  116.             // 目标应用程序的主窗体.  
  117.             IntPtr innerWnd = m_innerProcess.MainWindowHandle;  
  118.   
  119.             // 设置目标应用程序的主窗体的父亲(为我们的窗体).  
  120.             SetParent(innerWnd, panel1.Handle);  
  121.   
  122.             // 除去窗体边框.  
  123.             Int32 wndStyle = GetWindowLong(innerWnd, GWL_STYLE);  
  124.             wndStyle &= ~WS_BORDER;  
  125.             wndStyle &= ~WS_THICKFRAME;  
  126.             SetWindowLong(innerWnd, GWL_STYLE, wndStyle);  
  127.             SetWindowPos(innerWnd, IntPtr.Zero, 0, 0, 0, 0,  
  128.                 SWP_NOMOVE | SWP_NOSIZE | SWP_NOZORDER | SWP_FRAMECHANGED);  
  129.   
  130.             // 在Resize事件中更新目标应用程序的窗体尺寸.  
  131.             panel1_Resize(panel1, null);  
  132.         }  
  133. #endregion  
  134.     }  
  135.   
  136.   
  137. }  

 然后在 窗口的 load事件中 加入

详细代码 如下: 

[csharp] view plaincopy
  1. using System;  
  2. using System.Collections.Generic;  
  3. using System.ComponentModel;  
  4. using System.Data;  
  5. using System.Drawing;  
  6. using System.Linq;  
  7. using System.Text;  
  8. using System.Windows.Forms;  
  9. using System.Runtime;  
  10. using System.Runtime.InteropServices;  
  11. using System.Diagnostics;  
  12.   
  13. namespace 将程序窗口嵌入到任务栏中  
  14. {  
  15.     public partial class Form1 : Form  
  16.     {  
  17.         private System.Windows.Forms.Panel panel1;  
  18.         public Form1()  
  19.         {  
  20.             InitializeComponent();  
  21.             this.panel1 = new System.Windows.Forms.Panel();  
  22.             this.SuspendLayout();  
  23.             //   
  24.             // panel1  
  25.             //   
  26.             this.panel1.Dock = System.Windows.Forms.DockStyle.Fill;  
  27.             this.panel1.Location = new System.Drawing.Point(0, 0);  
  28.             this.panel1.Name = "panel1";  
  29.             this.panel1.Size = new System.Drawing.Size(292, 273);  
  30.             this.panel1.TabIndex = 0;  
  31.             this.Controls.Add(this.panel1);  
  32.   
  33.             Load += new EventHandler(Form1_Load);  
  34.         }  
  35.   
  36.         private void Form1_Load(object sender, EventArgs e)  
  37.         {  
  38.             //string sPath = Environment.GetEnvironmentVariable("windir");//获取系统变量 windir(windows)    
  39.             const string appFile =  
  40.                 "C:\\Program Files\\Windows NT\\Accessories\\wordpad.exe";  
  41.             InsertWindow insertwin = new InsertWindow(panel1, appFile);  
  42.   
  43.         }  
  44.   
  45.           
  46.     }  
  47. }  
posted @ 2014-09-25 16:52  r163  阅读(478)  评论(1编辑  收藏  举报