|
|
//****************************************************************************
//
// 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; }
|