WinInc ADO Sample

About

A WinInc sample reading a database by using ADO. The rows which have been read are displayed on the console screen.

ScreenShot

Source Code

ADO1.ASM
;*** sample for db access with ADO
;*** MDAC 2.6 has to be installed

        .386
        .MODEL FLAT,stdcall
        option casemap:none
        option proc:private


        .nolist
        .nocref
WIN32_LEAN_AND_MEAN equ 1
INC_OLE2            equ 1
        include windows.inc
        include windowsx.inc

;-- ADOFields and ADOField are *not*  defined in ADOINT.INC 
;-- so define them here *before* including ADOINT.INC

ADOFields   equ 
ADOField    equ 

        include adoint.inc
        .list
        .cref

?FILEDSN    equ 0       ;1=use FileDSN

sCLSID_Recordset textequ 
sIID__Recordset textequ 
;sCLSID_Command textequ 

IDD_DIALOG1 equ 101
IDC_LIST1   equ 1000
IDC_REFRESH equ 1001
IDC_CLEAR   equ 1002

        .const

;--- define the GUIDS used by the app

CLSID_Recordset  sCLSID_Recordset
IID_Recordset    sIID__Recordset

if ?FILEDSN
szFmtFileDSN    db "File Name=%s\db1.dsn",0
else
szFmtAccDB      db "Provider=Microsoft.Jet.OLEDB.4.0;Data Source=%s\DB1.MDB",0
endif

        align 4
        
wszSQLStatement dw L("Select Name,Sector from Shares"),0

CStr macro pszText:REQ
local xxx
    .const
xxx db pszText,0
    .code
    exitm 
endm

        .code

;--- get path of executable

GetModulePath proc pStrOut:ptr byte, iMax:dword
    invoke GetModuleFileName, NULL, pStrOut, iMax
    mov ecx,pStrOut
    .while (eax)
        .if (byte ptr [eax+ecx] == '\')
            mov byte ptr [eax+ecx],0
            .break
        .endif
        dec eax
    .endw
    ret 
GetModulePath endp

;--- read data from database into listbox 

ReadData proc uses esi hWnd:HWND

local vtSource:VARIANT
local vtActiveConnection:VARIANT
local vtTemp:VARIANT
local hWndLB:HWND
local hr:DWORD
local pCo:ptr Connection
local pCmd:ptr Command
local pRS:ptr ADORecordset
local pFs:ptr ADOFields
local pF:ptr ADOField
local vbTemp:VARIANT_BOOL
local szPath[MAX_PATH]:byte
local szDSN[MAX_PATH]:byte
local szText[256]:byte
local szFld1[80]:byte
local szFld2[80]:byte

    invoke GetDlgItem, hWnd, IDC_LIST1
    mov hWndLB,eax

    lea eax,vtTemp
    invoke VariantInit, eax
    lea eax,vtSource
    invoke VariantInit, eax
    lea eax,vtActiveConnection
    invoke VariantInit, eax

;--------------------------------- create recordset
    invoke CoCreateInstance, addr CLSID_Recordset, 0, CLSCTX_INPROC_SERVER, addr IID_Recordset, addr pRS
    .if (eax != S_OK)
        invoke MessageBox, hWnd, CStr("CoCreateInstance(Recordset) failed"), 0, MB_OK
        xor eax,eax
        ret
    .endif

    invoke GetModulePath, addr szPath, sizeof szPath
if ?FILEDSN
;--------------------------------- create fully qualified path for DB1.DSN
    invoke wsprintf, addr szDSN, addr szFmtFileDSN, addr szPath
else
;--------------------------------- create fully qualified path for DB1.MDB
    invoke wsprintf, addr szDSN, addr szFmtAccDB, addr szPath
endif

;--------------------------------- transform FileDSN to a BSTR
;--------------------------------- all BSTRs transfered to ADO must be
;--------------------------------- dynamically allocated using SysAllocString.
;--------------------------------- dont use static allocated wide strings

    invoke SysAllocStringLen, NULL, eax
    .if (!eax)
        ret
    .endif
    mov vtActiveConnection.bstrVal,eax
    mov vtActiveConnection.vt,VT_BSTR
    invoke MultiByteToWideChar, CP_ACP, 0, addr szDSN, -1, eax, MAX_PATH

;--------------------------------- transform SQL statement to BSTR
    invoke SysAllocString, addr wszSQLStatement
    .if (!eax)
        ret
    .endif
    mov vtSource.bstrVal,eax
    mov vtSource.vt,VT_BSTR

;--------------------------------- open recordset
;--------------------------------- supply connection data with Recordset::Open
    invoke vf(pRS, %ADORecordset, Open), vtSource, vtActiveConnection, \
            adOpenForwardOnly, adLockReadOnly, adCmdText

    .if (eax != S_OK)
        mov hr,eax
        invoke wsprintf, addr szText, CStr("Recordset::Open failed [%X]"), hr
        invoke MessageBox, hWnd, addr szText, 0, MB_OK
        invoke vf(pRS, %ADORecordset, Release)
        ret
    .endif

    xor esi,esi
    .while (1)
;--------------------------------- check for EOF 
        invoke vf(pRS, %ADORecordset, get_EOF),addr vbTemp
        movsx eax,vbTemp
        .break .if (eax)
        mov szFld1,0
        mov szFld2,0
;--------------------------------- get fields collection
        invoke vf(pRS, %ADORecordset, get_Fields), addr pFs
        .if (eax == S_OK)

;--------------------------------- get first field into szFld1
            mov vtTemp.vt,VT_I4
            mov vtTemp.lVal,0
            invoke vf(pFs, %ADOFields, get_Item), vtTemp, addr pF
            .if (eax == S_OK)
                invoke vf(pF, %ADOField, get_Value), addr vtTemp
                .if (vtTemp.vt == VT_BSTR)
                    invoke WideCharToMultiByte, CP_ACP, 0, \
                        vtTemp.bstrVal, -1, addr szFld1, sizeof szFld1, NULL, NULL
                    invoke SysFreeString, vtTemp.bstrVal
                .endif
                invoke vf(pF, %ADOField, Release)
            .endif

;--------------------------------- get second field into szFld2
            mov vtTemp.vt,VT_I4
            mov vtTemp.lVal,1
            invoke vf(pFs, %ADOFields, get_Item), vtTemp, addr pF
            .if (eax == S_OK)
                invoke vf(pF, %ADOField, get_Value), addr vtTemp
                .if (vtTemp.vt == VT_BSTR)
                    invoke WideCharToMultiByte, CP_ACP, 0, \
                        vtTemp.bstrVal, -1, addr szFld2, sizeof szFld2, NULL, NULL
                    invoke SysFreeString, vtTemp.bstrVal
                .endif
                invoke vf(pF, %ADOField, Release)
            .endif

            invoke vf(pFs, %ADOFields, Release)
        .endif

        inc esi
        invoke wsprintf, addr szText, CStr("%u., %s, %s"), esi, addr szFld1, addr szFld2
        invoke ListBox_AddString( hWndLB, addr szText)

;--------------------------------- move cursor to next row
        invoke vf(pRS, %ADORecordset, MoveNext)
        .break .if (eax != S_OK)
    .endw
;--------------------------------- clean up
    invoke vf(pRS, %ADORecordset, Close)
    invoke vf(pRS, %ADORecordset, Release)
    ret
ReadData endp


dlgproc proc hWnd:HWND, message:DWORD, wParam:WPARAM, lParam:LPARAM

        mov eax,message
        .if (eax == WM_INITDIALOG)
            mov eax,1
        .elseif (eax == WM_CLOSE)
            invoke EndDialog, hWnd, 0
        .elseif (eax == WM_COMMAND)
            movzx eax,word ptr wParam+0
            .if (eax == IDCANCEL)
                invoke EndDialog, hWnd, 0
            .elseif (eax == IDC_CLEAR)
                invoke GetDlgItem, hWnd, IDC_LIST1
                invoke ListBox_ResetContent( eax)
            .elseif (eax == IDC_REFRESH)
                invoke ReadData, hWnd
            .endif
            xor eax,eax
        .else
            xor eax,eax
        .endif
        ret
dlgproc endp

WinMain proc hInstance:HINSTANCE, hPrecInst:HINSTANCE, lpszCmdLine:LPSTR, iCmdShow:DWORD

    invoke CoInitialize, 0
    invoke DialogBoxParam, hInstance, IDD_DIALOG1, 0, dlgproc, 0
    invoke CoUninitialize
    xor eax,eax
    ret

WinMain endp

WinMainCRTStartup   proc public
    invoke GetModuleHandle,0
    invoke WinMain, eax, 0, 0, 0
    invoke ExitProcess, eax
WinMainCRTStartup   endp

end
 

RSRC.RC
#include "resource.h"
#include "rsrc.h"

IDD_DIALOG1 DIALOG DISCARDABLE  0, 0, 268, 189
STYLE DS_MODALFRAME | DS_CENTER | WS_POPUP | WS_CAPTION | WS_SYSMENU
CAPTION "ADO Sample"
FONT 8, "MS Sans Serif"
BEGIN
    PUSHBUTTON      "E&xit",IDCANCEL,175,168,50,14
    LISTBOX         IDC_LIST1,7,7,254,153,LBS_NOINTEGRALHEIGHT | WS_VSCROLL | 
                    WS_TABSTOP
    PUSHBUTTON      "&Read DB",IDC_REFRESH,43,168,50,14
    PUSHBUTTON      "&Clear",IDC_CLEAR,109,168,50,14
END