⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 guivc.txt

📁 将MATLAB窗口画在VC的GUI上 轻松实现用MATLAB和VC画图
💻 TXT
字号:
将MATLAB窗口画在VC的GUI上
山城棒棒儿军 @ 2004-06-29 17:18

将MATLAB窗口画在VC的GUI上 
这几天,根据simwe论坛的scie提供的思路以及源代码,照着练习了一下。估计scie的matlab是6.1的,反正直接下载他的源代码,在我的机器上编译不通过。仔细设置断点,单步调试分析,总算找出了出错的地方,在于函数mlfHGInitialize( ),这个函数的调用方式不对。scie以及何强、何英的《MATLAB扩展编程》一书中讲到的调用方式都是mlfHGInitialize( NULL,NULL)。而我在libsglinit.cpp文件中看到的调用格式只有两种: 
mwLibhgInit( const char *name, mexcpp_information info ) 
     : init(1), mwLibInit( name, info ) { const char *p = "lib"; int argc = 1; mlfHGInitialize( &argc, &p ); } 
 mwLibhgInit(mexcpp_information info) 
   : init(1), mwLibInit(info) { const char *p = "lib"; int argc = 1; mlfHGInitialize( &argc, &p ); } 
 mwLibhgInit(mexcpp_information info, int* argc, const char** argv) 
   : init(1), mwLibInit(info) { mlfHGInitialize(argc, argv); } 
 ~mwLibhgInit() { if (init) {mlfHGWaitForFiguresToDie(); mlfHGTerminate();} } 
因此,照类似的调用方式修改源代码后,程序就能够正常运行了。 
下面说说整个程序的实现步骤及其关键部分。 
我自己的程序是采用matlab数学库编写的,没有利用对m文件进行预先编译的源文件。不过,可以写出m文件,进行编译,采用的命令是: 
mcc -p -W mainhg libmwsglm.mlib drawSin.m 
  经过编译,得到cpp文件,利于自己找到需要的命令。譬如,在编译后的cpp文件中,我找到了Nfigure,Nclose等命令。在基于对话框的VC的MFC界面上画图。具体步骤是: 
1. 在VC中建立一个基于对话框的MFC工程MatVcGUI; 
2. 在Dialog上布置好相应的控件,其中主要有接收输入参数的Edit box控件、画图窗口(将MATLAB的figure放置位置的地方)的Group box控件(IDC_MATDRAW),以及运行按钮控件; 
3. 编写绘图按钮的响应函数大致如下: 
void CMatVcGUIDlg::OnDraw() 
{ 
int bWait = 0; 
if(tobool(isempty(h_a))) 
{ 
    // figure窗口的一些属性设置 
char FigName[]="_Figure_"; 
double BKColor[] = {0.9,0.9,0.9}; 
char strVisible[] = "Off"; 
mwArray mwFigName(FigName); 
mwArray mwBKColor(1,3,BKColor); 
mwArray mwVisible(strVisible); 
    // 根据属性值创建axis对象句柄,稍后解释CreateAxis函数 
h_a = CreateAxis(mwFigName,mwBKColor,mwVisible); 
  //  Win32API函数FindWindow根据窗口名称寻找窗口句柄 
HWND hFig=::FindWindow(NULL,FigName); 
if(hFig == NULL) 
{ 
AfxMessageBox("不能够创建Figure窗口,绘图失败!"); 
return; 
} 
   //  Win32API函数获取窗口属性,具体含义查找MSDN 
long lStyle = ::GetWindowLong(hFig,GWL_STYLE); 
//  Win32API函数设置窗口属性,去掉标题栏与边框 
::SetWindowLong(hFig, GWL_STYLE,lStyle& 
(~WS_CAPTION) & (~WS_THICKFRAME)); 
       // 设置窗口初始位置(反正窗口不可见的,无所谓) 
 ::SetWindowPos(hFig,NULL,0,0,0,0,SWP_NOMOVE | SWP_NOSIZE 
| SWP_NOZORDER | SWP_NOACTIVATE | SWP_FRAMECHANGED); 
RECT PlotRec; 
   // 获得绘图窗口的控件的窗口句柄 
CWnd *PlotArea = GetDlgItem(IDC_MATDRAW); 
// 得到绘图窗口控件(group box)的矩形区域位置 
PlotArea->GetWindowRect(&PlotRec); 
   // 得到绘图窗口控件的宽与高 
long Width = PlotRec.right - PlotRec.left; 
long Height = PlotRec.bottom - PlotRec.top; 
  // 用Win32API函数将figure窗口(hFig)的父窗口设置为绘图窗口控件 
::SetParent(hFig, PlotArea->GetSafeHwnd()); 
  // 用Win32API函数设置figure窗口在绘图窗口控件中的相对位置及其显示风格 
::SetWindowPos(hFig,NULL,1,7,Width-2,Height-10, 
SWP_NOZORDER | SWP_NOACTIVATE); 
// 绘制图形,稍后解释 
DrawSin(); 
  // 将axes的父figure窗口设置为可见,稍后解释 
SetVisible(h_a,mwArray("On")); 
bWait = 1; 
  // 进入窗口等待状态,运行了Vclose()函数后,将接着此句之后往下执行 
mlfHGWaitForFiguresToDie(); 
} 
if(bWait == 0) 
DrawSin(); 
} 
其中,涉及到的几个函数的应用的解释: 
A.  mwArray CMatVcGUIDlg::CreateAxis(mwArray strFigName, 
mwArray BKColor, mwArray strVisible) 
{ 
//hf = figure('NumberTitle','off','Name','testMixFigure','Menubar','none', 
// 'Color',[0.8 0.8 0.8],'visible','off','DoubleBuffer','on'); 
mwArray h_f = figure( 
mwArray("NumberTitle"),mwArray("Off"), 
mwArray("Name"),strFigName,//strFigName, 
mwArray("Menubar"),mwArray("None"), 
mwArray("Color"),BKColor, 
mwArray("Visible"),strVisible,//strVisible, 
mwArray("DoubleBuffer"),mwArray("On")); 
  // h_a = axes('Parent', h_f, 'Box', 'On'); 
mwArray h_a = axes(mwArray("Parent"),h_f,mwArray("Box"),mwArray("On")); 
return h_a; 
} 

B. void CMatVcGUIDlg::DrawSin() 
{ 
UpdateData(TRUE); 
if(tobool(isempty(h_a))) 
OnDraw(); 
else{   
double pi = 3.141592653589793; 
// t=0:0.05:2; 
mwArray t = colon(0,0.05,2); 
  //  y = a* sin(2pi*w*t); 其中a,w是类成员变量,接收输入参数 
//  h_a是类成员变量,为创建的axes对象句柄; 
  mwArray y = a*sin(2*pi*w*t); 
      // plot(t, y, 'Parent', h_a); 
  Vplot(t,y,mwArray("Parent"),h_a); 
} 
} 

C. void CMatVcGUIDlg::SetVisible(mwArray h_a, mwArray strVisible) 
{ 
// h_f = get(h_a,"Parent"); 
mwArray h_f = get(h_a, mwArray("Parent")); 
// set(h_f,"Visible",strVisible); 
   Vset(h_f, mwArray("Visible"), strVisible); 
} 

4. 在BOOL CMatVcGUIDlg::OnInitDialog()中加入如下代码,进行MATLAB的库的初始化: 
   h_a = empty(); 
libmmfileInitialize(); 
libmwsglmInitialize(); 
int argc; 
argc=1; 
const char *p = "lib"; 
mlfHGInitialize(&argc,&p); 

5. 在void CMatVcGUIDlg::OnClose() 加入函数Vclose在退出程序的时候关闭打开的figure窗口。     
void CMatVcGUIDlg::OnClose() 
{ 
// close('all'); 
Vclose(mwArray("all")); 
CDialog::OnClose(); 
} 

6. 在void CMatVcGUIDlg::OnDestroy() 中加入如下代码中止MATLAB的一些库 
   libmwsglmTerminate(); 
libmmfileTerminate(); 
mlfHGTerminate(); 



总结 
1. 用到的Win32API函数: 
FindWindow() 
GetWindowLong() 
SetWindowLong() 
SetWindowPos() 
GetDlgItem() 
GetWindowRect() 
SetParent() 
SetWindowPos() 
具体的使用查找Win32API手册以及MSDN,其实还有很多其他的有用的API函数,有空了解了解Win32API手册。 

2. 用到的MATLAB库函数主要有: 
libmmfileInitialize(); 
libmwsglmInitialize(); 
   mlfHGInitialize(&argc,&p); 
   mlfHGWaitForFiguresToDie(); 
libmwsglmTerminate(); 
libmmfileTerminate(); 
mlfHGTerminate(); 
figure,axes,plot,Vclose等函数,这些函数也可以有其他的一些形式。 
具体的再libmwsglm.hpp中,其中还给出了很多其他函数的原型。在程序调试过程中出现一些错误的时候,应该可以自己想办法在这些头文件中寻找解决办法。涉及绘图的函数主要在libmwsglm.hpp,libsgl.hpp中,想必其他函数(数学库的)也应该在某些头文件中找到他们的声明。 

3. mlfHGWaitForFiguresToDie()函数的作用 
  mlfHGWaitForFiguresToDie()函数使得窗口进入等待状态,没有他,生成的figure立即销毁,在Vclose all之后,返回到该函数的下一个语句接着往下执行。 


 

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -