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

namespace US.Browser.IE
{
    /// <summary>
    /// 嵌入引用程序区域
    /// </summary>
    [ToolboxBitmap(typeof(UProcess), "UProcess.bmp")] //设置嵌入程序图标
    public class UProcess : Panel
    {
        private static List<UProcess> uap = new List<UProcess>(); //所有的应用窗体管理
        private IContainer comp = null; //容器
        private Process upe = null; //启动的应用程序
        private string name; //程序路径

        /// <summary>
        /// 应用程序路径
        /// </summary>
        public string filename
        {
            get { return name; }
            set
            {
                if (!value.ToLower().EndsWith(".exe")) { throw new Exception("只能启动exe一用程序"); }
                else if (!File.Exists(value)) { throw new Exception("路径不存在"); }
                name = value;
            }
        }

        /// <summary>
        /// 启动程序
        /// </summary>
        /// <returns></returns>
        public static UProcess init(string name)
        {
            UProcess up = new UProcess();
            up.filename = name; return up;
        }

        /// <summary>
        /// 初始化
        /// </summary>
        public UProcess()
        {
            comp = new Container(); //初始化容器
        }

        /// <summary>
        /// 启动程序
        /// </summary>
        public void Start()
        {
            if (upe == null && name != null)
            {
                ProcessStartInfo _ps = new ProcessStartInfo(name); //启动应用程序参数
                upe = Process.Start(_ps);//启动引用程序
                upe.WaitForInputIdle(); Application.Idle += new EventHandler(Application_Idle);
            }
        }

        /// <summary>
        /// 应用程序加载
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        void Application_Idle(object sender, EventArgs e)
        {
            if (this.upe == null || this.upe.HasExited)
            {
                Application.Idle -= Application_Idle; this.Dispose(); return;
            }
            else if (this.upe.MainWindowHandle == IntPtr.Zero) { return; }
            else //添加到制定容器中
            {
                Application.Idle -= Application_Idle;
                Add(this.upe, this); uap.Add(this);
                this.upe.EnableRaisingEvents = true;
                this.upe.Exited += new EventHandler(upe_Exited);
            }
        }

        /// <summary>
        /// 结束进程触发
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        void upe_Exited(object sender, EventArgs e)
        {
            this.comp.Dispose(); CloseP();
        }

        /// <summary>
        /// 添加到制定容器中
        /// </summary>
        /// <param name="app"></param>
        /// <param name="con"></param>
        private bool Add(Process app, Control con)
        {
            try
            {
                int uem = BLL.WindowHWND.SetParent(app.MainWindowHandle, con.Handle);//嵌入到父层
                BLL.WindowHWND.SetWindowLong(new HandleRef(this, app.MainWindowHandle), BLL.WindowHWND.GWL_STYLE, BLL.WindowHWND.WS_VISIBLE);//显示
                BLL.WindowHWND.MoveWindow(app.MainWindowHandle, 0, 0, con.Width, con.Height, true); //移动到指定的位置
                return (uem != 0);
            }
            catch (Exception) { return false; }
        }

        /// <summary>
        /// 结束程序
        /// </summary>
        public void CloseP()
        {
            if (this.upe != null)
            {
                try
                {
                    if (!this.upe.HasExited) { this.upe.Kill(); this.upe = null; }
                    uap.Remove(this); this.Dispose();
                }
                catch (Exception) { }
            }
        }

        /// <summary>
        /// 应用程序关闭
        /// </summary>
        /// <param name="e"></param>
        protected override void OnHandleDestroyed(EventArgs e)
        {
            CloseP(); base.OnHandleDestroyed(e);
        }

        /// <summary>
        /// 大小变化使用
        /// </summary>
        /// <param name="eventargs"></param>
        protected override void OnResize(EventArgs eventargs)
        {
            if (this.upe != null)
            {
                BLL.WindowHWND.MoveWindow(this.upe.MainWindowHandle, 0, 0, this.Width, this.Height, true);
            }

            base.OnResize(eventargs);
        }

        /// <summary>
        /// 重新绘制页面
        /// </summary>
        /// <param name="e"></param>
        protected override void OnSizeChanged(EventArgs e)
        {
            this.Invalidate();
            base.OnSizeChanged(e);
        }
    }
}
