为了账号安全,请及时绑定邮箱和手机立即绑定

Matlab.NET混合编程调用Figure窗体

标签:
C

阅读目录

  • 1.前言

  • 2.Matlab.NET混合编程概述 

  • 3.MatlabFigure控件的封装过程

              本博客所有文章分类的总目录:【总目录】本博客博文总目录-实时更新

      Matlab和C#混合编程文章目录 :【目录】Matlab和C#混合编程文章目录

回到目录

1.前言

做Matlab.NET混合编程好几年了,虽然Matlab很多函数忘记得差不多了,但基本的东西还是能熟练使用。特别是在C#调用Matlab函数这方面,积累了比较多的经验,和使用经验密切相关。根据很多朋友经常遇到的WinForm窗体混编调用Matlab的Figure的问题,花了一些功夫,把这个封装为C#控件,使得大家可以很容易调用Matlab的Figure了。 

回到目录

2.Matlab.NET混合编程概述 

这方面就不仔细阐述了,主要是利用Matlab的Deploytool工具将m函数编译为.NET程序集,然后在C#中调用的过程。然后程序可以在安装MCR的机器上运行,这个过程如果懂Matalb和C#的人,其实看看帮助很容易理解,也有例子。在这里不仔细讲解。2012年,我录制过国内第一套Matlab.NET混合编程视频教程,与ILoveMatab论坛的管理员Math商量之后,已经免费开放,大家去论坛下载即可。 

混合编程最重要的是利用matlab的科学计算功能和强大的工具箱函数。但目前很多学生做这个,都只是为了简单的绘图,.NET绘图其实也很强大。很多人混编,就想把Matlab绘图产生的Figure在WinForm窗体中显示,但是Matlab并没有提供直接的解决方法。只能找另外的方法,我目前想到的有2种: 

1.先把Figure保存为图片,然后WinForm窗体去读取图片; 

2.利用Windows API 技术,动态的获取窗体句柄,然后嵌入到WinForm中。

 第一种方法很容易想到,也很容易解决,就不仔细讲了。

 第二中方法懂开发的人一般能想得到,但是学生一般不是很容易想到,即使想到,做出来也很难。

 下面我就把第二种方法的实现过程讲解一下。

回到目录

3.MatlabFigure控件的封装过程

控件的设计思想:

1.能够在WinForm桌面程序调用Matlab混编产生的Figure,主要是根据Figure的标题文字

2.Figure嵌入在控件C中,C的大小应该和Figure的大小一致,程序只需要关心控件的大小状态就可以

3.初始化的时候,Figure的大小根据控件C的大小进行调整

4.Figure的大小将随着控件的大小改变而改变

其实根据上面阐述的原理,精通Windows API的人很快就可以解决,主要就这么几个函数,我贴一下代码: 

复制代码

 1 DllImport("user32.dll")] 2 public static extern IntPtr FindWindow(string lpClassName, string lpWindowName); 3  4 [DllImport("user32.dll")] 5 public static extern bool MoveWindow(IntPtr hWnd, int X, int Y, int nWidth, int nHeight, bool bRepaint); 6  7 [DllImport("user32.dll")] 8 public static extern IntPtr SetParent(IntPtr hWndChild, IntPtr hWndNewParent); 9 10 [StructLayout(LayoutKind.Sequential)]11 public struct RECT12 {13     public int left;14     public int top;15     public int right;16     public int bottom;17 }18 19 [DllImport("user32.dll")]20 public static extern int GetClientRect(IntPtr hwnd, ref RECT rc);21 22 [DllImport("user32.dll", EntryPoint = "SendMessage")]23 private static extern int SendMessage(IntPtr hwnd, int wMsg, int wParam, int lParam);24 25 /// <summary>最大化窗口,最小化窗口,正常大小窗口26 /// nCmdShow:0隐藏,3最大化,6最小化,5正常显示27 /// </summary>28 [DllImport("user32.dll", EntryPoint = "ShowWindow")]29 public static extern int ShowWindow(IntPtr hwnd, int nCmdShow);30 31 [DllImport("user32.dll")]32 public static extern bool GetWindowRect(IntPtr hwnd, out RECT lpRect);33 34 35 public class _SW36 {37     public const int SW_HIDE = 0;38     public const int SW_SHOWNORMAL = 1;39     public const int SW_SHOWMINIMIZED = 2;40     public const int SW_SHOWMAXIMIZED = 3;41     public const int SW_MAXIMIZE = 3;42     public const int SW_SHOWNOACTIVATE = 4;43     public const int SW_SHOW = 5;44     public const int SW_MINIMIZE = 6;45     public const int SW_SHOWMINNOACTIVE = 7;46     public const int SW_SHOWNA = 8;47     public const int SW_RESTORE = 9;48 }

复制代码

 

在Figure窗体显示后,通过FindWindow("SunAwtFrame", figureTitleName);来动态获取窗体的句柄,注意Figure的类型都是”SunAwtFrame”,这个要专业点的软件查出来。获取窗体之后,然后通过 SetParent和MoveWindow来设置子窗体,并改变窗体的大小。控件的详细代码就不贴了,主要是上面的封装过程吧,把逻辑搞懂了,很容易。由于源代码是给商业项目使用,暂时不开放。贴一段窗体寻找的代码,为了防止Figure还未显示,程序已经在寻找,特意加了一个延时: 

复制代码

 1 #region 寻找窗体 2 int num = 0 ; 3 while (num <5 ) 4 { 5     num++; 6     //若找不到窗体,循环5次,每次100ms 7     if (wf == IntPtr.Zero) 8     { 9         wf = FindWindow("SunAwtFrame", figureTitleName);                    10         Thread.Sleep(timeSpan);11     }12     else13     {   //找到隐藏起来14         ShowWindow(wf, _SW.SW_HIDE);break;15     }16 }           17 if (wf == IntPtr.Zero)18 {19     MessageBox.Show("无法获取Figure窗体,请确认信息是否正确");20     return;21 }22 #endregion

复制代码

 看看效果图:


点击查看更多内容
TA 点赞

若觉得本文不错,就分享一下吧!

评论

作者其他优质文章

正在加载中
  • 推荐
  • 评论
  • 收藏
  • 共同学习,写下你的评论
感谢您的支持,我会继续努力的~
扫码打赏,你说多少就多少
赞赏金额会直接到老师账户
支付方式
打开微信扫一扫,即可进行扫码打赏哦
今天注册有机会得

100积分直接送

付费专栏免费学

大额优惠券免费领

立即参与 放弃机会
意见反馈 帮助中心 APP下载
官方微信

举报

0/150
提交
取消