Article View: borland.public.cppbuilder.nativeapi
Article #475Re: Cleaning up after using GetDisplayNameOf()
From: Darko Miletic
Date: Thu, 13 Mar 2008 13:23
Date: Thu, 13 Mar 2008 13:23
138 lines
5091 bytes
5091 bytes
> Do I have to take care of freeing that memory, or is someone else taking
> care of freeing the STRRET.pOleStr (e.g. pDesktopFolder) ?
Yes you do as stated in documentation.
>
> Please feel free to mention any other (clean-up) issues that you might
> notice with the code sample below.
>
> Thanks,
>
> Kris
First of all if your app is VCL CoInitialize is not needed. By default
COM is initialized in VCL app.
I would never assume anything in API. You should always check uType to
see what is the appropriate action. Also for safety reasons it would be
good to use RAII idiom to handle resource cleanup properly.
Here is my version of the same thing. It is longer and uses only
standard C and C++ library together with Windows API hence it is console
app.
The only thing that can be removed in VCL app is use of ole_init.
//---------------------------------------------------------------------------
#include <windows.h>
#include <shlobj.h>
#include <cstdlib>
#include <string>
#include <vector>
#include <iostream>
#pragma comment(lib,"shell32.lib")
//---------------------------------------------------------------------------
struct ole_init {
ole_init(void) : _isinit(false) {
_isinit = SUCCEEDED(::CoInitialize(NULL));
}
~ole_init(void) {
if (_isinit) {
_isinit = false;
::CoUninitialize();
}
}
bool init_ok(void) const { return _isinit; }
private:
bool _isinit;
};
std::wstring string2wstring (const std::string& str) {
std::wstring result;
if (!str.empty()) {
std::vector<wchar_t> buffer(str.size());
std::size_t res = std::mbstowcs(&buffer[0],str.c_str(),str.size());
if (res > 0) {
result.assign(buffer.begin(),buffer.end());
}
}
return result;
}
struct pidl_holder {
explicit pidl_holder(int folder) : _pidl(NULL) {
LPITEMIDLIST ppidl = NULL;
HRESULT hr = ::SHGetSpecialFolderLocation(NULL,folder,&ppidl);
if (SUCCEEDED(hr)) {
_pidl = ppidl;
}
}
~pidl_holder(void) { release(); }
LPITEMIDLIST ptr(void) {return _pidl;}
private:
LPITEMIDLIST _pidl;
void release(void) {
if (NULL != _pidl) {
::CoTaskMemFree(_pidl);
_pidl = NULL;
}
}
};
struct shdesktop_folder {
shdesktop_folder(void) : _desktop_folder(NULL) {
LPSHELLFOLDER df = NULL;
if (SUCCEEDED(::SHGetDesktopFolder(&df))) {
_desktop_folder = df;
}
}
~shdesktop_folder(void) {
if (NULL != _desktop_folder) {
_desktop_folder->Release();
_desktop_folder = NULL;
}
}
LPSHELLFOLDER ptr(void) { return _desktop_folder; }
private:
LPSHELLFOLDER _desktop_folder;
};
std::wstring get_display_name(void) {
ole_init ol;
std::wstring result;
if (ol.init_ok()) {
pidl_holder pidlobj(CSIDL_PERSONAL);
LPITEMIDLIST pidl = pidlobj.ptr();
if (NULL != pidl) {
shdesktop_folder deskFolder;
LPSHELLFOLDER pDesktopFolder = deskFolder.ptr();
if (NULL != pDesktopFolder) {
STRRET sname = {};
HRESULT hr = pDesktopFolder->GetDisplayNameOf( pidl
,SHGDN_INFOLDER
,&sname);
if (SUCCEEDED(hr)) {
if (sname.uType == STRRET_WSTR) {
result = sname.pOleStr;
::CoTaskMemFree(sname.pOleStr);
sname.pOleStr = NULL;
} else if (sname.uType == STRRET_CSTR) {
result = string2wstring(sname.cStr);
} //else here add the third case code
}
}
}
}
return result;
}
int main(int /*argc*/, char** /*argv[]*/)
{
std::wcout << get_display_name() << std::endl;
return EXIT_SUCCESS;
}
//---------------------------------------------------------------------------
Technical Details
Message-ID:
<47d92ad2@newsgroups.borland.com>Path:
arc1-ca.pugleaf.net!g2news1.google.com!news3.google.com!proxad.net!feeder1-2.proxad.net!194.25.134.126.MISMATCH!newsfeed01.sul.t-online.de!t-online.de!newsgroups.borland.com!not-for-mailReferences:
<47d8ec90$1@newsgroups.borland.com>Show Full Headers
Complete Article Headers
X-Google-Thread: 10cc67,b8d31d04a1ebb7b9 X-Google-Attributes: gid10cc67,public,usenet X-Google-Language: ENGLISH,ASCII-7-bit Date: Thu, 13 Mar 2008 11:23:16 -0200 From: Darko Miletic <kiklop@fibertel.com.ar> Reply-To: Darko Miletic <kiklop@fibertel.com.ar> User-Agent: Thunderbird 2.0.0.12 (Windows/20080213) MIME-Version: 1.0 Newsgroups: borland.public.cppbuilder.nativeapi Subject: Re: Cleaning up after using GetDisplayNameOf() References: <47d8ec90$1@newsgroups.borland.com> In-Reply-To: <47d8ec90$1@newsgroups.borland.com> Content-Type: text/plain; charset=ISO-8859-1; format=flowed Content-Transfer-Encoding: 7bit X-Antivirus: avast! (VPS 080313-0, 13/03/2008), Outbound message X-Antivirus-Status: Clean NNTP-Posting-Host: 200.49.157.165 Message-ID: <47d92ad2@newsgroups.borland.com> X-Trace: newsgroups.borland.com 1205414610 200.49.157.165 (13 Mar 2008 06:23:30 -0700) Lines: 138 Path: arc1-ca.pugleaf.net!g2news1.google.com!news3.google.com!proxad.net!feeder1-2.proxad.net!194.25.134.126.MISMATCH!newsfeed01.sul.t-online.de!t-online.de!newsgroups.borland.com!not-for-mail