关于虚表
1、虚表是一个特殊的listview,一些特性可以通用。
2、虚表对大数据比较适合,几百万条数据毫无压力。
3、数据量大的情况下(过几十万数据):虚表占用内存非常少,加载速度也非常快。listview 占内存非常多,加载速度非常慢。
4、数据在内存中处理速度是很快的,我们看到的慢,一般是加载到组件中并显示出来这段时间太长。
虚表库增强版
1、在原vlist的基础上增加或改进了部分功能。
2、主要优化了table操作方面的功能,对ado和sqlite未做优化。
- setColumns(标题,宽度,格式) 设置标题列,进行了改进,支持设置列宽度,列对齐方式等格式
- setColumnWidth()改变列宽
- doubleBuffer() 启用双缓冲,防止闪烁。默认自动开启
- onSortColumn(col,desc) 点击列标题进行排序
- onClick(row,col) 鼠标左键点击项目事件
- onDblClick(row,col) 鼠标左键双击项目事件
- onRClick(row,col) 鼠标右键点击项目事件
- onRDblClick(row,col) 鼠标右键双击项目事件
- onKeyDown(vkey) 按键按下事件(对回车键无效)
- onItemChanged(row) 列表项被改变事件
- 改进了 onSortColumn(),不影响列对齐方式等格式
- 改进了 clearColumnImage(),不影响列对齐方式等格式
- 改进了 setColumnImage(),不影响列对齐方式等格式
- 改进了 setTable(),可以直接给虚表赋值,使用 tableAdapter 类
- getItems() 获取全部项目内容,重新整理组合为数组型数据表
- getTable() 获取全部项目内容,返回的数据格式同settable()时相同
- getRowText()取行文本
- getColumnTextAll()取全部列标题
- getSelectedAll()取全部选择项
- 公开了 update()函数
- 对 tableAdapter 增加或优化了 insertRow(),addRow(), delRow()、getRowText()、setItemText()、getTable()、getItems()等函数
- 增加勾选框功能,增加setCheckBox() 函数,可在不影响当前“整行选择”设置的前提下实现显示/隐藏勾选框功能
- 改进或增加了setChecked(__)、getChecked(__) 、getCheckedAll() 函数,用于操作勾选框
- 过滤按键事件,只保留方向键等部分按键的默认事件
- 默认 整行选择
- 默认 显示表格线
- 默认 添加标题栏排序图标
- 默认 启用双缓冲
- 改进其它细节
注意事项:
- 不能直接使用操作 listview 内容的函数,如 setItem()、addItem()、 delItem()等。
- 但是 setTable()、setItemText()函数已进行了改进,可以直接使用。
- 可以用 insertRow()、addRow()、delRow()函数,添加或删除行数据。
- 针对 tableAdapter 增加或优化了部分对内容进行编辑的函数。
- 标题栏文本、宽度、格式等可以修改,但列数尽量始终保持一致,中途不要修改。
- 尽量不要使用 items 获取虚表内容。可以使用 getTable()、getItems()函数获取。
- 用 checkbox=true 启用勾选框,会强制将虚表设置为“整行选择”。建议使用 setCheckBox(True)。
库代码
//vlistEx 虚表控件(光庆增强版 2021-7-19)
//在原vlist的基础上增加部分功能
//参考lujjjh的vlistview做了一些小的改进
//原帖 http://bbs.aardio.com/forum.php?mod=viewthread&tid=11729
import win.ui.ctrl.listview;
import win.imageList;
namespace win.ui.ctrl;
class vlistEx {
ctor (parent,tParam) {
if (tParam) {
tParam.cls = "SysListView32";
tParam.style |= 0x1000/*_LVS_OWNERDATA*/;
if (tParam.edge)
tParam.exstyle |= 0x200/*_WS_EX_CLIENTEDGE*/;
select tParam.mode {
case "icon" tParam.style |= 0x0/*_LVS_ICON*/;
case "list" tParam.style |= 0x3/*_LVS_LIST*/;
case "smallicon" tParam.style |= 0x2/*_LVS_SMALLICON*/;
else tParam.style |= 0x1/*_LVS_REPORT*/;
}
if (tParam.editable) tParam.style |= 0x200/*_LVS_EDITLABELS*/;
if (tParam.hscroll) tParam.style |= 0x800/*_LVS_ALIGNLEFT*/;
if (tParam.vscroll) tParam.style |= 0x0/*_LVS_ALIGNTOP*/;
if (tParam.msel === false) tParam.style |= 0x4/*_LVS_SINGLESEL*/;
if (tParam.asel === null || tParam.asel) tParam.style |= 0x8/*_LVS_SHOWSELALWAYS*/;
}
}
onCreate = function () {
this.fullRow = true;
this.gridLines = true;
this.setExtended(0x10000/*_LVS_EX_DOUBLEBUFFER*/);
this.setColumnImageList(columnImageList);
this._prenotify = function(id, code, ptr) {
if (code = 0xFFFFFF4F/*_LVN_GETDISPINFOW*/) {
var dispInfo = ptr ? owner.getNotifyDispInfo(code, ptr);
var item = dispInfo.item;
var data = this.dataAdapter.getItem(item.iItem,item.iSubItem);
if(item.mask & 0x8/*_LVIF_STATE*/){
item.stateMask = 0xF000/*_LVIS_STATEIMAGEMASK*/
if(this.dataAdapter._dataSource[item.iItem].checked){
item.state = 2<<12
}else {
item.state = 1<<12
}
}
if (type(data) === "table"){
..table.mixin(item, data);
}
else{
item.text = tostring(data);
}
owner.setNotifyDispInfo(ptr,dispInfo);
return 1;
}
elseif(code=0xFFFFFF94/*_LVN_COLUMNCLICK*/) {
var nm = this.getNotifyMessage(code,ptr)
var desc = this.getColumnImage(nm.iSubItem) == 0;
if(this.onSortColumn){
for (i = 1; this.columnCount){
var col = LVCOLUMN();
col.mask = 0x1/*_LVCF_FMT*/
this.getColumn(col,i)
this.setColumn({fmt=col.fmt&(~0x800 /*_LVCFMT_IMAGE*/)},i);
}
if( this.onSortColumn(nm.iSubItem,desc) ){
var col = LVCOLUMN();
col.mask =0x1/*_LVCF_FMT*/
this.getColumn(col,nm.iSubItem)
this.setColumn({iImage=desc?1:0,fmt=col.fmt|0x800/*_LVCFMT_IMAGE*/|0x1000/*_LVCFMT_BITMAP_ON_RIGHT*/},nm.iSubItem)
}
}
}
elseif(code=0xFFFFFFFE/*_NM_CLICK*/){
var event = this.getNotifyMessage(code,ptr);
if( ! event.iItem && event.iSubItem ) return ;
if(this.onClick){
this.onClick(event.iItem,event.iSubItem);
}
if(this.dataAdapter._dataSource[event.iItem]){
if (event.iSubItem==1 or this.getExtended(0x4/*_LVS_EX_CHECKBOXES*/)){
this.dataAdapter._dataSource[event.iItem].checked = !this.dataAdapter._dataSource[event.iItem].checked;
this.dataAdapter.update()
}
}
}
elseif(code=0xFFFFFFFD/*_NM_DBLCLK*/){
var event = this.getNotifyMessage(code,ptr);
if( ! event.iItem && event.iSubItem ) return ;
if(this.onDblClick){
this.onDblClick(event.iItem,event.iSubItem);
}
}
elseif(code=0xFFFFFFFB/*_NM_RCLICK*/){
var event = this.getNotifyMessage(code,ptr);
if( ! event.iItem && event.iSubItem ) return ;
if(this.onRClick){
this.onRClick(event.iItem,event.iSubItem);
}
}
elseif(code=0xFFFFFFFA/*_NM_RDBLCLK*/){
var event = this.getNotifyMessage(code,ptr);
if( ! event.iItem && event.iSubItem ) return ;
if(this.onRDblClick){
this.onRDblClick(event.iItem,event.iSubItem);
}
}
elseif(code=0xFFFFFF9B/*_LVN_ITEMCHANGED*/){
var event = this.getNotifyMessage(code,ptr);
if( (event.uChanged & 0x8/*_LVIF_STATE*/)
&& (event.uNewState & 0x2/*_LVIS_SELECTED*/) ){
if(this.onItemChanged){
this.onItemChanged(event.iItem);
}
}
}
elseif(code=0xFFFFFF65/*_LVN_KEYDOWN*/){
var nmkey = ..raw.convert(ptr,{
struct hdr = ::NMHDR();
WORD vkey;
INT flags;
});
if(this.onKeyDown){
if (this.onKeyDown(nmkey.vkey)) return true;
}
/**
只支持以下按键的默认事件:
0x21/*_VK_PGUP*/,
0x22/*_VK_PGDN*/,
0x23/*_VK_END*/,
0x24/*_VK_HOME*/,
0x25/*_VK_LEFT*/,
0x26/*_VK_UP*/,
0x27/*_VK_RIGHT*/
0x28/*_VK_DOWN*/,
**/
if (nmkey.vkey<0x21 || nmkey.vkey>0x28) return true;
}
}
}
createAdapter = function(dataSource,...){
var ad =classAdapter(this, dataSource,...)
ad.update();
return ad;
}
createTableAdapter = function(dataSource,...){
var ad =tableAdapter(this, dataSource,...)
ad.update();
return ad;
}
createAdoAdapter = function(dataSource,...){
var ad = adoAdapter(this, dataSource,...)
ad.update();
return ad;
}
createSqliteAdapter = function(dataSource,...){
var ad =sqliteAdapter(this, dataSource,...)
ad.update();
return ad;
}
_onDestroy = function () {
if( this.dataAdapter ) {
this.dataAdapter.__close();
};
}
doubleBuffer = function(v=true){
this.setExtended(0x10000/*_LVS_EX_DOUBLEBUFFER*/,v);
}
setCheckBox = function(v=true){
this.setExtended(0x4/*_LVS_EX_CHECKBOXES*/,v)
}
setChecked = function(item,checked=true){
if !item {
for(i=1;#this.dataAdapter._dataSource;1){
this.dataAdapter._dataSource[i].checked=checked;
}
}elseif( type(item)="table"){
for(i=1;#item;1){
this.dataAdapter._dataSource[item[i]].checked=checked;
}
}else{
this.dataAdapter._dataSource[item].checked=checked;
}
this.update();
}
getChecked = function(item){
if !item {
var t={}
for(i=1;#this.dataAdapter._dataSource;1){
if(this.dataAdapter._dataSource[i].checked){
table.push(t,i)
}
}
return t;
}else{
if this.dataAdapter._dataSource[item]
return this.dataAdapter._dataSource[item].checked
}
}
getSelectedAll =function(){
var t={};
for(i=1;this.count;1){
if(this.getSelected(i)) ..table.push(t,i)
}
return t;
}
getCheckedAll =function(){
var t={};
for(i=1;this.count;1){
if(this.getChecked(i)) ..table.push(t,i)
}
return t;
}
setColumns = function(coltext,colwidth,colstyle){
setCol(this,coltext,colwidth,colstyle);
}
clearColumnImage = function(){
for (i = 1; this.columnCount){
var col = LVCOLUMN();
col.mask = 0x1/*_LVCF_FMT*/
this.getColumn(col,i)
this.setColumn({fmt=col.fmt&(~0x800 /*_LVCFMT_IMAGE*/)},i);
}
}
setColumnImage = function(col,iImage){
var lvcol = LVCOLUMN();
lvcol.mask =0x1/*_LVCF_FMT*/
this.getColumn(lvcol,col)
this.setColumn({iImage=iImage,fmt=lvcol.fmt|0x800/*_LVCFMT_IMAGE*/|0x1000/*_LVCFMT_BITMAP_ON_RIGHT*/},col)
}
setColumnWidth = function(col,width){
this.setColumn({cx=width},col)
}
getRowText = function(row){
return this.getItemText(row,-1))
}
delRow = function(row){
if (this.dataAdapter.delRow){
this.dataAdapter.delRow(row);
}
}
setItemText = function(row,col,text){
if (this.dataAdapter.setItem){
this.dataAdapter.setItem(row,col,text);
}
}
insertRow = function(row,...){
if (this.dataAdapter.insertRow){
var text={...}
if (type(text[[1]])="table"){
this.dataAdapter.insertRow(row,text[[1]]);
}else{
this.dataAdapter.insertRow(row,text);
}
}
}
addRow = function(...){
this.insertRow(,...);
}
getColumnTextAll = function(){
var t={}
for(i=1;this.columnCount;1){
..table.push(t,this.getColumnText(i))
}
return t;
}
setTable = function(dataSource,fields){
if(!fields){ //如果没有指定标题栏
if(dataSource[["fields"]]) fields=dataSource[["fields"]]//默认
elseif(#dataSource && !#(dataSource[1])) fields=..table.keys(dataSource[1])//字典,键名列表
}
if (type(fields)="string") fields=..string.split(fields,",;");//将字符串转换为“表”
if (type(fields)!="table") fields={}; //取消非法字段指定
if (#fields){
var curfields=this.getColumnTextAll();
if (#fields!=#curfields or ..table.tostring(curfields)!=..table.tostring(fields)) this.setColumns(fields)
}else{
fields = null;
if (!#dataSource) this.setColumns();
elseif (this.columnCount!=#(dataSource[1])){
this.setColumns(..string.split(..string.repeat(#(dataSource[1]),' ')))
}
}
return this.createTableAdapter(dataSource,fields);
}
getItems = function(){
return this.dataAdapter.getItems();
}
getTable = function(){
return this.dataAdapter.getTable();
}
update = function(){
return this.dataAdapter.update();
}
@_metaProperty;
}
namespace vlistEx {
_metaProperty = ..win.ui.ctrl.listview._metaProperty;
columnImageList = ..win.imageList(16, 15);
columnImageList.add('GIF\56\57a \0\15\0\x80\0\0\x80\x80\x80\xff\0\xff\33\xf9\4\0\0\0\0\0\44\0\0\0\0 \0\15\0\0\2\31\x8c\x8f\xa9\xcb\xed\15\xa3\x9c\xb4N\xf0\x80\xde\56k\xbfA\\\xd7\x84 \x97Y\xea\xca\xb6\xee\11\xc7F\1\0;', 0xff00ff);
LVCOLUMN = class {
INT mask = 0;
int fmt;
int cx;
ptr text;
int cchTextMax;
int iSubItem = 1;
int iImage;
int iOrder;
}
setCol = function(owner,fields,colwidth,colstyle){
for(i=owner.columnCount-1;0;-1){
::SendMessageInt(owner.hwnd, 0x101C/*_LVM_DELETECOLUMN*/, i, 0);
}
if !(fields && #fields) return;
if (type(fields)!="table") fields={fields};
var str,rc,width,col
if (!colwidth){
str = ..string.join(fields);
rc = owner.clientRect;
width = rc.right - rc.left;
col = width/ #str;
}
for(i=1;#fields;1) {
var cwidth
if(colwidth){
if (type(colwidth)="table"){
cwidth=colwidth[[i]]:0
}else{
cwidth=colwidth
}
}else{
cwidth=col*#fields[i]
}
var cstyle
if(colstyle){
if (type(colstyle)="table"){
cstyle=colstyle[[i]]:0
}else{
cstyle=colstyle
}
}else{
cstyle=0
}
owner.insertColumn(fields[i],cwidth,i,cstyle);
if(i=1 and cstyle){
var col1 = owner.getColumn(,1);
col1.fmt=cstyle
owner.setColumn(col1,1)
}
}
};
class baseAdapter {
ctor (listview,dataSource) {
this._listview = listview;
this._dataSource = dataSource;
if( listview.dataAdapter ) listview.dataAdapter.__close();
listview.dataAdapter = this;
}
update = function(){
::SendMessageInt(listview.hwnd, 0x102F/*_LVM_SETITEMCOUNT*/,this.count(), 0x2/*_LVSICF_NOSCROLL*/);
}
__close = function(){ this._listview.dataAdapter = null; if( this.close ) this.close() };
}
var baseAdapter = baseAdapter;
class classAdapter {
ctor (listview,dataSource,columns, ...) {
this = baseAdapter(listview,dataSource);
var instance = this._dataSource(columns,...);
};
count = function () {
return instance.count();
};
getItem = function (row, col) {
return instance.getItem(row, col);
}
}
class tableAdapter {
ctor (listview,dataSource,columns, ...) {
this = baseAdapter(listview,dataSource);
this._columns = columns;
};
count = function () {
return #(this._dataSource);
};
getItem = function (row, col) {
if (this._columns) return this._dataSource[row][[this._columns[col]]];
else return this._dataSource[row][col];
}
getItems = function () {
if (!#(this._dataSource)) return {};
var t = {};
for(rows=1;this._listview.count){
var row = {}
for(cols=1;this._listview.columnCount) {
if (this._columns) ..table.push(row,this._dataSource[rows][[this._columns[cols]]]);
else ..table.push(row,this._dataSource[rows][cols]);
}
..table.push(t,row) ;
}
return t;
}
getTable = function () {
return this._dataSource;
}
delRow = function(row){
if (!row or row>#(this._dataSource) or row<1) return ;
..table.remove(this._dataSource,row);
this.update()
}
setItem = function(row,col,text){
if (!row or row>#(this._dataSource) or row<1) return ;
if (this._columns) this._dataSource[row][this._columns[col]]=text;
else this._dataSource[row][col]=text;
this.update()
}
insertRow = function(row,text){
if(!row or row>(#(this._dataSource)+1) or row<1) row=#(this._dataSource)+1;
if(type(text)!="table") return ;
if (this._columns){
if (text[[this._columns[1]]]){
..table.insert(this._dataSource,text,row)
}else {
var t={}
for(i=1;#this._columns;1){
t[this._columns[i]]=text[[i]]
}
..table.insert(this._dataSource,t,row)
}
}else{
..table.insert(this._dataSource,text,row)
}
this.update()
}
}
class adoAdapter {
ctor (listview,dataSource, ...) {
this = baseAdapter(listview,dataSource);
};
count = function () {
var count = dataSource.getRecordCount();
if (count === -1) error("请以静态方式打开记录集。",3);
return count;
};
getItem = function (row, col) {
dataSource.Move(row - 1, 1/*_adBookmarkFirst*/);
return dataSource(col - 1).value;
}
close = function(){ if(dataSource) { dataSource.close(); dataSource = null; } };
}
class sqliteAdapter {
ctor (listview,dataSource,sql) {
this = baseAdapter(listview,dataSource);
this.rowIdx = null;
};
count = function () {
var row = dataSource.stepQuery( ..string.replace(sql,"^\s*<@@SELECT@>.+?<@@FROM@>\s+","SELECT COUNT(*) FROM ",1), )
if(!row) error("sql必须是SELECT ... FROM 语句",3);
return row["COUNT(*)"];
};
getItem = function (row, col) {
if( this.rowIdx == row ){
return this.row[col]
}
var stmt = dataSource.prepare( sql + " Limit 1 Offset " + row-1);
this.row = stmt.stepResult()
stmt.finalize();;
this.rowIdx = row;
return this.row[col];
}
}
}
/**intellisense()
?win.ui.ctrl.vlistEx = !ctrl_vlist.
!ctrl_vlist.clearColumnImage() = 清空全部列标题图标。
!ctrl_vlist.setColumnImage(__,) = 设置列标题图标。\n参数1:列号;\n参数2:图标索引。
!ctrl_vlist.update() = 刷新显示虚表内容。
!ctrl_vlist.getItems() = 获取虚表全部内容,返回数组型表。
!ctrl_vlist.getRowText(__) = 取行文本。参数1:行号。
!ctrl_vlist.setTable(__,) = 设置数据表。\n参数1:数据表,数组型或字典型均可。\n参数2:字典型数据表的列名数组。如果数据表为数组型,此参数可省略。
!ctrl_vlist.getTable() = 获取数据表。返回的数据格式同settable()时相同。
!ctrl_vlist.setColumns(__,,) = 设置标题栏。\n参数1:列文本,文本或文本数组;\n参数2:列宽,-1为自动填充剩余空间\n参数3:样式,使用_LVCFMT_前缀的常量。\n如果列宽或样式为非数组,则全部列都按当前值处理。
!ctrl_vlist.setColumnWidth(__,) = 设置列宽度。\n参数1:列号;\n参数2:宽度值。-1为自动填充至末尾。
!ctrl_vlist.setColumnText(__,"") = 设置标题栏文本。\n参数1:列号;\n参数2:标题文本。
!ctrl_vlist.getColumnText(__) = 取指定列标题栏文本
!ctrl_vlist.getColumnTextAll() = 取所有列标题栏文本
!ctrl_vlist.setItemText(__,,"") = 设置单元格文本。\n参数1:行号\n参数2:列号\n参数3:内容文本
!ctrl_vlist.getItemText(__,,) = 取单元格文本。\n参数1:行号\n参数2:列号,默认值为1,如果为-1,则取整行文本数组。\n参数3:缓冲区长度,默认为520。
!ctrl_vlist.getSelectedAll() = 取全部选择项。
!ctrl_vlist.doubleBuffer() = 启用双缓冲,防止闪烁。
!ctrl_vlist.insertRow(__,) = 插入一行。\n参数1:插入行号(插入到该行前)\n 从1开始,默认为行数+1(插入到最后一行后)。\n参数2:每列内容。可以用1个表,也可以用多个参数。
!ctrl_vlist.addRow(__) = 在末尾添加一行。\n参数:每列内容。可以用1个表,也可以用多个参数。
!ctrl_vlist.delRow(__) = 删除一行。\n参数:要删除的行号。
!ctrl_vlist.onItemChanged(row) = @.onItemChanged = function(row){
/*列表项被改变事件,row:改变后的列表项行号*/
__
}
!ctrl_vlist.onSortColumn(列号,是否倒序) = @.onSortColumn = function(col,desc){
/*点击列标题进行排序。col:列号,从1开始。desc:是否倒序。返回true重置标题栏排序图标*/
import godking
..table.sortEx(owner.getTable(),col,desc,0/*数据转换*/)
owner.update()
return true;
}
!ctrl_vlist.onClick(行号,列号) = @.onClick = function(row/*行*/,col/*列*/){
/*鼠标左键点击项目事件*/
__
}
!ctrl_vlist.onDblClick(行号,列号) = @.onDblClick = function(row/*行*/,col/*列*/){
/*鼠标左键双击项目事件*/
__
}
!ctrl_vlist.onRClick(行号,列号) = @.onRClick = function(row/*行*/,col/*列*/){
/*鼠标右键点击项目事件*/
__
}
!ctrl_vlist.onRDblClick(行号,列号) = @.onRDblClick = function(row/*行*/,col/*列*/){
/*鼠标右键双击项目事件*/
__
}
!ctrl_vlist.onKeyDown(vkey) = @.onKeyDown = function(vkey/*键代码*/){
var index = owner.selIndex;
/*按键按下事件,返回true则阻止默认事件*/
__
}
!ctrl_vlist.insertColumn(.(列标题,列宽,位置,格式) = 插入列。\n参数1:标题字符串、图像索引、指定LVCOLUMN结构体成员的table对象\n参数2:列宽度,-1为自动填充剩余空间\n参数3:插入位置,从1开始\n参数4:列格式,使用_LVCFMT_前缀的常量指定,如_LVCFMT_LEFT为文本左对齐
!ctrl_vlist.getColumn() = !lvcolumn.
!ctrl_vlist.getColumn(.(列参数表,列序号) = 参数一可以为空,或是指定LVCOLUMN结构体成员键值的参数表,\n返回LVCOLUMN结构体
!ctrl_vlist.setColumn(.({cx=100},列序号) = 改变列宽
!ctrl_vlist.setColumn(.(列参数表,列序号) = 参数一指定LVCOLUMN结构体成员键值的参数表,\n也可以是LVCOLUMN结构体对象,自动设置掩码参数.
!ctrl_vlist.getEditControl() = 开始编辑时返回编辑控件,\n此控件在完成编辑后会自动销毁,不必手动销毁\n取消发送_WM_CANCELMODE消息即可\n!edit.
?.getEditControl = !edit.
!ctrl_vlist.editLable(.(行序号) = 编辑指定项,无参数则编辑选定项\n此函数成功返回编辑文本框句柄\n返则返回0
!ctrl_vlist.setItemPos(__/*项索引*/,x,y) = 设置图标项坐标
!ctrl_vlist.count = 项目总数
!ctrl_vlist.delColumn(__) = 删除指定列
!ctrl_vlist.columnCount = 列总数
!ctrl_vlist.clear() = 清空所有项
!ctrl_vlist.getNextItem(.(起始索引,选项) = 参数二为一个或多个 _LVNI_ 前缀的常量合并\n默认为 _LVNI_ALL \n起始索引默认为0
!ctrl_vlist.getFocused() = 获取当前焦点项位置,返回数值,\n不存在焦点项则返回0
!ctrl_vlist.getSelection(.(起始索引) = 获取选中项,返回数值,\n不存在选中项则返回0\n可选指定起始索引,默认为0
!ctrl_vlist.getItemRect(.(行,列,RECT,选项) = 返回表示项目表示项目区块的RECT结构体,\n除第一个参数以外,其他参数为可选参数,\n如果不指定列则返回所在行区块,\n使用_LVIR_前缀常量指定选项
!ctrl_vlist.getItemRect() = !rect.
!ctrl_vlist.hitTest(.(x坐标,y坐标,是否屏幕坐标) = 该函数返回指定坐标的行号,参数三可省略,默认为false.\n如果不指定任何参数,则自动调用 win.getMessagePos() 获取消息坐标\n该函数有第二、第三个返回值并可能为0
!ctrl_vlist.setSelected(__/*项索引*/) = 选中项目。参数@1为项索引
!ctrl_vlist.setSelected(__/*项索引*/,false) = 取消选中项目。参数@1为项索引
!ctrl_vlist.getSelected(__/*项索引*/) = 指定项是否被选中。参数@1为项索引
!ctrl_vlist.getSelectedAll() = 取所有被选中项的索引表。
!ctrl_vlist.setChecked(__) = 勾选指定索引项(checked)。参数@1为项索引
!ctrl_vlist.setChecked(__,false) = 取消勾选指定索引项(checked)。参数@1为项索引
!ctrl_vlist.getChecked(__) = 返回指定索引项是否被勾选(checked)。参数@1为项索引
!ctrl_vlist.getCheckedAll() = 返回所有被勾选项的索引表(checked)。
!ctrl_vlist.setItemState(.(项索引,状态位,掩码) = 设置状态,参数三如果省略则使用参数二的值.
!ctrl_vlist.getItemState(.(项索引,状掩码 ) = 读取状态值
!ctrl_vlist.selIndex = 当前选定项索引(最后一次选定的索引)
!ctrl_vlist.fullRow = 是否选中整行
!ctrl_vlist.checkbox = 属性:显示/隐藏选择框(勾选框)。可获取此属性值。\n改变此属性时会同时改变“整行选择”属性。
!ctrl_vlist.setCheckBox(true) = 函数:显示/隐藏选择框(勾选框)。设置时不影响“整行选择”设置。
!ctrl_vlist.hwnd = 控件句柄
!ctrl_vlist.id = 控件ID
!ctrl_vlist._parentForm = 控件所在的父窗口(指win.form对象)\n!winform.
!ctrl_vlist.getParent() = 返回父窗口\n!static.
!ctrl_vlist.setParent(__/*控件对象*/) = 改变父窗口
!ctrl_vlist.disabled = 是否禁用
!ctrl_vlist.left = 左侧坐标
!ctrl_vlist.right = 右侧坐标
!ctrl_vlist.top = 顶部坐标
!ctrl_vlist.bottom = 底部坐标
!ctrl_vlist.width = 宽度
!ctrl_vlist.height = 高度
!ctrl_vlist.redraw() = 刷新
!ctrl_vlist.setRedraw(false) = 禁止重绘
!ctrl_vlist.setRedraw(true) = 恢复重绘
!ctrl_vlist.show(true__) = 显示控件
!ctrl_vlist.getRect() = 控件区块位置(::RECT结构体)
!ctrl_vlist.getRect(true) = 控件屏幕区块位置(::RECT结构体)
!ctrl_vlist.setRect(rc) = 设置控件区块位置(::RECT结构体)
!ctrl_vlist.setRect(rc,true) = 设置控件屏幕区块位置(::RECT结构体)
!ctrl_vlist.getClientRect() = 控件客户区块位置(::RECT结构体)\n!rect.
!ctrl_vlist.getFont() = 控件字体(::LOGFONT结构体)\n!logfont.
!ctrl_vlist.setFont(__/*指定字体*/) = 指定LOGFONT字体对象,或逻辑字体句柄
!ctrl_vlist.setFont(混入字体属性) = @.setFont(point=10;name="宋体");
!ctrl_vlist.clientRect = 获取控件客户区块位置(::RECT结构体)
!ctrl_vlist.theme = 外观主题,例如\nwinform.button.theme = "Explorer"\nwinform.button.theme = false
!ctrl_vlist.modifyStyle(.(remove,add) = 如果指定第三个参数,则使用此参数调用::SetWidnowPos
!ctrl_vlist.modifyStyleEx(.(remove,add) = 如果指定第三个参数,则使用此参数调用::SetWidnowPos
!ctrl_vlist.capture = 是否捕获全局鼠标消息
!ctrl_vlist.close() = 关闭控件窗口
!ctrl_vlist.setExtended(_LVS_EX__) = 启用树视图指定扩展样式
!ctrl_vlist.setExtended(_LVS_EX__,false) = 取消树视图指定扩展样式
!ctrl_vlist.getExtended() = 获取树视图扩展样式
!ctrl_vlist.getExtended(_LVS_EX__) = 获取树视图指定扩展样式
!ctrl_vlist.gridLines = 是否显示网格线
!ctrl_vlist.setFocus() = 设置焦点
!ctrl_vlist.setPos(.(x坐标,y坐标,宽,高,插入位置,参数) = 调整窗口位置或排序,所有参数可选\n同时指定x,y坐标则移动位置\n同时指定宽高则改变大小\n指定插入位置(句柄或_HWND前缀常量)则调整Z序
!ctrl_vlist.getPos() = 返回相对坐标,宽,高\nx,y,cx,cy=win.getPos(hwnd)
!ctrl_vlist.getTileViewInfo() = 返回排列显示相关属性
!ctrl_vlist.setTileViewInfo() = 设置排列显示相关属性
!ctrl_vlist.ensureVisible() = 保证显示选中项
!ctrl_vlist.ensureVisible(__) = 保证显示指定项
!ctrl_vlist.getImageList( _LVSIL__ ) = 获取指定图像列表,\n可选使用 _LVSIL_ 前缀常量指定类型
!ctrl_vlist.setImageList( imageList,_LVSIL__ ) = 获取指定图像列表,\n可选使用 _LVSIL_ 前缀常量指定类型
!ctrl_vlist.fillParent(.(列序号) = 使指定列自适应父窗口宽度,\n如果不指定列默认调整最后一列
!ctrl_vlist.adjust = @.adjust = function(cx,cy){
winform.listview.fillParent(/*列序号*/);
}
!ctrl_vlist.findItem(.(查找文本,起始位置,是否部份匹配,是否返回查询) = 使用文本查找匹配项,\n除第一个参数外,所有参数可选,默认支持部份匹配,并查找所有项
!ctrl_vlist.addCtrl = @.addCtrl(\n edit ={ cls="edit";left=0;top=0;right=50;bottom=50;autoResize=false ;hide=1;edge=1; }\n)
!ctrl_vlist.createAdoAdapter(__/*ADO数据源*/) = 设置数据源\nSQL查询语句必须显示的指定要显示的字段以及顺序
!ctrl_vlist.createAdapter( 类对象 ) = @.createAdapter( class {\n count = function () {\n return 10;\n } \n getItem = function (row, col) {\n return ..string.random(3);\n }\n close = function () {\n \n }\n});
!ctrl_vlist.createTableAdapter(.(table对象,列名数组) = 设置数据源,参数@2可选
!ctrl_vlist.createSqliteAdapter(.(sqlite连接对象,sql语句) = 设置数据源\nsql必须使用SELECT 显示的字段列表 FROM开始
!ctrl_vlist.createAdapter() = !ctrl_vlist_adapte.
!ctrl_vlist.createTableAdapter() = !ctrl_vlist_adapte.
!ctrl_vlist.createAdoAdapter() = !ctrl_vlist_adapte.
!ctrl_vlist.createSqliteAdapter() = !ctrl_vlist_adapte.
!ctrl_vlist.dataAdapter = 数据源适配器\n!ctrl_vlist_adapte.
!ctrl_vlist_adapte.update() = 更新数据源
!ctrl_vlist_adapte.close = @.close = function(){
__/*自定义数据连接关闭操作*/
}
end intellisense**/
调用示例
import win.ui;
import win.ui.ctrl.vlistEx;
/*DSG{{*/
mainForm = win.form(text="vlistEx - table adapter";right=853;bottom=578)
mainForm.add(
vlist={cls="vlistEx";left=11;top=14;right=842;bottom=572;ah=1;aw=1;edge=1;transparent=1;z=1}
)
/*}}*/
var t ={fields={"序号","姓名","年龄","地址","身份证"}}
math.randomize()
for(i=1;100000;1){
var tt={}
tt["序号"]=i
tt["姓名"]=math.random(1000,9999)+"姓名"
tt["年龄"]=math.random(10,99)
tt["地址"]=math.random(1000,9999)+"地址"
tt["身份证"]=math.random(1000,9999)+"身份证"
..table.push(t,tt)
}
mainForm.vlist.setTable(t)
mainForm.vlist.setCheckBox(true)
mainForm.vlist.onSortColumn = function(col,desc){
/*点击列标题进行排序。col:列号,从1开始。desc:是否倒序。返回true重置标题栏排序图标*/
import godking
..table.sortEx(owner.getTable(),col,desc,0/*数据转换*/)
owner.update()
return true;
}
mainForm.show();
win.loopMessage();