home *** CD-ROM | disk | FTP | other *** search
-
-
-
-
- Using Microsoft Foundation Classes
- with
- Borland C++ 3.1
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Prepared by:
- Language Business Unit
- Borland International
- 1800 Green Hills Road
- PO Box 660001
- Scotts Valley, CA 95067-0001
-
-
-
- Table of Contents
-
- Table of Contents i
- Overview 1
- Changes to MFC 2
- Changes to SRC\VALIDADD.CPP 2
- Changes to SRC\DOSIO_.H 3
- Changes to SRC\OLEPTR_.H 3
- Changes to SRC\FILE.CPP 4
- Changes to SRC\WINDOW.CPP 4
- Changes to SRC\WINDLGS.CPP 5
- Changes to SRC\OBJECT.CPP 6
- Changes to the Build Process 7
- Preparing for the Build Process 7
- Changes to SRC\MAKEFILE 7
- Debug Information and TASM 11
- Memory Model Issues 12
- Building with 386^Max 12
- Building the Example Programs 13
- Changes to the Build Process 13
- Building An Example: ABOUT2 13
- Changes to SAMPLES|ABOUT2\MAKEFILE 13
- Changes to SAMPLES\ABOUT2\ABOUT2.H 14
- Changes to Other Example Programs 14
- Changes to SAMPLES\CTRLTEST\WCLSTEST.CPP 14
- Changes to SAMPLES\CTRLTEST\PAREDIT2.CPP 15
- Changes to SAMPLES\CTRLTEST\FEATPEN.CPP 15
- Changes to SAMPLES\CTRLTEST\CUSTLIST.CPP 15
-
-
-
-
- Overview
-
- This document describes how to build and use Microsoft Foundation Class (MFC)
- programs with Borland C++ 3.1. This document is divided into several sections. The
- first describes changes to make to the MFC source files; the second, changes and
- suggestions for the build process; and the final section explores compiling an example
- providing with Microsoft C/C++ 7.0.
-
- The changes described in this document are necessary for several reasons. Some relate to
- non-standard syntax that Microsoft uses in their C++ compiler, while others relate to
- differences in assembly language extensions and makefile conventions.
-
- If you are using MFC for your Windows programs, you will find many advantages in
- using Borland C++ 3.1 instead of Microsoft C/C++ 7.0:
-
- * Borland provides far faster development times, with its lightning fast compiles.
- * Borland provides a Windows hosted IDE.
- * Borland provides more sophisticated Windows tools, such as Resource Workshop,
- WinSight, and WinSpector.
- * Borland provides a far more robust, compliant implementation of C++.
- * Borland provides templates and other advanced C++ features.
- * Borland provides automatic, safe precompiled headers and a smart project manager.
-
- If you are interested in a more detailed technical comparison of Borland C++ 3.1 and
- Microsoft C/C++ 7.0, be sure to ask for our technical whitepaper: "Borland C++ 3.1 &
- Application Frameworks v. Microsoft C/C++ 7.0, An Expose".
-
-
-
-
- Changes to MFC
-
- This section describes the various changes you will need to make to the MFC source
- code. Note that the line numbers mentioned are based on the version of MFC in the first
- shipping packages of Microsoft C/C++ 7.0. The actual line numbers are subject to
- change should Microsoft provide interim versions of MFC. Note further that any line
- number references assume that you have made all previously mentioned changes to the
- particular file.
-
- Changes to SRC\VALIDADD.CPP
-
- 1. Add the following lines at the top of the file:
-
- #ifdef __TURBOC__
- #pragma inline
- #endif
-
- 2. Because "asm" in not a valid keyword within an existing inline asm statement in
- Borland C++ 3.1, you need to change the _asm _emit's to db's in the following
- manner:
-
- #ifdef __TURBOC__
- db 0x66
- #else
- _asm _emit 0x66
- #endif
-
- 3. Because Borland C++ 3.1 doesn't accept inline asm labels, you need to make the
- following labels into C++ labels:
-
- skip_write_test
- skip_range_test
- done
-
- For example, instead of leaving the label skip_write_test in an inline asm block as
- illustrated below,
-
- jnz done
- skip_write_test:
-
- close the inline asm block, then open another after the label.
-
- jnz done
- }
- skip_write_test:
- _asm {
-
-
- The label done needs a semicolon after it as follows:
-
- }
- skip_range_test:
- _asm {
- inc word ptr bValid
- }
- done:
- ;
- }
- else
-
- 4. The comparison:
-
- cmp bReadWrite, 0
-
- needs a type override. You need to change it to
-
- cmp word ptr bReadWrite, 0
-
- There are 2 occurrences of this statement in the file. Also, the increment:
-
- inc bValid
-
- needs a type override. You need to change it to
-
- inc word ptr bValid
-
- There are also 2 occurrences of this statement in SRC\VALIDADD.CPP.
-
- 5. Borland C++ 3.1 doesn't allow assembler-style comments in inline assembler, so you
- should change all such comments to C++ style comments.
-
- Changes to SRC\DOSIO_.H
-
- 1. Change line 33 from:
-
- #define DOSCALL call DOS3Call
-
- to
-
- #define DOSCALL call far ptr DOS3Call
-
- Changes to SRC\OLEPTR_.H
-
- 1. Because Borland C++ 3.1 does not allow Microsoft-style based pointers, you should
- change line 17 from:
-
- ASSERT(_AFX_FP_SEG(lp) == _segname("_DATA"));
-
- to
-
- #ifndef __TURBOC__
- ASSERT(_AFX_FP_SEG(lp) == _segname("_DATA"));
- #endif
-
- Changes to SRC\FILE.CPP
-
- 1. Add the following lines at the top of the file:
-
- #ifdef __TURBOC__
- #pragma inline
- #endif
-
- 2. Replace line 68 with the lines:
-
- }
- __seek_err:
- _asm {
-
- 3. Replace line 87 with the lines:
-
- }
- __rename_err:
- _asm {
-
- 4. Replace line 106 with the lines:
-
- }
- __remove_err:
- _asm {
-
- 5. Replace line 129 with the lines:
-
- }
- __lock_err1:
- _asm {
-
- Changes to SRC\WINDOW.CPP
-
- The function FindMessageEntry has inline assembler statements which Borland
- C++ 3.1 does not recognize. You should replace this function with the following one,
- which is compatible with both MSC/C++ 7.0 and Borland C++ 3.1.
-
- static CMessageEntry FAR* NEAR
- FindMessageEntry(CMessageEntry FAR* lpEntry, UINT nMsg, UINT nID)
- {
- _asm {
- LES BX,lpEntry
- MOV AX,nMsg
- MOV DX,nID
- }
- __loop:
- _asm {
-
- MOV CX,WORD PTR ES:[BX+4] // nSig (0 =>
- end)
- JCXZ __failed
- CMP AX,WORD PTR ES:[BX] // nMessage
- JE __found_1
- }
- __next:
- #ifdef __TURBOC__
- static const int CMESSAGEENTRYSIZE = sizeof(CMessageEntry);
- _asm {
- ADD BX,CMESSAGEENTRYSIZE
- JMP __loop
- }
- #else
- _asm {
- ADD BX,SIZE CMessageEntry
- JMP __loop
- }
- #endif
- __found_1:
- _asm {
- CMP DX,WORD PTR ES:[BX+2] // nID
- JNE __next
- // found a match
- MOV WORD PTR lpEntry,BX
- MOV WORD PTR lpEntry+2,ES
- JMP __end
- }
- __failed:
- _asm {
- XOR AX,AX
- MOV WORD PTR lpEntry,AX
- MOV WORD PTR lpEntry+2,AX
- }
- __end:
- return lpEntry;
- }
-
- Changes to SRC\WINDLGS.CPP
-
- 1. Line 705 contains a syntax error that MSC/C++ 7.0 does not detect. You need to
- change line 705 from:
-
- 700: BOOL
- 701: CFindReplaceDialog::Create(BOOL bFindDialogOnly,
- 702: LPCSTR lpszFindWhat,
- 703: LPCSTR lpszReplaceWith /* = NULL */,
- 704: DWORD dwFlags /* = FR_DOWN */,
- 705: CWnd* pParentWnd ) : CDialog((UINT)0, pParentWnd)
- 706: {
- ^
- the syntax error is here
-
-
- to
-
- 700: BOOL
- 701: CFindReplaceDialog::Create(BOOL bFindDialogOnly,
- 702: LPCSTR lpszFindWhat,
- 703: LPCSTR lpszReplaceWith /* = NULL */,
- 704: DWORD dwFlags /* = FR_DOWN */,
- 705: CWnd* pParentWnd ) // : CDialog((UINT)0, pParentWnd)
- 706: {
-
- Changes to SRC\OBJECT.CPP
-
- 1. The function AfxNewHandler on line 179 is prototyped incorrectly to be used as a
- new handler. You should replace it with:
-
- void cdecl AfxNewHandler(void)
- {
- // AFX memory allocation will never return "NULL" it will always
- throw
- // a memory exception instead
- AfxThrowMemoryException();
- }
-
-
- Changes to the Build Process
-
- This section describes changes you will need to make to your build process in order to
- build MFC applications. It covers changes to the makefile as well as particulars relating
- to memory models and DPMI servers.
-
- Preparing for the Build Process
-
- When building the MFC class library with Borland C++ 3.1, you must use Borland's
- MAKE utility. When you invoke MAKE, you need to specify all the switches you would
- normally use with NMAKE and append these two options:
-
- MAKE ...normal options... -D__TURBOC__ -N
-
- Since MSC/C++ 7.0 requires the INCLUDE and LIB environment variables to be set,
- while Borland C++ 3.1 does not, you will need to create a TURBOC.CFG file that
- defines these paths. Also, you will need to define some macros to control the building of
- the MFC class library.
-
- For example, if you installed Borland C++ 3.1 in C:\BORLANDC and MSC/C++ 7.0 in
- C:\C700, your TURBOC.CFG file would look like this:
-
- -Ic:\borlandc\include ; Standard headers
- -Ic:\c700\mfc\include ; AFX headers
- -Lc:\borlandc\lib ; Standard libraries
- -Lc:\c700\mfc\lib ; MFC class libs
- -D__MSC ; Tells std headers to allow MS bugs
- -DBASED_CODE ; Don't use handle-based pointers
- -D_asm=asm ; MS uses _asm, Borland uses asm
- -D_stat=stat
-
- The default optimization options for compiling MFC with C/C++ 7.0 are /Oselg. You
- can use these options with Borland C++ 3.1, or you can compile with -O2 -po for fastest
- code and -O1 -po for smallest code.
-
- Changes to SRC\MAKEFILE
-
- Note: all line number references that follow assume that you have made all previously
- mentioned changes to the file.
-
- 1. Replace lines 47-48 with the lines:
-
- !ifdef __TURBOC__
- CPP=bcc
- CC=bcc
- !else
-
-
- CPP=cl
- CC=cl
- !endif
-
- 2. Replace line 84 with the lines:
-
- !ifdef __TURBOC__
- DEBUGOPTS=/Od /N
- !else
- DEBOPTS=/Odr /f
- !endif
-
- 3. Replace line 96 with the lines:
-
- !ifdef __TURBOC__
- DEBOPTS=$(DEBOPTS) /v
- !else
- DEBOPTS=$(DEBOPTS) /Zi
- !endif
-
- 4. Replace line 105 with the lines:
-
- !ifdef __TURBOC__
- CVEXTRA=/v
- !else
- CVEXTRA=/Zi
- !endif
-
- 5. Replace lines 112-128 with the lines:
-
- !if "$(MODEL)"=="s" || "$(MODEL)"=="S" || "$(MODEL)"==""
- !ifdef __TURBOC__
- CL_MODEL=/ms /D_M_I86SM
- !else
- CL_MODEL=/AS
- !endif
- !else
- !if "$(MODEL)"=="m" || "$(MODEL)"=="M"
- !ifdef __TURBOC__
- CL_MODEL=/mm /D_M_I86MM
- !else
- CL_MODEL=/AM
- !endif
- !else
- !if "$(MODEL)"=="c" || "$(MODEL)"=="C"
- !ifdef __TURBOC__
- CL_MODEL=/mc /D_M_I86CM
- !else
- CL_MODEL=/AC
- !endif
- !else
- !if "$(MODEL)"=="l" || "$(MODEL)"=="L"
- !ifdef __TURBOC__
- CL_MODEL=/ml /D_M_I86LM
- !else
- CL_MODEL=/AL
- !endif
- !else
- !error MODEL must be one of S, M, C, L.
- !endif
- !endif
- !endif
- !endif
-
- 6. Replace lines 155-157 with the lines:
-
- !ifdef __TURBOC__
- TARGOPTS=/WSE /OW /2
- MKWIN=1
- EXPFLAG=/WSE
- !else
- TARGOPTS=/GA /GEs /G2
- MKWIN=1
- EXPFLAG=/GEe
- !endif
-
- 7. Replace line 184 with the lines:
-
- !ifdef __TURBOC__
- CL_OPT=/w /a- $(DEBOPTS) $(TARGOPTS) $(OPT)
- !else
- CL_OPT=/W3 /Zp $(DEBOPTS) $(TARGOPTS) $(OPT)
- !endif
-
- 8. Replace lines 196-199 with the lines:
-
- !ifdef __TURBOC__
- TARGDEFS=/D_WINDOWS
- TARGOPTS=/WDE /2 /D_WINDLL
- !else
- CL_MODEL=$(CL_MODEL)w
- TARGDEFS=/D_WINDOWS
- TARGOPTS=/GD /G2
- # /GD will define _WINDLL
- !endif
-
- 9. Replace line 252 with the lines:
-
- !ifdef __TURBOC__
- CPPFLAGS=$(CPPFLAGS) /H=$(PCH_FILE)
- !else
- CPPFLAGS=$(CPPFLAGS) /Yu /Fp$(PCH_FILE)
- !endif
-
- 10. Replace lines 264-271 with the lines:
-
- !ifdef __TURBOC__
- .cpp{$D}.obj:
- $(CPP) @<<
- $(CPPFLAGS) /c /o$@ $<
- <<
-
- .c{$D}.obj:
- $(CC) @<<
- $(CFLAGS) /c /o$@ $<
- <<
- !else
- .cpp{$D}.obj:
- $(CPP) @<<
- $(CPPFLAGS) /c /Fo$@ $<
- <<
-
- .c{$D}.obj:
- $(CC) @<<
- $(CFLAGS) /c /Fo$@ $<
- <<
- !endif
-
- 11. Replace lines 310-312 with the lines:
-
- !ifdef __TURBOC__
- $(CPP) @<<
- /c /H=$(PCH_FILE) $(CL_STANDARD) $(CL_MODEL) $(CL_OPT)
- $(DEFS) $(CVEXTRA) /c /o$D\object.obj object.cpp
- <<
- !else
- $(CPP) @<<
- /c /Yc /Fp$(PCH_FILE) $(CL_STANDARD) $(CL_MODEL) $(CL_OPT)
- $(DEFS) $(CVEXTRA) /c /Fo$D\object.obj object.cpp
- <<
- !endif
-
- 12. Replace lines 325-338 with the lines:
-
- !ifdef __TURBOC__
- !if "$(CODEVIEW)"=="2"
- $D\memory.obj : memory.cpp
- $(CPP) @<<
- $(CPPFLAGS) $(CVEXTRA) /c /o$D\memory.obj memory.cpp
- <<
-
- !ifdef MKWIN
- $D\winmain.obj : winmain.cpp
- $(CPP) @<<
- $(CPPFLAGS) $(CVEXTRA) /c /o$D\winmain.obj winmain.cpp
- <<
-
- $D\window.obj : window.cpp
- $(CPP) @<<
- $(CPPFLAGS) $(CVEXTRA) /c /o$D\window.obj window.cpp
- <<
-
- $D\winapp.obj : winapp.cpp
- $(CPP) @<<
- $(CPPFLAGS) $(CVEXTRA) /c /o$D\winapp.obj winapp.cpp
- <<
- !endif
- !endif
- !else
- !if "$(CODEVIEW)"=="2"
- $D\memory.obj : memory.cpp
- $(CPP) @<<
- $(CPPFLAGS) $(CVEXTRA) /c /Fo$D\memory.obj memory.cpp
- <<
-
- !ifdef MKWIN
- $D\winmain.obj : winmain.cpp
- $(CPP) @<<
- $(CPPFLAGS) $(CVEXTRA) /c /Fo$D\winmain.obj winmain.cpp
- <<
-
- $D\window.obj : window.cpp
- $(CPP) @<<
- $(CPPFLAGS) $(CVEXTRA) /c /Fo$D\window.obj window.cpp
- <<
-
- $D\winapp.obj : winapp.cpp
- $(CPP) @<<
- $(CPPFLAGS) $(CVEXTRA) /c /Fo$D\winapp.obj winapp.cpp
- <<
- !endif
- !endif
- !endif
-
- 13. Replace lines 378-380 with the following lines:
-
- !ifdef __TURBOC__
- $(CPP) @<<
- $(CPPFLAGS) $(EXPFLAG) /c /o$D\version.obj version.cpp
- <<
- !else
- $(CPP) @<<
- $(CPPFLAGS) $(EXPFLAG) /c /Fo$D\version.obj version.cpp
- <<
- !endif
-
- 14. Replace lines 394-400 with the following lines:
-
- !ifdef __TURBOC__
- tlib /P128 @<<
- ..\lib\$(GOAL) &
- -+$(OBJS:.obj =.obj -+)
- <<
- !else
- lib /PAGESIZE:128 @<<
- ..\lib\$(GOAL)
- y
- $(OBJS)
- nul
- ;
- <<
- !endif
-
- 15. Replace all occurences of $D with $(D)
-
- Debug Information and TASM
-
- The debug information in some files that contain inline assembler statements may cause
- TASM to run out of memory. You can:
-
- 1. Try to give TASM more memory.
- 2. Compile the file outside of the MAKE procedure.
- 3. Try using MAKER -S to free more real-mode memory for TASM during the MAKE
- process.
- 4. Change SRC\MAKEFILE to spawn TASMX for the offending files. For example,
- to compile and assemble SRC\FILE.CPP, add the following line to the end of
- SRC\MAKEFILE:
-
- $D\file.obj : file.cpp
- $(CPP) $(CFLAGS) -S -n$(D) file.cpp
- @tasmx /ml /t $(D)\file.asm,$(D)\file.obj
-
- Memory Model Issues
-
- In medium model, the MFC class library source code relies on a non-standard extension
- to member function modifiers. You cannot compile the MFC class library in medium
- model with any compiler that does not support this non-standard extension.
-
- In small or compact model, some of the example programs will not link with Borland
- C++ 3.1. This is because more of the runtime library is pulled in by the link step. To
- run these examples, use a larger memory model.
-
- Building with 386^Max
-
- If you are running the version of 386^Max that comes with MSC/C++ 7.0, version 6.01d,
- you may get errors or hangs from 386max's DPMI server while building the MFC class
- library or example files. If this happens, insert the following line in the 386MAX.PRO
- file in the directory where 386MAX is installled:
-
- NODPMI
-
- This will allow Borland C++ 3.1 to use its own DPMI server and will prevent these
- problems.
-
-
-
- Building the Example Programs
-
- This section discusses building the MFC sample programs using Borland C++ 3.1. You
- will need to make changes to your build process, and in some cases fix syntax errors in
- the sample programs.
-
- Changes to the Build Process
-
- To build the sample applications, you will need to copy the TURBOC.CFG from the
- MFC\SRC directory. In addition, because the resource compiler does not explicitly path
- WINDOWS.H and other header files, you must change the implicit rule in your
- BUILTINS.MAK file so that MAKE will include the directory where the headers reside.
-
- For example, if you installed Borland C++ 3.1 in C:\BORLANDC and MSC/C++ 7.0 in
- C:\C700, you would change the .rc.res rule to:
-
- .rc.res:
- $(RC) $(RFLAGS) /I\borlandc\include;\c700\mfc\include /r $&
-
- Building An Example: ABOUT2
-
- The makefiles for the sample programs follow the same pattern. To build a sample with
- Borland C++ 3.1, you will need to change each makefile. The steps for doing this
- follow, using ABOUT2 as an example. In addition to changing the makefile, you will
- have to change some of the source files.
-
- Note that the examples are all small model examples. If you have built the large model
- libary, you must change the makefile to use that library. If you have problems linking
- the examples in small model with Borland C++ 3.1, rebuild the library and the example
- in large model.
-
- Begin by copying MFC\SRC\TURBOC.CFG into the SAMPLES\ABOUT2 directory.
- Remember, you must repeat this step for each example program that you build.
-
- Changes to SAMPLES|ABOUT2\MAKEFILE
-
- 1. Replace lines 25-36 with the lines:
-
- !ifdef __TURBOC__
- CPPFLAGS= /DWINVER=0x0310 /ms /w /a- /WE /OW /2
- LINKFLAGS=/Twe /L\borlandc\lib;\c700\mfc\lib
-
- !if "$(DEBUG)"=="1"
- CPPFLAGS=/D_DEBUG $(CPPFLAGS) /Od /v /N
- LINKFLAGS=$(LINKFLAGS) /v
- LIBS=safxcwd cws
- !else
- CPPFLAGS=$(CPPFLAGS) /Oselg
- LINKFLAGS=$(LINKFLAGS)
- LIBS=safxcw cws
- !endif
- !else
- CPPFLAGS= /DWINVER=0x0300 /AS /W3 /Zp /GA /GEs /G2
- LINKFLAGS=/NOD /ONERROR:NOEXE
-
- !if "$(DEBUG)"=="1"
- CPPFLAGS=/D_DEBUG $(CPPFLAGS) /Od /f /Zi
- LINKFLAGS=$(LINKFLAGS) /COD
- LIBS=safxcwd libw slibcew
- !else
- CPPFLAGS=$(CPPFLAGS) /Oselg /Gs
- LINKFLAGS=$(LINKFLAGS)
- LIBS=safxcw libw slibcew
- !endif
- !endif
-
- 2. Replace line 55 with the lines:
-
- !ifdef __TURBOC__
- tlink $(LINKFLAGS) c0ws about2, about2, NUL, $(LIBS),
- about2.def;
- !else
- link $(LINKFLAGS) about2, about2, NUL, $(LIBS), about2.def;
- !endif
-
- Changes to SAMPLES\ABOUT2\ABOUT2.H
-
- 1. Line 92 has a syntax error. DECLARE_MESSAGE_MAP() cannot be followed by a
- semicolon. You should change it to:
-
- 90: // Message map defined in the .cpp file.
- 91: //
- 92: DECLARE_MESSAGE_MAP()
- 93: private:
- 94: short m_nCurrentColor;
- 95: short m_nCurrentFigure;
- 96: };
-
- Changes to Other Example Programs
-
- The following describes changes you will need to make to some of the other sample
- programs provided with C/C++ 7.0.
-
- Changes to SAMPLES\CTRLTEST\WCLSTEST.CPP
-
- 1. Line 26 has a syntax error. DECLARE_MESSAGE_MAP() cannot be followed by a
- semicolon. You should change it to:
-
- 25: void OnIllegalChar();
- 26: DECLARE_MESSAGE_MAP()
- 27: };
-
- Changes to SAMPLES\CTRLTEST\PAREDIT2.CPP
-
- 1. Line 41 has a syntax error. DECLARE_MESSAGE_MAP() cannot be followed by a
- semicolon. You should change it to:
-
- 40: static LONG FAR PASCAL __export WndProcHook(HWND, UINT, UINT,
- LONG);
- 41: DECLARE_MESSAGE_MAP()
-
- Changes to SAMPLES\CTRLTEST\FEATPEN.CPP
-
- 1. Lines 38 and 97 have syntax errors. DECLARE_MESSAGE_MAP() cannot be
- followed by a semicolon. You should change these lines to:
-
- 37: void OnConfigure();
- 38: DECLARE_MESSAGE_MAP()
- 39: };
-
- 96: void OnChooseInkColor();
- 97: DECLARE_MESSAGE_MAP()
- 98:};
-
- Changes to SAMPLES\CTRLTEST\CUSTLIST.CPP
-
- 1. Line 121 has a syntax error. DECLARE_MESSAGE_MAP() cannot be followed by
- a semicolon. You should change it to:
-
- 120: void OnOK();
- 121: DECLARE_MESSAGE_MAP()
- 122:};
-
-
-
-
- 15
-
-
-