
#include "stdafx.h"
#include "TableEx.h"

#ifdef VK_1CPP_SourceTable

//CInitTableWrap InitTableWrap; //artbear

CMapStringToPtr DocNamesArrayArtbear;
struct SDocNames{
	DWORD id;
	CString strFolder;
};

class CSheetViewMy: public CSheetView
{
public:
	virtual void  OnInitialUpdate(void)
	{
		CSheetView::OnInitialUpdate();
	};

};

typedef int(CBLContext::*P_CONT_CALLASP)(int,CValue * *);
typedef int(CBLContext::*P_CONT_CALLASF)(int,CValue &,CValue * *);
typedef int(CBLContext::*P_CONT_GETNPARAMS)(int);
typedef int(CBLContext::*P_CONT_HASRETVAL)(int);
typedef int(CBLContext::*P_CONT_GETPARAMDEFVALUE)(int,int,CValue*);
typedef void(CBLContext::*P_CONT_DESTRUCTOR)(void);

static P_CONT_CALLASP pCallAsProcDbl;

static P_CONT_CALLASP pCallAsProc;
static P_CONT_CALLASF pCallAsFunc;
static P_CONT_GETNPARAMS pGetNParams;
static P_CONT_GETPARAMDEFVALUE pGetParamDefValue;
static P_CONT_HASRETVAL pHasRetVal;
static P_CONT_DESTRUCTOR pDestructor;

int iCountStream = 0;

int procGetAllTypedItem(class CString &str,long l1,long l2,enum PageType pt)
{
	if(str.CollateNoCase("ModuleText") == 0)
		return 1;

	CMetaDataCont *pMD = GetMetaData();
	CMetaDataObj* pMDO = pMD->FindObject(l1);
	CString str1 = GetModuleFullName(l1, str, 0, pMD);
	str1.MakeUpper();

	SDocNames *pDocNames = NULL;
	pDocNames = new SDocNames;
	pDocNames->id = l1;
	pDocNames->strFolder = str;
	DocNamesArrayArtbear.SetAt(str1,pDocNames);

	return 1;
}

int CTableWrapEx::SetTable(class CValue **ppValue)
{
	// возвращает:
	// 0 - таблица установлена
	// 1 - необходим вызов штатной обработки
	// 2 - ошибка пути
	// 3 - ошибка имени таблицы
	// 4 - прочие ошибки
	int res = 1;
	CString strPath = ppValue[1]->GetString();
	CString strName = ppValue[0]->GetString();
	strPath = AllTrim(strPath);
	if(!strPath.IsEmpty())
	{
		strPath.MakeUpper();
		int nn = strPath.Find("@MD");
		if(nn >= 0)
		{
			CString strPathTemp = strPath.Left(nn);
			strPath = CString("MD.Обработка.")+AllTrim(strPathTemp)+".Форма";
			strPath.MakeUpper();
		}

		if(strPath.Left(3).CompareNoCase("MD.") == 0)
		{
			// внутри md
			CString strDoc = strPath.Mid(3);
			SDocNames *pDocNames = NULL;
			if(DocNamesArrayArtbear.Lookup(strDoc, (void*&)pDocNames))
			{
				CApp7* pApp7 = (CApp7*) AfxGetApp();
				CProfile7* pProfile7 = pApp7->GetProps();
				CString Prop8 = pProfile7->GetStringProp(0x08); // полный путь к файлу 1Cv7.MD (с именем файла)
				CString strFull = "";
				strFull.Format("%s\\%s\\%s_Number%d\\WorkBook",Prop8,pDocNames->strFolder,pDocNames->strFolder,pDocNames->id);
				CWorkBookDoc* pDoc = (CWorkBookDoc*)CConfigCont::PathToDocument(strFull);
				if(pDoc == NULL)
				{
					CString str;
					CTypedCont *pTypedCont;
					if(CConfigCont::IDToPath(pDocNames->id,pDocNames->strFolder,str,&pTypedCont,0))
						pDoc = pTypedCont->GetWorkBook();
				}
				if(pDoc)
				{
					if(strName.IsEmpty())
					{
						CStringArray cStringArray;
						pDoc->GetTablesName(cStringArray);
						if(cStringArray.GetSize() > 0)
							strName = cStringArray.GetAt(0);
					}

					int n = 0;
					CSheetDoc* pSheetDoc = (CSheetDoc*)pDoc->FindDocument(strName, &n);
					if(pSheetDoc)
					{
						m_pSheetDocIn = pSheetDoc;
						DWORD* pdw = (DWORD*)pSheetDoc;
						m_pSheet = (CSheet*)&pdw[0x2C];
						if(m_pSheetDocOut && (CTemplate7::GetDocumentID(m_pSheetDocOut) != 0))
						{
							m_pSheetDocOut->UpdateAllViews(NULL, 8, NULL);
						}
						res = 0;
					}
					else
						res = 3;
				}
				else
					res = 4;
			}
			else
				res = 2;
		}
		else
		{
			if(strPath.Right(3).CompareNoCase("MXL") == 0)
			{
				*ppValue[0] = strPath;
				return 1;
			}
			// из внешнего отчета
			CTemplate7* pTempl = CTemplate7::FromID(0xBA);

			if(pTempl == NULL)
				return 4;

			POSITION pos = pTempl->GetFirstDocPosition();
			while(pos)
			{
				CWorkBookDoc* pTemplDoc = (CWorkBookDoc*)pTempl->GetNextDoc(pos);
				if(pTemplDoc)
				{
					CString strSrc = pTemplDoc->GetSourcePathName();
					if(strSrc.CompareNoCase(strPath) == 0)
					{
						CStringArray cStringArray;
						pTemplDoc->GetTablesName(cStringArray);
						if(strName.IsEmpty())
						{
							if(cStringArray.GetSize() > 0)
								strName = cStringArray.GetAt(0);
						}
						int n = 0;
						CSheetDoc* pSheetDoc = (CSheetDoc*)pTemplDoc->FindDocument(strName, &n);
						if(pSheetDoc)
						{
							m_pSheetDocIn = pSheetDoc;
							DWORD* pdw = (DWORD*)pSheetDoc;
							m_pSheet = (CSheet*)&pdw[0x2C];
							if(m_pSheetDocOut && (CTemplate7::GetDocumentID(m_pSheetDocOut) != 0))
							{
								m_pSheetDocOut->UpdateAllViews(NULL, 8, NULL);
							}
							return 0;
						}
						return 3;
					}
				}
			}

			pTempl = CTemplate7::FromID(0xA1);

			if(pTempl == NULL)
				return 4;

			if(strName.IsEmpty())
				strName = "Moxel WorkPlace";

			COleStorage pOleStorage(NULL);
			CFileException excepFile;
			if(pOleStorage.Open(strPath, CFile::shareExclusive, &excepFile))
			{
				COleStreamFile * pOleStream = pOleStorage.OpenStream(CContainer::GetContentsStreamName(), CFile::shareExclusive, &excepFile);
				if(pOleStream)
				{
					DWORD StreamLen = pOleStream->GetLength();
					char* buf = (char*)malloc(StreamLen);
					pOleStream->Read(buf, StreamLen);
					CItemList list1;
					int n = 0;
					CString strStreamName = "";
					list1.LoadFromString(buf, &n);
					for(int j = list1.FindGenericItem("Moxcel.Worksheet", -1); j >= 0; j = list1.FindGenericItem("Moxcel.Worksheet", ++j))
					{
						CItem* pItem = (CItem*)list1.GetItemAt(j);
						int w = pItem->WhatIsIt();
						if(w == 1)
						{
							CItem* pItem1 = (CItem*)((CGenericItem*)pItem)->m_array.GetAt(1);
							CItem* pItem2 = (CItem*)((CGenericItem*)pItem)->m_array.GetAt(2);
							if((strName.CompareNoCase(pItem2->m_str) == 0) ||
								((pItem2->m_str.CompareNoCase("Moxel WorkPlace") == 0) &&
								 (strName.CompareNoCase("Таблица") == 0)))
							{
								strStreamName = pItem1->m_str;
							}
						}
					}
					free(buf);
					pOleStorage.ReleaseStream(pOleStream, TRUE);
					if(strStreamName.IsEmpty() == FALSE)
					{
						if(pOleStream = pOleStorage.OpenStream(strStreamName, CFile::shareExclusive, &excepFile))
						{
							CArchive ar(pOleStream, CArchive::load);
							if(m_pSheetDocIn)
							{
								// пытаемся очистить ранее созданные нами CSheetDoc
								if(CTemplate7::GetDocumentID(m_pSheetDocIn) == 0)
									delete m_pSheetDocIn;
							}
							m_pSheetDocIn = (CSheetDoc*)CSheetDoc::CreateObject();//new CSheetDoc;
//							CTemplate7::RegisterDocument(m_pSheetDocIn);
//							pTempl->AddDocument(m_pSheetDocIn);

							m_pSheetDocIn->DeleteContents();
							m_pSheetDocIn->Serialize(ar);
							DWORD* pdw = (DWORD*)m_pSheetDocIn;
							m_pSheet = (CSheet*)&pdw[0x2C];
							if(m_pSheetDocOut && (CTemplate7::GetDocumentID(m_pSheetDocOut) != 0))
							{
								m_pSheetDocOut->UpdateAllViews(NULL, 8, NULL);
							}
							CTemplate7::UnRegisterDocument(m_pSheetDocIn);
							pOleStorage.ReleaseStream(pOleStream, TRUE);
							res = 0;
						}
						else
							res = 4;
					}
					else
						res = 3;
				}
				else
					res = 4;
				pOleStorage.Release(TRUE);
			}
			else
				res = 2;
		}
	}
	return res;
}

static DWORD dwCSheetDocVTable = 0;
static int iMethNum_SourceTable = -1;
static int iMethNum_Options = -1;

void CTableWrapEx::DecrRef(void)
{
	int aRefCount = m_RefCount;
	CSheetDoc* pSheetDoc = m_pSheetDocIn;

	(this->*pDestructor)();

	// пытаемся очистить ранее созданные нами CSheetDoc
	if((--aRefCount == 0) && pSheetDoc && (*(DWORD*)pSheetDoc == dwCSheetDocVTable) && (CTemplate7::GetDocumentID(pSheetDoc) == 0))
			delete pSheetDoc;
}

int CTableWrapEx::CallAsProc(int iMethNum,class CValue **ppValue)
{
	//CString strMeth = this->GetMethodName(iMethNum,1);
	//if(strMeth.CompareNoCase("ИсходнаяТаблица") == 0)
	if(iMethNum == iMethNum_SourceTable)
	{
		int res = SetTable(ppValue);
		int bCallExept = ppValue[2]->GetNumeric();
		if(bCallExept == 0)
			return S_OK;

		if(res == 0)
			return S_OK;
		else if(res != 1)
		{
			// 2 - ошибка пути
			// 3 - ошибка имени таблицы
			// 4 - прочие ошибки
			if(res == 2)
				CBLModule::RaiseExtRuntimeError("Неверно задан путь к исходной таблице!", mmRedErr);
			else if(res == 3)
				CBLModule::RaiseExtRuntimeError("Неверно задано имя исходной таблицы!", mmRedErr);
			else
				CBLModule::RaiseExtRuntimeError("Ошибка при установке исходной таблицы!", mmRedErr);
			return S_FALSE;
		}
	}
	//else if(strMeth.CompareNoCase("Опции") == 0)
	else if(iMethNum == iMethNum_Options)
	{
		int ret = (this->*pCallAsProc)(iMethNum, ppValue);

		POSITION pos = m_pSheetDocOut->GetFirstViewPosition();
		while(pos)
		{
			CSheetViewMy* pSheetView = (CSheetViewMy*)m_pSheetDocOut->GetNextView(pos);
			CSheetSelection pSel = *(pSheetView->GetTailSelection());
			int nPosVert = pSheetView->GetScrollPos(SB_VERT);
			int nPosHorz = pSheetView->GetScrollPos(SB_HORZ);
			pSheetView->OnInitialUpdate();
			pSheetView->ClearSelection();
			pSheetView->SelectArea(pSel);
			pSheetView->ScrollToPosition(nPosHorz,nPosVert);
		}

		return ret;
	}

	return (this->*pCallAsProc)(iMethNum, ppValue);
};

int CTableWrapEx::CallAsFunc(int iMethNum,class CValue & rValue,class CValue **ppValue)
{
	//CString strMeth = this->GetMethodName(iMethNum,1);
	//if(strMeth.CompareNoCase("ИсходнаяТаблица") == 0)
	if(iMethNum == iMethNum_SourceTable)
	{
		int res = SetTable(ppValue);
		int bCallExept = ppValue[2]->GetNumeric();
		rValue = res;

		if(bCallExept == 0)
			return S_OK;

		if(res == 0)
		{
			rValue = 1L;
			return S_OK;
		}
		else if(res != 1)
		{
			// 2 - ошибка пути
			// 3 - ошибка имени таблицы
			// 4 - прочие ошибки
			if(res == 2)
				CBLModule::RaiseExtRuntimeError("Неверно задан путь к исходной таблице!", mmRedErr);
			else if(res == 3)
				CBLModule::RaiseExtRuntimeError("Неверно задано имя исходной таблицы!", mmRedErr);
			else
				CBLModule::RaiseExtRuntimeError("Ошибка при установке исходной таблицы!", mmRedErr);
			return S_FALSE;
		}

		rValue = 2L;
		return (this->*pCallAsProc)(iMethNum, ppValue);
	}

	return (this->*pCallAsFunc)(iMethNum, rValue, ppValue);
};

int CTableWrapEx::HasRetVal(int iMethNum)const
{
	//CString strMeth = this->GetMethodName(iMethNum,1);
	//if(strMeth.CompareNoCase("ИсходнаяТаблица") == 0)
	if(iMethNum == iMethNum_SourceTable)
	{
		return 1;
	}

	return (this->*pHasRetVal)(iMethNum);
};

int CTableWrapEx::GetNParams(int iMethNum)const
{
	//CString strMeth = this->GetMethodName(iMethNum,1);
	//if(strMeth.CompareNoCase("ИсходнаяТаблица") == 0)
	if(iMethNum == iMethNum_SourceTable)
	{
		return 3;
	}

	return (this->*pGetNParams)(iMethNum);
};

int CTableWrapEx::GetParamDefValue(int iMethNum,int iParamNum,class CValue * pDefValue)const
{
	//CString strMeth = this->GetMethodName(iMethNum,1);
	//if(strMeth.CompareNoCase("ИсходнаяТаблица") == 0)
	if(iMethNum == iMethNum_SourceTable)
	{
		if(iParamNum == 1)
		{
			*pDefValue = "";
			return 1;
		}
		if(iParamNum == 2)
		{
			*pDefValue = 1;
			return 1;
		}
	}

	return (this->*pGetParamDefValue)(iMethNum, iParamNum, pDefValue);
};

union{
	void* pV;
	P_CONT_CALLASP pCallAsProcU;
	P_CONT_CALLASF pCallAsFuncU;
	P_CONT_GETNPARAMS pGetNParamsU;
	P_CONT_GETPARAMDEFVALUE pGetParamDefValueU;
	P_CONT_HASRETVAL pHasRetValU;
	P_CONT_DESTRUCTOR pDestructorU;
	DWORD dwF;
} ConvCallTab;

void CTableWrapEx::SetTableWrap(CBLContext* pTabCont)
{
	CTableWrapEx* pTableWrapEx;
	pTableWrapEx = new CTableWrapEx;

	DWORD old;
	VirtualProtect(((BYTE*)*((DWORD*)pTabCont)),0x100,PAGE_EXECUTE_READWRITE,&old);

	CSheetDoc mSheetDoc;
	dwCSheetDocVTable = *(DWORD*)&mSheetDoc;
	//*/
	ConvCallTab.dwF = *(((DWORD*)*(DWORD*)pTabCont)+0x06);
	pDestructor = ConvCallTab.pDestructorU;
	ConvCallTab.dwF = *(((DWORD*)*(DWORD*)pTableWrapEx)+0x06);
	P_CONT_DESTRUCTOR pD = ConvCallTab.pDestructorU;
	DWORD dwDestructor = *(DWORD*)&pD;
	((DWORD*)*((DWORD*)pTabCont))[0x06] = dwDestructor;
	//*/

	//*/
	ConvCallTab.dwF = *(((DWORD*)*(DWORD*)pTabCont)+0x20);
	pCallAsFunc = ConvCallTab.pCallAsFuncU;
	ConvCallTab.dwF = *(((DWORD*)*(DWORD*)pTableWrapEx)+0x20);
	P_CONT_CALLASF pF = ConvCallTab.pCallAsFuncU;
	DWORD dwCallAsFunc = *(DWORD*)&pF;
	((DWORD*)*((DWORD*)pTabCont))[0x20] = dwCallAsFunc;
	//*/

	//*/
	ConvCallTab.dwF = *(((DWORD*)*(DWORD*)pTabCont)+0x1F);
	pCallAsProc = ConvCallTab.pCallAsProcU;
	ConvCallTab.dwF = *(((DWORD*)*(DWORD*)pTableWrapEx)+0x1F);
	P_CONT_CALLASP pP = ConvCallTab.pCallAsProcU;
	DWORD dwCallAsProc = *(DWORD*)&pP;
	((DWORD*)*((DWORD*)pTabCont))[0x1F] = dwCallAsProc;
	//*/

	//*/
	ConvCallTab.dwF = *(((DWORD*)*(DWORD*)pTabCont)+0x1C);
	pGetNParams = ConvCallTab.pGetNParamsU;
	ConvCallTab.dwF = *(((DWORD*)*(DWORD*)pTableWrapEx)+0x1C);
	P_CONT_GETNPARAMS pGP = ConvCallTab.pGetNParamsU;
	DWORD dwGetNParams = *(DWORD*)&pGP;
	((DWORD*)*((DWORD*)pTabCont))[0x1C] = dwGetNParams;
	//*/

	//*/
	ConvCallTab.dwF = *(((DWORD*)*(DWORD*)pTabCont)+0x1D);
	pGetParamDefValue = ConvCallTab.pGetParamDefValueU;
	ConvCallTab.dwF = *(((DWORD*)*(DWORD*)pTableWrapEx)+0x1D);
	P_CONT_GETPARAMDEFVALUE pGD = ConvCallTab.pGetParamDefValueU;
	DWORD dwGetParamDefValue = *(DWORD*)&pGD;
	((DWORD*)*((DWORD*)pTabCont))[0x1D] = dwGetParamDefValue;
	//*/

	//*/
	ConvCallTab.dwF = *(((DWORD*)*(DWORD*)pTabCont)+0x1E);
	pHasRetVal = ConvCallTab.pHasRetValU;
	ConvCallTab.dwF = *(((DWORD*)*(DWORD*)pTableWrapEx)+0x1E);
	P_CONT_HASRETVAL pHRV = ConvCallTab.pHasRetValU;
	DWORD dwHasRetVal = *(DWORD*)&pHRV;
	((DWORD*)*((DWORD*)pTabCont))[0x1E] = dwHasRetVal;
	//*/

	iMethNum_SourceTable = pTabCont->FindMethod("SourceTable");
	iMethNum_Options = pTabCont->FindMethod("Options");
	delete pTableWrapEx;

	CTableWrapExDbl* pTableWrapExDbl;
	pTableWrapExDbl = new CTableWrapExDbl;

	//*/
	/* artbear
	CGroupContext* pGrCont;
	pGrCont = (CGroupContext*)(RUNTIME_CLASS(CGroupContext)->CreateObject());
	*/
	{
		CBLPtr<CGroupContext> ptrGrCont("ГрупповойКонтекст");
		if(ptrGrCont)
		{
			CGroupContext* pGrCont = ptrGrCont;// artbear

			VirtualProtect(((BYTE*)*((DWORD*)pGrCont)),0x100,PAGE_EXECUTE_READWRITE,&old);

			ConvCallTab.dwF = *(((DWORD*)*(DWORD*)pGrCont)+0x1F);
			pCallAsProcDbl = ConvCallTab.pCallAsProcU;
			ConvCallTab.dwF = *(((DWORD*)*(DWORD*)pTableWrapExDbl)+0x1F);
			P_CONT_CALLASP pP = ConvCallTab.pCallAsProcU;
			DWORD dwCallAsProc = *(DWORD*)&pP;
			((DWORD*)*((DWORD*)pGrCont))[0x1F] = dwCallAsProc;

			// delete pGrCont; // artbear
		}
	}
	//*/

	delete pTableWrapExDbl;

	iCountStream = 0;
	CConfigCont::GetAllTypedItem(procGetAllTypedItem,0,ptDialog,0);
};

int CTableWrapExDbl::CallAsProc(int iMethNum,class CValue **ppValue)
{
	CString strMeth = this->GetMethodName(iMethNum,1);
	if(strMeth.CompareNoCase("Опции") == 0)
	{
		int ret = (this->*pCallAsProcDbl)(iMethNum, ppValue);

		int sz = GetSize();
		for(int i = 0; i < sz; i++)
		{
			CBLContext* pCont = GetContext(i);
			if(pCont)
			{
				int n = pCont->FindMethod(strMeth);
				if(n >= 0)
				{
					CTableWrapEx* pTabl = (CTableWrapEx*)pCont;
					POSITION pos = pTabl->m_pSheetDocOut->GetFirstViewPosition();
					while(pos)
					{
						CSheetViewMy* pSheetView = (CSheetViewMy*)pTabl->m_pSheetDocOut->GetNextView(pos);
						pSheetView->OnInitialUpdate();
					}
				}
			}
		}

		return ret;
	}

	return (this->*pCallAsProcDbl)(iMethNum, ppValue);
};

void CInitTableWrap::Init(void)
{
#ifdef VK_1CPP_SourceTable
//	if (!pMainAddIn->Property["EnableTableSourceTable"])
//		return ;

	// перехват объекта Таблица
	CBLContext* pTablCont = CBLContext::CreateInstance("Table");
	if(pTablCont)
		CTableWrapEx::SetTableWrap(pTablCont);
#endif
}
#endif

#ifdef ONECPP_ARTBEAR

/******************************************************************************************/
// CTableEx class implementation
/******************************************************************************************/

/*enum {
    procFromString,
    funcToString,
    funcIsNil,
    procSetNil,
    funcIsEqual,
    procNew,
    lastDBGUIDMethod
};*/

class CObjID CTableEx::ObjID;
bool CTableEx::bIsInit = false;

//class CParamDefs CTableEx::defFnNames;

IMPLEMENT_DYNCREATE(CTableEx, CBLContext);

static DWORD dwCSheetDocVTable = 0;
static int iMethNum_SourceTable = -1;
static int iMethNum_Options = -1;


CMapStringToPtr DocNamesArray1;
struct SDocNames1{
	DWORD id;
	CString strFolder;
};

class CSheetViewMy1: public CSheetView
{
public:
	virtual void  OnInitialUpdate(void)
	{
		CSheetView::OnInitialUpdate();
	};

};

int procGetAllTypedItem1(class CString &str,long l1,long l2,enum PageType pt)
{
	if(str.CollateNoCase("ModuleText") == 0)
		return 1;

	CMetaDataCont *pMD = GetMetaData();
	CMetaDataObj* pMDO = pMD->FindObject(l1);
	CString str1 = GetModuleFullName(l1, str, 0, pMD);
	str1.MakeUpper();

	SDocNames1 *pDocNames = NULL;
	pDocNames = new SDocNames1;
	pDocNames->id = l1;
	pDocNames->strFolder = str;
	DocNamesArray1.SetAt(str1,pDocNames);

	return 1;
}


int CTableEx::SetTable(class CValue **ppValue)
{
	// возвращает:
	// 0 - таблица установлена
	// 1 - необходим вызов штатной обработки
	// 2 - ошибка пути
	// 3 - ошибка имени таблицы
	// 4 - прочие ошибки
	int res = 1;
	CString strPath = ppValue[1]->GetString();
	CString strName = ppValue[0]->GetString();
	strPath = AllTrim(strPath);
	if(!strPath.IsEmpty())
	{
		strPath.MakeUpper();
		int nn = strPath.Find("@MD");
		if(nn >= 0)
		{
			CString strPathTemp = strPath.Left(nn);
			strPath = CString("MD.Обработка.")+AllTrim(strPathTemp)+".Форма";
			strPath.MakeUpper();
		}

		if(strPath.Left(3).CompareNoCase("MD.") == 0)
		{
			// внутри md
			CString strDoc = strPath.Mid(3);
			SDocNames1 *pDocNames = NULL;
			if(DocNamesArray1.Lookup(strDoc, (void*&)pDocNames))
			{
				CApp7* pApp7 = (CApp7*) AfxGetApp();
				CProfile7* pProfile7 = pApp7->GetProps();
				CString Prop8 = pProfile7->GetStringProp(0x08); // полный путь к файлу 1Cv7.MD (с именем файла)
				CString strFull = "";
				strFull.Format("%s\\%s\\%s_Number%d\\WorkBook",Prop8,pDocNames->strFolder,pDocNames->strFolder,pDocNames->id);
				CWorkBookDoc* pDoc = (CWorkBookDoc*)CConfigCont::PathToDocument(strFull);
				if(pDoc == NULL)
				{
					CString str;
					CTypedCont *pTypedCont;
					if(CConfigCont::IDToPath(pDocNames->id,pDocNames->strFolder,str,&pTypedCont,0))
						pDoc = pTypedCont->GetWorkBook();
				}
				if(pDoc)
				{
					if(strName.IsEmpty())
					{
						CStringArray cStringArray;
						pDoc->GetTablesName(cStringArray);
						if(cStringArray.GetSize() > 0)
							strName = cStringArray.GetAt(0);
					}

					int n = 0;
					CSheetDoc* pSheetDoc = (CSheetDoc*)pDoc->FindDocument(strName, &n);
					if(pSheetDoc)
					{
						m_pSheetDocIn = pSheetDoc;
						DWORD* pdw = (DWORD*)pSheetDoc;
						m_pSheet = (CSheet*)&pdw[0x2C];
						if(m_pSheetDocOut && (CTemplate7::GetDocumentID(m_pSheetDocOut) != 0))
						{
							m_pSheetDocOut->UpdateAllViews(NULL, 8, NULL);
						}
						res = 0;
					}
					else
						res = 3;
				}
				else
					res = 4;
			}
			else
				res = 2;
		}
		else
		{
			if(strPath.Right(3).CompareNoCase("MXL") == 0)
			{
				*ppValue[0] = strPath;
				return 1;
			}
			// из внешнего отчета
			CTemplate7* pTempl = CTemplate7::FromID(0xBA);

			if(pTempl == NULL)
				return 4;

			POSITION pos = pTempl->GetFirstDocPosition();
			while(pos)
			{
				CWorkBookDoc* pTemplDoc = (CWorkBookDoc*)pTempl->GetNextDoc(pos);
				if(pTemplDoc)
				{
					CString strSrc = pTemplDoc->GetSourcePathName();
					if(strSrc.CompareNoCase(strPath) == 0)
					{
						CStringArray cStringArray;
						pTemplDoc->GetTablesName(cStringArray);
						if(strName.IsEmpty())
						{
							if(cStringArray.GetSize() > 0)
								strName = cStringArray.GetAt(0);
						}
						int n = 0;
						CSheetDoc* pSheetDoc = (CSheetDoc*)pTemplDoc->FindDocument(strName, &n);
						if(pSheetDoc)
						{
							m_pSheetDocIn = pSheetDoc;
							DWORD* pdw = (DWORD*)pSheetDoc;
							m_pSheet = (CSheet*)&pdw[0x2C];
							if(m_pSheetDocOut && (CTemplate7::GetDocumentID(m_pSheetDocOut) != 0))
							{
								m_pSheetDocOut->UpdateAllViews(NULL, 8, NULL);
							}
							return 0;
						}
						return 3;
					}
				}
			}

			pTempl = CTemplate7::FromID(0xA1);

			if(pTempl == NULL)
				return 4;

			if(strName.IsEmpty())
				strName = "Moxel WorkPlace";

			COleStorage pOleStorage(NULL);
			CFileException excepFile;
			if(pOleStorage.Open(strPath, CFile::shareExclusive, &excepFile))
			{
				COleStreamFile * pOleStream = pOleStorage.OpenStream(CContainer::GetContentsStreamName(), CFile::shareExclusive, &excepFile);
				if(pOleStream)
				{
					DWORD StreamLen = pOleStream->GetLength();
					char* buf = (char*)malloc(StreamLen);
					pOleStream->Read(buf, StreamLen);
					CItemList list1;
					int n = 0;
					CString strStreamName = "";
					list1.LoadFromString(buf, &n);
					for(int j = list1.FindGenericItem("Moxcel.Worksheet", -1); j >= 0; j = list1.FindGenericItem("Moxcel.Worksheet", ++j))
					{
						CItem* pItem = (CItem*)list1.GetItemAt(j);
						int w = pItem->WhatIsIt();
						if(w == 1)
						{
							CItem* pItem1 = (CItem*)((CGenericItem*)pItem)->m_array.GetAt(1);
							CItem* pItem2 = (CItem*)((CGenericItem*)pItem)->m_array.GetAt(2);
							if((strName.CompareNoCase(pItem2->m_str) == 0) ||
								((pItem2->m_str.CompareNoCase("Moxel WorkPlace") == 0) &&
								 (strName.CompareNoCase("Таблица") == 0)))
							{
								strStreamName = pItem1->m_str;
							}
						}
					}
					free(buf);
					pOleStorage.ReleaseStream(pOleStream, TRUE);
					if(strStreamName.IsEmpty() == FALSE)
					{
						if(pOleStream = pOleStorage.OpenStream(strStreamName, CFile::shareExclusive, &excepFile))
						{
							CArchive ar(pOleStream, CArchive::load);
							if(m_pSheetDocIn)
							{
								// пытаемся очистить ранее созданные нами CSheetDoc
								if(CTemplate7::GetDocumentID(m_pSheetDocIn) == 0)
									delete m_pSheetDocIn;
							}
							m_pSheetDocIn = (CSheetDoc*)CSheetDoc::CreateObject();//new CSheetDoc;
//							CTemplate7::RegisterDocument(m_pSheetDocIn);
//							pTempl->AddDocument(m_pSheetDocIn);

							m_pSheetDocIn->DeleteContents();
							m_pSheetDocIn->Serialize(ar);
							DWORD* pdw = (DWORD*)m_pSheetDocIn;
							m_pSheet = (CSheet*)&pdw[0x2C];
							if(m_pSheetDocOut && (CTemplate7::GetDocumentID(m_pSheetDocOut) != 0))
							{
								m_pSheetDocOut->UpdateAllViews(NULL, 8, NULL);
							}
							CTemplate7::UnRegisterDocument(m_pSheetDocIn);
							pOleStorage.ReleaseStream(pOleStream, TRUE);
							res = 0;
						}
						else
							res = 4;
					}
					else
						res = 3;
				}
				else
					res = 4;
				pOleStorage.Release(TRUE);
			}
			else
				res = 2;
		}
	}
	return res;
}

CTableEx::CTableEx()
{
	// перехват объекта Таблица
	pTabCont = CBLContext::CreateInstance("Table");
	iMethNum_SourceTable = pTabCont->FindMethod("SourceTable");
	iMethNum_Options = pTabCont->FindMethod("Options");
}

CTableEx::~CTableEx()
{
	pTabCont->DecrRef();
	//delete pTabCont;
}

// CBLContext implementation

int  CTableEx::CallAsFunc(int iMethNum,class CValue & rValue,class CValue * *ppValue)
{
    int ret = 0;
	if(iMethNum == iMethNum_SourceTable)
	{
		int res = SetTable(ppValue);
		int bCallExept = ppValue[2]->GetNumeric();
		rValue = res;

		if(bCallExept == 0)
			return S_OK;

		if(res == 0)
		{
			rValue = 1L;
			return S_OK;
		}
		else if(res != 1)
		{
			// 2 - ошибка пути
			// 3 - ошибка имени таблицы
			// 4 - прочие ошибки
			if(res == 2)
				RuntimeError("Неверно задан путь к исходной таблице!", mmRedErr);
			else if(res == 3)
				RuntimeError("Неверно задано имя исходной таблицы!", mmRedErr);
			else
				RuntimeError("Ошибка при установке исходной таблицы!", mmRedErr);
			return S_FALSE;
		}

		rValue = 2L;
		return pTabCont->CallAsProc(iMethNum, ppValue);
	}

	return pTabCont->CallAsFunc(iMethNum, rValue, ppValue);
}


int  CTableEx::CallAsProc(int iMethNum,class CValue * * ppValue)
{
    int ret = 0;
	if(iMethNum == iMethNum_SourceTable)
	{
		int res = SetTable(ppValue);
		int bCallExept = ppValue[2]->GetNumeric();
		if(bCallExept == 0)
			return S_OK;

		if(res == 0)
			return S_OK;
		else if(res != 1)
		{
			// 2 - ошибка пути
			// 3 - ошибка имени таблицы
			// 4 - прочие ошибки
			if(res == 2)
				RuntimeError("Неверно задан путь к исходной таблице!", mmRedErr);
			else if(res == 3)
				RuntimeError("Неверно задано имя исходной таблицы!", mmRedErr);
			else
				RuntimeError("Ошибка при установке исходной таблицы!", mmRedErr);
			return S_FALSE;
		}
	}
	//else if(strMeth.CompareNoCase("Опции") == 0)
	else if(iMethNum == iMethNum_Options)
	{
		int ret = pTabCont->CallAsProc(iMethNum, ppValue);

		POSITION pos = m_pSheetDocOut->GetFirstViewPosition();
		while(pos)
		{
			CSheetViewMy1* pSheetView = (CSheetViewMy1*)m_pSheetDocOut->GetNextView(pos);
			CSheetSelection pSel = *(pSheetView->GetTailSelection());
			int nPosVert = pSheetView->GetScrollPos(SB_VERT);
			int nPosHorz = pSheetView->GetScrollPos(SB_HORZ);
			pSheetView->OnInitialUpdate();
			pSheetView->ClearSelection();
			pSheetView->SelectArea(pSel);
			pSheetView->ScrollToPosition(nPosHorz,nPosVert);
		}

		return ret;
	}

	return pTabCont->CallAsProc(iMethNum, ppValue);
}


int  CTableEx::FindMethod(char const * lpMethodName)const
{
	return pTabCont->FindMethod(lpMethodName);
}

char const *  CTableEx::GetMethodName(int iMethodNum,int iMethodAlias)const
{
  return pTabCont->GetMethodName(iMethodNum, iMethodAlias);
}

int  CTableEx::GetNMethods(void)const
{
  return pTabCont->GetNMethods();
}

int  CTableEx::HasRetVal(int iMethodNum)const
{
	if(iMethodNum == iMethNum_SourceTable)
	{
		return 1;
	}
	
	return pTabCont->HasRetVal(iMethodNum);
}

int CTableEx::GetNParams(int iMethodNum)const
{
	if(iMethodNum == iMethNum_SourceTable)
	{
		return 3;
	}

	return pTabCont->GetNParams(iMethodNum);
}

int  CTableEx::GetParamDefValue(int iMethodNum,int iParamNum,class CValue * pDefValue)const
{	
	if(iMethodNum == iMethNum_SourceTable)
	{
		if(iParamNum == 1)
		{
			*pDefValue = "";
			return 1;
		}
		if(iParamNum == 2)
		{
			*pDefValue = 1;
			return 1;
		}
	}

	return pTabCont->GetParamDefValue(iMethodNum, iParamNum, pDefValue);
}



void  CTableEx::DecrRef(void)
{
	int aRefCount = m_RefCount;
	CSheetDoc* pSheetDoc = m_pSheetDocIn;

	//(this->*pDestructor)();

	// пытаемся очистить ранее созданные нами CSheetDoc
	if((--aRefCount == 0) && pSheetDoc && (*(DWORD*)pSheetDoc == dwCSheetDocVTable) && (CTemplate7::GetDocumentID(pSheetDoc) == 0))
				delete pSheetDoc;

	CBLContext::DecrRef();
}

char const *  CTableEx::GetCode(void)const
{
  return pTabCont->GetCode();
}

int  CTableEx::GetDestroyUnRefd(void)const
{
  return pTabCont->GetDestroyUnRefd();
}

void  CTableEx::GetExactValue(class CValue & vParam)
{
	CBLContext::GetExactValue(vParam);
	pTabCont->GetExactValue(vParam);
}

class CObjID   CTableEx::GetID(void)const
{
	return ObjID;
}

class CBLContextInternalData *  CTableEx::GetInternalData(void)
{
	return pTabCont->GetInternalData();
}

long  CTableEx::GetTypeID(void)const
{
	return 100;
}

char const *  CTableEx::GetTypeString(void)const
{
	return "ТаблицаРасширенная";
}

class CType   CTableEx::GetValueType(void)const
{
	CType tType(100);	
	return tType;
}


void  CTableEx::IncrRef(void)
{
	CBLContext::IncrRef();
}

void  CTableEx::InitObject(class CType const & tType)
{
	CBLContext::InitObject(tType);
	pTabCont->InitObject(tType);

	if (!bIsInit)
	{
		bIsInit = true;

		CSheetDoc mSheetDoc;
		dwCSheetDocVTable = *(DWORD*)&mSheetDoc;

		CConfigCont::GetAllTypedItem(procGetAllTypedItem1,0,ptDialog,0);
	}
}

void  CTableEx::InitObject(char const * strName)
{
	CBLContext::InitObject(strName);
	pTabCont->InitObject(strName);
	if (!bIsInit)
	{
		bIsInit = true;

		CSheetDoc mSheetDoc;
		dwCSheetDocVTable = *(DWORD*)&mSheetDoc;

		CConfigCont::GetAllTypedItem(procGetAllTypedItem1,0,ptDialog,0);
	}
}

int  CTableEx::IsExactValue(void)const
{
	return pTabCont->IsExactValue();
}

int  CTableEx::IsOleContext(void)const
{
	return pTabCont->IsOleContext();
}

int  CTableEx::IsPropReadable(int iPropNum)const
{
	return pTabCont->IsPropReadable(iPropNum);
}

int  CTableEx::IsPropWritable(int iPropNum)const
{
	return pTabCont->IsPropWritable(iPropNum);
}

int  CTableEx::IsSerializable(void)
{
	return 0;
}

int  CTableEx::SaveToString(class CString & csStr)
{	
	return 0;
}

void  CTableEx::SelectByID(class CObjID cID,long lNum)
{
	//CBLContext::SelectByID(cID,lNum);
	pTabCont->SelectByID(cID,lNum);
}


int  CTableEx::GetNProps(void)const
{
	return pTabCont->GetNProps();
}

char const *  CTableEx::GetPropName(int A,int B)const
{	
	return pTabCont->GetPropName(A, B);
}

int  CTableEx::GetPropVal(int iPropNum,class CValue & rValue)const
{
	return pTabCont->GetPropVal(iPropNum, rValue);
}

int  CTableEx::SetPropVal(int iPropNum,class CValue const & vValue)
{
	return pTabCont->SetPropVal(iPropNum, vValue);
}

int  CTableEx::FindProp(char const * Name)const
{
	return pTabCont->FindProp(Name);
}

#endif
