| Общие положения. | Объекты | Функции. |
В DBasic существует три типа объектов.
Оконные объекты представляют собой обычные Windows окна в которые интегрирован необходимый функционал. Они могут быть двух типов. Первые предназначены для отображения в окнах диалога DBasic. Типичным примером такого объекта может быть окно типа EDITDATE. В качестве примера демонстрируется фрагмент его кода:
#pragma warning( disable : 4086 )
LRESULT CALLBACK EditDateProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{//==============================================================================
EDITDATE *pDate;
pDate= (EDITDATE*) GetWindowLong( hwnd, 0 );
switch( uMsg ) {
case WM_CREATE:
pDate= new EDITDATE;
if( ! pDate ) return -1L;
SetWindowLong( hwnd, 0, (LONG)pDate );
SendMessage( hwnd, WM_SETFONT, 0, 0 );
break;
case WM_DESTROY:
IF pDate THEN
delete pDate;
SetWindowLong( hwnd, 0, 0 );
ENDI
break;
case WM_SETFOCUS:
if( pDate ) pDate->ShowCaret( hwnd );
break;
case WM_KILLFOCUS:
HideCaret( hwnd );
DestroyCaret();
break;
case WM_LBUTTONDOWN:
if( pDate ) pDate->SetPosition( LOWORD(lParam) );
SetFocus( hwnd );
break;
case WM_GETDLGCODE:
return DLGC_WANTCHARS| DLGC_WANTARROWS;
case WM_KEYDOWN:
if( pDate ) {
if( pDate->Type( hwnd, wParam ) ) {
InvalidateRect( hwnd, NULL, FALSE );
UpdateWindow( hwnd );
}
}
break;
case WM_PAINT:
if( pDate ) pDate->Paint( hwnd );
break;
case WM_SETTEXT:
if( pDate ) pDate->Set( (PSTR)lParam );
InvalidateRect( hwnd, NULL, FALSE );
UpdateWindow( hwnd );
break;
case WM_GETTEXT:
if( pDate ) return pDate->Get( (PSTR)lParam, (WORD)wParam );
break;
case WM_GETTEXTLENGTH:
if( pDate ) return pDate->Len();
return 0L;
default:
return (DefWindowProc(hwnd, uMsg, wParam, lParam));
}
return 0L;
}// EditDateProc;
Здесь используется тот факт, что в случае неизвестного класса окна
в окне диалога DBasic ведет себя как если-бы это было текстовое окно.HWND WINAPI RSTBL_Load( HWND hwnd, PSTR name )
{//===========================================
RECT rc;
HWND hTblWnd;
RSTBL * pTbl;
GetClientRect( hwnd, &rc );
hTblWnd= CreateWindow( TBLCLASSNAME, NULL,
WS_CHILD| WS_VSCROLL,
0, 0, rc.right-rc.left, rc.bottom-rc.top,
hwnd, NULL, hInst, NULL);
if( ! hTblWnd ) {
ERRBOX( hwnd, 101, 0 );
return NULL;
}
pTbl= (RSTBL *) GetWindowLong( hTblWnd, 0 );
pTbl->hParent= hwnd;
pTbl->SetName( name );
return hTblWnd;
}
BOOL WINAPI RSTBL_Show( HWND hTbl, HANDLE hRs, PSTR Title, PSTR Style )
{//====================================================================
RSTBL * pTbl= (RSTBL *) GetWindowLong( hTbl, 0 );
HCURSOR hcur = SetCursor(LoadCursor(NULL, IDC_WAIT));
WORD style= pTbl->SetStyle( Style, TRUE );
BOOL res= pTbl->Open( (DBSET*)hRs, Title );
if( res ) {
if( (style & TBL_UNTUNE)==0 ) pTbl->TuneRead();
ShowWindow( hTbl, SW_SHOW );
UpdateWindow( hTbl );
}
SetCursor(hcur);
SetFocus(hTbl);
return res;
}
DBasic использует свои собственные объекты, а не ActiveX. Они представляют собой обычные DLL модули, которые должны выполнять следующие соглашения. Прежде всего в нем должна быть определена функция для инициализации класса. Эта функция должна возвращать любой идентификатор объекта этого класса, который DBasic будет передовать всем методам данного класса в качестве первого параметра. Префикс имени этой функции, как и всех методов класса должен совпадать с именем DLL модуля. Например:
HANDLE WINAPI RSODBC_New( HANDLE hBase, PSTR szName )
{//==================================================
RECSET * pRs= new RECSET( (HDBC)hBase, szName );
if( ! pRs ) return NULL;
return (HANDLE)pRs;
}Соответственно методы данного класса будут иметь вид:
BOOL WINAPI RSODBC_Open( HANDLE hRs, PSTR Query, PSTR Type )
{//=========================================================
RECSET * pRs= (RECSET *) hRs;
return pRs->Open( Query, Type );
}
DWORD WINAPI RSODBC_Refresh( HANDLE hRs, BOOL On )
{//===============================================
RECSET * pRs= (RECSET *) hRs;
if( pRs->Refresh( On ) ) return pRs->RecCount();
return 0L;
}Далее должна быть реализована функция для удаления созданного
объекта класс. Например:
BOOL WINAPI RSODBC_Close( HANDLE hRs )
{//===================================
RECSET * pRs= (RECSET *) hRs;
if( ! hRs ) return FALSE;
pRs->Close();
delete pRs;
return TRUE;
}Кроме того должны быть реализованы две функции.
Первая, должна иметь имя вида имя модуля плюс "_HANDLE" и должна возвращать
хэндел инстоляции модуля, который DBasic использует для доступа к строковым
ресурсам модуля.
HANDLE WINAPI RSODBC_HANDLE( void )
{//================================
return (HANDLE) hInst;
}Вторая, должна иметь фиксированное имя RELEASE и необходима если
какой-либо из методов класса возвращает ссылку на переменную типа VARIABLE.
void WINAPI RELEASE( PVARIABLE pVar )
{//==================================
if( pVar ) delete pVar;
}И в заключение. Все функции и методы должны быть описаны
в строковом ресурсе DLL модуля. Для выше приведенного примера это будет.
STRINGTABLE DISCARDABLE BEGIN 1 "RSODBC!RSODBC_New( OBJECTНумерация должна начинаться с единицы и быть сплошной. После пропуска очередной цифры могут располагаться внутренние строковые ресурсы модуля., STRING ) LONG " 2 "RSODBC!RSODBC_Open( LONG , STRING , STRING ) BOOL" 3 "RSODBC!RSODBC_Refresh( LONG , BOOL ) LONG" 4 "RSODBC!RSODBC_Close( LONG , BOOL On ) " END
DBasic позволяет использовать обычные ActiveX элементы при условии если они не имеют визуализации. Например, можно прекрасно использовать ADO.
SET Base=CreateObject("ADODB.Connection")
ConStr= "driver={SQL Server};server=VLAD-DUBEIKOV;database=TEST;uid=sa;pwd=;"
Base.Open(ConStr)
SET Rs=Base.Execute("select * from country order by name")
Count=Rs.Fields.Count
FOR i=0 TO Count-1
SET Prp=Rs.Fields(i).Properties
FOR j=0 TO Prp.Count-1
Res=INPUT(Rs.Fields(i).Name,Prp.Item(j).Name,Prp.Item(j).Value)
NEXT
ERASE Prp
NEXT
Count=Rs.RecordCount
FOR i=1 TO 2
IF Rs.EOF THEN EXIT
V1=Rs.Fields(0).Value
V2=Rs.Fields(1).Value
Rs.MoveNext()
NEXT
ERASE Rs
SET Rs=CreateObject("ADODB.Recordset")
Rs.Open("select * from country order by name",Base,1,3,8)
Rs.AddNew()
Rs.Fields("NAME").Value="aaaa"
Rs.Update()
Rs.Close()
ERASE Rs
ERASE BaseДля того, чтобы отличить метод от свойства
DBasic использует скобки. Не забывайте их указывать при вызове
метода без параметров. И учтите, что DBasic не понимает default
свойств объектов. Поэтому нужно прописывать весь путь до запрашиваемого
свойства полностью. Т.е например, писать Rs.Fields(0).Value, а не
Rs.Fields(0), как допустимо в VB.
| Общие положения. | Функции. |