1

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

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

但是strlen(bufText)等于1,唯一的字符bufText是列表视图子项的第一个。

我在这里做错了什么?

4

2 回答 2

4

这是我的代码:

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

但是strlen(bufText)等于1,唯一的字符 bufText是列表视图子项的第一个。

我在这里做错了什么?

我认为问题在于您正在构建 Unicode 模式(自 VS2005 以来一直是默认模式),因此ListView_GetItemText()向您发送了一个 Unicode 字符串,但您有一个mismatch,因为类型bufTextchar*(即 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

(因为is的 Unicode UTF-16 表示,for his ,for is ,for is ;是 Unicode终止符。)0x0068e0x0065l0x006Co0x006F0x0000NUL

但是当您将上述字节序列解释ANSI string时,ANSI 字符串的(单字节)终止符是(ASCII ) 字节之后的第一个字节,因此在 ANSI 中您只需得到:NUL 0x000x68h

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

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


我的建议是只迁移到现代软件中的 Unicode 构建

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

例如

#include <vector> // for std::vector

....
//
// Allocate a vector of 256 wchar_t's (so use Unicode).
//
// (Note: Memory is automatically cleaned up in the destructor,
// no need for *manual* delete[].)
//
std::vector<wchar_t> bufText( 256 );

//
// Get text from the list-view control.
//
ListView_GetItemText
(
    GetDlgItem(myWindow, MYLISTVIEW), 
    myInt, 
    1, 
    &bufText[0],    // <--- pointer to first character in the buffer
    bufText.size()  // <--- size of the buffer, in wchar_t's
);
于 2013-07-01T10:33:31.047 回答
2

您正在使用 Unicode 构建,但将 ANSI 缓冲区(通过强制转换)传递给控件。更改自:

char* bufText = new char[256];

到:

wchar_t* bufText = new wchar_t[256];

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

于 2013-07-01T09:30:39.727 回答