Click here to Skip to main content
15,899,474 members
Home / Discussions / COM
   

COM

 
GeneralRe: L"" Pin
bulg23-May-08 13:49
bulg23-May-08 13:49 
AnswerRe: L"" Pin
Tony Richards23-May-08 13:22
Tony Richards23-May-08 13:22 
AnswerRe: L"" Pin
prasad_som24-May-08 23:52
prasad_som24-May-08 23:52 
AnswerRe: L"" Pin
Mike Dimmick28-May-08 7:21
Mike Dimmick28-May-08 7:21 
QuestionGetting linker problems with COleDispatchDriver Pin
swati1123-May-08 4:21
swati1123-May-08 4:21 
AnswerRe: Getting linker problems with COleDispatchDriver Pin
prasad_som25-May-08 0:06
prasad_som25-May-08 0:06 
AnswerRe: Getting linker problems with COleDispatchDriver Pin
Stephen Hewitt26-May-08 15:05
Stephen Hewitt26-May-08 15:05 
QuestionDrag & drop works in XP, fails in Vista - help? Pin
pauljlucas22-May-08 18:18
pauljlucas22-May-08 18:18 
I have code that implements drag & drop for a ShowPicturesOnArrival event. The code works fine under Windows XP but fails under Vista with an:

Invalid FORMATETC structure

error. For completeness, the relevant Registry keys I've added are below. Items preceeded by a "v" are values for the above key, not subkeys.

HKEY_CLASSES_ROOT
  MyApp
    shell
      open
        DropTarget
        v CLSID [REG_SZ] = {My-GUID}

HKEY_LOCAL_MACHINE
  SOFTWARE
    Classes
      CLSID
        {My-GUID}
        v (default) [REG_SZ] MyApp
          InprocServer32
          v (default) [REG_SZ] = C:\path\to\My.dll
          v ThreadingModel [REG_SZ] = Apartment
    Microsoft
      Windows
        CurrentVersion
          Explorer
            AutoplayHandlers
              EventHandlers
                ShowPicturesOnArrival
                v MyApp [REG_SZ]
              Handlers
                MyApp
                v Action [REG_SZ] = "Copy pictures ..."
                v DefaultIcon [REG_SZ] = C:\path\to\MyApp.exe,0
                v InvokeProgID [REG_SZ] = MyApp
                v InvokeVerb [REG_SZ] = open
                v Provider [REG_SZ] = MyApp's name

My code follows. (Yes, I know it's a lot to look through, but any help much
appreciated. The failure occurs where the comment containing "fails" below
is.) First, I have a utility reference-counting class:

class LC_DLLRefCount {
public:
    static ULONG get() {
        return m_refCount;
    }
protected:
    LC_DLLRefCount()  { ++m_refCount; }
    ~LC_DLLRefCount() { --m_refCount; }
private:
    static ULONG volatile m_refCount;
};

ULONG volatile LC_DLLRefCount::m_refCount;

Next, my IClassFactory implementation:

class LC_ClassFactory : public IClassFactory, public LC_DLLRefCount {
public:
    LC_ClassFactory() : m_refCount( 0 ) { }

    ULONG STDMETHODCALLTYPE AddRef() {
        return ++m_refCount;
    }

    ULONG STDMETHODCALLTYPE Release() {
        ULONG const remaining = --m_refCount;
        if ( !remaining )
            delete this;
        return remaining;
    }

    HRESULT STDMETHODCALLTYPE CreateInstance( IUnknown*, REFIID,
                                              LPVOID* );
    HRESULT STDMETHODCALLTYPE LockServer( BOOL );
    HRESULT STDMETHODCALLTYPE QueryInterface( REFIID, LPVOID* );
private:
    ULONG volatile m_refCount;
};

HRESULT STDMETHODCALLTYPE LC_ClassFactory::CreateInstance
    ( IUnknown *pUnkOuter, REFIID iid, LPVOID *ppv )
{
    if ( ::IsBadWritePtr( ppv, sizeof( LPVOID ) ) )
        return E_POINTER;
    if ( pUnkOuter )
        return CLASS_E_NOAGGREGATION;
    *ppv = NULL;
    LC_AutoplayHandler *const handler = new LC_AutoplayHandler();
    if ( !handler )
        return E_OUTOFMEMORY;
    HRESULT result = handler->QueryInterface( iid, ppv );
    if ( FAILED( result ) )
        delete handler;
    return result;
}

HRESULT STDMETHODCALLTYPE LC_ClassFactory::LockServer( BOOL lock ) {
    if ( lock )
        ++m_refCount;
    else
        --m_refCount;
    return S_OK;
}

HRESULT STDMETHODCALLTYPE LC_ClassFactory::QueryInterface
    ( REFIID iid, LPVOID *ppv )
{
    if ( ::IsBadWritePtr( ppv, sizeof( LPVOID ) ) )
        return E_POINTER;
    if ( ::IsEqualIID( iid, IID_IUnknown ) )
        *ppv = dynamic_cast<IUnknown*>( this );
    else if ( ::IsEqualIID( iid, IID_IClassFactory ) )
        *ppv = dynamic_cast<IClassFactory*>( this );
    else {
        *ppv = NULL;
        return E_NOINTERFACE;
    }
    AddRef();
    return S_OK;
}

Next, my IDropTarget implementation:

class LC_AutoplayHandler : public IDropTarget, public LC_DLLRefCount {
public:
    LC_AutoplayHandler() : m_refCount( 0 ) { }

    ULONG STDMETHODCALLTYPE AddRef() {
        return ++m_refCount;
    }

    ULONG STDMETHODCALLTYPE Release() {
        ULONG const remaining = --m_refCount;
        if ( !remaining )
            delete this;
        return remaining;
    }

    HRESULT STDMETHODCALLTYPE QueryInterface( REFIID, LPVOID* );

    HRESULT STDMETHODCALLTYPE Drop( LPDATAOBJECT, DWORD, POINTL,
                                    PDWORD );
    HRESULT STDMETHODCALLTYPE DragEnter( LPDATAOBJECT, DWORD, POINTL,
                                         PDWORD );
    HRESULT STDMETHODCALLTYPE DragLeave();
    HRESULT STDMETHODCALLTYPE DragOver( DWORD, POINTL, PDWORD );
private:
    ULONG volatile m_refCount;
};

HRESULT STDMETHODCALLTYPE LC_AutoplayHandler::DragEnter
    ( LPDATAOBJECT, DWORD, POINTL, PDWORD pEffect )
{
    *pEffect = DROPEFFECT_COPY;
    return S_OK;
}

HRESULT STDMETHODCALLTYPE LC_AutoplayHandler::DragLeave() {
    return S_OK;
}

HRESULT STDMETHODCALLTYPE LC_AutoplayHandler::DragOver
    ( DWORD, POINTL, PDWORD pEffect )
{
    *pEffect = DROPEFFECT_COPY;
    return S_OK;
}

HRESULT STDMETHODCALLTYPE LC_AutoplayHandler::Drop
    ( LPDATAOBJECT pDO, DWORD, POINTL, PDWORD )
{
    UINT autoplayShellIDLists = ::RegisterClipboardFormat(
        TEXT("Autoplay Enumerated IDList Array")
    );
    if ( !autoplayShellIDLists )
        return ::GetLastError();

    FORMATETC formatEtc = {
        autoplayShellIDLists, NULL, DVASPECT_CONTENT, -1,
        TYMED_HGLOBAL
    };
    STGMEDIUM medium = { 0 };

    HRESULT result = pDO->GetData( &formatEtc, &medium );
    if ( FAILED( result ) )
        return result;

    // The call to GetData() above fails with:
    //
    //     Invalid FORMATETC structure
    //

    // ... elided ...

    ::ReleaseStgMedium( &medium );
    return result;
}

HRESULT STDMETHODCALLTYPE LC_AutoplayHandler::QueryInterface
    ( REFIID iid, LPVOID *ppv )
{
    if ( ::IsBadWritePtr( ppv, sizeof( LPVOID ) ) )
        return E_POINTER;
    if ( ::IsEqualIID( iid, IID_IUnknown ) )
        *ppv = dynamic_cast<IUnknown*>( this );
    else if ( ::IsEqualIID( iid, IID_IDropTarget ) )
        *ppv = dynamic_cast<IDropTarget*>( this );
    else {
        *ppv = NULL;
        return E_NOINTERFACE;
    }
    AddRef();
    return S_OK;
}

Finally, my Dll* functions implementation:

#define LC_DLL_EXPORT(T) extern "C" __declspec(dllexport) T __stdcall

LC_DLL_EXPORT(HRESULT) DllCanUnloadNow() {
    bool const canUnload = LC_DLLRefCount::get() == 0;
    return canUnload ? S_OK : S_FALSE;
}

LC_DLL_EXPORT(HRESULT) DllGetClassObject( REFCLSID clsid, REFIID iid,
                                          LPVOID *ppv ) {
    if ( !::IsEqualCLSID( clsid, LC_AP_GUID ) )
        return CLASS_E_CLASSNOTAVAILABLE;
    if ( ::IsBadWritePtr( ppv, sizeof( LPVOID ) ) )
        return E_POINTER;
    *ppv = NULL;
    LC_ClassFactory *const factory = new LC_ClassFactory();
    if ( !factory )
        return E_OUTOFMEMORY;
    factory->AddRef();
    HRESULT result = factory->QueryInterface( iid, ppv );
    factory->Release();
    return result;
}

Are there any mistakes in the above code but it just happens to work in XP but not Vista? How can this be made to work in Vista? Thanks.

- Paul
Question[Message Deleted] Pin
pra84veen22-May-08 1:54
pra84veen22-May-08 1:54 
QuestionRe: COM PORT PinPopular
CPallini22-May-08 2:55
mveCPallini22-May-08 2:55 
Questionactivex control printing Pin
subramanyeswari20-May-08 20:23
subramanyeswari20-May-08 20:23 
Questionactivex control printing Pin
subramanyeswari20-May-08 0:16
subramanyeswari20-May-08 0:16 
AnswerRe: activex control printing Pin
subramanyeswari22-May-08 18:21
subramanyeswari22-May-08 18:21 
GeneralRe: activex control printing Pin
subramanyeswari22-May-08 19:53
subramanyeswari22-May-08 19:53 
QuestionAbout Comm Control Pin
savitri16-May-08 21:20
savitri16-May-08 21:20 
AnswerRe: About Comm Control Pin
ShilpiP19-May-08 1:42
ShilpiP19-May-08 1:42 
QuestionCOM object releasing Pin
Prasann Mayekar15-May-08 20:55
Prasann Mayekar15-May-08 20:55 
AnswerRe: COM object releasing Pin
Stephen Hewitt22-May-08 18:56
Stephen Hewitt22-May-08 18:56 
QuestionReturn error desc from COM to VB6 Pin
technoxicated15-May-08 3:07
technoxicated15-May-08 3:07 
AnswerRe: Return error desc from COM to VB6 Pin
technoxicated16-May-08 18:39
technoxicated16-May-08 18:39 
QuestionWINAPI Borderless sizable child window/control Pin
Lennymnr14-May-08 10:15
Lennymnr14-May-08 10:15 
QuestionRe: WINAPI Borderless sizable child window/control Pin
CPallini15-May-08 2:42
mveCPallini15-May-08 2:42 
QuestionQuery regarding Registeration and Unregisteration of COM dll. Pin
sandeepkavade13-May-08 1:51
sandeepkavade13-May-08 1:51 
QuestionRe: Query regarding Registeration and Unregisteration of COM dll. Pin
CPallini13-May-08 2:08
mveCPallini13-May-08 2:08 
AnswerRe: Query regarding Registeration and Unregisteration of COM dll. Pin
sandeepkavade13-May-08 3:42
sandeepkavade13-May-08 3:42 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.