Why did the InputBox method go, and why did MessageBox stay? - vb.net

My A-Level programming project is unfortunately in vb.net.
I remembered that InputBox was a method, so I tried it. It came back as undeclared.
Eventually I found a forum where someone mentioned that if you import the Microsoft.VisualBasic namespace you can use it again, but apparently that's been removed aswell ('InputBox' is not a member of 'Microsoft.VisualBasic').
I'm lost as to why Microsoft decided to remove InputBox, but keep MessageBox seeing as though they're both as useful as each other - even for a language as old as VB.
To get round this, would I create a form dedicated to collecting user inputs? There must be an better way to get InputBox back, I just can't seem to find it.
Thank you.
Edit for replication of my error:
'create a normal forms app (I'm using .NET Core 3.0)
Public Class frmExample
Private Sub frmExample_Load(sender as Object, e as EventArgs) Handles MyBase.Load
Dim userInput as string
userInput = Interaction.InputBox("Example") 'InputBox is not a member of Interaction
userInput = Microsoft.VisualBasic.InputBox("Example") 'InputBox is not a member of Microsoft.VisualBasic
End Sub
End Class

In .NET Core 3.0 InputBox is not a method. This works as expected, however, in .NET Core 5.0.
In order to fix this: Change your Target Framework in Project Properties to .NET Core 5.0.
Or alternatively do what #Jimi suggested which was to simply create an InputBox form yourself.

Related

.NET 5 VB Late bound variables unavailable at run time due to Public member 'Visible' on type 'Application' not found

I've searched the forums for something similar to this, but most of the issues I've seen do not have access to the variables in the debugger and have issues with casting the object.
I'm running a C# application which calls a VB class called wrapper.cs, which uses MS Word objects. This code was tried and tested and worked fine with .NET 4.8 but now breaks in .NET 5.
I have a variable: Protected m_wdApp As Object
When the class is instantiated, it calls:
Public Sub New()
m_wdApp = CreateObject("Word.Application")
m_wdApp.Visible = False
m_outputFormat = DOC_FORMAT
End Sub
This throws the following exception:
Now the above would be all very fine and well, if I wasn't able to actually look at the contents of the m_wrdApp and see that yes, they are all intact and are all visible in my watch Windows.
Using the Immediate window, attempting to access any of these attributes from the Word object throws an error (as you'd expect).
However, if I ask VS to "add a watch" to one of the attributes, for instance this "Visible" which we currently need, it comes out with this convoluted watch name:
I should note that all of this worked fine before upgrading to .NET 5, so I'm wondering if this is either a bug or there are some new rules for dealing with late bound variables.
As #dbasnett and #charlieface mentioned above, we should be using Interop.
We added Imports Microsoft.Office.Interop
We also changed
Protected m_wdApp As Object
to...
Protected m_wdApp As Word.Application
And needed to update variables such as
Dim inlineShape As Object
to
Dim inlineShape As Word.InlineShape
and...
For Each hl As Object In m_wdApp.ActiveDocument.Hyperlinks
to:
For Each hl As Word.Hyperlink In m_wdApp.ActiveDocument.Hyperlinks
I couldn't see why moving away from late binding would impact us and I'm assuming the move the Interop is in line with .NET 5 coding guidelines, with their many improvements in Interop code in recent years.
Many thanks for this tip guys!

Regarding vba classes coded in Visual Studio VB.net

I'm trying to start coding my macros for Excel in Visual Studio, it needs changing some things but I think I'm ok as for normal modules go.
My question is, how do I code classes there?
When I try to code a new class it forces me an argument called Of:
Public Class FNMT(Of)
Public Sub TratarDatos(arr As Object, Dict As Object)
End Sub
End Class
And says it's expecting an identifier. How would classes work in Visual Studio? I couldn't use properties neither, it was saying that I can't use the Let/Get.
Can't find anything about this either here nor in google. Any insights?
This is how I'm writting the code:

stimulsoft report add my function with vb.net

we can add our function with this way
https://www.youtube.com/watch?v=TEYuQmia9IY
but it in c#
i want the way in vb.net
the problem in using namspacing in vb.net
thanks
In the video posted there are some critical steps missing. It seems that they are given for granted but without it you could not achieve a successful reference to your code from the Report Designer.
First: To clarify the problem between VB.NET and C#. If you want to use VB as scripting language for your report you need to set it in the Report Properties. You will find the ScriptLanguage property in the same property grid for the report where they set the reference to your application. Changing this property is not required because this property refers to the code written inside the report not the code in which you have written your app.
Second: In your VB.NET app your code that defines the function should be as this
Namespace MyFunc
Public Class Main
Public Shared Sub ShowMessage(text As String)
MessageBox.Show(text)
End Sub
End Class
End Namespace
Usually in VB.NET you don't define explicitily a namespace (everything is inside the main namespace defined in the project properties) but if you want a separate namespace there is nothing to stop you.
Third: In the Report Code Page you write
Imports WindowsFormApplication2.MyFunc
Fourth: After completing the design of your report remember to save it in the same folder where the application is created. (Usually Project\BIN\DEBUG) Otherwise the reference to your executable will fail.
Fifth: The Stimulsoft assemblies are installed in the GAC, but to be sure that they are found when you run the report don't forget to set their references to Copy Local = True when you run your app inside Visual Studio

COM App calling .NET form calling COM form, works when compiled but not in VB6 IDE

I have a legacy VB6 / COM application that we are migrating all of the code to .NET (VB.NET) via a .NET DLL. All new form development is being done in the .NET DLL.
We use function pointers to call back to COM functions within .NET form:
I create a delegate in .NET
Set the delegate to the AddressOf the COM function at runtime (GetDelegateForFunctionPointer)
Show the .NET Form
Invoke the delegate
COM App --> .NET Form --> COM function
This works fine for functions. Where this breaks down is when I call a COM function that shows a form.
COM App --> .NET Form --> COM function --> COM Form
The COM function will execute and the form will show, but when executing in the VB6 IDE the COM form's logic does not execute. The controls are shown, but any click or form_load events are not executed. This is not an issue when the VB6 application is compiled.
Another issue I've noticed is that the VB6 IDE "freezes" until the .NET form unloads. I can not stop the debugger, set breakpoints, or interact with IDE's menu. It is as if the VB6 IDE allows the .NET DLL to take complete control over the thread. I believe these two issues are related.
EDIT:
The .NET form is modal, which may be the reason for the IDE thread lock. I'm just wondering if there is a way around it. Also, I've looked at the InteropForms Toolkit. It does not solve my problem. Even setting their sample forms to modal causes the same IDE thread lock to occur.
EDIT 2:
My previous edit did allude to another workaround: Make the .NET form show as modeless when the host application is VB6.
If InStr(Process.GetCurrentProcess().ProcessName, "vb6", CompareMethod.Text) > 0 Then
frm.Show()
Else
frm.ShowDialog()
frm.Dispose()
End If
The simple COM App --> .NET Form --> COM function --> COM Form scenario can work using the InteropForms Toolkit 2.1. Here is some code that does it, without using delegates or AddressOf.
First, we have our COM library which I'll call ComLibrary. We have the following code:
SimpleForm.frm:
Option Explicit
Private Sub Form_Load()
MsgBox "In SimpleForm_Load"
End Sub
Private Sub OkButton_Click()
Unload Me
End Sub
Private Sub TalkButton_Click()
MsgBox "Hello"
End Sub
SimpleClass.cls:
Option Explicit
Public Function ShowTheDialog() As Long
Dim f As SimpleForm
Set f = New SimpleForm
f.Show vbModal
ShowTheDialog = 1
End Function
Compile this to a .dll so that we can reference it in our .NET library.
Next, we'll create our .NET forms library. I did this using the "VB6 InteropForms Library" project template using the default project name of InteropFormsLibrary1. I added a reference to the ComLibrary project. The form has a single button named "CallComFunction."
InteropForm1.vb:
Imports Microsoft.InteropFormTools
<InteropForm()> _
Public Class InteropForm1
Private Sub CallComFunction_Click(sender As System.Object, e As System.EventArgs) Handles CallComFunction.Click
Dim sc As ComLibrary.SimpleClass
sc = New ComLibrary.SimpleClass
Dim result As Integer
result = sc.ShowTheDialog()
End Sub
End Class
Before compiling this, we need to create the InteropForms wrapper classes per the toolkit documentation. Do this by accessing the Tools > Generator InteropForms Wrapper Classes menu.
Finally, we create the VB6 host app.
Form1.frm:
Option Explicit
Private Sub DialogButton_Click()
Dim f As InteropFormLibrary1.InteropForm1
Set f = New InteropForm1
f.Show vbModal
End Sub
When I run the host application in the VB6 IDE, I can click the button the VB6 form which then displays the VB.NET form. From there, I click another button which uses an instance of SimpleClass to display SimpleForm. The MsgBox statements in the form load event and the button click handlers work. And everything works when compiling the VB6 host app as well.
It looks like your VB6 IDE is loading your VB application as an "in-process" COM object, although that does not make much sense to me... However if that is the case,it would mean that you have a single message loop for your application and your debugger, which might explain at least some of these issues. I have not used a VB-classic IDE in too many years, so I do not know how it works. Maybe there is an option there somewhere to load your app in a separated process?
Update -
It seems my guess was correct. See this other question and its answers for more information and possible workarounds:
https://stackoverflow.com/a/518217/501196

Form load Event fires twice, using Interop Forms Toolkit

I've been following a codeproject article on using the interop forms toolkit (basically a way for developers to slowly upgrade their VB6 projects to .net by allowing .net components run in VB6)
http://www.codeproject.com/KB/vb-interop/VB6InteropToolkit2.aspx
While the .NET form is working fine in all other testing projects and environments, I've found that the Form_load event is actually firing twice once it's in executing in the VB6 runtime.
Not only annoying, its forcing my initialization code to execute twice (causing all kind of problems on the second run).
Is there any explanation as to why this is happening (I'd like to understand the reason)?
Is there anything better way to work-around this apart from
If (runBefore = True) Then
It's possible for this occur if you implicitly begin loading a form by accessing a public variable in the form from another module, then explicitly .show the form before the loading is complete.
hi i've tried this and it works..
i put it in form_activate. basically to test if the form is already loaded. if it is, then unload it. I use i as counter.
Private Sub Form_Activate()
Dim TestForm As Form
i = 0
For Each TestForm In Forms
If TestForm.Name = "frmStocks" Then i = i + 1
If i = 2 Then Unload Me
Next TestForm
End Sub