summaryrefslogtreecommitdiffstats
path: root/private/oleauto/sample/spoly2
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--private/oleauto/sample/spoly2/cenumpt.cpp281
-rw-r--r--private/oleauto/sample/spoly2/cenumpt.h39
-rw-r--r--private/oleauto/sample/spoly2/clsid.c46
-rw-r--r--private/oleauto/sample/spoly2/clsid.h30
-rw-r--r--private/oleauto/sample/spoly2/cpoint.cpp356
-rw-r--r--private/oleauto/sample/spoly2/cpoint.h145
-rw-r--r--private/oleauto/sample/spoly2/cpoly.cpp897
-rw-r--r--private/oleauto/sample/spoly2/cpoly.h235
-rw-r--r--private/oleauto/sample/spoly2/hostenv.h117
-rw-r--r--private/oleauto/sample/spoly2/macmain.cpp397
-rw-r--r--private/oleauto/sample/spoly2/makefile342
-rw-r--r--private/oleauto/sample/spoly2/misc.cpp215
-rw-r--r--private/oleauto/sample/spoly2/mk.bat19
-rw-r--r--private/oleauto/sample/spoly2/mk.cmd13
-rw-r--r--private/oleauto/sample/spoly2/readme.txt62
-rw-r--r--private/oleauto/sample/spoly2/resource.h50
-rw-r--r--private/oleauto/sample/spoly2/spoly.h71
-rw-r--r--private/oleauto/sample/spoly2/spoly2.def14
-rw-r--r--private/oleauto/sample/spoly2/spoly2.icobin0 -> 766 bytes
-rw-r--r--private/oleauto/sample/spoly2/spoly2.r298
-rw-r--r--private/oleauto/sample/spoly2/spoly2.r3226
-rw-r--r--private/oleauto/sample/spoly2/spoly2.rc15
-rw-r--r--private/oleauto/sample/spoly2/spoly2.reg20
-rw-r--r--private/oleauto/sample/spoly2/statbar.cpp368
-rw-r--r--private/oleauto/sample/spoly2/statbar.h142
-rw-r--r--private/oleauto/sample/spoly2/tdata.cpp344
-rw-r--r--private/oleauto/sample/spoly2/winmain.cpp293
27 files changed, 4835 insertions, 0 deletions
diff --git a/private/oleauto/sample/spoly2/cenumpt.cpp b/private/oleauto/sample/spoly2/cenumpt.cpp
new file mode 100644
index 000000000..178afd967
--- /dev/null
+++ b/private/oleauto/sample/spoly2/cenumpt.cpp
@@ -0,0 +1,281 @@
+/***
+*cenumpt.cpp
+*
+* Copyright (C) 1992-1994, Microsoft Corporation. All Rights Reserved.
+*
+*Purpose:
+* This module implements the CEnumPoint class.
+*
+*
+*Implementation Notes:
+*
+*****************************************************************************/
+
+#include "hostenv.h"
+#include "cenumpt.h"
+
+
+CEnumPoint::CEnumPoint()
+{
+ m_refs = 0;
+
+ m_psa = NULL;
+ m_celts = 0;
+ m_iCurrent = 0;
+}
+
+
+/***
+*HRESULT CEnumPoint::Create(SAFEARRAY*, CEnumPoint**)
+*Purpose:
+* This routine creates a CPoint enumerator from the given
+* (1 X N) SafeArray of CPoint IDispatch pointers.
+*
+*Entry:
+* psa = pointer to a SafeArray of VARIANTs
+*
+*Exit:
+* return value = HRESULT
+*
+* *ppenum = pointer to a CPoint enumerator
+*
+***********************************************************************/
+HRESULT
+CEnumPoint::Create(SAFEARRAY FAR* psa, CEnumPoint FAR* FAR* ppenum)
+{
+ long lBound;
+ HRESULT hresult;
+ CEnumPoint FAR* penum;
+
+
+ // Verify that the SafeArray is the proper shape.
+ //
+ if(SafeArrayGetDim(psa) != 1)
+ return ResultFromScode(E_INVALIDARG);
+
+ hresult = SafeArrayGetLBound(psa, 1, &lBound);
+ if(FAILED(hresult))
+ return hresult;
+
+ if(lBound != 0)
+ return ResultFromScode(E_INVALIDARG);
+
+ penum = new FAR CEnumPoint();
+ if(penum == NULL)
+ return ResultFromScode(E_OUTOFMEMORY);
+ penum->AddRef();
+
+ hresult = SafeArrayGetUBound(psa, 1, &lBound);
+ if(FAILED(hresult))
+ goto LError0;
+
+ penum->m_psa = psa;
+ penum->m_celts = lBound + 1;
+
+ *ppenum = penum;
+
+ return NOERROR;
+
+LError0:;
+ penum->Release();
+
+ return hresult;
+}
+
+
+//---------------------------------------------------------------------
+// IUnknown methods
+//---------------------------------------------------------------------
+
+
+STDMETHODIMP
+CEnumPoint::QueryInterface(REFIID riid, void FAR* FAR* ppv)
+{
+ if(IsEqualIID(riid, IID_IEnumVARIANT) || IsEqualIID(riid, IID_IUnknown)){
+ *ppv = this;
+ AddRef();
+ return NOERROR;
+ }
+ *ppv = NULL;
+ return ResultFromScode(E_NOINTERFACE);
+}
+
+
+STDMETHODIMP_(unsigned long)
+CEnumPoint::AddRef()
+{
+ return ++m_refs;
+}
+
+
+STDMETHODIMP_(unsigned long)
+CEnumPoint::Release()
+{
+ if(--m_refs == 0){
+ if(m_psa != NULL)
+ SafeArrayDestroy(m_psa);
+ delete this;
+ return 0;
+ }
+ return m_refs;
+}
+
+
+//---------------------------------------------------------------------
+// IEnumVARIANT methods
+//---------------------------------------------------------------------
+
+
+/***
+*HRESULT CEnumPoint::Next(unsigned long, VARIANT*, unsigned long*)
+*Purpose:
+* Attempt to get the next 'celt' items in the enumeration sequence.
+*
+*Entry:
+* celt = the number of elements to get
+*
+*Exit:
+* return value = HRESULT
+* S_OK
+* S_FALSE - the end of the sequence was reached
+*
+* rgvar = array of the next 'celt' items
+* *pceltFetched = count of the elements actually fetched.
+*
+***********************************************************************/
+STDMETHODIMP
+CEnumPoint::Next(
+ unsigned long celt,
+ VARIANT FAR* rgvar,
+ unsigned long FAR* pceltFetched)
+{
+ long ix;
+ unsigned int i;
+ HRESULT hresult;
+
+
+ for(i = 0; i < celt; ++i)
+ VariantInit(&rgvar[i]);
+
+ for(i = 0; i < celt; ++i){
+ if(m_iCurrent == m_celts){
+ hresult = ResultFromScode(S_FALSE);
+ goto LDone;
+ }
+
+ ix = m_iCurrent++;
+ hresult = SafeArrayGetElement(m_psa, &ix, &rgvar[i]);
+ if(FAILED(hresult))
+ goto LError0;
+ }
+
+ hresult = NOERROR;
+
+LDone:;
+ if (pceltFetched != NULL)
+ *pceltFetched = i;
+
+ return hresult;
+
+LError0:;
+
+ for(i = 0; i < celt; ++i)
+ VariantClear(&rgvar[i]);
+
+ return hresult;
+}
+
+
+/***
+*HRESULT CEnumPoint::Skip(unsigned long)
+*Purpose:
+* Attempt to skip over the next 'celt' elements in the enumeration
+* sequence.
+*
+*Entry:
+* celt = the count of elements to skip
+*
+*Exit:
+* return value = HRESULT
+* S_OK
+* S_FALSE - the end of the sequence was reached
+*
+***********************************************************************/
+STDMETHODIMP
+CEnumPoint::Skip(unsigned long celt)
+{
+ m_iCurrent += celt;
+
+ if(m_iCurrent > m_celts)
+ m_iCurrent = m_celts;
+
+ return (m_iCurrent == m_celts)
+ ? ResultFromScode(S_FALSE) : NOERROR;
+}
+
+
+/***
+*HRESULT CEnumPoint::Reset(void)
+*Purpose:
+* Reset the enumeration sequence back to the beginning.
+*
+*Entry:
+* None
+*
+*Exit:
+* return value = SHRESULT CODE
+* S_OK
+*
+***********************************************************************/
+STDMETHODIMP
+CEnumPoint::Reset()
+{
+ m_iCurrent = 0;
+
+ return NOERROR;
+}
+
+
+/***
+*HRESULT CEnumPoint::Clone(IEnumVARIANT**)
+*Purpose:
+* Retrun a CPoint enumerator with exactly the same state as the
+* current one.
+*
+*Entry:
+* None
+*
+*Exit:
+* return value = HRESULT
+* S_OK
+* E_OUTOFMEMORY
+*
+***********************************************************************/
+STDMETHODIMP
+CEnumPoint::Clone(IEnumVARIANT FAR* FAR* ppenum)
+{
+ HRESULT hresult;
+ SAFEARRAY FAR* psa;
+ CEnumPoint FAR* penum;
+
+ hresult = SafeArrayCopy(m_psa, &psa);
+ if(FAILED(hresult))
+ return hresult;
+
+ hresult = CEnumPoint::Create(psa, &penum);
+ if(FAILED(hresult))
+ goto LError0;
+
+ // Assert(penum->m_celts == m_celts);
+
+ penum->m_iCurrent = m_iCurrent;
+
+ *ppenum = penum;
+
+ return NOERROR;
+
+LError0:
+ SafeArrayDestroy(psa);
+
+ return hresult;
+}
diff --git a/private/oleauto/sample/spoly2/cenumpt.h b/private/oleauto/sample/spoly2/cenumpt.h
new file mode 100644
index 000000000..c0d670f93
--- /dev/null
+++ b/private/oleauto/sample/spoly2/cenumpt.h
@@ -0,0 +1,39 @@
+/***
+*cenumpt.h
+*
+* Copyright (C) 1992-1994, Microsoft Corporation. All Rights Reserved.
+* Information Contained Herein Is Proprietary and Confidential.
+*
+*Purpose:
+* Definition of the CEnumPoint class.
+*
+*Implementation Notes:
+*
+*****************************************************************************/
+
+class CEnumPoint : public IEnumVARIANT
+{
+public:
+ static HRESULT Create(SAFEARRAY FAR* psa, CEnumPoint FAR* FAR* ppenum);
+
+ /* IUnknown methods */
+ STDMETHOD(QueryInterface)(REFIID riid, void FAR* FAR* ppv);
+ STDMETHOD_(unsigned long, AddRef)(void);
+ STDMETHOD_(unsigned long, Release)(void);
+
+ /* IEnumVARIANT methods */
+ STDMETHOD(Next)(unsigned long celt, VARIANT FAR* rgvar, unsigned long FAR* pceltFetched);
+ STDMETHOD(Skip)(unsigned long celt);
+ STDMETHOD(Reset)(void);
+ STDMETHOD(Clone)(IEnumVARIANT FAR* FAR* ppenum);
+
+ CEnumPoint();
+
+private:
+
+ unsigned long m_refs;
+
+ unsigned long m_celts;
+ unsigned long m_iCurrent;
+ SAFEARRAY FAR* m_psa;
+};
diff --git a/private/oleauto/sample/spoly2/clsid.c b/private/oleauto/sample/spoly2/clsid.c
new file mode 100644
index 000000000..5994746b5
--- /dev/null
+++ b/private/oleauto/sample/spoly2/clsid.c
@@ -0,0 +1,46 @@
+/***
+*clsid.c
+*
+* Copyright (C) 1992-1994, Microsoft Corporation. All Rights Reserved.
+* Information Contained Herein Is Proprietary and Confidential.
+*
+*Purpose:
+* This file allocates and initializes the CLSIDs.
+*
+*****************************************************************************/
+
+#ifdef _PPCMAC
+#pragma data_seg ("_FAR_DATA")
+#pragma data_seg ( )
+#endif //_PPCMAC
+
+#ifdef _MAC
+# include <Types.h>
+#ifdef _MSC_VER
+# include <Processe.h>
+# include <AppleEve.h>
+#else //_MSC_VER
+# include <Processes.h>
+# include <AppleEvents.h>
+#endif //_MSC_VER
+#else
+# include <windows.h>
+#endif
+
+#ifndef WIN32
+#include <compobj.h>
+#endif //!WIN32
+
+// this redefines the DEFINE_GUID() macro to do allocation.
+//
+#include <initguid.h>
+
+#ifndef INITGUID
+# define INITGUID
+#endif
+
+// due to the previous header, including this causes the DEFINE_GUID
+// definitions in the following header(s) to actually allocate data.
+//
+#include "clsid.h"
+
diff --git a/private/oleauto/sample/spoly2/clsid.h b/private/oleauto/sample/spoly2/clsid.h
new file mode 100644
index 000000000..6e7634d47
--- /dev/null
+++ b/private/oleauto/sample/spoly2/clsid.h
@@ -0,0 +1,30 @@
+/***
+*clsid.h
+*
+* Copyright (C) 1992-1994, Microsoft Corporation. All Rights Reserved.
+* Information Contained Herein Is Proprietary and Confidential.
+*
+*Purpose:
+* This file defines the CLSIDs
+*
+*Implementation Notes:
+*
+*****************************************************************************/
+
+DEFINE_GUID(CLSID_CPoly2, 0x00020464, 0, 0, 0xC0, 0, 0, 0, 0, 0, 0, 0x46);
+DEFINE_GUID(CLSID_CPoint2, 0x00020465, 0, 0, 0xC0, 0, 0, 0, 0, 0, 0, 0x46);
+
+
+#ifdef INITGUID
+# ifdef _MAC
+/* Define this under PPC Metroworks */
+# if !defined(_MW_BUILD)
+DEFINE_GUID(IID_IDispatch, 0x00020400L, 0, 0, 0xC0, 0, 0, 0, 0, 0, 0, 0x46);
+DEFINE_GUID(IID_IEnumVARIANT, 0x00020404L, 0, 0, 0xC0, 0, 0, 0, 0, 0, 0, 0x46);
+# endif
+DEFINE_GUID(GUID_NULL, 0L, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0);
+DEFINE_GUID(IID_IUnknown, 0x00000000L, 0, 0, 0xC0, 0, 0, 0, 0, 0, 0, 0x46);
+DEFINE_GUID(IID_IClassFactory, 0x00000001L, 0, 0, 0xC0, 0, 0, 0, 0, 0, 0, 0x46);
+# endif
+#endif
+
diff --git a/private/oleauto/sample/spoly2/cpoint.cpp b/private/oleauto/sample/spoly2/cpoint.cpp
new file mode 100644
index 000000000..24c95fa41
--- /dev/null
+++ b/private/oleauto/sample/spoly2/cpoint.cpp
@@ -0,0 +1,356 @@
+/***
+*cpoint.cpp
+*
+* Copyright (C) 1992-1994, Microsoft Corporation. All Rights Reserved.
+*
+*Purpose:
+* This module implements the CPoint and CPointCF classes.
+*
+* This module is intended as a sample implementation of the IDispatch
+* interface, and its purpose is to demonstrate how an object can
+* expose methods and properties for programatic and cross-process
+* access via the IDispatch interface.
+*
+*Implementation Notes:
+*
+*****************************************************************************/
+
+#include "spoly.h"
+#include "cpoint.h"
+
+
+CPoint::CPoint()
+{
+ m_x = 0;
+ m_y = 0;
+ m_refs = 0;
+ m_ptinfo = NULL;
+}
+
+/***
+*CPoint::Create(void)
+*Purpose:
+* Create an instance of a CPoint object.
+*
+*Entry:
+* None
+*
+*Exit:
+* returns a CPoint*, NULL if creation failed.
+*
+***********************************************************************/
+CPoint FAR*
+CPoint::Create()
+{
+ HRESULT hresult;
+ CPoint FAR* ppoint;
+ ITypeInfo FAR* ptinfo;
+extern INTERFACEDATA NEAR g_idataCPoint;
+
+
+ if((ppoint = new FAR CPoint()) == NULL)
+ return NULL;
+ ppoint->AddRef();
+
+ hresult =
+ CreateDispTypeInfo(&g_idataCPoint, LOCALE_SYSTEM_DEFAULT, &ptinfo);
+ if(hresult != NOERROR)
+ goto LError0;
+
+ ppoint->m_ptinfo = ptinfo;
+
+ return ppoint;
+
+LError0:;
+ ppoint->Release();
+
+ return NULL;
+}
+
+
+//---------------------------------------------------------------------
+// IUnknown Methods
+//---------------------------------------------------------------------
+
+
+STDMETHODIMP
+CPoint::QueryInterface(REFIID riid, void FAR* FAR* ppv)
+{
+ if(IsEqualIID(riid, IID_IUnknown) || IsEqualIID(riid, IID_IDispatch)){
+ *ppv = this;
+ AddRef();
+ return NOERROR;
+ }
+ *ppv = NULL;
+ return ResultFromScode(E_NOINTERFACE);
+}
+
+
+STDMETHODIMP_(unsigned long)
+CPoint::AddRef(void)
+{
+ return ++m_refs;
+}
+
+
+STDMETHODIMP_(unsigned long)
+CPoint::Release(void)
+{
+ if(--m_refs == 0){
+ if(m_ptinfo != NULL){
+ m_ptinfo->Release();
+ }
+ delete this;
+ return 0;
+ }
+ return m_refs;
+}
+
+
+//---------------------------------------------------------------------
+// IDispatch methods
+//---------------------------------------------------------------------
+
+
+STDMETHODIMP
+CPoint::GetTypeInfoCount(unsigned int FAR* pctinfo)
+{
+ // this object has a single *introduced* interface
+ //
+ *pctinfo = 1;
+
+ return NOERROR;
+}
+
+
+STDMETHODIMP
+CPoint::GetTypeInfo(unsigned int itinfo, LCID lcid, ITypeInfo FAR* FAR* pptinfo)
+{
+ UNUSED(lcid);
+
+ if(itinfo != 0)
+ return ResultFromScode(DISP_E_BADINDEX);
+
+ m_ptinfo->AddRef();
+ *pptinfo = m_ptinfo;
+
+ return NOERROR;
+}
+
+
+/***
+*HRESULT CPoint::GetIDsOfNames(REFIID, char**, unsigned int, LCID, DISPID*)
+*Purpose:
+* This method translates the given array of names to a corresponding
+* array of DISPIDs.
+*
+* Index 0 of the name array is the member name, and indices 1-N if
+* present represent named parameters on that member.
+*
+* The local ID ('lcid') is unused by this naive implementation. A more
+* sophisticated implementation, sensitive to localization and natural
+* language support would use the locale ID to interpret the given names
+* in a correct locale specific context.
+*
+*Entry:
+* rgszNames = pointer to an array of names
+* cNames = the number of names in the rgszNames array
+* lcid = the callers locale ID
+*
+*Exit:
+* return value = HRESULT
+* rgid = array of name IDs corresponding to the rgszNames array
+* this array will contain -1 for each entry that is not known.
+*
+***********************************************************************/
+STDMETHODIMP
+CPoint::GetIDsOfNames(
+ REFIID riid,
+ OLECHAR FAR* FAR* rgszNames,
+ unsigned int cNames,
+ LCID lcid,
+ DISPID FAR* rgdispid)
+{
+ UNUSED(lcid);
+
+ if(!IsEqualIID(riid,IID_NULL))
+ return ResultFromScode(DISP_E_UNKNOWNINTERFACE);
+
+ return DispGetIDsOfNames(m_ptinfo, rgszNames, cNames, rgdispid);
+}
+
+
+/***
+*HRESULT CPoint::Invoke(...)
+*Purpose:
+* Dispatch a method or property request for objects of type CPoint.
+*
+* see the IDispatch document for more information, and a general
+* description of this method.
+*
+*Entry:
+* dispidMember = the DISPID of the member being requested
+*
+* riid = reference to the interface ID of the interface on this object
+* that the requested member belongs to. IID_NULL means to interpret
+* the member as belonging to the implementation defined "default"
+* or "primary" interface.
+*
+* lcid = the caller's locale ID
+*
+* wFlags = flags indicating the type of access being requested
+*
+* pdispparams = pointer to the DISPPARAMS struct containing the
+* requested members arguments (if any) and its named parameter
+* DISPIDs (if any).
+*
+*Exit:
+* return value = HRESULT
+* see the IDispatch spec for a description of possible success codes.
+*
+* pvarResult = pointer to a caller allocated VARIANT containing
+* the members return value (if any).
+*
+* pexcepinfo = caller allocated exception info structure, this will
+* be filled in only if an exception was raised that must be passed
+* up through Invoke to an enclosing handler.
+*
+* puArgErr = pointer to a caller allocated UINT, that will contain the
+* index of the offending argument if a DISP_E_TYPEMISMATCH error
+* was returned indicating that one of the arguments was of an
+* incorrect type and/or could not be reasonably coerced to a proper
+* type.
+*
+***********************************************************************/
+STDMETHODIMP
+CPoint::Invoke(
+ DISPID dispidMember,
+ REFIID riid,
+ LCID lcid,
+ unsigned short wFlags,
+ DISPPARAMS FAR* pdispparams,
+ VARIANT FAR* pvarResult,
+ EXCEPINFO FAR* pexcepinfo,
+ unsigned int FAR* puArgErr)
+{
+ UNUSED(lcid);
+
+ if(!IsEqualIID(riid, IID_NULL))
+ return ResultFromScode(DISP_E_UNKNOWNINTERFACE);
+
+ return DispInvoke(
+ this, m_ptinfo,
+ dispidMember, wFlags, pdispparams,
+ pvarResult, pexcepinfo, puArgErr);
+}
+
+
+//---------------------------------------------------------------------
+// Introduced methods
+//---------------------------------------------------------------------
+
+short METHODCALLTYPE EXPORT
+CPoint::GetX()
+{
+ return m_x;
+}
+
+void METHODCALLTYPE EXPORT
+CPoint::SetX(short x)
+{
+ m_x = x;
+}
+
+short METHODCALLTYPE EXPORT
+CPoint::GetY()
+{
+ return m_y;
+}
+
+void METHODCALLTYPE EXPORT
+CPoint::SetY(short y)
+{
+ m_y = y;
+}
+
+
+//---------------------------------------------------------------------
+// Implementation of the CPoint Class Factory
+//---------------------------------------------------------------------
+
+CPointCF::CPointCF()
+{
+ m_refs = 0;
+}
+
+IClassFactory FAR*
+CPointCF::Create()
+{
+ CPointCF FAR* pCF;
+
+ if((pCF = new FAR CPointCF()) == NULL)
+ return NULL;
+ pCF->AddRef();
+ return pCF;
+}
+
+STDMETHODIMP
+CPointCF::QueryInterface(REFIID riid, void FAR* FAR* ppv)
+{
+ if(IsEqualIID(riid, IID_IUnknown) || IsEqualIID(riid, IID_IClassFactory)){
+ *ppv = this;
+ ++m_refs;
+ return NOERROR;
+ }
+ *ppv = NULL;
+ return ResultFromScode(E_NOINTERFACE);
+}
+
+STDMETHODIMP_(unsigned long)
+CPointCF::AddRef(void)
+{
+ return ++m_refs;
+}
+
+STDMETHODIMP_(unsigned long)
+CPointCF::Release(void)
+{
+ if(--m_refs == 0){
+ delete this;
+ return 0;
+ }
+ return m_refs;
+}
+
+STDMETHODIMP
+CPointCF::CreateInstance(
+ IUnknown FAR* punkOuter,
+ REFIID riid,
+ void FAR* FAR* ppv)
+{
+ HRESULT hresult;
+ CPoint FAR *ppoint;
+
+ UNUSED(punkOuter);
+
+ if((ppoint = CPoint::Create()) == NULL){
+ *ppv = NULL;
+ return ResultFromScode(E_OUTOFMEMORY);
+ }
+ hresult = ppoint->QueryInterface(riid, ppv);
+ ppoint->Release();
+ return hresult;
+}
+
+STDMETHODIMP
+#ifdef _MAC
+CPointCF::LockServer(unsigned long fLock)
+#else
+CPointCF::LockServer(BOOL fLock)
+#endif
+{
+ UNUSED(fLock);
+
+ return NOERROR;
+}
+
diff --git a/private/oleauto/sample/spoly2/cpoint.h b/private/oleauto/sample/spoly2/cpoint.h
new file mode 100644
index 000000000..c16ee20bd
--- /dev/null
+++ b/private/oleauto/sample/spoly2/cpoint.h
@@ -0,0 +1,145 @@
+/***
+*cpoint.h
+*
+* Copyright (C) 1992-1994, Microsoft Corporation. All Rights Reserved.
+* Information Contained Herein Is Proprietary and Confidential.
+*
+*Purpose:
+* Definition of the CPoint class.
+*
+* The CPoint object exposes two properties for programatic access
+* via the IDispatch interface.
+*
+* properties:
+* X - the 'x' coordinate of the point
+* Y - the 'y' coordinate of the point
+*
+*Implementation Notes:
+*
+*****************************************************************************/
+
+#ifndef CLASS
+#ifdef __TURBOC__
+#define CLASS class huge
+#else
+#define CLASS class FAR
+#endif
+#endif
+
+class CPoly;
+
+CLASS CPoint : public IDispatch {
+ friend class CPoly;
+
+public:
+ static CPoint FAR* Create();
+
+ /* IUnknown methods */
+ STDMETHOD(QueryInterface)(REFIID riid, void FAR* FAR* ppvObj);
+ STDMETHOD_(unsigned long, AddRef)(void);
+ STDMETHOD_(unsigned long, Release)(void);
+
+ /* IDispatch methods */
+ STDMETHOD(GetTypeInfoCount)(unsigned int FAR* pcTypeInfo);
+
+ STDMETHOD(GetTypeInfo)(
+ unsigned int iTypeInfo,
+ LCID lcid,
+ ITypeInfo FAR* FAR* ppTypeInfo);
+
+ STDMETHOD(GetIDsOfNames)(
+ REFIID riid,
+ OLECHAR FAR* FAR* rgszNames,
+ unsigned int cNames,
+ LCID lcid,
+ DISPID FAR* rgdispid);
+
+ STDMETHOD(Invoke)(
+ DISPID dispidMember,
+ REFIID riid,
+ LCID lcid,
+ unsigned short wFlags,
+ DISPPARAMS FAR* pdispparams,
+ VARIANT FAR* pvarResult,
+ EXCEPINFO FAR* pexcepinfo,
+ unsigned int FAR* pwArgErr);
+
+ /* Introduced methods */
+
+ virtual short METHODCALLTYPE EXPORT GetX(void);
+ virtual void METHODCALLTYPE EXPORT SetX(short x);
+ virtual short METHODCALLTYPE EXPORT GetY(void);
+ virtual void METHODCALLTYPE EXPORT SetY(short y);
+
+private:
+ CPoint();
+
+ unsigned long m_refs;
+
+ short m_x;
+ short m_y;
+
+ ITypeInfo FAR* m_ptinfo;
+};
+
+// member DISPIDs
+//
+enum IDMEMBER_CPOINT {
+ IDMEMBER_CPOINT_GETX = 1,
+ IDMEMBER_CPOINT_SETX,
+ IDMEMBER_CPOINT_GETY,
+ IDMEMBER_CPOINT_SETY,
+ IDMEMBER_CPOINT_MAX
+};
+
+// member indices - this is an enumeration of all members on CPoint
+//
+enum IMETH_CPOINT {
+ IMETH_CPOINT_QUERYINTERFACE = 0,
+ IMETH_CPOINT_ADDREF,
+ IMETH_CPOINT_RELEASE,
+ IMETH_CPOINT_GETTYPEINFOCOUNT,
+ IMETH_CPOINT_GETTYPEINFO,
+ IMETH_CPOINT_GETIDSOFNAMES,
+ IMETH_CPOINT_INVOKE,
+
+ IMETH_CPOINT_GETX,
+ IMETH_CPOINT_SETX,
+ IMETH_CPOINT_GETY,
+ IMETH_CPOINT_SETY
+};
+
+// structure used to link together lists of points
+//
+struct POINTLINK {
+ POINTLINK FAR* next;
+ CPoint FAR* ppoint;
+};
+
+
+// The CPoint Class Factory
+//
+CLASS CPointCF : public IClassFactory
+{
+public:
+ static IClassFactory FAR* Create();
+
+ /* IUnknown methods */
+ STDMETHOD(QueryInterface)(REFIID iid, void FAR* FAR* ppv);
+ STDMETHOD_(unsigned long, AddRef)(void);
+ STDMETHOD_(unsigned long, Release)(void);
+
+ /* IClassFactory methods */
+ STDMETHOD(CreateInstance)(
+ IUnknown FAR* pUnkOuter, REFIID iid, void FAR* FAR* ppv);
+#ifdef _MAC
+ STDMETHOD(LockServer)(unsigned long fLock);
+#else
+ STDMETHOD(LockServer)(BOOL fLock);
+#endif
+
+private:
+ CPointCF();
+
+ unsigned long m_refs;
+};
diff --git a/private/oleauto/sample/spoly2/cpoly.cpp b/private/oleauto/sample/spoly2/cpoly.cpp
new file mode 100644
index 000000000..5f547e39f
--- /dev/null
+++ b/private/oleauto/sample/spoly2/cpoly.cpp
@@ -0,0 +1,897 @@
+/***
+*cpoly.cpp
+*
+* Copyright (C) 1992-1994, Microsoft Corporation. All Rights Reserved.
+*
+*Purpose:
+* This module implements the CPoly and CPolyCF classes.
+*
+* This module is intended as a sample implementation of the IDispatch
+* interface, and its purpose is to demonstrate how an object can
+* expose methods and properties for programatic and cross-process
+* access via the IDispatch interface.
+*
+*Implementation Notes:
+*
+*****************************************************************************/
+
+#include "spoly.h"
+#include "cpoint.h"
+#include "cpoly.h"
+#include "cenumpt.h"
+
+#ifndef _MAC
+extern CStatBar FAR* g_psb;
+#endif
+
+#ifdef _MAC
+extern "C" WindowPtr g_pwndClient;
+#endif
+
+// our global list of polygons.
+//
+POLYLINK FAR* g_ppolylink = (POLYLINK FAR*)NULL;
+
+// global count of polygons.
+//
+int g_cPoly = 0;
+
+
+CPoly::CPoly()
+{
+ m_refs = 0;
+ m_xorg = 0;
+ m_yorg = 0;
+ m_width = 0;
+ m_cPoints = 0;
+
+ m_red = 0;
+ m_green = 0;
+ m_blue = 0;
+
+ m_ptinfo = NULL;
+
+ m_ppointlink = NULL;
+ m_ppointlinkLast = NULL;
+}
+
+
+/***
+*CPoly *CPoly::Create(void)
+*Purpose:
+* Create an instance of a CPoly object, and add it to the global
+* list of polygons.
+*
+*Entry:
+* None
+*
+*Exit:
+* returns a polygon object, NULL the allocation failed.
+*
+***********************************************************************/
+CPoly FAR*
+CPoly::Create()
+{
+ HRESULT hresult;
+ CPoly FAR* ppoly;
+ ITypeInfo FAR* ptinfo;
+ POLYLINK FAR* ppolylink;
+extern INTERFACEDATA NEAR g_idataCPoly;
+
+
+ if((ppolylink = new FAR POLYLINK) == (POLYLINK FAR*)NULL)
+ return (CPoly FAR*)NULL;
+
+ if((ppoly = new FAR CPoly()) == (CPoly FAR*)NULL)
+ return (CPoly FAR*)NULL;
+
+ ppoly->AddRef();
+
+ // create and attach its TypeInfo
+ //
+ hresult = CreateDispTypeInfo(&g_idataCPoly, LOCALE_SYSTEM_DEFAULT, &ptinfo);
+ if(hresult != NOERROR)
+ goto LError0;
+
+ ppoly->m_ptinfo = ptinfo;
+
+ // push the new polygon onto the front of the polygon list.
+ //
+ ++g_cPoly;
+
+ ppolylink->ppoly = ppoly;
+
+ ppolylink->next = g_ppolylink;
+ g_ppolylink = ppolylink;
+
+#ifndef _MAC
+ SBprintf(g_psb, TSTR("#poly = %d"), g_cPoly);
+#endif
+
+ return ppoly;
+
+
+LError0:;
+ ppoly->Release();
+
+ return NULL;
+}
+
+
+//---------------------------------------------------------------------
+// IUnknown Methods
+//---------------------------------------------------------------------
+
+
+STDMETHODIMP
+CPoly::QueryInterface(REFIID riid, void FAR* FAR* ppv)
+{
+ if(!IsEqualIID(riid, IID_IUnknown))
+ if(!IsEqualIID(riid, IID_IDispatch)) {
+ *ppv = NULL;
+ return ResultFromScode(E_NOINTERFACE);
+ }
+
+ *ppv = this;
+ AddRef();
+ return NOERROR;
+}
+
+
+STDMETHODIMP_(unsigned long)
+CPoly::AddRef()
+{
+ return ++m_refs;
+}
+
+
+STDMETHODIMP_(unsigned long)
+CPoly::Release()
+{
+ POLYLINK FAR* FAR* pppolylink, FAR* ppolylinkDead;
+
+ if(--m_refs == 0){
+ Reset(); // release all CPoints
+
+ // remove ourselves from the global list of polygons
+ //
+ for( pppolylink = &g_ppolylink;
+ *pppolylink != NULL;
+ pppolylink = &(*pppolylink)->next)
+ {
+ if((*pppolylink)->ppoly == this){
+ ppolylinkDead = *pppolylink;
+ *pppolylink = (*pppolylink)->next;
+ delete ppolylinkDead;
+ break;
+ }
+ }
+
+ if(m_ptinfo != NULL){
+ m_ptinfo->Release();
+ }
+
+ --g_cPoly;
+
+#ifndef _MAC
+ SBprintf(g_psb, TSTR("#poly = %d"), g_cPoly);
+#endif
+
+ delete this;
+ return 0;
+ }
+ return m_refs;
+}
+
+
+//---------------------------------------------------------------------
+// IDispatch Methods
+//---------------------------------------------------------------------
+
+STDMETHODIMP
+CPoly::GetTypeInfoCount(unsigned int FAR* pctinfo)
+{
+ // This object has a single *introduced* interface
+ //
+ *pctinfo = 1;
+
+ return NOERROR;
+}
+
+
+STDMETHODIMP
+CPoly::GetTypeInfo(unsigned int itinfo, LCID lcid, ITypeInfo FAR* FAR* pptinfo)
+{
+ UNUSED(lcid);
+
+ if(itinfo != 0)
+ return ResultFromScode(DISP_E_BADINDEX);
+
+ m_ptinfo->AddRef();
+ *pptinfo = m_ptinfo;
+
+ return NOERROR;
+}
+
+
+/***
+*HRESULT CPoly::GetIDsOfNames(char**, unsigned int, LCID, DISPID*)
+*Purpose:
+* This method translates the given array of names to a corresponding
+* array of DISPIDs.
+*
+* This method deferrs to a common implementation shared by
+* both the CPoly and CPoint objects. See the description of
+* 'SPolyGetIDsOfNames()' in dispimpl.cpp for more information.
+*
+*Entry:
+* rgszNames = pointer to an array of names
+* cNames = the number of names in the rgszNames array
+* lcid = the callers locale ID
+*
+*Exit:
+* return value = HRESULT
+* rgdispid = array of DISPIDs corresponding to the rgszNames array
+* this array will contain -1 for each entry that is not known.
+*
+***********************************************************************/
+STDMETHODIMP
+CPoly::GetIDsOfNames(
+ REFIID riid,
+ OLECHAR FAR* FAR* rgszNames,
+ unsigned int cNames,
+ LCID lcid,
+ DISPID FAR* rgdispid)
+{
+ UNUSED(lcid);
+
+ if(!IsEqualIID(riid, IID_NULL))
+ return ResultFromScode(DISP_E_UNKNOWNINTERFACE);
+
+ return DispGetIDsOfNames(m_ptinfo, rgszNames, cNames, rgdispid);
+}
+
+
+/***
+*HRESULT CPoly::Invoke(...)
+*Purpose:
+* Dispatch a method or property request for objects of type CPoly.
+*
+* see the IDispatch document for more information, and a general
+* description of this method.
+*
+*Entry:
+* dispidMember = the DISPID of the member being requested
+*
+* riid = reference to the interface ID of the interface on this object
+* that the requested member belongs to. IID_NULL means to interpret
+* the member as belonging to the implementation defined "default"
+* or "primary" interface.
+*
+* lcid = the caller's locale ID
+*
+* wFlags = flags indicating the type of access being requested
+*
+* pdispparams = pointer to the DISPPARAMS struct containing the
+* requested members arguments (if any) and its named parameter
+* DISPIDs (if any).
+*
+*Exit:
+* return value = HRESULT
+* see the IDispatch spec for a description of possible success codes.
+*
+* pvarResult = pointer to a caller allocated VARIANT containing
+* the members return value (if any).
+*
+* pexcepinfo = caller allocated exception info structure, this will
+* be filled in only if an exception was raised that must be passed
+* up through Invoke to an enclosing handler.
+*
+* puArgErr = pointer to a caller allocated UINT, that will contain the
+* index of the offending argument if a DISP_E_TYPEMISMATCH error
+* was returned indicating that one of the arguments was of an
+* incorrect type and/or could not be reasonably coerced to a proper
+* type.
+*
+***********************************************************************/
+STDMETHODIMP
+CPoly::Invoke(
+ DISPID dispidMember,
+ REFIID riid,
+ LCID lcid,
+ unsigned short wFlags,
+ DISPPARAMS FAR* pdispparams,
+ VARIANT FAR* pvarResult,
+ EXCEPINFO FAR* pexcepinfo,
+ unsigned int FAR* puArgErr)
+{
+ UNUSED(lcid);
+
+ if(!IsEqualIID(riid, IID_NULL))
+ return ResultFromScode(DISP_E_UNKNOWNINTERFACE);
+
+ return DispInvoke(
+ this, m_ptinfo,
+ dispidMember, wFlags, pdispparams,
+ pvarResult, pexcepinfo, puArgErr);
+}
+
+
+//---------------------------------------------------------------------
+// Introduced Methods
+//---------------------------------------------------------------------
+
+
+/***
+*void CPoly::Draw(void)
+*Purpose:
+* Draw the polygon, using the current x/y origin and line width
+* properties.
+*
+*Entry:
+* None
+*
+*Exit:
+* None
+*
+***********************************************************************/
+void METHODCALLTYPE EXPORT
+CPoly::Draw()
+{
+ short xorg, yorg;
+ POINTLINK FAR* ppointlinkFirst, FAR* ppointlink;
+
+ if((ppointlinkFirst = m_ppointlink) == (POINTLINK FAR*)NULL)
+ return;
+
+#ifdef _MAC /* { */
+
+ short x,y;
+ RGBColor rgb;
+ WindowPtr pwndSaved;
+
+ GetPort(&pwndSaved);
+ SetPort(g_pwndClient);
+
+ PenNormal();
+ PenSize(m_width, m_width);
+
+ rgb.red = m_red;
+ rgb.green = m_green;
+ rgb.blue = m_blue;
+ RGBForeColor(&rgb);
+
+ xorg = m_xorg;
+ yorg = m_yorg;
+
+ MoveTo(
+ xorg + ppointlinkFirst->ppoint->m_x,
+ yorg + ppointlinkFirst->ppoint->m_y);
+
+ for(ppointlink = ppointlinkFirst->next;
+ ppointlink != (POINTLINK FAR*)NULL;
+ ppointlink = ppointlink->next)
+ {
+ x = xorg + ppointlink->ppoint->m_x;
+ y = yorg + ppointlink->ppoint->m_y;
+ LineTo(x, y);
+ }
+
+ LineTo(
+ xorg + ppointlinkFirst->ppoint->m_x,
+ yorg + ppointlinkFirst->ppoint->m_y);
+
+ SetPort(pwndSaved);
+
+#else /* }{ */
+
+ HDC hdc;
+ RECT rect;
+ HPEN hpen, hpenOld;
+extern HWND g_hwndClient;
+
+ GetClientRect(g_hwndClient, &rect);
+ xorg = m_xorg + (short) rect.left;
+ yorg = m_yorg + (short) rect.top;
+
+ hdc = GetDC(g_hwndClient);
+ hpen = CreatePen(PS_SOLID, m_width, RGB(m_red, m_green, m_blue));
+ hpenOld = (HPEN)SelectObject(hdc, hpen);
+
+#ifdef WIN32
+ MoveToEx(hdc,
+ xorg + ppointlinkFirst->ppoint->m_x,
+ yorg + ppointlinkFirst->ppoint->m_y, NULL);
+#else
+ MoveTo(hdc,
+ xorg + ppointlinkFirst->ppoint->m_x,
+ yorg + ppointlinkFirst->ppoint->m_y);
+#endif
+
+ for(ppointlink = ppointlinkFirst->next;
+ ppointlink != (POINTLINK FAR*)NULL;
+ ppointlink = ppointlink->next)
+ {
+ LineTo(hdc,
+ xorg + ppointlink->ppoint->m_x,
+ yorg + ppointlink->ppoint->m_y);
+ }
+
+ LineTo(hdc,
+ xorg + ppointlinkFirst->ppoint->m_x,
+ yorg + ppointlinkFirst->ppoint->m_y);
+
+ SelectObject(hdc, hpenOld);
+ DeleteObject(hpen);
+
+ ReleaseDC(g_hwndClient, hdc);
+
+#endif /* } */
+}
+
+
+/***
+*void CPoly::Reset(void)
+*Purpose:
+* Release all points referenced by this poly.
+*
+*Entry:
+* None
+*
+*Exit:
+* None
+*
+***********************************************************************/
+void METHODCALLTYPE EXPORT
+CPoly::Reset()
+{
+ POINTLINK FAR* ppointlink, FAR* ppointlinkNext;
+
+ for(ppointlink = m_ppointlink;
+ ppointlink != (POINTLINK FAR*)NULL;
+ ppointlink = ppointlinkNext)
+ {
+ ppointlinkNext = ppointlink->next;
+ ppointlink->ppoint->Release();
+ delete ppointlink;
+ }
+
+ m_cPoints = 0;
+ m_ppointlink = NULL;
+ m_ppointlinkLast = NULL;
+}
+
+
+/***
+*HRESULT CPoly::AddPoint(short, short)
+*Purpose:
+* Add a CPoint with the given coordinates to the end of our current
+* list of points.
+*
+*Entry:
+* x,y = the x and y coordinates of the new point.
+*
+*Exit:
+* return value = HRESULT
+*
+***********************************************************************/
+HRESULT METHODCALLTYPE
+CPoly::AddPoint(short x, short y)
+{
+ CPoint FAR* ppoint;
+ POINTLINK FAR* ppointlink;
+
+ ppoint = CPoint::Create();
+ if(ppoint == (CPoint FAR*)NULL)
+ return ResultFromScode(E_OUTOFMEMORY);
+
+ ppoint->SetX(x);
+ ppoint->SetY(y);
+
+ ppointlink = new FAR POINTLINK;
+ if(ppointlink == (POINTLINK FAR*)NULL){
+ delete ppoint;
+ return ResultFromScode(E_OUTOFMEMORY);
+ }
+
+ ppointlink->ppoint = ppoint;
+ ppointlink->next = (POINTLINK FAR*)NULL;
+
+ if(m_ppointlinkLast == (POINTLINK FAR*)NULL){
+ m_ppointlink = m_ppointlinkLast = ppointlink;
+ }else{
+ m_ppointlinkLast->next = ppointlink;
+ m_ppointlinkLast = ppointlink;
+ }
+
+ ++m_cPoints;
+
+ return NOERROR;
+}
+
+
+/***
+*IUnknown FAR* CPoly::EnumPoints(void);
+*Purpose:
+* Return and enumerator for the points in this polygon.
+*
+*Entry:
+* None
+*
+*Exit:
+* return value = HRESULT
+*
+* *ppenum = pointer to an IEnumVARIANT for the points in this polygon
+*
+***********************************************************************/
+IUnknown FAR* METHODCALLTYPE EXPORT
+CPoly::EnumPoints()
+{
+ unsigned int i;
+ HRESULT hresult;
+ VARIANT var;
+ SAFEARRAY FAR* psa;
+ IUnknown FAR* punk;
+ CEnumPoint FAR* penum;
+ POINTLINK FAR* ppointlink;
+ SAFEARRAYBOUND rgsabound[1];
+
+ rgsabound[0].lLbound = 0;
+ rgsabound[0].cElements = m_cPoints;
+
+ psa = SafeArrayCreate(VT_VARIANT, 1, rgsabound);
+ if(psa == NULL){
+ hresult = ResultFromScode(E_OUTOFMEMORY);
+ goto LError0;
+ }
+
+ ppointlink = m_ppointlink;
+ for(i = 0; i < m_cPoints; ++i){
+ long ix[1];
+
+ if(ppointlink == NULL){
+ // this indicates an internal consistency error.
+ // (this test should probably be an assertion)
+ hresult = ResultFromScode(E_FAIL);
+ goto LError1;
+ }
+
+ V_VT(&var) = VT_DISPATCH;
+ hresult = ppointlink->ppoint->QueryInterface(
+ IID_IDispatch, (void FAR* FAR*)&V_DISPATCH(&var));
+ if(hresult != NOERROR)
+ goto LError1;
+
+ ix[0] = i;
+ SafeArrayPutElement(psa, ix, &var);
+
+ ppointlink = ppointlink->next;
+ }
+
+ hresult = CEnumPoint::Create(psa, &penum);
+ if(hresult != NOERROR)
+ goto LError1;
+
+ // ownership of the array has passed to the enumerator
+ psa = NULL;
+
+ hresult = penum->QueryInterface(IID_IUnknown, (void FAR* FAR*)&punk);
+ if(hresult != NOERROR)
+ goto LError2;
+
+ penum->Release();
+
+ return punk;
+
+LError2:;
+ penum->Release();
+
+LError1:;
+ // destroy the array if we were not successful creating the enumerator.
+ if(psa != NULL)
+ SafeArrayDestroy(psa);
+
+LError0:;
+ return NULL;
+}
+
+
+short METHODCALLTYPE EXPORT
+CPoly::GetXOrigin()
+{
+ return m_xorg;
+}
+
+void METHODCALLTYPE EXPORT
+CPoly::SetXOrigin(short x)
+{
+ m_xorg = x;
+}
+
+short METHODCALLTYPE EXPORT
+CPoly::GetYOrigin()
+{
+ return m_yorg;
+}
+
+void METHODCALLTYPE EXPORT
+CPoly::SetYOrigin(short y)
+{
+ m_yorg = y;
+}
+
+short METHODCALLTYPE EXPORT
+CPoly::GetWidth()
+{
+ return m_width;
+}
+
+
+void METHODCALLTYPE EXPORT
+CPoly::SetWidth(short width)
+{
+ m_width = width;
+}
+
+short METHODCALLTYPE EXPORT
+CPoly::get_red()
+{
+ return m_red;
+}
+
+void METHODCALLTYPE EXPORT
+CPoly::set_red(short red)
+{
+ m_red = red;
+}
+
+short METHODCALLTYPE EXPORT
+CPoly::get_green()
+{
+ return m_green;
+}
+
+void METHODCALLTYPE EXPORT
+CPoly::set_green(short green)
+{
+ m_green = green;
+}
+
+short METHODCALLTYPE EXPORT
+CPoly::get_blue()
+{
+ return m_blue;
+}
+
+void METHODCALLTYPE EXPORT
+CPoly::set_blue(short blue)
+{
+ m_blue = blue;
+}
+
+
+/***
+*void CPoly::Dump(void)
+*Purpose:
+* Output a debug dump of this instance.
+*
+*Entry:
+* None
+*
+*Exit:
+* None
+*
+***********************************************************************/
+void METHODCALLTYPE EXPORT
+CPoly::Dump()
+{
+#ifdef _MAC
+
+ // REVIEW: implement for the mac
+
+#else
+
+ TCHAR buffer[80];
+ POINTLINK FAR* ppointlink;
+
+ wsprintf(buffer, TSTR("CPoly(0x%x) =\n"), (int)this);
+ OutputDebugString(buffer);
+
+ wsprintf(buffer,
+ TSTR(" xorg = %d, yorg = %d, width = %d, rgb = {%d,%d,%d}\n points = "),
+ m_xorg, m_yorg, m_width,
+ get_red(),
+ get_green(),
+ get_blue());
+
+ OutputDebugString(buffer);
+
+ for(ppointlink = m_ppointlink;
+ ppointlink != (POINTLINK FAR*)NULL;
+ ppointlink = ppointlink->next)
+ {
+ wsprintf(buffer, TSTR("{%d,%d}"),
+ ppointlink->ppoint->GetX(),
+ ppointlink->ppoint->GetY());
+ OutputDebugString(buffer);
+
+ wsprintf(buffer, TSTR(" "));
+ OutputDebugString(buffer);
+ }
+ wsprintf(buffer, TSTR("\n"));
+ OutputDebugString(buffer);
+
+#endif
+}
+
+/***
+*void CPoly::PolyDraw(void)
+*Purpose:
+* Draw all polygons.
+*
+*Entry:
+* None
+*
+*Exit:
+* None
+*
+***********************************************************************/
+void
+CPoly::PolyDraw()
+{
+ POLYLINK FAR* polylink;
+
+ for(polylink = g_ppolylink;
+ polylink != (POLYLINK FAR*)NULL;
+ polylink = polylink->next)
+ {
+ polylink->ppoly->Draw();
+ }
+}
+
+
+/***
+*void PolyTerm(void)
+*Purpose:
+* Release all polygons.
+*
+*Entry:
+* None
+*
+*Exit:
+* None
+*
+***********************************************************************/
+void
+CPoly::PolyTerm()
+{
+ POLYLINK FAR* ppolylink;
+ POLYLINK FAR* ppolylinkNext;
+
+ for(ppolylink = g_ppolylink;
+ ppolylink != (POLYLINK FAR*)NULL;
+ ppolylink = ppolylinkNext)
+ {
+ ppolylinkNext = ppolylink->next;
+ ppolylink->ppoly->Release();
+ delete ppolylink;
+ }
+ g_ppolylink = NULL;
+}
+
+
+/***
+*void PolyDump(void)
+*Purpose:
+* Invoke the debug Dump() method on all polygons were currently
+* holding on to.
+*
+*Entry:
+* None
+*
+*Exit:
+* None
+*
+***********************************************************************/
+void
+CPoly::PolyDump()
+{
+ POLYLINK FAR* ppolylink;
+
+ if(g_ppolylink == (POLYLINK FAR*)NULL){
+#ifndef _MAC
+ OutputDebugString(TSTR("\t(none)\n"));
+#endif
+ return;
+ }
+
+ for(ppolylink = g_ppolylink;
+ ppolylink != (POLYLINK FAR*)NULL;
+ ppolylink = ppolylink->next)
+ {
+ ppolylink->ppoly->Dump();
+ }
+}
+
+
+//---------------------------------------------------------------------
+// Implementation of the CPoly Class Factory
+//---------------------------------------------------------------------
+
+
+CPolyCF::CPolyCF()
+{
+ m_refs = 0;
+}
+
+IClassFactory FAR*
+CPolyCF::Create()
+{
+ CPolyCF FAR* pCF;
+
+ if((pCF = new FAR CPolyCF()) == NULL)
+ return NULL;
+ pCF->AddRef();
+ return pCF;
+}
+
+STDMETHODIMP
+CPolyCF::QueryInterface(REFIID riid, void FAR* FAR* ppv)
+{
+ if(IsEqualIID(riid, IID_IUnknown) || IsEqualIID(riid, IID_IClassFactory)){
+ *ppv = this;
+ ++m_refs;
+ return NOERROR;
+ }
+ *ppv = NULL;
+ return ResultFromScode(E_NOINTERFACE);
+}
+
+STDMETHODIMP_(unsigned long)
+CPolyCF::AddRef(void)
+{
+ return ++m_refs;
+}
+
+STDMETHODIMP_(unsigned long)
+CPolyCF::Release(void)
+{
+ if(--m_refs == 0){
+ delete this;
+ return 0;
+ }
+ return m_refs;
+}
+
+STDMETHODIMP
+CPolyCF::CreateInstance(
+ IUnknown FAR* punkOuter,
+ REFIID iid,
+ void FAR* FAR* ppv)
+{
+ HRESULT hresult;
+ CPoly FAR *ppoly;
+
+ UNUSED(punkOuter);
+
+ if((ppoly = CPoly::Create()) == NULL){
+ *ppv = NULL;
+ return ResultFromScode(E_OUTOFMEMORY);
+ }
+ hresult = ppoly->QueryInterface(iid, ppv);
+ ppoly->Release();
+ return hresult;
+}
+
+STDMETHODIMP
+#ifdef _MAC
+CPolyCF::LockServer(unsigned long fLock)
+#else
+CPolyCF::LockServer(BOOL fLock)
+#endif
+{
+ UNUSED(fLock);
+
+ return NOERROR;
+}
+
diff --git a/private/oleauto/sample/spoly2/cpoly.h b/private/oleauto/sample/spoly2/cpoly.h
new file mode 100644
index 000000000..bc1dea9fe
--- /dev/null
+++ b/private/oleauto/sample/spoly2/cpoly.h
@@ -0,0 +1,235 @@
+/***
+*cpoly.h
+*
+* Copyright (C) 1992-1994 Microsoft Corporation. All Rights Reserved.
+* Information Contained Herein Is Proprietary and Confidential.
+*
+*Purpose:
+* Definition of the CPoly class.
+*
+* The CPoly class defines a number of methods and exposes them for
+* external programmability via IDispatch,
+*
+* methods:
+* DRAW - draw the polygon
+* RESET - delete all points from the polygon
+*
+* ADDPOINT(X, Y) - add a point with coordinates (x,y) to the polygon
+*
+* ENUMPOINTS - return a collection of the polygon's points
+*
+* GETXORIGIN - get and set the X origin of the polygon
+* SETXORIGIN
+*
+* GETYORIGIN - get and set the Y origin of the polygon
+* SETYORIGIN
+*
+* GETWIDTH - get and set the line width of the polygon
+* SETWIDTH
+*
+* UNDONE: update description
+*
+*Implementation Notes:
+*
+*****************************************************************************/
+
+
+#ifndef CLASS
+# ifdef __TURBOC__
+# define CLASS class huge
+# else
+# define CLASS class FAR
+# endif
+#endif
+
+class CPoint;
+
+CLASS CPoly : public IDispatch
+{
+public:
+ static CPoly FAR* Create();
+
+ /* IUnknown methods */
+ STDMETHOD(QueryInterface)(REFIID riid, void FAR* FAR* ppvObj);
+ STDMETHOD_(unsigned long, AddRef)(void);
+ STDMETHOD_(unsigned long, Release)(void);
+
+ /* IDispatch methods */
+ STDMETHOD(GetTypeInfoCount)(unsigned int FAR* pcTypeInfo);
+
+ STDMETHOD(GetTypeInfo)(
+ unsigned int iTypeInfo,
+ LCID lcid,
+ ITypeInfo FAR* FAR* ppTypeInfo);
+
+ STDMETHOD(GetIDsOfNames)(
+ REFIID riid,
+ OLECHAR FAR* FAR* rgszNames,
+ unsigned int cNames,
+ LCID lcid,
+ DISPID FAR* rgdispid);
+
+ STDMETHOD(Invoke)(
+ DISPID dispidMember,
+ REFIID riid,
+ LCID lcid,
+ unsigned short wFlags,
+ DISPPARAMS FAR* pdispparams,
+ VARIANT FAR* pvarResult,
+ EXCEPINFO FAR* pexcepinfo,
+ unsigned int FAR* puArgErr);
+
+ /* Introduced methods */
+
+ virtual void METHODCALLTYPE EXPORT Draw(void);
+ virtual void METHODCALLTYPE EXPORT Reset(void);
+
+ // add a point with the given 'x' and 'y' coordinates
+ virtual HRESULT METHODCALLTYPE EXPORT AddPoint(short x, short y);
+
+ // return a collection of the polygon's points
+ virtual IUnknown FAR* METHODCALLTYPE EXPORT EnumPoints(void);
+
+ // get/set the polygon's X origin property
+ virtual short METHODCALLTYPE EXPORT GetXOrigin(void);
+ virtual void METHODCALLTYPE EXPORT SetXOrigin(short x);
+
+ // get/set the polygon's Y origin property
+ virtual short METHODCALLTYPE EXPORT GetYOrigin(void);
+ virtual void METHODCALLTYPE EXPORT SetYOrigin(short y);
+
+ virtual short METHODCALLTYPE EXPORT GetWidth(void);
+ virtual void METHODCALLTYPE EXPORT SetWidth(short width);
+
+ virtual short METHODCALLTYPE EXPORT get_red(void);
+ virtual void METHODCALLTYPE EXPORT set_red(short red);
+
+ virtual short METHODCALLTYPE EXPORT get_green(void);
+ virtual void METHODCALLTYPE EXPORT set_green(short green);
+
+ virtual short METHODCALLTYPE EXPORT get_blue(void);
+ virtual void METHODCALLTYPE EXPORT set_blue(short blue);
+
+ // Debug method
+ virtual void METHODCALLTYPE EXPORT Dump(void);
+
+public:
+
+ // Draw all polygons.
+ static void PolyDraw(void);
+
+ // Release all polygons.
+ static void PolyTerm(void);
+
+ // Dump all polygons to dbwin.
+ static void PolyDump(void);
+
+
+private:
+ CPoly();
+
+ short m_xorg;
+ short m_yorg;
+ short m_width;
+
+ short m_red;
+ short m_green;
+ short m_blue;
+
+ unsigned long m_refs;
+ unsigned int m_cPoints;
+
+ ITypeInfo FAR* m_ptinfo;
+
+ POINTLINK FAR* m_ppointlink;
+ POINTLINK FAR* m_ppointlinkLast;
+};
+
+// DISPIDs for the members and properties available via IDispatch.
+//
+enum IDMEMBER_CPOLY {
+ IDMEMBER_CPOLY_DRAW = 1,
+ IDMEMBER_CPOLY_RESET,
+ IDMEMBER_CPOLY_ADDPOINT,
+ IDMEMBER_CPOLY_ENUMPOINTS,
+ IDMEMBER_CPOLY_GETXORIGIN,
+ IDMEMBER_CPOLY_SETXORIGIN,
+ IDMEMBER_CPOLY_GETYORIGIN,
+ IDMEMBER_CPOLY_SETYORIGIN,
+ IDMEMBER_CPOLY_GETWIDTH,
+ IDMEMBER_CPOLY_SETWIDTH,
+ IDMEMBER_CPOLY_GETRED,
+ IDMEMBER_CPOLY_SETRED,
+ IDMEMBER_CPOLY_GETGREEN,
+ IDMEMBER_CPOLY_SETGREEN,
+ IDMEMBER_CPOLY_GETBLUE,
+ IDMEMBER_CPOLY_SETBLUE,
+ IDMEMBER_CPOLY_DUMP,
+ IDMEMBER_CPOLY_MAX
+};
+
+// CPoly method indices
+//
+enum IMETH_CPOLY {
+ IMETH_CPOLY_QUERYINTERFACE = 0,
+ IMETH_CPOLY_ADDREF,
+ IMETH_CPOLY_RELEASE,
+ IMETH_CPOLY_GETTYPEINFOCOUNT,
+ IMETH_CPOLY_GETTYPEINFO,
+ IMETH_CPOLY_GETIDSOFNAMES,
+ IMETH_CPOLY_INVOKE,
+ IMETH_CPOLY_DRAW,
+ IMETH_CPOLY_RESET,
+ IMETH_CPOLY_ADDPOINT,
+ IMETH_CPOLY_ENUMPOINTS,
+ IMETH_CPOLY_GETXORIGIN,
+ IMETH_CPOLY_SETXORIGIN,
+ IMETH_CPOLY_GETYORIGIN,
+ IMETH_CPOLY_SETYORIGIN,
+ IMETH_CPOLY_GETWIDTH,
+ IMETH_CPOLY_SETWIDTH,
+ IMETH_CPOLY_GETRED,
+ IMETH_CPOLY_SETRED,
+ IMETH_CPOLY_GETGREEN,
+ IMETH_CPOLY_SETGREEN,
+ IMETH_CPOLY_GETBLUE,
+ IMETH_CPOLY_SETBLUE,
+ IMETH_CPOLY_DUMP,
+ IMETH_CPOLY_MAX
+};
+
+// structure used to link together polygons
+//
+struct POLYLINK {
+ POLYLINK FAR* next;
+ CPoly FAR* ppoly;
+};
+
+
+// The CPoly class factory
+//
+CLASS CPolyCF : public IClassFactory
+{
+public:
+ static IClassFactory FAR* Create();
+
+ /* IUnknown methods */
+ STDMETHOD(QueryInterface)(REFIID riid, void FAR* FAR* ppv);
+ STDMETHOD_(unsigned long, AddRef)(void);
+ STDMETHOD_(unsigned long, Release)(void);
+
+ /* IClassFactory methods */
+ STDMETHOD(CreateInstance)(
+ IUnknown FAR* pUnkOuter, REFIID riid, void FAR* FAR* ppv);
+#ifdef _MAC
+ STDMETHOD(LockServer)(unsigned long fLock);
+#else
+ STDMETHOD(LockServer)(BOOL fLock);
+#endif
+
+private:
+ CPolyCF();
+
+ unsigned long m_refs;
+};
+
diff --git a/private/oleauto/sample/spoly2/hostenv.h b/private/oleauto/sample/spoly2/hostenv.h
new file mode 100644
index 000000000..56a311393
--- /dev/null
+++ b/private/oleauto/sample/spoly2/hostenv.h
@@ -0,0 +1,117 @@
+/***
+*hostenv.h
+*
+* Copyright (C) 1992-1994, Microsoft Corporation. All Rights Reserved.
+*
+*Purpose:
+* Generic host specific includes.
+*
+*Implementation Notes:
+*
+*****************************************************************************/
+
+#if defined(_MAC)
+
+#if defined(_PPCMAC)
+#pragma data_seg("_FAR_DATA")
+#pragma data_seg( )
+#define MAXLONG 0x7fffffff
+#define EventHandlerProcPtr AEEventHandlerUPP
+#else //_PPCMAC
+#define GetMenuItemText(mApple,menuItem,daName) GetItem(mApple,menuItem,daName)
+#endif //_PPCMAC
+
+#endif //_MAC
+
+#if defined(_MAC)
+
+#if defined(_MSC_VER)
+
+# include <values.h>
+# include <types.h>
+# include <string.h>
+# include <quickdra.h>
+# include <fonts.h>
+# include <events.h>
+# include <resource.h>
+# include <menus.h>
+# include <textedit.h>
+# include <dialogs.h>
+# include <desk.h>
+# include <toolutil.h>
+# include <memory.h>
+# include <files.h>
+# include <osutils.h>
+# include <osevents.h>
+# include <diskinit.h>
+# include <packages.h>
+# include <traps.h>
+# include <AppleEve.h>
+
+#else //_MSC_VER
+
+# include <values.h>
+# include <types.h>
+# include <strings.h>
+# include <quickdraw.h>
+# include <fonts.h>
+# include <events.h>
+# include <resources.h>
+# include <windows.h>
+# include <menus.h>
+# include <textedit.h>
+# include <dialogs.h>
+# include <desk.h>
+# include <toolutils.h>
+# include <memory.h>
+# include <files.h>
+# include <osutils.h>
+# include <osevents.h>
+# include <diskinit.h>
+# include <packages.h>
+# include <traps.h>
+# include <AppleEvents.h>
+
+#endif //_MSC_VER
+
+# include <ole2.h>
+# include <olenls.h>
+# include <dispatch.h>
+
+# define TCHAR char
+# define TSTR(str) str
+# define STRING(str) (str)
+# define WIDESTRING(str) (str)
+
+#elif defined(WIN32)
+
+# include <windows.h>
+
+# if defined(UNICODE)
+ #define TCHAR WCHAR
+ #define TSTR(str) L##str
+ #define STRING(str) (str)
+ #define WIDESTRING(str) (str)
+# else
+ #define TCHAR char
+ #define TSTR(str) str
+ #define STRING(str) AnsiString(str)
+ #define WIDESTRING(str) WideString(str)
+ extern "C" char FAR* AnsiString(OLECHAR FAR* strIn);
+ extern "C" OLECHAR FAR* WideString(char FAR* strIn);
+# endif
+
+
+#else /* WIN16 */
+
+# include <windows.h>
+# include <ole2.h>
+# include <olenls.h>
+# include <dispatch.h>
+
+# define TCHAR char
+# define TSTR(str) str
+# define STRING(str) (str)
+# define WIDESTRING(str) (str)
+#endif
+
diff --git a/private/oleauto/sample/spoly2/macmain.cpp b/private/oleauto/sample/spoly2/macmain.cpp
new file mode 100644
index 000000000..12ca8ba77
--- /dev/null
+++ b/private/oleauto/sample/spoly2/macmain.cpp
@@ -0,0 +1,397 @@
+/***
+*macmain.cpp
+*
+* Copyright (C) 1992-1994, Microsoft Corporation. All Rights Reserved.
+*
+*Purpose:
+* This module is the main entry point for the sample IDispatch polygon
+* server, spoly2.exe.
+*
+* This program is intended to demonstrate an implementation of the IDispatch
+* interface. Spoly is a very simple app, that implements two simple objects,
+* CPoly and CPoint and exposes their properties and methods for programatic
+* and cross-process access via IDispatch.
+*
+*Implementation Notes:
+*
+*****************************************************************************/
+
+#include "spoly.h"
+#include "cpoint.h"
+#include "cpoly.h"
+
+#include <stdio.h>
+
+extern "C" {
+
+Boolean g_fInitOle = false;
+#ifndef _PPCMAC
+Boolean g_fInitLibraryManager = false;
+#endif //_PPCMAC
+WindowPtr g_pwndClient = nil;
+
+}
+
+void Init(void);
+void EventLoop(void);
+
+void AdjustMenus(void);
+void Close(WindowPtr window);
+void DoEvent(EventRecord *pevent);
+void DoMenuCommand(long menuResult);
+void Quit(void);
+#ifndef _MSC_VER
+#ifndef ConstStr255Param
+#define ConstStr255Param StringPtr
+#endif
+#endif
+void Fatal(ConstStr255Param);
+
+Boolean
+IsAppWindow(WindowPtr window)
+{
+ return (window == nil)
+ ? false : ((WindowPeek)window)->windowKind == userKind;
+}
+
+Boolean
+IsDAWindow(WindowPtr window)
+{
+ return (window == nil)
+ ? false : (((WindowPeek)window)->windowKind < 0);
+}
+
+void
+main()
+{
+ Init();
+ EventLoop();
+}
+
+void
+EventLoop()
+{
+ EventRecord event;
+ RgnHandle cursorRgn;
+
+ cursorRgn = NewRgn();
+ while(1){
+ if(WaitNextEvent(everyEvent, &event, MAXLONG, cursorRgn))
+ DoEvent(&event);
+ }
+}
+
+void
+DoEvent(EventRecord *pevent)
+{
+ char key;
+ short part;
+ WindowPtr window;
+
+ switch(pevent->what){
+ case mouseDown:
+ part = FindWindow(pevent->where, &window);
+ switch(part){
+ case inMenuBar:
+ AdjustMenus();
+ DoMenuCommand(MenuSelect(pevent->where));
+ break;
+
+ case inSysWindow: /* let the system handle the mouseDown */
+ SystemClick(pevent, window);
+ break;
+
+ case inContent:
+ if(window != FrontWindow()){
+ SelectWindow(window);
+ }
+ break;
+
+ case inDrag:
+ DragWindow(window, pevent->where, &qd.screenBits.bounds);
+ break;
+ }
+ break;
+
+ case keyDown:
+ case autoKey: /* check for menukey equivalents */
+ key = (char)(pevent->message & charCodeMask);
+ if(pevent->modifiers & cmdKey){ /* Command key down */
+ if(pevent->what == keyDown){
+ /* enable/disable/check menu items properly */
+ AdjustMenus();
+ DoMenuCommand(MenuKey(key));
+ }
+ }
+ break;
+
+ case updateEvt:
+ window = (WindowPtr)pevent->message;
+ if(IsAppWindow(window)){
+ BeginUpdate(window);
+ if(!EmptyRgn(window->visRgn)){
+ SetPort(window);
+ EraseRect(&window->portRect);
+ }
+ EndUpdate(window);
+ }
+ break;
+
+ case kHighLevelEvent:
+ AEProcessAppleEvent(pevent);
+ break;
+ }
+}
+
+void
+Enable(MenuHandle hmenu, short sItem, Boolean fEnable)
+{
+ if(fEnable)
+ EnableItem(hmenu, sItem);
+ else
+ DisableItem(hmenu, sItem);
+}
+
+void
+AdjustMenus()
+{
+ Boolean fIsDA;
+ MenuHandle hmenu;
+
+ fIsDA = IsDAWindow(FrontWindow());
+
+ /* we can allow desk accessories to be closed from the menu */
+ hmenu = GetMHandle(mFile);
+ Enable(hmenu, iClose, fIsDA);
+
+ hmenu = GetMHandle(mEdit);
+ Enable(hmenu, iUndo, fIsDA);
+ Enable(hmenu, iCut, fIsDA);
+ Enable(hmenu, iCopy, fIsDA);
+ Enable(hmenu, iClear, fIsDA);
+ Enable(hmenu, iPaste, fIsDA);
+}
+
+// Spoly2 self test
+HRESULT
+DoPoly()
+{
+ HRESULT hresult;
+ int numpoly, i, j;
+
+static struct {
+ short x;
+ short y;
+} rgptPoly[] = {
+ { 25, 0}
+ , { 75, 0}
+ , {100, 25}
+ , {100, 75}
+ , { 75, 100}
+ , { 25, 100}
+ , { 0, 75}
+ , { 0, 25}
+};
+
+static struct {
+ short red;
+ short green;
+ short blue;
+} rgrgbColors[] = {
+ { 0, 0, 0}
+ , { 0, 0, 0x7fff}
+ , { 0, 0x7fff, 0}
+ , {0x7fff, 0, 0}
+ , {0x7fff, 0, 0x7fff}
+ , {0x7fff, 0x7fff, 0}
+ , {0x7fff, 0x7fff, 0x7fff}
+};
+
+ CPoly *rgprempoly[DIM(rgrgbColors)];
+
+ numpoly = DIM(rgprempoly);
+
+ // init
+ for(i = 0; i < numpoly; ++i)
+ rgprempoly[i] = (CPoly*)NULL;
+
+ for(i = 0; i < numpoly; ++i){
+ if((rgprempoly[i] = CPoly::Create()) == NULL)
+ goto LError0;
+
+ for(j = 0; j < DIM(rgptPoly); ++j)
+ rgprempoly[i]->AddPoint(rgptPoly[j].x, rgptPoly[j].y);
+
+ for(j = 0; j < DIM(rgrgbColors); ++j){
+ rgprempoly[i]->SetWidth(i + j);
+ rgprempoly[i]->set_red(rgrgbColors[j].red);
+ rgprempoly[i]->set_green(rgrgbColors[j].green);
+ rgprempoly[i]->set_blue(rgrgbColors[j].blue);
+ rgprempoly[i]->SetXOrigin((2*i) + j << 4);
+ rgprempoly[i]->SetYOrigin(j << 4);
+ rgprempoly[i]->Draw();
+ }
+ }
+
+ hresult = NOERROR;
+
+LError0:;
+ for(i = 0; i < numpoly; ++i){
+ if(rgprempoly[i] != (CPoly*)NULL){
+ rgprempoly[i]->Release();
+ }
+ }
+
+ return hresult;
+}
+
+void
+DoMenuCommand(long menuResult)
+{
+ short menuID; /* the resource ID of the selected menu */
+ short menuItem; /* the item number of the selected menu */
+ Str255 daName;
+
+ menuID = HiWord(menuResult);
+ menuItem = LoWord(menuResult);
+
+ switch(menuID){
+ case mApple:
+ switch(menuItem){
+ case iAbout: /* bring up alert for About */
+ Alert(rAboutAlert, nil);
+ break;
+ default:
+ GetMenuItemText(GetMHandle(mApple), menuItem, daName);
+ OpenDeskAcc(daName);
+ break;
+ }
+ break;
+
+ case mFile:
+ switch(menuItem){
+ case iClose:
+ Close(FrontWindow());
+ break;
+ case iQuit:
+ Quit();
+ break;
+ }
+ break;
+
+ case mEdit:
+ SystemEdit(menuItem-1);
+ break;
+
+ case mSpoly:
+ switch(menuItem){
+ case iTest:
+ DoPoly();
+ break;
+ }
+ }
+
+ HiliteMenu(0);
+}
+
+void
+Close(WindowPtr window)
+{
+ if(IsDAWindow(window))
+ CloseDeskAcc(((WindowPeek)window)->windowKind);
+ else if(IsAppWindow(window))
+ CloseWindow(window);
+}
+
+#if defined(_MSC_VER)
+OSErr pascal
+#else
+pascal OSErr
+#endif
+RemoteLowLevelEvt(AppleEvent theAppEvt, AppleEvent reply, long HandlerRefCon)
+{
+ long cb;
+ OSErr err;
+ DescType descType;
+ EventRecord event;
+
+ UNUSED(reply);
+ UNUSED(HandlerRefCon);
+
+ err = AEGetKeyPtr(
+ &theAppEvt,
+ keyDirectObject,
+ typeWildCard,
+ &descType,
+ (Ptr)&event, sizeof(event), &cb);
+
+ if(err != noErr)
+ return err;
+
+ DoEvent(&event);
+
+ return noErr;
+}
+
+void
+Init()
+{
+ Handle menuBar;
+
+ MaxApplZone();
+
+ InitGraf((Ptr)&qd.thePort);
+ InitFonts();
+ InitWindows();
+ InitMenus();
+ TEInit();
+ InitDialogs(nil);
+ InitCursor();
+ FlushEvents(everyEvent, 0);
+
+#ifndef _PPCMAC
+ if (InitOleManager(0) != NOERROR)
+ Fatal((ConstStr255Param)"\pCould not initialize OLE Applet");
+ g_fInitLibraryManager = true;
+#endif //_PPCMAC
+
+ if(InitOle() != NOERROR)
+ Fatal((ConstStr255Param)"\pUnable to Initialize Ole");
+ g_fInitOle = true;
+
+ if(AEInstallEventHandler('OLE2', 'EVNT', (EventHandlerProcPtr)RemoteLowLevelEvt, 0, false) != noErr)
+ Fatal((ConstStr255Param)"\pUnable to install handler");
+
+ if((g_pwndClient = (WindowPtr)NewPtr(sizeof(WindowRecord))) == nil)
+ Fatal((ConstStr255Param)"\pOut of memory");
+ g_pwndClient = GetNewCWindow(rWindow, (Ptr)g_pwndClient, (WindowPtr)-1);
+
+ if((menuBar = GetNewMBar(rMenuBar)) == nil)
+ Fatal((ConstStr255Param)"\pUnable to load menu bar");
+ SetMenuBar(menuBar);
+ DisposHandle(menuBar);
+ AddResMenu(GetMHandle(mApple), 'DRVR'); /* add DA names to Apple menu */
+ DrawMenuBar();
+}
+
+void
+Quit()
+{
+ if(g_fInitOle)
+ UninitOle();
+#ifndef _PPCMAC
+ if(g_fInitLibraryManager)
+ UninitOleManager(); // clean up applet
+#endif //_PPCMAC
+ ExitToShell();
+}
+
+/* display fatal error alert, and exit */
+void
+Fatal(ConstStr255Param msg)
+{
+ SetCursor(&qd.arrow);
+ ParamText(msg, (ConstStr255Param)"\p", (ConstStr255Param)"\p", (ConstStr255Param)"\p");
+ Alert(rUserAlert, nil);
+ Quit();
+}
diff --git a/private/oleauto/sample/spoly2/makefile b/private/oleauto/sample/spoly2/makefile
new file mode 100644
index 000000000..dcb062a63
--- /dev/null
+++ b/private/oleauto/sample/spoly2/makefile
@@ -0,0 +1,342 @@
+##############################################################################
+#
+# (c) Copyright Microsoft Corp. 1992-1994 All Rights Reserved
+#
+# File:
+#
+# makefile - makefile for spoly2.exe
+#
+# Purpose:
+#
+# Builds the OLE 2.0 sample IDispatch server, spoly2.exe.
+#
+#
+# Usage:
+#
+# NMAKE ; build with defaults
+# or: NMAKE option ; build with the given option(s)
+# or: NMAKE clean ; erase all compiled files
+#
+# option:
+# dev = [win16 | win32 | mac] ; dev=win16 is the default
+# CPU = [i386 | M68K | MIPS | ALPHA | PPC]
+# DEBUG=[0|1] ; DEBUG=1 is the default
+#
+# Notes:
+#
+# This makefile assumes that the PATH, INCLUDE and LIB environment
+# variables are setup properly.
+#
+##############################################################################
+
+
+
+##########################################################################
+#
+# Default Settings
+#
+
+!if "$(dev)" == ""
+dev = win16
+!endif
+
+!if !("$(dev)" == "win16" || "$(dev)" == "win32" || "$(dev)" == "mac")
+!error Invalid dev option, choose from [win16 | win32 | mac]
+!endif
+
+!if "$(dev)" == "win16"
+TARGET = WIN16
+!endif
+
+!if "$(dev)" == "win32"
+TARGET = WIN32
+!endif
+
+!if "$(dev)" == "mac"
+TARGET = MAC
+!endif
+
+!if "$(DEBUG)" == ""
+DEBUG = 1
+!endif
+
+
+##########################################################################
+#
+# WIN16 Settings
+#
+!if "$(TARGET)" == "WIN16"
+
+CC = cl
+LINK = link
+
+RCFLAGS = -dWIN16
+CFLAGS = -W3 -AM -GA -GEs -DWIN16
+LINKFLAGS = /NOD /NOI /BATCH /ONERROR:NOEXE
+
+LIBS = libw.lib mlibcew.lib
+
+!if "$(DEBUG)" == "1"
+CFLAGS = $(CFLAGS) -Od -Zi -D_DEBUG $(CL)
+LINKFLAGS = $(LINKFLAGS) /COD
+!else
+CFLAGS = $(CFLAGS) -Ox $(CL)
+LINKFLAGS = $(LINKFLAGS) /FAR /PACKC
+!endif
+!endif
+
+
+##########################################################################
+#
+# WIN32 Settings
+#
+!if "$(TARGET)" == "WIN32"
+
+!if "$(CPU)"==""
+
+!if "$(PROCESSOR_ARCHITECTURE)"=="" || "$(PROCESSOR_ARCHITECTURE)"=="x86"
+CPU=i386
+!else
+CPU=$(PROCESSOR_ARCHITECTURE)
+!endif
+
+!endif #CPU
+
+!if "$(CPU)" == "i386"
+CC = cl386
+LINK = link
+CFLAGS = -D_X86_=1
+!endif
+!if "$(CPU)" == "MIPS"
+CC = cl
+LINK = link
+CFLAGS = -D_MIPS_=1 -DUNICODE
+!endif
+!if "$(CPU)" == "ALPHA"
+CC = claxp
+LINK = link
+CFLAGS = -D_ALPHA_=1 -DUNICODE
+!endif
+!if "$(CPU)" == "PPC"
+CC = cl
+LINK = link
+CFLAGS = -D_PPC_=1 -DUNICODE
+!endif
+
+RCFLAGS = -dWIN32
+CFLAGS = $(CFLAGS) -nologo -W3 -DWIN32 -DINC_OLE2 -D_MT $(CL)
+LINKFLAGS = -Incremental:NO -Pdb:NONE -subsystem:windows -entry:WinMainCRTStartup -machine:$(CPU)
+
+LIBS = libc.lib kernel32.lib user32.lib gdi32.lib
+
+
+!if "$(DEBUG)" == "1"
+CFLAGS = $(CFLAGS) -Od -Z7 -D_DEBUG $(CL)
+LINKFLAGS = -debug:full -debugtype:cv,coff $(LINKFLAGS)
+!else
+CFLAGS = $(CFLAGS) -Ox
+!endif
+!endif
+
+
+##########################################################################
+#
+# MAC Settings
+#
+!if "$(TARGET)" == "MAC"
+
+CC = cl
+LINK = link
+
+RCFLAGS = -d_MAC
+
+!if "$(CPU)"=="PPC"
+CFLAGS = -W3 -D_MAC -D_PPCMAC -D_pascal= -D__pascal=
+LINKFLAGS = -machine:mppc -ENTRY:mainCRTStartup -NOPACK -NODEFAULTLIB
+LIBS = interfac.lib libc.lib ole2auto.lib ole2.lib
+!else
+CFLAGS = -W3 -AL -D_MAC
+LINKFLAGS = -machine:$(CPU) -ENTRY:mainCRTStartup -NOPACK -NODEFAULTLIB
+LIBS = interfac.lib llibcs.lib lsanes.lib swap.lib
+!endif
+
+!if "$(DEBUG)" == "1"
+CFLAGS = $(CFLAGS) -Od -Zi -D_DEBUG $(CL)
+LINKFLAGS = $(LINKFLAGS) -debug:full -debugtype:cv
+!else
+CFLAGS = $(CFLAGS) -Ox $(CL)
+!endif
+
+MRC = mrc
+
+!if "$(CPU)"=="PPC"
+MRCOPT = -D_PPCMAC -s$(VBATOOLS)\win32\ppc\lib
+!else
+MRCOPT =
+!endif
+
+MAKEPEF = makepef
+
+!endif
+
+
+##########################################################################
+#
+# Application Settings
+#
+
+SRCDIR = $(OLEPROG)\SAMPLE\spoly2
+
+!if "$(TARGET)" == "MAC" && "$(CPU)"=="PPC"
+OBJDIR=$(SRCDIR)\macppc
+!else
+OBJDIR=$(SRCDIR)\$(TARGET)
+!endif
+
+!if [if not exist $(OBJDIR)\*.* mkdir $(OBJDIR)] != 0
+!endif
+
+!if "$(TARGET)" == "WIN16"
+LIBS = ole2.lib compobj.lib ole2disp.lib $(LIBS)
+!else
+!if "$(TARGET)" == "WIN32"
+LIBS = ole32.lib oleaut32.lib uuid.lib $(LIBS)
+!endif
+!if "$(TARGET)" == "MAC"
+!if "$(CPU)" != "PPC"
+LIBS = olenrf.obj oanrf.obj $(LIBS)
+!endif
+!endif
+!endif
+
+OBJS = \
+!if "$(TARGET)" == "MAC"
+ $(OBJDIR)\macmain.obj \
+!else
+ $(OBJDIR)\winmain.obj \
+!endif
+ $(OBJDIR)\cpoly.obj \
+ $(OBJDIR)\cpoint.obj \
+ $(OBJDIR)\cenumpt.obj \
+!if "$(TARGET)" != "MAC"
+ $(OBJDIR)\statbar.obj \
+!endif
+ $(OBJDIR)\clsid.obj \
+ $(OBJDIR)\misc.obj \
+ $(OBJDIR)\tdata.obj
+
+goal : setflags $(OBJDIR)\spoly2.exe
+
+setflags :
+ set CL=$(CFLAGS)
+
+clean :
+ if exist $(OBJDIR)\*.obj del $(OBJDIR)\*.obj
+ if exist $(OBJDIR)\spoly2.exe del $(OBJDIR)\spoly2.exe
+ if exist $(OBJDIR)\spoly2.map del $(OBJDIR)\spoly2.map
+ if exist $(OBJDIR)\spoly2.res del $(OBJDIR)\spoly2.res
+ if exist $(OBJDIR)\spoly2.rs del $(OBJDIR)\spoly2.rs
+ if exist $(SRCDIR)\*.pdb del $(SRCDIR)\*.pdb
+
+
+##########################################################################
+#
+# Application Build (WIN16 Specific)
+#
+
+!if "$(TARGET)" == "WIN16"
+
+$(OBJDIR)\spoly2.exe : $(OBJS) $(SRCDIR)\spoly2.def $(OBJDIR)\spoly2.res $(SRCDIR)\spoly2.ico
+ link $(LINKFLAGS) @<<
+$(OBJS: =+^
+),
+$@,$(OBJDIR)\spoly2.map/map,
+$(LIBS),
+$(SRCDIR)\spoly2.def
+<<
+ rc -k -t $(OBJDIR)\spoly2.res $@
+!endif
+
+
+##########################################################################
+#
+# Application Build (WIN32 Specific)
+#
+!if "$(TARGET)" == "WIN32"
+
+$(OBJDIR)\spoly2.exe : $(OBJS) $(SRCDIR)\spoly2.def $(OBJDIR)\spoly2.res $(SRCDIR)\spoly2.ico
+ cvtres -r -$(CPU) $(OBJDIR)\spoly2.res -o $(OBJDIR)\spoly2.rs
+ $(LINK) @<<
+ $(LINKFLAGS)
+ -out:$@
+ -map:$*.map
+ $(OBJS)
+ $(OBJDIR)\spoly2.rs
+ $(LIBS)
+<<
+!endif
+
+
+##########################################################################
+#
+# Application Build (MAC Specific)
+#
+!if "$(TARGET)" == "MAC"
+$(OBJDIR)\spoly2.exe : $(OBJS) $(OBJDIR)\spoly2.x
+ $(LINK) @<<
+ $(LINKFLAGS)
+ -out:$@
+ -map:$*.map
+ $(OBJS)
+ $(LIBS)
+<<
+ copy $(OBJDIR)\spoly2.x $(OBJDIR)\spoly2
+!if "$(CPU)" == "PPC"
+ $(MAKEPEF) $(OBJDIR)\spoly2.exe $(OBJDIR)\spoly2.pef
+!else
+ cvpack $(OBJDIR)\spoly2.exe
+ $(MRC) $(MRCOPT) -e $(OBJDIR)\spoly2.exe -a -o $(OBJDIR)\spoly2
+!endif
+
+$(OBJDIR)\spoly2.x: $(SRCDIR)\spoly2.r
+ $(MRC) $(MRCOPT) -D_MAC -o $(OBJDIR)\spoly2.x $(SRCDIR)\spoly2.r
+!endif
+
+##########################################################################
+#
+# Application Build (Common)
+#
+$(OBJDIR)\spoly2.res : $(SRCDIR)\spoly2.rc $(SRCDIR)\resource.h
+ rc $(RCFLAGS) -r -fo$@ $(SRCDIR)\spoly2.rc
+
+
+!if "$(TARGET)" == "MAC"
+$(OBJDIR)\macmain.obj: $(SRCDIR)\macmain.cpp $(SRCDIR)\hostenv.h $(SRCDIR)\resource.h $(SRCDIR)\spoly.h $(SRCDIR)\statbar.h
+ $(CC) -c -Fo$@ $(SRCDIR)\macmain.cpp
+!else
+$(OBJDIR)\winmain.obj: $(SRCDIR)\winmain.cpp $(SRCDIR)\hostenv.h $(SRCDIR)\resource.h $(SRCDIR)\spoly.h $(SRCDIR)\statbar.h
+ $(CC) -c -Fo$@ $(SRCDIR)\winmain.cpp
+!endif
+
+$(OBJDIR)\cpoint.obj: $(SRCDIR)\cpoint.cpp $(SRCDIR)\cpoint.h $(SRCDIR)\hostenv.h $(SRCDIR)\spoly.h $(SRCDIR)\statbar.h
+ $(CC) -c -Fo$@ $(SRCDIR)\cpoint.cpp
+
+$(OBJDIR)\cpoly.obj: $(SRCDIR)\cpoly.cpp $(SRCDIR)\cpoint.h $(SRCDIR)\cpoly.h $(SRCDIR)\hostenv.h $(SRCDIR)\spoly.h $(SRCDIR)\statbar.h
+ $(CC) -c -Fo$@ $(SRCDIR)\cpoly.cpp
+
+$(OBJDIR)\clsid.obj: $(SRCDIR)\clsid.c $(SRCDIR)\clsid.h
+ $(CC) -c -Fo$@ $(SRCDIR)\clsid.c
+
+$(OBJDIR)\cenumpt.obj: $(SRCDIR)\cenumpt.cpp $(SRCDIR)\cenumpt.h
+ $(CC) -c -Fo$@ $(SRCDIR)\cenumpt.cpp
+
+!if "$(TARGET)" != "MAC"
+$(OBJDIR)\statbar.obj: $(SRCDIR)\statbar.cpp $(SRCDIR)\statbar.h
+ $(CC) -c -Fo$@ $(SRCDIR)\statbar.cpp
+!endif
+
+$(OBJDIR)\misc.obj: $(SRCDIR)\misc.cpp $(SRCDIR)\hostenv.h $(SRCDIR)\spoly.h
+ $(CC) -c -Fo$@ $(SRCDIR)\misc.cpp
+
+$(OBJDIR)\tdata.obj: $(SRCDIR)\tdata.cpp
+ $(CC) -c -Fo$@ $(SRCDIR)\tdata.cpp
diff --git a/private/oleauto/sample/spoly2/misc.cpp b/private/oleauto/sample/spoly2/misc.cpp
new file mode 100644
index 000000000..3b7c0ff69
--- /dev/null
+++ b/private/oleauto/sample/spoly2/misc.cpp
@@ -0,0 +1,215 @@
+/***
+*misc.cpp
+*
+* Copyright (C) 1992-1994, Microsoft Corporation. All Rights Reserved.
+*
+*Purpose:
+*
+*Implementation Notes:
+*
+*****************************************************************************/
+
+
+#include "spoly.h"
+#include "cpoint.h"
+#include "cpoly.h"
+
+#include <stdio.h>
+
+#ifdef _MAC
+# include <string.h>
+# include <ctype.h>
+#endif
+
+unsigned long g_dwPolyCF = 0;
+unsigned long g_dwPointCF = 0;
+
+IClassFactory FAR* g_ppolyCF = NULL;
+IClassFactory FAR* g_ppointCF = NULL;
+
+
+#ifdef _MAC
+struct regentry{
+ char *szKey;
+ char *szValue;
+} g_rgregentry[] = {
+
+ { "CLSID\\{00020464-0000-0000-C000-000000000046}",
+ "OLE Automation SPoly2 1.0 Application" }
+
+ , { "CLSID\\{00020464-0000-0000-C000-000000000046}\\LocalServer",
+ "SPL2" }
+
+ , { "CLSID\\{00020464-0000-0000-C000-000000000046}\\ProgID",
+ "SPoly2.Application" }
+
+ , { "CLSID\\{00020464-0000-0000-C000-000000000046}\\InprocHandler",
+ "OLE2:Def$DefFSet" }
+
+ , { "SPL2", "{00020464-0000-0000-C000-000000000046}" }
+
+ , { "SPoly2.Application\\CLSID",
+ "{00020464-0000-0000-C000-000000000046}" }
+
+};
+
+HRESULT
+EnsureRegistration()
+{
+ HKEY hkey;
+
+ if(RegOpenKey(HKEY_CLASSES_ROOT, "SPL2", &hkey) == NOERROR){
+ RegCloseKey(hkey);
+ return NOERROR;
+ }
+
+ for(int i = 0; i < DIM(g_rgregentry); ++i){
+ if(RegSetValue(HKEY_CLASSES_ROOT, g_rgregentry[i].szKey, REG_SZ, g_rgregentry[i].szValue, 0) != ERROR_SUCCESS)
+ return ResultFromScode(E_FAIL);
+ }
+
+ return NOERROR;
+}
+#endif
+
+/***
+*HRESULT InitOle(void)
+*Purpose:
+* Initialize Ole, and register our class factories.
+*
+*Entry:
+* None
+*
+*Exit:
+* None
+*
+***********************************************************************/
+STDAPI
+InitOle()
+{
+ HRESULT hresult;
+
+ if((hresult = OleInitialize(NULL)) != NOERROR)
+ goto LError0;
+
+#ifdef _MAC
+ if((hresult = EnsureRegistration()) != NOERROR)
+ goto LError0;
+#endif
+
+ // Register the CPoint Class Factory
+ //
+ if((g_ppointCF = CPointCF::Create()) == NULL){
+ hresult = ResultFromScode(E_OUTOFMEMORY);
+ goto LError1;
+ }
+
+ hresult = CoRegisterClassObject(
+ CLSID_CPoint2,
+ g_ppointCF,
+ CLSCTX_LOCAL_SERVER,
+ REGCLS_MULTIPLEUSE,
+ &g_dwPointCF);
+ if(hresult != NOERROR)
+ goto LError1;
+
+ // Register the CPoly Class Factory.
+ //
+ if((g_ppolyCF = CPolyCF::Create()) == NULL){
+ hresult = ResultFromScode(E_OUTOFMEMORY);
+ goto LError1;
+ }
+
+ hresult = CoRegisterClassObject(
+ CLSID_CPoly2,
+ g_ppolyCF,
+ CLSCTX_LOCAL_SERVER,
+ REGCLS_MULTIPLEUSE,
+ &g_dwPolyCF);
+ if(hresult != NOERROR)
+ goto LError1;
+
+ g_ppolyCF->Release();
+
+ g_ppointCF->Release();
+
+ return NOERROR;
+
+
+LError1:;
+ if(g_ppolyCF != NULL)
+ g_ppolyCF->Release();
+
+ if(g_ppointCF != NULL)
+ g_ppointCF->Release();
+
+ UninitOle();
+
+LError0:;
+ return hresult;
+}
+
+STDAPI
+UninitOle()
+{
+ // Tell Ole to release our class factories.
+ //
+ if(g_dwPointCF != 0L)
+ CoRevokeClassObject(g_dwPointCF);
+
+ if(g_dwPolyCF != 0L)
+ CoRevokeClassObject(g_dwPolyCF);
+
+ OleUninitialize();
+
+ return NOERROR;
+}
+
+// disable unicode expansion for assertions
+#undef UNICODE
+
+void
+Assert(int fCond, char FAR* file, int line, char FAR* message)
+{
+ char * fmt;
+ char buf[128];
+
+ if(fCond)
+ return;
+
+ fmt = (message == NULL)
+ ? "Assertion failed: %s(%d)"
+ : "Assertion failed: %s(%d) '%s'";
+ sprintf(buf, fmt, file, line, message);
+
+#ifdef _MAC
+ DebugStr(c2pstr(buf));
+#else
+#ifdef WIN32
+ OutputDebugStringA(buf);
+#else //WIN32
+ OutputDebugString(buf);
+#endif //WIN32
+ DebugBreak();
+#endif
+}
+
+#ifdef _MAC
+#if defined(_MSC_VER)
+int pascal
+#else
+pascal int
+#endif
+stricmp(char *first, char *last)
+{
+ unsigned short f, l;
+
+ do{
+ f = tolower(*first++);
+ l = tolower(*last++);
+ }while(f && f == l);
+
+ return f - l;
+}
+#endif
+
diff --git a/private/oleauto/sample/spoly2/mk.bat b/private/oleauto/sample/spoly2/mk.bat
new file mode 100644
index 000000000..091192cd7
--- /dev/null
+++ b/private/oleauto/sample/spoly2/mk.bat
@@ -0,0 +1,19 @@
+REM setup the environment for the spoly2 makefile
+
+set OLDLIB=%LIB%
+set OLDPATH=%PATH%
+set OLDINC=%INCLUDE%
+
+set PATH=%TOOLS%\HDOS\BIN;%TOOLS%\HDOS\C800\BIN
+set LIB=%TOOLS%\HDOS\C800\LIB;%OLEPROG%\build\dispatch\DWIN16;%OLEPROG%\build\ole2nls\dwin16;%OLEPROG%\OLE\WIN16\D
+set INCLUDE=%TOOLS%\HDOS\C800\INCLUDE;%OLEPROG%\OLE\WIN16;%OLEPROG%\SRC\DISPATCH
+
+nmake %1 %2 %3 %4 %5
+
+set LIB=%OLDLIB%
+set PATH=%OLDPATH%
+set INCLUDE=%OLDINC%
+
+set OLDPATH=
+set OLDINC=
+set OLDLIB=
diff --git a/private/oleauto/sample/spoly2/mk.cmd b/private/oleauto/sample/spoly2/mk.cmd
new file mode 100644
index 000000000..cd22f7fed
--- /dev/null
+++ b/private/oleauto/sample/spoly2/mk.cmd
@@ -0,0 +1,13 @@
+REM The spoly2.exe makefile assumes that PATH, LIB, and include are setup.
+
+@setlocal
+
+REM we get rc.exe and winstub.exe from \tools\win
+
+set PATH=%TOOLS%\HOS2\BIN;%TOOLS%\HOS2\C700\BIN
+set INCLUDE=%TOOLS%\HOS2\C700\INCLUDE;%OLEPROG%\ole\dwin16;%OLEPROG%\src\dispatch
+set LIB=%TOOLS%\HOS2\C700\LIB;%OLEPROG%\ole\dwin16;%OLEPROG%\build\dwin16
+
+nmake %1 %2 %3 %4 %5
+
+@endlocal
diff --git a/private/oleauto/sample/spoly2/readme.txt b/private/oleauto/sample/spoly2/readme.txt
new file mode 100644
index 000000000..cf29f66e5
--- /dev/null
+++ b/private/oleauto/sample/spoly2/readme.txt
@@ -0,0 +1,62 @@
+-------------------------------------
+OLE Automation Sample Program: SPoly2
+-------------------------------------
+
+SPoly2 is a program which draws polygons. The only way to
+make spoly2 draw a polygon is to use its programmability
+interface.
+
+One OLE Automation object is exposed by spoly2:
+ * spoly2.application
+
+Spoly2.Application is the object associated with spoly2's main
+window. It controls drawing polygons and clearing the display.
+
+
+-----------------
+Program Structure
+-----------------
+SPoly2 implements IDispatch by using INTERFACEDATA, DispGetIDsOfNames
+and DispInvoke.
+
+
+
+------------------------------------
+Methods defined on spoly2.application
+------------------------------------
+
+
+Name Description
+------------------------------------------------------------------
+Draw() Draw the polygon.
+
+Reset() Delete all points from the polygon.
+
+AddPoint(X, Y) Add a point with coordinates (x,y)
+ to the polygon
+
+EnumPoints() as VT_ENUM Return a collection of the polygon's
+ points
+
+GetXOrigin() as short Get the X origin of the polygon.
+
+SetXOrigin(x as short) Set the X origin of the polygon.
+
+GetYOrigin() as short Get the Y origin of the polygon.
+
+SetYOrigin(y as short) Set the Y origin of the polygon.
+
+GetWidth() as short Get and the line width of the polygon.
+
+SetWidth(width as short) Set the line width of the polygon.
+
+
+
+---------------------------
+Shortcomings of this sample
+---------------------------
+1. Many items in this sample should be properties. Instead,
+they are implemented as methods. Anything which behaves like
+an attribute of the object should be a property.
+
+2. This is not a good example of how to implement a collection. \ No newline at end of file
diff --git a/private/oleauto/sample/spoly2/resource.h b/private/oleauto/sample/spoly2/resource.h
new file mode 100644
index 000000000..ebc4b78d1
--- /dev/null
+++ b/private/oleauto/sample/spoly2/resource.h
@@ -0,0 +1,50 @@
+/***
+*resource.h
+*
+* Copyright (C) 1992-1994, Microsoft Corporation. All Rights Reserved.
+*
+*Purpose:
+*
+*Implementation Notes:
+*
+*****************************************************************************/
+
+#ifdef _MAC
+
+#define kMinSize 500 /* minimum size (in K) */
+#define kPrefSize 500 /* preferred size (in K) */
+
+#define rMenuBar 128 /* menu bar */
+#define rAboutAlert 128 /* about alert */
+#define rUserAlert 129 /* error alert */
+#define rWindow 128 /* application's window */
+
+#define mApple 128 /* Apple menu */
+#define iAbout 1
+
+#define mFile 129 /* File menu */
+#define iNew 1
+#define iClose 4
+#define iQuit 12
+
+#define mEdit 130 /* Edit menu */
+#define iUndo 1
+#define iCut 3
+#define iCopy 4
+#define iPaste 5
+#define iClear 6
+
+#define mSpoly 131
+#define iTest 1
+
+#define kMinHeap 21 * 1024
+#define kMinSpace 8 * 1024
+
+#else /* WIN16 || WIN32 */
+
+# define IDM_CLEAR 1
+# define IDM_DUMP 2
+# define IDM_FIRSTCHILD 100
+
+#endif
+
diff --git a/private/oleauto/sample/spoly2/spoly.h b/private/oleauto/sample/spoly2/spoly.h
new file mode 100644
index 000000000..c1c60567a
--- /dev/null
+++ b/private/oleauto/sample/spoly2/spoly.h
@@ -0,0 +1,71 @@
+/***
+*spoly.h - Application-wide definitions
+*
+* Copyright (C) 1992-1994, Microsoft Corporation. All Rights Reserved.
+*
+*Purpose:
+*
+*Implementation Notes:
+*
+*****************************************************************************/
+
+#include "hostenv.h"
+#include "resource.h"
+#include "clsid.h"
+
+#if defined(_MAC)
+# define STRSTR strstr
+#elif defined(WIN32)
+# include "statbar.h"
+# define STRSTR strstr
+#else /* WIN16 */
+# include "statbar.h"
+# define STRSTR _fstrstr
+#endif
+
+#ifdef _MAC
+# define UNUSED(X) ((void)(void*)&(X))
+#else
+# define UNUSED(X) (X)
+#endif
+
+#define DIM(X) (sizeof(X) / sizeof(X[0]))
+
+extern "C" void Assert(int, char FAR*, int, char FAR*);
+#define ASSERT(X) Assert(X, __FILE__, __LINE__, NULL)
+#define ASSERTSZ(X, MSG) Assert(X, __FILE__, __LINE__, MSG)
+
+#ifndef EXPORT
+# if defined(WIN32)
+# define EXPORT
+# elif defined(_MAC)
+# define EXPORT
+# else
+# define EXPORT __export
+# endif
+#endif
+
+#ifndef NEAR
+# if defined(WIN32)
+# define NEAR
+# elif defined(_MAC)
+# define NEAR
+# else
+# define NEAR __near
+# endif
+#endif
+
+#if defined(WIN32)
+# define CC_CALL CC_STDCALL
+# define METHODCALLTYPE __stdcall
+#elif defined(_MAC)
+# define CC_CALL CC_CDECL
+# define METHODCALLTYPE
+#else
+# define CC_CALL CC_PASCAL
+# define METHODCALLTYPE __pascal
+#endif
+
+STDAPI InitOle();
+STDAPI UninitOle();
+
diff --git a/private/oleauto/sample/spoly2/spoly2.def b/private/oleauto/sample/spoly2/spoly2.def
new file mode 100644
index 000000000..d34c3efdf
--- /dev/null
+++ b/private/oleauto/sample/spoly2/spoly2.def
@@ -0,0 +1,14 @@
+
+NAME SPOLY2
+
+DESCRIPTION 'IDispatch Polygon Test Server #2'
+
+EXETYPE WINDOWS
+
+STUB 'WINSTUB.EXE'
+
+CODE PRELOAD MOVEABLE DISCARDABLE
+DATA PRELOAD MULTIPLE
+
+HEAPSIZE 4096
+STACKSIZE 8192
diff --git a/private/oleauto/sample/spoly2/spoly2.ico b/private/oleauto/sample/spoly2/spoly2.ico
new file mode 100644
index 000000000..27307a078
--- /dev/null
+++ b/private/oleauto/sample/spoly2/spoly2.ico
Binary files differ
diff --git a/private/oleauto/sample/spoly2/spoly2.r b/private/oleauto/sample/spoly2/spoly2.r
new file mode 100644
index 000000000..da787724d
--- /dev/null
+++ b/private/oleauto/sample/spoly2/spoly2.r
@@ -0,0 +1,298 @@
+/***
+*spoly2.r
+*
+* Copyright (C) 1992-1994, Microsoft Corporation. All Rights Reserved.
+*
+*Purpose:
+* Resource script for spoly2.
+*
+*
+*Implementation Notes:
+*
+*****************************************************************************/
+
+#ifdef _PPCMAC
+include "cfrg.rsc";
+#endif
+
+#include "types.r"
+#include "resource.h"
+
+/* we use an MBAR resource to conveniently load all the menus */
+
+resource 'MBAR' (rMenuBar, preload) {
+ {
+ mApple,
+ mFile,
+ mEdit,
+ mSpoly
+ }
+};
+
+
+resource 'MENU' (mApple, preload) {
+ mApple,
+ textMenuProc,
+ 0b11111111111111111111111111111101,
+ enabled,
+ apple,
+ {
+ "About Spoly2\311",
+ noicon, nokey, nomark, plain;
+ "-",
+ noicon, nokey, nomark, plain
+ }
+};
+
+resource 'MENU' (mFile, preload) {
+ mFile,
+ textMenuProc,
+ 0b00000000000000000000100000000000,
+ enabled,
+ "File",
+ {
+ "New",
+ noicon, "N", nomark, plain;
+ "Open",
+ noicon, "O", nomark, plain;
+ "-",
+ noicon, nokey, nomark, plain;
+ "Close",
+ noicon, "W", nomark, plain;
+ "Save",
+ noicon, "S", nomark, plain;
+ "Save As\311",
+ noicon, nokey, nomark, plain;
+ "Revert",
+ noicon, nokey, nomark, plain;
+ "-",
+ noicon, nokey, nomark, plain;
+ "Page Setup\311",
+ noicon, nokey, nomark, plain;
+ "Print\311",
+ noicon, nokey, nomark, plain;
+ "-",
+ noicon, nokey, nomark, plain;
+ "Quit",
+ noicon, "Q", nomark, plain
+ }
+};
+
+resource 'MENU' (mEdit, preload) {
+ mEdit,
+ textMenuProc,
+ 0b00000000000000000000000000000000,
+ enabled,
+ "Edit",
+ {
+ "Undo",
+ noicon, "Z", nomark, plain;
+ "-",
+ noicon, nokey, nomark, plain;
+ "Cut",
+ noicon, "X", nomark, plain;
+ "Copy",
+ noicon, "C", nomark, plain;
+ "Paste",
+ noicon, "V", nomark, plain;
+ "Clear",
+ noicon, nokey, nomark, plain
+ }
+};
+
+resource 'MENU' (mSpoly, preload) {
+ mSpoly,
+ textMenuProc,
+ 0b00000000000000000000000000000001,
+ enabled,
+ "Spoly",
+ {
+ "Test", noicon, nokey, nomark, plain
+ }
+};
+
+/* this ALRT and DITL are used as an About screen */
+
+resource 'ALRT' (rAboutAlert, purgeable) {
+ {40, 20, 160, 290},
+ rAboutAlert,
+ {
+ /* [1] */
+ OK, visible, silent,
+ /* [2] */
+ OK, visible, silent,
+ /* [3] */
+ OK, visible, silent,
+ /* [4] */
+ OK, visible, silent
+ }
+};
+
+resource 'DITL' (rAboutAlert, purgeable) {
+ { /* array DITLarray: 5 elements */
+ /* [1] */
+ {88, 180, 108, 260},
+ Button {
+ enabled,
+ "OK"
+ },
+ /* [2] */
+ {8, 8, 24, 214},
+ StaticText {
+ disabled,
+ "IDispatch Polygon Server"
+ }
+ }
+};
+
+
+/* this ALRT and DITL are used as an error screen */
+
+resource 'ALRT' (rUserAlert, purgeable) {
+ {40, 20, 120, 260},
+ rUserAlert,
+ { /* array: 4 elements */
+ /* [1] */
+ OK, visible, silent,
+ /* [2] */
+ OK, visible, silent,
+ /* [3] */
+ OK, visible, silent,
+ /* [4] */
+ OK, visible, silent
+ }
+};
+
+
+resource 'DITL' (rUserAlert, purgeable) {
+ {
+ /* [1] */
+ {50, 150, 70, 230},
+ Button {
+ enabled,
+ "OK"
+ },
+ /* [2] */
+ {10, 60, 30, 230},
+ StaticText {
+ disabled,
+ "Error. ^0"
+ },
+ /* [3] */
+ {8, 8, 40, 40},
+ Icon {
+ disabled,
+ 2
+ }
+ }
+};
+
+
+resource 'WIND' (rWindow, preload, purgeable) {
+ {60, 40, 380, 500},
+ documentProc, visible, goAway, 0x0, "Spoly2"
+};
+
+
+resource 'SIZE' (-1) {
+ dontSaveScreen,
+ acceptSuspendResumeEvents,
+ enableOptionSwitch,
+ canBackground,
+ multiFinderAware,
+ backgroundAndForeground,
+ dontGetFrontClicks,
+ ignoreChildDiedEvents,
+ is32BitCompatible,
+ isHighLevelEventAware,
+ localAndRemoteHLEvents,
+ reserved,
+ reserved,
+ reserved,
+ reserved,
+ reserved,
+ kPrefSize * 1024,
+ kMinSize * 1024
+};
+
+resource 'BNDL' (134) {
+ 'SPL2',
+ 0,
+ { /* array TypeArray: 2 elements */
+ /* [1] */
+ 'FREF',
+ { /* array IDArray: 1 elements */
+ /* [1] */
+ 0, 134
+ },
+ /* [2] */
+ 'ICN#',
+ { /* array IDArray: 1 elements */
+ /* [1] */
+ 0, 134
+ }
+ }
+};
+
+data 'FREF' (134) {
+ $"4150 504C 0000 4E" /* APPL..N */
+};
+
+data 'ICN#' (134) {
+ $"000F FE00 001F FE00 0030 0600 0060 0600" /* ..þ...þ..0...`.. */
+ $"0060 0600 0060 0600 0060 7FF0 007F FFF0" /* .`...`...`.ð..ÿð */
+ $"007F FE30 0003 0030 0003 0030 0003 07FF" /* ..þ0...0...0...ÿ */
+ $"0003 0FFF 0003 FFF3 0003 FFF3 0000 3003" /* ...ÿ..ÿó..ÿó..0. */
+ $"0000 3003 0004 3003 0018 3FFF 0078 3FFF" /* ..0...0...?ÿ.x?ÿ */
+ $"01F0 0000 00F0 01E0 0060 0330 0120 0638" /* .ð...ð.à.`.0. .8 */
+ $"0600 0038 1E00 0070 7C00 00E0 3C00 03C0" /* ...8...p|..à<..À */
+ $"1800 0700 0800 07F8 0000 0000 0000 0000" /* .......ø........ */
+ $"000F FE00 001F FE00 003F FE00 007F FE00" /* ..þ...þ..?þ...þ. */
+ $"007F FE00 007F FE00 007F FFF0 007F FFF0" /* ..þ...þ...ÿð..ÿð */
+ $"007F FFF0 0003 FFF0 0003 FFF0 0003 FFFF" /* ..ÿð..ÿð..ÿð..ÿÿ */
+ $"0003 FFFF 0003 FFFF 0003 FFFF 0000 3FFF" /* ..ÿÿ..ÿÿ..ÿÿ..?ÿ */
+ $"0000 3FFF 0004 3FFF 0018 3FFF 0078 3FFF" /* ..?ÿ..?ÿ..?ÿ.x?ÿ */
+ $"01F0 0000 00F0 01E0 0060 0330 0120 0638" /* .ð...ð.à.`.0. .8 */
+ $"0600 0038 1E00 0070 7C00 00E0 3C00 03C0" /* ...8...p|..à<..À */
+ $"1800 0700 0800 07F8 0000 0000 0000 0000" /* .......ø........ */
+};
+
+data 'icl4' (133) {
+ $"0000 0000 0000 0000 0000 0000 0000 0000" /* ................ */
+ $"0000 0000 0000 0666 6666 6666 0000 0000" /* .......fffff.... */
+ $"0000 0000 0000 6666 6666 6666 0000 0000" /* ......ffffff.... */
+ $"0000 0000 0006 6000 0000 0066 0000 0000" /* ......`....f.... */
+ $"0000 0000 0066 0000 0000 0066 0000 0000" /* .....f.....f.... */
+ $"0000 0000 0066 0000 0000 0066 0000 0000" /* .....f.....f.... */
+ $"0000 0000 0066 0000 0000 0066 0000 0000" /* .....f.....f.... */
+ $"0000 0000 0066 0000 0033 3333 3333 3000" /* .....f...333330. */
+ $"0000 0000 0066 6666 6333 3333 3333 3000" /* .....fffc333330. */
+ $"0000 0000 0066 6666 3366 6666 0003 3000" /* .....fff3fff..0. */
+ $"0000 0000 0000 0003 3000 0000 0003 3000" /* ........0.....0. */
+ $"0000 0000 0000 0003 3000 0000 0003 3000" /* ........0.....0. */
+ $"0000 0000 0000 0003 3000 0066 6666 6666" /* ........0..fffff */
+ $"0000 0000 0000 0003 3000 0666 6666 6666" /* ........0..fffff */
+ $"0000 0000 0000 0003 3333 6633 3333 3006" /* ........33f3330. */
+ $"0000 0000 0000 0003 3336 6333 3333 3006" /* ........36c3330. */
+ $"0000 0000 0000 0000 0006 6000 0000 0006" /* ..........`..... */
+ $"0000 0000 0000 0000 0006 6000 0000 0006" /* ..........`..... */
+ $"0000 0000 0000 0030 0006 6000 0000 0006" /* .......0..`..... */
+ $"0000 0000 0000 3300 0006 6666 6666 6666" /* ......3...ffffff */
+ $"0000 0000 0033 F300 0006 6666 6666 6666" /* .....3ó...ffffff */
+ $"0000 0000 333F 3000 0000 0000 0000 0000" /* ....3?0......... */
+ $"0000 0000 03F3 3000 0000 0000 0000 0000" /* .....ó0......... */
+ $"0000 0000 0033 0000 0000 0000 0000 0000" /* .....3.......... */
+ $"0000 0000 3003 0000 0000 0000 0000 0000" /* ....0........... */
+ $"0000 0033 0000 0000 0000 0000 0000 0000" /* ...3............ */
+ $"0000 33F3 0000 0000 0000 0000 0000 0000" /* ..3ó............ */
+ $"0033 3F30 0000 0000 0000 0000 0000 0000" /* .3?0............ */
+ $"0003 F330 0000 0000 0000 0000 0000 0000" /* ..ó0............ */
+ $"0000 3300 0000 0000 0000 0000 0000 0000" /* ..3............. */
+ $"0000 0300 0000 0000 0000 0000 0000 0000" /* ................ */
+ $"0000 0000 0000 0000 0000 0000 0000 0000" /* ................ */
+};
+
+data 'SPL2' (0, "Owner resource") {
+ $"00" /* . */
+};
+
diff --git a/private/oleauto/sample/spoly2/spoly2.r32 b/private/oleauto/sample/spoly2/spoly2.r32
new file mode 100644
index 000000000..9f7e78a54
--- /dev/null
+++ b/private/oleauto/sample/spoly2/spoly2.r32
@@ -0,0 +1,26 @@
+REGEDIT
+
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+; registration info SPoly2.Application (defaults to SPoly2.Application.1)
+
+HKEY_CLASSES_ROOT\SPoly2.Application = OLE Automation SPoly2 Application
+HKEY_CLASSES_ROOT\spoly2.Application\Clsid = {00020464-0000-0000-C000-000000000046}
+
+
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;; registration info SPoly2 1.0
+
+; (Application Object)
+HKEY_CLASSES_ROOT\SPoly2.Application.1 = OLE Automation SPoly2 1.0 Application
+HKEY_CLASSES_ROOT\SPoly2.Application.1\Clsid = {00020464-0000-0000-C000-000000000046}
+
+HKEY_CLASSES_ROOT\CLSID\{00020464-0000-0000-C000-000000000046} = OLE Automation Spoly2 1.0 Application
+HKEY_CLASSES_ROOT\CLSID\{00020464-0000-0000-C000-000000000046}\ProgID = SPoly2.Application
+HKEY_CLASSES_ROOT\CLSID\{00020464-0000-0000-C000-000000000046}\VersionIndependentProgID = SPoly2.Application
+HKEY_CLASSES_ROOT\CLSID\{00020464-0000-0000-C000-000000000046}\LocalServer32 = spoly2.exe /Automation
+
+
+HKEY_CLASSES_ROOT\CLSID\{00020465-0000-0000-C000-000000000046} = SPoly2.SPoint2
+HKEY_CLASSES_ROOT\CLSID\{00020465-0000-0000-C000-000000000046}\ProgID = SPoly2.Application.1
+HKEY_CLASSES_ROOT\CLSID\{00020465-0000-0000-C000-000000000046}\VersionIndependentProgID = SPoly.Application
+HKEY_CLASSES_ROOT\CLSID\{00020465-0000-0000-C000-000000000046}\LocalServer32 = spoly2.exe /Automation
diff --git a/private/oleauto/sample/spoly2/spoly2.rc b/private/oleauto/sample/spoly2/spoly2.rc
new file mode 100644
index 000000000..98e9daca8
--- /dev/null
+++ b/private/oleauto/sample/spoly2/spoly2.rc
@@ -0,0 +1,15 @@
+#define NOKERNEL
+#define NOGDI
+#define NOSOUND
+#define NOCOMM
+#define NODRIVERS
+#include "windows.h"
+#include "spoly.h"
+
+SPOLY ICON spoly2.ico
+
+SPolyMenu MENU
+BEGIN
+ MENUITEM "&Clear" IDM_CLEAR
+ MENUITEM "&Dump" IDM_DUMP
+END
diff --git a/private/oleauto/sample/spoly2/spoly2.reg b/private/oleauto/sample/spoly2/spoly2.reg
new file mode 100644
index 000000000..fdc7f79a8
--- /dev/null
+++ b/private/oleauto/sample/spoly2/spoly2.reg
@@ -0,0 +1,20 @@
+REGEDIT
+
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+; registration info SPoly2.Application (defaults to SPoly2.Application.1)
+
+HKEY_CLASSES_ROOT\SPoly2.Application = OLE Automation SPoly2 Application
+HKEY_CLASSES_ROOT\spoly2.Application\Clsid = {00020464-0000-0000-C000-000000000046}
+
+
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;; registration info SPoly2 1.0
+
+; (Application Object)
+HKEY_CLASSES_ROOT\SPoly2.Application.1 = OLE Automation SPoly2 1.0 Application
+HKEY_CLASSES_ROOT\SPoly2.Application.1\Clsid = {00020464-0000-0000-C000-000000000046}
+
+HKEY_CLASSES_ROOT\CLSID\{00020464-0000-0000-C000-000000000046} = OLE Automation Spoly2 1.0 Application
+HKEY_CLASSES_ROOT\CLSID\{00020464-0000-0000-C000-000000000046}\ProgID = SPoly2.Application
+HKEY_CLASSES_ROOT\CLSID\{00020464-0000-0000-C000-000000000046}\VersionIndependentProgID = SPoly2.Application
+HKEY_CLASSES_ROOT\CLSID\{00020464-0000-0000-C000-000000000046}\LocalServer = spoly2.exe /Automation
diff --git a/private/oleauto/sample/spoly2/statbar.cpp b/private/oleauto/sample/spoly2/statbar.cpp
new file mode 100644
index 000000000..01feae48c
--- /dev/null
+++ b/private/oleauto/sample/spoly2/statbar.cpp
@@ -0,0 +1,368 @@
+/***
+*statbar.cpp
+*
+* Copyright (C) 1992-1994, Microsoft Corporation. All Rights Reserved.
+* Information Contained Herein Is Proprietary and Confidential.
+*
+*Purpose:
+*
+*Implementation Notes:
+*
+*****************************************************************************/
+
+#include <stdarg.h>
+
+#include "hostenv.h"
+#include "statbar.h"
+
+
+extern "C" long FAR PASCAL StatBarWndProc(HWND, unsigned int, WPARAM, LPARAM);
+
+
+TCHAR FAR* CStatBar::m_szWndClass = TSTR("StatBarWndClass");
+
+
+CStatBar::CStatBar()
+{
+ m_refs = 0;
+
+ m_x = 0;
+ m_y = 0;
+ m_width = 0;
+ m_height = 0;
+
+ m_bstrMsg = NULL;
+
+ m_hfont = (HFONT)0;
+}
+
+CStatBar::~CStatBar()
+{
+ SysFreeString(m_bstrMsg);
+}
+
+
+/***
+*PUBLIC CStatBar FAR* CStatBar::Create(HINSTANCE, HWND)
+*
+*Purpose:
+*
+*Entry:
+*
+*Exit:
+*
+***********************************************************************/
+CStatBar FAR*
+CStatBar::Create(HINSTANCE hinst, HWND hwndFrame)
+{
+ CStatBar FAR* psb;
+
+ psb = new FAR CStatBar();
+ if(psb == NULL)
+ return NULL;
+ psb->AddRef();
+
+ if(!psb->Register(hinst))
+ goto LFail;
+
+ psb->m_hwnd = CreateWindow(
+ CStatBar::m_szWndClass,
+ NULL,
+ WS_CHILD | WS_CLIPSIBLINGS,
+ 0, 0, 0, 0,
+ hwndFrame,
+ 0,
+ hinst,
+ NULL);
+
+ if(!psb->m_hwnd)
+ goto LFail;
+
+ // Stash the newly created CStatBar* in the extra bytes of the
+ // associated window so we can get at the instance in the message
+ // proc.
+ //
+ // Note: we do not AddRef for this reference. We make sure that the
+ // window is destroyed when the refcnt goes to 0.
+ //
+ SetWindowLong(psb->m_hwnd, 0, (long)psb);
+
+ return psb;
+
+LFail:;
+ delete psb;
+ return NULL;
+}
+
+
+//---------------------------------------------------------------------
+// IUnknown Methods
+//---------------------------------------------------------------------
+
+
+STDMETHODIMP
+CStatBar::QueryInterface(REFIID riid, void FAR* FAR* ppv)
+{
+ if(IsEqualIID(riid,IID_IUnknown)){
+ *ppv = this;
+ AddRef();
+ return NOERROR;
+ }
+ *ppv = (void FAR*)NULL;
+ return ResultFromScode(E_NOINTERFACE);
+}
+
+
+STDMETHODIMP_(unsigned long)
+CStatBar::AddRef(void)
+{
+ return ++m_refs;
+}
+
+
+STDMETHODIMP_(unsigned long)
+CStatBar::Release(void)
+{
+ if(--m_refs == 0){
+
+ // destroy the status bar window.
+ //
+ SendMessage(m_hwnd, WM_DESTROY, 0, 0L);
+
+ delete this;
+ return 0;
+ }
+
+ return m_refs;
+}
+
+
+//---------------------------------------------------------------------
+// Introduced Methods
+//---------------------------------------------------------------------
+
+
+/***
+*PRIVATE BOOL CStatBar::Register(HINSTANCE)
+*
+*Purpose:
+* Register the status bar window class.
+*
+*Entry:
+* None
+*
+*Exit:
+* return value = BOOL, TRUE if successful, FALSE if not.
+*
+***********************************************************************/
+BOOL
+CStatBar::Register(HINSTANCE hinst)
+{
+ WNDCLASS wc;
+
+ // register the class, unless already registered.
+ if(GetClassInfo(hinst, m_szWndClass, &wc) == 0){
+ wc.style = 0;
+ wc.lpfnWndProc = StatBarWndProc;
+ wc.cbClsExtra = 0;
+ wc.cbWndExtra = sizeof(CStatBar FAR*);
+ wc.hInstance = hinst;
+ wc.hIcon = 0;
+ wc.hCursor = LoadCursor(NULL, IDC_ARROW);
+ wc.hbrBackground = (HBRUSH)GetStockObject(LTGRAY_BRUSH);
+ wc.lpszMenuName = 0;
+ wc.lpszClassName = CStatBar::m_szWndClass;
+ if(!RegisterClass(&wc))
+ return FALSE;
+ }
+ return TRUE;
+}
+
+
+/***
+*PUBLIC void CStatBar::Show(void)
+*
+*Purpose:
+* Show the status bar window associated with this CStatBar instance.
+*
+*Entry:
+* None
+*
+*Exit:
+* None
+*
+***********************************************************************/
+void
+CStatBar::Show()
+{
+ ShowWindow(m_hwnd, SW_SHOW);
+}
+
+void
+CStatBar::SetFont(HFONT hfont)
+{
+ HDC hdc;
+ TEXTMETRIC tm;
+ HFONT hfontOld;
+
+ // compute the character sizes given this new font.
+ //
+ hdc = GetDC(m_hwnd);
+ hfontOld = (HFONT)SelectObject(hdc, hfont);
+ GetTextMetrics(hdc, &tm);
+ m_dxFont = tm.tmAveCharWidth;
+ m_dyFont = tm.tmHeight + tm.tmExternalLeading;
+ SelectObject(hdc, hfontOld);
+ ReleaseDC(m_hwnd, hdc);
+
+ m_hfont = hfont;
+}
+
+/***
+*PRIVATE CStatBar::WMPaint(void)
+*
+*Purpose:
+* This method is responsible for drawing the status bar, and is called
+* in response to a WM_PAINT message.
+*
+*Entry:
+* None
+*
+*Exit:
+* None
+*
+***********************************************************************/
+void
+CStatBar::WMPaint()
+{
+ HDC hdc;
+ RECT rcMsg;
+ HRGN hrgn;
+ HFONT hfontOld;
+ PAINTSTRUCT ps;
+ HPEN hpenBlack, hpenWhite, hpenGray, hpenOld;
+
+ hdc = BeginPaint(m_hwnd, &ps);
+
+ // compute the message box rect
+ //
+ rcMsg.top = 3;
+ rcMsg.bottom= m_height - 3;
+ rcMsg.left = m_dxFont;
+ rcMsg.right = m_width - m_dxFont;
+
+ // prepare the pens
+ //
+ hpenWhite = (HPEN)GetStockObject(WHITE_PEN);
+ hpenBlack = (HPEN)GetStockObject(BLACK_PEN);
+ hpenGray = CreatePen(PS_SOLID, 1, GetSysColor(COLOR_BTNSHADOW));
+
+ // draw a top gray line
+ //
+ hpenOld = (HPEN)SelectObject(hdc, hpenGray);
+#if defined(WIN16)
+ MoveTo(hdc, ps.rcPaint.left, 0);
+#elif defined(WIN32)
+ MoveToEx(hdc, ps.rcPaint.left, 0, NULL);
+#endif
+ LineTo(hdc, ps.rcPaint.right, 0);
+
+ // draw a white line just under
+ //
+ SelectObject(hdc, hpenWhite);
+#if defined(WIN16)
+ MoveTo(hdc, ps.rcPaint.left, 1);
+#elif defined(WIN32)
+ MoveToEx(hdc, ps.rcPaint.left, 1, NULL);
+#endif
+ LineTo(hdc, ps.rcPaint.right, 1);
+
+ // do not overwrite the background color
+ //
+ SetBkMode(hdc, TRANSPARENT);
+
+ // message area
+ //
+ SelectObject(hdc, hpenBlack);
+#if defined(WIN16)
+ MoveTo(hdc, rcMsg.left, rcMsg.bottom);
+#elif defined(WIN32)
+ MoveToEx(hdc, rcMsg.left, rcMsg.bottom, NULL);
+#endif
+ LineTo(hdc, rcMsg.left, rcMsg.top);
+ LineTo(hdc, rcMsg.right, rcMsg.top);
+
+ SelectObject(hdc, hpenWhite);
+ LineTo(hdc, rcMsg.right, rcMsg.bottom);
+ LineTo(hdc, rcMsg.left, rcMsg.bottom);
+
+ // select the black pen for writing
+ //
+ SelectObject(hdc, hpenBlack);
+
+ // select the status bar font to write in
+ //
+ hfontOld = (HFONT)SelectObject(hdc, m_hfont);
+
+ // set the clipping region
+ //
+ hrgn = CreateRectRgn(
+ rcMsg.left, rcMsg.top, rcMsg.right, rcMsg.bottom);
+
+ SelectClipRgn(hdc, hrgn);
+
+ // draw the status message
+ //
+ TextOut(
+ hdc,
+ rcMsg.left + (m_dxFont / 2),
+ rcMsg.top + ((rcMsg.bottom - rcMsg.top - m_dyFont) / 2),
+ STRING(m_bstrMsg), (SysStringLen(m_bstrMsg)));
+
+ // cleanup
+ //
+ SelectObject(hdc, hpenOld);
+ SelectObject(hdc, hfontOld);
+
+ DeleteObject(hrgn);
+ DeleteObject(hpenGray);
+
+ EndPaint(m_hwnd, &ps);
+}
+
+extern "C" long FAR PASCAL
+StatBarWndProc(
+ HWND hwnd,
+ unsigned int message,
+ WPARAM wParam,
+ LPARAM lParam)
+{
+ CStatBar FAR* psb;
+
+ switch(message){
+ case WM_SIZE:
+ return 0;
+ case WM_PAINT:
+ psb = (CStatBar FAR*)GetWindowLong(hwnd, 0);
+ psb->WMPaint();
+ return 0;
+ }
+ return(DefWindowProc(hwnd, message, wParam, lParam));
+}
+
+
+//---------------------------------------------------------------------
+// Status Bar Utilities
+//---------------------------------------------------------------------
+
+extern "C" void
+SBprintf(CStatBar FAR* psb, TCHAR FAR* szFmt, ...)
+{
+ va_list args;
+static TCHAR buf[256];
+
+ va_start(args, szFmt);
+ wvsprintf(buf, szFmt, args);
+ psb->SetText(WIDESTRING(buf));
+ psb->Update();
+}
diff --git a/private/oleauto/sample/spoly2/statbar.h b/private/oleauto/sample/spoly2/statbar.h
new file mode 100644
index 000000000..52523081e
--- /dev/null
+++ b/private/oleauto/sample/spoly2/statbar.h
@@ -0,0 +1,142 @@
+/***
+*statbar.h
+*
+* Copyright (C) 1992-1994, Microsoft Corporation. All Rights Reserved.
+* Information Contained Herein Is Proprietary and Confidential.
+*
+*Purpose:
+*
+*Implementation Notes:
+* This file requires windows.h and ole2.h
+*
+*****************************************************************************/
+
+class CStatBar : public IUnknown {
+public:
+ static CStatBar FAR* Create(HINSTANCE hinst, HWND hwndFrame);
+
+ // IUnknown methods
+ //
+ STDMETHOD(QueryInterface)(REFIID riid, void FAR* FAR* ppv);
+ STDMETHOD_(unsigned long, AddRef)(void);
+ STDMETHOD_(unsigned long, Release)(void);
+
+ // Introduced methods
+ //
+ void Show(void);
+ inline void Move(void);
+ inline void Update(void);
+
+ inline int GetX(void);
+ inline void SetX(int x);
+
+ inline int GetY(void);
+ inline void SetY(int y);
+
+ inline int GetHeight(void);
+ inline void SetHeight(int height);
+
+ inline int GetWidth(void);
+ inline void SetWidth(int width);
+
+ //inline HFONT GetFont(void);
+ void SetFont(HFONT hfont);
+
+ //char FAR* GetText(void);
+ inline void SetText(OLECHAR FAR* sz);
+
+ void WMPaint(void);
+ BOOL Register(HINSTANCE);
+
+private:
+ CStatBar();
+ ~CStatBar();
+
+ unsigned long m_refs;
+
+ HWND m_hwnd; // the status bar window handle
+
+ int m_x; // x coordinate of upper left corner
+ int m_y; // y coordinate of upper left corner
+ int m_height;
+ int m_width;
+
+ HFONT m_hfont;
+ int m_dyFont; // font height
+ int m_dxFont; // font width
+
+ BSTR m_bstrMsg; // the status bar text
+
+ static TCHAR FAR* m_szWndClass;
+};
+
+inline void
+CStatBar::Move()
+{
+ MoveWindow(m_hwnd, m_x, m_y, m_width, m_height, TRUE);
+}
+
+inline void
+CStatBar::Update()
+{
+ InvalidateRect(m_hwnd, NULL, TRUE);
+ UpdateWindow(m_hwnd);
+}
+
+inline int
+CStatBar::GetX()
+{
+ return m_x;
+}
+
+inline void
+CStatBar::SetX(int x)
+{
+ m_x = x;
+}
+
+inline int
+CStatBar::GetY(void)
+{
+ return m_y;
+}
+
+inline void
+CStatBar::SetY(int y)
+{
+ m_y = y;
+}
+
+inline int
+CStatBar::GetHeight(void)
+{
+ return m_height;
+}
+
+inline void
+CStatBar::SetHeight(int height)
+{
+ m_height = height;
+}
+
+inline int
+CStatBar::GetWidth(void)
+{
+ return m_width;
+}
+
+inline void
+CStatBar::SetWidth(int width)
+{
+ m_width = width;
+}
+
+inline void
+CStatBar::SetText(OLECHAR FAR* sz)
+{
+ SysFreeString(m_bstrMsg);
+ m_bstrMsg = SysAllocString(sz);
+}
+
+extern "C" void
+SBprintf(CStatBar FAR* psb, TCHAR FAR* szFmt, ...);
diff --git a/private/oleauto/sample/spoly2/tdata.cpp b/private/oleauto/sample/spoly2/tdata.cpp
new file mode 100644
index 000000000..5bb5394c7
--- /dev/null
+++ b/private/oleauto/sample/spoly2/tdata.cpp
@@ -0,0 +1,344 @@
+/***
+*tdata.cpp
+*
+* Copyright (C) 1991-1994, Microsoft Corporation. All Rights Reserved.
+* Information Contained Herein Is Proprietary and Confidential.
+*
+*Purpose:
+* CPoly and CPoint type data descriptions.
+*
+* These data descriptions are used to construct TypeInfos for these
+* objects at runtime.
+*
+*****************************************************************************/
+
+#include "spoly.h"
+#include "cpoint.h"
+#include "cpoly.h"
+
+
+//---------------------------------------------------------------------
+// CPoint type data definitions
+//---------------------------------------------------------------------
+
+
+static PARAMDATA NEAR rgpdataCPointSetX[] =
+{
+ { OLESTR("X"), VT_I2 }
+};
+
+static PARAMDATA NEAR rgpdataCPointSetY[] =
+{
+ { OLESTR("Y"), VT_I2 }
+};
+
+static METHODDATA NEAR rgmdataCPoint[] =
+{
+ // CPoint::GetX()
+ {
+ OLESTR("GetX"),
+ NULL,
+ IDMEMBER_CPOINT_GETX,
+ IMETH_CPOINT_GETX,
+ CC_CALL,
+ 0,
+ DISPATCH_METHOD,
+ VT_I2
+ },
+
+ // CPoint::SetX()
+ {
+ OLESTR("SetX"),
+ rgpdataCPointSetX,
+ IDMEMBER_CPOINT_SETX,
+ IMETH_CPOINT_SETX,
+ CC_CALL,
+ DIM(rgpdataCPointSetX),
+ DISPATCH_METHOD,
+ VT_EMPTY
+ },
+
+ // CPoint::GetY()
+ {
+ OLESTR("GetY"),
+ NULL,
+ IDMEMBER_CPOINT_GETY,
+ IMETH_CPOINT_GETY,
+ CC_CALL,
+ 0,
+ DISPATCH_METHOD,
+ VT_I2
+ },
+
+ // CPoint::SetY()
+ {
+ OLESTR("SetY"),
+ rgpdataCPointSetY,
+ IDMEMBER_CPOINT_SETY,
+ IMETH_CPOINT_SETY,
+ CC_CALL,
+ DIM(rgpdataCPointSetY),
+ DISPATCH_METHOD,
+ VT_EMPTY
+ }
+};
+
+INTERFACEDATA NEAR g_idataCPoint =
+{
+ rgmdataCPoint, DIM(rgmdataCPoint)
+};
+
+
+//---------------------------------------------------------------------
+// CPoly type data definitions
+//---------------------------------------------------------------------
+
+
+static PARAMDATA NEAR rgpdataCPolyAddPoint[] =
+{
+ { OLESTR("x"), VT_I2 },
+ { OLESTR("y"), VT_I2 }
+};
+
+static PARAMDATA NEAR rgpdataCPolySetXOrigin[] =
+{
+ { OLESTR("x"), VT_I2 }
+};
+
+static PARAMDATA NEAR rgpdataCPolySetYOrigin[] =
+{
+ { OLESTR("y"), VT_I2 }
+};
+
+static PARAMDATA NEAR rgpdataCPolySetWidth[] =
+{
+ { OLESTR("width"), VT_I2 }
+};
+
+static PARAMDATA NEAR rgpdataCPolySetRed[] =
+{
+ { OLESTR("red"), VT_I2 }
+};
+
+static PARAMDATA NEAR rgpdataCPolySetGreen[] =
+{
+ { OLESTR("green"), VT_I2 }
+};
+
+static PARAMDATA NEAR rgpdataCPolySetBlue[] =
+{
+ { OLESTR("blue"), VT_I2 }
+};
+
+static METHODDATA NEAR rgmdataCPoly[] =
+{
+ // void CPoly::Draw(void)
+ {
+ OLESTR("Draw"),
+ NULL,
+ IDMEMBER_CPOLY_DRAW,
+ IMETH_CPOLY_DRAW,
+ CC_CALL,
+ 0,
+ DISPATCH_METHOD,
+ VT_EMPTY
+ },
+
+ // void CPoly::Reset(void)
+ {
+ OLESTR("Reset"),
+ NULL,
+ IDMEMBER_CPOLY_RESET,
+ IMETH_CPOLY_RESET,
+ CC_CALL,
+ 0,
+ DISPATCH_METHOD,
+ VT_EMPTY
+ },
+
+ // HRESULT CPoly::AddPoint(short x, short y)
+ {
+ OLESTR("AddPoint"),
+ rgpdataCPolyAddPoint,
+ IDMEMBER_CPOLY_ADDPOINT,
+ IMETH_CPOLY_ADDPOINT,
+ CC_CALL,
+ DIM(rgpdataCPolyAddPoint),
+ DISPATCH_METHOD,
+ VT_ERROR
+ },
+
+ // IUnknown FAR* CPoly::EnumPoints(void)
+ {
+ OLESTR("EnumPoints"),
+ NULL,
+ IDMEMBER_CPOLY_ENUMPOINTS,
+ IMETH_CPOLY_ENUMPOINTS,
+ CC_CALL,
+ 0,
+ DISPATCH_METHOD,
+ VT_UNKNOWN
+ },
+
+ // short CPoly::GetXOrigin(void)
+ {
+ OLESTR("GetXOrigin"),
+ NULL,
+ IDMEMBER_CPOLY_GETXORIGIN,
+ IMETH_CPOLY_GETXORIGIN,
+ CC_CALL,
+ 0,
+ DISPATCH_METHOD,
+ VT_I2
+ },
+
+ // void CPoly::SetXOrigin(short x)
+ {
+ OLESTR("SetXOrigin"),
+ rgpdataCPolySetXOrigin,
+ IDMEMBER_CPOLY_SETXORIGIN,
+ IMETH_CPOLY_SETXORIGIN,
+ CC_CALL,
+ DIM(rgpdataCPolySetXOrigin),
+ DISPATCH_METHOD,
+ VT_EMPTY
+ },
+
+ // short CPoly::GetYOrigin(void)
+ {
+ OLESTR("GetYOrigin"),
+ NULL,
+ IDMEMBER_CPOLY_GETYORIGIN,
+ IMETH_CPOLY_GETYORIGIN,
+ CC_CALL,
+ 0,
+ DISPATCH_METHOD,
+ VT_I2
+ },
+
+ // void CPoly::SetYOrigin(short y)
+ {
+ OLESTR("SetYOrigin"),
+ rgpdataCPolySetYOrigin,
+ IDMEMBER_CPOLY_SETYORIGIN,
+ IMETH_CPOLY_SETYORIGIN,
+ CC_CALL,
+ DIM(rgpdataCPolySetYOrigin),
+ DISPATCH_METHOD,
+ VT_EMPTY
+ },
+
+ // short CPoly::GetWidth(void)
+ {
+ OLESTR("GetWidth"),
+ NULL,
+ IDMEMBER_CPOLY_GETWIDTH,
+ IMETH_CPOLY_GETWIDTH,
+ CC_CALL,
+ 0,
+ DISPATCH_METHOD,
+ VT_I2
+ },
+
+ // void CPoly::SetWidth(short width)
+ {
+ OLESTR("SetWidth"),
+ rgpdataCPolySetWidth,
+ IDMEMBER_CPOLY_SETWIDTH,
+ IMETH_CPOLY_SETWIDTH,
+ CC_CALL,
+ DIM(rgpdataCPolySetWidth),
+ DISPATCH_METHOD,
+ VT_EMPTY
+ },
+
+ // short CPoly::get_red(void)
+ {
+ OLESTR("get_red"),
+ NULL,
+ IDMEMBER_CPOLY_GETRED,
+ IMETH_CPOLY_GETRED,
+ CC_CALL,
+ 0,
+ DISPATCH_METHOD,
+ VT_I2
+ },
+
+ // void CPoly::set_red(short red)
+ {
+ OLESTR("set_red"),
+ rgpdataCPolySetRed,
+ IDMEMBER_CPOLY_SETRED,
+ IMETH_CPOLY_SETRED,
+ CC_CALL,
+ DIM(rgpdataCPolySetRed),
+ DISPATCH_METHOD,
+ VT_EMPTY
+ },
+
+ // short CPoly::get_green(void)
+ {
+ OLESTR("get_green"),
+ NULL,
+ IDMEMBER_CPOLY_GETGREEN,
+ IMETH_CPOLY_GETGREEN,
+ CC_CALL,
+ 0,
+ DISPATCH_METHOD,
+ VT_I2
+ },
+
+ // void CPoly::set_green(short green)
+ {
+ OLESTR("set_green"),
+ rgpdataCPolySetGreen,
+ IDMEMBER_CPOLY_SETGREEN,
+ IMETH_CPOLY_SETGREEN,
+ CC_CALL,
+ DIM(rgpdataCPolySetGreen),
+ DISPATCH_METHOD,
+ VT_EMPTY
+ },
+
+ // short CPoly::get_blue(void)
+ {
+ OLESTR("get_blue"),
+ NULL,
+ IDMEMBER_CPOLY_GETBLUE,
+ IMETH_CPOLY_GETBLUE,
+ CC_CALL,
+ 0,
+ DISPATCH_METHOD,
+ VT_I2
+ },
+
+ // void CPoly::set_blue(short blue)
+ {
+ OLESTR("set_blue"),
+ rgpdataCPolySetBlue,
+ IDMEMBER_CPOLY_SETBLUE,
+ IMETH_CPOLY_SETBLUE,
+ CC_CALL,
+ DIM(rgpdataCPolySetBlue),
+ DISPATCH_METHOD,
+ VT_EMPTY
+ },
+
+ // void CPoly::Dump(void)
+ {
+ OLESTR("Dump"),
+ NULL,
+ IDMEMBER_CPOLY_DUMP,
+ IMETH_CPOLY_DUMP,
+ CC_CALL,
+ 0,
+ DISPATCH_METHOD,
+ VT_EMPTY
+ },
+
+};
+
+INTERFACEDATA NEAR g_idataCPoly =
+{
+ rgmdataCPoly, DIM(rgmdataCPoly)
+};
diff --git a/private/oleauto/sample/spoly2/winmain.cpp b/private/oleauto/sample/spoly2/winmain.cpp
new file mode 100644
index 000000000..c3c8b9a78
--- /dev/null
+++ b/private/oleauto/sample/spoly2/winmain.cpp
@@ -0,0 +1,293 @@
+/***
+*winmain.cpp
+*
+* Copyright (C) 1992-1994, Microsoft Corporation. All Rights Reserved.
+* Information Contained Herein Is Proprietary and Confidential.
+*
+*Purpose:
+* This module is the main entry point for the sample IDispatch polygon
+* server, spoly2.exe.
+*
+* This program is intended to demonstrate an implementation of the IDispatch
+* interface. Spoly2 is a very simple app, that implements two simple objects,
+* CPoly and CPoint and exposes their properties and methods for programatic
+* and cross-process access via IDispatch.
+*
+*Implementation Notes:
+*
+*****************************************************************************/
+
+#include <stdio.h>
+#include <string.h>
+
+#include "spoly.h"
+#include "cpoint.h"
+#include "cpoly.h"
+
+
+HINSTANCE g_hinst = 0;
+
+HWND g_hwndFrame = 0;
+HWND g_hwndClient = 0;
+
+TCHAR g_szFrameWndClass[] = TSTR("FrameWClass");
+
+CStatBar FAR* g_psb = NULL;
+
+
+BOOL InitApplication(HINSTANCE);
+BOOL InitInstance(HINSTANCE, int);
+
+extern "C" int PASCAL WinMain(HINSTANCE, HINSTANCE, LPSTR, int);
+extern "C" long FAR PASCAL FrameWndProc(HWND, UINT, WPARAM, LPARAM);
+
+
+extern "C" int PASCAL
+WinMain(
+ HINSTANCE hinst,
+ HINSTANCE hPrevInstance,
+ LPSTR lpCmdLine,
+ int nCmdShow)
+{
+ MSG msg;
+ int retval;
+ HRESULT hresult;
+
+ if(!hPrevInstance)
+ if(!InitApplication(hinst))
+ return FALSE;
+
+ if((hresult = InitOle()) != NOERROR)
+ return FALSE;
+
+ if(!InitInstance(hinst, nCmdShow)){
+ retval = FALSE;
+ goto LExit;
+ }
+
+ while(GetMessage(&msg, NULL, NULL, NULL)) {
+ TranslateMessage(&msg);
+ DispatchMessage(&msg);
+ }
+
+ g_psb->Release();
+ CPoly::PolyTerm();
+
+ retval = msg.wParam;
+
+LExit:;
+ UninitOle();
+
+ return retval;
+}
+
+
+BOOL
+InitApplication(HINSTANCE hinst)
+{
+ WNDCLASS wc;
+
+ wc.style = CS_HREDRAW | CS_VREDRAW;
+ wc.lpfnWndProc = FrameWndProc;
+ wc.cbClsExtra = 0;
+ wc.cbWndExtra = 0;
+ wc.hInstance = hinst;
+ wc.hIcon = LoadIcon(hinst, TSTR("SPOLY"));
+ wc.hCursor = LoadCursor(NULL, IDC_ARROW);
+ wc.hbrBackground = (HBRUSH) (COLOR_APPWORKSPACE+1);
+ wc.lpszMenuName = TSTR("SPolyMenu");
+ wc.lpszClassName = g_szFrameWndClass;
+
+ if(!RegisterClass(&wc))
+ return FALSE;
+
+ return TRUE;
+}
+
+#ifdef WIN32
+#define szAppTitle TSTR("IDispatch Polygon Server #2 (32-bit)")
+#else //WIN32
+#define szAppTitle TSTR("IDispatch Polygon Server #2")
+#endif //WIN32
+
+BOOL
+InitInstance(HINSTANCE hinst, int nCmdShow)
+{
+ g_hinst = hinst;
+
+ // Create a main frame window
+ //
+ g_hwndFrame = CreateWindow(
+ g_szFrameWndClass,
+ szAppTitle,
+ WS_OVERLAPPEDWINDOW | WS_CLIPCHILDREN,
+ CW_USEDEFAULT,
+ CW_USEDEFAULT,
+ CW_USEDEFAULT,
+ CW_USEDEFAULT,
+ NULL,
+ NULL,
+ hinst,
+ NULL);
+ if(!g_hwndFrame)
+ return FALSE;
+
+ g_hwndClient = GetWindow(g_hwndFrame, GW_CHILD);
+ if(!g_hwndClient)
+ return FALSE;
+
+ // create the status bar
+ //
+ g_psb = CStatBar::Create(g_hinst, g_hwndFrame);
+ if(!g_psb)
+ return FALSE;
+
+ // initialize and show the status bar
+ //
+ g_psb->SetHeight(GetSystemMetrics(SM_CYCAPTION) - 1);
+ g_psb->SetFont((HFONT)GetStockObject(SYSTEM_FONT));
+ g_psb->SetText(OLESTR(""));
+ g_psb->Show();
+
+ ShowWindow(g_hwndFrame, nCmdShow);
+
+ UpdateWindow(g_hwndFrame);
+
+ return TRUE;
+}
+
+
+void
+FrameWndOnCreate(HWND hwnd)
+{
+ CLIENTCREATESTRUCT ccs;
+
+ ccs.hWindowMenu = NULL;
+ ccs.idFirstChild = IDM_FIRSTCHILD;
+
+ g_hwndClient = CreateWindow(
+ TSTR("MDICLIENT"),
+ 0,
+ WS_CHILD | WS_CLIPCHILDREN | WS_VISIBLE,
+ 0, 0, 0, 0,
+ hwnd,
+ (HMENU) 1,
+ g_hinst,
+ &ccs);
+}
+
+
+void
+FrameWndOnSize(HWND hwnd)
+{
+ RECT rc;
+ int height;
+
+ // Get the client rectangle for the frame window
+ GetClientRect(hwnd, &rc);
+
+ height = g_psb->GetHeight();
+
+ // adjust the client win to make room for the status bar.
+ //
+ MoveWindow(
+ g_hwndClient,
+ rc.left,
+ rc.top,
+ rc.right - rc.left,
+ rc.bottom - rc.top - height,
+ TRUE);
+
+ // move the status bar to the bottom of the newly positioned window.
+ //
+ g_psb->SetX(rc.left);
+ g_psb->SetY(rc.bottom - height),
+ g_psb->SetWidth(rc.right - rc.left);
+ g_psb->Move();
+}
+
+
+extern "C" long FAR PASCAL
+FrameWndProc(
+ HWND hwnd,
+ UINT message,
+ WPARAM wParam,
+ LPARAM lParam)
+{
+ switch(message){
+ case WM_COMMAND:
+ switch(wParam){
+ case IDM_DUMP:
+ CPoly::PolyDump();
+ return 0;
+
+ case IDM_CLEAR:
+ InvalidateRect(g_hwndClient, NULL, TRUE);
+ return 0;
+ }
+ break;
+
+ case WM_CREATE:
+ FrameWndOnCreate(hwnd);
+ break;
+
+ case WM_SIZE:
+ FrameWndOnSize(hwnd);
+ return 1;
+
+ case WM_PAINT:
+ CPoly::PolyDraw();
+ break;
+
+ case WM_CLOSE:
+ DestroyWindow(hwnd);
+ return 0;
+
+ case WM_DESTROY:
+ PostQuitMessage(0);
+ return 0;
+ }
+ return DefFrameProc(hwnd, g_hwndClient, message, wParam, lParam);
+}
+
+
+#if defined(WIN32)
+
+extern "C" OLECHAR FAR*
+ConvertStrAtoW(char FAR* strIn, OLECHAR FAR* buf, UINT size)
+{
+ MultiByteToWideChar(CP_ACP, MB_PRECOMPOSED,
+ strIn, -1, buf, size) ;
+ return buf;
+}
+
+extern "C" OLECHAR FAR*
+WideString(char FAR* strIn)
+{
+ static OLECHAR buf[256];
+
+ return (ConvertStrAtoW(strIn, buf, 256));
+}
+
+extern "C" char FAR*
+ConvertStrWtoA(OLECHAR FAR* strIn, char FAR* buf, UINT size)
+{
+ int badConversion = FALSE;
+
+ WideCharToMultiByte(CP_ACP, NULL,
+ strIn, -1,
+ buf, size,
+ NULL, &badConversion);
+ return buf;
+}
+
+extern "C" char FAR*
+AnsiString(OLECHAR FAR* strIn)
+{
+ static char buf[256];
+
+ return (ConvertStrWtoA(strIn, buf, 256));
+}
+
+#endif
+