//////////////////////////////////////////////////////////////////////
//
// Разработчик: Алексей Фёдоров aka АЛьФ, mailto: alf@dorex.pro
//
//////////////////////////////////////////////////////////////////////
//
// v7Windows.cpp: implementation of the Cv7Windows class.
//
//////////////////////////////////////////////////////////////////////

#include "stdafx.h"
#include "addin.h"
#include "v7Windows.h"
#include "InitFormEx.h"

#include "artbear\TrayIconManager.h"
#include "sizecbar.h"
 
#ifdef _DEBUG
#undef THIS_FILE
static char THIS_FILE[]=__FILE__;
#define new DEBUG_NEW
#endif

void CopyMenu(CMenu* pMenuSrc, CMenu* pMenuDes, bool f = false);

extern CBLModule7* pGlobalModuleFormEx;

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

static UINT uMainWindowStyle = 0;
static UINT uChildWindowStyle = 0;
static UINT uChildModalWindowStyle = 0;

boost::shared_ptr<CMenuManager> CMenuManager::pManager;

IMPLEMENT_DYNCREATE(Cv7Windows,CBLContext);

class CObjID Cv7Windows::ObjID;

struct Cv7Windows::paramdefs Cv7Windows::defFnNames[] = {
	{{"GetMenu","ПолучитьМеню"}, TRUE, 0},
	{{"EnableMenu","ДоступностьМеню"}, TRUE, 2},
	{{"VisibleMenu","ВидимостьМеню"}, TRUE, 2},
	{{"GetToolBars","ПолучитьПанели"}, TRUE, 0},
	{{"ShowToolBar","ПоказыватьПанель"}, TRUE, 2},
	{{"ShowToolBars","ПоказыватьПанели"}, TRUE, 1},
	{{"ShowStatusBar","ПоказыватьСтрокуСостояния"}, TRUE, 1},
	{{"WindowsStyle","СтильОкна"}, TRUE, 2},
	{{"WindowsSize","РазмерОкна"}, TRUE, 5},
	{{"WindowsPos","ПоложениеОкна"}, TRUE, 3},
	{{"WindowsMenu","МенюОкна"}, TRUE, 5},
	{{"CenterWindow","ЦентрироватьОкно"}, TRUE, 1},
	{{"Maximize","Максимизировать"}, TRUE, 1},
	{{"Minimize","Минимизировать"}, TRUE, 1},
	{{"Restore","Восстановить"}, TRUE, 1},
	{{"GetResolution","ПолучитьРазрешение"}, TRUE, 2},
	{{"BringWindowToTop","НаПереднийПлан"}, TRUE, 1},
	{{"BeginModalState","ВключитьМодальныйРежим"}, TRUE, 0},
	{{"EndModalState","ВыключитьМодальныйРежим"}, TRUE, 0},
	{{"MinimizeToTray","МинимизироватьВТрей"}, FALSE, 1},

	{{"CloseWindow",	"ЗакрытьОкно"},	true, 2},
	{{"CloseAllWindows",	"ЗакрытьВсеОкна"},	FALSE, 1},
	{{"SendCommand","ОтправитьКоманду"}, TRUE, 2},
	{{"PostCommand","ПослатьКоманду"}, TRUE, 2},
	{{"UpdateWindow","ОбновитьОкно"}, FALSE, 1},
	{{"SetFocus","УстановитьФокус"}, FALSE, 1},
	{{"GetTextSize","ПолучитьРазмерТекста"}, FALSE, 4},
	{NULL,0,0}
};

Cv7Windows::Cv7Windows(int param):CBLContext(param)
{

}

Cv7Windows::~Cv7Windows()
{
}

//void Cv7Windows::MenuToValueList(CMenu* pNextMenu, CValue& retValue)
void MenuToValueList(CMenu* pNextMenu, CValue& retValue)
{
	if(pNextMenu)
	{
		CBLContext* pVLCont = CBLContext::CreateInstance("ValueList");
		if(pVLCont)
		{
			int num = pVLCont->FindMethod("AddValue");
			if(num >= 0)
			{
				CString st = "";
				CValue v1;
				CValue v2 = st;
				CValue *pParam[2] = {&v1, &v2};
				UINT c = pNextMenu->GetMenuItemCount();
				if(c != 0xFFFFFFFF)
				{
					for(UINT i = 0; i < c ; i++)
					{
						//CString stDeb = "";
						//stDeb.Format("%x",pNextMenu->GetMenuItemID(i));
						//stDeb.Format("%x",pNextMenu->GetMenuState(i,MF_BYPOSITION));
						//stDeb.MakeUpper();
						UINT uMenuState = pNextMenu->GetMenuState(i,MF_BYPOSITION);
						if(uMenuState == MF_SEPARATOR)
						{
							v1 = "-";
							v2 = "-";
							pVLCont->CallAsProc(num,pParam);
						}
						else
						{
							CString stMenu = "";
							pNextMenu->GetMenuString(i,stMenu,MF_BYPOSITION);
							//if(!stMenu.IsEmpty())
							{
								CMenu* pSubMenu = pNextMenu->GetSubMenu(i);
								v1 = pNextMenu->GetMenuItemID(i);
								MenuToValueList(pSubMenu, v1);
								//v2 = stDeb+"h :: "+stMenu;
								v2 = stMenu;
								pVLCont->CallAsProc(num,pParam);
							}
						}
					}
					retValue.AssignContext(pVLCont);
				}
			}
			pVLCont->DecrRef();
		}
	}
}

void CMenuManager::SetMenuItemStyle(CMenu* pNextMenu,CString& stName,UINT uStyle)
{
	if(pNextMenu)
	{
		UINT c = pNextMenu->GetMenuItemCount();
		if(c != 0xFFFFFFFF)
		for(UINT i = 0; i < c ; i++)
		{
			CString stMenu = "";
			pNextMenu->GetMenuString(i,stMenu,MF_BYPOSITION);
			stMenu.TrimLeft();
			stMenu.TrimRight();
			if(stMenu.CompareNoCase(stName) == 0)
			{
				MENUITEMINFO MenuItemInfo;
				MenuItemInfo.cbSize = sizeof(MENUITEMINFO);
				MenuItemInfo.fMask = MIIM_ID;
				pNextMenu->GetMenuItemInfo(i,&MenuItemInfo,TRUE);
				UINT idMenu = MenuItemInfo.wID;
				pNextMenu->EnableMenuItem(i,MF_BYPOSITION | uStyle);
			}
		}
	}
}

void CMenuManager::SetVisibleMainMenu(CMenu* pMenu)
{
	int n = unvisibleMenus.GetSize();
	int nn = srcMenus.GetSize();
	int p = -1;
	for(int i = 0; i < nn; i++)
		if(srcMenus.GetAt(i) == (DWORD)pMenu->GetSafeHmenu()) p = i;

	if(p >= 0)
	{
		CMenu *pMenuT = CMenu::FromHandle((HMENU)tempMenus.GetAt(p));
		if(pMenuT)
		{
			if(int(pMenu->GetMenuItemCount()) >= 0)
			{
				while(pMenu->GetMenuItemCount()) pMenu->DeleteMenu(0,MF_BYPOSITION);
				CopyMenu(pMenuT,pMenu, true);
			}
		}
	}
	else
	{
		CMenu cMenu;
		cMenu.CreateMenu();
		CopyMenu(pMenu,&cMenu, true);
		tempMenus.Add((DWORD)cMenu.Detach());
		srcMenus.Add((DWORD)pMenu->GetSafeHmenu());
	}

	for(i = 0; i < n; i++)
	{
		CString st = unvisibleMenus.GetAt(i);
		int nnn = pMenu->GetMenuItemCount();
		for(int f = 0; f < nnn; f++)
		{
			CString stMenu = "";
			pMenu->GetMenuString(f,stMenu,MF_BYPOSITION);
			if(stMenu == st)
			{
				pMenu->DeleteMenu(f,MF_BYPOSITION);
				f--; nn--;
			}
		}
	}
}

int  Cv7Windows::CallAsFunc(int iMethNum,class CValue & rValue,class CValue * *ppValue)
{
	switch (iMethNum) {
	case methSendCommand:
		{
			WPARAM wParam = ppValue[0]->GetNumeric();
			LPARAM lParam = ppValue[1]->GetNumeric();
			rValue = pMainWindow->SendMessage(WM_COMMAND, wParam, lParam);
			return TRUE;
		}
	case methPostCommand:
		{
			WPARAM wParam = ppValue[0]->GetNumeric();
			LPARAM lParam = ppValue[1]->GetNumeric();
			rValue = pMainWindow->PostMessage(WM_COMMAND, wParam, lParam);
			return TRUE;
		}
	case methGetMenu:
		{
			CMenu* pMenu = pMainWindow->GetMenu();
			MenuToValueList(pMenu, rValue);
			return TRUE;
		}
	case methEnableMenu:
		{
			CString stMenu = ppValue[0]->GetString();
			int flag = ppValue[1]->GetNumeric();

			CMenuManager::Get()->SetEnableMenu(stMenu, flag);
			return TRUE;
		}
	case methVisibleMenu:
		{
			CString stMenu = ppValue[0]->GetString();
			int flag = ppValue[1]->GetNumeric();

			CMenuManager::Get()->SetVisibleMenu(stMenu, flag);
			return TRUE;
		}
	case methGetToolBars:
		{
			CBLContext* pVLCont = CBLContext::CreateInstance("ValueList");
			if(pVLCont)
			{
				int num = pVLCont->FindMethod("AddValue");
				if(num >= 0)
				{
					CString st = "";
					CValue v1;
					CValue v2 = st;
					CValue *pParam[2] = {&v1, &v2};
					CWnd *pWnd = pMainWindow->GetWindow(GW_CHILD);
					while(pWnd)
					{
						CString st = "";
						BOOL vis = FALSE;
						if((CString("CDockBar7") == pWnd->GetRuntimeClass()->m_lpszClassName) ||
							(CString("CControlBar") == pWnd->GetRuntimeClass()->m_lpszClassName))
						{
							CWnd* pChWnd = pWnd->GetWindow(GW_CHILD);
							while(pChWnd)
							{
								pChWnd->GetWindowText(st);
								if(st.IsEmpty())
									st = "Панель окон";

								vis = pChWnd->IsWindowVisible();

								v1 = long(vis);
								v2 = st;

								pVLCont->CallAsProc(num,pParam);

								pChWnd = pChWnd->GetNextWindow();
							}
						}

						pWnd = pWnd->GetNextWindow();
					}
					rValue.AssignContext(pVLCont);
					pVLCont->DecrRef();
				}
			}
			break;
		}
	case methShowToolBar:
		{
			CWnd *pWnd = pMainWindow->GetWindow(GW_CHILD);
			while(pWnd)
			{
				CString st = ppValue[0]->GetString();
				CString stWnd = "";
				BOOL vis = (ppValue[1]->GetNumeric() != 0L);
				if((CString("CDockBar7") == pWnd->GetRuntimeClass()->m_lpszClassName) ||
					(CString("CControlBar") == pWnd->GetRuntimeClass()->m_lpszClassName))
				{
					CWnd* pChWnd = pWnd->GetWindow(GW_CHILD);
					while(pChWnd)
					{
						pChWnd->GetWindowText(stWnd);
						if(stWnd.IsEmpty())
						{
							stWnd = "Панель окон";
							if(st.CompareNoCase(stWnd) == 0)
							{
								if(vis)
									pWnd->ShowWindow(SW_SHOW);
								else
									pWnd->ShowWindow(SW_HIDE);
							}
						}
						else
						if(st == stWnd)
						{
							if(vis)
								pChWnd->ShowWindow(SW_SHOW);
							else
								pChWnd->ShowWindow(SW_HIDE);
						}

//CCustomToolBar7(0x1a8)->SECCustomToolBar(0x1a8)->SECControlBar(0x134)->CControlBar(0x7c)->CWnd(0x40)->CCmdTarget(0x20)->CObject(0x4)->Формы
						pChWnd = pChWnd->GetNextWindow();
					}
				}

				pWnd = pWnd->GetNextWindow();
			}
			pMainWindow->RecalcLayout();
			break;
		}
	case methShowToolBars:
		{
			CWnd *pWnd = pMainWindow->GetWindow(GW_CHILD);
			UINT Style = SW_SHOW;
			if(ppValue[0]->GetNumeric() == 0) Style = SW_HIDE;
			while(pWnd)
			{
				if(CString("CDockBar7") == pWnd->GetRuntimeClass()->m_lpszClassName)
					pWnd->ShowWindow(Style);
				else if(CString("CControlBar") == pWnd->GetRuntimeClass()->m_lpszClassName)
					pWnd->ShowWindow(Style);
				pWnd = pWnd->GetNextWindow();
			}
			pMainWindow->RecalcLayout();
			break;
		}
	case methShowStatusBar:
		{
			CWnd *pWnd = pMainWindow->GetWindow(GW_CHILD);
			UINT Style = SW_SHOW;
			if(ppValue[0]->GetNumeric() == 0) Style = SW_HIDE;
			while(pWnd)
			{
				if(CString("SECStatusBar") == pWnd->GetRuntimeClass()->m_lpszClassName)
					pWnd->ShowWindow(Style);
				pWnd = pWnd->GetNextWindow();
			}
			pMainWindow->RecalcLayout();
			break;
		}
	case methWindowStyle:
		{
			bool current = false;
			CFormAllCtrlsContext* pForm;
			CBLContext* pBLCont = ppValue[0]->GetContext();
			if (pBLCont)
			{
				if(!strcmp(pBLCont->GetRuntimeClass()->m_lpszClassName,"CFormAllCtrlsContext"))
				{
					pForm = (CFormAllCtrlsContext*)pBLCont;
					pForm->IncrRef();
					current = true;
				}
			}

			if(current)
			{
				CGetDoc7* pDoc = (CGetDoc7*)pForm->m_GetDoc;

				if (pDoc->ExistWindow())
				{
// 					POSITION aPOS = ((CDocument*)pDoc)->GetFirstViewPosition();
// 					CWnd* pView = (CWnd*)((CDocument*)pDoc)->GetNextView(aPOS);
					CWnd* pView = GetFormView(pDoc);
					CWnd * pWnd = NULL;
					bool modal = false;
					if(pView == NULL)
					{
						pWnd = pDoc->GetFrame();
						pView = pWnd;
						modal = true;
					}
					else
						pWnd = pView->GetParent();

					if(pWnd)
					{
						UINT curStyle = pWnd->GetStyle();
						DWORD style = ppValue[1]->GetNumeric();
						if(style == 0x01)
						{
							if(modal)
							{
								if(uChildModalWindowStyle != 0) curStyle = uChildModalWindowStyle;
								else uChildModalWindowStyle = curStyle;
							}
							else
							{
								if(uChildWindowStyle != 0) curStyle = uChildWindowStyle;
								else uChildWindowStyle = curStyle;
							}
							curStyle ^= WS_BORDER;
						}
						else if((style == 0x02) && modal)
						{
							if(uChildModalWindowStyle == 0) uChildModalWindowStyle = curStyle;
							curStyle = WS_POPUPWINDOW | WS_VISIBLE;
						}
						else if((style == 0x02) && (!modal))
						{
							if(uChildWindowStyle == 0) uChildWindowStyle = curStyle;
							curStyle = 0x0000C000 | WS_DLGFRAME /*WS_THICKFRAME*/ | WS_VISIBLE | WS_CHILD | WS_CLIPSIBLINGS;
						}
						else if(style == 0x00)
						{
							if(modal)
							{
								if(uChildModalWindowStyle != 0) curStyle = uChildModalWindowStyle;
							}
							else
							{
								if(uChildWindowStyle != 0) curStyle = uChildWindowStyle;
							}

						}
						pWnd->ModifyStyle(0xFFFFFFFF,curStyle,SWP_DRAWFRAME);
					}
					pView->Invalidate();
				}
				pForm->DecrRef();
			}
			else
			{
				UINT curStyle = pMainWindow->GetStyle();
				DWORD style = ppValue[1]->GetNumeric();
				if(style == 0x01)
				{
					if(curStyle != (WS_POPUPWINDOW | WS_VISIBLE))
					{
						if(uMainWindowStyle == 0) uMainWindowStyle = curStyle;
						pMainWindow->ModifyStyle(WS_BORDER,0,SWP_DRAWFRAME);
					}
					else if(uMainWindowStyle != 0)
					{
						pMainWindow->ModifyStyle(0xFFFFFFFF,uMainWindowStyle);
						pMainWindow->ModifyStyle(WS_BORDER,0,SWP_DRAWFRAME);
					}
				}
				else if(style == 0x02)
				{
					if(curStyle != (WS_POPUPWINDOW | WS_VISIBLE))
					{
						if(uMainWindowStyle == 0) uMainWindowStyle = curStyle;
						pMainWindow->ModifyStyle(0xFFFFFFFF,WS_POPUPWINDOW | WS_VISIBLE,SWP_DRAWFRAME);
					}
				}
				else
					if((uMainWindowStyle != 0) && (uMainWindowStyle != curStyle))
						pMainWindow->ModifyStyle(0xFFFFFFFF,uMainWindowStyle,SWP_DRAWFRAME);
			}
			break;
		}
	case methWindowSize:
		{
			bool current = false;
			CFormAllCtrlsContext* pForm;
			CBLContext* pBLCont = ppValue[0]->GetContext();
			BOOL bMDI = (ppValue[4]->GetNumeric() != 0L);
			if(bMDI)
				pBLCont = NULL;

			if (pBLCont)
			{
				if(!strcmp(pBLCont->GetRuntimeClass()->m_lpszClassName,"CFormAllCtrlsContext"))
				{
					pForm = (CFormAllCtrlsContext*)pBLCont;
					pForm->IncrRef();
					current = true;
				}
			}

			if(current)
			{
				CGetDoc7* pDoc = (CGetDoc7*)pForm->m_GetDoc;

				if (pDoc->ExistWindow())
				{
					CWnd * pWnd = NULL;
					pWnd = pDoc->GetFrame();

					/*
					//POSITION aPOS = ((CDocument*)pDoc)->GetFirstViewPosition();
					//CWnd* pView = (CWnd*)((CDocument*)pDoc)->GetNextView(aPOS);
					CWnd* pView = GetFormView(pDoc);
					CWnd * pWnd = NULL;
					bool modal = false;
					if(pView == NULL)
					{
						pWnd = pDoc->GetFrame();
						pView = pWnd;
						modal = true;
					}
					else
						pWnd = pView->GetParent();
					*/

					if(pWnd)
					{
						RECT rect;
						pWnd->GetWindowRect(&rect);
						//if(pWnd->IsKindOf(RUNTIME_CLASS(CGetDlg)))
						//	pMainWindow->ScreenToClient(&rect);
						CWnd * pParent = pWnd->GetParent();
						pParent->ScreenToClient(&rect);

						int w = rect.right - rect.left;
						int h = rect.bottom - rect.top;
						if(ppValue[1]->type == 1)
							if(ppValue[1]->GetNumeric() > 0)
								rect.right = rect.left + ppValue[1]->GetNumeric();
						if(ppValue[2]->type == 1)
							if(ppValue[2]->GetNumeric() > 0)
								rect.bottom = rect.top + ppValue[2]->GetNumeric();
						(*ppValue[1]) = w;
						(*ppValue[2]) = h;
						pWnd->MoveWindow(&rect);
						//if(pWnd->IsKindOf(RUNTIME_CLASS(CGetDlg)))
						//	pWnd->CenterWindow();
					}
				}
				pForm->DecrRef();
			}
			else
			{
				CWnd* pWnd = pMainWindow;
				if(bMDI)
					pWnd = CWnd::FromHandle(pMainWindow->m_hWndMDIClient);

				UINT curStyle = pMainWindow->GetStyle();
				int f = ppValue[3]->GetNumeric();
				if(f == 1)
				{
					if(curStyle != (WS_POPUPWINDOW | WS_VISIBLE))
					{
						if(uMainWindowStyle == 0) uMainWindowStyle = curStyle;
						pMainWindow->ModifyStyle(0xFFFFFFFF,WS_POPUPWINDOW | WS_VISIBLE,SWP_DRAWFRAME);
					}
				}
				else if(f == 2)
					if((uMainWindowStyle != 0) && (uMainWindowStyle != curStyle))
						pMainWindow->ModifyStyle(0xFFFFFFFF,uMainWindowStyle,SWP_DRAWFRAME);
				RECT rect;
				pWnd->GetWindowRect(&rect);
				int w = rect.right - rect.left;
				int h = rect.bottom - rect.top;
				if(ppValue[1]->type == 1)
					if(ppValue[1]->GetNumeric() > 0)
						rect.right = rect.left + ppValue[1]->GetNumeric();
				if(ppValue[2]->type == 1)
					if(ppValue[2]->GetNumeric() > 0)
						rect.bottom = rect.top + ppValue[2]->GetNumeric();
				(*ppValue[1]) = w;
				(*ppValue[2]) = h;
				if(!bMDI)
					pWnd->MoveWindow(&rect);
				if(f != 0)
					pMainWindow->CenterWindow();
			}
			break;
		}
	case methWindowPos:
		{
			bool current = false;
			CFormAllCtrlsContext* pForm;
			CBLContext* pBLCont = ppValue[0]->GetContext();
			if (pBLCont)
			{
				if(!strcmp(pBLCont->GetRuntimeClass()->m_lpszClassName,"CFormAllCtrlsContext"))
				{
					pForm = (CFormAllCtrlsContext*)pBLCont;
					pForm->IncrRef();
					current = true;
				}
			}

			if(current)
			{
				CGetDoc7* pDoc = (CGetDoc7*)pForm->m_GetDoc;

				if (pDoc->ExistWindow())
				{
					CWnd * pWnd = NULL;
					pWnd = pDoc->GetFrame();

					/*
					//POSITION aPOS = ((CDocument*)pDoc)->GetFirstViewPosition();
					//CWnd* pView = (CWnd*)((CDocument*)pDoc)->GetNextView(aPOS);
					CWnd* pView = GetFormView(pDoc);
					CWnd * pWnd = NULL;
					bool modal = false;
					if(pView == NULL)
					{
						pWnd = pDoc->GetFrame();
						pView = pWnd;
						modal = true;
					}
					else
						pWnd = pView->GetParent();
					*/

					if(pWnd)
					{
						RECT rect;
						WINDOWPLACEMENT wp;
						wp.length = sizeof(WINDOWPLACEMENT);
						if(pWnd->GetWindowPlacement(&wp))
							CopyRect(&rect,&(wp.rcNormalPosition));
						else
							pWnd->GetWindowRect(&rect);
						//if(pWnd->IsKindOf(RUNTIME_CLASS(CGetDlg)))
							//pMainWindow->ScreenToClient(&rect);
						//	pWnd->ScreenToClient(&rect);
						//pMainWindow->ScreenToClient(&rect);

						int l = rect.left;
						int t = rect.top;
						if(ppValue[1]->type == 1)
							if(ppValue[1]->GetNumeric() >= 0)
							{
								rect.left = ppValue[1]->GetNumeric();
								rect.right = rect.right - l + rect.left;
							}
						if(ppValue[2]->type == 1)
							if(ppValue[2]->GetNumeric() >= 0)
							{
								rect.top = ppValue[2]->GetNumeric();
								rect.bottom = rect.bottom - t + rect.top;
							}
						(*ppValue[1]) = (long)l;
						(*ppValue[2]) = (long)t;
						//if(pWnd->IsKindOf(RUNTIME_CLASS(CGetDlg)))
						//pMainWindow->ScreenToClient(&rect);
						pWnd->MoveWindow(&rect);
					}
				}
				pForm->DecrRef();
			}
			else
			{
				RECT rect;
				pMainWindow->GetWindowRect(&rect);
				int l = rect.left;
				int t = rect.top;
				if(ppValue[1]->type == 1)
					if(ppValue[1]->GetNumeric() >= 0)
					{
						rect.left = ppValue[1]->GetNumeric();
						rect.right = rect.right - l + rect.left;
					}
				if(ppValue[2]->type == 1)
					if(ppValue[2]->GetNumeric() >= 0)
					{
						rect.top = ppValue[2]->GetNumeric();
						rect.bottom = rect.bottom - t + rect.top;
					}
				(*ppValue[1]) = (long)l;
				(*ppValue[2]) = (long)t;
				pMainWindow->MoveWindow(&rect);
			}
			break;
		}
	case methWindowMenu:
		{
			bool current = false;
			CFormAllCtrlsContext* pForm;
			CBLContext* pBLCont = ppValue[0]->GetContext();
			if (pBLCont)
			{
				if(!strcmp(pBLCont->GetRuntimeClass()->m_lpszClassName,"CFormAllCtrlsContext"))
				{
					pForm = (CFormAllCtrlsContext*)pBLCont;
					pForm->IncrRef();
					current = true;
				}
			}

			if(current)
			{
				CGetDoc7* pDoc = (CGetDoc7*)pForm->m_GetDoc;

				if (pDoc->ExistWindow())
				{
// 					POSITION aPOS = ((CDocument*)pDoc)->GetFirstViewPosition();
// 					CWnd* pView = (CWnd*)((CDocument*)pDoc)->GetNextView(aPOS);
					CWnd* pView = GetFormView(pDoc);
					CWnd * pWnd = NULL;
					bool modal = false;
					if(pView == NULL)
					{
						pWnd = pDoc->GetFrame();
						pView = pWnd;
						modal = true;
					}
					else
						pWnd = pView->GetParent();

					if(pWnd)
					{
						pWnd->GetSystemMenu(TRUE);
						CMenu* pMenu = pWnd->GetSystemMenu(FALSE);
						if(pMenu)
						{
							if(ppValue[1]->GetNumeric() == 0)
								pMenu->DeleteMenu(SC_CLOSE, MF_BYCOMMAND);

							if(ppValue[2]->GetNumeric() == 0)
							{
								pMenu->DeleteMenu(SC_MAXIMIZE, MF_BYCOMMAND);
								pWnd->ModifyStyle(WS_MAXIMIZEBOX,0,SWP_DRAWFRAME);
							}
							else
							{
								pWnd->ModifyStyle(0,WS_MAXIMIZEBOX,SWP_DRAWFRAME);
							}

							if(ppValue[3]->GetNumeric() == 0)
							{
								pMenu->DeleteMenu(SC_MINIMIZE, MF_BYCOMMAND);
								pWnd->ModifyStyle(WS_MINIMIZEBOX,0,SWP_DRAWFRAME);
							}
							else
							{
								pWnd->ModifyStyle(0,WS_MINIMIZEBOX,SWP_DRAWFRAME);
							}

							if(ppValue[4]->GetNumeric() == 0)
								pMenu->DeleteMenu(SC_RESTORE, MF_BYCOMMAND);
						}
						//else pBkEndUI->DoMessageLine("pMenu = NULL");
					}
				}
				pForm->DecrRef();
			}
			else
			{
				pMainWindow->GetSystemMenu(TRUE);
				CMenu* pMenu = pMainWindow->GetSystemMenu(FALSE);
				if(pMenu)
				{
					if(ppValue[1]->GetNumeric() == 0)
						pMenu->DeleteMenu(SC_CLOSE, MF_BYCOMMAND);

					if(ppValue[2]->GetNumeric() == 0)
					{
						pMenu->DeleteMenu(SC_MAXIMIZE, MF_BYCOMMAND);
						pMainWindow->ModifyStyle(WS_MAXIMIZEBOX,0,SWP_DRAWFRAME);
					}
					else
					{
						pMainWindow->ModifyStyle(0,WS_MAXIMIZEBOX,SWP_DRAWFRAME);
					}

					if(ppValue[3]->GetNumeric() == 0)
					{
						pMenu->DeleteMenu(SC_MINIMIZE, MF_BYCOMMAND);
						pMainWindow->ModifyStyle(WS_MINIMIZEBOX,0,SWP_DRAWFRAME);
					}
					else
					{
						pMainWindow->ModifyStyle(0,WS_MINIMIZEBOX,SWP_DRAWFRAME);
					}

					if(ppValue[4]->GetNumeric() == 0)
						pMenu->DeleteMenu(SC_RESTORE, MF_BYCOMMAND);
				}
				//else pBkEndUI->DoMessageLine("pMenu = NULL");
			}
			break;
		}
	case methCenterWindow:
		{
			bool current = false;
			CFormAllCtrlsContext* pForm;
			CBLContext* pBLCont = ppValue[0]->GetContext();
			if (pBLCont)
			{
				if(!strcmp(pBLCont->GetRuntimeClass()->m_lpszClassName,"CFormAllCtrlsContext"))
				{
					pForm = (CFormAllCtrlsContext*)pBLCont;
					pForm->IncrRef();
					current = true;
				}
			}

			if(current)
			{
				CGetDoc7* pDoc = (CGetDoc7*)pForm->m_GetDoc;

				if (pDoc->ExistWindow())
				{
// 					POSITION aPOS = ((CDocument*)pDoc)->GetFirstViewPosition();
// 					CWnd* pView = (CWnd*)((CDocument*)pDoc)->GetNextView(aPOS);
					CWnd* pView = GetFormView(pDoc);
					CWnd * pWnd = NULL;
					bool modal = false;
					if(pView == NULL)
					{
						pWnd = pDoc->GetFrame();
						pView = pWnd;
						modal = true;
					}
					else
						pWnd = pView->GetParent();

					if(pWnd) pWnd->CenterWindow();
				}
				pForm->DecrRef();
			}
			else
			{
				pMainWindow->CenterWindow();
			}
			break;
		}
	case methMaximize:
		{
			bool current = false;
			CFormAllCtrlsContext* pForm;
			CBLContext* pBLCont = ppValue[0]->GetContext();
			if (pBLCont)
			{
				if(!strcmp(pBLCont->GetRuntimeClass()->m_lpszClassName,"CFormAllCtrlsContext"))
				{
					pForm = (CFormAllCtrlsContext*)pBLCont;
					pForm->IncrRef();
					current = true;
				}
			}

			if(current)
			{
				CGetDoc7* pDoc = (CGetDoc7*)pForm->m_GetDoc;

				if (pDoc->ExistWindow())
				{
					CWnd * pWnd = NULL;

					pWnd = pDoc->GetFrame();

					if(pWnd) pWnd->ShowWindow(SW_MAXIMIZE);
				}
				pForm->DecrRef();
			}
			else
			{
				pMainWindow->ShowWindow(SW_MAXIMIZE);
			}
			break;
		}
	case methMinimize:
		{
			bool current = false;
			CFormAllCtrlsContext* pForm;
			CBLContext* pBLCont = ppValue[0]->GetContext();
			if (pBLCont)
			{
				if(!strcmp(pBLCont->GetRuntimeClass()->m_lpszClassName,"CFormAllCtrlsContext"))
				{
					pForm = (CFormAllCtrlsContext*)pBLCont;
					pForm->IncrRef();
					current = true;
				}
			}

			if(current)
			{
				CGetDoc7* pDoc = (CGetDoc7*)pForm->m_GetDoc;

				if (pDoc->ExistWindow())
				{
					CWnd * pWnd = NULL;
					pWnd = pDoc->GetFrame();

					if(pWnd) pWnd->ShowWindow(SW_MINIMIZE);
				}
				pForm->DecrRef();
			}
			else
			{
				pMainWindow->ShowWindow(SW_MINIMIZE);
			}
			break;
		}
	case methRestore:
		{
			bool current = false;
			CFormAllCtrlsContext* pForm;
			CBLContext* pBLCont = ppValue[0]->GetContext();
			if (pBLCont)
			{
				if(!strcmp(pBLCont->GetRuntimeClass()->m_lpszClassName,"CFormAllCtrlsContext"))
				{
					pForm = (CFormAllCtrlsContext*)pBLCont;
					pForm->IncrRef();
					current = true;
				}
			}

			if(current)
			{
				CGetDoc7* pDoc = (CGetDoc7*)pForm->m_GetDoc;

				if (pDoc->ExistWindow())
				{
					CWnd * pWnd = NULL;
					pWnd = pDoc->GetFrame();

					if(pWnd) pWnd->ShowWindow(SW_RESTORE);
				}
				pForm->DecrRef();
			}
			else
			{
				pMainWindow->ShowWindow(SW_RESTORE);
			}
			break;
		}
	case methSetFocus:
		{
			bool current = false;
			CFormAllCtrlsContext* pForm;
			CBLContext* pBLCont = ppValue[0]->GetContext();
			if (pBLCont)
			{
				if(!strcmp(pBLCont->GetRuntimeClass()->m_lpszClassName,"CFormAllCtrlsContext"))
				{
					pForm = (CFormAllCtrlsContext*)pBLCont;
					pForm->IncrRef();
					current = true;
				}
			}

			if(current)
			{
				CGetDoc7* pDoc = (CGetDoc7*)pForm->m_GetDoc;

				if (pDoc->ExistWindow())
				{
// 					POSITION aPOS = ((CDocument*)pDoc)->GetFirstViewPosition();
// 					CWnd* pView = (CWnd*)((CDocument*)pDoc)->GetNextView(aPOS);
					CWnd* pView = GetFormView(pDoc);
					CWnd * pWnd = NULL;
					bool modal = false;
					if(pView == NULL)
					{
						pWnd = pDoc->GetFrame();
						pView = pWnd;
						modal = true;
					}
					else
						pWnd = pView->GetParent();

					if(pWnd)
					{
						pWnd->SetFocus();
					}
				}
				pForm->DecrRef();
			}
			else
			{
				pMainWindow->SetFocus();
			}
			break;
		}
	case methUpdateWindow:
		{
			bool current = false;
			CFormAllCtrlsContext* pForm;
			CBLContext* pBLCont = ppValue[0]->GetContext();
			if (pBLCont)
			{
				if(!strcmp(pBLCont->GetRuntimeClass()->m_lpszClassName,"CFormAllCtrlsContext"))
				{
					pForm = (CFormAllCtrlsContext*)pBLCont;
					pForm->IncrRef();
					current = true;
				}
			}

			if(current)
			{
				CGetDoc7* pDoc = (CGetDoc7*)pForm->m_GetDoc;

				if (pDoc->ExistWindow())
				{
// 					POSITION aPOS = ((CDocument*)pDoc)->GetFirstViewPosition();
// 					CWnd* pView = (CWnd*)((CDocument*)pDoc)->GetNextView(aPOS);
					CWnd* pView = GetFormView(pDoc);
					CWnd * pWnd = NULL;
					bool modal = false;
					if(pView == NULL)
					{
						pWnd = pDoc->GetFrame();
						pView = pWnd;
						modal = true;
					}
					else
						pWnd = pView->GetParent();

					if(pWnd)
					{
						pWnd->UpdateData();
						pWnd->UpdateWindow();
						pWnd->Invalidate();
						pWnd->RedrawWindow();
					}
				}
				pForm->DecrRef();
			}
			else
			{
				pMainWindow->UpdateData();
				pMainWindow->UpdateWindow();
				pMainWindow->Invalidate();
				pMainWindow->RedrawWindow();
			}
			break;
		}
	case methBringWindowToTop:
		{
			bool current = false;
			CFormAllCtrlsContext* pForm;
			CBLContext* pBLCont = ppValue[0]->GetContext();
			if (pBLCont)
			{
				if(!strcmp(pBLCont->GetRuntimeClass()->m_lpszClassName,"CFormAllCtrlsContext"))
				{
					pForm = (CFormAllCtrlsContext*)pBLCont;
					pForm->IncrRef();
					current = true;
				}
			}

			if(current)
			{
				CGetDoc7* pDoc = (CGetDoc7*)pForm->m_GetDoc;

				if (pDoc->ExistWindow())
				{
// 					POSITION aPOS = ((CDocument*)pDoc)->GetFirstViewPosition();
// 					CWnd* pView = (CWnd*)((CDocument*)pDoc)->GetNextView(aPOS);
					CWnd* pView = GetFormView(pDoc);
					CWnd * pWnd = NULL;
					bool modal = false;
					if(pView == NULL)
					{
						pWnd = pDoc->GetFrame();
						pView = pWnd;
						modal = true;
					}
					else
						pWnd = pView->GetParent();

					if(pWnd) pWnd->BringWindowToTop();
				}
				pForm->DecrRef();
			}
			else
			{
				pMainWindow->BringWindowToTop();
			}
			break;
		}
	case methGetResolution:
		{
			(*ppValue[0]) = ::GetSystemMetrics(SM_CXSCREEN);
			(*ppValue[1]) = ::GetSystemMetrics(SM_CYSCREEN);
			break;
		}
	case methBeginModalState:
		{
			CInitFormEx::Get().SetSystemTopmostModalState(TRUE);
			break;
		}
	case methEndModalState:
		{
			CInitFormEx::Get().SetSystemTopmostModalState(FALSE);
			break;
		}

	case methCloseWindow:
		{
			rValue = funcCloseWindow(*ppValue[0], *ppValue[1]);
			break;
		}
	default:
		return FALSE;
	};
	return TRUE;
}

/*
					//CCustomToolBar7 SECCustomToolBar
					CWnd* pWndBtn = pWnd->GetWindow(GW_CHILD);
					while(pWndBtn)
					{
						if(CString("CCustomToolBar7") == pWndBtn->GetRuntimeClass()->m_lpszClassName)
						{
							SECCustomToolBar* pToolBar = (SECCustomToolBar*)pWndBtn;
							int cToolBtn = pToolBar->GetBtnCount();
							CString stDeb1 = "";
							for(int f = 0; f < cToolBtn; f++)
							{
								UINT styleBtn = pToolBar->GetButtonStyle(f);
								UINT idBnt = pToolBar->GetItemID(f);
								stDeb1.Format("Style = %x ID = %x",styleBtn,idBnt);
								if(idBnt == MenuItemInfo.wID)
								{
									pBkEndUI->DoMessageLine(stDeb1);
									if(uStyle)
										styleBtn |= 0x00040000;
									else
										styleBtn |= 0x00040000;
									pToolBar->SetButtonStyle(f,styleBtn);
									pToolBar->RedrawWindow();
								}
							}
						}
						pWndBtn = pWndBtn->GetNextWindow();
					}
*/

int  Cv7Windows::CallAsProc(int iMethNum,class CValue * * ppValue)
{
	switch (iMethNum) {
	case methMinimizeToTray:
		{
			int param = ppValue[0]->GetNumeric();
			if(param == 1)
				CTrayIconManager::Get()->EnableMinimizeToTray();
			else if(param == 0)
				CTrayIconManager::Get()->DisableMinimizeToTray();
			break;
		}
	case methCloseAllWindows:
		{
			procCloseAllWindows(*ppValue[0]);
			break;
		}
	case methGetTextSize:
		{
			CString csBuf = ppValue[0]->GetString();

			HFONT font = (HFONT)(UINT)ppValue[1]->GetNumeric();
			if(!font)
			{
				CApp7* pApp7 = (CApp7*) AfxGetApp();
				CProfile7* pProfile7 = pApp7->GetProps();
				font = pProfile7->GetHFONTProp(0x2C);
			}
			/*
			CDC* pDC = CWnd::GetDesktopWindow()->GetDC();
			CFont* pFont = CFont::FromHandle(font);

			CFont* pOldFont = pDC->SelectObject(pFont);
			CSize sz = pDC->GetTextExtent(csBuf);
			(*ppValue[2]) = sz.cx;
			(*ppValue[3]) = sz.cy;

			pDC->SelectObject(pOldFont);
			*/
			SIZE sz;
			HDC hdc = GetDC(NULL);
			SelectObject(hdc, font);

			GetTextExtentPoint32(hdc, csBuf,csBuf.GetLength(), &sz);
			ReleaseDC(NULL, hdc);

			(*ppValue[2]) = sz.cx;
			(*ppValue[3]) = sz.cy;
			break;
		}
	default:
		return FALSE;
	};
	return TRUE;
}


int  Cv7Windows::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 *  Cv7Windows::GetMethodName(int iMethodNum,int iMethodAlias)const
{
	if ((iMethodNum>=0) && (iMethodNum<lastMethod))
		return defFnNames[iMethodNum].Names[iMethodAlias];
	return NULL;
}

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

int  Cv7Windows::HasRetVal(int iMethodNum)const
{
	if ((iMethodNum>=0) && (iMethodNum<lastMethod))
		return defFnNames[iMethodNum].HasReturnValue;
	return FALSE;
}

int Cv7Windows::GetNParams(int iMethodNum)const
{
	if ((iMethodNum>=0) && (iMethodNum<lastMethod))
		return defFnNames[iMethodNum].NumberOfParams;
	return 0;
}

int  Cv7Windows::GetParamDefValue(int iMethodNum,int iParamNum,class CValue * pDefValue)const
{
	switch (iMethodNum)
	{
	case methGetResolution:
		{
			switch (iParamNum)
			{
			case 0:
				*pDefValue = -1L;
				break;
			case 1:
				*pDefValue = -1L;
				break;
			default:
				return FALSE;
			}
			break;
		}
	case methWindowStyle:
	case methCenterWindow:
	case methMaximize:
	case methMinimize:
	case methRestore:
	case methUpdateWindow:
	case methSetFocus:
	case methBringWindowToTop:
		{
			switch (iParamNum)
			{
			case 0:
				*pDefValue = 0L;
				break;
			default:
				return FALSE;
			}
			break;
		}
	case methWindowSize:
	case methWindowPos:
		{
			switch (iParamNum)
			{
			case 0:
				*pDefValue = 0L;
				break;
			case 1:
			case 2:
				*pDefValue = -1L;
				break;
			case 3:
				*pDefValue = 0L;
				break;
			case 4:
				*pDefValue = 0L;
				break;
			default:
				return FALSE;
			}
			break;
		}
	case methWindowMenu:
		{
			switch (iParamNum)
			{
			case 0:
				*pDefValue = 0L;
				break;
			case 1:
			case 2:
			case 3:
			case 4:
				*pDefValue = 1L;
				break;
			default:
				return FALSE;
			}
			break;
		}
	
	case methCloseWindow:
		{
			if (1 == iParamNum){
 				*pDefValue = 0L;
				return TRUE;
			}
			return FALSE;
		}
	case methCloseAllWindows:
		{
			*pDefValue = -1;
			break;
		}
	case methGetTextSize:
		{
			if (1 == iParamNum){
 				*pDefValue = 0L;
				return TRUE;
			}
			return FALSE;
		}
	default:
		return FALSE;
	}
	return TRUE;
}

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

char const *  Cv7Windows::GetCode(void)const
{
	return NULL;
}

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

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

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

class CBLContextInternalData *  Cv7Windows::GetInternalData(void)
{
	return CBLContext::GetInternalData();
}

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

char const *  Cv7Windows::GetTypeString(void)const
{
	return "Окна";
}

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

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

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

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

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

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

int  Cv7Windows::IsPropReadable(int iPropNum)const
{
	return TRUE;
}

int  Cv7Windows::IsPropWritable(int iPropNum)const
{
	return TRUE;
}

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

int  Cv7Windows::SaveToString(class CString & csStr)
{
	csStr = "";
	return TRUE;
}

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

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

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

int  Cv7Windows::GetPropVal(int iPropNum,class CValue & rValue)const
{
	return FALSE;
}

int  Cv7Windows::SetPropVal(int iPropNum,class CValue const & vValue)
{
	return FALSE;
}

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

// с отработкой всех необходимых событий по закрытию окна - например, ПриЗакрытии
BOOL Cv7Windows::CloseWindow(CGroupContext* pGroupCont, int NumericValue)
{
	CGetDoc7* pDoc = GetDoc7(pGroupCont);
	if(!pDoc)
		return FALSE;

	if (!NumericValue)
		// TODO возможно, первый параметр должен быть другим числом, 
		// но у меня ни на тестах, ни в реальной базе не падает
		pDoc->SetWantClose(0, 1); // не задавать вопросов при закрытии несохраненных документов/элементов справочников
	
	// нужно самостоятельно обнулить все ссылки на КонтекстФормы.Форма (1С этого почему-то не делает)
	// иначе если сохранить его в отдельной переменной до закрытия, 
	// а потом пытаться использовать после физического закрытия - будет баг
	// также 1С будет падать, если эту переменную передать 
	// в какой-нибудь метод любой ВК, которая принимает форму
	// например, АктивИкс.УстановитьАтрибут или Форма.УстановитьФорму

	CFormAllCtrlsContext* pForm = GetFormContext(pGroupCont);
	if (!pForm)
		return TRUE;
	
	CValuePtrArray& CValueArray = pForm->m_Array;
	for(int i = 0; i < CValueArray.GetSize(); ++i)
	{
		CValue* pValue = CValueArray.GetAt(i);
		pValue->Reset();
	}

	// мой вариант artbear
	pDoc->GetFrame()->SendMessage(WM_CLOSE, 0, 0);

	return TRUE;
}

// почти полный аналог аналогичной функции CSystem::funcCloseForm из 1С++
BOOL Cv7Windows::funcCloseWindow(const CValue& GroupContValue, const CValue& NumericValue)
{
	ValidateParamGroupContext(GroupContValue, "Нужно передавать групповой контекст");
	ValidateParamNumeric(NumericValue, "Нужно передать число");
	
	CGroupContext* pGroupCont = static_cast<CGroupContext*>(GroupContValue.GetContext());
	CloseWindow(pGroupCont, NumericValue.GetNumeric());
	
	return TRUE;
}

void Cv7Windows::procCloseAllWindows(const CValue& ValueTimeout)
{
	// закрываем модальные окна
	CGetDoc7* pDoc7 = NULL;
	while (pDoc7 = CGetDlg::GetTopmostDocunent())
	{
		CWnd* pDlg = pDoc7->GetFrame();
		if(pDlg)
			pDlg->SendMessage(WM_CLOSE);
		else
			break;
	}
	// закрываем обычные дочерние окна
	CMDIFrameWnd* pMainFrameWnd = GetMainFrame();
	if(pMainFrameWnd == NULL) return;
	CWnd* wndMDIClient = CWnd::FromHandle(pMainFrameWnd->m_hWndMDIClient);
	if(wndMDIClient == NULL) return;
	//CWnd* pChildWnd = wndMDIClient->GetWindow(GW_CHILD);

	CInitFormEx::Get().GetModalWindowTimers().SetAutoKillTimers(ValueTimeout);

	// TODO - нужен функционал запрет закрытия некоторых окон !!

	// 	{
	// 		CMDIChildWnd * pChild = pMainFrameWnd->MDIGetActive();
	// 		while(pChild)
	// 		{
	// 			CDocument* pDoc = pChild->GetActiveDocument();
	// 			if(IS_KINDOF_RUNTIME_CLASS(pDoc, CGetDoc7)){
	// 				CGetDoc7* pDoc7 = static_cast<CGetDoc7*>(pDoc);
	// 				CGroupContext* pGroupContext = pDoc7->m_pGroupContext;
	// 				CloseWindow(pGroupContext);
	// 			}
	// 			CMDIChildWnd * const pNextChild = pMainFrameWnd->MDIGetActive();
	// 			if (pNextChild == pChild )
	// 				break; // неудача
	// 			
	// 			pChild = pNextChild;
	// 		}
	// 
	// 	}

	CWnd* pChildWnd = wndMDIClient->GetWindow(GW_CHILD);
	while(pChildWnd)
	{
		CWnd* pNextChild = pChildWnd->GetNextWindow();
		pChildWnd->SendMessage(WM_CLOSE);
		pChildWnd = pNextChild;
	}

	CInitFormEx::Get().GetModalWindowTimers().RestoreAutoKillTimers();
}

CMenuManager::CMenuManager()
{
	
}

CMenuManager::~CMenuManager()
{
	int n = tempMenus.GetSize();
	for(int i = 0; i < n; i++)
	{
		CMenu *pMenuT = CMenu::FromHandle((HMENU)tempMenus.GetAt(i));
		if(pMenuT) pMenuT->DestroyMenu();
	}

	srcMenus.RemoveAll();
	tempMenus.RemoveAll();
	unvisibleMenus.RemoveAll();
	unenableMenus.RemoveAll();
}

void CMenuManager::MakeSystemMessages( HWND hwnd, UINT message, LPARAM lParam, WPARAM wParam )
{
	switch (message)
	{
		case WM_INITMENUPOPUP:
			{
				CWnd* pWnd = CWnd::FromHandle(hwnd);
				if(pWnd)
				{
					CMenu *pMenuSys = pWnd->GetSystemMenu(FALSE);
					if(!pMenuSys) return;
					if(pMenuSys->GetSafeHmenu() != (HMENU)wParam)
					{
						CMenu *pMenu = CMenu::FromHandle((HMENU)wParam);
						if(pMenu)
						{
							/*
							//pBkEndUI->DoMessageLine("WM_INITMENUPOPUP");
							CBLContext* pVLCont = CBLContext::CreateInstance("ValueList");
							if(pVLCont)
							{
								CValue vMenu;
								MenuToValueList(pMenu, vMenu);
								if(pGlobalModuleFormEx)
								{
									int iStatusCode = pGlobalModuleFormEx->GetStatusCode();
									pGlobalModuleFormEx->SetStatusCode(1);

									CString strWParam = "";
									strWParam.Format("%08x", wParam);

									CString strLParam = "";
									strLParam.Format("%08x", lParam);

									CValue vWParam = strWParam;
									CValue vLParam = strLParam;
									CValue FlagDoSystemHandlerValue = 1;
									CValue vContext;

									if(pWnd->IsKindOf(RUNTIME_CLASS(CMDIChildWnd)))
									{
										CMDIChildWnd * pChild = (CMDIChildWnd*)pWnd;
										CDocument* pDoc = pChild->GetActiveDocument();
										if(pDoc)
										{
											if(pDoc->IsKindOf(RUNTIME_CLASS(CGetDoc7)))
											{
												CGroupContext *pCont = ((CGetDoc7*)pDoc)->GetGroupContext();
												if(pCont)
												{
													pCont->IncrRef();
													vContext.AssignContext(pCont);
												}
											}
										}
									}
									else
										pBkEndUI->DoMessageLine(PrintRTC(pWnd));

									CValue *lArray[5] = {&vWParam, &vLParam, &vContext, &vMenu, &FlagDoSystemHandlerValue};
										
									CEventsManager::GetManager().SendEventToGlobalModules(meOnInitMenu, lArray);
									
									bool bFSO = FlagDoSystemHandlerValue.GetNumeric() != 0;

									pGlobalModuleFormEx->SetStatusCode(iStatusCode);
								}
							}
							*/

							int n = unvisibleMenus.GetSize();
							if(n > 0)
							{
								CMenu cMenu;
								cMenu.CreatePopupMenu();
								CopyMenu(pMenu,&cMenu);
								tempMenus.Add((DWORD)cMenu.Detach());
								srcMenus.Add((DWORD)wParam);

								for(int i = 0; i < n; i++)
								{
									CString st = unvisibleMenus.GetAt(i);
									if(st != "")
									{
										int nn = pMenu->GetMenuItemCount();
										for(int f = 0; f < nn; f++)
										{
											CString stMenu = "";
											pMenu->GetMenuString(f,stMenu,MF_BYPOSITION);
											if(stMenu == st)
											{
												pMenu->DeleteMenu(f,MF_BYPOSITION);
												f--; nn--;
											}
										}
									}
								}
								int nn = pMenu->GetMenuItemCount();
								bool IsLastSep = true;
								for(int f = 0; f < nn; f++)
								{
									UINT uMenuState = pMenu->GetMenuState(f,MF_BYPOSITION);
									if(uMenuState == MF_SEPARATOR)
									{
										if(IsLastSep)
										{
											pMenu->DeleteMenu(f,MF_BYPOSITION);
											f--; nn--;
										}
										else
											IsLastSep = true;
									}
									else
										IsLastSep = false;
								}
								nn = pMenu->GetMenuItemCount();
								if(IsLastSep && (nn > 0))
									pMenu->DeleteMenu(nn-1,MF_BYPOSITION);
							}
						}
					}
				}
				break;
			}
		case WM_UNINITMENUPOPUP:
			{
				CWnd* pWnd = CWnd::FromHandle(hwnd);
				if(pWnd)
				{
					CMenu *pMenuSys = pWnd->GetSystemMenu(FALSE);
					if(!pMenuSys) return;
					if(pMenuSys->GetSafeHmenu() != (HMENU)wParam)
					{
						CMenu *pMenu = CMenu::FromHandle((HMENU)wParam);
						if(pMenu)
						{
							int n = srcMenus.GetSize();
							int p = -1;
							for(int i = 0; i < n; i++)
								if(srcMenus.GetAt(i) == wParam) p = i;

							if(p >= 0)
							{
								CMenu *pMenuT = CMenu::FromHandle((HMENU)tempMenus.GetAt(p));
								if(pMenuT)
								{
									if(int(pMenu->GetMenuItemCount()) >= 0)
									{
										while(pMenu->GetMenuItemCount() && pMenu->DeleteMenu(0,MF_BYPOSITION));
										CopyMenu(pMenuT,pMenu);
									}
									tempMenus.RemoveAt(p);
									srcMenus.RemoveAt(p);
									pMenuT->DestroyMenu();
								}
							}
						}
					}
				}
				break;
			}
	} // switch

}

void CMenuManager::MakeSystemMessages_Post( HWND hwnd, UINT message, LPARAM lParam, WPARAM wParam )
{
	switch (message)
	{
	case WM_INITMENUPOPUP:
		{
			CMenu *pMenu = CMenu::FromHandle((HMENU)wParam);
			if(pMenu)
			{
				int n = unenableMenus.GetSize();
				for(int i = 0; i < n; i++)
				{
					CString st = unenableMenus.GetAt(i);
					int nn = pMenu->GetMenuItemCount();
					for(int f = 0; f < nn; f++)
					{
						CString stMenu = "";
						pMenu->GetMenuString(f,stMenu,MF_BYPOSITION);
						if(stMenu == st)
							pMenu->EnableMenuItem(f,MF_BYPOSITION | MF_GRAYED | MF_DISABLED);
					}
				}
			}
			return;
		}
	}
}

void CMenuManager::SetVisibleMenu(const CString& stMenu, int flag)
{
	if(flag == 0)
	{
		bool add = true;
		int n = unvisibleMenus.GetSize();
		for(int i = 0; i < n; i++)
			if(unvisibleMenus.GetAt(i) == stMenu)
			{
				add = false;
				//break;
			}
			if(add) unvisibleMenus.Add(LPCTSTR(stMenu));
	}
	else
	{
		int n = unvisibleMenus.GetSize();
		for(int i = 0; i < n; i++)
			if(unvisibleMenus.GetAt(i) == stMenu)
			{
				unvisibleMenus.RemoveAt(i);
				i--;n--;
			}
	}
	
	CMenu7* pMenu1 = (CMenu7*)(((DWORD*)pApp)+0x66);
	CMenu7* pMenu2 = (CMenu7*)(((DWORD*)pApp)+0x68);
	CMenu* pMenu = pMainWindow->GetMenu();
	SetVisibleMainMenu(pMenu1);
	SetVisibleMainMenu(pMenu2);
	SetVisibleMainMenu(pMenu);
	
	pMainWindow->DrawMenuBar();
}

void CMenuManager::SetEnableMenu(const CString& stMenu, int flag)
{
	if(flag == 0)
	{
		bool add = true;
		int n = unenableMenus.GetSize();
		for(int i = 0; i < n; i++)
			if(unenableMenus.GetAt(i) == stMenu)
			{
				add = false;
				//break;
			}
			if(add) unenableMenus.Add(LPCTSTR(stMenu));
	}
	else
	{
		int n = unenableMenus.GetSize();
		for(int i = 0; i < n; i++)
			if(unenableMenus.GetAt(i) == stMenu)
			{
				unenableMenus.RemoveAt(i);
				i--;n--;
			}
	}
	
	UINT Style = 0;
	if(flag == 0) Style = MF_GRAYED | MF_DISABLED;
	CString st = "";
	st = stMenu;
	CMenu7* pMenu1 = (CMenu7*)(((DWORD*)pApp)+0x66);
	CMenu7* pMenu2 = (CMenu7*)(((DWORD*)pApp)+0x68);
	CMenu* pMenu = pMainWindow->GetMenu();
	
	SetMenuItemStyle(pMenu,st,Style);
	SetMenuItemStyle(pMenu1,st,Style);
	SetMenuItemStyle(pMenu2,st,Style);
	pMainWindow->DrawMenuBar();
}

void CopyMenu(CMenu* pMenuSrc, CMenu* pMenuDes, bool f)
{
	if(pMenuSrc)
	{
		CMenu7::AddSMenu(pMenuSrc, pMenuDes);
		if(f)
		{
			int n = pMenuDes->GetMenuItemCount();
			for(int i = 0; i < n; i++)
			{
				CMenu* pNextMenu = pMenuDes->GetSubMenu(i);
				if(pNextMenu)
					CMenu7::SetOwnerDraw(pNextMenu,0,1);
			}
		}
		else
			CMenu7::SetOwnerDraw(pMenuDes,0,1);
	}
}
