Continue to Site

Eng-Tips is the largest engineering community on the Internet

Intelligent Work Forums for Engineering Professionals

  • Congratulations KootK on being selected by the Eng-Tips community for having the most helpful posts in the forums last week. Way to Go!

Sending Visual Basic Output Window (Program Output) to a Form (Text Box) or File

Status
Not open for further replies.

rotw

Mechanical
May 25, 2013
1,143
Hi there,

I have a visual basic 2017 windows desktop application. The application calls a Fortran DLL. The Fortran version that is running is "gcc".
So when the Fortran DLL is being executed, its output displays in the Visual Basic Output Window. This appears to be working quite well.

Now what I would like is to have that output be sent either to a text.box in VB form or written to a text file.
The objective is to make the info visible to a user.

Any clue how to do this?

Thanks in advance.

 
Replies continue below

Recommended for you

Do you have access to the Fortran source code - can you modify it?

If you can, change the function in the DLL to return a string instead of writing to the screen. Is it just a small string or swathes of information?
 
The dll is likely writing its output to the stdout (and stderr) stream. If you do a websearch on "VBA redirect stdout" or something similar, you'll probably find something useful.
 
First off, thanks for your input.

xwb,
w.r.t to source code, I can modify the Fortran source code.
It is true that the source code requests to write to the screen (e.g. write (*,*) style).
I guess you mean to write the output to a string (character) and pass that string to VB.
But yes it is quite some amount of info, so a bit of an effort to put all that stuff into characters.

By the way, as I understood from some websearch, it seems the 'allocconsole' instruction in the Fortran DLL could be of help (but still not sure about how). Problem is, it looks like Fortran GCC (old fashion) could not handle that feature (while Intel Fortran seems to handle that).

Cowski,
Yes this seems to be the way out, but I struggle to find anything useful on the web, most of the web search redirects me to issues which people have with processes (means processes which are started within VB (e.g. shell execution command) and then people typically wants to read the output on file or form instead of console...). This is not my exact case, as the DLL is called and running externally if I can put it this way.

Any further info with regard to the 'redirect stdout' concerning my specific case? I would appreciate any help.

Thanks again

 
allocconsole is a Microsoft feature. Since Intel Fortran has its roots in Compaq, DEC and Microsoft, it would support MS feature

If you write a fotran program that call the one function in the DLL, then use IO redirection to call that function, it will then display the output in your textbox. The only problem is there is no interaction with the program. If you need to pass parameters in they can be passed in from the command line to the fortran program.



 
xwb,

Actually I don't need VB to interact in the sense you mentioned. It is just display of the Fortran output screen in a VB textbox.

By now the only way I found is to output everything in a text file which is printed by Fortran into some folder, then the text file is read by VB. This solution is really poor relatively to the purpose I originally wanted to achieve. I really would like to avoid this method.

If it is not too much asking, could you please drop two or three lines of example on how to implement the IO direction?

Thanks for your help.

 
Are you doing this in VBA, VB6, VB.net or VBScript (from HTA)? Different people refer to all these variants as VB.
 
"By now the only way I found is to output everything in a text file which is printed by Fortran into some folder, then the text file is read by VB. This solution is really poor relatively to the purpose I originally wanted to achieve. I really would like to avoid this method."

Why not do both? Write to the box and write to file.

TTFN (ta ta for now)
I can do absolutely anything. I'm an expert! faq731-376 forum1529 Entire Forum list
 
xwb,

Good question. I am using VB.net.

IRstuff,

Yes having both is okay, but as a minimum I need to have a direct method that would by pass the external file print out method. Until now I am unable to implement the later. I am getting all the info I need from the Fortran DLL, works well but it is all going to the VB output / debug window.

 
This is something I wrote some time ago in VS2005. It may still work on the current versions. Say you have a dll called pantun. It just prints a line of verse. First wrap it into a console application pantuncaller
Code:
Imports System.Runtime.InteropServices
Imports System.threading
Module PantunCaller
   Declare Sub pantun Lib "pantundll.dll" Alias "_TREKTEKTEK@4" (ByRef line As Integer)
   Sub Main()
      Dim args As String() = Environment.GetCommandLineArgs()
      Dim linesmax As Integer = CInt(args(1))
      Dim line As Integer
      For ii = 1 To linesmax
         line = CInt(Math.Ceiling(Rnd() * 200)) + 1
         Call pantun(line)
         Thread.Sleep(2000)
      Next   End Sub
End Module
This is a form with a text box and a button. Whenever the button is pressed, a random number of strings is regurgitated by the caller. This is a single threaded way of doing this - not very efficient if you get lots of output very quickly
Code:
Imports System.IO
Imports System.Diagnostics

Public Class pantunvbcont

   Private Sub btnFill_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnFill.Click
      btnFill.Enabled = False
      Dim poet As New Process
      poet.StartInfo.UseShellExecute = False
      poet.StartInfo.RedirectStandardOutput = True
      ' Set up the process to be called
      poet.StartInfo.FileName = "pantuncaller.exe"
      poet.StartInfo.Arguments = CStr(CInt(Math.Ceiling(Rnd() * 10)) + 1)
      ' Just a hint in the debug as to how many we are getting
      Console.WriteLine(poet.StartInfo.Arguments)
      ' Tricks to stop a console window flashing
      poet.StartInfo.CreateNoWindow = True
      poet.StartInfo.WindowStyle = ProcessWindowStyle.Hidden
      poet.Start()

      ' set up the redirected output
      Dim babble As System.IO.StreamReader = poet.StandardOutput
      Dim phrase As String
      Do While poet.HasExited = False
         ' get the redirected output
         phrase = babble.ReadLine
         ' update text box
         txtPoem.AppendText(phrase & vbCrLf)
         ' refresh screen (can use me.refresh)
         System.Windows.Forms.Application.DoEvents()
      Loop
      ' dispose otherwise we get a memory leak
      poet.Dispose()

      btnFill.Enabled = True
   End Sub
 
End Class
A better way would be to do this in a separate thread but then you start getting into invoke problems. I never got round to fixing the invoke problem because real work took priority - that was 12 years ago. Still haven't gotten back to it.

 
Example of how to do this with threads and delegates. I don't know if this has been replaced by lambdas or whether lambdas exist in the latest version of vb.net
Code:
Imports System.IO
Imports System.Diagnostics
Imports System.Threading

Public Class pantunvbinv

   Private Sub btnFill_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnFill.Click
      ' This will be enabled when the thread is finished
      btnFill.Enabled = False

      ' If we use a thread, the UI is not held up so we do not get grey areas while the UI is locked
      Dim trdBabbler As Thread
      trdBabbler = New Thread(AddressOf tskBabbler)
      trdBabbler.IsBackground = True
      trdBabbler.Start()
   End Sub
   '
   ' Delegate for updating txtPoem
   Private Delegate Sub txtBabbleDelegate(ByVal text As String)
   Private Sub txtBabble(ByVal text As String)
      txtPoem.AppendText(text)
   End Sub
   '
   ' Delegate for enabling fill button
   Private Delegate Sub btnFillEnableDelegate()
   Private Sub btnFillEnable()
      btnFill.Enabled = True
   End Sub
   '
   ' Thread to poll the remote executable for text output
   Private Sub tskBabbler()
      Dim poet As New Process
      poet.StartInfo.UseShellExecute = False
      poet.StartInfo.RedirectStandardOutput = True
      ' Set up the process to be called
      poet.StartInfo.FileName = "pantuncaller.exe"
      poet.StartInfo.Arguments = CStr(CInt(Math.Ceiling(Rnd() * 10)) + 1)
      ' Just a hint in the debug as to how many we are getting
      Console.WriteLine(poet.StartInfo.Arguments)
      ' Tricks to stop a console window flashing
      poet.StartInfo.CreateNoWindow = True
      poet.StartInfo.WindowStyle = ProcessWindowStyle.Hidden
      poet.Start()

      ' set up the redirected output
      Dim babble As System.IO.StreamReader = poet.StandardOutput
      Dim phrase As String
      Do While poet.HasExited = False
         ' poll for output
         phrase = babble.ReadLine
         ' update text box
         Invoke(New txtBabbleDelegate(AddressOf txtBabble), phrase & vbCrLf)
      Loop
      ' dispose otherwise we get a memory leak
      poet.Dispose()
      Invoke(New btnFillEnableDelegate(AddressOf btnFillEnable))
   End Sub
End Class
 
xwb,

Sorry for delay to answer.
Thanks very much for your efforts on this ; I am working on some other areas of the code right now. So, as soon as I will be able, I will have a look at your lines of code and I hope I could revert on my progress.

Appreciate the help so far.





 
Status
Not open for further replies.

Part and Inventory Search

Sponsor