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

#include "stdafx.h"
#include "sizecbar.h"

extern CBkEndUI * pBkEndUI;
extern DWORD myPlatformId;
extern HHOOK MouseHookHandle;
extern HHOOK HookHandle;
extern HHOOK WndHookHandle;
extern HHOOK WndPreHookHandle;
extern CDWordArray srcMenus;
extern CDWordArray tempMenus;
extern CStringArray unvisibleMenus;
extern CStringArray unenableMenus;
extern class CMDIFrameWnd * pMainWindow;
extern CWinApp* pApp;
extern bool bMinimizeToTray;
bool bStopHook = false;

BOOL bTrayIconVisible;
extern NOTIFYICONDATA	nidIconData;

CMapStringToPtr cModuleMap;

CString PrintRTC(CRuntimeClass* pClass)
{
	CString txt;
	CString adr;
	while(pClass)
	{
		adr.Format("(0x%x)",pClass->m_nObjectSize);
		txt=txt+pClass->m_lpszClassName+adr+"->";
		//pClass=(*pClass->m_pfnGetBaseClass)();
		pClass=pClass->m_pfnGetBaseClass();
	}
	return txt;
}

CString PrintRTC(CObject* pObj)
{
	if(!pObj)
		return "";
	return PrintRTC(pObj->GetRuntimeClass());
}

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);
	}
}

int GetProcNumFromModule(CBLModule *pMod, const char* nameProc0, const char* nameProc1, int& type, int& numarg)
{

	CString strID;
	long longID;
	((CBLModule7*)pMod)->GetID(strID, longID);

// artbear исправление бага 2503
// http://cvs.alterplast.ru/bugs/show_bug.cgi?id=2503
// если делать кеш по типу формы, тогда получается конфликт с ТурбоМД :(
/*
	CString ID = "";
	ID.Format("%s/%d/%d", strID, longID, pMod->GetLoadedID());


>> 18.08.2006 16:55:12 artbear wrote:
>> как определить, что модуль формы изменился?

>> 18.08.2006 16:56:22 orefkov wrote:
>> Не надо определять, что он изменился.
>> Надо делать кэш не для каждого ТИПА форм, а для каждого ЭКЗЕМПЛЯРА форм.

>> 18.08.2006 16:56:53 artbear wrote:
>> ладно, а чем отличаются две формы? какой параметр для них уникален?

>> 18.08.2006 16:57:49 orefkov wrote:
>> Уникален указатель на модуль
*/
	CString ID = "";
	ID.Format("%d", pMod);

//end
	CModuleInfoFormEx* pModuleInfo;
	if(!cModuleMap.Lookup(ID, (void *&)pModuleInfo))
	{
		pModuleInfo = new CModuleInfoFormEx;
		cModuleMap.SetAt(ID, pModuleInfo);
	}

	CProcInfoFormEx* pProcInfo = NULL;
	if((longID == -1) || (!pModuleInfo->cProcMap.Lookup(nameProc0, (void *&)pProcInfo)))
	{
		if(pProcInfo == NULL)
		{
			pProcInfo = new CProcInfoFormEx;
			pProcInfo->num = -1;
			pProcInfo->type = 0;
			pProcInfo->numarg = 0;
		}

		int r = pMod->FindProc(nameProc0,0);
		if(r<0)
		{
			r = pMod->FindProc(nameProc1,0);
			if(r<0)
			{
				r = pMod->FindFunc(nameProc0);
				if(r<0)
				{
					r = pMod->FindFunc(nameProc1);
				}
			}
		}
		if(r>=0)
		{
			CBLProcInfo cblProcInfo;
			if(pMod->GetProcInfo(r,cblProcInfo))
			{
				pProcInfo->num = r;
				pProcInfo->type = cblProcInfo.GetType();
				pProcInfo->numarg = cblProcInfo.GetNParams();
			}
		}

		pModuleInfo->cProcMap.SetAt(nameProc0, pProcInfo);
	}
	type = pProcInfo->type;
	numarg = pProcInfo->numarg;
	int ret = pProcInfo->num;

	return ret;
}

BOOL _CallFromGlobalModules(CGroupContext *pCont, CBLModule *pMod, const char* nameProc0, const char* nameProc1, int argNum, CValue** vArray, bool bCallSysProc)
{

	ULONG id = CBLModule::GetFirstLoadedModuleID(); //CBLModule7
	bool f = (id != 0);

	int r = -1;
	CBLModule7* pGlobalModule = GetGlobalModule();

	BOOL result = FALSE;
	int type;
	int numarg;

	while(f)
	{
		pMod = CBLModule::GetLoadedModule(id);
		if(pMod)
		{
			r = GetProcNumFromModule(pMod, nameProc0, nameProc1, type, numarg);
			if(r>=0)
			{
				CBLProcInfo blProcInfo;
				pMod->GetProcInfo(r, blProcInfo);

				if(pGlobalModule)
				if(pGlobalModule != pMod)
					((CBLModule7*)pMod)->SetStatusCode(pGlobalModule->GetStatusCode());

				int GLargNum = argNum;
				int s = 0;

				CValue p1, p2, p3, p4, p5, p6, p7, p8, p9, p10;
				CValue *vArrayGl[10] = {&p1, &p2, &p3, &p4, &p5, &p6, &p7, &p8, &p9, &p10};
				if(pCont)
				{
					vArrayGl[0]->AssignContext(pCont);
					s = 1;
					GLargNum++;
				}
				for(int i = 0; i<argNum; i++)
					*vArrayGl[i + s] = *vArray[i];

				for(i = GLargNum; i<numarg; i++)
					*vArrayGl[i + s] = *vArray[i];

				int t = type;
				if(bCallSysProc)
				{
					GLargNum = numarg;
					if(t == 1)
					{
						if(pMod->CallAsProc(r,GLargNum,vArray))
							result = TRUE;
					}
					else
					{
						CValue arValue;
						if(pMod->CallAsFunc(r,arValue,GLargNum,vArray))
							result = TRUE;
					}
				}
				else
				{
					if(numarg < GLargNum) GLargNum = numarg;
					if(t == 1)
					{
						if(pMod->CallAsProc(r,GLargNum,vArrayGl))
							result = TRUE;
					}
					else
					{
						CValue arValue;
						if(pMod->CallAsFunc(r,arValue,GLargNum,vArrayGl))
							result = TRUE;
					}
					if(pCont)
					{
						for(int i = 0; i<argNum; i++)
							*vArray[i] = *vArrayGl[i+1];
					}
					else
						for(int i = 0; i<argNum; i++)
							*vArray[i] = *vArrayGl[i];
				}
				
				if(pGlobalModule)
				if(pGlobalModule->GetStatusCode())
					pGlobalModule->SetStatusCode(((CBLModule7*)pMod)->GetStatusCode());
			}
		}
		id = CBLModule::GetNextLoadedModuleID(id);
		f = (id != 0);
	}
	return result;
}

void _CallModuleProc(class CGetDoc7* pDoc, const char* nameProc0,const  char* nameProc1, int argNum, CValue** vArray, BOOL bCallGlobal)
{
	if(pDoc)
	{
		CGroupContext *pCont = pDoc->GetGroupContext();
		if(pCont)
		{
			CBLContext *pCont0;
			for(int i = 0; i<pCont->GetSize(); i++)
			{
				pCont0 = pCont->GetContext(i);
				if(!strcmp(pCont0->GetRuntimeClass()->m_lpszClassName,"CDocContext"))
					((CDocContext*)pCont0)->SetEnableNewLine(1);
			}
			//CBLModule7 * pMod = (CBLModule7*)GetModuleByContext(pCont); //WM_CLOSE
			CBLModule7 * pMod = pDoc->m_pBLModule;
			pCont->Accept();
			int r = -1;
			if(pMod)
			{
				int type;
				int numarg;
				r = GetProcNumFromModule(pMod, nameProc0, nameProc1, type, numarg);
				if(r>=0)
				{
					if(numarg < argNum) argNum = numarg;
					int t = type;

					pDoc->OnStartBatch();
					if(t == 1)
					{
						pMod->CallAsProc(r,argNum,vArray);
					}
					else
					{
						CValue arValue;
						pMod->CallAsFunc(r,arValue,argNum,vArray);
					}
					pDoc->OnEndBatch(0);
					CBLContext *pCont0;
					for(int i = 0; i<pCont->GetSize(); i++)
					{
						pCont0 = pCont->GetContext(i);
						if(!strcmp(pCont0->GetRuntimeClass()->m_lpszClassName,"CDocContext"))
							((CDocContext*)pCont0)->SetEnableNewLine(1);
					}
				}
			}
			if(bCallGlobal)
				_CallFromGlobalModules(pCont, NULL, nameProc0, nameProc1, argNum, vArray);
		}
		else if(bCallGlobal)
		{
			CValue p1, p2, p3, p4, p5, p6, p7, p8, p9, p10;
			CValue *vArrayGl[10] = {&p1, &p2, &p3, &p4, &p5, &p6, &p7, &p8, &p9, &p10};
			for(int i = 0; i<argNum; i++)
				*vArrayGl[i+1] = *vArray[i];
			_CallFromGlobalModules(NULL, NULL, nameProc0, nameProc1, argNum+1, vArrayGl);
			for(i = 0; i<argNum; i++)
				*vArray[i] = *vArrayGl[i+1];
		}
	}
	else if(bCallGlobal)
	{
		CValue p1, p2, p3, p4, p5, p6, p7, p8, p9, p10;
		CValue *vArrayGl[10] = {&p1, &p2, &p3, &p4, &p5, &p6, &p7, &p8, &p9, &p10};
		for(int i = 0; i<argNum; i++)
			*vArrayGl[i+1] = *vArray[i];
		_CallFromGlobalModules(NULL, NULL, nameProc0, nameProc1, argNum+1, vArrayGl);
		for(i = 0; i<argNum; i++)
			*vArray[i] = *vArrayGl[i+1];
	}
}

void CallModuleProc(const char* nameProc0,const  char* nameProc1, int argNum, CValue** vArray)
{
	CMDIFrameWnd * pMainFrame1 = GetMainFrame();
	CWnd* pActiveWnd = pMainFrame1->GetActiveWindow();
	CGetDoc7* pDoc7 = NULL;
	if(pMainFrame1->GetSafeHwnd() != pActiveWnd->GetSafeHwnd())
		pDoc7 = CGetDlg::GetTopmostDocunent();

	bool bNeedCallGlob = true;
	if(pDoc7)
	{
		CWnd* pWndFrame = pDoc7->GetFrame();
		_CallModuleProc(pDoc7,nameProc0,nameProc1,argNum,vArray);
		bNeedCallGlob = false;
	}
	else
	{
		CMDIFrameWnd * pMainFrame = GetMainFrame();
		if(pMainFrame)
		{
			CMDIChildWnd * pChild = pMainFrame->MDIGetActive();
			if(pChild)
			{
				CWnd* wndFocus = pMainFrame->GetFocus();
				if(wndFocus)
				{
					CFrameWnd * pParentFrame = wndFocus->GetParentFrame();
					if(pParentFrame && pParentFrame->GetSafeHwnd() == pChild->GetSafeHwnd())
					{
						CDocument* pDoc = pChild->GetActiveDocument();
						if(pDoc)
							if(!strcmp(pDoc->GetRuntimeClass()->m_pfnGetBaseClass()->m_lpszClassName,"CGetDoc7"))
							{
								_CallModuleProc((CGetDoc7*)pDoc,nameProc0,nameProc1,argNum,vArray);
								bNeedCallGlob = false;
							}
					}
				}
			}
		}
	}
	if(bNeedCallGlob)
	{
		CValue p1, p2, p3, p4, p5, p6, p7, p8, p9, p10;
		CValue *vArrayGl[10] = {&p1, &p2, &p3, &p4, &p5, &p6, &p7, &p8, &p9, &p10};
		for(int i = 0; i<argNum; i++)
			*vArrayGl[i+1] = *vArray[i];
		_CallFromGlobalModules(NULL, NULL, nameProc0, nameProc1, argNum+1, vArrayGl);
		for(i = 0; i<argNum; i++)
			*vArray[i] = *vArrayGl[i+1];
	}
}

BOOL TrayShow()
{
	BOOL bSuccess = FALSE;
	if(!bTrayIconVisible)
	{
		bSuccess = Shell_NotifyIcon(NIM_ADD,&nidIconData);
		if(bSuccess)
			bTrayIconVisible = TRUE;
	}
	else
	{
		TRACE0("ICON ALREADY VISIBLE");
	}
	return bSuccess;
}

BOOL TrayHide()
{
	BOOL bSuccess = FALSE;
	if(bTrayIconVisible)
	{
		bSuccess = Shell_NotifyIcon(NIM_DELETE,&nidIconData);
		if(bSuccess)
			bTrayIconVisible= FALSE;
	}
	else
	{
		TRACE0("ICON ALREADY HIDDEN");
	}
	return bSuccess;
}

void OnTrayNotify(HWND hWnd, WPARAM wParam, LPARAM lParam) 
{ 
    UINT uID; 
    UINT uMsg; 
 
    uID = (UINT) wParam; 
    uMsg = (UINT) lParam; 
 
	if (uID != 1)
		return;
	
    switch (uMsg ) 
	{ 
	case WM_LBUTTONDBLCLK:
		if(TrayHide())
		{
			pMainWindow->ShowWindow(SW_SHOW);
			pMainWindow->ActivateFrame(SW_RESTORE);
			//pMainWindow->BringWindowToTop();
		}
		break;
    } 
     return; 
 } 

LRESULT __stdcall Wnd_Hook(int code, WPARAM wParam, LPARAM lParam)
{
	if(code>=0)
	{
		if(pMainWindow)
		{
			PCWPRETSTRUCT pRetStruct = (PCWPRETSTRUCT) lParam;
			switch (pRetStruct->message)
			{
			case WM_SYSCOMMAND:
				{
					if(bMinimizeToTray)
					{
						if(pMainWindow->GetSafeHwnd() == pRetStruct->hwnd)
						{
							UINT nID = (UINT) pRetStruct->wParam;
							if (((nID & 0xFFF0) == SC_MINIMIZE) && (TrayShow()))
							{
								CWnd* pWnd = CWnd::FromHandle(pRetStruct->hwnd);
								if(pWnd)
									pWnd->ShowWindow(SW_HIDE);
								//ret = 1;
							}
						}
					}
					break;
				}
			case WM_TRAY_ICON_NOTIFY_MESSAGE:
				{
					if(bMinimizeToTray)
						if(pMainWindow->GetSafeHwnd() == pRetStruct->hwnd)
						{
							OnTrayNotify(pRetStruct->hwnd, pRetStruct->wParam, pRetStruct->lParam);
							//ret = 1;
						}
					break;
				}
			case WM_INITMENUPOPUP:
				{
					CMenu *pMenu = CMenu::FromHandle((HMENU)pRetStruct->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);
							}
						}
					}
					break;
				}
			case WM_SIZE:
				{
					CWnd* pWnd = CWnd::FromHandle(pRetStruct->hwnd);
					if(pWnd)
					{
						CValue fwSizeType = DWORD(pRetStruct->wParam);
						CValue nWidth = LOWORD(pRetStruct->lParam);
						CValue nHeight = HIWORD(pRetStruct->lParam);
						CValue *lArray[3] = {&fwSizeType, &nWidth, &nHeight};
						CDocument* pDoc7 = NULL;
						if(!strcmp(pWnd->GetRuntimeClass()->m_lpszClassName,"CTabFrame"))//CBrowseView7
						{
							pDoc7 = ((CTabFrame*)pWnd)->GetActiveDocument();
						}
						else if(!strcmp(pWnd->GetRuntimeClass()->m_lpszClassName,"CSizingControlBar"))
						{
							CGetDlg* pDlg = (CGetDlg*)((CSizingControlBar*)pWnd)->m_pChildDlg;
							if(pDlg)
								pDoc7 = pDlg->m_pDoc;
						}
						if(pDoc7)
							if(pDoc7->IsKindOf(RUNTIME_CLASS(CGetDoc7)))
								_CallModuleProc((CGetDoc7*)pDoc7,"ПриИзмененииРазмераОкна","OnSize",3,lArray);
					}
					break;
				}

			}
		}
	}
	else
		return CallNextHookEx(WndHookHandle, code, wParam, lParam);

	return 0;
}

LRESULT __stdcall WndPre_Hook(int nCode, WPARAM wParam, LPARAM lParam)
{
	if(nCode < 0) return CallNextHookEx(WndPreHookHandle, nCode, wParam, lParam);

	LRESULT ret = 0;
	if(pMainWindow)
	{
		PCWPSTRUCT pStruct = (PCWPSTRUCT) lParam;
		switch (pStruct->message)
		{
			case WM_INITMENUPOPUP:
				{
					CWnd* pWnd = CWnd::FromHandle(pStruct->hwnd);
					if(pWnd)
					{
						CMenu *pMenuSys = pWnd->GetSystemMenu(FALSE);
						if(pMenuSys->GetSafeHmenu() != (HMENU)pStruct->wParam)
						{
							CMenu *pMenu = CMenu::FromHandle((HMENU)pStruct->wParam);
							if(pMenu)
							{
								int n = unvisibleMenus.GetSize();
								if(n > 0)
								{
									CMenu cMenu;
									cMenu.CreatePopupMenu();
									CopyMenu(pMenu,&cMenu);
									tempMenus.Add((DWORD)cMenu.Detach());
									srcMenus.Add((DWORD)pStruct->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(pStruct->hwnd);
					if(pWnd)
					{
						CMenu *pMenuSys = pWnd->GetSystemMenu(FALSE);
						if(pMenuSys->GetSafeHmenu() != (HMENU)pStruct->wParam)
						{
							CMenu *pMenu = CMenu::FromHandle((HMENU)pStruct->wParam);
							if(pMenu)
							{
								int n = srcMenus.GetSize();
								int p = -1;
								for(int i = 0; i < n; i++)
									if(srcMenus.GetAt(i) == pStruct->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;
				} // case
		} // switch
	} // if
	return ret;
}

LRESULT __stdcall Key_Hook(int code, WPARAM wParam, LPARAM lParam)
{
//	CBLModule* pExeMod = CBLModule::GetExecutedModule();

	LRESULT ret = 0;
	if((code>=0) && /*(pExeMod == NULL)*/ (bStopHook == false))
	{
		if((lParam & 0x40000000) == 0)
		{
			CValue KeyCode;
			CValue AltPressFlag;
			CValue ShiftPressFlag;
			CValue CtrlPressFlag;
			CValue r = 1;
            CValue Symbol;
            unsigned char State[256];
            unsigned short S[2];

			KeyCode = wParam;
			AltPressFlag = 0L;
			ShiftPressFlag = 0L;
			CtrlPressFlag = 0L;

            GetKeyboardState( State );

            if(State[VK_SHIFT] & 0x80) ShiftPressFlag = 1;
            if(State[VK_CONTROL] & 0x80) CtrlPressFlag = 1;
			//if(GetKeyState(VK_SHIFT) & 0x80) ShiftPressFlag = 1;
			//if(GetKeyState(VK_CONTROL) & 0x80) CtrlPressFlag = 1;
			if(lParam & 0x20000000) AltPressFlag = 1;

            // Переведем код клавиши в символ
            if (ToAscii(wParam, ((lParam>>16) & 0xFF), State, S, 0) > 0) 
                Symbol = CString(S[0]);
            else
                Symbol = "";

			CValue *lArray[6] = {&KeyCode, &AltPressFlag, &ShiftPressFlag, &CtrlPressFlag, &Symbol, &r};
			CallModuleProc("ПриНажатииКнопкиКлавиатуры","OnChar", 6, lArray);
			if(r.GetNumeric() == 0) ret = 1;
		}
		CallNextHookEx(HookHandle, code, wParam, lParam);
	}
	else
		ret = CallNextHookEx(HookHandle, code, wParam, lParam);
	//if(ret == 1) CallNextHookEx(HookHandle, code, wParam, lParam);
	//else ret = CallNextHookEx(HookHandle, code, wParam, lParam);
	return ret;
}

typedef struct tagMOUSEHOOKSTRUCT_EX {
    POINT   pt;
    HWND    hwnd;
    UINT    wHitTestCode;
    DWORD   dwExtraInfo;
	DWORD	dwData;
} *PMOUSEHOOKSTRUCT_EX;

LRESULT __stdcall Mouse_Hook(int code, WPARAM wParam, LPARAM lParam)
{
//	CBLModule* pExeMod = CBLModule::GetExecutedModule();

	LRESULT ret = 0;
	if((code>=0) && /*(pExeMod == NULL)*/ (bStopHook == false))
	{
		PMOUSEHOOKSTRUCT mStruct;
		mStruct = (PMOUSEHOOKSTRUCT)lParam;
		CWnd* pWnd = CWnd::FromHandle(mStruct->hwnd);
		if(pWnd)
		{
			CGetDoc7* pDoc7 = NULL;
			if(CString("CGetDlg") == pWnd->GetRuntimeClass()->m_lpszClassName)
			{
				pDoc7 = CGetDlg::GetTopmostDocunent();
				if(pDoc7->GetFrame() != pWnd)
					pDoc7 = NULL;

			}
			else if(CString("CTabFrame") != pWnd->GetRuntimeClass()->m_lpszClassName)
			{
				CWnd* pPWnd = pWnd->GetParent();
				bool f = true;
				while(pPWnd && f)
				{
					if((CString("CTabFrame") != pPWnd->GetRuntimeClass()->m_lpszClassName) &&
						(CString("CGetDlg") != pPWnd->GetRuntimeClass()->m_lpszClassName))
						pPWnd = pPWnd->GetParent();
					else
						f = false;
				}
				if(pPWnd)
				{
					if(CString("CTabFrame") == pPWnd->GetRuntimeClass()->m_lpszClassName)
						pDoc7 = (CGetDoc7*)((CTabFrame*)pPWnd)->GetActiveDocument();
					else if(CString("CGetDlg") == pPWnd->GetRuntimeClass()->m_lpszClassName)
					{
						pDoc7 = CGetDlg::GetTopmostDocunent();
						if(pDoc7->GetFrame() != pPWnd)
							pDoc7 = NULL;
					}
				}
			}
			else
				pDoc7 = (CGetDoc7*)((CTabFrame*)pWnd)->GetActiveDocument();

			//if(pDoc7)
			if((pDoc7 == NULL) || (!strcmp(pDoc7->GetRuntimeClass()->m_pfnGetBaseClass()->m_lpszClassName,"CGetDoc7")))
			{
				UINT nKeyState = 0;
				short sKeyState = GetKeyState(VK_SHIFT);
				if(sKeyState & 0x80) nKeyState |= MK_SHIFT;

				sKeyState = GetKeyState(VK_LBUTTON);
				if(sKeyState & 0x80) nKeyState |= MK_LBUTTON;

				sKeyState = GetKeyState(VK_RBUTTON);
				if(sKeyState & 0x80) nKeyState |= MK_RBUTTON;

				sKeyState = GetKeyState(VK_MBUTTON);
				if(sKeyState & 0x80) nKeyState |= MK_MBUTTON;

				sKeyState = GetKeyState(VK_CONTROL);
				if(sKeyState & 0x80) nKeyState |= MK_CONTROL;

				POINT pt;
				pt.x = mStruct->pt.x;
				pt.y = mStruct->pt.y;

				CWnd* pView = NULL;
				if(pDoc7)
				{
					POSITION aPOS = ((CDocument*)pDoc7)->GetFirstViewPosition();
					pView = (CWnd*)((CDocument*)pDoc7)->GetNextView(aPOS);
					if(pView == NULL)
						pView = pDoc7->GetFrame();
				}
				else
					pView = GetMainFrame();

				if(pView)
					pView->ScreenToClient(&pt);

				CValue Flags = nKeyState;
				CValue x = pt.x;
				CValue y = pt.y;
				CValue r = 1;
				CValue d = 0L;
				CValue *lArray[5] = {&Flags, &x, &y, &r, &d};

				bStopHook = true;
				switch (wParam)
				{
					case WM_MOUSEMOVE:
						{
							_CallModuleProc(pDoc7,"ПриДвиженииМыши","OnMouseMove", 4, lArray);
							break;
						}
					case WM_RBUTTONDOWN:
						{
							_CallModuleProc(pDoc7,"ПриНажатииПравойКнопки","OnRButtonDown", 4, lArray);
							break;
						}
					case WM_LBUTTONDOWN:
						{
							_CallModuleProc(pDoc7,"ПриНажатииЛевойКнопки","OnLButtonDown", 4, lArray);
							break;
						}
					case WM_RBUTTONUP:
						{
							_CallModuleProc(pDoc7,"ПриОтжатииПравойКнопки","OnRButtonUp", 4, lArray);
							break;
						}
					case WM_LBUTTONUP:
						{
							_CallModuleProc(pDoc7,"ПриОтжатииЛевойКнопки","OnLButtonUp", 4, lArray);
							break;
						}
					case WM_LBUTTONDBLCLK:
						{
							_CallModuleProc(pDoc7,"ПриДвойномНажатииЛевойКнопки","OnLButtonDblClk", 4, lArray);
							break;
						}
					case WM_RBUTTONDBLCLK:
						{
							_CallModuleProc(pDoc7,"ПриДвойномНажатииПравойКнопки","OnRButtonDblClk", 4, lArray);
							break;
						}
					case WM_MOUSEWHEEL:
						{
							d = (short)HIWORD(((PMOUSEHOOKSTRUCT_EX)mStruct)->dwData);
							_CallModuleProc(pDoc7,"ПриПрокруткеКолесаМыши","OnMouseWheel", 5, lArray);
							break;
						}
				}
				bStopHook = false;
				if(r.GetNumeric() == 0) ret = 1;
			}
		}
		CallNextHookEx(MouseHookHandle, code, wParam, lParam);
	}
	else
		ret = CallNextHookEx(MouseHookHandle, code, wParam, lParam);
	//if(ret == 1) CallNextHookEx(MouseHookHandle, code, wParam, lParam);
	//else ret = CallNextHookEx(MouseHookHandle, code, wParam, lParam);
	return ret;
}

