您的位置:首页 > 编程语言 > MATLAB

Matlab与COM应用(三)——Matlab COM客户端支持

2013-01-14 15:39 465 查看
转自 http://www.matlabsky.com/forum.php?mod=viewthread&tid=1165
将Matlab作为客户端应用程序,就是编写M语言或者在Matlab命令行中利用Matlab提供的COM客户端函数来实现COM对象的创建、属性的访问、方法的执行和事件的响应。从而实现应用程序的集成。

在matlab天空中,我们讲到Matlab作为客户端的时候,有两种进程:
内进程:Matlab调用DLL文件或者ActiveX控件(比如MSCal.Calendar)
外进程:Matlab调用EXE文件或者应用程序(比如Excel)

由于两者是不同的东西,故需要使用不同的创建函数
ActiveX控件:actxcontrol
Application程序:actxserver

但是对两者的所有操作(属性、方法和事件)都是一致的,故在下面的所有讲解中,我们都会只是以ActiveX控件为例子说明,至于应用程序(外进程)的操作没有特殊说明,则与ActiveX完全一致。

在本节我们主要讲到下面的内容:

1.ProgID查询
2.创建COM对象
3.COM对象属性
4.COM对象方法
5.COM对象事件
6.COM相关其他函数
7.COM应用实例
a.Matlab调用ActiveX控件——MWsamp
b.Matlab调用Excel软件编程
c.将Matlab图像和Simulink框图保存到Powerpoint

在正式讲解之前我想说明下三个在COM中经常用到的概念(如果说学过VB的网友应该不会太陌生):

属性:就是对象保存的数据或者信息,可以直接访问或赋值,比如颜色、位置
方法:对象定义的函数,用来实现对象的某一种动作或行为,比如添加、删除
事件:触发某种回调的手段,相当于Matlab的callback,比如单击、双击

1、ProgID的查询

每个COM组件都由唯一的标识符ProgID区别,它是字符串,由商家定义。在编程时,我们需要通过这个唯一的标识符来调用相关组件。

但是我的PC上到底有哪些COM对象和它们的ProgID到底是多少,是进行COM客户端编程的前提。

下面我们讲解下如何查询PC中现有的COM组件:

注意:只有ActiveX可以查询,应用程序的ProgID是没法直接查询的,你只能从厂商那里获取,或者网上找找,故下面的方法只是针对ActiveX而言的。

1、actxcontrollist

此时获取PC中所有ActiveX列表,返回的是一个n*3的cell行数据,每行对应一个COM对象(ActiveX控件)的具体信息,包括名称、ProgID和路径。其实我们需要的就是那个ProgID。

>> info=actxcontrollist%看看PC上有那些ActiveX控件,返回n*3的cell,每行对应一个控件的名称、ProgID和路径

info =

[1x31 char] [1x24 char] [1x31 char]

[1x32 char] [1x25 char] [1x31 char]

'AGMEvents Class' [1x22 char] [1x61 char]

[1x29 char] [1x21 char] [1x57 char]

[1x20 char] [1x20 char] [1x64 char]

%由于太多,限于版面,我这里只是列出一部分

%下面看看第3个控件的详细信息

>> inf0{3,:}%不要与我说cell数据不会操作,如果是,查看帮助文档

ans =

AGMEvents Class%控件名称

ans =

AGApplet.AGMEvents.110%控件ProgID

ans =

C:\Program Files\Ansys Inc\v110\AISOL\AGP\intel\AGAppletU.dll%控件路径,可以看出是ansys的一个东东

复制代码

2、actxcontrolselect

在Matlab中输入actxcontrolselect,将以GUI的形式展现PC上所有的ActiveX,并可直接创建相关ActiveX的COM组件

<ignore_js_op>


3、优化大师ActiveX搜索

<ignore_js_op>


2、创建COM对象

在1#和http://www.matlabsky.com/thread-1164-1-1.html我们讲过
Matlab作为客户端的时候,有两种进程:
内进程:Matlab调用DLL文件或者ActiveX控件(比如MSCal.Calendar)
外进程:Matlab调用EXE文件或者应用程序,其实也可以叫自动化服务(比如Excel)

由于两者是不同的东西,故需要使用不同的创建函数
ActiveX控件:actxcontrol
Application程序:actxserver

1、创建COM ActiveX控件

(1)使用actxcontrol命令

ch = actxcontrol('progid',position,fig_handle,event_handler)

progid:控件的ID,可以通过actxcontrollist查询
position:控件的位置,在figure中的相对位置,[Left Botton Length Height]
fig_handle:句柄,表示在哪个figure中显示,也就是指定控件的装载“容器”
event_handle:事件句柄,就是控件的回调函数的句柄
ch:创建的控件的句柄

注意:由于应用程序没法在figure上显示,故progid必须是控件的ProgID

>>s=get(0,'screensize');

>>fh=figure('position',[s(3)/4 s(4)/4 s(3)/2 s(4)/2],'menubar','none','name','ActiveX Control Demo——by Matlabsky','numbertitle','off','resize','off');

>>ch=actxcontrol('mscal.calendar',[0 0 s(3)/2 s(4)/2],fh)

复制代码

此时创建了一个位于windows屏幕中央的figure(ActiveX的容器),figure中装载着'mscal.calendar'(微软日历)控件

<ignore_js_op>


(2)使用actxcontrolselect命令

在Matlab中输入actxcontrolselect,将以GUI的形式展现PC上所有的ActiveX,并可直接创建相关ActiveX的COM组件

<ignore_js_op>


2、创建COM自动化服务

sh=actxserver('ProgID','pcname')

progid:应用程序(服务进程)的ID,通过厂商获取
pcname:当使用远程应用程序时,需要输入远程计算机名或者IP地址
sh:返回创建的服务的句柄

>>sh=actxserver('excel.application');

>>sh.visible=1;

复制代码

此时会启动MS的Excel应用程序

注意:我们常遇到的在word或者excel中调用Matlab的,那是Matlab是服务器了,不是现在的客户端

<ignore_js_op>


2009-4-16 11:52:12 上传

下载附件 (40.5 KB)

3、COM对象属性设置和获取

现在终于进入到Matlab COM客服端的核心内容了,前面的知识都是铺垫而已。从现在开始正式对COM组件进行操作!

在这里我们主要涉及下面三个内容:
(1)属性的查询
(2)属性获取和设置
(3)添加和删除自定义属性

由于的COM ActiveX控件和COM自动化服务的属性设置、方法条用和事件触发大同小异,没有太大的区别,在没有特殊说明的情况下,则基本完全一致。故在下面的教程中,我们大部分以ActiveX控件进行举例说明,希望大家能举一反三。

为了好下面的说明,我们先建立两个COM对象,图像参见3#

%创建一个ActiveX控件

s=get(0,'screensize');

fh=figure('position',[s(3)/4 s(4)/4 s(3)/2 s(4)/2],'menubar','none','name','ActiveX Control Demo——by Matlabsky','numbertitle','off','resize','off');

ch=actxcontrol('mscal.calendar',[0 0 s(3)/2 s(4)/2],fh);%control handle

%创建一个自动化服务

>>sh=actxserver('excel.application');%server handle

>>sh.visible=1;

复制代码

1、属性查询

要进行属性设置和获取,当然先要知道我们的ActiveX控件到底有那些属性了,在这里我们只要有两种方法:

(1)inspect(ch)
使用Matlab的属性查看器(Properties Inspector)打开控件的属性页,在这里我们不光可以直接进行查询还可以属性设置。其实,在工作空间中双击ActiveX对象句柄也可以打开该属性面板。

<ignore_js_op>


(2)propedit(ch)
打开控件自带(内建)的属性设页,同样我们可以进行属性获取和设置。注意不是所有的COM对象都有内建属性页的

<ignore_js_op>


其实我们还可以通过其他非正式方法获取对象属性,比如在使用actxcontrolselect创建控件的时候就可以直接设置属性,还有get/set(ch)就可以直接获取所有属性。

2、属性获取和设置

这里提供三种方法,具体使用那种可以根据自己的偏爱,但是各种方法的优缺点和实质,我在下面都进行了详细分析。

(1)Matlab经典格式get(ch)/set(ch)
get(ch,'pro')或者get(ch):属性获取
set(ch,'pro','value')或者set(ch):属性设置

当pro属性为空的时候,get(ch)返回控件ch的所有属性的当前值;set(ch)返回ch的所有属性,此时属性值全部为空

此时的get/set函数是Matlab的内部函数,该方法同时设置和获取多个控件、多个属性并且属性名大小写无所谓,但必须使用“'”封闭,对Matlab句柄对象或者GUI熟悉的网友来说这个是会很顺眼的。

>> get(ch)%由于版面这里只列出一部分

BackColor: 2147483663

Day: 5

DayFont: [1x1 Interface.Standard_OLE_Types.Font]

DayFontColor: 0

DayLength: 1

FirstDay: 7

>> set(ch)

ans =

BackColor: {}

Day: {}

DayFont: {}

DayFontColor: {}

DayLength: {}

FirstDay: {}

>>get(ch,{'value','year','month','day'})%使用cell类型,同时获取控件ch的4个属性

ans =

'2009-4-16' [2009] [4] [16]

>>set(ch,{'month','day'},{12,5})%同时设置月份和日期两个属性,现在应该是12月5号

复制代码

看看下面两幅图的日期是否改变了,设置后是不是2009.12.5

<ignore_js_op>


下面再演示下,同时获取和设置多个对象的属性,set/get的更多应用以参考Matlab的帮助文档

f=figure('position',[100 100 500 400],'name','Multi-Pros Demo——by Matlabsky');

h1=actxcontrol('mscal.calendar',[0 200 250 200],f);

h2=actxcontrol('mscal.calendar',[250 200 250 200],f);

h3=actxcontrol('mscal.calendar',[0 0 250 200],f);

h4=actxcontrol('mscal.calendar',[250 0 250 200],f);

H=[h1,h2,h3,h4];

set(H,'day',15);

复制代码

<ignore_js_op>


(2)VB经典的结构体点连接格式
ch.pro:属性获取
ch.pro=value:属性设置

该格式是VB的经典结构体形式,使用过VB的网友一定会比较熟悉。同样此时的pro不区分大小写,但是每次只能设置和获取一个属性

>> [ch.day ch.DAY ch.dAy]%参数获取,我们可以看出,pro不区分大小写

ans =

5 5 5

>> ch.day=10%直接赋值就将日期设置为10,注意此时返回的是ch的类型不是日期

ch =

COM.mscal_calendar

>> ch.day%看看日期是不是修改了

ans =

10

复制代码

(3)点连接和函数调用综合使用形式
ch.get('pro')或者ch.get():属性获取
ch.set('por','value')或者ch.set():属性设置

由于使用方法和(1)的一致,只是将那个ch放在前面并使用“.”连接而已,具体使用就不再重复了

注意此时的get/set不再是Matlab的那个get/set了,这个是Matlab自动在所有ActiveX控件中添加的方法,也即是说它们是控件ch的一个方法,但是该方法具有Matlab中get/set的所有功能,故该格式综合VB和Matlab的性质。VB的结构体点连接和Matlab的多个属性同时调用

另外我们还可以在工作空间(workspace)中直接双击对象变量名,打开属性查看器,直接查看和编辑属性

3、属性添加和删除

有些情况下控件自带的属性不能够满足我们的需求,此时我们需要向控件添加自己的属性。恩,Matlab为我们呢提供了addproperty和deleteproperty函数,注意这两个函数同get/set一样,既是Matlab内函数,也是控件的方法(Matlab自动为每个控件添加的,而不是控件自带的),当然使用方法和注意事项和get/set很类似了,具体我就不累述了。

ch.addproperty('proname')或者addproperty(ch,'proname'):添加自定义属性
ch.deleteproperty('proname')或者addproperty(ch,'proname'):删除自定义属性

使用上面函数的创建的自定义属性,可以使用get/set命令进行查询和编辑

>>ch.addproperty('copyright');%或者addproperty(ch,'copyright')

>>ch.set('copyright','by matlabsky');%或者set(ch,'copyright','by matlabsky')或者ch.copyright='by matlabsky'

ans =

by matlabsky

>>ch.copyright%或者get(ch,'copyright')或者ch.get('copyright')

>>ch.deleteproperty('copyright');%或者deleteproperty(ch,'copyright')

复制代码

4、COM对象方法调用

所谓方法(methods),就是COM组件对象定义的函数(function),它用来执行对象的某一种动作和行为。

注意:在Matlab创建COM组件时,会自动向组件中添加写方法,比如get/set、invoke、delete等,因此此时控件的方法是有控件自带和Matlab创建的两部分构成的。

对于所有Matlab自动添加的方法,都可以两种执行方式:
(1)Matlab函数调用格式:methodname(ch,var1,var2...),ch是控件句柄,var是参数列表,比如get(ch,'day'),这个只有Matlab自动添加的才有效
(2)点连接函数调用混合方式:ch.methodname(var1,var2),注意大小写必须匹配,和属性的纯点连接形式不一样哦,属性是可以不区分大小写的哦,比如ch.get('day')
(3)使用invoke触发:ch.invoke('methodname',var2,var2...)或者invoke(ch,'methodname',var2,var2...),比如ch.invoke('get','day'),其实这个就是ch.day

对于控件自带的方法,只能使用(2)和(3),比如对于控件自带的NextDay方法,ch.NextDay(注意大小写)是有效的,而nextday(ch)是错误的,因为nextday不Matlab内部函数

因为methodname既是控件的方法,也是Matlab自带函数,因此会出现上面的三种调用格式都是合法的。比如在上一节提到的get/set,还有这一节的invoke等等

1、COM对象方法查询

methods(ch) 显示COM对象ch的所有方法
methods(ch,'-full') 包含每个方法的详细完整说明
methodsview(ch) 使用GUI界面完整的显示所有方法

>> methods(ch)

Methods for class COM.mscal_calendar:

AboutBox NextYear PreviousYear constructorargs get move send

NextDay PreviousDay Refresh delete interfaces propedit set

NextMonth PreviousMonth Today deleteproperty invoke release

NextWeek PreviousWeek addproperty events load save

>> methods(ch,'-full')%由于较多我这里只是列出一些

Methods for class COM.mscal_calendar:

HRESULT AboutBox(handle)

HRESULT NextDay(handle)

。。。。。。。

addproperty(handle, string)

MATLAB array constructorargs(handle)

delete(handle, MATLAB array)

MATLAB array get(handle)

。。。。。。

>> methodsview(ch)

复制代码

<ignore_js_op>


从列表中可以看到,那些以HRESULT作为返回类型的方法,就是控件自带的,而其余都是Matlab自定义的。其实只有列表前头的那些方法才是真正控制对象实现某个功能的。Matlab自定义的只是为了方面执行这些自带的方法。

2、COM对象方法执行(方法很多,但是这里我们只说明使用invoke)

ch.invoke或者invoke(ch)
ch.invoke('methodsname',var1,var2...)或者invoke(ch,'mothodesname',var1,var2...)

第一种形式是返回控件所有自带的方法及具体参数格式,这个与methods函数返回的内容不同
第二种就是执行带输入参数的某个方法

>> ch.invoke

NextDay = HRESULT NextDay(handle)

NextMonth = HRESULT NextMonth(handle)

NextWeek = HRESULT NextWeek(handle)

NextYear = HRESULT NextYear(handle)

PreviousDay = HRESULT PreviousDay(handle)

PreviousMonth = HRESULT PreviousMonth(handle)

PreviousWeek = HRESULT PreviousWeek(handle)

PreviousYear = HRESULT PreviousYear(handle)

Refresh = HRESULT Refresh(handle)

Today = HRESULT Today(handle)

AboutBox = HRESULT AboutBox(handle)

>> ch.invoke('previousweek')%前移一个礼拜

ans =

NaN

复制代码

5、COM对象事件触发

所谓事件,就是触发某种回调的手段,通常通过控件与用户交互的手段触发,响应某些用户的特殊操作。在Matlab中国COM对象能够响应多种事件,比如鼠标单击、改变对象某个属性等等。

当某个事件发生时,需要调用事件的回调函数,在Matlab中的事件发生的时候,Matlab自动调用某个M文件或者Matlab函数来响应。

1、获取对象事件列表(events是Matlab自动添加的方法)

events(ch)
ch.events
ch.invoke('events')或者invoke(ch,'events')
上面三种方式可以达到同样的效果,显示对象ch的所有事件,但是返回的结果有些不同,大家可以比较下

>> events(ch)

Click = void Click()

DblClick = void DblClick()

KeyDown = void KeyDown(int16 KeyCode, int16 Shift)

KeyPress = void KeyPress(int16 KeyAscii)

KeyUp = void KeyUp(int16 KeyCode, int16 Shift)

BeforeUpdate = void BeforeUpdate(int16 Cancel)

AfterUpdate = void AfterUpdate()

NewMonth = void NewMonth()

NewYear = void NewYear()

>> invoke(ch,'events')

ans =

Click: 'void Click()'

DblClick: 'void DblClick()'

KeyDown: 'void KeyDown(int16 KeyCode, int16 Shift)'

KeyPress: 'void KeyPress(int16 KeyAscii)'

KeyUp: 'void KeyUp(int16 KeyCode, int16 Shift)'

BeforeUpdate: 'void BeforeUpdate(int16 Cancel)'

AfterUpdate: 'void AfterUpdate()'

NewMonth: 'void NewMonth()'

NewYear: 'void NewYear()'

复制代码

2、注册事件的响应回调函数

ch.registerevent({'eventname',event_hanle})
registerevent(ch,{'eventname',event_handle})
上面的命令就是给对象的eventname事件,添加回调。注意如果eventname不指定或者为空的话,那默认给ch所有事件添加同一个回调
比如给ch添加如下回调:
先编写单击回调函数click(单击时日历控件会自动将日期切换到那一天):

function click(handles,eventID,eventName,varargin)%输入参数格式必须这么写

%hanles就是COM对象的句柄

%eventID事件的ID

%eventName事件的详细信息包括Type、Source和EventsID

%varargin其它输入参数

disp('执行的是单击(click),日期已改变!')

disp(['您选中的日期为:' handles.value])%会自动切换到点击的那一天

复制代码

再编写双击回调函数dblclick(日历控件没有定义双击,我们设置为前移一个礼拜):

function click(handles,eventID,eventName,varargin)%输入参数格式必须这么写

%hanles就是COM对象的句柄

%eventID事件的ID

%eventName事件的详细信息包括Type、Source和EventsID

disp('执行的是单击(click),日期已改变!')

disp(['您选中的日期为:' handles.value])

复制代码

现在注册两个回调函数:

>>registerevent(ch,{'click',@click,'dblclick',@dblclick})%单击双击分开注册,没有注册的为空

%现在双击和单击试试看看有什么效果

%这里是点击的效果

执行的是单击(click),日期已改变!

您选中的日期为:2009-2-16

%这里是双击的效果,注意此时会先执行单击再执行双击回调,因为双击可以分为按下和弹起

执行的是单击(click),日期已改变!

您选中的日期为:2009-2-24

执行的是双击(dblclick),日期后移一个礼拜!

双击后日期为:2009-2-17

>>registerevent(ch,@click)%此时将所有没有注册事件回调函数设置为click,注意刚才注册双击不会被覆盖

%我们在日历控件上点击、敲下键盘看是不是得到一样的反应,结果如下

%鼠标单击的效果,其实同时执行了多个回调

执行的是单击(click),日期已改变!

您选中的日期为:2009-2-11

执行的是单击(click),日期已改变!

您选中的日期为:2009-2-11

执行的是单击(click),日期已改变!

您选中的日期为:2009-2-11

%敲键盘的效果,其实同时执行了多个回调

执行的是单击(click),日期已改变!

您选中的日期为:2009-2-12

执行的是单击(click),日期已改变!

您选中的日期为:2009-2-12

执行的是单击(click),日期已改变!

您选中的日期为:2009-2-12

复制代码

3、已注册事件查询

有时我们需要知道到底那些事件已注册了,恩,Matlab提供了eventlisteners函数
eventlisteners(ch)或者ch.eventlisteners

>> ch.eventlisteners

ans =

'click' @click

'dblclick' @dblclick

'DblClick' @click

'KeyDown' @click

'KeyPress' @click

'KeyUp' @click

'BeforeUpdate' @click

'AfterUpdate' @click

'NewMonth' @click

'NewYear' @click

复制代码

4、撤销事件回调

unregisterevent(ch,@event_callback)%注销回调函数为event_callback的事件回调
unregisterevent(ch,{'eventname',@event_callback})%注销指定事件的指定回调,注意一次只能撤销一个,如果输入多个那么只是撤销第一个
unregisterallevents(ch)%撤销ch的所有回调,一次性

6、COM相关其他函数介绍

其实前面的介绍已经将Matlab调用其他COM组件讲解的很详细了,并且教程都是按大家思维整理的,详细说明的共同点和差异。接下来就差实践了!

但是为了大家更好的读懂某些应用程序和充分应用COM技术,我再补充几个在COM涉及的函数。

在这里值说明该函数是干什么的,不做具体说明,感兴趣的网友可以直接查看Matlab帮助文档。

delete:程序结束时需要删除创建的COM对象
release:释放接口
interfaces:列出COM对象的自定义端口
isa:判断是不是属于某个类型
iscom:判断是不是COM对象
isevent:判断是否为COM对象的事件(callback)
ismethod:是否为方法
isinterface:是否为接口
isprop:是否为属性
save:将COM对象保存为mat文件
load:从mat文件中加载COM对象
move:移动和重设ActiveX的位置和尺寸

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: