Win 10 固定程序到任务栏开始菜单的代码

原创
2016/06/23 11:30
阅读数 3K
enum VERB
{
    kPinToTaskbarID = 5386,      // Win7+
    kUnpinFromTaskbarID = 5387,  // Win7+
    kPinToStartID = 51201,       // Win8+
    kUnpinFromStartID = 51394   // Win10+
};
bool DoVerbOnFile(VERB verb, LPCWSTR path, LPCWSTR file)
{
    if (path == NULL || !PathFileExists(path))
        return true;

    WCHAR filepath[MAX_PATH] = { 0, };
    if (file == NULL)
    {
        lstrcpy(filepath, path);
        wchar_t *p = wcsrchr(filepath, L'\\');
        if (p)
        {
            *p = '\0';
            file = p + 1;
            path = filepath;
        }
    }

    const wchar_t* resource_ptr = NULL;
    int length = ::LoadStringW(LoadLibrary(L"shell32.dll"), (DWORD)verb, reinterpret_cast<wchar_t*>(&resource_ptr), 0);
    if (length == 0 || resource_ptr == NULL)
        return false;
    std::wstring ResName(resource_ptr, length);

    CComPtr<IShellWindows> ShellWindow;
    HRESULT hr = ShellWindow.CoCreateInstance(CLSID_ShellWindows);
    if (FAILED(hr)) return false;

    CComVariant varloc(0);
    CComVariant varlocroot(0);
    CComPtr<IDispatch> pdisp;
    long lHwnd = 0;
    int nOptions = SWFO_NEEDDISPATCH;
    hr = ShellWindow->FindWindowSW(&varloc, &varlocroot, 8, &lHwnd, nOptions, &pdisp);
    if (FAILED(hr)) return false;

    CComPtr<IWebBrowserApp> BrowserApp;
    hr = pdisp->QueryInterface(IID_IWebBrowserApp, (void**)&BrowserApp);
    if (FAILED(hr)) return false;

    CComPtr<IServiceProvider> ServiceProvider;
    hr = BrowserApp->QueryInterface(IID_IServiceProvider, (void**)&ServiceProvider);
    if (FAILED(hr)) return false;

    CComPtr<IShellBrowser> ShellBrowser;
    hr = ServiceProvider->QueryService(SID_STopLevelBrowser, IID_IShellBrowser, (void**)&ShellBrowser);
    if (FAILED(hr)) return false;

    CComPtr<IShellView> ShellView;
    hr = ShellBrowser->QueryActiveShellView(&ShellView);
    if (FAILED(hr)) return false;

    pdisp.Release();
    hr = ShellView->GetItemObject(0, IID_IDispatch, (LPVOID*)&pdisp);
    if (FAILED(hr)) return false;

    CComPtr<IShellFolderViewDual> ShellFolderView;
    hr = pdisp->QueryInterface(IID_IShellFolderViewDual, (LPVOID*)&ShellFolderView);
    if (FAILED(hr)) return false;

    pdisp.Release();
    hr = ShellFolderView->get_Application(&pdisp);
    if (FAILED(hr)) return false;

    CComPtr<IShellDispatch2> ShellDispatch;
    hr = pdisp->QueryInterface(IID_IShellDispatch2, (LPVOID*)&ShellDispatch);
    if (FAILED(hr)) return false;

    CComPtr<Folder> fo;
    hr = ShellDispatch->NameSpace(CComVariant(path), &fo);
    if (FAILED(hr)) return false;

    CComPtr<FolderItem> fot;
    hr = fo->ParseName(CComBSTR(file), &fot);
    if (FAILED(hr)) return false;

    CComPtr<FolderItemVerbs> fotv;
    hr = fot->Verbs(&fotv);
    if (FAILED(hr)) return false;

    long cnt;
    hr = fotv->get_Count(&cnt);
    if (FAILED(hr)) return false;

    int i = 0;
    for (; i < cnt; ++i)
    {
        CComPtr<FolderItemVerb> foiv;
        if (FAILED(fotv->Item(CComVariant(i), &foiv))) continue;;

        CComBSTR VerbName;
        if (FAILED(foiv->get_Name(&VerbName))) continue;;

        if (ResName == (LPCWSTR)VerbName)
        {
            foiv->DoIt();
            break;
        }
    }
    return SUCCEEDED(hr) && i < cnt;
}

bool TaskbarAndStartPin(bool bPin, LPCWSTR filepath)
{
    CoInitialize(NULL);
    if (!DoVerbOnFile(bPin ? VERB::kPinToTaskbarID : VERB::kUnpinFromTaskbarID, filepath))
        return false;
    return DoVerbOnFile(bPin ? VERB::kPinToStartID : VERB::kUnpinFromStartID, filepath);
}

这个代码可以有效的将文件和目录固定要任务栏与开始菜单, 有部分是摘自Chromium源码, 但是Chromium中的实现方式不能有效的工作在Win10上.

原理不多说了, 一切都在代码中。

展开阅读全文
打赏
0
13 收藏
分享
加载中
该评论暂时无法显示,详情咨询 QQ 群:912889742

引用来自“冬天之雪”的评论

据说有windows 10 sdk。
不用据说,100% 的有。
Visual Studio 都自带 Windows SDK。
Visual Studio 2015 包含 Windows 8、Windows 8.1、.NETFX SDK。位于 Program Files (x86)\Windows Kits\ 目录下,SDK 占用空间约 5G。
@蜗牛狂奔吧
2016/07/04 19:16
回复
举报

引用来自“冬天之雪”的评论

据说有windows 10 sdk。
有吗? 请指教!
2016/07/04 18:22
回复
举报
据说有windows 10 sdk。
2016/07/04 17:39
回复
举报
更多评论
打赏
4 评论
13 收藏
0
分享
返回顶部
顶部