Object reference not set to an instance of an object

S

sadegh

Hi,
I have a problem with my Progressbar Form. the following code runs
correctly. But...


progressForm = new fclsProgress();
progressForm.percent = 0;
Thread doSomethingThread = new Thread(delegate()
{
for (int i=0; i<100; i++)
{
if (progressForm.cancel == true)
break;
progressForm.percent = i;
// ... do something
}

MyNamespace.MyClass.ActiveForm.Invoke((MethodInvoker)delegate
{ this.progressForm.Close(); });
}

doSomethingThread.Start();
progressForm.ShowDialog();


But when I minimize my program, It is stoped by the following error
message:
"Object reference not set to an instance of an object"
on line:
MyNamespace.MyClass.ActiveForm.Invoke((MethodInvoker)delegate
{ this.progressForm.Close(); });

Every help would be appreciated.
 
A

Alberto Poblacion

sadegh said:
[...]
But when I minimize my program, It is stoped by the following error
message:
"Object reference not set to an instance of an object"
on line:
MyNamespace.MyClass.ActiveForm.Invoke((MethodInvoker)delegate
{ this.progressForm.Close(); });

The error message means that one of the parts in that line is null. You
could easily determine which one it is by means of the debugger. I suspect
that it is ActiveForm (if no form is left active after you minimize your
main form), but the debugger is your friend here; just examine the various
parts of that line after you get the error.
 
S

sadegh

[...]
But when I minimize my program, It is stoped by the following error
message:
"Object reference not set to an instance of an object"
on line:
MyNamespace.MyClass.ActiveForm.Invoke((MethodInvoker)delegate
{ this.progressForm.Close(); });

The error message means that one of the parts in that line is null. You
could easily determine which one it is by means of the debugger. I suspect
that it is ActiveForm (if no form is left active after you minimize your
main form), but the debugger is your friend here; just examine the various
parts of that line after you get the error.

Thanks Alberto,
It seems that there was no ActiveForm. so I solved this problem by
adding 3 lines before the error line to activate my program MainForm:

-----------------------

for (int i=0; i<100; i++)
{
if (progressForm.cancel == true)
break;
progressForm.percent = i;
// ... do something
}

IntPtr mainFormHandle = FindWindowByCaption(IntPtr.Zero,
mainFormCaption); // find MainFormHandle by its caption
SetForegroundWindow(mainFormHandle); // activate MainForm
Thread.Sleep(100); // wait for windows to activate MainForm

MyNamespace.MyClass.ActiveForm.Invoke((MethodInvoker)delegate
{ this.progressForm.Close(); });

-------------------------------------
// FindWindowByCaption defenition:

[DllImport("user32.dll", EntryPoint = "FindWindow", SetLastError =
true)]
static extern IntPtr FindWindowByCaption(IntPtr zeroOnly, string
lpWindowName);


// SetForegroundWindow defenition:

[return: MarshalAs(UnmanagedType.Bool)]
[DllImport("user32", CharSet = CharSet.Ansi, SetLastError = true,
ExactSpelling = true)]
public static extern bool SetForegroundWindow(IntPtr hwnd);

============================

Thanks again.
 
H

Harlan Messinger

sadegh said:
[...]
But when I minimize my program, It is stoped by the following error
message:
"Object reference not set to an instance of an object"
on line:
MyNamespace.MyClass.ActiveForm.Invoke((MethodInvoker)delegate
{ this.progressForm.Close(); });
The error message means that one of the parts in that line is null. You
could easily determine which one it is by means of the debugger. I suspect
that it is ActiveForm (if no form is left active after you minimize your
main form), but the debugger is your friend here; just examine the various
parts of that line after you get the error.

Thanks Alberto,
It seems that there was no ActiveForm. so I solved this problem by
adding 3 lines before the error line to activate my program MainForm:

-----------------------

for (int i=0; i<100; i++)
{
if (progressForm.cancel == true)
break;
progressForm.percent = i;
// ... do something
}

IntPtr mainFormHandle = FindWindowByCaption(IntPtr.Zero,
mainFormCaption); // find MainFormHandle by its caption
SetForegroundWindow(mainFormHandle); // activate MainForm
Thread.Sleep(100); // wait for windows to activate MainForm

MyNamespace.MyClass.ActiveForm.Invoke((MethodInvoker)delegate
{ this.progressForm.Close(); });

-------------------------------------
// FindWindowByCaption defenition:

[DllImport("user32.dll", EntryPoint = "FindWindow", SetLastError =
true)]
static extern IntPtr FindWindowByCaption(IntPtr zeroOnly, string
lpWindowName);


// SetForegroundWindow defenition:

[return: MarshalAs(UnmanagedType.Bool)]
[DllImport("user32", CharSet = CharSet.Ansi, SetLastError = true,
ExactSpelling = true)]
public static extern bool SetForegroundWindow(IntPtr hwnd);

This seems unnecessarily indirect. Assuming the code above is inside the
form in question, it seems you would also need to change the first line to

progressForm = new fclsProgress(this.Text);

and then, in progress form's constructor, you'd have

public fclsProgress(caption)
{
...
mainFormCaption = caption;
}

where mainFormCaption is declared as a private field of fclsProgress. In
that case, you can avoid all the sleuthing to find the form when you
need it by making the following changes up front:

progressForm = new fclsProgress(this);

and

public fclsProgress(form)
{
...
mainForm = form;
}

with mainForm as the private field.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top