VB6.0 : initialize method of a User Control called when loading a VB project - vb6

Whenever we load a VB project it will call Initialize event of a User Control ( if there is any in the project). My problem is that is that I have some code in UserControl_Initialize that will try to create instances of other COM objects. On my build machine those controls are not registered. One option is to move the code to some other method other than Initialize but I want to know if there is a better solution? Somewhere I found that we may have a check to see if the calling application is VB editor then skip the initialization code...

You can use:
If Not Me.DesignMode Then
...
End If
An other solution we used was a little function which can be used globally:
Public Function IsRuntime() as Boolean
On Error Goto NotRuntime
Debug.Print(1 / 0)
IsRuntime = True
Exit Function
NotRuntime:
IsRuntime = False
End If
Don't know if it is syntactically well formed, but the idea should be clear:
Only in the IDE the debug statement is called.

This only happens if your project was saved with the form designer open: this means that at startup the form is displayed (maybe in the background) and consequently, all controls on it need to be initialized. Hence, your user control initializer is called if this control is used on the form.
To prevent this, simply save the project with the form designer closed.

Related

Winforms Application Fails To Launch [closed]

Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 3 years ago.
Improve this question
I have a winforms application that is installed on multiple computers. Most of the time it works perfectly but for a small subset of users the application fails to launch. The only resolution I have found for this issue is to reinstall the application on the users machine.
I have included screenshots below showing the application working after a successful launch and also a screenshot showing what the user sees when the application fails
Normal Launch:
Failed Launch:
When the application fails, the startup form does not get rendered at all. On the users desktop there is nothing visible at all and the program is not outside of any visible area.
If anyone could provide answers or insight into the following questions it would be much appreciated.
What could cause this problem?
Windows or program related?
How could this be fixed?
I have included code snippets from the startup form below
Starting code:
private static void Main()
{
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
Application.SetUnhandledExceptionMode(UnhandledExceptionMode.CatchException);
Application.Run(new Timelord());
}
public Timelord()
{
this.InitializeComponent();
this.BringToFront();
this.Focus();
// Displays a date and gets the version of the program
lblDate.Text = DateTime.Now.ToShortDateString();
Version version = System.Reflection.Assembly.GetExecutingAssembly().GetName().Version;
if (ApplicationDeployment.IsNetworkDeployed)
{
lblVersion.Text = string.Format("v{0}", ApplicationDeployment.CurrentDeployment.CurrentVersion.ToString(4));
}
// Loads the comboboxes for selection
this.loadComboUser();
this.loadComboCompany();
this.loadComboTick();
}
I think what is happening is that there is an error being thrown in your Timelord constructor under certain conditions. Since Timelord is the "startup" object for your application, a failure to create its instance properly would cause serious problems. Here is what I would recommend doing to identify those conditions, and to eliminate the issue with the form only being partially created.
I am assuming based on your comment about the program reading from a database that one or more of the following methods perform data access calls to a database
this.loadComboUser();
this.loadComboCompany();
this.loadComboTick();
You typically want to avoid method calls, ESPECIALLY data access calls in a constructor. There are many reasons for this that I won't list here, but this other stackoverflow article explains some of them.
Is it OK to put a database initialization call in a C# constructor?
To correct these issues, implement an eventhandler for the load event and move all of your Timelord constructor code into the Load event handler. The Form.Load event fires after the constructor is complete but before a form is displayed for the first time.
https://learn.microsoft.com/en-us/dotnet/api/system.windows.forms.form.load?view=netframework-4.7.2
Here is how I would recommend restructuring your Timelord object.
public Timelord()
{
this.InitializeComponent();
}
Private Sub Timelord_Load(sender As Object, e As EventArgs) Handles MyBase.Load
{
Try
{
this.BringToFront();
this.Focus();
// Displays a date and gets the version of the program
lblDate.Text = DateTime.Now.ToShortDateString();
Version version = System.Reflection.Assembly.GetExecutingAssembly().GetName().Version;
if (ApplicationDeployment.IsNetworkDeployed)
{
lblVersion.Text = string.Format("v{0}", ApplicationDeployment.CurrentDeployment.CurrentVersion.ToString(4));
}
// Loads the comboboxes for selection
this.loadComboUser();
this.loadComboCompany();
this.loadComboTick();
}
Catch(Exception ex)
{
MessageBox.Show($"The following error occurred in the Timelord constructor {Environment.NewLine}{ex.Message}")
}
}
Making this change will allow the Timelord constructor to completely create the object, then the Load event will run and load any data into the UI. This way, if an error occurs, you will have at least completely created the Timelord Form and can catch the error.
What could cause this problem?
Your startup object (Timelord()) throwing an error in the constructor, therefore not properly creating object.
Windows or program related?
Program related
How could this be fixed?
Separating your Forms logic so that the only code in the constructor is your instantiation logic.
Implementing Try/Catch blocks to trap errors

Suppressing Visio.Application alerts

I have a VBScript that opens a Visio file in the background by using Visio.Application in invisible mode.
Set Visioapp = CreateObject("Visio.Application")
Visioapp.Visible = False
Set Visio = Visioapp.Documents.Open(VisioFile)
This works fine except when I try to open a file that generates a pop-up while I'm processing it. If that happens, the application would show an alert to notify the user but since the application is invisible to the user (or running without a user present), the script just hangs indefinitely, waiting for input that won't be coming.
If I were writing VBA code for Excel or Word I could use Application.DisplayAlerts = False (and/or possibly DisplayEvents). But in my VBScript the Visio application doesn't have that property. Visioapp.DisplayAlerts = False will give me the error "Object doesn't support this property or method".
How do I suppress the popups generated by a Visio application opened from VBScript?
Summarizing the comments from #Dave and #Noodles, the Visio Application object does not have a property DisplayAlerts like other Office applications have. Instead it provides a property AlertResponse that allows you to define whether the application should respond to alerts with OK, Cancel, Abort, Retry, …
To have the application respond with OK to all alerts change your code to something like this:
Set Visioapp = CreateObject("Visio.Application")
visioapp.AlertResponse = vbOk
Set Visio = Visioapp.Documents.Open(VisioFile)
Note that in this case you can use the symbolic constants that VBScript already provides (vbOk, vbCancel, vbAbort, vbRetry, …). For application-specific constants (e.g. the SaveFlags for the SaveAsEx method) this won't work, though. In those cases you'll have to either use the numeric value:
Visio.SaveAsEx "C:\path\to\output.vsd", 1
or define the constant in your script:
Const visSaveAsRO = 1
...
Visio.SaveAsEx "C:\path\to\output.vsd", visSaveAsRO

How to run-time click an arrayed command-button (by another arrayed or similar one) in vb6?

Run-time sending click command to a similar command-button named cmd1 is so easy from another control:
cmd1_Click
But this similar type not works when we're going to send this command from another form, there. For example by:
Form2.cmd1_Click
Then for this time we used to write:
Form2.cmd1.value = True
But now my question is for when this command-button is an array of controls. How we can code this doing one?
Comment turned to a an answer as the OP is happy with the response.
Equivalent for an array of controls is:
Form2.cmd1(0).value = True.
Or move your code from out of the event handler into a Public Sub and call the code from both your other form and the event handler

Interactively execute code while debugging in Scala

Is there a method for inserting code into a Scala application while debugging? For example, could I have something like this,
var c = 1.0
0.until(10).foreach{ i =>
if (i == 5) {
startDebuggingMagicHere()
}
}
where I could then inspect and interact with c, i, and any other variable in scope via methods and assignment.
In the Scala-IDE plugin for Eclipse, debugging is supported. Set a breakpoint in the Scala code and you will be able to do limited things. Current support is not as good as that for Java. I believe it is planned to improve by the Summer.
What you can do is:
use the "variables" view to see the current values of variables and modify values,
tell the debugger to "drop to frame" so that it starts the current method call again, using the original values from the stack,
modify code and save the file which causes the debugger to insert the new code and drop to frame, i.e. restart the method call (this does not always work - depending how much you change the code you may need to restart the app, e.g. if you change the class definition)
What you can't do is:
inspect variables from the editor,
write code in the "display" view and execute it. Both of these work with Java, but not Scala.

Add item to Error List in Macro

I want to notify the user of the macro if something went wrong during the execution of the macro. I was wondering if it would be possible to add an item to the Visual Studio error list?
It is possible to do so from within an AddIn (like here), but I would like to do the same thing from a macro.
Edit
To further clarify what i want to achive, here is the sample from the Samples macro library (Alt+F8 -> Samples -> Utilities -> SaveView())
Sub SaveView()
Dim name As String
name = InputBox("Enter the name you want to save as:", "Save window layout")
If (name = "") Then
MsgBox("Empty string, enter a valid name.")
Else
DTE.WindowConfigurations.Add(name)
End If
End Sub
Instead of the MsgBox("...") alert I want to put the error into the VS error list.
You can add an item in the Task List easily from your macro. Just use the AddTaskToList method from that article and change m_objDTE to DTE. I've tried it and it worked.
However, adding the item in Error List, is probably impossible. You need to call VS services, see how adding an error is done in an add-in. I created a macro from this code and it didn't work. In general, VS services don't work in macros. I was able to create ErrorListProvider successfully. I could access it's methods and properties. But calling ErrorListProvider.Task.Add caused COM exception. If you want to play with it, several notes:
As described in the article, you need to get 4 assemblies out of the GAC e.g. to c:\dlls\ directory. Since Macros IDE doesn't allow you to browse when you Add Reference, you need to copy these dlls into ...\Microsoft Visual Studio 10.0\Common7\IDE\PublicAssemblies directory (change the 10.0 to your VS version). Then, when you Add Reference in Macros IDE, you should see the assemblies.
The GetService function always returned Nothing. Add the following field to the class:
Private serviceProvider As IServiceProvider = New Microsoft.VisualStudio.Shell.ServiceProvider(CType(DTE, Microsoft.VisualStudio.OLE.Interop.IServiceProvider))
and in GetService function change line:
objService = Microsoft.VisualStudio.Shell.Package.GetGlobalService(serviceType)
to
objService = serviceProvider.GetService(serviceType)
As I wrote, everything seems OK then but ErrorListProvider.Task.Add fails.
I think that for your situation outputting something to your own output pane would be more suitable. The error list is generally used for errors within the project the user is working on, not for errors caused by running macros. Especially when someone says it can't be done. :)
Outputting to your own output pane is pretty easy:
DTE.Windows.Item(Constants.vsWindowKindOutput).Activate()
Dim panes As OutputWindowPanes = window.OutputWindowPanes
Dim my_pane As OutputWindowPane
Try
my_pane = panes.Item("SaveView")
Catch exception As System.ArgumentException
my_pane = panes.Add("SaveView")
End Try
my_pane.Activate()
my_pane.OutputString("Empty string, enter a valid name." + vbCrLf)
Hope this helps.
Cheers,
Sebastiaan
Is this not what you want?
HOWTO: Add an error with navigation to the Error List from a Visual Studio add-in
http://www.mztools.com/articles/2008/MZ2008022.aspx

Resources