搜索
查看: 636|回复: 4

[win] 分享listbox自绘鼠标经过item项的hover效果实现方式

  [复制链接]

39

主题

174

帖子

1028

积分

荣誉会员

htmlayout.cn 我的学习笔记

Rank: 8Rank: 8

积分
1028
发表于 2018-9-16 16:06:29 | 显示全部楼层 |阅读模式
本帖最后由 popdes 于 2018-9-16 16:13 编辑

一直有想模仿下360浏览器上面的下载界面,今天有时间正好研究了下。

GIF3.gif

利用了listbox的GDI自绘范例,学习的时候发现drawItem.itemState中没有mouseHover这个状态,看来要自己判断了。
实现这个hover效果,考虑了以下两种方式

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

关键代码如下:
  1. winform.listbox.wndproc = function(hwnd,message,wParam,lParam){
  2.     if(message == 0x200/*_WM_MOUSEMOVE*/){
  3.          
  4.         var x,y = win.getMessagePos();  
  5.         var item = winform.listbox.hitTest(x,y,true);
  6.         if(listboxsel == item){
  7.                 return ;
  8.         }else {
  9.             listboxsel = item;
  10.             
  11.             winform.listbox.redraw();
复制代码

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

第二种方式:利用

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

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

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

完整代码如下:
  1. //GDI自绘
  2. import win.ui;
  3. /*DSG{{*/
  4. var winform = win.form(text="listbox自绘(GDI方式)";right=757;bottom=467)
  5. winform.add(
  6. 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}
  7. )
  8. /*}}*/

  9. winform.listbox.onMeasureItem = function(measureItem){
  10.     measureItem.itemHeight = 51;  
  11. }
  12. import win.imageList;
  13. import console
  14. console.open()

  15. var listboxsel = null;
  16. var beforesel = null;
  17. winform.listbox.onDrawItem = function(drawItem){
  18.      gdi.selectBrush(
  19.       
  20.         function(hdc,pen,brush){

  21.             var rc = drawItem.rcItem;
  22.             gdi.fillRect(hdc,0xFFFFFF,rc);
  23.             if (drawItem.itemID > 0) {  
  24.                 gdi.drawLine(hdc,rc.left, rc.top,rc.right, rc.top);
  25.             }
  26.             
  27.             if (drawItem.itemState & 1/*_ODS_SELECTED*/) {  
  28.                 //gdi.fillGradient(hdc,rc,0xFFFFFF, 0xC3BCA9,1/*_GRADIENT_FILL_RECT_V*/)
  29.                 gdi.fillRect(hdc,0xFFF5E2,rc);
  30.             }else {
  31.                 if(listboxsel == (drawItem.itemID+1)){
  32.                     gdi.fillRect(hdc,0xEEB7FF,rc);
  33.                 }   
  34.             }
  35.             
  36.             //加图标测试
  37.             win.imageList.shell( 0/*_SHIL_LARGE*/ ).draw(0,hdc,rc.left+20,rc.top+10);
  38.             
  39.             win.imageList.shell( 0/*_SHIL_LARGE*/ ).draw(0,hdc,rc.width()/2+200,rc.top+10);
  40.             font = ::LOGFONT(weight=300;color=0x9C9C9C);
  41.             gdi.textOut(hdc,font,"打开",rc.width()/2+235, rc.top+20);
  42.             win.imageList.shell( 0/*_SHIL_JUMBO*/ ).draw(1,hdc,rc.width()/2+270,rc.top+10);
  43.             gdi.textOut(hdc,font,"文件夹",rc.width()/2+300, rc.top+20);
  44.             //加文字测试
  45.             var str = winform.listbox.getItemText(drawItem.itemID + 1);
  46.             var str2 = "9.88MB       -文件已删除"
  47.             var font = ::LOGFONT(weight=400;color=0x000000);
  48.             gdi.textOut(hdc,font,str,rc.left+60, rc.top+10);
  49.             font = ::LOGFONT(weight=300;color=0xB0B0B0);
  50.             gdi.textOut(hdc,font,str2,rc.left+60, rc.top+30);
  51.             
  52.          },drawItem.hDC,0xF5FDFF/*背景色*/,0xEEEEEE/*画笔色*/)
  53. }
  54.   
  55. for(i=1;60){
  56.     winform.listbox.add("网页操作小助手.zip");
  57. }

  58. winform.listbox.wndproc = function(hwnd,message,wParam,lParam){
  59.     if(message == 0x200/*_WM_MOUSEMOVE*/){
  60.          
  61.         var x,y = win.getMessagePos();  
  62.         var item = winform.listbox.hitTest(x,y,true);
  63.         if(listboxsel == item){
  64.                 return ;
  65.         }else {
  66.             listboxsel = item;
  67.             if(beforesel == null){
  68.                 beforesel = listboxsel;
  69.                  
  70.             }else {
  71.                 winform.listbox.invalidate(winform.listbox.getItemRect(beforesel),0)
  72.                 beforesel = listboxsel;
  73.             }
  74.             winform.listbox.invalidate(winform.listbox.getItemRect(item))
  75.             winform.listbox.update();
  76.         }
  77.     }

  78. }

  79. winform.show();
  80. win.loopMessage();
复制代码

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

试验之后总感觉实现一个hover的功能稍显复杂了, 不知道各位看官有没有更好的方案。再此拜谢!

后面的一些功能还在测试,等测试好了一并更新到以下楼层,就不在另外开贴了。
大概还有待测试的功能有:1,鼠标放到文件名地方出现提示文,2,鼠标放在【打开】和【文件夹】上面实现图标hover效果,3,每行最后增加一个删除按钮(类似tabs控件的右上角x号)
! www.HtmLayout.Cn 我的学习笔记
回复

使用道具 举报

39

主题

174

帖子

1028

积分

荣誉会员

htmlayout.cn 我的学习笔记

Rank: 8Rank: 8

积分
1028
 楼主| 发表于 2018-9-16 18:16:18 | 显示全部楼层
第一更:
浏览目录文件,添加到listbox中,并显示其系统图标和文件大小等信息
1537092326841860.png

完整代码如下: (测试的话,自己手动把目录路径改改再运行)
  1. //GDI自绘
  2. import win.ui;
  3. /*DSG{{*/
  4. var winform = win.form(text="listbox自绘(GDI方式)";right=757;bottom=467)
  5. winform.add(
  6. 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}
  7. )
  8. /*}}*/

  9. winform.listbox.onMeasureItem = function(measureItem){
  10.     measureItem.itemHeight = 51;  
  11. }
  12. import win.imageList;
  13. import console
  14. console.open()

  15. var listboxsel = null;
  16. var beforesel = null;

  17. import fsys;
  18. import fsys.info;
  19. import fsys.file;
  20. var filename;
  21. var boxTab = {};

  22. var files,,dirs = ..fsys.list("D:\360安全浏览器下载");
  23. for(i=1;#files)
  24. {
  25.         filename = files[ i ];
  26.         var sfi = fsys.info.get(files[filename],0x10/*_SHGFI_USEFILEATTRIBUTES*/ | 0x4000/*_SHGFI_SYSICONINDEX*/ );
  27.         var fileSize = tonumber(fsys.file(files[filename]).size64());
  28.         if(fileSize/1024 >= 1){
  29.             if(fileSize/1024/1024 >= 1){
  30.                 sizes = tostring(math.round(fileSize/1024/1024,2))++" MB";
  31.             }else {
  32.                 sizes = tostring(math.round(fileSize/1024,2))++" KB";
  33.             }
  34.                
  35.         }else {
  36.             sizes = tostring(fileSize)++" B";
  37.         }
  38.        
  39.         table.mixin(boxTab,{ iImage = sfi.iIcon; text = string.toUnicode(filename); size = sizes });
  40.         winform.listbox.add(table.tostring(boxTab))
  41. }

  42. winform.listbox.onDrawItem = function(drawItem){
  43.      gdi.selectBrush(
  44.      
  45.         function(hdc,pen,brush){
  46.             //获取并分解需要显示的数据(字符串转表)
  47.                         var strTab = eval(winform.listbox.getItemText(drawItem.itemID + 1))
  48.             var rc = drawItem.rcItem;
  49.                     gdi.fillRect(hdc,0xFFFFFF,rc);
  50.                     if (drawItem.itemID > 0) {  
  51.                             gdi.drawLine(hdc,rc.left, rc.top,rc.right, rc.top);
  52.                     }
  53.                    
  54.                     if (drawItem.itemState & 1/*_ODS_SELECTED*/) {  
  55.                             gdi.fillRect(hdc,0xFFF5E2,rc);
  56.                     }else {
  57.                             if(listboxsel == (drawItem.itemID+1)){
  58.                                     gdi.fillRect(hdc,0xEEB7FF,rc);
  59.                             }       
  60.                     }
  61.                    
  62.                     //加图标测试       
  63.                     win.imageList.shell( 0/*_SHIL_LARGE*/ ).draw(strTab.iImage,hdc,rc.left+20,rc.top+10);
  64.                    
  65.                     win.imageList.shell( 0/*_SHIL_LARGE*/ ).draw(0,hdc,rc.width()/2+200,rc.top+10);
  66.                     var font = ::LOGFONT(weight=300;color=0x9C9C9C);
  67.                     gdi.textOut(hdc,font,"打开",rc.width()/2+235, rc.top+20);
  68.                     win.imageList.shell( 0/*_SHIL_JUMBO*/ ).draw(1,hdc,rc.width()/2+270,rc.top+10);
  69.                     gdi.textOut(hdc,font,"文件夹",rc.width()/2+300, rc.top+20);
  70.                     //加文字测试
  71.                     font = ::LOGFONT(weight=400;color=0x000000);
  72.                     gdi.textOut(hdc,font,strTab.text,rc.left+60, rc.top+10);
  73.                     font = ::LOGFONT(weight=300;color=0xB0B0B0);
  74.                     gdi.textOut(hdc,font,strTab.size,rc.left+60, rc.top+30);
  75.                    
  76.                    },drawItem.hDC,0xF5FDFF/*背景色*/,0xEEEEEE/*画笔色*/)
  77. }

  78. winform.listbox.wndproc = function(hwnd,message,wParam,lParam){
  79.         if(message == 0x200/*_WM_MOUSEMOVE*/){
  80.                
  81.                 var x,y = win.getMessagePos();  
  82.         var item = winform.listbox.hitTest(x,y,true);
  83.         if(item == null){
  84.                 return ;
  85.         }
  86.         if(listboxsel == item){
  87.                         return ;
  88.                 }else {
  89.                         listboxsel = item;
  90.                         if(beforesel == null){
  91.                                 beforesel = listboxsel;
  92.                                
  93.                         }else {
  94.                                 if(beforesel){
  95.                                         winform.listbox.invalidate(winform.listbox.getItemRect(beforesel),0)       
  96.                                 }
  97.                                 beforesel = listboxsel;
  98.                         }
  99.                         winform.listbox.invalidate(winform.listbox.getItemRect(item))
  100.                         winform.listbox.update();
  101.                 }
  102.         }

  103. }

  104. winform.show();
  105. win.loopMessage();
复制代码
! www.HtmLayout.Cn 我的学习笔记
回复

使用道具 举报

39

主题

174

帖子

1028

积分

荣誉会员

htmlayout.cn 我的学习笔记

Rank: 8Rank: 8

积分
1028
 楼主| 发表于 2018-9-17 12:59:07 | 显示全部楼层
第二更: 增加右侧[删除]按钮和功能,并增加此按钮的动态hover效果.
GIF33.gif
  1. //GDI自绘
  2. import win.ui;
  3. import fonts.fontAwesome;
  4. /*DSG{{*/
  5. var winform = win.form(text="listbox自绘(GDI方式)";right=778;bottom=445;border="dialog frame")
  6. winform.add(
  7. button={cls="button";text="增加行";left=0;top=385;right=779;bottom=436;z=2};
  8. 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}
  9. )
  10. /*}}*/

  11. winform.listbox.onMeasureItem = function(measureItem){
  12.     measureItem.itemHeight = 51;  
  13. }
  14. import win.imageList;
  15. import console
  16. console.open()

  17. var listboxsel = null;
  18. var beforesel = null;
  19. var colorsel = false;

  20. import fsys;
  21. import fsys.info;
  22. import fsys.file;
  23. var filename;
  24. var boxTab = {};

  25. var files,,dirs = ..fsys.list("D:\BaiduNetdiskDownload");
  26. for(i=1;#files)
  27. {
  28.         filename = files[ i ];
  29.         var sfi = fsys.info.get(files[filename],0x10/*_SHGFI_USEFILEATTRIBUTES*/ | 0x4000/*_SHGFI_SYSICONINDEX*/ );
  30.         var fileSize = tonumber(fsys.file(files[filename]).size64());
  31.         if(fileSize/1024 >= 1){
  32.             if(fileSize/1024/1024 >= 1){
  33.                 sizes = tostring(math.round(fileSize/1024/1024,2))++" MB";
  34.             }else {
  35.                 sizes = tostring(math.round(fileSize/1024,2))++" KB";
  36.             }
  37.                
  38.         }else {
  39.             sizes = tostring(fileSize)++" B";
  40.         }
  41.        
  42.         table.mixin(boxTab,{ iImage = sfi.iIcon; text = filename; size = sizes });
  43.         winform.listbox.add(table.tostring(boxTab))
  44. }

  45. winform.listbox.onDrawItem = function(drawItem){
  46.      gdi.selectBrush(
  47.      
  48.         function(hdc,pen,brush){
  49.             //获取并分解需要显示的数据(字符串转表)
  50.                         var strTab = eval(winform.listbox.getItemText(drawItem.itemID + 1))
  51.             var rc = drawItem.rcItem;
  52.                     gdi.fillRect(hdc,0xFFFFFF,rc);
  53.                     if (drawItem.itemID > 0) {  
  54.                             gdi.drawLine(hdc,rc.left, rc.top,rc.right, rc.top);
  55.                     }
  56.                    
  57.                     if (drawItem.itemState & 1/*_ODS_SELECTED*/) {  
  58.                             gdi.fillRect(hdc,0xFFF5E2,rc);
  59.                             if(colorsel){
  60.                                     font = ::LOGFONT(weight=700;color=0x6112FF;name='FontAwesome';h=-16);
  61.                                     gdi.textOut(hdc,font,'\uF057',rc.width()/2+345, rc.top+20);
  62.                             }else {
  63.                                     font = ::LOGFONT(weight=700;color=0x9C9C9C;name='FontAwesome';h=-16);
  64.                                     gdi.textOut(hdc,font,'\uF057',rc.width()/2+345, rc.top+20);
  65.                             }
  66.                            
  67.                     }else {
  68.                             if(listboxsel == (drawItem.itemID+1)){
  69.                                     gdi.fillRect(hdc,0xEEB7FF,rc);
  70.                             }       
  71.                     }
  72.                    
  73.                     //加图标测试       
  74.                     win.imageList.shell( 0/*_SHIL_LARGE*/ ).draw(strTab.iImage,hdc,rc.left+20,rc.top+10);
  75.                     win.imageList.shell( 0/*_SHIL_LARGE*/ ).draw(0,hdc,rc.width()/2+200,rc.top+10);
  76.                     var font = ::LOGFONT(weight=300;color=0x9C9C9C;);
  77.                     gdi.textOut(hdc,font,"打开",rc.width()/2+235, rc.top+20);
  78.                     win.imageList.shell( 0/*_SHIL_JUMBO*/ ).draw(1,hdc,rc.width()/2+270,rc.top+10);
  79.                     gdi.textOut(hdc,font,"文件夹",rc.width()/2+300, rc.top+20);

  80.                     //加文字测试
  81.                     font = ::LOGFONT(weight=400;color=0x000000);
  82.                     gdi.textOut(hdc,font,strTab.text,rc.left+60, rc.top+10);
  83.                     font = ::LOGFONT(weight=300;color=0xB0B0B0);
  84.                     gdi.textOut(hdc,font,strTab.size,rc.left+60, rc.top+30);
  85.                    
  86.                    },drawItem.hDC,0xF5FDFF/*背景色*/,0xEEEEEE/*画笔色*/)
  87. }

  88. winform.listbox.wndproc = function(hwnd,message,wParam,lParam){
  89.     select(message) {
  90.             case 0x200/*_WM_MOUSEMOVE*/ {
  91.                     var x,y = win.getMessagePos();  
  92.                 var item = winform.listbox.hitTest(x,y,true);
  93.                 if(item == null){
  94.                         return ;
  95.                 }
  96.                
  97.                     if(listboxsel == item){        /* 若鼠标在同一行item内游动 */
  98.                             /* 首先,判断是否要显示[删除]按钮,通过判断鼠标是不是在选中item行内 */
  99.                     if(listboxsel == winform.listbox.selIndex){
  100.                             x,y = win.toClient(winform.listbox.hwnd,x,y);
  101.                                         var rc = winform.listbox.getItemRect(item);
  102.                                         rc.left = rc.width()/2+345;
  103.                                         rc.top = rc.top+20;
  104.                                         rc.bottom = rc.bottom-20 ;
  105.                                         //判断鼠标游动的区间是不是在[删除]按钮范围
  106.                                         if( ::PtInRect(rc,x,y) ){
  107.                                                 if(colorsel == false){        //鼠标从[删除]按钮外部移动到内部区域
  108.                                                         colorsel = true;
  109.                                                         //设置更新区,并更新
  110.                                                         winform.listbox.invalidate(winform.listbox.getItemRect(item))
  111.                                                         winform.listbox.update();
  112.                                                         return;       
  113.                                                 }
  114.                                                 return ; //一直在内部区域游动,则不更新
  115.                                         }else {
  116.                                                 if(colorsel == true){        //鼠标从内到外
  117.                                                         colorsel = false;
  118.                                                         //设置更新区,并更新
  119.                                                         winform.listbox.invalidate(winform.listbox.getItemRect(item))
  120.                                                         winform.listbox.update();
  121.                                                         return ;
  122.                                                 }
  123.                                                 return ; //一直在外部区域游动,则不更新
  124.                                         }        
  125.                     }
  126.                     return ;
  127.                         }else {
  128.                                 //设置hover效果
  129.                                 listboxsel = item;
  130.                                 if(beforesel == null){        //第一次执行,初始化
  131.                                         beforesel = listboxsel;
  132.                                        
  133.                                 }else {
  134.                                         //先关闭上次绘制区域
  135.                                         if(beforesel){
  136.                                                 winform.listbox.invalidate(winform.listbox.getItemRect(beforesel),0)       
  137.                                         }
  138.                                         beforesel = listboxsel;
  139.                                 }
  140.                                 //绘制当前区域
  141.                                 winform.listbox.invalidate(winform.listbox.getItemRect(item));
  142.                                 winform.listbox.update();
  143.                         }
  144.             }
  145.             case 0x202/*_WM_LBUTTONUP*/ {
  146.                     if(colorsel){        /* 若鼠标在删除按钮区域内单击了 */
  147.                                 var selindex = winform.listbox.selIndex
  148.                                 var strTab = winform.listbox.getItemText(selindex);
  149.                                 var tabStr = eval(strTab)
  150.                                 var ret = winform.msgboxTest("您确定要删除 ["++tabStr.text++"] 文件吗?");
  151.                                 if(ret){
  152.                                         winform.listbox.delete(selindex);
  153.                                         colorsel = false;
  154.                                 }
  155.                         }
  156.             }
  157.             else {
  158.             }
  159.     }
  160. }

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

  166. winform.show();
  167. win.loopMessage();
复制代码
! www.HtmLayout.Cn 我的学习笔记
回复

使用道具 举报

39

主题

174

帖子

1028

积分

荣誉会员

htmlayout.cn 我的学习笔记

Rank: 8Rank: 8

积分
1028
 楼主| 发表于 2018-9-17 15:00:46 | 显示全部楼层
最后一更:
修改界面中[删除] / [打开] / [文件夹] 鼠标样式效果,并增加对应功能.
修改界面: 不选中项目的时候,不出现 功能 按键.

本次测试基本结束了. 后面有时间继续简化下, 看看能不能封装下.
其他的一些界面问题就不再写了.

GIF.gif

  1. //GDI自绘
  2. import win.ui;
  3. import fonts.fontAwesome;
  4. /*DSG{{*/
  5. var winform = win.form(text="listbox自绘(GDI方式)";right=778;bottom=445;border="dialog frame")
  6. winform.add(
  7. button={cls="button";text="增加行";left=0;top=385;right=779;bottom=436;z=2};
  8. 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}
  9. )
  10. /*}}*/

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

  14. import win.imageList;
  15. import process;

  16. var listboxsel = null;
  17. var beforesel = null;
  18. var colorsel = false;
  19. var opensel = false;
  20. var filesel = false;

  21. import fsys;
  22. import fsys.info;
  23. import fsys.file;
  24. var filename;
  25. var boxTab = {};

  26. var files,,dirs = ..fsys.list("D:\BaiduNetdiskDownload");
  27. for(i=1;#files)
  28. {
  29.         filename = files[ i ];
  30.         var sfi = fsys.info.get(files[filename],0x10/*_SHGFI_USEFILEATTRIBUTES*/ | 0x4000/*_SHGFI_SYSICONINDEX*/ );
  31.         var fileSize = tonumber(fsys.file(files[filename]).size64());
  32.         if(fileSize/1024 >= 1){
  33.             if(fileSize/1024/1024 >= 1){
  34.                 sizes = tostring(math.round(fileSize/1024/1024,2))++" MB";
  35.             }else {
  36.                 sizes = tostring(math.round(fileSize/1024,2))++" KB";
  37.             }
  38.                
  39.         }else {
  40.             sizes = tostring(fileSize)++" B";
  41.         }
  42.        
  43.         table.mixin(boxTab,{ iImage = sfi.iIcon; text = filename; size = sizes ; filePath = files[filename] });
  44.         winform.listbox.add(table.tostring(boxTab))
  45. }

  46. winform.listbox.onDrawItem = function(drawItem){
  47.      gdi.selectBrush(
  48.      
  49.         function(hdc,pen,brush){
  50.             //获取并分解需要显示的数据(字符串转表)
  51.                         var strTab = eval(winform.listbox.getItemText(drawItem.itemID + 1))
  52.             var rc = drawItem.rcItem;
  53.                     gdi.fillRect(hdc,0xFFFFFF,rc);
  54.                     if (drawItem.itemID > 0) {  
  55.                             gdi.drawLine(hdc,rc.left, rc.top,rc.right, rc.top);
  56.                     }                
  57.                     if (drawItem.itemState & 1/*_ODS_SELECTED*/) {  
  58.                             gdi.fillRect(hdc,0xFFF5E2,rc);
  59.                             //删除文件
  60.                             if(colorsel){
  61.                                     font = ::LOGFONT(weight=700;color=0x6112FF;name='FontAwesome';h=-16);
  62.                                     gdi.textOut(hdc,font,'\uF057',rc.width()/2+345, rc.top+20);
  63.                             }else {
  64.                                     font = ::LOGFONT(weight=700;color=0x9C9C9C;name='FontAwesome';h=-16);
  65.                                     gdi.textOut(hdc,font,'\uF057',rc.width()/2+345, rc.top+20);
  66.                             }
  67.                             //打开文件
  68.                             if(opensel){
  69.                                     font = ::LOGFONT(weight=500;color=0x6112FF;name='FontAwesome';h=-16);
  70.                                     gdi.textOut(hdc,font,'\uF0F6 打开',rc.width()/2+190, rc.top+20);
  71.                             }else {
  72.                                     font = ::LOGFONT(weight=300;color=0x9C9C9C;name='FontAwesome';h=-16);
  73.                                     gdi.textOut(hdc,font,'\uF0F6 打开',rc.width()/2+190, rc.top+20);
  74.                             }
  75.                             //打开文件夹
  76.                             if(filesel){
  77.                                     font = ::LOGFONT(weight=500;color=0x6112FF;name='FontAwesome';h=-16);
  78.                                     gdi.textOut(hdc,font,'\uF115 文件夹',rc.width()/2+260, rc.top+20);
  79.                             }else {
  80.                                     font = ::LOGFONT(weight=300;color=0x9C9C9C;name='FontAwesome';h=-16);
  81.                                     gdi.textOut(hdc,font,'\uF115 文件夹',rc.width()/2+260, rc.top+20);
  82.                             }
  83.                     }else {
  84.                             if(listboxsel == (drawItem.itemID+1)){
  85.                                     gdi.fillRect(hdc,0xEEB7FF,rc);
  86.                             }       
  87.                     }

  88.                     //文件图标
  89.                     win.imageList.shell( 0/*_SHIL_LARGE*/ ).draw(strTab.iImage,hdc,rc.left+20,rc.top+10);
  90.                     //文件名
  91.                     font = ::LOGFONT(weight=400;color=0x000000);
  92.                     gdi.textOut(hdc,font,strTab.text,rc.left+60, rc.top+10);
  93.                     //文件大小
  94.                     font = ::LOGFONT(weight=300;color=0xB0B0B0);
  95.                     gdi.textOut(hdc,font,strTab.size,rc.left+60, rc.top+30);
  96.                    
  97.                    },drawItem.hDC,0xF5FDFF/*背景色*/,0xEEEEEE/*画笔色*/)
  98. }

  99. winform.listbox.wndproc = function(hwnd,message,wParam,lParam){
  100.     select(message) {
  101.         case 0x200/*_WM_MOUSEMOVE*/ {
  102.             var x,y = win.getMessagePos();  
  103.             var item = winform.listbox.hitTest(x,y,true);
  104.             if(item == null){
  105.                 return ;
  106.             }
  107.             
  108.             if(listboxsel == item){   /* 若鼠标在同一行item内游动 */
  109.                 /* 首先,判断是否要显示[删除]按钮,通过判断鼠标是不是在选中item行内 */
  110.                 if(listboxsel == winform.listbox.selIndex){
  111.                     x,y = win.toClient(winform.listbox.hwnd,x,y);
  112.                     for(i=1;3;1){
  113.                             select(i) {
  114.                                     case 1 {        //open
  115.                                             var rc = winform.listbox.getItemRect(item);
  116.                                             rc.left = rc.width()/2+190;
  117.                                             rc.right = rc.left+60;
  118.                                             rc.top = rc.top+10;
  119.                                             rc.bottom = rc.bottom-10 ;
  120.                                             //判断鼠标游动的区间是不是在[删除]按钮范围
  121.                                             if( ::PtInRect(rc,x,y) ){
  122.                                                 if(opensel == false){    //鼠标从[删除]按钮外部移动到内部区域
  123.                                                     opensel = true;
  124.                                                     //设置更新区,并更新
  125.                                                     winform.listbox.invalidate(winform.listbox.getItemRect(item))
  126.                                                     winform.listbox.update();
  127.                                                     break ;
  128.                                                 }
  129.                                                 continue ; //一直在内部区域游动,则不更新
  130.                                             }else {
  131.                                                 if(opensel == true){ //鼠标从内到外
  132.                                                     opensel = false;
  133.                                                     //设置更新区,并更新
  134.                                                     winform.listbox.invalidate(winform.listbox.getItemRect(item))
  135.                                                     winform.listbox.update();
  136.                                                     break ;
  137.                                                 }
  138.                                                 continue ; //一直在外部区域游动,则不更新
  139.                                             }
  140.                                                                    
  141.                                            
  142.                                     }
  143.                                     case 2 {        //file
  144.                                             var filerc = winform.listbox.getItemRect(item);
  145.                                             filerc.left = filerc.width()/2+260;
  146.                                             filerc.right = filerc.left+70;
  147.                                             filerc.top = filerc.top+10;
  148.                                             filerc.bottom = filerc.bottom-10 ;
  149.                                             //判断鼠标游动的区间是不是在[删除]按钮范围
  150.                                             if( ::PtInRect(filerc,x,y) ){
  151.                                                 if(filesel == false){    //鼠标从[删除]按钮外部移动到内部区域
  152.                                                     filesel = true;
  153.                                                     //设置更新区,并更新
  154.                                                     winform.listbox.invalidate(winform.listbox.getItemRect(item))
  155.                                                     winform.listbox.update();
  156.                                                     break;
  157.                                                 }
  158.                                                 continue ; //一直在内部区域游动,则不更新
  159.                                             }else {
  160.                                                 if(filesel == true){ //鼠标从内到外
  161.                                                     filesel = false;
  162.                                                     //设置更新区,并更新
  163.                                                     winform.listbox.invalidate(winform.listbox.getItemRect(item))
  164.                                                     winform.listbox.update();
  165.                                                     break ;
  166.                                                 }
  167.                                                 continue ; //一直在外部区域游动,则不更新
  168.                                             }
  169.                                            
  170.                                     }
  171.                                     case 3 {        //del
  172.                                             var delrc = winform.listbox.getItemRect(item);
  173.                                             delrc.left = delrc.width()/2+345;
  174.                                             delrc.top = delrc.top+20;
  175.                                             delrc.bottom = delrc.bottom-20 ;
  176.                                             //判断鼠标游动的区间是不是在[删除]按钮范围
  177.                                             if( ::PtInRect(delrc,x,y) ){
  178.                                                 if(colorsel == false){    //鼠标从[删除]按钮外部移动到内部区域
  179.                                                     colorsel = true;
  180.                                                     //设置更新区,并更新
  181.                                                     winform.listbox.invalidate(winform.listbox.getItemRect(item))
  182.                                                     winform.listbox.update();
  183.                                                     break;
  184.                                                 }
  185.                                                 continue ; //一直在内部区域游动,则不更新
  186.                                             }else {
  187.                                                 if(colorsel == true){ //鼠标从内到外
  188.                                                     colorsel = false;
  189.                                                     //设置更新区,并更新
  190.                                                     winform.listbox.invalidate(winform.listbox.getItemRect(item))
  191.                                                     winform.listbox.update();
  192.                                                     break ;
  193.                                                 }
  194.                                                 continue ; //一直在外部区域游动,则不更新
  195.                                             }
  196.                                     }
  197.                             }
  198.                     }
  199.                 }
  200.                 return ;
  201.                         }else {
  202.                                 //设置hover效果
  203.                                 listboxsel = item;
  204.                                 if(beforesel == null){        //第一次执行,初始化
  205.                                         beforesel = listboxsel;
  206.                                        
  207.                                 }else {
  208.                                         //先关闭上次绘制区域
  209.                                         if(beforesel){
  210.                                                 winform.listbox.invalidate(winform.listbox.getItemRect(beforesel),0)       
  211.                                         }
  212.                                         beforesel = listboxsel;
  213.                                 }
  214.                                 //绘制当前区域
  215.                                 winform.listbox.invalidate(winform.listbox.getItemRect(item));
  216.                                 winform.listbox.update();
  217.                         }
  218.             }
  219.             case 0x202/*_WM_LBUTTONUP*/ {
  220.                     //删除功能
  221.                     if(colorsel){        /* 若鼠标在删除按钮区域内单击了 */
  222.                                 var selindex = winform.listbox.selIndex
  223.                                 var strTab = winform.listbox.getItemText(selindex);
  224.                                 var tabStr = eval(strTab)
  225.                                 var ret = winform.msgboxTest("您确定要删除 ["++tabStr.text++"] 文件吗?");
  226.                                 if(ret){
  227.                                         winform.listbox.delete(selindex);
  228.                                         colorsel = false;
  229.                                 }
  230.                                 return ;
  231.                         };
  232.                         //打开文件
  233.                         if(opensel){        /* 若鼠标在打开按钮区域内单击了 */
  234.                                 var selindex = winform.listbox.selIndex
  235.                                 var strTab = winform.listbox.getItemText(selindex);
  236.                                 var tabStr = eval(strTab)
  237.                                 process.execute(tabStr.filePath);
  238.                                 return ;
  239.                         }
  240.                         //打开文件夹
  241.                         if(filesel){        /* 若鼠标在打开按钮区域内单击了 */
  242.                                 var selindex = winform.listbox.selIndex
  243.                                 var strTab = winform.listbox.getItemText(selindex);
  244.                                 var tabStr = eval(strTab)
  245.                                 var path = io.splitpath(tabStr.filePath);
  246.                                 process.execute(path.dir);
  247.                                 return ;
  248.                         }
  249.             }
  250.             else {
  251.             }
  252.     }
  253. }

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

  259. winform.show();
  260. win.loopMessage();
复制代码

评分

参与人数 1银币 +20 收起 理由
Danboy + 20 很给力!

查看全部评分

! www.HtmLayout.Cn 我的学习笔记
回复

使用道具 举报

39

主题

174

帖子

1028

积分

荣誉会员

htmlayout.cn 我的学习笔记

Rank: 8Rank: 8

积分
1028
 楼主| 发表于 2018-9-17 22:39:09 | 显示全部楼层
追更一下:
估计有些人喜欢右侧的【打开】和【文件夹】一直显示着,所以这次主要把右侧功能区显示限制解除,并完善了下鼠标在右侧功能区的hover效果和点击效果。可以直接移动过去想点哪就点哪了。
增加启动即提示选择要显示的文件夹功能。

代码还没整理有点乱,看官们多包涵。

  1. //GDI自绘
  2. import win.ui;
  3. import fonts.fontAwesome;
  4. /*DSG{{*/
  5. var winform = win.form(text="listbox自绘(GDI方式)";right=778;bottom=445;border="dialog frame")
  6. winform.add(
  7. button={cls="button";text="增加行";left=0;top=385;right=779;bottom=436;z=2};
  8. 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}
  9. )
  10. /*}}*/

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

  14. import win.imageList;
  15. import process;

  16. var listboxsel = null;
  17. var beforesel = null;
  18. var colorsel = false;
  19. var opensel = false;
  20. var filesel = false;

  21. import fsys;
  22. import fsys.info;
  23. import fsys.file;
  24. import fsys.dlg;
  25. var filename;
  26. var boxTab = {};

  27. var dirPath;
  28. if( !io.exist(dirPath) ) {
  29.         dirPath = fsys.dlg.opendir()
  30. }
  31. if(!dirPath){
  32.         dirPath = "D:";
  33. }
  34. var files,,dirs = ..fsys.list(dirPath);
  35. for(i=1;#files)
  36. {
  37.         filename = files[ i ];
  38.         var sfi = fsys.info.get(files[filename],0x10/*_SHGFI_USEFILEATTRIBUTES*/ | 0x4000/*_SHGFI_SYSICONINDEX*/ );
  39.         var fileSize = tonumber(fsys.file(files[filename]).size64());
  40.         if(fileSize/1024 >= 1){
  41.             if(fileSize/1024/1024 >= 1){
  42.                 sizes = tostring(math.round(fileSize/1024/1024,2))++" MB";
  43.             }else {
  44.                 sizes = tostring(math.round(fileSize/1024,2))++" KB";
  45.             }
  46.                
  47.         }else {
  48.             sizes = tostring(fileSize)++" B";
  49.         }
  50.         
  51.         table.mixin(boxTab,{ iImage = sfi.iIcon; text = filename; size = sizes ; filePath = files[filename] });
  52.         winform.listbox.add(table.tostring(boxTab))
  53. }

  54. winform.listbox.onDrawItem = function(drawItem){
  55.      gdi.selectBrush(
  56.      
  57.         function(hdc,pen,brush){
  58.             //获取并分解需要显示的数据(字符串转表)
  59.                         var strTab = eval(winform.listbox.getItemText(drawItem.itemID + 1))
  60.             var rc = drawItem.rcItem;
  61.                     gdi.fillRect(hdc,0xFFFFFF,rc);
  62.                     if (drawItem.itemID > 0) {  
  63.                             gdi.drawLine(hdc,rc.left, rc.top,rc.right, rc.top);
  64.                     }                 
  65.                     if (drawItem.itemState & 1/*_ODS_SELECTED*/) {  
  66.                             gdi.fillRect(hdc,0xFFF5E2,rc);
  67.                     }else {
  68.                             if(listboxsel == (drawItem.itemID+1)){
  69.                                     gdi.fillRect(hdc,0xEEB7FF,rc);
  70.                             }            
  71.                     }
  72.                                                        
  73.                                         //删除文件
  74.                     if(colorsel){
  75.                         var x,y = win.getMessagePos();  
  76.                                     var item = winform.listbox.hitTest(x,y,true);

  77.                                     if((drawItem.itemID+1) == item){
  78.                                             font = ::LOGFONT(weight=700;color=0x6112FF;name='FontAwesome';h=-16);
  79.                             gdi.textOut(hdc,font,'\uF057',rc.width()/2+345, rc.top+20);
  80.                                     }else {
  81.                                             font = ::LOGFONT(weight=700;color=0x9C9C9C;name='FontAwesome';h=-16);
  82.                             gdi.textOut(hdc,font,'\uF057',rc.width()/2+345, rc.top+20);
  83.                                     }
  84.                     }else {
  85.                             font = ::LOGFONT(weight=700;color=0x9C9C9C;name='FontAwesome';h=-16);
  86.                             gdi.textOut(hdc,font,'\uF057',rc.width()/2+345, rc.top+20);
  87.                     }
  88.                     
  89.                     if(opensel){
  90.                         var x,y = win.getMessagePos();  
  91.                                     var item = winform.listbox.hitTest(x,y,true);

  92.                                     if((drawItem.itemID+1) == item){
  93.                                             font = ::LOGFONT(weight=500;color=0x6112FF;name='FontAwesome';h=-16);
  94.                             gdi.textOut(hdc,font,'\uF0F6 打开',rc.width()/2+190, rc.top+20);
  95.                                     }else {
  96.                                             font = ::LOGFONT(weight=300;color=0x9C9C9C;name='FontAwesome';h=-16);
  97.                             gdi.textOut(hdc,font,'\uF0F6 打开',rc.width()/2+190, rc.top+20);
  98.                                     }
  99.                            
  100.                     }else {
  101.                             font = ::LOGFONT(weight=300;color=0x9C9C9C;name='FontAwesome';h=-16);
  102.                             gdi.textOut(hdc,font,'\uF0F6 打开',rc.width()/2+190, rc.top+20);
  103.                     }
  104.                     
  105.                     if(filesel){
  106.                         var x,y = win.getMessagePos();  
  107.                                     var item = winform.listbox.hitTest(x,y,true);

  108.                                     if((drawItem.itemID+1) == item){
  109.                                             font = ::LOGFONT(weight=500;color=0x6112FF;name='FontAwesome';h=-16);
  110.                             gdi.textOut(hdc,font,'\uF115 文件夹',rc.width()/2+260, rc.top+20);
  111.                                     }else {
  112.                                             font = ::LOGFONT(weight=300;color=0x9C9C9C;name='FontAwesome';h=-16);
  113.                             gdi.textOut(hdc,font,'\uF115 文件夹',rc.width()/2+260, rc.top+20);
  114.                                     }
  115.                     
  116.                     }else {
  117.                             font = ::LOGFONT(weight=300;color=0x9C9C9C;name='FontAwesome';h=-16);
  118.                             gdi.textOut(hdc,font,'\uF115 文件夹',rc.width()/2+260, rc.top+20);
  119.                     }

  120.                     //文件图标
  121.                     win.imageList.shell( 0/*_SHIL_LARGE*/ ).draw(strTab.iImage,hdc,rc.left+20,rc.top+10);
  122.                     //文件名
  123.                     font = ::LOGFONT(weight=400;color=0x000000);
  124.                     gdi.textOut(hdc,font,strTab.text,rc.left+60, rc.top+10);
  125.                     //文件大小
  126.                     font = ::LOGFONT(weight=300;color=0xB0B0B0);
  127.                     gdi.textOut(hdc,font,strTab.size,rc.left+60, rc.top+30);
  128.                     
  129.                    },drawItem.hDC,0xF5FDFF/*背景色*/,0xEEEEEE/*画笔色*/)
  130. }

  131. winform.listbox.wndproc = function(hwnd,message,wParam,lParam){
  132.     select(message) {
  133.         case 0x200/*_WM_MOUSEMOVE*/ {
  134.             var x,y = win.getMessagePos();  
  135.             var item = winform.listbox.hitTest(x,y,true);
  136.             if(item == null){
  137.                 return ;
  138.             }
  139.             
  140.             if(listboxsel == item){   /* 若鼠标在同一行item内游动 */
  141.                     x,y = win.toClient(winform.listbox.hwnd,x,y);
  142.                     for(i=1;3;1){
  143.                             select(i) {
  144.                                     case 1 {        //open
  145.                                             var rc = winform.listbox.getItemRect(item);
  146.                                             rc.left = rc.width()/2+190;
  147.                                             rc.right = rc.left+60;
  148.                                             rc.top = rc.top+10;
  149.                                             rc.bottom = rc.bottom-10 ;
  150.                                             //判断鼠标游动的区间是不是在[删除]按钮范围
  151.                                             if( ::PtInRect(rc,x,y) ){
  152.                                                 if(opensel == false){    //鼠标从[删除]按钮外部移动到内部区域
  153.                                                     opensel = true;
  154.                                                     //设置更新区,并更新
  155.                                                     winform.listbox.invalidate(winform.listbox.getItemRect(item))
  156.                                                     winform.listbox.update();
  157.                                                     break ;
  158.                                                 }
  159.                                                 continue ; //一直在内部区域游动,则不更新
  160.                                             }else {
  161.                                                 if(opensel == true){ //鼠标从内到外
  162.                                                     opensel = false;
  163.                                                     //设置更新区,并更新
  164.                                                     winform.listbox.invalidate(winform.listbox.getItemRect(item))
  165.                                                     winform.listbox.update();
  166.                                                     break ;
  167.                                                 }
  168.                                                 continue ; //一直在外部区域游动,则不更新
  169.                                             }
  170.                                                                     
  171.                                             
  172.                                     }
  173.                                     case 2 {        //file
  174.                                             var filerc = winform.listbox.getItemRect(item);
  175.                                             filerc.left = filerc.width()/2+260;
  176.                                             filerc.right = filerc.left+70;
  177.                                             filerc.top = filerc.top+10;
  178.                                             filerc.bottom = filerc.bottom-10 ;
  179.                                             //判断鼠标游动的区间是不是在[删除]按钮范围
  180.                                             if( ::PtInRect(filerc,x,y) ){
  181.                                                 if(filesel == false){    //鼠标从[删除]按钮外部移动到内部区域
  182.                                                     filesel = true;
  183.                                                     //设置更新区,并更新
  184.                                                     winform.listbox.invalidate(winform.listbox.getItemRect(item))
  185.                                                     winform.listbox.update();
  186.                                                     break;
  187.                                                 }
  188.                                                 continue ; //一直在内部区域游动,则不更新
  189.                                             }else {
  190.                                                 if(filesel == true){ //鼠标从内到外
  191.                                                     filesel = false;
  192.                                                     //设置更新区,并更新
  193.                                                     winform.listbox.invalidate(winform.listbox.getItemRect(item))
  194.                                                     winform.listbox.update();
  195.                                                     break ;
  196.                                                 }
  197.                                                 continue ; //一直在外部区域游动,则不更新
  198.                                             }
  199.                                             
  200.                                     }
  201.                                     case 3 {        //del
  202.                                             var delrc = winform.listbox.getItemRect(item);
  203.                                             delrc.left = delrc.width()/2+345;
  204.                                             delrc.top = delrc.top+20;
  205.                                             delrc.bottom = delrc.bottom-20 ;
  206.                                             //判断鼠标游动的区间是不是在[删除]按钮范围
  207.                                             if( ::PtInRect(delrc,x,y) ){
  208.                                                 if(colorsel == false){    //鼠标从[删除]按钮外部移动到内部区域
  209.                                                     colorsel = true;
  210.                                                     //设置更新区,并更新
  211.                                                     winform.listbox.invalidate(winform.listbox.getItemRect(item))
  212.                                                     winform.listbox.update();
  213.                                                     break;
  214.                                                 }
  215.                                                 continue ; //一直在内部区域游动,则不更新
  216.                                             }else {
  217.                                                 if(colorsel == true){ //鼠标从内到外
  218.                                                     colorsel = false;
  219.                                                     //设置更新区,并更新
  220.                                                     winform.listbox.invalidate(winform.listbox.getItemRect(item))
  221.                                                     winform.listbox.update();
  222.                                                     break ;
  223.                                                 }
  224.                                                 continue ; //一直在外部区域游动,则不更新
  225.                                             }
  226.                                     }
  227.                             }
  228.                     }
  229.                 return ;
  230.                         }else {
  231.                                 //设置hover效果
  232.                                 listboxsel = item;
  233.                                 if(beforesel == null){        //第一次执行,初始化
  234.                                         beforesel = listboxsel;
  235.                                        
  236.                                 }else {
  237.                                         //先关闭上次绘制区域
  238.                                         if(beforesel){
  239.                                                 winform.listbox.invalidate(winform.listbox.getItemRect(beforesel),0)        
  240.                                         }
  241.                                         beforesel = listboxsel;
  242.                                 }
  243.                                 //绘制当前区域
  244.                                 winform.listbox.invalidate(winform.listbox.getItemRect(item));
  245.                                 winform.listbox.update();
  246.                         }
  247.             }
  248.             case 0x202/*_WM_LBUTTONUP*/ {
  249.                     //删除功能
  250.                     if(colorsel){        /* 若鼠标在删除按钮区域内单击了 */
  251.                                 var selindex = winform.listbox.selIndex
  252.                                 var strTab = winform.listbox.getItemText(selindex);
  253.                                 var tabStr = eval(strTab)
  254.                                 var ret = winform.msgboxTest("您确定要删除 ["++tabStr.text++"] 文件吗?");
  255.                                 if(ret){
  256.                                         winform.listbox.delete(selindex);
  257.                                         colorsel = false;
  258.                                 }
  259.                                 return ;
  260.                         };
  261.                         //打开文件
  262.                         if(opensel){        /* 若鼠标在打开按钮区域内单击了 */
  263.                                 var selindex = winform.listbox.selIndex
  264.                                 var strTab = winform.listbox.getItemText(selindex);
  265.                                 var tabStr = eval(strTab)
  266.                                 process.execute(tabStr.filePath);
  267.                                 return ;
  268.                         }
  269.                         //打开文件夹
  270.                         if(filesel){        /* 若鼠标在打开按钮区域内单击了 */
  271.                                 var selindex = winform.listbox.selIndex
  272.                                 var strTab = winform.listbox.getItemText(selindex);
  273.                                 var tabStr = eval(strTab)
  274.                                 var path = io.splitpath(tabStr.filePath);
  275.                                 process.execute(path.dir);
  276.                                 return ;
  277.                         }
  278.             }
  279.             else {
  280.             }
  281.     }
  282. }

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

  288. winform.show();
  289. win.loopMessage();
复制代码


! www.HtmLayout.Cn 我的学习笔记
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 注册会员

本版积分规则

手机版|未经许可严禁引用或转载本站文章|站长邮箱|aardio.com|aardio官方社区 ( 皖ICP备09012014号 )

GMT+8, 2018-10-22 04:35 , Processed in 0.062500 second(s), 26 queries .

Powered by Discuz! X3.4

© 2001-2017 Comsenz Inc.

快速回复 返回顶部 返回列表