0

当我右键单击一个 lnk 文件 - 命名空间扩展中的虚拟文件夹上的链接 - 时,会调用我的实现的函数CreateViewObject和/或。这些函数使用as 参数调用。此外,当调用 QueryContextMenu 时,也会设置该标志。这意味着 1)我知道应该显示一个菜单,以及 2)因为这个菜单是由 .lnk 文件查询的标志,并且(来源 Microsoft):GetUiObjectOfIShellFolder/IShellFolder2IID_IContextMenu(riid)CMF_VERBSONLY (0x00000002)CMF_VERBSONLY

0x00000002。快捷菜单是快捷文件(通常为 .lnk 文件)的菜单。快捷菜单处理程序应忽略此值。

大多数情况下,当此标志存在时,我不会添加菜单项。右键单击 .lnk 文件时,Windows 将返回 .lnk 文件的标准菜单,并提供删除此文件的机会。我在 Windows 7 上的收藏夹文件夹中也有同样的机会。由于 Windows 10 和快速访问的“介绍”,它不再可能了。默认情况下不会显示“取消固定”菜单项。

由于命名空间扩展非常困难,因此假设IID_IContextMenuCMF_VERBSONLY知道对象是否在快速访问中固定以及如何取消固定它 - 我可能必须打开自动跳转列表文件夹,然后根据我的对象检查所有跳转列表文件displayname - ,我想知道是否有更简单的方法来处理这个问题(最后跳转列表是 lnk 文件的串联)。

谢谢你的帮助

4

1 回答 1

0

感谢 Simon Mourier 的提示,这里有一种可能的方法来检查文件夹(任何类型)是否被固定在快速访问中......

extern bool __cdecl IsInQuickAccess(LPWSTR folderParsingName)
{
    IShellFolder* desktopFolder;
    HRESULT hr = SHGetDesktopFolder(&desktopFolder);
    bool isInQuickAccess = false;

    if (SUCCEEDED(hr))
    {
        LPITEMIDLIST quickAccessIdList;
        hr = desktopFolder->ParseDisplayName(NULL, NULL, _T("shell:::{679f85cb-0220-4080-b29b-5540cc05aab6}"), NULL, &quickAccessIdList, NULL);

        if (SUCCEEDED(hr))
        {
            IShellFolder* quickAccessFolder;
            hr = desktopFolder->BindToObject(quickAccessIdList, NULL, IID_PPV_ARGS(&quickAccessFolder));

            if (SUCCEEDED(hr))
            {
                IEnumIDList* currentChildren = NULL;
                hr = quickAccessFolder->EnumObjects(NULL, SHCONTF_FOLDERS, &currentChildren);

                if (SUCCEEDED(hr))
                {
                    CString wPathToFolder = CharLower(folderParsingName);
                    LPITEMIDLIST childPidl = NULL;

                    while (!isInQuickAccess && currentChildren->Next(1, &childPidl, NULL) == S_OK)
                    {
                        STRRET childDisplayName;
                        hr = quickAccessFolder->GetDisplayNameOf(childPidl, SHGDN_FORPARSING, &childDisplayName);

                        if (SUCCEEDED(hr))
                        {
                            LPWSTR childDisplayNameString;
                            hr = StrRetToStr(&childDisplayName, NULL, &childDisplayNameString);

                            if (SUCCEEDED(hr))
                            {
                                LPWSTR childDisplayNameStringToLower = CharLower(childDisplayNameString);

                                if (wPathToFolder.Compare(childDisplayNameStringToLower) == 0)
                                    isInQuickAccess = true;

                                CoTaskMemFree(childDisplayNameString);
                            }
                        }
                    }

                    CoTaskMemFree(childPidl);
                    currentChildren->Release();
                }
                quickAccessFolder->Release();
            }
            CoTaskMemFree(quickAccessIdList);
        }
        desktopFolder->Release();
    }
    return isInQuickAccess;
}

并在此处从家中取消固定(检查具有给定显示名称的文件夹是否可以快速访问)。

extern void __cdecl UnpinFromHome(LPWSTR folderParsingName)
{
    IShellFolder* desktopFolder;
    HRESULT hr = SHGetDesktopFolder(&desktopFolder);

    if (SUCCEEDED(hr))
    {
        LPITEMIDLIST quickAccessIdList;
        hr = desktopFolder->ParseDisplayName(NULL, NULL, _T("shell:::{679f85cb-0220-4080-b29b-5540cc05aab6}"), NULL, &quickAccessIdList, NULL);

        if (SUCCEEDED(hr))
        {
            IShellFolder* quickAccessFolder;
            hr = desktopFolder->BindToObject(quickAccessIdList, NULL, IID_PPV_ARGS(&quickAccessFolder));

            if (SUCCEEDED(hr))
            {
                IEnumIDList* currentChildren = NULL;
                hr = quickAccessFolder->EnumObjects(NULL, SHCONTF_FOLDERS, &currentChildren);

                if (SUCCEEDED(hr))
                {
                    CString wPathToFolder = CharLower(folderParsingName);
                    LPITEMIDLIST childPidl = NULL;
                    bool isInQuickAccess = false;

                    while (!isInQuickAccess && currentChildren->Next(1, &childPidl, NULL) == S_OK)
                    {
                        STRRET childDisplayName;
                        hr = quickAccessFolder->GetDisplayNameOf(childPidl, SHGDN_FORPARSING, &childDisplayName);

                        if (SUCCEEDED(hr))
                        {
                            LPWSTR childDisplayNameString;
                            hr = StrRetToStr(&childDisplayName, NULL, &childDisplayNameString);

                            if (SUCCEEDED(hr))
                            {
                                LPWSTR childDisplayNameStringToLower = CharLower(childDisplayNameString);

                                if (wPathToFolder.Compare(childDisplayNameStringToLower) == 0)
                                {
                                    IContextMenu* childContextMenu;
                                    LPCITEMIDLIST childCPidl = childPidl;
                                    hr = quickAccessFolder->GetUIObjectOf(NULL, 1, &childCPidl, IID_IContextMenu, NULL, (void**)&childContextMenu);

                                    if (SUCCEEDED(hr))
                                    {
                                        HMENU hmenu = CreatePopupMenu();
                                        if (hmenu)
                                        {
                                            hr = childContextMenu->QueryContextMenu(hmenu, 0, 1, 0x7FFF, CMF_NORMAL);
                                            if (SUCCEEDED(hr))
                                            {
                                                CMINVOKECOMMANDINFO info = { 0 };
                                                info.cbSize = sizeof(info);
                                                info.hwnd = NULL;
                                                info.lpVerb = "unpinfromhome";
                                                info.nShow = 1;
                                                info.fMask = CMIC_MASK_ASYNCOK;
                                                childContextMenu->InvokeCommand(&info);
                                            }
                                            DestroyMenu(hmenu);
                                        }

                                    }
                                    isInQuickAccess = true;
                                }
                                CoTaskMemFree(childDisplayNameString);
                            }
                        }
                    }
                    CoTaskMemFree(childPidl);
                    currentChildren->Release();
                }
                quickAccessFolder->Release();
            }
            CoTaskMemFree(quickAccessIdList);
        }
        desktopFolder->Release();
    }
}
于 2018-03-15T22:36:29.783 回答