OMX_ERRORTYPE VideoFilter::ComponentReturnBuffer(OMX_U32 nPortIndex)
{
    if(nPortIndex == IN_PORT)
    {
        FlushInputBuffer();
        ReturnInputBuffer();
    }

    if(nPortIndex == OUT_PORT)
    {
        FlushOutputBuffer();
        while(1)
        {
            OMX_BUFFERHEADERTYPE *pBufferHdr = NULL;
            pBufferHdr = GetFirstOutBufferHdrFromList();
            if(pBufferHdr == NULL)
                break;
            ports[OUT_PORT]->SendBuffer(pBufferHdr);
        }
        bNeedOutBuffer = OMX_TRUE;
    }

    bInReturnBufferState = OMX_FALSE;

    return OMX_ErrorNone;
}
OMX_ERRORTYPE VideoFilter::FlushComponent(OMX_U32 nPortIndex)
{
    LOG_DEBUG("Flush filter port: %d\n", (int)nPortIndex);

    if(nPortIndex == IN_PORT)
    {
        FlushInputBuffer();
        ReturnInputBuffer();
        bLastInput = OMX_FALSE;
        bLastOutput = OMX_FALSE;
        nDecodeOnly = 0;
        bGetNewSegment = OMX_TRUE;
    }

    if(nPortIndex == OUT_PORT)
    {
        FlushOutputBuffer();
        while(1)
        {
            OMX_BUFFERHEADERTYPE *pBufferHdr = NULL;
            pBufferHdr = GetFirstOutBufferHdrFromList();
            if(pBufferHdr == NULL)
                break;
            ports[OUT_PORT]->SendBuffer(pBufferHdr);
        }
        bNeedOutBuffer = OMX_TRUE;
    }

    return OMX_ErrorNone;
}
예제 #3
0
파일: scrsaver.cpp 프로젝트: elfmz/far2l
int ScreenSaver(int EnableExit)
{
	INPUT_RECORD rec;
	clock_t WaitTime;

	if (ScreenSaverActive)
		return 1;

	ChangePriority ChPriority(ChangePriority::IDLE);

	for (WaitTime=GetProcessUptimeMSec(); GetProcessUptimeMSec()-WaitTime<500;)
	{
		if (PeekInputRecord(&rec))
			return 1;

		WINPORT(Sleep)(100);
	}

	ScreenSaverActive=TRUE;
	CONSOLE_CURSOR_INFO CursorInfo;
	Console.GetCursorInfo(CursorInfo);
	{
		SaveScreen SaveScr;
		SetCursorType(0,10);
		randomize();
		SetScreen(0,0,ScrX,ScrY,L' ',F_LIGHTGRAY|B_BLACK);

		for (size_t I=0; I<ARRAYSIZE(Star); I++)
		{
			Star[I].Type=STAR_NONE;
			Star[I].Color=0;
		}

		int Step=0;

		while (!PeekInputRecord(&rec))
		{
			clock_t CurTime=GetProcessUptimeMSec();

			if (EnableExit && Opt.InactivityExit && Opt.InactivityExitTime>0 &&
			        CurTime-StartIdleTime>Opt.InactivityExitTime*60000 &&
			        FrameManager->GetFrameCount()==1)
			{
				FrameManager->ExitMainLoop(FALSE);
				return 0;
			}

			WINPORT(Sleep)(50);
			ShowSaver(Step++);
		}
	}
	SetCursorType(CursorInfo.bVisible!=FALSE, CursorInfo.dwSize);
	ScreenSaverActive=FALSE;
	FlushInputBuffer();
	StartIdleTime=GetProcessUptimeMSec();
	return 1;
}
예제 #4
0
파일: grabber.cpp 프로젝트: alexlav/conemu
bool RunGraber()
{
	static bool InGrabber=false;

	if (!InGrabber)
	{
		InGrabber=true;
		WaitInMainLoop=FALSE;
		FlushInputBuffer();
		Grabber Grabber;
		InGrabber=false;
		return true;
	}

	return false;
}
예제 #5
0
void FileList::ReadFileNames(int KeepSelection, int IgnoreVisible, int DrawMessage)
{
	TPreRedrawFuncGuard preRedrawFuncGuard(PR_ReadFileNamesMsg);
	TaskBar TB(false);

	strOriginalCurDir=strCurDir;

	if (!IsVisible() && !IgnoreVisible)
	{
		UpdateRequired=TRUE;
		UpdateRequiredMode=KeepSelection;
		return;
	}

	UpdateRequired=FALSE;
	AccessTimeUpdateRequired=FALSE;
	DizRead=FALSE;
	FAR_FIND_DATA_EX fdata;
	FileListItem *CurPtr=0,**OldData=0;
	string strCurName, strNextCurName;
	int OldFileCount=0;
	StopFSWatcher();

	if (this!=CtrlObject->Cp()->LeftPanel && this!=CtrlObject->Cp()->RightPanel)
		return;

	string strSaveDir;
	apiGetCurrentDirectory(strSaveDir);
	{
		string strOldCurDir = strCurDir;

		if (!SetCurPath())
		{
			FlushInputBuffer(); // Очистим буффер ввода, т.к. мы уже можем быть в другом месте...

			if (!StrCmp(strCurDir, strOldCurDir)) //?? i??
			{
				GetPathRoot(strOldCurDir,strOldCurDir);

				if (!apiIsDiskInDrive(strOldCurDir))
					IfGoHome(strOldCurDir.At(0));

				/* При смене каталога путь не изменился */
			}

			return;
		}
	}
	SortGroupsRead=FALSE;

	if (GetFocus())
		CtrlObject->CmdLine->SetCurDir(strCurDir);

	LastCurFile=-1;
	Panel *AnotherPanel=CtrlObject->Cp()->GetAnotherPanel(this);
	AnotherPanel->QViewDelTempName();
	size_t PrevSelFileCount=SelFileCount;
	SelFileCount=0;
	SelFileSize=0;
	TotalFileCount=0;
	TotalFileSize=0;
	CacheSelIndex=-1;
	CacheSelClearIndex=-1;

	if (Opt.ShowPanelFree)
	{
		unsigned __int64 TotalSize,TotalFree;

		if (!apiGetDiskSize(strCurDir,&TotalSize,&TotalFree,&FreeDiskSize))
			FreeDiskSize=0;
	}

	if (FileCount>0)
	{
		strCurName = ListData[CurFile]->strName;

		if (ListData[CurFile]->Selected)
		{
			for (int i=CurFile+1; i < FileCount; i++)
			{
				CurPtr = ListData[i];

				if (!CurPtr->Selected)
				{
					strNextCurName = CurPtr->strName;
					break;
				}
			}
		}
	}

	if (KeepSelection || PrevSelFileCount>0)
	{
		OldData=ListData;
		OldFileCount=FileCount;
	}
	else
		DeleteListData(ListData,FileCount);

	ListData=nullptr;
	int ReadOwners=IsColumnDisplayed(OWNER_COLUMN);
	int ReadNumLinks=IsColumnDisplayed(NUMLINK_COLUMN);
	int ReadNumStreams=IsColumnDisplayed(NUMSTREAMS_COLUMN);
	int ReadStreamsSize=IsColumnDisplayed(STREAMSSIZE_COLUMN);
	string strComputerName;

	if (ReadOwners)
	{
		CurPath2ComputerName(strCurDir, strComputerName);
		// сбросим кэш SID`ов
		SIDCacheFlush();
	}

	SetLastError(ERROR_SUCCESS);
	int AllocatedCount=0;
	FileListItem *NewPtr;
	// сформируем заголовок вне цикла
	wchar_t Title[2048];
	int TitleLength=Min((int)X2-X1-1,(int)(ARRAYSIZE(Title))-1);
	//wmemset(Title,0x0CD,TitleLength); //BUGBUG
	//Title[TitleLength]=0;
	MakeSeparator(TitleLength, Title, 9, nullptr);
	BOOL IsShowTitle=FALSE;
	BOOL NeedHighlight=Opt.Highlight && PanelMode != PLUGIN_PANEL;

	if (!Filter)
		Filter=new FileFilter(this,FFT_PANEL);

	//Рефреш текущему времени для фильтра перед началом операции
	Filter->UpdateCurrentTime();
	CtrlObject->HiFiles->UpdateCurrentTime();
	bool bCurDirRoot = false;
	ParsePath(strCurDir, nullptr, &bCurDirRoot);
	PATH_TYPE Type = ParsePath(strCurDir, nullptr, &bCurDirRoot);
	bool NetRoot = bCurDirRoot && (Type == PATH_REMOTE || Type == PATH_REMOTEUNC);

	FileCount = 0;
	string strFind = strCurDir;
	AddEndSlash(strFind);
	strFind+=L'*';
	::FindFile Find(strFind, true);
	DWORD FindErrorCode = ERROR_SUCCESS;
	bool UseFilter=Filter->IsEnabledOnPanel();
	bool ReadCustomData=IsColumnDisplayed(CUSTOM_COLUMN0)!=0;

	DWORD StartTime = GetTickCount();

	while (Find.Get(fdata))
	{
		FindErrorCode = GetLastError();

		if ((Opt.ShowHidden || !(fdata.dwFileAttributes & (FILE_ATTRIBUTE_HIDDEN|FILE_ATTRIBUTE_SYSTEM))) && (!UseFilter || Filter->FileInFilter(fdata, nullptr, &fdata.strFileName)))
		{
			if (FileCount>=AllocatedCount)
			{
				AllocatedCount+=4096;
				FileListItem **pTemp;

				if (!(pTemp=(FileListItem **)xf_realloc(ListData,AllocatedCount*sizeof(*ListData))))
					break;

				ListData=pTemp;
			}

			ListData[FileCount] = new FileListItem;
			ListData[FileCount]->Clear();
			NewPtr=ListData[FileCount];
			NewPtr->FileAttr = fdata.dwFileAttributes;
			NewPtr->CreationTime = fdata.ftCreationTime;
			NewPtr->AccessTime = fdata.ftLastAccessTime;
			NewPtr->WriteTime = fdata.ftLastWriteTime;
			NewPtr->ChangeTime = fdata.ftChangeTime;
			NewPtr->FileSize = fdata.nFileSize;
			NewPtr->AllocationSize = fdata.nAllocationSize;
			NewPtr->strName = fdata.strFileName;
			NewPtr->strShortName = fdata.strAlternateFileName;
			NewPtr->Position=FileCount++;
			NewPtr->NumberOfLinks=1;

			if (fdata.dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT)
			{
				NewPtr->ReparseTag=fdata.dwReserved0; //MSDN
			}
			if (!(fdata.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY))
			{
				TotalFileSize += NewPtr->FileSize;

				if (ReadNumLinks)
					NewPtr->NumberOfLinks=GetNumberOfLinks(fdata.strFileName);
			}
			else
			{
				NewPtr->AllocationSize = 0;
			}

			NewPtr->SortGroup=DEFAULT_SORT_GROUP;

			if (ReadOwners)
			{
				string strOwner;
				GetFileOwner(strComputerName, NewPtr->strName,strOwner);
				NewPtr->strOwner = strOwner;
			}

			NewPtr->NumberOfStreams=NewPtr->FileAttr&FILE_ATTRIBUTE_DIRECTORY?0:1;
			NewPtr->StreamsSize=NewPtr->FileSize;

			if (ReadNumStreams||ReadStreamsSize)
			{
				EnumStreams(TestParentFolderName(fdata.strFileName)?strCurDir:fdata.strFileName,NewPtr->StreamsSize,NewPtr->NumberOfStreams);
			}

			if (ReadCustomData)
				CtrlObject->Plugins->GetCustomData(NewPtr);

			if (!(fdata.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY))
				TotalFileCount++;

			//memcpy(ListData+FileCount,&NewPtr,sizeof(NewPtr));
//      FileCount++;

			DWORD CurTime = GetTickCount();
			if (CurTime - StartTime > RedrawTimeout)
			{
				StartTime = CurTime;
				if (IsVisible())
				{
					if (!IsShowTitle)
					{
						if (!DrawMessage)
						{
							Text(X1+1,Y1,ColorIndexToColor(COL_PANELBOX),Title);
							IsShowTitle=TRUE;
							SetColor(Focus ? COL_PANELSELECTEDTITLE:COL_PANELTITLE);
						}
					}

					LangString strReadMsg(MReadingFiles);
					strReadMsg << FileCount;

					if (DrawMessage)
					{
						ReadFileNamesMsg(strReadMsg);
					}
					else
					{
						TruncStr(strReadMsg,TitleLength-2);
						int MsgLength=(int)strReadMsg.GetLength();
						GotoXY(X1+1+(TitleLength-MsgLength-1)/2,Y1);
						FS<<L" "<<strReadMsg<<L" ";
					}
				}

				if (CheckForEsc())
				{
					break;
				}
			}
		}
	}

	if (!(FindErrorCode==ERROR_SUCCESS || FindErrorCode==ERROR_NO_MORE_FILES || FindErrorCode==ERROR_FILE_NOT_FOUND))
		Message(MSG_WARNING|MSG_ERRORTYPE,1,MSG(MError),MSG(MReadFolderError),MSG(MOk));

	if ((Opt.ShowDotsInRoot || !bCurDirRoot) || (NetRoot && CtrlObject->Plugins->FindPlugin(Opt.KnownIDs.Network))) // NetWork Plugin
	{
		if (FileCount>=AllocatedCount)
		{
			FileListItem **pTemp;

			if ((pTemp=(FileListItem **)xf_realloc(ListData,(FileCount+1)*sizeof(*ListData))))
				ListData=pTemp;
		}

		if (ListData)
		{
			ListData[FileCount] = new FileListItem;

			string TwoDotsOwner;
			if (ReadOwners)
			{
				GetFileOwner(strComputerName,strCurDir,TwoDotsOwner);
			}

			FILETIME TwoDotsTimes[4]={};
			if(apiGetFindDataEx(strCurDir,fdata))
			{
				TwoDotsTimes[0]=fdata.ftCreationTime;
				TwoDotsTimes[1]=fdata.ftLastAccessTime;
				TwoDotsTimes[2]=fdata.ftLastWriteTime;
				TwoDotsTimes[3]=fdata.ftChangeTime;
			}

			AddParentPoint(ListData[FileCount],FileCount,TwoDotsTimes,TwoDotsOwner);

			FileCount++;
		}
	}

	if (IsColumnDisplayed(DIZ_COLUMN))
		ReadDiz();

	if (NeedHighlight)
	{
		CtrlObject->HiFiles->GetHiColor(ListData, FileCount);
	}

	if (AnotherPanel->GetMode()==PLUGIN_PANEL)
	{
		HANDLE hAnotherPlugin=AnotherPanel->GetPluginHandle();
		PluginPanelItem *PanelData=nullptr;
		string strPath;
		size_t PanelCount=0;
		strPath = strCurDir;
		AddEndSlash(strPath);

		if (CtrlObject->Plugins->GetVirtualFindData(hAnotherPlugin,&PanelData,&PanelCount,strPath))
		{
			FileListItem **pTemp;

			if ((pTemp=(FileListItem **)xf_realloc(ListData,(FileCount+PanelCount)*sizeof(*ListData))))
			{
				ListData=pTemp;

				for (size_t i=0; i < PanelCount; i++)
				{
					CurPtr = ListData[FileCount+i];
					PluginPanelItem &pfdata=PanelData[i];
					PluginToFileListItem(&PanelData[i],CurPtr);
					CurPtr->Position=FileCount;
					TotalFileSize += pfdata.FileSize;
					CurPtr->PrevSelected=CurPtr->Selected=0;
					CurPtr->ShowFolderSize=0;
					CurPtr->SortGroup=CtrlObject->HiFiles->GetGroup(CurPtr);

					if (!TestParentFolderName(pfdata.FileName) && !(CurPtr->FileAttr & FILE_ATTRIBUTE_DIRECTORY))
						TotalFileCount++;
				}

				// цветовую боевую раскраску в самом конце, за один раз
				CtrlObject->HiFiles->GetHiColor(&ListData[FileCount],PanelCount);
				FileCount+=static_cast<int>(PanelCount);
			}

			CtrlObject->Plugins->FreeVirtualFindData(hAnotherPlugin,PanelData,PanelCount);
		}
	}

	InitFSWatcher(false);
	CorrectPosition();

	if (KeepSelection || PrevSelFileCount>0)
	{
		MoveSelection(ListData,FileCount,OldData,OldFileCount);
		DeleteListData(OldData,OldFileCount);
	}

	if (SortGroups)
		ReadSortGroups(false);

	if (!KeepSelection && PrevSelFileCount>0)
	{
		SaveSelection();
		ClearSelection();
	}

	SortFileList(FALSE);

	if (CurFile>=FileCount || StrCmpI(ListData[CurFile]->strName,strCurName))
		if (!GoToFile(strCurName) && !strNextCurName.IsEmpty())
			GoToFile(strNextCurName);

	/* $ 13.02.2002 DJ
		SetTitle() - только если мы текущий фрейм!
	*/
	if (CtrlObject->Cp() == FrameManager->GetCurrentFrame())
		SetTitle();

	FarChDir(strSaveDir); //???
}
예제 #6
0
void FileList::ReadFileNames(int KeepSelection, int UpdateEvenIfPanelInvisible, int DrawMessage)
{
	SCOPED_ACTION(TPreRedrawFuncGuard)(std::make_unique<FileListPreRedrawItem>());
	SCOPED_ACTION(TaskBar)(false);

	strOriginalCurDir = strCurDir;

	if (!IsVisible() && !UpdateEvenIfPanelInvisible)
	{
		UpdateRequired=TRUE;
		UpdateRequiredMode=KeepSelection;
		return;
	}

	UpdateRequired=FALSE;
	AccessTimeUpdateRequired=FALSE;
	DizRead=FALSE;
	api::FAR_FIND_DATA fdata;
	decltype(ListData) OldData;
	string strCurName, strNextCurName;
	StopFSWatcher();

	if (this!=Global->CtrlObject->Cp()->LeftPanel && this!=Global->CtrlObject->Cp()->RightPanel)
		return;

	string strSaveDir;
	api::GetCurrentDirectory(strSaveDir);
	{
		string strOldCurDir(strCurDir);

		if (!SetCurPath())
		{
			FlushInputBuffer(); // Очистим буффер ввода, т.к. мы уже можем быть в другом месте...

			if (strCurDir == strOldCurDir) //?? i??
			{
				GetPathRoot(strOldCurDir,strOldCurDir);

				if (!api::IsDiskInDrive(strOldCurDir))
					IfGoHome(strOldCurDir.front());

				/* При смене каталога путь не изменился */
			}

			return;
		}
	}
	SortGroupsRead=FALSE;

	if (GetFocus())
		Global->CtrlObject->CmdLine->SetCurDir(strCurDir);

	LastCurFile=-1;
	Panel *AnotherPanel=Global->CtrlObject->Cp()->GetAnotherPanel(this);
	AnotherPanel->QViewDelTempName();
	size_t PrevSelFileCount=SelFileCount;
	SelFileCount=0;
	SelFileSize=0;
	TotalFileCount=0;
	TotalFileSize=0;
	CacheSelIndex=-1;
	CacheSelClearIndex=-1;
	FreeDiskSize = -1;
	if (Global->Opt->ShowPanelFree)
	{
		api::GetDiskSize(strCurDir, nullptr, nullptr, &FreeDiskSize);
	}

	if (!ListData.empty())
	{
		strCurName = ListData[CurFile].strName;

		if (ListData[CurFile].Selected && !ReturnCurrentFile)
		{
			for (size_t i=CurFile+1; i < ListData.size(); i++)
			{
				if (!ListData[i].Selected)
				{
					strNextCurName = ListData[i].strName;
					break;
				}
			}
		}
	}

	if (KeepSelection || PrevSelFileCount>0)
	{
		OldData.swap(ListData);
	}
	else
		DeleteListData(ListData);

	DWORD FileSystemFlags = 0;
	string PathRoot;
	GetPathRoot(strCurDir, PathRoot);
	api::GetVolumeInformation(PathRoot, nullptr, nullptr, nullptr, &FileSystemFlags, nullptr);

	ListData.clear();

	bool ReadOwners = IsColumnDisplayed(OWNER_COLUMN);
	bool ReadNumLinks = IsColumnDisplayed(NUMLINK_COLUMN);
	bool ReadNumStreams = IsColumnDisplayed(NUMSTREAMS_COLUMN);
	bool ReadStreamsSize = IsColumnDisplayed(STREAMSSIZE_COLUMN);

	if (!(FileSystemFlags&FILE_SUPPORTS_HARD_LINKS) && IsWindows7OrGreater())
	{
		ReadNumLinks = false;
	}

	if(!(FileSystemFlags&FILE_NAMED_STREAMS))
	{
		ReadNumStreams = false;
		ReadStreamsSize = false;
	}

	string strComputerName;

	if (ReadOwners)
	{
		string strTemp;
		CurPath2ComputerName(strCurDir, strComputerName, strTemp);
	}

	SetLastError(ERROR_SUCCESS);
	// сформируем заголовок вне цикла
	string Title = MakeSeparator(X2-X1-1, 9, nullptr);
	BOOL IsShowTitle=FALSE;
	BOOL NeedHighlight=Global->Opt->Highlight && PanelMode != PLUGIN_PANEL;

	if (!Filter)
		Filter = std::make_unique<FileFilter>(this,FFT_PANEL);

	//Рефреш текущему времени для фильтра перед началом операции
	Filter->UpdateCurrentTime();
	Global->CtrlObject->HiFiles->UpdateCurrentTime();
	bool bCurDirRoot = false;
	ParsePath(strCurDir, nullptr, &bCurDirRoot);
	PATH_TYPE Type = ParsePath(strCurDir, nullptr, &bCurDirRoot);
	bool NetRoot = bCurDirRoot && (Type == PATH_REMOTE || Type == PATH_REMOTEUNC);

	string strFind(strCurDir);
	AddEndSlash(strFind);
	strFind+=L'*';
	api::FindFile Find(strFind, true);
	DWORD FindErrorCode = ERROR_SUCCESS;
	bool UseFilter=Filter->IsEnabledOnPanel();
	bool ReadCustomData=IsColumnDisplayed(CUSTOM_COLUMN0)!=0;

	DWORD StartTime = GetTickCount();

	std::all_of(CONST_RANGE(Find, fdata) -> bool
	{
		Global->CatchError();
		FindErrorCode = Global->CaughtError();

		if ((Global->Opt->ShowHidden || !(fdata.dwFileAttributes & (FILE_ATTRIBUTE_HIDDEN|FILE_ATTRIBUTE_SYSTEM))) && (!UseFilter || Filter->FileInFilter(fdata, nullptr, &fdata.strFileName)))
		{
			if (ListData.size() == ListData.capacity())
				ListData.reserve(ListData.size() + 4096);

			ListData.emplace_back(VALUE_TYPE(ListData)());
			auto& NewItem = ListData.back();

			NewItem.FileAttr = fdata.dwFileAttributes;
			NewItem.CreationTime = fdata.ftCreationTime;
			NewItem.AccessTime = fdata.ftLastAccessTime;
			NewItem.WriteTime = fdata.ftLastWriteTime;
			NewItem.ChangeTime = fdata.ftChangeTime;
			NewItem.FileSize = fdata.nFileSize;
			NewItem.AllocationSize = fdata.nAllocationSize;
			NewItem.strName = fdata.strFileName;
			NewItem.strShortName = fdata.strAlternateFileName;
			NewItem.Position = ListData.size() - 1;
			NewItem.NumberOfLinks=1;

			if (fdata.dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT)
			{
				NewItem.ReparseTag=fdata.dwReserved0; //MSDN
			}
			if (!(fdata.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY))
			{
				TotalFileSize += NewItem.FileSize;

				if (ReadNumLinks)
					NewItem.NumberOfLinks = GetNumberOfLinks(fdata.strFileName, true);
			}
			else
			{
				NewItem.AllocationSize = 0;
			}

			NewItem.SortGroup=DEFAULT_SORT_GROUP;

			if (ReadOwners)
			{
				string strOwner;
				GetFileOwner(strComputerName, NewItem.strName,strOwner);
				NewItem.strOwner = strOwner;
			}

			NewItem.NumberOfStreams=NewItem.FileAttr&FILE_ATTRIBUTE_DIRECTORY?0:1;
			NewItem.StreamsSize=NewItem.FileSize;

			if (ReadNumStreams||ReadStreamsSize)
			{
				EnumStreams(TestParentFolderName(fdata.strFileName)? strCurDir : fdata.strFileName, NewItem.StreamsSize, NewItem.NumberOfStreams);
			}

			if (ReadCustomData)
				NewItem.strCustomData = Global->CtrlObject->Plugins->GetCustomData(NewItem.strName);

			if (!(fdata.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY))
				TotalFileCount++;

			DWORD CurTime = GetTickCount();
			if (CurTime - StartTime > (DWORD)Global->Opt->RedrawTimeout)
			{
				StartTime = CurTime;
				if (IsVisible())
				{
					if (!IsShowTitle)
					{
						if (!DrawMessage)
						{
							Text(X1+1,Y1,ColorIndexToColor(COL_PANELBOX),Title);
							IsShowTitle=TRUE;
							SetColor(Focus ? COL_PANELSELECTEDTITLE:COL_PANELTITLE);
						}
					}

					LangString strReadMsg(MReadingFiles);
					strReadMsg << ListData.size();

					if (DrawMessage)
					{
						ReadFileNamesMsg(strReadMsg);
					}
					else
					{
						TruncStr(strReadMsg,static_cast<int>(Title.size())-2);
						int MsgLength=(int)strReadMsg.size();
						GotoXY(X1+1+(static_cast<int>(Title.size())-MsgLength-1)/2,Y1);
						Global->FS << L" "<<strReadMsg<<L" ";
					}
				}

				Global->CtrlObject->Macro.SuspendMacros(true);
				bool check = CheckForEsc();
				Global->CtrlObject->Macro.SuspendMacros(false);
				if (check)
				{
					// break loop
					return false;
				}
			}
		}
		return true;
	});
예제 #7
0
파일: message.cpp 프로젝트: alexlav/conemu
int Message(
    DWORD Flags,
    size_t Buttons,
    const wchar_t *Title,
    const wchar_t * const *Items,
    size_t ItemsNumber,
    Plugin* PluginNumber,
    const GUID* Id
)
{
	string strTempStr;
	string strClipText;
	int X1,Y1,X2,Y2;
	int Length, BtnLength;
	DWORD I, MaxLength, StrCount;
	BOOL ErrorSets=FALSE;
	const wchar_t **Str;
	wchar_t *PtrStr;
	const wchar_t *CPtrStr;
	string strErrStr;

	IsWarningStyle = (Flags&MSG_WARNING) != 0;
	IsErrorType = (Flags&MSG_ERRORTYPE) != 0;

	if(IsErrorType)
	{
		LastError = GetLastError();
		NtStatus = ifn.RtlGetLastNtStatus();
		ErrorSets = GetErrorString(strErrStr);
	}

#if 1 // try to replace inserts
	if (Items && 0 != (Flags & MSG_INSERT_STRINGS))
	{
		string str_err(strErrStr);
		DWORD insert_mask = 0;
		size_t len = strErrStr.GetLength(), pos = 0, inserts_n = 0, inserts[10];

		for (size_t i = 1; i <= ItemsNumber-Buttons; ++i)
		{
			if (0 != (Flags & MSG_INSERT_STR(i)))
			{
				inserts[inserts_n++] = i;
				if (inserts_n >= ARRAYSIZE(inserts))
					break;
			}
		}

		while (str_err.Pos(pos, L"%", pos))
		{
			if (pos >= len-1)
				break;

			if (str_err.At(pos+1) >= L'1' && str_err.At(pos+1) <= L'9')
			{
				size_t insert_i = 0, pos1 = pos+1;
				while (pos1 < len && str_err.At(pos1) >= L'0' && str_err.At(pos1) <= L'9')
				{
					insert_i = 10*insert_i + str_err.At(pos1) - L'0';
					++pos1;
				}
				if (insert_i >= 1 && insert_i <= inserts_n)
				{
					insert_mask |= MSG_INSERT_STR(inserts[insert_i-1]);
					const wchar_t *replacement = Items[inserts[insert_i-1]-1];
					str_err.Replace(pos,pos1-pos,replacement);
					len += wcslen(replacement) - (pos1-pos);
					pos += wcslen(replacement) - (pos1-pos);
				}
				else
					pos = pos1;
			}
			else if (str_err.At(pos+1) == L'%') // "%%"
				pos += 2;
			else
				++pos;
		}
		if (insert_mask == (Flags & MSG_INSERT_STRINGS))
			strErrStr = str_err;
	}
#endif

	// выделим пам¤ть под рабочий массив указателей на строки (+запас 16)
	Str=(const wchar_t **)xf_malloc((ItemsNumber+ADDSPACEFORPSTRFORMESSAGE) * sizeof(wchar_t*));

	if (!Str)
		return -1;

	StrCount=static_cast<DWORD>(ItemsNumber-Buttons);

	// предварительный обсчет максимального размера.
	for (BtnLength=0,I=0; I<static_cast<DWORD>(Buttons); I++) //??
	{
		BtnLength+=HiStrlen(Items[I+StrCount])+2+2+1; // "[ ", " ]", " "
	}
	if(BtnLength)
	{
		BtnLength--;
	}

	DWORD MAX_WIDTH_MESSAGE = Max(ScrX-1-5-5, BtnLength);

	for (MaxLength=BtnLength,I=0; I<StrCount; I++)
	{
		if (static_cast<DWORD>(Length=StrLength(Items[I]))>MaxLength)
			MaxLength=Length;
	}

	// учтем размер заголовка
	if (Title && *Title)
	{
		I=(DWORD)StrLength(Title)+2;

		if (MaxLength < I)
			MaxLength=I;

		strClipText.Append(Title).Append(L"\r\n\r\n");
	}

	// перва¤ коррекци¤ максимального размера
	MaxLength = Min(MaxLength, MAX_WIDTH_MESSAGE);

	// теперь обработаем MSG_ERRORTYPE
	DWORD CountErrorLine=0;

	if ((Flags & MSG_ERRORTYPE) && ErrorSets)
	{
		strClipText.Append(strErrStr).Append(L"\r\n");

		// подсчет количества строк во врапенном сообщениеи
		++CountErrorLine;
		//InsertQuote(ErrStr); // оквочим
		// вычисление "красивого" размера
		DWORD LenErrStr=(DWORD)strErrStr.GetLength();

		if (LenErrStr > MAX_WIDTH_MESSAGE)
		{
			// половина меньше?
			if (LenErrStr/2 < MAX_WIDTH_MESSAGE)
			{
				// а половина + 1/3?
				if ((LenErrStr+LenErrStr/3)/2 < MAX_WIDTH_MESSAGE)
					LenErrStr=(LenErrStr+LenErrStr/3)/2;
				else
					LenErrStr/=2;
			}
			else
				LenErrStr=MAX_WIDTH_MESSAGE;
		}

		MaxLength = Max(MaxLength, LenErrStr);

		// а теперь проврапим
		FarFormatText(strErrStr,LenErrStr,strErrStr,L"\n",0); //?? MaxLength ??
		PtrStr = strErrStr.GetBuffer();

		//BUGBUG: string не предназначен дл¤ хранени¤ строк разделЄнных \0
		while ((PtrStr=wcschr(PtrStr,L'\n')) )
		{
			*PtrStr++=0;

			if (*PtrStr)
				CountErrorLine++;
		}

		strErrStr.ReleaseBuffer();

		if (CountErrorLine > ADDSPACEFORPSTRFORMESSAGE)
			CountErrorLine=ADDSPACEFORPSTRFORMESSAGE; //??
	}

	//BUGBUG: string не предназначен дл¤ хранени¤ строк разделЄнных \0
	// заполн¤ем массив...
	CPtrStr=strErrStr;

	for (I=0; I < CountErrorLine; I++)
	{
		Str[I]=CPtrStr;
		CPtrStr+=StrLength(CPtrStr)+1;

		if (!*CPtrStr) // два идущих подр¤д нул¤ - "хандец" всему
		{
			++I;
			break;
		}
	}

	bool EmptyText=false;
	if(ItemsNumber==Buttons && !I)
	{
		EmptyText=true;
		Str[I]=L"";
		I++;
		StrCount++;
		ItemsNumber++;
	}

	for (size_t J=0; J < ItemsNumber-(EmptyText?1:0); ++J, ++I)
	{
		Str[I]=Items[J];
	}

	for (size_t i = 0; i < ItemsNumber-Buttons; ++i)
	{
		strClipText.Append(Items[i]).Append(L"\r\n");
	}
	strClipText.Append(L"\r\n");
	for (size_t i = ItemsNumber-Buttons; i < ItemsNumber; ++i)
	{
		if(i > ItemsNumber-Buttons)
		{
			strClipText.Append(L' ');
		}
		strClipText.Append(Items[i]);
	}

	StrCount+=CountErrorLine;
	MessageX1=X1=(int(ScrX-MaxLength))/2-4;
	MessageX2=X2=X1+MaxLength+9;
	Y1=(ScrY-static_cast<int>(StrCount))/2-2;

	if (Y1 < 0)
		Y1=0;

	MessageY1=Y1;
	MessageY2=Y2=Y1+StrCount+3;
	string strHelpTopic(strMsgHelpTopic);
	strMsgHelpTopic.Clear();
	// *** ¬ариант с ƒиалогом ***

	if (Buttons>0)
	{
		size_t ItemCount=StrCount+Buttons+1;
		DialogItemEx *PtrMsgDlg;
		DialogItemEx *MsgDlg = new DialogItemEx[ItemCount+1];

		if (!MsgDlg)
		{
			xf_free(Str);
			return -1;
		}

		for (DWORD i=0; i<ItemCount+1; i++)
			MsgDlg[i].Clear();

		int RetCode;
		MessageY2=++Y2;
		MsgDlg[0].Type=DI_DOUBLEBOX;
		MsgDlg[0].X1=3;
		MsgDlg[0].Y1=1;
		MsgDlg[0].X2=X2-X1-3;
		MsgDlg[0].Y2=Y2-Y1-1;

		if (Title && *Title)
			MsgDlg[0].strData = Title;

		FARDIALOGITEMTYPES TypeItem=DI_TEXT;
		unsigned __int64 FlagsItem=DIF_SHOWAMPERSAND;
		BOOL IsButton=FALSE;
		int CurItem=0;
		bool StrSeparator=false;
		bool Separator=false;
		for (PtrMsgDlg=MsgDlg+1,I=1; I < ItemCount; ++I, ++PtrMsgDlg, ++CurItem)
		{
			if (I==StrCount+1 && !StrSeparator && !Separator)
			{
				PtrMsgDlg->Type=DI_TEXT;
				PtrMsgDlg->Flags=DIF_SEPARATOR;
				PtrMsgDlg->Y1=PtrMsgDlg->Y2=I+1;
				CurItem--;
				I--;
				Separator=true;
				continue;
			}
			if(I==StrCount+1)
			{
				TypeItem=DI_BUTTON;
				FlagsItem=DIF_CENTERGROUP|DIF_DEFAULTBUTTON|DIF_FOCUS;
				IsButton=TRUE;
				FirstButtonIndex=CurItem+1;
				LastButtonIndex=CurItem;
			}
			else
			{
				FlagsItem&=~DIF_DEFAULTBUTTON;
			}

			PtrMsgDlg->Type=TypeItem;
			PtrMsgDlg->Flags|=FlagsItem;
			CPtrStr=Str[CurItem];

			if (IsButton)
			{
				PtrMsgDlg->Y1=Y2-Y1-2+(Separator?1:0);
				PtrMsgDlg->strData+=CPtrStr;
				LastButtonIndex++;
			}
			else
			{
				PtrMsgDlg->X1=(Flags & MSG_LEFTALIGN)?5:-1;
				PtrMsgDlg->Y1=I+1;
				wchar_t Chr=*CPtrStr;

				if (Chr == L'\1' || Chr == L'\2')
				{
					CPtrStr++;
					PtrMsgDlg->Flags|=(Chr==2?DIF_SEPARATOR2:DIF_SEPARATOR);
					if(I==StrCount)
					{
						StrSeparator=true;
					}
				}
				else
				{
					if (StrLength(CPtrStr)>X2-X1-9)
					{
						PtrMsgDlg->Type=DI_EDIT;
						PtrMsgDlg->Flags|=DIF_READONLY|DIF_BTNNOCLOSE|DIF_SELECTONENTRY;
						PtrMsgDlg->X1=5;
						PtrMsgDlg->X2=X2-X1-5;
						PtrMsgDlg->strData=CPtrStr;
					}
					else
					{
						//xstrncpy(PtrMsgDlg->Data,CPtrStr,Min((int)MAX_WIDTH_MESSAGE,(int)sizeof(PtrMsgDlg->Data))); //?? ScrX-15 ??
						PtrMsgDlg->strData = CPtrStr; //BUGBUG, wrong len
					}
				}
			}
		}

		{
			if(Separator)
			{
				FirstButtonIndex++;
				LastButtonIndex++;
				MessageY2++;
				Y2++;
				MsgDlg[0].Y2++;
				ItemCount++;
			}
			Dialog Dlg(MsgDlg,ItemCount,MsgDlgProc, &strClipText);
			if (X1 == -1) X1 = 0;
			if (Y1 == -1) Y1 = 0;
			Dlg.SetPosition(X1,Y1,X2,Y2);
			if(Id) Dlg.SetId(*Id);

			if (!strHelpTopic.IsEmpty())
				Dlg.SetHelp(strHelpTopic);

			Dlg.SetPluginOwner(reinterpret_cast<Plugin*>(PluginNumber)); // «апомним номер плагина

			if (IsWarningStyle)
			{
				Dlg.SetDialogMode(DMODE_WARNINGSTYLE);
			}

			Dlg.SetDialogMode(DMODE_MSGINTERNAL);
			if (Flags & MSG_NOPLUGINS)
				Dlg.SetDialogMode(DMODE_NOPLUGINS);
			FlushInputBuffer();

			if (Flags & MSG_KILLSAVESCREEN)
				SendDlgMessage((HANDLE)&Dlg,DM_KILLSAVESCREEN,0,0);

			Dlg.Process();
			RetCode=Dlg.GetExitCode();
		}

		delete [] MsgDlg;
		xf_free(Str);
		return(RetCode<0?RetCode:RetCode-StrCount-1-(Separator?1:0));
	}

	// *** Ѕез ƒиалога! ***
	SetCursorType(0,0);

	if (!(Flags & MSG_KEEPBACKGROUND))
	{
		SetScreen(X1,Y1,X2,Y2,L' ',ColorIndexToColor((Flags & MSG_WARNING)?COL_WARNDIALOGTEXT:COL_DIALOGTEXT));
		MakeShadow(X1+2,Y2+1,X2+2,Y2+1);
		MakeShadow(X2+1,Y1+1,X2+2,Y2+1);
		Box(X1+3,Y1+1,X2-3,Y2-1,ColorIndexToColor((Flags & MSG_WARNING)?COL_WARNDIALOGBOX:COL_DIALOGBOX),DOUBLE_BOX);
	}

	SetColor((Flags & MSG_WARNING)?COL_WARNDIALOGTEXT:COL_DIALOGTEXT);

	if (Title && *Title)
	{
		string strTempTitle = Title;

		if (strTempTitle.GetLength() > MaxLength)
			strTempTitle.SetLength(MaxLength);

		GotoXY(X1+(X2-X1-1-(int)strTempTitle.GetLength())/2,Y1+1);
		FS<<L" "<<strTempTitle<<L" ";
	}

	for (I=0; I<StrCount; I++)
	{
		CPtrStr=Str[I];
		wchar_t Chr=*CPtrStr;

		if (Chr == 1 || Chr == 2)
		{
			Length=X2-X1-5;

			if (Length>1)
			{
				SetColor((Flags & MSG_WARNING)?COL_WARNDIALOGBOX:COL_DIALOGBOX);
				GotoXY(X1+3,Y1+I+2);
				DrawLine(Length,(Chr == 2?3:1));
				CPtrStr++;
				int TextLength=StrLength(CPtrStr);

				if (TextLength<Length)
				{
					GotoXY(X1+3+(Length-TextLength)/2,Y1+I+2);
					Text(CPtrStr);
				}

				SetColor((Flags & MSG_WARNING)?COL_WARNDIALOGBOX:COL_DIALOGTEXT);
			}

			continue;
		}

		if ((Length=StrLength(CPtrStr))>ScrX-15)
			Length=ScrX-15;

		int Width=X2-X1+1;
		wchar_t *lpwszTemp = nullptr;
		int PosX;
		if (Flags & MSG_LEFTALIGN)
		{
			lpwszTemp = (wchar_t*)xf_malloc((Width-10+1)*sizeof(wchar_t));
			_snwprintf(lpwszTemp,Width-10+1,L"%.*s",Width-10,CPtrStr);
			GotoXY(X1+5,Y1+I+2);
		}
		else
		{
			PosX=X1+(Width-Length)/2;
			lpwszTemp = (wchar_t*)xf_malloc((PosX-X1-4+Length+X2-PosX-Length-3+1)*sizeof(wchar_t));
			_snwprintf(lpwszTemp,PosX-X1-4+Length+X2-PosX-Length-3+1,L"%*s%.*s%*s",PosX-X1-4,L"",Length,CPtrStr,X2-PosX-Length-3,L"");
			GotoXY(X1+4,Y1+I+2);
		}

		Text(lpwszTemp);
		xf_free(lpwszTemp);
	}

	/* $ 13.01.2003 IS
	   - ѕринудительно уберем запрет отрисовки экрана, если количество кнопок
	     в сообщении равно нулю и макрос закончил выполн¤тьс¤. Ёто необходимо,
	     чтобы заработал прогресс-бар от плагина, который был запущен при помощи
	     макроса запретом отрисовки (bugz#533).
	*/
	xf_free(Str);

	if (!Buttons)
	{
		if (ScrBuf.GetLockCount()>0 && !CtrlObject->Macro.PeekKey())
			ScrBuf.SetLockCount(0);

		ScrBuf.Flush();
	}

	return 0;
}
예제 #8
0
int CKMotionIO::Connect()
{
	char reason[256];

	FT_STATUS ftStatus;

	if (NonRespondingCount==2) return 1;

	m_SaveChars[0]=0;  // start anew

	Mutex->Lock();

	if (!RequestedDeviceAvail(reason))
	{
		ErrorMessageBox(reason);
		Mutex->Unlock();
		return 1;
	}


	
	#define TIME_TO_TRY_TO_OPEN 3000

	// FT_ListDevices OK, number of devices connected is in numDevs

	// usually during boot the board comes and goes, since it appeared 
	// to be there, try for a while to open it

	DWORD t0=timeGetTime();

	for (;;) 
	{
		ftStatus = FT_OpenEx((void *)USB_Loc_ID,FT_OPEN_BY_LOCATION,&ftHandle);

		
		if (ftStatus == FT_OK) 
		{
			// FT_Open OK, use ftHandle to access device

			if (SetLatency(2))
			{
				Mutex->Unlock();
				return 1;
			}

			
			if (FlushInputBuffer())
			{
				FT_Close(ftHandle);
				Mutex->Unlock();
				return 1;
			}

			m_Connected=true;  // All set

			Mutex->Unlock();
			return 0;
		}
		else 
		{
			// FT_Open failed

			if (timeGetTime()-t0 > TIME_TO_TRY_TO_OPEN)
			{
				ErrorMessageBox("Unable to open KMotion device");
				Mutex->Unlock();
				return 1;
			}

			Sleep(100);  // delay a bit then loop back and try again
		}
	}

	Mutex->Unlock();
	return 0;
}
예제 #9
0
int CKMotionIO::Connect()
{
	char reason[256];

	int ftStatus;

	if (NonRespondingCount==CONNECT_TRIES) return 1;

	m_SaveChars[0]=0;  // start anew

	Mutex->Lock();

	if (!RequestedDeviceAvail(reason))
	{
		ErrorMessageBox(reason);
		Mutex->Unlock();
		return 1;
	}


	
	#define TIME_TO_TRY_TO_OPEN 3000

	// FT_ListDevices OK, number of devices connected is in numDevs

	// usually during boot the board comes and goes, since it appeared 
	// to be there, try for a while to open it

	DWORD t0=timeGetTime();

	for (;;) 
	{
		ftStatus = ftdi_usb_open_desc_index(ftdi, VENDOR, PRODUCT, NULL, NULL, USB_Loc_ID);
		
		if (ftStatus < FT_OK)
		{
		  log_info("ftdi_usb_open_desc_index failed: %d (%s)", ftStatus, ftdi_get_error_string(ftdi));
		  // FT_Open failed
			if (timeGetTime()-t0 > TIME_TO_TRY_TO_OPEN)
			{
			  ErrorMessageBox("Unable to open KMotion device");
				Mutex->Unlock();
				return 1;
			}

			Sleep(100);  // delay a bit then loop back and try again
		}
		else
		{
			// FT_Open OK, use ftHandle to access device

			if (SetLatency(2))
			{
				//Close handle
				if(_ftdi_usb_close(ftdi) < FT_OK){
				  log_info("_ftdi_usb_close failed: %d (%s)", ftStatus, ftdi_get_error_string(ftdi));
				}
				Mutex->Unlock();
				return 1;
			}

			
			if (FlushInputBuffer())
			{
				log_info("FAIL: FlushInputBuffer for device %d",USB_Loc_ID);
				//This is the key to why it works on second attempt
				//After usb_close has executed once the device works forever.
				//The ftdi device is not closed when killing the KMotionServer
				//Try to recover from this action when initialising this class.
        if(_ftdi_usb_close(ftdi) < FT_OK){
          log_info("_ftdi_usb_close failed: %d (%s)", ftStatus, ftdi_get_error_string(ftdi));
        }
				Mutex->Unlock();
				return 1;
			}
			m_Connected=true;  // All set

			Mutex->Unlock();
			return 0;
		}
	}

	Mutex->Unlock();
	return 0;
}
예제 #10
0
파일: message.cpp 프로젝트: elfmz/far2l
int Message(
    DWORD Flags,
    int Buttons,
    const wchar_t *Title,
    const wchar_t * const *Items,
    int ItemsNumber,
    INT_PTR PluginNumber
)
{
	FARString strTempStr;
	int X1,Y1,X2,Y2;
	int Length, BtnLength, J;
	DWORD I, MaxLength, StrCount;
	BOOL ErrorSets=FALSE;
	const wchar_t **Str;
	wchar_t *PtrStr;
	const wchar_t *CPtrStr;
	FARString strErrStr;

	if (Flags & MSG_ERRORTYPE)
		ErrorSets = GetErrorString(strErrStr);

	// выделим память под рабочий массив указателей на строки (+запас 16)
	Str=(const wchar_t **)xf_malloc((ItemsNumber+ADDSPACEFORPSTRFORMESSAGE) * sizeof(wchar_t*));

	if (!Str)
		return -1;

	StrCount=ItemsNumber-Buttons;

	// предварительный обсчет максимального размера.
	for (BtnLength=0,I=0; I<static_cast<DWORD>(Buttons); I++) //??
	{
		BtnLength+=HiStrlen(Items[I+StrCount])+2+2+1; // "[ ", " ]", " "
	}
	if(BtnLength)
	{
		BtnLength--;
	}

	for (MaxLength=BtnLength,I=0; I<StrCount; I++)
	{
		if (static_cast<DWORD>(Length=StrLength(Items[I]))>MaxLength)
			MaxLength=Length;
	}

	// учтем так же размер заголовка
	if (Title && *Title)
	{
		I=(DWORD)StrLength(Title)+2;

		if (MaxLength < I)
			MaxLength=I;
	}

	// певая коррекция максимального размера
	if (MaxLength > MAX_WIDTH_MESSAGE)
		MaxLength=MAX_WIDTH_MESSAGE;

	// теперь обработаем MSG_ERRORTYPE
	DWORD CountErrorLine=0;

	if ((Flags & MSG_ERRORTYPE) && ErrorSets)
	{
		// подсчет количества строк во врапенном сообщениеи
		++CountErrorLine;
		//InsertQuote(ErrStr); // оквочим
		// вычисление "красивого" размера
		DWORD LenErrStr=(DWORD)strErrStr.GetLength();

		if (LenErrStr > MAX_WIDTH_MESSAGE)
		{
			// половина меньше?
			if (LenErrStr/2 < MAX_WIDTH_MESSAGE)
			{
				// а половина + 1/3?
				if ((LenErrStr+LenErrStr/3)/2 < MAX_WIDTH_MESSAGE)
					LenErrStr=(LenErrStr+LenErrStr/3)/2;
				else
					LenErrStr/=2;
			}
			else
				LenErrStr=MAX_WIDTH_MESSAGE;
		}
		else if (LenErrStr < MaxLength)
			LenErrStr=MaxLength;

		if (MaxLength > LenErrStr && MaxLength >= MAX_WIDTH_MESSAGE)
			MaxLength=LenErrStr;

		if (MaxLength < LenErrStr && LenErrStr <= MAX_WIDTH_MESSAGE)
			MaxLength=LenErrStr;

		// а теперь проврапим
		//PtrStr=FarFormatText(ErrStr,MaxLength-(MaxLength > MAX_WIDTH_MESSAGE/2?1:0),ErrStr,sizeof(ErrStr),"\n",0); //?? MaxLength ??
		FarFormatText(strErrStr,LenErrStr,strErrStr,L"\n",0); //?? MaxLength ??
		PtrStr = strErrStr.GetBuffer();

		//BUGBUG: FARString не преднозначен для хранения строк разделённых \0
		while ((PtrStr=wcschr(PtrStr,L'\n')) )
		{
			*PtrStr++=0;

			if (*PtrStr)
				CountErrorLine++;
		}

		strErrStr.ReleaseBuffer();

		if (CountErrorLine > ADDSPACEFORPSTRFORMESSAGE)
			CountErrorLine=ADDSPACEFORPSTRFORMESSAGE; //??
	}

	//BUGBUG: FARString не преднозначен для хранения строк разделённых \0
	// заполняем массив...
	CPtrStr=strErrStr;

	for (I=0; I < CountErrorLine; I++)
	{
		Str[I]=CPtrStr;
		CPtrStr+=StrLength(CPtrStr)+1;

		if (!*CPtrStr) // два идущих подряд нуля - "хандец" всему
		{
			++I;
			break;
		}
	}

	bool EmptyText=false;
	if(ItemsNumber==Buttons && !I)
	{
		EmptyText=true;
		Str[I]=L"";
		I++;
		StrCount++;
		ItemsNumber++;
	}

	for (J=0; J < ItemsNumber-(EmptyText?1:0); ++J, ++I)
	{
		Str[I]=Items[J];
	}

	StrCount+=CountErrorLine;
	MessageX1=X1=(ScrX-MaxLength)/2-4;
	MessageX2=X2=X1+MaxLength+9;
	Y1=(ScrY-StrCount)/2-2;

	if (Y1 < 0)
		Y1=0;

	MessageY1=Y1;
	MessageY2=Y2=Y1+StrCount+3;
	FARString strHelpTopic(strMsgHelpTopic);
	strMsgHelpTopic.Clear();
	// *** Вариант с Диалогом ***

	if (Buttons>0)
	{
		DWORD ItemCount=StrCount+Buttons+1;
		DialogItemEx *PtrMsgDlg;
		DialogItemEx *MsgDlg = new(std::nothrow) DialogItemEx[ItemCount+1];

		if (!MsgDlg)
		{
			xf_free(Str);
			return -1;
		}

		for (DWORD i=0; i<ItemCount+1; i++)
			MsgDlg[i].Clear();

		int RetCode;
		MessageY2=++Y2;
		MsgDlg[0].Type=DI_DOUBLEBOX;
		MsgDlg[0].X1=3;
		MsgDlg[0].Y1=1;
		MsgDlg[0].X2=X2-X1-3;
		MsgDlg[0].Y2=Y2-Y1-1;

		if (Title && *Title)
			MsgDlg[0].strData = Title;

		int TypeItem=DI_TEXT;
		DWORD FlagsItem=DIF_SHOWAMPERSAND;
		BOOL IsButton=FALSE;
		int CurItem=0;
		bool StrSeparator=false;
		bool Separator=false;
		for (PtrMsgDlg=MsgDlg+1,I=1; I < ItemCount; ++I, ++PtrMsgDlg, ++CurItem)
		{
			if (I==StrCount+1 && !StrSeparator && !Separator)
			{
				PtrMsgDlg->Type=DI_TEXT;
				PtrMsgDlg->Flags=DIF_SEPARATOR;
				PtrMsgDlg->Y1=PtrMsgDlg->Y2=I+1;
				CurItem--;
				I--;
				Separator=true;
				continue;
			}
			if(I==StrCount+1)
			{
				PtrMsgDlg->DefaultButton=TRUE;
				PtrMsgDlg->Focus=TRUE;
				TypeItem=DI_BUTTON;
				FlagsItem=DIF_CENTERGROUP;
				IsButton=TRUE;
				FirstButtonIndex=CurItem+1;
				LastButtonIndex=CurItem;
			}

			PtrMsgDlg->Type=TypeItem;
			PtrMsgDlg->Flags|=FlagsItem;
			CPtrStr=Str[CurItem];

			if (IsButton)
			{
				PtrMsgDlg->Y1=Y2-Y1-2+(Separator?1:0);
				PtrMsgDlg->strData+=CPtrStr;
				LastButtonIndex++;
			}
			else
			{
				PtrMsgDlg->X1=(Flags & MSG_LEFTALIGN)?5:-1;
				PtrMsgDlg->Y1=I+1;
				wchar_t Chr=*CPtrStr;

				if (Chr == L'\1' || Chr == L'\2')
				{
					CPtrStr++;
					PtrMsgDlg->Flags|=(Chr==2?DIF_SEPARATOR2:DIF_SEPARATOR);
					if(I==StrCount)
					{
						StrSeparator=true;
					}
				}
				else if (StrLength(CPtrStr)>X2-X1-9)
				{
					PtrMsgDlg->Type=DI_EDIT;
					PtrMsgDlg->Flags|=DIF_READONLY|DIF_BTNNOCLOSE|DIF_SELECTONENTRY;
					PtrMsgDlg->X1=5;
					PtrMsgDlg->X2=X2-X1-5;
					PtrMsgDlg->strData=CPtrStr;
					continue;
				}

				//xstrncpy(PtrMsgDlg->Data,CPtrStr,Min((int)MAX_WIDTH_MESSAGE,(int)sizeof(PtrMsgDlg->Data))); //?? ScrX-15 ??
				PtrMsgDlg->strData = CPtrStr; //BUGBUG, wrong len
			}
		}

		{
			if(Separator)
			{
				FirstButtonIndex++;
				LastButtonIndex++;
				MessageY2++;
				Y2++;
				MsgDlg[0].Y2++;
				ItemCount++;
			}
			IsWarningStyle=Flags&MSG_WARNING;
			Dialog Dlg(MsgDlg,ItemCount,MsgDlgProc);
			Dlg.SetPosition(X1,Y1,X2,Y2);

			if (!strHelpTopic.IsEmpty())
				Dlg.SetHelp(strHelpTopic);

			Dlg.SetPluginNumber(PluginNumber); // Запомним номер плагина

			if (IsWarningStyle)
			{
				Dlg.SetDialogMode(DMODE_WARNINGSTYLE);
			}

			Dlg.SetDialogMode(DMODE_MSGINTERNAL);
			FlushInputBuffer();

			if (Flags & MSG_KILLSAVESCREEN)
				SendDlgMessage((HANDLE)&Dlg,DM_KILLSAVESCREEN,0,0);

			Dlg.Process();
			RetCode=Dlg.GetExitCode();
		}

		delete [] MsgDlg;
		xf_free(Str);
		return(RetCode<0?RetCode:RetCode-StrCount-1-(Separator?1:0));
	}

	// *** Без Диалога! ***
	SetCursorType(0,0);

	if (!(Flags & MSG_KEEPBACKGROUND))
	{
		SetScreen(X1,Y1,X2,Y2,L' ',(Flags & MSG_WARNING)?COL_WARNDIALOGTEXT:COL_DIALOGTEXT);
		MakeShadow(X1+2,Y2+1,X2+2,Y2+1);
		MakeShadow(X2+1,Y1+1,X2+2,Y2+1);
		Box(X1+3,Y1+1,X2-3,Y2-1,(Flags & MSG_WARNING)?COL_WARNDIALOGBOX:COL_DIALOGBOX,DOUBLE_BOX);
	}

	SetColor((Flags & MSG_WARNING)?COL_WARNDIALOGTEXT:COL_DIALOGTEXT);

	if (Title && *Title)
	{
		FARString strTempTitle = Title;

		if (strTempTitle.GetLength() > MaxLength)
			strTempTitle.SetLength(MaxLength);

		GotoXY(X1+(X2-X1-1-(int)strTempTitle.GetLength())/2,Y1+1);
		FS<<L" "<<strTempTitle<<L" ";
	}

	for (I=0; I<StrCount; I++)
	{
		int PosX;
		CPtrStr=Str[I];
		wchar_t Chr=*CPtrStr;

		if (Chr == 1 || Chr == 2)
		{
			int Length=X2-X1-5;

			if (Length>1)
			{
				SetColor((Flags & MSG_WARNING)?COL_WARNDIALOGBOX:COL_DIALOGBOX);
				GotoXY(X1+3,Y1+I+2);
				DrawLine(Length,(Chr == 2?3:1));
				CPtrStr++;
				int TextLength=StrLength(CPtrStr);

				if (TextLength<Length)
				{
					GotoXY(X1+3+(Length-TextLength)/2,Y1+I+2);
					Text(CPtrStr);
				}

				SetColor((Flags & MSG_WARNING)?COL_WARNDIALOGBOX:COL_DIALOGTEXT);
			}

			continue;
		}

		if ((Length=StrLength(CPtrStr))>ScrX-15)
			Length=ScrX-15;

		int Width=X2-X1+1;
		wchar_t *lpwszTemp = nullptr;

		if (Flags & MSG_LEFTALIGN)
		{
			lpwszTemp = (wchar_t*)xf_malloc((Width-10+1)*sizeof(wchar_t));
			swprintf(lpwszTemp,Width-10+1,L"%.*ls",Width-10,CPtrStr);
			GotoXY(X1+5,Y1+I+2);
		}
		else
		{
			PosX=X1+(Width-Length)/2;
			lpwszTemp = (wchar_t*)xf_malloc((PosX-X1-4+Length+X2-PosX-Length-3+1)*sizeof(wchar_t));
			swprintf(lpwszTemp,PosX-X1-4+Length+X2-PosX-Length-3+1,L"%*ls%.*ls%*ls",PosX-X1-4,L"",Length,CPtrStr,X2-PosX-Length-3,L"");
			GotoXY(X1+4,Y1+I+2);
		}

		Text(lpwszTemp);
		xf_free(lpwszTemp);
	}

	/* $ 13.01.2003 IS
	   - Принудительно уберем запрет отрисовки экрана, если количество кнопок
	     в сообщении равно нулю и макрос закончил выполняться. Это необходимо,
	     чтобы заработал прогресс-бар от плагина, который был запущен при помощи
	     макроса запретом отрисовки (bugz#533).
	*/
	xf_free(Str);

	if (!Buttons)
	{
		if (ScrBuf.GetLockCount()>0 && !CtrlObject->Macro.PeekKey())
			ScrBuf.SetLockCount(0);

		ScrBuf.Flush();
	}

	return 0;
}