CIS 488 Programming Assignment 14 Using ’s OWL

Introduction

The purpose of this programming assignment is to give you practice developing a Windows program using Borland Object Windows Library, Version 2.0.

Assignment

In this assignment you will convert your Windows program to Borland OWL. You will define 1) a ++ class representing the application, 2) a class implementing your main window, 3) classes implementing your boxes, and 4) redefine the struct's used to transfer data between your main window and your dialog boxes.

To keep the assignment as simple as possible, start with version 8 or version 9 of your program. In other words, do not start with the MDI version of your program.

Note: Borland's Turbo C++ will not build a 32 bit version.

Method

Copy all the files for Assignment 8, or all the files that make the .EXE of Assignment 9, to corresponding files for this assignment and change all occurrences of "08" or "09" to "14". If you decide to use Assignment 9 as the base for this one, you will not have to copy the files that compose your .DLL, since you will use it as is and thus it will remain unchanged.

Important: Make sure your source files have the extention .CPP so the will recognize them as C++ files.

Recommendation: Do not attempt to transform the application and window procedure code by stepwise modification. You will be overwhelmed with errors and confusion. Instead, create a new source file PROG14.CPP and develop the program step by step as was done in class and the notes. As needed, copy code from Assignment 8 (or 9) files and add it to the C++ code in PROG14.CPP. You will not have to modify such copied code if you do this right. The final program will be a mixture of C++ code and C code. The C code will be compiled by the C++ compiler as is.

Step 1: Derive an Application Class Derive a class, TProg14App, from the OWL class TApplication. It should have a public constructor member function and redefine the virtual void member function InitMainWindow.

The redefined function InitMainWindow should create a main window using the new operator.

Convert your WinMain function to an OwlMain function that defines and runs an instance of TProg14App.

To test at this time, the main window should be an instance of a window class that is already defined, e.g., an OWL window class.

Step 2: Derive a Main Window Class

Derive a class, TMainWindow, from the OWL class TWindow. It should 1) have a public constructor, 2) redefine the public virtual void functions Paint and SetupWindow, 3) define a public virtual void function CMXxxxx to respond to each command message, and 4) declare a response table. In addition, the class TMainWindow should have protected or private data members to hold hText, the handle to the displayed text, ef, the ENUMFACE struct and curFace, the current font selection. Finally, the class should define the following two member functions to simplify others:

virtual BOOL PrintWindow() { return ::PrintWindow( HWindow, GetApplication()->hInstance, hText, ef.faceName[curFace] ); } and void DoFontItem( int i ) { curFace = i; Invalidate( TRUE ); }

Important: Put the class declaration in your header file and the implementation in TOPWIN14.CPP. Put any data definitions needed by the class declaration in the header file also.

The member function PrintWindow is what is called a wrapper for the non member function of the same name. The operator :: ensures the non member function is called. The member function DoFontItem should be either private or protected and simplifies the member functions responding to font selection menu choices.

The member function SetupWindow is called to initialize the TMainWindow C++ object after Windows has created the visible window on screen. It has the following form

void TMainWindow::SetupWindow() { TWindow::SetupWindow();

HANDLE hInst = GetApplication()->hInstance;

2 ... }

You should load the text resource, make the font menu and initialize the current font selection in this function.

Each command message response function is declared in the class as

virtual void CMXxxxx(); and defined this way for one line bodies

void TMainWindow::CMXxxxx() { ... } or this way for longer bodies

void TMainWindow::CMXxxxx() { ... }

Important note: In OWL we cannot define a member function to respond to a range of wParam values. Thus you must define a command message response function for each of the 20 possible font menu choices.

You can test your program at this stage if you are careful not to use any commands that would activate dialog boxes.

Step 3: Derive Dialog Box Classes

For each of your dialog boxes that exchange data with the main window, derive a class TXxxxxDlg from the OWL class TDialog. Each class should have a public constructor and a pointer data member for pointing to each dialog control object that, to or from which, you will need to transfer data. It will also declare a response table and message response functions for any messages it must process.

The constructor will use the new operator to create a control object for each pointer defined in the class.

Any other dialog initialization should be done in a virtual void function SetupWindow that is a member of the dialog class.

Dialogs that have scrollbars should have the following private member function defined:

void SetPosLabel( int i ) { SetDlgItemInt( HWindow, IDC_VALUE1+i, scr[i]->GetPosition(), FALSE ); }

Notifications from scroll bars are handled by a response function declared as follows:

3 virtual void IDScrollBar1Msg();

The response function has a response table entry like this:

EV_CHILD_NOTIFY( IDC-SCROLL1, UINT_MAX, IDScrollBar1Msg )

where the constant UINT_MAX sends all notifications from the scroll bar to the response function.

The body of a scroll bar response function simply calls the function SetPosLabel to keep its label up to date with its position. All other scroll bar actions are handled by OWL.

Step 4: Transfer Dialog Data

Following the method discussed in class, define structs to hold dialog data and arrange for their automatic transfer with the following statement in the constructor:

SetTransferBuffer( &xdd );

A dialog containing a list box must use one of two methods to transfer the list box data. Either 1) define a constructor to initialize the PTListBoxData pointer in the dialog's data struct, or 2) initialize the list box in a redefined SetupWindow member function and retrieve its selection and contents if appropriate in a member function that responds to the OK button press.

A dialog that has three scroll bars would use the following definitions:

struct XxxxxDlgData { TScrollBarData scr[3]; };

XxxxxDlgData xdd = {{ { 0, 255, 127 }, { 0, 255, 127 }, { 0, 255, 127 } }};

Important note: the double curly braces {{ ... }} in the above example are necessary. Single braces will produce an error. The outer pair of braces surrounds the data initializing the struct while the inner pair of braces surrounds the data initializing the array.

The main window executes the dialogs as discussed in class.

Step 5: Repaint on Window Resize

You may have noticed during testing that if you resize the main window, the text is not all redrawn to fit the new window size. This happens because OWL registers your window classes automatically and does not include the class style flags that repaint a window when

4 it is resized. To remedy this, we must do two things: make sure our window has a unique class name and that it is registered with the style flags that cause it to be redrawn.

Add the following member function overrides to your main window class declaration:

virtual char far* GetClassName() { return "Prog14Window"; }

virtual void GetWindowClass( WNDCLASS& wc ) { TWindow::GetWindowClass( wc ); wc.style |= (CS_HREDRAW | CS_VREDRAW); }

Make sure these functions are protected members of the class.

These functions override the OWL functions in class TWindow. The function GetClassName assigns the name "Prog14Window" to the new window class. The function GetWindowClass retrieves the WNDCLASS struct used to register the window class. Before it returns it adds to wc.style the flags CS_HREDRAW | CS_VREDRAW that are needed to make the window class redraw its windows when they are resized.

Report

The report for this assignment consists of the following items:

· Title Page

· Annotated and Highlighted Program Listings

· Sample Printed Output from the Window

· Sample(s) of the Program on Screen (Use [Shift | Ctrl | Alt -] PrintScrn to clipboard, paste to word processor.)

Important:

· use a highlighter to mark the differences between this assignment and the previous one, and

· use only 8.5 by 11" paper with smooth edges.

5