SHGetFileInfo не возвращает местоположение значка

Я пытаюсь извлечь значок файла и вернуть его в GetIconLocation расширения оболочки. вообще меняю иконки файлов (te.docx.xx) с расширением xx и возвращаю иконку файла без xx. (для этого я создаю временный файл в каталоге temp с исходным расширением, например, te.docx) моя операционная система — Windows 7 x64. мой код:

    STDMETHODIMP CTxtIconShlExt::GetIconLocation (
    UINT uFlags,  LPTSTR szIconFile, UINT cchMax,
    int* piIndex, UINT* pwFlags )
{
DWORD     dwFileSizeLo, dwFileSizeHi;
DWORDLONG qwSize;
HANDLE    hFile;
OutputDebugStringW(L"Hello world, from GetIconLocation !");
    std::string strFilePath;
    std::string tempFolder="c:\\.tmp";
    std::string tempFile="tmpfile";
    std::string fileWithOutDN;
    SHFILEINFO retShFileInfo;
    for(int i = 0; m_szFilename[i] != 0; i++)
    {
        strFilePath += m_szFilename[i];
        }

    fileWithOutDN= strFilePath.substr(0,strFilePath.size()-3 );
    std::string extension = fileWithOutDN.substr(fileWithOutDN.find_last_of("."));
    CreateDirectory(tempFolder.c_str(),NULL);

    tempFile=tempFolder+"\\"+tempFile+extension;

    GetFileAttributes(tempFile.c_str()); // from winbase.h
    if(INVALID_FILE_ATTRIBUTES == GetFileAttributes(tempFile.c_str()) && GetLastError()==ERROR_FILE_NOT_FOUND)
    {
        //File not found
        HANDLE h = CreateFile(tempFile.c_str(),    // name of the file
                          GENERIC_WRITE, // open for writing
                          0,             // sharing mode, none in this case
                          0,             // use default security descriptor
                          CREATE_ALWAYS, // overwrite if exists
                          FILE_ATTRIBUTE_NORMAL,
                          0);
        if (h)
        {
             CloseHandle(h);
        }else
        {
            return S_FALSE; //faild to create file
        }
    }

    ZeroMemory(&retShFileInfo, sizeof(SHFILEINFO));
    CoInitialize(NULL);
    SHGetFileInfo(tempFile.c_str(),256,&retShFileInfo,sizeof(SHFILEINFO),SHGFI_ICON | SHGFI_LARGEICON);
    lstrcpyn ( szIconFile, retShFileInfo.szDisplayName, cchMax );
    *piIndex = retShFileInfo.iIcon;
    *pwFlags = 0;
    return S_OK;

моя проблема в том, что retShFileInfo.szDisplayName возвращает пустой массив (все элементы равны нулю), он должен возвращать полный путь к местоположению значка. Я пытаюсь играть с комбинацией флагов, но ничего не помогает


person Beno    schedule 19.08.2013    source источник
comment
Вы должны использовать флаг SHGFI_ICONLOCATION, чтобы получить местоположение значка. Кроме того, CreateFile() возвращает INVALID_HANDLE_VALUE в случае сбоя, что равно -1, а не 0 (поэтому вы неправильно тестируете на сбой).   -  person Jonathan Potter    schedule 19.08.2013
comment
Спасибо, но это не помогло. Я все еще получаю retShFileInfo.szDisplayName как пустой массив (я не вижу там никакого пути)   -  person Beno    schedule 19.08.2013
comment
Есть ли у .tmp значок в вашей системе? Если это не так, он будет использовать значок файла по умолчанию, и я не думаю, что в этом случае вы что-нибудь вернете. Вместо этого попробуйте .txt.   -  person Jonathan Potter    schedule 19.08.2013
comment
SHGetFileInfo() возвращает код ошибки, который вы не проверяете на сбой. Какое значение он на самом деле возвращает?   -  person Remy Lebeau    schedule 19.08.2013
comment
.tmp — это просто имя папки. tempFile равен: C:\.tmp\tmpfile.docx   -  person Beno    schedule 19.08.2013
comment
Если вы используете флаг SHGFI_USEFILEATTRIBUTES, вам вообще не нужно создавать временный файл, просто дайте ему имя файла с желаемым расширением, и он вернет информацию о значке по умолчанию для этого расширения.   -  person Remy Lebeau    schedule 19.08.2013
comment
Я получаю возвращаемое значение = 1   -  person Beno    schedule 19.08.2013
comment
Вас может заинтересовать ответ, который я получил здесь когда у меня была такая же проблема.   -  person Felix Dombek    schedule 08.03.2017
comment
Возможный дубликат Я не могу заставить SHGetFileInfo вернуть местоположение значка   -  person Felix Dombek    schedule 09.03.2017