说三道四技术文摘-感悟人生的经典句子
说三道四 > 文档快照

VB用API函数改进ListView控件的显示效果

HTML文档下载 WORD文档下载 PDF文档下载
VB用API函数改进ListView控件的显示效果
作者:王建兵
一 、ListView 使 用 简 介
---- ListView 控 件 是VB 开 发 者 非 常 喜 爱 的 控 件 之 一。 作 为Windows95 公 共 控 件 组(COMCTL32.OCX) 的 成 员, 它 经 常 与 经 常 与TreeView、ImageList 等 控 件 联 合 使 用。 即 用 TreeView 显 示 一 个 的树 型 结 构, 而 用 ListView 显 示 选 中 的 节 点(Node) 对 象 的 记 录
集。

---- 这 是 笔 者 在 开 发 财 务 软 件 项 目 中 的<< 凭 证 管 理>> 模 块的 一 个 用 户 界 面。 屏 幕 左 边 是 一 个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) 的 过 程 也 会 显 示 出 来, 所 以 在 填 充 的 过 程 中 屏 幕会 不 停 的 闪 动, 这 种 现 象 当 然 不 能 被 用 户 所 接 受。 如 何 解决 这 个 问 题 呢 ?

三、 解 决 方 案
---- 用Windows API 函 数 可 以 解 决 这 个 问 题。 首 先 对 几 个 用 到的API 函 数 做 一 解 释 和 说 明。

---- 1. GetClientRect Lib "user32" (ByVal hwnd As Long, lpRect As RECT)As Long

---- 此 函 数 的 功 能 是 获 得 一 个 指 定 对 象 窗 口(Window) 的 矩 型框 区 域(rectangle)。

---- Hwnd 为 指 定 对 象 或 窗 体 的 句 柄。LpRect 为 返 回 矩 型 框 的结 构( 必 须 定 义 为 结 构 类 型 的 变 量) 。

---- 2. ValidateRect Lib "user32" (ByVal hwnd As Long, lpRect As RECT)As Long

---- 此 函 数 的 功 能 是 使 指 定 的 矩 型 区 域 生 效。 这 样 会 通 知Windows 不 必 对 指 定 的 区 域 进 行 重 画(Redraw)。

---- 3. InvalidateRect Lib "user32" (ByVal hwnd As Long, lpRect As RECT,ByVal bErase As Long) As Long

---- 此 函 数 的 功 能 是 使 指 定 的 矩 型 区 域 无 效。 这 样 会 通 知Windows 要 对 指 定 的 区 域 进 行 重 画。

---- 具 体 实 现 的 步 骤 如 下:

---- 1. 在 填 充 结 果 集 之 前 先 用GetClientRect 函 数 获 得ListView的 显 示 区 域。

---- 2. 在 增 加 完 一 个 显 示 项 目(ListItem) 后 用ValidateRect 函 数置 这 一 区 域 为 有 效。 这 样Windows 就 不 会 显 示 每 一 条ListItem,屏 幕 闪 动 的 现 象 就 会 消 失。

---- 3. 在 填 充 结 果 集 之 后, 用InvalidateRect 函 数 置 这 一 区 域为 无 效。 这 样Windows 就 会 重 画ListView 的 内 容, 结 果 集 被 完 整的 显 示 出 来。

---- 下 面 是 笔 者 在 项 目 开 发 中 的 一 个 程 序 实 例。 程 序 名 为FillListView。 该 程 序 将 填 写 一 个Access 数 据 库(FISCAL.MDB) 的 凭证 表(Table) 的 内 容 到ListView 中。

---- 首 先 进 入VB5.0, 新 建 一 个 窗 体(Form), 名 为Form1。

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


控 件 名 Name

ListView Lvw

Imagelist imlList

Command Button。 Command1


---- 将ImageList 控 件 中 充 填 一 个 名 为“item” 的 图 象 后 与ListView 控 件 关 联。

---- 在<< 工 程>> 菜 单 命 令 条 中 进 入“ 引 用” 对 话 框, 选 择“Microsoft DAO Object Library”

---- 在Form 的 通 用 模 块(Modle) 中 定 义 以 下 变 量。


Private Type RECT ' 用 来 定 义 一 个 区 域 的 坐 标。

Left As Long

Top As Long

Right As Long

Bottom As Long

End Type

'- - - - - -

' Windows API 函 数 的 声 明。

Private Declare Function InvalidateRect Lib "user32"

(ByVal hwnd As Long, lpRect As RECT, ByVal bErase As Long) As Long

Private Declare Function ValidateRect Lib "user32"

(ByVal hwnd As Long, lpRect As RECT) As Long

Private Declare Function GetClientRect Lib "user32"

(ByVal hwnd As Long, lpRect As RECT) As Long



Dim mbSearchCancel As Boolean

' 用 来 定 义 查 询 中 断 的 标 志。

' True 表 示 中 止 查 询;False 表 示 正 在 查 询。


---- 将 该Form 的KeyPreview 属 性 设 为True, 以 控 制 窗 体 接 收 键 盘事 件。

---- 然 后 在Form 的KeyPress 事 件 中 写 下 列 代 码:


If KeyAscii = vbKeyEscape Then

mbSearchCancel = True

' 当 用 户 按Escape 键 时, 置mbSearchCancel 变 量 为True。

End If

' 表 示 结 束 查 询。

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



子 程 序 的 代 码 为:

Private Sub FillListView()

'

Dim itmX As ListItem ' 定 义 一 个ListView 的 显 示 项 目。

Dim sSQL As String ' 查 询 字 串 变 量 。

'

Dim rc As RECT ' ListView 的 显 示 区 域。

Dim wrkJet As Workspace ' 数 据 库 工 作 空 间。

Dim dbFISCAL As Database ' 数 据 库 对 象。

Dim RS As Recordset ' 数 据 结 果 集。



On Error GoTo ErrFillListView



Screen.MousePointer = vbHourglass

lvw.ListItems.Clear: ' 清 除ListView 的 内 容。

'- - - - - - - -

' 定 义ListView 的 列 头 的 名 称。

With lvw.ColumnHeaders

.Add , , " 凭 证 编 号", 800

.Add , , " 凭 证 日 期", 1000

.Add , , " 凭 证 字 号", 1000

.Add , , " 凭 证 类 别", 800

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

.Add , , " 借 方 金 额 合 计", 1000, lvwColumnRight

End With



'- - - - - - -

' 产 生 查 询 语 句。

sSQL = "select voucher_id,voucher_number,voucher_date,
voucher_type_shortname,"

sSQL=sSQL&"voucher_type_name,voucher_memo,voucher_amount from VOUCHER"

sSQL = sSQL & "order by voucher_number"

' '- - - - - - -

' 打 开 一 个 数 据 库 结 果 集。

Set wrkJet = CreateWorkspace("NewJetWorkspace", "admin", "",
dbUseJet)

Set dbFISCAL = wrkJet.OpenDatabase("FISCAL.mdb")

Set RS=. dbFISCAL .Open sSQL,dbOpenForwardOnly

'- - - - - - - -

' 获 得listview 的 显 示 区 域。

Call GetClientRect(lvw.hwnd, rc)



Do While Not RS.EOF()

DoEvents

If mbSearchCancel Then

' 中 断 退 出

RS.Close: Set RS = Nothing ' 关 闭、 清 除 结 果 集。

mbSearchCancel = False

Screen.MousePointer = vbDefault

'- - - - - -

' 刷 新ListView 的 内 容, 显 示 已 经 查 出 的 记 录 数。

Call InvalidateRect(lvw.hwnd, rc, True)

Exit Sub

End If

'- - - - - - -

' 增 加 一 个 显 示 项 目ListItem。

With lvw.ListItems

Set itmX = .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

End With

'- - - - - -

' 避 免 显 示 区 域 的 闪 动 现 象。

Call ValidateRect(lvw.hwnd, rc)

RS.MoveNext

Loop



'- - - -

'- 刷 新ListView 的 内 容。 显 示 所 有 查 出 的 记 录 数。

Call InvalidateRect(lvw.hwnd, rc, True)

'- - - - -

' 关 闭、 清 除 结 果 集。

RS.Close: Set RS = Nothing

creen.MousePointer = vbDefault

Exit Sub

ErrFillListView:

Screen.MousePointer = vbDefault

MsgBox Err & ":" & Error, vbInformation, Me.Caption

Exit Sub

End Sub

---- 编 写 完 毕 后 按F5 执 行 该 程 序, 用 鼠 标 点 击CommandButton,将 开 始 查 询 并 填 写 凭 证 的 内 容 到ListView 中 去。

---- 关 于ListView 本 文 只 是 描 述 了 它 如 何 填 充 大 量 结 果 集 的方 法, 它 还 有 很 多 特 性(property) 和 方 法(method), 利 用 它 们 可以 达 到 更 完 美 的 显 示 效 果, 有 兴 趣 的 读 者 可 以 进 一 步 研究。 不 管 是 开 发 什 么 样 的 应 用 程 序, 只 有 坚 持 面 向 用 户、方 便 用 户 的 原 则, 这 样 的 软 件 才 具 有 强 大 的 生 命 力。

---- “ 用Visual Studio 开 发 分 布 式Web 应 用” 系 列 文 章( 之 十),读 者 有 何 意 见 或 建 议, 请 发E-mail 至:ms_visualstudio@hotmail.com。 谢 谢 !---- 编 者
AWS集群计算新增内存分析EC2实例 手游:鼓足力气,掰弯传统3D游戏大作 LBA兴起:未来移动广告将基于地理位置 苹果发布2013财年Q1财报:iPhone销量及营收低于预期 不再被墙后 一个全新GitHub到来 与乔布斯并肩作战的日子 Google抛弃Exchange ActiveSync WP用户获DAV支持 Facebook真的要做“Facebook Phone”? 程序员,都去写一写前端代码吧 清除山寨和广告应用,“豌豆洗白白”服务上线 谷歌另类“开源” 程度仍不及Facebook和Twitter 想在云中分一份蛋糕? 不妨试试“山寨” 为何乔布斯脾气怪糟 却能让一群最优秀的人为他卖命? 单页Web设计案例+技巧攻略(多图) IE10里的捕捉模式和响应式设计 在“亚马逊商店”出售自己:产品经理这么找工作 【CTO俱乐部第92期】大规模存储与电商架构演化实战分享 刘黎明:PaaS是非主流业务,要与IaaS融合 个人手机游戏开发者之死 为什么苹果的应用审核是个笑话? 程序员性格怪癖是才华横溢的表现,还是危险分子的征兆? JavaScript Source Map详解 8条学习编程的可靠建议 一周消息树:亲爱的GitHub,我们怎么访问不了你? [回顾] 2012年几大编程语言就业趋势分析 研发周报:微软无视W3C 拒绝遵循WebRTC标准 移动周报:夫妻档闯江湖 事业爱情双丰收 当服务器遇见锤子:第六届AWS全球创业大赛落幕 C# DataTable 和List之间相互转换的方法 iPad如何在三年内改变世界 划时代的成果:新DNA存储技术 轻而易举装下世界 关于Global.asa的出错信息 請問各位在javamail中是如何發送附件的? 给一个女孩的信 单元格求和公式的问题(急) 我的系统经常报错:unable to load interpreter /lib/ld-linux.so.2 .NET中有没类似JUNIT或者DUNIT的测试框架? 有没有广州的MM(女程序员也可以)进来留个联系方式,我想和你们交个朋友 如何读取和删除TXT文件中的一行,在线· 最近想参加一个vc的培训,请各位议议是否有必要,选择哪个? 关于shtml的问题 面试注意问题有哪些? 怎么写一个事件,关闭网页的背景音乐 高分求助::关于VC下控制台下书写程序的问题? 我想看我的数据库里都有些什么表,请问在sql *plus里用什么命令? 如何在Office和IE的工具栏里添加自己的图标? 求救!!SOS!!!!!!!!SOS!!!!!! 请问怎样在win2000上安装SQL server ce 问一下,在web页面下,能显示MessageBox么? 求教:什么是设计模式? 名字前有 “抗日统一联盟”字样的进来领分, 每人10分, 先到先得 , 送完为止 急问:为什么生成控件OCX文件时的classid有时相同有时不同?? 请问:要实现类似photoshop的界面,要从何着手 我刚入门的,请各位高手指点一二,小弟在此谢过!~~~ 在我的程序中通过OLE启动Word,当此Word文档关闭之前程序能否得到通知? 谁能告诉我classpath到底是干什么用的???? 一个数据库中表的记录写到另外一个数据库中的表里!UP有分 急问,关于C#多线程的问题!!!!! 有6to23的用户吗?问个问题! 新手上路,如何读word或文本文件到网页上来? 在线等待!!! 有那一个控件同时可以调用多种播放格式文件的也就是说他的play可以自动调用mov,rm,flash的切换播放 提问提问!!!数据库连接 任命ravenkatte为大版主 在.h和.cpp文件中切换有什么快捷键吗? JavaScript一个难点!急!麻烦JavaScript老师给以回复! 關於 sqlcommand 查詢的問題100分 为什么无法包含gl/glut.h? 使用SQL语句向Oracle.8.1.7的Blob字段插入较长16进制编码字符串的问题 谁有ASCII码的表 请问在代理服务器上设置多个IP地址有什么好处? 如何用 VBScript实现:奠基一个按钮,显示一段内容? 水晶报表问题 请教高手:汉字内码怎么转化为相应的汉字??谢谢!! 请教!! 关于GetOpenFileName(OPENFILENAME)问题请教 为什么CList<CString,CString&> m_list不能当参数传递?急急急!!!!! 突然听人说在帖子了被人骂的感觉很爽,但本人平时言表谨小慎微,所以一直没机会体会,现在特开一帖,望各位仁兄仁妹开怀痛骂,定以高分相 关于microsoft speech sdk5.1的问题?请高人指点。 急问:在vc6中randmize()函数在哪个库中! 如何屏蔽键盘上的按键? 转会成功!放分庆贺! 甲乙丙三个好朋友同游世博后,租车回家.合理分摊车费.甲在全程3/1处下车,乙在全程3/2处下车,丙一个人做到终点,付了90元车费.他们三人怎样分摊车费比较合理? 为庆祝世博会圆满结束,学校举行大型体操表演,每行16人或18人都正好站成整排,参加演出的学生不到300. ”梨不嫩!”是表示那个国家 如此其贤也 什么意思 我们的教师,为什么总是鼓励我们莫名其妙的民族自豪?我们的教师,为什么总是鼓励我们莫名其妙的民族自豪感?结果都变成了盲目的夜郎自大? 贫者语于富者曰的语是什么意思 我想用这个图字体 要这种若隐若现的状态 用什麼软件就是“金星教育中学”这几个字弄成这种形式的就行 若望仆不相师 仆 的意思 我想知道这下面两张图是用什麼软件做出来的.怎麼做谢谢. 他会感到自豪.英语翻译. 《报任安书》以周文王、与哪些人的传世之作产生的原因,说明《 》也是由于 什么 ,告诉后人 什么的道理 全球十佳旅游城市排名揭晓 上海第六巴日美拟明年将普天间空中加油机转往岩国中国“北斗”即将在泰国落地使用宁夏“10·14”灭门杀人案犯罪嫌疑中组部:干部离退休3年内不得到原管辖杭州一大妈在城市空地种2000余株罂中国网络媒体论坛宣言“让网络清朗”中航工业否认为2.7万名员工配备iP世界关注中国“关键性会议” 将为长远内罗毕火车与公交车相撞死伤数十人韩国议员呼吁韩朝积极合作解决开城问题重磅推299元智能吸顶灯 鸿雁智慧照广西公布首批区直部门权力清单和责任清济南特产泉城二怪 济南旅游的吃货情结居庸关长城惊现巨型飞艇 东风风神意欲广西地税简政放权为小微企业注入新动能云南曲靖大扶贫格局惠及380余万人焦裕禄之女忆父亲:曾连续50多天坚守伊朗与六国达成协议 同意遏制核计划甘肃古浪:三代人共谱治沙壮歌河南织密“电商网”连通国际覆盖农村韩国拟将民谣《阿里郎》列为重要非物质重生之澈溪妾美不及妻随身悠闲乡村生活万兽掌控者奇卷混在女子高校金牌特工绝品医师蛊王杉杉来吃侯门嫡女剑湖旅游海云居旅游石宝山石窟旅游兴教寺旅游天然太极图旅游大理无为寺旅游苍山寺旅游核武器研制基地展览馆旅游天封塔旅游招远淘金小镇旅游招远黄金博物馆旅游
备案号:鲁ICP备13029499号-2 说三道四 www.s3d4.cn 说三道四技术文摘