PORTING XCTL FROM BORLAND 16-BIT TO VISUAL C++ 6.0 (32 BIT) =========================================================== The procedure for migrating XCTL project from Borland to Visual C++ consists of the following steps: - Create new Visual C++ projects, described in Section 1. - Update project settings as described in Section 2. - Make neccessary changes to source files as described in Section 3. - Make neccessary changes to resources as described in Section 4. - Build all executable files (exe and dlls) - Project/Rebuild all. If there are any errors left, these errors can guide you to make more changes to source files. - Once the build is successful, copy other neccessary files to output directory (Debug directory under the project root for debug build, which is active by default), such as other dlls, *.ini, *.mak, *.hlp. *.dat). - You should now be able to execute program. I tested it only for basic operations. 1. Creating Visual C++ projects ------------------------------- 1) Create new Visual C++ Project (File/New choose Win32 Application, then choose empty project). Name this project XControl (it is for the main program). 2) Add projects for each dll in the same workspace. (Projects/Add to project/New/Project choose Win32 dll then choose empty project). Repeat this step for each dll. At any time, you can set any one of these projects as an active project by right clicking on its name in the workspace window. The active project name is shown in bold letters. 3) Define project interdependecies. In that way, VC++ knows how to build the whole app. Use Project/Dependencies. XControl depends on motors, counters and splib. Counters depends on motors and splib. Motors depend on splib. Splib is not dependent of anything. 4) Copy all source files (*.h, *.cpp, *.c, *rc) to the project root directory (for the dlls also in the same directory). 5) Add these files to corresponding projects (for *.h files this is not neccessary, compiler itself will place them under "external dependencies" group). 2. Updating project settings ---------------------------- Project Settings for splib - General tab: set Output files to Debug (leave intermediate files in separate folder) - C/C++ tab: add to defines: Build_Library - C/C++ tab: make sure there is option /MD (for release) or /MDd (for debug) (eliminate /MT or /ML) Project Settings for motors - General tab: set Output files to Debug - Link tab, add Debug\splib.lib to library modules - to eliminate "unresolved external timeSetEvent" add winmm.lib to library modules - C/C++ tab: add to defines: Build_Motors, Use_Library - C/C++ tab: make sure there is option /MD (for release) or /MDd (for debug) (eliminate /MT or /ML) Project Settings for counters - General tab: set Output files to Debug - Link tab, add winmm.lib, Debug\splib.lib and Debug\motors.lib to library modules - C/C++ tab: add to defines: Build_Counters, Use_Library - C/C++ tab: make sure there is option /MD (for release) or /MDd (for debug) (eliminate /MT or /ML) Project Settings for XControl - Link tab, add winmm.lib, Debug\splib.lib, Debug\counters.lib and Debug\motors.lib to library modules - C/C++ tab: add defines Use_Counters, Use_Motors, Use_Library, Use_ImageCCD - C/C++ tab: make sure there is option /MD (for release) or /MDd (for debug) (eliminate /MT or /ML) 3. Changes to source files -------------------------- all files where applicable (use Edit/Find in files): - predefined macro __WIN32__ should be renamed to _WIN32 - change _export to __declspec(dllexport). Be sure that this new string is places in front of the words WINAPI or CALLBACK. In few places, word _export is just deleted. That is mentioned elsewhere in this document - delete all words __rtti - rename constants MAXDIR MAXFILE MAXPATH MAXEXT MAXDRIVE to _MAX_DIR _MAX_FNAME MAX_PATH _MAX_EXT _MAX_DRIVE respectively - change fnsplit to _splitpath - change fnmerge to _makepath - change chdir to _chdir and add #include - change try { var=new..; A;} catch (xalloc){B;} to var = new...; if (var) { A; } else { B; } - you can remove warning "truncation from const double to float" by adding f to the end of float constants e.g. 1.0f - you can remove warning "truncation from const int to char" by adding cast to the right side, e.g. b[i][j] = (char)255; m_curve.h - change _export to __declspec(dllexport) in #define _CURVECLASS - change _import to __declspec(dllimport) in #define _CURVECLASS m_devcom.h and m_psd.h - change _export to __declspec(dllexport) in #define _COUNTERCLASS - change _import to __declspec(dllimport) in #define _COUNTERCLASS m_dlg.cpp - introduce variable int edgeTmp; in function TAngleControl::Dlg_OnCommand - replace line SetScrollRange(BarHandle,SB_CTL,GetBarEgde(LEFT),GetBarEgde(RIGHT),TRUE); with edgeTmp = GetBarEgde(LEFT); SetScrollRange(BarHandle,SB_CTL,edgeTmp,GetBarEgde(RIGHT),TRUE); comhead.h - comment out #include , <_defs.h> - add #include in front of - add #define M_PI 3.14159265358979323846 comclass.h - delete all words _export dlg_tpl.cpp - comment out Ctl3dColorChange(); lines kpmt1.c - changed: mov dx, rd to mov dx, WORD PTR rd in inline asm code in several places to eliminate error "operand size conflict" also for mov dx,rs mov ax,d and mov i,ax - eliminated return _AX because it is Borland specific (Visual C++ does not need return statement to return with result in AX according to MSDN Power2 sample). radicon.h - macro CALLTYPE changed to: #define CALLTYPE __cdecl _Cdecl changed to __cdecl kisl1.c - changed: mov dx, rd to mov dx, WORD PTR rd and similar l_layer.cpp - comment out #include - comment out HANDLE hTheModule; line - change line BOOL DllEntryPoint(HANDLE hModule,DWORD dwFunction,LPVOID) to BOOL WINAPI DllMain(HINSTANCE hModule, DWORD dwFunction, LPVOID ) - change line hTheModule = hModule; to hModuleInstance = hModule; - comment out BWCCRegister line - add ; at the end of line with SearchAgain: label - replace timeGetTime() with clock() m_data.cpp - add cast (float) to MaxInt and MinInt m_devcom.h - change __rtti keyword to nothing m_layer.h - add: #if defined (Build_Motors) #define _MOTORCLASS __declspec(dllexport) #elif defined(Use_Motors) #define _MOTORCLASS __declspec(dllimport) #else #define _MOTORCLASS #endif - add _MOTORCLASS before the word WINAPI in each declaration - remove words WINAPI and CALLBACK from lines beginning with typedef m_layer.cpp - add _MOTORCLASS in front of WINAPI for each function that has _export keyword - change line BOOL DllEntryPoint(HANDLE hModule,DWORD dwFunction,LPVOID) to BOOL WINAPI DllMain(HINSTANCE hModule, DWORD dwFunction, LPVOID ) - comment out BWCCRegister line and after that line add: hModuleInstance = hModule; motors.cpp - I eliminated word _export; maybe it should be changed to __declspec(dllexport)? - I also commented out lines with calls to inp() and outp(), but under Windows 95 only, _inp and _outp can be used - I changed some casts in this manner: ( FARPROC ) gInitialize = GetProcAddress( hGPIBModule,"IEEE488_INITIALIZE" ); to gInitialize = (TInitialize) GetProcAddress( hGPIBModule,"IEEE488_INITIALIZE" ); Change: ( FARPROC ) gSend = GetProcAddress( hGPIBModule,"IEEE488_SEND" ); to gSend = (TSend) GetProcAddress( hGPIBModule,"IEEE488_SEND" ); etc. c_layer.cpp - remove #include (in all other files also) - comment out #pragma argsused (disables unknown pragma warning) (in all other files also) - eliminate call BWCCRegister (hModule); - change _export to __declspec(dllexport) . This should be placed in front of WINAPI or CALLBACK words (the order is important here) - add extern "C" to FakeDevice and pTime declarations. Add dummy initializer = "" to pTime declaration - because 32bit dlls behave differently during load, you need to guard LibMain and WEP functions with #ifndef _WIN32. In the #else part of this guard, add: BOOL WINAPI DllMain(HINSTANCE hModule, DWORD dwFunction, LPVOID ) { switch (dwFunction) { case DLL_PROCESS_ATTACH: bModulLoaded = FALSE; hModuleInstance = hModule; // BWCCRegister (hModule); lpDList = ( LPDList ) new TDList( nMaxDeviceAllowed, hModule ); hMotorDll = GetModuleHandle( "motors.dll" ); break; }; return TRUE; } c_layer.h - add __declspec(dllexport) in front of WINAPI and CALLBACK words counters.cpp - introduce local int variable _AX and insert mov _AX, ax at the end of inline asm code (apply to each function where _AX is returned from the function) braunpsd.c - change ( FARPROC ) cast to ( FARPROC& ) - change struct time to SYSTEMTIME - change gettime to GetLocalTime - change t1.ti_sec to (int)t1.wSecond Do the same for t2.ti_sec m_justag.cpp - to eliminate warning on forcing int to bool, for example in some statement x = y; where x is of type bool, and y is of type int, you can rewrite the statement as x = ( y != 0 ); m_main.cpp - add #include - comment out BWCCRegister line - comment out Ctl3dColorChange line - change string Borland C++ compiler to Visual C++ compiler - change __BORLANDC__ to _MSC_VER/2 - introduce variable char _arg[_MAX_PATH] and use GetModuleFileName() API function to initialize it instead of using _argv[] - I commented out the line metioning "device32.dll" because I did not have that dll - remove word _export from FrameWndProc declaration lines m_arscan.cpp and m_scan.cpp - add #include m_arscan.cpp, m_scan.cpp, m_device.cpp, m_justag.h and m_justag.cpp - remove declarations of struct date and struct time and introduce SYSTEMTIME st; instead - change d.da_year d.da_mon d.da_day to (int)st.wYear (int)st.wMonth (int)st.wDay (somewhere datum is used instead of d, and zeit instead of t) - change t.ti_hour t.ti_min ti.ti_sec to (int)st.wHour (int)st.wMinute (int)st.wSecond - change both getdate and gettime with GetLocalTime m_mothw.h - remove word CALLBACK from lpfnLimitWatch declaration line m_steerng.cpp - remove word _export from RecallSteering declaration line - change atof to atoi in line cmp.P1 = (TCParam)atof(p1); 4. Changes to Resources ----------------------- main.rc - ICON, BITMAP, CURSOR resources - delete inline definitions, (all except the first line); Open the .rc file in Borland IDE and use copy to clipboard of the resource, and make new temporary resource in VC++ with the same attributes, then use export command to save it to file. Delete temporary resource, and put the file name in the original ICON or BITMAP or CURSOR resource definition line - to eliminate some "duplicate resource id" warnings, change 1 to -1 in the corresponding LTEXT lines - comment out CLASS "bordlg" lines - change custom bwcc elements to standard controls: 1) change word CONTROL to GROUPBOX, if there is "BorShade" string in the same line 1b) change word CONTROL to EDITTEXT, if there is "EDIT" string in the same line 2) change CONTROL to AUTOCHECKBOX, if there is "BorCheck" string in the same line, and there is no BS_3STATE in the line 3) change CONTROL to AUTO3STATE, if there are "BorCheck" and BS_3STATE in the same line 4) change word CONTROL to CTEXT, if there is "BorStatic" string in the same line 5) change word CONTROL to PUSHBUTTON, if there is "BorBtn" string in the same line 6) change word CONTROL to RADIOBUTTON, if there is "BorRadio" string in the same line 7) change word CONTROL to PUSHBUTTON, if there is BS_USERBUTTON string in the same line 8) in these lines, delete the part after the second comma, but do not delete the trailing four numbers e.g. change the line CONTROL "Belichtungsregelung", -1, "BorShade", BSS_RGROUP | BSS_CAPTION | BSS_CENTER | WS_CHILD | WS_VISIBLE, 119, 93, 101, 50 to GROUPBOX "Belichtungsregelung", -1, 119, 93, 101, 50