我知道我不应该从没有创建它的线程访问控件,但我还是尝试了它并且得到了一个非常特殊的错误。我在汇编中做过,每个人都讨厌阅读,所以这里是C中的等价代码:
/* Function that returns the number of characters after startOfItem
that are not some delimeter. startOfItem[maxSize] is guaranteed to
be at a valid address and to be a delimiter. The function is defined
elsewhere and works perfectly. */
unsigned int getSizeOfItem(char* startOfItem, unsigned int maxSize);
/* This function runs in a worker thread. It has an exception handler that is
omitted here for clarity, and because it is never run anyway. */
void itemizeAndAddToListbox (HWND hListbox, char* strings, unsigned int size) {
while (size) {
unsigned int sizeOfItem = getSizeOfItem(strings, size);
strings[sizeOfItem] = 0; //overwrite the delimiting character with null
SendMessage( hListbox, LB_ADDSTRING, (WPARAM) 0, (LPARAM) strings );
/* passing a pointer to a different thread is a no-no, but SendMessage
does not return until the message is processed, so no disposal issues
are possible. And I happen to know that all addresses from *strings
to strings[sizeOfItem] remain valid. */
strings += sizeOfItem+1;
size -= sizeOfItem+1;
};
}
信不信由你,这可以完美地从一个没有创建hListbox的线程直到最后一个项目,此时列表框通过读取字符串[size + 1]导致访问冲突。它在UI线程(创建列表框的线程)中抛出异常,忽略工作线程的异常处理程序。 SendMessage()不恰当地返回0而不是列表框错误代码。
我通过从工作线程向UI线程的窗口发送用户定义的消息来完成这项工作,该窗口又将具有相同参数的LB_ADDSTRING消息发送到完全相同的列表框,并且它完美地工作。当从UI线程发送消息时,异常还没有发生,但这是一个随机的差异,我对正确的工作代码感到紧张。任何人都知道列表框首先在字符串的空终止结束之外访问内存,以及我可以做些什么来阻止它这样做?
答案 0 :(得分:0)
由于SendMessage()将调用序列化到接收线程,因此我希望在UI线程上发生异常,因为那是添加字符串的那个。
MSDN SendMessage: '返回值指定消息处理的结果;这取决于发送的消息。这不是列表框中的错误代码,除非消息处理程序将其放在那里,否则不会将异常放入消息字段中。
如果你用一个1号的字符串打电话,最后'size'会发生什么?将'size'设置为-1,即。不是假的?
RGDS, 马丁