BorlandTalk.com Forum Index BorlandTalk.com
Borland discussion newsgroups
 
Archives   FAQFAQ   SearchSearch   MemberlistMemberlist   UsergroupsUsergroups   RegisterRegister 
 ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

ZOrder of Forms

 
Post new topic   Reply to topic    BorlandTalk.com Forum Index -> C++ Builder (VCL Components Usage)
View previous topic :: View next topic  
Author Message
Chris
Guest





PostPosted: Tue Apr 25, 2006 7:03 pm    Post subject: ZOrder of Forms Reply with quote



Hi

I'm struggling a bit with the window ZOrder in my app.

The problem is that I need to display a window non-modally but this window
occasionally shows modal forms.

The non-modal form also must have a task bar button so that the user can
easily switch between the main screen and the non-modal form.

So to recap:

Form1 (Main Form with taskbar button)
Form2 (Non-Modal Form with taskbar button)
Form3 (Modal Form called from Form2)

If the user has all three screens open and is working in Form3 then the
ZOrder (visually) looks like

Form1
Form2
Form3

and there are two buttons on the task bar (Form1 , Form2).

If the user swaps to another application and then back to mine by clicking
on the taskbar buttons all works well if he uses Form1's taskbar button,
i.e. the forms are still 'stacked' in the same order as when he left, but if
he clicks on Form2's taskbar button then Form2 (which is disabled because
Form3 is modal) comes to the front and hence the app appears to have locked
(clicking between the taskbar buttons does bring the forms back into the
'correct' order eventually).

i.e.

Form1
Form3
Form2

To see this in action create a new application with three forms, add a
button to form1 and 2.

In Form1::ButtonClick
Form2->Show();

In Form2::ButtonClick
Form3->ShowModal();

I use the following to create the taskbar button in form2

void __fastcall TForm2::CreateParams(TCreateParams &Params)
{
TForm::CreateParams(Params);
Params.ExStyle |= WS_EX_APPWINDOW;
}

Running the app and following the above and you should see the problem.

I think that a solution might be to somehow disable Form2 from reacting to
any clicks on it's taskbar button if it is disabled and instead pass the
message (or whatever) on to Form1's taskbar button.

An alternate solution was to remove the taskbar button of Form2 before
showing Form3, I tried using this:

long exstyle = GetWindowLong(hwnd, GWL_EXSTYLE);
SetWindowLong(hwnd, GWL_EXSTYLE, exstyle & ~WS_EX_APPWINDOW);

But unfortunately this didn't work.

Anyone able to help?

Best regards

Chris
Back to top
JD
Guest





PostPosted: Wed Apr 26, 2006 7:03 am    Post subject: Re: ZOrder of Forms Reply with quote



"Chris" <nospam (AT) nospam (DOT) com> wrote:
Quote:

[...] but if he clicks on Form2's taskbar button then Form2
(which is disabled because Form3 is modal) comes to the
front

I'm sure that there are several ways to get what you want but
this worked for me:

//-------------------------------------------------------------
__fastcall TForm1::TForm1(TComponent* Owner) : TForm(Owner)
{
Application->OnActivate = AppActivate;
}
//-------------------------------------------------------------
__fastcall TForm1::~TForm1()
{
Application->OnActivate = NULL;
}
//-------------------------------------------------------------
void __fastcall TForm1::AppActivate(TObject *Sender)
{
if( Form3->Visible ) ::SetForegroundWindow( Form3->Handle );
}
//-------------------------------------------------------------

If you have other issues like dynamic allocation ect., you'll
have to work out the details.

~ JD
Back to top
Chris
Guest





PostPosted: Wed Apr 26, 2006 8:03 am    Post subject: Re: ZOrder of Forms Reply with quote



"JD" <nospam (AT) nospam (DOT) com> wrote in message
news:444f0d87$1 (AT) newsgroups (DOT) borland.com...
Quote:

I'm sure that there are several ways to get what you want but
this worked for me:

//-------------------------------------------------------------
__fastcall TForm1::TForm1(TComponent* Owner) : TForm(Owner)
{
Application->OnActivate = AppActivate;
}
//-------------------------------------------------------------
__fastcall TForm1::~TForm1()
{
Application->OnActivate = NULL;
}
//-------------------------------------------------------------
void __fastcall TForm1::AppActivate(TObject *Sender)
{
if( Form3->Visible ) ::SetForegroundWindow( Form3->Handle );
}
//-------------------------------------------------------------


Hi JD

Thanks for the answer.

I don't think this will work fo rme though as the sample I posted was just
to reproduce the problem. I was really looking for a solution that was more
generic (i.e. didn't have to know what other forms might be visible etc) as
in my real app all the forms are created dynamically etc and I'm sure the
logic to try and keep everything working smoothly would be a nightmare.

I will see what others care to suggest and then see what works the best.

Thanks once again

Chris
Back to top
JD
Guest





PostPosted: Wed Apr 26, 2006 11:03 am    Post subject: Re: ZOrder of Forms Reply with quote

"Chris" <nospam (AT) nospam (DOT) com> wrote:
Quote:

I don't think this will work fo rme though as the sample I
posted was just to reproduce the problem. I was really
looking for a solution that was more generic (i.e. didn't
have to know what other forms might be visible etc)

You should have included that information to begin with.


#include <vector>
std::vector<TForm*>vForms;
//-------------------------------------------------------------
__fastcall TForm1::TForm1(TComponent* Owner) : TForm(Owner)
{
Application->OnActivate = AppActivate;
Application->OnDeactivate = AppDeactivate;
}
//-------------------------------------------------------------
__fastcall TForm1::~TForm1()
{
Application->OnActivate = NULL;
Application->OnDeactivate = NULL;
}
//-------------------------------------------------------------
void __fastcall TForm1::AppDeactivate(TObject *Sender)
{
for( int x = 0; x < Screen->FormCount; ++x )
{
if( Screen->Forms[x]->Visible ) vForms.push_back( Screen->Forms[x] );
}
}
//-------------------------------------------------------------
void __fastcall TForm1::AppActivate(TObject *Sender)
{
for( int x = vForms.size() - 1; x > -1; --x )
{
::SetForegroundWindow( vForms[x]->Handle );
}
}
//-------------------------------------------------------------

~ JD
Back to top
JD
Guest





PostPosted: Wed Apr 26, 2006 11:03 am    Post subject: Re: ZOrder of Forms Reply with quote

"JD" <nospam (AT) nospam (DOT) com> wrote:
Quote:


I should add that if you have doubts about the reliability
of the sample, the Screen::Forms property maintaines the list
according to their ZOrder.

~ JD
Back to top
Chris
Guest





PostPosted: Sat Apr 29, 2006 12:03 pm    Post subject: Re: ZOrder of Forms Reply with quote

Hi JD

Thanks for the revised version. This is better but still has problems (if
just form1 and Form2 are showing, clicking on Form2's task bar button
results in incorrect zorder etc)

I will keep playing to see if I get anywhere, but I must confess that I have
added a 'Window List' menu item to my app and I may yet remove all task bar
buttons and simply let the user select the screen via the menu.

Thanks for looking all the same and for the pointers.

Chris
Back to top
Display posts from previous:   
Post new topic   Reply to topic    BorlandTalk.com Forum Index -> C++ Builder (VCL Components Usage) All times are GMT
Page 1 of 1

 
Jump to:  
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum


Powered by phpBB © 2001, 2006 phpBB Group
SEO toolkit © 2004-2006 webmedic.