как получить значки принтера - PullRequest
1 голос
/ 10 января 2020

извините, это может выглядеть как дублирующий вопрос, потому что был опубликован похожий вопрос, но ответы на которые были неполными. Я хочу создать список доступных принтеров с указанием состояния принтера и значка, связанного с каждым принтером. на данный момент я могу получить список и связанные с ним состояния, но я не могу получить значки. из ранее опубликованного вопроса ответ включал использование SHGetFileInfo, но когда я попробовал это, никакие значки не были возвращены. Я подозреваю, что было что-то, что мне нужно сделать перед вызовом SHGetFileInfo, потому что ответ включал в себя утверждение, которое включало в себя объединение двух PIDL, теперь, потому что это был не реальный код, а комментарий, который я не мог полностью понять, как его реализовать. вот ссылка на вопрос

for (int i=0; i < dwReturned; i++)
{
    HICON hIcon = NULL;

    LPITEMIDLIST pidlPrinters = NULL;
    LPITEMIDLIST pidl = NULL;
    LPENUMIDLIST pEnum = NULL;
    LPSHELLFOLDER pDesktopFolder = NULL;
    IShellFolder* psfPrinters = NULL;
    STRRET strName;
    TCHAR pszDisplayName[MAX_PATH];
    HRESULT hr;
    SHFILEINFO sfi;

    hr = SHGetFolderLocation(m_pParentWnd->m_hWnd, CSIDL_PRINTERS, 0, 0, &pidlPrinters);

    if(hr == S_OK)
    {
        hr = SHGetDesktopFolder(&pDesktopFolder);
    }

    if(hr == S_OK)
    {
        hr = pDesktopFolder->BindToObject(pidlPrinters, 0, IID_IShellFolder, reinterpret_cast<void**> 
             (&psfPrinters));
    }

    if(hr == S_OK)
    {
        hr = psfPrinters->EnumObjects(m_pParentWnd->m_hWnd, SHCONTF_FOLDERS | SHCONTF_NONFOLDERS, 
            &pEnum);
    }

    if(hr == S_OK)
    {
        while (pEnum->Next(1, &pidl, 0) == S_OK)
        {
            psfPrinters->GetDisplayNameOf(pidl,SHGDN_NORMAL, &strName);

            StrRetToBuf(&strName, pidl, pszDisplayName, MAX_PATH);

            //pInfo is PRINTER_INFO_2 *

            if (_wcsicmp(pszDisplayName, pInfo[i].pPrinterName) == 0)
            {
                SHGetFileInfo((LPCTSTR)pidl, 0, &sfi, sizeof(SHFILEINFO),  SHGFI_PIDL | SHGFI_ICON | 
                SHGFI_DISPLAYNAME | SHGFI_TYPENAME); 
                hIcon = sfi.hIcon;
            }

            IMalloc* Malloc = NULL;
            SHGetMalloc(&Malloc);
            Malloc->Free(pidl);
            Malloc->Release();
       }

       pDesktopFolder->Release();
       pEnum->Release();

       //Some other code
    }
}

1 Ответ

0 голосов
/ 16 января 2020

Вы можете использовать IShellFolder::GetUIObjectOf, чтобы извлечь значок, следующий пример - попытка.

            psfPrinters->GetDisplayNameOf(pidl, SHGDN_NORMAL, &strName);

            IExtractIcon* eIcon = NULL;
            hr = psfPrinters->GetUIObjectOf(NULL, 1, (LPCITEMIDLIST*)&pidl, IID_IExtractIcon, NULL, reinterpret_cast<void**>(&eIcon));
            if (hr == S_OK)
            {
                WCHAR iconFileLocation[200];
                int index;
                UINT flag = 0;
                hr = eIcon->GetIconLocation(NULL, iconFileLocation, sizeof(iconFileLocation), &index, &flag);
                if (hr == S_OK)
                {
                    UINT size = 100;
                    eIcon->Extract(iconFileLocation, index, &hIcon, NULL, size);
                    if (hr == S_OK)
                    {
                        // Draw printer icon on client area for checking purpose
                        DrawIcon(hdc, xNew, y, hIcon);
                        xNew += size;
                    }
                }
            }

Пример вывода кода выше:

enter image description here

...