簡體   English   中英

如何在Windows 7上的C ++中為虛擬文件夾創建快捷方式?

[英]How to create shortcut for virtual folder in C++ on windows 7?

我使用的平台是Windows7。我需要在Windows 7上為虛擬文件夾創建快捷方式。我使用Windows 7 SDK示例在“計算機”下創建一個虛擬文件夾:

在此處輸入圖片說明

示例項目名稱稱為ExplorerDataProvider ,它為IShellFolder類定義CLSID:

// add classes supported by this module here
const CLASS_OBJECT_INIT c_rgClassObjectInit[] =
{
{ &CLSID_FolderViewImpl,            CFolderViewImplFolder_CreateInstance },
{ &CLSID_FolderViewImplContextMenu,CFolderViewImplContextMenu_CreateInstance },
};

CFolderViewImplFolder_CreateInstance的定義是:

HRESULT CFolderViewImplFolder_CreateInstance(REFIID riid, void **ppv)
{
*ppv = NULL;
CFolderViewImplFolder* pFolderViewImplShellFolder = new (std::nothrow) CFolderViewImplFolder(0);
HRESULT hr = pFolderViewImplShellFolder ? S_OK : E_OUTOFMEMORY;
if (SUCCEEDED(hr))
{
    hr = pFolderViewImplShellFolder->QueryInterface(riid, ppv);
    pFolderViewImplShellFolder->Release();
}
return hr;
}

然后CFolderViewImplFolder實現IShellFolder2IPersistFolder2 我在這里找到了用於創建打印機快捷方式的類似代碼: https : //www.codeproject.com/Articles/596642/Creating-a-shortcut-programmatically-in-Cplusplushttps://msdn.microsoft。 COM / EN-US /庫/ aa969393.aspx#Shellink_Item_Identifiers

一旦有了IShellFolder的類標識符,就可以調用CoCreateInstance函數來檢索接口的地址。 然后,您可以調用該接口以枚舉文件夾中的對象,並檢索要搜索的對象的項目標識符的地址。 最后,可以在調用IShellLink :: SetIDList成員函數時使用該地址來創建該對象的快捷方式。

我修改了

hr = SHGetMalloc(&pMalloc);
hr = SHGetDesktopFolder( &pDesktopFolder );
hr = SHGetSpecialFolderLocation( NULL, CSIDL_PRINTERS, &netItemIdLst );
hr = pDesktopFolder->BindToObject( netItemIdLst, NULL, IID_IShellFolder, (void **)&pPrinterFolder );

// testFolder is the CLSID for the virtual folder implementation
hr = CoCreateInstance(testFolder, NULL, CLSCTX_INPROC_SERVER, IID_IShellFolder, (LPVOID*)&pVirtualFolder);

要么

hr = CoCreateInstance(testFolder, NULL, CLSCTX_INPROC_SERVER, IID_IShellFolder2, (LPVOID*)&pVirtualFolder);

但是pVirtualFolder仍然為NULL,並且打印出“找不到相應的接口”。

使用CoCreateInstance時有什么問題嗎? 還是我不應該使用這種解決方案? 有任何示例代碼嗎?

要創建快捷方式,可以使用官方文檔 這是為“ This PC”(又名: ComputerFolder )的子代創建快捷方式的示例代碼。

int main()
{
    CoInitialize(NULL);
    // I've used my Apple's iCloud as an example (name is in french)
    // it's a virtual folder, a shell namespace extension
    HRESULT hr = CreateComputerChildShortCut(L"Photos iCloud", L"c:\\temp\\my icloud");
    printf("hr:0x%08X\n", hr);
    CoUninitialize();
    return 0;
}

HRESULT CreateComputerChildShortCut(LPWSTR childDisplayName, LPWSTR path)
{
    // get My Computer folder's ShellItem (there are other ways for this...)
    CComPtr<IShellItem> folder;
    HRESULT hr = SHCreateItemInKnownFolder(FOLDERID_ComputerFolder, 0, NULL, IID_PPV_ARGS(&folder));
    if (FAILED(hr)) return hr;

    // enumerate children
    CComPtr<IEnumShellItems> items;
    hr = folder->BindToHandler(NULL, BHID_EnumItems, IID_PPV_ARGS(&items));
    if (FAILED(hr)) return hr;

    for (CComPtr<IShellItem> item; items->Next(1, &item, NULL) == S_OK; item.Release())
    {
        // get parsing path (if's often useful)
        CComHeapPtr<wchar_t> parsingPath;
        item->GetDisplayName(SIGDN_DESKTOPABSOLUTEPARSING, &parsingPath);
        wprintf(L"Path: %s\n", parsingPath);

        // get display name
        CComHeapPtr<wchar_t> displayName;
        item->GetDisplayName(SIGDN_NORMALDISPLAY, &displayName);
        wprintf(L" Name: %s\n", displayName);

        if (!lstrcmpi(childDisplayName, displayName))
        {
            // get pidl
            // it's the unambiguous way of referencing a shell thing
            CComHeapPtr<ITEMIDLIST> pidl;
            hr = SHGetIDListFromObject(item, &pidl);
            if (FAILED(hr)) return hr;

            // create an instance of the standard Shell's folder shortcut creator
            CComPtr<IShellLink> link;
            hr = link.CoCreateInstance(CLSID_FolderShortcut);
            if (FAILED(hr)) return hr;

            // just use the pidl
            hr = link->SetIDList(pidl);
            if (FAILED(hr)) return hr;

            CComPtr<IPersistFile> file;
            hr = link->QueryInterface(&file);
            if (FAILED(hr)) return hr;

            // save the shortcut (we could also change other IShellLink parameters)
            hr = file->Save(path, FALSE);
            if (FAILED(hr)) return hr;
            break;
        }
    }
    return S_OK;
}

當然,如果您知道絕對的解析路徑或絕對的pidl,則不必枚舉任何內容,這只是出於演示目的。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM