2010-06-29 82 views
3

我正在使用SHGetSpecialFolderLocation API函数。我的应用程序设置为“使用Unicode字符集”。C++:在API函数中使用std :: wstring

这是我到目前为止有:

int main (int, char **) 
{ 
    LPITEMIDLIST pidl; 
    HRESULT hr = SHGetSpecialFolderLocation(NULL, CSIDL_PERSONAL, &pidl); 


    /* Confused at this point */ 
    wstring wstrPath; 

    wstrPath.resize (_MAX_PATH); 
    BOOL f = SHGetPathFromIDList(pidl, wstrPath.c_str()); 
    /* End confusion */ 

我得到的错误是:

error C2664: 'SHGetPathFromIDListW' : cannot convert parameter 2 from 'const wchar_t *' to 'LPWSTR' 

有人能帮忙吗?什么是适当的C++方法来做到这一点?

谢谢!

+1

与这个问题没有什么关系,但'SHGetSpecialFolderLocation' /'SHGetSpecialFolderPath'已经过时。微软建议'SHGetKnownFolderPath'(http://msdn.microsoft.com/en-us/library/bb762188.aspx),或者,如果你想保持与Windows XP的兼容,'SHGetFolderPath'(http://msdn.microsoft .COM/EN-US /库/ bb762181.aspx)。 – Philipp 2010-06-29 06:56:33

回答

6

第二个参数是一个参数,所以不能只通过c_str(这是const)直接。这可能是最简单的做法:

wchar_t wstrPath[MAX_PATH]; 
BOOL f = SHGetPathFromIDList(pidl, wstrPath); 

MAX_PATH目前有260个字符。

+1

+1。我们也可以使用std :: vector 来实现这个功能,并使用&v [0],但是当使用MAX_PATH像这样容易地在堆栈中分配char缓冲区时,我们可以使用它,它既是最简单也是最快的解决方案。 – stinky472 2010-06-29 01:47:27

+0

@Stinky:你也可以做&wstrPath [0]。没有理由你被迫在这里使用一个字符串。 – 2010-06-29 01:48:35

+0

谢谢一堆。 :)我仍然在学习C++。 – 2010-06-29 02:23:20

1

std::basic_string::c_str()返回一个常量缓冲区到它的内存。如果要修改字符串,你必须做这样的事情:

wstring wstrPath; 
wstrPath.resize(MAX_PATH); 
BOOL f = SHGetPathFromIDList(pidl, &wstrPath[0]); 
wstrPath.erase(
    std::find(wstrPath.begin(), wstrPath.end(), L'\0'), wstrPath.end() 
); //Throw away unused buffer space 

编辑:这应该如果你不害怕C库的工作也(虽然我没有测试它像我测试过的实现上):

wstring wstrPath; 
wstrPath.resize(MAX_PATH); 
BOOL f = SHGetPathFromIDList(pidl, &wstrPath[0]); 
wstrPath.resize(wcslen(wstrPath.c_str())); 
1

wstring::c_str()回报const wchar_t*只有读取。 LPWSTR不是const类型,并且该参数是out参数。您将需要自己分配缓冲区。你可以这样做:

wchar_t buf[MAX_PATH] = {0}; 
BOOL f = SHGetPathFromIDList(pidl, buf); 
wstring wstrPath = buf; 
+1

为什么{}中的零点? – 2010-06-29 01:46:15

+0

它将buf数组的所有元素初始化为零。如果初始化器列表的长度小于数组的大小,则其余元素将初始化为零,因此将第一个元素初始化为零实际上会将整个buf数组清零。 – 2010-06-29 13:14:13

+0

因为同样的原因,空括号'{}'也是如此。 (复活一个非常古老的线程,我知道,可以随意忽略:)) – 2014-12-15 18:10:00

0

wstring :: c_str()不允许你用这种方式修改它的内部缓冲区。你最简单的解决方法是创建一个wchar_t的缓冲自己,并把它传入的wstring构造:

wchar_t buf[MAX_PATH]; 
BOOL f = SHGetPathFromIDList(pidl, buf); 
wstring wstrPath(buf); 
+0

这里唯一的缺点是你最终复制缓冲区两次。 – 2010-06-29 01:56:36

0

可以在basic_string的获得1个数组项的地址指针可写字符串数据。虽然C++标准不能保证这块内存必须是连续的,但在所有已知的实现中都是安全的(How bad is code using std::basic_string as a contiguous buffer)。

std::wstring path(_MAX_PATH, L'\0'); 
BOOL f = SHGetPathFromIDList(pidl, &path[0]);