I'm writing a space invaders style game in Visual Basic for my HSC Software Design project. As part of that, I am using the following line of code to detect whether an enemy hit the player's ship.
If ship.Bounds.IntersectsWith(enemy(i).Bounds) And enemy(i).Visible = True And ship.Visible = True Then
This code is located within a For loop that runs for each enemy. I use that loop to move the enemies as well as check shots and stuff. This For loop runs within a Timer set to a 1 millisecond delay.
I am receiving a NullReferenceException error on this line, and it says Object reference not set to an instance of an object. I know that means one of either enemy(i) or ship isn't set to an object instance or something, because I've already closed the form. Here's the interesting bit:
Firstly, I received this error when this form wasn't even loaded. During the time the application was running, this form was never opened.
Secondly, even if it was running, it occurred quite a while after I stopped the timer with Timer2.Stop(). I checked through my code and there is no way possible that this code should try to execute.
I'm so confused right now, what is going on?
Related
I have a form for viewing data in a table, which can open a pop up form to edit the data.
When data is edited in the pop up form, Access throws a write conflict error upon closing that form and returning to the original.
The strange behavior I'm experiencing is that when I make a change to the popup's class module in VBA, even if I immediately undo the change and save, the error will be resolved exactly once.
To be clear:
I make a change to the popup's class module in VBA (even a change I immediately undo and re-save)
I can open the pop up from my original form, edit records, then close the pop up. No error is thrown on closing the pop up.
I then open the pop up and edit records a second time. Then upon closing the pop up a write conflict error is displayed. This continues each subsequent time.
I now make a change to the popup's class module (again, even a trivial one), the error is resolved for one edit again, and the process repeats.
Does anybody know why this behavior could be occurring? Any help would be much appreciated.
Well the issue centers on if two users, or in this case two bits of code try to edit a record that is already dirty.
If the main form causes the record to become dirty (changed, but not saved), if then you run ANY other code that ALSO changes that data, then you get the conflict.
The simple solution then is to ALWAYS ensure that the the current forms record is safely tucked away and saved before you run + call code that might change that dirty record. And that includes that popup form + class.
So in your code that launches the form/class code? Do this RIGHT BEFORE you launch that 2nd form:
If me.Dirty = True then me.dirty = False
So, the above will safe write out the dirty record, and now you are free to launch/run any other code that might change that record. And because you run the above? Well, the record is not dirty anymore, and thus you should not see nor receive a write conflict error.
So adding a check to save if dirty before you launch/run that additional code/form will resolve this issue. In fact, as a habit, for just about "any" launching of additional UI forms, it a good idea to safe tuck away and save the current forms record when launching additional UI bits and parts.
I have code stuck.
It might be in an infinite loop.
Not sure.
Is there a way to break the program to stop at the current line of code that it is running on?
I'd like to avoid shutting down excel because I want to be able to catch where in the loop it is, and by going into the code, I will be able to tell how much processing was done. I would like to break into the code, if possible.
It is stuck on hour glass.
Ctrl+Break doesn't seem to work
Seems like the running code has hijacked all the quota that cpu is giving to excel.
If there is nothing I can do now, is there something in the future I can do to where I can more easily break into the code?
I'm thinking that an intermittent wait within a loop might be a feasible solution.
In the future, include a DoEvents inside the loop. It will run a little slower, but you will be able to use Ctrl+Break to stop it from running.
Create a progress dialog when entering the loop and include a Cancel button. Within your loop check for the Cancel signal/event. This also gives you some flexibility on how you react to the Cancel - you could stop the loop and display key information in a new dialog box (for example).
Basic steps to achieve what I have described (not necessarily the most elegant or the most re-useable, but simple enough for those of lesser experience):
create a modeless (not modal) Form with either suitable labels or a progressbar item (for
visual effect). Include a public property (Boolean) for Cancel (e.g.
boolCancel)
Place a button on form and onClick set boolCancel = True
In your main code, show the form just before your problem loop.
while in your loop you can update some label or progress bar on the
form so that you have a visual indication of whether the loop is
doing something of value or if it is now simply spinning its wheels.
How you do this depends on what your loop is doing.
Also while in your loop check your boolCancel value. If true then
display any state information you want and break from the loop.
If your loop ends normally, hide/unload the progress dialog.
I wrote a VB.NET Windows Forms app that requests a string from an out-of-process COM object every time the activate event fires. My form has two tabs, so I need to programmatically flip to the correct tab every time my window gains focus. Works fine, until...
By chance, someone ran a vbscript (yes, script, not exe) that contains:
Set shell = CreateObject("WScript.Shell")
shell.AppActivate("Window Title That Matches My App")
This script consistently crashes my app. Usually so badly that the Exception dialog usually can't paint itself. I have to kill it from task manager. Sometimes the Exception is readable. (I also confirmed the exception by attaching to the running exe with Visual Studio). It's: "System.Runtime.InteropServices.COMException (0x8001010D): An outgoing call cannot be made since the application is dispatching an input-synchronous call."
What's really messing with my mind is that my app has multiple instance detection using a mutex, and if an existing instance is running, my own code (compiled) uses VB.NET's own AppActivate keyword, and this does NOT crash my app. It activates the running instance and exits the redundant instance as expected.
The problem seems solely to be triggered by cscript/wscript's AppActivate. I wrote a 3-liner .vbs to confirm this. It's repeatable.
Is there a way to trap or avoid this in my compiled app?
It's not clear to me WHY this approach actually fixes the problem, but it DOES work:
Add a timer to the form.
Move all the _Activated code to the timer's _Tick event.
Make the _Activated event start the timer.
Make the _Tick event stop the timer then perform the COM stuff.
Im using some custom control in vb.net, where I have a boolean property that, whenever it changes, it starts a timer if it's value is false or stops if it's true.
If the timer runs for several seconds, it raises a messagebox that warns of a problem happening.
The problem is that this messagebox shows even in design time. As I have traced, the default value for the property is false when the control loads in the winform in design time, it seems it starts the timer and when it ends raises the messagebox, this happens whenever I open the project or rebuild it.
I don't get why this behaviour, as this should only happen at run time but it's driving me crazy, I have tried starting the timer directly when the property changes in the setter and creating "onpropertychanged" events, but this still happens in design time.
Anyone has an idea of how to get rid of this or how to solve it to avoid this of happening, is really disturbing that things happens when the program isn't even running.
Thanks in advance.
Regards
The common way is to use the DesignMode property of the control.
true if the Component is in design mode; otherwise, false.
So in your property, before starting the timer, first check if DesignMode is False.
We have an application that allows custom UI and interaction via SDK.
A DLL is developed for this purpose using VB.Net and the SDK.
An object variable refers to the application and there are some other object variables for components within the application.
Application allows assigning VBScript code to button(s) displayed in toolbar. The VBScript code is:
Dim Utility_Main
Set Utility_Main = CreateObject("Utility.Application")
Utility_Main.Launch()
This launches a form (custom UI) and users can interact with the application via this form.
Although application itself has its own UI, this utility form is created for database lookup, preserving certain attributes of application objects etc.
In just about every exit point of the form, a procedure is called to unset object variables for application and its components using following code:
========================================
Try
Marshal.ReleaseComObject(objX)
Catch
End Try
Try
objX = Nothing
GC.Collect()
Catch
End Try
Note1: ReleaseComObject and setting object variable to Nothing was wrapped in "If (Not objX is Nothing) Then". But it was changed to above format to make sure it gets called.
Note2: GC.Collect was added later to force GC.
========================================
This is done for each object in reverse order of object hierarchy.
Application's executable (Application.exe) remains loaded in both of the following cases:
Application is closed first and then Utility form is closed
Utility form is closed first and then the application is closed
The only time "Application.exe" goes away is if Application is closed first and then Utility form is closed by clicking on "End Task" in Task Manager.
Any help will be greatly appreciated.
I realize you say that it was split up for some reason, but this should be:
Try
If objX IsNot Nothing Then
Marshal.ReleaseComObject(objX)
End If
Catch e As ArgumentException
' hopefully you have some debug output here
Finally
objX = Nothing
GC.Collect() ' really doubt this is necessary
End Try
This guarantees that objX is released if it is not Nothing, and if that throws an exception (note the list of exceptions), then you can catch it and figure out what happened. Whether or not an exception is thrown, objX will be set to Nothing and the GC will be invoked.
It's probably not this code that is causing your program to stay open. You will need to show more code (how they interact, or any non-daemon threads that you may manually start will also be to blame). It sounds like Utility is forcing the Application to stay alive with a non-daemon, background thread, but it really could be the other way around, and it could be the case that doing that in both directions.