Click here to Skip to main content
15,860,972 members
Articles / Desktop Programming / WTL

Form Designer

26 Jul 2021CPOL24 min read 349.8K   82.5K   230  
Component for adding scriptable forms capabilities to an application.
// FormViewer.h : Declaration of the CFormViewer
//
// Author : David Shepherd
//			Copyright (c) 2002, DaeDoe-Software
//
/////////////////////////////////////////////////////////////////////////////

#ifndef __FORMVIEWER_H_
#define __FORMVIEWER_H_

#include "resource.h"       // main symbols
#include <atlctl.h>

#include "DDAxWindow.h"
#include "EventSink.h"
#include "ViewableForm.h"

// microsoft script control
#import <msscript.ocx> raw_interfaces_only

namespace AxFormViewer {

/////////////////////////////////////////////////////////////////////////////
// CItemInfo
class CItemInfo
{
private:
	// disallow standalone instantiation
	CItemInfo();
	CItemInfo(const CItemInfo &ItemInfo);
	// disallow external destruction
	virtual ~CItemInfo();
	// these private members ensure that an object of this class
	// can only be created using CreateObject() and can only be
	// destroyed using DeleteObject()

	// disallow assignment
	const CItemInfo &operator=(const CItemInfo &ItemInfo);
	// this works in conjunction with the other private members
	// to ensure that there is only ever a single instance of
	// this class per item

public:
	// creates a new object
	static CItemInfo *CreateObject();
	// deletes an existing object
	static void DeleteObject(const CItemInfo *pItemInfo);

	// name
	std::wstring m_Name;
	// tag
	std::wstring m_Tag;
	// host window
	CDDAxWindow m_HostWindow;
	// todo : add additional item information here as required
};
// CItemInfo pointer list
typedef std::list<CItemInfo *> CItemInfoPtrList;
// CItemInfo pointer vector
typedef std::vector<CItemInfo *> CItemInfoPtrVector;
// CAutoItemInfoPtr
#include "AutoItemInfoPtr.h"

/////////////////////////////////////////////////////////////////////////////
// type definitions

// CEventSink pointer list
typedef std::list<CEventSink*> CEventSinkPtrList;

// maps an object name to an IDispatch interface
typedef std::map<std::wstring,CComPtr<IDispatch> > CObjectNameToIDispatchMap;

/////////////////////////////////////////////////////////////////////////////
// CFormViewer

// window traits
typedef CWinTraits<
	// standard styles
	WS_CHILD|WS_VISIBLE|WS_HSCROLL|WS_VSCROLL|
	// clipping
	WS_CLIPCHILDREN|WS_CLIPSIBLINGS,
	// extended styles
	WS_EX_CONTROLPARENT|WS_EX_CLIENTEDGE> CFormViewerWinTraits;
// base class
typedef CWindowImpl<
	class CFormViewer,CWindow,CFormViewerWinTraits> CFormViewerBase;
// viewer CComControl
typedef CComControl<CFormViewer,CFormViewerBase> CFormViewerComControl;
// all these typedefs are required to make CHAIN_MSG_MAP compile

class ATL_NO_VTABLE CFormViewer :
	public CComObjectRootEx<CComSingleThreadModel>,
	public IDispatchImpl<IFormViewer2, &IID_IFormViewer2, &LIBID_DDFORMSLib, TlbVerMaj, TlbVerMin>,
	public CFormViewerComControl,
	public IPersistStreamInitImpl<CFormViewer>,
	public IOleControlImpl<CFormViewer>,
	public IOleObjectImpl<CFormViewer>,
	public IOleInPlaceActiveObjectImpl<CFormViewer>,
	public IViewObjectExImpl<CFormViewer>,
	public IOleInPlaceObjectWindowlessImpl<CFormViewer>,
	public IConnectionPointContainerImpl<CFormViewer>,
	public IPersistStorageImpl<CFormViewer>,
	public IPersistPropertyBagImpl<CFormViewer>,
	public ISpecifyPropertyPagesImpl<CFormViewer>,
	public IQuickActivateImpl<CFormViewer>,
	public IDataObjectImpl<CFormViewer>,
	public IProvideClassInfo2Impl<&CLSID_FormViewer, &DIID__IFormViewerEvents, &LIBID_DDFORMSLib, TlbVerMaj, TlbVerMin>,
	public IPropertyNotifySinkCP<CFormViewer>,
	public CComCoClass<CFormViewer, &CLSID_FormViewer>,
	public CEventSinkNotifySink
{
private:
	// the form
	CComObject<CViewableForm> *m_pForm;
	// list of items in the form (sorted by zorder)
	CItemInfoPtrList m_ItemInfoPtrList;
	// the window after which all items will be placed
	CWindow m_ItemRootWindow;

	// list of event sinks
	CEventSinkPtrList m_EventSinkPtrList;

	// exposed objects
	CObjectNameToIDispatchMap m_ExposedObjects;

	// script text
	std::wstring m_ScriptText;
	// script control
	CComPtr<MSScriptControl::IScriptControl> m_spScriptControl;

// properties
	// border visible
	VARIANT_BOOL m_BorderVisible;
	// background color
	OLE_COLOR m_BackColor;

	// determines which item has the focus
	CItemInfo *GetFocusItem();

	// resets the form viewer
	void Reset();
	// sets the range and visibility of the scrollbars
	void SetScrollbars();
	// loads the script constants into the script control
	void LoadScriptConstants();
	// loads the exposed objects into the script control
	void LoadExposedObjects();

	// initialises the form from the passed stream
	void InitialiseFormFromStream(
		const CComPtr<IStream> &spStream,DWORD StreamVersion);
	// creates items from the passed stream
	void CreateItemsFromStream(
		const CComPtr<IStream> &spStream,DWORD StreamVersion);
	// loads the script from the passed stream
	void LoadScriptFromStream(
		const CComPtr<IStream> &spStream,DWORD StreamVersion);
	// determines if the form is loaded
	BOOL IsFormLoaded();
	// loads the form from the passed stream
	void InternalLoad(const CComPtr<IStream> &spStream);
	// unloads the form
	void InternalUnload();

	// exposes a named object
	void ExposeObject(
		const std::wstring &Name,const CComPtr<IDispatch> &spDispatch);

	// creates an event sink
	void CreateEventSink(
		const std::wstring &Name,const CComPtr<IDispatch> &spDispatch);

	// tabs forward to the next item
	void TabForwardToNextItem();
	// tabs backward to the next item
	void TabBackwardToNextItem();

	// tab direction
	enum TabDirection {
		// forward
		TabDirectionForward,
		// backward
		TabDirectionBackward };

	// tabs to the next item
	void TabToNextItem(TabDirection Direction);

public:
	CFormViewer();
	virtual ~CFormViewer();

DECLARE_REGISTRY_RESOURCEID(IDR_FORMVIEWER)

DECLARE_PROTECT_FINAL_CONSTRUCT()

BEGIN_COM_MAP(CFormViewer)
	COM_INTERFACE_ENTRY(IFormViewer2)
	COM_INTERFACE_ENTRY(IFormViewer)
	COM_INTERFACE_ENTRY(IDispatch)
	COM_INTERFACE_ENTRY(IViewObjectEx)
	COM_INTERFACE_ENTRY(IViewObject2)
	COM_INTERFACE_ENTRY(IViewObject)
	COM_INTERFACE_ENTRY(IOleInPlaceObjectWindowless)
	COM_INTERFACE_ENTRY(IOleInPlaceObject)
	COM_INTERFACE_ENTRY2(IOleWindow, IOleInPlaceObjectWindowless)
	COM_INTERFACE_ENTRY(IOleInPlaceActiveObject)
	COM_INTERFACE_ENTRY(IOleControl)
	COM_INTERFACE_ENTRY(IOleObject)
	COM_INTERFACE_ENTRY(IPersistStreamInit)
	COM_INTERFACE_ENTRY2(IPersist, IPersistStreamInit)
	COM_INTERFACE_ENTRY(IConnectionPointContainer)
	COM_INTERFACE_ENTRY(ISpecifyPropertyPages)
	COM_INTERFACE_ENTRY(IQuickActivate)
	COM_INTERFACE_ENTRY(IPersistStorage)
	COM_INTERFACE_ENTRY(IPersistPropertyBag)
	COM_INTERFACE_ENTRY(IDataObject)
	COM_INTERFACE_ENTRY(IProvideClassInfo)
	COM_INTERFACE_ENTRY(IProvideClassInfo2)
END_COM_MAP()

BEGIN_PROP_MAP(CFormViewer)
	PROP_DATA_ENTRY("_cx", m_sizeExtent.cx, VT_UI4)
	PROP_DATA_ENTRY("_cy", m_sizeExtent.cy, VT_UI4)
	PROP_ENTRY("BorderVisible", DISPID_BORDERVISIBLE, CLSID_PropPageFormViewer)
	PROP_ENTRY("BackColor", DISPID_BACKCOLOR, CLSID_StockColorPage)
	// Example entries
	// PROP_ENTRY("Property Description", dispid, clsid)
	// PROP_PAGE(CLSID_StockColorPage)
END_PROP_MAP()

BEGIN_CONNECTION_POINT_MAP(CFormViewer)
	CONNECTION_POINT_ENTRY(IID_IPropertyNotifySink)
END_CONNECTION_POINT_MAP()

BEGIN_MSG_MAP(CFormViewer)
	CHAIN_MSG_MAP(CFormViewerComControl)
	DEFAULT_REFLECTION_HANDLER()
	MESSAGE_HANDLER(WM_CREATE, OnCreate)
	MESSAGE_HANDLER(WM_DESTROY, OnDestroy)
	MESSAGE_HANDLER(WM_SIZE, OnSize)
	MESSAGE_HANDLER(WM_ERASEBKGND, OnEraseBkgnd)
	MESSAGE_HANDLER(WM_HSCROLL, OnHScroll)
	MESSAGE_HANDLER(WM_VSCROLL, OnVScroll)
END_MSG_MAP()
// Handler prototypes:
//  LRESULT MessageHandler(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled);
//  LRESULT CommandHandler(WORD wNotifyCode, WORD wID, HWND hWndCtl, BOOL& bHandled);
//  LRESULT NotifyHandler(int idCtrl, LPNMHDR pnmh, BOOL& bHandled);

// event sink notify sink
	void ESNS_ProcessEvent(
		const std::wstring &SourceName,const std::wstring &EventName,
		SAFEARRAY *pParams,VARIANT *pResult);

// base class overrides
	HRESULT FinalConstruct();
	void FinalRelease();
	BOOL PreTranslateAccelerator(LPMSG pMsg,HRESULT &hRet);
	HRESULT OnDraw(ATL_DRAWINFO &di);

// IViewObjectEx
	DECLARE_VIEW_STATUS(VIEWSTATUS_SOLIDBKGND | VIEWSTATUS_OPAQUE)

// message handlers
	LRESULT OnCreate(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled);
	LRESULT OnDestroy(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled);
	LRESULT OnSize(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled);
	LRESULT OnSetFocus(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled);
	LRESULT OnEraseBkgnd(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled);
	LRESULT OnHScroll(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled);
	LRESULT OnVScroll(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled);

// IFormViewer
public:
	STDMETHOD(About)();
	STDMETHOD(LoadFromFile)(/*[in]*/ BSTR FileName);
	STDMETHOD(Unload)();
	STDMETHOD(Expose)(
		/*[in]*/ BSTR Name,
		/*[in]*/ IDispatch *pDispatch);
	STDMETHOD(get_Form)(/*[out, retval]*/ IViewableForm **ppViewableForm);
	STDMETHOD(get_BorderVisible)(/*[out, retval]*/ VARIANT_BOOL *pVal);
	STDMETHOD(put_BorderVisible)(/*[in]*/ VARIANT_BOOL newVal);
	STDMETHOD(get_BackColor)(/*[out, retval]*/ OLE_COLOR *pVal);
	STDMETHOD(put_BackColor)(/*[in]*/ OLE_COLOR newVal);

// IFormViewer2
	STDMETHOD(GetItemDetails)(
		/*[in]*/ IDispatch *pDispatch,
		/*[out, retval]*/ IFormViewerItemDetails **ppFormViewerItemDetails);
	STDMETHOD(GetItemClassId)(
		/*[in]*/ IDispatch *pDispatch,
		/*[out, retval]*/ BSTR *pClassId);
	STDMETHOD(GetItemName)(
		/*[in]*/ IDispatch *pDispatch,
		/*[out, retval]*/ BSTR *pName);
	STDMETHOD(GetItemTag)(
		/*[in]*/ IDispatch *pDispatch,
		/*[out, retval]*/ BSTR *pTag);
	STDMETHOD(GetItemPosition)(
		/*[in]*/ IDispatch *pDispatch,
		/*[out]*/ long *pLeft,
		/*[out]*/ long *pTop,
		/*[out]*/ long *pWidth,
		/*[out]*/ long *pHeight,
		/*[out]*/ long *pTabNumber);
	STDMETHOD(SetItemPosition)(
		/*[in]*/ IDispatch *pDispatch,
		/*[in]*/ long Left,
		/*[in]*/ long Top,
		/*[in]*/ long Width,
		/*[in]*/ long Height,
		/*[in]*/ long TabNumber);
	STDMETHOD(get_Items)(
		/*[out, retval]*/ IFormViewerItemCollection **ppFormViewerItemCollection);
};

} // namespace AxFormViewer

#endif //__FORMVIEWER_H_

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