首页 如何用VC6进行PC-DMIS二次开发(初级)

如何用VC6进行PC-DMIS二次开发(初级)

举报
开通vip

如何用VC6进行PC-DMIS二次开发(初级)如何用VC6进行PC-DMIS二次开发(初级) 如何用VC6进行PC-DMIS二次开发(初级) 目录 第一章( 序 第二章( PC-DMIS的优势 第三章( 一个简单的范例 第四章( 了解PC-DMIS的对象结构 第五章( 与PC-DMIS对象交流 第六章( 范例1:从 PC-DMIS 测量程序中获取数据 第七章( 范例2:向 PC-DMIS 测量程序中写入数据 第八章( 范例3:听听 PC-DMIS 在干什么, 第九章( 后记 第一章( 序 1) 开始阅读之前 要能够较好地理解本文的内容,您...

如何用VC6进行PC-DMIS二次开发(初级)
如何用VC6进行PC-DMIS二次开发(初级) 如何用VC6进行PC-DMIS二次开发(初级) 目录 第一章( 序 第二章( PC-DMIS的优势 第三章( 一个简单的范例 第四章( 了解PC-DMIS的对象结构 第五章( 与PC-DMIS对象交流 第六章( 范例1:从 PC-DMIS 测量程序中获取数据 第七章( 范例2:向 PC-DMIS 测量程序中写入数据 第八章( 范例3:听听 PC-DMIS 在干什么, 第九章( 后记 第一章( 序 1) 开始阅读之前 要能够较好地理解本文的内容,您必须至少熟悉一种开发语言,至少会使用一种开发 环境进行简单对话框程序的开发,对坐标测量和PC-DMIS有一定的了解,能够看懂 PC-DMIS程式代码。 若您希望使用C++和MFC进行二次开发,您必须熟悉C++语法,并熟练使用VC和 MFC进行开发。 若您参照本文的范例为执行开发,请了解: A. PC-DMIS联机运行时,若操作错误,可能产生各类伤害风险。请注意安全 B. 本文中的例子仅用于说明实现指定功能的方法,并未在效率优化、防止操作者 操作错误等方面进行特别的防范,在开发过程中您需要自己把好关 C. 笔者能力有限,许多程式中使用的方法可能并不是最合理的,也并不保证您参 考后能够获得理想的结果,开发程式发布前请您作好代码检查和效果验证/测试 工作 2) 阅读本文将获得的收获 本文将通过多个案例,逐步带您进入PC-DMIS二次开发的世界,使您掌握用Visual C++和MFC编写PC-DMIS二次开程序的方法。学习完本文后,参照文中的案例,相信您一定能编写出实用的PC-DMIS二次开发程序。 3) 本文的开发环境: Windows XP SP2 Visual C++ 6.0 PC-DMIS 3.5 CAD MR2 说明:尽管本文中范例所用的开发工具和PC-DMIS版本较低,但大部分例子(第七 章中用到Active 控件的除外)都能在各种版本的PC-DMIS上使用,并能在WIN7 下运行。 一旦您掌握了开发的方法,开发工具和PC-DMIS的版本并不会对您的开发工作造成 影响。 笔者使用Visual C++开发的原因有两个,一是只会使用C++作为开发工具,二是C++ 能够开发出功能更加强大的功能,尤其是MFC,能够非常方便地实现“文档/视图”架 构,便于数据的管理。 若您习惯使用Visual Basic或其它语言进行开发,那么本文中的案例您不能直接引用 到正在开发的工程中,但您能从方法和思路上获得一些启发。 4) 关于本文中的范例 本文中的范例都放在与本文同目录中的DSWs目录中。这些范例都是从第一个范例复 制升级的。 在复制过程中,笔者仅修改了工程(Project)的目录名称,所以每个范例中的头文 件和实现文件名称都与第1个范例相同。无论使用哪个范例,链接后产生的可执行文 件都是“Introduction.exe”。 5) 二次开发是什么 在阅读本文之前,也许您需要了解一下何为“二次开发”,如果您已了解此概念,或已是个中高手,请略过此节。 工业革命以来,重复单调的工作大部分由机械代替人手来完成。机械化的发展,使生产效率不断提高,逐步实现了大规模生产。由于生产效率不断提高,许多商品的价格大幅下降,从而让许多普通家庭也用上了在手工时代较为昂贵的商品。1946年计算机发明,并在不久后投入生产过程控制,进一步提高了生产的自动化程度。计算机软件,这种人类智慧的结晶,在很大程度上代替人的思考,并越来越多地代替人的决策,让人类不仅解放了双手,更协助人类延伸了思考的能力。人工智能的应用就是最好的证明。 优秀的软件通常拥有友好的界面和强大的功能,使人容易掌握,并用简单的操作完成复杂的工作。 那么,是否有了计算机软件,工作绩效已经最佳化了呢,人的操作是否已经最简便了,没有提升的空间了呢,非也。同一个软件,不同的用户常用到的功能是不一样的。有的人使用面狭窄,有的使用面广泛。就象一部智能手机,有的人仅用它来打电话发短信,有的人却喜欢将所有能用的功能都尝试一下,或安装上很多软件。对于通用的软件而言,为了控制学习和操作的复杂性(保持通用性),不可能将每一个用户的工作重心都考虑到, 设计 领导形象设计圆作业设计ao工艺污水处理厂设计附属工程施工组织设计清扫机器人结构设计 得让每 一个用户都感觉到象是专门为自己设计的软件一样(如果是这样当然是最好的,这样软件就能以最适合的方式进行使用,从而获得最高的工作效率)。为了兼顾通用性并满足客户特定需求,优秀的软件采用了三种方法来实现“可订制”特性,就象订做皮鞋和西装一样。这三种方法是:购买/安装模块可选,操作界面可订制,提供开发接口。 实现模块可选择性有两个目的,一是让客户能够只购买自己需要的功能,这样可以节省客户的成本,对软件的销售也有帮助;二是节省计算机的(安装时的)磁盘空间和(运行时的)内存空间。 可订制的界面,指软件的操作界面是可订制的,客户可以根据自己使用各功能的频率,重新安排菜单/工具栏/客户区的位置和大小,从而打造出最适合自己的界面。 开发接口用于提供给客户扩展软件功能的能力。通常情况下,当用户操作软件时,用户每输入一个指令,软件就执行一个动作。一项复杂的工作,往往需要非常多的步骤来完成。在这种情况下,用户就需要与软件进行非常多的交互,从而耗费许多人力。过多的操作会降低工作效率,并增加出错的可能性。大部分情况下,人的操作其出错概率远高过软件本身出错的概率,效率却远低于软件作业。如果大部分工作内容是相同的,人就会由重复的手工劳作,陷入重复的计算机操作中。为了改善这一状况,许多软件提供了“开发接口”。通过开发接口,用户除了通过鼠标和键盘来输入操作命令以外,还可经由已经编好的指令序列来向软件发出操作命令。看到这里您是否觉得奇怪,软件本身就是指令序列构成的,我们又用指令序列来操作它,没错,这就是二次开发。 二次开发就是在已开发的软件的基础上(姑且称之为一次开发),通过编写(开发)指令序列来向软件发出操作指令,从而用软件来操作软件,进一步提高工作效率和品质的作业方式。 6) 为了加深您的印象,下面举个简单的例子来示范如何用指令序列来操作EXCEL。 如下图的EXCEL文档,现在需要将5个单元格中的内容移到A列中最前面的5行中。 如果采用手动操作,我们需要执行以下动作(手工进行): a). 将“a1 = 0.997”移动到A1单元格 b). 将“a2 = 0.404”移动到A2单元格 c). 将“a3 = 0.423”移动到A3单元格 d). 将“a4 = 0.879”移动到A4单元格 e). 将“a5 = 0.079”移动到A5单元格 完成以上的5个步骤,一个熟练的工作人员大概需要15S的时间。 我们再看看如何用指令序列来完成这一工作。 在EXCEL中,存在两种“二次开发”,最简单的开发是“宏”程序(如果您愿意承认这也是一种开发的话)。EXCEL可以让我们把自己的操作 记录 混凝土 养护记录下载土方回填监理旁站记录免费下载集备记录下载集备记录下载集备记录下载 下来,就象录音一样。录制完以后,我们可以播放它。这种录制的作品就是“宏”。宏是一种VB脚本,每次播放时,宏都执行同样的操作。 为了让大家先有个直观的印象,我们先来录制一个宏,然后运行宏来完成上面的移动单元格的工作,看看需要多久(不计宏的录制时间。因为在大量重复操作的情况下,宏的录制时间相对是可以忽略不计的,即我们假设开发软件的时间相对使用软件来工作节省的时间是可以忽略不计的,否则软件就没有开发的价值了)。 a). 先把“Book1”中的内容复制到新建的“Book2”工作簿中(以便将来在Book2中演示宏的执行效果)。复制完后,切换回“Book1”工作簿,然后选择菜单“宏/录制新宏” b). EXCEL弹出“录制新宏”对话框。如下图。在“快捷键”栏位中输入小写字母“q”并按确定。(指定了CTRL+q的快捷键,当宏录制好以后,每次我们按CTRL+q操作时,宏就会被执行) c). EXCEL进入录制宏的状态,并显示出“停止录制”的工具栏,如下图。 d). 把移动单元格的操作手动执行一遍。现在“Book1”中的内容如下图 e). 点击“停止录制”工具栏中的蓝色正方形按钮,宏就被EXCEL记录下来,成为可以重复执行的指令序列 f). 切换到“Book2”工作簿,按下“CTRL+q”,看看发生了什么,移动单元格的操作在一瞬间被自动完成了~ 我们再来看看这个操作是如何实现的,宏里面到底记录了些什么, a). 选择菜单“工具/宏/Visual Basic 编辑器(V)” b). Visual Basic 编辑器窗口打开。展开窗口左侧“工程资源管理器”中的“模块”文件夹,双击其中的“模块1”,刚才录制的宏的内容在代码窗口中显示出来。代码窗口中,蓝色字体的是关键字,黑色字体的是代码,绿色字体的是注释 c). 为了便于理解,我在每句代码后面加入了注释,并重新将窗口画面贴在下方。您 现在可以了解每句代码所执行的操作了。 通过上面的例子,您是否对“二次开发”有了更直观的认识, 第二章( PC-DMIS的优势 通过对多家测量软件的了解,作者发现在各种测量软件中,PC-DMIS有以下的优势: 1) 免费的接口:PC-DMIS的开发接口是天生集成在软件中的。只要您购买PC-DMIS软 件,就默认拥有了其二次开发接口,无须额外付费 2) 丰富的接口:PC-DMIS提供了一套覆盖从应用程序操作到点数据类型定义的有序组织 的对象接口,提供给开发者灵活而强大的操控能力 3) 层次对象结构:在第四章中您将看到, PC-DMIS的二次开发接口按照测量程序的对 象模型有序地组织在一起,非常易于理解和掌握 4) 提供ActiveX控件:通过这些控件,您可以监听到PC-DMIS运作时发出的消息,从 而实时了解到量测程序执行的进度和状态,为下一步的操作提供依据 5) 接口的通用性:通过类型库,您可以用多种语言来进行开发 第三章( 一个简单的范例 为了让大家对PC-DMIS二次开发有更直观的印象,本章我们通过一个例子(名字就叫作Introduction吧)来示范如何通过开发程序与PC-DMIS交互。 完整的工程内容放在与本文同一目录中的“DSWs\Introduction”目录中。此工程已在VC6.0中编译通过。本章末尾有运行的画面。您可以在VC6中打开此工程查看具体的代码,并在此基础上作进一步的开发。 在本章中会用到较多的Visual C++和MFC的操作。如果您不熟悉,请先进行了解。不过笔者会以简单直观的描述辅以较多的图片,尽量让您能够看懂。 从Introduction中并不能看到二次开发所带来的效率提升。它只是示范了如何通过二次开发来操控测量软件。在实际的二次开发工作中,您可以将一系列依次执行的操作安排在一个模块中,从而让操作者用一个简单的操作来调用它们,此时效率的提升才显现出来。 Introduction将完成以下功能:获得PC-DMIS中打开的量测程序名称及路径,提供一个按钮让操作者启动量测程序执行,您可以通过它打开量测程序,也可以将当前量测程序另存。其主界面如下: 我们来看看Introduction的开发过程。概览如下: 一. 在VC中建立一个名称为“Introduction”的对话框工程 二. 在工程中加入用于与操作者交互的控件 三. 加入控件响应函数(当操作者操作控件,比如点击“启动程式运行”时,Introduction 将调用这些函数来实现控件代表的操作) 四. 加入与PC-DMIS交互的类库,并将类库的头文件包含到要使用它的文件中(这些 类库是PC-DMIS与Introduction之间通讯的接口。Introduction通过这些类库 中声明的类来建构对象,并通过这些对象与PC-DMIS交互) 五. 加入控件响应函数将要调用的功能函数(将所有的操作代码都写在控件响应函数中 是不好的习惯。如果这样做的话,相同的代码可能会在几个控件响应函数中重复出 现。在这里我们将它们声明为函数,从而实现代码重用。在实际的开发工程中这是 非常重要的) 六. 加入与PC-DMIS交互的对象的变量的声明 七. 填充函数代码 八. 编译和链接 九. 测试 通过以上步骤,我们就能开发出能够操控PC-DMIS的程序,是不是很简单呢, 下面我们来一步一步地介绍开发过程。 为了让不熟悉VC的朋友看得比较明白,下面的步骤写得比较细,从而也比较冗长。如果有些步骤对您来说很熟悉,请略过它们。 一( 在VC中建立一个名称为“Introduction”的对话框工程 1. 打开VC,并选择菜单“File/New”,或按快捷键“CTRL+N”,VC弹出新建对话 框。 2. 在对话框中选择“Projects”选项页,在左下方的列表中选择“MFC AppWizard (exe)”,即MFC应用程序向导,在 “Project name”栏中输入工程名称为 “Introduction”,然后点击“OK”按钮 3. 应用程序向导进入STEP 1。在该页中选择“Dialog based”(对话框应用程序), 再点击NEXT按钮 4. 应用程序向导进入STEP 2。在该页中选上“Automation”,再点击NEXT按钮 5. 应用程序向导进入STEP 3。在该页中选择“How would you like to use the MFC library?”选项为“As a statically linked library”,然后点击NEXT按钮 6. 应用程序向导进入STEP 4。该页报告了应用程序向导将要自动生成的类以及其 头文件和实现文件名称。不用修改,点击“Finish”按钮即可 7. VC弹出对话框,报告它给我们干了些什么事情,以及我们选择的设置。点击 OK按钮即可 8. 经过一番动作,VC出现以下界面。笔者假定读者对VC的开发界面已经比较 熟悉,这里就不介绍了。画面中央就是VC为我们生成的初始对话框。 二( 在工程中加入用于与操作者交互的控件 1. 先删除“TODO: 在这里设置对话控制”控件。 2. 加入实现以下4个功能需要的控件1)获得打开的量测程序名称及路径,2)启 动量测程序执行,3)打开量测程序,4)将当前量测程序另存。完成后的界面 如下: (编辑框控件的ID为“IDC_EDIT_PRG_FOR_OPEN”。记住这个ID,将来取得 要打开的量测程式路径时需要用到。) (对话框中的“确定”、“取消”按钮是MFC自动生成的。在本程序中,它们都 只有一个作用,就是退出对话框,所以您可以删除掉一个。) 三( 加入控件响应函数 1. 双击“取得程式名称和路径”按钮,VC弹出对话框让我们确认它准备帮我们添 加到工程中的响应函数名称。在此对话框中点击“OK”按钮,同意默认的名称即 可。 2. 当我们点击“OK”按钮后,VC自动在主对话框的实现文件 “IntroductionDlg.cpp”末尾,为我们添加了一个函数。如下图。 此时“OnButtonGetPrgPathName”函数是一个空壳,但是当用户点击“取得 程式名称和路径”按钮时,该函数会被立即调用。 只要我们将取得程式名称和路径的操作代码写在此函数中,即可实现当用户点 击“取得程式名称和路径”按钮时,程式就执行“取得程式名称和路径”的操作。 (为了让用户在点击“取得程式名称和路径”按钮时激发此函数的调用,MFC还 做了大量的工作,此处不再详述) Void CIntroductionDlg::OnButtonGetPrgPathName() { // TODO: Add your control notification handler code here } 3. 按相同的方法给“启动程式运行”、“打开量测程式”、“另存量测程式”添加响应 函数。所有的响应函数完成后的IntroductionDlg.cpp文件尾部内容如下。 (如果您给四个按钮的ID不同,则VC为您生成的响应函数名称也不同。这并 不影响各按钮的功能,但您需要了解这一点。) (如果您希望VC给你的函数名称与下图中完全一致,您可以在VC弹出“Add Member Function”对话框时,修改函数名称,或者将四个按钮的ID依次命名 为“IDC_BUTTON_GET_PRG_PATH_NAME”、“IDC_BUTTON_LAUNCH”、 “IDC_BUTTON_OPEN_PRG”、“IDC_BUTTON_SAVE_AS_PRG”) 4. 刚才加入的响应函数中都没有任何函数代码,它只是展示了控件响应的框架。 我们会在稍后添加实际的操作代码 四( 加入与PC-DMIS交互的类库,并将头文件包含到主对话框的实现文件中 1. 按“CTRL+W”快捷键,打开“MFC ClassWizard”(MFC类向导)对话框 2. 点击“Add Class…”(新增类)按钮,在弹出的菜单中选择“From a type library….”(从类型库中新增) 3. VC弹出“Import from Type Library”对话框。在该对话框中定位到PC-DMIS 的安装目录,并选择“pcdlrn.tlb”文件,再点击“打开”按钮。该文件中保存着 PC-DMIS的二次开发接口 4. VC弹出“Confirm Classes”对话框,要求确认要导入的类。为简便起见,我们 导入类型库中包含的所有的类。在列表框中选中所有的类,并点击“OK”按钮。 5. 退出“MFC ClassWizard” 6. 看看工程中,是不是多了一个名为“pcdlrn.h”的头文件和一个名为 “pcdlrn.cpp”的实现文件, 7. 将“pcdlrn.h”包含到主对话框的实现文件中:双击左侧文件列表中的 “IntroductionDlg.cpp”,切换到此文件,在头部添加一句“#include "pcdlrn.h"” 五( 加入控件响应函数将要调用的功能函数 1. 先来分析一下我们需要的函数。我们的程序准备实现4个功能:获得PC-DMIS中打开的量测程序名称及路径,启动量测程序执行,打开量测程序,将当前量测程序另存。 于是我们需要以下6个函数: a) 连接PC-DMIS:BOOL ConnectPcdmis() // 所有与 PC-DMIS交互的操作都必须在连接PC-DMIS后才能进行,否则PC-DMIS 根本听不到我们的程序在说什么,也不会有任何反应 b) 释放PC-DMIS:void ReleasePcdmis() // 要养成好的习惯, 一旦与PC-DMIS的交互告一段落,就将应用程序与PC-DMIS的连接切 断,不要一直占用PC-DMIS的Automation服务资源 c) 获得PC-DMIS中打开的量测程序名称及路径:CString GetPRGPathName() d) 启动量测程序执行:void LaunchPRG() e) 打开量测程序:BOOL OpenPRG(CString csPRGPathName) f) 将当前量测程序另存:void SaveAsPRG(CString csPRGPathName) 2. 在工程中加入以上6个函数定义。下面示范如何加入第一个函数。其它的函数 请自行加入 a) 双击“IntroductionDlg.cpp”,切换到该文件 b) 按“CTRL+END”,将光标移到文件尾 c) 点击WizardBar工具栏上的倒三角形图标 d) 在弹出的菜单中选择“Add member Function…”(VC弹出“Add member Function…”对话框) e) 在“Function Type”中输入函数返回类型为“BOOL” f) 在“Function Declaration”中输入函数声明“ConnectPcdmis()” g) 点击“OK”按钮 3. 加入了6个函数后的文件内容如下图。 4. 象控件响应函数一样,这些刚加入的函数都是空壳。我们会在稍后添加代码 六( 加入与PC-DMIS交互的对象的变量声明 为了实现程序的4个功能(获得PC-DMIS中打开的量测程序名称及路径,启动量测程序执行,打开量测程序,将当前量测程序另存),我们需要连接PC-DMIS的以下对(通过它们来操控PC-DMIS):应用程序(类库中的包装类名为“IApplication”)、象 测量程序集合(类库中的包装类名为“IPartPrograms”)、测量程序(类库中的包装类名为“IPartProgram”)。将光标放在“IntroductionDlg.cpp”头部,加入以下变量声明(为了简单起见,我们直接使用了文件作用域的全局变量): IApplication app_pcdlrn; IPartPrograms pps_pcdlrn; IPartProgram pp_pcdlrn; 七( 填充函数代码。为了避免编译错误,我们先填充被控件响应函数调用的功能函数,再填充控件响应函数。下面分别叙述功能函数的用途,以及如何来编写其中的代码。为简单起见,以下函数中未加入容错代码。 1. 连接PC-DMIS:BOOL ConnectPcdmis() BOOL CIntroductionDlg::ConnectPcdmis() { // 1 联接 APPLICATION。如果失败就报错退出 if(!app_pcdlrn.CreateDispatch("PCDLRN.Application")) { AfxMessageBox("无法连接PC-DMIS服务。请确认 PC-DMIS 正确安装,或重新启动电脑再试试。", MB_SYSTEMMODAL|MB_SETFOREGROUND|MB_ICONWARNING); return FALSE; } // 设置PC-DMIS 窗口可见 app_pcdlrn.SetVisible(TRUE); app_pcdlrn.Maximize(); // 2 联接 PART PROGRAMS pps_pcdlrn=app_pcdlrn.GetPartPrograms(); return TRUE; } 2. 释放PC-DMIS:void ReleasePcdmis() 函数内容:测试接口指针,如果不为空,说明接口尚未释放,释放它。 void CIntroductionDlg::ReleasePcdmis() { if(pps_pcdlrn.m_lpDispatch) pps_pcdlrn.ReleaseDispatch(); // 释放 PART PROGRAMS 对象 if(app_pcdlrn.m_lpDispatch) app_pcdlrn.ReleaseDispatch(); // 释放 APPLICATION 对象 } 3. 获得PC-DMIS中打开的量测程序名称及路径:CString GetPRGPathName() CString CIntroductionDlg::GetPRGPathName() { // 将路径和名称连接在一起,构成测量程序的完整路径 return pp_pcdlrn.GetPath()+pp_pcdlrn.GetName(); } 4. 启动量测程序执行:void LaunchPRG() void CIntroductionDlg::LaunchPRG() { pp_pcdlrn.AsyncExecute(); } 5. 打开量测程序:BOOL OpenPRG(CString csPRGPathName) csPRGPathName是文件路径。 BOOL CIntroductionDlg::OpenPRG(CString csPRGPathName) { if(pps_pcdlrn.Open(csPRGPathName,"CMM1")!=NULL) { return TRUE; } else { return FALSE; } } 6. 将当前量测程序另存:void SaveAsPRG(CString csPRGPathName) csPRGPathName是测量程序另存路径。 void CIntroductionDlg::SaveAsPRG(CString csPRGPathName) { pp_pcdlrn.SaveAs(csPRGPathName); } 7. 控件响应——取得测量程序名称和路径:OnButtonGetPrgPathName void CIntroductionDlg::OnButtonGetPrgPathName() { CString msg; if(!ConnectPcdmis()) return; // 连接PC-DMIS。若失败则退出 // 检查是否有打开的测量程式。如果没有,则报错退出 if(pps_pcdlrn.GetCount()<1) { AfxMessageBox("您至少需要打开一个量测程式,才能执行此操作~",MB_ICONWARNING); ReleasePcdmis(); return; } pp_pcdlrn=app_pcdlrn.GetActivePartProgram(); // 连接PC-DMIS当前测量程式 msg="测量程序路径为:"; // 生成消息字符串 msg+=GetPRGPathName(); pp_pcdlrn.ReleaseDispatch(); // 释放PC-DMIS当前测量程式 ReleasePcdmis(); // 用完后,第一时间释放PC-DMIS AfxMessageBox(msg,MB_ICONINFORMATION); // 用对话框报告测量程序路径 } 8. 控件响应——启动测量程序运行:OnButtonLaunch void CIntroductionDlg::OnButtonLaunch() { if(!ConnectPcdmis()) return; // 连接PC-DMIS。若失败则退出 // 检查是否有打开的测量程式。如果没有,则报错退出 if(pps_pcdlrn.GetCount()<1) { AfxMessageBox("您至少需要打开一个量测程式,才能执行此操作~",MB_ICONWARNING); ReleasePcdmis(); return; } pp_pcdlrn=app_pcdlrn.GetActivePartProgram(); // 连接PC-DMIS当前测量程式 LaunchPRG(); // 启动运行 pp_pcdlrn.ReleaseDispatch(); // 释放PC-DMIS当前测量程式 ReleasePcdmis(); // 用完后,第一时间释放PC-DMIS } 9. 控件响应——打开测量程序:OnButtonOpenPrg void CIntroductionDlg::OnButtonOpenPrg() { CString csPRGPathName; // 从编辑框中取得操作者输入的测量程序路径 GetDlgItem(IDC_EDIT_PRG_FOR_OPEN)->GetWindowText(csPRGPathName); if(!ConnectPcdmis()) return; // 连接PC-DMIS。若失败则退出 pps_pcdlrn.Open(csPRGPathName,"CMM1"); // 打开测量程序 ReleasePcdmis(); // 用完后,第一时间释放PC-DMIS } 10. 控件响应——另存测量程序:OnButtonSaveAsPrg 在此函数中,同时展示了如何用Windows的文件对话框来取得另存路径。 void CIntroductionDlg::OnButtonSaveAsPrg() { CString csPRGPathName; // 利用Windows 标准 excel标准偏差excel标准偏差函数exl标准差函数国标检验抽样标准表免费下载红头文件格式标准下载 文件对话框取得另存路径 CFileDialog fileDlg(FALSE,".PRG",NULL,OFN_HIDEREADONLY | OFN_OVERWRITEPROMPT," PC-DMIS测量程序 (*.PRG)|*.PRG",NULL); fileDlg.m_ofn.lpstrTitle="请指定测量程序另存路径"; if(fileDlg.DoModal()==IDOK) { csPRGPathName=fileDlg.GetPathName(); } else // 若操作者取消了另存对话框,则不执行任何操作,直接退出 { return; } if(!ConnectPcdmis()) return; // 连接PC-DMIS。若失败则退出 // 检查是否有打开的测量程式。如果没有,则报错退出 if(pps_pcdlrn.GetCount()<1) { AfxMessageBox("您至少需要打开一个量测程式,才能执行此操作~",MB_ICONWARNING); ReleasePcdmis(); return; } pp_pcdlrn=app_pcdlrn.GetActivePartProgram(); // 连接PC-DMIS当前测量程式 pp_pcdlrn.SaveAs(csPRGPathName); pp_pcdlrn.ReleaseDispatch(); // 释放PC-DMIS当 前测量程式 ReleasePcdmis(); // 用完后,第一时间 释放PC-DMIS } 八( 编译和链接。 1. 选择菜单“Build / Rebuild All” 2. 确认编译和链接结果为0错误、0警告 九( 测试 1. 在PC-DMIS中打开一个测量程序。笔者打开的测量程序为“TEST” 2. 点击VC工具栏上的惊叹号按钮 3. Introduction.exe主界面显示出来 4. 点击“取得程式名称和路径”,Introduction.exe弹出以下对话框: 5. 点击“启动程式运行”,TEST.PRG开始运行 6. 在编辑框中输入要打开的测量程式,然后点击“打开测量程式”,测量程式被打 开 7. 点击“另存测量程式”按钮,Introjection.exe弹出文件对话框,要求输入另存 路径。输入路径并点击保存按钮后,PC-DMIS将测量程式另存 第四章( 了解PC-DMIS的对象结构 一(PC-DMIS对象清单 二(PC-DMIS对象层次 三(从PC-DMIS帮助文件中获取对象操作接口信息 一(PC-DMIS对象清单 通过第三章的范例,笔者初步介绍了如何与PC-DMIS的AUTOMATION服务器连接,并用其提供的接口操控PC-DMIS对象。 本章我们来全面地了解一下,PC-DMIS提供了哪些哪些对象,这些对象分别有哪些操作接口。 通过了解PC-DMIS提供的接口,我们就能知道,通过二次开发,我们能干什么,或者当我们需要开发某个功能时,能够判定PC-DMIS是否提供了相应的接口。 PC-DMIS提供的对象(接口)清单如下表: 注:1(以下接口笔者在此未列出:在较高版本中被取消了或升级了的接口,或极少使用的接口 2(有部分对象名称在不同的PC-DMIS版本中不完全一致 二(PC-DMIS对象层次 从清单中并不能看出对象层次。我们将其整理后得到如下的对象层次图: 注: 1(右侧对象是左侧对象的成员 2(从C++的对象层次的角度来看,下图中有此子对象是由父对象派生而来,而不是其成员,对此笔者并未作严格区分。请读者从实际的语境中作区分即可 3(有些对象同时属于多个对象的成员,笔者并未一一列出 三(从PC-DMIS帮助文件中获取对象接口信息 无论如何,从本文中您不可能了解到PC-DMIS对象及接口的全部信息。了解如何从帮助文件查询操作接口是必要的。 下面描述了如何从PC-DMIS帮助文件中了解对象接口信息。 1( 打开帮助文件,定位到Automation并展开它,其子项就是各类对象接口的详细信息。 注:由于PC-DMIS4.2的帮助文件组织得更有条理,所以笔者习惯从PC-DMIS4.2的帮助文件中获取接口信息。下图也是PC-DMIS4.2的帮助文件画面。 2( 要了解某个对象的介绍及其提供的接口,点击其左侧的+号,可以看到其成员分为 “Properties”(属性)和“Methods”(方法)两部分。有一些还有“Event”(事件)。 如果你有VB开发的经验,对于上述名词应该是非常熟悉的。 属性:通过读取对象属性,可以获得成员值、对象状态 方法:操作对象的接口 事件:如果您想在对象发生某些事件时执行特定的操作,可以监听该对象的事件,并在 该事件响应函数中加入您的操作代码 第五章( 与PC-DMIS对象交流 一(连接PC-DMIS对象(拨通电话) 二(取得已连接对象的子对象(成员)或父对象 三(通过已连接的对象向PC-DMIS发出命令 四(向已连接的对象写入信息 五(监听PC-DMIS对象发出的消息 六(枚举常量的值 本章我们先描述如何进行这些操作,后面的章节中将会有范例供大家参考。 一(连接PC-DMIS对象(拨通电话) 在PC-DMIS中,要连接指定的对象,一般需要从顶层对象Application开始,向下逐级连接,就象打电话时,先拨国家代码,再拨区号,最后拨电话号码。 其一般步骤如下: 1( 找到该对象在对象层次图中的位置 2( 从该对象所处的位置,向左溯源到Application对象,由此我们得到一条从Application 到指定对象的“连接路径” 3( 连接Application对象 4( 通过Application对象取得“连接路径”上的下游对象 5( 重复第4步操作,直到连接上指定的对象 比如现在想连接PC-DMIS中已打开的名称为“ABC.PRG”的测量程序的编辑窗口,操作过程如下: 1( 连接Application 2( 取得Application的PartPrograms 3( 遍历PartPrograms,连接上其中名称为“ABC.PRG”的PartProgram 4( 通过已连接上的PartProgram,取得其EditWindow 注:为便于操作,PC-DMIS提供了一些“捷径”,比如 1( 通过Application的“ActivePartProgram”接口,可以直接连接上当前测量程序 2( 许多对象都有“Application”成员,通过它可直接连接Application对象 3( 许多对象都有“Parent”成员,通过它可取得其父对象。比如通过Command.Parent取得 Commands对象 二(取得已连接对象的子对象(成员)或父对象 前面讲过,PC-DMIS对象的成员分为三类:属性、方法、事件。要取得已连接对象的子成员,读取其属性即可。 将类库(.TLB文件)导入VC中,属性和方法的界限模糊了,有许多属性也被转换成了成员函数,而另一些属性则转换成了成员变量。方法则一般转换成函数。 比如,Command对象被转换成ICommandWrapper类,其DimensionCommand属性被变换成成员函数,其声明形式为:LPDISPATCH GetDimensionCommand(); 1( 要从Command对象获取其DimensionCommand成员,使用 GetDimensionCommand() 函数属性即可: IDimensionCmdWrapper dim; dim = cmd.GetDimensionCommand(); // 假设 dim 是已连接上的Command对象 2( 如何获取对象的对象, 使用“对象名.Parent”属性即可。 类库导入VC时,Command对象的Parent属性被变换为成员函数。其声明形式为:LPDISPATCH GetParent(); 3( 如何取得顶层对象(Application), 绝大部分PC-DMIS对象都是Application对象的成员(或成员的成员)。要从某个对象获得Application对象(Application是顶层对象),使用“Command.Application”属性即可。 类库导入VC时,对象的“Application”属性被转换为成员函数。其声明形式为:LPDISPATCH GetApplication(); 三(通过已连接的对象向PC-DMIS发出命令 通过对象的方法,PC-DMIS提供了很多操作。比如,通过Application对象可以退出PC-DMIS、最大化/最小化窗口;通过PartPrograms对象可以打开、关闭测量程序;通过PartProgram对象可以启动运行、清除标记、关闭它自己,等等。 例,要通过PartPrograms对象将D:\Introduction.PRG打开,并关闭其它测量程序,操作过程如下: pps_pcdlrn.CloseAll(); // 假设pps_pcdlrn是已连接上的PartPrograms对象 pps_pcdlrn.Open(“d:\\Introduction.prg”,”CMM1”); // “CMM1”是机器名称,用于指示测量程序是联机还是脱机打开 若想在测量程序中标记第20到第30条命令,并启动测量程序执行,可以这样操作: cmd20 = cmds.Item ( COleVariant ( 20 ) ); // 连接第20条命令 cmd30 = cmds.Item ( COleVariant ( 30 ) ); // 连接第30条命令 pp_pcdlrn.SetExecutionBlock ( cmd20 , cmd30 ) ; // 标记第20~30条命令 pp_pcdlrn.AsyncExecute ( ) ; // 启动测量程序运行 四(向已连接的对象写入信息 要向对象写入信息,直接设置其属性值即可。在VC中,转换后的函数通常为“SetXxxxx”形式。 比如, 设置PC-DMIS窗口标题: void IApplication :: SetCaption(LPCTSTR); 设置当前目录: Void IApplication :: SetCurrentUserDirectory(LPCTSTR); 设置PC-DMIS窗口宽度: void IApplication :: SetWidth(long); 设置测量命令的某个字串:BOOL ICommandWrapper :: PutText(LPCTSTR NewVal, long DataType, long TypeIndex); 设置特征的坐标: BOOL IFeatCmdWrapper :: PutPoint(long PointType, long TheoMeas, double X, double Y, double Z); 等等…… 有一些操作会有多种实现方法。 比如,对于测量特征,要设置其理论值,既可使用FeatCommand的PutPoint方法,也可使用Command的PutText方法。 前者是设置特征的坐标,后者是向该测量命令的TX、TY、TZ字段中置入数值字符串(需要操作三次以分别写入三个值)。 两种方法示范如下: // 第一种方法:设置特征坐标 featCmd = cmd.GetFeatureCommand(); featCmd . PutPoint ( FPOINT_CENTROID , FDATA_THEO , 0.1234 , 0.5678, 0.9012 ); // 第二种方法:向命令中置入字串 cmd.PutText ( “0.1234”, 7 , 0 ); cmd.PutText ( “0.5678”, 8 , 0 ); cmd.PutText ( “0.9012”, 9 , 0 ); 五(监听PC-DMIS对象发出的消息 相对其它操作来说,在VC中开发的程序,要监听PC-DMIS发出的消息是比较复杂的。 本章先简单介绍一下在VC开发工程中监听PC-DMIS消息的过程。具体的操作放到第八章范例3中介绍。 在VC中监听PC-DMIS消息的方法如下: 1( 将PC-DMIS提供的ActiveX控件加入到工程中 2( 将ActiveX控件的头文件包含到需要监听事件的文件头部 3( 声明ActiveX控件对象 4( 在应用程序界面中添加ActiveX控件 5( 将ActiveX控件包装对象连接上ActiveX控件 6( 将ActiveX控件连接上PC-DMIS 7( 添加事件响应函数 8( 编写函数代码 六(枚举常量的值 PC-DMIS对象的属性和方法中会用到非常多的枚举型参数。每个枚举量是一种数据类型, 它只有有限个值。 例,取得特征坐标的GetPoint函数,其语法为:Return Value=expression.GetPoint(PointType, TheoMeas, X, Y, Z) 其中的TheoMeas就是一个枚举型参数,它的几个可取的值为:FDATA_THEO(理论值)、 FDATA_MEAS(实测值)、FDATA_TARG(目标值)。 在VC中,GetPoint函数的形式如下:BOOL IFeatCmdWrapper :: GetPoint(long PointType, long TheoMeas, double* X, double* Y, double* Z); 根据以上的形式,TheoMeas是一个long型值。要在VC中使用此函数,我们必须知道枚 举常量所代表的具体的值是多少。 在PC-DMIS的对象的方法中,类似的枚举量很多,所以我们必须掌握查询它们的值的方法。 要了解这些枚举量的值,可以在EXCEL中观察。 本文前面已示范了如何操作EXCEL的Visual Basic窗口。在此处笔者示范如何在EXCEL中查看PC-DMIS对象接口,以及枚举量的值。 1( 在EXCEL中浏览PC-DMIS对象 A. 打开Visual Basic窗口,选择“工具/引用”菜单 B. 在弹出的对话框中选中您要查看的PC-DMIS对象库。此处笔者选中“PC-Dmis 3.5 Object Library”。点击“确定”按钮 C. 显示对象浏览器 D. 选择PCDLRN库 E. PC-DMIS的对象库显示出来。如下图。在“类”一栏中选中某个对象,右侧就会显 示出其全部的成员。 2( 查看枚举量的值: A. 选中枚举量,Visual Basic窗口下方即会显示其值。从下图中可以看出, “FDATA_THEO”枚举常量值为2。 B. 在二次开发工程中,将枚举值定义为常量,然后就能方便地使用其名称了(可读 性较佳)。 比如我们可以定义:const LONG FDATA_THEO = 2;,然后调用GetPoint函数 就可以传递“FDATA_THEO”给它了。 第六章( 范例1:从 PC-DMIS 测量程序中获取数据 本章我们编写一个二次开发程序,将当前PC-DMIS中开启的测量程序中的所有特征的名称、XYZ坐标读出,保存在一个数组中,并且用对话框将这些数据一个个显示出来。 为了简单起见,本章的开发范例在第一章的“Introduction”基础上添加功能,并重新命名为“GetDataIntroduction” 完整的工程内容放在与本文同一目录中的“DSWs\GetDataIntroduction”目录中。此工程 已在VC6.0中编译通过。 在开始开发工作之间,先 规划 污水管网监理规划下载职业规划大学生职业规划个人职业规划职业规划论文 一下: 一(声明所需的常量和变量 二(在界面中添加取得特征数据的按钮 三(为该按钮添加响应函数 四(编写函数代码。在按钮响应函数中,操作按如下步骤进行: 1. 连接PC-DMIS 2. 连接上Commands(命令集合)控件,取得集合中的命令个数 3. 遍历所有的命令(从第1个遍历到最后1个):检查每个命令是否是特征命令。 如果是:取得其名称及点坐标;如果不是,检查下一条命令 4. 释放Commands 5. 释放PC-DMIS 下面根据规划来执行开发。 双击工程目录中的“Introduction.dsw”,打开GetDataIntroduction工程。 一(声明所需的常量和变量 特征A. 分析:为取得所有特征数据,工程中需要:用来保存特征数据的数组、保存 个数变量、(取特征坐标时)传递给函数的枚举量。 a) 用来保存特征数据的数组:本工程中使用CString型二维数组,最多容纳 100个特征,每个特征储存4个数据:名称、X坐标、Y坐标、Z坐标 b) 传递给函数的枚举量:在VC中,取得特征坐标的函数被包装成以下形 式:BOOL GetPoint(long PointType, long TheoMeas, double* X, double* Y, double* Z); 这意味着我们要向GetPoint函数传递PointType、TheoMeas以及三个 指针(指针指向的变量用于容纳XYZ坐标)。 下图显示了从FeatCommand 中取得坐标时的可用选项。假设我们需 要取得“FPOINT_CENTROID”(中心点)的“FDATA_THEO”(理论坐标) 从EXCEL中查询这两个“FPOINT_CENTROID”和“FDATA_THEO”的值, 得到FPOINT_CENTROID=0;FDATA_THEO=2 B. 在工程中加入常量及变量定义。为简单起见,笔者直接将其定义为文件作用域的 全局变量,添加在“IntroductionDlg.cpp”文件头部。 二(在界面中添加取得特征数据的按钮:给主对话框添加一个按钮,赋予其ID为 “IDC_BUTTON_GET_DATA”,按钮名称为“取得特征数据” 三(为该按钮添加响应函数:双击刚添加的“取得特征数据”按钮,VC为我们添加一个 “OnButtonGetData”函数 四(编写函数代码。在该函数(用于取得特征数据)中,操作按如下步骤进行: 1. 连接PC-DMIS 2. 连接上Commands(命令集合)控件,取得集合中的命令个数 3. 通过循环遍历所有的命令(从第1个遍历到最后1个):检查该命令是否是特征 命令。如果是:取得其名称及点坐标;如果不是,检查下一条命令 4. 释放Commands 5. 释放PC-DMIS 完整的函数代码如下: void CIntroductionDlg::OnButtonGetData() { // 函数作用域的变量定义 CString msg; // 消息字串 DOUBLE x,y,z; // XYZ坐标 char chBuf[64]; // 字符缓冲区 LONG lCmdNumber; // 测量程序中的命令个数 LONG l; // 循环变量 ICommandWrapper cmd_pcdlrn; // 命令 IFeatCmdWrapper featCmd_pcdlrn; // 特征命令 if(!ConnectPcdmis()) return; // 连接PC-DMIS。若失败则退出 // 检查是否有打开的测量程式。如果没有,则报错退出 if(pps_pcdlrn.GetCount()<1) { AfxMessageBox("您至少需要打开一个量测程式,才能执行此操作~",MB_ICONWARNING); ReleasePcdmis(); return; } // 连接PC-DMIS当前测量程式 pp_pcdlrn=app_pcdlrn.GetActivePartProgram(); /* 取得数据并存入数组 */ iFeatCount=0; // 取得的特征计数清零 cmds_pcdlrn=pp_pcdlrn.GetCommands(); // 连接命令集合对象 lCmdNumber=cmds_pcdlrn.GetCount(); // 取得命令个数 // 遍历所有命令 for(l=1;l<=lCmdNumber&&iFeatCount<100;l++) { cmd_pcdlrn=cmds_pcdlrn.Item(COleVariant(l)); // 连接命令 if(!cmd_pcdlrn.GetIsFeature()) // 如果不是特征命令,下一个 { continue; } csFeatData[iFeatCount][0]=cmd_pcdlrn.GetText(2,0); // 取得特征名称 featCmd_pcdlrn=cmd_pcdlrn.GetFeatureCommand(); // 连接特征命令 featCmd_pcdlrn.GetPoint(FPOINT_CENTROID,FDATA_THEO,&x,&y,&z); // 取得特征坐标 // 将X坐标转换成字符串并存入数组 ::sprintf(chBuf,"%.3f",x); csFeatData[iFeatCount][1]=chBuf; // 将Y坐标转换成字符串并存入数组 ::sprintf(chBuf,"%.3f",y); csFeatData[iFeatCount][2]=chBuf; // 将Z坐标转换成字符串并存入数组 ::sprintf(chBuf,"%.3f",z); csFeatData[iFeatCount][3]=chBuf; iFeatCount++; // 特征计数加1 } /* 取数据过程结束 */ // 若未取得任何特征数据就发出警告 if(iFeatCount==0) { AfxMessageBox("警告~未从PC-DMIS中取得任何特征数据。",MB_ICONWARNING); goto PROCESS_END; } // 将数据用对话框显示给操作者 for(l=0;l m_hWnd); 您可以将连接操作理解为“灵魂附体”。通过连接,我们就可以用 app_events_pcdlrn来操控ActiveX控件。 二(在主界面中加入两个按钮用于连接和断开ActiveX控件,编写响应函数 注: 在实际的开发工程中,您可能希望开发程序自动链接和自动断开链接,而不是用按钮来手动操作。 要实现自动连接和断开,您可以将连接操作放在开发程序启动时必定调用的某个函数中(比如OnInitDialog)来执行,将断开操作放在开发程序退出前必定调用的某个函数中来执行。 基于以下的原因,笔者将连接和断开操作用按钮来手动执行: 1( 手动操作能更直观地演示“必须先连接才能监听到消息” 2( 若将连接操作放在开发程序启动时执行,则,若开发程序早于PC-DMIS启动,则在开发程序启 动过程中,PC-DMIS尚未启动,连接操作会失败。这种情况的后果就是即便稍后启动了PC-DMIS, 开发程式也无法监听到事件消息。换句话说如果要保证自动连接成功,必须让PC-DMIS先启动。 这是实际的开发工作中必须注意的。要解决此问题,可以设置一个Timer,定时检查PC-DMIS 是否启动,若PC-DMIS已启动且当前尚未连接,则执行连接。 A. 加入按钮。 在这里笔者加入了两个按钮“连接ActiveX对象”和“断开ActiveX对象”,并将其ID分别设置为“IDC_BUTTON_CONNECT_ACTIVEX_CONTROL”和“IDC_BUTTON_DIS_CONNECT_ACTIVEX_CONTROL” B. 添加响应函数 a) 分别双击“连接ActiveX对象”和“断开ActiveX对象”按钮,VC为 我们添加了“OnButtonConnectActivexControl”和 “OnButtonDisConnectActivexControl”函数 b) 在响应函数中添加以下代码: void CIntroductionDlg::OnButtonConnectActivexControl() { // TODO: Add your control notification handler code here app_events_pcdlrn.Connect(); // 连接 } void CIntroductionDlg::OnButtonDisConnectActivexControl() { // TODO: Add your control notification handler code here app_events_pcdlrn.Disconnect(); // 断开 } 三(为ActiveX控件添加事件响应 A. 添加响应函数 a) 右击主对话框界面中的ActiveX控件,并在弹出的菜单中选择 “Events…” b) VC弹出“New Windows Message and Event Handlers for class CIntroductionDlg”对话框。 在该对话框中选择IDC_APPEVENTSCTRL1控件,在该控件的事件中选 择OnEndExecution事件,并点击Add Handler按钮,VC为我们添 加了事件响应(机制和)函数OnOnEndExecutionAppeventsctrl1。 用同样的方法添加对OnOpenPartProgram事件的响应函数 OnOnOpenPartProgramAppeventsctrl1。 c) VC为我们添加的代码如下。注意VC使用EVENTSINK_MAP(类似于 MESSAGE_MAP)实现了控件消息对函数的调用。 BEGIN_EVENTSINK_MAP(CIntroductionDlg, CDialog) //{{AFX_EVENTSINK_MAP(CIntroductionDlg) ON_EVENT(CIntroductionDlg, IDC_APPEVENTSCTRL1, 4 /* OnEndExecution */, OnOnEndExecutionAppeventsctrl1, VTS_DISPATCH VTS_I4) ON_EVENT(CIntroductionDlg, IDC_APPEVENTSCTRL1, 6 /* OnOpenPartProgram */, OnOnOpenPartProgramAppeventsctrl1, VTS_DISPATCH) //}}AFX_EVENTSINK_MAP END_EVENTSINK_MAP() void CIntroductionDlg::OnOnEndExecutionAppeventsctrl1(LPDISPATCH PartProg, long TerminationType) { // TODO: Add your control notification handler code here } void CIntroductionDlg::OnOnOpenPartProgramAppeventsctrl1(LPDISPATCH PartProg) { // TODO: Add your control notification handler code here } B. 编辑函数代码。 根据要实现的功能,我们在VC自动添加的函数中输入如下代码。笔者还添加了一个名为“ExportDimensions”的函数用来执行数据输出。 void CIntroductionDlg::ExportDimensions() { // 这是一个空函数,函数代码请您根据前面章节的内容自己完成。 } BEGIN_EVENTSINK_MAP(CIntroductionDlg, CDialog) //{{AFX_EVENTSINK_MAP(CIntroductionDlg) ON_EVENT(CIntroductionDlg, IDC_APPEVENTSCTRL1, 4 /* OnEndExecution */, OnOnEndExecutionAppeventsctrl1, VTS_DISPATCH VTS_I4) ON_EVENT(CIntroductionDlg, IDC_APPEVENTSCTRL1, 6 /* OnOpenPartProgram */, OnOnOpenPartProgramAppeventsctrl1, VTS_DISPATCH) //}}AFX_EVENTSINK_MAP END_EVENTSINK_MAP() void CIntroductionDlg::OnOnEndExecutionAppeventsctrl1(LPDISPATCH PartProg, long TerminationType) { // 输出测量结果 AfxMessageBox("测量程序执行结束,现在导出测量数据。",MB_ICONINFORMATION); ExportDimensions(); } void CIntroductionDlg::OnOnOpenPartProgramAppeventsctrl1(LPDISPATCH PartProg) { // 局部变量声明 IPartProgram prg_pcdlrn; // 测量程序对象 ICommands cmds_pcdlrn; // 测量命令集合对象 ICommandWrapper cmd_pcdlrn; // 测量命令对象 CString msg; // 用于显示在对话框中的消息字符串 LONG lCmdNumber; // 测量程序中的命令个数 LONG l; // 循环变量 prg_pcdlrn.AttachDispatch(PartProg); // 连接测量程序 cmds_pcdlrn=prg_pcdlrn.GetCommands(); // 连接命令集合对象 lCmdNumber=cmds_pcdlrn.GetCount(); // 取得命令个数 msg="您刚才打开的测量程序中使用的测针名称为:\""; // 初始化消息 // 遍历所有命令,找出第一支测针名称,并警告操作者 for(l=1;l<=lCmdNumber;l++) { cmd_pcdlrn=cmds_pcdlrn.Item(COleVariant(l)); // 连接命令 // “61” 是测量命令类型,代表“Load Probe”命令 if(cmd_pcdlrn.GetType()!=61) { continue; } // 将测针名称加入到消息中 // 为何DataType是“152”,请参考第六章末尾的说明 msg+=cmd_pcdlrn.GetText(152,0); msg+="\"\n"; msg+="请确认机器上是否安装了正确的测针,"; // 保证对话框不被任何窗口挡住。要求操作者确认测针 AfxMessageBox(msg,MB_SYSTEMMODAL|MB_SETFOREGROUND|MB_ICONQUESTION); // 找到第一根测针就结束 break; } cmds_pcdlrn.ReleaseDispatch(); // 释放命令集合 prg_pcdlrn.ReleaseDispatch(); // 释放测量程序 } 四(编译和链接,测试功能 A. 启动二次开发程式,主界面如下: B. 点击“连接ActiveX对象按钮” C. 在编辑框中输入程式路径,点击“打开测量程式”按钮。PC-DMIS打开测量程 式后,Introduction监听到了该消息,它检查测量程式后,提示确认测针: D. 点击“启动程式运行”按钮,测量程式开始执行。程式执行结束后,Introduction 监听到了该消息。它弹出以下对话框: E. 点击“断开ActiveX对象”按钮,再次执行测量程序或打开测量程序, Introduction不会有任何反应,因为它已经“听不到”PC-DMIS发出的任何消 息了。 注: 1( 搜索Load Probe命令时,使用的判断语句如下: if(cmd_pcdlrn.GetType()!=61) { continue; } 代码中的“61” 是测量命令类型,代表“Load Probe”命令。 PC-DMIS给每种命令类型赋予了一个长整型的编号。在遍历命令时我们经常需要判断命令的类型。 取得命令类型的方法如下: A( 在PC-DMIS测量程式中插入一条该类型的命令 B( 在编辑窗口中点击右键,在弹出的菜单中选择“Change Pop-up Display / Command Information” C( 将光标放在要了解类型的命令上,停留片刻,PC-DMIS弹出TIP框,在其中显示了命令类型 2( PC-DMIS发出事件消息后,在响应该消息的函数返回之前,PC-DMIS一直处于等待状态中。若等待时 间过长,PC-DMIS会弹出以下对话框。此时尽快响应开发程式的对话框或其它提示,让响应函数返回, 然后点击“切换到(S)„”或“重试(R)”按钮(可能需要多点几次)即可。若事件响应函数的处理 过程较长,或必须要人为响应时,上述情况会经常出现。要避免出现此种情况,您必须让事件响应函数 尽快返回。 第九章( 后记 PC-DMIS提供了丰富的二次开发接口,我们利用它,能够开发出功能强大的程序,大幅提高检测工作的品质和效率。 本文中所述的方法和范例,仅是冰山一角,对许多问题都没有深入探讨。若您未从事过PC-DMIS二次开发,希望您花费宝贵的时间阅读后,能够有一个比较清晰的思路,笔者就觉得非常欣慰了。 笔者曾制作二次开发程式数十个,并在使用人员的督促下,不断升级改进。这种开发和改进的经历对于自己能力的提升非常有好处。 如果您对二次开发有兴趣,不妨也多编写程式,并多吸收使用者的意见,不断改进提升应用技巧。 愿您早日编写出强大好用的二次开发程式,让PC-DMIS创造出更大的价值。 若您在开发过程中有任何疑问,可发邮件到笔者的邮箱探讨。然笔者并不是经常使用该邮箱,若未能及时回复,请勿见怪。笔者的邮箱是:anby_vip@vip.sina.com。 全文完
本文档为【如何用VC6进行PC-DMIS二次开发(初级)】,请使用软件OFFICE或WPS软件打开。作品中的文字与图均可以修改和编辑, 图片更改请在作品中右键图片并更换,文字修改请直接点击文字进行修改,也可以新增和删除文档中的内容。
该文档来自用户分享,如有侵权行为请发邮件ishare@vip.sina.com联系网站客服,我们会及时删除。
[版权声明] 本站所有资料为用户分享产生,若发现您的权利被侵害,请联系客服邮件isharekefu@iask.cn,我们尽快处理。
本作品所展示的图片、画像、字体、音乐的版权可能需版权方额外授权,请谨慎使用。
网站提供的党政主题相关内容(国旗、国徽、党徽..)目的在于配合国家政策宣传,仅限个人学习分享使用,禁止用于任何广告和商用目的。
下载需要: 免费 已有0 人下载
最新资料
资料动态
专题动态
is_721103
暂无简介~
格式:doc
大小:1MB
软件:Word
页数:74
分类:互联网
上传时间:2017-09-21
浏览量:1057