• listview 样式 LVS_REPORT 与 LVS_EDITLABELS 编辑单元格时,当前行第一列内容不显示


    今天想做一个可编辑单元格的 listview,样式是 LVS_REPORT LVS_EDITLABELS

    网上搜索了一些相关资料,照葫芦画瓢写了一个,可测试的时候发现,当从第2列开始编辑的时候,第1列的内容就显示不出来。

    网上搜索了一下,有一个网友和我遇到的问题一样: https://stackoverflow.com/questions/8658128/subclassing-list-view-to-edit-only-its-subitems?rq=1

    下面是他贴出来的代码:

    WNDPROC     wpOrigEditProc;
    RECT        rcSubItem;
    
    LRESULT CALLBACK WndProcEditList(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) {
        switch (uMsg) {
            case WM_WINDOWPOSCHANGING:
                {
                    WINDOWPOS *pos = (WINDOWPOS*) lParam;
    
                    pos->x  = rcSubItem.left; // 定位 listview 编辑框的位置
                    pos->cx = rcSubItem.right;
                }
                break;
            default:
                return CallWindowProc(wpOrigEditProc, hWnd, uMsg, wParam, lParam);
        }
        return 1;
    } 
    
    LRESULT CALLBACK WndProcList(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) {
        static HWND             hEdit;
        static RECT             rc;
        static LVITEM           lvI;
        static unsigned char    bEditing = 0;
        switch (uMsg) {
            case WM_NOTIFY:
                switch (((NMHDR*) lParam)->code) {
                    case NM_CLICK:
                        lvI.iItem       = ((NMITEMACTIVATE*) lParam)->iItem;
                        lvI.iSubItem    = ((NMITEMACTIVATE*) lParam)->iSubItem;
                        break;
                    case NM_DBLCLK:
                        SendMessage(hWnd, LVM_EDITLABEL, lvI.iItem, 0);
                        break;
                    case LVN_BEGINLABELEDIT:
                        {
                            char    text[32];
                            bEditing        = 1;
                            hEdit           = (HWND) SendMessage(hWnd, LVM_GETEDITCONTROL, 0, 0);
                            rcSubItem.top   = lvI.iSubItem;
                            rcSubItem.left  = LVIR_LABEL;
                            SendMessage(hWnd, LVM_GETSUBITEMRECT, lvI.iItem, (long) &rcSubItem);
                            rcSubItem.right = SendMessage(hWnd, LVM_GETCOLUMNWIDTH, lvI.iSubItem, 0);
                            wpOrigEditProc  = (WNDPROC) SetWindowLong(hEdit, GWL_WNDPROC, (long) WndProcEditList);
                            lvI.pszText     = text;
                            lvI.cchTextMax  = 32;
                            SendMessage(hWnd, LVM_GETITEMTEXT, lvI.iItem, (long) &lvI);
                            SetWindowText(hEdit, lvI.pszText);
                        }
                        break;
                    case LVN_ENDLABELEDIT:
                        bEditing = 0;
                        SetWindowLong(hEdit, GWL_WNDPROC, (long) wpOrigEditProc);
                        if (!lvI.iSubItem) return 1;
                        lvI.pszText = ((NMLVDISPINFO*) lParam)->item.pszText;
                        if (!lvI.pszText) return 1;
                        SendMessage(hWnd, LVM_SETITEMTEXT, lvI.iItem, (long) &lvI);
                        break;
                    default:
                        return CallWindowProc((WNDPROC) GetClassLong(hWnd, GCL_WNDPROC), hWnd, uMsg, wParam, lParam);
                }
                break;
            case WM_PAINT:
                if (bEditing) {
                    RECT rcItem;
                    if (lvI.iSubItem > 0) {
                        rcItem.left = LVIR_LABEL;
                        if (SendMessage(hWnd, LVM_GETITEMRECT, lvI.iItem, (long) &rcItem))
                            ValidateRect(hWnd, &rcItem);
                    }
                }
            default:
                return CallWindowProc((WNDPROC) GetClassLong(hWnd, GCL_WNDPROC), hWnd, uMsg, wParam, lParam);
        }
        return 0;
    }
    
    LRESULT CALLBACK WndProcMain(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) {
        static HWND hList;
        static RECT rc;
        switch (uMsg) {
            case WM_NOTIFY:
                switch (((NMHDR*) lParam)->code) {
                    case NM_CLICK:
                    case NM_DBLCLK:
                    case LVN_BEGINLABELEDIT:
                    case LVN_ENDLABELEDIT:
                        return CallWindowProc(WndProcList, ((NMHDR*) lParam)->hwndFrom, uMsg, wParam, lParam);
                }
                break;
            case WM_CREATE:
                {
                    LVCOLUMN        lvc;
                    LVITEM          lvI;
                    unsigned int    i;
                    float           vertex;
                    char            text[32];
    
                    hList = CreateWindow(WC_LISTVIEW, 0, WS_CHILD | WS_VISIBLE | LVS_REPORT | LVS_EDITLABELS, rc.left, rc.top, rc.right, rc.bottom, hWnd, 0, hInstance, 0);
                    SendMessage(hList, LVM_SETEXTENDEDLISTVIEWSTYLE, 0, LVS_EX_FULLROWSELECT | LVS_EX_GRIDLINES);
                    SetWindowLong(hList, GWL_WNDPROC, (long) WndProcList);
    
                    lvc.mask    = LVCF_WIDTH;
                    lvc.cx      = 30;
                    SendMessage(hList, LVM_INSERTCOLUMN, 0, (LPARAM) &lvc);
    
                    lvc.mask    = LVCF_TEXT;
                    lvc.pszText = "Vertex";
                    SendMessage(hList, LVM_INSERTCOLUMN, 1, (LPARAM) &lvc);
                    SendMessage(hList, LVM_SETCOLUMNWIDTH, 1, LVSCW_AUTOSIZE_USEHEADER);
    
                    lvI.mask    = LVIF_TEXT;
                    lvI.pszText = text;
    
                    for (i = 0; i < 10; i++) {
                        vertex = (float) i;
                        lvI.iItem       = i;
                        lvI.iSubItem    = 0;    
                        sprintf(text, "%d", i);
                        SendMessage(hList, LVM_INSERTITEM, 0, (LPARAM) &lvI);
                        lvI.iSubItem    = 1;    
                        sprintf(text, "%f, %f, %f", vertex - 1, vertex, vertex + 1);
                        SendMessage(hList, LVM_SETITEM, 0, (LPARAM) &lvI);
                    }
                }
                break;
            case WM_SIZE:
                GetClientRect(hWnd, &rc);
                MoveWindow(hList, rc.left, rc.top, rc.right, rc.bottom, 1);
                SendMessage(hList, LVM_SETCOLUMNWIDTH, 1, LVSCW_AUTOSIZE_USEHEADER);
                break;
            case WM_DESTROY:
                PostQuitMessage(0);
                break;
            default:
                return DefWindowProc(hWnd, uMsg, wParam, lParam);
        }
        return 0;
    }

    至于为什么当编辑第2,3,... 列时,当前行的第1列的内容不显示的原因,我还是没找到。

    不过我找到了一个解决办法: 就是给 listview 添加一个空白列, 宽度设置为 0

    lvc.mask = LVCF_TEXT | LVCF_WIDTH | LVCF_FMT;

    lvc.pszText = "";
    lvc.cx = 0; //宽度设置为 0
    lvc.fmt = LVCFMT_CENTER;

    这也是不是办法的办法了,反正我没有更好的解决方案。

  • 相关阅读:
    Linux内核通杀提权漏洞CVE-2016-5195
    Android APP安全评估工具 Drozer
    (转)手机安全测试
    微信公众号获取的图片不能正常显示的问题
    android开发时gen和bin目录的SVN管理(转)
    处理千万级以上的数据提高查询速度的方法(转)
    Java遍历JSON
    Java反射得到属性的值和设置属性的值(转)
    java如何得到GET和POST请求URL和参数列表(转)
    Oracle Database 11G R2 标准版 企业版 下载地址(转)
  • 原文地址:https://www.cnblogs.com/personnel/p/9407556.html
Copyright © 2020-2023  润新知