Общие положения. | Объекты | Функции. |
В 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.
Общие положения. | Функции. |