« 上一篇: 最近比较忙“正事”儿了,blog中matlab的文章就没有继续增加多少了~ 下一篇: matlab database工具箱中的几处不爽的地方 »
山城棒棒儿军 @ 2004-05-12 21:49

MATLAB6.x & VC6.0: 将plot图片显示在MFC程序的窗口中
实验环境:
Pwin2K SP3, MATLAB6.5, Visual C++ 6.0 SP?

1 问题的提出

通过调用mcc,可以将MATLAB程序编译为C/C++或库文件,并嵌入到自己的VC应用程序中。该方法不仅适于纯粹的运算代码,也适于图形函数,比如plot等等。不过遇到的问题是,每次调用plot函数,将产生一个新的窗口,这使得我们的VC程序风格不能统一,看起来很别扭。而且,这个跳出来的窗口特征太明显,让人一下子就认出来是MATLAB做的,这在有些时候会让您的客户、老板、同事、同学、gg、mm觉得很不屑:偷懒呐!
那么为了让程序看上去更专业,能否将图片嵌入我们的VC窗口,或者对话框里面,而不让它跳出来呢?


2 分析

实际上,在执行plot之后,执行以下命令:
set(gca)
你会发现有这样一个属性:Parent,它就是该窗口的父窗口,也就是在哪个父窗口中显示。对它进行设置,可以形成复杂的GUI界面,我们看看MATLAB提供的demo就知道了。如果该属性为空,这个plot窗口就会以独立窗口的形式显示出来。
因此,MATLAB的绘图功能本身是支持显示在某个特定父窗口中的。然而遗憾的是,Parent属性不是用Win32的handle指定的,而是用MATLAB的字符串形式的ID。我们在VC中很难利用此功能。


3 逆向思维

既然不能直接把图画在指定窗口中,那么画好后再挪到这个窗口可以吗?
思路就是这么简单,查一下Win32 API,可以找到两个函数:FindWindow和SetParent。顾名思义,我想怎么做,你已经猜出八九分了吧


4 代码实现

核心代码如下:

m_hmat = ::FindWindow(NULL, "Figure No. 1");
::SetParent(m_hmat, m_hWnd);
首先找到窗口名为"Figure No. 1"的窗口的句柄,然后将它的父窗口设置为某个窗口就行了。这段代码包含于个DOC/VIEW结构的MFC程序的View类中,m_hWnd就是该View的窗口句柄。
5 应用实例

应用实例在这里下载:SglMFC.zip
这个程序是以《MATLAB扩展编程》第九章的例子SGLMFC为基础改制的,在SglMFCView.cpp中加入了菜单项Embed及其回调函数OnSGLEmbed。至于如何对该工程进行编译,请参考该书的相关内容。



6 其它细节

几点说明如下:
■ 该程序是个简单的示范程序,编程并不严密。内含debug版本的可执行程序,请严格按照下面流程运行:
 (1) SGL|Start
 (2) SGL|Demo,这时显示出一个plot窗口
 (3) SGL|Embed,plot窗口跑到View中
 (4) 双击窗口栏,充满整个View
 (5) 关闭该窗口
 (6) SGL-Stop
 (7) 退出程序
点击这里看演示结果。

■ 该方法仍然会先显示弹出式plot窗口,为了禁止在VC窗口之外显示plot,应该先用figure命令显示一个隐含的窗口,绘图完毕、并挪动到VC窗口内部后在显示出来,例如
 >> figure('Visible','off')
 >> plot([1:100])
 >> figure(1)

■ 为了去掉plot的菜单和按钮,在相应的MATLAB程序中应该先执行:set(gcf, 'MenuBar','none');

■ 如果显示的图片比较多,就不能用"Figure No. 1"唯一确定各个窗口了,应该是2或者3等等。这需要你用MATLAB代码和VC代码巧妙地编程加以控制

■ 用Win32API还可以将窗口的名字和图标改掉,彻底去除MATLAB的痕迹




5 声明

程序本身并不完善,如果遇到问题,请尽量自己解决




energy
2002.12.3


最新评论 (点击这里查看更早的所有评论...)


星矢

2004-05-21 09:05

呵,谢了,还是我路径没设对!另外有个问题
我的函数声明是这样的
mwArray cube(mwArray * y, mwArray * z, mwArray x0, mwArray y0, mwArray z0)
我调用时,这样声明变量
mwArray X0,Y0,Z0,*X,*Y,Z;
 X0=0;
 Y0=0;
 Z0=0;
 Z=cube(&X,&Y,X0,Y0,Z0);



星矢

2004-05-21 09:05

结果出现了这样的错误
error C2664: 'cube' : cannot convert parameter 1 from 'class mwArray ** ' to 'class mwArray *'
       Types pointed to are unrelated; conversion requires reinterpret_cast, C-style cast or function-style cast
我记得我看过的matlab的C++数学库中的多输入输出就是这样来定义的,怎么回事呢?



山城棒棒儿军

2004-05-21 11:27

我不清楚,其实我还没有做过包含数学库的相关练习
不过你可以根据提示将Z申请为
mwArray *Z;
试试



星矢

2004-05-21 15:53

我试了,好象也不行!
我是用mcc将M文件编译成C++文件,引入工程。
但我看有些文章说,对于较大的程序,编译成dll比较好,这个我没用过,也不知编成dll后如何调用。
不知是不是这样?



hanson

2004-08-21 12:03

你的cube函数是matlab生成的么,如果是的话好像是你的函数原形有问题,第一个参数应该是mxArray **y



江山

2004-11-24 10:07

应用实例在哪?



d.liu

2005-01-12 11:15

实例不能下载啊。想看看实例。我正面对这样的问题。另外,这个思路,是不是对引擎的方式也是适用的吧?谢谢。



Genial

2005-01-12 12:00

这个程序的代码我也没有了
我当时从网上下载后,直接在我的机器上也不可以运行。
对的,这里只是进行的win32API编程,对于引擎方式应该是可以的



边缘

2005-08-03 10:50

libmatlb.hpp这个库在C++的工程设置中如何添加路径怎么设置


2008-05-07 10:09


评论 / 个人网页 / 扔小纸条
* 昵称

已经注册过? 请登录

新用户请先注册 以便能显示头像及追踪评论回复

Email
网址
* 评论
表情
 


 

分类小组论坛
杂谈 , 娱乐、八卦 , 文学、艺术 , 体育 , 旅游、同城 , 象牙塔 , 情感 , 时尚、生活 , 星座 , 科技

请注意遵守中华人民共和国法律法规, 如威胁到本站生存, 将依法向有关部门报告, 同时本站的相关记录可能成为对您不利的证据.

相关法律法规
全国人大常委会关于维护互联网安全的决定
中华人民共和国计算机信息系统安全保护条例
中华人民共和国计算机信息网络国际联网管理暂行规定
计算机信息网络国际联网安全保护管理办法
计算机信息系统国际联网保密管理规定