一個好用的DBGRID----VC數(shù)據(jù)庫開發(fā)之二.doc_第1頁
一個好用的DBGRID----VC數(shù)據(jù)庫開發(fā)之二.doc_第2頁
一個好用的DBGRID----VC數(shù)據(jù)庫開發(fā)之二.doc_第3頁
一個好用的DBGRID----VC數(shù)據(jù)庫開發(fā)之二.doc_第4頁
一個好用的DBGRID----VC數(shù)據(jù)庫開發(fā)之二.doc_第5頁
已閱讀5頁,還剩1頁未讀 繼續(xù)免費閱讀

下載本文檔

版權說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權,請進行舉報或認領

文檔簡介

一個好用的DBGRID-VC數(shù)據(jù)庫開發(fā)之二陳松樂一、引言在用vc開發(fā)關于數(shù)據(jù)庫的項目時,通常我們只好用微軟的DBGRID作為數(shù)據(jù)庫表格控件,其實微軟的DBGRID并不好用,想找一份好的幫助文檔都找不到,并且界面并不友好,比起C+Builder中的DBGRID來說是遜色不少,但是DBGRID在開發(fā)數(shù)據(jù)庫的項目中又是常用的控件,所以就一直想找一個好用的DBGRID,可是網(wǎng)上又沒有找到。上次在無意中看到了CGridCtrl(一個很漂亮的表格控件,如果你還沒有用過,可以到/miscctrl/gridctrl.asp/下載,上面還有詳細的使用說明)支持虛模式,在這種模式下,即使你向這個表格插入一百萬條數(shù)據(jù),它并不會真的生成一百萬行,而是隨著你的滾動條的滾動,計算出在屏幕上要顯示的行和列,然后會向你提供一個接口,通過這個接口,你可以在這兒設置你要顯示的數(shù)據(jù)。這給了我一些啟示,我決定用它來做一個DBGRID。下面的例子是它的一個應用。點擊這里下載demo2(/注:請編者在這里聯(lián)接上例子demo2)二、原理DBGRID和一般的GRID的不同之處在于,一般的GRID并不適合顯示大的數(shù)據(jù)量,如果你的一個查詢結果有上萬條記錄的話,如果你都要插入到GRID中,這將是一個很慢的過程,并且你在GRID中移動滾動條的話,它的記錄的滾動也是很慢的,而DBGRID并不會真正把這些記錄的數(shù)據(jù)全部插入到控件中,當DBGRID的滾動條滾動時,它會根據(jù)DBGRID的顯示面積的大小和查詢得到的總的記錄數(shù)計算出當前應該顯示哪那些行,然后會把那幾行的記錄數(shù)據(jù)插入到表格中,這樣速度當然是很快的,而且沒有數(shù)據(jù)量多少的限制。幸運的是,CGridCtrl類已經(jīng)為我們提供了這種機制,它是采用虛模式的方式,要使用這種方式,按照以下的步驟就可以了:步驟一初始化void SetVirtualMode(TRUE)設為虛模式BOOL SetRowCount(int nRows) 設置總的行數(shù)。BOOL SetFixedRowCount(int nFixedRows = 1)設置固定的行數(shù)據(jù)BOOL SetColumnCount(int nCols)設置列數(shù)BOOL SetFixedColumnCount(int nFixedCols = 1)設置固定的列數(shù)步驟二響應消息顯示數(shù)據(jù)我們假設CGridCtrl是放在對話框上,而且它關聯(lián)的變量是m_Grid,利用ClassWizard添加對話框的OnNotify響應函數(shù)。這個響應函數(shù)的寫法是固定的,類似下面的代碼:BOOL CMyOdbcDlg:OnNotify(WPARAM wParam, LPARAM lParam, LRESULT* pResult) / TODO: Add your specialized code here and/or call the base classif (wParam = (WPARAM)m_Grid.GetDlgCtrlID() *pResult = 1; GV_DISPINFO *pDispInfo = (GV_DISPINFO*)lParam; if (GVN_GETDISPINFO = pDispInfo-hdr.code)SetGridItem(pDispInfo);/*這是我們自己加的函數(shù),在這個函數(shù)里我們設置當前要顯示的數(shù)據(jù)*/return TRUE; return CDialog:OnNotify(wParam, lParam, pResult);在上面的代碼中,SetGridItem(pDispInfo)是我們自己加的函數(shù),在這個函數(shù)里我們設置當前要顯示的數(shù)據(jù),pDispInfo是一個GV_DISPINFO的結構體對象,在這個結構中包含了每個單元格的信息,如行號,列號,有沒有位圖,背景色,前景色等,CGRIDCTRL會在當前要顯示那個單元格時,會把這個單元格的行號,列號傳遞給我們,我們只要在里面設置要顯示的數(shù)據(jù)就可以了。如下面是一個顯示數(shù)據(jù)的例子。int CMyOdbcDlg:SetGridItem(GV_DISPINFO *pDispInfo)pDispInfo-item.strText.Format(“row%d,col%d”,pDispInfo-item.row, pDispInfo-item.col); return 0;通過上面的介紹,我們應該已經(jīng)會使用CGridCtrl虛模式,下面說明一下用CGridCtrl虛模式做DBGRID的原理,大家都知道,MFC的CRecordset類支持多種游標機制,如雙向游標的,如果我們是用ClassWizard來生成一個查詢的CRecordset的派生類的話,那么可以調(diào)用函數(shù)CRecordset:SetAbsolutePosition(),用這種方式方式來做DBGRID真是太簡單了,因為在上面的int CMyOdbcDlg:SetGridItem(GV_DISPINFO *pDispInfo)函數(shù)中,我們已經(jīng)知道要顯示的是哪一行,哪一列的數(shù)據(jù),所以只要通過CRecordset:SetAbsolutePosition(pDispInfo-item.row)函數(shù),把游標定位到那一行,然后獲取每個字段的數(shù)據(jù)就可以了。但是使用上面的方法有一個不好的地方在于,我們必須用ClassWizard為每個查詢從CRecordset派生出新類,這樣做很不方便,在VC知識庫第六期上面有一篇介紹“單獨使用CRecordset”文章,可是上面的CRecordset打開方式只能使用CRecordset:forwardOnly,游標只能向前滾動,我們不能使用CRecordset:SetAbsolutePosition()函數(shù),如果要想使用方便的話,我們必須想別的辦法,來提供當前要顯示的那個單元格的數(shù)據(jù)。我們知道,oracle數(shù)據(jù)庫并不支持雙向游標,那么為什么我們用ClassWizard為查詢從CRecordset派生的類能夠使游標雙向移動呢?我的猜想是這樣的,CRecordset類其實把每次獲取的數(shù)據(jù)都保存了下來,并且保存了每行記錄所在的位置,這樣,當我們調(diào)用CRecordset:SetAbsolutePosition()函數(shù)時,它就可以得到我們想要的數(shù)據(jù)了。不管這種猜想對不對,按照上面的思路已經(jīng)實現(xiàn)一個很好用的DBGRID。我把封裝成了類COdbcDBGRIDFILE,它實現(xiàn)的原理是首先得到所查詢的行數(shù),列數(shù),然后設置CGridCtrl的屬性,如把它設為虛模式,設定CGridCtrl的行數(shù)和列數(shù)等。然后使用內(nèi)存映射文件來保存每條記錄數(shù)據(jù),同時用一個結構體來記錄下這條記錄所在的位置。這里有一個小技巧,如果查詢的結果有幾十萬條的話,如果我們一開始就把所有的這些記錄都保存在內(nèi)存映射文件中的話,那么時間要很長,所以根本不能滿足應用,所以我們在開始時,只會獲取記錄集的一部分用于顯示,當用戶在CGRIDCTRL上拖動滾動條向下滾動時,它會隨著用戶的滾動不斷的獲取數(shù)據(jù),這樣顯示上面就一點問題也沒有。三、使用實例好了,給大家說了這么多,下面就看看如何使用這個封裝好的類COdbcDBGRIDFILE這個類對外的接口只有4個函數(shù)可以被調(diào)用,下面簡單的說明一下這4個函數(shù)COdbcDBGridFILE(CGridCtrl *pGrid = NULL, CDatabase *pDatabase = NULL, CString strSql = , CString strFilePath = )/構造函數(shù),必須把所要的變量傳遞進去。int InitGrid();/初始化函數(shù)int SetGridText(GV_DISPINFO *pDispInfo);/被外部函數(shù)調(diào)用接口,用來返回每個單元格應該顯示的int Release();/釋放資源按照下面的步驟做一遍,你就能夠知道它是不是很實用了。步驟一新建一個基于對話框的工程,命名為demo2,打開stdafx.h文件,加入#include,從例子中把OdbcDBGRIDFILE.h, OdbcDBGRIDFILE.cpp復制到這個工程的目錄下,并且加入到工程中,方法是菜單project-add to project-files,選擇這二個文件就可以了。不要忘了,你要把CGRIDCTRL類的文件都包含進來。步驟二在對話框上,按照上面的樣例放上一個CURSTOMER CTROL(就是一個人頭的那個控件),在屬性的CLASS上輸入MFCGridCtrl,ID為IDC_GRIDODBC,然后在放上其它編輯框和按鈕控件,為四個編輯框控件通過CLASSWIZARD關聯(lián)變量CStringm_strPass;/口令CStringm_strSource;/數(shù)據(jù)源名CStringm_strSql;/查詢sqlCStringm_strUser;/用戶名在類CDemo2Dlg中加入下面的幾個成員變量CGridCtrl m_Grid;COdbcDBGRIDFILE *m_pMapFile;CImageList m_ImageList;CDatabase m_db;當然你要在CDemo2Dlg的聲明文件中加入#include gridctrl.h#include OdbcDBGRIDFILE.h在CDemo2Dlg:DoDataExchange(CDataExchange* pDX)函數(shù)中加入DDX_Control(pDX, IDC_GRIDODBC, m_Grid);在CDemo2Dlg的構造函數(shù)中加入m_pMapFile = NULL;步驟三、用ClassWizard生成CDemo2Dlg的CDemo2Dlg:OnNotify消息響應函數(shù),在這個函數(shù)中,輸入如下的代碼BOOL CDemo2Dlg:OnNotify(WPARAM wParam, LPARAM lParam, LRESULT* pResult) / TODO: Add your specialized code here and/or call the base class if (wParam = (WPARAM)m_Grid.GetDlgCtrlID() *pResult = 1; GV_DISPINFO *pDispInfo = (GV_DISPINFO*)lParam; if (GVN_GETDISPINFO = pDispInfo-hdr.code) SetGridItem(pDispInfo);return TRUE; return CDialog:OnNotify(wParam, lParam, pResult);在上面的代碼中,SetGridItem(pDispInfo)是我們自己加的函數(shù),在這個函數(shù)里我們設置當前要顯示的數(shù)據(jù)步驟四為CDemo2Dlg加入查詢按鈕的響應函數(shù)OnBtnquery()下面是這個函數(shù)的代碼void CDemo2Dlg:OnBtnquery() this-Release();/*這個函數(shù)用于釋放資源的*/CString strConn;UpdateData(TRUE);strConn.Format(ODBC;DSN=%s;UID=%s;PWD=%s,m_strSource,m_strUser, m_strPass); BOOL bResult = m_db.Open(strConn);if(bResult = FALSE) return;/*上面的代碼用于連接數(shù)據(jù)庫*/m_pMapFile = new COdbcDBGRIDFILE(&m_Grid, &m_db, m_strSql, c:csl.txt);m_pMapFile-InitGrid();/*初始化函數(shù),用于創(chuàng)建內(nèi)存映射文件等*/在上面的代碼中,調(diào)用了COdbcDBGRIDFILE的構造函數(shù),它的原型是COdbcDBGRIDFILE:COdbcDBGRIDFILE(CGridCtrl *pGrid , CDatabase *pDatabase, CString strSql, CString strFilePath),其中的參數(shù)的含義如下CGridCtrl *pGrid-是一個指向CGridCtrl的指針CDatabase *pDatabase-是一個指向Cdatabase的指針,你必須把一個已經(jīng)連接好的Cdatabase的對象傳遞進去。CString strSql-是一個查詢語句,如select * from emp;CString strFilePath-是一個用于生成內(nèi)存映射文件的文件的路徑步驟五為CDemo2Dlg加入成員函數(shù)SetGridItem(pDispInfo),這個函數(shù)是CDemo2Dlg:OnNotify()中調(diào)用的,我們用它來設置顯示記錄數(shù)據(jù)。void CDemo2Dlg:SetGridItem(GV_DISPINFO *pDispInfo)/*在這兒你可自己進行設置,如第一行為查詢的字段中文名,第一行為行的序號等,如果你不進行設置,那么默認會取每個查詢得到的字段名,每一行的序號*/m_pMapFile-SetGridText(pDispInfo);/*上面的函數(shù)只是用來得到了本來,你還可以用它來進行另外一些屬性,如當超過一定的值是顯示DBGRID的不同的前景色和前景色等*/步驟六添加成員

溫馨提示

  • 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會有圖紙預覽,若沒有圖紙預覽就沒有圖紙。
  • 4. 未經(jīng)權益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
  • 5. 人人文庫網(wǎng)僅提供信息存儲空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負責。
  • 6. 下載文件中如有侵權或不適當內(nèi)容,請與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準確性、安全性和完整性, 同時也不承擔用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。

評論

0/150

提交評論