你的位置:首页 > ASP.net教程

[ASP.net教程]在winform上内嵌入其它的程序


这段代码很有意义,用于把一个程序的界面嵌入到我们自己程序的某个指定窗体上.

比如在某个项目里,我需要把基恩士的激光扫描轮廓显示给客户看,但是激光的DLL中并没有这种功能提供. 于是我想先启动激光的官方程序用以显示轮廓, 然后再把这种显示界面嵌入到我自己程序的界面上指定的位置上.

在笔者构想的PLC仿真器由梯形图编辑器, 3D仿真组态环境两部分组成, 这两部分就可以考虑开发成独立的软件,然后嵌入到我需要的另外的一款PLC仿真教学软件中去.

源代码如下:

 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.InteropServices; 10 using System.Diagnostics; 11 using System.Threading; 12  13 namespace WindowsFormsApplication1 14 { 15   public partial class Form1 : Form 16   { 17     Process p; 18  19     public Form1() 20     { 21       InitializeComponent(); 22     } 23  24     #region API 25     [DllImport("user32.dll")] 26     private static extern int SetParent(IntPtr hWndChild, IntPtr hWndParent); 27  28     [DllImport("user32.dll")] 29     private static extern bool ShowWindowAsync(IntPtr hWnd, int nCmdShow); 30  31     [DllImport("user32.dll", SetLastError = true)] 32     private static extern bool PostMessage(IntPtr hWnd, uint Msg, int wParam, int lParam); 33  34     [DllImport("user32.dll", EntryPoint = "SetWindowPos")] 35     private static extern bool SetWindowPos(IntPtr hWnd, int hWndInsertAfter, 36           int X, int Y, int cx, int cy, uint uFlags); 37  38     [DllImport("user32.dll")] 39     private static extern int SendMessage(IntPtr hWnd, uint Msg, int wParam, int lParam); 40  41     [DllImport("user32.dll", SetLastError = true, CharSet = CharSet.Auto)] 42     private static extern uint SetWindowLong(IntPtr hwnd, int nIndex, uint newLong); 43  44     [DllImport("user32.dll", SetLastError = true, CharSet = CharSet.Auto)] 45     private static extern uint GetWindowLong(IntPtr hwnd, int nIndex); 46  47     [DllImport("user32.dll", CharSet = CharSet.Auto)] 48     private static extern bool ShowWindow(IntPtr hWnd, short State); 49  50     private const int HWND_TOP = 0x0; 51     private const int WM_COMMAND = 0x0112; 52     private const int WM_QT_PAINT = 0xC2DC; 53     private const int WM_PAINT = 0x000F; 54     private const int WM_SIZE = 0x0005; 55     private const int SWP_FRAMECHANGED = 0x0020; 56     public enum ShowWindowStyles : short 57     { 58       SW_HIDE = 0, 59       SW_SHOWNORMAL = 1, 60       SW_NORMAL = 1, 61       SW_SHOWMINIMIZED = 2, 62       SW_SHOWMAXIMIZED = 3, 63       SW_MAXIMIZE = 3, 64       SW_SHOWNOACTIVATE = 4, 65       SW_SHOW = 5, 66       SW_MINIMIZE = 6, 67       SW_SHOWMINNOACTIVE = 7, 68       SW_SHOWNA = 8, 69       SW_RESTORE = 9, 70       SW_SHOWDEFAULT = 10, 71       SW_FORCEMINIMIZE = 11, 72       SW_MAX = 11 73     } 74     #endregion 75  76     private void Form1_Load(object sender, EventArgs e) 77     { 78       p = new Process(); 79       //需要启动的程序 80       p.StartInfo.FileName = @"calc.exe"; 81       //为了美观,启动的时候最小化程序 82       p.StartInfo.WindowStyle = ProcessWindowStyle.Minimized; 83       //启动 84       p.Start(); 85  86       //这里必须等待,否则启动程序的句柄还没有创建,不能控制程序 87       Thread.Sleep(10000); 88       //最大化启动的程序 89       ShowWindow(p.MainWindowHandle, (short)ShowWindowStyles.SW_MAXIMIZE); 90       //设置被绑架程序的父窗口 91       SetParent(p.MainWindowHandle, this.Handle); 92       //改变尺寸 93       ResizeControl(); 94     } 95  96     //控制嵌入程序的位置和尺寸 97     private void ResizeControl() 98     { 99       SendMessage(p.MainWindowHandle, WM_COMMAND, WM_PAINT, 0);100       PostMessage(p.MainWindowHandle, WM_QT_PAINT, 0, 0);101 102       SetWindowPos(103       p.MainWindowHandle,104        HWND_TOP,105        0 - 10,//设置偏移量,把原来窗口的菜单遮住106        0 - 32,107        (int)this.Width + 32,108        (int)this.Height + 32,109        SWP_FRAMECHANGED);110 111       SendMessage(p.MainWindowHandle, WM_COMMAND, WM_SIZE, 0);112     }113 114     private void Form1_SizeChanged(object sender, EventArgs e)115     {116       ResizeControl();117     }118 119     private void Form1_FormClosing(object sender, FormClosingEventArgs e)120     {121       p.Kill();122       p.Dispose();123     }124   }125 }

 

核心功能利用了windows API中的SetParent()

程序运行后, 先启动calc.exe(windows计算器), 然后等待10秒后再显示本程序自己的窗体, 这时你会发现这个窗体已经把calc.exe的界面包含进来的.

这样你就可以清楚的看到嵌入的效果是怎么样的.

 

本文源代码