Click here to Skip to main content
15,884,537 members
Articles / Desktop Programming / WTL

Form Designer

26 Jul 2021CPOL24 min read 351.1K   82.5K   230  
Component for adding scriptable forms capabilities to an application.
// PropertyHelpers.h
//
// Author : David Shepherd
//			Copyright (c) 2003, DaeDoe-Software
//
/////////////////////////////////////////////////////////////////////////////

#pragma once

// begin custom property put implementation block
#define CUSTOM_PROPERTY_PUT_BEGIN(type,name,dispid)						\
	HRESULT STDMETHODCALLTYPE put_##name(type newVal)					\
	{																	\
	IMP_BEGIN															\
		REQUEST_EDIT(dispid)											\
		HRESULT hr=S_OK;												\
		__if_exists(_On##name##Changing)								\
		{																\
			hr=_On##name##Changing(newVal);								\
			if(!SUCCEEDED(hr))											\
			{															\
				throw CHResult(hr);										\
			}															\
		}																\
		__if_exists(On##name##Changing)									\
		{																\
			hr=On##name##Changing(newVal);								\
			if(!SUCCEEDED(hr))											\
			{															\
				throw CHResult(hr);										\
			}															\
		}

// end custom property put implementation block
#define CUSTOM_PROPERTY_PUT_END(type,name,dispid)						\
		__if_exists(On##name##Changed)									\
		{																\
			On##name##Changed();										\
		}																\
		PROPERTY_CHANGED(dispid)										\
	IMP_END																\
		return RetVal;													\
	}

// begin custom property putref implementation block
#define CUSTOM_PROPERTY_PUTREF_BEGIN(type,name,dispid)					\
	HRESULT STDMETHODCALLTYPE putref_##name(type newVal)				\
	{																	\
	IMP_BEGIN															\
		REQUEST_EDIT(dispid)											\
		HRESULT hr=S_OK;												\
		__if_exists(_On##name##Changing)								\
		{																\
			hr=_On##name##Changing(newVal);								\
			if(!SUCCEEDED(hr))											\
			{															\
				throw CHResult(hr);										\
			}															\
		}																\
		__if_exists(On##name##Changing)									\
		{																\
			hr=On##name##Changing(newVal);								\
			if(!SUCCEEDED(hr))											\
			{															\
				throw CHResult(hr);										\
			}															\
		}

// end custom property putref implementation block
#define CUSTOM_PROPERTY_PUTREF_END(type,name,dispid)					\
		__if_exists(On##name##Changed)									\
		{																\
			On##name##Changed();										\
		}																\
		PROPERTY_CHANGED(dispid)										\
	IMP_END																\
		return RetVal;													\
	}

// begin custom property get implementation block
#define CUSTOM_PROPERTY_GET_BEGIN(type,name,dispid)						\
	HRESULT STDMETHODCALLTYPE get_##name(type *pVal)					\
	{																	\
	IMP_BEGIN															\
		if(pVal==NULL)													\
		{																\
			throw CHResult(E_POINTER);									\
		}

// end custom property get implementation block
#define CUSTOM_PROPERTY_GET_END(type,name,dispid)						\
	IMP_END																\
		return RetVal;													\
	}

// standard custom property implementation
#define IMPLEMENT_CUSTOM_PROPERTY(type,name,member,dispid)				\
	CUSTOM_PROPERTY_PUT_BEGIN(type,name,dispid)							\
		member=newVal;													\
	CUSTOM_PROPERTY_PUT_END(type,name,dispid)							\
	CUSTOM_PROPERTY_GET_BEGIN(type,name,dispid)							\
		*pVal=member;													\
	CUSTOM_PROPERTY_GET_END(type,name,dispid)							\
	HRESULT _On##name##Changing(type newVal)							\
	{																	\
		return S_OK;													\
	}

// standard custom color property implementation
#define IMPLEMENT_CUSTOM_COLOR_PROPERTY(name,member,dispid)				\
	CUSTOM_PROPERTY_PUT_BEGIN(OLE_COLOR,name,dispid)					\
		member=newVal;													\
	CUSTOM_PROPERTY_PUT_END(OLE_COLOR,name,dispid)						\
	CUSTOM_PROPERTY_GET_BEGIN(OLE_COLOR,name,dispid)					\
		*pVal=member;													\
	CUSTOM_PROPERTY_GET_END(OLE_COLOR,name,dispid)						\
	HRESULT _On##name##Changing(OLE_COLOR newVal)						\
	{																	\
		if(!SUCCEEDED(OleTranslateColor(newVal,NULL,NULL)))				\
		{																\
			return E_INVALIDARG;										\
		}																\
		return S_OK;													\
	}

// standard custom boolean property implementation
#define IMPLEMENT_CUSTOM_BOOL_PROPERTY(name,member,dispid)				\
	CUSTOM_PROPERTY_PUT_BEGIN(VARIANT_BOOL,name,dispid)					\
		member=newVal;													\
	CUSTOM_PROPERTY_PUT_END(VARIANT_BOOL,name,dispid)					\
	CUSTOM_PROPERTY_GET_BEGIN(VARIANT_BOOL,name,dispid)					\
		*pVal=member;													\
	CUSTOM_PROPERTY_GET_END(VARIANT_BOOL,name,dispid)					\
	HRESULT _On##name##Changing(VARIANT_BOOL newVal)					\
	{																	\
		if(newVal!=VARIANT_TRUE and newVal!=VARIANT_FALSE)				\
		{																\
			return E_INVALIDARG;										\
		}																\
		return S_OK;													\
	}

// standard custom text property implementation
#define IMPLEMENT_CUSTOM_TEXT_PROPERTY(name,member,dispid)				\
	CUSTOM_PROPERTY_PUT_BEGIN(BSTR,name,dispid)							\
		member=newVal;													\
	CUSTOM_PROPERTY_PUT_END(BSTR,name,dispid)							\
	CUSTOM_PROPERTY_GET_BEGIN(BSTR,name,dispid)							\
		*pVal=CComBSTR(member).Detach();								\
	CUSTOM_PROPERTY_GET_END(BSTR,name,dispid)							\
	HRESULT _On##name##Changing(BSTR newVal)							\
	{																	\
		return S_OK;													\
	}

// standard custom font property implementation
#define IMPLEMENT_CUSTOM_FONT_PROPERTY(name,member,dispid)				\
	CUSTOM_PROPERTY_PUT_BEGIN(IFontDisp*,name,dispid)					\
		if(newVal==NULL)												\
		{																\
			throw CHResult(E_POINTER);									\
		}																\
		member=CloneFont(newVal);										\
	CUSTOM_PROPERTY_PUT_END(IFontDisp*,name,dispid)						\
	CUSTOM_PROPERTY_PUTREF_BEGIN(IFontDisp*,name,dispid)				\
		if(newVal==NULL)												\
		{																\
			throw CHResult(E_POINTER);									\
		}																\
		member=newVal;													\
	CUSTOM_PROPERTY_PUTREF_END(IFontDisp*,name,dispid)					\
	CUSTOM_PROPERTY_GET_BEGIN(IFontDisp*,name,dispid)					\
		*pVal=member;													\
		if(*pVal!=NULL)													\
		{																\
			(void)(*pVal)->AddRef();									\
		}																\
	CUSTOM_PROPERTY_GET_END(IFontDisp*,name,dispid)						\
	HRESULT _On##name##Changing(IFontDisp* newVal)						\
	{																	\
		return S_OK;													\
	}

// standard custom picture property implementation
#define IMPLEMENT_CUSTOM_PICTURE_PROPERTY(name,member,dispid)			\
	CUSTOM_PROPERTY_PUT_BEGIN(IPictureDisp*,name,dispid)				\
		if(newVal==NULL)												\
		{																\
			throw CHResult(E_POINTER);									\
		}																\
		member=ClonePicture(newVal);									\
	CUSTOM_PROPERTY_PUT_END(IPictureDisp*,name,dispid)					\
	CUSTOM_PROPERTY_PUTREF_BEGIN(IPictureDisp*,name,dispid)				\
		if(newVal==NULL)												\
		{																\
			throw CHResult(E_POINTER);									\
		}																\
		member=newVal;													\
	CUSTOM_PROPERTY_PUTREF_END(IPictureDisp*,name,dispid)				\
	CUSTOM_PROPERTY_GET_BEGIN(IPictureDisp*,name,dispid)				\
		*pVal=member;													\
		if(*pVal!=NULL)													\
		{																\
			(void)(*pVal)->AddRef();									\
		}																\
	CUSTOM_PROPERTY_GET_END(IPictureDisp*,name,dispid)					\
	HRESULT _On##name##Changing(IPictureDisp* newVal)					\
	{																	\
		return S_OK;													\
	}

// creates the default font
CComPtr<IFontDisp> CreateDefaultFont();
// clones the passed font
CComPtr<IFontDisp> CloneFont(const CComPtr<IFontDisp> &spFontDisp);

// creates the default picture
CComPtr<IPictureDisp> CreateDefaultPicture();
// clones the passed picture
CComPtr<IPictureDisp> ClonePicture(const CComPtr<IPictureDisp> &spPictureDisp);

By viewing downloads associated with this article you agree to the Terms of Service and the article's licence.

If a file you wish to view isn't highlighted, and is a text file (not binary), please let us know and we'll add colourisation support for it.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


Written By
Web Developer
United Kingdom United Kingdom
This member has not yet provided a Biography. Assume it's interesting and varied, and probably something to do with programming.

Comments and Discussions