From Support Wiki
Migrating from CTD 1.5 to 2.0
Denis Roy - Gupta Technologies
This article is intended to assist programmers who are faced with the challenge of migrating CTD 1.5 applications to CTD 2.0. The topics discussed below are also applicable to the migration from CTD 1.5 to CTD 2.1. For a complete list of changes since CTD 1.5, please refer to your Team Developer release notes.
Converting OLE2 objects to ActiveX within CTD 2.x does not work
For a workaround on how to convert OLE2 objects to ActiveX, please read the article "Converting data in OLE2 format to ActiveX format" that can be found at http://www.guptaworldwide.com/tech/support/bulletins/ctd/051101.asp
External libraries will be named differently than they were named in CTD 1.5.
For example, the tooltip library which was previously cbtti15.dll is now cbtti20.dll. Install CTD 2.0 in a separate directory (eg. C:\Program Files\Centura 2.0) and make a copy of all your sources in a new directory structure (eg. C:\Inventory Programs 2.0 ..) so as not to overwrite your current code. After opening one of the applications, go to Tools | Preferences | Directories menu item, specify the correct path where the CTD 2.0 library files can be found, and change the library names in the application. Avoid opening CTD applications by double-clicking on the .APP file. Iinstead always start CTD first and then use the File | Open menu item or the toolbar to open the application.
Non-editable datafields in CTD 2.0 will receive focus.
This is a feature that has pretty much become a Windows standard, and not a bug. The disabled datafield will still be protected from any input. However, by allowing the focus to enter these fields, the data can be copied from the disabled datafield and then pasted somewhere else. If the non-standard behavior is required, a functional class could be called for each window's Sam_CreateComplete to loop through the child datafields and multiline text fields to disable them if they are found to be non-editable. Here's an example:
Set hWndChild = p_hWndParent
Set hWndChild = SalGetFirstChild( hWndChild, TYPE_DataField TYPE_MultilineText)
Loop
If hWndChild = hWndNULL
Break
Set nStyle = GetWindowLongA( hWndChild, GWL_STYLE )
!
Set nType = SalGetType ( hWndChild )
If ( nType = TYPE_DataField ) OR ( nType = TYPE_MultilineText )
If (nStyle & ES_READONLY)
Call SalEnableWindow( hWndChild )
Call SalDisableWindow( hWndChild )
!
Set hWndChild = SalGetNextChild( hWndChild, TYPE_DataField TYPE_MultilineText )
Other Issues
Assuming that the CTD 2.0 migration also includes moving to Windows 2000 / NT and new COM+ components, any remaining migration issues are likely to be functionality "outside" of SAL, such as: custom controls and changed object libraries.
For example, If the CTD 1.5 application was developed using the Calendar Control 8.0 and now you are using the newer version Calendar Control 9.0, you will experience some compile errors.
In the Calendar control, the first problem that needs to be resolved is "Undefined symbol .... " ; Create an instance of the new AX_MSACAL_Calendar control. This should be done by using the Controls tool in layout mode. Click on the ActiveX icon, select the Calendar Control 9.0, and drag and drop it on the form. You will want to keep the old control MSACAL_Calendar until you have applied all the code in the Message Actions to the new control. Apply the message actions to the new control (don't cut and paste, use the Coding Assistant). In CTD 1.5 and the initial release of CTD 2.0, a problem was identified when accessing the ActiveX control in the outline. Do not comment-out or delete the old control directly in the outline; instead, when the old control is no longer needed, delete it in layout mode. Now recompile and you will notice that the "Unresolved symbol" problem has now been fixed. The remaining compile errors will identify the need to resolve "Undefined functions .". Take a look at the Calendar Control 9.0 Class Definitions and you will see that the object AX_MSACAL_Calendar is derived from a COM Proxy class which is derived from a Functional Class (interface).
All access to the object should be through the interface (Functional Class: MSACAL_ICalendar). If we search the interface we do not find the functions called SetValue or GetValue; instead we find functions called PropGetValue and PropSetValue. The translation is not always that obvious; however, in this case it was easy to determine that we must use PropSetValue and PropGetValue. Notice that the functions now use Variants as parameters in order to make them more flexible (anything can go in a Variant). However, we must set them correctly using date.SetDate, string.SetString etc. etc.
The following code is an example of using PropSetValue and PropGetValue:
Dialog Box: dlgCalendar
Description:
Tool Bar
Contents
Pushbutton: pbOk
Message Actions
On SAM_Click
Call axCalendar.PropGetValue( vDate )
Call vDate.GetDate( dtTmp )
Set p_dDate = dtTmp
Call SalEndDialog( hWndForm, TRUE )
AX_MSACAL_Calendar: axCalendar
Message Actions
On DblClick
Parameters
Actions
Call SalSendMsg(pbOk, SAM_Click, 0, 0)
Functions
Window Parameters
Window Variables
Message Actions
On SAM_CreateComplete
If p_dDate = DATETIME_Null
Set p_dDate = SalDateCurrent( )
Call vDate.SetDate( p_dDate )
Call axCalendar.PropSetValue( vDate )
If the CTD 1.5 application was developed using Microsoft's Office 97 Object libraries or later versions (eg. Microsoft Word Object Library 8.0) and now you are using Office 2000 (Microsoft Word Object Library 9.0), you will notice the impact resulting from Microsoft's implementation of COM+. To resolve this, start by re-generating the library. Use the Tools | ActiveX Explorer then select the library (eg. Microsoft Word 9.0 Object Library), select the required classes and Generate using the Generate Deep option.
Note: When re-generating an object library, it is a good practice to remove the included library from the application and delete the Centura APL (eg. Microsoft Word 9.0 Object Library.APL), from the Centura AXLibs directory, before re-generating from the Type Library, this will ensure that none of the code from the previous library will remain in the application.
ActiveX controls have changed. The objects now consist of COM Proxy Classes and the standard COM functions. To create the object you now need to access the Create or CreateEx functions of the COM Proxy Class.
Code Example :
Set bReturn = oWord.Create( )
If bReturn
Call oWord.PropSetVisible( TRUE )
Else
Set bReturn = FALSE
Call SalMessageBox( "Create Word Object failed", 'Error', MB_Ok )
The previous method of using Detach to destroy the object is now replaced with the Release function. Code example :
Call oWord.Release( )
As was shown with the Calendar Control, all interactions with the object should be done by accessing the functions exposed by the interface (Functional Class). To get information as to how to call these functions refer to the documentation provided by the vendor of the object library.