一步一步自绘listbox实现html中的伸缩列表导航栏功能

By admin at 2021-08-04 • 0人收藏 • 1333人看过

在html中伸缩导航栏, 用的应该是比较常见的控件,一般放置软件左侧, 诸如下面图片中的形式

image.pngimage.pngimage.png

前面写过自绘listbox实现音乐播放器界面, 这次参照上次的理论和代码改造为伸缩导航栏


代码和库已经封装完毕, 需要下载的请看

楼下 2 楼代码

如果代码有更新 , 会继续盖楼更新, 请持续关注


13 个回复 | 最后更新于 2021-09-10
2021-08-07   #1

注意:

此楼为写库过程中使用过的测试代码 , 只是为了演示此库也可以使用漂亮的滚动条, 最新封装库和完整工程代码看楼下楼层.


把plus模拟滚动条加上看看效果, 这里参考https://www.htmlayout.cn/t/372#Post1043

简单的调试下单元格大小适应滚动条 , 似乎效果看着还不错, 哈

GIF.gif

import fonts.fontAwesome;
//GDI自绘
import win.ui;
/*DSG{{*/
var winform = win.form(text="listbox自绘伸缩导航栏";right=715;bottom=449;bgcolor=12639424)
winform.add(
listbox={cls="listbox";left=0;top=0;right=145;bottom=450;bgcolor=16777215;db=1;dl=1;dt=1;items={};ownerDraw=1;z=1};
static={cls="static";left=147;top=0;right=712;bottom=450;align="center";bgcolor=15780518;center=1;db=1;dl=1;dr=1;dt=1;font=LOGFONT(h=-47);z=2}
)
/*}}*/

import win.ui.ctrl.plus;
    class scrollbarEx{
        ctor(ctrl,iWidth = 10,itemHeight = 15){//listbox,滚动条宽度、列表项行高
            if(!ctrl[["hwnd"]]) error("参数必须是窗口对象",2);  
            this = ctrl;
            var rc = this.getRect()
            rc.bottom += itemHeight;
            this.modifyStyle(,0x4000000/*_WS_CLIPSIBLINGS*/);
            var dyPlus = winform.add(
                plus = {cls="plus";left = rc.right-iWidth;top=rc.top; bottom=rc.bottom;width = iWidth;hide=1;bgcolor=-8750470;border={radius=5};color=14587648;foreTop=50;paddingLeft=1;paddingRight=1;dr=1;dt=1;db=1;z=1}
            );
            sb = dyPlus.plus; 
            ..win.setPos(sb.hwnd,,,,,0);
            ..win.setPos(this.hwnd,,,,,1);
            sb.skin(style)
            var max = this.count * itemHeight; //显示区域高度 = 总项目得高度
               var overstep = (max - rc.height()) / itemHeight//溢出表项计数 = 超出窗口显示,额外的项目
               var thumb = ..math.floor(rc.height() / max * sb.height);   
               var trackPos =     overstep;
            sb.setTrackbarRange(0,overstep);
            sb.foreTop = thumb;
            sb.progressPos = trackPos
            var step = 1 //..math.floor( (max + rc.height()) / sb.foreTop );//绝对高度的时候计算步进
            sb.show(overstep > 0);
            sb.onPosChanged = function( pos,thumbTrack ){
                if(thumbTrack){ 
                    trackPos = overstep - pos;
                    //..io.print(trackPos)
                    ::SendMessageInt(this.hwnd, 0x115/*_WM_VSCROLL*/,::MAKELONG(4/*_SB_THUMBPOSITION*/,trackPos), 0);
                }   
            }
               this.wndproc = function(hwnd,message,wParam,lParam){
                    select(message) {
                        case 0x20A/*_WM_MOUSEWHEEL*/ {
                        if( ::HIWORD(wParam) & 0x8000){ 
                            if(sb.stepProgress(-step)){::SendMessageInt(this.hwnd, 0x115/*_WM_VSCROLL*/, 1/*_SB_LINEDOWN*/, 0);} 
                        }else { 
                            ::SendMessageInt(this.hwnd, 0x115/*_WM_VSCROLL*/,  0/*_SB_LINEUP*/, 0);
                               sb.stepProgress(step);
                            }
                        return 0;      
                        }case 0x115/*_WM_VSCROLL*/{
                            //..io.print(::HIWORD(wParam),::LOWORD(wParam))     
                        }case 0x200/*_WM_MOUSEMOVE*/{
                            if(wParam & 1/*_MK_LBUTTON*/){
                                var x,y = ..win.getMessagePos(lParam);
                              var topIndex = ::SendMessageInt(this.hwnd,0x18E/*_LB_GETTOPINDEX*/,0,0);
                              /*获取列表框中第一个可见项的索引。最初,索引 0 的项位于列表框的顶部,
                              但如果列表框内容已滚动,则另一项可能位于顶部。多列列表框中的第一个可见项是左上角项。*/
                              trackPos = overstep - topIndex;
                              sb.progressPos = trackPos;
                            }
                        }case 0x181/*_LB_INSERTSTRING*/{//LB_ADDFILE、LB_ADDSTRING没有尝试,不知道要不要一起处理。 
                            max = (this.count + 1) * itemHeight; //显示区域高度,在_LB_INSERTSTRING事件中,添加表项在事件之前发生实际表项数目要 + 1
                           overstep = (max - rc.height()) / itemHeight//溢出表项计数 
                           thumb = ..math.floor(rc.height() / max * sb.height);    
                           var topIndex = ::SendMessageInt(this.hwnd,0x18E/*_LB_GETTOPINDEX*/,0,0);
                           trackPos =  overstep - topIndex;
                        sb.setTrackbarRange(0,overstep);
                        sb.foreTop = thumb;
                        sb.progressPos = trackPos;
                        sb.show(overstep > 0);
                        }case 0x182/*_LB_DELETESTRING*/{
                        max = (this.count - 1) * itemHeight; //显示区域高度,在_LB_DELETESTRING事件中,删除表项在事件之后发生,实际表项数目要 - 1
                           overstep = (max - rc.height()) / itemHeight//溢出表项计数 
                           thumb = ..math.floor(rc.height() / max * sb.height);    
                           trackPos = overstep;
                        sb.setTrackbarRange(0,overstep);
                        sb.foreTop = thumb;
                        sb.progressPos = trackPos;
                        sb.show(overstep > 0);
                        }case 0x184/*_LB_RESETCONTENT*/{
                            sb.show(false); 
                        }   
                    }  
              }
        };
     
    }
    namespace scrollbarEx{  
        style = {
            background={
                default=0xFFE1E1E1; 
            };
            color={
                default = 0xBD15A43D;
                hover  = 0xFF15A43D;
                active  = 0xFF15A43D;
            }
       } 
    }




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

import console
console.open()

var MenuList = {
    {
        groupName = "应用管理";
        二级菜单 = {
			"应用_demo1";
			"应用_demo2";
			"应用_demo3";
			"应用_demo4";
		},
        展开=false;
    },
    {
        groupName = "协议管理";
        二级菜单 = {
			"协议_demo1";
			"协议_demo2";
			"协议_demo3";
		},
        展开=false;
    },
    {
        groupName = "日志管理";
        二级菜单 = {
			"日志_demo1";
			"日志_demo2";
			"日志_demo3";
			"日志_demo4";
		},
        展开=false;
    },
    {
        groupName = "系统管理";
        二级菜单 = {
			"系统_demo1";
			"系统_demo2";
		},
        展开=false;
    },
};

for(k,v in MenuList){
	winform.listbox.add(v.groupName);
}

winform.listbox.oncommand = function(id,event){
    var index = winform.listbox.selIndex;//winform.listbox.hitTest();
	if(index){
		var name = winform.listbox.getItemText(index);
		var subClick = true;
		for(i=1;#MenuList;1){
			if(MenuList[i].groupName == name){
				var count = #MenuList[i].二级菜单;
				if(MenuList[i].展开){
					for(j=count;1;-1){
						winform.listbox.delete(index+j);
					}
					MenuList[i].展开 = false;
				}else {
					for(j=1;count;1){
						winform.listbox.add(MenuList[i].二级菜单[j],index+j);
					}
					MenuList[i].展开 = true;
				}
				subClick = false;
				break;
			}
		}
		if( subClick ){
			winform.static.text = name;
		}
	}
}

 

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.fillRect(hdc,0xFFF5E2,rc);
            }
            
            
           //加文字测试
            var text = winform.listbox.getItemText(drawItem.itemID + 1);
            var font = ::LOGFONT(weight=400;color=0x000000);
            var Findflag = false;
            for(i=1;#MenuList;1){
				if(MenuList[i].groupName == text){
					gdi.textOut(hdc,font,text,rc.left+10, rc.top+10);
					
					var ICO = '\uF0D7';
					var font = ::LOGFONT(color=0xB0B0B0;h=-18;name='FontAwesome'); 
					if (MenuList[i].展开==true) {
						ICO = '\uF0D8';
					}
					
					gdi.textOut(hdc,font,ICO,rc.right-30, rc.top+10);

					Findflag = true;
					break;
				}
			}
            if( !Findflag ){
            	gdi.textOut(hdc,font,text,rc.left+30, rc.top+10);	
            }
            
         },drawItem.hDC,0xF5FDFF/*背景色*/,0xEEEEEE/*画笔色*/)
}

scrollbarEx(winform.listbox,5,35);

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


2021-08-07   #2

2021-08-29更新:

增加选中状态的持续保持功能.

2021-8-8 22:11再次更新:

将oncommand改为onSelChange , 避免在鼠标点击其他界面后产生焦点问题.

将去除焦点框改为0x10/*_ODS_FOCUS*/.


2021-8-7 20:20 增加默认展开与否设置, 增加了颜色设置, 删除焦点框, 优化了下代码.


简单的封装了个库, 下面是库和调用示例:

GIF.gif

exListbox.aardio 库代码:

import fonts.fontAwesome;
class exListbox{
	ctor( winform , MenuList , itemHeight,bgcolor=0xa0a0a0,headColor=0x302D29,subColor=0x3F3C38,textColor=0xD1D1D1,selColor=0x6E6B67 ){
		winform.bgcolor = bgcolor;
		this.seltext = null;
		winform.onMeasureItem = function(measureItem){
    		measureItem.itemHeight = itemHeight;  
		}
		
		winform.onDrawItem = function(drawItem){
     		..gdi.selectBrush(
        		function(hdc,pen,brush){
            		var rc = drawItem.rcItem;

            		var alltext = winform.getItemText(drawItem.itemID + 1);
            		var textTab = ..string.split(alltext,"<|>");
            		var text = textTab[2];
            		var font = ::LOGFONT(weight=400;color=textColor);
            		
            		var indexAll = textTab[1];
            		var head = ..string.split(indexAll,"<.>");
            		if(head[[2]]!=null){
            			if (drawItem.itemState & 1/*_ODS_SELECTED*/ or alltext == this.seltext) {  
                			..gdi.fillRect(hdc,selColor,rc);
            			}else {
                			..gdi.fillRect(hdc,subColor,rc);
            			}
            		}else {
            			..gdi.fillRect(hdc,headColor,rc);
            		}
            		
            		if(head[[2]]!=null){
            			..gdi.textOut(hdc,font,text,rc.left+60, rc.top+10);
            			var subico = ..string.unescape(textTab[3]);
            			var font = ::LOGFONT(color=textColor;h=-18;name='FontAwesome'); 
            			..gdi.textOut(hdc,font,subico,rc.left+30, rc.top+10);
            		}else {
						..gdi.textOut(hdc,font,text,rc.left+40, rc.top+10);
						var subico = ..string.unescape(textTab[3]);
            			var font = ::LOGFONT(color=textColor;h=-18;name='FontAwesome'); 
            			..gdi.textOut(hdc,font,subico,rc.left+10, rc.top+10);
						
						var ICO = '\uF0D7';
						var font = ::LOGFONT(color=textColor;h=-18;name='FontAwesome'); 
						var index = tonumber(head[1]);
						if (MenuList[index].展开==true) {
							ICO = '\uF0D8';
						}
						..gdi.textOut(hdc,font,ICO,rc.right-30, rc.top+10);
            		}

					if (drawItem.itemState & 0x10/*_ODS_FOCUS*/) {
						//去掉焦点框  
                		::DrawFocusRect(hdc,rc);
            		}

            		
         		},drawItem.hDC,0xa0a0a0/*背景色*/,0xa0a0a0/*画笔色*/)
		}
		
		for(k,v in MenuList){
			if(v.展开){
				for(j=1;#v;1){
					winform.add(v[j]);
				}
			}else {
				winform.add(v[1]);
			}
			
		}

		winform.onSelChange = function(){
    		var selindex = winform.selIndex;
			if(selindex){
				var name = winform.getItemText(selindex);
				var textTab = ..string.split(name,"<|>");
        		var indexAll = textTab[1];
        		var head = ..string.split(indexAll,"<.>");
        		var index = tonumber(head[1]);
        		var subindex = tonumber(head[2]);
        		var count = #MenuList[index]-1;
				if(head[[2]]==null){
					if( MenuList[index].展开 ){
						for(j=count;1;-1){
							winform.delete(selindex+j);
						}
						MenuList[index].展开 = false;
					}else {
						for(j=1;count;1){
							winform.add(MenuList[index][1+j],selindex+j);
						}
						MenuList[index].展开 = true;
					}	
				}else {
					//设置更新区,并更新
                    var lastIndex = winform.find(this.seltext);
                    this.seltext =  winform.selText;
                    if(lastIndex){
                        winform.invalidate(winform.getItemRect(lastIndex));
                        winform.update();
                    }
			 		if(this.onClick) this.onClick(index,subindex,textTab[2]);
				}
			}
		}
	};
}

使用的时候, 放到lib文件夹里, 然后调用 , 

注意: 手动去开启listbox的自绘属性

mainform.aardio

import win.ui;
/*DSG{{*/
mainForm = win.form(text="aardio工程15";right=959;bottom=591)
mainForm.add(
button={cls="button";text="Button";left=424;top=224;right=872;bottom=310;z=2};
edit={cls="edit";text="Edit";left=403;top=348;right=751;bottom=414;edge=1;multiline=1;z=3};
listbox={cls="listbox";left=0;top=0;right=163;bottom=592;items={};ownerDraw=1;z=1}
)
/*}}*/

import console
console.open()


var MenuList = {
	{
		"1|应用管理|\uF013";
		"1.1|应用_demo1|\uF014";
		"1.2|应用_demo2|\uF015";
		"1.3|应用_demo3|\uF016";
		"1.4|应用_demo4|\uF017";
		展开 = false;
	},
	{
		"2|协议管理|\uF0E8";
		"2.1|协议_demo1|\uF0E9";
		"2.2|协议_demo2|\uF0EA";
		"2.3|协议_demo3|\uF0EB";
		展开 = true;
	},
	{
		"3|日志管理|\uF039";
		"3.1|日志_demo1|\uF040";
		"3.2|日志_demo2|\uF041";
		"3.3|日志_demo3|\uF042";
		"3.4|日志_demo4|\uF043";
		展开 = false;
	}
	{
		"4|协议管理2|\uF0E8";
		"4.1|协议2_demo1|\uF0E9";
		"4.2|协议2_demo2|\uF0EA";
		"4.3|协议2_demo3|\uF0EB";
		展开 = false;
	},
	{
		"5|日志管理2|\uF039";
		"5.1|日志2_demo1|\uF040";
		"5.2|日志2_demo2|\uF041";
		"5.3|日志2_demo3|\uF042";
		"5.4|日志2_demo4|\uF043";
		展开 = false;
	}
}

import exListbox;
var exx = exListbox(mainForm.listbox,MenuList,30,0x000000,0x272E2D,0x663202,0xFFD859,0x3E8427);

exx.onClick = function(index,subindex,text){
	console.log(index,subindex,text)
}


mainForm.show();
return win.loopMessage();

工程下载:


listbox折叠功能演示.zip


希望用上的人能回复下, 给个支持, 截个图分享下配色方案.

2021-08-10   #3

,感谢分享
调了个黑色的
var exx = exListbox(mainForm.listbox,MenuList,45,0x2E2E2E,0x3C3C3C,0x2E2E2E,0xFFFFFF,0x666666);image.png

2021-08-10   #4

如果有人喜欢每次强制最多展开一项, 其他项需要自动折叠, 那么可以将库中的onSelChange()改为下面的代码

                winform.onSelChange = function(){
    		        var selindex = winform.selIndex;
			if(selindex){
				var name = winform.getItemText(selindex);
				var textTab = ..string.split(name,"<|>");
        		var indexAll = textTab[1];
        		var head = ..string.split(indexAll,"<.>");
        		var index = tonumber(head[1]);
        		var subindex = tonumber(head[2]);
        		var count = #MenuList[index]-1;
				if(head[[2]]==null){
					if( MenuList[index].展开 ){
						for(j=count;1;-1){
							winform.delete(selindex+j);
						}
						MenuList[index].展开 = false;
					}else {
						var zindex = 0;
						for(k,v in MenuList){
							zindex++;
							if( MenuList[k].展开 ){
								var subCount = #MenuList[k]-1;
								for(j=subCount;1;-1){
									winform.delete(zindex+j);
								}
								MenuList[k].展开 = false;
							}
						}

						for(j=1;count;1){
							winform.add(MenuList[index][1+j],index+j);
						}
						MenuList[index].展开 = true;
					}	
				}else {
			 		if(this.onClick) this.onClick(index,subindex,textTab[2]);
				}
			}
		}


2021-08-26   #5

返璞归真, 简洁风格 , 类似win10文件资源管理器风格, 将多余的图标都删除了

GIF.gif

aardio工程15.zip


2021-08-27   #6

回复#6 @admin :

电工风格...哈哈

2021-08-29   #7

20210829重大更新:

增加选中状态的持续保持功能.


这次更新后, 当你选中某项后, 不会因为点击了展开或者折叠功能从而导致选中状态丢失的情况发生. 无论是折叠还是展开, 都不会覆盖掉被选中的状态, 如下图所示:

GIF.gif

其实代码并没有多增加两句, 就是增加了个记录上次选中项目的记录功能

修改后库代码如下:

import fonts.fontAwesome;
class exListbox{
	ctor( winform , MenuList , itemHeight,bgcolor=0xa0a0a0,headColor=0x302D29,subColor=0x3F3C38,textColor=0xD1D1D1,selColor=0x6E6B67 ){
		winform.bgcolor = bgcolor;
		
		this.seltext = null;
		winform.onMeasureItem = function(measureItem){
    		measureItem.itemHeight = itemHeight;  
		}
		
		winform.onDrawItem = function(drawItem){
     		..gdi.selectBrush(
        		function(hdc,pen,brush){
            		var rc = drawItem.rcItem;

            		var alltext = winform.getItemText(drawItem.itemID + 1);
            		var textTab = ..string.split(alltext,"<|>");
            		var text = textTab[2];
            		var font = ::LOGFONT(weight=400;color=textColor);
            		
            		var indexAll = textTab[1];
            		var head = ..string.split(indexAll,"<.>");
            		if(head[[2]]!=null){
            			if (drawItem.itemState & 1/*_ODS_SELECTED*/ or alltext == this.seltext) {  
                			..gdi.fillRect(hdc,selColor,rc);
            			}else {
            			    ..gdi.fillRect(hdc,subColor,rc);
            			}
            		}else {
            			..gdi.fillRect(hdc,headColor,rc);
            		}
            		
            		if(head[[2]]!=null){
            			..gdi.textOut(hdc,font,text,rc.left+40, rc.top+10);

            		}else {
						..gdi.textOut(hdc,font,text,rc.left+30, rc.top+10);
						
						var ICO = '\uF054';
						var font = ::LOGFONT(color=0xB8B8B8;h=-14;name='FontAwesome'); 
						var index = tonumber(head[1]);
						if (MenuList[index].展开==true) {
							ICO = '\uF078';
						}
						..gdi.textOut(hdc,font,ICO,rc.left+10, rc.top+10);
            		}

					if (drawItem.itemState & 0x10/*_ODS_FOCUS*/) {
						//去掉焦点框  
                		::DrawFocusRect(hdc,rc);
            		}

            		
         		},drawItem.hDC,0xa0a0a0/*背景色*/,0xa0a0a0/*画笔色*/)
		}
		
		for(k,v in MenuList){
			if(v.展开){
				for(j=1;#v;1){
					winform.add(v[j]);
				}
			}else {
				winform.add(v[1]);
			}
			
		}

		winform.onSelChange = function(){
    		var selindex = winform.selIndex;
			if(selindex){
				var name = winform.getItemText(selindex);
				var textTab = ..string.split(name,"<|>");
        		var indexAll = textTab[1];
        		var head = ..string.split(indexAll,"<.>");
        		var index = tonumber(head[1]);
        		var subindex = tonumber(head[2]);
        		var count = #MenuList[index]-1;
				if(head[[2]]==null){
					if( MenuList[index].展开 ){
						for(j=count;1;-1){
							winform.delete(selindex+j);
						}
						MenuList[index].展开 = false;
					}else {
						for(j=1;count;1){
							winform.add(MenuList[index][1+j],selindex+j);
						}
						MenuList[index].展开 = true;
					}	
				}else {
					 //设置更新区,并更新
					var lastIndex = winform.find(this.seltext);
					this.seltext =  winform.selText;
					if(lastIndex){
						winform.invalidate(winform.getItemRect(lastIndex));
                    	winform.update();
					}
					
			 		if(this.onClick) this.onClick(index,subindex,textTab[2]);
				}
			}
		}
	};
}

listbox折叠功能演示.zip

上面演示是针对 返璞归真那个精简版改的, 如果你是用复杂版的, 同样的参考上面代码修改下即可.


2021-09-01   #8


无标题.png

非常漂亮的Listbox,正好短视频需要做语音合成。

import win.ui;
/*DSG{{*/
mainForm = win.form(text="auGen";right=682;bottom=352;bgcolor=16777215;border="none";max=false;mode="popup";sysmenu=false;title=false)
mainForm.add(
edit={cls="edit";left=157;top=52;right=682;bottom=327;autohscroll=false;bgcolor=16777215;border=1;font=LOGFONT(h=-16;name='Microsoft YaHei UI');multiline=1;vscroll=1;z=1};
listbox={cls="listbox";left=-2;top=-2;right=157;bottom=383;edge=1;items={};ownerDraw=1;z=3};
notice={cls="static";left=162;top=331;right=682;bottom=351;bgcolor=16777215;font=LOGFONT(name='Microsoft YaHei UI');transparent=1;z=4};
static={cls="static";text="百度语音合成";left=178;top=10;right=366;bottom=34;font=LOGFONT(h=-20;name='Microsoft YaHei UI';weight=700);transparent=1;z=2}
)
/*}}*/
import win.ui.simpleWindow2;
sw = win.ui.simpleWindow2(mainForm);
import exListbox;
menulist = {
 {
  "1|1-音色选择|\uF2BD",
  "1.0|女声|\uF182",
  "1.1|男声|\uF183",
  "1.3|逍遥|\uF183",
  "1.4|丫丫|\uF182",
  展开 = true
 },
 {
  "2|2-输入内容|\uF044",
  展开 = false
 },
 {
  "3|3-合成音频|\uF028",
  "3.1|下载音频|\uF0ED",
  展开 = true
 },
 {
  "4|4-查看|\uF1C7",
  "4.1|打开目录|\uF07C",
  展开 = true
 },
}
elb = exListbox(mainForm.listbox, menulist,30,0x2E2E2E,0x3C3C3C,0x2E2E2E,0xFFFFFF,0x666666)
elb.onClick = function(index,subindex,text){
    if (index==1) {
     mainForm.notice.text = "选择合成" ++ text ++ "语音";
     voice = subindex;
    } elseif(index==3){
        if (#mainForm.edit.text<1) {
            mainForm.notice.text = "请输入要合成的语音内容";
            return
        };
     var wmPlay = com.CreateObject("{6BF52A52-394A-11d3-B153-00C04F79FAA6}");
     import baidu.speech;
     var http = baidu.speech(); 
     
     /*
     支持下面三种写法:
     http.setAuth( 这里直接写access_token )
     http.setAuth( 这里写一个可以获取access_token的网址 )
     http.setAuth( "hkMI2fBTaKHDLolNxkPw7ylQ","tbUgpyqX9MiCE0LKozGFaGRoLS7xZHqs" )
     ) 
     */
     http.setAuth( "hkMI2fBTaKHDLolNxkPw7ylQ","tbUgpyqX9MiCE0LKozGFaGRoLS7xZHqs" )
     
     var mp3Url,err = http.text2audio( 
         tex = mainForm.edit.text;
         per = voice;
     )
             
     wmPlay.Url =  mp3Url;
     wmPlay.controls.play();
     
     import inet.httpFile;
     import time;
     tm = time.now();
     tm.format="%Y%m%d%H%M%S";
     
     hf = inet.httpFile(mp3Url, "mp3/"++tostring(tm)++".mp3")
     hf.download()
     mainForm.notice.text = tostring(tm)++".mp3已下载"
    
    } elseif(index==4){
        import process;
        process.explore(io.localpath("/mp3"));
    }
    
    
}
voice = 0;
mainForm.show();
return win.loopMessage();


2021-09-02   #9

感谢分享,希望越来越好!

2021-09-02   #10

再分享一个小技巧,对于需要实时变更菜单标题的需求,可以用如下代码重新指定MenuList。这样的好处是可以利用图标字体显示选中状态或其他需要实施变更的信息。

关键listbox需要先clear,不然会重复绘制。MenuList可以修改,也可以重新指定新的列表。

import exListbox;
var exx = exListbox(mainForm.listbox,MenuList,30);
 
exx.onClick = function(index,subindex,text){
    if (index==5 and subindex==2) {
    	MenuList[5][3] = "5.2|日志2|\uF041";
    	mainForm.listbox.clear()
    	exx = exListbox(mainForm.listbox,MenuList,30);
    }
    
}


2021-09-02   #11

回复#10 @jerryxjr1220 :

开源的好处就是可以任意修改代码为自己所用, 这个需求可以利用return返回值来自动修改menuList并刷新列表, 不用listbox.clear


可以这样操作:

1.库里增加个 this.MenuList = MenuList; 用来保存传递进来的表, 下面就可以修改这个表了.

2.this.OnClick() 函数增加return 返回值, 我们在库里接受到返回值, 然后去执行修改操作

修改后的库代码如下:

import fonts.fontAwesome;
class exListbox{
	ctor( winform , MenuList , itemHeight,bgcolor=0xa0a0a0,headColor=0x302D29,subColor=0x3F3C38,textColor=0xD1D1D1,selColor=0x6E6B67 ){
		winform.bgcolor = bgcolor;
		this.MenuList = MenuList;
		this.seltext = null;
		winform.onMeasureItem = function(measureItem){
    		measureItem.itemHeight = itemHeight;  
		}
		
		winform.onDrawItem = function(drawItem){
     		..gdi.selectBrush(
        		function(hdc,pen,brush){
            		var rc = drawItem.rcItem;

            		var alltext = winform.getItemText(drawItem.itemID + 1);
            		var textTab = ..string.split(alltext,"<|>");
            		var text = textTab[2];
            		var font = ::LOGFONT(weight=400;color=textColor);
            		
            		var indexAll = textTab[1];
            		var head = ..string.split(indexAll,"<.>");
            		if(head[[2]]!=null){
            			if (drawItem.itemState & 1/*_ODS_SELECTED*/ or alltext == this.seltext) {  
                			..gdi.fillRect(hdc,selColor,rc);
            			}else {
                			..gdi.fillRect(hdc,subColor,rc);
            			}
            		}else {
            			..gdi.fillRect(hdc,headColor,rc);
            		}
            		
            		if(head[[2]]!=null){
            			..gdi.textOut(hdc,font,text,rc.left+40, rc.top+10);

            		}else {
						..gdi.textOut(hdc,font,text,rc.left+30, rc.top+10);
						
						var ICO = '\uF054';
						var font = ::LOGFONT(color=0xB8B8B8;h=-14;name='FontAwesome'); 
						var index = tonumber(head[1]);
						if (this.MenuList[index].展开==true) {
							ICO = '\uF078';
						}
						..gdi.textOut(hdc,font,ICO,rc.left+10, rc.top+10);
            		}

					if (drawItem.itemState & 0x10/*_ODS_FOCUS*/) {
						//去掉焦点框  
                		::DrawFocusRect(hdc,rc);
            		}

            		
         		},drawItem.hDC,0xa0a0a0/*背景色*/,0xa0a0a0/*画笔色*/)
		}
		
		for(k,v in this.MenuList){
			if(v.展开){
				for(j=1;#v;1){
					winform.add(v[j]);
				}
			}else {
				winform.add(v[1]);
			}
			
		}

		winform.onSelChange = function(){
    		var selindex = winform.selIndex;
			if(selindex){
				var name = winform.getItemText(selindex);
				var textTab = ..string.split(name,"<|>");
        		var indexAll = textTab[1];
        		var head = ..string.split(indexAll,"<.>");
        		var index = tonumber(head[1]);
        		var subindex = tonumber(head[2]);
        		var count = #this.MenuList[index]-1;
				if(head[[2]]==null){
					if( this.MenuList[index].展开 ){
						for(j=count;1;-1){
							winform.delete(selindex+j);
						}
						this.MenuList[index].展开 = false;
					}else {
						for(j=1;count;1){
							winform.add(this.MenuList[index][1+j],selindex+j);
						}
						this.MenuList[index].展开 = true;
					}	
				}else {
					//设置更新区,并更新
                    var lastIndex = winform.find(this.seltext);
                    this.seltext =  winform.selText;
                    if(lastIndex){
                        winform.invalidate(winform.getItemRect(lastIndex));
                        winform.update();
                    }
			 		if(this.onClick) {
			 			var retText = this.onClick(index,subindex,textTab[2]);
			 			if(retText != null){
			 				var selindex = winform.selIndex;
			 				this.MenuList[index][subindex+1]  = retText;
			 				this.seltext = retText;

			 				winform.add(retText,selindex)
	 						winform.delete(selindex+1)
	 						winform.selIndex = selindex;

			 			}
			 		};
				}
			}
		}
	};
}

使用的时候

exx.onClick = function(index,subindex,text){
	console.log(index,subindex,text)
	if (index==5 and subindex==2) {
        return "5.2|日志被修改了";
    }
}

image.png

aardio工程15.zip


2021-09-02   #12

不错不错,功能更完善了!

2021-09-10   #13

感谢分享,博主很用心,发的东西都非常实用!

登录后方可回帖

登 录
信息栏
本站永久域名:HtmLayout.Cn
aardio可以快速开发上位机,本站主要记录了学习过程中遇到的问题和解决办法及aardio代码分享

这里主要专注于aardio学习交流和经验分享.
纯私人站,当笔记本用的,学到哪写到哪.

AARDIO语言QQ群:70517368
Aardio 官方站:Aardio官方
Aardio最新功能:Aardio官方更新日志
C大Aardio论坛:Aar爱好者论坛
本 站 主 站:Stm32cube中文网
Sciter中文在线文档Sciter在线学习文档
赞助商:才仁机械
Loading...