0

Windows 资源管理器能够在禁用搜索和索引时显示自定义横幅:

资源管理器索引未运行图像

我想在带有自定义消息和自定义链接处理程序的自定义命名空间扩展中显示类似的横幅。是否有我可以实现的命名空间扩展接口允许我提供此功能?我在命名空间扩展文档中搜索了各种术语,但我无法找出要使用的正确术语。

4

1 回答 1

0

Microsft 没有记录该功能。我发现了如何从命名空间扩展中显示信息栏。

图片

首先你需要声明 3 个未记录的接口

IInfobarHost

MIDL_INTERFACE("e38fe0f3-3db0-47ee-a314-25cf7f4bf521")
IInfoBarHost : public IUnknown
{
public:
    virtual HRESULT STDMETHODCALLTYPE Inform(IInfoBarMessage* msg) = 0;
    virtual HRESULT STDMETHODCALLTYPE CancelInform(GUID guid) = 0;
};

IInfobarMessage

MIDL_INTERFACE("819d1334-9d74-4254-9ac8-dc745ebc5386")
IInfoBarMessage : public IUnknown
{
public:
    virtual HRESULT STDMETHODCALLTYPE GetMessageID(GUID* guid,INT* intVal) = 0;
    virtual HRESULT STDMETHODCALLTYPE GetMessageW(LPWSTR* message) = 0;
    virtual HRESULT STDMETHODCALLTYPE CreateMenu(HMENU* pMwnu) = 0;
    virtual HRESULT STDMETHODCALLTYPE HandleMenu(HWND hwnd,int intVal) = 0;
};

IBrowserProgressSessionProvider

MIDL_INTERFACE("18140CBD-AA23-4384-A38D-6A8D3E2BE505")
IBrowserProgressSessionProvider : public IUnknown
{
public:
    virtual HRESULT STDMETHODCALLTYPE BeginSession() = 0; //Unknown
    virtual HRESULT STDMETHODCALLTYPE EndSession() = 0;//Unknown
    virtual HRESULT STDMETHODCALLTYPE GetCurrentSession(PDWORD sessionId) = 0;
    virtual HRESULT STDMETHODCALLTYPE ActivateSession() = 0;//Unknown
};

IID_IInfoBarHost : e38fe0f3-3db0-47ee-a314-25cf7f4bf521
IID_IBrowserProgressConnection : 20174539-B2C7-4EC7-970B-04201F9CDBAD
IID_IBrowserProgressAggregator : 5EA8EEC4-C34B-4DE0-9B56-0E15FD8C8F80
IID_IBrowserProgressSessionProvider : 18140CBD-AA23-4384-A38D-6A8D3E2BE505

2.创建一个类并实现IInfoBarMessage。
GetMessageID(GUID* guid,INT* pIntVal)
获取信息栏 guid。为当前信息栏消息生成自己的随机指南。

HRESULT STDMETHODCALLTYPE CInfoBarMessageImpl::GetMessageID(GUID* guid, INT* intVal) {
    //Our InformationBar GUID (generated in constructor)
    *guid = this->guid;
    return S_OK;
}

GetMessageW(LPWSTR* message)
获取 InformationBar 消息
分配内存并将 unicode 字符串复制到参数(使用 CoTaskMemAlloc)

HRESULT STDMETHODCALLTYPE CInfoBarMessageImpl::GetMessageW(LPWSTR* message) {
    if (!this->message) { //message set at constructor or set at our own initialize function
        return E_FAIL;
    }
    *message = (LPWSTR)CoTaskMemAlloc(sizeof(WCHAR) * (this->messageLen + 1));
    wcscpy_s(*message, this->messageLen + 1, this->message);
    return S_OK;
}
  1. 从 ShellView(IShellView) 获取 IServiceProvider 并获取 IBrowserProgressSessionProvider 接口获取 dwCookie 值。
    之后,使用“GetCurrentSession”中的“dwCookie”从 GIT(GlobalInterfaceTable) 获取 IBrowserProgressConnection,并从 BrowserProgressConnection 获取 IInfoBarHost 接口
//CInfobarManger is own class (does not implement anyone)
void CInfoBarManager::ShowInfoBar(IShellView* shview) {
    HRESULT hr;
    DWORD dwCookie = 0;

    if (!this->sprovider) {
        hr = shview->QueryInterface(IID_IServiceProvider, (PVOID*)&sprovider);
        if (FAILED(hr)) {
            goto escapeArea;
        }
    }

    if (!this->sessionProvider) {
        hr = this->sprovider->QueryService(IID_IBrowserProgressAggregator, IID_IBrowserProgressSessionProvider, (PVOID*)&this->sessionProvider);
        if (FAILED(hr)) {
            goto escapeArea;
        }
    }

    hr = sessionProvider->GetCurrentSession(&dwCookie);
    if (FAILED(hr)) {
        goto escapeArea;
    }

    //Get GIT
    if (!this->git) {
        hr = CoCreateInstance(CLSID_StdGlobalInterfaceTable, NULL, CLSCTX_INPROC_SERVER,
            IID_IGlobalInterfaceTable, (PVOID*)&this->git);
        if (FAILED(hr)) {
            goto escapeArea;
        }
    }

    hr = this->git->GetInterfaceFromGlobal(dwCookie, IID_IBrowserProgressConnecion, (PVOID*)&this->browserProgress);
    if (hr == S_OK) {
        hr = this->browserProgress->QueryInterface(IID_IInfoBarHost, (PVOID*)&this->host);
        if (hr == S_OK) {
            //Call Relase in explorer inside
            this->infoMsg->AddRef();
            this->host->Inform(this->infoMsg);
        }
    }
escapeArea:
    return;
}
  1. 如果 uMsg 为 17 (onrefresh) 或其他位置(如果需要),则在 MessageSFVCB 显示信息栏。
//in MessageSFVCB
else if (uMsg == 17) { //OnRefresh
    if (!this->infobar) {
        this->infobar = new CInfoBarManager();
        infobar->InitializeSimple(L"NSE Information Bar Message");
    }
    infobar->ShowInfoBar(this->shview); //IShellView
}

示例代码:https ://github.com/bho3538/NSEInformationBar

于 2020-09-18T11:34:00.903 回答