Browse Source

继续做嵌入控件

yuzhengyang 8 years ago
parent
commit
c1897bff46
3 changed files with 180 additions and 190 deletions
  1. 161 189
      Fork.Net/Y.Skin/YoPanel/EmbedPanel.cs
  2. 14 1
      Fork.Net/Y.Test/Form1.Designer.cs
  3. 5 0
      Fork.Net/Y.Test/Form1.cs

+ 161 - 189
Fork.Net/Y.Skin/YoPanel/EmbedPanel.cs

@@ -1,11 +1,5 @@
 using System;
 using System;
-using System.Collections.Generic;
 using System.ComponentModel;
 using System.ComponentModel;
-using System.Drawing;
-using System.Data;
-using System.Linq;
-using System.Text;
-using System.Threading.Tasks;
 using System.Windows.Forms;
 using System.Windows.Forms;
 using System.Diagnostics;
 using System.Diagnostics;
 using System.IO;
 using System.IO;
@@ -23,7 +17,6 @@ namespace Y.Skin.YoPanel
             appIdleAction = new Action<object, EventArgs>(Application_Idle);
             appIdleAction = new Action<object, EventArgs>(Application_Idle);
             appIdleEvent = new EventHandler(appIdleAction);
             appIdleEvent = new EventHandler(appIdleAction);
         }
         }
-
         public EmbedPanel(IContainer container)
         public EmbedPanel(IContainer container)
         {
         {
             container.Add(this);
             container.Add(this);
@@ -31,46 +24,7 @@ namespace Y.Skin.YoPanel
             appIdleAction = new Action<object, EventArgs>(Application_Idle);
             appIdleAction = new Action<object, EventArgs>(Application_Idle);
             appIdleEvent = new EventHandler(appIdleAction);
             appIdleEvent = new EventHandler(appIdleAction);
         }
         }
-        /// <summary>
-        /// 将属性<code>AppFilename</code>指向的应用程序打开并嵌入此容器
-        /// </summary>
-        public void Start()
-        {
-            if (m_AppProcess != null)
-            {
-                Stop();
-            }
-            try
-            {
-                ProcessStartInfo info = new ProcessStartInfo(this.m_AppFilename);
-                info.UseShellExecute = true;
-                info.WindowStyle = ProcessWindowStyle.Minimized;
-                //info.WindowStyle = ProcessWindowStyle.Hidden;
-                m_AppProcess = Process.Start(info);
-                // Wait for process to be created and enter idle condition
-                m_AppProcess.WaitForInputIdle();
-                //todo:下面这两句会引发 NullReferenceException 异常,不知道怎么回事                
-                //m_AppProcess.Exited += new EventHandler(m_AppProcess_Exited);
-                //m_AppProcess.EnableRaisingEvents = true;
-                Application.Idle += appIdleEvent;
-            }
-            catch (Exception ex)
-            {
-                MessageBox.Show(this, string.Format("{1}{0}{2}{0}{3}"
-                    , Environment.NewLine
-                    , "*" + ex.ToString()
-                    , "*StackTrace:" + ex.StackTrace
-                    , "*Source:" + ex.Source
-                    ), "内嵌程序加载失败");
-                if (m_AppProcess != null)
-                {
-                    if (!m_AppProcess.HasExited)
-                        m_AppProcess.Kill();
-                    m_AppProcess = null;
-                }
-            }
 
 
-        }
         /// <summary>
         /// <summary>
         /// 确保应用程序嵌入此容器
         /// 确保应用程序嵌入此容器
         /// </summary>
         /// </summary>
@@ -78,21 +32,15 @@ namespace Y.Skin.YoPanel
         /// <param name="e"></param>
         /// <param name="e"></param>
         void Application_Idle(object sender, EventArgs e)
         void Application_Idle(object sender, EventArgs e)
         {
         {
-            if (this.m_AppProcess == null || this.m_AppProcess.HasExited)
+            if (m_AppProcess == null || m_AppProcess.HasExited)
             {
             {
-                this.m_AppProcess = null;
+                m_AppProcess = null;
                 Application.Idle -= appIdleEvent;
                 Application.Idle -= appIdleEvent;
                 return;
                 return;
             }
             }
             if (m_AppProcess.MainWindowHandle == IntPtr.Zero) return;
             if (m_AppProcess.MainWindowHandle == IntPtr.Zero) return;
             Application.Idle -= appIdleEvent;
             Application.Idle -= appIdleEvent;
             EmbedProcess(m_AppProcess, this);
             EmbedProcess(m_AppProcess, this);
-            //ShowWindow(m_AppProcess.MainWindowHandle, SW_SHOWNORMAL);
-            //var parent = GetParent(m_AppProcess.MainWindowHandle);//你妹,不管用,全是0
-            //if (parent == this.Handle)
-            //{
-            //    Application.Idle -= appIdleEvent;
-            //}
         }
         }
         /// <summary>
         /// <summary>
         /// 应用程序结束运行时要清除这里的标识
         /// 应用程序结束运行时要清除这里的标识
@@ -103,50 +51,10 @@ namespace Y.Skin.YoPanel
         {
         {
             m_AppProcess = null;
             m_AppProcess = null;
         }
         }
-        //public void Start(string appFilename)
-        //{
-        //    this.AppFilename = AppFilename;
-        //    Start();
-        //}
-        /// <summary>
-        /// 将属性<code>AppFilename</code>指向的应用程序关闭
-        /// </summary>
-        public void Stop()
-        {
-            if (m_AppProcess != null)// && m_AppProcess.MainWindowHandle != IntPtr.Zero)
-            {
-                try
-                {
-                    if (!m_AppProcess.HasExited)
-                        m_AppProcess.Kill();
-                }
-                catch (Exception)
-                {
-                }
-                m_AppProcess = null;
-            }
-        }
 
 
-        protected override void OnHandleDestroyed(EventArgs e)
-        {
-            Stop();
-            base.OnHandleDestroyed(e);
-        }
 
 
-        protected override void OnResize(EventArgs eventargs)
-        {
-            if (m_AppProcess != null)
-            {
-                MoveWindow(m_AppProcess.MainWindowHandle, 0, 0, this.Width, this.Height, true);
-            }
-            base.OnResize(eventargs);
-        }
 
 
-        protected override void OnSizeChanged(EventArgs e)
-        {
-            this.Invalidate();
-            base.OnSizeChanged(e);
-        }
+
 
 
         #region 属性
         #region 属性
         /// <summary>
         /// <summary>
@@ -200,75 +108,135 @@ namespace Y.Skin.YoPanel
         /// <summary>
         /// <summary>
         /// 标识内嵌程序是否已经启动
         /// 标识内嵌程序是否已经启动
         /// </summary>
         /// </summary>
-        public bool IsStarted { get { return (this.m_AppProcess != null); } }
-
+        public bool IsStarted { get { return (m_AppProcess != null); } }
         #endregion 属性
         #endregion 属性
 
 
-        #region Win32 API
-        [DllImport("user32.dll", EntryPoint = "GetWindowThreadProcessId", SetLastError = true,
-             CharSet = CharSet.Unicode, ExactSpelling = true,
-             CallingConvention = CallingConvention.StdCall)]
-        private static extern long GetWindowThreadProcessId(long hWnd, long lpdwProcessId);
-
-        [DllImport("user32.dll", SetLastError = true)]
-        private static extern IntPtr FindWindow(string lpClassName, string lpWindowName);
-
-        [DllImport("user32.dll", SetLastError = true)]
-        public static extern long SetParent(IntPtr hWndChild, IntPtr hWndNewParent);
-
-        [DllImport("user32.dll", EntryPoint = "GetWindowLongA", SetLastError = true)]
-        private static extern long GetWindowLong(IntPtr hwnd, int nIndex);
 
 
-        public static IntPtr SetWindowLong(HandleRef hWnd, int nIndex, int dwNewLong)
+        /// <summary>
+        /// 启动嵌入程序并嵌入到控件
+        /// </summary>
+        /// <param name="appFilename"></param>
+        public void Start(string appFilename)
         {
         {
-            if (IntPtr.Size == 4)
+            AppFilename = appFilename;
+            Start();
+        }
+        public void Start()
+        {
+            //停止正在运行的进程
+            if (m_AppProcess != null) Stop();
+            try
             {
             {
-                return SetWindowLongPtr32(hWnd, nIndex, dwNewLong);
+                ProcessStartInfo info = new ProcessStartInfo(m_AppFilename);
+                info.UseShellExecute = true;
+                info.WindowStyle = ProcessWindowStyle.Minimized;
+                //info.WindowStyle = ProcessWindowStyle.Hidden;
+                m_AppProcess = Process.Start(info);
+                //等待创建进程
+                m_AppProcess.WaitForInputIdle();
+                //todo:下面这两句会引发 NullReferenceException 异常,不知道怎么回事                
+                //m_AppProcess.Exited += new EventHandler(m_AppProcess_Exited);
+                //m_AppProcess.EnableRaisingEvents = true;
+                Application.Idle += appIdleEvent;
+                //EmbedProcess(m_AppProcess, this);
+            }
+            catch (Exception ex)
+            {
+                //嵌入失败杀死进程
+                if (m_AppProcess != null)
+                {
+                    if (!m_AppProcess.HasExited)
+                        m_AppProcess.Kill();
+                    m_AppProcess = null;
+                }
+            }
+        }
+        /// <summary>
+        /// 重新嵌入
+        /// </summary>
+        public void ReEmbed()
+        {
+            EmbedProcess(m_AppProcess, this);
+        }
+        /// <summary>
+        /// 退出嵌入的程序
+        /// </summary>
+        public void Stop()
+        {
+            if (m_AppProcess != null)// && m_AppProcess.MainWindowHandle != IntPtr.Zero)
+            {
+                try
+                {
+                    if (!m_AppProcess.HasExited)
+                        m_AppProcess.Kill();
+                }
+                catch (Exception) { }
+                m_AppProcess = null;
             }
             }
-            return SetWindowLongPtr64(hWnd, nIndex, dwNewLong);
         }
         }
-        [DllImport("user32.dll", EntryPoint = "SetWindowLong", CharSet = CharSet.Auto)]
-        public static extern IntPtr SetWindowLongPtr32(HandleRef hWnd, int nIndex, int dwNewLong);
-        [DllImport("user32.dll", EntryPoint = "SetWindowLongPtr", CharSet = CharSet.Auto)]
-        public static extern IntPtr SetWindowLongPtr64(HandleRef hWnd, int nIndex, int dwNewLong);
-
-        [DllImport("user32.dll", SetLastError = true)]
-        private static extern long SetWindowPos(IntPtr hwnd, long hWndInsertAfter, long x, long y, long cx, long cy, long wFlags);
-
-        [DllImport("user32.dll", SetLastError = true)]
-        private static extern bool MoveWindow(IntPtr hwnd, int x, int y, int cx, int cy, bool repaint);
-
-        [DllImport("user32.dll", EntryPoint = "PostMessageA", SetLastError = true)]
-        private static extern bool PostMessage(IntPtr hwnd, uint Msg, uint wParam, uint lParam);
-
-        [DllImport("user32.dll", SetLastError = true)]
-        private static extern IntPtr GetParent(IntPtr hwnd);
-        ///// <summary>
-        ///// ShellExecute(IntPtr.Zero, "Open", "C:/Program Files/TTPlayer/TTPlayer.exe", "", "", 1);
-        ///// </summary>
-        ///// <param name="hwnd"></param>
-        ///// <param name="lpOperation"></param>
-        ///// <param name="lpFile"></param>
-        ///// <param name="lpParameters"></param>
-        ///// <param name="lpDirectory"></param>
-        ///// <param name="nShowCmd"></param>
-        ///// <returns></returns>
-        //[DllImport("shell32.dll", EntryPoint = "ShellExecute")]
-        //public static extern int ShellExecute(
-        //IntPtr hwnd,
-        //string lpOperation,
-        //string lpFile,
-        //string lpParameters,
-        //string lpDirectory,
-        //int nShowCmd
-        //);
-        //[DllImport("kernel32.dll")]
-        //public static extern int OpenProcess(int dwDesiredAccess, bool bInheritHandle, int dwProcessId); 
-        [DllImport("user32.dll", EntryPoint = "ShowWindow", SetLastError = true)]
-        static extern bool ShowWindow(IntPtr hWnd, int nCmdShow);
-
 
 
+        /// <summary>
+        /// 将程序嵌入控件
+        /// </summary>
+        /// <param name="app">嵌入程序</param>
+        /// <param name="control">指定控件</param>
+        private void EmbedProcess(Process app, Control control)
+        {
+            //验证程序和控件非空
+            if (app == null || app.MainWindowHandle == IntPtr.Zero || control == null) return;
+            try
+            {
+                //核心代码:嵌入程序
+                SetParent(app.MainWindowHandle, control.Handle);
+            }
+            catch (Exception) { }
+            try
+            {
+                //移除嵌入的窗口的窗口标题栏
+                SetWindowLong(new HandleRef(this, app.MainWindowHandle), GWL_STYLE, WS_VISIBLE);
+            }
+            catch (Exception) { }
+            try
+            {
+                //将嵌入的窗口欧放置到合适位置,填满宽高
+                MoveWindow(app.MainWindowHandle, 0, 0, control.Width, control.Height, true);
+            }
+            catch (Exception) { }
+        }
 
 
+        #region 重写部分方法
+        /// <summary>
+        /// 窗体句柄销毁
+        /// </summary>
+        /// <param name="e"></param>
+        protected override void OnHandleDestroyed(EventArgs e)
+        {
+            Stop();//将应用关闭
+            base.OnHandleDestroyed(e);
+        }
+        /// <summary>
+        /// 窗体大小修改
+        /// </summary>
+        /// <param name="eventargs"></param>
+        protected override void OnResize(EventArgs eventargs)
+        {
+            if (m_AppProcess != null)
+            {
+                MoveWindow(m_AppProcess.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);
+        }
+        #endregion
+        #region Win32 API 常量
         private const int SWP_NOOWNERZORDER = 0x200;
         private const int SWP_NOOWNERZORDER = 0x200;
         private const int SWP_NOREDRAW = 0x8;
         private const int SWP_NOREDRAW = 0x8;
         private const int SWP_NOZORDER = 0x4;
         private const int SWP_NOZORDER = 0x4;
@@ -298,46 +266,50 @@ namespace Y.Skin.YoPanel
         private const int SW_RESTORE = 9; //{同 SW_SHOWNORMAL}
         private const int SW_RESTORE = 9; //{同 SW_SHOWNORMAL}
         private const int SW_SHOWDEFAULT = 10; //{同 SW_SHOWNORMAL}
         private const int SW_SHOWDEFAULT = 10; //{同 SW_SHOWNORMAL}
         private const int SW_MAX = 10; //{同 SW_SHOWNORMAL}
         private const int SW_MAX = 10; //{同 SW_SHOWNORMAL}
+        #endregion
+        #region Win32 API 方法声明
+        [DllImport("user32.dll", EntryPoint = "GetWindowThreadProcessId", SetLastError = true,
+            CharSet = CharSet.Unicode, ExactSpelling = true, CallingConvention = CallingConvention.StdCall)]
+        private static extern long GetWindowThreadProcessId(long hWnd, long lpdwProcessId);
 
 
-        //const int PROCESS_ALL_ACCESS = 0x1F0FFF;
-        //const int PROCESS_VM_READ = 0x0010;
-        //const int PROCESS_VM_WRITE = 0x0020;     
-        #endregion Win32 API
+        [DllImport("user32.dll", SetLastError = true)]
+        private static extern IntPtr FindWindow(string lpClassName, string lpWindowName);
 
 
+        [DllImport("user32.dll", SetLastError = true)]
+        public static extern long SetParent(IntPtr hWndChild, IntPtr hWndNewParent);
 
 
-        public void EmbedAgain()
-        {
-            EmbedProcess(m_AppProcess, this);
-            MessageBox.Show("完毕");
-        }
-        /// <summary>
-        /// 将指定的程序嵌入指定的控件
-        /// </summary>
-        private void EmbedProcess(Process app, Control control)
+        [DllImport("user32.dll", EntryPoint = "GetWindowLongA", SetLastError = true)]
+        private static extern long GetWindowLong(IntPtr hwnd, int nIndex);
+
+        public static IntPtr SetWindowLong(HandleRef hWnd, int nIndex, int dwNewLong)
         {
         {
-            // Get the main handle
-            if (app == null || app.MainWindowHandle == IntPtr.Zero || control == null) return;
-            try
-            {
-                // Put it into this form
-                SetParent(app.MainWindowHandle, control.Handle);
-            }
-            catch (Exception)
-            { }
-            try
-            {
-                // Remove border and whatnot               
-                SetWindowLong(new HandleRef(this, app.MainWindowHandle), GWL_STYLE, WS_VISIBLE);
-            }
-            catch (Exception)
-            { }
-            try
+            if (IntPtr.Size == 4)
             {
             {
-                // Move the window to overlay it on this window
-                MoveWindow(app.MainWindowHandle, 0, 0, control.Width, control.Height, true);
+                return SetWindowLongPtr32(hWnd, nIndex, dwNewLong);
             }
             }
-            catch (Exception)
-            { }
+            return SetWindowLongPtr64(hWnd, nIndex, dwNewLong);
         }
         }
+
+        [DllImport("user32.dll", EntryPoint = "SetWindowLong", CharSet = CharSet.Auto)]
+        public static extern IntPtr SetWindowLongPtr32(HandleRef hWnd, int nIndex, int dwNewLong);
+
+        [DllImport("user32.dll", EntryPoint = "SetWindowLongPtr", CharSet = CharSet.Auto)]
+        public static extern IntPtr SetWindowLongPtr64(HandleRef hWnd, int nIndex, int dwNewLong);
+
+        [DllImport("user32.dll", SetLastError = true)]
+        private static extern long SetWindowPos(IntPtr hwnd, long hWndInsertAfter, long x, long y, long cx, long cy, long wFlags);
+
+        [DllImport("user32.dll", SetLastError = true)]
+        private static extern bool MoveWindow(IntPtr hwnd, int x, int y, int cx, int cy, bool repaint);
+
+        [DllImport("user32.dll", EntryPoint = "PostMessageA", SetLastError = true)]
+        private static extern bool PostMessage(IntPtr hwnd, uint Msg, uint wParam, uint lParam);
+
+        [DllImport("user32.dll", SetLastError = true)]
+        private static extern IntPtr GetParent(IntPtr hwnd);
+
+        [DllImport("user32.dll", EntryPoint = "ShowWindow", SetLastError = true)]
+        static extern bool ShowWindow(IntPtr hWnd, int nCmdShow);
+        #endregion Win32 API
     }
     }
 }
 }

+ 14 - 1
Fork.Net/Y.Test/Form1.Designer.cs

@@ -29,6 +29,7 @@
         private void InitializeComponent()
         private void InitializeComponent()
         {
         {
             this.components = new System.ComponentModel.Container();
             this.components = new System.ComponentModel.Container();
+            this.button2 = new System.Windows.Forms.Button();
             this.embedPanel1 = new Y.Skin.YoPanel.EmbedPanel(this.components);
             this.embedPanel1 = new Y.Skin.YoPanel.EmbedPanel(this.components);
             this.flexiblePanel1 = new Y.Skin.YoPanel.FlexiblePanel();
             this.flexiblePanel1 = new Y.Skin.YoPanel.FlexiblePanel();
             this.listBox1 = new System.Windows.Forms.ListBox();
             this.listBox1 = new System.Windows.Forms.ListBox();
@@ -37,9 +38,19 @@
             this.flexiblePanel1.SuspendLayout();
             this.flexiblePanel1.SuspendLayout();
             this.SuspendLayout();
             this.SuspendLayout();
             // 
             // 
+            // button2
+            // 
+            this.button2.Location = new System.Drawing.Point(220, 57);
+            this.button2.Name = "button2";
+            this.button2.Size = new System.Drawing.Size(75, 23);
+            this.button2.TabIndex = 3;
+            this.button2.Text = "button2";
+            this.button2.UseVisualStyleBackColor = true;
+            this.button2.Click += new System.EventHandler(this.button2_Click);
+            // 
             // embedPanel1
             // embedPanel1
             // 
             // 
-            this.embedPanel1.AppFilename = "D:\\Soft\\DisplayX.1034260498.exe";
+            this.embedPanel1.AppFilename = "D:\\FTP\\tools\\小工具\\显示器检测.exe";
             this.embedPanel1.AppProcess = null;
             this.embedPanel1.AppProcess = null;
             this.embedPanel1.BackColor = System.Drawing.SystemColors.ActiveCaption;
             this.embedPanel1.BackColor = System.Drawing.SystemColors.ActiveCaption;
             this.embedPanel1.Dock = System.Windows.Forms.DockStyle.Right;
             this.embedPanel1.Dock = System.Windows.Forms.DockStyle.Right;
@@ -90,6 +101,7 @@
             this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 12F);
             this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 12F);
             this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
             this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
             this.ClientSize = new System.Drawing.Size(780, 413);
             this.ClientSize = new System.Drawing.Size(780, 413);
+            this.Controls.Add(this.button2);
             this.Controls.Add(this.embedPanel1);
             this.Controls.Add(this.embedPanel1);
             this.Controls.Add(this.flexiblePanel1);
             this.Controls.Add(this.flexiblePanel1);
             this.Name = "Form1";
             this.Name = "Form1";
@@ -108,6 +120,7 @@
         private System.Windows.Forms.Label label1;
         private System.Windows.Forms.Label label1;
         private System.Windows.Forms.Button button1;
         private System.Windows.Forms.Button button1;
         private Skin.YoPanel.EmbedPanel embedPanel1;
         private Skin.YoPanel.EmbedPanel embedPanel1;
+        private System.Windows.Forms.Button button2;
     }
     }
 }
 }
 
 

+ 5 - 0
Fork.Net/Y.Test/Form1.cs

@@ -21,5 +21,10 @@ namespace Y.Test
             //embedPanel1.AppFilename = @"D:\Temp\n.exe";
             //embedPanel1.AppFilename = @"D:\Temp\n.exe";
             embedPanel1.Start();
             embedPanel1.Start();
         }
         }
+
+        private void button2_Click(object sender, EventArgs e)
+        {
+            embedPanel1.ReEmbed();
+        }
     }
     }
 }
 }