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