给listview的单元格添加tooltip气泡提示

Mr_MAO 5天前 194

//当listview中单元格的字符串宽度大于列宽(文本溢出)时,显示tooltip气泡提示
 
import win.ui;
/*DSG{{*/
var winform = win.form(text="ListView单元格添加tooltip提示";right=559;bottom=367)
winform.add(
listview={cls="listview";left=32;top=32;right=520;bottom=320;edge=1;fullRow=1;gridLines=1;z=1}
)
/*}}*/
 
import win.ui.tooltip;
import gdip;
 
winform.listview.columns = [
    ["序号",40],
    ["ISBN",100],
    ["标题",130],
    ["作者",60],
    ["出版社",100],
    ["价格",50]
]
 
winform.listview.items = {
    {"1","978-7-5217-0652-9","平凡的世界","路遥","陕西人民出版社","30"};
    {"2","978-7-218-13617-2","零基础Python从入门到精通","零查快学","广东人民出版社","50"};
    {"3","978-7-111-12345-6","这是一个超级超级超级长的书名用来测试提示功能","作者名","出版社名称","99"};
}
 
// 创建 tooltip 控件
var tooltipCtrl = win.ui.tooltip(winform);
var currentTool = false;
 
// 检查文本是否超出列宽的自定义函数
var isTextOverflow = function(text, columnWidth, font){
    if(!text || text == "") return false;
 
    var hdc = ::GetDC(winform.listview.hwnd);
    var gdipFont = gdip.font(hdc, font);
    
    var g = gdip.graphics(hdc);
    var rc,len = g.measureString(text, gdipFont, ::RECTF(), gdip.stringformat());
    ::ReleaseDC(winform.listview.hwnd, hdc);
 
    var scaleX = winform.getScale();  //考虑界面的scale
    return rc.width * scaleX > columnWidth;  //此处不太完善
}
 
// 处理鼠标移动事件
winform.listview.wndproc = function(hwnd,message,wParam,lParam){
    if(message == 0x200/*_WM_MOUSEMOVE*/){
        var x = lParam & 0xFFFF;
        var y = (lParam >> 16) & 0xFFFF;
 
        // 获取鼠标位置的单元格
        var row, col = winform.listview.hitTest(x, y);
 
        if(row && col){
            // 获取单元格文本
            var cellText = winform.listview.getItemText(row, col);
 
            // 获取列宽
            var columnWidth = winform.listview.getItemRect(row, col,,2/*_LVIR_LABEL*/).width;           
             
            // 获取字体
            var font = winform.listview.getFont()
 
            // 检查文本是否溢出
            if( isTextOverflow(cellText, columnWidth, font) ){
                var toolKey = row ++ "," ++ col;
                if(currentTool != toolKey){ 
                    if(currentTool){
                        var ti = tooltipCtrl.getTool(winform.listview)
                        if(ti) tooltipCtrl.delTool(ti);
                    }
                    currentTool = toolKey;
                    tooltipCtrl.addTool(winform.listview, cellText);
                }
            }else{
                // 文本未溢出,删除前面tooltip
                if(currentTool){
                    var ti = tooltipCtrl.getTool(winform.listview)
                    if(ti) tooltipCtrl.delTool(ti);
                    currentTool = false;
                }    
            }
        }else{
            if(currentTool){
                var ti = tooltipCtrl.getTool(winform.listview)
                if(ti) tooltipCtrl.delTool(ti);
                currentTool = false;
            }      
        }
    }
}
 
winform.show();
win.loopMessage();


最新回复 (3)
  • netfox 4天前
    0 2

  • 近我者赤 3天前
    0 3
    只2,3列支持,4,5列不支持吗?
  • Mr_MAO 2天前
    0 4
    近我者赤 只2,3列支持,4,5列不支持吗?

    上面代码没有考虑两个方面:一是listview单元格的padding;二是在列宽只有一个字符溢出时,listview在处理字符溢出时会减一个字符并加上"...",减去的一个“英文字符”与“中文字符”宽度实际上是不同的,所以不太完善😀~

返回