//////////////////////////////////////////////////////////////////////
//
// Разработчик: Алексей Фёдоров aka АЛьФ, mailto: alf@dorex.ru
//
//////////////////////////////////////////////////////////////////////

#include "stdafx.h"
#include "addin.h"
#include "Service.h"
#include "TreeChoose.h"
#include "MDIClientWnd.h"
#include "supergrid\MySuperGrid.h"
#ifndef FORMEX_DLL
#include ".\\TurboBL\\gcboost.h"
#endif
#include "FormExMenu.h"
#include "PaintHook.h"
#include "FormExFormView.h"
#include "sizecbar.h"
#ifndef FORMEX_DLL
#include ".\CursorGrid\V7CursorGridCtrl.h"
#endif

// artbear
#include "TableEx.h"
// end
#include "BLModuleWrapper.h"

#define FORMEX_VERSION 0x02000200

#define BUFSIZE 80
#define	VER_NT_WORKSTATION			1
#define	VER_NT_DOMAIN_CONTROLLER	2
#define	VER_NT_SERVER				3

#define	VER_SUITE_SMALLBUSINESS				0x00000001
#define	VER_SUITE_ENTERPRISE				0x00000002
#define	VER_SUITE_BACKOFFICE				0x00000004
#define	VER_SUITE_COMMUNICATIONS			0x00000008
#define	VER_SUITE_TERMINAL					0x00000010
#define	VER_SUITE_SMALLBUSINESS_RESTRICTED	0x00000020
#define	VER_SUITE_EMBEDDEDNT				0x00000040
#define	VER_SUITE_DATACENTER				0x00000080
#define	VER_SUITE_SINGLEUSERTS				0x00000100
#define	VER_SUITE_PERSONAL					0x00000200
#define	VER_SUITE_BLADE						0x00000400

extern IDispatch *pGlobalConnection;
extern HINSTANCE hDllInstance;
extern HHOOK MouseHookHandle;
extern HHOOK HookHandle;
extern class CWinApp* pApp;
extern BOOL bSetDrawWrap;
extern CMapStringToPtr DocNamesArray;

//CSizingControlBar* pWndToDock = NULL;
CWnd* pWndToDock = NULL;

//##############################################################################
//#################### код для реализации метода SendKeys ######################
#define WorkBufLen							0x00000028
#define MaxSendKeyRecs						0x00000029
#define MaxInt								0x7FFFFFFF
#define MaxLongint							0x7FFFFFFF

static char WorkBuf[WorkBufLen+1];
int AllocationSize;

typedef BYTE THKeys[MaxLongint];

typedef struct tsendkey {
  char*  Name;
  BYTE VKey;
} TSendKey;


static TSendKey SendKeyRecs [] = {
   {"BKSP", VK_BACK},
   {"BS", VK_BACK},
   {"BACKSPACE", VK_BACK},
   {"BREAK", VK_CANCEL},
   {"CAPSLOCK", VK_CAPITAL},
   {"CLEAR", VK_CLEAR},
   {"DEL", VK_DELETE},
   {"DELETE", VK_DELETE},
   {"DOWN", VK_DOWN},
   {"END", VK_END},
   {"ENTER", VK_RETURN},
   {"ESC", VK_ESCAPE},
   {"ESCAPE", VK_ESCAPE},
   {"F1", VK_F1},
   {"F10", VK_F10},
   {"F11", VK_F11},
   {"F12", VK_F12},
   {"F13", VK_F13},
   {"F14", VK_F14},
   {"F15", VK_F15},
   {"F16", VK_F16},
   {"F2", VK_F2},
   {"F3", VK_F3},
   {"F4", VK_F4},
   {"F5", VK_F5},
   {"F6", VK_F6},
   {"F7", VK_F7},
   {"F8", VK_F8},
   {"F9", VK_F9},
   {"HELP", VK_HELP},
   {"HOME", VK_HOME},
   {"INS", VK_INSERT},
   {"LEFT", VK_LEFT},
   {"NUMLOCK", VK_NUMLOCK},
   {"PGDN", VK_NEXT},
   {"PGUP", VK_PRIOR},
   {"PRTSC", VK_PRINT},
   {"RIGHT", VK_RIGHT},
   {"SCROLLLOCK", VK_SCROLL},
   {"TAB", VK_TAB},
   {"UP", VK_UP}
  }; 

#define  VK_NULL 0
#define  VK_SemiColon 186
#define  VK_Equal 187
#define  VK_Comma 188
#define  VK_Minus 189
#define  VK_Period 190
#define  VK_Slash 191
#define  VK_BackQuote 192
#define  VK_LeftBracket 219
#define  VK_BackSlash 220
#define  VK_RightBracket 221
#define  VK_Quote 222
#define  VK_Last VK_Quote

#define INVALIDKEY  0xFFFF
#define VKKEYSCANSHIFTON  0x01
#define VKKEYSCANCTRLON  0x02
#define VKKEYSCANALTON  0x04

bool UsingParens, ShiftDown, ControlDown, AltDown, FoundClose;
char* PosSpace;
int I, L;
WORD  NumTimes, MKey;
char KeyString[20];

bool WWait;

bool BitSet(BYTE BitTable, BYTE BitMask)
{
  return ((BitTable & BitMask) != 0);
}


void SetBit(BYTE* BitTable, BYTE BitMask)
{
  *BitTable |= BitMask;
}

void KeyboardEvent(BYTE VKey, BYTE ScanCode, DWORD Flags)
{ 
  MSG KeyboardMsg;

  keybd_event(VKey, ScanCode, Flags, 0);
  if (WWait)
    while (PeekMessage(&KeyboardMsg, 0, WM_KEYFIRST, WM_KEYLAST, PM_REMOVE))
    {
      TranslateMessage(&KeyboardMsg);
      DispatchMessage(&KeyboardMsg);
    }
}

void SendKeyDown(BYTE VKey, WORD NumTimes, bool GenUpMsg)
{
  WORD Cnt;
  BYTE ScanCode;
  bool NumState;
  BYTE KeyBoardState[256];

  if (VKey == VK_NUMLOCK)
  {
    NumState = GetKeyState(VK_NUMLOCK) & 1;
    GetKeyboardState(KeyBoardState);
    if (NumState) 
    {
      KeyBoardState[VK_NUMLOCK] &=  !1;
    }
    else
    {
      KeyBoardState[VK_NUMLOCK] |= 1;
    }
    SetKeyboardState(KeyBoardState);
    return;
  }
  ScanCode = (BYTE) MapVirtualKey(VKey, 0);
  for(Cnt = 1;Cnt <= NumTimes; Cnt++)
  {
    switch (VKey) 
    {
       case VK_UP:
       case VK_DOWN:
       case VK_LEFT:
       case VK_RIGHT:
       case VK_HOME:
       case VK_END:
       case VK_PRIOR:
       case VK_NEXT:
       case VK_INSERT:
       case VK_DELETE:
         KeyboardEvent(VKey, ScanCode, KEYEVENTF_EXTENDEDKEY);
         if (GenUpMsg) 
           KeyboardEvent(VKey, ScanCode, KEYEVENTF_EXTENDEDKEY | KEYEVENTF_KEYUP);
         break;
       default:
         KeyboardEvent(VKey, ScanCode, 0);
         if (GenUpMsg)
           KeyboardEvent(VKey, ScanCode, KEYEVENTF_KEYUP);
         break;
    }
  }
}

void SendKeyUp(BYTE VKey)
{
  BYTE ScanCode;

  ScanCode = (BYTE) MapVirtualKey(VKey, 0);
  switch (VKey) 
  {
     case VK_UP:
     case VK_DOWN:
     case VK_LEFT:
     case VK_RIGHT:
     case VK_HOME:
     case VK_END:
     case VK_PRIOR:
     case VK_NEXT:
     case VK_INSERT:
     case VK_DELETE:
       KeyboardEvent(VKey, ScanCode, KEYEVENTF_EXTENDEDKEY & KEYEVENTF_KEYUP);
       break;
     default:
       KeyboardEvent(VKey, ScanCode, KEYEVENTF_KEYUP);
       break;
  }  
}

void SendKey(WORD MKey, WORD NumTimes, bool GenDownMsg)
{
  if (BitSet(MKey >> 8, VKKEYSCANSHIFTON)) SendKeyDown(VK_SHIFT, 1, false);
  if (BitSet(MKey >> 8, VKKEYSCANCTRLON)) SendKeyDown(VK_CONTROL, 1, false);
  if (BitSet(MKey >> 8, VKKEYSCANALTON)) SendKeyDown(VK_MENU, 1, false);
  SendKeyDown((BYTE)MKey, NumTimes, GenDownMsg);
  if (BitSet(MKey >> 8, VKKEYSCANSHIFTON)) SendKeyUp(VK_SHIFT);
  if (BitSet(MKey >> 8, VKKEYSCANCTRLON)) SendKeyUp(VK_CONTROL);
  if (BitSet(MKey >> 8, VKKEYSCANALTON)) SendKeyUp(VK_MENU);
}

//{Implements a simple binary search to locate special key name strings}

WORD StringToVKey(char* KeyString)
{
  bool Found, Collided;
  BYTE Bottom, Top, Middle;
  WORD Res;

  Res = INVALIDKEY;
  Bottom = 1;
  Top = MaxSendKeyRecs;
  Found = false;
  Middle = (Bottom + Top) >> 1;
  do
  {
    Collided = ((Bottom == Middle) || (Top == Middle));
    if (strcmp(KeyString, SendKeyRecs[Middle].Name) == 0)
    {
      Found = true;
      Res = SendKeyRecs[Middle].VKey;
    }
    else
    {
      if (strcmp(KeyString, SendKeyRecs[Middle].Name) > 0) Bottom = Middle;
        else Top = Middle;
      Middle = (Bottom + Top + 1) >> 1;
    }
  } while( !((Found) || (Collided)) );
  return Res;
}

void PopUpShiftKeys()
{
  if (!UsingParens)
  {
    if (ShiftDown) SendKeyUp(VK_SHIFT);
    if (ControlDown) SendKeyUp(VK_CONTROL);
    if (AltDown) SendKeyUp(VK_MENU);
    ShiftDown = false;
    ControlDown = false;
    AltDown = false;
  }
}

bool SendKeys(char* SendKeysString, bool Wait, LPCTSTR lang)
{
	bool Res;
	char cp[2];
	char temp[20];
	HKL curr_dwhkl;
	HKL dwhkl;

  curr_dwhkl = GetKeyboardLayout(0);
  dwhkl = LoadKeyboardLayout(lang,KLF_ACTIVATE);

  WWait = Wait;
  cp[0] = 0;
  cp[1] = 0;
  AllocationSize = MaxInt;
  Res = false;
  UsingParens = false;
  ShiftDown = false;
  ControlDown = false;
  AltDown = false;
  I = 0;
  L = strlen(SendKeysString);
  if (L > AllocationSize) L = AllocationSize;
  if (L == 0) return Res;

  while (I < L)
  {
    switch (SendKeysString[I])
	{
      case '(' :
        UsingParens = true;
        I++;
        break;
      case ')' :
        UsingParens = false;
        PopUpShiftKeys();
        I++;
        break;
      case '%' :
        AltDown = true;
        SendKeyDown(VK_MENU, 1, false);
        I++;
        break;
      case '+' :
        ShiftDown = true;
        SendKeyDown(VK_SHIFT, 1, false);
        I++;
        break;
      case '^' :
        ControlDown = true;
        SendKeyDown(VK_CONTROL, 1, false);
        I++;
        break;
      case '{' : 
        NumTimes = 1;
        if (SendKeysString[I + 1] == '{')
        {
          MKey = VK_LeftBracket;
          SetBit((BYTE*)((int)&MKey+1), VKKEYSCANSHIFTON);
          SendKey(MKey, 1, true);
          PopUpShiftKeys();
          I += 3;
          continue;// goto Cont;
        }
        KeyString[0] = 0;
        FoundClose = false;
        while (I<=L)
        {
          I++;
          if (SendKeysString[I] == '}')
          {
            FoundClose = true;
            I++;
            break;
          }
          cp[0] = toupper(SendKeysString[I]);
          strcat(KeyString, cp);
        } 
        if (!FoundClose) return Res;
        if (SendKeysString[I] == '}')
        {
          MKey = VK_RightBracket;
          SetBit((BYTE*)((int)&MKey+1),VKKEYSCANSHIFTON);
          SendKey(MKey, 1, true);
          PopUpShiftKeys();
          I++;
          continue;// goto Cont;
        }
        PosSpace = strchr(KeyString, ' ');
        if (PosSpace)
        { 
          *PosSpace = 0;
          PosSpace++;
          strcpy(temp, PosSpace);
          NumTimes = atoi(temp);
        }
        if (strlen(KeyString) == 1)
        {
          MKey = VkKeyScanEx(KeyString[0],dwhkl);
        }
        else
        {
          if (KeyString[0] == '$')
          {
            KeyString[0] = ' ';
            MKey = atoi(KeyString);
          }
          else
          {
            MKey = StringToVKey(KeyString);
          }
        }
        if (MKey != INVALIDKEY)
        {
          SendKey(MKey, NumTimes, true);
          PopUpShiftKeys();
          continue;// goto Cont;
        }
        break;
      case '~' : 
        SendKeyDown(VK_RETURN, 1, true);
        PopUpShiftKeys();
        I++;
        break;
      default:
        MKey = VkKeyScanEx(SendKeysString[I],dwhkl);
        if (MKey != INVALIDKEY)
        {
          SendKey(MKey, 1, true);
          PopUpShiftKeys();
        } 
        else
        {
          Res = false;
          return Res;
        }
        I++;
        break;
    }
//Cont:
  }
  Res = true;
  PopUpShiftKeys();
  ActivateKeyboardLayout(curr_dwhkl,KLF_REORDER);
  return Res;
}
//******************************************************************************

//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////

extern CBkEndUI * pBkEndUI;
extern BOOL m_bEnabledColor;
extern BOOL m_bLocalColor;
extern BOOL m_bShowKL;
extern UINT StatusTimer;
extern CMDIClientWnd * wndMDIClient;
extern UINT uTimer;
extern CString strTimerName;
extern class CMetaDataCont * pMetaDataCont;
extern CDWordArray glCursorArray;
extern DWORD myPlatformId;
extern CDWordArray glCursorWindowsArray;

IMPLEMENT_DYNCREATE(CService,CBLContext);

class CObjID CService::ObjID;

struct CService::paramdefs CService::defFnNames[] = {
	{{"ColourBrowse",			"ВключитьРаскраскуТаблиц"},			FALSE, 1},
	{{"UnColourBrowse",			"ВыключитьРаскраскуТаблиц"},		FALSE, 0},
	{{"ActiveContext",			"АктивныйКонтекст"},				TRUE, 1},
	{{"CallAsProcedure",		"ВыполнитьПроцедуру"},				TRUE, 3},
	{{"CallAsFunction",			"ВыполнитьФункцию"},				TRUE, 4},
	{{"GetContextVar",			"ПолучитьПеременнуюКонтекста"},		TRUE, 3},
	{{"SetContextVar",			"УстановитьПеременнуюКонтекста"},	TRUE, 3},
	{{"ChooseValue",			"ВыбратьЗначение"},					TRUE, 6},
	{{"AddGlobalModule",		"ДобавитьГлобальныйМодуль"},		TRUE, 1},
	{{"DeleteGlobalModule",		"УдалитьГлобальныйМодуль"},			TRUE, 1},
	{{"ShowKeyboardIndicator",	"ПоказыватьИндикаторКлавиатуры"},	FALSE, 1},
	{{"SetWallpaper",			"УстановитьОбои"},					FALSE, 4},
	{{"HeightTableString",		"ВысотаСтрокиТаблицы"},				TRUE, 3},
	{{"HideTable",				"ПрятатьТаблицу"},					FALSE, 2},
	{{"GetTableNames",			"ПолучитьИменаТаблицы"},			TRUE, 1},
	{{"GetGUID",				"ПолучитьGUID"},					TRUE, 0},
	{{"OSVersion",				"ВерсияОС"},						TRUE, 0},
	{{"IdleProcessing",			"ОбработкаОжидания"},				TRUE, 2},
	{{"ListMoxel",				"СписокТаблиц"},					TRUE, 0},
	{{"UnLoadAddIn",			"ВыгрузитьВнешнююКомпоненту"},		TRUE, 1},
	{{"Play",					"Воспроизвести"},					FALSE, 1},
	{{"GetPrintersList",		"ПолучитьСписокПринтеров"},			TRUE, 0},
	{{"IsPrinterReady",			"ГотовностьПринтера"},				TRUE, 1},
	{{"SetCursor",				"УстановитьКурсор"},				FALSE, 1},
	{{"SendKeys",				"ЭмулироватьКлавиатуру"},			TRUE, 3},
	{{"CreateFont",				"СоздатьШрифт"},					TRUE, 8},
	{{"DeleteFont",				"УдалитьШрифт"},					FALSE, 1},
	{{"CommandLine",			"КоманднаяСтрока"},					TRUE, 0},
#ifndef FORMEX_DLL
	{{"LoadModule",				"ЗагрузитьМодуль"},					TRUE, 1},
	{{"UnLoadModule",			"ВыгрузитьМодуль"},					TRUE, 0},
#else
	{{"Version",				"Версия"},							TRUE, 1},
#endif
	{{"VersionFormEx",			"ВерсияFormEx"},					TRUE, 1},
	{{"AsyncEvent",				"ВнешнееСобытие"},					FALSE, 3},
	{{"MouseHook",				"ПерехватМыши"},					TRUE, 1},
	{{"KeyHook",				"ПерехватКлавиатуры"},				TRUE, 1},
	{{"CreateFontCausedBy",		"СоздатьШрифтНаОсновании"},			TRUE, 9},
	{{"ValueListDraw",			"ПерехватОтрисовкиСписков"},		TRUE, 1},
	{{"AllFormsList",			"СписокВсехФорм"},					TRUE, 0},
	{{"OpenDockableForm",		"ОткрытьФормуКакПанель"},			TRUE, 6},
	{{"OpenToolsForm",			"ОткрытьПлавающуюФорму"},			TRUE, 6},
	{{"GetUsersList",			"ПолучитьСписокПользователей"},		TRUE, 1},
	{{"Test",					"Проверка"},						FALSE, 2},
	{NULL,0,0}
	};

#ifndef FORMEX_DLL
CBLModule* GetModuleByContext(CGroupContext* pCont)
{
  CBLModule * pMod = NULL;  
	if(pCont->m_FlagAutoDestroy > 100) 
  {              
    pMod = ((CGCBoost::SGCInfo*)pCont->m_FlagAutoDestroy)->m_pMod;
  }
  return pMod;
}
#endif

CService::CService():CBLContext()
{
}

CService::CService(int param):CBLContext(param)
{
}

CService::~CService()
{
}

int GetFromVL(structVIA** pVIA, PValueItemArrayT* pValItAr, int count, ULONG* index, CPtrArray* AllValues, CPtrArray* AllValuesArray, CValue* val2select, CPtrArray * ppValItAr = NULL)
{
	if(ppValItAr == NULL)
		ppValItAr = new CPtrArray;

	int sz = sizeof(CValue);
	for(int i=0; i<count; i++)
	{
		(*index)++;
		CValue* val = (CValue*)pValItAr->GetAt(i);
		CBLContext* pVLCont = val->GetContext();
		pVIA[i] = (structVIA*)malloc(sizeof(structVIA));
		memcpy(&pVIA[i]->Value, val, sz);
		AllValues->Add(val);
		AllValuesArray->Add(pVIA[i]);
		pVIA[i]->Index = (DWORD)(*index);
		pVIA[i]->Checked = ((CValueItem*)val)->GetCheck();
		pVIA[i]->ValueItem = (CValueItem*)val;
		CString str = ((CValueItem*)val)->GetPresent();
		pVIA[i]->Descr = new CString;
		pVIA[i]->Type  = 1;
		pVIA[i]->Count = 0;
		*(pVIA[i]->Descr) = str;
		pVIA[i]->Selected = *val == *val2select ? TRUE : FALSE; // AM - added
		if(pVLCont) 
		{
			if(!strcmp(pVLCont->GetRuntimeClass()->m_lpszClassName,"CValueListContext"))
			{
				CValueListContextData* pVLCD = ((CValueListContextData*)pVLCont->GetInternalData());
				PValueItemArrayT *pValItArNew = (PValueItemArrayT*)pVLCD->GetValueList();

				bool bNeedAdd = true;
				int arrsz = ppValItAr->GetSize();
				for(int j = 0; j < arrsz; j++)
				{
					void* pValItArOld = ppValItAr->GetAt(j);
					if(pValItArOld == pValItArNew)
					{
						bNeedAdd = false;
						break;
					}
				}

				if(bNeedAdd)
				{
					ppValItAr->Add(pValItArNew);

					pVIA[i]->Type  = 0;

					int s = pValItArNew->GetSize();
					pVIA[i]->NextLevel = new PstructVIA[s];
					// AM - next line changed
					pVIA[i]->Count = GetFromVL(pVIA[i]->NextLevel, pValItArNew, s, index, AllValues, AllValuesArray, val2select, ppValItAr);

					ppValItAr->RemoveAt(arrsz);
				}
			}
		}
	}
	return count;
}

/*
UINT GetMenuFromVL(CMenu* pMenuChoose,structVIA** pVIA,int count, BOOL WithCheck)
{
	for(int i = 0; i<count; i++)
	{
		if(*(pVIA[i]->Descr) == "-")
		{
			pMenuChoose->AppendMenu(MF_SEPARATOR);
		}
		else if(pVIA[i]->Type == 1)
		{
			UINT nFlags = MF_STRING; // | MF_POPUP
			if(WithCheck && pVIA[i]->Checked) nFlags |= MF_CHECKED;

			pMenuChoose->AppendMenu(nFlags,pVIA[i]->Index,(LPCTSTR)*(pVIA[i]->Descr));
		}
		else
		{
			CMenu *SubMenu;
			SubMenu = new CMenu;
			SubMenu->CreatePopupMenu();
			GetMenuFromVL(SubMenu,pVIA[i]->NextLevel, pVIA[i]->Count, WithCheck);
			pMenuChoose->InsertMenu(i,MF_BYPOSITION | MF_STRING | MF_POPUP | MF_INSERT,
				(UINT)SubMenu->Detach(),
				(LPCTSTR)*(pVIA[i]->Descr));
			SubMenu->DestroyMenu();
			delete SubMenu;
		}
	}
	return 0;
}
*/

UINT GetMenuFromVL(CFormExMenu* pMenuChoose,structVIA** pVIA,int count, BOOL WithCheck, HFONT hFont)
{
	for(int i = 0; i<count; i++)
	{
		if(*(pVIA[i]->Descr) == "-")
		{
			((CMenu*)pMenuChoose)->AppendMenu(MF_SEPARATOR|MF_OWNERDRAW);
		}
		else if(pVIA[i]->Type == 1)
		{
			UINT nFlags = MF_STRING|MF_OWNERDRAW; // | MF_POPUP
			if(WithCheck && pVIA[i]->Checked) nFlags |= MF_CHECKED;

			((CMenu*)pMenuChoose)->AppendMenu(nFlags,pVIA[i]->Index,(LPCTSTR)*(pVIA[i]->Descr));
		}
		else
		{
			CFormExMenu *SubMenu;
			SubMenu = new CFormExMenu(hFont);
			SubMenu->m_pParent = pMenuChoose->m_pParent;
			SubMenu->CreatePopupMenu();
			GetMenuFromVL(SubMenu,pVIA[i]->NextLevel, pVIA[i]->Count, WithCheck, hFont);
			pMenuChoose->AppendMenu(MF_STRING | MF_POPUP | MF_OWNERDRAW | MF_INSERT,
				SubMenu, (LPCTSTR)*(pVIA[i]->Descr));
		}
	}
	return 0;
}

void FreeVL(structVIA** pVIA, int count)
{
	for(int i=0; i<count; i++)
	{
		if(pVIA[i]->Type == 0) FreeVL(pVIA[i]->NextLevel, pVIA[i]->Count);
		delete pVIA[i]->Descr;
		free(pVIA[i]);
	}
	delete [] pVIA;
}

int  CService::CallAsFunc(int iMethNum,class CValue & rValue,class CValue * *ppValue)
{
	try{
	switch (iMethNum)
	{
	case methGetUsersList:
		{
			rValue.CreateObject("ValueList");
			CBLContext* pCont = rValue.GetContext();
			if (pCont)
			{
				int nAddValueMeth = pCont->FindMethod("AddValue");
				if (nAddValueMeth != -1)
				{
					CValue val1;
					CValue val2;
					CValue* Par[2] = {&val1, &val2};

					CString strUs = ppValue[0]->GetString();
					if(strUs.IsEmpty())
						strUs = CDataBase7::m_sUserdefFileName;
					else
						if(strUs.GetAt(strUs.GetLength()) == '\\')
							strUs += "usrdef\\users.usr";
						else
							strUs += "\\usrdef\\users.usr";
					CString strCont = CContainer::GetContentsStreamName();
					COleStorage cOleStorage(NULL);
					CFileException cFileException;
					if(cOleStorage.Open(strUs, STGM_TRANSACTED | STGM_READ | STGM_SHARE_DENY_WRITE, &cFileException))
					{
						COleStreamFile* pOleStreamFile = cOleStorage.OpenStream(strCont,STGM_READ | STGM_SHARE_EXCLUSIVE, &cFileException);
						if(pOleStreamFile)
						{
							ULONG cbStreamSize = pOleStreamFile->GetLength();
							char* buf;
							buf = new char[cbStreamSize+1];
							pOleStreamFile->Read(buf, cbStreamSize);
							buf[cbStreamSize] = 0;
							CItemList cItemList;
							int n = cbStreamSize;
							cItemList.LoadFromString(buf, &n);
							n = cItemList.GetNItems();
							for(int i = 0; i < n; i++)
							{
								CGenericItem* pItem = cItemList.GetItemAt(i);
								if(pItem)
								{
									if((*(DWORD*)pItem) == (*(DWORD*)&cItemList))
									{
										CItemList *pItemSubList = (CItemList*)pItem;
										if(pItemSubList->GetNItems() >=3)
										{
											val1 = val2 = ((CItem*)pItemSubList->GetItemAt(2))->m_str;
											pCont->CallAsProc(nAddValueMeth, Par);
										}
									}
								}
								
							}

							pOleStreamFile->Close();
						}
						cOleStorage.Release(TRUE);
					}
				}
			}
			break;
		}
	case methOpenToolsForm:
		{
			rValue = 0L;
			SECMDIFrameWnd* pMainFrameWnd = (SECMDIFrameWnd*)GetMainFrame();
			if(pMainFrameWnd)
			{
				CBLContext* pGlobal = CBLContext::GetLoadedContext(1);
				int iOF = pGlobal->FindMethod("ОткрытьФормуМодально");
				int colParam = pGlobal->GetNParams(iOF);
				if(colParam > 6)
					colParam = 6;

				CValue retVal;
				CValue *paramVal[6];
				for(int num = 0; num < colParam; num++)
					paramVal[num]=ppValue[num];

				pWndToDock = pMainFrameWnd;
				if(pGlobal->CallAsFunc(iOF,retVal,paramVal))
				{
					for(num = 0; num < colParam; num++)
						ppValue[num]=paramVal[num];
					rValue = 1;
				}
			}
			break;
		}
 	case methOpenDockableForm:
		{
			SECMDIFrameWnd* pMainFrameWnd = (SECMDIFrameWnd*)GetMainFrame();
			if(pMainFrameWnd)
			{
				pMainFrameWnd->EnableDocking(CBRS_ALIGN_ANY);

				CSizingControlBar* pDockWnd;
				pDockWnd = new CSizingControlBar;
				//pDockWnd->m_bAutoDelete = TRUE;
				if(pDockWnd->Create("", pMainFrameWnd, CSize(200, 100), TRUE, AFX_IDW_CONTROLBAR_FIRST + 32))
				{
					pDockWnd->SetBarStyle(pDockWnd->GetBarStyle()|CBRS_FLYBY | CBRS_SIZE_DYNAMIC);
					pDockWnd->EnableDocking(CBRS_ALIGN_ANY);

					//HINSTANCE hFrame=GetModuleHandle("frame.dll");
					//DWORD* adr;
					//adr = (DWORD*)GetProcAddress(hFrame,"?dwSECDockBarMap@SECMDIFrameWnd@@1QAY01$$CBKA");
					// [0] - ID элемента диалога
					// [1] - флаг расположения
					//ULONG lDockBar10 = adr[0]; - верх
					//ULONG lDockBar11 = adr[1];
					//ULONG lDockBar20 = adr[2]; - низ
					//ULONG lDockBar21 = adr[3];
					//ULONG lDockBar30 = adr[4]; - лево
					//ULONG lDockBar31 = adr[5];
					//ULONG lDockBar40 = adr[6]; - право
					//ULONG lDockBar41 = adr[7];

					//pDockWnd->m_wndChild.
					//CFormExFormView* pPane = &pDockWnd->m_wndChild;

					CWnd* pWndSpl = NULL;

					CBLContext* pGlobal = CBLContext::GetLoadedContext(1);
					int iOF = pGlobal->FindMethod("ОткрытьФормуМодально");
					int colParam = pGlobal->GetNParams(iOF);
					if(colParam > 6)
						colParam = 6;

					CValue retVal;
					CValue *paramVal[6];
					for(int num = 0; num < colParam; num++)
						paramVal[num]=ppValue[num];

					pWndToDock = pDockWnd;
					if(pGlobal->CallAsFunc(iOF,retVal,paramVal))
					{
						//0xE81B - верх
						//0xE81C - лево
						//0xE81D - право
						//0xE81E - низ
						//CDockBar* pDockBar = (CDockBar*)pMainFrameWnd->GetDlgItem(0xE81D);
						//pDockWnd->m_nDockBarID = 0xE81D;
						CRect rect;
						pMainFrameWnd->DockControlBar(pDockWnd,0xE81D,&rect); //pDockBar//pDockWnd->m_
					}
					else
					{
						pDockWnd->DestroyWindow();
						delete pDockWnd;
					}
					pWndToDock = NULL;
				}
				else
				{
					delete pDockWnd;
				}
			}
			break;
		}
	case methAllFormsList:
		{
			//CBodyTextDoc
			//CTextOutputContext
			CTextOutputContext* pCont = (CTextOutputContext*)CBLContext::CreateInstance("Text");
			if(pCont)
			{
				POSITION pos = DocNamesArray.GetStartPosition();
				while(pos)
				{
					CString key;
					void* ptr;
					DocNamesArray.GetNextAssoc(pos, key, ptr);
					pCont->m_pBodyTextDoc->AddLine(key);
				}
			}
			rValue.AssignContext(pCont);
			break;
		}
	case methValueListDraw:
		{
			rValue = 0L;
			if(bSetDrawWrap)
				rValue = 1L;

			int n = ppValue[0]->GetNumeric();
			if((n == 0) && (bSetDrawWrap == TRUE))
			{
				bSetDrawWrap = FALSE;
				CWrapModule::SetWrapCheckListBoxDrawItem(FALSE);

				CMDIFrameWnd* pWnd = GetMainFrame();
				if(pWnd)
				{
					CWnd* pMDIWnd = CWnd::FromHandle(pWnd->m_hWndMDIClient);
					if(pMDIWnd)
					{
						CWnd* pMDIWndCh = pMDIWnd->GetNextWindow(GW_CHILD);
						while(pMDIWndCh)
						{
							pMDIWndCh->RedrawWindow();
							pMDIWndCh = pMDIWndCh->GetNextWindow();
						}
					}
				}
			}
			else if((n == 1) && (bSetDrawWrap == FALSE))
			{
				bSetDrawWrap = TRUE;
				CWrapModule::SetWrapCheckListBoxDrawItem(TRUE);

				CMDIFrameWnd* pWnd = GetMainFrame();
				if(pWnd)
				{
					CWnd* pMDIWnd = CWnd::FromHandle(pWnd->m_hWndMDIClient);
					if(pMDIWnd)
					{
						CWnd* pMDIWndCh = pMDIWnd->GetNextWindow(GW_CHILD);
						while(pMDIWndCh)
						{
							pMDIWndCh->RedrawWindow();
							pMDIWndCh = pMDIWndCh->GetNextWindow();
						}
					}
				}
			}
			break;
		}
//		MouseHookHandle = SetWindowsHookEx(WH_MOUSE, Mouse_Hook, pApp->m_hInstance, pApp->m_nThreadID);
//		HookHandle = SetWindowsHookEx(WH_KEYBOARD, Key_Hook, pApp->m_hInstance, pApp->m_nThreadID);
	case methMouseHook:
		{
			if(MouseHookHandle)
			{
				rValue = 1L;
				if(ppValue[0]->GetNumeric() == 0)
				{
					if(UnhookWindowsHookEx(MouseHookHandle) == TRUE)
						MouseHookHandle = NULL;
				}
			}
			else
			{
				rValue = 0L;
				if((ppValue[0]->GetNumeric() == 1) && (pApp != NULL))
				{
					MouseHookHandle = SetWindowsHookEx(WH_MOUSE, Mouse_Hook, pApp->m_hInstance, pApp->m_nThreadID);
				}
			}
			break;
		}
	case methKeyHook:
		{
			if(HookHandle)
			{
				rValue = 1L;
				if(ppValue[0]->GetNumeric() == 0)
				{
					if(UnhookWindowsHookEx(HookHandle) == TRUE)
						HookHandle = NULL;
				}
			}
			else
			{
				rValue = 0L;
				if((ppValue[0]->GetNumeric() == 1) && (pApp != NULL))
				{
					HookHandle = SetWindowsHookEx(WH_KEYBOARD, Key_Hook, pApp->m_hInstance, pApp->m_nThreadID);
				}
			}
			break;
		}
	case methCreateFont:
		{
			CWnd* pMainWnd = GetMainFrame();
			
			CApp7* pApp7 = (CApp7*) AfxGetApp();
			CProfile7* pProfile7 = pApp7->GetProps();
			HFONT hFont = pProfile7->GetHFONTProp(0x2c);//pApp7->GetProfileFont(0);//(HFONT)pMainWnd->GetFont()->GetSafeHandle();

			LOGFONT lFont;
			GetObject(hFont, sizeof(LOGFONT), (LPSTR)&lFont);
			CString strFaceName = ppValue[0]->GetString();
			if(!strFaceName.IsEmpty())
			{
				memcpy(lFont.lfFaceName,LPCSTR(strFaceName),strFaceName.GetLength());
				lFont.lfFaceName[strFaceName.GetLength()] = char(0);
			}

			if(ppValue[1]->GetNumeric() >= 0)
				lFont.lfHeight = ppValue[1]->GetNumeric();
			int w = ppValue[2]->GetNumeric();
			if(w >=0)
			{
				if(w == 1)
					lFont.lfWeight = FW_THIN;
				else if(w == 2)
					lFont.lfWeight = FW_EXTRALIGHT;
				else if(w == 3)
					lFont.lfWeight = FW_LIGHT;
				else if(w == 4)
					lFont.lfWeight = FW_NORMAL;
				else if(w == 5)
					lFont.lfWeight = FW_MEDIUM;
				else if(w == 6)
					lFont.lfWeight = FW_SEMIBOLD;
				else if(w == 7)
					lFont.lfWeight = FW_BOLD;
				else if(w == 8)
					lFont.lfWeight = FW_EXTRABOLD;
				else if(w == 9)
					lFont.lfWeight = FW_HEAVY;
				else
					lFont.lfWeight = FW_DONTCARE;
			}

			if(ppValue[3]->GetNumeric() >= 0)
				lFont.lfItalic = ppValue[3]->GetNumeric();

			if(ppValue[4]->GetNumeric() >= 0)
				lFont.lfUnderline = ppValue[4]->GetNumeric();
			if(ppValue[5]->GetNumeric() >= 0)
				lFont.lfStrikeOut = ppValue[5]->GetNumeric();

			w = ppValue[6]->GetNumeric();
			if(w >= 0)
			{
				lFont.lfEscapement = w;
				lFont.lfOrientation = w;
				lFont.lfOutPrecision = OUT_TT_ONLY_PRECIS;
			}
			if(ppValue[7]->GetNumeric() >= 0)
			{
				lFont.lfCharSet = ppValue[7]->GetNumeric();
			}

			// ANSI_CHARSET            0
			// DEFAULT_CHARSET         1
			// SYMBOL_CHARSET          2
			// SHIFTJIS_CHARSET        128
			// HANGEUL_CHARSET         129
			// HANGUL_CHARSET          129
			// GB2312_CHARSET          134
			// CHINESEBIG5_CHARSET     136
			// OEM_CHARSET             255
			// JOHAB_CHARSET           130
			// HEBREW_CHARSET          177
			// ARABIC_CHARSET          178
			// GREEK_CHARSET           161
			// TURKISH_CHARSET         162
			// VIETNAMESE_CHARSET      163
			// THAI_CHARSET            222
			// EASTEUROPE_CHARSET      238
			// RUSSIAN_CHARSET         204
			// MAC_CHARSET             77
			// BALTIC_CHARSET          186

			rValue = (long)::CreateFontIndirect(&lFont);
			break;
		}
	case methCreateFontCausedBy:
		{
			CWnd* pMainWnd = GetMainFrame();
			
			HFONT hFont = (HFONT)(DWORD)ppValue[0]->GetNumeric();

			LOGFONT lFont;
			GetObject(hFont, sizeof(LOGFONT), (LPSTR)&lFont);
			CString strFaceName = ppValue[1]->GetString();
			if(!strFaceName.IsEmpty())
			{
				memcpy(lFont.lfFaceName,LPCSTR(strFaceName),strFaceName.GetLength());
				lFont.lfFaceName[strFaceName.GetLength()] = char(0);
			}

			if(ppValue[2]->GetNumeric() >= 0)
				lFont.lfHeight = ppValue[2]->GetNumeric();
			int w = ppValue[3]->GetNumeric();
			if(w >=0)
			{
				if(w == 1)
					lFont.lfWeight = FW_THIN;
				else if(w == 2)
					lFont.lfWeight = FW_EXTRALIGHT;
				else if(w == 3)
					lFont.lfWeight = FW_LIGHT;
				else if(w == 4)
					lFont.lfWeight = FW_NORMAL;
				else if(w == 5)
					lFont.lfWeight = FW_MEDIUM;
				else if(w == 6)
					lFont.lfWeight = FW_SEMIBOLD;
				else if(w == 7)
					lFont.lfWeight = FW_BOLD;
				else if(w == 8)
					lFont.lfWeight = FW_EXTRABOLD;
				else if(w == 9)
					lFont.lfWeight = FW_HEAVY;
				else
					lFont.lfWeight = FW_DONTCARE;
			}

			if(ppValue[4]->GetNumeric() >= 0)
				lFont.lfItalic = ppValue[4]->GetNumeric();

			if(ppValue[5]->GetNumeric() >= 0)
				lFont.lfUnderline = ppValue[5]->GetNumeric();
			if(ppValue[6]->GetNumeric() >= 0)
				lFont.lfStrikeOut = ppValue[6]->GetNumeric();

			w = ppValue[7]->GetNumeric();
			if(w >= 0)
			{
				lFont.lfEscapement = w;
				lFont.lfOrientation = w;
				lFont.lfOutPrecision = OUT_TT_ONLY_PRECIS;
			}
			if(ppValue[8]->GetNumeric() >= 0)
			{
				lFont.lfCharSet = ppValue[8]->GetNumeric();
			}

			rValue = (long)::CreateFontIndirect(&lFont);
			break;
		}
	case methSendKeys:
		{
			CString strLang = "";
			if(ppValue[2]->type == 1)
			{
				long l = ppValue[2]->GetNumeric();
				switch(l)
				{
					case 1:
						strLang = "English (United States)";
						break;
					case 2:
						strLang = "Russian";
						break;
					case 3:
						strLang = "Ukrainian";
						break;
					case 4:
						strLang = "Belarusian";
						break;
					case 5:
						strLang = "German (Germany)";
						break;
					case 6:
						strLang = "French (France)";
						break;
					default:
						strLang = "English (United States)";
				}
			}
			else
				strLang = ppValue[2]->GetString();
			rValue = (long)SendKeys((char*)ppValue[0]->Format(),ppValue[1]->GetNumeric() != 0L, (LPCTSTR) strLang);
			break;
		}
	case methGetPrintersList:
		{
			CBLContext* pVLCont = CBLContext::CreateInstance("СписокЗначений");
			if(pVLCont)
			{
				int num = pVLCont->FindMethod("AddValue");
				if(num >= 0)
				{
					CString st = "";
					CValue v1;
					CValue v2;
					CValue *pParam[2] = {&v1, &v2};
					DWORD				dwSizeNeeded;
					DWORD				dwNumItems;
					DWORD				dwItem;

					LPBYTE	lpInfo = NULL;
					DWORD Flags = PRINTER_ENUM_LOCAL;
					DWORD Level = 2;
					if(myPlatformId == VER_PLATFORM_WIN32_NT)
					{
						//Level++;
						Flags |= PRINTER_ENUM_CONNECTIONS;
					}

					// Get buffer size
					EnumPrinters ( Flags, NULL, Level, NULL, 0, &dwSizeNeeded, &dwNumItems );

					// allocate memory
					lpInfo = (LPBYTE)malloc(dwSizeNeeded);
					if (lpInfo)
					if ( EnumPrinters ( Flags,		// what to enumerate
								NULL,			// printer name (NULL for all)
								Level,				// level
								(LPBYTE)lpInfo,		// buffer
								dwSizeNeeded,		// size of buffer
								&dwSizeNeeded,		// returns size
								&dwNumItems			// return num. items
							  ))
						for ( dwItem = 0; dwItem < dwNumItems; dwItem++ )
						{
							if(myPlatformId == VER_PLATFORM_WIN32_NT)
								st = CString(LPPRINTER_INFO_2(lpInfo)[dwItem].pPrinterName);
							else
								st = CString(LPPRINTER_INFO_2(lpInfo)[dwItem].pPrinterName);

							v1 = st;
							v2 = st;
							pVLCont->CallAsProc(num,pParam);
						}
					free(lpInfo);
				}
				rValue.AssignContext(pVLCont);
			}
			break;
		}
	case methIsPrinterReady:
		{
			rValue = -1L;
			CString st = ppValue[0]->GetString();
			DWORD				dwSizeNeeded;
			DWORD				dwNumItems;
			DWORD				dwItem;

			LPBYTE	lpInfo = NULL;
			DWORD Flags = PRINTER_ENUM_LOCAL;
			DWORD Level = 2;
			if(myPlatformId == VER_PLATFORM_WIN32_NT)
			{
				//Level++;
				Flags |= PRINTER_ENUM_CONNECTIONS;
			}

			// Get buffer size
			EnumPrinters ( Flags, NULL, Level, NULL, 0, &dwSizeNeeded, &dwNumItems );

			// allocate memory
			lpInfo = (LPBYTE)malloc(dwSizeNeeded);
			if (lpInfo)
			if ( EnumPrinters ( Flags,		// what to enumerate
						NULL,			// printer name (NULL for all)
						Level,				// level
						(LPBYTE)lpInfo,		// buffer
						dwSizeNeeded,		// size of buffer
						&dwSizeNeeded,		// returns size
						&dwNumItems			// return num. items
					  ))
				for ( dwItem = 0; dwItem < dwNumItems; dwItem++ )
				{
					if(st == LPPRINTER_INFO_2(lpInfo)[dwItem].pPrinterName)
					{
						DWORD ret = LPPRINTER_INFO_2(lpInfo)[dwItem].Status;
						if(ret == 0)
							rValue = 0L;
						else
						{
							CBLContext* pVLCont = CBLContext::CreateInstance("СписокЗначений");
							if(pVLCont)
							{
								int num = pVLCont->FindMethod("AddValue");
								if(num >= 0)
								{
									CString st = "";
									CValue v1;
									CValue v2;
									CValue *pParam[2] = {&v1, &v2};
									if(ret & PRINTER_STATUS_PAUSED)
									{
										st = "Принтер в режиме ПАУЗА";
										v1 = st; v2 = st;
										pVLCont->CallAsProc(num,pParam);
									}
									if(ret & PRINTER_STATUS_ERROR)
									{
										st = "Ошибка принтера";
										v1 = st; v2 = st;
										pVLCont->CallAsProc(num,pParam);
									}
									if(ret & PRINTER_STATUS_PENDING_DELETION)
									{
										st = "Удаление задачи";
										v1 = st; v2 = st;
										pVLCont->CallAsProc(num,pParam);
									}
									if(ret & PRINTER_STATUS_PAPER_JAM)
									{
										st = "Застряла бумага";
										v1 = st; v2 = st;
										pVLCont->CallAsProc(num,pParam);
									}
									if(ret & PRINTER_STATUS_PAPER_OUT)
									{
										st = "Нет бумаги";
										v1 = st; v2 = st;
										pVLCont->CallAsProc(num,pParam);
									}
									if(ret & PRINTER_STATUS_MANUAL_FEED)
									{
										st = "Включена ручная подача бумаги";
										v1 = st; v2 = st;
										pVLCont->CallAsProc(num,pParam);
									}
									if(ret & PRINTER_STATUS_PAPER_PROBLEM)
									{
										st = "Проблемы с бумагой";
										v1 = st; v2 = st;
										pVLCont->CallAsProc(num,pParam);
									}
									if(ret & PRINTER_STATUS_OFFLINE)
									{
										st = "Принтер выключен";
										v1 = st; v2 = st;
										pVLCont->CallAsProc(num,pParam);
									}
									if(ret & PRINTER_STATUS_IO_ACTIVE)
									{
										st = "Порт принтера занят";
										v1 = st; v2 = st;
										pVLCont->CallAsProc(num,pParam);
									}
									if(ret & PRINTER_STATUS_BUSY)
									{
										st = "Принтер занят";
										v1 = st; v2 = st;
										pVLCont->CallAsProc(num,pParam);
									}
									if(ret & PRINTER_STATUS_PRINTING)
									{
										st = "Идет печать";
										v1 = st; v2 = st;
										pVLCont->CallAsProc(num,pParam);
									}
									if(ret & PRINTER_STATUS_OUTPUT_BIN_FULL)
									{
										st = "Очередь переполнена";
										v1 = st; v2 = st;
										pVLCont->CallAsProc(num,pParam);
									}
									if(ret & PRINTER_STATUS_NOT_AVAILABLE)
									{
										st = "Принтер недоступен";
										v1 = st; v2 = st;
										pVLCont->CallAsProc(num,pParam);
									}
									if(ret & PRINTER_STATUS_WAITING)
									{
										st = "Принтер в режиме ОЖИДАНИЕ";
										v1 = st; v2 = st;
										pVLCont->CallAsProc(num,pParam);
									}
									if(ret & PRINTER_STATUS_PROCESSING)
									{
										st = "Прием задания на печать";
										v1 = st; v2 = st;
										pVLCont->CallAsProc(num,pParam);
									}
									if(ret & PRINTER_STATUS_INITIALIZING)
									{
										st = "Принтер инициализируется";
										v1 = st; v2 = st;
										pVLCont->CallAsProc(num,pParam);
									}
									if(ret & PRINTER_STATUS_WARMING_UP)
									{
										st = "Прогрев принтера";
										v1 = st; v2 = st;
										pVLCont->CallAsProc(num,pParam);
									}
									if(ret & PRINTER_STATUS_TONER_LOW)
									{
										st = "Низкий уровень тонера";
										v1 = st; v2 = st;
										pVLCont->CallAsProc(num,pParam);
									}
									if(ret & PRINTER_STATUS_NO_TONER)
									{
										st = "Нет тонера";
										v1 = st; v2 = st;
										pVLCont->CallAsProc(num,pParam);
									}
									if(ret & PRINTER_STATUS_PAGE_PUNT)
									{
										st = "Перекос листа";
										v1 = st; v2 = st;
										pVLCont->CallAsProc(num,pParam);
									}
									if(ret & PRINTER_STATUS_USER_INTERVENTION)
									{
										st = "Печать прервана пользователем";
										v1 = st; v2 = st;
										pVLCont->CallAsProc(num,pParam);
									}
									if(ret & PRINTER_STATUS_OUT_OF_MEMORY)
									{
										st = "Недостаточно памяти";
										v1 = st; v2 = st;
										pVLCont->CallAsProc(num,pParam);
									}
									if(ret & PRINTER_STATUS_DOOR_OPEN)
									{
										st = "Открыт лоток принтера";
										v1 = st; v2 = st;
										pVLCont->CallAsProc(num,pParam);
									}
									if(ret & PRINTER_STATUS_SERVER_UNKNOWN)
									{
										st = "Неизвестный сервер";
										v1 = st; v2 = st;
										pVLCont->CallAsProc(num,pParam);
									}
									if(ret & PRINTER_STATUS_POWER_SAVE)
									{
										st = "Принтер в режиме ЭНЕРГОСБЕРЕЖЕНИЯ";
										v1 = st; v2 = st;
										pVLCont->CallAsProc(num,pParam);
									}
								}
								rValue.AssignContext(pVLCont);
							}
							else
								rValue = -2L;
						}
						break;
					}
				}
			free(lpInfo);
			break;
		}
	case methUnLoadAddIn:
		{
			// TODO: необходимо разобраться с отключением страницы свойств компоненты
			// void CAppFrame::RemoveOptionsPage(struct _GUID const &);
			
			CString stAddInName = ppValue[0]->GetString();
			rValue = 0L;
			CApp7* pApp = (CApp7*)AfxGetApp();
			if(pApp)
			{
				//UINT n = *(UINT*)((DWORD)pApp+0x260);
				UINT n = (UINT)pApp->bufAppFrame[103];
				DWORD** ppAddInArray = (DWORD**)pApp->bufAppFrame[102];
				for(UINT i = 0; i < n; i++)
				{
					DWORD** pAddIn = (DWORD**)ppAddInArray[i];
					char* pAddInFullName = (char*)pAddIn[9];
					HMODULE hAddIn = (HMODULE)pAddIn[8];
					char lpFullPath[_MAX_PATH];
					LPTSTR lpAddInFileName;
					GetFullPathName(pAddInFullName,_MAX_PATH,lpFullPath,&lpAddInFileName);
					if(stAddInName.CompareNoCase(lpAddInFileName) == 0)
					{
						int m = (int)pAddIn[12];
						DWORD** pAddInObjArr = (DWORD**)pAddIn[11];

						for(int t = 0; t < m; t++)
						{
							DWORD* pAddInCurObj = pAddInObjArr[t];
							struct _GUID* pAddInObjGUID = (struct _GUID*)(pAddInCurObj+7);
							pApp->RemoveOptionsPage(*pAddInObjGUID);

						}
						((tempAddInClass*)pAddIn)->UnLoadAddIn(0);
						for(UINT f = i; f < (n-1); f++)
							ppAddInArray[f] = ppAddInArray[f+1];
						pApp->bufAppFrame[103] = n - 1;

						::AfxFreeLibrary(hAddIn);

						rValue = 1L;
						break;
					}
				}
			}
			break;
		}
	case methListMoxel:
		{
			/*
IDispatch *pDisp = NULL;
HRESULT hr = ::CreateObject (L"Excel.Application", &pDisp);
// код функции, возвращающей по ProgID указатель на IDispatch, простой, если надо пришлю

CStdOleBLContext *pOleCont = new CStdOleBLContext(TRUE);
reinterpret_cast<void**> (pOleCont) [8] = pDisp;

rValue.Reset ();
rValue.AssignContext (pOleCont);

pOleCont -> DecrRef ();
*/

			CBLContext* pVLCont = CBLContext::CreateInstance("СписокЗначений");
			if(pVLCont)
			{

				int num = pVLCont->FindMethod("AddValue");
				if(num >= 0)
				{
					CMDIFrameWnd* pMainFrame = GetMainFrame();
					if(pMainFrame)
					{
						CMDIChildWnd * pChild = pMainFrame->MDIGetActive();
										
						while(pChild)
						{
							CString st = "";
							pChild->GetWindowText(st);
							CValue v1;
							CValue v2 = st;
							CValue *pParam[2] = {&v1, &v2};
							CDocument* pDoc = pChild->GetActiveDocument();
							if(pDoc)
								if(CString("CSheetDoc") == pDoc->GetRuntimeClass()->m_lpszClassName)
								{
									CSheetDoc* pSheetDoc = (CSheetDoc*)pDoc;
									CBLContext* pTabCont = CBLContext::CreateInstance("Table");
									if(pTabCont)
									{
										((CTableWrapEx*)pTabCont)->m_pSheetDocOut = pSheetDoc;
										((CTableWrapEx*)pTabCont)->dwFlag1 = CTemplate7::GetDocumentID(pSheetDoc);
										DWORD dw = (DWORD)pSheetDoc;
										((CTableWrapEx*)pTabCont)->dwFlag2 = (dw + 0xB0);
										((DWORD*)pTabCont)[0x118] = 1;
										((DWORD*)pTabCont)[0x11D] = 1;
										v1.AssignContext(pTabCont);
										pVLCont->CallAsProc(num,pParam);
									}
								}
							

							pChild = (CMDIChildWnd*)pChild->GetNextWindow();
						}
					}
				}
				rValue.AssignContext(pVLCont);
			}
			break;
		}
	case methIdleProcessing:
		{
			rValue = "";
			if(!strTimerName.IsEmpty())
				rValue = strTimerName;

			CWnd* pMainWnd = GetMainFrame();
			if(pMainWnd)
			{
				UINT nElapse = ppValue[1]->GetNumeric();
				strTimerName = ppValue[0]->GetString();
				if(strTimerName.IsEmpty() || (nElapse == 0))
				{
					if(uTimer)
						pMainWnd->KillTimer(uTimer);
					uTimer = 0;
				}
				else
				{
					if(uTimer)
						pMainWnd->KillTimer(uTimer);
					uTimer = pMainWnd->SetTimer(501,nElapse,(TIMERPROC)TimerProc);
//					if(uTimer) rValue = 1;
				}
			}
			break;
		}
	case methOSVersion:
		{
			OSVERSIONINFOEXEX osvi;
			ZeroMemory(&osvi, sizeof(OSVERSIONINFOEXEX));
			osvi.dwOSVersionInfoSize = sizeof(OSVERSIONINFOEXEX);
			BOOL bOsVersionInfoEx;
			if( !(bOsVersionInfoEx = GetVersionEx ((OSVERSIONINFO *) &osvi)) )
			{
				osvi.dwOSVersionInfoSize = sizeof (OSVERSIONINFO);
				if (! GetVersionEx ( (OSVERSIONINFO *) &osvi) ) 
					return S_FALSE;
			}

			CString stRet = "";
			CString stVer = "";
			switch (osvi.dwPlatformId)
			{
				// Test for the Windows NT product family.
			case VER_PLATFORM_WIN32_NT:
				
				stRet = "NT\r\n";
				// Test for the specific product.
				if ( osvi.dwMajorVersion == 5 && osvi.dwMinorVersion == 2 )
					stRet += "Server2003\r\n";
				
				if ( osvi.dwMajorVersion == 5 && osvi.dwMinorVersion == 1 )
					stRet += "XP\r\n";
				
				if ( osvi.dwMajorVersion == 5 && osvi.dwMinorVersion == 0 )
					stRet += "2000\r\n";
				
				if ( osvi.dwMajorVersion <= 4 )
					stRet += "NT\r\n";
				
				// Test for specific product on Windows NT 4.0 SP6 and later.
				if( bOsVersionInfoEx )
				{
					// Test for the workstation type.
					if ( osvi.wProductType == VER_NT_WORKSTATION )
					{
						if( osvi.dwMajorVersion == 4 )
							stRet += "Workstation40\r\n";
						else if( osvi.wSuiteMask & VER_SUITE_PERSONAL )
							stRet += "HomeEdition\r\n";
						else
							stRet += "Professional\r\n";
					}
					
					// Test for the server type.
					else if ( osvi.wProductType == VER_NT_SERVER || 
						osvi.wProductType == VER_NT_DOMAIN_CONTROLLER )
					{
						if( osvi.dwMajorVersion == 5 && osvi.dwMinorVersion == 2 )
						{
							if( osvi.wSuiteMask & VER_SUITE_DATACENTER )
								stRet += "DatacenterEdition\r\n";
							else if( osvi.wSuiteMask & VER_SUITE_ENTERPRISE )
								stRet += "EnterpriseEdition\r\n";
							else if ( osvi.wSuiteMask == VER_SUITE_BLADE )
								stRet += "WebEdition\r\n";
							else
								stRet += "StandardEdition\r\n";
						}
						
						else if( osvi.dwMajorVersion == 5 && osvi.dwMinorVersion == 0 )
						{
							if( osvi.wSuiteMask & VER_SUITE_DATACENTER )
								stRet += "DatacenterServer\r\n";
							else if( osvi.wSuiteMask & VER_SUITE_ENTERPRISE )
								stRet += "AdvancedServer\r\n";
							else
								stRet += "Server\r\n";
						}
						
						else  // Windows NT 4.0 
						{
							if( osvi.wSuiteMask & VER_SUITE_ENTERPRISE )
								stRet += "Server40EnterpriseEdition\r\n";
							else
								stRet += "Server40\r\n";
						}
					}
				}
				else  // Test for specific product on Windows NT 4.0 SP5 and earlier
				{
					HKEY hKey;
					char szProductType[BUFSIZE];
					DWORD dwBufLen=BUFSIZE;
					LONG lRet;
					
					lRet = RegOpenKeyEx( HKEY_LOCAL_MACHINE,
						"SYSTEM\\CurrentControlSet\\Control\\ProductOptions",
						0, KEY_QUERY_VALUE, &hKey );
					if( lRet == ERROR_SUCCESS )
					{
						
						lRet = RegQueryValueEx( hKey, "ProductType", NULL, NULL,
							(LPBYTE) szProductType, &dwBufLen);
						if((lRet == ERROR_SUCCESS) && (dwBufLen <= BUFSIZE))
						{
							RegCloseKey( hKey );
							
							if ( lstrcmpi( "WINNT", szProductType) == 0 )
								stRet += "Workstation";
							if ( lstrcmpi( "LANMANNT", szProductType) == 0 )
								stRet += "Server";
							if ( lstrcmpi( "SERVERNT", szProductType) == 0 )
								stRet += "AdvancedServer";
							
							stVer.Format("%d%d\r\n", osvi.dwMajorVersion, osvi.dwMinorVersion );
							stRet += stVer;
						}
					}
				}
				
				// Display service pack (if any) and build number.
				
				if( osvi.dwMajorVersion == 4 && 
					lstrcmpi( osvi.szCSDVersion, "Service Pack 6" ) == 0 )
				{
					HKEY hKey;
					LONG lRet;
					
					// Test for SP6 versus SP6a.
					lRet = RegOpenKeyEx( HKEY_LOCAL_MACHINE,
						"SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\Hotfix\\Q246009",
						0, KEY_QUERY_VALUE, &hKey );
					if( lRet == ERROR_SUCCESS )
						stVer.Format( "Service Pack 6a (Build %d)\r\n", osvi.dwBuildNumber & 0xFFFF );         
					else // Windows NT 4.0 prior to SP6a
					{
						stVer.Format( "%s (Build %d)\r\n",
							osvi.szCSDVersion,
							osvi.dwBuildNumber & 0xFFFF);
					}
					
					RegCloseKey( hKey );
				}
				else // not Windows NT 4.0 
				{
					stVer.Format( "%s (Build %d)\r\n",
						osvi.szCSDVersion,
						osvi.dwBuildNumber & 0xFFFF);
				}
				
				stRet += stVer;
				
				break;
				
				// Test for the Windows Me/98/95.
			case VER_PLATFORM_WIN32_WINDOWS:
				  
				stRet = "9x\r\n";
				if (osvi.dwMajorVersion == 4 && osvi.dwMinorVersion == 0)
				{
					stRet += "Windows95\n";
					if ( osvi.szCSDVersion[1] == 'C' || osvi.szCSDVersion[1] == 'B' )
						stRet += "OSR2\r\n";
				} 
				  
				if (osvi.dwMajorVersion == 4 && osvi.dwMinorVersion == 10)
				{
					stRet += "Windows98\r\n";
					if ( osvi.szCSDVersion[1] == 'A' )
						stRet += "SE\r\n";
				} 
				  
				if (osvi.dwMajorVersion == 4 && osvi.dwMinorVersion == 90)
				{
					stRet += "WindowsME\r\n";
				} 
				break;
				  
			case VER_PLATFORM_WIN32s:
				  
				stRet = "Win32s\r\n";
				break;
			}

			rValue = stRet;
			
			break;
		}
	case methActiveContext:
		{
			rValue = 0L;
			CMDIFrameWnd * pMainFrame = GetMainFrame();
			if(pMainFrame)
			{
				CGetDoc7* pDoc7 = CGetDlg::GetTopmostDocunent();
				// фиксим вызов метода до физического открытия окна обработки
				if(pDoc7)
				{
					if(pDoc7->ExistWindow() == 0)
						pDoc7 = NULL;
					else
					{
						CWnd* pWnd = pDoc7->GetForm();
						if((pWnd == NULL) || (pWnd->IsWindowVisible() == FALSE))
						pDoc7 = NULL;
					}
				}
				if(pDoc7)
				{
					CGroupContext *pCont = pDoc7->GetGroupContext();
					if(pCont)
					{
						rValue = 1L;
						pCont->IncrRef();
						ppValue[0]->AssignContext(pCont);
					}
				}
				else
				{
					CMDIChildWnd * pChild = pMainFrame->MDIGetActive();
									
					if(pChild)
					{
						CDocument* pDoc = pChild->GetActiveDocument();
						if(pDoc)
						{
							if(!strcmp(pDoc->GetRuntimeClass()->m_pfnGetBaseClass()->m_lpszClassName,"CGetDoc7"))
							{
								CGroupContext *pCont = ((CGetDoc7*)pDoc)->GetGroupContext();
								if(pCont)
								{
									rValue = 1L;
									pCont->IncrRef();
									ppValue[0]->AssignContext(pCont);
								}
							}
							else if(CString("CSheetDoc") == pDoc->GetRuntimeClass()->m_lpszClassName)
							{
								CSheetDoc* pSheetDoc = (CSheetDoc*)pDoc;
								CBLContext* pTabCont = CBLContext::CreateInstance("Table");
								if(pTabCont)
								{
									((CTableWrapEx*)pTabCont)->m_pSheetDocOut = pSheetDoc;
									((CTableWrapEx*)pTabCont)->dwFlag1 = CTemplate7::GetDocumentID(pSheetDoc);
									DWORD dw = (DWORD)pSheetDoc;
									((CTableWrapEx*)pTabCont)->dwFlag2 = (dw + 0xB0);
									((DWORD*)pTabCont)[0x118] = 1;
									((DWORD*)pTabCont)[0x11D] = 1;
									rValue = 1L;
									ppValue[0]->AssignContext(pTabCont);
								}
							}
						}
					}
				}
			}
			break;
		}
#ifndef FORMEX_DLL
	case methLoadModule:
		{
			rValue = 0L;
			CBLModule * pMod = CBLModule::GetExecutedModule();
			CBLContext* pCont = CBLModuleWrapper::GetContextFromModule(pMod);
			if (pCont)      
			{
				if (!(pCont->m_FlagAutoDestroy > 100))        
					pCont->m_FlagAutoDestroy = (int)new CGCBoost::SGCInfo(pMod,NULL);
				
				rValue = 1L;
			}
			break;
		}
	case methUnLoadModule:
		{      
			rValue = 0L; //VerQueryValueA
			CBLModule * pMod = CBLModule::GetExecutedModule();
			CBLContext* pCont = CBLModuleWrapper::GetContextFromModule(pMod);
			if (pCont)      
			{
				rValue = 1L;
				if (((CGCBoost::SGCInfo*)pCont)->m_pData == NULL)
					delete (CGCBoost::SGCInfo*)pCont->m_FlagAutoDestroy;
			}			
			break;
		}
#endif
	case methCallAsProcedure:
		{
			rValue = 0L;
			CGroupContext * pCont = (CGroupContext*)ppValue[0]->GetContext();
			CBLModule * pMod;
			if(pCont)
			{
				pMod = GetModuleByContext(pCont);
			}
			else
			{
				pMod = CBLModule::GetExecutedModule();
			}
			if(pMod)
			{
				int r = pMod->FindProc(ppValue[1]->GetString(),0);
				if(r<0) r = pMod->FindFunc(ppValue[1]->GetString());
				if(r>=0)
				{
					CBLProcInfo * pProcInfo;
					pProcInfo = new CBLProcInfo();
					pMod->GetProcInfo(r,*pProcInfo);
					int nParams = pProcInfo->GetNParams();
					int s = 0;
					int i;

					CValue** lArray = NULL;
					if(nParams > 0)
					{
						lArray = new PValueT[nParams];
    
						CBLContext* pValListCont = ppValue[2]->GetContext();
						if(pValListCont)
						{
							if(!strcmp(pValListCont->GetRuntimeClass()->m_lpszClassName,"CValueListContext"))
							{
								CValueListContextData* pVLCD = ((CValueListContextData*)pValListCont->GetInternalData());
								PValueItemArrayT *pValItAr = (PValueItemArrayT*)pVLCD->GetValueList();
								if(nParams>=pValItAr->GetSize()) s = pValItAr->GetSize();
								else s = nParams;

								for(i=0; i<s; i++) lArray[i] = (CValue*)pValItAr->GetAt(i);
							}
						}

						for(i=s; i<nParams; i++)
						{
							lArray[i] = (CValue*)malloc(sizeof(CValue));
							lArray[i]->CValue::CValue();
						}
					}

					rValue = pMod->CallAsProc(r,nParams,lArray);
					if(rValue.GetNumeric() == 0)
					{
						CValue arValue;
						rValue = pMod->CallAsFunc(r,arValue,nParams,lArray);
					}

					for(i=s; i<nParams; i++)
					{
						lArray[i]->CValue::~CValue();
						free(lArray[i]);
					}
					delete pProcInfo;
				}
			};
			break;
		}
	case methCallAsFunction:
		{
			rValue = 0L;
			CGroupContext * pCont = (CGroupContext*)ppValue[0]->GetContext();
			CBLModule * pMod;
			if(pCont)
			{
				pMod = GetModuleByContext(pCont);
			}
			else
			{
				pMod = CBLModule::GetExecutedModule();
			}
			if(pMod)
			{
				int r = pMod->FindFunc(ppValue[1]->GetString());
				if(r>=0)
				{
					CBLProcInfo * pProcInfo;
					pProcInfo = new CBLProcInfo();
					pMod->GetProcInfo(r,*pProcInfo);
					int nParams = pProcInfo->GetNParams();
					int s = 0;
					int i;

					CValue** lArray = NULL;
					if(nParams > 0)
					{
						lArray = new PValueT[nParams];

						CBLContext* pValListCont = ppValue[2]->GetContext();
						if(pValListCont)
						{
							if(!strcmp(pValListCont->GetRuntimeClass()->m_lpszClassName,"CValueListContext"))
							{
								CValueListContextData* pVLCD = ((CValueListContextData*)pValListCont->GetInternalData());
								PValueItemArrayT *pValItAr = (PValueItemArrayT*)pVLCD->GetValueList();
								if(nParams>=pValItAr->GetSize()) s = pValItAr->GetSize();
								else s = nParams;

								for(i=0; i<s; i++) lArray[i] = (CValue*)pValItAr->GetAt(i);
							}
						}

						for(i=s; i<nParams; i++)
						{
							lArray[i] = (CValue*)malloc(sizeof(CValue));
							lArray[i]->CValue::CValue();
						}
					}

					CValue arValue;

					rValue = pMod->CallAsFunc(r,arValue,nParams,lArray);
					if(rValue.GetNumeric()) *ppValue[3] = arValue;

					for(i=s; i<nParams; i++)
					{
						lArray[i]->CValue::~CValue();
						free(lArray[i]);
					}
					delete pProcInfo;
				}
			}
			break;
		}
	case methGetContextVar:
		{
			rValue = 0L;
			CGroupContext * pCont = (CGroupContext*)ppValue[0]->GetContext();
			CBLModule * pMod;
			if(pCont)
			{
				pMod = GetModuleByContext(pCont);
			}
			else
			{
				pMod = CBLModule::GetExecutedModule();
			}
			if(pMod)
			{
				int r = pMod->FindStaticVar(ppValue[1]->GetString());
				if(r>=0)
					rValue = pMod->GetStaticVarValue(r,*ppValue[2],0);
			}
			break;
		}
	case methSetContextVar:
		{
			rValue = 0L;
			CGroupContext * pCont = (CGroupContext*)ppValue[0]->GetContext();
			CBLModule * pMod;
			if(pCont)
			{
				pMod = GetModuleByContext(pCont);
			}
			else
			{
				pMod = CBLModule::GetExecutedModule();
			}
			if(pMod)
			{
				int r = pMod->FindStaticVar(ppValue[1]->GetString());
				if(r>=0) rValue = pMod->SetStaticVarValue(r,*ppValue[2],0);
			}
			break;
		}
	case methChooseValue:
		{
			/*
CPoint CCursorGridCtrl::GetContextMenuPosition() const;
(координаты экрана)
класс табличного поля: CV7CursorGridCtrl
наследуется от CCursorGridCtrl
так что проверить можно так: pWnd->GetRuntimeClass() == RUNTIME_CLASS(CV7CursorGridCtrl)
			*/
			pBkEndUI->DoStatusLine("Выбор значения");
			rValue = 0L;
			CBLContext* pValListCont = ppValue[0]->GetContext();
			if(pValListCont)
			{
				if(!strcmp(pValListCont->GetRuntimeClass()->m_lpszClassName,"CValueListContext"))
				{
					CValueListContextData* pVLCD = ((CValueListContextData*)pValListCont->GetInternalData());
					PValueItemArrayT *pValItAr = (PValueItemArrayT*)pVLCD->GetValueList();

					int s = pValItAr->GetSize();
					structVIA** pVIA = new PstructVIA[s];
					CPtrArray AllValues;
					CPtrArray AllValuesArray;
					ULONG index = 0;
					// AM - next line changed
					GetFromVL(pVIA, pValItAr, s, &index, &AllValues, &AllValuesArray, ppValue[1]);

					if(ppValue[3]->GetNumeric() == 1)
					{
						AFX_MANAGE_STATE(AfxGetStaticModuleState())
						CTreeChoose* pTreeChoose;
						pTreeChoose = new CTreeChoose((char*)(LPCSTR)ppValue[2]->GetString(), GetMainFrame());
						pTreeChoose->SetTreeArray(pVIA, s);
						pTreeChoose->m_SelGroup = (ppValue[4]->GetNumeric() !=  0);
						int nRet = -1;
						nRet = pTreeChoose->DoModal();

						switch ( nRet )
						{
							case IDOK:
								if(pTreeChoose->m_Selected)
								{
									rValue = 1L;
									*ppValue[1] = *((CValue*)(pTreeChoose->m_Selected));
								}
								break;
							case -1:
								pBkEndUI->DoMessageLine("ERROR!", mmNone);
								break;
							default:
								break;
						};

						delete pTreeChoose;
					}
					else
					{
						POINT pos;
						pos.x = 0;
						pos.y = 0;
						::GetCursorPos(&pos);
						BOOL CheckItem = ((ppValue[4]->GetNumeric() == 1) || (ppValue[4]->GetNumeric() == 3));
						CGetDoc7* pDoc7 = CGetDlg::GetTopmostDocunent();
						CMDIFrameWnd* pMain = GetMainFrame();
						CWnd* pParent = CWnd::FromHandle(pMain->m_hWndMDIClient);
						if(pDoc7)
						{
							CGetDlg* pGetDlg = (CGetDlg*)pDoc7->GetFrame();
							if(pGetDlg)
							{
								pParent = (CWnd*)pGetDlg;
								if(ppValue[4]->GetNumeric() < 2)
								{
									CGetField * pField = ((CGetDoc7*)pDoc7)->GetActiveField();
									if(pField)
									{
										CBrowse* pBr = ((CGetDoc*)pDoc7)->GetBrowse();
										int ColIndex = -1;
										if(pBr)
											ColIndex = pBr->GetColumnIndex(((CFormCtrl*)pField)->m_ID);
										if(ColIndex < 0)
										{
											CWnd* pWnd = pGetDlg->GetDlgItem(((CFormCtrl*)pField)->m_ID);
											if(pWnd)
											{
												RECT rcItem = {0,0,0,0};
												if(CString("CBrowse") == pWnd->GetRuntimeClass()->m_lpszClassName)
												{
													int curCol = (int)*((int*)pWnd+0x31);
													int curRow = (int)*((int*)pWnd+0x30);
													if((*((int*)pWnd+0x23) == 0) && (*((int*)pWnd+0x2A) >= 0))
														curRow =  (int)*((int*)pWnd+0x2A);
													((CBrowse*)pWnd)->GetCellRect(&rcItem, curRow,curCol);
													pWnd->ClientToScreen(&rcItem);
												}
												else
												{
													pWnd->GetWindowRect(&rcItem);
												}
												pos.x = rcItem.left;
												pos.y = rcItem.bottom;
											}
										}
										else
										{
											RECT rcItem = {0,0,0,0};
											int curCol = (int)*((int*)pBr+0x31);
											int curRow = (int)*((int*)pBr+0x30);
											if((*((int*)pBr+0x23) == 0) && (*((int*)pBr+0x2A) >= 0))
												curRow =  (int)*((int*)pBr+0x2A);
											pBr->GetCellRect(&rcItem, curRow,curCol);
											pBr->ClientToScreen(&rcItem);
											pos.x = rcItem.left;
											pos.y = rcItem.bottom;
										}
									}
								}
							}
						}
						else
						{
							CMDIFrameWnd * pMainFrame = GetMainFrame();
							if(pMainFrame)
							{
								CMDIChildWnd * pChild = pMainFrame->MDIGetActive();
								if(pChild)
								{
									CView* pView = pChild->GetActiveView();
									if(pView)
									{
										pParent = (CWnd*)pView;
										if(ppValue[4]->GetNumeric() < 2)
										{
											CDocument* pDoc = pView->GetDocument();
											if(pDoc)
											{
												if(CString("CSheetDoc") == pDoc->GetRuntimeClass()->m_lpszClassName)
												{
													//CSheetDoc* pSheetDoc = (CSheetDoc*)pDoc;
													//pParent //CSheetView
													//pChild //CSplittFrame
													CSheetView* pSheetView = (CSheetView*)pParent;
													CSheetSelection* pSel = pSheetView->GetTailSelection();
													CRect rcItem = pSheetView->GetSelectionRect(pSel);
													pSheetView->ClientToScreen(&rcItem);
													pos.x = rcItem.left;
													pos.y = rcItem.bottom;
												}
												else
												{
													CGetField * pField = ((CGetDoc7*)pDoc)->GetActiveField();
													if(pField)
													{
#ifndef FORMEX_DLL
														CWnd* pFieldWnd = ((CGetDoc7*)pDoc)->GetFieldWnd(pField);
														bool bCGField = false;
														if(pFieldWnd && pFieldWnd->IsKindOf(RUNTIME_CLASS(CV7CursorGridCtrl)))
														{
															bCGField = true;
															CPoint ptCGC = ((CV7CursorGridCtrl*)pFieldWnd)->GetContextMenuPosition();
															pos.x = ptCGC.x;
															pos.y = ptCGC.y;
														}

														if(bCGField == false)
														{
#endif
															CBrowse* pBr = ((CGetDoc*)pDoc)->GetBrowse();
															int ColIndex = -1;
															if(pBr)
															{
																CString str = pBr->GetRuntimeClass()->m_lpszClassName;
																if(CString("CMySuperGrid") == pBr->GetRuntimeClass()->m_lpszClassName)
																{
																	if(((CFormCtrl*)pField)->m_ID == pBr->GetDlgCtrlID())
																		ColIndex = -2;
																}
																else
																	ColIndex = pBr->GetColumnIndex(((CFormCtrl*)pField)->m_ID);
															}

															if(ColIndex == -2)
															{
																CRect rcItem;
																((CMySuperGrid*)pBr)->GetSelRect(rcItem);
																if(!rcItem.IsRectEmpty())
																{
																	pBr->ClientToScreen(&rcItem);
																	pos.x = rcItem.left;
																	pos.y = rcItem.bottom;
																}
															}
															else if(ColIndex < 0)
															{
																CWnd* pWnd = pView->GetDlgItem(((CFormCtrl*)pField)->m_ID);
																if(pWnd)
																{
																	RECT rcItem = {0,0,0,0};
																	if(CString("CBrowse") == pWnd->GetRuntimeClass()->m_lpszClassName)
																	{
																		int curCol = (int)*((int*)pWnd+0x31);
																		int curRow = (int)*((int*)pWnd+0x30);
																		if((*((int*)pWnd+0x23) == 0) && (*((int*)pWnd+0x2A) >= 0))
																			curRow =  (int)*((int*)pWnd+0x2A);
																		((CBrowse*)pWnd)->GetCellRect(&rcItem, curRow,curCol);
																		pWnd->ClientToScreen(&rcItem);
																	}
																	else
																	{
																		pWnd->GetWindowRect(&rcItem);
																	}
																	pos.x = rcItem.left;
																	pos.y = rcItem.bottom;
																}
															}
															else
															{
																RECT rcItem = {0,0,0,0};
																int curCol = (int)*((int*)pBr+0x31);
																int curRow = (int)*((int*)pBr+0x30);
																if((*((int*)pBr+0x23) == 0) && (*((int*)pBr+0x2A) >= 0))
																	curRow =  (int)*((int*)pBr+0x2A);
																pBr->GetCellRect(&rcItem, curRow,curCol);
																pBr->ClientToScreen(&rcItem);
																pos.x = rcItem.left;
																pos.y = rcItem.bottom;
															}
#ifndef FORMEX_DLL
														}
#endif
													}
												}
											}
										}
									}
								}
							}
						}
						/*/
						CMenu* pMenuChoose;
						pMenuChoose = new CMenu;
						pMenuChoose->CreatePopupMenu();
						GetMenuFromVL(pMenuChoose,pVIA,s, CheckItem);
						UINT nRet = pMenuChoose->TrackPopupMenu(TPM_RETURNCMD | TPM_NONOTIFY | TPM_LEFTALIGN | TPM_LEFTBUTTON,pos.x,pos.y,pParent);
						//*/
						//*/
						HFONT hFont = (HFONT)(long)ppValue[5]->GetNumeric();
						if(hFont == NULL)
						{
							CApp7* pApp7 = (CApp7*) AfxGetApp();
							CProfile7* pProfile7 = pApp7->GetProps();
							hFont = pProfile7->GetHFONTProp(0x2c);
						}
						CFormExMenu* pMenuChoose;
						pMenuChoose = new CFormExMenu(hFont);
						pMenuChoose->m_pParent = pParent;
						pMenuChoose->Init();
						pMenuChoose->CreatePopupMenu();
						GetMenuFromVL(pMenuChoose,pVIA,s, CheckItem, hFont);
						UINT nRet = pMenuChoose->TrackPopupMenu(TPM_RETURNCMD | TPM_NONOTIFY | TPM_LEFTALIGN | TPM_LEFTBUTTON,pos.x,pos.y,pParent);
						//*/
						if(nRet)
						{
							rValue = 1L;
							if(CheckItem)
							{
								structVIA* pVIAres = (structVIA*)AllValuesArray.GetAt(nRet-1);
								pVIAres->ValueItem->SetCheck(!(pVIAres->Checked));
								*ppValue[1] = pVIAres->Value; //*((CValue*)(pVIAres->Value));
							}
							else
							{
								structVIA* pVIAres = (structVIA*)AllValuesArray.GetAt(nRet-1);
								*ppValue[1] = pVIAres->Value; //*((CValue*)(pVIAres->Value));
							}
//								*ppValue[1] = *((CValue*)(AllValues.GetAt(nRet-1)));
						}
						pMenuChoose->DestroyMenu();
						delete pMenuChoose;

					}

					AllValues.RemoveAll();
					AllValuesArray.RemoveAll();
					FreeVL(pVIA, s);

				}
				else pBkEndUI->DoMessageLine("Неверный параметр",mmRedErr);
			}
			else pBkEndUI->DoMessageLine("Неверный параметр",mmRedErr);
			break;
		}
	case methAddGlobalModule:
		{
			rValue = 0L;
			CBLModule7* pNewMod;
			CString stSource = ppValue[0]->GetString();
			CString stLFFrus = "#ЗагрузитьИзФайла";
			CString stLFFeng = "#LoadFromFile";
			int compRus = stLFFrus.CompareNoCase(stSource.Left(17));
			int compEng = stLFFeng.CompareNoCase(stSource.Left(13));
			if((compRus == 0) || (compEng == 0))
			{
				CString FileName = "";
				int i = 0;
				while(true)
				{
					unsigned char ch = stSource.GetAt(i++);
					if(ch < ' ') break;
				}
				if(compRus == 0)
				{
					if(i <= 17)
					{
						CBLModule::RaiseExtRuntimeError("Ошибка в директиве #ЗагрузитьИзФайла.",0);
						return S_FALSE;
					}
					FileName = stSource.Mid(17,i-17);
				}
				else
				{
					if(i <= 13)
					{
						CBLModule::RaiseExtRuntimeError("Ошибка в директиве #LoadFromFile.",0);
						return S_FALSE;
					}
					FileName = stSource.Mid(17,i-13);
				}

				FileName.TrimLeft();
				FileName.TrimRight();

				CFile SourceFile;
				CFileException fileException;

				if ( !SourceFile.Open( FileName, CFile::modeRead, &fileException ) )
				{
					char errBuf[0x0FFF];
					if(fileException.GetErrorMessage((LPTSTR)errBuf,0x0FFF))
						CBLModule::RaiseExtRuntimeError(CString("Ошибка при открытии файла: ")+FileName+"\r\n"+errBuf,0);
					else
						CBLModule::RaiseExtRuntimeError(CString("Ошибка при открытии файла: ")+FileName,0);
					return S_FALSE;
				}
				stSource = "";
				char buf[0xFFFF];
				int bytesRead = SourceFile.ReadHuge(buf,0xFFFE);
				while(bytesRead)
				{
					buf[bytesRead] = 0;
					stSource += buf;
					bytesRead = SourceFile.Read(buf,0xFFFE);
				}
				SourceFile.Close();
			}

			pNewMod = new CBLModule7(CBLContext::GetLoadedContext(CBLContext::GetFirstLoadedContextID()), stSource);
			pNewMod->SetID("ModuleText",1);
			if(pNewMod->Compile())
			{
				if(pNewMod->PrepareToLoad())
				{
					if(pNewMod->Load())
					{
						CBLModule7 * pGlobMod = GetGlobalModule();
						pGlobMod->AssignFriendModule(pNewMod);
						pNewMod->AssignFriendModule(pGlobMod);
						if(pNewMod->Execute() != 0) rValue = pNewMod->GetLoadedID();
						else
						{
							pNewMod->Unload();
							delete pNewMod;
						}
					}
				}
			}

			break;
		}
	case methDeleteGlobalModule:
		{
			rValue = 0L;
			CBLModule* pGlobMod = GetGlobalModule();
			ULONG id = ppValue[0]->GetNumeric();

			bool f = true;
			if(pGlobMod) f = (id != pGlobMod->GetLoadedID());
			if((id != 0) && f)
			{
				CBLModule7* pNewMod;
				pNewMod = (CBLModule7*)CBLModule7::GetLoadedModule(id);
				if(pNewMod)
				{
					pNewMod->Unload();
					pNewMod->~CBLModule7();
					rValue = 1L;
				}
			}

			break;
		}
	case methHeightTableString:
		{
			CBLContext* pCont = ppValue[0]->GetContext();//CTableOutputContext
			if(pCont)
			{
			
//			CSheet* pSheet0 = (CSheet*)(*((DWORD*)pCont+14));
//			CSheetDoc* pSheetDoc0 = (CSheetDoc*)(*((DWORD*)pCont+11));
//			CSheet* pSheet = (CSheet*)(*((DWORD*)pCont+10));

				CSheetDoc* pSheetDoc = (CSheetDoc*)(*((DWORD*)pCont+8));
				if(pSheetDoc)
				{
					POSITION aPOS = pSheetDoc->GetFirstViewPosition();
					CSheetView* pSheetView = (CSheetView*)pSheetDoc->GetNextView(aPOS);
					rValue = 0L;
					if(pSheetView)
					{
						int row = ppValue[1]->GetNumeric();
						if(row>0)
						{
							CRect rect = pSheetView->GetCellRect(row - 1,0);
							if(ppValue[2]->GetNumeric() == 1)
							{
								rValue = pSheetView->YPixelToMillimeters(rect.Height());
								rValue = rValue.GetNumeric()/CNumeric(100);
							}
							else if(ppValue[2]->GetNumeric() == 2)
							{
								rValue = rect.Height();
							}
							else
							{
								rValue = pSheetView->YPixelToUnit(rect.Height());
							}
						}
					}
				}
			}
			break;
		}
	case methGetTableNames:
		{
			CBLContext* pCont = ppValue[0]->GetContext();//CTableOutputContext
			
//			CSheetDoc* pSheetDoc = (CSheetDoc*)(*((DWORD*)pCont+8));
//			POSITION aPOS = pSheetDoc->GetFirstViewPosition();
//			CSheetView* pSheetView = (CSheetView*)pSheetDoc->GetNextView(aPOS);

			CSheet* pSheet = (CSheet*)(*((DWORD*)pCont+10));
			if(pSheet)
			{
				CBLContext* pVLCont = CBLContext::CreateInstance("ValueTable");
				if(pVLCont)
				{
					int numNC = pVLCont->FindMethod("NewColumn");
					if(numNC >= 0)
					{
						CValue v1;
						CValue v2;
						CValue v3;
						CValue v4;
						CValue v5;
						CValue v6;
						CValue v7;
						CValue v8;
						CValue *pParam[8] = {&v1, &v2, &v3, &v4, &v5, &v6, &v7, &v8};
						for(int i = 0; i < 8; i++)
							pVLCont->GetParamDefValue(numNC, i, pParam[i]);

						CValue retVal;
						v1 = "Адрес";
						pVLCont->CallAsFunc(numNC, retVal, pParam);
						v1 = "Идентификатор";
						pVLCont->CallAsFunc(numNC, retVal, pParam);
						v1 = "Лево";
						pVLCont->CallAsFunc(numNC, retVal, pParam);
						v1 = "Верх";
						pVLCont->CallAsFunc(numNC, retVal, pParam);
						v1 = "Право";
						pVLCont->CallAsFunc(numNC, retVal, pParam);
						v1 = "Низ";
						pVLCont->CallAsFunc(numNC, retVal, pParam);

						rValue.AssignContext(pVLCont);
						int numNL = pVLCont->FindMethod("NewLine");
						int numSV = pVLCont->FindMethod("SetValue");
						if((numNL >= 0) && (numSV >= 0))
						{
							v1 = "";
							v2 = "";
							v3 = "";
							CSheetNames SheetNames;
							SheetNames = pSheet->GetNames();

							CNamedArrayItem** pNamedArray = (CNamedArrayItem**)SheetNames.buf[1];
							int count = (SheetNames.buf[2] - SheetNames.buf[1])/4;
							CString str;
							long countLine = 0;
							for(i = 0; i < count; i++)
								if(pNamedArray[i] != NULL)
								{
									v1 = "";
									pVLCont->CallAsFunc(numNL, retVal, pParam);
									countLine++;
									v1 = countLine;

									v2 = 1;
									CString str;
									str.Format("R%dC%d:R%dC%d",pNamedArray[i]->SheetNamedItem.buf[5]+1,
										pNamedArray[i]->SheetNamedItem.buf[4]+1,
										pNamedArray[i]->SheetNamedItem.buf[7]+1,
										pNamedArray[i]->SheetNamedItem.buf[6]+1);
									v3 = str;
									if(!pVLCont->CallAsFunc(numSV, retVal, pParam))
										pVLCont->CallAsProc(numSV, pParam);

									v2 = 2;
									v3 = pNamedArray[i]->Name;
									if(!pVLCont->CallAsFunc(numSV, retVal, pParam))
										pVLCont->CallAsProc(numSV, pParam);

									v2 = 3;
									v3 = pNamedArray[i]->SheetNamedItem.buf[4]+1;
									if(!pVLCont->CallAsFunc(numSV, retVal, pParam))
										pVLCont->CallAsProc(numSV, pParam);

									v2 = 4;
									v3 = pNamedArray[i]->SheetNamedItem.buf[5]+1;
									if(!pVLCont->CallAsFunc(numSV, retVal, pParam))
										pVLCont->CallAsProc(numSV, pParam);

									v2 = 5;
									v3 = pNamedArray[i]->SheetNamedItem.buf[6]+1;
									if(!pVLCont->CallAsFunc(numSV, retVal, pParam))
										pVLCont->CallAsProc(numSV, pParam);

									v2 = 6;
									v3 = pNamedArray[i]->SheetNamedItem.buf[7]+1;
									if(!pVLCont->CallAsFunc(numSV, retVal, pParam))
										pVLCont->CallAsProc(numSV, pParam);
								}

						}
						
					}
				}
			}
			break;
		}
	case methGetGUID:
		{
			HRESULT hr;
			GUID  guid;
			hr=CoCreateGuid(&guid);
			if (!FAILED(hr))
			{
				LPOLESTR szGUID = new WCHAR [39];
 				StringFromGUID2(guid,szGUID,39);
				rValue = CString(szGUID);
				delete szGUID;
			}
			break;
		}
	case methCommandLine:
		{
			CApp7* pApp7 = (CApp7*) AfxGetApp();
			rValue = pApp7->m_lpCmdLine;
			break;
		}
#ifdef FORMEX_DLL
	case methVersionFormEx:
#endif
	case methVersion:
		{
			rValue = FORMEX_VERSION;
			CString strVer = "";
			strVer.Format("%d.%d.%d.%d",((FORMEX_VERSION&0xFF000000)>>24),
										((FORMEX_VERSION&0x00FF0000)>>16),
										((FORMEX_VERSION&0x0000FF00)>>8),
										((FORMEX_VERSION&0x000000FF)));
			*ppValue[0] = strVer;
			break;
		}
	default:
		return S_FALSE;
	}
	}catch(...) {
		CBLModule::RaiseExtRuntimeError(CString("Возникла критическая ошибка. Описание ошибки, возвращаемое Windows: ") + strLastError(),0);
		return S_FALSE;
	};
	return S_OK;
}

int  CService::CallAsProc(int iMethNum,class CValue * * ppValue)
{
	try{
	switch (iMethNum)
	{
	case methAsyncEvent:
		{
			if(pGlobalConnection)
			{
				IAsyncEvent *iAsyncEvent = NULL;
				pGlobalConnection->QueryInterface(IID_IAsyncEvent,(void **)&iAsyncEvent);
				if(iAsyncEvent)
				{
					CString str1 = ppValue[0]->GetString();
					CString str2 = ppValue[1]->GetString();
					CString str3 = ppValue[2]->GetString();
					iAsyncEvent->ExternalEvent(str1.AllocSysString(), str2.AllocSysString(), str3.AllocSysString());
					iAsyncEvent->Release();
				}
			}
			break;
		}
	case methSetCursor:
		{
			CWnd * pView = GetMainFrame();
			if(pView)
			{
				HCURSOR hCur = NULL;
				bool reset = false;
				if(ppValue[0]->type == 1)
				{
					int sysCursor = ppValue[0]->GetNumeric();
					if(sysCursor == 1)
						hCur = ::LoadCursor(NULL, IDC_ARROW);
					else if(sysCursor == 2)
						hCur = ::LoadCursor(NULL, IDC_IBEAM);
					else if(sysCursor == 3)
						hCur = ::LoadCursor(NULL, IDC_WAIT);
					else if(sysCursor == 4)
						hCur = ::LoadCursor(NULL, IDC_CROSS);
					else if(sysCursor == 5)
						hCur = ::LoadCursor(NULL, IDC_UPARROW);
					else if(sysCursor == 6)
						hCur = ::LoadCursor(NULL, IDC_SIZENWSE);
					else if(sysCursor == 7)
						hCur = ::LoadCursor(NULL, IDC_SIZENESW);
					else if(sysCursor == 8)
						hCur = ::LoadCursor(NULL, IDC_SIZEWE);
					else if(sysCursor == 9)
						hCur = ::LoadCursor(NULL, IDC_SIZENS);
					else if(sysCursor == 10)
						hCur = ::LoadCursor(NULL, IDC_SIZEALL);
					else if(sysCursor == 11)
						hCur = ::LoadCursor(NULL, IDC_NO);
					else if(sysCursor == 12)
						hCur = ::LoadCursor(NULL, IDC_APPSTARTING);
					else if(sysCursor == 13)
						hCur = ::LoadCursor(NULL, IDC_HELP);
					else if(sysCursor == 14)
						hCur = ::LoadCursor(NULL, MAKEINTRESOURCE(32649));//IDC_HAND
					else if(sysCursor == 15)
						hCur = ::LoadCursor(NULL, IDC_APPSTARTING);
					else
						reset = true;
				}
				else if(ppValue[0]->type == 2)
				{
					hCur = ::LoadCursorFromFile(ppValue[0]->GetString());
				}
				if((hCur == NULL) && (reset == false))
					pBkEndUI->DoMessageLine("Неверно задан курсор.",mmRedErr);
				else if(reset == true)
				{
					int szArr = glCursorWindowsArray.GetSize();
					for(int iContAr = 0; iContAr < szArr; iContAr++)
						if(glCursorWindowsArray.GetAt(iContAr) == (DWORD)pView->GetSafeHwnd())
						{
							glCursorWindowsArray.RemoveAt(iContAr);
							glCursorArray.RemoveAt(iContAr);
							break;
						}
				}
				else
				{
					int szArr = glCursorWindowsArray.GetSize();
					int iContAr = -1;
					if(szArr > 0)
					{
						for(iContAr = 0; iContAr < szArr; iContAr++)
							if(glCursorWindowsArray.GetAt(iContAr) == (DWORD)pView->GetSafeHwnd())
								break;
					}
					if((iContAr < 0) || (iContAr == szArr))
					{
						glCursorWindowsArray.Add((DWORD)pView->GetSafeHwnd());
						glCursorArray.Add((DWORD)hCur);
					}
					else
						glCursorArray.SetAt(iContAr,(DWORD)hCur);
				}
			}

			break;
		}
	case methTest:
		{
			//CTableOutputContext

			CGroupContext* pCont = (CGroupContext*)ppValue[0]->GetContext();
			if(pCont)
			{
				int sz = pCont->GetSize();
				for(int i = 0; i < sz; i++)
				{
					CBLContext* pContAr = pCont->GetContext(i);
				}
				int n = pCont->GetNProps();
			}

			//CUsersSet::GetUsersCnt(); - количество экземпляров 1С, запущенных в режиме Предприятие

			/*
			CApp7* pApp7 = (CApp7*) AfxGetApp();
			CProfile7* pProfile7 = pApp7->GetProps();

			CString Prop0 = pProfile7->GetStringProp(0x00); // каталог, в который установлен движок
			CString Prop1 = pProfile7->GetStringProp(0x01); // каталог базы
			CString Prop2 = pProfile7->GetStringProp(0x02); // каталог пользователя
			CString Prop3 = pProfile7->GetStringProp(0x03); // временный каталог
			CString Prop4 = pProfile7->GetStringProp(0x04); // полный путь к файлу 1Cv7.CFG (с именем файла)
			CString Prop5 = pProfile7->GetStringProp(0x05); // полный путь к файлу 1Cv7.DD (с именем файла)
			CString Prop6 = pProfile7->GetStringProp(0x06); // полный путь к файлу 1Cv7.DDS (с именем файла)
			CString Prop7 = pProfile7->GetStringProp(0x07); // полный путь к файлу 1Cv7.DBA (с именем файла)
			CString Prop8 = pProfile7->GetStringProp(0x08); // полный путь к файлу 1Cv7.MD (с именем файла)
			CString Prop9 = pProfile7->GetStringProp(0x09); // полный путь к файлу 1Cv7.LCK (с именем файла)
			CString PropA = pProfile7->GetStringProp(0x0A); // ???
			CString PropB = pProfile7->GetStringProp(0x0B); // ???
			CString PropC = pProfile7->GetStringProp(0x0C); // имя текущей ИБ в списке баз
			CString PropD = pProfile7->GetStringProp(0x0D); // имя текущего пользователя
			CString PropE = pProfile7->GetStringProp(0x0E); // полное имя текущего пользователя
			CString PropF = pProfile7->GetStringProp(0xF); // ???
			CString Prop10 = pProfile7->GetStringProp(0x10); // название набора прав текущего пользователя
			CString Prop11 = pProfile7->GetStringProp(0x11); // название интерфейса текущего пользователя
			CString Prop12 = pProfile7->GetStringProp(0x12); // путь в реестре к установкам текущего пользователя (относительно HKEY_CURRENT_USER\Software\1C\1Cv7\7.7)
			*/
			/*
			pBkEndUI->DoMessageLine(Prop1);
			pBkEndUI->DoMessageLine(Prop2);
			pBkEndUI->DoMessageLine(Prop3);
			pBkEndUI->DoMessageLine(Prop4);
			pBkEndUI->DoMessageLine(Prop5);
			pBkEndUI->DoMessageLine(Prop6);
			pBkEndUI->DoMessageLine(Prop7);
			pBkEndUI->DoMessageLine(Prop8);
			pBkEndUI->DoMessageLine(Prop9);
			pBkEndUI->DoMessageLine(PropA);
			pBkEndUI->DoMessageLine(PropB);
			pBkEndUI->DoMessageLine(PropC);
			pBkEndUI->DoMessageLine(PropD);
			pBkEndUI->DoMessageLine(PropE);
			pBkEndUI->DoMessageLine(PropF);
			*/

			//SECMDIFrameWnd * pMainFrame = (SECMDIFrameWnd*)GetMainFrame();
			
			//pBkEndUI->DoMessageLine(pApp7->GetMetaData()->GetTaskDef()->GetMDPassword());
			//pBkEndUI->DoMessageLine(HashPasswordString("A1L2E3X4"));

			/*
//			CSheet* pSheet0 = (CSheet*)(*((DWORD*)pCont+14));
			CBLContext* pCont = ppValue[0]->GetContext();
			CSheetSelection* pSheetSel = (CSheetSelection*)(*((DWORD*)pCont+10));

			CBLContext* pCont1 = ppValue[1]->GetContext();
			CSheetSelection* pSheetSel1 = (CSheetSelection*)(*((DWORD*)pCont1+10));

			CSheetDoc* pSheetDoc = (CSheetDoc*)(*((DWORD*)pCont+9));
			CSheetDoc* pSheetDoc1 = (CSheetDoc*)(*((DWORD*)pCont1+9));

			CSheet* pSheet = (CSheet*)(*((DWORD*)(*((DWORD*)pCont+8))+3));
			CSheet* pSheet1 = (CSheet*)(*((DWORD*)(*((DWORD*)pCont1+8))+3));

			CSize size;
			CSize size0;
			size0 = size = pSheet->GetSize();
			CSize size1;
			size1 = pSheet1->GetSize();
			if(size1.cx > size.cx)
				size.cx = size1.cx;
			size.cy += size1.cy;
			pSheet->SetSize(size);

			pSheet->PasteCells(*pSheet1,*pSheetSel1,2);

			CRect rect = pSheetSel->GetRect();
			CRect rect1 = pSheetSel1->GetRect();

			rect.bottom = size.cy + rect.top - 1;
			rect.right = size.cy + rect.left - 1;
			pSheetSel->SelectRect(rect);

//			pSheet->CopyCells(*pSheet1, *pSheetSel);

//			pSheetSel->Insert(*pSheetSel1, sdTwo);
*/
			//*/ CMoxelObjectContext2

/*
			CBLContext *pCont = CBLContext::GetLoadedContext(CBLContext::GetFirstLoadedContextID());
			CBLModule myModule(pCont,ppValue[0]->GetString());
			CBLModule *pModule = CBLModule::GetExecutedModule(); //GetGlobalModule();//
			CBLModule *pGlModule = GetGlobalModule();//
			//SaveCompiledModuleToFile(pGlModule, "C:\\log1.txt");
			SaveCompiledModuleToFile(pModule, "C:\\log0.txt");
			CValue* pValue2 = ppValue[1];

*/

			/*
DWORD adr = 0x210158E0;
DWORD mod_int = (DWORD)pModule->pIntInfo->pCompiledModule;
CBLModule::EnableDebugDump(1);
__asm{
	mov ecx, [mod_int]
	call [adr]
}
			*/
			//myModule.pIntInfo->Compile();


/*
			if(myModule.Compile())
			{
//				SaveCompiledModuleToFile(&myModule);
				CCompileProcInfo* pPI = (CCompileProcInfo*)pModule->pIntInfo->pCompiledModule->ProcArray.GetAt(3);
				CCompileProcInfo* pPI1 = (CCompileProcInfo*)myModule.pIntInfo->pCompiledModule->ProcArray.GetAt(1);
				myModule.Execute();
				myModule.CallAsProc(1,0,NULL);

				CString st;
				st.Format("%d :: %d :: %d",myModule.GetNProcs(), myModule.GetNStaticVars(), myModule.GetNCurSourceLines());
				pBkEndUI->DoMessageLine(st, mmNone);
			}
			//*/

			break;
		}
	case methDeleteFont:
		{
			HFONT hFont = (HFONT)(long)ppValue[0]->GetNumeric();
			::DeleteObject(hFont);
			break;
		}
	case methPlay:
		{
			CString wavName = ppValue[0]->GetString();
			::sndPlaySound(wavName,SND_ASYNC);
			break;
		}
	case methColorBrowse:
		{
			m_bLocalColor = (ppValue[0]->GetNumeric() == 1);
			m_bEnabledColor = TRUE;
			//CBrowse::SetWrap();
			CBrowseWrapper::SetWrap();
			break;
		}
	case methUnColorBrowse:
		{
			m_bLocalColor = FALSE;
			m_bEnabledColor = FALSE;
			//CBrowse::OffWrap();
			CBrowseWrapper::OffWrap();
			break;
		}
	case methShowKeyboardIndicator:
		{
			SECStatusBar* pStatus = (SECStatusBar*)AfxGetApp()->m_pMainWnd->GetDescendantWindow(AFX_IDW_STATUS_BAR);
			if(pStatus)
			{
				int count = pStatus->GetCount();
				UINT* nIDs;
				UINT* nStyles;
				int* cxWidths;
				nIDs = (UINT*)malloc(count*sizeof(UINT));
				nStyles = (UINT*)malloc(count*sizeof(UINT));
				cxWidths = (int*)malloc(count*sizeof(int));
				for(int i = 0; i<count; i++)
					pStatus->GetPaneInfo(i,nIDs[i],nStyles[i],cxWidths[i]);
				if((!m_bShowKL) & (ppValue[0]->GetNumeric() == 1))
				{
					m_bShowKL = TRUE;
					pStatus->AllocElements(count+2,100);
					pStatus->SetPaneInfo(count+1,NULL,SBPS_NORMAL, 43);
					pStatus->SetPaneInfo(count,NULL,SBPS_NORMAL, 20);
					char KLName[KL_NAMELENGTH]; 
					if(GetLocaleInfo((LCID)((WORD)GetKeyboardLayout(AfxGetApp()->m_nThreadID)),LOCALE_SABBREVLANGNAME,KLName,KL_NAMELENGTH))
						pStatus->SetPaneText(count,KLName,KL_NAMELENGTH);
					StatusTimer = pStatus->SetTimer(500,100,(TIMERPROC)TimerProc);
				}
				else if(m_bShowKL & (ppValue[0]->GetNumeric() == 0))
				{
					m_bShowKL = FALSE;
					count -= 2;
					pStatus->AllocElements(count,100);
					if(StatusTimer)
					{
						pStatus->KillTimer(StatusTimer);
						StatusTimer = 0;
					}
				}
				for(i = 0; i<count; i++)
					pStatus->SetPaneInfo(i,nIDs[i],nStyles[i],cxWidths[i]);
				free(nIDs);
				free(nStyles);
				free(cxWidths);
			}
			break;
		}
	case methSetWallpaper:
		{
			if(wndMDIClient == NULL) break;

			if(!ppValue[0]->GetString().IsEmpty())
			{
				CGalleryHolder * pGalleryHolder = CGalleryHolder::GetGallery();
				if(pGalleryHolder)
				{
					ULONG picID = pGalleryHolder->FindByAlias(ppValue[0]->GetString());
					if(picID)
					{
						CPictureHolder7 * pic;
						pic = new CPictureHolder7(pGalleryHolder->GetPicture(picID));

						CDC dcMem;
						CDC* pDC = CWnd::GetDesktopWindow()->GetDC();

						if (dcMem.CreateCompatibleDC(pDC))
						{
							CSize hmSize = pic->GetSize();

							CBitmap bmMem;

							if (bmMem.CreateCompatibleBitmap(pDC, hmSize.cx, hmSize.cy))
							{
								CBitmap* pOldBM = dcMem.SelectObject(&bmMem);

								dcMem.FillSolidRect(0, 0, hmSize.cx, hmSize.cy, RGB(0x100,0x100,0x100));
								RECT rect1;
								RECT rect2;
								rect1.top = 0;
								rect1.left = 0;
								rect1.right = hmSize.cx;
								rect1.bottom = hmSize.cy;
								
								pic->Render(dcMem, rect1, 0, &rect2);

								wndMDIClient->m_Bitmap.Attach(bmMem.Detach());

								dcMem.SelectObject(pOldBM);
							}
						}
						CWnd::GetDesktopWindow()->ReleaseDC(pDC);
						delete pic;
					}
					else
					{
						HBITMAP hBitmap = (HBITMAP)LoadImage(NULL, ppValue[0]->GetString(), IMAGE_BITMAP, 0, 0, LR_LOADFROMFILE);

						if(hBitmap != NULL)
							wndMDIClient->m_Bitmap.Attach(hBitmap);
					}
					wndMDIClient->CreateGrayBitmap();
				}

			}
			wndMDIClient->m_nBkColor = ppValue[3]->GetNumeric();
			wndMDIClient->m_nType = ppValue[1]->GetNumeric();
			wndMDIClient->m_bGray = (ppValue[2]->GetNumeric() == 1);
			wndMDIClient->RedrawWindow();

			break;
		}
	case methHideTable:
		{
			CBLContext* pCont = ppValue[0]->GetContext();//CTableOutputContext

			CSheetDoc* pSheetDoc = (CSheetDoc*)(*((DWORD*)pCont+8));
			POSITION aPOS = pSheetDoc->GetFirstViewPosition();
			CSheetView* pSheetView = (CSheetView*)pSheetDoc->GetNextView(aPOS);
			if(pSheetView)
			{
				if(ppValue[1]->GetNumeric() == 1)
					pSheetView->GetParent()->GetParent()->ShowWindow(SW_HIDE);
				else if(ppValue[1]->GetNumeric() == 0)
					pSheetView->GetParent()->GetParent()->ShowWindow(SW_SHOW);
			}
			break;
		}
	default:
		return S_FALSE;
	}
	}catch(...) {
		CBLModule::RaiseExtRuntimeError(CString("Возникла критическая ошибка. Описание ошибки, возвращаемое Windows: ") + strLastError(),0);
		return S_FALSE;
	};
	return S_OK;
}


int  CService::FindMethod(char const * lpMethodName)const
{
	int i;
	for (i = 0;i<lastMethod;i++){
		if (!stricmp(lpMethodName,defFnNames[i].Names[0]))
			return i;
		if (!stricmp(lpMethodName,defFnNames[i].Names[1]))
			return i;
	}
	return -1;
}

char const * CService::GetMethodName(int iMethodNum,int iMethodAlias)const
{
	if (iMethodNum >= lastMethod) 
		return "mError";
	else
		return defFnNames[iMethodNum].Names[iMethodAlias];
}

int  CService::GetNMethods(void)const
{
	return lastMethod;
}

int  CService::HasRetVal(int iMethodNum)const
{
	return defFnNames[iMethodNum].HasReturnValue ;
}

int CService::GetNParams(int iMethodNum)const
{
	return defFnNames[iMethodNum].NumberOfParams;
}

int  CService::GetParamDefValue(int iMethodNum,int iParamNum,class CValue * pDefValue)const
{
	switch (iMethodNum)
	{
	case methGetUsersList:
		{
			*pDefValue = "";
			break;
		}
	case methValueListDraw:
		{
			*pDefValue = -1;
			break;
		}
	case methMouseHook:
	case methKeyHook:
		{
			*pDefValue = -1;
			break;
		}
	case methVersion:
		{
			*pDefValue = "";
			break;
		}
	case methSendKeys:
			if(iParamNum == 1)
				*pDefValue = 0L;
			else if(iParamNum == 2)
				*pDefValue = "English (United States)";
			break;
	case methSetCursor:
		{
			*pDefValue = -1;
			break;
		}
	case methCreateFontCausedBy:
		{
			if(iParamNum == 0)
				return 0;
			else if(iParamNum == 1)
				*pDefValue = "";
			else
				*pDefValue = -1;
			break;
		}
	case methCreateFont:
		{
			if(iParamNum == 0)
				*pDefValue = "";
			else
				*pDefValue = -1;
			break;
		}
	case methChooseValue:
		{
			switch (iParamNum)
			{
			case 4:
			case 5:
				*pDefValue = 0L;
				break;
			case 6:
				*pDefValue = -1L;
				break;
			default:
				return 0;
			}
			break;
		}
	case methColorBrowse:
		{
			*pDefValue = 0L;
			break;
		}
#ifndef FORMEX_DLL
  case methLoadModule:
		{
			*pDefValue = 0L;
			break;
		}
#endif
	case methSetWallpaper:
		{
			if(iParamNum == 2)
				*pDefValue = 0L;
			else if(iParamNum == 3)
				*pDefValue = -1L;
			break;
		}
	case methCallAsProcedure:
	case methCallAsFunction:
		{
			if(iParamNum == 2)
			{
				*pDefValue = 0L;
				break;
			}
		}
	case methOpenToolsForm:
	case methOpenDockableForm:
		{
			CBLContext* pGlobal = CBLContext::GetLoadedContext(1);
			int iOF = pGlobal->FindMethod("ОткрытьФорму");
			int colParam = pGlobal->GetNParams(iOF);
			int num = iParamNum-1;
			if(iParamNum <= colParam) pGlobal->GetParamDefValue(iOF,num,pDefValue);
			break;
		}
	default:
		return 0;
	}
	return 1;
}

void  CService::DecrRef(void)
{
	CBLContext::DecrRef();
}

char const *  CService::GetCode(void)const
{
	return 0;
}

int  CService::GetDestroyUnRefd(void)const
{
	return 1;
}

void  CService::GetExactValue(class CValue & vParam)
{
	CBLContext::GetExactValue(vParam);
}

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

class CBLContextInternalData *  CService::GetInternalData(void)
{

	return CBLContext::GetInternalData();

}

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

char const *  CService::GetTypeString(void)const
{
#ifdef FORMEX_DLL
	return "Сервис";
#else
	return "СервисРасшФормы";
#endif
}

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

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

void  CService::InitObject(class CType const & tType)
{
	CBLContext::InitObject(tType);
}

void  CService::InitObject(char const * strName)
{
	CBLContext::InitObject(strName);
}

int  CService::IsExactValue(void)const
{
	return FALSE;
}

int  CService::IsOleContext(void)const
{
	return FALSE;
}

int  CService::IsPropReadable(int iPropNum)const
{
	return FALSE;
}

int  CService::IsPropWritable(int iPropNum)const
{
	return FALSE;
}

int  CService::IsSerializable(void)
{
	return FALSE;
}

int  CService::SaveToString(class CString & csStr)
{
#ifdef FORMEX_DLL
	csStr = "Service";
#else
	csStr = "ServiceFormEx";
#endif
	return TRUE;
}

void  CService::SelectByID(class CObjID cID,long lNum)
{
	CBLContext::SelectByID(cID,lNum);
}

int  CService::GetNProps(void)const
{
	return 0;
}

char const * CService::GetPropName(int A,int B)const
{
	return NULL;
}

int  CService::GetPropVal(int iPropNum,class CValue & rValue)const
{
	return -1;
}

int  CService::SetPropVal(int iPropNum,class CValue const & vValue)
{
	return -1;
}

int  CService::FindProp(char const * Name)const
{
	return -1;
}
