Tricky form problem

C

Christian Schwarz

Hello,

I'm totally stuck at the following tricky problem. Hopefully someone of you
has got an advice how to solve ...

Our main application class has got a main form which shows some buttons
(main menu). The Click-EventHandler of those buttons create and show (using
ShowDialog method) different modal child forms. Some of those modal child
forms also create and show other modal child forms. To make it short, all
forms are modal and all is working like a charm. I really don't want to
change this part of the application.

In order to use the devices as phones, one of our customer equiped the
devices with modem cards (CF). The phone functionality should be available
at any time throughout the whole application. So I extended our main
application class by installing an hotkey (RegisterHotKey, Win32 API) to
toggle a form which exposes some phone functionality (do calls, read and
write sms, ...). This phone form is created in our main application class
and works well as long as it is shown (using Show method) from within the
main form. When using the hotkey from within a modal child form of the main
form, we get into trouble. Altough the phone form pops up, it doesn't react
on clicks. There is not problem closing the phone form by pressing the
hotkey again. On the other side, when using ShowDialog() there's no problem
showing and using the phone form from within one of the child forms.
Unfortunately, when popping up the phone form automatically because of an
incoming call or an incoming sms, the ShowDialog() method blocks the event
processing of our modem class (the IncomingVoiceCall-Event in the code
snippets below) until the form is closed. So I cannot use the ShowDialog()
method.

The question is, why doesn't work the Show() method from within modal child
forms? Is there a way to get around this problem? Do you see a better way?

Here are some code snippets for better understanding:

MainClass()
{
static void Main(...)
{
Application.Run(new MainForm());
}
}

public class MainForm : Form
{
private MyApplication m_App;

protected override OnLoad(...)
{
this.m_App = new MyApplication();
this.m_App.Init();
}
}

public class MyApplication
{
private Phone m_Phone;

public void Init()
{
this.m_Phone = new Phone();
this.m_Phone.PhoneForm = new PhoneForm();

RegisterHotKey(...);
}

private void OnPhoneHotKey()
{
this.Phone.ShowForm();
}
}

public class Phone
{
private GsmModem m_Modem;
private IStandardPhoneForm m_PhoneForm;

public Phone()
{
this.m_Modem = new GsmModem();
this.m_Modem.IncomingVoiceCall += new
IncomingVoiceCallEventHandler(this.IncomingVoiceCall);
}

public IStandardPhoneForm PhoneForm
{
get ...
set ...
}

public void ShowForm()
{
this.m_PhoneForm.ShowForm();
}

private void IncomingVoiceCall(...)
{
... send calling number by calling PhoneForm methods
... ringing
this.PhoneForm.ShowIncomingVoiceCall(...);
}
}

public class PhoneForm : Form, IStandardPhoneForm
{
private void InvokeShowForm(object sender, EventArgs args)
{
if (!this.Visible)
{
this.Show();
}
else
{
this.BringToFront();
}
}

public void ShowForm()
{
... activate standard TabPage
this.Invoke(new EventHandler(this.InvokeShowForm));
}

public void ShowIncomingVoiceCall(...)
{
... activate incoming voice call TabPage
this.Invoke(new EventHandler(this.InvokeShowForm));
}
}

Greetings, Christian
 
P

Paul G. Tobey [eMVP]

Why does it have to be a single application? Couldn't you start a separate
phone application at an appropriate time to handle dialing or whatever?

Paul T.
 
C

Christian Schwarz

Why does it have to be a single application? Couldn't you start a
separate
phone application at an appropriate time to handle dialing or whatever?

I've already thought about this.

There are at least the following two reason against this solution. First, it
would greatly complicate the communication between the Phone class and the
rest of our application. For instance, calling a special phone number or
sending a short message automatically would require inter-process
communication. Second, the additional memory overhead required for running
another .NET CF application could be the overkill.

If there's really no other solution, I'll have to split it into two seperate
applications ...

Greetings, Christian
 
A

Alex Feinman [MVP]

I concur with Paul - a separate dialer is the best solution in this case.
The memory overhead is not going to be a killer - most likely an extra 500 K
or so. As for interprocess communication, there are numerous ways to handle
it and none of them is more complex than the problem with forms you are
having.
 
P

Paul G. Tobey [eMVP]

Right. Most of the run-time is shared between the processes, anyway. The
only other solution I can see is to make everything modeless so a dialer is
just one more form in a large collection where none is more important than
any other.

Paul T.
 
D

Duncan Mole

I had this problem once. If all your forms are full screen then the only
benefit of ShowDialog is getting a Dialog result. You can define an enum to
mimic the values you were using, declare a delegate to take this type and
implement a simple call back mecanism like Show(SimpleCallBack callWhenDone)
 
C

Christian Schwarz

Right. Most of the run-time is shared between the processes, anyway. The

Do you know wether the managed assemblies also shared between the processes?

Greetings, Christian
 
D

Daniel Moth

Right. Most of the run-time is shared between the processes, anyway. The

Interesting. Where are you getting that information from Paul? It is
contrary to my understanding (every process loads the CLR into its space
inc. libraries; the GAC is just a convenience for not copying the .NETcf
assemblies in each app's directory).

Cheers
Daniel
 
P

Paul G. Tobey [eMVP]

The code would likely just be mapped from one address space to another, but
no, I don't have a deep understanding of the characteristics of the CE CLR.
You could probably run a test to figure that out...

Paul T.
 
P

Paul G. Tobey [eMVP]

At the CE level, 'loading' a DLL a second time doesn't actually 'load'
anything new anywhere. It simply maps the executable code into the new
process. So, I guess you could say that you 'lose' that part of the address
space, but there's no significant 'load' operation going on...

Paul T.
 
D

Daniel Moth

Hmm... thanks for that... I was looking for a speed/memory gain for .NETcf
apps starting after the first one but that doesn't seem to be the case...

Cheers
Daniel
 
P

Paul G. Tobey [eMVP]

My guess is that the code JITter separately JITs for each program, which
makes sense, although it would be nice if there were a switch which would
allow you to 'combine' the JIT space for several processes, if those were
highly cooperative processes, as would be the case here.

Paul T.

Daniel Moth said:
Hmm... thanks for that... I was looking for a speed/memory gain for .NETcf
apps starting after the first one but that doesn't seem to be the case...

Cheers
Daniel

Paul G. Tobey said:
At the CE level, 'loading' a DLL a second time doesn't actually 'load'
anything new anywhere. It simply maps the executable code into the new
process. So, I guess you could say that you 'lose' that part of the address
space, but there's no significant 'load' operation going on...

Paul T.

Daniel Moth said:
Right. Most of the run-time is shared between the processes, anyway.
The

Interesting. Where are you getting that information from Paul? It is
contrary to my understanding (every process loads the CLR into its
space
inc. libraries; the GAC is just a convenience for not copying the
.NETcf
assemblies in each app's directory).

Cheers
Daniel


"Paul G. Tobey [eMVP]" <ptobey no spam AT no instrument no spam DOT
com>
wrote in message Right. Most of the run-time is shared between the processes, anyway.
The
only other solution I can see is to make everything modeless so a dialer
is
just one more form in a large collection where none is more important
than
any other.

Paul T.

I concur with Paul - a separate dialer is the best solution in this
case.
The memory overhead is not going to be a killer - most likely an
extra
500
K or so. As for interprocess communication, there are numerous ways
to
handle it and none of them is more complex than the problem with
forms
you
are having.

--
Alex Feinman
---
Visit http://www.opennetcf.org
Why does it have to be a single application? Couldn't you start a
separate
phone application at an appropriate time to handle dialing or
whatever?

I've already thought about this.

There are at least the following two reason against this solution.
First,
it
would greatly complicate the communication between the Phone class and
the
rest of our application. For instance, calling a special phone number
or
sending a short message automatically would require inter-process
communication. Second, the additional memory overhead required for
running
another .NET CF application could be the overkill.

If there's really no other solution, I'll have to split it into two
seperate
applications ...

Greetings, Christian
 
C

Christian Schwarz

Many thanks for your suggestions. It seems a seperate application is the
only solution. I'll think about it ...

Greetings, Christian
 
P

Paul G. Tobey [eMVP]

"Only" probably not, but "fastest to market" and "most reliable in all
situations", probably so.

Paul T.
 

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