HELLO.CPP (HELLO OLE Sample)
/*************************************************************************
-
- OLE Automation Hello 2.0 Application.
-
- hello.cpp
-
- CHello implementation
-
- Written by Microsoft Product Support Services, Windows Developer Support
- (c) Copyright Microsoft Corp. 1994 All Rights Reserved
-
- ***********************************************************************/
#include <windows.h>
#include <windowsx.h>
#ifdef WIN16
#include <ole2.h>
#include <compobj.h>
#include <dispatch.h>
#include <variant.h>
#include <olenls.h>
#endif
#include "hello.h"
/*
* CHello::Create
*
* Purpose:
* Creates an instance of the Hello Application object and initializes it.
*
* Parameters:
* hinst HINSTANCE of application.
* lpszHelloMessage Initial Hello message.
* pphello Returns Hello automation object.
*
* Return Value:
* HRESULT
*
*/
HRESULT
CHello::Create(HINSTANCE hinst, LPTSTR lpszHelloMessage, CHello FAR* FAR*
pphello)
{
TCHAR ach[STR_LEN];
TCHAR achFullName[260];
HRESULT hr;
CHello FAR* phello = NULL;
HWND hwnd;
*pphello = NULL;
// Create Hello Application object
phello = new CHello();
if (phello == NULL)
goto error;
// Create Main Window
hwnd = CreateDialog(hinst, MAKEINTRESOURCE(IDD_MAINWINDOW), NULL, NULL);
if (!hwnd)
{
hr = ResultFromScode(E_OUTOFMEMORY);
goto error;
}
phello->m_cRef = 0;
phello->m_bVisible = FALSE;
phello->m_hwnd = hwnd;
phello->m_hinst = hinst;
// FullName
GetModuleFileName(hinst, achFullName, sizeof(achFullName));
phello->m_bstrFullName = SysAllocString(TO_OLE_STRING(achFullName));
if (NULL == phello->m_bstrFullName)
{
hr = ResultFromScode(E_OUTOFMEMORY);
goto error;
}
// Name
LoadString(hinst, IDS_Name, ach, sizeof(ach));
phello->m_bstrName = SysAllocString(TO_OLE_STRING(ach));
if (NULL == phello->m_bstrName)
{
hr = ResultFromScode(E_OUTOFMEMORY);
goto error;
}
// ProgID
LoadString(hinst, IDS_ProgID, ach, sizeof(ach));
phello->m_bstrProgID = SysAllocString(TO_OLE_STRING(ach));
if (NULL == phello->m_bstrProgID)
{
hr = ResultFromScode(E_OUTOFMEMORY);
goto error;
}
// Hello Message
phello->m_bstrHelloMsg = SysAllocString(TO_OLE_STRING(lpszHelloMessage));
if (NULL == phello->m_bstrHelloMsg)
{
hr = ResultFromScode(E_OUTOFMEMORY);
goto error;
}
// Load type information from type library. If required, notify user on
failure.
hr = LoadTypeInfo(&phello->m_ptinfo, IID_IHello);
if (FAILED(hr))
{
LoadString(hinst, IDS_ErrorLoadingTypeLib, ach, sizeof(ach));
MessageBox(NULL, ach, FROM_OLE_STRING(phello->m_bstrName), MB_OK);
goto error;
}
*pphello = phello;
return NOERROR;
error:
if (phello == NULL) return ResultFromScode(E_OUTOFMEMORY);
if (phello->m_bstrFullName) SysFreeString(phello->m_bstrFullName);
if (phello->m_bstrName) SysFreeString(phello->m_bstrName);
if (phello->m_bstrProgID) SysFreeString(phello->m_bstrProgID);
if (phello->m_bstrHelloMsg) SysFreeString(phello->m_bstrHelloMsg);
if (phello->m_ptinfo) phello->m_ptinfo->Release();
// Set to NULL to prevent destructor from attempting to free again
phello->m_bstrFullName = NULL;
phello->m_bstrName = NULL;
phello->m_bstrProgID = NULL;
phello->m_bstrHelloMsg = NULL;
phello->m_ptinfo = NULL;
delete phello;
return hr;
}
/*
* CHello::CHello
*
* Purpose:
* Constructor for CHello object. Initializes members to NULL.
*
*/
#pragma warning (disable : 4355)
CHello::CHello() : m_SupportErrorInfo(this, IID_IHello)
#pragma warning (default : 4355)
{
extern ULONG g_cObj;
m_hwnd = NULL;
m_bstrFullName = NULL;
m_bstrName = NULL;
m_bstrProgID = NULL;
m_bstrHelloMsg = NULL;
m_ptinfo = NULL;
m_bVisible = 0;
}
/*
* CHello::~CHello
*
* Purpose:
* Destructor for CHello object.
*
*/
CHello::~CHello()
{
extern ULONG g_cObj;
if (m_bstrFullName) SysFreeString(m_bstrFullName);
if (m_bstrName) SysFreeString(m_bstrName);
if (m_bstrProgID) SysFreeString(m_bstrProgID);
if (m_bstrHelloMsg) SysFreeString(m_bstrHelloMsg);
if (m_ptinfo) m_ptinfo->Release();
if (IsWindow(m_hwnd)) DestroyWindow(m_hwnd);
}
/*
* CHello::QueryInterface, AddRef, Release
*
* Purpose:
* Implements IUnknown::QueryInterface, AddRef, Release
*
*/
STDMETHODIMP
CHello::QueryInterface(REFIID iid, void FAR* FAR* ppv)
{
*ppv = NULL;
if (iid == IID_IUnknown || iid == IID_IDispatch || iid == IID_IHello )
*ppv = this;
else if (iid == IID_ISupportErrorInfo)
*ppv = &m_SupportErrorInfo;
else return ResultFromScode(E_NOINTERFACE);
AddRef();
return NOERROR;
}
STDMETHODIMP_(ULONG)
CHello::AddRef(void)
{
#ifdef _DEBUG
TCHAR ach[50];
wsprintf(ach, TEXT("AddRef: Ref = %ld, Hello\r\n"), m_cRef+1);
OutputDebugString(ach);
#endif
return ++m_cRef;
}
STDMETHODIMP_(ULONG)
CHello::Release(void)
{
#ifdef _DEBUG
TCHAR ach[50];
wsprintf(ach, TEXT("Release: Ref = %ld, Hello\r\n"), m_cRef-1);
OutputDebugString(ach);
#endif
if(--m_cRef == 0)
{
delete this;
return 0;
}
return m_cRef;
}
/*
* CHello::GetTypeInfoCount
*
* Purpose:
* Implements IDispatch::GetTypeInfoCount.
*
*/
STDMETHODIMP
CHello::GetTypeInfoCount(UINT FAR* pctinfo)
{
*pctinfo = 1;
return NOERROR;
}
/*
* CHello::GetTypeInfo
*
* Purpose:
* Implements IDispatch::GetTypeInfo.
*
*/
STDMETHODIMP
CHello::GetTypeInfo(
UINT itinfo,
LCID lcid,
ITypeInfo FAR* FAR* pptinfo)
{
*pptinfo = NULL;
if(itinfo != 0)
return ResultFromScode(DISP_E_BADINDEX);
m_ptinfo->AddRef();
*pptinfo = m_ptinfo;
return NOERROR;
}
/*
* CHello::GetIDsOfNames
*
* Purpose:
* Implements IDispatch::GetIDsOfNames. The standard implementation,
DispGetIDsOfNames,
* is used.
*
*/
STDMETHODIMP
CHello::GetIDsOfNames(
REFIID riid,
OLECHAR FAR* FAR* rgszNames,
UINT cNames,
LCID lcid,
DISPID FAR* rgdispid)
{
return DispGetIDsOfNames(m_ptinfo, rgszNames, cNames, rgdispid);
}
/*
* CHello::Invoke
*
* Purpose:
* Implements IDispatch::Invoke. The standard implementation, DispInvoke,
* is used.
*
*/
STDMETHODIMP
CHello::Invoke(
DISPID dispidMember,
REFIID riid,
LCID lcid,
WORD wFlags,
DISPPARAMS FAR* pdispparams,
VARIANT FAR* pvarResult,
EXCEPINFO FAR* pexcepinfo,
UINT FAR* puArgErr)
{
HRESULT hr;
m_bRaiseException = FALSE;
hr = DispInvoke(
this, m_ptinfo,
dispidMember, wFlags, pdispparams,
pvarResult, pexcepinfo, puArgErr);
if (m_bRaiseException)
{
if (NULL != pexcepinfo)
_fmemcpy(pexcepinfo, &m_excepinfo, sizeof(EXCEPINFO));
return ResultFromScode(DISP_E_EXCEPTION);
}
else return hr;
}
/*
* CHello::put_HelloMessage, get_HelloMessage, SayHello
*
* Purpose:
* Implements the standard Application, FullName, Name, Parent & Visible
properties
* and the Quit method.
*
*/
STDMETHODIMP
CHello::get_Application(IHello FAR* FAR* ppHello)
{
HRESULT hr;
*ppHello = NULL;
hr = QueryInterface(IID_IDispatch, (void FAR* FAR*)ppHello);
if (FAILED(hr))
return RaiseException(IDS_Unexpected);
return hr;
}
STDMETHODIMP
CHello::get_FullName(BSTR FAR* pbstr)
{
*pbstr = SysAllocString(m_bstrFullName);
return NOERROR;
}
STDMETHODIMP
CHello::get_Name(BSTR FAR* pbstr)
{
*pbstr = SysAllocString(m_bstrName);
return NOERROR;
}
STDMETHODIMP
CHello::get_Parent(IHello FAR* FAR* ppHello)
{
HRESULT hr;
*ppHello = NULL;
hr = QueryInterface(IID_IDispatch, (void FAR* FAR*)ppHello);
if (FAILED(hr))
return RaiseException(IDS_Unexpected);
return NOERROR;
}
STDMETHODIMP
CHello::put_Visible(VARIANT_BOOL bVisible)
{
ShowWindow(bVisible ? SW_SHOW : SW_HIDE);
return NOERROR;
}
STDMETHODIMP
CHello::get_Visible(VARIANT_BOOL FAR* pbool)
{
*pbool = m_bVisible;
return NOERROR;
}
STDMETHODIMP
CHello::Quit()
{
// CoDisconnectObject has no effect for an inproc server. So the
controller
// will GP fault if it attempts to access the object (including calling
IUnknown::Release())
// after Quit has been called. For a local server, CoDisconnectObject will
disconnect
// the object from external connections. So the controller will get an RPC
error if
// it accesses the object after calling Quit and controller will not GP
fault.
CoDisconnectObject((LPUNKNOWN)this, 0);
PostMessage(m_hwnd, WM_CLOSE, 0, 0L);
return NOERROR;
}
/*
* CHello::put_HelloMessage, get_HelloMessage, SayHello
*
* Purpose:
* Implements the HelloMessage property and the SayHello method.
*
*/
STDMETHODIMP
CHello::put_HelloMessage(BSTR bstrMessage)
{
SysReAllocString(&m_bstrHelloMsg, bstrMessage);
return NOERROR;
}
STDMETHODIMP
CHello::get_HelloMessage(BSTR FAR* pbstrMessage)
{
*pbstrMessage = SysAllocString(m_bstrHelloMsg);
return NOERROR;
}
STDMETHODIMP
CHello::SayHello()
{
SetDlgItemText(m_hwnd, IDC_HELLODISPLAY, FROM_OLE_STRING(m_bstrHelloMsg));
return NOERROR;
}
STDMETHODIMP_(void)
CHello::ShowWindow(int nCmdShow)
{
// Return if curently hidden and asked to hide or currently visible
// and asked to show.
if ((!m_bVisible && nCmdShow == SW_HIDE) || (m_bVisible && nCmdShow !=
SW_HIDE))
return;
m_bVisible = (nCmdShow == SW_HIDE) ? FALSE : TRUE;
// The Automation object shutdown behavior is as follows:
// 1. If the object application is visible, it shuts down only in response
to an
// explicit user command (File/Exit) or it's programmatic equivalent (for
example
// the Quit method of the Application object).
// 2. If the object application is not visible, it goes away when it's last
// object is released.
//
// CoLockObjectExternal can be used to increment the ref count of the
application object
// when it is visible. This will implement shutdown behavior 1. When the
application
// goes invisible, CoLockObjectExternal is used to decrement the ref
count. This will
// implement shutdown behavior 2.
if (m_bVisible)
CoLockObjectExternal(this, TRUE /*fLock*/, TRUE/*ignored when
fLock==TRUE*/);
else CoLockObjectExternal(this, FALSE/*fLock*/,
TRUE/*fLastLockReleases*/);
::ShowWindow (m_hwnd, nCmdShow);
}
/*
* CHello::RaiseException
*
* Purpose:
* Fills the EXCEPINFO structure and signal IDispatch::Invoke to return
DISP_E_EXCEPTION.
* Sets ErrorInfo object for vtable-binding controllers.
*
*/
STDMETHODIMP
CHello::RaiseException(int nID)
{
extern SCODE g_scodes[];
TCHAR szError[STR_LEN];
ICreateErrorInfo *pcerrinfo;
IErrorInfo *perrinfo;
HRESULT hr;
_fmemset(&m_excepinfo, 0, sizeof(EXCEPINFO));
m_excepinfo.wCode = nID;
if (LoadString(m_hinst, nID, szError, sizeof(szError)))
m_excepinfo.bstrDescription = SysAllocString(TO_OLE_STRING(szError));
m_excepinfo.bstrSource = SysAllocString(m_bstrProgID);
m_bRaiseException = TRUE;
// Set ErrInfo object so that vtable binding containers can get
// rich error information.
hr = CreateErrorInfo(&pcerrinfo);
if (SUCCEEDED(hr))
{
pcerrinfo->SetGUID(IID_IHello);
if (m_excepinfo.bstrSource)
pcerrinfo->SetSource(m_excepinfo.bstrSource);
if (m_excepinfo.bstrDescription)
pcerrinfo->SetDescription(m_excepinfo.bstrDescription);
hr = pcerrinfo->QueryInterface(IID_IErrorInfo, (LPVOID FAR*) &perrinfo);
if (SUCCEEDED(hr))
{
SetErrorInfo(0, perrinfo);
perrinfo->Release();
}
pcerrinfo->Release();
}
return ResultFromScode(g_scodes[nID-1001]);
}
/*
* ISupportErrorInfo implementation
*
*/
CSupportErrorInfo::CSupportErrorInfo(IUnknown FAR* punkObject, REFIID riid)
{
m_punkObject = punkObject;
m_iid = riid;
}
STDMETHODIMP
CSupportErrorInfo::QueryInterface(REFIID iid, void FAR* FAR* ppv)
{
return m_punkObject->QueryInterface(iid, ppv);
}
STDMETHODIMP_(ULONG)
CSupportErrorInfo::AddRef(void)
{
return m_punkObject->AddRef();
}
STDMETHODIMP_(ULONG)
CSupportErrorInfo::Release(void)
{
return m_punkObject->Release();
}
STDMETHODIMP
CSupportErrorInfo::InterfaceSupportsErrorInfo(REFIID riid)
{
return (riid == m_iid) ? NOERROR : ResultFromScode(S_FALSE);
}
- Software for developers
-
Delphi Components
.Net Components
Software for Android Developers
- More information resources
-
MegaDetailed.Net
Unix Manual Pages
Delphi Examples
- Databases for Amazon shops developers
-
Amazon Categories Database
Browse Nodes Database