#ifndef UTILS_H_INCLUDED #define UTILS_H_INCLUDED #include #include #include #define RELEASE_CODE #define QUERY_CODE #define BEGIN_XC_IMPL(cls) \ STDMETHODIMP cls##_QueryInterface(I##cls *This, REFIID iid, void **ppvObject) \ { \ if (InlineIsEqualGUID(iid, &IID_IErrorInfo)) \ printf("Looking for error info iface on %p\n", This); \ if (InlineIsEqualGUID(iid, &IID_IUnknown) || \ InlineIsEqualGUID(iid, &IID_IDispatch) || \ InlineIsEqualGUID(iid, &IID_I##cls)) \ *ppvObject = This; \ QUERY_CODE \ else \ return E_NOINTERFACE; \ \ I##cls##_AddRef(This); \ \ return S_OK; \ } \ \ STDMETHODIMP_(ULONG) cls##_AddRef(I##cls *This) \ { \ ((cls*)This)->m_refCount++; \ return S_OK; \ } \ \ STDMETHODIMP_(ULONG) cls##_Release(I##cls *This) \ { \ if (--(((cls*)This)->m_refCount) == 0) { \ RELEASE_CODE \ LocalFree(This); \ } \ return S_OK; \ } \ \ static ITypeInfo *ti; \ \ STDMETHODIMP cls##_GetTypeInfoCount(I##cls *This, UINT *pctinfo) \ { \ *pctinfo = 1; \ return S_OK; \ } \ \ STDMETHODIMP cls##_GetTypeInfo(I##cls *This, UINT itinfo, LCID lcid, \ ITypeInfo **pptinfo) \ { \ if (itinfo != 0) \ return DISP_E_BADINDEX; \ *pptinfo = ti; \ ITypeInfo_AddRef(ti); \ return S_OK; \ } \ \ STDMETHODIMP cls##_GetIDsOfNames(I##cls *This, REFIID iid, LPOLESTR *rgszNames, \ UINT cNames, LCID lcid, DISPID *rgDispId) \ { \ return DispGetIDsOfNames(ti, rgszNames, cNames, rgDispId); \ } \ \ STDMETHODIMP cls##_Invoke(I##cls *This, DISPID dispIdMember, REFIID iid, \ LCID lcid, WORD wFlags, DISPPARAMS *pDispParams, VARIANT *pVarResult, \ EXCEPINFO *pExcepInfo, UINT *puArgErr) \ { \ return DispInvoke(This, ti, dispIdMember, wFlags, pDispParams, pVarResult, \ pExcepInfo, puArgErr); \ } #define XCOBJ_QUERY_CODE \ else if (InlineIsEqualGUID(iid, &IID_IXCObject)) \ *ppvObject = This; #define XCLINEOBJ_QUERY_CODE \ XCOBJ_QUERY_CODE \ else if (InlineIsEqualGUID(iid, &IID_IXCLineObject)) \ *ppvObject = This; #define END_XC_IMPL(cls) \ HRESULT init_##cls(ITypeLib *tl) \ { \ HRESULT hres; \ \ hres = ITypeLib_GetTypeInfoOfGuid(tl, &IID_I##cls, &ti); \ if (hres == S_OK) \ ITypeInfo_AddRef(ti); \ return hres; \ } \ \ HRESULT close_##cls() \ { \ ITypeInfo_Release(ti); \ return S_OK; \ } \ \ cls* make_##cls() \ { \ cls *ptr = (cls*)LocalAlloc(LMEM_FIXED|LMEM_ZEROINIT, \ sizeof(cls)); \ ptr->iface.lpVtbl = &vtbl; \ return ptr; \ } #define COM_VTBL_BEGIN(cls) \ static I##cls##Vtbl vtbl = { \ cls##_QueryInterface, \ cls##_AddRef, \ cls##_Release, \ cls##_GetTypeInfoCount, \ cls##_GetTypeInfo, \ cls##_GetIDsOfNames, \ cls##_Invoke, #define XCOBJ_VTBL_BEGIN(cls) \ COM_VTBL_BEGIN(cls) \ XCObject_get_object_handle, \ XCObject_get_color, \ XCObject_put_color, \ XCObject_select, \ XCObject_update, #define XCLINEOBJ_VTBL_BEGIN(cls) \ XCOBJ_VTBL_BEGIN(cls) \ XCLineObject_get_width, \ XCLineObject_put_width, \ XCLineObject_put_border, \ XCLineObject_get_border, \ XCLineObject_put_closed, \ XCLineObject_get_closed, #define COM_VTBL_END() \ }; #define XCOBJ_VTBL_END COM_VTBL_END #define XCLINEOBJ_VTBL_END XCOBJ_VTBL_END #define BEGIN_XC_CLASS(cls) \ typedef struct cls { \ interface I##cls iface; \ int m_refCount; #define BEGIN_XCOBJ_CLASS(cls) \ BEGIN_XC_CLASS(cls) \ long handle; \ int type; #define END_XC_CLASS(cls) \ } cls, *cls##Ptr; \ cls* make_##cls(); \ HRESULT init_##cls(ITypeLib *tl); \ HRESULT close_##cls(); #define END_XCOBJ_CLASS END_XC_CLASS #define GET_METHOD(cls, member, xc_member, type, castfn, code) \ STDMETHODIMP cls##_get_##member(I##cls *This, type *pVal) \ { \ HRESULT hres; \ long handle; \ \ if ((hres = I##cls##_get_object_handle(This, &handle)) != S_OK) \ return hres; \ code \ *pVal = castfn(&handle)->xc_member; \ \ return S_OK; \ } #define PUT_METHOD(cls, member, xc_member, type, castfn, code) \ STDMETHODIMP cls##_put_##member(I##cls *This, type newVal) \ { \ HRESULT hres; \ long handle; \ \ if ((hres = I##cls##_get_object_handle(This, &handle)) != S_OK) \ return hres; \ code \ castfn(&handle)->xc_member = newVal; \ I##cls##_update(This, 1); \ \ return S_OK; \ } #define PROPERTY_IMPL2(cls, member, xc_member, type, castfn, get_code, put_code) \ GET_METHOD(cls, member, xc_member, type, castfn, get_code) \ PUT_METHOD(cls, member, xc_member, type, castfn, put_code) #define PROPERTY_IMPL(cls, member, xc_member, type, castfn) \ PROPERTY_IMPL2(cls, member, xc_member, type, castfn, ;, ;) enum xc_error_code { XC_E_TYPEMISMATCH = 0xD, XC_E_FIRST = 600, XC_E_HANDLE, XC_E_COLORINDEX, XC_E_ARCNOTCIRCLE, XC_E_ARCINVALIDANGLES, XC_E_INVALIDBORDER, XC_E_OUTOFRANGE, XC_E_NUMARGS, XC_E_JUSTIFY, XC_E_LAST }; extern wchar_t *error_msg[]; #define XC_ERROR_MSG(code) error_msg[code-XC_E_FIRST] #define ECODE(code) MAKE_SCODE(SEVERITY_ERROR, FACILITY_CONTROL, code) int get_string_index_from_variant(VARIANT *val, char **sarray, int ssize); int get_string_index(BSTR val, char **sarray, int ssize); int get_wide_string_index(BSTR val, wchar_t **sarray, int ssize); char* convert_from_bstr(BSTR val); BSTR convert_to_bstr(char *str); char *string_from_parts(stringpart *parts); stringpart* string_to_parts(char *str); #endif /* UTILS_H_INCLUDED */