[c#] 通过 WIN32 API 实现嵌入程序窗体


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



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

我把它封装到一个类中:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Diagnostics;
using System.Runtime.InteropServices;
using System.Windows.Forms;
namespace System.Windows.Forms
{
    class InsertWindow
    {
        /// <summary>
        /// 将程序嵌入窗体
        /// </summary>
        /// <param name="pW">容器</param>
        /// <param name="appname">程序名</param>
        public InsertWindow(Panel pW,string appname)
        {
            this.pan = pW;
            this.LoadEvent(appname);
            pane();
        }

        ~InsertWindow()
        {
            if (m_innerProcess!=null)
            {
                m_innerProcess.Dispose();
            }
        }

        #region  函数和变量声明
        /*
        * 声明 Win32 API
        */

        [DllImport("user32.dll")]
        static extern IntPtr SetParent(IntPtr hWndChild,
            IntPtr hWndNewParent
        );

        [DllImport("user32.dll")]
        static extern Int32 GetWindowLong(IntPtr hWnd,
            Int32 nIndex
        );

        [DllImport("user32.dll")]
        static extern Int32 SetWindowLong(IntPtr hWnd,
            Int32 nIndex,
            Int32 dwNewLong
        );

        [DllImport("user32.dll")]
        static extern Int32 SetWindowPos(IntPtr hWnd,
            IntPtr hWndInsertAfter,
            Int32 X,
            Int32 Y,
            Int32 cx,
            Int32 cy,
            UInt32 uFlags
        );

        /*
         * 定义 Win32 常数
         */
        const Int32 GWL_STYLE = -16;
        const Int32 WS_BORDER = (Int32)0x00800000L;
        const Int32 WS_THICKFRAME = (Int32)0x00040000L;

        const Int32 SWP_NOMOVE = 0x0002;
        const Int32 SWP_NOSIZE = 0x0001;
        const Int32 SWP_NOZORDER = 0x0004;
        const Int32 SWP_FRAMECHANGED = 0x0020;

        const Int32 SW_MAXIMIZE = 3;
        IntPtr HWND_NOTOPMOST = new IntPtr(-2);

        // 目标应用程序的进程.
        Process m_innerProcess = null;
        #endregion

        #region  容器
        private Panel pan = null;
        public Panel panel1
        {
            set { pan = value; }
            get { return pan; }
        }
        private void pane()
        {
            panel1.Anchor = AnchorStyles.Left | AnchorStyles.Top |
             AnchorStyles.Right | AnchorStyles.Bottom;
            panel1.Resize += new EventHandler(panel1_Resize);
        }
        private void panel1_Resize(object sender, EventArgs e)
        {
            // 设置目标应用程序的窗体样式.

            IntPtr innerWnd = m_innerProcess.MainWindowHandle;
            SetWindowPos(innerWnd, IntPtr.Zero, 0, 0,
                panel1.ClientSize.Width, panel1.ClientSize.Height,
                SWP_NOZORDER);
        }
        #endregion

        #region  相应事件
        private void LoadEvent(string appFile)
        {

            // 启动目标应用程序.
            m_innerProcess = Process.Start(appFile);
            m_innerProcess.StartInfo.WindowStyle = ProcessWindowStyle.Hidden; //隐藏
            // 等待, 直到那个程序已经完全启动. 
            m_innerProcess.WaitForInputIdle();

            // 目标应用程序的主窗体.
            IntPtr innerWnd = m_innerProcess.MainWindowHandle;

            // 设置目标应用程序的主窗体的父亲(为我们的窗体).
            SetParent(innerWnd, panel1.Handle);

            // 除去窗体边框.
            Int32 wndStyle = GetWindowLong(innerWnd, GWL_STYLE);
            wndStyle &= ~WS_BORDER;
            wndStyle &= ~WS_THICKFRAME;
            SetWindowLong(innerWnd, GWL_STYLE, wndStyle);
            SetWindowPos(innerWnd, IntPtr.Zero, 0, 0, 0, 0,
                SWP_NOMOVE | SWP_NOSIZE | SWP_NOZORDER | SWP_FRAMECHANGED);

            // 在Resize事件中更新目标应用程序的窗体尺寸.
            panel1_Resize(panel1, null);
        }
#endregion
    }


}



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

详细代码 如下:

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Runtime;
using System.Runtime.InteropServices;
using System.Diagnostics;

namespace 将程序窗口嵌入到任务栏中
{
    public partial class Form1 : Form
    {
        private System.Windows.Forms.Panel panel1;
        public Form1()
        {
            InitializeComponent();
            this.panel1 = new System.Windows.Forms.Panel();
            this.SuspendLayout();
            // 
            // panel1
            // 
            this.panel1.Dock = System.Windows.Forms.DockStyle.Fill;
            this.panel1.Location = new System.Drawing.Point(0, 0);
            this.panel1.Name = "panel1";
            this.panel1.Size = new System.Drawing.Size(292, 273);
            this.panel1.TabIndex = 0;
            this.Controls.Add(this.panel1);

            Load += new EventHandler(Form1_Load);
        }

        private void Form1_Load(object sender, EventArgs e)
        {
            //string sPath = Environment.GetEnvironmentVariable("windir");//获取系统变量 windir(windows)  
            const string appFile =
                "C:\\Program Files\\Windows NT\\Accessories\\wordpad.exe";
            InsertWindow insertwin = new InsertWindow(panel1, appFile);

        }

        
    }
}


  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值