PRODUCT : Borland C++ NUMBER : 1172 VERSION : 3.1 OS : WIN DATE : October 22, 1993 PAGE : 1/4 TITLE : Mastering the OWL Transfer mechanism. MASTERING THE OWL TRANSFER MECHANISM ==================================== In order to use transfer to get data to the child controls of a window object, we must create a child window object for each control we want to transfer to. This is typically done in the constructor of the window object. For example: class TMyDialog : public TDialog { public: PTEdit edit; PTComboBox dropdown_combo; }; TMyDialog::TMyDialog( PTWindowsObject parent, LPSTR title ) : TDialog( parent , title ) { edit = new TEdit( this , ID_EDIT , max_text_transfer); dropdown_combo = new TComboBox( this , ID_DROP_DOWN , max_text_transfer ); ... } Then you have to declare a structure which has data members that correspond to the proper controls on the dialog. They must be listed in the order which the controls are constructed in the dialog. Since TMyDialog will construct a TEdit, then a TComboBox, that is the order you would list the transfer data members in the structure. for example: struct TMyDialogTransfer { char edit[ max_text_transfer ]; PTComboBoxData dropdown_combo; ... }; PRODUCT : Borland C++ NUMBER : 1172 VERSION : 3.1 OS : WIN DATE : October 22, 1993 PAGE : 2/4 TITLE : Mastering the OWL Transfer mechanism. How do you know what data member to use to transfer to a specific control? Get online help on that control, like TComboBox, look at the help for the Transfer function. If there is no Transfer function, check the base class. For example TRadioButton does not define one, but inherits TCheckBox's. Some controls, like TButton and TGroupBox inherit TWindowObjects. This means they don't transfer anything. The online help for TComboBox::Transfer says that it expects to get a pointer to a PTComboBoxData. This means you want a to use a PTComboBoxData as the data member to transfer to the combobox. When the transfer happens, a pointer to whatever is in the transfer struct will be passed to each control. Common errors: ============== Do not use a char * to transfer to TEdit or TStatic; use a char[ TextLen ] where TextLen is the same value that the TEdit child in the TDialog is contructed with. Do not use a TScrollBarData* to transfer to TScrollBars. Use a TScrollBarData. Do not use a TComboBoxData or PTComboBoxData* to transfer to comboboxes. Use a PTComboBoxData. The third parameter to the TEdit constructor is important for transfering. If it is 0, the transfer would not work. It specifies how many bytes we can transfer from the char* in the transfer buffer. If I make a child control like: new TEdit( this , ID_EDIT , 256 ); I need a 'char edit_transfer[ 256 ];' in my transfer structure. TStatic controls do not have transfer on by default. If you want to transfer to one, you must call its EnableTransfer function. A common errors is to think you are transferring to a static control, when in fact you are not. What will happen is that later controls will use the static data for their own transfer, which will create problems. PRODUCT : Borland C++ NUMBER : 1172 VERSION : 3.1 OS : WIN DATE : October 22, 1993 PAGE : 3/4 TITLE : Mastering the OWL Transfer mechanism. Note that Modeless dialog boxes do not transfer data back out, you can do it yourself by overriding CloseWindow(int) for the dialog. If the user hits OK in a modal dialog, the data will be transfered back. If the user hits cancel, or closes via the system menu, nothing is transfered back. The memory you allocate for the transfer buffer has to persist after you set the transfer buffer. Let look at some code: TMyWindow::BuildDialog( RTMessage ) { struct TDialogTransfer dialog_transfer; my_dialog = new TMyDialog( this , "DIALOG_1" ); dialog->SetTransferBuffer( &dialog_transfer ); } TMyWindow::RunDialog( RTMessage ) { GetApplication()->ExecDialog( my_dialog ); } The above will cause a crash, since my_dialog will try to access the transfer buffer which has gone out of scope. This is because the transfer buffer is a local variable to the BuildDialog function. Debugging techniques: ===================== Look at the code for the Transfer data member of various controls. Note the size it returns. That size should match the size of the data member listed in this struct. For example: TScrollBar::Transfer returns sizeof( TScrollBarData ) which would indicate that I want a TScrollBarData in the struct, not a TScrollBarData*. Also, build the OWL library with debug info and set breakpoing in the Transfer functions for the various controls, like TScrollBar::Transfer. Inspect the DataPtr variable and compare it to what you know is the corresponding data member in the transfer struct. Be aware that DataPtr will be a pointer to that data member. PRODUCT : Borland C++ NUMBER : 1172 VERSION : 3.1 OS : WIN DATE : October 22, 1993 PAGE : 4/4 TITLE : Mastering the OWL Transfer mechanism. TransferData() is the function you use to force a dialog or window to transfer data to/from the child controls. For example: dialog_pointer->TransferData( TF_GETDATA ); There is a known problem with the TComboBox::Transfer function which can cause memory corruption. A correction for this problem is available available as COMBTR.ZIP in the BCPPWIN Forum, lib 11 on CompuServe and on the Borland BBS at (408)431-5096. Source code to an example implementing OWL Transfer can be downloaded as OWLXFR.ZIP from the Borland BBS at (408)431-5096. The source code is an excellent supplement to the above document. DISCLAIMER: You have the right to use this technical information subject to the terms of the No-Nonsense License Statement that you received with the Borland product to which this information pertains.