HOME
SCREEN SHOTS
DOWNLOADS
CODE SAMPLES

Sample Code for SD DataGrid

These examples from the SD DataGrid Trial Version show how easy it is to use SD DataGrid in your application.

BCX sample.    Screen Shot.

PureBasic ODBC sample.    Screen Shot.

Liberty BASIC ODBC sample.    Screen Shot.

C/C++ Sample

The following code compiles with
  • MinGW-3.1.0-1 as C or C++.
  • Pelles C.
  • LccWin32
  • Dev-C++

#include <windows.h>
#include <windowsx.h>
#include <commctrl.h>
#include <stdio.h>

#include "SdDataGrid.h"

#define ID_MENU 2001
#define ID_EXIT 6001
#define ID_EDIT 1
#define ID_UNDOFIELD 6002
#define ID_UNDOROW 6003
#define ID_UNDELETEROW 6004
#define ID_GRID 901

HINSTANCE AppInst;
HINSTANCE hLibGrid;
HWND Form1;
HWND hGrid;

INT retval;
CHAR ClassName[20];

COL_INFO CI; // must have global scope.

LRESULT CALLBACK WndProc (HWND, UINT, WPARAM, LPARAM);
LRESULT HandleGridMsg(UINT);
VOID HandleMenu(WPARAM, LPARAM);
VOID LoadGridData(HWND);

int WINAPI WinMain(HINSTANCE hInst,HINSTANCE hPrev,LPSTR CmdLine,int CmdShow)
{
  WNDCLASS Wc;
  MSG      Msg;
  
  strcpy(ClassName,"SDDGtest");
  AppInst    =  hInst;
  
  Wc.style         =  CS_HREDRAW | CS_VREDRAW | CS_OWNDC;
  Wc.lpfnWndProc   =  WndProc;
  Wc.cbClsExtra    =  0;
  Wc.cbWndExtra    =  0;
  Wc.hInstance     =  hInst;
  Wc.hIcon         =  NULL;
  Wc.hCursor       =  LoadCursor(NULL,IDC_ARROW);
  Wc.hbrBackground =  (HBRUSH)(COLOR_BTNFACE+1);
  Wc.lpszMenuName  =  MAKEINTRESOURCE(ID_MENU);
  Wc.lpszClassName =  ClassName;
  RegisterClass(&Wc);

  Form1 = CreateWindowEx(0,ClassName,"SD DataGrid Demo",WS_OVERLAPPEDWINDOW|WS_CLIPCHILDREN,
  20,20,600,400,NULL,(HMENU)NULL,AppInst,NULL);
  
  ShowWindow(Form1,SW_SHOW);
  if(hGrid) LoadGridData(hGrid);

  while(GetMessage(&Msg,NULL,0,0))
  {
    HWND hActiveWindow = GetActiveWindow();
    if(!IsWindow(hActiveWindow) || !IsDialogMessage(hActiveWindow,&Msg))
    {
      TranslateMessage(&Msg);
      DispatchMessage(&Msg);
    }
  }
  return Msg.wParam;
}

LRESULT CALLBACK WndProc (HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam)
{
  INT LwP;
  RECT rc;

  if(Msg >= ROW_BEFORE_NAVIGATE && Msg <= COMBO_FILL)
  {
    return HandleGridMsg(Msg);
  }
  
  switch(Msg)
  {            
    case WM_CREATE:
    {
      hLibGrid = LoadLibrary("sd_datagrid_demo.dll");
      if(hLibGrid)
      {
        if(C_initGridfuncs(hLibGrid))
        {
          GetClientRect(Form1,&rc);
          hGrid = CreateGrid(hWnd,AppInst,GRIDSTYLE_SUNKEN,ID_GRID,0,0,rc.right,rc.bottom);
        }
      }
      break;
    }

    case WM_INITMENUPOPUP:
    {
      HandleMenu(wParam,lParam);
      break;
    }

    case WM_COMMAND:
    {
      if(!HIWORD(wParam))
      {
        LwP = LOWORD(wParam);
        if(LwP == ID_EXIT) 
        {
          PostMessage(hWnd,WM_CLOSE,0,0);
        }
        if(LwP == ID_UNDOFIELD)
        {
          UndoField(hGrid);
        }
        if(LwP == ID_UNDOROW)
        {
          UndoRow(hGrid);
        }
        if(LwP == ID_UNDELETEROW)
        {
          UndeleteRow(hGrid);
        }
      }
      break;
    }

    case WM_SIZE:
    {
      GetClientRect(Form1,&rc);
      MoveWindow(hGrid,0,0,rc.right,rc.bottom,FALSE);
      break;
    }

    case WM_CLOSE:
    {
      if(hGrid) 
      {
        FreeGrid(hGrid);
        DestroyWindow(hGrid);
      }
      if(hLibGrid) FreeLibrary(hLibGrid);
      break;
    }
      
    case WM_DESTROY:
    {
      UnregisterClass(ClassName,AppInst);
      PostQuitMessage(0);
      break;
    }
  }
  return DefWindowProc(hWnd,Msg,wParam,lParam);
}

VOID LoadGridData(HWND hg)
{
//Creates 100 rows x 15 columns and fills the grid with imaginary data.
//This is the slowest way to load data.
  INT iRow=0;
  INT iColumn;
  COLORREF x;
  CHAR tmp[51];
  CHAR tmp2[51];
  CHAR fooData[20];
  
  iRow = DimCols(hg,15);
  if(iRow != 1) return;

  SetRowHeight(hGrid,35);
  CI.FldSize = 50;
  CI.DataType = SD_CHAR; //fields are strings.
  CI.Precision = 0;

  x = RGB(244, 240, 228);
  
  for(iColumn = 1; iColumn <= 15; iColumn++)
  {
    // set alternating display properties for example.
    if(CI.ColBackClr == x)
    {
      CI.ColWidth = 130;
      CI.ColBackClr = RGB(250, 250, 238);
      CI.ColForeClr = RGB(250, 150, 150);
      CI.Alignment = HDF_RIGHT;
      CI.MultiLine = FALSE;
      CI.FontName = "Times New Roman";
      CI.PointSize = 10;
      CI.Bold = FW_BOLD;
      CI.Italic = 1;
      CI.Underline = 1;
    }
    else
    {
      CI.ColWidth = 70;
      CI.ColBackClr = x;
      CI.ColForeClr = 0;
      CI.Alignment = HDF_CENTER;
      CI.MultiLine = TRUE;
      CI.FontName = "Arial";
      CI.PointSize = 8;
      CI.Bold = 0;
      CI.Italic = 0;
      CI.Underline = 0;
    }

    // create some column labels.
    sprintf(tmp,"%d",iColumn);
    sprintf(tmp2,"%s%s","Column ",tmp);
    CI.ColName = (CHAR*)tmp2;
    
    // define the field.
    DefineField(hg,iColumn,FIELD_EDITBOX, &CI);
  }
  
  // create some data.
  for(iRow = 1; iRow <= 100; iRow++)
  {
    sprintf(tmp,"%d",iRow);
    for(iColumn = 1; iColumn <= 15; iColumn++)
    {
      sprintf(tmp2,"%d",iColumn);
      sprintf(fooData,"%s%s%s%s","Row ",tmp," Column ",tmp2);
      
      // create the cell with the data.
      CreateCell(hg,iRow,iColumn,fooData);
    }
  }

  SetUndoBuffer(hg);
  return;
}


LRESULT HandleGridMsg(UINT Msg)
{
  LRESULT ret = 0;
  
  switch(Msg)
  {
    case ROW_BEFORE_NAVIGATE:
    {
      //returns: 0 = continue, 1 = cancel row navigation
      MessageBox(Form1,"ROW_BEFORE_NAVIGATE","Message",0);
      break;
    }

    case ROW_BEFORE_DELETE:
    {
      //returns: 0 = continue, 1 = cancel
      MessageBox(Form1,"ROW_BEFORE_DELETE","Message",0);
      break;
    }

    case ROW_DELETED:
    {
      //returns: None
      MessageBox(Form1,"ROW_DELETED","Message",0);
      break;
    }

    case ROW_UNDELETED:
    {
      //returns: None
      MessageBox(Form1,"ROW_UNDELETED","Message",0);      
      break;
    }

    case CELL_BEFORE_UPDATE:
    {
      //returns: 0 = continue, 1 = cancel
      MessageBox(Form1,"CELL_BEFORE_UPDATE","Message",0);
      break;
    }

    case CELL_AFTER_UPDATE:
    {
      //returns: None
      MessageBox(Form1,"CELL_AFTER_UPDATE","Message",0);
      break;
    }

    case ROW_BEFORE_SELECT:
    {
      //returns: 0 = continue, 1 = cancel
      MessageBox(Form1,"ROW_BEFORE_SELECT","Message",0);
      break;
    }

    case GRID_RIGHT_CLICK:
    {
      //returns: None
      MessageBox(Form1,"GRID_RIGHT_CLICK","Message",0);
      break;
    }

    case COMBO_FILL:
    {
      //returns: None
      MessageBox(Form1,"COMBO_FILL","Message",0);
      break;
    }
  }
  return ret;
}


VOID HandleMenu(WPARAM wParam, LPARAM lParam)
{
  HMENU hMnuEdit = GetSubMenu(GetMenu(Form1),ID_EDIT);
  if((HMENU)wParam == hMnuEdit)
  {
    EnableMenuItem(hMnuEdit,ID_UNDOFIELD,!CanUndoField(hGrid));
    EnableMenuItem(hMnuEdit,ID_UNDOROW,!CanUndoRow(hGrid));
    EnableMenuItem(hMnuEdit,ID_UNDELETEROW,!CanUndeleteRow(hGrid));
  }
  return;
}




BCX Sample

GUI "SDDGtest", PIXELS #include "SdDataGrid.h" CONST ID_MENU = 2001 CONST ID_EXIT = 6001 CONST ID_EDIT = 1 CONST ID_UNDOFIELD = 6002 CONST ID_UNDOROW = 6003 CONST ID_UNDELETEROW = 6004 CONST ID_GRID = 901 DIM CI AS COL_INFO DIM retval AS INT DIM AppInst AS HINSTANCE DIM hLibGrid AS HINSTANCE DIM Form1 AS HWND DIM hGrid AS HWND GLOBAL MainMenu AS HMENU GLOBAL FileMenu AS HMENU GLOBAL EditMenu AS HMENU SUB FORMLOAD Form1 = BCX_FORM ("SD DataGrid Demo", 0, 0, 600, 400, WS_OVERLAPPEDWINDOW OR WS_CLIPCHILDREN) MainMenu = CreateMenu() FileMenu = CreateMenu() EditMenu = CreateMenu() InsertMenu(MainMenu, 0, MF_POPUP, FileMenu, "&File") AppendMenu(FileMenu, MF_STRING, ID_EXIT, "E&xit") InsertMenu(MainMenu, 1, MF_POPUP, EditMenu, "&Edit") AppendMenu(EditMenu, MF_STRING, ID_UNDOFIELD, "Undo &Field") AppendMenu(EditMenu, MF_STRING, ID_UNDOROW, "Undo &Row") AppendMenu(EditMenu, MF_STRING, ID_UNDELETEROW, "&Undelete Row") SetMenu (Form1, MainMenu) CENTER (Form1) SHOW (Form1) CALL LoadGridData(hGrid) END SUB BEGIN EVENTS DIM rc AS RECT IF(Msg >= ROW_BEFORE_NAVIGATE AND Msg <= COMBO_FILL) THEN FUNCTION = HandleGridMsg(Msg) END IF SELECT CASE CBMSG CASE WM_CREATE AppInst = BCX_HINSTANCE hLibGrid = LoadLibrary("sd_datagrid_demo.dll") IF hLibGrid THEN IF C_initGridfuncs(hLibGrid) THEN GetClientRect(Form1,&rc) hGrid = CreateGrid(CBHNDL,AppInst,GRIDSTYLE_SUNKEN,ID_GRID,0,0,rc.right,rc.bottom) END IF END IF CASE WM_COMMAND IF NOT CBCTLMSG THEN IF CBCTL = ID_EXIT THEN PostMessage(CBHNDL, WM_CLOSE, 0, 0) IF CBCTL = ID_UNDOFIELD THEN UndoField(hGrid) IF CBCTL = ID_UNDOROW THEN UndoRow(hGrid) IF CBCTL = ID_UNDELETEROW THEN UndeleteRow(hGrid) END IF CASE WM_INITMENUPOPUP HandleMenu(CBWPARAM,CBLPARAM) CASE WM_SIZE GetClientRect(Form1,&rc) MoveWindow(hGrid,0,0,rc.right,rc.bottom,FALSE) CASE WM_CLOSE IF hGrid THEN FreeGrid(hGrid) DestroyWindow(hGrid) FreeLibrary(hLibGrid) END IF END SELECT END EVENTS SUB LoadGridData(hg AS HWND) DIM iRow DIM iColumn DIM x AS COLORREF DIM tmp$[51] AS CHAR DIM tmp2$[51] AS CHAR DIM fooData$[20] AS CHAR iRow = DimCols(hg,15) IF iRow <> 1 THEN EXIT SUB SetRowHeight(hg,35) CI.FldSize = 50 CI.DataType = SD_CHAR 'fields are strings. CI.Precision = 0 x = RGB(244, 240, 228) FOR iColumn = 1 TO 15 ' set alternating display properties for example. IF CI.ColBackClr = x Then CI.ColWidth = 130 CI.ColBackClr = RGB(250, 250, 238) CI.ColForeClr = RGB(250, 150, 150) CI.Alignment = HDF_RIGHT CI.MultiLine = FALSE CI.FontName = "Times New Roman" CI.PointSize = 10 CI.Bold = FW_BOLD CI.Italic = 1 CI.Underline = 1 ELSE CI.ColWidth = 70 CI.ColBackClr = x CI.ColForeClr = 0 CI.Alignment = HDF_CENTER CI.MultiLine = TRUE CI.FontName = "Arial" CI.PointSize = 8 CI.Bold = 0 CI.Italic = 0 CI.Underline = 0 END IF ' create some column labels. tmp$= str$(iColumn) tmp2$ = "Column " + tmp$ CI.ColName = tmp2$ ' define the field. DefineField(hg,iColumn,FIELD_EDITBOX, &CI) NEXT 'iColumn ' create some data. FOR iRow = 1 to 100 tmp$ = str$(iRow) FOR iColumn = 1 to 15 tmp2$ = str$(iColumn) fooData$ = "Row " + tmp$ + " Column " + tmp2$ ' create the cell with the data. CreateCell(hg,iRow,iColumn,fooData$) NEXT NEXT SetUndoBuffer(hg) END SUB FUNCTION HandleGridMsg(Msg AS UINT) AS LRESULT LOCAL ret AS LRESULT SELECT CASE Msg CASE ROW_BEFORE_NAVIGATE 'returns: 0 = continue, 1 = cancel row navigation MessageBox(Form1,"ROW_BEFORE_NAVIGATE","Message",0) CASE ROW_BEFORE_DELETE 'returns: 0 = continue, 1 = cancel MessageBox(Form1,"ROW_BEFORE_DELETE","Message",0) CASE ROW_DELETED 'returns: None MessageBox(Form1,"ROW_DELETED","Message",0) CASE ROW_UNDELETED 'returns: None MessageBox(Form1,"ROW_UNDELETED","Message",0) CASE CELL_BEFORE_UPDATE 'returns: 0 = continue, 1 = cancel MessageBox(Form1,"CELL_BEFORE_UPDATE","Message",0) CASE CELL_AFTER_UPDATE 'returns: None MessageBox(Form1,"CELL_AFTER_UPDATE","Message",0) CASE ROW_BEFORE_SELECT 'returns: 0 = continue, 1 = cancel MessageBox(Form1,"ROW_BEFORE_SELECT","Message",0) CASE GRID_RIGHT_CLICK 'returns: None MessageBox(Form1,"GRID_RIGHT_CLICK","Message",0) CASE COMBO_FILL 'returns: None MessageBox(Form1,"COMBO_FILL","Message",0) END SELECT FUNCTION = ret END FUNCTION FUNCTION HandleMenu(wParam AS WPARAM, lParam AS LPARAM) AS VOID LOCAL hMnuEdit AS HMENU hMnuEdit = GetSubMenu(GetMenu(Form1), ID_EDIT) IF((HMENU)wParam = hMnuEdit) THEN $CCODE EnableMenuItem(hMnuEdit,ID_UNDOFIELD,!CanUndoField(hGrid)); EnableMenuItem(hMnuEdit,ID_UNDOROW,!CanUndoRow(hGrid)); EnableMenuItem(hMnuEdit,ID_UNDELETEROW,!CanUndeleteRow(hGrid)); $CCODE END IF END FUNCTION
The examples above create this application.

 

PureBasic ODBC Example


;A simple application that demonstrates the ability of the odbcLoadRecordsetSQL function
;to execute a SELECT query, configure the grid, and display the results.
;Event messages are displayed in the EditorGadget.

IncludeFile "SdDataGrid.pbi" ;contains constants and structures

Global ghGrid, ghEdit, ghEnv, ghDBc
;menus
Global ghMenuEdit, gID_Exit, gID_Undo, gID_Field, gID_Row, gID_UndeleteRow, gID_Execute

gID_Exit = 1
gID_Field = 3
gID_Row = 4
gID_UndeleteRow = 5
gID_Execute = 6

#main     = 0
#edit1    = 0
#GridLib  = 0
#IDGRID1  = 1200

Procedure AddText(txt$): AddGadgetItem(#edit1, -1, txt$): EndProcedure
Procedure LoWord(x): ProcedureReturn x & $FFFF: EndProcedure
Procedure HiWord(x): ProcedureReturn x >> 16: EndProcedure

Procedure ODBCErrMsg()
  ercd = CallFunction(#GridLib, "odbcGetErrCode")
  pMsg$ = PeekS(CallFunction(#GridLib, "odbcGetErrMsg"))
  MessageRequester("ODBC Error", "ODBC Err code: " + Str(ercd) + Chr(13) + pMsg$,0)
EndProcedure

Procedure Connect(connstr$)
  ghEnv = CallFunction(#GridLib, "odbcAllocEnv")
  If ghEnv = #SQL_ERROR
    ODBCErrMsg()
    ProcedureReturn #False
  Else
    ghDBc = CallFunction(#GridLib, "odbcConnect", ghEnv, connstr$)
    If ghDBc = #SQL_ERROR
      ODBCErrMsg()
      ProcedureReturn #False
    EndIf
  EndIf
  ProcedureReturn #True
EndProcedure

Procedure QuerySelect(sql$)
  hStmt = CallFunction(#GridLib, "odbcLoadRecordsetSQL", ghGrid, ghDBc, sql$, #True)
  If hStmt <> #SQL_ERROR
    CallFunction(#GridLib, "odbcFreeStmt", hStmt)
    CallFunction(#GridLib, "SetUndoBuffer", ghGrid)
  Else
    ODBCErrMsg()
  EndIf
EndProcedure

Procedure CleanupAndExit()
  If ghDBc > 0
    ;close database
    CallFunction(#GridLib, "odbcDisconnect", ghDBc)
    ;free database
    CallFunction(#GridLib, "odbcFreeDB", ghDBc)
  EndIf
  ;free environment
  If ghEnv > 0
    CallFunction(#GridLib, "odbcFreeEnv", ghEnv)
  EndIf

  If ghGrid > 0
    CallFunction(#GridLib, "FreeGrid", ghGrid)
    DestroyWindow_(ghGrid)
  EndIf
    
  CloseWindow(#main)
  End
EndProcedure

Procedure MainWndProc(hWnd, Msg, wParam, lParam)
  Retval= #PB_ProcessPureBasicEvents
  
  If LoWord(wParam) = #IDGRID1
    ;Handle grid notifications
    Select Msg
      Case #ROW_BEFORE_NAVIGATE
        ;responses: 0 = continue, 1 = cancel row navigation
        AddText("#ROW_BEFORE_NAVIGATE")
        
      Case #ROW_BEFORE_DELETE
        ;responses: 0 = continue, 1 = cancel
        AddText("#ROW_BEFORE_DELETE")
        
      Case #ROW_DELETED
        ;responses: None
        AddText("#ROW_DELETED")
        
      Case #ROW_UNDELETED
        ;responses: None
        AddText("#ROW_UNDELETED")
        
      Case #CELL_BEFORE_UPDATE
        ;responses: 0 = continue, 1 = cancel
        AddText("#CELL_BEFORE_UPDATE")
        
      Case #CELL_AFTER_UPDATE
        ;responses: None
        AddText("#CELL_AFTER_UPDATE")
        
      Case #ROW_BEFORE_SELECT
        ;responses: 0 = continue, 1 = cancel
        AddText("#ROW_BEFORE_SELECT")
        
      Case #GRID_RIGHT_CLICK
        ;responses: None
        AddText("#GRID_RIGHT_CLICK")
        
      Case #COMBO_FILL
        ;responses: None
        AddText("#COMBO_FILL")
        
    EndSelect
  Else
    ;Enable or disable menu items
    Select Msg
      Case #WM_INITMENUPOPUP
        If wParam = ghMenuEdit
          DisableMenuItem(gID_Undo, 1!CallFunction(#GridLib, "CanUndoRow", ghGrid))
          DisableMenuItem(gID_Field, 1!CallFunction(#GridLib, "CanUndoField", ghGrid))
          DisableMenuItem(gID_Row, 1!CallFunction(#GridLib, "CanUndoRow", ghGrid))
          DisableMenuItem(gID_UndeleteRow, 1!CallFunction(#GridLib, "CanUndeleteRow", ghGrid))
        EndIf
    EndSelect
  EndIf
  
  ProcedureReturn  Retval
EndProcedure

hMain = OpenWindow(#main, 0, 0, 640, 400, #PB_Window_SystemMenu|#PB_Window_MinimizeGadget|#PB_Window_MaximizeGadget|#PB_Window_SizeGadget|#PB_Window_ScreenCentered, "PureBasic SD DataGrid Demo")
If hMain
  SetWindowCallback(@MainWndProc())
  ;allow the grid to recieve tab messages
  RemoveKeyboardShortcut(0,#PB_Shortcut_Tab)
  RemoveKeyboardShortcut(0,#PB_Shortcut_Tab|#PB_Shortcut_Shift)
  
  hInst = GetWindowLong_(hMain, #GWL_HINSTANCE)

  If CreateMenu(0, WindowID(#main))
    MenuTitle("&File") 
      MenuItem(gID_Exit, "E&xit") 
    MenuTitle("&Edit")
      OpenSubMenu("&Undo")
        MenuItem(gID_Field, "&Field")
        MenuItem(gID_Row, "&Row")
        CloseSubMenu()
      MenuItem(gID_UndeleteRow, "Undelete &Row")
    MenuTitle("&Query")
      MenuItem(gID_Execute, "E&xecute")
  EndIf

  ;Get ID of Undo menu
  hMenu = GetMenu_(hMain)
  ghMenuEdit = GetSubMenu_(hMenu,1)
  gID_Undo = GetSubMenu_(ghMenuEdit,0)
  
  CtlHeight = WindowHeight()-MenuHeight()
  CreateGadgetList(WindowID(#main))
  ghEdit = EditorGadget(#edit1, 0, 0, 200, CtlHeight , #PB_Container_Raised)
  AddText("Grid Messages")
  
  If OpenLibrary(#GridLib, "SD_DataGrid_Demo.dll")
    ghGrid = CallFunction(#GridLib, "CreateGrid", hMain, hInst, #GRIDSTYLE_SUNKEN, #IDGRID1, 200, 0, WindowWidth()-200, CtlHeight)
    If ghGrid = 0
      MessageRequester("Error", "Could not Create Grid"+Chr(13)+"Ending program.",0)
      CleanupAndExit()
    EndIf
    
    Driver$ = "Microsoft Access Driver (*.MDB)"
    DbPath$ = "OrderEntry2.mdb"
    Uid$ = "": Pwd$ = ""
    connectstr$ = "Dbq="+DbPath$+";"+"Driver={"+Driver$+"};"+"Uid="+Uid$+";Pwd="+Pwd$
  
    If #False = Connect(connectstr$)
      MessageRequester("Database Error", "Database connection not available."+Chr(13)+"Ending program.",0)
      CleanupAndExit()
    EndIf
  Else
    MessageRequester("Error", "Could not locate SD_DataGrid_Demo.dll"+Chr(13)+"Ending program.", 0)
    CleanupAndExit()
  EndIf
  
  Repeat
    eventid = WaitWindowEvent()
    Select eventid
      Case #PB_Event_SizeWindow
        CtlHeight = WindowHeight()-MenuHeight()
        MoveWindow_(ghGrid, 200, 0, WindowWidth()-200, CtlHeight, 1)
        MoveWindow_(ghEdit, 0, 0, 200, CtlHeight, 1)
        
      Case #PB_Event_Menu
        Select EventMenuID()
          Case gID_Exit
            CleanupAndExit()
          Case gID_UndeleteRow
            CallFunction(#GridLib, "UndeleteRow", ghGrid)
          Case gID_Field
            CallFunction(#GridLib, "UndoField", ghGrid)
          Case gID_Row
            CallFunction(#GridLib, "UndoRow", ghGrid)
          Case gID_Execute
            SQL$ = "SELECT ProductID, PartNo, ProductDesc, UnitPrice FROM Products ORDER BY ProductDesc"
            QuerySelect(SQL$)
        EndSelect

      Case #PB_Event_CloseWindow
        Quit = #True
    EndSelect
  Until Quit
  CleanupAndExit()
EndIf
The PureBasic example above creates this application.

 

Liberty BASIC ODBC Example



'A simple application that demonstrates the ability of the odbcLoadRecordsetSQL function
'to execute a SELECT query, configure the grid, and display the results.

Nomainwin

Global SQL.ERROR, True, False, gGridLoaded, ghGrid, ghDBc, ghEnv, SQL$

SQL.ERROR = -1
True = 1: False = 0
IDGRID = 2105
GRIDSTYLE.SUNKEN = 2
database$ = "OrderEntry2.mdb"
SQL$ = "SELECT ProductID, PartNo, ProductDesc, UnitPrice FROM Products ORDER BY ProductDesc"

Struct Rc, _
  Left As Long, _
  Top As Long, _
  Right As Long, _
  Bottom As Long
  
  WindowWidth = 600
  WindowHeight = 400
  UpperLeftX=(DisplayWidth-WindowWidth)/2
  UpperLeftY=(DisplayHeight-WindowHeight)/2
  
  Menu #main, "&File", "E&xit", menu.quit
  Menu #main, "&Database", _
              "&Query", menuQuery, _
              |, _
              "Requery", menuRequery
    
  Open "SD DataGrid odbcLoadRecordsetSQL Demo" For Window As #main
  
  #main "trapclose quit"
  #main "resizehandler resize"
  hMain = Hwnd(#main)
  
  On Error Goto [ErrTrap]
  
  Open "SD_DataGrid_Demo.dll" For Dll As #SdDataGrid
  gGridLoaded = True
  
  Calldll #user32, "GetWindowLongA", hMain As Ulong, _GWL_HINSTANCE As Long, hInst As Ulong
  
  Calldll #SdDataGrid, "CreateGrid", hMain As Ulong, hInst As Ulong, _
    GRIDSTYLE.SUNKEN As Long, IDGRID As Long, _
    0 As Long, 0 As Long, 0 As Long, 0 As Long, ghGrid As Ulong

  'Optional:
  'Calldll #SdDataGrid, "ShowLineNumbers", ghGrid As Ulong, False As Long, r As Long
  
  Driver$ = "Microsoft Access Driver (*.MDB)"
  DbPath$ = DefaultDir$+"\"+database$
  Uid$ = "": Pwd$ = ""
  connectstr$ = "Dbq="+DbPath$+";"+"Driver={"+Driver$+"};"+"Uid="+Uid$+";Pwd="+Pwd$
  
  If Not(Connect(connectstr$)) Then
    Notice "Database Error"+cr$+"Database connection not available."+cr$+"Ending program."
    Call quit "#main"
  End If

  Call resize "#main"
  
  While 1 'application loop
    Scan
    Calldll #kernel32, "Sleep", 1 As Ulong, r As Void
  Wend

[ErrTrap]
  Notice Err$
  Call quit "#main"

Sub menu.quit
  Call quit "#main"
End Sub

Sub quit handle$
  If ghDBc > 0 Then
    'close database
    Calldll #SdDataGrid, "odbcDisconnect", ghDBc As Long, r As Long
    'free database
    Calldll #SdDataGrid, "odbcFreeDB", ghDBc As Long, r As Long
  End If
  'free environment
  If ghEnv > 0 Then Calldll #SdDataGrid, "odbcFreeEnv", ghEnv As Long, r As Long
  If ghGrid Then 
    Calldll #SdDataGrid, "FreeGrid", ghGrid As Ulong, r As Long
    Calldll #user32, "DestroyWindow", ghGrid As Ulong, r As Long
  End If
  Close #handle$
  If gGridLoaded Then Close #SdDataGrid
  End
End Sub

Sub resize handle$
  hWnd = Hwnd(#handle$)
  Calldll #user32, "GetClientRect", hWnd As Ulong, Rc As Struct, r As Long
  gridX2 = Rc.Right.struct
  gridY2 = Int(Rc.Bottom.struct) - 10
  Calldll #user32, "MoveWindow", ghGrid As Ulong, 0 As Long, 10 As Long, _
  gridX2 As Long, gridY2 As Long, 0 As Long, r As Long
End Sub

Function Connect(connstr$)
  Calldll #SdDataGrid, "odbcAllocEnv", ghEnv As Long
  If ghEnv = SQL.ERROR Then
    Call ODBCErrMsg$: Exit Function
  Else
    Calldll #SdDataGrid, "odbcConnect", ghEnv As Long, connstr$ As Ptr, ghDBc As Long
    If ghDBc = SQL.ERROR Then 
      Call ODBCErrMsg$: Exit Function
    End If
  End If
  Connect = True
End Function

Sub menuQuery
  Calldll #SdDataGrid, "odbcLoadRecordsetSQL", ghGrid As Ulong, ghDBc As Long, _
    SQL$ As Ptr, True As Long, hStmt As Long
  If hStmt <> SQL.ERROR Then
    Calldll #SdDataGrid, "odbcFreeStmt", hStmt As Long, ret As Long
    Calldll #SdDataGrid, "SetUndoBuffer", ghGrid As Ulong, r As Void
  Else
    Call ODBCErrMsg$
  End If
End Sub

Sub menuRequery
  'save grid display
  Calldll #SdDataGrid, "ViewGrid", ghGrid As Ulong, False As Long, r As Long
  Call menuQuery
  'restore grid display
  Calldll #SdDataGrid, "ViewGrid", ghGrid As Ulong, True As Long, r As Long
End Sub

Sub ODBCErrMsg$
  Calldll #SdDataGrid, "odbcGetErrCode", ercd As Long
  Calldll #SdDataGrid, "odbcGetErrMsg", pMsg As Long
  Notice "ODBC Err code: "; ercd; Chr$(13); Winstring(pMsg)
End Sub

The Liberty BASIC example above creates this application.

© Copyright 2004, 2005 Syberden.net. All rights reserved.