用API函數改進ListView控件的顯示效果

發表于:2007-07-14來源:作者:點擊數: 標簽:
王建兵 ListView使用簡介 ListView控件是 VB 開發 者非常喜愛的控件之一。作為 Windows 95公共控件組(COMCTL32.OCX) 的成員,它經常與經常與TreeView、ImageList等控件聯合使用。即用TreeView顯示一個的樹 型結構,而用ListView顯示選中的節點(Node)對象的記
王建兵

ListView使用簡介
  ListView控件是VB開發者非常喜愛的控件之一。作為Windows95公共控件組(COMCTL32.OCX) 的成員,它經常與經常與TreeView、ImageList等控件聯合使用。即用TreeView顯示一個的樹 型結構,而用ListView顯示選中的節點(Node)對象的記錄
集。
  這是筆者在開發財務軟件項目中的$#@60;$#@60;憑證管理$#@62;$#@62;模塊的一個用戶界 面。屏幕左邊是一個TreeView控件,用來顯示會計憑證的類別;右邊是一個istView,用來顯示 對應類別的憑證目錄;上方是一個菜單條控件(MenuBar)和一個工具條控件(ToolBar);下方是 一個狀態欄控件(StatusBar),用來顯示憑證數個當前日期。

  大家可以看到圖中所 示的界面非常類似于Window95/98的資源瀏覽器,Windows的界面風格做為一種標準已為廣大 用戶所接受。而Windows操作系統的主要的優點就是為所有的應用程序提供了公用的界面。知道 如何使用基于Windows的應用程序的用戶,很容易學會使用其他應用程序。

  這種使 用Windows95公共控件組合的方法能夠達到與Windows界面的一致性,所以在目前VB5.0應用 程序的開發中經常使用。

二、填充大量結果集所遇到的問題
  在實際應用開發中,經常用ListView填充一個數據庫結果集(Recordset)的內容。即先寫 一段SQL查詢語句,產生一個結果集,然后將結果集的每一條記錄用DO...LOOP循環語句中填到ListView 中。

  但是當結果集很大時(例如有5000條以上的記錄),填充所需要的時間會很長。 用戶不得不等很長時間完成一個查詢。所以在查詢的過程中必須允許用戶按Escape鍵退出。具 體做法是在DO...LOOP循環體中加一條DoEvents函數,并寫一段中斷退出程序代碼。

   DoEvents函數的功能是:轉讓控制權,以便讓操作系統處理其它的事件。這樣在長時間的查詢 過程中,如果用戶按了Escape鍵,將退出循環體,結束查詢過程。

  但是這樣又會引 發另外一個問題:由于DoEvents可以讓操作系統響應別的事件,循環體中填充每一條ListView 項目(ListItem)的過程也會顯示出來,所以在填充的過程中屏幕會不停的閃動,這種現象當然 不能被用戶所接受。如何解決這個問題呢?

三、解決方案
  用WindowsAPI函數可以解決這個問題。首先對幾個用到的API函數做一解釋和說明。

   1.GetClientRectLib"user32"(ByValhwndAsLong,lpRectAsRECT)As Long

  此函數的功能是獲得一個指定對象窗 Window)的矩型框區域(rectangle)。

   Hwnd為指定對象或窗體的句柄。LpRect為返回矩型框的結構(必須定義為結構類型的變量)。

   2.ValidateRectLib"user32"(ByValhwndAsLong,lpRectAsRECT)As Long

  此函數的功能是使指定的矩型區域生效。這樣會通知Windows不必對指定 的區域進行重畫(Redraw)。

  3.InvalidateRectLib"user32"(ByVal hwndAsLong,lpRectAsRECT,ByValbEraseAsLong)AsLong

  此函數的 功能是使指定的矩型區域無效。這樣會通知Windows要對指定的區域進行重畫。

   具體實現的步驟如下:

  1.在填充結果集之前先用GetClientRect函數獲得ListView的 顯示區域。

  2.在增加完一個顯示項目(ListItem)后用ValidateRect函數置這一 區域為有效。這樣Windows就不會顯示每一條ListItem,屏幕閃動的現象就會消失。

   3.在填充結果集之后,用InvalidateRect函數置這一區域為無效。這樣Windows就會重畫ListView 的內容,結果集被完整的顯示出來。

  下面是筆者在項目開發中的一個程序實例。程 序名為FillListView。該程序將填寫一個Aclearcase/" target="_blank" >ccess數據庫(FISCAL.MDB)的憑證表(Table)的內容 到ListView中。

  首先進入VB5.0,新建一個窗體(Form),名為Form1。

   然后在Form中增加下列控件。


控件名Name

ListViewLvw

ImagelistimlList

CommandButton。Command1


  將ImageList控件中充填一個名為“item”的圖象后與ListView控件關聯。

   在$#@60;$#@60;工程$#@62;$#@62;菜單命令條中進入“引用”對話框,選擇“MicrosoftDAOObjectLibrary”

   在Form的通用模塊(Modle)中定義以下變量。


PrivateTypeRECT用來定義一個區域的坐標。

LeftAsLong

TopAsLong

Right AsLong

BottomAsLong

EndType

  --

Windows API函數的聲明。

PrivateDeclareFunctionInvalidateRectLib"user32"

(ByVal hwndAsLong,lpRectAsRECT,ByValbEraseAsLong)AsLong

PrivateDeclare FunctionValidateRectLib"user32"

(ByValhwndAsLong,lpRect AsRECT)AsLong

PrivateDeclareFunctionGetClientRectLib"user32"

(ByVal hwndAsLong,lpRectAsRECT)AsLong


DimmbSearchCancelAsBoolean

用來定義查詢中斷的標志。

True表示中止查詢;False表示正在查詢。


  將該Form的KeyPreview屬性設為True,以控制窗體接收鍵盤事件。

  然后在Form 的KeyPress事件中寫下列代碼:


IfKeyAscii=vbKeyEscapeThen

mbSearchCancel=True

當用戶按Escape 鍵時,置mbSearchCancel變量為True。

EndIf

表示結束查詢。

在Command Button的Click事件中調用填充子程序:CallFillListView。


子程序的代碼 為:

PrivateSubFillListView()


DimitmXAsListItem定義一 個ListView的顯示項目。

DimsSQLAsString查詢字串變量。


Dim rcAsRECTListView的顯示區域。

DimwrkJetAsWorkspace數據庫工作空間。

Dim dbFISCALAsDatabase數據庫對象。

DimRSAsRecordset數據結果集。


On ErrorGoToErrFillListView


Screen.MousePointer=vbHourglass

lvw.ListItems.Clear: 清除ListView的內容。

    

定義ListView的列頭的名稱。

With lvw.ColumnHeaders

.Add,,"憑證編號",800

.Add,," 憑證日期",1000

.Add,,"憑證字號",1000

.Add,," 憑證類別",800

.Add,,"首行摘要",1440

.Add,," 借方金額合計",1000,lvwColumnRight

EndWith


  - --

產生查詢語句。

sSQL="selectvoucher_id,voucher_number,voucher_date,
voucher_type_shortname,"

sSQL=sSQL&"voucher_type_name,voucher_memo,voucher_amount fromVOUCHER"

sSQL=sSQL&"orderbyvoucher_number"

  ---

打開一個數據庫結果集。

SetwrkJet=CreateWorkspace("NewJetWorkspace", "admin","",
dbUseJet)

SetdbFISCAL=wrkJet.OpenDatabase("FISCAL.mdb")

Set RS=.dbFISCAL.OpensSQL,dbOpenForwardOnly

    

獲得listview 的顯示區域。

CallGetClientRect(lvw.hwnd,rc)


DoWhileNotRS.EOF()

DoEvents

If mbSearchCancelThen

中斷退出

RS.Close:SetRS=Nothing關閉、清 除結果集。

mbSearchCancel=False

Screen.MousePointer=vbDefault

  --

刷新ListView的內容,顯示已經查出的記錄數。

CallInvalidateRect(lvw.hwnd, rc,True)

ExitSub

EndIf

  ---

增加一個顯示 項目ListItem。

Withlvw.ListItems

SetitmX=.Add(,,""& RS!voucher_number,"item","item")

憑證編號

itmX.SubItems(1) =Format$(""&RS!voucher_date,"yyyy/mm/dd")

憑證日期

itmX.SubItems(2)=""&RS!voucher_type_shortname &"-"—

憑證字號

&""&RS!voucher_number


itmX.SubItems(3)="" &RS!voucher_type_name

憑證類別

itmX.SubItems(4)=""&RS!voucher_memo

首行摘要

itmX.SubItems(5)=Format$(""&RS!voucher_amount, "#,###.00")

借方合計金額

itmX.Tag=""& RS!voucher_id

EndWith

  --

避免顯示區域的閃動現象。

Call ValidateRect(lvw.hwnd,rc)

RS.MoveNext

Loop


  

- 刷新ListView的內容。顯示所有查出的記錄數。

CallInvalidateRect(lvw.hwnd,rc, True)

  -

關閉、清除結果集。

RS.Close:SetRS=Nothing

creen.MousePointer =vbDefault

ExitSub

ErrFillListView:

Screen.MousePointer= vbDefault

MsgBoxErr&":"&Error,vbInformation,Me.Caption

Exit Sub

EndSub

  編寫完畢后按F5執行該程序,用鼠標點擊CommandButton,將 開始查詢并填寫憑證的內容到ListView中去。

  關于ListView本文只是描述了它 如何填充大量結果集的方法,它還有很多特性(property)和方法(method),利用它們可以達到 更完美的顯示效果,有興趣的讀者可以進一步研究。不管是開發什么樣的應用程序,只有堅持 面向用戶、方便用戶的原則,這樣的軟件才具有強大的生命力。

原文轉自:http://www.anti-gravitydesign.com

国产97人人超碰caoprom_尤物国产在线一区手机播放_精品国产一区二区三_色天使久久综合给合久久97