BOWEL Sample
String Manager
This documents describes an example of using BOWEL to port an OWL application to MFC. The application is very rudimentary; it simply maintains a list of strings. There are two dialog boxes to port; figure 1 contains a screen-grab of the application's main dialog which allows the user to add, remove and edit strings, as well as moving them up and down; figure 2 shows the other dialog which simply allows the user to edit a string.
Figure1: The main dialog.
Figure2: The string editting dialog.
The directory, bowel\demo\bc5, contains the original OWL version of the application, and the directory, bowel\demo\vc6, contains the BOWEL/MFC version.
Porting Process
Since version 0.1 of BOWEL only supports dialogs, it is only these that have been ported; the rest of the application has been rewritten (actually regenerated using the AppWizard). To see the changes required, look at the files, vc6/BOWELDlC.h, vc6/BOWELDlC.cpp, vc6/StringEditDlg.h, vc6/StringEditDlg.cpp. All changes have been documented using the following notation:
For cases where code was replaced:
//ADDED{
new_code;
//}
//REMOVED{
//old_code;
//}
Or for cases where code was added:
//ADDED{
new_code;
//}
Below is a description of all required changes:
BOWELDlC.h
Change 1:
//REMOVED{
// #include "bowelapp.rh"
//}
//ADDED{
#include "resource.h"
//}
VC6 puts all resources in a single file, using a single resource header file, so I did this also. The former is very hard to avoid if you want to use the resource editor, but you don't have to do the latter since VC6 allows resource header includes. However, for the sake of laziness, I followed VC6's convention in this example.
Change 2:
//REMOVED{
// #include <string.h>
//}
//ADDED{
#include <string>
using std::string;
//}
VC6 prefers the new ANSI approach to using the STL header files, rather than BC5's old-fashioned method.
Change 3:
//REMOVED{
// DECLARE_RESPONSE_TABLE(TBOWELDlgClient);
//}
//ADDED{
DECLARE_MESSAGE_MAP();
//}
I haven't written BOWEL versions of the OWL message-handling macros. If anyone feel like doing this, it would be a very useful addition to the library, since the most common porting change required is to change these macros.
BOWELDlC.cpp
Change 1:
//ADDED{
#include "stdafx.h"
//}
Include the VC6 precompiled header marker file.
Change 2:
//REMOVED{
// #include <fstream.h>
//}
//ADDED{
#include <fstream>
using std::ifstream;
using std::ofstream;
//}
See change 2 for BOWELDlC.h.
Change 3:
//REMOVED{
// DEFINE_RESPONSE_TABLE1(TBOWELDlgClient, TDialog)
// EV_BN_CLICKED(IDC_ADD, AddBNClicked),
// EV_BN_CLICKED(IDC_REMOVE, RemoveBNClicked),
// EV_BN_CLICKED(IDC_MOVE_UP, MoveUpBNClicked),
// EV_BN_CLICKED(IDC_MOVE_DOWN, MoveDownBNClicked),
// EV_BN_CLICKED(IDC_EDIT, EditBNClicked),
// END_RESPONSE_TABLE;
//}
//ADDED{
BEGIN_MESSAGE_MAP(TBOWELDlgClient, TDialog)
ON_BN_CLICKED(IDC_ADD, AddBNClicked)
ON_BN_CLICKED(IDC_REMOVE, RemoveBNClicked)
ON_BN_CLICKED(IDC_MOVE_UP, MoveUpBNClicked)
ON_BN_CLICKED(IDC_MOVE_DOWN, MoveDownBNClicked)
ON_BN_CLICKED(IDC_EDIT, EditBNClicked)
END_MESSAGE_MAP()
//}
As in change 3 for BOWELDlC.cpp, the OWL message handling macros are replaced with their MFC equivalents. It seems that just about all OWL macros have direct MFC equivalents, so this process is quite straight-forward. Caution: when doing this yourself, take particular note of the punctuation - if you get it wrong, strange errors result.
StringEditDlg.h
Change 1:
//REMOVED{
// #include <string.h>
//}
//ADDED{
#include <string>
using std::string;
//}
See change 2 for BOWELDlC.h
Change 2:
//REMOVED{
// #include "bowelapp.rh"
//}
//ADDED{
#include "resource.h"
//}
See change 1 for BOWELDlC.h
Change 3:
//REMOVED{
// DECLARE_RESPONSE_TABLE(TStringEditDlg);
//}
//ADDED{
DECLARE_MESSAGE_MAP();
//}
See change 3 for BOWELDlC.h
StringEditDlg.cpp
Change 1:
//ADDED{
#include "stdafx.h"
//}
See change 1 for BOWELDlC.cpp.
Change 2:
//REMOVED{
// DEFINE_RESPONSE_TABLE1(TStringEditDlg, TDialog)
// {{TStringEditDlgRSP_TBL_BEGIN}}
// EV_BN_CLICKED(IDOK, OKBNClicked),
// //{{TStringEditDlgRSP_TBL_END}}
// END_RESPONSE_TABLE;
//}
//ADDED{
BEGIN_MESSAGE_MAP(TStringEditDlg, TDialog)
ON_BN_CLICKED(IDOK, OKBNClicked)
END_MESSAGE_MAP()
//}
Summary
BOWEL could not be used to port the main application class, but was useful in porting the dialogs. By using BOWEL, the changes required to port the dialogs from OWL to MFC were greatly reduced; all of the dialog box logic was retained without alteration. The changes that were made were of the following types:
-
Import resource definitions from a different file.
-
Use new ANSI include file convention for STL classes.
-
Replace the message handling macros from OWL to MFC.
-
Use stdafx.h include to enable precompiled headers.
The main other type of change, that was not required in this port but may be encountered in others, is when OWL member functions, member variables, or classes, which BOWEL does not yet support, are used. There are two main courses to take when this happens: (1) hand-port the code to MFC code, or (2) add support for the required class. In cases where you choose to do the latter, I would be extremely grateful if you would send me the additions to BOWEL so that I can add them to the library (your input will be creditted).
|