诸位可能也注意到了在本网站的讨论组中有很多询问matlab对外接口的问题,遗憾的是这是一个较为复杂的问题,那么多种语言和各种不同的要求,一时难以系统的讲清楚。而且进来我的主要兴趣也不在编程上,用matlab只是做一些算法的分析,于是总是笼统的介绍一些解决方向,没能直接的给网友们一个好用的答案。看着这些问题越积越多,总觉得不是办法。所以我在这里挑了一个最简单的实现途径——VB对MATLAB的DDE连接,做了一个demo,希望能够给大家一些启发。
这个程序名叫SimuMATLAB,实际上可以相当于MATLAB的一个新界面,可以实现命令的输入,数据结果和图像结果的现实。
程序的界面如下
最上面的是输入文本框TextInput,在此可以键入matlab的命令,按回车键后这条命令就会传递给MATLAB。如果按ESC键则会将框中内容清空,以便输入。
中间的是输出文本框TextOutput,显示matlab返回的文本结果。
最下的是一个图形框Picture1,显示matlab当前更新的figure的内容。
还有一个文本框TextGet是看不见的(visible属性设成false),它被用来接受matlab中返回的数据。
工程文件下载simumatlab.zip
源程序如下
Private Sub Form_Resize() With TextInput .Left = 0 .Top = 0 .Width = Me.ScaleWidth End With With TextOutput .Left = 0 .Top = TextInput.Height + 5 .Width = Me.ScaleWidth .Height = Me.ScaleHeight / 2 - .Top End With With Picture1 .Left = 0 .Top = Me.ScaleHeight / 2 + 5 .Width = Me.ScaleWidth .Height = Me.ScaleHeight - .Top End With End Sub
Private Sub TextInput_KeyPress(KeyAscii As Integer) If KeyAscii = vbKeyReturn Then Rem Initiate the conversation between the TextInput Rem control and MATLAB under the Engine topic. Rem Set the item to EngEvalString. TextInput.LinkMode = vbLinkNone TextInput.LinkTimeout = 1000 Rem Make it enough long for MATLAB to complete its work TextInput.LinkTopic = "MATLAB|Engine" TextInput.LinkItem = "EngEvalString" TextInput.LinkMode = vbLinkManual Rem Get the current string in the TextInput control. Rem This text is the command string to send to MATLAB. szCommand = TextInput.Text Rem Perform DDE Execute with the command string. TextInput.LinkExecute szCommand TextInput.LinkMode = vbLinkNone Rem Initiate the conversation between the TextGet Rem control and MATLAB under the Engine topic. Rem Set the item to EngStringResult.
TextGet.LinkMode = vbLinkNone TextGet.LinkTopic = "MATLAB|Engine" TextGet.LinkItem = "EngStringResult" TextGet.LinkMode = vbLinkManual TextGet.LinkRequest TextGet.LinkMode = vbLinkNone
Rem Append output text to the end of TextOutput. TextOutput.Text = TextOutput.Text & TextGet.Text Rem Move cursor to the end of TextOutput TextOutput.SelStart = Len(TextOutput.Text)
Rem Ask if there any figure was updated. TextGet.LinkMode = vbLinkNone TextGet.LinkTopic = "MATLAB|Engine" TextGet.LinkItem = "EngFigureResult" TextGet.LinkMode = vbLinkManual TextGet.LinkRequest TextGet.LinkMode = vbLinkNone
Rem If answer is yes,then figure is stored in clipboard Rem Take it from clipboard and paste it to Picture1 If TextGet.Text = "yes" Then Picture1.Picture = Clipboard.GetData End If
Rem Avoid the beep by pressed return KeyAscii = 0
ElseIf KeyAscii = 27 Then 'Esc KeyAscii = 0 TextInput.Text = "" End If
End Sub
除了程序中的注释以外,还想做一些说明。
LinkMode还可以设置成自动方式,但我觉得手动方式处理起来更有条理一些。
LinkTimeOut是一个很重要的量,原先设定的初始值一般太小,在做第一次连接的时候要消耗较长的时间,往往引起超时错误。
用picturebox控件自己的DDE连接功能原本也应该是可以的,但是我在尝试的时候发现传过来的图像有错行的现象(有时在用WORD写论文时,“粘贴”功能也会有同样的错误,而用“选择性粘贴”则不会)。所以该用另一种方式:先用文本形式询问图像的情况,如果没有图像的变更则返回“no”,否则返回“yes”,这时图形已由matlab负责拷贝到剪贴板上了,程序只要将其从剪贴板上取下来即可。
程序还使用了一个技巧。VB中的文本框控件没有提供移动可视窗口的命令,我用了SelStart把光标指向最后的字符,这样就能每次看到更新的文本输出。注意,我每次都把新的输出添加到历史输出结果的后面,而没有清除的代码,所以操作的次数多了会超出文本框64K的容量。
程序还对Resize做了一些安排,使得不受放大缩小的影响。
本程序是在VB 5.0 英文版和MATLAB 5.3 (R11)上调试通过的。
(责任编辑:泉水) |