Win32 ListView - 在LVM_INSERTITEM之后处理无效

时间:2015-03-06 14:53:16

标签: c++ windows listview winapi sendmessage

调用

后,窗口句柄(窗口类= WC_LISTVIEW)出现问题
SendMessage(hListView_, LVM_INSERTITEM , 0, (LPARAM)&lvItem);

,其中

hListView_

是列表视图窗口的句柄和

lvItem

是一个LVITEM结构。以下代码

std::cout << "Last error: " << GetLastError() << std::endl;
SendMessage(hListView_, LVM_INSERTITEM , 0, (LPARAM)&lvItem);
std::cout << "Last error: " << GetLastError() << std::endl;

打印

Last error: 0
Last error: 6

根据Win32 System Error Codes代码6表示ERROR_INVALID_HANDLE。

我按如下方式创建LVITEM结构:

// define a char-buffer
char szBuffer[256];
szBuffer[0] = '\0';

// create new list view item
LVITEM lvItem;
lvItem.cchTextMax = 256;
lvItem.mask = LVIF_TEXT;
lvItem.iItem = 0;
lvItem.stateMask = 0;
lvItem.state = 0;
lvItem.iSubItem = 0;
snprintf(szBuffer, 256, "%s", myString.c_str());
lvItem.pszText = szBuffer;

从创建窗口的同一线程(列表视图)调用此代码。 还要注意我有

lvItem.iSubItem = 0;

根据LVM_INSERTITEM要求。此调用之前列表视图为空。而且,我实际上可以看到列表视图中插入的值(即我可以在GUI的列表视图中看到该项)。 但是,当我尝试使用窗口句柄后,应用程序崩溃(没有异常,只是崩溃)。

非常了解可能导致此问题的任何提示。

谢谢。

2 个答案:

答案 0 :(得分:-1)

您没有理由致电GetLastErrorLVM_INSERTITEM的文档并未说明您应该这样做。它只是说SendMessage在成功时返回新项的索引,在失败时返回-1。因此,通过检查SendMessage返回的值来检查错误。

另一个问题是您没有初始化LVITEM的所有字段。这总是一个错误。你可以使用这样的初始化声明:

LVITEM lvItem = { 0 };

没有真正需要单独的文本缓冲区。你可以这样做:

LVITEM lvItem = { 0 };
lvItem.mask = LVIF_TEXT;
lvItem.cchTextMax = myString.length() + 1;
lvItem.pszText = myString.c_str();
int indexOfNewItem = SendMessage(hListView_, LVM_INSERTITEM, 0, (LPARAM)&lvItem);
if (indexOfNewItem == -1)
    // deal with failure

事实上你的错误很可能存在于其他地方。我没有看到SendMessage调用导致应用程序崩溃的任何特定原因。至少现在您知道在发送LVM_INSERTITEM时如何检查错误。如果这不会导致错误,那么证据就是崩溃是由其他一些代码引起的,并且您错误地识别了此代码,因为当它的值没有意义时,您错误地调用了GetLastError

答案 1 :(得分:-1)

谢谢David Heffernan的帮助。我终于找到了问题,这是(正如你的建议)在代码中的不同位置。

我错过了以下一行(在我上面发布的代码之前调用的另一个函数)

lvItem.pszText = szBuffer;

,其中

char szBuffer[256]; // char-buffer

进行以下通话时

SendMessage(hListView_, LVM_GETITEMTEXT, (WPARAM) i, (LPARAM) &lvItem);

非常感谢你的帮助!

编辑:如果我已经完成

lvItem.pszText = myString.c_str();

而不是char-buffer这可能不会发生,所以谢谢你的提示!