以FoxPro的界面为例。设主程序为Winform.exe,FoxPro编译的程序为vfpTest.exe。
1 在Winform中新建一个窗口VFPSHOW作为所有vfp打开后的父窗口,提供一个单例模式实现窗口唯一打开

VFPSHOW实例
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;

WIN API
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中

VFP进程放入C#窗口中
#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程序

最多允许5个VFP程序
Process[] allProcess = Process.GetProcessesByName("vfpTest");
if (allProcess != null && allProcess.Length >= 5)

{
InfoProcess.MessageShow("该控制台最多允许5个VFP程序同时运行!");
return;
}
6 完整文件:上传时报错,有需要的再说
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 地球OL攻略 —— 某应届生求职总结
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· .NET周刊【3月第1期 2025-03-02】
· [AI/GPT/综述] AI Agent的设计模式综述