如何在C ++中创建外壳程序使用的IconHandler? [英] How to create a IconHandler used by the shell in c++?

查看:128
本文介绍了如何在C ++中创建外壳程序使用的IconHandler?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我试图用C ++编写一个图标处理程序,但是这样做有一些问题.我从 codeproject

I tried to code an icon handler in c++ but i have some issues to do this. I followed the turoriel from codeproject

本教程的不同之处在于,我想使用Visual Studio向导(2013)的ATL项目对dll进行编码.因此,我创建了一个新的ATL项目,并且对该项目有一个COM +1类(即标头的代码).

The difference with this tutorial is i wanna code my dll with an ATL project from the wizard of visual studio (2013). So i create a new ATL project and i had a COM +1 class to this project (this the code of the header).

问题是它接缝了我的dll,但之后又分离了.

The problem is it seams that my dll is attach but is detach right after.

我将在下面放一些代码和更多的说明:

I'll put some code and more explication bellow :

extern "C" BOOL WINAPI DllMain(HINSTANCE hInstance, DWORD dwReason, LPVOID lpReserved)
{
    if (dwReason == DLL_PROCESS_ATTACH)
    {
        _AtlModule.InitLibId();
        //_AtlModule.RegisterAppId();
    }

    return _AtlModule.DllMain(dwReason, lpReserved);;
}

这是我dll的入口点.我对此入口点做了很多尝试和测试.我试图写一些dwReason的登录功能,并且该功能仅在编译时才启动.一次使用属性DLL_PROCESS_ATTACH,另一次使用属性DLL_PROCESS_DETACH.之后,即使我将注册表设置为在文件的IconHandler中调用此dll,也无法进行任何工作.

This is my entry point of my dll. I did a lot of try and test on this entry point. I tried to write some log in function of the dwReason and this function is launch only when i compile. One time with the attribute DLL_PROCESS_ATTACH and an other time with the attribute DLL_PROCESS_DETACH. After that nothing seams to work even when i set my registry to call this dll in the IconHandler of my file.

我将放置dllmain.h,handler.h,idl文件和rgs文件.如果您需要更多代码来帮助我,我会在以后放它们.

I'll put my dllmain.h, my handler.h, my idl file and my rgs file. If you need more code to help me i'll put them later.

dllmain.h

dllmain.h

class CQIIconDllModule : public ATL::CAtlDllModuleT< CQIIconDllModule >
{
public :
    DECLARE_LIBID(LIBID_QIIconDllLib)
    DECLARE_REGISTRY_APPID_RESOURCEID(IDR_QIHANDLER, "{7FFCD43D-9EB3-4F76-940C-98C333FB8A99}")
};

extern class CQIIconDllModule _AtlModule;

IconHandler.h

IconHandler.h

// QIHandler.h : Declaration of the CQIHandler

#pragma once
#include "resource.h"       // main symbols
#include <ShlObj.h>


#include "QIIconDll_i.h"



#if defined(_WIN32_WCE) && !defined(_CE_DCOM) && !defined(_CE_ALLOW_SINGLE_THREADED_OBJECTS_IN_MTA)
#error "Single-threaded COM objects are not properly supported on Windows CE platform, such as the Windows Mobile platforms that do not include full DCOM support. Define _CE_ALLOW_SINGLE_THREADED_OBJECTS_IN_MTA to force ATL to support creating single-thread COM object's and allow use of it's single-threaded COM object implementations. The threading model in your rgs file was set to 'Free' as that is the only threading model supported in non DCOM Windows CE platforms."
#endif

using namespace ATL;


// CQIHandler

class ATL_NO_VTABLE CQIHandler :
    public CComObjectRootEx<CComSingleThreadModel>,
    public CComCoClass<CQIHandler, &CLSID_QIHandler>,
    public IQIHandler,
    public IPersistFile,
    public IExtractIcon
{
public:
    CQIHandler()
    {
    }

DECLARE_REGISTRY_RESOURCEID(IDR_QIHANDLER)

DECLARE_NOT_AGGREGATABLE(CQIHandler)

BEGIN_COM_MAP(CQIHandler)
    COM_INTERFACE_ENTRY(IQIHandler)
    COM_INTERFACE_ENTRY(IPersistFile)
    COM_INTERFACE_ENTRY(IExtractIcon)
END_COM_MAP()



    DECLARE_PROTECT_FINAL_CONSTRUCT()

    HRESULT FinalConstruct()
    {
        return S_OK;
    }

    void FinalRelease()
    {
    }

public:
     // IPersistFile
    STDMETHODIMP GetClassID( CLSID* ) { return E_NOTIMPL; }
    STDMETHODIMP IsDirty() { return E_NOTIMPL; }
    STDMETHODIMP Save( LPCOLESTR, BOOL ) { return E_NOTIMPL; }
    STDMETHODIMP SaveCompleted( LPCOLESTR ) { return E_NOTIMPL; }
    STDMETHODIMP GetCurFile( LPOLESTR* ) { return E_NOTIMPL; }

    STDMETHODIMP Load( LPCOLESTR wszFile, DWORD )
        { 
        USES_CONVERSION;
        lstrcpyn ( m_szFilename, W2CT(wszFile), MAX_PATH );
        return S_OK;
        }

    // IExtractIcon
    STDMETHODIMP GetIconLocation( UINT uFlags, LPTSTR szIconFile, UINT cchMax,
                                  int* piIndex, UINT* pwFlags );
    STDMETHODIMP Extract( LPCTSTR pszFile, UINT nIconIndex, HICON* phiconLarge,
                          HICON* phiconSmall, UINT nIconSize );

protected:
    TCHAR     m_szFilename[MAX_PATH];   // Full path to the file in question.


};

OBJECT_ENTRY_AUTO(__uuidof(QIHandler), CQIHandler)

我的idl文件

// QIIconDll.idl : IDL source for QIIconDll
//

// This file will be processed by the MIDL tool to
// produce the type library (QIIconDll.tlb) and marshalling code.

import "oaidl.idl";
import "ocidl.idl";

[
    object,
    uuid(a817e7a2-43fa-11d0-9e44-00aa00b6770a),
    dual,   
    pointer_default(unique)
]
interface IComponentRegistrar : IDispatch
{
    [id(1)] HRESULT Attach([in] BSTR bstrPath);
    [id(2)] HRESULT RegisterAll();
    [id(3)] HRESULT UnregisterAll();
    [id(4)] HRESULT GetComponents([out] SAFEARRAY(BSTR)* pbstrCLSIDs, [out] SAFEARRAY(BSTR)* pbstrDescriptions);
    [id(5)] HRESULT RegisterComponent([in] BSTR bstrCLSID);
    [id(6)] HRESULT UnregisterComponent([in] BSTR bstrCLSID);
};

[
    object,
    uuid(1A80BA8B-2932-4EB4-AA88-5216F92BBA33),
    pointer_default(unique)
]
interface IQIHandler : IUnknown{
};


[
    uuid(17AD604F-FDD1-453C-A2D2-EAD3FCC42AB5),
    version(1.0),
    custom(a817e7a1-43fa-11d0-9e44-00aa00b6770a,"{D32D9690-E6A4-44D8-A949-5F39D35269F8}")
]
library QIIconDllLib
{
    importlib("stdole2.tlb");
    [
        uuid(D32D9690-E6A4-44D8-A949-5F39D35269F8)      
    ]
    coclass CompReg
    {
        [default] interface IComponentRegistrar;
    };
    [
        uuid(7FFCD43D-9EB3-4F76-940C-98C333FB8A99)      
    ]
    coclass QIHandler
    {
        [default] interface IQIHandler;
    };
};

rgs文件:

HKCR
{
    NoRemove CLSID
    {
        ForceRemove {D32D9690-E6A4-44D8-A949-5F39D35269F8} = s 'CompReg Class'
        {
            InprocServer32 = s '%MODULE%'
            {
                val ThreadingModel = s 'Apartment'
            }
            TypeLib = s '{17AD604F-FDD1-453C-A2D2-EAD3FCC42AB5}'
            Version = s '1.0'
        }
    }
}

rgs处理程序文件:

rgs handler file :

HKCR
{
    NoRemove CLSID
    {
        ForceRemove {7FFCD43D-9EB3-4F76-940C-98C333FB8A99} = s 'QIHandler Class'
        {
            InprocServer32 = s '%MODULE%'
            {
                val ThreadingModel = s 'Apartment'
            }
            TypeLib = s '{17AD604F-FDD1-453C-A2D2-EAD3FCC42AB5}'
            Version = s '1.0'
        }
    }


    NoRemove qifile
    {
        NoRemove DefaultIcon = s '%%1'
        NoRemove ShellEx
        {
            ForceRemove IconHandler = s '{7FFCD43D-9EB3-4F76-940C-98C333FB8A99}'
        }
    }
}

我希望我的解释清楚.如果您需要更多信息来回答我的问题,请告诉我,我会尽快答复我.多谢您抽出宝贵的时间来帮助我.

I hope i was clear in my explanation. If you need more information to response at my question just tell me i'll be fast with my answer. I'll thank you to take your time to help me.

弗洛里安

在dllmain上查看我的测试. cpp

See my test on my dllmain. cpp

    BOOL ret = false;
    FILE *file; 
    fopen_s(&file, "test.txt","a+"); /* apend file (add text to 
        a file or create a file if it does not exist.*/ 
    if (dwReason == DLL_PROCESS_ATTACH)
    {
        fprintf(file,"%s","Initialize AtlModule\n"); /*writes*/ 
        _AtlModule.InitLibId();
        HRESULT hr = _AtlModule.RegisterAppId();
        if (SUCCEEDED(hr))
        {
            fprintf(file,"%s","Registrer app succeeded \n"); /*writes*/ 
            hr = _AtlModule.RegisterServer(TRUE, &CLSID_QIHandler);
            if (SUCCEEDED(hr))
            {
                fprintf(file,"%s","RegisterServer succeeded \n"); /*writes*/ 
                hr = _AtlModule.UpdateRegistryAppId(TRUE);
                if (SUCCEEDED(hr))
                {
                    fprintf(file,"%s","UpdateRegistryAppId succeeded \n"); /*writes*/ 
                    ret = true;
                }
            }
        }

    }
#ifdef _DEBUG
    else if (dwReason == DLL_PROCESS_DETACH)
    {
        _AtlModule.UpdateRegistryAppId(FALSE);
        _AtlModule.Term();
    }//*/
#endif
    if (dwReason == DLL_PROCESS_DETACH && lpReserved != NULL)
    {
        ret = true;
    }
    else if (dwReason == DLL_PROCESS_DETACH)
    {
        fprintf(file,"%s","Execption ! \n"); /*writes*/ 
    }

    fclose(file); /*done!*/ 
    return ret;

test.txt中的结果:

The result in my test.txt :

Initialize AtlModule
Registrer app succeeded 
RegisterServer succeeded 
UpdateRegistryAppId succeeded 
Execption ! 

这里的人有想法吗?

推荐答案

我没有找到可以解决我问题的解决方案.因此,即使这不是执行此操作的最佳方法,我也用C#编写了处理程序,因为这会调用某些本机函数.

I didn't found any solution to work my solution. So i write my handler in C# even if this is not the best way to do that because that call some native function.

我使用了来自代码项目的以下教程: NET-Shell-Extensions-Shell-Icon-Handlers

I used the follow tutorial from code-project : NET-Shell-Extensions-Shell-Icon-Handlers

我希望本教程能够对某些人有所帮助.如果有人对我的预览问题有答案,我将很高兴知道我该怎么做.

I hope this tutorial gonna help some people. If someone have the answer to my preview question i will be glad to know what i have to do.

弗洛里安

这篇关于如何在C ++中创建外壳程序使用的IconHandler?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆