Multiple Windows

So far we have dealt with the simple case where there is only one window. Now, let's investigate the more usual case where many windows can be active simultaneously. Assume that the above examples have been built within a database that defines customers, products, and orders and that we have created non-modal windows and programs for viewing and browsing these objects. Assume also that these new programs have been built using the Framework (i.e. they register themselves and so on) and that they have been called ProcCustomers, ProcProducts, and ProcOrders respectively. We would want to be able to open these windows from our main application window, so the first change we must make is to add menu items to the main application window menu. For example, we might have a menu items that says "Customers..." and assign the tag "CUSTOMERS" to it. Similarly, we could have menu items with labels "Products..." and "Orders..." and give these tags "PRODUCTS" and "ORDERS" respectively. The actual labels and tags could be different of course.

To handle these new actions, we add the following lines to the main window program, MainWindowProg, after line [73].

[73.1]when vlAction = "CUSTOMERS"
[73.2]  ProcCustomers (vlStatus, "ENTERWINDOW")
[73.3]when vlAction = "PRODUCTS"
[73.4]  ProcProducts (vlStatus, "ENTERWINDOW",
[73.5]when vlAction = "ORDERS"
[73.6]  ProcOrders (vlStatus, "ENTERWINDOW")

Since there can be several windows open at one time, we must ensure that the Framework makes the windows for processing customers, products, and orders "children" of the main application window. By doing this, we can be sure that, if the user exits from the main window, all other windows are closed properly (see the discussion on EXIT and EXITAPPLICATION below). At any given time, the Framework tracks what it thinks is the current process (the one being interacted with at that time). Every time our application window gets the focus, we want to tell the Framework that this is the current process. This is done by inserting the following lines after line [75] that are executed when an ENTERWINDOW occurs.

[75.1] %%make ourselves current
[75.2]  pSetCurrentProcess ("wMainWindow")

Handling EXIT and EXITAPPLICATION also needs some changes. For example, if we are terminating the main application window, we need to tell the other windows to EXIT as well. We don't want to build in to each window the knowledge of all other windows, so we add a new local variable to the local procedure plExecAction

[68a]              in vlAction) \
[68a.1]       local ( vlProcessId)

and replace lines [81a] to [84a] with the following.

[81b]when vlAction in ("EXIT", "EXITAPPLICATION")
[82b]    pDispatchAction (vlStatus, "EXIT", \
[83b]           "#TOCHILDREN", \
[84b]           MainState.stProcessId, "")
[84b.1] if vlStatus <> "CANCEL"
[84b.2]   plClose (vlStatus)
[84b.3]   pUnRegisterProcess (vlStatus, \
[84b.4]           MainState.stProcessId, "")

In this new code, we first make a call to pDispatchAction. This call uses the #TOCHILDREN parameter to indicate that the EXIT action is to be sent to all the application window's children. In this case, that means any of the windows for editing customers, products, or orders (if they are open). Notice that the application window code does not need to know who its children are or if they are open. The Framework keeps track of that.

If all processes (except the main application window) EXIT, then vlStatus is not CANCEL, then plClose is called to close the application window and then pUnRegisterProcess is called to tell the Framework that this window is terminating.