-
Jun 25th, 2022, 08:05 AM
#1
Thread Starter
PowerPoster
RC5 Sqlite Like Adodb.Connection/Adodb.RecordSet(WithOut Reg Com Dll)
Demo Down load
Rc5_Adodb.RecordSet.zip
it's also can change to [VB SQLite Library (COM-Wrapper)]
Minimum code to achieve the most commonly used functions
Code:
Sub TestSqliteComDll()
Dim Cnn As cConnection
Set Cnn = New_cConnection
MsgBox Cnn.Version
End Sub
Code:
Option Explicit
'免注册加载DLL-
''COM DLL可以放在当前目录或SysWOW64就能引用成功,
'C:\Windows\SysWOW64
'Set cn2 = CreateObjectXX("sqlite3.dll", ClsStr_Obj) '放在系统目录,可以不带路径
'Set cn2 = CreateObjectXX(ThisWorkbook.path & "\sqlite3.dll", ClsStr_Obj)
'DLL放在当前目录,要添加完整路径
Private Type UUID
d1 As Long
d2 As Integer
d3 As Integer
d4(7) As Byte
End Type
Private Declare Function CLSIDFromString Lib "ole32" (ByVal str As Long, id As UUID) As Long
Private Declare Function IIDFromString Lib "ole32" (ByVal str As Long, id As UUID) As Long
Private Declare Function DispCallFunc Lib "oleaut32.dll" (ByVal pvInstance As Long, ByVal offsetinVft As Long, ByVal CallConv As Long, ByVal retTYP As Integer, ByVal paCNT As Long, ByRef paTypes As Integer, ByRef paValues As Long, ByRef retVAR As Variant) As Long
Private Declare Function GetProcAddress Lib "kernel32.dll" (ByVal hModule As Long, ByVal lpProcName As String) As Long
Private Declare Function LoadLibrary Lib "kernel32.dll" Alias "LoadLibraryA" (ByVal lpLibFileName As String) As Long
Private Declare Function FreeLibrary Lib "kernel32" (ByVal hLibModule As Long) As Long
Function New_cRecordset() As cRecordset
Set New_cRecordset = CreateObjectXX(App.Path & "\dhRichClient3.dll", _
"{351A3F14-5448-40A6-8E25-1F55A2CF989D}")
End Function
Function New_cConnection() As cConnection
Set New_cConnection = CreateObjectXX(App.Path & "\dhRichClient3.dll", _
"{6B16C696-FB30-42CE-827C-090956209CEC}")
End Function
Function CreateObjectXX(DllFileName As String, sCLSID As String, Optional ForIID_IDispatch As Boolean, Optional H As Long) As Object
'先声明对象真实类型才可以免注册加载COM DLL
Const sIID_IClassFactory As String = "{00000001-0000-0000-C000-000000000046}"
Const sIID_IDispatch As String = "{00020400-0000-0000-C000-000000000046}"
Const sIID_IUnknown As String = "{00000000-0000-0000-C000-000000000046}"
Dim lCLSID As UUID, IID_IClassFactory As UUID, IID_IDispatch As UUID, IID_IUnknown As UUID
Dim lOle As Object, fo As Object
Dim FUNC As Long, ret As Variant, ty(2) As Integer, pm(2) As Long, vParams(2) As Variant
IIDFromString StrPtr(sIID_IClassFactory), IID_IClassFactory
IIDFromString StrPtr(sIID_IDispatch), IID_IDispatch
IIDFromString StrPtr(sIID_IUnknown), IID_IUnknown
CLSIDFromString StrPtr(sCLSID), lCLSID
H = LoadLibrary(DllFileName)
FUNC = GetProcAddress(H, "DllGetClassObject")
ty(0) = vbLong
ty(1) = vbLong
ty(2) = vbObject
vParams(0) = VarPtr(lCLSID)
vParams(1) = VarPtr(IID_IClassFactory)
vParams(2) = VarPtr(fo)
pm(0) = VarPtr(vParams(0))
pm(1) = VarPtr(vParams(1))
pm(2) = VarPtr(vParams(2))
Dim l As Long
l = DispCallFunc(0&, FUNC, 4, vbObject, 3, ty(0), pm(0), ret)
' DispCallFunc ObjPtr(fo), 32, 1, vbLong, 0, 0, 0, ret
If fo Is Nothing Then Exit Function
vParams(0) = 0&
If ForIID_IDispatch Then
vParams(1) = VarPtr(IID_IDispatch) '一般的COM DLL可以用这个
Else
vParams(1) = VarPtr(IID_IUnknown) ' tlbinf32.dll只能用这个(默认就用这种方法)
End If
vParams(2) = VarPtr(lOle)
DispCallFunc ObjPtr(fo), 12&, 4, vbObject, 3, ty(0), pm(0), ret
Set CreateObjectXX = lOle
Set fo = Nothing
Set lOle = Nothing
End Function
Self writing class connection and recordset, instead of adodb For objects such as recordset, only 12 interfaces (or methods) need to be implemented for normal mode calls.
Four interfaces of connection: createnewdb, opendb, execute, openrecordset
8 interfaces of recordset: openrecordset, get item (let item), addnew, updatebatch, RecordCount, EOF, MoveNext
===================
Connection.CLS
Code:
Option Explicit
Public cConnectionA As cConnection
'cConnection={6B16C696-FB30-42CE-827C-090956209CEC}
Public State As Long
Private Sub Class_Initialize()
'Set cConnectionA = New cConnection
Set cConnectionA = CreateObjectXX(App.Path & "\dhRichClient3.dll", _
"{6B16C696-FB30-42CE-827C-090956209CEC}")
End Sub
Sub CreateNewDB(dBFile As String)
cConnectionA.CreateNewDB dBFile
End Sub
Sub OpenDB(dBFile As String)
On Error Resume Next
cConnectionA.OpenDB dBFile
If Err.Number = 0 Then
State = 1
End If
End Sub
Sub Execute(Sql As String)
cConnectionA.Execute Sql
End Sub
Function OpenRecordset(Sql As String) As Variant ' cRecordset
Set OpenRecordset = cConnectionA.OpenRecordset(Sql)
End Function
Private Sub Class_Terminate()
Set cConnectionA = Nothing
End Sub
============
Recordset.CLS
Code:
Option Explicit
Dim cRecordset1 As cRecordset
'cRecordset={351A3F14-5448-40A6-8E25-1F55A2CF989D}
'.open变成OpenRecordset
' New ADODB.Recordset变成=new cRecordset2
'= CreateObject("adodb.recordset")变成=new cRecordset2
'.update变成.UpdateBatch
'取消RS.Close
Private Sub Class_Initialize()
'Set cRecordset1 = New cRecordset
Set cRecordset1 = CreateObjectXX(App.Path & "\dhRichClient3.dll", _
"{351A3F14-5448-40A6-8E25-1F55A2CF989D}")
End Sub
Public Sub OpenRecordset(Sql As String, Cnn As Connection, Optional ReadOnly As Boolean, Optional b)
'Sub OpenRecordset([SQL As String], [Cnn], [ReadOnly As Boolean])
Call cRecordset1.OpenRecordset(Sql, Cnn.cConnectionA)
End Sub
Public Property Get Item(Field As Variant) As Variant
Item = cRecordset1(Field)
End Property
Public Property Let Item(Field As Variant, ByVal vNewValue As Variant)
cRecordset1(Field) = vNewValue
End Property
Sub AddNew()
cRecordset1.AddNew
End Sub
Sub UpdateBatch()
cRecordset1.UpdateBatch
End Sub
Public Property Get RecordCount() As Long
RecordCount = cRecordset1.RecordCount
End Property
Public Property Get EOF() As Boolean
EOF = cRecordset1.EOF
End Property
Sub MoveNext()
cRecordset1.MoveNext
End Sub
Private Sub Class_Terminate()
Set cRecordset1 = Nothing
End Sub
Last edited by xiaoyao; Jun 29th, 2022 at 04:44 PM.
-
Jun 25th, 2022, 08:07 AM
#2
Thread Starter
PowerPoster
Re: RC5 Sqlite Like Adodb.Connection/Adodb.RecordSet(WithOut Reg Com Dll)
Code:
Dim RS As cRecordset
Set RS = New_cRecordset
RS.OpenRecordset "select top 1 * from WxMyFenSi where FSuserid='13647' and FSBgFg=54 ", Cnn
If RS.EOF Then
RS.AddNew
RS("FSuserid") = "13647"
Else
RS.AddNew
RS("FSuserid") = InputBox("", "New User", "user" & Timer)
End If
RS("FSBgFg") = 54
RS("FSopenid") = "x23"
RS("FSnickname") = "1111"
RS("FSremark") = Now()
RS("MI") = "123"
RS.UpdateBatch
'RS.Close
Set RS = Nothing
-
Jun 26th, 2022, 01:00 PM
#3
Re: RC5 Sqlite Like Adodb.Connection/Adodb.RecordSet(WithOut Reg Com Dll)
I strongly suggest, to use the "officially recommended version" of regfree loading with RC-Dlls,
which is the following (to be placed in a true "drop-in *.bas module):
Code:
Option Explicit
Private Declare Function LoadLibraryW Lib "kernel32" (ByVal lpLibFileName As Long) As Long
Private Declare Function GetInstanceEx Lib "DirectCOM" (spFName As Long, spClassName As Long, Optional ByVal UseAlteredSearchPath As Boolean = True) As Object
Private Const DirectComDllRelPath = "\Bin\DirectCOM.dll", RCDllRelPath = "\Bin\RC6.dll"
Public Property Get New_c() As cConstructor
Static st_RC As cConstructor
If st_RC Is Nothing Then
If App.LogMode Then 'we run compiled - and try to ensure regfree instantiation from \Bin\
On Error Resume Next
LoadLibraryW StrPtr(App.Path & DirectComDllRelPath)
Set st_RC = GetInstanceEx(StrPtr(App.Path & RCDllRelPath), StrPtr("cConstructor"))
If st_RC Is Nothing Then MsgBox "Couldn't load regfree, will try with a registered version next..."
On Error GoTo 0
End If
If st_RC Is Nothing Then Set st_RC = cGlobal.New_c 'fall back to loading a registered version
End If
Set New_c = st_RC
End Property
Public Property Get Cairo() As cCairo
Static st_CR As cCairo
If st_CR Is Nothing Then Set st_CR = New_c.Cairo
Set Cairo = st_CR
End Property
As said, when placed in a *.bas-Module (e.g. named and saved as 'modRCRegfree.bas'),
the above will act like a true drop-in, which will not require any further code-adaptions on your end (not even Sub Main() is needed).
All you have to do, to ship your RC-dependent App regfree (after putting this module in + recompiling your Exe - is):
- put a \Bin\-SubFolder into the same directory which contains your Executable (e.g. MyApp.exe)
- place copies of all Dll-Files of the RC5 or RC6 package in that \Bin\-SubFolder ...
... (from the place, where your registered version resides)
- double-check the Private Const-line in the above module-code and adjust the Paths if necessary...
... (when your Project references vbRichClient5, change the red-marked RC6-string-part of that Const-line to: vbRichClient5)
But that's it.
Since any RC-Object can be derived from either New_c or Cairo -
(no matter if you need an SQLite-Connection, or Rs... or CairoDrawing-Objects) -
the two above *.bas-module Properties are entirely sufficient to ensure that your App will work without registration.
HTH
Olaf
Last edited by Schmidt; Jun 26th, 2022 at 01:04 PM.
-
Jun 29th, 2022, 11:17 AM
#4
Thread Starter
PowerPoster
Re: RC5 Sqlite Like Adodb.Connection/Adodb.RecordSet(WithOut Reg Com Dll)
Can rc5.dll add an API export of'getinstanceex'stdcall?
LIKE GetInstanceEx Lib "vbRichClient5.DLL" ?
I just want to use the SQLite database. As a result, three DLLs (vb\u cairo\u sqlite.dll, vbrichclient5.dll, directcom.dll) are required. The hard disk occupies a large space and has a large number of files, which is inconvenient.
SQLite with ODBC driver needs to install and register drivers and DLLs, which requires administrator permissions and is troublesome.
I heard that MySQL also has a way to call or use ODBC driver with only a DLL.
If sqlit3 DLL source code is directly compiled into a com DLL, which becomes a CRecordset, and the encapsulation of cconnection is perfect.
Or directly packaged as adodb Interfaces such as recordset.
Or just one sqlite3 DLL (called by cdecl or stdcall), and then write a module in VB6 to package it into two classes: recordset and connection, which is the most convenient.
This method supports various versions of sqlite DLL. The earlier version takes up less space. The latest version has complete functions and fewer bugs.
Last edited by xiaoyao; Jun 29th, 2022 at 01:20 PM.
-
Jun 29th, 2022, 01:15 PM
#5
Thread Starter
PowerPoster
Re: RC5 Sqlite Like Adodb.Connection/Adodb.RecordSet(WithOut Reg Com Dll)
For the processing of many interfaces or methods, add error handling to each process, and the amount of code will be large. Use general processes and error handling methods to reduce the amount of code.
Code:
Function delete() As Boolean: delete = DoAction("Delete", "Delete Recordset"): End Function
Function AddNew() As Boolean: AddNew = DoAction("AddNew"): End Function
Function UpdateBatch() As Boolean: UpdateBatch = DoAction("UpdateBatch", "Update Datas"): End Function
Function DoAction(ActionName As String, Optional ErrTip As String) As Boolean
On Error GoTo Err
Select Case ActionName
Case "Delete"
cRecordset1.delete
Case "AddNew"
cRecordset1.AddNew
Case "UpdateBatch"
cRecordset1.UpdateBatch
End Select
DoAction = True
Exit Function
Err:
DoErr IIf(ErrTip <> "", ErrTip, ActionName)
End Function
in test2.bas:
Code:
Public ErrDescription As String, ErrNumber As Long
Public ShowErr As Boolean
Sub DoErr(Optional ActionName As String)
ErrNumber = Err.Number
ErrDescription = Err.Description
If ShowErr Then MsgBox IIf(ActionName <> "", "Do Action:" & ActionName & " ", "") & "Err:" & ErrNumber & "," & ErrDescription
End Sub
Code:
Function Delete() As Boolean
On Error GoTo Err
cRecordset1.Delete
Delete = True
Exit Function
Err:
DoErr "Delete RecordSet"
End Function
Function AddNew() As Boolean
On Error GoTo Err
cRecordset1.AddNew
AddNew = True
Exit Function
Err:
DoErr "RecordSet AddNew"
End Function
Function UpdateBatch() As Boolean
On Error GoTo Err
cRecordset1.UpdateBatch
UpdateBatch = True
Exit Function
Err:
DoErr "RecordSet UpdateBatch"
End Function
-
Jun 29th, 2022, 01:58 PM
#6
Thread Starter
PowerPoster
Re: RC5 Sqlite Like Adodb.Connection/Adodb.RecordSet(WithOut Reg Com Dll)
can't find cGlobal.New_c in dhRichClient3.dll?
rc5:
Code:
MsgBox Conn.Version
Public Property Get Conn() As cConnection
Static st_CR As cConnection
If st_CR Is Nothing Then Set st_CR = New_c.Connection
Set Conn = st_CR
End Property
Last edited by xiaoyao; Jun 29th, 2022 at 02:01 PM.
-
Jun 29th, 2022, 02:25 PM
#7
Re: RC5 Sqlite Like Adodb.Connection/Adodb.RecordSet(WithOut Reg Com Dll)
Originally Posted by xiaoyao
can't find cGlobal.New_c in dhRichClient3.dll?
As already explained in another thread - using the age-old dhRichClient3 will only save you:
- about 2MB on disk (compared to the vbRichClient5-package)
- about 3MB on disk (compared to the RC6-package)
Hint:
Just delete the last 2GB *.mp4-videofile you've downloaded from some weird corner of the internet,
to make room for about 1000 RC5-packages or 600 RC6 ones...
Really, ... your "FileSize-concerns" are so far fetched... it's ridiculous.
Olaf
-
Jun 29th, 2022, 02:50 PM
#8
Re: RC5 Sqlite Like Adodb.Connection/Adodb.RecordSet(WithOut Reg Com Dll)
-
Jun 29th, 2022, 03:40 PM
#9
Thread Starter
PowerPoster
Re: RC5 Sqlite Like Adodb.Connection/Adodb.RecordSet(WithOut Reg Com Dll)
Because a friend has made a browser plug-in that needs to be run on different operating systems, the program is required to occupy less hard disk space as much as possible to prevent false positives of anti-virus software. Many users only have guess permission on their computers, can not register com DLLs, and can not run exe with administrator permission
For example, use a Google kernel browser control, some 3M, some 20m, and some 200-500m.
Sometimes it is only used as a web page interface to replace Windows Forms.
Sometimes it is used to display some web pages, and sometimes it needs to display advanced functions such as video 3D.
Therefore, different versions and different hard disk sizes have an impact.
Changing three DLLs into one and 8m into 800K will have little impact on the operation, but the latest version of COM DLLs cannot be registered on some win7 systems and may not be loaded without registration. RC5 some windows system APIs do not exist in the old version of the operating system, resulting in the failure to load the DLL and the failure to register and run the com DLL. So the old version has its applicable scenarios
-
Jun 29th, 2022, 03:49 PM
#10
Thread Starter
PowerPoster
Re: RC5 Sqlite Like Adodb.Connection/Adodb.RecordSet(WithOut Reg Com Dll)
Originally Posted by Arnoutdv
The compilation fails, and there is a lot of code. It is difficult and takes a lot of time to successfully apply.
Sometimes, some lightweight versions are needed to implement the simplest query, reading and modification.
Such as reading data
A=rs ("field 1") value
B=rs ("field 2") value
Modify field value
RS ("field 1") = "A1"
RS ("field 2") = "TTT"
-
Jun 29th, 2022, 04:26 PM
#11
Thread Starter
PowerPoster
Re: RC5 Sqlite Like Adodb.Connection/Adodb.RecordSet(WithOut Reg Com Dll)
RC5 cConstructor GUID={CAECC935-9C70-4176-8BED-C39B2E33B31F}
'RC5 cConnection GUID={E71C0E12-8F07-40DF-87E9-82775B8E22B9}
'RC5 cRecordSet GUID={1305534D-72BC-4D88-9C24-14FAC8327C01}
Code:
Function New_cRecordset() As cRecordset
Set New_cRecordset =CreateObjectXX(App.Path & "\vbRichClient5.dll", _
"{1305534D-72BC-4D88-9C24-14FAC8327C01}"
End Function
Function New_cConnection() As cConnection
Set New_cConnection= CreateObjectXX(App.Path & "\vbRichClient5.dll", _
"{E71C0E12-8F07-40DF-87E9-82775B8E22B9}")
End Function
-
Jun 29th, 2022, 04:30 PM
#12
Thread Starter
PowerPoster
Re: RC5 Sqlite Like Adodb.Connection/Adodb.RecordSet(WithOut Reg Com Dll)
Code:
Public Property Get New_c() As cConstructor ' cConstructor
Static st_RC As cConstructor
If st_RC Is Nothing Then
Set st_RC = CreateObjectXX(App.Path & "\vbRichClient5.dll", _
"{CAECC935-9C70-4176-8BED-C39B2E33B31F}")
End If
Set New_c = st_RC
End Property
Function New_cRecordset() As cRecordset
Set New_cRecordset =New_c.Recordset
End Function
Function New_cConnection() As cConnection
Set New_cConnection=New_c.Connection
End Function
Posting Permissions
- You may not post new threads
- You may not post replies
- You may not post attachments
- You may not edit your posts
-
Forum Rules
|
Click Here to Expand Forum to Full Width
|