The Perl Toolchain Summit needs more sponsors. If your company depends on Perl, please support this very important event.
=head1 Win32::GUI Tutorial - Part 5 - More than one window

=head2 A simple multi-window program

Before going further into control details, we'll explore the case of
applications that make use of more than one window.

In principle, Win32::GUI does not limit the number of windows a program
can have: we've seen that the usual procedure for a program is:

=over 4

=item 1

create the main window, eg:

	$Window = new Win32::GUI::Window(...);

=item 2

create controls, eg:

	$Window->Add...(...);

=item 3

show the window, eg:

	$Window->Show();

=item 4

call the dialog phase, eg:

	Win32::GUI::Dialog();

=back

Steps 1, 2 and 3 can be repeated how many times you like, to create
several independent windows:

	use Win32::GUI;
	
	$W1 = new Win32::GUI::Window(
		-name  => "W1",
		-title => "First Window",
		-pos   => [ 100, 100 ],
		-size  => [ 300, 200 ],
	);
	$W2 = new Win32::GUI::Window(
		-name  => "W2",
		-title => "Second Window",
		-pos   => [ 150, 150 ],
		-size  => [ 300, 200 ],
	);

	$W1->Show();
	$W2->Show();
	
	Win32::GUI::Dialog();


the two windows we've created are displayed on the screen and are both 
able to intercept events and user interaction, with the rather obvious 
limitation that while the code for a window's event is executing, the
other one is frozen; whis is due to the single-threaded nature of Perl,
although work is being done for a full featured multithreaded Perl).

=for HTML <BR><BR><CENTER><IMG SRC="guitut5-1.gif"></CENTER>

One thing to note is that even if the windows are two, they belong to
the same process and share a single message loop, so when you exit from
one window (or when the program terminates for whatever reason), they
both disappear:

	sub W1_Terminate { return -1; }

=head2 Main and popup windows

A much more common case is to have a program using a main window, 
initially shown, and one or more popup windows (generally DialogBoxes)
that are shown in response to a precise function; to make an example,
you can imagine the Windows Explorer as your main window and the File
Properties dialog as a popup window.

We'll modify our program so that the second window appears when the
user clicks the button on the first window:

	use Win32::GUI;
	
	$W1 = new Win32::GUI::Window(
		-name  => "W1",
		-title => "Main Window",
		-pos   => [ 100, 100 ],
		-size  => [ 300, 200 ],
	);
	$W1->AddButton(
		-name => "Button1",
		-text => "Open popup window",
		-pos  => [ 10, 10 ],
	);
	
	$W2 = new Win32::GUI::Window(
		-name  => "W2",
		-title => "Popup Window",
		-pos   => [ 150, 150 ],
		-size  => [ 300, 200 ],
	);

	$W1->Show();
	
	Win32::GUI::Dialog();

	sub Button1_Click { $W2->Show(); }
	
	sub W1_Terminate { return -1; }

Furthermore, we put a button on the second window to make it go away:

	$W2->AddButton(
		-name => "Button2",
		-text => "Close this window",
		-pos  => [ 10, 10 ],
	);
	
	sub Button2_Click { $W2->Hide(); }

=for HTML <BR><BR><CENTER><IMG SRC="guitut5-2.gif"></CENTER>

This rather basic example shows the skeleton framework for a typical
multi-window application; but there are still two issues we want to
address: the mortality of popup windows and their "modal" behaviour.

=head2 Keeping popup windows alive

If you choose to close the second window with the Close (little X)
button on the upper right corner, you'll notice that the window
disappear, and that it does not show anymore when you press the
button on the main window!

What's happening here is that we requested a C<W2_Terminate> action,
and since we didn't provide an event for this, Win32::GUI proceeds
with the default behaviour for the close button, which is to destroy
the window. The result is that you can't show $W2 anymore, because
it does not exists anymore as a valid window (although it still exists
as a Perl object). To let our window survive the close action, we need
to provide a customary C<Terminate> event:

	sub W2_Terminate {
		$W2->Hide();
		return 0;
	}

The C<return 0> is B<very important> in this case, because it tells
Windows to avoid the destruction of our window (it is just hidden), so
that we can show it again using the button in C<$W1>.

=head2 Simulating "modal" windows

Here is another very common functionality you may want to implement:
when a popup window is open, you don't want the user to interact with
the main window; this is known as using a "modal" window, a window that
gets all your attention and does not let you go forward with the 
program unless you have disposed of it.

Win32::GUI does not have direct support for modal windows, but you can
simulate the behaviour with this trick:

	sub W1_Activate {
		if($W2->IsVisible) {
			$W2->SetForegroundWindow();
			return 0;
		}
		return 1;
	}

The meaning should be obvious enough: if the popup window is shown,
trying to activate the main window automatically reports you to the
popup window; otherwise, the main window becomes the active one as
normal. Of course, if you have more than one popup window, you should
add code for everyone of them:

	sub W1_Activate {
		if($W2->IsVisible) { $W2->SetForegroundWindow(); return 0; }
		if($W3->IsVisible) { $W3->SetForegroundWindow(); return 0; }
		# ... and so on
		return 1;
	}