【发布时间】:2020-01-10 16:55:03
【问题描述】:
抱歉,这可能看起来像一个重复的问题,因为发布了类似的问题,但给出的答案不完整。我想创建一个可用打印机列表,说明打印机的状态以及与每台打印机关联的图标。此时我能够获取列表及其相关状态,但失败的地方是获取图标。从之前发布的问题中,答案涉及使用 SHGetFileInfo,但是当我尝试它时,没有返回任何图标。我怀疑在调用 SHGetFileInfo 之前我需要做一些事情,因为答案包括一个涉及组合两个 PIDL 的语句,现在因为它不是实际代码而是一个我无法完全理解如何实现它的注释。 here is a link to the question
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
}
}
【问题讨论】:
-
IEnumObjects::Next返回一个相对 pidl,您需要将它与父文件夹的完整 pidl 结合起来才能得到SHGetFileInfo可以使用的东西。这就像拥有“file.txt”并将其添加到“c:\folder\”以获取完整路径名。您可以使用ILCombine函数来执行此操作。 -
感谢您的回答,但我仍然无法获得图标。它现在显示此“GlowWindow.exe 中 0x758F35D2 (KernelBase.dll) 处的第一次机会异常:0x40080201:WinRT 发起错误(参数:0x80040155、0x00000052、0x03E5F3F8)。onecore\com\combase\dcomrem\marshal.cxx(1111) )\combase.dll!753F49E8: (caller: 7538747C) ReturnHr(19) tid(1348) 80040155 Interface not registered Msg:[Failed to marshal with IID={000214EB-0000-0000-C000-000000000046}]“输出窗口
-
不知道抱歉。不过看起来是个不同的问题。
-
我认为 ILCombine 函数可以解决问题的任何方式,我只需要找到解决该异常的方法
-
只要有处理异常的东西,第一次机会异常就不是问题。如果您的程序没有崩溃,我会说不要担心。
标签: winapi visual-c++ printing