Modeless status form, controls display as black

E

Ellen

Hi --

Excuse me if this is a common question and has been answered recently,
my searches didn't turn up what I was looking for.


I'm trying to write a modeless status form that other classes can call
and display information to the user while they're working.

The problem is that the controls aren't showing up correctly in the
status form when I call frm.Show() -- they show up as black rectangles
where the controls should be. They'll appear correctly if I use
frm.ShowDialog(), but I don't want a modal form.

I'm sure I'm missing something really basic here. What am I doing wrong?

TIA.
 
A

AlexS

Hi, Ellen

sounds like message loop doesn't execute properly when you do Show.
ShowDialog creates separate message loop - that could be one of reasons why
you have this problem.
Can you post code snippet illustrating this behavior?

HTH
Alex
 
E

Ellen

AlexS said:
Hi, Ellen

sounds like message loop doesn't execute properly when you do Show.
ShowDialog creates separate message loop - that could be one of reasons why
you have this problem.
Can you post code snippet illustrating this behavior?

HTH
Alex

Alex --


I can recreate this in a number of ways. My solution needs a VB module
because I'm going to do some MS Office automation. It doesn't matter
whether the status form is coded in C# or VB.NET, or whether the form is
in the same assembly as the client or not, I get the same results.
StatusForm is just a form that doesn't do *anything* yet.

Is there something wrong with my basic approach? What's the simplest way
to code a status form?


Public Class Client
Protected UI as myUI.Common

Public Sub New()
UI = new myUI.Common
End Sub

Public Sub DoSomethingAndTellMe()
' (once the basics work, I'll pass strings to display)
UI.ShowStatus()

' do other things.
End Sub
End Class


' in a separate assembly:

namespace myUI
{
public class Common
{
internal StatusForm statform;

public Common()
{
statform = new StatusForm();
}
public void ShowStatusForm()
{
try
{
statform.Show();
}
catch(Exception ex)
{
Console.WriteLine(ex.Message);
}

}

}
}
 
A

AlexS

Ellen,

it's not clear how you call DoSomethingAndTellMe and how you do
ShowStatusForm.

Quick and dirty variant is - not Main method body:

using System;

using System.Windows.Forms;

namespace DefaultNamespace

{

public class MainForm : System.Windows.Forms.Form

{

public MainForm()

{

InitializeComponent();


}


[STAThread]

public static void Main(string[] args)

{

StatusForm sf=new StatusForm();

sf.Show();

Application.Run(new MainForm());

}


private void InitializeComponent()

{

this.AutoScaleBaseSize = new System.Drawing.Size(5, 13);

this.ClientSize = new System.Drawing.Size(292, 266);

this.Text = "MainForm";

this.Name = "MainForm";

}

}


public class StatusForm : Form {

Button b;

public StatusForm() {

this.Text="Status form";

b=new Button();

b.Text="status button";

b.Click+=new EventHandler(bClick);

this.Controls.Add(b);

}


private void bClick(object sender, EventArgs ea) {

MessageBox.Show("status button clicked");

}

}

}
 
E

Ellen

AlexS said:
Ellen,

it's not clear how you call DoSomethingAndTellMe and how you do
ShowStatusForm.

Yet another class instantiates a Client object and then calls
Client.DoSomethingAndTellMe. The whole solution is eventually going to
be a set of DLLs that hooks into MS Office. It's already got too much
stuff in it to reduce to a code snippet, which is why I left it out.


In your example, why are you calling calling a MainForm? I see by
stepping through your code how that somehow "finishes" displaying sf.
But I don't want a second form -- and certainly not a modal one -- I
just want a modeless status form, that I can show and hide as I need to.

Thanks for taking the time, by the way.




Quick and dirty variant is - not Main method body:

using System;

using System.Windows.Forms;

namespace DefaultNamespace

{

public class MainForm : System.Windows.Forms.Form

{

public MainForm()

{

InitializeComponent();


}


[STAThread]

public static void Main(string[] args)

{

StatusForm sf=new StatusForm();

sf.Show();

Application.Run(new MainForm());

}


private void InitializeComponent()

{

this.AutoScaleBaseSize = new System.Drawing.Size(5, 13);

this.ClientSize = new System.Drawing.Size(292, 266);

this.Text = "MainForm";

this.Name = "MainForm";

}

}


public class StatusForm : Form {

Button b;

public StatusForm() {

this.Text="Status form";

b=new Button();

b.Text="status button";

b.Click+=new EventHandler(bClick);

this.Controls.Add(b);

}


private void bClick(object sender, EventArgs ea) {

MessageBox.Show("status button clicked");

}

}

}
 
A

AlexS

Ellen,

I would suggest to check for modal and modeless definitions. In .Net
ShowDialog is for modal, Show for modeless. Hence the sample. You can put my
definition of StatusForm in separate class project and it will work just the
same.

Maybe you meant something else? I am now not sure why you say
But I don't want a second form -- and certainly not a modal one -- I
just want a modeless status form, that I can show and hide as I need to.
In any case it will be second form - or in Win32 terms - window.

Sample demonstrates simple technique to show another modeless window, which
could be used to display status or for something else. Hide and Show methods
allow to hide and show the window. As soon as message loop is started in
Application.Run, both windows do coexist nearly independently and can
interact.

Because you don't post the code you use to instantiate your modeless window
and show it, I can't really say more.

HTH
Alex

Ellen said:
AlexS said:
Ellen,

it's not clear how you call DoSomethingAndTellMe and how you do
ShowStatusForm.

Yet another class instantiates a Client object and then calls
Client.DoSomethingAndTellMe. The whole solution is eventually going to
be a set of DLLs that hooks into MS Office. It's already got too much
stuff in it to reduce to a code snippet, which is why I left it out.


In your example, why are you calling calling a MainForm? I see by
stepping through your code how that somehow "finishes" displaying sf.
But I don't want a second form -- and certainly not a modal one -- I
just want a modeless status form, that I can show and hide as I need to.

Thanks for taking the time, by the way.




Quick and dirty variant is - not Main method body:

using System;

using System.Windows.Forms;

namespace DefaultNamespace

{

public class MainForm : System.Windows.Forms.Form

{

public MainForm()

{

InitializeComponent();


}


[STAThread]

public static void Main(string[] args)

{

StatusForm sf=new StatusForm();

sf.Show();

Application.Run(new MainForm());

}


private void InitializeComponent()

{

this.AutoScaleBaseSize = new System.Drawing.Size(5, 13);

this.ClientSize = new System.Drawing.Size(292, 266);

this.Text = "MainForm";

this.Name = "MainForm";

}

}


public class StatusForm : Form {

Button b;

public StatusForm() {

this.Text="Status form";

b=new Button();

b.Text="status button";

b.Click+=new EventHandler(bClick);

this.Controls.Add(b);

}


private void bClick(object sender, EventArgs ea) {

MessageBox.Show("status button clicked");

}

}

}
 
E

Ellen

I understand the difference between modal and modeless, and that
ShowDialog is for modal. In your code example everything else stops
until MainForm goes away, that's why I said I didn't want a modal form.

OK, here's a .sln that mirrors (I think) what I'm doing. What I'm not
understanding is how Application.Run() fits into this.

TIA.



// IN A CONSOLE APP THAT REFERENCES MAINDLL:
using System;
namespace testit
{
class Class1
{
[STAThread]
static void Main(string[] args)
{
MainDLL.Class2 cls = new MainDLL.Class2();
cls.DoSomething();
}
}
}


// IN A CLASS LIBRARY:
using System;
using System.Windows.Forms;

namespace MainDLL
{

// THIS IS IN Class2.cs

public class Class2
{
private Form1 frm;
public Class2()
{
frm = new Form1();
}

public void DoSomething()
{
ShowStatusForm("writing lines...");

for(int i = 0; i < 99; i++)
Console.WriteLine("line {0}", i);
}

public void ShowStatusForm(string msg)
{
frm.label1.Text = msg;
frm.Show();
}
}



// THIS IS IN Form1.cs

public class Form1 : System.Windows.Forms.Form
{
public System.Windows.Forms.Label label1;

public Form1()
{
InitializeComponent();
}

private void InitializeComponent()
{
this.label1 = new System.Windows.Forms.Label();
this.label1.Location = new System.Drawing.Point(80, 16);
this.label1.Name = "label1";
this.label1.Size = new System.Drawing.Size(144, 24);
this.label1.TabIndex = 0;
this.label1.Text = "My Status Message";

this.AutoScaleBaseSize = new System.Drawing.Size(5, 13);
this.ClientSize = new System.Drawing.Size(292, 126);
this.Controls.Add(this.label1);
this.Name = "Form1";
this.Text = "Form1";
this.Load += new System.EventHandler(this.Form1_Load);

}

private void Form1_Load(object sender, System.EventArgs e)
{

}
}

}
 
A

AlexS

Ellen,

what do you mean by "In your code example everything else stops
until MainForm goes away"? You can click button on StatusForm and if you
add controls to MainForm, they will be available and will react.

Application.Run starts message loop. I think I mentioned that already.
Otherwise you have to use ShowDialog - which has its own message loop.
Without message loop windows, which you created, can't receive any messages
and can't react on any.

Anyway, if I get you right, you can modify my sample by changing
Application.Run(new MainForm()) to simple call
Application.Run();

This will show only status form. In your code, you have to add
Application.Run(); in main Main method - no pun intended. Main, which is
defined as entry point for application. In posted code message loop is not
started anywhere.

See Application.Run overloads and related samples in .Net help files or in
MSDN for more details.

HTH
Alex
 
E

Ellen

Is there any other way to start the message loop? Do I need to make
another thread?

If I follow your suggestion and add Application.Run() to testit.Main(),

1) The form doesn't display correctly until all 99 lines have been
written to the console.
2) No code after Application.Run() runs. If I add
Application.Run();
Console.WriteLine("all done.");

to my Main(), "all done" will never get written.




Ellen,

what do you mean by "In your code example everything else stops
until MainForm goes away"? You can click button on StatusForm and if you
add controls to MainForm, they will be available and will react.

Application.Run starts message loop. I think I mentioned that already.
Otherwise you have to use ShowDialog - which has its own message loop.
Without message loop windows, which you created, can't receive any messages
and can't react on any.

Anyway, if I get you right, you can modify my sample by changing
Application.Run(new MainForm()) to simple call
Application.Run();

This will show only status form. In your code, you have to add
Application.Run(); in main Main method - no pun intended. Main, which is
defined as entry point for application. In posted code message loop is not
started anywhere.

See Application.Run overloads and related samples in .Net help files or in
MSDN for more details.

HTH
Alex


I understand the difference between modal and modeless, and that
ShowDialog is for modal. In your code example everything else stops
until MainForm goes away, that's why I said I didn't want a modal form.

OK, here's a .sln that mirrors (I think) what I'm doing. What I'm not
understanding is how Application.Run() fits into this.

TIA.



// IN A CONSOLE APP THAT REFERENCES MAINDLL:
using System;
namespace testit
{
class Class1
{
[STAThread]
static void Main(string[] args)
{
MainDLL.Class2 cls = new MainDLL.Class2();
cls.DoSomething();
}
}
}


// IN A CLASS LIBRARY:
using System;
using System.Windows.Forms;

namespace MainDLL
{

// THIS IS IN Class2.cs

public class Class2
{
private Form1 frm;
public Class2()
{
frm = new Form1();
}

public void DoSomething()
{
ShowStatusForm("writing lines...");

for(int i = 0; i < 99; i++)
Console.WriteLine("line {0}", i);
}

public void ShowStatusForm(string msg)
{
frm.label1.Text = msg;
frm.Show();
}
}



// THIS IS IN Form1.cs

public class Form1 : System.Windows.Forms.Form
{
public System.Windows.Forms.Label label1;

public Form1()
{
InitializeComponent();
}

private void InitializeComponent()
{
this.label1 = new System.Windows.Forms.Label();
this.label1.Location = new System.Drawing.Point(80, 16);
this.label1.Name = "label1";
this.label1.Size = new System.Drawing.Size(144, 24);
this.label1.TabIndex = 0;
this.label1.Text = "My Status Message";

this.AutoScaleBaseSize = new System.Drawing.Size(5, 13);
this.ClientSize = new System.Drawing.Size(292, 126);
this.Controls.Add(this.label1);
this.Name = "Form1";
this.Text = "Form1";
this.Load += new System.EventHandler(this.Form1_Load);

}

private void Form1_Load(object sender, System.EventArgs e)
{

}
}

}
 
A

AlexS

Ellen,

1. Of course, because you have tight loop when writing to console and do not
allow message loop to run. If you insert DoEvents() call in the loop, form
will appear immediately.
2. it will run after you close the form - which means, message loop will
complete.

I would suggest to get some book on how to program for windows, for example,
Petzold's Programming Windows with C#, and read a bit about basic behavior
of windows, message loops and such :)

I think it's never late to learn. Unfortunately Windows is not easy
environment to play with without at least some background.

HTH
Alex

Ellen said:
Is there any other way to start the message loop? Do I need to make
another thread?

If I follow your suggestion and add Application.Run() to testit.Main(),

1) The form doesn't display correctly until all 99 lines have been
written to the console.
2) No code after Application.Run() runs. If I add
Application.Run();
Console.WriteLine("all done.");

to my Main(), "all done" will never get written.




Ellen,

what do you mean by "In your code example everything else stops
until MainForm goes away"? You can click button on StatusForm and if you
add controls to MainForm, they will be available and will react.

Application.Run starts message loop. I think I mentioned that already.
Otherwise you have to use ShowDialog - which has its own message loop.
Without message loop windows, which you created, can't receive any messages
and can't react on any.

Anyway, if I get you right, you can modify my sample by changing
Application.Run(new MainForm()) to simple call
Application.Run();

This will show only status form. In your code, you have to add
Application.Run(); in main Main method - no pun intended. Main, which is
defined as entry point for application. In posted code message loop is not
started anywhere.

See Application.Run overloads and related samples in .Net help files or in
MSDN for more details.

HTH
Alex


I understand the difference between modal and modeless, and that
ShowDialog is for modal. In your code example everything else stops
until MainForm goes away, that's why I said I didn't want a modal form.

OK, here's a .sln that mirrors (I think) what I'm doing. What I'm not
understanding is how Application.Run() fits into this.

TIA.



// IN A CONSOLE APP THAT REFERENCES MAINDLL:
using System;
namespace testit
{
class Class1
{
[STAThread]
static void Main(string[] args)
{
MainDLL.Class2 cls = new MainDLL.Class2();
cls.DoSomething();
}
}
}


// IN A CLASS LIBRARY:
using System;
using System.Windows.Forms;

namespace MainDLL
{

// THIS IS IN Class2.cs

public class Class2
{
private Form1 frm;
public Class2()
{
frm = new Form1();
}

public void DoSomething()
{
ShowStatusForm("writing lines...");

for(int i = 0; i < 99; i++)
Console.WriteLine("line {0}", i);
}

public void ShowStatusForm(string msg)
{
frm.label1.Text = msg;
frm.Show();
}
}



// THIS IS IN Form1.cs

public class Form1 : System.Windows.Forms.Form
{
public System.Windows.Forms.Label label1;

public Form1()
{
InitializeComponent();
}

private void InitializeComponent()
{
this.label1 = new System.Windows.Forms.Label();
this.label1.Location = new System.Drawing.Point(80, 16);
this.label1.Name = "label1";
this.label1.Size = new System.Drawing.Size(144, 24);
this.label1.TabIndex = 0;
this.label1.Text = "My Status Message";

this.AutoScaleBaseSize = new System.Drawing.Size(5, 13);
this.ClientSize = new System.Drawing.Size(292, 126);
this.Controls.Add(this.label1);
this.Name = "Form1";
this.Text = "Form1";
this.Load += new System.EventHandler(this.Form1_Load);

}

private void Form1_Load(object sender, System.EventArgs e)
{

}
}

}
 
E

Ellen

Ya know, you're kind of a condescending jerk. I've been programming in
VB6 for a long time, I just happen to be new to .NET.



Ellen,

1. Of course, because you have tight loop when writing to console and do not
allow message loop to run. If you insert DoEvents() call in the loop, form
will appear immediately.
2. it will run after you close the form - which means, message loop will
complete.

I would suggest to get some book on how to program for windows, for example,
Petzold's Programming Windows with C#, and read a bit about basic behavior
of windows, message loops and such :)

I think it's never late to learn. Unfortunately Windows is not easy
environment to play with without at least some background.

HTH
Alex

Is there any other way to start the message loop? Do I need to make
another thread?

If I follow your suggestion and add Application.Run() to testit.Main(),

1) The form doesn't display correctly until all 99 lines have been
written to the console.
2) No code after Application.Run() runs. If I add
Application.Run();
Console.WriteLine("all done.");

to my Main(), "all done" will never get written.





AlexS wrote:

Ellen,

what do you mean by "In your code example everything else stops
until MainForm goes away"? You can click button on StatusForm and if
you
add controls to MainForm, they will be available and will react.

Application.Run starts message loop. I think I mentioned that already.
Otherwise you have to use ShowDialog - which has its own message loop.
Without message loop windows, which you created, can't receive any
messages
and can't react on any.

Anyway, if I get you right, you can modify my sample by changing
Application.Run(new MainForm()) to simple call
Application.Run();

This will show only status form. In your code, you have to add
Application.Run(); in main Main method - no pun intended. Main, which is
defined as entry point for application. In posted code message loop is
not
started anywhere.

See Application.Run overloads and related samples in .Net help files or
in
MSDN for more details.

HTH
Alex




I understand the difference between modal and modeless, and that
ShowDialog is for modal. In your code example everything else stops
until MainForm goes away, that's why I said I didn't want a modal form.

OK, here's a .sln that mirrors (I think) what I'm doing. What I'm not
understanding is how Application.Run() fits into this.

TIA.



// IN A CONSOLE APP THAT REFERENCES MAINDLL:
using System;
namespace testit
{
class Class1
{
[STAThread]
static void Main(string[] args)
{
MainDLL.Class2 cls = new MainDLL.Class2();
cls.DoSomething();
}
}
}


// IN A CLASS LIBRARY:
using System;
using System.Windows.Forms;

namespace MainDLL
{

// THIS IS IN Class2.cs

public class Class2
{
private Form1 frm;
public Class2()
{
frm = new Form1();
}

public void DoSomething()
{
ShowStatusForm("writing lines...");

for(int i = 0; i < 99; i++)
Console.WriteLine("line {0}", i);
}

public void ShowStatusForm(string msg)
{
frm.label1.Text = msg;
frm.Show();
}
}



// THIS IS IN Form1.cs

public class Form1 : System.Windows.Forms.Form
{
public System.Windows.Forms.Label label1;

public Form1()
{
InitializeComponent();
}

private void InitializeComponent()
{
this.label1 = new System.Windows.Forms.Label();
this.label1.Location = new System.Drawing.Point(80, 16);
this.label1.Name = "label1";
this.label1.Size = new System.Drawing.Size(144, 24);
this.label1.TabIndex = 0;
this.label1.Text = "My Status Message";

this.AutoScaleBaseSize = new System.Drawing.Size(5, 13);
this.ClientSize = new System.Drawing.Size(292, 126);
this.Controls.Add(this.label1);
this.Name = "Form1";
this.Text = "Form1";
this.Load += new System.EventHandler(this.Form1_Load);

}

private void Form1_Load(object sender, System.EventArgs e)
{

}
}

}
 
A

AlexS

Ellen,

I don't know what you know. I just see the code you write and questions you
ask. No offence meant.

..Net docs clearly state what Application.Run does and what are modal /
modeless forms. Your questions miss the point sometimes. That's why I
suggested the book. It's not easy to explain all details in couple of
phrases - I can't repeat all the stuff the guys wrote in the books here.

Is your code working now?

:)

Alex

Ellen said:
Ya know, you're kind of a condescending jerk. I've been programming in
VB6 for a long time, I just happen to be new to .NET.



Ellen,

1. Of course, because you have tight loop when writing to console and do not
allow message loop to run. If you insert DoEvents() call in the loop, form
will appear immediately.
2. it will run after you close the form - which means, message loop will
complete.

I would suggest to get some book on how to program for windows, for example,
Petzold's Programming Windows with C#, and read a bit about basic behavior
of windows, message loops and such :)

I think it's never late to learn. Unfortunately Windows is not easy
environment to play with without at least some background.

HTH
Alex

Is there any other way to start the message loop? Do I need to make
another thread?

If I follow your suggestion and add Application.Run() to testit.Main(),

1) The form doesn't display correctly until all 99 lines have been
written to the console.
2) No code after Application.Run() runs. If I add
Application.Run();
Console.WriteLine("all done.");

to my Main(), "all done" will never get written.





AlexS wrote:


Ellen,

what do you mean by "In your code example everything else stops
until MainForm goes away"? You can click button on StatusForm and if
you

add controls to MainForm, they will be available and will react.

Application.Run starts message loop. I think I mentioned that already.
Otherwise you have to use ShowDialog - which has its own message loop.
Without message loop windows, which you created, can't receive any
messages

and can't react on any.

Anyway, if I get you right, you can modify my sample by changing
Application.Run(new MainForm()) to simple call
Application.Run();

This will show only status form. In your code, you have to add
Application.Run(); in main Main method - no pun intended. Main, which is
defined as entry point for application. In posted code message loop is
not

started anywhere.

See Application.Run overloads and related samples in .Net help files or
in

MSDN for more details.

HTH
Alex




I understand the difference between modal and modeless, and that
ShowDialog is for modal. In your code example everything else stops
until MainForm goes away, that's why I said I didn't want a modal form.

OK, here's a .sln that mirrors (I think) what I'm doing. What I'm not
understanding is how Application.Run() fits into this.

TIA.



// IN A CONSOLE APP THAT REFERENCES MAINDLL:
using System;
namespace testit
{
class Class1
{
[STAThread]
static void Main(string[] args)
{
MainDLL.Class2 cls = new MainDLL.Class2();
cls.DoSomething();
}
}
}


// IN A CLASS LIBRARY:
using System;
using System.Windows.Forms;

namespace MainDLL
{

// THIS IS IN Class2.cs

public class Class2
{
private Form1 frm;
public Class2()
{
frm = new Form1();
}

public void DoSomething()
{
ShowStatusForm("writing lines...");

for(int i = 0; i < 99; i++)
Console.WriteLine("line {0}", i);
}

public void ShowStatusForm(string msg)
{
frm.label1.Text = msg;
frm.Show();
}
}



// THIS IS IN Form1.cs

public class Form1 : System.Windows.Forms.Form
{
public System.Windows.Forms.Label label1;

public Form1()
{
InitializeComponent();
}

private void InitializeComponent()
{
this.label1 = new System.Windows.Forms.Label();
this.label1.Location = new System.Drawing.Point(80, 16);
this.label1.Name = "label1";
this.label1.Size = new System.Drawing.Size(144, 24);
this.label1.TabIndex = 0;
this.label1.Text = "My Status Message";

this.AutoScaleBaseSize = new System.Drawing.Size(5, 13);
this.ClientSize = new System.Drawing.Size(292, 126);
this.Controls.Add(this.label1);
this.Name = "Form1";
this.Text = "Form1";
this.Load += new System.EventHandler(this.Form1_Load);

}

private void Form1_Load(object sender, System.EventArgs e)
{

}
}

}
 
E

Ellen

Well I apologize for flying off the handle if it's simple
misunderstanding. Is English your first language?

Here's the thing: all I'm trying to do is RE-create functionality that's
actually quite simple to do in VB6. It's not that I'm new to Windows
programming, it's that I'm new to doing it with all the
behind-the-scenes trickery that VB automatically throws in for you. IOW,
I'm new to doing it without VB's version of ActiveX and COM.

Thanks for your help, but it appears you can't actually help me. Maybe
someone else will read all this and respond someday.



Ellen,

I don't know what you know. I just see the code you write and questions you
ask. No offence meant.

.Net docs clearly state what Application.Run does and what are modal /
modeless forms. Your questions miss the point sometimes. That's why I
suggested the book. It's not easy to explain all details in couple of
phrases - I can't repeat all the stuff the guys wrote in the books here.

Is your code working now?

:)

Alex

Ya know, you're kind of a condescending jerk. I've been programming in
VB6 for a long time, I just happen to be new to .NET.



Ellen,

1. Of course, because you have tight loop when writing to console and do
not
allow message loop to run. If you insert DoEvents() call in the loop,
form
will appear immediately.
2. it will run after you close the form - which means, message loop will
complete.

I would suggest to get some book on how to program for windows, for
example,
Petzold's Programming Windows with C#, and read a bit about basic
behavior
of windows, message loops and such :)

I think it's never late to learn. Unfortunately Windows is not easy
environment to play with without at least some background.

HTH
Alex



Is there any other way to start the message loop? Do I need to make
another thread?

If I follow your suggestion and add Application.Run() to testit.Main(),

1) The form doesn't display correctly until all 99 lines have been
written to the console.
2) No code after Application.Run() runs. If I add
Application.Run();
Console.WriteLine("all done.");

to my Main(), "all done" will never get written.





AlexS wrote:



Ellen,

what do you mean by "In your code example everything else stops
until MainForm goes away"? You can click button on StatusForm and if

you


add controls to MainForm, they will be available and will react.

Application.Run starts message loop. I think I mentioned that already.
Otherwise you have to use ShowDialog - which has its own message loop.
Without message loop windows, which you created, can't receive any

messages


and can't react on any.

Anyway, if I get you right, you can modify my sample by changing
Application.Run(new MainForm()) to simple call
Application.Run();

This will show only status form. In your code, you have to add
Application.Run(); in main Main method - no pun intended. Main, which
is
defined as entry point for application. In posted code message loop is

not


started anywhere.

See Application.Run overloads and related samples in .Net help files or

in


MSDN for more details.

HTH
Alex





I understand the difference between modal and modeless, and that
ShowDialog is for modal. In your code example everything else stops
until MainForm goes away, that's why I said I didn't want a modal
form.
OK, here's a .sln that mirrors (I think) what I'm doing. What I'm not
understanding is how Application.Run() fits into this.

TIA.



// IN A CONSOLE APP THAT REFERENCES MAINDLL:
using System;
namespace testit
{
class Class1
{
[STAThread]
static void Main(string[] args)
{
MainDLL.Class2 cls = new MainDLL.Class2();
cls.DoSomething();
}
}
}


// IN A CLASS LIBRARY:
using System;
using System.Windows.Forms;

namespace MainDLL
{

// THIS IS IN Class2.cs

public class Class2
{
private Form1 frm;
public Class2()
{
frm = new Form1();
}

public void DoSomething()
{
ShowStatusForm("writing lines...");

for(int i = 0; i < 99; i++)
Console.WriteLine("line {0}", i);
}

public void ShowStatusForm(string msg)
{
frm.label1.Text = msg;
frm.Show();
}
}



// THIS IS IN Form1.cs

public class Form1 : System.Windows.Forms.Form
{
public System.Windows.Forms.Label label1;

public Form1()
{
InitializeComponent();
}

private void InitializeComponent()
{
this.label1 = new System.Windows.Forms.Label();
this.label1.Location = new System.Drawing.Point(80, 16);
this.label1.Name = "label1";
this.label1.Size = new System.Drawing.Size(144, 24);
this.label1.TabIndex = 0;
this.label1.Text = "My Status Message";

this.AutoScaleBaseSize = new System.Drawing.Size(5, 13);
this.ClientSize = new System.Drawing.Size(292, 126);
this.Controls.Add(this.label1);
this.Name = "Form1";
this.Text = "Form1";
this.Load += new System.EventHandler(this.Form1_Load);

}

private void Form1_Load(object sender, System.EventArgs e)
{

}
}

}
 
R

Ron

Hi Ellen.

I think I had a similar problem, where a label did not appear on my modeless
status form
(which appeared over top of the main form).
I was able to resolve the problem by forcing the status form to be
repainted.

So, I created my status form when my app started...

// Create the form
StatusForm mf = new StatusForm();

and then when I wanted to display the status form...

// Set the Message property that my status form will copy to the label
mf.Message = "Backing up datafiles...";
// Display my status form
mf.Show();
// Make the status form repaint (so it showed the label)
mf.Update();
// Do the background work
DoTheBackup();
// Finished, so hide the status form
mf.Hide();

Finally, when my app closed, I disposed of the status form...

// Dispose of status form
mf.Dispose();

Hope this helps.

Good Luck!

Ron

Ellen said:
Well I apologize for flying off the handle if it's simple
misunderstanding. Is English your first language?

Here's the thing: all I'm trying to do is RE-create functionality that's
actually quite simple to do in VB6. It's not that I'm new to Windows
programming, it's that I'm new to doing it with all the
behind-the-scenes trickery that VB automatically throws in for you. IOW,
I'm new to doing it without VB's version of ActiveX and COM.

Thanks for your help, but it appears you can't actually help me. Maybe
someone else will read all this and respond someday.
<snip>
 
B

bottas

Thanks for the suggestion, I'll check it out, but actually I just
figured out a way to get where I need to go.

I just need to call Application.DoEvents() after I call statform.Show();

I'll make sure I dispose of the form properly, but DoEvents fixed the
problem for me.
 

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