You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
303 lines
7.2 KiB
303 lines
7.2 KiB
//****************************************************************************
|
|
//
|
|
// BLClient sample for Microsoft Messenger SDK
|
|
//
|
|
// Module: BLClient.exe
|
|
// File: clUtil.cpp
|
|
// Content: Usefull clases for COM and Connection points
|
|
//
|
|
//
|
|
// Copyright (c) Microsoft Corporation 1997-1998
|
|
//
|
|
// THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF
|
|
// ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO
|
|
// THE IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A
|
|
// PARTICULAR PURPOSE.
|
|
//****************************************************************************
|
|
|
|
|
|
#include "pch.hxx"
|
|
#include "clUtil.h"
|
|
#include <instance.h>
|
|
#include "demand.h"
|
|
|
|
|
|
#define ASSERT _ASSERTE
|
|
|
|
//****************************************************************************
|
|
//
|
|
// CLASS RefCount
|
|
//
|
|
//****************************************************************************
|
|
|
|
//****************************************************************************
|
|
//
|
|
// Constructor
|
|
//
|
|
//****************************************************************************
|
|
|
|
RefCount::RefCount(void)
|
|
{
|
|
m_cRef = 1;
|
|
|
|
Assert(NULL != g_pInstance);
|
|
CoIncrementInit("RefCount::RefCount", MSOEAPI_START_SHOWERRORS, NULL, NULL);
|
|
}
|
|
|
|
//****************************************************************************
|
|
//
|
|
// Destructor
|
|
//
|
|
//****************************************************************************
|
|
|
|
RefCount::~RefCount(void)
|
|
{
|
|
CoDecrementInit("RefCount::RefCount", NULL);
|
|
}
|
|
|
|
|
|
//****************************************************************************
|
|
//
|
|
// ULONG STDMETHODCALLTYPE RefCount::AddRef(void)
|
|
//
|
|
//****************************************************************************
|
|
|
|
ULONG STDMETHODCALLTYPE RefCount::AddRef(void)
|
|
{
|
|
ASSERT(m_cRef >= 0);
|
|
|
|
InterlockedIncrement(&m_cRef);
|
|
|
|
return (ULONG) m_cRef;
|
|
}
|
|
|
|
|
|
//****************************************************************************
|
|
//
|
|
// ULONG STDMETHODCALLTYPE RefCount::Release(void)
|
|
//
|
|
//****************************************************************************
|
|
|
|
ULONG STDMETHODCALLTYPE RefCount::Release(void)
|
|
{
|
|
if (0 == InterlockedDecrement(&m_cRef))
|
|
{
|
|
delete this;
|
|
return 0;
|
|
}
|
|
|
|
ASSERT(m_cRef > 0);
|
|
return (ULONG) m_cRef;
|
|
}
|
|
|
|
|
|
//****************************************************************************
|
|
//
|
|
// CLASS CNotify
|
|
//
|
|
//****************************************************************************
|
|
|
|
//****************************************************************************
|
|
//
|
|
// Constructor
|
|
//
|
|
//****************************************************************************
|
|
|
|
CNotify::CNotify() :
|
|
m_pcnpcnt(NULL),
|
|
m_pcnp(NULL),
|
|
m_dwCookie(0),
|
|
m_pUnk(NULL)
|
|
{
|
|
}
|
|
|
|
|
|
//****************************************************************************
|
|
//
|
|
// destructor
|
|
//
|
|
//****************************************************************************
|
|
|
|
CNotify::~CNotify()
|
|
{
|
|
Disconnect(); // Make sure we're disconnected
|
|
}
|
|
|
|
|
|
//****************************************************************************
|
|
//
|
|
// HRESULT CNotify::Connect(IUnknown *pUnk, REFIID riid, IUnknown *pUnkN)
|
|
//
|
|
// Connects the sink to the container
|
|
//
|
|
//****************************************************************************
|
|
|
|
HRESULT CNotify::Connect(IUnknown *pUnk, REFIID riid, IUnknown *pUnkN)
|
|
{
|
|
HRESULT hr;
|
|
|
|
ASSERT(0 == m_dwCookie);
|
|
|
|
// Get the connection container
|
|
hr = pUnk->QueryInterface(IID_IConnectionPointContainer, (void **)&m_pcnpcnt);
|
|
if (SUCCEEDED(hr))
|
|
{
|
|
// Find an appropriate connection point
|
|
hr = m_pcnpcnt->FindConnectionPoint(riid, &m_pcnp);
|
|
if (SUCCEEDED(hr))
|
|
{
|
|
ASSERT(NULL != m_pcnp);
|
|
// Connect the sink object
|
|
hr = m_pcnp->Advise((IUnknown *)pUnkN, &m_dwCookie);
|
|
}
|
|
}
|
|
|
|
if (FAILED(hr))
|
|
{
|
|
m_dwCookie = 0;
|
|
}
|
|
else
|
|
{
|
|
m_pUnk = pUnk; // keep around for caller
|
|
}
|
|
|
|
return hr;
|
|
}
|
|
|
|
|
|
//****************************************************************************
|
|
//
|
|
// HRESULT CNotify::Disconnect (void)
|
|
//
|
|
// Disconnects the sink from the container
|
|
//
|
|
//****************************************************************************
|
|
|
|
HRESULT CNotify::Disconnect (void)
|
|
{
|
|
if (0 != m_dwCookie)
|
|
{
|
|
|
|
// Disconnect the sink object
|
|
m_pcnp->Unadvise(m_dwCookie);
|
|
m_dwCookie = 0;
|
|
|
|
m_pcnp->Release();
|
|
m_pcnp = NULL;
|
|
|
|
m_pcnpcnt->Release();
|
|
m_pcnpcnt = NULL;
|
|
|
|
m_pUnk = NULL;
|
|
}
|
|
|
|
return S_OK;
|
|
}
|
|
|
|
|
|
//****************************************************************************
|
|
//
|
|
// CLASS BSTRING
|
|
//
|
|
//****************************************************************************
|
|
|
|
//****************************************************************************
|
|
//
|
|
// Constructor
|
|
//
|
|
//****************************************************************************
|
|
|
|
// We don't support construction from an ANSI string in the Unicode build.
|
|
#ifndef UNICODE
|
|
|
|
BSTRING::BSTRING(LPCSTR lpcString)
|
|
{
|
|
m_bstr = NULL;
|
|
|
|
// Compute the length of the required BSTR, including the null
|
|
int cWC = MultiByteToWideChar(CP_ACP, 0, lpcString, -1, NULL, 0);
|
|
if (cWC <= 0)
|
|
return;
|
|
|
|
// Allocate the BSTR, including the null
|
|
m_bstr = SysAllocStringLen(NULL, cWC - 1); // SysAllocStringLen adds another 1
|
|
|
|
ASSERT(NULL != m_bstr);
|
|
if (NULL == m_bstr)
|
|
{
|
|
return;
|
|
}
|
|
|
|
// Copy the string
|
|
MultiByteToWideChar(CP_ACP, 0, lpcString, -1, (LPWSTR) m_bstr, cWC);
|
|
|
|
// Verify that the string is null terminated
|
|
ASSERT(0 == m_bstr[cWC - 1]);
|
|
}
|
|
|
|
#endif // #ifndef UNICODE
|
|
|
|
|
|
//****************************************************************************
|
|
//
|
|
// CLASS BTSTR
|
|
//
|
|
//****************************************************************************
|
|
|
|
//****************************************************************************
|
|
//
|
|
// Constructor
|
|
//
|
|
//****************************************************************************
|
|
|
|
BTSTR::BTSTR(BSTR bstr)
|
|
{
|
|
m_psz = LPTSTRfromBstr(bstr);
|
|
}
|
|
|
|
|
|
//****************************************************************************
|
|
//
|
|
// Destructor
|
|
//
|
|
//****************************************************************************
|
|
|
|
BTSTR::~BTSTR()
|
|
{
|
|
if (NULL != m_psz)
|
|
MemFree(m_psz);
|
|
}
|
|
|
|
|
|
//****************************************************************************
|
|
//
|
|
// LPTSTR LPTSTRfromBstr(BSTR bstr)
|
|
//
|
|
// Converts a BSTR to a LPTSTR
|
|
//
|
|
//****************************************************************************
|
|
|
|
LPTSTR LPTSTRfromBstr(BSTR bstr)
|
|
{
|
|
if (NULL == bstr)
|
|
return NULL;
|
|
|
|
int cch = WideCharToMultiByte(CP_ACP, 0, (LPWSTR)bstr, -1, NULL, 0, NULL, NULL);
|
|
if (cch <= 0)
|
|
return NULL;
|
|
|
|
LPTSTR psz;
|
|
|
|
if (!MemAlloc((void **)&psz, sizeof(TCHAR) * (cch+1)))
|
|
return NULL;
|
|
|
|
#ifndef UNICODE
|
|
WideCharToMultiByte(CP_ACP, 0, (LPWSTR)bstr, -1, psz, cch+1, NULL, NULL);
|
|
#else
|
|
StrCpyN(psz, bstr, cch+1);
|
|
wcscpy(psz, bstr);
|
|
#endif
|
|
|
|
return psz;
|
|
}
|
|
|