SGI Windows NT Toolbox
|Download Files|

From Developer News, September/October 1997:

Microsoft Foundation Classes-to-ViewKit Porting Strategy

by Ara Jerahian, Applications Engineering


Porting a Windows® application, written with the Microsoft® Foundation Class (MFC) library, to a native UNIX base is not a trivial task. However, with some thought and help from APIs like ViewKit and tools like RapidAppTM, the translation of your application structure can be straightforward and the orientation of your objects can, for the most part, remain unchanged.

The ViewKit application framework is a collection of classes written in C++ that gives you access to commonly needed facilities for applications based on Motif. RapidApp is a user-interface builder that allows users to construct a Motif interface interactively and to generate a C++ program based on ViewKit. With these APIs/tools and some knowledge of application framework paradigms, you can efficiently translate MFC base Windows code to a ViewKit-based Motif application.

In this article, I will discuss the general mapping of some of the base Microsoft Foundation Class application objects and their respective constructs to ViewKit.

Base Classes and Windows

Quite often, different object-oriented application programming approaches can share many of the same concepts in their framework. Table 1 lists some of the base application MFC objects and their appropriate ViewKit equivalents.

MFC ViewKit Concept
CWinApp

InitInstance()
VkApp

createWindows()
Provides central facilities
C[MDI]FrameWnd VkWindow/VkSimpleWindow Top-level window
C[MDI]ChildWnd

PreCreateWindow()
VkSimpleWindow/VkWindow

afterRealizeHook()
Top-level window
CDocument

UpdateAllViews()
VkModel

updateViews()
Application data object
CView VkComponent The presentation of the data in a window
Table 1: MFC Objects and Their ViewKit Equivalents

At the top of the MFC application hierarchy is the CWinApp object. The CWinApp base class determines most of the application's behavior. The equivalent in ViewKit is the VkApp object. Programs for both cases instantiate a single, global, derived "App" object from the base classes that encapsulate the main event loop for the application. One of the more important members in CWinApp is InitInstance(), a virtual member function that makes the calls needed to construct and display the application's main frame window. VkApp does not share an equivalent member function, but since a ViewKit application needs a user-defined main() (one that's not hidden in the underlying API), you can call a function you have defined in your derived VkApp object (such as createWindows()) to instantiate and display your main application window before calling VkApp::run() (also from main()).

The CMDIFrameWnd (MDI stands for multiple document interface) object represents the MFC application's main frame window. In the ViewKit application, the main application window will most probably be a VkWindow, but can also be a VkSimpleWindow if a menu is not needed. In MFC, most child windows of the CMDIFrameWnd will reside within its confines. Each child window will be in an active or inactive state, based on whichever has input focus and is often determined by executing a mouse click in that window. For SGI, this concept does not translate easily if a user has Point-to-Type keyboard focus set. Here, the window manager assumes a window is active when the mouse pointer is moved over that window, thus making it difficult for a main menu item to operate on the "active" window. Thus, the effective scope of the main VkWindow main menu should have global effects on all of its child windows, which would basically be other top-level shells controlled by the main window.

The CMDIChildWnd object represents the MFC application's MDI child frame window. In the ViewKit application, the child window will most probably be a VkSimpleWindow, but can also be a VkWindow, once again based on whether or not these child windows need menus. Here, the effective menu scope should only be local to that window, affecting only the data presented in that child window. Child windows often include views that present data to the user and allow interaction with the application (refer to "Model/View Architecture" for more information).

The relationship of a single document interface (SDI) main frame window and its single child window (CFrameWnd and CChildWnd objects respectively) differ slightly in translation to the ViewKit framework. Since there should be only one instance of a child window in an SDI application, these child windows are usually kept within the confines of the main window. In the ViewKit/Motif world, this makes the SDI child window merely a container within the main frame of the application, like an XmForm or an XmBulletinBoard. This container will exist within the confines and extents of the main window.

Model/View Architecture

Typically, MFC applications contain the application and frame classes discussed above, plus two other classes that represent the document and the view. This document-view architecture is the core of the application framework and is based on the Model/View/Controller (MVC) classes from the SmallTalk world (see Figure 1). In simple terms, the document-view (Model/View) architecture separates data from the user's view of the data. An obvious benefit is multiple views of the same data (such as stock data with both a chart and a table view). The derived document does the actual reading and writing of the document object's data. The view class represents a window that is contained inside a frame window (typically a child window to the application); the derived class interacts with its associated document class and does the application's display. In MFC, documents are based on class CDocument and views are objects typically derived from class CView that manages user interaction with a document. The MFC framework manages all interactions among documents, views, and frame windows and the application object.

ViewKit follows a similar paradigm to support the MVC architecture. It includes a VkModel abstract class that is intended to be subclassed. This provides the data members and any additional functions required to implement the document. ViewKit components derived from VkComponent can be used as both views and controllers. These views can arrange to be notified of changes to the model by registering a member function with the VkModel::updateCallback list (this callback registration is automatically handled in MFC when the virtual CView::OnUpdate function is overloaded by the derived class). The callbacks on this list can then be invoked when a subclass of VkModel calls updateViews() (this is equivalent to the MFC CDocument::UpdateAllViews() function). This method is just a convenient way to invoke the functions on the updateCallback list. Components used as controllers are expected to send messages to subclasses of VkModel to alter the state of the model. This protocol must be worked out between the VkModel subclass and the controller components. Views and controllers often work closely enough that, in most cases, a single object can function as both a controller and a view. This should probably be the case if the MFC/ViewKit application object structure is to remain the equivalent.

Figure 1: Relationships between Model, View, and Controller objects

Summary

The ViewKit application framework can be used to cleanly port a Windows MFC application by understanding the underlying elements shared between the two frameworks. Both share the same concept of an application object, windows, and the model/view architecture. The respective objects can be easily mapped from one framework to the other with the goal of minimizing changes to the overall application structure. By using the ViewKit mappings described in this article, your MFC application can be thus cleanly ported to IRIX with few structural changes.

Reference

Young, Douglas A., Object-Oriented Programming with C++ and OSF/Motif, 2nd ed., Prentice Hall, 1995.


Copyright © 1997, Silicon Graphics, Inc.