本帖最后由 kk_lee69 于 2018-4-1 23:48 编辑
关于listview虚表直接读取数据库的方法,求助修改范例成SQL的!!
官网有个范例 是listview虚表 直接拿SQLlite 的数据库 当作 listview虚表的数据 直接使用,这样的好处是 即使你的数据再多 也是分次 读取 就不会卡了
无奈 小弟 对于 SQLLITE的 UDF 实在没辙,我研究了半天 总是搞不懂原理
无法改成 把SQL DB 当作数据库来源的方法 ,所以上来求助
listview虚表 我已经很熟了 所以理论上不应该是我不会使用,只是以前的方法都是读进
数组 然后 利用数组 当作listview虚表 的数据源
只是最近遇到了 数据太多 读进数组太慢 想要改成 分次读取 分次秀出的方法
所以才把脑筋动到了 数据库上……
以下是 范例程序 与 数据库 麻烦 高手帮我改个范例
資料庫檔案如下:
或者 也可以利用 下面的檔案 建立資料庫
範例程式如下:
#include <GUIConstants.au3>
#include <WindowsConstants.au3>
#include <GuiListView.au3>
#include <SQLite.au3>
Opt( "MustDeclareVars", 1 )
Global Const $tagNMLVCACHEHINT = $tagNMHDR & ";int iFrom;int iTo"
Global $hLV
Example()
Func Example()
_SQLite_Startup()
; Check databases
Local $iRows1 = CheckDB( "Test1.db" )
Local $iRows2 = CheckDB( "Test2.db" )
Local $iRows3 = CheckDB( "Test3.db" )
Local $iRows
; Create GUI
GUICreate( "Virtual ListViews", 850, 400 )
; Create Tab
Local $idTab = GUICtrlCreateTab( 10, 10, 850-20, 400-20 )
GUICtrlCreateTabItem( "Test1.db: " & Format( $iRows1 ) & " rows" )
GUICtrlCreateTabItem( "Test2.db: " & Format( $iRows2 ) & " rows" )
GUICtrlCreateTabItem( "Test3.db: " & Format( $iRows3 ) & " rows" )
GUICtrlCreateTabItem( "" )
; Create ListView
Local $idLV = GUICtrlCreateListView( "", 20, 40, 850-40, 400-60, $LVS_OWNERDATA, BitOR( $WS_EX_CLIENTEDGE, $LVS_EX_DOUBLEBUFFER, $LVS_EX_FULLROWSELECT ) )
$hLV = GUICtrlGetHandle( $idLV ) ; Virtual listview Reduces flicker
For $i = 0 To 9
_GUICtrlListView_AddColumn( $hLV, "Col" & $i, 75 )
Next
GUIRegisterMsg( $WM_NOTIFY, "WM_NOTIFY" )
GUISetState( @SW_SHOW )
; Data for first tab
$iRows = $iRows1
If $iRows Then _SQLite_Open( "Test1.db" )
GUICtrlSendMsg( $idLV, $LVM_SETITEMCOUNT, $iRows, 0 )
; Message loop
While 1
Switch GUIGetMsg()
Case $idTab
If $iRows Then _SQLite_Close( -1 )
Switch GUICtrlRead( $idTab )
Case 0
$iRows = $iRows1
If $iRows Then _SQLite_Open( "Test1.db" )
Case 1
$iRows = $iRows2
If $iRows Then _SQLite_Open( "Test2.db" )
Case 2
$iRows = $iRows3
If $iRows Then _SQLite_Open( "Test3.db" )
EndSwitch
GUICtrlSendMsg( $idLV, $LVM_SETITEMCOUNT, $iRows, 0 )
Case $GUI_EVENT_CLOSE
ExitLoop
EndSwitch
WEnd
If $iRows Then _SQLite_Close( -1 )
_SQLite_Shutdown()
GUIDelete()
EndFunc
Func WM_NOTIFY( $hWnd, $iMsg, $wParam, $lParam )
Local Static $tText = DllStructCreate( "wchar[50]" )
Local Static $pText = DllStructGetPtr( $tText )
Local Static $aResult, $iRows, $iFrom
Local $tNMHDR, $hWndFrom, $iCode
$tNMHDR = DllStructCreate( $tagNMHDR, $lParam )
$hWndFrom = HWnd( DllStructGetData( $tNMHDR, "hWndFrom" ) )
$iCode = DllStructGetData( $tNMHDR, "Code" )
Switch $hWndFrom
Case $hLV
Switch $iCode
Case $LVN_GETDISPINFOW
Local $tNMLVDISPINFO = DllStructCreate( $tagNMLVDISPINFO, $lParam )
If BitAND( DllStructGetData( $tNMLVDISPINFO, "Mask" ), $LVIF_TEXT ) Then
Local $iIndex = DllStructGetData( $tNMLVDISPINFO, "Item" ) - $iFrom + 1
If $iIndex > 0 And $iIndex < $iRows + 1 Then
Local $sItem = $aResult[$iIndex][DllStructGetData($tNMLVDISPINFO,"SubItem")]
DllStructSetData( $tText, 1, $sItem )
DllStructSetData( $tNMLVDISPINFO, "Text", $pText )
DllStructSetData( $tNMLVDISPINFO, "TextMax", StringLen( $sItem ) )
EndIf
EndIf
Case $LVN_ODCACHEHINT
Local $tNMLVCACHEHINT = DllStructCreate( $tagNMLVCACHEHINT, $lParam ), $iColumns
$iFrom = DllStructGetData( $tNMLVCACHEHINT, "iFrom" )
Local $sSQL = "SELECT * FROM lvdata WHERE item_id >= " & $iFrom & _
" AND item_id <= " & DllStructGetData( $tNMLVCACHEHINT, "iTo" ) & ";"
_SQLite_GetTable2d( -1, $sSQL, $aResult, $iRows, $iColumns )
EndSwitch
EndSwitch
Return $GUI_RUNDEFMSG
EndFunc
Func CheckDB( $sDBname )
Local $aRow, $iRows = 0
If FileExists( $sDBname ) Then
_SQLite_Open( $sDBname )
_SQLite_QuerySingleRow( -1, "SELECT max(item_id) FROM lvdata;", $aRow )
_SQLite_Close( -1 )
EndIf
If IsArray( $aRow ) Then _
$iRows = $aRow[0] + 1
Return $iRows
EndFunc
Func Format( $iInt )
Return StringRegExpReplace( $iInt, "(\A\d{1,3}(?=(\d{3})+\z)|\d{3}(?=\d))", "\1," )
EndFunc
|