ListView_GetItemText只获取第一个字符

时间:2013-07-01 09:10:13

标签: c++ winapi listview

我正在尝试使用ListView_GetItemText()获取ListView子项的文本值 这是我的代码:

char *bufText = new char[256];
ListView_GetItemText(GetDlgItem(myWindow, MYLISTVIEW), myInt, 1, (LPTSTR)bufText, 256);
myInt是列表视图中一行的索引。

strlen(bufText)等于1,bufText中唯一的字符是list-view子项的第一个字符。

我在这里做错了什么?

2 个答案:

答案 0 :(得分:4)

  

这是我的代码:

char *bufText = new char[256];
ListView_GetItemText(GetDlgItem(myWindow, MYLISTVIEW), myInt, 1, (LPTSTR)bufText, 256);
     

strlen(bufText)等于1,是唯一的字符   bufText是list-view子项的第一个。

     

我在这里做错了什么?

我认为问题在于你以Unicode模式构建(这是自VS2005以来的默认设置),所以ListView_GetItemText()向你发送了一个Unicode字符串,但你有一个< strong> mismatch ,因为bufText的类型是char*(即ANSI / MBCS字符串),而不是wchar_t*(即Unicode UTF-16字符串)。

编译器帮助您,给您一条错误消息,因为您传递的指针是ANSI / MBCS字符串(char* bufText参数)而不是wchar_t*
但是,不是试图监听编译器,而是使用错误的类型转换为LPTSTR(在Unicode版本中将其扩展为wchar_t*)将其关闭。


那么,你为什么只得到一个角色

假设存储在列表视图控件中的文本(由ListView_GetItemText()检索)为"hello"

它在内存中的Unicode表示是:

68 00   65 00   6C 00   6C 00   6F 00   00 00
  h       e       l        l      o      NUL

(因为h的Unicode UTF-16表示为0x0068e的{​​{1}}为0x0065l的{​​{1}}为0x006Co0x006F; 0x0000是Unicode NUL终止符。)

但是当将上述字节序列解释为 ANSI字符串时,ANSI的(单字节)NUL终止符string是0x00(ASCII 0x68)字节后面的第一个 h字节,所以在ANSI中你只得到:

68  00      <---- ANSI stops at the *first* 0x00 byte
 h  \0

即。 "h" ANSI字符串,因此您只需获取初始Unicode UTF-16字符串的第一个字符


我的建议是转到现代软件中的Unicode版本

此外,那些原始C类数组字符不是现代C ++:它们不是异常安全的,而且你必须注意手动 {{1返回的指针等。
最好使用现代强大的RAII容器,例如delete[]std::vector

e.g。

std::wstring

答案 1 :(得分:2)

您正在使用Unicode构建,但是向控件传递(使用强制转换)ANSI缓冲区。改变自:

char* bufText = new char[256];

为:

wchar_t* bufText = new wchar_t[256];

(或者,如果您特别想使用ANSI,请发送LVM_GETITEMTEXTA消息而不是使用宏。)