Общие положения. Объекты Функции.

В DBasic существует три типа объектов.

  • Оконные объекты
  • Dbasic объекты
  • ActiveX объекты
  • Оконные объекты

    Оконные объекты представляют собой обычные 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 ведет себя как если-бы это было текстовое окно.
    Вторые - для интеграции собственно в окна DBasic. Они ни чем принципиально не отличаются от выше описанных окон за исключением, что для создания и дальнейщего отображения должны быть реализованы дополнительные функции. Это можно видеть на примере из RSTBL.
    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 объекты

    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
    Нумерация должна начинаться с единицы и быть сплошной. После пропуска очередной цифры могут располагаться внутренние строковые ресурсы модуля.

    ActiveX объекты

    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.


    Общие положения.   Функции.
    Hosted by uCoz