2016-12-08 33 views
1

我想创建一个使用winapi的Rust虚拟列表视图。我有一个正常的listview工作,但虚拟的不会显示任何数据。 我设置的项目编号为:虚拟列表视图不显示任何文本

user32::SendMessageW(list_hwnd, winapi::LVM_SETITEMCOUNT, (ALL_DATA.read().unwrap().len()-1) as u64, 0); 

我创建列表本身:

let style = WS_VISIBLE | WS_CHILD | WS_TABSTOP | 
      LVS_NOSORTHEADER | LVS_OWNERDATA | LVS_AUTOARRANGE | 
      LVS_SINGLESEL | LVS_REPORT; 
let hwnd = user32::CreateWindowExW(
    0, 
    wc.as_ptr() as *mut _, 
    to_wstring("").as_ptr() as *mut _, 
    style, 
    0, 
    0, 
    rc_client.right - rc_client.left, 
    rc_client.bottom - rc_client.top, 
    hwnd_parent, 
    0 as HMENU, 
    // IDC_MAIN_LISTVIEW, 
    h_instance, 
    std::ptr::null_mut() 
); 

LVN_GETDISPINFOW消息我尝试使用添加文字:

if (mask & LVIF_TEXT) == 0 { 
    let len = ALL_DATA.read().unwrap().len(); 
    if ix >= len - 1 { 
     println!("ix bigger then index! ix: {:?} len: {:?}", ix, len); 
     return 0; 

    } 
    let ref item = ALL_DATA.read().unwrap()[ix]; 

    let f = |key| { 
     let ref vec = STRING_CACHE.read().unwrap()[(key)]; 
     let ptr = STRING_CACHE.read().unwrap()[(key)].as_ptr(); 
     (ptr, vec.len()) 
    }; 

    let (ptr, _) = match (*(l_param as *const NMLVDISPINFOW)).item.iSubItem { 
     0 => f(&item.item), 
     1 => f(&item.sub_item), 
     n => { 
      println!("Found subitem: {:?}", n); 
      return 0; 
     } 
    }; 

    // Try to set text in dispinfo 
    (*(l_param as *mut NMLVDISPINFOW)).item.pszText = ptr as LPWSTR; 

    return 0; 
} 

STRING_CACHE是一个HashMap<String, Vec<u16>>。我使用这个,所以从window_prow()返回时字符串不会丢失。

当我编译并运行代码时,它似乎填充了列表视图,但没有文字可见。

The complete code can be found at GitHub

回答

1
if (mask & LVIF_TEXT) == 0 

如果LVIF_TEXT标志IS NOT目前该语句检查。您需要提供文本时的标志IS目前代替:

if (mask & LVIF_TEXT) != 0 

或者:

if (mask & LVIF_TEXT) == LVIF_TEXT 
+0

omg,我是一个阻碍!谢谢您的帮助 :) –

0

您正在使用虚拟列表视图控件,因此您不要使用LVM_INSERTITEM;相反,您只需拨打LVM_SETITEMCOUNT设置项目数,然后列表视图将负责其余部分。尤其是,您不应该手动制作LVITEM,特别是不要使用LPSTR_TEXTCALLBACK

更多的参考资料:

另外,与A端向后兼容性,并且不识别Unicode的消息;如果您处理W消息,则不需要处理它们。

+0

之前,其实我已经试过了,很抱歉这么说。我更新了SETITEMCOUNT的代码。我使用了横幅,并确保指针生存下来,它似乎设置在项目上,但仍然没有文字可见。指针是否必须居住在globalalloc或somewhere? –

+0

如果您检查[LVITEM'结构](https://msdn.microsoft.com/en-us/library/windows/desktop/bb774760(v = vs.85).aspx)的文档,您会请参阅'pszText'字段文档,指针必须保持有效,直到“收到下一个通知后”。我不知道这是否意味着在下一个'LVN_GETDISPINFO'之后,对于任何单元格或特定单元格而言,但这意味着它必须在从窗口过程返回后才能生存。我不知道如何在Rust中做到这一点;抱歉。 – andlabs

+0

谢谢任何​​方式。我将所有字符串存储在全局变量中,只要程序正在运行,它们就是有效的。我甚至试图用GlobalAlloc分配它们,但ListView中仍然没有文本。 –