这次说的是如何在XP/2003的任务列表中添加自己的任务。
CodeProject上有篇文章,
Namespace Extensions: The Tasks Band Disclosed
By Henk Devos
By Henk Devos
说的是这个主题。但是这位大拿有个关键地方讲错了。我实现了所有的接口,但是Explorer在get_Name()后报出:RtlHeapFree( 00090000, xxxxxxxx )错误。
在newsgroups上左找右找,发现有人说他遇到过同样问题,下面有人跟贴,说他顺利解决,并贴出源码。看了一眼发现和我的没任何本质区别,为什么这小子就成功了呢?!
经过一个多小时和一个午饭的间隔,终于找到原因。发现跟贴那个小子估计是在吹牛,因为那篇文章中涉及的所有BSTR类型,都应该是LPWSTR。
这两者有什么区别呢?
BSTR是微软为ActiveX(之前叫做OLE)专门设计的字符串类型,有自己独特的分配函数SysAllocString和释放函数SysFreeString。其内部数据结构为:
DWORD len;
WCHAR str[...];
其中len记录的是str的长度,不包括null结束符。而SysAllocString返回的地址和SysFreeString接受的地址都是&str[0],而不是&len。对于C++来说,微软给BSTR的定义是:
typedef WCHAR* LPWSTR;
typedef LPWSTR LPOLESTR;
typedef LPOLESTR BSTR;
而它的根源,WCHAR*,根本就没有这个特征。SysAllocString分配得到的内存,实际上是&len,而不是&str[0],因此SysFreeString实际上相等于:
RtlHeapFree( m_hBSTRAllocHeap, (LPVOID)((LPBYTE) buf - sizeof(DWORD)) );
可以想见,用另外一个不知道BSTR细节的HeapFree释放&str[0],当然会出错。
在写了一个自己的NSEAllocString后,问题解决。 :)