自绘listbox实现类似360浏览器下载界面功能

By admin at 2018-09-16 • 0人收藏 • 512人看过

先上360的界面:

image.png

aardio里面有listbox的自绘示例,在此基础上先增加一点点功能看看效果

//GDI自绘
import win.ui;
/*DSG{{*/
var winform = win.form(text="listbox自绘(GDI方式)";right=757;bottom=467)
winform.add(
listbox={cls="listbox";left=12;top=11;right=745;bottom=457;bgcolor=16777215;db=1;dl=1;dr=1;dt=1;items={};ownerDraw=1;vscroll=1;z=1}
)
/*}}*/


winform.listbox.onMeasureItem = function(measureItem){
    measureItem.itemHeight = 51;  
}
import win.imageList;
winform.listbox.onDrawItem = function(drawItem){
     gdi.selectBrush(
     
        function(hdc,pen,brush){
        
            var rc = drawItem.rcItem;
    		gdi.fillRect(hdc,0xFFFFFF,rc);
    		
    		if (drawItem.itemID > 0) {  
    			gdi.drawLine(hdc,rc.left, rc.top,rc.right, rc.top);
    		} 
    		
    		if (drawItem.itemState & 1/*_ODS_SELECTED*/) {  
        		//gdi.fillGradient(hdc,rc,0xFFFFFF, 0xC3BCA9,1/*_GRADIENT_FILL_RECT_V*/)
    			gdi.fillRect(hdc,0xFFF5E2,rc);
    		}
    		//加图标测试
    		win.imageList.shell( 0/*_SHIL_LARGE*/ ).draw(0,hdc,rc.left+20,rc.top+10);
    		//加文字测试
    		var str = winform.listbox.getItemText(drawItem.itemID + 1);
    		var str2 = "9.88MB       -文件已删除"
    		var font = ::LOGFONT(weight=400;color=0x000000);
    		gdi.textOut(hdc,font,str,rc.left+60, rc.top+10);
    		font = ::LOGFONT(weight=300;color=0xB0B0B0); 
    		gdi.textOut(hdc,font,str2,rc.left+60, rc.top+30); 
    		
   		},drawItem.hDC,0xF5FDFF/*背景色*/,0xEEEEEE/*画笔色*/)
}
 
for(i=1;10){ 
	winform.listbox.add("网页操作小助手.zip");
}
//win.imageList
winform.show();
win.loopMessage();

效果如下:

image.png

8 个回复 | 最后更新于 2018-09-17
2018-09-16   #1

image.png

//GDI自绘
import win.ui;
/*DSG{{*/
var winform = win.form(text="listbox自绘(GDI方式)";right=757;bottom=467)
winform.add(
listbox={cls="listbox";left=12;top=11;right=745;bottom=457;bgcolor=16777215;db=1;dl=1;dr=1;dt=1;items={};ownerDraw=1;vscroll=1;z=1}
)
/*}}*/


winform.listbox.onMeasureItem = function(measureItem){
    measureItem.itemHeight = 51;  
}
import win.imageList;
winform.listbox.onDrawItem = function(drawItem){
     gdi.selectBrush(
     
        function(hdc,pen,brush){
        
            var rc = drawItem.rcItem;
    		gdi.fillRect(hdc,0xFFFFFF,rc);
    		
    		if (drawItem.itemID > 0) {  
    			gdi.drawLine(hdc,rc.left, rc.top,rc.right, rc.top);
    		} 
    		
    		if (drawItem.itemState & 1/*_ODS_SELECTED*/) {  
        		//gdi.fillGradient(hdc,rc,0xFFFFFF, 0xC3BCA9,1/*_GRADIENT_FILL_RECT_V*/)
    			gdi.fillRect(hdc,0xFFF5E2,rc);
    		}
    		//加图标测试
    		win.imageList.shell( 0/*_SHIL_LARGE*/ ).draw(0,hdc,rc.left+20,rc.top+10);
    		
    		win.imageList.shell( 0/*_SHIL_LARGE*/ ).draw(0,hdc,rc.width()/2+200,rc.top+10);
    		font = ::LOGFONT(weight=300;color=0x9C9C9C); 
    		gdi.textOut(hdc,font,"打开",rc.width()/2+235, rc.top+20);
    		win.imageList.shell( 0/*_SHIL_JUMBO*/ ).draw(1,hdc,rc.width()/2+270,rc.top+10);
    		gdi.textOut(hdc,font,"文件夹",rc.width()/2+300, rc.top+20);
    		//加文字测试
    		var str = winform.listbox.getItemText(drawItem.itemID + 1);
    		var str2 = "9.88MB       -文件已删除"
    		var font = ::LOGFONT(weight=400;color=0x000000);
    		gdi.textOut(hdc,font,str,rc.left+60, rc.top+10);
    		font = ::LOGFONT(weight=300;color=0xB0B0B0); 
    		gdi.textOut(hdc,font,str2,rc.left+60, rc.top+30); 
    		
   		},drawItem.hDC,0xF5FDFF/*背景色*/,0xEEEEEE/*画笔色*/)
}
 
for(i=1;10){ 
	winform.listbox.add("网页操作小助手.zip");
}
//win.imageList
winform.show();
win.loopMessage();


2018-09-16   #2

添加listbox鼠标经过item项hover背景效果。

这个功能,试验了两种方式,

第一种方式:利用redraw()刷新启发重绘...,然后在自绘里面判断是否要绘制hover背景

关键代码如下:

var listboxsel = null;
var beforesel = null;
winform.listbox.onDrawItem = function(drawItem){
     gdi.selectBrush(
     
        function(hdc,pen,brush){

            var rc = drawItem.rcItem;
    		gdi.fillRect(hdc,0xFFFFFF,rc);
    		if (drawItem.itemID > 0) {  
    			gdi.drawLine(hdc,rc.left, rc.top,rc.right, rc.top);
    		} 
    		
    		if (drawItem.itemState & 1/*_ODS_SELECTED*/) {  
        		//gdi.fillGradient(hdc,rc,0xFFFFFF, 0xC3BCA9,1/*_GRADIENT_FILL_RECT_V*/)
    			gdi.fillRect(hdc,0xFFF5E2,rc);
    		}else {
    			if(listboxsel == (drawItem.itemID+1)){
    				gdi.fillRect(hdc,0xEEB7FF,rc);
    			}	
    		}
    		
    		//加图标测试
    		win.imageList.shell( 0/*_SHIL_LARGE*/ ).draw(0,hdc,rc.left+20,rc.top+10);
    		
    		win.imageList.shell( 0/*_SHIL_LARGE*/ ).draw(0,hdc,rc.width()/2+200,rc.top+10);
    		font = ::LOGFONT(weight=300;color=0x9C9C9C); 
    		gdi.textOut(hdc,font,"打开",rc.width()/2+235, rc.top+20);
    		win.imageList.shell( 0/*_SHIL_JUMBO*/ ).draw(1,hdc,rc.width()/2+270,rc.top+10);
    		gdi.textOut(hdc,font,"文件夹",rc.width()/2+300, rc.top+20);
    		//加文字测试
    		var str = winform.listbox.getItemText(drawItem.itemID + 1);
    		var str2 = "9.88MB       -文件已删除"
    		var font = ::LOGFONT(weight=400;color=0x000000);
    		gdi.textOut(hdc,font,str,rc.left+60, rc.top+10);
    		font = ::LOGFONT(weight=300;color=0xB0B0B0); 
    		gdi.textOut(hdc,font,str2,rc.left+60, rc.top+30); 
    		
   		},drawItem.hDC,0xF5FDFF/*背景色*/,0xEEEEEE/*画笔色*/)
}
 
for(i=1;60){ 
	winform.listbox.add("网页操作小助手.zip");
}

winform.listbox.wndproc = function(hwnd,message,wParam,lParam){
	if(message == 0x200/*_WM_MOUSEMOVE*/){
		
		var x,y = win.getMessagePos();  
        var item = winform.listbox.hitTest(x,y,true);
        if(listboxsel == item){
        		return ; 
		}else {
			listboxsel = item;
			
			winform.listbox.redraw();
			
/*
			if(beforesel == null){
				beforesel = listboxsel;
				
			}else {
				winform.listbox.invalidate(winform.listbox.getItemRect(beforesel),0)
				beforesel = listboxsel;
			}
			winform.listbox.invalidate(winform.listbox.getItemRect(item))
			winform.listbox.update();
*/
		}
	}

}

虽然这种方式也实现了hover效果,但是,listbox由于刷新导致整个闪烁。


第二种方式: 利用

listbox.invalidate(__/*可选使用::RECT()对象指定客户区*/) = 使窗口绘图区无效

listbox.update();//更新指定区域

结合拦截鼠标位置信息,判断有效和无效item

完整代码如下:

//GDI自绘
import win.ui;
/*DSG{{*/
var winform = win.form(text="listbox自绘(GDI方式)";right=757;bottom=467)
winform.add(
listbox={cls="listbox";left=12;top=11;right=745;bottom=457;bgcolor=16777215;clipch=1;db=1;dl=1;dr=1;dt=1;items={};ownerDraw=1;vscroll=1;z=1}
)
/*}}*/

winform.listbox.onMeasureItem = function(measureItem){
    measureItem.itemHeight = 51;  
}
import win.imageList;
import console
console.open()

var listboxsel = null;
var beforesel = null;
winform.listbox.onDrawItem = function(drawItem){
     gdi.selectBrush(
     
        function(hdc,pen,brush){

            var rc = drawItem.rcItem;
    		gdi.fillRect(hdc,0xFFFFFF,rc);
    		if (drawItem.itemID > 0) {  
    			gdi.drawLine(hdc,rc.left, rc.top,rc.right, rc.top);
    		} 
    		
    		if (drawItem.itemState & 1/*_ODS_SELECTED*/) {  
        		//gdi.fillGradient(hdc,rc,0xFFFFFF, 0xC3BCA9,1/*_GRADIENT_FILL_RECT_V*/)
    			gdi.fillRect(hdc,0xFFF5E2,rc);
    		}else {
    			if(listboxsel == (drawItem.itemID+1)){
    				gdi.fillRect(hdc,0xEEB7FF,rc);
    			}	
    		}
    		
    		//加图标测试
    		win.imageList.shell( 0/*_SHIL_LARGE*/ ).draw(0,hdc,rc.left+20,rc.top+10);
    		
    		win.imageList.shell( 0/*_SHIL_LARGE*/ ).draw(0,hdc,rc.width()/2+200,rc.top+10);
    		font = ::LOGFONT(weight=300;color=0x9C9C9C); 
    		gdi.textOut(hdc,font,"打开",rc.width()/2+235, rc.top+20);
    		win.imageList.shell( 0/*_SHIL_JUMBO*/ ).draw(1,hdc,rc.width()/2+270,rc.top+10);
    		gdi.textOut(hdc,font,"文件夹",rc.width()/2+300, rc.top+20);
    		//加文字测试
    		var str = winform.listbox.getItemText(drawItem.itemID + 1);
    		var str2 = "9.88MB       -文件已删除"
    		var font = ::LOGFONT(weight=400;color=0x000000);
    		gdi.textOut(hdc,font,str,rc.left+60, rc.top+10);
    		font = ::LOGFONT(weight=300;color=0xB0B0B0); 
    		gdi.textOut(hdc,font,str2,rc.left+60, rc.top+30); 
    		
   		},drawItem.hDC,0xF5FDFF/*背景色*/,0xEEEEEE/*画笔色*/)
}
 
for(i=1;60){ 
	winform.listbox.add("网页操作小助手.zip");
}

winform.listbox.wndproc = function(hwnd,message,wParam,lParam){
	if(message == 0x200/*_WM_MOUSEMOVE*/){
		
		var x,y = win.getMessagePos();  
        var item = winform.listbox.hitTest(x,y,true);
        if(listboxsel == item){
        		return ; 
		}else {
			listboxsel = item;
			if(beforesel == null){
				beforesel = listboxsel;
				
			}else {
				winform.listbox.invalidate(winform.listbox.getItemRect(beforesel),0)
				beforesel = listboxsel;
			}
			winform.listbox.invalidate(winform.listbox.getItemRect(item))
			winform.listbox.update();
		}
	}

}

winform.show();
win.loopMessage();


上面的代码也实现这个hover功能,效果比第一种方式好。基本无闪烁。

GIF2.gif

2018-09-16   #3

每行文件图标调用系统默认图标的方式:

import fsys.info;
//加图标测试
var sfi = fsys.info.get("D:\360安全浏览器下载\inst.exe", 0x4000/*_SHGFI_SYSICONINDEX*/ | 0x10/*_SHGFI_DISPLAYNAME*/);
    		
win.imageList.shell( 0/*_SHIL_LARGE*/ ).draw(sfi.iIcon,hdc,rc.left+20,rc.top+10);

image.png

2018-09-16   #4

浏览目录文件,添加到listbox中,并显示其图标和大小等信息

//GDI自绘
import win.ui;
import fonts.fontAwesome;
/*DSG{{*/
var winform = win.form(text="listbox自绘(GDI方式)";right=757;bottom=467)
winform.add(
listbox={cls="listbox";left=12;top=11;right=745;bottom=457;bgcolor=16777215;clipch=1;db=1;dl=1;dr=1;dt=1;items={};ownerDraw=1;vscroll=1;z=1}
)
/*}}*/

winform.listbox.onMeasureItem = function(measureItem){
    measureItem.itemHeight = 51;  
}
import win.imageList;
import console
console.open()

var listboxsel = null;
var beforesel = null;

import fsys;
import fsys.info;
import fsys.file;
var filename;
var boxTab = {};

var files,,dirs = ..fsys.list("D:\360安全浏览器下载");
for(i=1;#files)
{
	filename = files[i];
	var sfi = fsys.info.get(files[filename],0x10/*_SHGFI_USEFILEATTRIBUTES*/ | 0x4000/*_SHGFI_SYSICONINDEX*/ );
	var fileSize = tonumber(fsys.file(files[filename]).size64());
	if(fileSize/1024 >= 1){
    	if(fileSize/1024/1024 >= 1){
        	sizes = tostring(math.round(fileSize/1024/1024,2))++" MB";
    	}else {
        	sizes = tostring(math.round(fileSize/1024,2))++" KB";
    	}
        	
	}else {
    	sizes = tostring(fileSize)++" B";
	}
	
	table.mixin(boxTab,{ iImage = sfi.iIcon; text = string.toUnicode(filename); size = sizes });
	winform.listbox.add(table.tostring(boxTab))
}

winform.listbox.onDrawItem = function(drawItem){
     gdi.selectBrush(
     
        function(hdc,pen,brush){
            //获取并分解需要显示的数据(字符串转表)
			var strTab = eval(winform.listbox.getItemText(drawItem.itemID + 1))
            var rc = drawItem.rcItem;
    		gdi.fillRect(hdc,0xFFFFFF,rc);
    		if (drawItem.itemID > 0) {  
    			gdi.drawLine(hdc,rc.left, rc.top,rc.right, rc.top);
    		} 
    		
    		if (drawItem.itemState & 1/*_ODS_SELECTED*/) {  
    			gdi.fillRect(hdc,0xFFF5E2,rc);
    		}else {
    			if(listboxsel == (drawItem.itemID+1)){
    				gdi.fillRect(hdc,0xEEB7FF,rc);
    			}	
    		}
    		
    		//加图标测试	
    		win.imageList.shell( 0/*_SHIL_LARGE*/ ).draw(strTab.iImage,hdc,rc.left+20,rc.top+10);
    		
    		win.imageList.shell( 0/*_SHIL_LARGE*/ ).draw(0,hdc,rc.width()/2+200,rc.top+10);
    		var font = ::LOGFONT(weight=300;color=0x9C9C9C); 
    		gdi.textOut(hdc,font,"打开",rc.width()/2+235, rc.top+20);
    		win.imageList.shell( 0/*_SHIL_JUMBO*/ ).draw(1,hdc,rc.width()/2+270,rc.top+10);
    		gdi.textOut(hdc,font,"文件夹",rc.width()/2+300, rc.top+20);
    		font = ::LOGFONT(weight=700;color=0x9C9C9C;name='FontAwesome';h=-16); 
    		gdi.textOut(hdc,font,'\uF057',rc.width()/2+345, rc.top+20);
    		//加文字测试
    		font = ::LOGFONT(weight=400;color=0x000000);
    		gdi.textOut(hdc,font,strTab.text,rc.left+60, rc.top+10);
    		font = ::LOGFONT(weight=300;color=0xB0B0B0); 
    		gdi.textOut(hdc,font,strTab.size,rc.left+60, rc.top+30); 
    		
   		},drawItem.hDC,0xF5FDFF/*背景色*/,0xEEEEEE/*画笔色*/)
}
 
winform.listbox.wndproc = function(hwnd,message,wParam,lParam){
	if(message == 0x200/*_WM_MOUSEMOVE*/){
		
		var x,y = win.getMessagePos();  
        var item = winform.listbox.hitTest(x,y,true);
        if(item == null){
        	return ; 
        }
        if(listboxsel == item){
        		return ; 
		}else {
			listboxsel = item;
			if(beforesel == null){
				beforesel = listboxsel;
				
			}else {
				if(beforesel){
					winform.listbox.invalidate(winform.listbox.getItemRect(beforesel),0)	
				}
				beforesel = listboxsel;
			}
			winform.listbox.invalidate(winform.listbox.getItemRect(item))
			winform.listbox.update();
		}
	}

}

winform.show();
win.loopMessage();

image.png

2018-09-17   #5

增加右侧[删除]按键功能和按键动态效果(鼠标经过hover变色).

//GDI自绘
import win.ui;
import fonts.fontAwesome;
/*DSG{{*/
var winform = win.form(text="listbox自绘(GDI方式)";right=778;bottom=445;border="dialog frame")
winform.add(
button={cls="button";text="增加行";left=0;top=385;right=779;bottom=436;z=2};
listbox={cls="listbox";left=0;top=0;right=779;bottom=376;bgcolor=16777215;clipch=1;db=1;dl=1;dr=1;dt=1;items={};ownerDraw=1;vscroll=1;z=1}
)
/*}}*/

winform.listbox.onMeasureItem = function(measureItem){
    measureItem.itemHeight = 51;  
}
import win.imageList;
import console
console.open()

var listboxsel = null;
var beforesel = null;
var colorsel = false;

import fsys;
import fsys.info;
import fsys.file;
var filename;
var boxTab = {};

var files,,dirs = ..fsys.list("D:\BaiduNetdiskDownload");
for(i=1;#files)
{
	filename = files[i];
	var sfi = fsys.info.get(files[filename],0x10/*_SHGFI_USEFILEATTRIBUTES*/ | 0x4000/*_SHGFI_SYSICONINDEX*/ );
	var fileSize = tonumber(fsys.file(files[filename]).size64());
	if(fileSize/1024 >= 1){
    	if(fileSize/1024/1024 >= 1){
        	sizes = tostring(math.round(fileSize/1024/1024,2))++" MB";
    	}else {
        	sizes = tostring(math.round(fileSize/1024,2))++" KB";
    	}
        	
	}else {
    	sizes = tostring(fileSize)++" B";
	}
	
	table.mixin(boxTab,{ iImage = sfi.iIcon; text = filename; size = sizes });
	winform.listbox.add(table.tostring(boxTab))
}

winform.listbox.onDrawItem = function(drawItem){
     gdi.selectBrush(
     
        function(hdc,pen,brush){
            //获取并分解需要显示的数据(字符串转表)
			var strTab = eval(winform.listbox.getItemText(drawItem.itemID + 1))
            var rc = drawItem.rcItem;
    		gdi.fillRect(hdc,0xFFFFFF,rc);
    		if (drawItem.itemID > 0) {  
    			gdi.drawLine(hdc,rc.left, rc.top,rc.right, rc.top);
    		} 
    		
    		if (drawItem.itemState & 1/*_ODS_SELECTED*/) {  
    			gdi.fillRect(hdc,0xFFF5E2,rc);
    			if(colorsel){
    				font = ::LOGFONT(weight=700;color=0x6112FF;name='FontAwesome';h=-16); 
    				gdi.textOut(hdc,font,'\uF057',rc.width()/2+345, rc.top+20);
    			}else {
    				font = ::LOGFONT(weight=700;color=0x9C9C9C;name='FontAwesome';h=-16); 
    				gdi.textOut(hdc,font,'\uF057',rc.width()/2+345, rc.top+20);
    			}
    			
    		}else {
    			if(listboxsel == (drawItem.itemID+1)){
    				gdi.fillRect(hdc,0xEEB7FF,rc);
    			}	
    		}
    		
    		//加图标测试	
    		win.imageList.shell( 0/*_SHIL_LARGE*/ ).draw(strTab.iImage,hdc,rc.left+20,rc.top+10);
    		win.imageList.shell( 0/*_SHIL_LARGE*/ ).draw(0,hdc,rc.width()/2+200,rc.top+10);
    		var font = ::LOGFONT(weight=300;color=0x9C9C9C;); 
    		gdi.textOut(hdc,font,"打开",rc.width()/2+235, rc.top+20);
    		win.imageList.shell( 0/*_SHIL_JUMBO*/ ).draw(1,hdc,rc.width()/2+270,rc.top+10);
    		gdi.textOut(hdc,font,"文件夹",rc.width()/2+300, rc.top+20);

    		//加文字测试
    		font = ::LOGFONT(weight=400;color=0x000000);
    		gdi.textOut(hdc,font,strTab.text,rc.left+60, rc.top+10);
    		font = ::LOGFONT(weight=300;color=0xB0B0B0); 
    		gdi.textOut(hdc,font,strTab.size,rc.left+60, rc.top+30); 
    		
   		},drawItem.hDC,0xF5FDFF/*背景色*/,0xEEEEEE/*画笔色*/)
}
 
winform.listbox.wndproc = function(hwnd,message,wParam,lParam){
    select(message) {
    	case 0x200/*_WM_MOUSEMOVE*/ {
    		var x,y = win.getMessagePos();  
        	var item = winform.listbox.hitTest(x,y,true);
        	if(item == null){
        		return ; 
        	}
        	
    		if(listboxsel == item){	/* 若鼠标在同一行item内游动 */
    			/* 首先,判断是否要显示[删除]按钮,通过判断鼠标是不是在选中item行内 */
            	if(listboxsel == winform.listbox.selIndex){
            		x,y = win.toClient(winform.listbox.hwnd,x,y);
					var rc = winform.listbox.getItemRect(item);
					rc.left = rc.width()/2+345;
					rc.top = rc.top+20;
					rc.bottom = rc.bottom-20 ;
					//判断鼠标游动的区间是不是在[删除]按钮范围
					if( ::PtInRect(rc,x,y) ){
						if(colorsel == false){	//鼠标从[删除]按钮外部移动到内部区域
							colorsel = true;
							//设置更新区,并更新
							winform.listbox.invalidate(winform.listbox.getItemRect(item))
							winform.listbox.update();
							return;	
						}
						return ; //一直在内部区域游动,则不更新
					}else {
						if(colorsel == true){	//鼠标从内到外
							colorsel = false;
							//设置更新区,并更新
							winform.listbox.invalidate(winform.listbox.getItemRect(item))
							winform.listbox.update();
							return ; 
						}
						return ; //一直在外部区域游动,则不更新
					} 	
            	}
            	return ; 
			}else {
				//设置hover效果
				listboxsel = item;
				if(beforesel == null){	//第一次执行,初始化
					beforesel = listboxsel;
					
				}else {
					//先关闭上次绘制区域
					if(beforesel){
						winform.listbox.invalidate(winform.listbox.getItemRect(beforesel),0)	
					}
					beforesel = listboxsel;
				}
				//绘制当前区域
				winform.listbox.invalidate(winform.listbox.getItemRect(item));
				winform.listbox.update();
			}
    	}
    	case 0x202/*_WM_LBUTTONUP*/ {
    		if(colorsel){	/* 若鼠标在删除按钮区域内单击了 */
				var selindex = winform.listbox.selIndex
				var strTab = winform.listbox.getItemText(selindex);
				var tabStr = eval(strTab)
				var ret = winform.msgboxTest("您确定要删除 ["++tabStr.text++"] 文件吗?");
				if(ret){
					winform.listbox.delete(selindex);
					colorsel = false;
				}
			}
    	}
    	else {
    	}
    }
}

winform.button.oncommand = function(id,event){
    var sstab = {};
	table.mixin(sstab,{ iImage = 0; text = "增加示例行"; size = "7.7 MB" });
	winform.listbox.add(table.tostring(sstab))	
}

winform.show();
win.loopMessage();

GIF33.gif

2018-09-17   #6

修改界面中[删除] / [打开] / [文件夹] 鼠标样式效果,并增加对应功能.

修改界面: 不选中项目的时候,不出现 功能 按键.

GIF.gif

//GDI自绘
import win.ui;
import fonts.fontAwesome;
/*DSG{{*/
var winform = win.form(text="listbox自绘(GDI方式)";right=778;bottom=445;border="dialog frame")
winform.add(
button={cls="button";text="增加行";left=0;top=385;right=779;bottom=436;z=2};
listbox={cls="listbox";left=0;top=0;right=779;bottom=376;bgcolor=16777215;clipch=1;db=1;dl=1;dr=1;dt=1;items={};ownerDraw=1;vscroll=1;z=1}
)
/*}}*/

winform.listbox.onMeasureItem = function(measureItem){
    measureItem.itemHeight = 51;  
}

import win.imageList;
import process;

var listboxsel = null;
var beforesel = null;
var colorsel = false;
var opensel = false;
var filesel = false;

import fsys;
import fsys.info;
import fsys.file;
var filename;
var boxTab = {};

var files,,dirs = ..fsys.list("D:\BaiduNetdiskDownload");
for(i=1;#files)
{
	filename = files[i];
	var sfi = fsys.info.get(files[filename],0x10/*_SHGFI_USEFILEATTRIBUTES*/ | 0x4000/*_SHGFI_SYSICONINDEX*/ );
	var fileSize = tonumber(fsys.file(files[filename]).size64());
	if(fileSize/1024 >= 1){
    	if(fileSize/1024/1024 >= 1){
        	sizes = tostring(math.round(fileSize/1024/1024,2))++" MB";
    	}else {
        	sizes = tostring(math.round(fileSize/1024,2))++" KB";
    	}
        	
	}else {
    	sizes = tostring(fileSize)++" B";
	}
	
	table.mixin(boxTab,{ iImage = sfi.iIcon; text = filename; size = sizes ; filePath = files[filename] });
	winform.listbox.add(table.tostring(boxTab))
}

winform.listbox.onDrawItem = function(drawItem){
     gdi.selectBrush(
     
        function(hdc,pen,brush){
            //获取并分解需要显示的数据(字符串转表)
			var strTab = eval(winform.listbox.getItemText(drawItem.itemID + 1))
            var rc = drawItem.rcItem;
    		gdi.fillRect(hdc,0xFFFFFF,rc);
    		if (drawItem.itemID > 0) {  
    			gdi.drawLine(hdc,rc.left, rc.top,rc.right, rc.top);
    		} 		
    		if (drawItem.itemState & 1/*_ODS_SELECTED*/) {  
    			gdi.fillRect(hdc,0xFFF5E2,rc);
    			//删除文件
    			if(colorsel){
    				font = ::LOGFONT(weight=700;color=0x6112FF;name='FontAwesome';h=-16); 
    				gdi.textOut(hdc,font,'\uF057',rc.width()/2+345, rc.top+20);
    			}else {
    				font = ::LOGFONT(weight=700;color=0x9C9C9C;name='FontAwesome';h=-16); 
    				gdi.textOut(hdc,font,'\uF057',rc.width()/2+345, rc.top+20);
    			}
    			//打开文件
    			if(opensel){
    				font = ::LOGFONT(weight=500;color=0x6112FF;name='FontAwesome';h=-16); 
    				gdi.textOut(hdc,font,'\uF0F6 打开',rc.width()/2+190, rc.top+20);
    			}else {
    				font = ::LOGFONT(weight=300;color=0x9C9C9C;name='FontAwesome';h=-16); 
    				gdi.textOut(hdc,font,'\uF0F6 打开',rc.width()/2+190, rc.top+20);
    			}
    			//打开文件夹
    			if(filesel){
    				font = ::LOGFONT(weight=500;color=0x6112FF;name='FontAwesome';h=-16); 
    				gdi.textOut(hdc,font,'\uF115 文件夹',rc.width()/2+260, rc.top+20);
    			}else {
    				font = ::LOGFONT(weight=300;color=0x9C9C9C;name='FontAwesome';h=-16); 
    				gdi.textOut(hdc,font,'\uF115 文件夹',rc.width()/2+260, rc.top+20);
    			}
    		}else {
    			if(listboxsel == (drawItem.itemID+1)){
    				gdi.fillRect(hdc,0xEEB7FF,rc);
    			}	
    		}

    		//文件图标
    		win.imageList.shell( 0/*_SHIL_LARGE*/ ).draw(strTab.iImage,hdc,rc.left+20,rc.top+10);
    		//文件名
    		font = ::LOGFONT(weight=400;color=0x000000);
    		gdi.textOut(hdc,font,strTab.text,rc.left+60, rc.top+10);
    		//文件大小
    		font = ::LOGFONT(weight=300;color=0xB0B0B0); 
    		gdi.textOut(hdc,font,strTab.size,rc.left+60, rc.top+30); 
    		
   		},drawItem.hDC,0xF5FDFF/*背景色*/,0xEEEEEE/*画笔色*/)
}
 
winform.listbox.wndproc = function(hwnd,message,wParam,lParam){
    select(message) {
        case 0x200/*_WM_MOUSEMOVE*/ {
            var x,y = win.getMessagePos();  
            var item = winform.listbox.hitTest(x,y,true);
            if(item == null){
                return ; 
            }
             
            if(listboxsel == item){   /* 若鼠标在同一行item内游动 */
                /* 首先,判断是否要显示[删除]按钮,通过判断鼠标是不是在选中item行内 */
                if(listboxsel == winform.listbox.selIndex){
                    x,y = win.toClient(winform.listbox.hwnd,x,y);
                    for(i=1;3;1){
                    	select(i) {
                    		case 1 {	//open
                    			var rc = winform.listbox.getItemRect(item);
                    			rc.left = rc.width()/2+190;
                    			rc.right = rc.left+60;
                    			rc.top = rc.top+10;
                    			rc.bottom = rc.bottom-10 ;
                    			//判断鼠标游动的区间是不是在[删除]按钮范围
                    			if( ::PtInRect(rc,x,y) ){
                        			if(opensel == false){    //鼠标从[删除]按钮外部移动到内部区域
                            			opensel = true;
                            			//设置更新区,并更新
                            			winform.listbox.invalidate(winform.listbox.getItemRect(item))
                            			winform.listbox.update();
                            			break ; 
                        			}
                        			continue ; //一直在内部区域游动,则不更新
                    			}else {
                        			if(opensel == true){ //鼠标从内到外
                            			opensel = false;
                            			//设置更新区,并更新
                            			winform.listbox.invalidate(winform.listbox.getItemRect(item))
                            			winform.listbox.update();
                            			break ; 
                        			}
                        			continue ; //一直在外部区域游动,则不更新
                    			}
                    						
                    			
                    		}
                    		case 2 {	//file
                    			var filerc = winform.listbox.getItemRect(item);
                    			filerc.left = filerc.width()/2+260;
                    			filerc.right = filerc.left+70;
                    			filerc.top = filerc.top+10;
                    			filerc.bottom = filerc.bottom-10 ;
                    			//判断鼠标游动的区间是不是在[删除]按钮范围
                    			if( ::PtInRect(filerc,x,y) ){
                        			if(filesel == false){    //鼠标从[删除]按钮外部移动到内部区域
                            			filesel = true;
                            			//设置更新区,并更新
                            			winform.listbox.invalidate(winform.listbox.getItemRect(item))
                            			winform.listbox.update();
                            			break; 
                        			}
                        			continue ; //一直在内部区域游动,则不更新
                    			}else {
                        			if(filesel == true){ //鼠标从内到外
                            			filesel = false;
                            			//设置更新区,并更新
                            			winform.listbox.invalidate(winform.listbox.getItemRect(item))
                            			winform.listbox.update();
                            			break ; 
                        			}
                        			continue ; //一直在外部区域游动,则不更新
                    			}
                    			
                    		}
                    		case 3 {	//del
                    			var delrc = winform.listbox.getItemRect(item);
                    			delrc.left = delrc.width()/2+345;
                    			delrc.top = delrc.top+20;
                    			delrc.bottom = delrc.bottom-20 ;
                    			//判断鼠标游动的区间是不是在[删除]按钮范围
                    			if( ::PtInRect(delrc,x,y) ){
                        			if(colorsel == false){    //鼠标从[删除]按钮外部移动到内部区域
                            			colorsel = true;
                            			//设置更新区,并更新
                            			winform.listbox.invalidate(winform.listbox.getItemRect(item))
                            			winform.listbox.update();
                            			break; 
                        			}
                        			continue ; //一直在内部区域游动,则不更新
                    			}else {
                        			if(colorsel == true){ //鼠标从内到外
                            			colorsel = false;
                            			//设置更新区,并更新
                            			winform.listbox.invalidate(winform.listbox.getItemRect(item))
                            			winform.listbox.update();
                            			break ; 
                        			}
                        			continue ; //一直在外部区域游动,则不更新
                    			}
                    		}
                    	}
                    } 
                }
                return ; 
			}else {
				//设置hover效果
				listboxsel = item;
				if(beforesel == null){	//第一次执行,初始化
					beforesel = listboxsel;
					
				}else {
					//先关闭上次绘制区域
					if(beforesel){
						winform.listbox.invalidate(winform.listbox.getItemRect(beforesel),0)	
					}
					beforesel = listboxsel;
				}
				//绘制当前区域
				winform.listbox.invalidate(winform.listbox.getItemRect(item));
				winform.listbox.update();
			}
    	}
    	case 0x202/*_WM_LBUTTONUP*/ {
    		//删除功能
    		if(colorsel){	/* 若鼠标在删除按钮区域内单击了 */
				var selindex = winform.listbox.selIndex
				var strTab = winform.listbox.getItemText(selindex);
				var tabStr = eval(strTab)
				var ret = winform.msgboxTest("您确定要删除 ["++tabStr.text++"] 文件吗?");
				if(ret){
					winform.listbox.delete(selindex);
					colorsel = false;
				}
				return ; 
			};
			//打开文件
			if(opensel){	/* 若鼠标在打开按钮区域内单击了 */
				var selindex = winform.listbox.selIndex
				var strTab = winform.listbox.getItemText(selindex);
				var tabStr = eval(strTab)
				process.execute(tabStr.filePath);
				return ; 
			}
			//打开文件夹
			if(filesel){	/* 若鼠标在打开按钮区域内单击了 */
				var selindex = winform.listbox.selIndex
				var strTab = winform.listbox.getItemText(selindex);
				var tabStr = eval(strTab)
				var path = io.splitpath(tabStr.filePath);
				process.execute(path.dir);
				return ; 
			}
    	}
    	else {
    	}
    }
}

winform.button.oncommand = function(id,event){
    var sstab = {};
	table.mixin(sstab,{ iImage = 0; text = "增加示例行"; size = "7.7 MB" });
	winform.listbox.add(table.tostring(sstab))	
}

winform.show();
win.loopMessage();


2018-09-17   #7

也许有些人就是喜欢文件和文件夹功能一直显示着,那么可以使用下面的代码

删除了必须选中才能执行 打开 和文件夹 的功能,好处是鼠标点哪就执行哪个。

自绘里面增加了一些判断,展示更好的动态效果。

image.png

//GDI自绘
import win.ui;
import fonts.fontAwesome;
/*DSG{{*/
var winform = win.form(text="listbox自绘(GDI方式)";right=778;bottom=445;border="dialog frame")
winform.add(
button={cls="button";text="增加行";left=0;top=385;right=779;bottom=436;z=2};
listbox={cls="listbox";left=0;top=0;right=779;bottom=376;bgcolor=16777215;clipch=1;db=1;dl=1;dr=1;dt=1;items={};msel=1;ownerDraw=1;vscroll=1;z=1}
)
/*}}*/

winform.listbox.onMeasureItem = function(measureItem){
    measureItem.itemHeight = 51;  
}

import win.imageList;
import process;

var listboxsel = null;
var beforesel = null;
var colorsel = false;
var opensel = false;
var filesel = false;

import fsys;
import fsys.info;
import fsys.file;
import fsys.dlg;
var filename;
var boxTab = {};

var dirPath;
if( !io.exist(dirPath) ) {
	dirPath = fsys.dlg.opendir()
}
if(!dirPath){
	dirPath = "D:\";
}
var files,,dirs = ..fsys.list(dirPath);
for(i=1;#files)
{
        filename = files[ i ];
        var sfi = fsys.info.get(files[filename],0x10/*_SHGFI_USEFILEATTRIBUTES*/ | 0x4000/*_SHGFI_SYSICONINDEX*/ );
        var file = fsys.file(files[filename],"r");
        var fileSize = tonumber(file.size64());
        file.close();//不关掉后面删除就会出错
        if(fileSize/1024 >= 1){
            if(fileSize/1024/1024 >= 1){
                sizes = tostring(math.round(fileSize/1024/1024,2))++" MB";
            }else {
                sizes = tostring(math.round(fileSize/1024,2))++" KB";
            }
                
        }else {
            sizes = tostring(fileSize)++" B";
        }
        
        table.mixin(boxTab,{ iImage = sfi.iIcon; text = filename; size = sizes ; filePath = files[filename] });
        winform.listbox.add(table.tostring(boxTab))
}

winform.listbox.onDrawItem = function(drawItem){
     gdi.selectBrush(
     
        function(hdc,pen,brush){
            //获取并分解需要显示的数据(字符串转表)
                        var strTab = eval(winform.listbox.getItemText(drawItem.itemID + 1))
            var rc = drawItem.rcItem;
                    gdi.fillRect(hdc,0xFFFFFF,rc);
                    if (drawItem.itemID > 0) {  
                            gdi.drawLine(hdc,rc.left, rc.top,rc.right, rc.top);
                    }                 
                    if (drawItem.itemState & 1/*_ODS_SELECTED*/) {  
                            gdi.fillRect(hdc,0xFFF5E2,rc); 
                    }else {
                            if(listboxsel == (drawItem.itemID+1)){
                                    gdi.fillRect(hdc,0xEEB7FF,rc);
                            }             
                    }
							
					//删除文件
                    if(colorsel){
                        var x,y = win.getMessagePos();  
            			var item = winform.listbox.hitTest(x,y,true);

            			if((drawItem.itemID+1) == item){
            				font = ::LOGFONT(weight=700;color=0x6112FF;name='FontAwesome';h=-16); 
                            gdi.textOut(hdc,font,'\uF057',rc.width()/2+345, rc.top+20);
            			}else {
            				font = ::LOGFONT(weight=700;color=0x9C9C9C;name='FontAwesome';h=-16); 
                            gdi.textOut(hdc,font,'\uF057',rc.width()/2+345, rc.top+20);
            			}
                    }else {
                            font = ::LOGFONT(weight=700;color=0x9C9C9C;name='FontAwesome';h=-16); 
                            gdi.textOut(hdc,font,'\uF057',rc.width()/2+345, rc.top+20);
                    }
                    
                    if(opensel){
                        var x,y = win.getMessagePos();  
            			var item = winform.listbox.hitTest(x,y,true);

            			if((drawItem.itemID+1) == item){
            				font = ::LOGFONT(weight=500;color=0x6112FF;name='FontAwesome';h=-16); 
                            gdi.textOut(hdc,font,'\uF0F6 打开',rc.width()/2+190, rc.top+20);
            			}else {
            				font = ::LOGFONT(weight=300;color=0x9C9C9C;name='FontAwesome';h=-16); 
                            gdi.textOut(hdc,font,'\uF0F6 打开',rc.width()/2+190, rc.top+20);
            			}
                            
                    }else {
                            font = ::LOGFONT(weight=300;color=0x9C9C9C;name='FontAwesome';h=-16); 
                            gdi.textOut(hdc,font,'\uF0F6 打开',rc.width()/2+190, rc.top+20);
                    }
                    
                    if(filesel){
                        var x,y = win.getMessagePos();  
            			var item = winform.listbox.hitTest(x,y,true);

            			if((drawItem.itemID+1) == item){
            				font = ::LOGFONT(weight=500;color=0x6112FF;name='FontAwesome';h=-16); 
                            gdi.textOut(hdc,font,'\uF115 文件夹',rc.width()/2+260, rc.top+20);
            			}else {
            				font = ::LOGFONT(weight=300;color=0x9C9C9C;name='FontAwesome';h=-16); 
                            gdi.textOut(hdc,font,'\uF115 文件夹',rc.width()/2+260, rc.top+20); 
            			}
                    
                    }else {
                            font = ::LOGFONT(weight=300;color=0x9C9C9C;name='FontAwesome';h=-16); 
                            gdi.textOut(hdc,font,'\uF115 文件夹',rc.width()/2+260, rc.top+20); 
                    }

                    //文件图标
                    win.imageList.shell( 0/*_SHIL_LARGE*/ ).draw(strTab.iImage,hdc,rc.left+20,rc.top+10);
                    //文件名
                    font = ::LOGFONT(weight=400;color=0x000000);
                    gdi.textOut(hdc,font,strTab.text,rc.left+60, rc.top+10);
                    //文件大小
                    font = ::LOGFONT(weight=300;color=0xB0B0B0); 
                    gdi.textOut(hdc,font,strTab.size,rc.left+60, rc.top+30); 
                    
                   },drawItem.hDC,0xF5FDFF/*背景色*/,0xEEEEEE/*画笔色*/)
}
 
winform.listbox.wndproc = function(hwnd,message,wParam,lParam){
    select(message) {
        case 0x200/*_WM_MOUSEMOVE*/ {
            var x,y = win.getMessagePos();  
            var item = winform.listbox.hitTest(x,y,true);
            if(item == null){
                return ; 
            }
             
            if(listboxsel == item){   /* 若鼠标在同一行item内游动 */
                    x,y = win.toClient(winform.listbox.hwnd,x,y);
                    for(i=1;3;1){
                            select(i) {
                                    case 1 {        //open
                                            var rc = winform.listbox.getItemRect(item);
                                            rc.left = rc.width()/2+190;
                                            rc.right = rc.left+60;
                                            rc.top = rc.top+10;
                                            rc.bottom = rc.bottom-10 ;
                                            //判断鼠标游动的区间是不是在[删除]按钮范围
                                            if( ::PtInRect(rc,x,y) ){
                                                if(opensel == false){    //鼠标从[删除]按钮外部移动到内部区域
                                                    opensel = true;
                                                    //设置更新区,并更新
                                                    winform.listbox.invalidate(winform.listbox.getItemRect(item))
                                                    winform.listbox.update();
                                                    break ; 
                                                }
                                                continue ; //一直在内部区域游动,则不更新
                                            }else {
                                                if(opensel == true){ //鼠标从内到外
                                                    opensel = false;
                                                    //设置更新区,并更新
                                                    winform.listbox.invalidate(winform.listbox.getItemRect(item))
                                                    winform.listbox.update();
                                                    break ; 
                                                }
                                                continue ; //一直在外部区域游动,则不更新
                                            }
                                                                    
                                            
                                    }
                                    case 2 {        //file
                                            var filerc = winform.listbox.getItemRect(item);
                                            filerc.left = filerc.width()/2+260;
                                            filerc.right = filerc.left+70;
                                            filerc.top = filerc.top+10;
                                            filerc.bottom = filerc.bottom-10 ;
                                            //判断鼠标游动的区间是不是在[删除]按钮范围
                                            if( ::PtInRect(filerc,x,y) ){
                                                if(filesel == false){    //鼠标从[删除]按钮外部移动到内部区域
                                                    filesel = true;
                                                    //设置更新区,并更新
                                                    winform.listbox.invalidate(winform.listbox.getItemRect(item))
                                                    winform.listbox.update();
                                                    break; 
                                                }
                                                continue ; //一直在内部区域游动,则不更新
                                            }else {
                                                if(filesel == true){ //鼠标从内到外
                                                    filesel = false;
                                                    //设置更新区,并更新
                                                    winform.listbox.invalidate(winform.listbox.getItemRect(item))
                                                    winform.listbox.update();
                                                    break ; 
                                                }
                                                continue ; //一直在外部区域游动,则不更新
                                            }
                                            
                                    }
                                    case 3 {        //del
                                            var delrc = winform.listbox.getItemRect(item);
                                            delrc.left = delrc.width()/2+345;
                                            delrc.top = delrc.top+20;
                                            delrc.bottom = delrc.bottom-20 ;
                                            //判断鼠标游动的区间是不是在[删除]按钮范围
                                            if( ::PtInRect(delrc,x,y) ){
                                                if(colorsel == false){    //鼠标从[删除]按钮外部移动到内部区域
                                                    colorsel = true;
                                                    //设置更新区,并更新
                                                    winform.listbox.invalidate(winform.listbox.getItemRect(item))
                                                    winform.listbox.update();
                                                    break; 
                                                }
                                                continue ; //一直在内部区域游动,则不更新
                                            }else {
                                                if(colorsel == true){ //鼠标从内到外
                                                    colorsel = false;
                                                    //设置更新区,并更新
                                                    winform.listbox.invalidate(winform.listbox.getItemRect(item))
                                                    winform.listbox.update();
                                                    break ; 
                                                }
                                                continue ; //一直在外部区域游动,则不更新
                                            }
                                    }
                            }
                    } 
                return ; 
                        }else {
                                //设置hover效果
                                listboxsel = item;
                                if(beforesel == null){        //第一次执行,初始化
                                        beforesel = listboxsel;
                                        
                                }else {
                                        //先关闭上次绘制区域
                                        if(beforesel){
                                                winform.listbox.invalidate(winform.listbox.getItemRect(beforesel),0)        
                                        }
                                        beforesel = listboxsel;
                                }
                                //绘制当前区域
                                winform.listbox.invalidate(winform.listbox.getItemRect(item));
                                winform.listbox.update();
                        }
            }
            case 0x202/*_WM_LBUTTONUP*/ {
                    //删除功能
                    if(colorsel){        /* 若鼠标在删除按钮区域内单击了 */
                                var selindex = winform.listbox.selIndex
                                var strTab = winform.listbox.getItemText(selindex);
                                var tabStr = eval(strTab)
                                var ret = winform.msgboxTest("您确定要删除 ["++tabStr.text++"] 文件吗?");
                                if(ret){
                                        winform.listbox.delete(selindex);
                                        colorsel = false;
                                }
                                return ; 
                        };
                        //打开文件
                        if(opensel){        /* 若鼠标在打开按钮区域内单击了 */
                                var selindex = winform.listbox.selIndex
                                var strTab = winform.listbox.getItemText(selindex);
                                var tabStr = eval(strTab)
                                process.execute(tabStr.filePath);
                                return ; 
                        }
                        //打开文件夹
                        if(filesel){        /* 若鼠标在打开按钮区域内单击了 */
                                var selindex = winform.listbox.selIndex
                                var strTab = winform.listbox.getItemText(selindex);
                                var tabStr = eval(strTab)
                                var path = io.splitpath(tabStr.filePath);
                                process.execute(path.dir);
                                return ; 
                        }
            }
            else {
            }
    }
}

winform.button.oncommand = function(id,event){
    var sstab = {};
        table.mixin(sstab,{ iImage = 0; text = "增加示例行"; size = "7.7 MB" });
        winform.listbox.add(table.tostring(sstab))        
}

winform.show();
win.loopMessage();


2018-09-17   #8

如果文件名太长怎么办?

我们可以进行判断和截取。

//文件名
font = ::LOGFONT(weight=400;color=0x000000);
if(string.len(strTab.text)>45){
   gdi.textOut(hdc,font,string.left(strTab.text,3,true)++"..."++string.right(strTab.text,19,true),rc.left+60, rc.top+10);
}else {
   gdi.textOut(hdc,font,strTab.text,rc.left+60, rc.top+10);
}

利用string.left(str,len,true)实现按照字符数进行截取。

登录后方可回帖

登 录
信息栏
本站永久域名:HtmLayout.Cn
纯私人站,当笔记本用的,学到哪写到哪,目前正在学aardio+halcon机器视觉.
本 站 主 站:Stm32cube中文网
Aardio 官方站:Aardio官方
Aardio最新功能:Aardio官方更新日志
aardio在线手册Aardio在线手册
Htmlayout皮肤Htmlayout皮肤引擎介绍
黑猫Aar教程网:简码编程
C大Aardio论坛:Aar爱好者论坛
AARDIO语言QQ群:70517368
赞助商:才仁机械
下载站:非凡软件站
Loading...