LabVIEW和LabWindows/CVI前面板界面中嵌入word等Office办公软件

在使用office办公软件的过程中,有时为了使用方便,通常会将如word,excel等嵌入到程序界面中。LabVIEW与LabWindows/CVI中同样支持这一功能,只需要提供相关的ActiveX插件就行。
ActiveX控件基于COM服务器进行操作,且与开发平台无关,因此,在一种编程语言上开发的ActiveX控件无需任何修改,就可在另一种编程语言中使用。由于其可重用性的特点,目前,除操作系统本身提供的ActiveX控件外,在网络资源上也能得到相当多的ActiveX控件,可以帮助我们完成各种各样的软件开发任务。
下面通过一个例子说明在LabVIEW和LabWindows/CVI平台中使用ActiveX控件编程的方法实现将如word,excel等嵌入到程序界面中。 需要的插件为:Edrawoffice Viewer ActiveX Control,Edraw office Viewer ActiveX Control不免费,使用介绍后总会弹出提示对话框,但不影响使用,当然也可以自己在网上找免费的资源。安装步骤如下:
1、 安装Edraw OfficeViewer ActiveX Control,安装完后在安装路径下找到redist文件夹,里面有32位和64位的officeviewer.ocx文件,其实我们需要的只是这个文件,即使电脑上不安装Edraw Office Viewer ActiveX Control,只要注册这个文件就可以了。
2、 需要手动注册officeviewer.ocx文件,注册方法如下:officeviewer.ocx下载放在目录c:\windows\syswow64目录下。CMD管理员运行,命令行中输入regsvr32 c:\Windows\SysWOW64\officeviewer.ocx(相应控件名)
3、 注册之后打开LabVIEW,在新建VI前面板中插入状态栏控件的方法为,在前面板“ActiveX容器”控件的右键菜单中选择“插入ActiveX对象...”命令,弹出“选择ActiveX对象”对话框,选择”Edraw OfficeViewer Component”,如图1所示。此时前面板中ActiveX容器显示如图2所示;


同样在LabWindows/CVI中,注册之后打开LabWindows/CVI,在新建uir前面板中鼠标右键快捷菜单选择ActiveX…,右键插入ActiveX对象,找到”Edraw OfficeViewer Component”,添加到面板上。如图3所示。此时前面板中ActiveX容器显示如图4所示;注意:在LabWindows/CVI中,需要引入引入了fp和.h文件 。步骤如下:右键菜单---》Generate ActiveX Control Driver创建控件驱动,也就是引入一堆操作头文件,否则无法编码操作。


LabVIEW前面板设计
本例VI程序运行前面板如图所示,在前面板上中间位置调用了我们已经注册好的ActiveX控件——“Edraw OfficeViewer Component”,当按下面板上的”打开文件”按钮,会弹出选择文件对话框,选择相应的文件后,word文档会显示在界面上;当我们在控件内修改文件后,点击”修改文件”按钮后,源文件的内容会被修改;点击“退出”按钮则退出程序。

LabVIEW程序框图的代码实现
本例程序框图使用了事件结构,在事件结构中响应前面板的所有命令按钮的“值改变”事件。通过事件结构我们可以实现我们所要求的功能。部分程序框图如下:

首先说明一下什么是属性,属性是指对象(如控件、VI或应用程序等)的特性,相当于C++类中的数据。具有“可读”、“可写”或“可读写”等操作方式。在程序框图中的属性节点函数上有一个小箭头,若在左边,表明该属性可写,若在右边,表明该属性可读。对于可读可写的属性,右键单击属性节点中的某个属性,可以在右键菜单中选择“转换为读取”或“转换为写入”,在两者之间进行切换。关于属性节点的生成不在本文论述的范围内。
LabWindows/CVI前面板设计
本例程序运行前面板如图所示,在前面板上的中间位置调用了操作系统提供的ActiveX控件——“Edraw OfficeViewer Component”, 当按下面板上的”生成报表”按钮,会自动生成报表;当按下面板上的”阅读报表”按钮,word报表文档会显示在界面上;当我们在控件内修改文件后,点击”修改报表”按钮后,源文件的内容会被修改;点击“退出”按钮则退出程序。

LabWindows/CVI程序的代码实现:

部分代码如下:
#include <cvirte.h>
#include <userint.h>
#include "wordreport.h"
#include "word.h"
#include <utility.h>
#include "report.h"
#include "officeviewer.h"
#define rowNum 1
static int panelHandle;
static CAObjHandle appHandle = 0;
static CAObjHandle docHandle = 0;
static CAObjHandle tablesHandle = 0;
static CAObjHandle columnsHandle=0;
static CAObjHandle borderHandle=0;
static CAObjHandle bordersHandle=0;
static CAObjHandle rowHandle=0,rowsHandle=0;
static CAObjHandle shadingHandle=0;
static CAObjHandle wordhandle=0;
char WordFileName[MAX_PATHNAME_LEN]={0};
int main (int argc, char *argv[])
{
if (InitCVIRTE (0, argv, 0) == 0)
return -1; /* out of memory */
if ((panelHandle = LoadPanel (0, "report.uir", PANEL)) < 0)
return -1;
DisplayPanel (panelHandle);
RunUserInterface ();
DiscardPanel (panelHandle);
return 0;
}
……
int CVICALLBACK Read (int panel, int control, int event,
void *callbackData, int eventData1, int eventData2)
{
switch (event)
{
case EVENT_COMMIT:
GetObjHandleFromActiveXCtrl (panelHandle, PANEL_EDOFFICE, &wordhandle);
GetProjectDir(WordFileName);
strcat(WordFileName,"\\model\\report.docx");
EDOfficeLib__DEDOfficeOpenWord (wordhandle, NULL, WordFileName, CA_DEFAULT_VAL, CA_DEFAULT_VAL, CA_DEFAULT_VAL, CA_DEFAULT_VAL,
CA_DEFAULT_VAL, CA_DEFAULT_VAL, CA_DEFAULT_VAL, CA_DEFAULT_VAL, CA_DEFAULT_VAL, NULL);
CA_DiscardObjHandle(wordhandle);
break;
}
return 0;
}
int CVICALLBACK Save (int panel, int control, int event,
void *callbackData, int eventData1, int eventData2)
{
switch (event)
{
case EVENT_COMMIT:
GetObjHandleFromActiveXCtrl (panelHandle, PANEL_EDOFFICE, &wordhandle);
GetProjectDir(WordFileName);
strcat(WordFileName,"\\model\\report.docx");
EDOfficeLib__DEDOfficeSaveAs (wordhandle, NULL, WordFileName, CA_DEFAULT_VAL, NULL);
CA_DiscardObjHandle(wordhandle);
break;
}
return 0;
}
EDOfficeLib__DEDOfficeOpenWord函数用于word文件的打开,其声明如下:
HRESULT EDOfficeLib__DEDOfficeOpenWord(CAObjHandle Object_Handle, ERRORINFO *Error_Info,const char *File_Name,VARIANT Confirm_Conversions, VARIANT Read_Only,VARIANT Add_To_Recent_Files,VARIANT Password_Document,VARIANT Password_Template, VARIANT Revert,VARIANT Write_Password_Document,VARIANT Write_Password_Template, VARIANT Format,VBOOL *Return_Value);
EDOfficeLib__DEDOfficeSaveAs函数用于office文件的保存,其声明如下:HRESULT EDOfficeLib__DEDOfficeSaveAs (CAObjHandle Object_Handle,ERRORINFO *Error_Info,const char *File_Path,VARIANT File_Format,VBOOL *Return_Value);
结论
由上面的例子可以看出,ActiveX控件类似于LabVIEW和LabWindows/CVI本身的控件,具有独立的显示界面,以及独立的属性、方法甚至事件,在系统中安装注册一个ActiveX控件后,操作系统中所有应用程序都可以使用这个控件,同时,LabVIEW和LabWindows/CVI语言调用ActiveX控件的编程也相对比较简单。