Click here to Skip to main content
13,766,364 members
Click here to Skip to main content

Stats

291K views
78.2K downloads
226 bookmarked
Posted 30 Dec 2005
Licenced CPOL

Form Designer

, 1 Aug 2009
Component for adding scriptable forms capabilities to an application.
MFCDemo.exe
CSDemo
App.ico
Bmp
ABottom.bmp
About.bmp
ALeft.bmp
ARight.bmp
ATop.bmp
AX.bmp
BringFront.bmp
Button.bmp
Center.bmp
Check.bmp
Combo.bmp
Copy.bmp
Cut.bmp
Delete.bmp
Down.bmp
Edit.bmp
Frame.bmp
Grid.bmp
GridSettings.bmp
HCenter.bmp
HScroll.bmp
HSL.bmp
HSpace.bmp
HSS.bmp
Left.bmp
List.bmp
New.bmp
Open.bmp
Paste.bmp
Picture.bmp
Preview.bmp
Progress.bmp
Props.bmp
Radio.bmp
Rectangle.bmp
Redo.bmp
Right.bmp
Save.bmp
SelAll.bmp
SelNone.bmp
SendBack.bmp
SL.bmp
Slider.bmp
Spin.bmp
SS.bmp
Tab.bmp
Text.bmp
Undo.bmp
Up.bmp
Validate.bmp
VCenter.bmp
VScroll.bmp
VSL.bmp
VSpace.bmp
VSS.bmp
Wand.bmp
CSDemo.suo
DaeDoe.bmp
MFCDemo
MFCDemo.dsp
MFCDemo.odl
MFCDemo.reg
res
DaeDoe.bmp
MFCDemo.ico
MFCDemoDoc.ico
Toolbar1.bmp
Toolbar2.bmp
Toolbar3.bmp
Wand.bmp
VBDemo
Bmp
ABottom.bmp
About.bmp
ALeft.bmp
ARight.bmp
ATop.bmp
AX.bmp
BringFront.bmp
Button.bmp
Center.bmp
Check.bmp
Combo.bmp
Copy.bmp
Cut.bmp
Delete.bmp
Down.bmp
Edit.bmp
Frame.bmp
Grid.bmp
GridSettings.bmp
HCenter.bmp
HScroll.bmp
HSL.bmp
HSpace.bmp
HSS.bmp
Left.bmp
List.bmp
New.bmp
Open.bmp
Paste.bmp
Picture.bmp
Preview.bmp
Progress.bmp
Props.bmp
Radio.bmp
Rectangle.bmp
Redo.bmp
Right.bmp
Save.bmp
SelAll.bmp
SelNone.bmp
SendBack.bmp
SL.bmp
Slider.bmp
Spin.bmp
SS.bmp
Tab.bmp
Text.bmp
Undo.bmp
Up.bmp
Validate.bmp
VCenter.bmp
VScroll.bmp
VSL.bmp
VSpace.bmp
VSS.bmp
Wand.bmp
DaeDoe.bmp
VBDemo.vbp
DDForms.chm
DDForms
Archive
FormEditorItems.rgs
vssver.scc
Constants.scr
DaeDoe.bmp
DDForms.def
DDForms.vcproj
DDForms.vcproj.vspscc
EventSinkPassThrough.rgs
FormEditor.bmp
FormEditor.rgs
FormEditorItemCollection.rgs
FormEditorItemDetails.rgs
FormViewer.bmp
FormViewer.rgs
FormViewerItemCollection.rgs
FormViewerItemDetails.rgs
mssccprj.scc
PropPageExtended.rgs
PropPageFormEditor.rgs
PropPageFormViewer.rgs
PropPageSimpleScriptEditor.rgs
SimpleScriptEditor.bmp
SimpleScriptEditor.rgs
vssver.scc
DDFormsTools
CodeMaxDriver
CodeMaxDriver.rgs
CodeMaxDriver.vcproj
CodeMaxDriver.vcproj.vspscc
CodeMaxDriverps.def
CodeMaxDriverPS.vcproj
CodeMaxDriverPS.vcproj.vspscc
mssccprj.scc
vssver.scc
CodeSenseDriver
CodeSenseDriver.rgs
CodeSenseDriver.vcproj
CodeSenseDriver.vcproj.vspscc
CodeSenseDriverps.def
CodeSenseDriverPS.vcproj
CodeSenseDriverPS.vcproj.vspscc
mssccprj.scc
vssver.scc
DDPropPageAll
DDPropPageAll.def
DDPropPageAll.vcproj
DDPropPageAll.vcproj.vspscc
mssccprj.scc
PropPageAll.rgs
vssver.scc
DDUnlock
DDUnlock.vcproj
DDUnlock.vcproj.vspscc
mssccprj.scc
vssver.scc
DDControlPack
DDButton.bmp
DDCheckBox.bmp
DDComboBox.bmp
DDControlPack.rgs
DDControlPack.vcproj
DDControlPack.vcproj.vspscc
DDHorzScrollBar.bmp
DDLabel.bmp
DDListBox.bmp
DDPicture.bmp
DDRadioButton.bmp
DDTextBox.bmp
DDVertScrollBar.bmp
mssccprj.scc
vssver.scc
Redistributables
Ansi
CodeMaxDriver.dll
CodeSenseDriver.dll
DDControlPack.dll
DDForms.dll
DDPropPageAll.dll
Unicode
CodeMaxDriver.dll
CodeSenseDriver.dll
DDControlPack.dll
DDForms.dll
DDPropPageAll.dll
// Script.cpp : Implementation of CScript
//
// Author : David Shepherd
//			Copyright (c) 2002, DaeDoe-Software
//
/////////////////////////////////////////////////////////////////////////////

#include "stdafx.h"
#include "DDForms.h"
#include "Script.h"

/////////////////////////////////////////////////////////////////////////////
// CScriptEditorLock

CScriptEditorLock::CScriptEditorLock(const CComPtr<IUnknown> &p) : m_p(p)
{
	// lock the editor
	if(m_p!=NULL)
	{
		if(!SUCCEEDED(m_p->LockExternal(TRUE)))
		{
			throw std::exception();
		}
	}
}

CScriptEditorLock::~CScriptEditorLock()
{
	// unlock the editor
	if(m_p!=NULL)
	{
		if(!SUCCEEDED(m_p->LockExternal(FALSE)))
		{
			ATLASSERT(FALSE);	// no recovery possible
		}
	}
}

/////////////////////////////////////////////////////////////////////////////
// CScript

std::wstring CScript::CreateEventHandlerName(
	const std::wstring &Source,const std::wstring &Event) const
{
	// create the event handler name
	return Source + L"_" + Event;
}

std::wstring CScript::CreateEventHandlerStartLocatorName(
	const std::wstring &Source,const std::wstring &Event) const
{
	// create the event handler start locator name
	std::wstringstream strm;
	strm << L"'@@DDF_EVENT_HANDLER_BEGIN";
	strm << L"(";
	strm << Source;
	strm << L",";
	strm << Event;
	strm << L")";
	return strm.str();
}

std::wstring CScript::CreateEventHandlerFinishLocatorName(
	const std::wstring &Source,const std::wstring &Event) const
{
	// create the event handler finish locator name
	std::wstringstream strm;
	strm << L"'@@DDF_EVENT_HANDLER_END";
	strm << L"(";
	strm << Source;
	strm << L",";
	strm << Event;
	strm << L")";
	return strm.str();
}

std::list<std::wstring> CScript::CreateEventHandlerBlock(
	const std::wstring &Source,const std::wstring &Event,
	const std::wstring &Parameters,const std::wstring &Body) const
{
	// create the event handler block
	std::list<std::wstring> EventHandlerBlock;
	// blank line
	EventHandlerBlock.push_back(L"");
	// start locator
	EventHandlerBlock.push_back(
		CreateEventHandlerStartLocatorName(Source,Event));
	// begin subroutine
	std::wstringstream strm;
	strm << L"Sub ";
	strm << CreateEventHandlerName(Source,Event);
	strm << L" ( ";
	strm << Parameters;
	strm << L" ) ";
	EventHandlerBlock.push_back(strm.str());
	// body
	SplitTokenisedString(Body,L"\r\n",EventHandlerBlock);
	// end subroutine
	EventHandlerBlock.push_back(L"End Sub");
	// finish locator
	EventHandlerBlock.push_back(
		CreateEventHandlerFinishLocatorName(Source,Event));
	// blank line
	EventHandlerBlock.push_back(L"");
	return EventHandlerBlock;
}

STDMETHODIMP CScript::AddEventHandler(BSTR Source, BSTR Event, BSTR Parameters)
{
IMP_BEGIN
	// prevent external updates to the editor
	CScriptEditorLock Lock(m_spEditor);

	// get the script buffer interface
	if(m_spEditor==NULL)
	{
		throw CHResult(E_FAIL);
	}
	CComQIPtr<IScriptBuffer> spBuffer(m_spEditor);
	if(spBuffer==NULL)
	{
		throw CHResult(E_FAIL);
	}
	// check the event handler does not already exist
	BOOL Found=FALSE;
	DWORD Line=0;
	if(!SUCCEEDED(spBuffer->FindText(0,CreateEventHandlerStartLocatorName(
		BSTR2W(Source),BSTR2W(Event)).c_str(),&Found,&Line)))
	{
		throw CHResult(E_FAIL);
	}
	if(Found)
	{
		throw CHResult(E_FAIL);
	}
	// get the number of lines in the editor
	DWORD LineCount=0;
	if(!SUCCEEDED(spBuffer->GetLineCount(&LineCount)))
	{
		throw CHResult(E_FAIL);
	}
	// add the event handler
	std::list<std::wstring> EventHandlerBlock=
		CreateEventHandlerBlock(BSTR2W(Source),BSTR2W(Event),
			BSTR2W(Parameters),L"\t'Todo : Add the event handler here!");
	if(!SUCCEEDED(spBuffer->InsertLines(LineCount,EventHandlerBlock.size(),
		ComClientStringArrayToServer(EventHandlerBlock).get())))
	{
		throw CHResult(E_FAIL);
	}
IMP_END
	return RetVal;
}

STDMETHODIMP CScript::IsEventHandled(BSTR Source, BSTR Event, VARIANT_BOOL *pRet)
{
IMP_BEGIN
	// prevent external updates to the editor
	CScriptEditorLock Lock(m_spEditor);

	// check parameters
	if(pRet==NULL)
	{
		throw CHResult(E_POINTER);
	}
	// get the script buffer interface
	if(m_spEditor==NULL)
	{
		throw CHResult(E_FAIL);
	}
	CComQIPtr<IScriptBuffer> spBuffer(m_spEditor);
	if(spBuffer==NULL)
	{
		throw CHResult(E_FAIL);
	}
	// determine if the event handler exists
	BOOL Found=FALSE;
	DWORD Line=0;
	if(!SUCCEEDED(spBuffer->FindText(0,CreateEventHandlerStartLocatorName(
		BSTR2W(Source),BSTR2W(Event)).c_str(),&Found,&Line)))
	{
		throw CHResult(E_FAIL);
	}
	*pRet=B2VB(Found);
IMP_END
	return RetVal;
}

STDMETHODIMP CScript::EditEventHandler(BSTR Source, BSTR Event)
{
IMP_BEGIN
	// prevent external updates to the editor
	CScriptEditorLock Lock(m_spEditor);

	// get the script buffer interface
	if(m_spEditor==NULL)
	{
		throw CHResult(E_FAIL);
	}
	CComQIPtr<IScriptBuffer> spBuffer(m_spEditor);
	if(spBuffer==NULL)
	{
		throw CHResult(E_FAIL);
	}
	// find the event handler
	BOOL Found=FALSE;
	DWORD Line=0;
	if(!SUCCEEDED(spBuffer->FindText(0,CreateEventHandlerStartLocatorName(
		BSTR2W(Source),BSTR2W(Event)).c_str(),&Found,&Line)))
	{
		throw CHResult(E_FAIL);
	}
	if(Found==FALSE)
	{
		throw CHResult(E_FAIL);
	}
	// get the script navigation interface
	CComQIPtr<IScriptNavigation> spNavigation(spBuffer);
	if(spNavigation==NULL)
	{
		throw CHResult(E_FAIL);
	}
	// go to the event handler line
	if(!SUCCEEDED(spNavigation->GoToLine(Line)))
	{
		throw CHResult(E_FAIL);
	}
IMP_END
	return RetVal;
}

STDMETHODIMP CScript::EditLine(long Line)
{
IMP_BEGIN
	// prevent external updates to the editor
	CScriptEditorLock Lock(m_spEditor);

	// get the script navigation interface
	if(m_spEditor==NULL)
	{
		throw CHResult(E_FAIL);
	}
	CComQIPtr<IScriptNavigation> spNavigation(m_spEditor);
	if(spNavigation==NULL)
	{
		throw CHResult(E_FAIL);
	}
	// go to the line
	// todo : check the line is valid
	if(!SUCCEEDED(spNavigation->GoToLine(Line)))
	{
		throw CHResult(E_FAIL);
	}
IMP_END
	return RetVal;
}

STDMETHODIMP CScript::Reset()
{
IMP_BEGIN
	// prevent external updates to the editor
	CScriptEditorLock Lock(m_spEditor);

	// get the script buffer interface
	if(m_spEditor==NULL)
	{
		throw CHResult(E_FAIL);
	}
	CComQIPtr<IScriptBuffer> spBuffer(m_spEditor);
	if(spBuffer==NULL)
	{
		throw CHResult(E_FAIL);
	}
	// get the number of lines in the editor
	DWORD LineCount=0;
	if(!SUCCEEDED(spBuffer->GetLineCount(&LineCount)))
	{
		throw CHResult(E_FAIL);
	}
	// delete all lines
	if(!SUCCEEDED(spBuffer->DeleteLines(0,LineCount)))
	{
		throw CHResult(E_FAIL);
	}
IMP_END
	return RetVal;
}

STDMETHODIMP CScript::LoadFromStream(IUnknown *pUnknown,long StreamVersion)
{
IMP_BEGIN
	// prevent external updates to the editor
	CScriptEditorLock Lock(m_spEditor);

	// check parameters
	if(pUnknown==NULL)
	{
		throw CHResult(E_POINTER);
	}
	CComQIPtr<IStream> spStream(pUnknown);
	if(spStream==NULL)
	{
		throw CHResult(E_FAIL);
	}
	// get the script buffer interface
	if(m_spEditor==NULL)
	{
		throw CHResult(E_FAIL);
	}
	CComQIPtr<IScriptBuffer> spBuffer(m_spEditor);
	if(spBuffer==NULL)
	{
		throw CHResult(E_FAIL);
	}
	// reset the script
	if(!SUCCEEDED(Reset()))
	{
		throw CHResult(E_FAIL);
	}
	// read in the script header
	CStreamScriptHeader ScriptHeader;
	ScriptHeader.ReadFromStream(spStream.p,StreamVersion);
	// read in the lines
	std::vector<std::wstring> Lines;
	for(long l=0; l<(long)ScriptHeader.m_LineCount; l++)
	{
		std::wstring Line;		// next line
		ReadFromStream(spStream.p,Line);
		Lines.push_back(Line);	// update the container
	}
	// transfer the lines to the editor
	if(!SUCCEEDED(spBuffer->InsertLines(
		0,ScriptHeader.m_LineCount,ComClientStringArrayToServer(Lines).get())))
	{
		throw CHResult(E_FAIL);
	}
	// remove the trailing blank line
	if(!SUCCEEDED(spBuffer->DeleteLines(ScriptHeader.m_LineCount,1)))
	{
		throw CHResult(E_FAIL);
	}
IMP_END
	return RetVal;
}

STDMETHODIMP CScript::SaveToStream(IUnknown *pUnknown)
{
IMP_BEGIN
	// prevent external updates to the editor
	CScriptEditorLock Lock(m_spEditor);

	// check parameters
	if(pUnknown==NULL)
	{
		throw CHResult(E_POINTER);
	}
	CComQIPtr<IStream> spStream(pUnknown);
	if(spStream==NULL)
	{
		throw CHResult(E_FAIL);
	}
	// get the script buffer interface
	if(m_spEditor==NULL)
	{
		throw CHResult(E_FAIL);
	}
	CComQIPtr<IScriptBuffer> spBuffer(m_spEditor);
	if(spBuffer==NULL)
	{
		throw CHResult(E_FAIL);
	}
	// get the number of lines in the editor
	DWORD LineCount=0;
	if(!SUCCEEDED(spBuffer->GetLineCount(&LineCount)))
	{
		throw CHResult(E_FAIL);
	}
	// transfer the lines from the editor
	LPCOLESTR *pLines=NULL;
	if(!SUCCEEDED(spBuffer->GetLines(0,LineCount,(LPOLESTR**)&pLines)))
	{
		throw CHResult(E_FAIL);
	}
	std::vector<std::wstring> Lines;	// local storage
	ComClientStringArrayFromServer(LineCount,pLines,Lines);
	// create the script header
	CStreamScriptHeader ScriptHeader;
	ScriptHeader.m_LineCount=LineCount;
	// write out the script header
	ScriptHeader.WriteToStream(spStream.p);
	// write out the lines
	for(long l=0; l<(long)ScriptHeader.m_LineCount; l++)
	{
		WriteToStream(spStream.p,Lines.at(l));
	}
IMP_END
	return RetVal;
}

STDMETHODIMP CScript::get_Text(BSTR *pVal)
{
IMP_BEGIN
	// prevent external updates to the editor
	CScriptEditorLock Lock(m_spEditor);

	// check parameters
	if(pVal==NULL)
	{
		throw CHResult(E_POINTER);
	}
	// get the script buffer interface
	if(m_spEditor==NULL)
	{
		throw CHResult(E_FAIL);
	}
	CComQIPtr<IScriptBuffer> spBuffer(m_spEditor);
	if(spBuffer==NULL)
	{
		throw CHResult(E_FAIL);
	}
	// get the number of lines in the editor
	DWORD LineCount=0;
	if(!SUCCEEDED(spBuffer->GetLineCount(&LineCount)))
	{
		throw CHResult(E_FAIL);
	}
	// transfer the lines from the editor
	LPCOLESTR *pLines=NULL;
	if(!SUCCEEDED(spBuffer->GetLines(0,LineCount,(LPOLESTR**)&pLines)))
	{
		throw CHResult(E_FAIL);
	}
	std::vector<std::wstring> Lines;	// local storage
	ComClientStringArrayFromServer(LineCount,pLines,Lines);
	// create the text
	std::wstring Text;
	for(long l=0; l<(long)LineCount; l++)
	{
		Text+=Lines.at(l);
		if(l < (long)(LineCount-1))		// if more lines follow
		{
			Text+=L"\r\n";
		}
	}
	// return the text
	*pVal=CComBSTR(Text.c_str()).Detach();
IMP_END
	return RetVal;
}

STDMETHODIMP CScript::put_Text(BSTR newVal)
{
IMP_BEGIN
	// prevent external updates to the editor
	CScriptEditorLock Lock(m_spEditor);

	// get the script buffer interface
	if(m_spEditor==NULL)
	{
		throw CHResult(E_FAIL);
	}
	CComQIPtr<IScriptBuffer> spBuffer(m_spEditor);
	if(spBuffer==NULL)
	{
		throw CHResult(E_FAIL);
	}
	// reset the script
	if(!SUCCEEDED(Reset()))
	{
		throw CHResult(E_FAIL);
	}
	// split the text into seperate lines
	std::vector<std::wstring> Lines;
	SplitTokenisedString(BSTR2W(newVal),L"\r\n",Lines);
	// transfer the lines to the editor
	if(!SUCCEEDED(spBuffer->InsertLines(
		0,Lines.size(),ComClientStringArrayToServer(Lines).get())))
	{
		throw CHResult(E_FAIL);
	}
	// remove the trailing blank line
	if(!SUCCEEDED(spBuffer->DeleteLines(Lines.size(),1)))
	{
		throw CHResult(E_FAIL);
	}
IMP_END
	return RetVal;
}

STDMETHODIMP CScript::get_Editor(IUnknown **ppUnknown)
{
IMP_BEGIN
	// check parameters
	if(ppUnknown==NULL)
	{
		throw CHResult(E_POINTER);
	}
	// get the script editor
	*ppUnknown=m_spEditor;
	if(*ppUnknown!=NULL)	// add ref it
	{
		(void)(*ppUnknown)->AddRef();
	}
IMP_END
	return RetVal;
}

STDMETHODIMP CScript::put_Editor(IUnknown *pUnknown)
{
IMP_BEGIN
	// set the script editor
	m_spEditor=pUnknown;
IMP_END
	return RetVal;
}

STDMETHODIMP CScript::AddEventHandlerEx(
	BSTR Source,BSTR Event,BSTR Parameters,BSTR Body)
{
IMP_BEGIN
	// prevent external updates to the editor
	CScriptEditorLock Lock(m_spEditor);

	// get the script buffer interface
	if(m_spEditor==NULL)
	{
		throw CHResult(E_FAIL);
	}
	CComQIPtr<IScriptBuffer> spBuffer(m_spEditor);
	if(spBuffer==NULL)
	{
		throw CHResult(E_FAIL);
	}
	// check the event handler does not already exist
	BOOL Found=FALSE;
	DWORD Line=0;
	if(!SUCCEEDED(spBuffer->FindText(0,CreateEventHandlerStartLocatorName(
		BSTR2W(Source),BSTR2W(Event)).c_str(),&Found,&Line)))
	{
		throw CHResult(E_FAIL);
	}
	if(Found)
	{
		throw CHResult(E_FAIL);
	}
	// get the number of lines in the editor
	DWORD LineCount=0;
	if(!SUCCEEDED(spBuffer->GetLineCount(&LineCount)))
	{
		throw CHResult(E_FAIL);
	}
	// add the event handler
	std::list<std::wstring> EventHandlerBlock=
		CreateEventHandlerBlock(BSTR2W(Source),BSTR2W(Event),
			BSTR2W(Parameters),BSTR2W(Body));
	if(!SUCCEEDED(spBuffer->InsertLines(LineCount,EventHandlerBlock.size(),
		ComClientStringArrayToServer(EventHandlerBlock).get())))
	{
		throw CHResult(E_FAIL);
	}
IMP_END
	return RetVal;
}

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)

Share

About the Author

DaveShep
Web Developer
United Kingdom United Kingdom
No Biography provided

You may also be interested in...

Permalink | Advertise | Privacy | Cookies | Terms of Use | Mobile
Web04-2016 | 2.8.181114.1 | Last Updated 1 Aug 2009
Article Copyright 2005 by DaveShep
Everything else Copyright © CodeProject, 1999-2018
Layout: fixed | fluid