C#调用Matlab画图,figure嵌入到Winform窗体

1 篇文章 1 订阅

C#调用Matlab并嵌入到Winform窗体,可以任意尺寸画图,先看效果:


感谢该博主提供的思路:https://www.cnblogs.com/asxinyu/archive/2013/04/14/3020813.html

一、实现原理:

        需要用到Windows API来设置窗体,用FindWindow查找图像窗体Figure1的句柄,使用SetParent设置Figure1父窗体为Winform的控件Panel,这样就把figure放进Winform里了,之所以放到panel控件里,而不是作为子窗体在winform里,是为了把它当做Winform的一个控件,便于布局。再使用MoveWindow移动到合适的位置,SetWindowLong去掉标题,不能通过边框改变大小,在Winform窗体SizeChanged事件里用MoveWindow改变Figure的大小,就能使Figure的尺寸和窗体同步改变。

      关于第一次调用matlab出图慢问题,可以开个线程循环等待窗体的生成,使用多线程就不会造成UI线程卡顿了。

二、关键代码:

1.使用到的Windows API

        #region //Windows API
        [DllImport("user32.dll")]
        public static extern IntPtr FindWindow(string lpClassName, string lpWindowName);
        [DllImport("user32.dll")]
        public static extern IntPtr SetParent(IntPtr hWndChild, IntPtr hWndNewParent);
        [DllImport("user32.dll", CharSet = CharSet.Auto)]
        public static extern int MoveWindow(IntPtr hWnd, int x, int y, int nWidth, int nHeight, bool BRePaint);

        const int GWL_STYLE = -16;
        const int WS_CAPTION = 0x00C00000;
        const int WS_THICKFRAME = 0x00040000;
        const int WS_SYSMENU = 0X00080000;
        [DllImport("user32")]
        private static extern int GetWindowLong(System.IntPtr hwnd, int nIndex);

        [DllImport("user32")]
        private static extern int SetWindowLong(System.IntPtr hwnd, int index, int newLong);
        [DllImport("user32")]
        private static extern int InvalidateRect(System.IntPtr hwnd, object rect, bool bErase);
        /// <summary>最大化窗口,最小化窗口,正常大小窗口
        /// nCmdShow:0隐藏,3最大化,6最小化,5正常显示
        /// </summary>
        [DllImport("user32.dll", EntryPoint = "ShowWindow")]
        public static extern int ShowWindow(IntPtr hwnd, int nCmdShow);
        #endregion

2.定义全局变量,窗体载入事件

       public delegate void UpdateUI();//委托用于更新UI
        Thread startload;//线程用于matlab窗体处理
        MatlabFunction matlabFunction;//matlab编译的类
        IntPtr figure1;//图像句柄
        private void Form1_Load(object sender, EventArgs e)
        {
            //实例化线程,用来初次调用matlab,并把图像窗体放到winform
            startload = new Thread(new ThreadStart(startload_run));
            //开始线程
            startload.Start();
        }

3.线程执行的方法,每隔50ms查找一下figure窗体,找到嵌入到winform的panel控件里。

        void startload_run()
        {
            int count50ms = 0;
            //实例化matlab对象
            matlabFunction = new MatlabFunction();
            //调用方法画高斯分布函数图
            matlabFunction.mysurf();//高斯分布函数

            //循环查找figure1窗体
            while (figure1 == IntPtr.Zero)
            {
                //查找matlab的Figure 1窗体
                figure1 = FindWindow("SunAwtFrame", "Figure 1");  
                //延时50ms
                Thread.Sleep(50);
                count50ms++;
                //20s超时设置
                if (count50ms >= 400)
                {
                    label1.Text = "matlab资源加载时间过长!";
                    return;
                }
            }

            //跨线程,用委托方式执行
            UpdateUI update = delegate
            {
                //隐藏标签
                label1.Visible = false;
                //设置matlab图像窗体的父窗体为panel
                SetParent(figure1, panel1.Handle);
                //获取窗体原来的风格
                var style = GetWindowLong(figure1, GWL_STYLE);
                //设置新风格,去掉标题,不能通过边框改变尺寸
                SetWindowLong(figure1, GWL_STYLE, style & ~WS_CAPTION & ~WS_THICKFRAME);
                //移动到panel里合适的位置并重绘
                MoveWindow(figure1, 0, 0, panel1.Width + 20, panel1.Height + 40, true);
                //调用显示窗体函数,隐藏再显示相当于刷新一下窗体
                //radiobutton按钮使能
                radioButton1.Enabled = true;
                radioButton2.Enabled = true;
                radioButton3.Enabled = true;
                radioButton4.Enabled = true;
                radioButton5.Enabled = true;
                radioButton6.Enabled = true;
               
            };
            panel1.Invoke(update);
            //再移动一次,防止显示错误
            Thread.Sleep(100);
            MoveWindow(figure1, 0, 0, panel1.Width + 20, panel1.Height + 40, true);
        }

三、注意事项

1.代码中的MatlabFunction 类是我自己封装的一些matlab演示函数,关于C#调用matlab这方面的网上很多,这里不作介绍。

2.工程使用vs2017和matlab2010b编译,程序运行需要 .net4.0和matlab2010或者matlab运行环境MCRInstaller。

四、完整代码

1.C#调用matlab图像嵌入winform工程源码:点击下载

2.matlab运行环境MCRInstaller 7.14:点击下载

  • 18
    点赞
  • 165
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 63
    评论
要在C# Winform嵌入基恩士应用程序exe,可以使用Process类来启动应用程序,并将其嵌入窗体中。以下是实现步骤: 1. 打开Visual Studio中的Winform项目,并在工具箱中添加一个Panel控件。 2. 在代码中使用Process类的Start方法来启动基恩士应用程序exe,并将其嵌入到Panel控件中。 3. 设置基恩士应用程序exe的属性和方法,以便与其进行交互。 以下是代码示例: ```csharp using System.Diagnostics; using System.Windows.Forms; namespace WinformApp { public partial class Form1 : Form { private Process process; public Form1() { InitializeComponent(); // 启动基恩士应用程序exe process = new Process(); process.StartInfo.FileName = "KeenShine.exe"; process.StartInfo.Arguments = ""; process.StartInfo.UseShellExecute = false; process.StartInfo.CreateNoWindow = true; process.StartInfo.RedirectStandardOutput = true; process.StartInfo.RedirectStandardError = true; process.Start(); // 将基恩士应用程序exe嵌入到Panel控件中 process.WaitForInputIdle(); SetParent(process.MainWindowHandle, panel1.Handle); // 设置窗体大小和位置 process.StartInfo.WindowStyle = ProcessWindowStyle.Normal; process.WaitForInputIdle(); MoveWindow(process.MainWindowHandle, 0, 0, panel1.Width, panel1.Height, true); // 设置基恩士应用程序exe的属性和方法 process.StandardInput.WriteLine("Command1"); var result = process.StandardOutput.ReadLine(); // ... } protected override void OnFormClosing(FormClosingEventArgs e) { base.OnFormClosing(e); // 关闭基恩士应用程序exe process.Kill(); } [DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = true)] private static extern IntPtr SetParent(IntPtr hWndChild, IntPtr hWndNewParent); [DllImport("user32.dll")] private static extern bool MoveWindow(IntPtr hWnd, int x, int y, int width, int height, bool repaint); } } ``` 在上面的代码中,panel1是Winform中的一个Panel控件,用来显示基恩士应用程序exe。你需要根据实际情况设置基恩士应用程序exe的属性和方法。需要注意的是,在关闭窗体时,需要使用Process类的Kill方法来关闭基恩士应用程序exe。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 63
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

哀歌与世无争

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值