예제 #1
0
bool CConEmuUpdate::QueryConfirmationInt(LPCWSTR asConfirmInfo)
{
	if (mb_InShowLastError || !gpConEmu)
		return false; // Если отображается ошибк - не звать

	bool lbConfirm;

	if (gpConEmu->isMainThread())
	{
		Assert(!mb_InetMode && mb_ManualCallMode);

		DontEnable de;
		int iBtn = MessageBox(NULL, asConfirmInfo, ms_DefaultTitle, MB_ICONQUESTION|MB_SETFOREGROUND|MB_SYSTEMMODAL|MB_YESNO);

		mb_InShowLastError = false;

		lbConfirm = (iBtn == IDYES);
	}
	else
	{
		MSectionLock SC; SC.Lock(mp_LastErrorSC, TRUE);
		SafeFree(ms_LastErrorInfo);
		ms_LastErrorInfo = lstrdup(asConfirmInfo);
		SC.Unlock();

		lbConfirm = gpConEmu->ReportUpdateConfirmation();
	}

	return lbConfirm;
}
예제 #2
0
CBackground::~CBackground()
{
	Destroy();
	//if (mh_MsImg32)
	//{
	//	FreeLibrary(mh_MsImg32);
	//	fAlphaBlend = NULL;
	//}

	MSectionLock SC;

	if (mcs_BkImgData)
		SC.Lock(mcs_BkImgData, TRUE);

	SafeFree(mp_BkImgData);
	mn_BkImgDataMax = 0;

	SafeFree(mp_BkEmfData);
	mn_BkImgDataMax = 0;

	if (mcs_BkImgData)
	{
		SC.Unlock();
		SafeDelete(mcs_BkImgData);
	}
}
예제 #3
0
void CConEmuUpdate::ReportErrorInt(wchar_t* asErrorInfo)
{
	if (mb_InShowLastError)
		return; // Две ошибки сразу не показываем, а то зациклимся

	MSectionLock SC; SC.Lock(mp_LastErrorSC, TRUE);
	SafeFree(ms_LastErrorInfo);
	ms_LastErrorInfo = asErrorInfo;
	SC.Unlock();

	// This will call back ShowLastError
	if (gpConEmu)
		gpConEmu->ReportUpdateError();
}
예제 #4
0
파일: RegHooks.cpp 프로젝트: EricSB/ConEmu
	void Store(HKEY hKey, RegKeyType rkt)
	{
		if (!hKey || IsPredefined(hKey))
		{
			_ASSERTE(hKey!=NULL);
			_ASSERTE(!IsPredefined(hKey) || (rkt>=RKT_HKCU && rkt<=RKT_HKLM64));
			return;
		}
		//mhk_Last = hkSoftware;
		//WARNING("### Process RegKeyBlocks!");
		MSectionLock SC; SC.Lock(&mc_Lock, TRUE, 500);
		RegKeyInfo* p = FindFreeSlot();
		p->hKey = hKey;
		p->rkt = rkt;
		mp_LastKey = p;
	};
예제 #5
0
void CConEmuUpdate::ShowLastError()
{
	if (ms_LastErrorInfo && *ms_LastErrorInfo)
	{
		mb_InShowLastError = true;

		MSectionLock SC; SC.Lock(mp_LastErrorSC, TRUE);
		wchar_t* pszError = ms_LastErrorInfo;
		ms_LastErrorInfo = NULL;
		SC.Unlock();

		MessageBox(pszError, MB_ICONINFORMATION, gpConEmu?gpConEmu->GetDefaultTitle():L"ConEmu Update");
		SafeFree(pszError);

		mb_InShowLastError = false;
	}
}
예제 #6
0
bool CConEmuUpdate::ShowConfirmation()
{
	bool lbConfirm = false;

	// May be null, if update package was dropped on ConEmu icon
	if (gpConEmu && ghWnd)
	{
		gpConEmu->UpdateProgress();
	}

	if (ms_LastErrorInfo && *ms_LastErrorInfo)
	{
		mb_InShowLastError = true;

		MSectionLock SC; SC.Lock(mp_LastErrorSC, TRUE);
		wchar_t* pszConfirm = ms_LastErrorInfo;
		ms_LastErrorInfo = NULL;
		SC.Unlock();

		DontEnable de;
		int iBtn = MessageBox(NULL, pszConfirm, ms_DefaultTitle, MB_ICONQUESTION|MB_SETFOREGROUND|MB_SYSTEMMODAL|MB_YESNO);

		SafeFree(pszConfirm);

		mb_InShowLastError = false;

		lbConfirm = (iBtn == IDYES);
	}
	else
	{
		MBoxAssert(ms_LastErrorInfo && *ms_LastErrorInfo);
	}

	if (!lbConfirm)
	{
		RequestTerminate();
		// May be null, if update package was dropped on ConEmu icon
		if (gpConEmu && ghWnd)
		{
			gpConEmu->UpdateProgress();
		}
	}

	return lbConfirm;
}
예제 #7
0
BOOL WINAPI PlugServerCommand(LPVOID pInst, CESERVER_REQ* pIn, CESERVER_REQ* &ppReply, DWORD &pcbReplySize, DWORD &pcbMaxReplySize, LPARAM lParam)
{
    BOOL lbRc = FALSE;
    BOOL fSuccess = FALSE;
    MSectionThread SCT(csTabs);

    if (pIn->hdr.cbSize < sizeof(CESERVER_REQ_HDR) || /*in.nSize < cbRead ||*/ pIn->hdr.nVersion != CESERVER_REQ_VER)
    {
        gpPlugServer->BreakConnection(pInst);
        return FALSE;
    }

    UINT nDataSize = pIn->hdr.cbSize - sizeof(CESERVER_REQ_HDR);

    // Все данные из пайпа получены, обрабатываем команду и возвращаем (если нужно) результат
    switch (pIn->hdr.nCmd)
    {
    case CMD_LANGCHANGE:
    {
        _ASSERTE(nDataSize>=4); //-V112
        // LayoutName: "00000409", "00010409", ...
        // А HKL от него отличается, так что передаем DWORD
        // HKL в x64 выглядит как: "0x0000000000020409", "0xFFFFFFFFF0010409"
        DWORD hkl = pIn->dwData[0];
        DWORD dwLastError = 0;
        HKL hkl1 = NULL, hkl2 = NULL;

        if (hkl)
        {
            WCHAR szLoc[10];
            _wsprintf(szLoc, SKIPLEN(countof(szLoc)) L"%08x", hkl);
            hkl1 = LoadKeyboardLayout(szLoc, KLF_ACTIVATE|KLF_REORDER|KLF_SUBSTITUTE_OK|KLF_SETFORPROCESS);
            hkl2 = ActivateKeyboardLayout(hkl1, KLF_SETFORPROCESS|KLF_REORDER);

            if (!hkl2)
                dwLastError = GetLastError();
            else
                fSuccess = TRUE;
        }

        pcbReplySize = sizeof(CESERVER_REQ_HDR) + sizeof(DWORD)*2;
        if (ExecuteNewCmd(ppReply, pcbMaxReplySize, pIn->hdr.nCmd, pcbReplySize))
        {
            lbRc = TRUE;
            ppReply->dwData[0] = fSuccess;
            ppReply->dwData[1] = fSuccess ? ((DWORD)(LONG)(LONG_PTR)hkl2) : dwLastError;
        }

        break;
    } // CMD_LANGCHANGE

#if 0
    case CMD_DEFFONT:
    {
        // исключение - асинхронный, результат не требуется
        SetConsoleFontSizeTo(FarHwnd, 4, 6);
        MoveWindow(FarHwnd, 0, 0, GetSystemMetrics(SM_CXSCREEN), GetSystemMetrics(SM_CYSCREEN), 1); // чтобы убрать возможные полосы прокрутки...
        break;
    }
    CMD_DEFFONT
#endif

    case CMD_REQTABS:
    case CMD_SETWINDOW:
    {
        MSectionLock SC;
        SC.Lock(csTabs, FALSE, 1000);
        DWORD nSetWindowWait = (DWORD)-1;

        if (pIn->hdr.nCmd == CMD_SETWINDOW)
        {
            ResetEvent(ghSetWndSendTabsEvent);

            // Для FAR2 - сброс QSearch выполняется в том же макро, в котором актирируется окно
            if (gFarVersion.dwVerMajor == 1 && pIn->dwData[1])
            {
                // А вот для FAR1 - нужно шаманить
                Plugin()->ProcessCommand(CMD_CLOSEQSEARCH, TRUE/*bReqMainThread*/, pIn->dwData/*хоть и не нужно?*/);
            }

            // Пересылается 2 DWORD
            BOOL bCmdRc = Plugin()->ProcessCommand(pIn->hdr.nCmd, TRUE/*bReqMainThread*/, pIn->dwData);

            DEBUGSTRCMD(L"Plugin: PlugServerThreadCommand: CMD_SETWINDOW waiting...\n");

            WARNING("Почему для FAR1 не ждем? Есть возможность заблокироваться в 1.7 или что?");
            if ((gFarVersion.dwVerMajor >= 2) && bCmdRc)
            {
                DWORD nTimeout = 2000;
#ifdef _DEBUG
                if (IsDebuggerPresent()) nTimeout = 120000;
#endif

                nSetWindowWait = WaitForSingleObject(ghSetWndSendTabsEvent, nTimeout);
            }

            if (nSetWindowWait == WAIT_TIMEOUT)
            {
                gbForceSendTabs = TRUE;
                DEBUGSTRCMD(L"Plugin: PlugServerThreadCommand: CMD_SETWINDOW timeout !!!\n");
            }
            else
            {
                DEBUGSTRCMD(L"Plugin: PlugServerThreadCommand: CMD_SETWINDOW finished\n");
            }
        }

        if (gpTabs && (nSetWindowWait != WAIT_TIMEOUT))
        {
            //fSuccess = WriteFile(hPipe, gpTabs, gpTabs->hdr.cbSize, &cbWritten, NULL);
            pcbReplySize = gpTabs->hdr.cbSize;
            if (ExecuteNewCmd(ppReply, pcbMaxReplySize, pIn->hdr.nCmd, pcbReplySize))
            {
                memmove(ppReply->Data, gpTabs->Data, pcbReplySize - sizeof(ppReply->hdr));
                lbRc = TRUE;
            }
        }

        SC.Unlock();
        break;
    } // CMD_REQTABS, CMD_SETWINDOW

    case CMD_FARSETCHANGED:
    {
        // Установить переменные окружения
        // Плагин это получает в ответ на CECMD_RESOURCES, посланное в GUI при загрузке плагина
        _ASSERTE(nDataSize>=8);
        FAR_REQ_FARSETCHANGED *pFarSet = (FAR_REQ_FARSETCHANGED*)pIn->Data;

        cmd_FarSetChanged(pFarSet);

        pcbReplySize = sizeof(CESERVER_REQ_HDR) + sizeof(DWORD);
        if (ExecuteNewCmd(ppReply, pcbMaxReplySize, pIn->hdr.nCmd, pcbReplySize))
        {
            lbRc = TRUE;
            ppReply->dwData[0] = TRUE;
        }

        //_ASSERTE(nDataSize<sizeof(gsMonitorEnvVar));
        //gbMonitorEnvVar = false;
        //// Плагин FarCall "нарушает" COMSPEC (копирует содержимое запускаемого процесса)
        //bool lbOk = false;

        //if (nDataSize<sizeof(gsMonitorEnvVar))
        //{
        //	memcpy(gsMonitorEnvVar, pszName, nDataSize);
        //	lbOk = true;
        //}

        //UpdateEnvVar(pszName);
        ////while (*pszName && *pszValue) {
        ////	const wchar_t* pszChanged = pszValue;
        ////	// Для ConEmuOutput == AUTO выбирается по версии ФАРа
        ////	if (!lstrcmpi(pszName, L"ConEmuOutput") && !lstrcmp(pszChanged, L"AUTO")) {
        ////		if (gFarVersion.dwVerMajor==1)
        ////			pszChanged = L"ANSI";
        ////		else
        ////			pszChanged = L"UNICODE";
        ////	}
        ////	// Если в pszValue пустая строка - удаление переменной
        ////	SetEnvironmentVariableW(pszName, (*pszChanged != 0) ? pszChanged : NULL);
        ////	//
        ////	pszName = pszValue + lstrlenW(pszValue) + 1;
        ////	if (*pszName == 0) break;
        ////	pszValue = pszName + lstrlenW(pszName) + 1;
        ////}
        //gbMonitorEnvVar = lbOk;

        break;
    } // CMD_FARSETCHANGED

    case CMD_DRAGFROM:
    {
#ifdef _DEBUG
        BOOL  *pbClickNeed = (BOOL*)pIn->Data;
        COORD *crMouse = (COORD *)(pbClickNeed+1);
#endif

        Plugin()->ProcessCommand(CMD_LEFTCLKSYNC, TRUE/*bReqMainThread*/, pIn->Data);
        CESERVER_REQ* pCmdRet = NULL;
        Plugin()->ProcessCommand(pIn->hdr.nCmd, TRUE/*bReqMainThread*/, pIn->Data, &pCmdRet);

        if (pCmdRet)
        {
            //fSuccess = WriteFile(hPipe, pCmdRet, pCmdRet->hdr.cbSize, &cbWritten, NULL);
            pcbReplySize = pCmdRet->hdr.cbSize;
            if (ExecuteNewCmd(ppReply, pcbMaxReplySize, pIn->hdr.nCmd, pcbReplySize))
            {
                lbRc = TRUE;
                memmove(ppReply->Data, pCmdRet->Data, pCmdRet->hdr.cbSize - sizeof(ppReply->hdr));
            }
            Free(pCmdRet);
        }

        break;
    } // CMD_DRAGFROM

    case CMD_EMENU:
    {
        COORD *crMouse = (COORD *)pIn->Data;
#ifdef _DEBUG
        const wchar_t *pszUserMacro = (wchar_t*)(crMouse+1);
#endif
        DWORD ClickArg[2] = {(DWORD)TRUE, (DWORD)MAKELONG(crMouse->X, crMouse->Y)};

        // Выделить файл под курсором
        DEBUGSTRMENU(L"\n*** ServerThreadCommand->ProcessCommand(CMD_LEFTCLKSYNC) begin\n");
        BOOL lb1 = Plugin()->ProcessCommand(CMD_LEFTCLKSYNC, TRUE/*bReqMainThread*/, ClickArg/*pIn->Data*/);
        DEBUGSTRMENU(L"\n*** ServerThreadCommand->ProcessCommand(CMD_LEFTCLKSYNC) done\n");

        // А теперь, собственно вызовем меню
        DEBUGSTRMENU(L"\n*** ServerThreadCommand->ProcessCommand(CMD_EMENU) begin\n");
        BOOL lb2 = Plugin()->ProcessCommand(pIn->hdr.nCmd, TRUE/*bReqMainThread*/, pIn->Data);
        DEBUGSTRMENU(L"\n*** ServerThreadCommand->ProcessCommand(CMD_EMENU) done\n");

        pcbReplySize = sizeof(CESERVER_REQ_HDR) + sizeof(DWORD)*2;
        if (ExecuteNewCmd(ppReply, pcbMaxReplySize, pIn->hdr.nCmd, pcbReplySize))
        {
            lbRc = TRUE;
            ppReply->dwData[0] = lb1;
            ppReply->dwData[1] = lb1;
        }

        break;
    } // CMD_EMENU

    case CMD_ACTIVEWNDTYPE:
    {
        int nWindowType = -1;
        //CESERVER_REQ Out;
        //ExecutePrepareCmd(&Out, CMD_ACTIVEWNDTYPE, sizeof(CESERVER_REQ_HDR)+sizeof(DWORD));

        if (gFarVersion.dwVerMajor>=2)
            nWindowType = Plugin()->GetActiveWindowType();

        //fSuccess = WriteFile(hPipe, &Out, Out.hdr.cbSize, &cbWritten, NULL);

        pcbReplySize = sizeof(CESERVER_REQ_HDR) + sizeof(DWORD);
        if (ExecuteNewCmd(ppReply, pcbMaxReplySize, pIn->hdr.nCmd, pcbReplySize))
        {
            lbRc = TRUE;
            ppReply->dwData[0] = nDataSize;
        }

        break;
    } // CMD_ACTIVEWNDTYPE

    case CECMD_ATTACH2GUI:
    {
        BOOL bAttached = Plugin()->Attach2Gui();
        pcbReplySize = sizeof(CESERVER_REQ_HDR) + sizeof(DWORD);
        if (ExecuteNewCmd(ppReply, pcbMaxReplySize, pIn->hdr.nCmd, pcbReplySize))
        {
            lbRc = TRUE;
            ppReply->dwData[0] = bAttached;
        }
        break;
    } // CECMD_ATTACH2GUI

    default:
    {
        CESERVER_REQ* pCmdRet = NULL;
        BOOL lbCmd = Plugin()->ProcessCommand(pIn->hdr.nCmd, TRUE/*bReqMainThread*/, pIn->Data, &pCmdRet);

        if (pCmdRet)
        {
            //fSuccess = WriteFile(hPipe, pCmdRet, pCmdRet->hdr.cbSize, &cbWritten, NULL);
            pcbReplySize = pCmdRet->hdr.cbSize;
            if (ExecuteNewCmd(ppReply, pcbMaxReplySize, pIn->hdr.nCmd, pcbReplySize))
            {
                lbRc = TRUE;
                memmove(ppReply->Data, pCmdRet->Data, pCmdRet->hdr.cbSize - sizeof(ppReply->hdr));
            }
            Free(pCmdRet);
        }

    } // default
    } // switch (pIn->hdr.nCmd)

    return lbRc;
}
예제 #8
0
MConHandle::operator const HANDLE()
{
	if (mpp_OutBuffer && *mpp_OutBuffer && (*mpp_OutBuffer != INVALID_HANDLE_VALUE))
	{
		LogHandle(Event::e_GetHandlePtr, *mpp_OutBuffer);
		return *mpp_OutBuffer;
	}

	if (mh_Handle == INVALID_HANDLE_VALUE)
	{
		if (mn_StdMode)
		{
			mh_Handle = GetStdHandle(mn_StdMode);
			LogHandle(Event::e_CreateHandleStd, mh_Handle);
		}
		else
		{
			// Чтобы случайно не открыть хэндл несколько раз в разных потоках
			MSectionLock CS; CS.Lock(&mcs_Handle, TRUE);

			// Во время ожидания хэндл мог быт открыт в другом потоке
			if (mh_Handle == INVALID_HANDLE_VALUE)
			{
				mh_Handle = CreateFileW(ms_Name, GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE,
										0, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0);

				if (mh_Handle != INVALID_HANDLE_VALUE)
				{
					mb_OpenFailed = FALSE;
				}
				else
				{
					mn_LastError = GetLastError();

					if (!mb_OpenFailed)
					{
						mb_OpenFailed = TRUE; // чтобы ошибка вываливалась только один раз!
						char szErrMsg[512], szNameA[10], szSelfFull[MAX_PATH];
						const char *pszSelf;
						char *pszDot;

						if (!GetModuleFileNameA(0,szSelfFull,MAX_PATH))
						{
							pszSelf = "???";
						}
						else
						{
							pszSelf = strrchr(szSelfFull, '\\');
							if (pszSelf) pszSelf++; else pszSelf = szSelfFull;

							pszDot = strrchr((char*)pszSelf, '.');

							if (pszDot) *pszDot = 0;
						}

						WideCharToMultiByte(CP_OEMCP, 0, ms_Name, -1, szNameA, sizeof(szNameA), 0,0);
						_wsprintfA(szErrMsg, SKIPLEN(countof(szErrMsg)) "%s: CreateFile(%s) failed, ErrCode=0x%08X\n", pszSelf, szNameA, mn_LastError);
						HANDLE h = GetStdHandle(STD_OUTPUT_HANDLE);

						if (h && h!=INVALID_HANDLE_VALUE)
						{
							DWORD dwWritten = 0;
							WriteFile(h, szErrMsg, lstrlenA(szErrMsg), &dwWritten, 0);
						}
					}
				}

				LogHandle(Event::e_CreateHandle, mh_Handle);
			}
		}
	}

	LogHandle(Event::e_GetHandle, mh_Handle);
	return mh_Handle;
};
예제 #9
0
// Создает (или возвращает уже созданный) HDC (CompatibleDC) для mp_BkImgData
bool CBackground::PutPluginBackgroundImage(/*CBackground* pBack,*/ LONG X, LONG Y, LONG Width, LONG Height)
{
	if (!this) return NULL;

	_ASSERTE(isMainThread());

	// Сразу
	mb_BkImgChanged = FALSE;

	/*if (mb_BkImgDelete && mp_BkImgData)
	{
		free(mp_BkImgData); mp_BkImgData = NULL;
		mb_BkImgExist = FALSE;
		return false;
	}*/
	if (!mb_BkImgExist)
		return false;

	MSectionLock SC;
	SC.Lock(mcs_BkImgData, FALSE);

	if (mb_BkEmfChanged)
	{
		// Сразу сброс
		mb_BkEmfChanged = FALSE;

		if (!mp_BkEmfData)
		{
			_ASSERTE(mp_BkEmfData!=NULL);
			return false;
		}

		// Нужно перекинуть EMF в mp_BkImgData
		BITMAPINFOHEADER bi = mp_BkEmfData->bi;
		size_t nBitSize = bi.biWidth*bi.biHeight*sizeof(COLORREF);
		size_t nWholeSize = sizeof(CESERVER_REQ_SETBACKGROUND)+nBitSize; //-V103 //-V119
		if (!mp_BkImgData || (mn_BkImgDataMax < nWholeSize))
		{
			if (mp_BkImgData)
				free(mp_BkImgData);
			mp_BkImgData = (CESERVER_REQ_SETBACKGROUND*)malloc(nWholeSize);
			if (!mp_BkImgData)
			{
				_ASSERTE(mp_BkImgData!=NULL);
				return false;
			}
		}

		*mp_BkImgData = *mp_BkEmfData;
		mp_BkImgData->bmp.bfType = 0x4D42/*BM*/;
		mp_BkImgData->bmp.bfSize = nBitSize+sizeof(BITMAPFILEHEADER)+sizeof(BITMAPINFOHEADER); //-V119

		// Теперь нужно сформировать DIB и нарисовать в нем EMF
		HDC hScreen = GetDC(NULL);
		//RECT rcMeta = {0,0, mn_BkImgWidth, mn_BkImgHeight}; // (in pixels)
		//RECT rcMetaMM = {0,0, mn_BkImgWidth*10, mn_BkImgHeight*10}; // (in .01-millimeter units)
		//HDC hdcEmf = CreateEnhMetaFile(NULL, NULL, &rcMetaMM, L"ConEmu\0Far Background\0\0");
		//if (!hdcEmf)
		//{
		//	_ASSERTE(hdcEmf!=NULL);
		//	return;
		//}

		HDC hdcDib = CreateCompatibleDC(hScreen);
		if (!hdcDib)
		{
			_ASSERTE(hdcDib!=NULL);
			//DeleteEnhMetaFile(hdcEmf);
			return false;
		}
		COLORREF* pBits = NULL;
		HBITMAP hDib = CreateDIBSection(hScreen, (BITMAPINFO*)&bi, DIB_RGB_COLORS, (void**)&pBits, NULL, 0);
		ReleaseDC(NULL, hScreen); hScreen = NULL;
		if (!hDib || !pBits)
		{
			_ASSERTE(hDib && pBits);
			return false;
		}

		HBITMAP hOld = (HBITMAP)SelectObject(hdcDib, hDib);

		size_t nBitsSize = bi.biWidth*bi.biHeight*sizeof(COLORREF);
		// Залить черным - по умолчанию
		#ifdef _DEBUG
			memset(pBits, 128, nBitSize);
		#else
			memset(pBits, 0, nBitsSize);
		#endif

		DWORD nEmfBits = mp_BkEmfData->bmp.bfSize - sizeof(BITMAPFILEHEADER) - sizeof(BITMAPINFOHEADER);
		LPBYTE pEmfBits = (LPBYTE)(mp_BkEmfData+1);
		HENHMETAFILE hdcEmf = SetEnhMetaFileBits(nEmfBits, pEmfBits);
		RECT rcPlay = {0,0, bi.biWidth, bi.biHeight};
		DWORD nPlayErr = 0;
		if (hdcEmf)
		{
			#ifdef _DEBUG
			ENHMETAHEADER	emh = {0};
			DWORD			PixelsX, PixelsY, MMX, MMY, cx, cy;
			emh.nSize = sizeof(ENHMETAHEADER);
			if( GetEnhMetaFileHeader( hdcEmf, sizeof( ENHMETAHEADER ), &emh ) )
			{
				// Get the characteristics of the output device
				HDC hDC = GetDC(NULL);
				PixelsX = GetDeviceCaps( hDC, HORZRES );
				PixelsY = GetDeviceCaps( hDC, VERTRES );
				MMX = GetDeviceCaps( hDC, HORZSIZE ) * 100;
				MMY = GetDeviceCaps( hDC, VERTSIZE ) * 100;
				ReleaseDC(NULL, hDC);

				// Calculate the rect in which to draw the metafile based on the
				// intended size and the current output device resolution
				// Remember that the intended size is given in 0.01mm units, so
				// convert those to device units on the target device
				cx = (int)((float)(emh.rclFrame.right - emh.rclFrame.left) * PixelsX / (MMX));
				cy = (int)((float)(emh.rclFrame.bottom - emh.rclFrame.top) * PixelsY / (MMY));
				//pw->PreferredSize.cx = ip.MulDivI32((emh.rclFrame.right - emh.rclFrame.left), PixelsX, MMX);
				//pw->PreferredSize.cy = ip.MulDivI32((emh.rclFrame.bottom - emh.rclFrame.top), PixelsY, MMY);
				_ASSERTE(cx>0 && cy>0);
				//if (pw->PreferredSize.cx < 0) pw->PreferredSize.cx = -pw->PreferredSize.cx;
				//if (pw->PreferredSize.cy < 0) pw->PreferredSize.cy = -pw->PreferredSize.cy;
				//rcPlay = MakeRect(emh.rclBounds.left,emh.rclBounds.top,emh.rclBounds.right,emh.rclBounds.bottom);
			}
			#endif

			if (!PlayEnhMetaFile(hdcDib, hdcEmf, &rcPlay))
			{
				nPlayErr = GetLastError();
				_ASSERTE(FALSE && (nPlayErr == 0));
			}

			GdiFlush();
			memmove(mp_BkImgData+1, pBits, nBitSize);
		}
		UNREFERENCED_PARAMETER(nPlayErr);

		SelectObject(hdcDib, hOld);
		DeleteObject(hDib);
		DeleteDC(hdcDib);
		if (hdcEmf)
		{
			DeleteEnhMetaFile(hdcEmf);
		}
		else
		{
			return false;
		}
	}

	if (!mp_BkImgData)
	{
		// Нужен ли тут? Или допустимая ситуация?
		_ASSERTE(mp_BkImgData!=NULL);
		return false;
	}

	bool lbFade = false;

	if (gpSet->isFadeInactive && !gpConEmu->isMeForeground(false))
		lbFade = true;

	bool lbRc = FillBackground(&mp_BkImgData->bmp, X, Y, Width, Height, eUpLeft, lbFade);

	//mb_BkImgChanged = FALSE;
	return lbRc;
}
예제 #10
0
// вызывается при получении нового Background (CECMD_SETBACKGROUND) из плагина
// и для очистки при закрытии (рестарте) консоли
SetBackgroundResult CBackground::SetPluginBackgroundImageData(CESERVER_REQ_SETBACKGROUND* apImgData, bool&/*OUT*/ bUpdate)
{
	if (!this) return esbr_Unexpected;

	//if (!isMainThread())
	//{

	//// При вызове из серверной нити (только что пришло из плагина)
	//if (mp_RCon->isConsoleClosing())
	//	return esbr_ConEmuInShutdown;

	bool bIsEmf = false;
	UINT nSize = IsBackgroundValid(apImgData, &bIsEmf);

	if (!nSize)
	{
		_ASSERTE(FALSE && "!IsBackgroundValid(apImgData, NULL)");
		return esbr_InvalidArg;
	}

	if (!apImgData->bEnabled)
	{
		//mb_BkImgDelete = TRUE;
		mb_BkImgExist = FALSE;
		NeedBackgroundUpdate();
		//Update(true/*bForce*/);
		bUpdate = true;
		return gpSet->isBgPluginAllowed ? esbr_OK : esbr_PluginForbidden;
	}

#ifdef _DEBUG

	if ((GetKeyState(VK_SCROLL) & 1))
	{
		static UINT nBackIdx = 0;
		wchar_t szFileName[32];
		_wsprintf(szFileName, SKIPLEN(countof(szFileName)) L"PluginBack_%04u.bmp", nBackIdx++);
		char szAdvInfo[512];
		BITMAPINFOHEADER* pBmp = (BITMAPINFOHEADER*)((&apImgData->bmp)+1);
		_wsprintfA(szAdvInfo, SKIPLEN(countof(szAdvInfo)) "\r\nnType=%i, bEnabled=%i,\r\nWidth=%i, Height=%i, Bits=%i, Encoding=%i\r\n",
		           apImgData->nType, apImgData->bEnabled,
		           pBmp->biWidth, pBmp->biHeight, pBmp->biBitCount, pBmp->biCompression);
		HANDLE hFile = CreateFile(szFileName, GENERIC_WRITE, FILE_SHARE_READ, 0, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, 0);

		if (hFile != INVALID_HANDLE_VALUE)
		{
			DWORD cbWrite;
			WriteFile(hFile, &apImgData->bmp, apImgData->bmp.bfSize, &cbWrite, 0);
			WriteFile(hFile, szAdvInfo, lstrlenA(szAdvInfo), &cbWrite, 0);
			CloseHandle(hFile);
		}
	}

#endif

	//	// Поскольку вызов асинхронный (сразу возвращаем в плагин), то нужно сделать копию данных
	//	CESERVER_REQ_SETBACKGROUND* pCopy = (CESERVER_REQ_SETBACKGROUND*)malloc(nSize);
	//	if (!pCopy)
	//		return esbr_Unexpected;
	//	memmove(pCopy, apImgData, nSize);
	//	// Запомнить последний актуальный, и послать в главную нить
	//	mp_LastImgData = pCopy;
	//	mb_BkImgDelete = FALSE;
	//	gpConEmu->PostSetBackground(this, pCopy);
	//	return gpSet->isBgPluginAllowed ? esbr_OK : esbr_PluginForbidden;
	//}

	//// Если вызов пришел во время закрытия консоли - игнорировать
	//if (mp_RCon->isConsoleClosing())
	////// Этот apImgData уже не актуален. Во время обработки сообщения пришел новый Background.
	////	|| (mp_LastImgData && mp_LastImgData != apImgData))
	//{
	//	free(apImgData);
	//	return esbr_Unexpected;
	//}

	// Ссылку на актуальный - не сбрасываем. Она просто информационная, и есть возможность наколоться с многопоточностью
	//mp_LastImgData = NULL;

	//UINT nSize = IsBackgroundValid(apImgData);
	//if (!nSize)
	//{
	//	// Не допустимый apImgData. Вроде такого быть не должно - все уже проверено
	//	_ASSERTE(IsBackgroundValid(apImgData) != 0);
	//	//free(apImgData);
	//	return esbr_InvalidArg;
	//}

	//MSectionLock SBK; SBK.Lock(&csBkImgData);
	//_ASSERTE(isMainThread());

	if (!mcs_BkImgData)
		mcs_BkImgData = new MSection();

	MSectionLock SC;
	SC.Lock(mcs_BkImgData, TRUE);

	if (bIsEmf)
	{
		if (!mp_BkEmfData || mn_BkEmfDataMax < nSize)
		{
			if (mp_BkEmfData)
			{
				free(mp_BkEmfData); mp_BkEmfData = NULL;
				mb_BkImgChanged = mb_BkEmfChanged = TRUE;
				mb_BkImgExist = FALSE;
				mn_BkImgWidth = mn_BkImgHeight = 0;
			}

			mn_BkEmfDataMax = nSize+8192;
			mp_BkEmfData = (CESERVER_REQ_SETBACKGROUND*)malloc(mn_BkEmfDataMax);
		}
	}
	else
	{
		if (!mp_BkImgData || mn_BkImgDataMax < nSize)
		{
			if (mp_BkImgData)
			{
				free(mp_BkImgData); mp_BkImgData = NULL;
				mb_BkImgChanged = TRUE;
				mb_BkImgExist = FALSE;
				mn_BkImgWidth = mn_BkImgHeight = 0;
			}

			mp_BkImgData = (CESERVER_REQ_SETBACKGROUND*)malloc(nSize);
		}
	}

	SetBackgroundResult rc;

	if (!(bIsEmf ? mp_BkEmfData : mp_BkImgData))
	{
		_ASSERTE((bIsEmf ? mp_BkEmfData : mp_BkImgData)!=NULL);
		rc = esbr_Unexpected;
	}
	else
	{
		if (bIsEmf)
			memmove(mp_BkEmfData, apImgData, nSize);
		else
			memmove(mp_BkImgData, apImgData, nSize);
		mb_BkImgChanged = TRUE;
		mb_BkEmfChanged = bIsEmf;
		mb_BkImgExist = TRUE;
		BITMAPINFOHEADER* pBmp = bIsEmf ? (&mp_BkEmfData->bi) : (&mp_BkImgData->bi);
		mn_BkImgWidth = pBmp->biWidth;
		mn_BkImgHeight = pBmp->biHeight;
		NeedBackgroundUpdate();

		//// Это была копия данных - нужно освободить
		//free(apImgData); apImgData = NULL;

		if (/*gpConEmu->isVisible(this) &&*/ gpSet->isBgPluginAllowed)
		{
			//Update(true/*bForce*/);
			bUpdate = true;
		}

		rc = esbr_OK;
	}

	return rc;
}
예제 #11
0
// Вызывается ТОЛЬКО в главной нити!
void CPluginBackground::UpdateBackground()
{
	if (!mn_BgPluginsCount)
		return;

	if (!ghConEmuWndDC || !IsWindow(ghConEmuWndDC))
		return;

	if (mb_ThNeedLoad)
	{
		LoadThSet(TRUE/*Мы уже в главной нити*/);
	}

	//RECT rcClient; GetClientRect(ghConEmuWndDC, &rcClient);
	struct PaintBackgroundArg Arg = m_Default;
	Arg.cbSize = sizeof(struct PaintBackgroundArg);
	//m_Default.dcSizeX = Arg.dcSizeX = rcClient.right+1;
	//m_Default.dcSizeY = Arg.dcSizeY = rcClient.bottom+1;
	m_Default.dcSizeX = Arg.dcSizeX = (m_Default.rcConWorkspace.right-m_Default.rcConWorkspace.left+1)*m_Default.MainFont.nFontCellWidth;
	m_Default.dcSizeY = Arg.dcSizeY = (m_Default.rcConWorkspace.bottom-m_Default.rcConWorkspace.top+1)*m_Default.MainFont.nFontHeight;
	// **********************************************************************************
	// запомнить данные из m_Default в m_Last, но т.к. там есть указатели - move не катит
	// **********************************************************************************
	//memmove(&m_Last, &m_Default, sizeof(m_Last));
	m_Last.MainFont = m_Default.MainFont;
	memmove(m_Last.crPalette, m_Default.crPalette, sizeof(m_Last.crPalette));
	m_Last.dcSizeX = m_Default.dcSizeX;
	m_Last.dcSizeY = m_Default.dcSizeY;
	m_Last.rcDcLeft = m_Default.rcDcLeft;
	m_Last.rcDcRight = m_Default.rcDcRight;
	m_Last.rcConWorkspace = m_Default.rcConWorkspace;
	m_Last.conCursor = m_Default.conCursor;
	m_Last.FarInterfaceSettings.Raw = m_Default.FarInterfaceSettings.Raw;
	m_Last.FarPanelSettings.Raw = m_Default.FarPanelSettings.Raw;
	memmove(m_Last.nFarColors, m_Default.nFarColors, sizeof(m_Last.nFarColors));
	m_Last.bPanelsAllowed = m_Default.bPanelsAllowed;
	// struct tag_BkPanelInfo
	m_Last.LeftPanel.bVisible = m_Default.LeftPanel.bVisible;
	m_Last.LeftPanel.bFocused = m_Default.LeftPanel.bFocused;
	m_Last.LeftPanel.bPlugin = m_Default.LeftPanel.bPlugin;
	m_Last.LeftPanel.rcPanelRect = m_Default.LeftPanel.rcPanelRect;
	m_Last.RightPanel.bVisible = m_Default.RightPanel.bVisible;
	m_Last.RightPanel.bFocused = m_Default.RightPanel.bFocused;
	m_Last.RightPanel.bPlugin = m_Default.RightPanel.bPlugin;
	m_Last.RightPanel.rcPanelRect = m_Default.RightPanel.rcPanelRect;
	// строки
	lstrcpyW(m_Last.LeftPanel.szCurDir, m_Default.LeftPanel.szCurDir);
	lstrcpyW(m_Last.LeftPanel.szFormat, m_Default.LeftPanel.szFormat);
	lstrcpyW(m_Last.LeftPanel.szHostFile, m_Default.LeftPanel.szHostFile);
	lstrcpyW(m_Last.RightPanel.szCurDir, m_Default.RightPanel.szCurDir);
	lstrcpyW(m_Last.RightPanel.szFormat, m_Default.RightPanel.szFormat);
	lstrcpyW(m_Last.RightPanel.szHostFile, m_Default.RightPanel.szHostFile);
	// **********************************************************************************

	if (m_Default.dcSizeX < 1 || m_Default.dcSizeY < 1)
	{
		_ASSERTE(m_Default.dcSizeX >= 1 && m_Default.dcSizeY >= 1);
		return;
	}

	SetDcPanelRect(&Arg.rcDcLeft, &Arg.LeftPanel, &Arg);
	SetDcPanelRect(&Arg.rcDcRight, &Arg.RightPanel, &Arg);

	// gpTabs отстает от реальности.
	Arg.Place = m_Default.Place;
	//if (!gpTabs)
	//	Arg.Place = pbp_Panels;
	//else if (gnCurrentWindowType == WTYPE_EDITOR)
	//	Arg.Place = pbp_Editor;
	//else if (gnCurrentWindowType == WTYPE_VIEWER)
	//	Arg.Place = pbp_Viewer;
	//else if (Arg.LeftPanel.bVisible || Arg.RightPanel.bVisible)
	//{
	//	_ASSERTE(gnCurrentWindowType == WTYPE_PANELS);
	//	Arg.Place = pbp_Panels;
	//}

	BITMAPINFOHEADER bi = {sizeof(BITMAPINFOHEADER)};
	bi.biWidth = Arg.dcSizeX;
	bi.biHeight = Arg.dcSizeY;
	bi.biPlanes = 1;
	bi.biBitCount = 32; //-V112
	bi.biCompression = BI_RGB;

	//_ASSERTE(Arg.LeftPanel.bVisible || Arg.RightPanel.bVisible);
	HDC hScreen = GetDC(NULL);

	RECT rcMeta = {0,0, Arg.dcSizeX, Arg.dcSizeY}; // (in pixels)
	int iWidthMM = GetDeviceCaps(hScreen, HORZSIZE); if (iWidthMM <= 0) { _ASSERTE(iWidthMM>0); iWidthMM = 1024; }
	int iHeightMM = GetDeviceCaps(hScreen, VERTSIZE); if (iHeightMM <= 0) { _ASSERTE(iHeightMM>0); iHeightMM = 768; }
	int iWidthPels = GetDeviceCaps(hScreen, HORZRES); if (iWidthPels <= 0) { _ASSERTE(iWidthPels>0); iWidthPels = 0; }
	int iHeightPels = GetDeviceCaps(hScreen, VERTRES); if (iHeightPels <= 0) { _ASSERTE(iHeightPels>0); iHeightPels = 0; }
	RECT rcMetaMM = {0,0, (rcMeta.right * iWidthMM * 100)/iWidthPels, (rcMeta.bottom * iHeightMM * 100)/iHeightPels}; // (in .01-millimeter units)

	HDC hdc = NULL;
	HENHMETAFILE hEmf = NULL;
	COLORREF* pBits = NULL;
	HBITMAP hDib = NULL, hOld = NULL;
#ifdef CREATE_EMF_TEMP_FILES
	wchar_t szEmfFile[MAX_PATH] = {};
#endif
	wchar_t *pszEmfFile = NULL;


	if (SETBACKGROUND_USE_EMF==1)
	{
		#ifdef CREATE_EMF_TEMP_FILES
		GetTempPath(MAX_PATH-32, szEmfFile);
		int nLen = lstrlen(szEmfFile);
		if (*szEmfFile && szEmfFile[nLen-1] != L'\\')
		{
			szEmfFile[nLen++] = L'\\';
			szEmfFile[nLen] = 0;
		}
		_wsprintf(szEmfFile+nLen, SKIPLEN(31) L"CeBack%u.emf", GetCurrentProcessId());
		pszEmfFile = szEmfFile;
		#endif

		hdc = CreateEnhMetaFile(hScreen, pszEmfFile, &rcMetaMM, L"ConEmu\0Far Background\0\0");
		if (!hdc)
		{
			_ASSERTE(hdc!=NULL);
			return;
		}
	}
	else
	{
		hdc = CreateCompatibleDC(hScreen);
		if (!hdc)
		{
			_ASSERTE(hdc!=NULL);
			return;
		}
		_ASSERTE(pBits = NULL);
		hDib = CreateDIBSection(hScreen, (BITMAPINFO*)&bi, DIB_RGB_COLORS, (void**)&pBits, NULL, 0);
	}
	ReleaseDC(NULL, hScreen); hScreen = NULL;

	Arg.hdc = hdc;

	if (SETBACKGROUND_USE_EMF==1)
	{
		HBRUSH hFillBr = CreateSolidBrush (
			#ifdef _DEBUG
				RGB(128,128,0)
			#else
				RGB(0,0,0)
			#endif
		);
		FillRect(hdc, &rcMeta, hFillBr);
		DeleteObject(hFillBr);
	}
	else
	{
		if (!hDib || !pBits)
		{
			_ASSERTE(hDib && pBits);
			if (hDib)
				DeleteObject(hDib);
			if (hdc)
				DeleteDC(hdc);
			return;
		}

		hOld = (HBITMAP)SelectObject(hdc, hDib);

		// Залить черным - по умолчанию
		#ifdef _DEBUG
			memset(pBits, 128, bi.biWidth*bi.biHeight*4); //-V112
		#else
			memset(pBits, 0, bi.biWidth*bi.biHeight*4);
		#endif
	}

	// Painting!
	int nProcessed = 0;
	MSectionLock SC; SC.Lock(csBgPlugins, TRUE);
	DWORD nFromLevel = 0, nNextLevel, nSuggested;
	DWORD dwDrawnPlaces = Arg.Place;

	while(true)
	{
		nNextLevel = nFromLevel;
		struct RegisterBackgroundArg *p = mp_BgPlugins;

		for(int i = 0; i < mn_BgPluginsCount; i++, p++)
		{
			if (p->Cmd != rbc_Register ||
			        !(p->dwPlaces & Arg.Place) ||
			        !(p->PaintConEmuBackground))
				continue; // пустая, неактивная в данном контексте, или некорректная ячейка

			// Слои
			nSuggested = p->dwSuggestedLevel;

			if (nSuggested < nFromLevel)
			{
				continue; // Этот слой уже обработан
			}
			else if (nSuggested > nFromLevel)
			{
				// Этот слой нужно будет обработать в следующий раз
				if ((nNextLevel == nFromLevel) || (nSuggested < nNextLevel))
					nNextLevel = nSuggested;

				continue;
			}

			// На уровне 0 (заливающий фон) должен быть только один плагин
			Arg.dwLevel = (nProcessed == 0) ? 0 : (nFromLevel == 0 && nProcessed) ? 1 : nFromLevel;
			Arg.lParam = mp_BgPlugins[i].lParam;
			Arg.dwDrawnPlaces = 0;
			//mp_BgPlugins[i].PaintConEmuBackground(&Arg);
			UpdateBackground_Exec(mp_BgPlugins+i, &Arg);
			// Что плагин покрасил (панели/редактор/вьювер считаются покрашенными по умолчанию)
			dwDrawnPlaces |= Arg.dwDrawnPlaces;
			//
			nProcessed++;
		}

		if (nNextLevel == nFromLevel)
			break; // больше слоев нет

		nFromLevel = nNextLevel;
	}

	SC.Unlock();
	// Sending background to GUI!

	if (nProcessed < 1)
	{
		// Ситуация возникает при старте ConEmu, когда панелей "еще нет"
		//_ASSERTE(nProcessed >= 1);
		if (mb_BgWasSent)
		{
			mb_BgWasSent = FALSE;
			CESERVER_REQ *pIn = ExecuteNewCmd(CECMD_SETBACKGROUND, sizeof(CESERVER_REQ_HDR)+sizeof(CESERVER_REQ_SETBACKGROUND));
			if (pIn)
			{
				pIn->Background.nType = 1;
				pIn->Background.bEnabled = FALSE;
				pIn->Background.dwDrawnPlaces = 0;
				CESERVER_REQ *pOut = ExecuteGuiCmd(FarHwnd, pIn, FarHwnd);

				if (pOut)
				{
					ExecuteFreeResult(pOut);
				}
				ExecuteFreeResult(pIn);
			}
		}
	}
	else // есть "отработавшие" плагины, обновить Background!
	{
		GdiFlush();
		DWORD nBitSize = 0, nBitsError = 0;
		if (SETBACKGROUND_USE_EMF==1)
		{
			hEmf = CloseEnhMetaFile(hdc);
			hdc = NULL;

			nBitSize = GetEnhMetaFileBits(hEmf, 0, NULL);
			if (nBitSize == 0)
			{
				dwDrawnPlaces = 0;
				nBitsError = GetLastError();
				_ASSERTE(nBitSize!=0);
				if (hEmf)
				{
					// В случае ошибки - сразу удаляем
					DeleteEnhMetaFile(hEmf);
					hEmf = NULL;
				}
			}
		}
		else
		{
			nBitSize = bi.biWidth*bi.biHeight*sizeof(COLORREF);
		}
		DWORD nWholeSize = sizeof(CESERVER_REQ_HDR)+sizeof(CESERVER_REQ_SETBACKGROUND)+nBitSize; //-V103 //-V119
		CESERVER_REQ *pIn = ExecuteNewCmd(CECMD_SETBACKGROUND, nWholeSize);

		if (!pIn)
		{
			_ASSERTE(pIn);
		}
		else
		{
			pIn->Background.nType = 1;
			pIn->Background.bEnabled = TRUE;
			pIn->Background.dwDrawnPlaces = dwDrawnPlaces;
			if (SETBACKGROUND_USE_EMF==1)
				pIn->Background.bmp.bfType = 0x4645/*EF*/;
			else
				pIn->Background.bmp.bfType = 0x4D42/*BM*/;
			pIn->Background.bmp.bfSize = nBitSize+sizeof(BITMAPFILEHEADER)+sizeof(BITMAPINFOHEADER); //-V119
			pIn->Background.bmp.bfOffBits = sizeof(BITMAPFILEHEADER)+sizeof(BITMAPINFOHEADER); //-V119
			pIn->Background.bi = bi;

			if (SETBACKGROUND_USE_EMF==1)
			{
				LPBYTE pBits = ((LPBYTE)&pIn->Background)+sizeof(pIn->Background);
				DWORD nBitsRc = (nBitSize && hEmf) ? GetEnhMetaFileBits(hEmf, nBitSize, pBits) : 0;
				_ASSERTE(nBitsRc == nBitSize);
				if (!nBitsRc)
				{
					_ASSERTE(nBitsRc!=NULL);
					// Отключить нафиг
					ExecutePrepareCmd(&pIn->hdr, CECMD_SETBACKGROUND, nWholeSize-nBitSize);
					pIn->Background.nType = 1;
					pIn->Background.bEnabled = FALSE;
					pIn->Background.dwDrawnPlaces = 0;
				}
			}
			else
			{
				memmove(((LPBYTE)&pIn->Background)+sizeof(pIn->Background), pBits, bi.biWidth*bi.biHeight*sizeof(COLORREF));
			}
			CESERVER_REQ *pOut = ExecuteGuiCmd(FarHwnd, pIn, FarHwnd);

			// Вызывается ТОЛЬКО в главной нити
			_ASSERTE(GetCurrentThreadId() == gnMainThreadId);
			if (pOut)
			{
				mb_BgWasSent = TRUE;
				// Сбросим флажок "Ошибка уже была показана"
				if (pOut->BackgroundRet.nResult == esbr_OK)
				{
					mb_BgErrorShown = FALSE;
				}
				// Показать ошибку, если есть
				else if ((pOut->BackgroundRet.nResult > esbr_OK) && (pOut->BackgroundRet.nResult <= esbr_LastErrorNo)
					&& (pOut->BackgroundRet.nResult != esbr_ConEmuInShutdown)
					&& !mb_BgErrorShown)
				{
					mb_BgErrorShown = TRUE;
					Plugin()->ShowMessage(CEBkError_ExecFailed+pOut->BackgroundRet.nResult, 0);
				}
				ExecuteFreeResult(pOut);
			}
			else if (!mb_BgErrorShown)
			{
				mb_BgErrorShown = TRUE;
				Plugin()->ShowMessage(CEBkError_ExecFailed, 0);
			}

			ExecuteFreeResult(pIn);
		}
	}

	if (SETBACKGROUND_USE_EMF == 0)
	{
		if (hdc && hOld)
			SelectObject(hdc, hOld);
		if (hDib)
			DeleteObject(hDib);
		if (hdc)
			DeleteDC(hdc);
	}
	else
	{
		if (hdc)
		{
			hEmf = CloseEnhMetaFile(hdc);
			hdc = NULL;
		}
		if (hEmf)
		{
			DeleteEnhMetaFile(hEmf);
			hEmf = NULL;
		}
	}
}
예제 #12
0
int CPluginBackground::RegisterSubplugin(RegisterBackgroundArg *pbk)
{
	if (!pbk)
	{
		_ASSERTE(pbk != NULL);
		return esbr_InvalidArg;
	}

	if (!gbBgPluginsAllowed)
	{
		_ASSERTE(gbBgPluginsAllowed == TRUE);
		return esbr_PluginForbidden;
	}

	if (pbk->cbSize != sizeof(*pbk))
	{
		_ASSERTE(pbk->cbSize == sizeof(*pbk));
		return esbr_InvalidArgSize;
	}

	if (pbk->Cmd == rbc_Register)
	{
		BOOL lbCheckCallback = CheckCallbackPtr(pbk->hPlugin, 1, (FARPROC*)&pbk->PaintConEmuBackground, TRUE, FALSE, FALSE);

		if (!lbCheckCallback)
		{
			_ASSERTE(lbCheckCallback==TRUE);
			return esbr_InvalidArgProc;
		}
	}

	MSectionLock SC; SC.Lock(csBgPlugins, TRUE);

	// Выделение памяти под плагины
	if (mp_BgPlugins == NULL || (mn_BgPluginsCount == mn_BgPluginsMax))
		ReallocItems(16);

	// go
	//BOOL lbNeedResort = FALSE;

	if (pbk->Cmd == rbc_Register)
	{
		// Память уже выделена
		int nFound = -1, nFirstEmpty = -1;

		for(int i = 0; i < mn_BgPluginsCount; i++)
		{
			if (mp_BgPlugins[i].Cmd == rbc_Register &&
			        mp_BgPlugins[i].hPlugin == pbk->hPlugin &&
			        mp_BgPlugins[i].PaintConEmuBackground == pbk->PaintConEmuBackground &&
			        mp_BgPlugins[i].lParam == pbk->lParam)
			{
				nFound = i; break;
			}

			if (nFirstEmpty == -1 && 0 == (int)mp_BgPlugins[i].Cmd)
				nFirstEmpty = i;
		}

		if (nFound == -1)
		{
			if (nFirstEmpty >= 0)
				nFound = nFirstEmpty;
			else
				nFound = mn_BgPluginsCount++;

			//lbNeedResort = (mn_BgPluginsCount>1);
		}

		mp_BgPlugins[nFound] = *pbk;
	}
	else if (pbk->Cmd == rbc_Unregister)
	{
		for(int i = 0; i < mn_BgPluginsCount; i++)
		{
			if (mp_BgPlugins[i].Cmd == rbc_Register &&
			        mp_BgPlugins[i].hPlugin == pbk->hPlugin &&
			        ((pbk->PaintConEmuBackground == NULL) ||
			         (mp_BgPlugins[i].PaintConEmuBackground == pbk->PaintConEmuBackground
			          && mp_BgPlugins[i].lParam == pbk->lParam)))
			{
				memset(mp_BgPlugins+i, 0, sizeof(*mp_BgPlugins));
				//lbNeedResort = TRUE;
			}
		}

		WARNING("Если количество зарегистрированных плагинов уменьшилось до 0");
		// Послать в GUI CECMD_SETBACKGROUND{bEnabled = FALSE}
		// Проверить, чтобы не было противного мелькания при закрытии FAR
	}
	else if (pbk->Cmd == rbc_Redraw)
	{
		// просто выставить gbNeedBgActivate
	}

	////TODO: Сортировка
	//if (lbNeedResort)
	//{
	//	WARNING("Сортировка зарегистрированных плагинов - CPluginBackground::RegisterBackground");
	//}
	SC.Unlock();
	// Когда активируется MainThread - обновить background
	mn_ReqActions |= ra_UpdateBackground;
	gbNeedBgActivate = TRUE;

	// В фар2 сразу дернем Synchro
	if (IS_SYNCHRO_ALLOWED)
	{
		Plugin()->ExecuteSynchro();
	}

	return esbr_OK;
}
예제 #13
0
bool CConEmuUpdate::StartLocalUpdate(LPCWSTR asDownloadedPackage)
{
	bool bRc = false;
	LPCWSTR pszName, pszExt;
	HANDLE hTarget = NULL;
	wchar_t *pszLocalPackage = NULL, *pszBatchFile = NULL;
	DWORD nLocalCRC = 0;
	BOOL lbDownloadRc = FALSE, lbExecuteRc = FALSE;

	LPCWSTR pszPackPref = L"conemupack.";
	size_t lnPackPref = _tcslen(pszPackPref);
	LPCWSTR pszSetupPref = L"conemusetup.";
	size_t lnSetupPref = _tcslen(pszSetupPref);

	_ASSERTE(gpConEmu && gpConEmu->isMainThread());

	if (InUpdate() != us_NotStarted)
	{
		MBoxError(L"Checking for updates already started");
		goto wrap;
	}

	if (mb_InCheckProcedure)
	{
		Assert(mb_InCheckProcedure==FALSE);
		goto wrap;
	}

	DeleteBadTempFiles();
	Inet.Deinit(true);

	pszName = PointToName(asDownloadedPackage);
	pszExt = PointToExt(pszName);
	if (!pszName || !*pszName || !pszExt || !*pszExt)
	{
		AssertMsg(L"Invalid asDownloadedPackage");
		goto wrap;
	}

	// Запомнить текущие параметры обновления
	if (!mp_Set)
		mp_Set = new ConEmuUpdateSettings;
	mp_Set->LoadFrom(&gpSet->UpdSet);

	mb_ManualCallMode = TRUE;

	// Clear possible last error
	{
		MSectionLock SC; SC.Lock(mp_LastErrorSC, TRUE);
		SafeFree(ms_LastErrorInfo);
	}

	ms_NewVersion[0] = 0;

	if ((lstrcmpni(pszName, pszPackPref, lnPackPref) == 0)
		&& (lstrcmpi(pszExt, L".7z") == 0)
		&& (((pszExt - pszName) - lnPackPref + 1) < sizeof(ms_NewVersion)))
	{
		// Check it was NOT installed with "Setupper"
		if (mp_Set->UpdateDownloadSetup() == 1)
		{
			DontEnable de;
			LPCWSTR pszConfirm = L"ConEmu was installed with setup!\nAre you sure to update installation with 7zip?";
			int iBtn = MessageBox(NULL, pszConfirm, ms_DefaultTitle, MB_ICONEXCLAMATION|MB_SETFOREGROUND|MB_SYSTEMMODAL|MB_YESNO|MB_DEFBUTTON2);
			if (iBtn != IDYES)
			{
				goto wrap;
			}
		}

		if (!Check7zipInstalled())
			goto wrap; // Error already reported

		// Forcing usage of 7zip package!
		mp_Set->isUpdateDownloadSetup = 2;

		//if (!CanUpdateInstallation())
		//{
		//	// Значит 7zip обломается при попытке распаковки
		//	goto wrap;
		//}

		// OK
		size_t nLen = (pszExt - pszName) - lnPackPref;
		wmemmove(ms_NewVersion, pszName+lnPackPref, nLen);
		ms_NewVersion[nLen] = 0;
	}
	else if ((lstrcmpni(pszName, pszSetupPref, lnSetupPref) == 0)
		&& (lstrcmpi(pszExt, L".exe") == 0)
		&& (((pszExt - pszName) - lnSetupPref + 1) < sizeof(ms_NewVersion)))
	{
		// Must be installed with "Setupper"
		if (mp_Set->UpdateDownloadSetup() != 1)
		{
			MBoxError(L"ConEmu was not installed with setup! Can't update!");
			goto wrap;
		}

		// OK
		size_t nLen = (pszExt - pszName) - lnSetupPref;
		wmemmove(ms_NewVersion, pszName+lnSetupPref, nLen);
		ms_NewVersion[nLen] = 0;
	}
	else
	{
		AssertMsg(L"Invalid asDownloadedPackage (2)");
		goto wrap;
	}


	// Сразу проверим, как нужно будет запускаться
	bNeedRunElevation = NeedRunElevation();

	_wsprintf(ms_CurVersion, SKIPLEN(countof(ms_CurVersion)) L"%02u%02u%02u%s", (MVV_1%100),MVV_2,MVV_3,_T(MVV_4a));
	//ms_NewVersion

	// StartLocalUpdate - запуск обновления из локального пакета

	mb_InetMode = false;
	mb_DroppedMode = true;



	pszLocalPackage = CreateTempFile(mp_Set->szUpdateDownloadPath, PointToName(asDownloadedPackage), hTarget);
	if (!pszLocalPackage)
		goto wrap;

	lbDownloadRc = DownloadFile(asDownloadedPackage, pszLocalPackage, hTarget, nLocalCRC, TRUE);
	CloseHandle(hTarget);
	if (!lbDownloadRc)
		goto wrap;


	if (mb_RequestTerminate)
		goto wrap;

	pszBatchFile = CreateBatchFile(pszLocalPackage);
	if (!pszBatchFile)
		goto wrap;

	if (!QueryConfirmation(us_ConfirmUpdate))
	{
		goto wrap;
	}

	Assert(mb_ManualCallMode==TRUE);
	Assert(mpsz_PendingBatchFile==NULL);

	mpsz_PendingPackageFile = pszLocalPackage;
	pszLocalPackage = NULL;
	mpsz_PendingBatchFile = pszBatchFile;
	pszBatchFile = NULL;
	m_UpdateStep = us_ExitAndUpdate;
	if (gpConEmu)
		gpConEmu->RequestExitUpdate();
	lbExecuteRc = TRUE;

wrap:
	_ASSERTE(mpsz_DeleteIniFile==NULL);

	_ASSERTE(mpsz_DeletePackageFile==NULL);
	mpsz_DeletePackageFile = NULL;
	if (pszLocalPackage)
	{
		if (*pszLocalPackage && (!lbDownloadRc || (!lbExecuteRc && !mp_Set->isUpdateLeavePackages)))
			mpsz_DeletePackageFile = pszLocalPackage;
			//DeleteFile(pszLocalPackage);
		else
			SafeFree(pszLocalPackage);
	}

	_ASSERTE(mpsz_DeleteBatchFile==NULL);
	mpsz_DeleteBatchFile = NULL;
	if (pszBatchFile)
	{
		if (*pszBatchFile && !lbExecuteRc)
			mpsz_DeleteBatchFile = pszBatchFile;
			//DeleteFile(pszBatchFile);
		else
			SafeFree(pszBatchFile);
	}

	if (!lbExecuteRc)
	{
		m_UpdateStep = us_NotStarted;
		mb_DroppedMode = false;
	}

	return bRc;
}
예제 #14
0
void CConEmuUpdate::StartCheckProcedure(BOOL abShowMessages)
{
	//DWORD nWait = WAIT_OBJECT_0;

	if (InUpdate() != us_NotStarted)
	{
		// Already in update procedure
		if (m_UpdateStep == us_ExitAndUpdate)
		{
			if (gpConEmu)
			{
				// Повторно?
				gpConEmu->RequestExitUpdate();
			}
		}
		else if (abShowMessages)
		{
			MBoxError(L"Checking for updates already started");
		}
		return;
	}

	gpSet->UpdSet.dwLastUpdateCheck = GetTickCount();

	// Сразу проверим, как нужно будет запускаться
	bNeedRunElevation = NeedRunElevation();

	mb_RequestTerminate = false;
	//if (!mh_StopThread)
	//	mh_StopThread = CreateEvent(NULL, TRUE/*manual*/, FALSE, NULL);
	//ResetEvent(mh_StopThread);

	// Запомнить текущие параметры обновления
	if (!mp_Set)
		mp_Set = new ConEmuUpdateSettings;
	mp_Set->LoadFrom(&gpSet->UpdSet);

	mb_ManualCallMode = abShowMessages;
	{
		MSectionLock SC; SC.Lock(mp_LastErrorSC, TRUE);
		SafeFree(ms_LastErrorInfo);
	}

	wchar_t szReason[128];
	if (!mp_Set->UpdatesAllowed(szReason))
	{
		wchar_t szErrMsg[255]; wcscpy_c(szErrMsg, L"Updates are not enabled in ConEmu settings\r\n");
		wcscat_c(szErrMsg, szReason);
		DisplayLastError(szErrMsg, -1);
		return;
	}

	mb_InCheckProcedure = TRUE;	
	mh_CheckThread = CreateThread(NULL, 0, CheckThreadProc, this, 0, &mn_CheckThreadId);
	if (!mh_CheckThread)
	{
		mb_InCheckProcedure = FALSE;
		DWORD nErrCode = GetLastError();
		wchar_t szErrMsg[255]; wcscpy_c(szErrMsg, L"ConEmu automatic update check failed!\r\n");
		if (nErrCode == ERROR_ACCESS_DENIED) wcscat_c(szErrMsg, L"Check your antivirus software\r\n");
		wcscat_c(szErrMsg, L"\r\nCreateThread(CheckThreadProc) failed\r\n");
		DisplayLastError(szErrMsg, nErrCode);
		return;
	}
	// OK
}
예제 #15
0
BOOL WINAPI PlugServerCommand(LPVOID pInst, CESERVER_REQ* pIn, CESERVER_REQ* &ppReply, DWORD &pcbReplySize, DWORD &pcbMaxReplySize, LPARAM lParam)
{
	BOOL lbRc = FALSE;
	//HANDLE hPipe = (HANDLE)ahPipe;
	//CESERVER_REQ *pIn=NULL;
	//BYTE cbBuffer[64]; // Для большей части команд нам хватит
	//DWORD cbRead = 0, cbWritten = 0, dwErr = 0;
	BOOL fSuccess = FALSE;
	MSectionThread SCT(csTabs);
	// Send a message to the pipe server and read the response.
	//fSuccess = ReadFile(hPipe, cbBuffer, sizeof(cbBuffer), &cbRead, NULL);
	//dwErr = GetLastError();

	//if (!fSuccess && (dwErr != ERROR_MORE_DATA))
	//{
	//	_ASSERTE("ReadFile(pipe) failed"==NULL);
	//	CloseHandle(hPipe);
	//	return 0;
	//}

	//pIn = (CESERVER_REQ*)cbBuffer; // Пока cast, если нужно больше - выделим память
	//_ASSERTE(pIn->hdr.cbSize>=sizeof(CESERVER_REQ_HDR) && cbRead>=sizeof(CESERVER_REQ_HDR));
	//_ASSERTE(pIn->hdr.nVersion == CESERVER_REQ_VER);

	if (pIn->hdr.cbSize < sizeof(CESERVER_REQ_HDR) || /*in.nSize < cbRead ||*/ pIn->hdr.nVersion != CESERVER_REQ_VER)
	{
		//CloseHandle(hPipe);
		gpPlugServer->BreakConnection(pInst);
		return FALSE;
	}

	//int nAllSize = pIn->hdr.cbSize;
	//pIn = (CESERVER_REQ*)Alloc(nAllSize,1);
	//_ASSERTE(pIn!=NULL);

	//if (!pIn)
	//{
	//	CloseHandle(hPipe);
	//	return 0;
	//}

	//memmove(pIn, cbBuffer, cbRead);
	//_ASSERTE(pIn->hdr.nVersion==CESERVER_REQ_VER);
	//LPBYTE ptrData = ((LPBYTE)pIn)+cbRead;
	//nAllSize -= cbRead;

	//while(nAllSize>0)
	//{
	//	//_tprintf(TEXT("%s\n"), chReadBuf);

	//	// Break if TransactNamedPipe or ReadFile is successful
	//	if (fSuccess)
	//		break;

	//	// Read from the pipe if there is more data in the message.
	//	fSuccess = ReadFile(
	//	               hPipe,      // pipe handle
	//	               ptrData,    // buffer to receive reply
	//	               nAllSize,   // size of buffer
	//	               &cbRead,    // number of bytes read
	//	               NULL);      // not overlapped

	//	// Exit if an error other than ERROR_MORE_DATA occurs.
	//	if (!fSuccess && ((dwErr = GetLastError()) != ERROR_MORE_DATA))
	//		break;

	//	ptrData += cbRead;
	//	nAllSize -= cbRead;
	//}

	//TODO("Может возникнуть ASSERT, если консоль была закрыта в процессе чтения");
	//_ASSERTE(nAllSize==0);

	//if (nAllSize>0)
	//{
	//	if (((LPVOID)cbBuffer) != ((LPVOID)pIn))
	//		Free(pIn);

	//	CloseHandle(hPipe);
	//	return 0; // удалось считать не все данные
	//}

	UINT nDataSize = pIn->hdr.cbSize - sizeof(CESERVER_REQ_HDR);

	// Все данные из пайпа получены, обрабатываем команду и возвращаем (если нужно) результат
	//fSuccess = WriteFile( hPipe, pOut, pOut->nSize, &cbWritten, NULL);

	if (pIn->hdr.nCmd == CMD_LANGCHANGE)
	{
		_ASSERTE(nDataSize>=4); //-V112
		// LayoutName: "00000409", "00010409", ...
		// А HKL от него отличается, так что передаем DWORD
		// HKL в x64 выглядит как: "0x0000000000020409", "0xFFFFFFFFF0010409"
		DWORD hkl = pIn->dwData[0];
		DWORD dwLastError = 0;
		HKL hkl1 = NULL, hkl2 = NULL;

		if (hkl)
		{
			WCHAR szLoc[10]; _wsprintf(szLoc, SKIPLEN(countof(szLoc)) L"%08x", hkl);
			hkl1 = LoadKeyboardLayout(szLoc, KLF_ACTIVATE|KLF_REORDER|KLF_SUBSTITUTE_OK|KLF_SETFORPROCESS);
			hkl2 = ActivateKeyboardLayout(hkl1, KLF_SETFORPROCESS|KLF_REORDER);

			if (!hkl2)
				dwLastError = GetLastError();
			else
				fSuccess = TRUE;
		}

		pcbReplySize = sizeof(CESERVER_REQ_HDR) + sizeof(DWORD)*2;
		if (ExecuteNewCmd(ppReply, pcbMaxReplySize, pIn->hdr.nCmd, pcbReplySize))
		{
			lbRc = TRUE;
			ppReply->dwData[0] = fSuccess;
			ppReply->dwData[1] = fSuccess ? ((DWORD)(LONG)(LONG_PTR)hkl2) : dwLastError;
		}

	}
	//} else if (pIn->hdr.nCmd == CMD_DEFFONT) {
	//	// исключение - асинхронный, результат не требуется
	//	SetConsoleFontSizeTo(FarHwnd, 4, 6);
	//	MoveWindow(FarHwnd, 0, 0, GetSystemMetrics(SM_CXSCREEN), GetSystemMetrics(SM_CYSCREEN), 1); // чтобы убрать возможные полосы прокрутки...
	else if (pIn->hdr.nCmd == CMD_REQTABS || pIn->hdr.nCmd == CMD_SETWINDOW)
	{
		MSectionLock SC; SC.Lock(csTabs, FALSE, 1000);
		DWORD nSetWindowWait = (DWORD)-1;

		if (pIn->hdr.nCmd == CMD_SETWINDOW)
		{
			ResetEvent(ghSetWndSendTabsEvent);

			// Для FAR2 - сброс QSearch выполняется в том же макро, в котором актирируется окно
			if (gFarVersion.dwVerMajor == 1 && pIn->dwData[1])
			{
				// А вот для FAR1 - нужно шаманить
				ProcessCommand(CMD_CLOSEQSEARCH, TRUE/*bReqMainThread*/, pIn->dwData/*хоть и не нужно?*/);
			}

			// Пересылается 2 DWORD
			BOOL bCmdRc = ProcessCommand(pIn->hdr.nCmd, TRUE/*bReqMainThread*/, pIn->dwData);

			DEBUGSTRCMD(L"Plugin: PlugServerThreadCommand: CMD_SETWINDOW waiting...\n");

			WARNING("Почему для FAR1 не ждем? Есть возможность заблокироваться в 1.7 или что?");
			if ((gFarVersion.dwVerMajor >= 2) && bCmdRc)
			{
				DWORD nTimeout = 2000;
				#ifdef _DEBUG
				if (IsDebuggerPresent()) nTimeout = 120000;
				#endif
				
				nSetWindowWait = WaitForSingleObject(ghSetWndSendTabsEvent, nTimeout);
			}

			DEBUGSTRCMD(L"Plugin: PlugServerThreadCommand: CMD_SETWINDOW finished\n");
		}

		if (gpTabs)
		{
			//fSuccess = WriteFile(hPipe, gpTabs, gpTabs->hdr.cbSize, &cbWritten, NULL);
			pcbReplySize = gpTabs->hdr.cbSize;
			if (ExecuteNewCmd(ppReply, pcbMaxReplySize, pIn->hdr.nCmd, pcbReplySize))
			{
				memmove(ppReply->Data, gpTabs->Data, pcbReplySize - sizeof(ppReply->hdr));
				lbRc = TRUE;
			}
		}

		SC.Unlock();
	}
	else if (pIn->hdr.nCmd == CMD_FARSETCHANGED)
	{
		// Установить переменные окружения
		// Плагин это получает в ответ на CECMD_RESOURCES, посланное в GUI при загрузке плагина
		_ASSERTE(nDataSize>=8);
		FAR_REQ_FARSETCHANGED *pFarSet = (FAR_REQ_FARSETCHANGED*)pIn->Data;

		cmd_FarSetChanged(pFarSet);

		pcbReplySize = sizeof(CESERVER_REQ_HDR) + sizeof(DWORD);
		if (ExecuteNewCmd(ppReply, pcbMaxReplySize, pIn->hdr.nCmd, pcbReplySize))
		{
			lbRc = TRUE;
			ppReply->dwData[0] = TRUE;
		}

		//_ASSERTE(nDataSize<sizeof(gsMonitorEnvVar));
		//gbMonitorEnvVar = false;
		//// Плагин FarCall "нарушает" COMSPEC (копирует содержимое запускаемого процесса)
		//bool lbOk = false;

		//if (nDataSize<sizeof(gsMonitorEnvVar))
		//{
		//	memcpy(gsMonitorEnvVar, pszName, nDataSize);
		//	lbOk = true;
		//}

		//UpdateEnvVar(pszName);
		////while (*pszName && *pszValue) {
		////	const wchar_t* pszChanged = pszValue;
		////	// Для ConEmuOutput == AUTO выбирается по версии ФАРа
		////	if (!lstrcmpi(pszName, L"ConEmuOutput") && !lstrcmp(pszChanged, L"AUTO")) {
		////		if (gFarVersion.dwVerMajor==1)
		////			pszChanged = L"ANSI";
		////		else
		////			pszChanged = L"UNICODE";
		////	}
		////	// Если в pszValue пустая строка - удаление переменной
		////	SetEnvironmentVariableW(pszName, (*pszChanged != 0) ? pszChanged : NULL);
		////	//
		////	pszName = pszValue + lstrlenW(pszValue) + 1;
		////	if (*pszName == 0) break;
		////	pszValue = pszName + lstrlenW(pszName) + 1;
		////}
		//gbMonitorEnvVar = lbOk;
	}
	else if (pIn->hdr.nCmd == CMD_DRAGFROM)
	{
		#ifdef _DEBUG
		BOOL  *pbClickNeed = (BOOL*)pIn->Data;
		COORD *crMouse = (COORD *)(pbClickNeed+1);
		#endif

		ProcessCommand(CMD_LEFTCLKSYNC, TRUE/*bReqMainThread*/, pIn->Data);
		CESERVER_REQ* pCmdRet = NULL;
		ProcessCommand(pIn->hdr.nCmd, TRUE/*bReqMainThread*/, pIn->Data, &pCmdRet);

		if (pCmdRet)
		{
			//fSuccess = WriteFile(hPipe, pCmdRet, pCmdRet->hdr.cbSize, &cbWritten, NULL);
			pcbReplySize = pCmdRet->hdr.cbSize;
			if (ExecuteNewCmd(ppReply, pcbMaxReplySize, pIn->hdr.nCmd, pcbReplySize))
			{
				lbRc = TRUE;
				memmove(ppReply->Data, pCmdRet->Data, pCmdRet->hdr.cbSize - sizeof(ppReply->hdr));
			}
			Free(pCmdRet);
		}

		//if (gpCmdRet && gpCmdRet == pCmdRet)
		//{
		//	Free(gpCmdRet);
		//	gpCmdRet = NULL; gpData = NULL; gpCursor = NULL;
		//}
	}
	else if (pIn->hdr.nCmd == CMD_EMENU)
	{
		COORD *crMouse = (COORD *)pIn->Data;
#ifdef _DEBUG
		const wchar_t *pszUserMacro = (wchar_t*)(crMouse+1);
#endif
		DWORD ClickArg[2] = {TRUE, MAKELONG(crMouse->X, crMouse->Y)};
		
		// Выделить файл под курсором
		DEBUGSTRMENU(L"\n*** ServerThreadCommand->ProcessCommand(CMD_LEFTCLKSYNC) begin\n");
		BOOL lb1 = ProcessCommand(CMD_LEFTCLKSYNC, TRUE/*bReqMainThread*/, ClickArg/*pIn->Data*/);
		DEBUGSTRMENU(L"\n*** ServerThreadCommand->ProcessCommand(CMD_LEFTCLKSYNC) done\n");

		// А теперь, собственно вызовем меню
		DEBUGSTRMENU(L"\n*** ServerThreadCommand->ProcessCommand(CMD_EMENU) begin\n");
		BOOL lb2 = ProcessCommand(pIn->hdr.nCmd, TRUE/*bReqMainThread*/, pIn->Data);
		DEBUGSTRMENU(L"\n*** ServerThreadCommand->ProcessCommand(CMD_EMENU) done\n");

		pcbReplySize = sizeof(CESERVER_REQ_HDR) + sizeof(DWORD)*2;
		if (ExecuteNewCmd(ppReply, pcbMaxReplySize, pIn->hdr.nCmd, pcbReplySize))
		{
			lbRc = TRUE;
			ppReply->dwData[0] = lb1;
			ppReply->dwData[1] = lb1;
		}
	}
	else if (pIn->hdr.nCmd == CMD_ACTIVEWNDTYPE)
	{
		int nWindowType = -1;
		//CESERVER_REQ Out;
		//ExecutePrepareCmd(&Out, CMD_ACTIVEWNDTYPE, sizeof(CESERVER_REQ_HDR)+sizeof(DWORD));

		if (gFarVersion.dwVerMajor>=2)
			nWindowType = GetActiveWindowType();

		//fSuccess = WriteFile(hPipe, &Out, Out.hdr.cbSize, &cbWritten, NULL);

		pcbReplySize = sizeof(CESERVER_REQ_HDR) + sizeof(DWORD);
		if (ExecuteNewCmd(ppReply, pcbMaxReplySize, pIn->hdr.nCmd, pcbReplySize))
		{
			lbRc = TRUE;
			ppReply->dwData[0] = nDataSize;
		}		
	}
	else
	{
		CESERVER_REQ* pCmdRet = NULL;
		BOOL lbCmd = ProcessCommand(pIn->hdr.nCmd, TRUE/*bReqMainThread*/, pIn->Data, &pCmdRet);

		if (pCmdRet)
		{
			//fSuccess = WriteFile(hPipe, pCmdRet, pCmdRet->hdr.cbSize, &cbWritten, NULL);
			pcbReplySize = pCmdRet->hdr.cbSize;
			if (ExecuteNewCmd(ppReply, pcbMaxReplySize, pIn->hdr.nCmd, pcbReplySize))
			{
				lbRc = TRUE;
				memmove(ppReply->Data, pCmdRet->Data, pCmdRet->hdr.cbSize - sizeof(ppReply->hdr));
			}
			Free(pCmdRet);
		}

		//if (gpCmdRet && gpCmdRet == pCmdRet) {
		//	Free(gpCmdRet);
		//	gpCmdRet = NULL; gpData = NULL; gpCursor = NULL;
		//}
	}

	//// Освободить память
	//if (((LPVOID)cbBuffer) != ((LPVOID)pIn))
	//	Free(pIn);

	//CloseHandle(hPipe);
	return lbRc;
}