// инициализация данных FormEx

#include "stdafx.h"
#include "AddIn.h"
#include "Service.h"
#include "FormEx.h"
#include "AttribEx.h"
#include "PaintHook.h"
#include "MDIClientWnd.h"
#include "WrapAboutDlg.h"
#include "v7Windows.h"

#include "InitFormEx.h"

#include "artbear\events.h"
#include "artbear\MethodsWrapper.h"

#include "artbear\TrayIconManager.h"
#include "v7Windows.h"

CInitFormEx::CPtr CInitFormEx::singletone; //(new CInitFormEx);

boost::shared_ptr<CAllFormsNamesManager> CAllFormsNamesManager::pAllFormsNamesManager;

HANDLE hProcess = NULL;
BOOL bMessageConfigMode = FALSE;

class CMDIFrameWnd * pMainWindow = NULL;

//HHOOK MouseHookHandle = 0;
//HHOOK CInitFormEx::m_KeyboardHookHandle = 0; //HHOOK HookHandle = 0;
// HHOOK WndHookHandle = 0;
// HHOOK WndPreHookHandle = 0;

BOOL m_bEnabledColor = FALSE;
BOOL m_bLocalColor = FALSE;
BOOL m_bNoInvalidate = FALSE;
BOOL m_bShowKL = FALSE;

BOOL m_bUseColorPlan = FALSE;

//DWORD myPlatformId;

CMDIClientWnd * wndMDIClient = NULL;
static LONG hMainWndProc = 0;
CDWordArray glColContArray;
//CString strTimerName = "";
//UINT uTimer = 0;

//UINT uMainWindowStyle = 0;
//UINT uChildWindowStyle = 0;
//UINT uChildModalWindowStyle = 0;

CDWordArray glCursorArray;
CDWordArray glCursorWindowsArray;

extern CBLModule7* pGlobalModuleFormEx;

//-------------------------------------------------------------------------------------
LRESULT FormEx_OnSetCursor(WORD nHittest)
{
	int szArr = glCursorWindowsArray.GetSize();
	if(szArr > 0)
	{
		CWnd* pWnd = NULL;
		POINT curPoint;
		if(::GetCursorPos(&curPoint))
		{
			CMDIFrameWnd * pMain1CFrame = GetMainFrame();
			if(pMain1CFrame)
			{
				CWnd* pWndT = pMain1CFrame;
				CGetDoc7* pDoc7 = CGetDlg::GetTopmostDocunent();
				if(pDoc7)
				{
					CGetDlg* pGetDlg = (CGetDlg*)pDoc7->GetFrame();
					if(pGetDlg)
					{
						pGetDlg->ScreenToClient(&curPoint);
						pWnd = pGetDlg->ChildWindowFromPoint(curPoint,CWP_SKIPINVISIBLE);//CWP_ALL);
						if(pWnd)
						{
							if((CString("CButton") == pWnd->GetRuntimeClass()->m_lpszClassName) && ((pWnd->GetStyle() & BS_GROUPBOX) == BS_GROUPBOX))
							{
								if(::SetWindowPos(pWnd->GetSafeHwnd(),HWND_BOTTOM,0,0,0,0,
													SWP_NOMOVE|
													SWP_NOACTIVATE|
													SWP_NOREDRAW|
													SWP_NOOWNERZORDER|
													SWP_NOSIZE|
													SWP_NOSENDCHANGING))
								{
									pWnd = pGetDlg->ChildWindowFromPoint(curPoint,CWP_ALL);
								}
							}
							else
							if((CString("CTabCtrl") == pWnd->GetRuntimeClass()->m_lpszClassName))
							{
								if(::SetWindowPos(pWnd->GetSafeHwnd(),HWND_BOTTOM,0,0,0,0,
													SWP_NOMOVE|
													SWP_NOACTIVATE|
													SWP_NOREDRAW|
													SWP_NOOWNERZORDER|
													SWP_NOSIZE|
													SWP_NOSENDCHANGING))
								{
									pWnd = pGetDlg->ChildWindowFromPoint(curPoint,CWP_ALL);
								}
							}
						}
					}
				}
				else
				{
					pMain1CFrame->ScreenToClient(&curPoint);
					pWnd = pMain1CFrame->ChildWindowFromPoint(curPoint,CWP_ALL);
				}
				if(pWnd == NULL) pWnd = pWndT;
				while(pWnd != pWndT)
				{
					pWndT->ClientToScreen(&curPoint);
					pWndT = pWnd;
					pWnd->ScreenToClient(&curPoint);
					pWnd = pWnd->ChildWindowFromPoint(curPoint,CWP_ALL);
					if(pWnd == NULL) pWnd = pWndT;
					else
					{
						if((CString("CButton") == pWnd->GetRuntimeClass()->m_lpszClassName) && ((pWnd->GetStyle() & BS_GROUPBOX) == BS_GROUPBOX))
						{
							if(::SetWindowPos(pWnd->GetSafeHwnd(),HWND_BOTTOM,0,0,0,0,
												SWP_NOMOVE|
												SWP_NOACTIVATE|
												SWP_NOREDRAW|
												SWP_NOOWNERZORDER|
												SWP_NOSIZE|
												SWP_NOSENDCHANGING))
							{
								pWnd = pWndT->ChildWindowFromPoint(curPoint,CWP_ALL);
								if(pWnd == NULL) pWnd = pWndT;
							}
						}
						else
						if((CString("CTabCtrl") == pWnd->GetRuntimeClass()->m_lpszClassName))
						{
							if(::SetWindowPos(pWnd->GetSafeHwnd(),HWND_BOTTOM,0,0,0,0,
												SWP_NOMOVE|
												SWP_NOACTIVATE|
												SWP_NOREDRAW|
												SWP_NOOWNERZORDER|
												SWP_NOSIZE|
												SWP_NOSENDCHANGING))
							{
								pWnd = pWndT->ChildWindowFromPoint(curPoint,CWP_ALL);
								if(pWnd == NULL) pWnd = pWndT;
							}
						}
					}
				}
				pWnd = pWndT;
				while(pWnd)
				{
					DWORD dwHWnd = (DWORD)pWnd->GetSafeHwnd();
					for(int iContAr = 0; iContAr < szArr; iContAr++)
						if(glCursorWindowsArray.GetAt(iContAr) == dwHWnd)
						{
							HCURSOR hCur = (HCURSOR)glCursorArray.GetAt(iContAr);
							::SetCursor(hCur);
							return 1;
						}

					if(pWnd == pMain1CFrame)
						pWnd = NULL;
					else
						pWnd = pWnd->GetParent();
				}
			}
		}
	}
	return 0;
}

LRESULT FormEx_OnCommand(WPARAM wParam, LPARAM lParam)
{
	LRESULT ret = FALSE;
	if(pGlobalModuleFormEx)
	{
		int iStatusCode = pGlobalModuleFormEx->GetStatusCode();
		pGlobalModuleFormEx->SetStatusCode(1);
			
		CValue v0 = wParam;
		CValue v1 = lParam;
		CValue vFSO = 1;

		CValue *lArray[3] = {&v0, &v1, &vFSO};
			
		CEventsManager::GetManager().SendEventToGlobalModules(meOnCommand, lArray);
		
		if((pGlobalModuleFormEx->GetStatusCode() == 0L) || (0L == (UINT)vFSO.GetNumeric())) ret = TRUE;

		pGlobalModuleFormEx->SetStatusCode(iStatusCode);
	}
	return ret;
}

LRESULT FormEx_OnSysCommand(WPARAM wParam, LPARAM lParam)
{
	LRESULT ret = FALSE;
	if(pGlobalModuleFormEx)
	{
		int iStatusCode = pGlobalModuleFormEx->GetStatusCode();
		pGlobalModuleFormEx->SetStatusCode(1);
			
		CValue v0 = wParam;
		CValue v1 = lParam;
		CValue vFSO = 1;

		CValue *lArray[3] = {&v0, &v1, &vFSO};
			
		CEventsManager::GetManager().SendEventToGlobalModules(meOnSysCommand, lArray);
		
		if((pGlobalModuleFormEx->GetStatusCode() == 0L) || (0L == (UINT)vFSO.GetNumeric())) ret = TRUE;

		pGlobalModuleFormEx->SetStatusCode(iStatusCode);
	}
	return ret;
}

LRESULT CALLBACK newMainWndProc(HWND hWnd, UINT nMessage, WPARAM wParam, LPARAM lParam)
{
	switch(nMessage) {
		case WM_DESTROY: // пусть будет, вдруг где-то сработает и что-то пойдет потом не так
		case WM_ENDSESSION: // работает начиная с WinXP
		{
			LRESULT hRes = ::CallWindowProc((WNDPROC)hMainWndProc,hWnd, nMessage, wParam, lParam);
			::SetWindowLong(pMainWindow->GetSafeHwnd(),GWL_WNDPROC,(LONG)hMainWndProc);
			return hRes;
		}
		case WM_QUERYENDSESSION:
		{
			::SetWindowLong(pMainWindow->GetSafeHwnd(),GWL_WNDPROC,(LONG)hMainWndProc);
			break;
		}
 		case WM_SETCURSOR:
		{
			if(FormEx_OnSetCursor(LOWORD(lParam))) return 1;
			break;
		}
		case WM_COMMAND:
		{
			if(FormEx_OnCommand(wParam,lParam)) return 0;
			break;
		}
		case WM_SYSCOMMAND:
		{
			if(FormEx_OnSysCommand(wParam,lParam)) return 0;
			break;
		}
	}
	return ::CallWindowProc((WNDPROC)hMainWndProc,hWnd, nMessage, wParam, lParam);
}

LRESULT WINAPI DlgProc( HWND hDlg, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
	switch( uMsg ) {
	case WM_INITDIALOG:
		return TRUE;
	case WM_COMMAND:
		switch( wParam ) {
		case IDOK:
			EndDialog( hDlg, TRUE );
			return TRUE;
		}
		break;
	}
	
	return FALSE;
}

CInitFormEx::CInitFormEx()  :
m_bStopHook_Keyboard_Mouse(false), m_bModalState(FALSE), m_bIsSqlVersion(::IsSQLVersion())
{
}

CInitFormEx::~CInitFormEx()
{
	Destroy();
}

// вызывается в CAddIn::Init()
bool CInitFormEx::Init(void)
{
	AFX_MANAGE_STATE(AfxGetAppModuleState())

	glColContArray.RemoveAll();
	glCursorArray.RemoveAll();
	glCursorWindowsArray.RemoveAll();

	SetupPlatformID();
	
	CTrayIconManager* pTrayIconManager = CTrayIconManager::Get(); // инициализация
	assert(NULL != pTrayIconManager);

	pMainWindow = GetMainFrame(); //CMainFrame -> SECMDIFrameWnd

	if(!pMainWindow) return false;

	if(!CInitFormEx::IsVersionOfPlatformAreEMBEDDEDNT())
	{
		hMainWndProc = ::GetWindowLong(pMainWindow->GetSafeHwnd(),GWL_WNDPROC);
		// этот код вызывает падение на Windows XP Embedded
		if(hMainWndProc)
			::SetWindowLong(pMainWindow->GetSafeHwnd(),GWL_WNDPROC,(LONG)newMainWndProc);
	}

	CWrapModule WrapModule;
	CGetDlgWrapped::SetWrap();
	
	hProcess=GetCurrentProcess();

	CMethodsWrapper MethodsWrapper;
	InitEvents();
	
	m_GlobalTimer = CTimerWithEvent::CreateStoppedTimer(501, meOnGlobalTimerForm);
	m_ModalWindowTimers.SetHooks();
	
	if(pApp)
	{
		LoadSettingsFromRegistry();

		AddSystemHooks();

		if(m_bEnabledColor)
		{
			CBrowseWrapper::SetWrap();
		}

		pStatusBarManager = CStatusBarManager::Create();
		pStatusBarManager->Init(m_bShowKL);
	}

	m_uiCenterBrowse = 1;

	wndMDIClient = new CMDIClientWnd;
	CProfile7* pProfile7 = pApp->GetProps();
	if(pProfile7)
	{
		CService::stBIN1CPath = pProfile7->GetStringProp(0);
		CService::stBase1CPath = pProfile7->GetStringProp(1);
	}

	if(!wndMDIClient->SubclassWindow(pMainWindow->m_hWndMDIClient))
	{
		pBkEndUI->DoMessageLine("Failed to subclass MDI client window", mmRedErr);
		delete wndMDIClient;
		wndMDIClient = NULL;
	}
	else
	{ //CTime::GetTickCount
		BOOL bWallpaper = FALSE;
		
		wndMDIClient->m_nBkColor = -1;
		wndMDIClient->m_bGray = false;

		CGalleryHolder * pGalleryHolder = CGalleryHolder::GetGallery();
		if(pGalleryHolder)
		{
			ULONG picID = pGalleryHolder->FindByAlias("Wallpaper");
			if(picID)
			{
// 				CPictureHolder7 * pic;
// 				pic = new CPictureHolder7(pGalleryHolder->GetPicture(picID));
				sh_ptr<CPictureHolder7> pPictureHolder7 = sh_ptr<CPictureHolder7>(new CPictureHolder7(pGalleryHolder->GetPicture(picID)));

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

				if (dcMem.CreateCompatibleDC(pDC))
				{
					CSize hmSize = pPictureHolder7->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;
						
						pPictureHolder7->Render(dcMem, rect1, 0, &rect2);

						wndMDIClient->m_Bitmap.Attach(bmMem.Detach());
						wndMDIClient->m_nType = 1;
						wndMDIClient->CreateGrayBitmap();

						dcMem.SelectObject(pOldBM);
					}
				}
				CWnd::GetDesktopWindow()->ReleaseDC(pDC);
				//delete pic;
				bWallpaper = TRUE;
			}
		}

		if(!bWallpaper)
		{
			if(pProfile7)
			{
				CString csPath = "";
				csPath = CService::stBase1CPath;
				CString csFile = "wallpaper.bmp";

				int nType = 5;
				HBITMAP hBitmap = (HBITMAP)LoadImage(NULL, csPath + csFile, IMAGE_BITMAP, 0, 0, LR_LOADFROMFILE);
				if(hBitmap == NULL)
				{
					for(int i = 1; i < 8; i++)
					{
						csFile.Format("wallpaper(%i).bmp", i);
						hBitmap = (HBITMAP)LoadImage(NULL, csPath + csFile, IMAGE_BITMAP, 0, 0, LR_LOADFROMFILE);
						if(hBitmap != NULL)
						{
							nType = i;
							break;
						}
					}
				}

				if(hBitmap != NULL)
				{
					wndMDIClient->m_Bitmap.Attach(hBitmap);
					wndMDIClient->CreateGrayBitmap();
					wndMDIClient->m_nType = nType;
				}
				//wndMDIClient->m_bGray = true;
			}
		}

		wndMDIClient->RedrawWindow();
	}

	CMenuManager* pMenuManager = CMenuManager::Get(); // инициализация
	assert(NULL != pMenuManager);

	CWrapAboutDlg::Init();

	m_FilesDropTarget.Enable();

	CAllFormsNamesManager* pAllFormsNamesManager = CAllFormsNamesManager::Get();
	//GetNamesOfAllForms();
	
	return true;
}

// вызывается в CAddIn::Done()
void CInitFormEx::Destroy(void)
{
/*
	{
		CLoadedAddInDllInfo* pDllContext = CLoadedAddInDllInfo::GetCurrentAddInDllInfo();
		if(pDllContext)
		{
			int s = pDllContext->m_pPtrArray.GetSize();
			for(int i = 0; i < s; i++)
			{
				CAddInDll_SEvent* pEvent = pDllContext->m_pPtrArray.GetAt(0);
				int ss = pEvent->m_SubEvent.m_strArr.GetSize();
				for(int ii = 0; ii < ss; ii++)
				{
					CAddInDll_SEventStr* pEventStr = (CAddInDll_SEventStr*)pEvent->m_SubEvent.m_strArr.GetAt(0);
					delete pEventStr;
					pEvent->m_SubEvent.m_strArr.RemoveAt(0);
				}
				delete pEvent;
				pDllContext->m_pPtrArray.RemoveAt(0);
			}
		}
	}
*/
	CEventsManager::GetManager().Clear();
	CMethodsWrapper::DestroyHooks();

	CMenuManager::Destroy();

	DestroySystemHooks();

	if(wndMDIClient != NULL)
	{
		CMDIFrameWnd * pMainFrame = GetMainFrame();
		if(pMainFrame)
		{
			wndMDIClient->RedrawWindow();
			if(!wndMDIClient->UnsubclassWindow())
				pBkEndUI->DoMessageLine("Failed to unsubclass MDI client window", mmRedErr);
			delete wndMDIClient;
		}
	}
	
	m_GlobalTimer = CTimerWithEvent::PCTimerWithEvent(NULL); // TODO скорее всего, нужно просто очистить значение или ничего не делать !!
	m_ModalWindowTimers.DestroyHooks(); // TODO скорее всего, нужно просто очистить значение или ничего не делать !!

	glColContArray.RemoveAll();
	glCursorArray.RemoveAll();
	glCursorWindowsArray.RemoveAll();
	
	SetSystemTopmostModalState(FALSE);

	CTrayIconManager::Destroy();

	SaveSettingsToRegistry();

	CIconManager::DestroyStaticContainer();

	CAllFormsNamesManager::Destroy();
}

// вызывается в начале CAddIn::Apply()
void CInitFormEx::BeforeApply(void)
{
}

// вызывается в конце CAddIn::Apply()
void CInitFormEx::Apply(void)
{
	if(m_bEnabledColor)
	{
		CBrowseWrapper::SetWrap();
	}
	else
	{
		m_bLocalColor = FALSE;
		CBrowseWrapper::OffWrap();
	};
	
	pStatusBarManager->SetStatusBar();
}
	
// TODO не забыть предопределенные процедуры 1С, которые зачем-то обрабатывает ФормЕкс 
// TODO не забыть процедуры таймера - ОбработкаОжидания глобальная ??
// TODO не забыть процедуры таймера - TimerProcFormEx - ОбработкаОжидания в форме ??

stEventData CV7GlobalEvents[]  =  
{
	// события, которые ищутся сначала в модуле активной формы,
	// а если не найдено, то ищутся и во всех глобальных модулях
    {meOnChar, "ПриНажатииКнопкиКлавиатуры","OnChar", 6, ekActiveForm, false, false, 0},
    {meOnCharUp, "ПриОтжатииКнопкиКлавиатуры","OnCharUp", 6, ekActiveForm, false, false, 0},

    {meOnItemExpanding, "ПриРазворачиванииУзла","OnItemExpanding",2, ekActiveForm, false, false, 0},
    {meOnItemExpanded, "ПослеРазворачиванияУзла","OnItemExpanded",2, ekActiveForm, false, false, 0},
    {meOnItemCollapsing, "ПриСворачиванииУзла","OnItemCollapsing",2, ekActiveForm, false, false, 0},
    {meOnItemCollapsed, "ПослеСворачиванияУзла","OnItemCollapsed",2, ekActiveForm, false, false, 0},
    {meOnCheckItem, "ПриПометкеУзла","OnCheckItem",3, ekActiveForm, false, false, 0},
    {meOnRButtonOverTree, "ПриНажатииПравойКнопкиНадДеревом","OnRButtonOverTree",2, ekActiveForm, false, false, 0},
    {meOnLButtonOverTree, "ПриНажатииЛевойКнопкиНадДеревом","OnLButtonOverTree",2, ekActiveForm, false, false, 0},
    
	// события, которые ищутся только во всех глобальных модулях
	{meOnStartObjectLock, "ПриНачалеБлокировкиОбъекта","OnStartObjectLock",1, ekOnlyGlobalModules, false, false, 0},
	{meOnObjectLocked, "ОбработкаБлокировкиОбъекта","OnObjectLocked",3, ekOnlyGlobalModules, false, false, 0},
	
	{meOnPrintTable, "ПриПечатиТаблицы","OnPrintTable",4, ekOnlyGlobalModules, false, false, 0},
	//{meOnPostPrint, "ПослеОтправкиНаПечать","PostPrint",3, ekOnlyGlobalModules, false, false, 0},
	//{meOnPrePrint, "ПриОтправкеНаПечать","PrePrint",3, ekOnlyGlobalModules, false, false, 0},
	
	{meOnLoadForm, "ПриЗагрузкеФормы","OnLoadForm",1, ekOnlyGlobalModules, false, false, 0},
	{meOnLoadFormModule, "ПриЗагрузкеМодуляФормы","OnLoadFormModule",1, ekOnlyGlobalModules, false, false, 0},
	{meOnLoadAsExternalForm, "ПриЗагрузкеВнешнегоОтчета","OnLoadAsExternalForm",1, ekOnlyGlobalModules, false, false, 0},
	{meOnLoadAsExternalDialog, "ПриЗагрузкеФормыВнешнегоОтчета","OnLoadExternalDialog",1, ekOnlyGlobalModules, false, false, 0},
	
	{meOnActivateDocForm, "ПриОткрытииФормыДокумента","OnActivateDocForm",15, ekOnlyGlobalModules, false, false, 0},
	{meOnTestAccess, "ПриПроверкеПравДоступа","OnTestAccess",5, ekOnlyGlobalModules, false, false, 0},

	// события, которые ищутся как в модуле формы, так и во всех глобальных модулях
	{meOnReadRepHistory, "ПриЧтенииНастройки","OnReadRepHistory",2, ekSimple, false, false, 0},
	{meOnWriteRepHistory, "ПриЗаписиНастройки","OnWriteRepHistory",2, ekSimple, false, false, 0},
	{meOnActivateWindow, "ПриАктивацииОкна","OnActivateWindow",0, ekSimple, false, false, 0},
	{meOnDeactivateWindow, "ПриДеактивацииОкна","OnDeactivateWindow",0, ekSimple, false, false, 0},
	{meOnClosed, "ПослеЗакрытия","OnClosed",0, ekSimple, false, false, 0},
	{meOnActivate, "ПослеОткрытия","OnActivate",0, ekSimple, false, false, 0},
	{meOnSaveSheetDoc, "ПриЗаписиТаблицы","OnSaveSheetDoc",4, ekOnlyGlobalModules, false, false, 0},
	
	{meOnRefresh, "ПослеОбновленияФормы","OnRefresh",0, ekSimple, false, false, 0},
	
	{meOnMultiLinePic, "ПиктограммаМногострочнойЧасти","MultiLinePic",1, ekSimple, false, false, 0},
	{meOnCreateForm, "ПослеСозданияФормы","OnCreateForm",0, ekSimple, false, false, 0},
	{meOnSize, "ПриИзмененииРазмераОкна","OnSize",3, ekSimple, false, false, 0},
	{meOnWndCommand, "ПриКомандеОкна","OnWndCommand",3, ekSimple, false, false, 0},

	{meOnMouseMove,"ПриДвиженииМыши","OnMouseMove", 4, ekSimple, false, false, 0},
	{meOnRButtonDown, "ПриНажатииПравойКнопки","OnRButtonDown", 4, ekSimple, false, false, 0},
	{meOnRButtonUp, "ПриОтжатииПравойКнопки","OnRButtonUp", 4, ekSimple, false, false, 0},
	{meOnRButtonDblClk, "ПриДвойномНажатииПравойКнопки","OnRButtonDblClk", 4, ekSimple, false, false, 0},
	{meOnLButtonDown, "ПриНажатииЛевойКнопки","OnLButtonDown", 4, ekSimple, false, false, 0},
	{meOnLButtonUp, "ПриОтжатииЛевойКнопки","OnLButtonUp", 4, ekSimple, false, false, 0},
	{meOnLButtonDblClk, "ПриДвойномНажатииЛевойКнопки","OnLButtonDblClk", 4, ekSimple, false, false, 0},
	{meOnMButtonDown, "ПриНажатииСреднейКнопки","OnMButtonDown", 4, ekSimple, false, false, 0},
	{meOnMButtonUp, "ПриОтжатииСреднейКнопки","OnMButtonUp", 4, ekSimple, false, false, 0},
	{meOnMButtonDblClk, "ПриДвойномНажатииСреднейКнопки","OnMButtonDblClk", 4, ekSimple, false, false, 0},
	{meOnMouseWheel, "ПриПрокруткеКолесаМыши","OnMouseWheel", 5, ekSimple, false, false, 0},

	// процедуры таймера - могут динамически добавляться и удаляться !
	{meOnLocalTimerForm, NULL,NULL,0, ekOneModule, false, true, 0},
	{meOnGlobalTimerForm, NULL,NULL,0, ekOnlyGlobalModules, false, true, 0},

	// предопределенные события глобальника от 1С - для поиска в других глобальниках
	{meOnStartSystem,			"ПриНачалеРаботыСистемы","OnStartSystem",0, ekSystem, false, false, 2628},
	{meOnFinishSystem,			"ПриЗавершенииРаботыСистемы","OnFinishSystem",0, ekSystem, false, false, 2629},
	{meOnDeleteItem,			"ПриУдаленииЭлемента","OnDeleteItem",2, ekSystem, false, false, 2943},
	{meOnOpenHistory,			"ПриОткрытииИстории","OnOpenHistory",3, ekSystem, false, false, 3777},
	{meOnWriteHistory,			"ПриЗаписиИстории","OnWriteHistory",4, ekSystem, false, false, 2944},
	{meOnDeleteHistory,			"ПриУдаленииИстории","OnDeleteHistory",4, ekSystem, false, false, 2945},
	{meOnWriteConst,			"ПриЗаписиКонстанты","OnWriteConst",2, ekSystem, false, false, 2941},
	{meOnDeleteDoc,				"ПриУдаленииДокумента","OnDeleteDoc",2, ekSystem, false, false, 2937},
	{meOnChangeTimeDoc,			"ПриИзмененииВремениДокумента","OnChangeTimeDoc",1, ekSystem, false, false, 2939},
	{meOnUnPosting,				"ПриОтменеПроведенияДокумента","OnUnPosting",1, ekSystem, false, false, 2938},
	{meOnSetSelectInJournal,	"ПриУстановкеОтбора","OnSetSelectInJournal",2, ekSystemInOneModule, false, false, 2942},
	{meOnDeleteAccount,			"ПриУдаленииСчета","OnDeleteAccount",2, ekSystem, false, false, 2978},
	{meOnOperEntryOffOn,		"ПриВыклВклПроводокОперации","OnOperEntryOffOn",1, ekSystem, false, false, 3229},
	{meOnPeriodChange,			"ПриСменеРасчетногоПериода","OnPeriodChange",2, ekSystem, false, false, 2992},

	// локальные события, перенаправляемые в глобальные модули
	{meOnOpen,					"Глобальная_ПриОткрытии",						"Global_OnOpen",				0, ekOnlyGlobalModules, false, false, 2935}, // обрабатывается перехватчиком 1С++
	{meOnClose,					"Глобальная_ПриЗакрытии",						"Global_OnClose",				0, ekOnlyGlobalModules, false, false, 2946},
	{meOnNewLine,				"Глобальная_ПриВводеСтроки",					"Global_OnNewLine",				0, ekOnlyGlobalModules, false, false, 2959},
	{meOnWrite,					"Глобальная_ПриЗаписи",							"Global_OnWrite",				0, ekOnlyGlobalModules, false, false, 2936},
	{meOnMoveIntoOtherGroup,	"Глобальная_ПриПереносеЭлементаВДругуюГруппу",	"Global_OnMoveIntoOtherGroup",	0, ekOnlyGlobalModules, false, false, 2940},
	{meOnCalculating,			"Глобальная_ПриРасчете",						"Global_OnCalculating",			0, ekOnlyGlobalModules, false, false, 2993},
	{meOnStartValueChoice,		"Глобальная_ПриНачалеВыбораЗначения",			"Global_OnStartValueChoice",	0, ekOnlyGlobalModules, false, false, 3305},
	{meOnReopen,				"Глобальная_ПриПовторномОткрытии",				"Global_OnReopen",				0, ekOnlyGlobalModules, false, false, 3521},
	{meOnTabCtrlPosChanged,		"Глобальная_ПриВыбореЗакладки",					"Global_OnTabCtrlPosChanged",	0, ekOnlyGlobalModules, false, false, 3204},
	{meProcessValueChoice,		"Глобальная_ОбработкаВыбораЗначения",			"Global_ProcessValueChoice",	0, ekOnlyGlobalModules, false, false, 3308},
	{meOnSelectLine,			"Глобальная_ПриВыбореСтроки",					"Global_OnSelectLine",			0, ekOnlyGlobalModules, false, false, 3275},
	{meProcessSelectLine,		"Глобальная_ОбработкаВыбораСтроки",				"Global_ProcessSelectLine",		0, ekOnlyGlobalModules, false, false, 3276},
	{meNew,						"Глобальная_ВводНового",						"Global_New",					0, ekOnlyGlobalModules, false, false, 3735}, // обрабатывается перехватчиком 1С++
	{meInputNew,				"Глобальная_ВводНового",						"Global_InputNew",				0, ekOnlyGlobalModules, false, false, 2903}, // обрабатывается перехватчиком 1С++
	{meInputCausedBy,			"Глобальная_ВводНаОсновании",					"Global_InputCausedBy",			0, ekOnlyGlobalModules, false, false, 2902}, // обрабатывается перехватчиком 1С++
	{meOnEditNewLine,			"Глобальная_ПриРедактированииНовойСтроки",		"Global_OnEditNewLine",			0, ekOnlyGlobalModules, false, false, 2960},
	{meOnStartEditLine,			"Глобальная_ПриНачалеРедактированияСтроки",		"Global_OnStartEditLine",		0, ekOnlyGlobalModules, false, false, 2934},
	{meOnFinishLineEdit,		"Глобальная_ПриОкончанииРедактированияСтроки",	"Global_OnFinishLineEdit",		0, ekOnlyGlobalModules, false, false, 3394},
	{meOnChangeLinesOrder,		"Глобальная_ПриИзмененииПорядкаСтрок",			"Global_OnChangeLinesOrder",	0, ekOnlyGlobalModules, false, false, 3326},
	{meOnDeleteLine,			"Глобальная_ПриУдаленииСтроки",					"Global_OnDeleteLine",			0, ekOnlyGlobalModules, false, false, 2958},
	{meOnSetOwner,				"Глобальная_ПриВыбореВладельца",				"Global_OnSetOwner",			0, ekOnlyGlobalModules, false, false, 3312},
	{meOnSetParent,				"Глобальная_ПриВыбореРодителя",					"Global_OnSetParent",			0, ekOnlyGlobalModules, false, false, 3311},
	{meOnHierarchyChange,		"Глобальная_ПриСменеИерархии",					"Global_OnHierarchyChange",		0, ekOnlyGlobalModules, false, false, 3565},
	{meOnSetViewBound,			"Глобальная_ПриУстановкеГраницыПросмотра",		"Global_OnSetViewBound",		0, ekOnlyGlobalModules, false, false, 3040},
	{meOnSetSelection,			"Глобальная_ПриУстановкеОтбора",				"Global_OnSetSelection",		0, ekOnlyGlobalModules, false, false, 3041},
	{meOnSetPresentation,		"Глобальная_ПриУстановкеПредставления",			"Global_OnSetPresentation",		0, ekOnlyGlobalModules, false, false, 3042},
	{meOnSetSelect,				"Глобальная_ПриУстановкеОтбора",				"Global_OnSetSelect",			0, ekOnlyGlobalModules, false, false, 3069},
	{meOnResultUpdate,			"Глобальная_ПриИсправленииРезультата",			"Global_OnResultUpdate",		0, ekOnlyGlobalModules, false, false, 2990},
	{meOnUpdateCancel,			"Глобальная_ПриОтменеИсправления",				"Global_OnUpdateCancel",		0, ekOnlyGlobalModules, false, false, 2991},
	{meOnSetRange,				"Глобальная_ПриУстановкеИнтервала",				"Global_OnSetRange",			0, ekOnlyGlobalModules, false, false, 3726},
	
	{meOnSheetCellProcessing, "ОбработкаЯчейкиТаблицы","SheetCellProcessing",4, ekSystemInOneModule, true, false, 2925}, // TODO обратить внимание на этот параметр FSO
	
	//{meOnExternEventProcessing, "ОбработкаВнешнегоСобытия", "ExternEventProcessing", 3, ekSystem, false, false, 2926},
	{meOnDrop, "Event_OnDrop","Событие_OnDrop", 1, ekOnlyGlobalModules, false, false, 0},
	{meOnURLDrop, "Event_OnURLDrop","Событие_OnURLDrop", 1, ekOnlyGlobalModules, false, false, 0},

	{meOnCommand, "ПриПолученииКомандыГлавнымОкном","OnCommandMainWindow", 3, ekOnlyGlobalModules, false, false, 0},
	{meOnSysCommand, "ПриПолученииСистемнойКомандыГлавнымОкном","OnSysCommandMainWindow", 3, ekOnlyGlobalModules, false, false, 0},

    {meOnLDblClkStatusBar, "ПриДвойномНажатииЛевойКнопкиВСтрокеСостояния","OnLDblClkStatusBar", 1, ekActiveForm, false, false, 0},

    {meOnWriteMessage, "ПриВыводеСообщения","OnWriteMessage", 7, ekOnlyGlobalModules, false, false, 0},
    {meOnShowControlBar, "ПриИзмененииВидимостиОкнаСообщений","OnShowControlBar", 3, ekOnlyGlobalModules, false, false, 0},
    {meOnWriteStatusLine, "ПриВыводеСтрокиСостояния","OnWriteStatusLine", 5, ekOnlyGlobalModules, false, false, 0},

    {meTraceLog, "ПриЛогеТрассировки","OnTraceLog", 6, ekOnlyGlobalModules, false, false, 0},
    {meOnValueTraceLogPresent, "ПриПолученииПредставленияПеременнойТрассировки","OnValueTraceLogPresent", 4, ekOnlyGlobalModules, false, false, 0},

    //{meTestCommandEnable, "ПроверкаДосутпностиКоманды","TestCommandEnable", 2, ekActiveForm, false, false, 0},
//	{meOnInitMenu, "ПриПодготовкеМеню","OnInitMenu", 5, ekOnlyGlobalModules, false, false, 0},
};

void CInitFormEx::InitEvents(void)
{
	// схема работы всегда такая - 	сначала добавляем события, потом глобальники

	CEventsManager& manager = CEventsManager::GetManager();
	for(int i=0; i < sizeof(CV7GlobalEvents)/sizeof(stEventData); i++)
		manager.AddEvent(CV7GlobalEvents[i]);

	if(CBLModule::GetFirstLoadedModuleID())
	{
 		for(ULONG id = CBLModule::GetFirstLoadedModuleID(); id; id = CBLModule::GetNextLoadedModuleID(id))
 			manager.AddGlobalModule(CBLModule::GetLoadedModule(id));

	}
	else // вдруг ФормЕкс грузится в теле основного глобальника 
		manager.AddGlobalModule(GetGlobalModule());

	CMethodsWrapper::InitHooks(manager);
}

void CInitFormEx::SaveSettingsToRegistry()
{
	if (!pApp)
		return;

	CProfile7* pProfile7 = pApp->GetProps();
	if(!pProfile7)
		return;

	HKEY hKey;
	HKEY hKey0;
	CString keyPath = CString("Software\\1C\\1Cv7\\7.7\\")+pProfile7->GetStringProp(0x12);
	BOOL res = TRUE;
	if(RegOpenKeyEx(HKEY_CURRENT_USER, keyPath+"\\FormEx", 0, KEY_WRITE, &hKey) != ERROR_SUCCESS)
	{
		DWORD dwDisposition;
		res = FALSE;
		if(RegOpenKeyEx(HKEY_CURRENT_USER, keyPath, 0, KEY_WRITE, &hKey0) == ERROR_SUCCESS)
			if((RegCreateKeyEx(hKey0, "FormEx", 0, NULL, REG_OPTION_NON_VOLATILE, KEY_WRITE, NULL, &hKey, &dwDisposition) == ERROR_SUCCESS))
				res = TRUE;
	}
	if(res)
	{
		RegSetValueEx(hKey, "EnabledColor", 0, REG_DWORD, (LPBYTE)&m_bEnabledColor, 4);
		RegSetValueEx(hKey, "LocalColor", 0, REG_DWORD, (LPBYTE)&m_bLocalColor, 4);
		RegSetValueEx(hKey, "ShowKeyboardLayout", 0, REG_DWORD, (LPBYTE)&m_bShowKL, 4);
		RegCloseKey(hKey);
	}

}

void CInitFormEx::LoadSettingsFromRegistry()
{
	if (!pApp)
		return;

	CProfile7* pProfile7 = pApp->GetProps();
	if(!pProfile7)
		return;

	HKEY hKey;
	CString keyPath = CString("Software\\1C\\1Cv7\\7.7\\")+pProfile7->GetStringProp(0x12)+"\\FormEx";

	if(RegOpenKeyEx(HKEY_CURRENT_USER, keyPath, 0, KEY_READ, &hKey) == ERROR_SUCCESS)
	{

		DWORD dwType, dwCount;
		CString strValue;
		dwCount = 4;
		RegQueryValueEx(hKey, "EnabledColor", NULL, &dwType, (LPBYTE)&m_bEnabledColor, &dwCount);
		RegQueryValueEx(hKey, "LocalColor", NULL, &dwType, (LPBYTE)&m_bLocalColor, &dwCount);
		RegQueryValueEx(hKey, "ShowKeyboardLayout", NULL, &dwType, (LPBYTE)&m_bShowKL, &dwCount);

		RegCloseKey(hKey);
	}
}

void CInitFormEx::AddSystemHooks()
{
	SetMouseSystemHook(TRUE); //m_MouseHookHandle = SetWindowsHookEx(WH_MOUSE, Mouse_Hook, pApp->m_hInstance, pApp->m_nThreadID);
	SetKeyboardSystemHook(TRUE); //m_KeyboardHookHandle = SetWindowsHookEx(WH_KEYBOARD, Key_Hook, pApp->m_hInstance, pApp->m_nThreadID);
	m_WndHookHandle.Init(WH_CALLWNDPROCRET, Wnd_Hook, pApp); //SetSystemHook(WH_CALLWNDPROCRET, m_WndHookHandle, Wnd_Hook, TRUE); //m_WndHookHandle = SetWindowsHookEx(WH_CALLWNDPROCRET, Wnd_Hook, pApp->m_hInstance, pApp->m_nThreadID);
	m_WndPreHookHandle.Init(WH_CALLWNDPROC, WndPre_Hook, pApp); //SetSystemHook(WH_CALLWNDPROC, m_WndPreHookHandle, WndPre_Hook, TRUE);  //m_WndPreHookHandle = SetWindowsHookEx(WH_CALLWNDPROC, WndPre_Hook, pApp->m_hInstance, pApp->m_nThreadID);
}

void CInitFormEx::DestroySystemHooks()
{
	SetMouseSystemHook(FALSE); //if(m_MouseHookHandle != 0) UnhookWindowsHookEx(m_MouseHookHandle);
	SetKeyboardSystemHook(FALSE); //if(m_KeyboardHookHandle != 0) UnhookWindowsHookEx(m_KeyboardHookHandle);
	m_WndHookHandle.Destroy(); //SetSystemHook(WH_CALLWNDPROCRET, m_WndHookHandle, Wnd_Hook, FALSE); //if(WndHookHandle != 0) UnhookWindowsHookEx(WndHookHandle);
	m_WndPreHookHandle.Destroy(); //SetSystemHook(WH_CALLWNDPROC, m_WndPreHookHandle, WndPre_Hook, FALSE);  //if(WndPreHookHandle != 0) UnhookWindowsHookEx(WndPreHookHandle);
}

#define ID_PANE_START 0xD000
#define ID_PANE_KEYLAYOUT 0xD001
#define ID_PANE_TIME 0xD002
#define ID_PANE_USERSTART 0xD010
#define ID_PANE_END 0xD100

void SECStatusBarFormEx::DrawItem(struct tagDRAWITEMSTRUCT * pDrawItemStruct)
{

	SStatusBarPane* pPane = CInitFormEx::Get().pStatusBarManager->GetVisiblePaneByIndex(pDrawItemStruct->itemID);
	if(pPane)
	{
		CDC* pDC = CDC::FromHandle(pDrawItemStruct->hDC);
		CRect r(pDrawItemStruct->rcItem);

		if((pPane->ImageIndex >= 0) && (CInitFormEx::Get().pStatusBarManager->m_ImageList.GetImageCount() > pPane->ImageIndex))
		{
			POINT pt;
			if(pPane->Caption.IsEmpty())
			{
				pt.x = r.left + (r.right - r.left - GetSystemMetrics(SM_CXICON)/2)/2;
				pt.y = r.top + (r.bottom - r.top - GetSystemMetrics(SM_CYICON)/2)/2;
			}
			else
			{
				pt.x = r.left;
				pt.y = r.top;
			}

			SIZE sz;
			sz.cx = 16;
			sz.cy = 15;

			POINT ptOrigin;
			ptOrigin.x = 0;
			ptOrigin.y = 0;

			CInitFormEx::Get().pStatusBarManager->m_ImageList.DrawIndirect(pDC, pPane->ImageIndex, pt, sz, ptOrigin);
			if(!pPane->Caption.IsEmpty())
			{
				r.left += sz.cx + 2;
				pDC->DrawText(pPane->Caption, r, DT_LEFT);
				//::DrawText(pDrawItemStruct->hDC, pPane->Caption, pPane->Caption.GetLength(), &pDrawItemStruct->rcItem, DT_LEFT);
			}
		}
		else
			pDC->DrawText(pPane->Caption, r, DT_LEFT);
			//::DrawText(pDrawItemStruct->hDC, pPane->Caption, pPane->Caption.GetLength(), &pDrawItemStruct->rcItem, DT_LEFT);
	}
}

void CStatusBarManager::AddImagesToList(CBitmap* pbmImage)
{
	m_ImageList.Add(pbmImage, RGB(0x00,0x80,0x80));
}

BOOL CStatusBarManager::GetStatusBar()
{
	if(!m_pStatus) m_pStatus = GetAppStatusBar();
	return (m_pStatus != NULL);
}

void CStatusBarManager::UpdateElements()
{
	if(!GetStatusBar()) return;

	int newcount = 0;

	int countPanes = m_Panes.GetSize();
	for(int i = 0; i < countPanes; i++)
	{
		SStatusBarPane* pPane = (SStatusBarPane*)m_Panes.GetAt(i);
		if(pPane->Visible)
			newcount++;
	};

	int count = m_pStatus->GetCount();

	vector<UINT> nIDs(count);
	vector<UINT> nStyles(count);
	vector<int> cxWidths(count);
	vector<CString> csTitle(count);
	
	for(i = 0; i<count; i++)
	{
		m_pStatus->GetPaneInfo(i,nIDs[i],nStyles[i],cxWidths[i]);
		m_pStatus->GetPaneText(i,csTitle[i]);

		SStatusBarPane* pPane = GetPaneByID(nIDs[i]);
		if(pPane)
			if(pPane->System)
				pPane->SetPane(nIDs[i], csTitle[i], "", pPane->Width, pPane->Style, -1, pPane->Visible, TRUE);
	}

	m_pStatus->AllocElements(newcount,100);

	int n = 0;
	for(i = 0; i < countPanes; i++)
	{
		SStatusBarPane* pPane = (SStatusBarPane*)m_Panes.GetAt(i);
		if(pPane->Visible)
		{
			int iRealWidth = GetPaneWidth(pPane);
			m_pStatus->SetPaneInfo(n,pPane->ID,pPane->Style,iRealWidth);
			m_pStatus->SetPaneText(n,pPane->Caption,pPane->Caption.GetLength());
			n++;
		}
	};

	SetKeyboardLayout(m_pStatus);
	SetLocalTime(m_pStatus);

	Invalidate();
}

void CStatusBarManager::Invalidate(void)
{
	if(!GetStatusBar()) return;

	m_pStatus->Invalidate();
}

SStatusBarPane* CStatusBarManager::GetPaneByID(UINT uiPaneID)
{
	int count = m_Panes.GetSize();
	for(int i = 0; i < count; i++)
	{
		SStatusBarPane* pPane = (SStatusBarPane*)m_Panes.GetAt(i);
		if(pPane->ID == uiPaneID)
			return pPane;
	};

	return NULL;
}

SStatusBarPane* CStatusBarManager::GetPaneByName(CString csName)
{
	int count = m_Panes.GetSize();
	for(int i = 0; i < count; i++)
	{
		SStatusBarPane* pPane = (SStatusBarPane*)m_Panes.GetAt(i);
		if(pPane->Name.CompareNoCase(csName) == 0)
			return pPane;
	};

	return NULL;
}

SStatusBarPane* CStatusBarManager::GetPaneByIndex(int iIndex)
{
	if((iIndex >= 0) && (iIndex < m_Panes.GetSize()))
		return (SStatusBarPane*)m_Panes.GetAt(iIndex);
	return NULL;
}

SStatusBarPane* CStatusBarManager::GetVisiblePaneByIndex(int iIndex)
{
	int n = -1;
	int count = m_Panes.GetSize();
	for(int i = 0; i < count; i++)
	{
		SStatusBarPane* pPane = (SStatusBarPane*)m_Panes.GetAt(i);
		if(pPane->Visible) n++;
		if(iIndex == n) return pPane;
	};
	return NULL;
}

int CStatusBarManager::GetPaneIndexByID(UINT uiPaneID)
{
	int count = m_Panes.GetSize();
	for(int i = 0; i < count; i++)
	{
		SStatusBarPane* pPane = (SStatusBarPane*)m_Panes.GetAt(i);
		if(pPane->ID == uiPaneID)
			return i;
	};

	return -1;
}

void CStatusBarManager::SetPaneText(UINT uiPaneID, CString csCaption)
{
	SStatusBarPane* pPane = GetPaneByID(uiPaneID);
	if(pPane)
	{
		pPane->Caption = csCaption;
		if(GetStatusBar())
		{
			int index = m_pStatus->CommandToIndex(uiPaneID);
			if(index >= 0)
				m_pStatus->SetPaneText(index, csCaption, csCaption.GetLength());
		}
	}
}

int CStatusBarManager::GetPaneWidth(SStatusBarPane* pPane)
{
	if(!GetStatusBar()) return 0;

	int iWidth = 0;
	if(pPane)
	{
		iWidth = pPane->Width;
		if(iWidth == 0)
		{
			SIZE sz;
			HFONT font = (HFONT)m_pStatus->GetFont();
			HDC hdc = GetDC(NULL);
			SelectObject(hdc, font);

			GetTextExtentPoint32(hdc, pPane->Caption,pPane->Caption.GetLength(), &sz);
			ReleaseDC(NULL, hdc);

			iWidth = sz.cx;
			if(pPane->ImageIndex >= 0)
				iWidth += 18;
		}
	}

	return iWidth;
}

int CStatusBarManager::GetPaneWidth(UINT uiPaneID)
{
	int iWidth = 0;
	SStatusBarPane* pPane = GetPaneByID(uiPaneID);
	if(pPane) iWidth = GetPaneWidth(pPane);

	return iWidth;
}

void CStatusBarManager::SetPaneWidth(UINT uiPaneID, int iWidth)
{
	SStatusBarPane* pPane = GetPaneByID(uiPaneID);
	if(pPane)
	{
		pPane->Width = iWidth;
		if(GetStatusBar())
		{
			int index = m_pStatus->CommandToIndex(uiPaneID);
			if(index >= 0)
			{
				int iRealWidth = GetPaneWidth(pPane);
				m_pStatus->SetPaneInfo(index,uiPaneID,0,iRealWidth);
			}
		}
	}
}

SStatusBarPane* CStatusBarManager::AddPane(UINT uiPaneID, CString csCaption, CString csName, int iWidth, int iStyle, int iImageIndex, BOOL bVisible, BOOL bSystem)
{
	SStatusBarPane* pPane = GetPaneByID(uiPaneID);
	if(pPane == NULL)
	{
		pPane = SStatusBarPane::Create();
		if(pPane)
		{
			pPane->SetPane(uiPaneID, csCaption, csName, iWidth, iStyle, iImageIndex, bVisible, bSystem);
			m_Panes.Add(pPane);
		}
	}

	return pPane;
}

UINT CStatusBarManager::AddPane(CString csCaption, CString csName, int iWidth, int iStyle, int iImageIndex, BOOL bVisible)
{
	UINT uiPaneID = ID_PANE_USERSTART;
	int count = m_Panes.GetSize();
	for(int i = 0; i < count; i++)
	{
		SStatusBarPane* pPane = (SStatusBarPane*)m_Panes.GetAt(i);
		if((!pPane->System) && (pPane->ID >= uiPaneID) && (pPane->ID < ID_PANE_END))
			uiPaneID = pPane->ID + 1;
	};

	AddPane(uiPaneID, csCaption, csName, iWidth, iStyle, iImageIndex, bVisible);

	UpdateElements();

	return uiPaneID;
}

void CStatusBarManager::SetStretchPane(SStatusBarPane* pPane)
{
	int count = m_Panes.GetSize();
	for(int i = 0; i < count; i++)
	{
		SStatusBarPane* pCurPane = (SStatusBarPane*)m_Panes.GetAt(i);
		pCurPane->Stretch = FALSE;
		pCurPane->Style &= ~SBPS_STRETCH;
	};

	if(!pPane)
	{
		pPane->Stretch = TRUE;
		pPane->Style |= SBPS_STRETCH;
	}
}

int CStatusBarManager::GetPanePosition(SStatusBarPane* pPane)
{
	return GetPaneIndexByID(pPane->ID) + 1;
}

void CStatusBarManager::MovePanel(UINT uiPaneID, int iSteps)
{
	int index = GetPaneIndexByID(uiPaneID);
	if(index >= 0)
	{
		SStatusBarPane* pPane = GetPaneByID(uiPaneID);
		if(pPane)
		{
			m_Panes.RemoveAt(index);
			int newindex = index + iSteps;
			if(newindex < 0) newindex = 0;
			if(newindex >= m_Panes.GetSize())
				m_Panes.Add(pPane);
			else
				m_Panes.InsertAt(newindex, pPane);

			UpdateElements();
		}
	}
}

void CStatusBarManager::DeletePane(UINT uiPaneID)
{
	SStatusBarPane* pPane = GetPaneByID(uiPaneID);
	if(pPane)
	{
		if(pPane->System)
		{
			pPane->Visible = FALSE;
		}
		else
		{
			int i = GetPaneIndexByID(uiPaneID);
			if(i >= 0)
			{
				m_Panes.RemoveAt(i);
				delete pPane;
			}
		}
		UpdateElements();
	}
}

void CStatusBarManager::DeleteAllPanes()
{
	int count = m_Panes.GetSize();
	for(int i = 0; i < count; i++)
	{
		SStatusBarPane* pPane = (SStatusBarPane*)m_Panes.GetAt(i);
		delete pPane;
	};
	m_Panes.RemoveAll();
}


void CStatusBarManager::SetTimer()
{
	if(!GetStatusBar()) return;

	m_StatusTimer = m_pStatus->SetTimer(500, 100, (TIMERPROC)TimerProc);
}


// static
void CALLBACK CStatusBarManager::TimerProc(HWND hWnd, UINT nMsg, UINT nIDEvent, DWORD dwTime)
{
	if(nIDEvent == 500)
	{
		SECStatusBar* pStatus = (SECStatusBar*)SECStatusBar::FromHandlePermanent(hWnd);
		if(pStatus)
		{
			SetKeyboardLayout(pStatus);
			SetLocalTime(pStatus);
		}
	}
}

void CStatusBarManager::SetIndicators(BOOL bShow, BOOL bHard)
{
	if(!GetStatusBar()) return;

	//UpdateSystemPanes();

	SStatusBarPane* pPane = NULL;

	int count = m_pStatus->GetCount();

	UINT nID;
	UINT nStyle;
	int cxWidth;
	CString csTitle;
	
	for(int i = 0; i<count; i++)
	{
		m_pStatus->GetPaneInfo(i,nID,nStyle,cxWidth);
		m_pStatus->GetPaneText(i,csTitle);

		if((nID < ID_PANE_START) || (nID > ID_PANE_END))
		{
			pPane = GetPaneByID(nID);
			if(!pPane)
				AddPane(nID, csTitle, "", cxWidth, nStyle, -1, TRUE, TRUE);
			else
				pPane->SetPane(nID, csTitle, "", pPane->Width, pPane->Style, -1, pPane->Visible, TRUE);

		}
	}

	pPane = GetPaneByID(ID_PANE_KEYLAYOUT);
	if(!pPane)
		pPane = AddPane(ID_PANE_KEYLAYOUT, "", "KeyboardLayout", 45, 0, -1, bShow);
	if(bHard)
		pPane->Visible = bShow;

	pPane = GetPaneByID(ID_PANE_TIME);
	if(!pPane)
		pPane = AddPane(ID_PANE_TIME, "", "LocalTime", 45, 0, -1, bShow);
	if(bHard)
		pPane->Visible = bShow;

	UpdateElements();
}

/*
void CStatusBarManager::SetSystemPaneText(int PaneIndex, const char * buf, int count)
{
	if(!GetStatusBar()) return;

	UINT nID;
	UINT nStyle;
	int cxWidth;

	m_pStatus->GetPaneInfo(PaneIndex,nID,nStyle,cxWidth);
	if((nID < ID_PANE_START) || (nID > ID_PANE_END))
	{
		SStatusBarPane* pPane = GetPaneByID(nID);
		if(!pPane)
			AddPane(nID, buf, "", cxWidth, nStyle, -1, TRUE, TRUE);
		else
			pPane->SetPane(nID, buf, "", pPane->Width, pPane->Style, -1, pPane->Visible, TRUE);
	}
}

void CStatusBarManager::UpdateSystemPanes()
{
	if(!GetStatusBar()) return;

	SStatusBarPane* pPane = NULL;

	int count = m_pStatus->GetCount();

	UINT nID;
	UINT nStyle;
	int cxWidth;
	CString csTitle;
	
	for(int i = 0; i<count; i++)
	{
		m_pStatus->GetPaneInfo(i,nID,nStyle,cxWidth);
		m_pStatus->GetPaneText(i,csTitle);

		if((nID < ID_PANE_START) || (nID > ID_PANE_END))
		{
			pPane = GetPaneByID(nID);
			if(!pPane)
				AddPane(nID, csTitle, "", cxWidth, nStyle, -1, TRUE, TRUE);
			else
				pPane->SetPane(nID, csTitle, "", pPane->Width, pPane->Style, -1, pPane->Visible, TRUE);

		}
	}
}
*/

void CStatusBarManager::Init(BOOL bShow)
{
	if(!GetStatusBar()) return;

	SetIndicators(m_bShowKL, TRUE);

	SetTimer();
}

void CStatusBarManager::SetStatusBar()
{
	if(!GetStatusBar()) return;

	SetIndicators(m_bShowKL, TRUE);
}

// static
void CStatusBarManager::SetKeyboardLayout(SECStatusBar* pStatus)
{
	if(pStatus)
	{
		char KLName[KL_NAMELENGTH]; 
		if(GetLocaleInfo((LCID)((WORD)GetKeyboardLayout(AfxGetApp()->m_nThreadID)),LOCALE_SABBREVLANGNAME,KLName,KL_NAMELENGTH))
		{
			CInitFormEx::Get().pStatusBarManager->SetPaneText(ID_PANE_KEYLAYOUT,KLName);
		}
	}
}

// static
void CStatusBarManager::SetLocalTime(SECStatusBar* pStatus)
{
	if(pStatus)
	{
		SYSTEMTIME SystemTime;
		GetLocalTime(&SystemTime);

		CString csTime = "";
		csTime.Format("%.2d:%.2d", SystemTime.wHour, SystemTime.wMinute);
		CInitFormEx::Get().pStatusBarManager->SetPaneText(ID_PANE_TIME,csTime);

	}
}

void CInitFormEx::SetIndicatorsForStatusBar(SECStatusBar* pStatus, unsigned int const * num1, int num2)
{
	pStatusBarManager->SetIndicators(m_bShowKL);
}

void CInitFormEx::ShowKeyboardIndicator(BOOL bShow)
{
	pStatusBarManager->SetIndicators(bShow, TRUE);
}

//BOOL CInitFormEx::SetSystemHook(int HookID, HHOOK& HookHandle, HOOKPROC HookProc, int bSetFlag)
BOOL CInitFormEx::SetSystemHook(CSystemMessagesHooker& HookHandle, int HookID, HOOKPROC HookProc, int bSetFlag)
{
	BOOL result = HookHandle.IsValid();
	if(HookHandle.IsValid())
	{
		if(!bSetFlag)
		{
			//if(UnhookWindowsHookEx(HookHandle) == TRUE)
			//	HookHandle = NULL;
			HookHandle.Destroy();
		}
	}
	else
	{
		if((TRUE == bSetFlag) && pApp)
		{
			HookHandle.Init(HookID, HookProc, pApp); //HookHandle = SetWindowsHookEx(HookID, HookProc, pApp->m_hInstance, pApp->m_nThreadID);
		}
	}

	return result;
}

BOOL CInitFormEx::SetKeyboardSystemHook(int bSetFlag)
{
	return SetSystemHook(m_KeyboardHookHandle, WH_KEYBOARD, Key_Hook, bSetFlag);
}

BOOL CInitFormEx::SetMouseSystemHook(int bSetFlag)
{
	return SetSystemHook(m_MouseHookHandle, WH_MOUSE, Mouse_Hook, bSetFlag);
}

void CInitFormEx::SetupPlatformID()
{
	// определяем версию ОС
	m_PlatformId = 0;
	m_wSuiteMask = 0;
	OSVERSIONINFOEXEX osvi;
	ZeroMemory(&osvi, sizeof(OSVERSIONINFOEXEX));
	osvi.dwOSVersionInfoSize = sizeof(OSVERSIONINFOEXEX);
	if(GetVersionEx ((OSVERSIONINFO *) &osvi))
	{
		m_PlatformId = osvi.dwPlatformId; //myPlatformId = osvi.dwPlatformId;
		m_wSuiteMask = osvi.wSuiteMask;
	}
	else
	{
		osvi.dwOSVersionInfoSize = sizeof (OSVERSIONINFO);
		if (GetVersionEx ( (OSVERSIONINFO *) &osvi))
			m_PlatformId = osvi.dwPlatformId; //myPlatformId = osvi.dwPlatformId;
	}
}

void CInitFormEx::SetSystemTopmostModalState(BOOL bSet)
{
	if (bSet == m_bModalState)
		return;
	
	m_bModalState = bSet;
	bool bEnableSystemWindows = !bSet;

	HWND hwnd;

	if(hwnd=::FindWindowEx(GetDesktopWindow(),NULL,"Progman",NULL))
		if(hwnd=::FindWindowEx(hwnd,NULL,"SHELLDLL_DefView",NULL))
			::EnableWindow(hwnd, bEnableSystemWindows);
	if(hwnd=::FindWindowEx(::GetDesktopWindow(),NULL,"Shell_TrayWnd",NULL))
		::EnableWindow(hwnd, bEnableSystemWindows);

	::SetWindowPos(pMainWindow->GetSafeHwnd(),HWND_TOPMOST,0,0,0,0, SWP_SHOWWINDOW | SWP_NOSIZE);
}

//int iCountStream = 0;

int CAllFormsNamesManager::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; // TODO проверить удаление
// 	pDocNames->id = l1;
// 	pDocNames->strFolder = str;
// 	DocNamesArray.SetAt(str1,pDocNames);
	CAllFormsNamesManager::Get()->Add(str1, l1, str);

	return 1;
}

void CAllFormsNamesManager::GetNamesOfAllForms()
{
	//iCountStream = 0;
	CConfigCont::GetAllTypedItem(procGetAllTypedItem,0,ptDialog,0);
}
