不同于常规程序嵌入Winform,CATIA启动时先出现dos界面,然后才是CATIA主程序界面,所以需要使用EnumWindows枚举窗体,找到CATIA主窗口界面。
主要代码:
/// <summary>
/// 运行CATIA并返回窗体句柄
/// </summary>
/// <param name="installPath">CATIA安装路径</param>
/// <returns>窗体句柄,有异常返回0</returns>
private void RunCATIA(string installPath)
{
try
{
if (System.IO.File.Exists(installPath))
{
// 启动CATIA
Process process = Process.Start(installPath);
process.WaitForInputIdle();
this._pId = process.Id;
//循环获取CATIA的窗体句柄
int exitTimes = 1000;//默认n次尝试后没找到则退出,注意这个和sleep必须掌握好时间
while (!_findCATIAWindowSuccess)
{
//System.Threading.Thread.Sleep(500);//
EnumWindows(new WNDENUMPROC(EnumWindowsProc), (uint)this._pId);
if (--exitTimes <= 0)
{
_catiaIntPtr = IntPtr.Zero;
return;
}
}
// 枚举窗口没有错误号时表明获取成功
if (Marshal.GetLastWin32Error() != 0)
{
//_catiaIntPtr = IntPtr.Zero;
}
}
else
{
MessageBox.Show("CATIA程序文件不存在!");
}
}
catch (Exception ex)
{
_catiaIntPtr = IntPtr.Zero;
MessageBox.Show(ex.Message);
}
}
/// <summary>
/// 枚举获取CATIA主窗体句柄,应该是个回调函数
/// </summary>
/// <param name="catiaIntPtr">窗体的句柄</param>
/// <param name="lParam">窗体所属进程ID</param>
/// <returns></returns>
private static bool EnumWindowsProc(IntPtr catiaIntPtr, uint lParam)
{
uint uiPid = 0;
if (GetParent(catiaIntPtr) == IntPtr.Zero)
{
GetWindowThreadProcessId(catiaIntPtr, ref uiPid);
if (uiPid == lParam) // 找到进程对应的主窗口句柄
{
int length = GetWindowTextLength(catiaIntPtr);
StringBuilder windowName = new StringBuilder(2 * length + 1);
GetWindowText(catiaIntPtr, windowName, windowName.Capacity);
if (windowName.ToString().Equals("CATIA V5 用于学生"))
{
_findCATIAWindowSuccess = true;
_catiaIntPtr = catiaIntPtr; // 把句柄缓存起来
SetLastError(0); // 设置无错误
return false; // 返回 false 以终止枚举窗口
}
else
{
return false;
}
}
}
return true;
}
完整示例程序
下载,注意:按自己的CATIA版本修改“CATIA V5 用于学生”,这是窗口名称。