C# Form窗口嵌套

转自:http://www.cnblogs.com/eugenewu0808/archive/2009/03/19/1416624.html

 

以FoxPro的界面为例。设主程序为Winform.exe,FoxPro编译的程序为vfpTest.exe。

1 在Winform中新建一个窗口VFPSHOW作为所有vfp打开后的父窗口,提供一个单例模式实现窗口唯一打开


 private static VFPSHOW mInstance = null;
        
/// <summary>
        
/// 单例模式
        
/// </summary>
        public static VFPSHOW Instance
        {
            
get
            {
                
if (mInstance == null || mInstance.IsDisposed)
                {
                    mInstance 
= new VFPSHOW();
                }
                
return mInstance;
            }
        }

 2 引入系统API,用于把VFP程序打开的表单窗口整合到VFPSHOW页面中,先添加如下引用:
using System.Diagnostics;
using System.Runtime.InteropServices;
using System.Threading;
using System.Reflection;
using System.Management;


 private const int SWP_NOOWNERZORDER = 0x200;
        
private const int SWP_NOREDRAW = 0x8;
        
private const int SWP_NOZORDER = 0x4;
        
private const int SWP_SHOWWINDOW = 0x0040;
        
private const int WS_EX_MDICHILD = 0x40;
        
private const int SWP_FRAMECHANGED = 0x20;
        
private const int SWP_NOACTIVATE = 0x10;
        
private const int SWP_ASYNCWINDOWPOS = 0x4000;
        
private const int SWP_NOMOVE = 0x2;
        
private const int SWP_NOSIZE = 0x1;
        
private const int GWL_STYLE = (-16);
        
private const int WS_VISIBLE = 0x10000000;
        
private const int WM_CLOSE = 0x10;
        
private const int WS_CHILD = 0x40000000;

        [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)]
        
private static extern long SetParent(IntPtr hWndChild, IntPtr hWndNewParent);

        [DllImport(
"user32.dll", EntryPoint = "GetWindowLongA", SetLastError = true)]
        
private static extern long GetWindowLong(IntPtr hwnd, int nIndex);

        [DllImport(
"user32.dll", EntryPoint = "SetWindowLongA", SetLastError = true)]
        
private static extern long SetWindowLong(IntPtr hwnd, int nIndex, long dwNewLong);
        
//private static extern int SetWindowLong(IntPtr hWnd, int nIndex, IntPtr 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, long wParam, long lParam);

        [DllImport(
"user32.dll")]
        
public static extern void SetForegroundWindow(IntPtr hwnd);

 3 用Process执行其它程序,vfpTest.exe,传入打开窗口命令,如 Do From myForm


 #region 运行进程
                IntPtr appWin;
                ProcessStartInfo psi 
= new ProcessStartInfo(strVFPPath);
                psi.RedirectStandardInput 
= true;
                psi.RedirectStandardOutput 
= true;
                psi.UseShellExecute 
= false;
                psi.Arguments 
= strArugments;

                Process _process 
= new Process();
                _process.StartInfo 
= psi;
                _process.EnableRaisingEvents 
= true;
                _process.Exited 
+= new EventHandler(_process_Exited);
                _process.Start();
 
#endregion

 4 把创建的表单移动到VFPSHOW中


                #region VFP进程放入C#窗口中
                
if (_process.WaitForInputIdle())
                {

                    
while (_process.MainWindowHandle.ToInt32() == 0)
                    {
                        Thread.Sleep(intMilliSecod);
                        _process.Refresh();
//必须刷新状态才能重新获得TITLE
                    }
                    _process.StartInfo 
= psi;

                    
// Get the main handle
                    appWin = _process.MainWindowHandle;

                    
// Put it into this form
                    SetParent(appWin, mInstance.Handle);
                    
// Move the window to overlay it on this window
                    
//MoveWindow(appWin, 0, 0, _mainParent.dockPanel1.Width, _mainParent.dockPanel1.Height, true);
                    MoveWindow(appWin, intX, intY, intWidth, intHeight, true);
                    
if (intX > mInstance.Width)
                    {
                        intX 
= 10;
                    }
                    
else
                    {
                        intX 
= intX + intWidth;
                    }
                }
                
#endregion

 5 通过上面4步就完成了VFP嵌入到VFPSHOW界面的效果,MDI窗口需要再加入一些判断:

(1)如果指定的VFP界面已经打开,只激活VFPSHOW界面,不再次打开


 ///因直接用process取不到进程的startinfo信息,所以采用以下方法
                SelectQuery selectQuery = new SelectQuery("select * from Win32_Process Where Name = 'vfpTest.exe'");
                
string strCmdLine = "";

                
using (ManagementObjectSearcher searcher = new ManagementObjectSearcher(selectQuery))
                {
                    
foreach (ManagementObject process in searcher.Get())
                    {
                        strCmdLine 
= process.Properties["CommandLine"].Value.ToString();
                        
if (strCmdLine.Substring(strCmdLine.IndexOf(' '+ 1== strArugments)
                        {
                            mInstance.Show();
//另一个进程执行时显示当前窗口
                            mInstance.Activate();
                            
return;
                        }
                    }
                }

(2)最多允许5个VFP程序


Process[] allProcess = Process.GetProcessesByName("vfpTest");
                
if (allProcess != null && allProcess.Length >= 5)
                
{
                    InfoProcess.MessageShow(
"该控制台最多允许5个VFP程序同时运行!");
                    
return;
                }
posted @ 2012-05-30 00:22  杂烩饭2012  阅读(707)  评论(0编辑  收藏  举报