Using Multiple Windows (by Brad Manske)

I'd want to address issues dealing with the creation of multiple windows in your PPL programs. This is not a tutorial on creating windows. It is more a collection of tips for when you do create multiple windows. ShowMessage is the most simple way to create a second window. It is useful for debugging and simple informational pop-up windows.

ShowMessage("Hello World" + #13#10 + "and Country");

Take a look at the #13#10 added above. This is a Carriage Return/Line Feed added to produce a second line. By formatting the text, you can make this simple command very useful. The Windows MessageBox is the next step up in complexity. It allows you to set the owner, the text in the message box, the caption and some flags. In the example below, there is no owner, the question about saving, "Save" is placed into the caption bar, finally the "yes", "no" and "cancel" buttons are created inside the dialog box.

i$ = MessageBox(NULL, "Do you want to save " + FileName$ + "?", "Save", MB_YESNOCANCEL);

It is pretty obvious from the names below, which buttons get created when you use these constants.

MB_OK
MB_OKCANCEL
MB_ABORTRETRYIGNORE
MB_YESNOCANCEL
MB_YESNO
MB_RETRYCANCEL

You can also specify an Icon to be placed in the MessageBox from the list below. Simply use the "|" OR operator.

For example MB_YESNOCANCEL | MB_ICONQUESTION

MB_ICONHAND
MB_ICONQUESTION
MB_ICONEXCLAMATION
MB_ICONASTERISK
MB_ICONWARNING = MB_ICONEXCLAMATION
MB_ICONERROR = MB_ICONHAND
MB_ICONINFORMATION = MB_ICONASTERISK
MB_ICONSTOP = MB_ICONHAND

MessageBox has additional features. Refer to MSDN for all of them. MessageBox can return a value based when the button is pressed. These values are defined in Dialog.PPL.

#define IDOK 1
#define IDCANCEL 2
#define IDABORT 3
#define IDRETRY 4
#define IDIGNORE 5
#define IDYES 6
#define IDNO 7

I try to use these values when returning from displaying a dialog box. When using ShowModal to display a dialog any value less than 100 can be use for a button and it will return automatically, I try to avoid confusion and not change the meaning of the defined values. Going back to my MessageBox example from above, "Yes" and "No" are pretty clear answers, but what about "Cancel"? If you are asking to save the file in response to a command to exit the program, the program flow go like this. User selects the Exit menu item. The menu exit handler would send a
WM_CLOSE command. Then you need a handler for the close event. In the Close event handler, call the MessageBox function and if you receive the "Cancel" ID, then return a FALSE from the OnClose event to stop the program from closing. The operation of the OnClose event is a little different in windows than it is in PPL. Windows will only send you an OnClose event when the entire application is closing. PPL allows you to open multiple windows per application and will send you an OnClose event for each window. This makes it easy in PPL to implement the ability to "Cancel" for each window. The next step is having more than one fully functional window for your application. For each new window that you create with the Form Editor, you need to:

• Select the Generate Library option in the Form -> Options menu.
• Change the form name so that a new windows class is created.
• Give each control on the forms a unique name.
• Give each control on the forms a unique ID. (required if getting the handles from the IDs)

For most forms you will probably want to select the "FormDefault" property. This property enables the use of the SIP (Soft Input Panel) on the PPC. You may open several windows for your program at the same time, then manage input by selectively showing the window that is needed. To Hide or Show a window use:

ShowWindow(FormHandle$, SW_HIDE); // or SW_SHOW

In creating more complex windows, you need to be careful about which styles are selected. The example below is how I added styles in the creation code for a window. This was necessary because the WS_EX_CaptionOKBtn style prevented my window from displaying on the PC as it is a PPC only style. So if your window refuses to display at all, you should review the styles that you have used and isolate the trouble-maker.

ExStyles$ = GetWindowLong(SizeDlgHandle$, GWL_EXSTYLE);
#ifdef _WIN32_WCE
// WS_EX_CAPTIONOKBTN is added here and not on the form because if added to
// the form then the form will not display on the PC
SetWindowLong(SizeDlgHandle$, GWL_EXSTYLE, ExStyles$ | WS_EX_CAPTIONOKBTN);
#else
// WS_EX_TOOLWINDOW is added here for the same reason as above except it will
// not show on the PPC if present.
SetWindowLong(SizeDlgHandle$, GWL_EXSTYLE, ExStyles$ | WS_EX_TOOLWINDOW);
#endif

I hope that this collection of tips has helped.