Windows资源管理器:自行实现的叠加图标不起作用

时间:2016-05-31 22:38:57

标签: c++ windows icons overlay explorer

我试图在Windows资源管理器中简单地显示一些叠加图标。 由于我对Windows编程相对较新(我只是在Mac编程方面有一些经验),所以我使用this文章开始。

所以这是我的代码:

Icon.h

#pragma once
#include "resource.h"
#include "ExplorerSync_i.h"

using namespace ATL;

class ATL_NO_VTABLE CIcon :
    public CComObjectRootEx<CComSingleThreadModel>,
    public CComCoClass<CIcon, &CLSID_Icon>,
    public IShellIconOverlayIdentifier,
    public IDispatchImpl<IIcon, &IID_IIcon, &LIBID_ExplorerSyncLib, /*wMajor =*/ 1, /*wMinor =*/ 0>
{
public:
    CIcon();
    STDMETHOD(GetOverlayInfo)(LPWSTR pwszIconFile, int cchMax, int *pIndex, DWORD* pdwFlags);
    STDMETHOD(GetPriority)(int* pPriority);
    STDMETHOD(IsMemberOf)(LPCWSTR pwszPath, DWORD dwAttrib);

DECLARE_REGISTRY_RESOURCEID(IDR_ICON)

BEGIN_COM_MAP(CIcon)
    COM_INTERFACE_ENTRY(IIcon)
    COM_INTERFACE_ENTRY(IDispatch)
    COM_INTERFACE_ENTRY(IShellIconOverlayIdentifier)
END_COM_MAP()

    HRESULT FinalConstruct()
    {
        return S_OK;
    }

    void FinalRelease()
    {
    }

protected:

};

Icon.cpp

#include "stdafx.h"
#include "Icon.h"
#using <system.dll>

using namespace System;
using namespace System::Diagnostics;

STDMETHODIMP CIcon::GetOverlayInfo(LPWSTR pwszIconFile, int cchMax, int * pIndex, DWORD * pdwFlags)
{
    GetModuleFileNameW(_AtlBaseModule.GetModuleInstance(), pwszIconFile, cchMax);
    *pIndex = 0;
    *pdwFlags = ISIOI_ICONFILE | ISIOI_ICONINDEX;
    return S_OK;
}

STDMETHODIMP CIcon::GetPriority(int * pPriority)
{    
    *pPriority = 0;
    return S_OK;
}

STDMETHODIMP CIcon::IsMemberOf(LPCWSTR pwszPath, DWORD dwAttrib)
{       
    wchar_t *s = _wcsdup(pwszPath);
    HRESULT r = S_FALSE;
    _wcslwr_s(s, 1);
    r = S_OK;
    free(s);
    return r;
}

CIcon::CIcon() {
}

ExplorerSync.cpp

#include "stdafx.h"
#include "resource.h"
#include "ExplorerSync_i.h"
#include "dllmain.h"
#include "Icon.h"
#using <system.dll>

using namespace System;
using namespace System::Diagnostics;
using namespace ATL;

STDAPI DllCanUnloadNow(void)
{
            return _AtlModule.DllCanUnloadNow();
    }

_Check_return_
STDAPI DllGetClassObject(_In_ REFCLSID rclsid, _In_ REFIID riid, _Outptr_ LPVOID* ppv)
{
        return _AtlModule.DllGetClassObject(rclsid, riid, ppv);
}

STDAPI DllRegisterServer(void)
{   
    HRESULT hr = _AtlModule.DllRegisterServer();

    // not possible to instantiate, because it is abstract according to error message
    //CIcon *cIcon = new (std::nothrow) CIcon();

        return hr;
}

STDAPI DllUnregisterServer(void)
{
    HRESULT hr = _AtlModule.DllUnregisterServer();
        return hr;
}

STDAPI DllInstall(BOOL bInstall, _In_opt_  LPCWSTR pszCmdLine)
{   
    HRESULT hr = E_FAIL;
    static const wchar_t szUserSwitch[] = L"user";

    if (pszCmdLine != NULL)
    {
        if (_wcsnicmp(pszCmdLine, szUserSwitch, _countof(szUserSwitch)) == 0)
        {
            ATL::AtlSetPerUserRegistration(true);
        }
    }

    if (bInstall)
    {   
        hr = DllRegisterServer();
        if (FAILED(hr))
        {
            DllUnregisterServer();
        }
    }
    else
    {
        hr = DllUnregisterServer();
    }

    return hr;
}

所以我主要使用上面提到的例子中的代码,因为它不起作用,我根据自己的想法改变了一些代码。

问题不在于编译。这通过regsvr32工作和注册,没有任何错误。但是我发现了一些事件日志条目,DllRegisterServer是唯一被调用的方法。所有其他功能(尤其是图标的接口实现)根本不会被调用。虽然在示例中没有完成,但我试图在DllRegisterServer方法中实例化Icon类,希望它有所帮助,但我不能这样做(错误消息:Icon是抽象的,无法实例化)。

所以有人能告诉我,出了什么问题,拜托? 非常感谢你!

0 个答案:

没有答案
相关问题