void DSVReadCommand :: ParseDSV( const string & line, CSVRow & rv ) { CSVRow row; unsigned int pos = 0, len = line.size(); string val; while( pos < len ) { char c = line[ pos++ ]; if ( c == Delim() ) { while( mCollapseSep && ALib::Peek( line, pos ) == Delim() ) { pos++; } row.push_back( Unquote( val ) ); val = ""; } else if ( c == '\\' ) { if ( pos == len ) { CSVTHROW( "Escape at end of line" ); } else { val += line[ pos++ ]; } } else { val += c; } } row.push_back( Unquote( val ) ); BuildCSVRow( row, rv ); }
void Shortcuts::EditItem(VMenu* Menu, ShortcutItem* Item, bool Root) { string strNewDir = Item->strFolder; string strNewPluginModule = Item->strPluginModule; string strNewPluginFile = Item->strPluginFile; string strNewPluginData = Item->strPluginData; DialogBuilder Builder(MFolderShortcutsTitle, HelpFolderShortcuts); Builder.AddText(MFSShortcut); Builder.AddEditField(&strNewDir, 50, L"FS_Path", DIF_EDITPATH); if (!strNewPluginModule.IsEmpty()) { Builder.AddSeparator(); Builder.AddText(MFSShortcutModule); Builder.AddEditField(&strNewPluginModule, 50, nullptr, DIF_READONLY); Builder.AddText(MFSShortcutFile); Builder.AddEditField(&strNewPluginFile, 50, nullptr, DIF_READONLY); Builder.AddText(MFSShortcutData); Builder.AddEditField(&strNewPluginData, 50, nullptr, DIF_READONLY); } Builder.AddOKCancel(); if (Builder.ShowDialog()) { Unquote(strNewDir); if (!IsLocalRootPath(strNewDir)) DeleteEndSlash(strNewDir); bool Save=true; string strTemp(strNewDir); apiExpandEnvironmentStrings(strNewDir,strTemp); if (apiGetFileAttributes(strTemp) == INVALID_FILE_ATTRIBUTES) { Save=!Message(MSG_WARNING | MSG_ERRORTYPE, 2, MSG(MError), strNewDir, MSG(MSaveThisShortcut), MSG(MYes), MSG(MNo)); } if (Save) { Item->strPluginData.Clear(); Item->strPluginFile.Clear(); Item->strPluginModule.Clear(); Item->strFolder = strNewDir; MenuItemEx* MenuItem = Menu->GetItemPtr(); MenuItem->strName = Item->strFolder; if(Root) { MakeItemName(Menu->GetSelectPos(), MenuItem); } Menu->SetPosition(-1, -1, -1, -1); Menu->SetUpdateRequired(TRUE); Menu->Show(); } } }
intptr_t WINAPI MkDirDlgProc(HANDLE hDlg,intptr_t Msg,intptr_t Param1,void* Param2) { switch (Msg) { case DN_LISTCHANGE: { if (Param1 == MKDIR_COMBOBOX_LINKTYPE) { SendDlgMessage(hDlg, DM_ENABLE, MKDIR_EDIT_LINKPATH, ToPtr(Param2 != 0)); } } break; case DN_CLOSE: { if (Param1==MKDIR_OK) { string strDirName=reinterpret_cast<LPCWSTR>(SendDlgMessage(hDlg,DM_GETCONSTTEXTPTR,MKDIR_EDIT,0)); Opt.MultiMakeDir=(SendDlgMessage(hDlg,DM_GETCHECK,MKDIR_CHECKBOX,0)==BSTATE_CHECKED); // это по поводу создания одиночного каталога, который // начинается с пробела! Чтобы ручками не заключать // такой каталог в кавычки if (Opt.MultiMakeDir && !wcspbrk(strDirName,L";,\"")) { QuoteSpaceOnly(strDirName); } // нужно создать только ОДИН каталог if (!Opt.MultiMakeDir) { // уберем все лишние кавычки Unquote(strDirName); // возьмем в кавычки, т.к. могут быть разделители InsertQuote(strDirName); } UserDefinedList* pDirList=reinterpret_cast<UserDefinedList*>(SendDlgMessage(hDlg,DM_GETDLGDATA,0,0)); if (!pDirList->Set(strDirName)) { Message(MSG_WARNING,1,MSG(MWarning),MSG(MIncorrectDirList),MSG(MOk)); return FALSE; } } } break; default: break; } return DefDlgProc(hDlg,Msg,Param1,Param2); }
intptr_t MkDirDlgProc(Dialog* Dlg,intptr_t Msg,intptr_t Param1,void* Param2) { switch (Msg) { case DN_EDITCHANGE: { if (Param1 == MKDIR_COMBOBOX_LINKTYPE) { Dlg->SendMessage( DM_ENABLE, MKDIR_EDIT_LINKPATH, ToPtr(Param2 != 0)); } } break; case DN_CLOSE: { if (Param1==MKDIR_OK) { string strDirName=reinterpret_cast<LPCWSTR>(Dlg->SendMessage(DM_GETCONSTTEXTPTR,MKDIR_EDIT,0)); Global->Opt->MultiMakeDir=(Dlg->SendMessage(DM_GETCHECK,MKDIR_CHECKBOX,0)==BSTATE_CHECKED); // это по поводу создания одиночного каталога, который // начинается с пробела! Чтобы ручками не заключать // такой каталог в кавычки if (Global->Opt->MultiMakeDir && strDirName.find_first_of(L";,\"") == string::npos) { QuoteSpaceOnly(strDirName); } // нужно создать только ОДИН каталог if (!Global->Opt->MultiMakeDir) { // уберем все лишние кавычки // возьмем в кавычки, т.к. могут быть разделители InsertQuote(Unquote(strDirName)); } auto pDirList=reinterpret_cast<std::vector<string>*>(Dlg->SendMessage(DM_GETDLGDATA,0,0)); split(*pDirList, strDirName, STLF_UNIQUE); if (pDirList->empty()) { Message(MSG_WARNING,1,MSG(MWarning),MSG(MIncorrectDirList),MSG(MOk)); return FALSE; } } } break; default: break; } return Dlg->DefProc(Msg,Param1,Param2); }
/* AcceptRhs() - accept a right-hand-side production item. * * On the right-hand side of a production, we just found either an * identifier or a quoted string. If it's an identifier, then it's * either a symbolic name for a terminal, or a non-terminal. If it's * a quoted string, then it's an unnamed terminal. * * We return the TSymbol associated with Token (created or found). */ static TSymbol* AcceptRhs(TToken LhsToken, TToken Token, TRule* Rule) { TSymbol* Symbol = NULL; if(Token.Type == TK_IDENT || Token.Type == TK_QUOTED) { Symbol = SymbolFind(Token); if(Symbol == NULL) /* if unknown identifier, presume non-terminal */ { if(Token.Type == TK_IDENT) Symbol = SymbolNewNonTerm(Token); else if(Token.Type == TK_QUOTED) { int Value = IsCharLiteral(Token); if(Value >= 0) { Symbol = SymbolNewTerm(Token); SymbolSetValue(Symbol, Value); } else { Symbol = LiteralFind(Token); if(Symbol == NULL) { TToken Clean = Unquote(Token); SyntaxError(ERROR_UNDECL_LITERAL_IN_PROD, Token, "Literal '%.*s' in production of '%.*s' should be " "defined with a %%token declaration.\n", Clean.TextLen, Clean.Text, LhsToken.TextLen, LhsToken.Text); } } } else assert(FALSE); } } else assert(FALSE); RuleAddSymbol(Rule, Symbol, Token); Symbol->UsedInRule = TRUE; return Symbol; }
int DeleteFileWithFolder(const string& FileName) { string strFileOrFolderName; strFileOrFolderName = FileName; Unquote(strFileOrFolderName); BOOL Ret=apiSetFileAttributes(strFileOrFolderName,FILE_ATTRIBUTE_NORMAL); if (Ret) { if (apiDeleteFile(strFileOrFolderName)) //BUGBUG { CutToSlash(strFileOrFolderName,true); return apiRemoveDirectory(strFileOrFolderName); } } return FALSE; }
CFilePath &CFilePath::Clean(DWORD dwCleanup) { if (dwCleanup & epcRemoveArgs) { if (dwCleanup & epcTrim) msPath.TrimLeft(); PathRemoveArgs(CStringLock(msPath)); } if (dwCleanup & epcRemoveIconLocation) PathParseIconLocation(CStringLock(msPath)); if (dwCleanup & epcTrim) Trim(); if (dwCleanup & epcUnquote) { Unquote(); if (dwCleanup & epcTrimInQuote) Trim(); } if (dwCleanup & epcExpandEnvStrings) ExpandEnvStrings(); if (dwCleanup & epcCanonicalize) Canonicalize(); if (dwCleanup & epcRemoveXXL) ShrinkXXLPath(); if (dwCleanup & epcSlashToBackslash) msPath.Replace('/', '\\'); if (dwCleanup & epcMakePretty) MakePretty(); return *this; }
static const char* OpSymStr(TOpSym* OpSym) { static char Buffer[256]; static char*Rover = Buffer; char* Result; SYMBOLS List = OpSym->Operator->List; int iList; TSymbol* Sym; assert(OpSym != NULL); if(Rover - Buffer > sizeof(Buffer)-MAX_SYM_STR) Rover = Buffer; Rover[0] = '\0'; if(OpSym->Operator->SymCount > 1) { for(iList=0; iList < SymbolListCount(List); ++iList) { Sym = SymbolListGet(List, iList); if(Sym == NULL) strcat(Rover, "X"); else { TToken Token = LiteralFromSymbol(Sym); if(OpSym->ListIndex == iList) strcat(Rover, "@"); if(Token.Text == NULL) Token = Sym->Name; Token = Unquote(Token); strncat(Rover, Token.Text, Token.TextLen); } } } else sprintf(Rover, "%.*s", OpSym->Operator->Decl.TextLen, OpSym->Operator->Decl.Text); Result = Rover; Rover += strlen(Rover)+1; return Result; }
// используется в GUI при загрузке настроек void FindComspec(ConEmuComspec* pOpt, bool bCmdAlso /*= true*/) { if (!pOpt) return; pOpt->Comspec32[0] = 0; pOpt->Comspec64[0] = 0; // Ищем tcc.exe if (pOpt->csType == cst_AutoTccCmd) { HKEY hk; BOOL bWin64 = IsWindows64(); wchar_t szPath[MAX_PATH+1]; // If tcc.exe can be found near to ConEmu location LPCWSTR ppszPredefined[] = { L"%ConEmuBaseDir%\\tcc.exe", L"%ConEmuDir%\\tcc.exe", // Sort of PortableApps locations L"%ConEmuDir%\\..\\tcc\\tcc.exe", L"%ConEmuDir%\\..\\..\\tcc\\tcc.exe", // End of predefined list NULL}; for (INT_PTR i = 0; ppszPredefined[i]; i++) { DWORD nExpand = ExpandEnvironmentStrings(ppszPredefined[i], szPath, countof(szPath)); if (nExpand && (nExpand < countof(szPath))) { if (FileExists(szPath)) { wcscpy_c(pOpt->Comspec32, szPath); wcscpy_c(pOpt->Comspec64, szPath); break; } } } // On this step - check "Take Command"! if (!*pOpt->Comspec32 || !*pOpt->Comspec64) { // [HKEY_LOCAL_MACHINE\SOFTWARE\JP Software\Take Command 13.0] // @="\"C:\\Program Files\\JPSoft\\TCMD13\\tcmd.exe\"" for (int b = 0; b <= 1; b++) { // b==0 - 32bit, b==1 - 64bit if (b && !bWin64) continue; bool bFound = false; DWORD nOpt = (b == 0) ? (bWin64 ? KEY_WOW64_32KEY : 0) : (bWin64 ? KEY_WOW64_64KEY : 0); if (!RegOpenKeyEx(HKEY_LOCAL_MACHINE, L"SOFTWARE\\JP Software", 0, KEY_READ|nOpt, &hk)) { wchar_t szName[MAX_PATH+1]; DWORD nLen; for (DWORD k = 0; !bFound && !RegEnumKeyEx(hk, k, szName, &(nLen = countof(szName)-1), 0,0,0,0); k++) { HKEY hk2; if (!RegOpenKeyEx(hk, szName, 0, KEY_READ|nOpt, &hk2)) { // Just in case, check "Path" too LPCWSTR rsNames[] = {NULL, L"Path"}; for (size_t n = 0; n < countof(rsNames); n++) { ZeroStruct(szPath); DWORD nSize = (countof(szPath)-1)*sizeof(szPath[0]); if (!RegQueryValueExW(hk2, rsNames[n], NULL, NULL, (LPBYTE)szPath, &nSize) && *szPath) { wchar_t* psz, *pszEnd; psz = (wchar_t*)Unquote(szPath, true); pszEnd = wcsrchr(psz, L'\\'); if (!pszEnd || lstrcmpi(pszEnd, L"\\tcmd.exe") || !FileExists(psz)) continue; lstrcpyn(pszEnd+1, L"tcc.exe", 8); if (FileExists(psz)) { bFound = true; if (b == 0) wcscpy_c(pOpt->Comspec32, psz); else wcscpy_c(pOpt->Comspec64, psz); } } } // for (size_t n = 0; n < countof(rsNames); n++) RegCloseKey(hk2); } } // for, подключи RegCloseKey(hk); } // L"SOFTWARE\\JP Software" } // for (int b = 0; b <= 1; b++) // Если установлен TCMD - предпочтительно использовать именно его, независимо от битности if (*pOpt->Comspec32 && !*pOpt->Comspec64) wcscpy_c(pOpt->Comspec64, pOpt->Comspec32); else if (*pOpt->Comspec64 && !*pOpt->Comspec32) wcscpy_c(pOpt->Comspec32, pOpt->Comspec64); } // If "Take Command" not installed - try "TCC/LE" if (!*pOpt->Comspec32 || !*pOpt->Comspec64) { // [HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\{16A21882-4138-4ADA-A390-F62DC27E4504}] // "DisplayVersion"="13.04.60" // "Publisher"="JP Software" // "DisplayName"="Take Command 13.0" // или // "DisplayName"="TCC/LE 13.0" // и наконец // "InstallLocation"="C:\\Program Files\\JPSoft\\TCMD13\\" for (int b = 0; b <= 1; b++) { // b==0 - 32bit, b==1 - 64bit if (b && !bWin64) continue; if (((b == 0) ? *pOpt->Comspec32 : *pOpt->Comspec64)) continue; // этот уже нашелся в TCMD bool bFound = false; DWORD nOpt = (b == 0) ? (bWin64 ? KEY_WOW64_32KEY : 0) : (bWin64 ? KEY_WOW64_64KEY : 0); if (!RegOpenKeyEx(HKEY_LOCAL_MACHINE, L"SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Uninstall", 0, KEY_READ|nOpt, &hk)) { wchar_t szName[MAX_PATH+1]; DWORD nLen; for (DWORD n = 0; !bFound && !RegEnumKeyEx(hk, n, szName, &(nLen = countof(szName)-1), 0,0,0,0); n++) { if (*szName != L'{') continue; HKEY hk2; if (!RegOpenKeyEx(hk, szName, 0, KEY_READ|nOpt, &hk2)) { ZeroStruct(szPath); DWORD nSize = (countof(szPath) - 1)*sizeof(szPath[0]); if (!RegQueryValueExW(hk2, L"Publisher", NULL, NULL, (LPBYTE)szPath, &nSize) && !lstrcmpi(szPath, L"JP Software")) { nSize = (countof(szPath)-12)*sizeof(szPath[0]); if (!RegQueryValueExW(hk2, L"InstallLocation", NULL, NULL, (LPBYTE)szPath, &nSize) && *szPath) { wchar_t* psz, *pszEnd; if (szPath[0] == L'"') { psz = szPath + 1; pszEnd = wcschr(psz, L'"'); if (pszEnd) *pszEnd = 0; } else { psz = szPath; } if (*psz) { pszEnd = psz+lstrlen(psz); if (*(pszEnd-1) != L'\\') *(pszEnd++) = L'\\'; lstrcpyn(pszEnd, L"tcc.exe", 8); if (FileExists(psz)) { bFound = true; if (b == 0) wcscpy_c(pOpt->Comspec32, psz); else wcscpy_c(pOpt->Comspec64, psz); } } } } RegCloseKey(hk2); } } // for, подключи RegCloseKey(hk); } // L"SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Uninstall" } // for (int b = 0; b <= 1; b++) } // Попытаться "в лоб" из "Program Files" if (!*pOpt->Comspec32 && !*pOpt->Comspec64) { const wchar_t* pszTcmd = L"C:\\Program Files\\JPSoft\\TCMD13\\tcc.exe"; const wchar_t* pszTccLe = L"C:\\Program Files\\JPSoft\\TCCLE13\\tcc.exe"; if (FileExists(pszTcmd)) wcscpy_c(pOpt->Comspec32, pszTcmd); else if (FileExists(pszTccLe)) wcscpy_c(pOpt->Comspec32, pszTccLe); } if (*pOpt->Comspec32 && !*pOpt->Comspec64) wcscpy_c(pOpt->Comspec64, pOpt->Comspec32); else if (*pOpt->Comspec64 && !*pOpt->Comspec32) wcscpy_c(pOpt->Comspec32, pOpt->Comspec64); } // if (pOpt->csType == cst_AutoTccCmd) // С поиском tcc закончили. Теперь, если pOpt->Comspec32/pOpt->Comspec64 остались не заполнены // нужно сначала попытаться обработать переменную окружения ComSpec, а потом - просто "cmd.exe" if (!*pOpt->Comspec32) GetComspecFromEnvVar(pOpt->Comspec32, countof(pOpt->Comspec32), csb_x32); if (!*pOpt->Comspec64) GetComspecFromEnvVar(pOpt->Comspec64, countof(pOpt->Comspec64), csb_x64); }
bool FindImageSubsystem(const wchar_t *Module, /*wchar_t* pstrDest,*/ DWORD& ImageSubsystem, DWORD& ImageBits, DWORD& FileAttrs) { if (!Module || !*Module) return false; bool Result = false; //ImageSubsystem = IMAGE_SUBSYSTEM_UNKNOWN; // Исключения нас не интересуют - команда уже сформирована и отдана в CreateProcess! //// нулевой проход - смотрим исключения //// Берем "исключения" из реестра, которые должны исполняться директом, //// например, некоторые внутренние команды ком. процессора. //string strExcludeCmds; //GetRegKey(strSystemExecutor,L"ExcludeCmds",strExcludeCmds,L""); //UserDefinedList ExcludeCmdsList; //ExcludeCmdsList.Set(strExcludeCmds); //while (!ExcludeCmdsList.IsEmpty()) //{ // if (!StrCmpI(Module,ExcludeCmdsList.GetNext())) // { // ImageSubsystem=IMAGE_SUBSYSTEM_WINDOWS_CUI; // Result=true; // break; // } //} //string strFullName=Module; LPCWSTR ModuleExt = PointToExt(Module); wchar_t *strPathExt/*[32767]*/ = NULL; //(L".COM;.EXE;.BAT;.CMD;.VBS;.JS;.WSH"); wchar_t *strPathEnv/*[32767]*/ = NULL; wchar_t *strExpand/*[32767]*/ = NULL; wchar_t *strTmpName/*[32767]*/ = NULL; wchar_t *pszFilePart = NULL; DWORD nPathExtLen = 0; LPCWSTR pszPathExtEnd = NULL; LPWSTR Ext = NULL; typedef LONG (WINAPI *RegOpenKeyExW_t)(HKEY hKey, LPCTSTR lpSubKey, DWORD ulOptions, REGSAM samDesired, PHKEY phkResult); RegOpenKeyExW_t _RegOpenKeyEx = NULL; typedef LONG (WINAPI *RegQueryValueExW_t)(HKEY hKey, LPCTSTR lpValueName, LPDWORD lpReserved, LPDWORD lpType, LPBYTE lpData, LPDWORD lpcbData); RegQueryValueExW_t _RegQueryValueEx = NULL; typedef LONG (WINAPI *RegCloseKey_t)(HKEY hKey); RegCloseKey_t _RegCloseKey = NULL; HMODULE hAdvApi = NULL; int cchstrPathExt = 32767; strPathExt = (wchar_t*)malloc(cchstrPathExt*sizeof(wchar_t)); *strPathExt = 0; int cchstrPathEnv = 32767; strPathEnv = (wchar_t*)malloc(cchstrPathEnv*sizeof(wchar_t)); *strPathEnv = 0; int cchstrExpand = 32767; strExpand = (wchar_t*)malloc(cchstrExpand*sizeof(wchar_t)); *strExpand = 0; int cchstrTmpName = 32767; strTmpName = (wchar_t*)malloc(cchstrTmpName*sizeof(wchar_t)); *strTmpName = 0; nPathExtLen = GetEnvironmentVariable(L"PATHEXT", strPathExt, cchstrPathExt-2); if (!nPathExtLen) { _wcscpy_c(strPathExt, cchstrPathExt, L".COM;.EXE;.BAT;.CMD;.VBS;.JS;.WSH"); nPathExtLen = lstrlen(strPathExt); } pszPathExtEnd = strPathExt+nPathExtLen; // Разбить на токены strPathExt[nPathExtLen] = strPathExt[nPathExtLen+1] = 0; Ext = wcschr(strPathExt, L';'); while (Ext) { *Ext = 0; Ext = wcschr(Ext+1, L';'); } TODO("Проверить на превышение длин строк"); // первый проход - в текущем каталоге LPWSTR pszExtCur = strPathExt; while (pszExtCur < pszPathExtEnd) { Ext = pszExtCur; pszExtCur = pszExtCur + lstrlen(pszExtCur)+1; _wcscpyn_c(strTmpName, cchstrTmpName, Module, cchstrTmpName); //-V501 if (!ModuleExt) { if (!*Ext) continue; _wcscatn_c(strTmpName, cchstrTmpName, Ext, cchstrTmpName); } if (GetImageSubsystem(strTmpName, ImageSubsystem, ImageBits/*16/32/64*/, FileAttrs)) { Result = true; goto wrap; } if (ModuleExt) { break; } } // второй проход - по правилам SearchPath // поиск по переменной PATH if (GetEnvironmentVariable(L"PATH", strPathEnv, cchstrPathEnv)) { LPWSTR pszPathEnvEnd = strPathEnv + lstrlen(strPathEnv); LPWSTR pszPathCur = strPathEnv; while (pszPathCur && (pszPathCur < pszPathEnvEnd)) { LPWSTR Path = pszPathCur; LPWSTR pszPathNext = wcschr(pszPathCur, L';'); if (pszPathNext) { *pszPathNext = 0; pszPathCur = pszPathNext+1; } else { pszPathCur = pszPathEnvEnd; } if (!*Path) continue; pszExtCur = strPathExt; while (pszExtCur < pszPathExtEnd) { Ext = pszExtCur; pszExtCur = pszExtCur + lstrlen(pszExtCur)+1; if (!*Ext) continue; if (SearchPath(Path, Module, Ext, cchstrTmpName, strTmpName, &pszFilePart)) { if (GetImageSubsystem(strTmpName, ImageSubsystem, ImageBits, FileAttrs)) { Result = true; goto wrap; } } } } } pszExtCur = strPathExt; while (pszExtCur < pszPathExtEnd) { Ext = pszExtCur; pszExtCur = pszExtCur + lstrlen(pszExtCur)+1; if (!*Ext) continue; if (SearchPath(NULL, Module, Ext, cchstrTmpName, strTmpName, &pszFilePart)) { if (GetImageSubsystem(strTmpName, ImageSubsystem, ImageBits, FileAttrs)) { Result = true; goto wrap; } } } // третий проход - лезем в реестр в "App Paths" if (!wcschr(Module, L'\\')) { hAdvApi = LoadLibrary(L"AdvApi32.dll"); if (!hAdvApi) goto wrap; _RegOpenKeyEx = (RegOpenKeyExW_t)GetProcAddress(hAdvApi, "RegOpenKeyExW"); _RegQueryValueEx = (RegQueryValueExW_t)GetProcAddress(hAdvApi, "RegQueryValueExW"); _RegCloseKey = (RegCloseKey_t)GetProcAddress(hAdvApi, "RegCloseKey"); if (!_RegOpenKeyEx || !_RegQueryValueEx || !_RegCloseKey) goto wrap; LPCWSTR RegPath = L"SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\App Paths\\"; // В строке Module заменить исполняемый модуль на полный путь, который // берется из SOFTWARE\Microsoft\Windows\CurrentVersion\App Paths // Сначала смотрим в HKCU, затем - в HKLM HKEY RootFindKey[] = {HKEY_CURRENT_USER,HKEY_LOCAL_MACHINE,HKEY_LOCAL_MACHINE}; BOOL lbAddExt = FALSE; pszExtCur = strPathExt; while (pszExtCur < pszPathExtEnd) { if (!lbAddExt) { Ext = NULL; lbAddExt = TRUE; } else { Ext = pszExtCur; pszExtCur = pszExtCur + lstrlen(pszExtCur)+1; if (!*Ext) continue; } _wcscpy_c(strTmpName, cchstrTmpName, RegPath); _wcscatn_c(strTmpName, cchstrTmpName, Module, cchstrTmpName); if (Ext) _wcscatn_c(strTmpName, cchstrTmpName, Ext, cchstrTmpName); DWORD samDesired = KEY_QUERY_VALUE; DWORD RedirectionFlag = 0; // App Paths key is shared in Windows 7 and above OSVERSIONINFO osv = {sizeof(OSVERSIONINFO)}; GetVersionEx(&osv); if (osv.dwMajorVersion < 6 || (osv.dwMajorVersion == 6 && osv.dwMinorVersion < 1)) { #ifdef _WIN64 RedirectionFlag = KEY_WOW64_32KEY; #else RedirectionFlag = IsWindows64() ? KEY_WOW64_64KEY : 0; #endif } for (size_t i = 0; i < countof(RootFindKey); i++) { if (i == (countof(RootFindKey)-1)) { if (RedirectionFlag) samDesired |= RedirectionFlag; else break; } HKEY hKey; if (_RegOpenKeyEx(RootFindKey[i], strTmpName, 0, samDesired, &hKey) == ERROR_SUCCESS) { DWORD nType = 0, nSize = sizeof(strTmpName)-2; int RegResult = _RegQueryValueEx(hKey, L"", NULL, &nType, (LPBYTE)strTmpName, &nSize); _RegCloseKey(hKey); if ((RegResult == ERROR_SUCCESS) && (nType == REG_SZ || nType == REG_EXPAND_SZ || nType == REG_MULTI_SZ)) { strTmpName[(nSize >> 1)+1] = 0; if (!ExpandEnvironmentStrings(strTmpName, strExpand, cchstrExpand)) _wcscpy_c(strExpand, cchstrExpand, strTmpName); if (GetImageSubsystem(Unquote(strExpand), ImageSubsystem, ImageBits, FileAttrs)) { Result = true; goto wrap; } } } }
int FarAppMain(int argc, char **argv) { Opt.IsUserAdmin = (geteuid()==0); _OT(SysLog(L"[[[[[[[[New Session of FAR]]]]]]]]]")); FARString strEditName; FARString strViewName; FARString DestNames[2]; int StartLine=-1,StartChar=-1; int CntDestName=0; // количество параметров-имен каталогов /*$ 18.04.2002 SKV Попользуем floating point что бы проинициализировался vc-ный fprtl. */ #ifdef _MSC_VER float x=1.1f; wchar_t buf[15]; swprintf(buf,L"%f",x); #endif // если под дебагером, то отключаем исключения однозначно, // иначе - смотря что указал юзвер. #if defined(_DEBUGEXC) Opt.ExceptRules=-1; #else Opt.ExceptRules=-1;//IsDebuggerPresent()?0:-1; #endif // Opt.ExceptRules=-1; #ifdef __GNUC__ Opt.ExceptRules=0; #endif //_SVS(SysLog(L"Opt.ExceptRules=%d",Opt.ExceptRules)); SetRegRootKey(HKEY_CURRENT_USER); Opt.strRegRoot = L"Software/Far2"; // По умолчанию - брать плагины из основного каталога Opt.LoadPlug.MainPluginDir=TRUE; Opt.LoadPlug.PluginsPersonal=TRUE; Opt.LoadPlug.PluginsCacheOnly=FALSE; g_strFarPath = g_strFarModuleName; bool translated = TranslateFarString<TranslateInstallPath_Bin2Share>(g_strFarPath); CutToSlash(g_strFarPath, true); if (translated) { // /usr/bin/something -> /usr/share/far2l g_strFarPath+= L"/" FAR_BASENAME; } WINPORT(SetEnvironmentVariable)(L"FARHOME", g_strFarPath); AddEndSlash(g_strFarPath); // don't inherit from parent process in any case WINPORT(SetEnvironmentVariable)(L"FARUSER", nullptr); WINPORT(SetEnvironmentVariable)(L"FARADMINMODE", Opt.IsUserAdmin?L"1":nullptr); // макросы не дисаблим Opt.Macro.DisableMacro=0; for (int I=1; I<argc; I++) { std::wstring arg_w = MB2Wide(argv[I]); if ((arg_w[0]==L'/' || arg_w[0]==L'-') && arg_w[1]) { switch (Upper(arg_w[1])) { case L'A': switch (Upper(arg_w[2])) { case 0: Opt.CleanAscii=TRUE; break; case L'G': if (!arg_w[3]) Opt.NoGraphics=TRUE; break; } break; case L'E': if (iswdigit(arg_w[2])) { StartLine=_wtoi((const wchar_t *)&arg_w[2]); wchar_t *ChPtr=wcschr((wchar_t *)&arg_w[2],L':'); if (ChPtr) StartChar=_wtoi(ChPtr+1); } if (I+1<argc) { strEditName = argv[I+1]; I++; } break; case L'V': if (I+1<argc) { strViewName = argv[I+1]; I++; } break; case L'M': switch (Upper(arg_w[2])) { case 0: Opt.Macro.DisableMacro|=MDOL_ALL; break; case L'A': if (!arg_w[3]) Opt.Macro.DisableMacro|=MDOL_AUTOSTART; break; } break; case L'I': Opt.SmallIcon=TRUE; break; case L'X': Opt.ExceptRules=0; #if defined(_DEBUGEXC) if (Upper(arg_w[2])==L'D' && !arg_w[3]) Opt.ExceptRules=1; #endif break; case L'C': if (Upper(arg_w[2])==L'O' && !arg_w[3]) { Opt.LoadPlug.PluginsCacheOnly=TRUE; Opt.LoadPlug.PluginsPersonal=FALSE; } break; case L'?': case L'H': ControlObject::ShowCopyright(1); show_help(); return 0; #ifdef DIRECT_RT case L'D': if (Upper(arg_w[2])==L'O' && !arg_w[3]) DirectRT=1; break; #endif case L'W': { Opt.WindowMode=TRUE; } break; } } else // простые параметры. Их может быть max две штукА. { if (CntDestName < 2) { if (IsPluginPrefixPath((const wchar_t *)arg_w.c_str())) { DestNames[CntDestName++] = (const wchar_t *)arg_w.c_str(); } else { apiExpandEnvironmentStrings((const wchar_t *)arg_w.c_str(), DestNames[CntDestName]); Unquote(DestNames[CntDestName]); ConvertNameToFull(DestNames[CntDestName],DestNames[CntDestName]); if (apiGetFileAttributes(DestNames[CntDestName]) != INVALID_FILE_ATTRIBUTES) CntDestName++; //??? } } } } //Настройка OEM сортировки. Должна быть после CopyGlobalSettings и перед InitKeysArray! //LocalUpperInit(); //InitLCIDSort(); //Инициализация массива клавиш. Должна быть после CopyGlobalSettings! InitKeysArray(); //WaitForInputIdle(GetCurrentProcess(),0); std::set_new_handler(nullptr); if (!Opt.LoadPlug.MainPluginDir) //если есть ключ /p то он отменяет /co Opt.LoadPlug.PluginsCacheOnly=FALSE; if (Opt.LoadPlug.PluginsCacheOnly) { Opt.LoadPlug.strCustomPluginsPath.Clear(); Opt.LoadPlug.MainPluginDir=FALSE; Opt.LoadPlug.PluginsPersonal=FALSE; } InitConsole(); GetRegKey(L"Language",L"Main",Opt.strLanguage,L"English"); if (!Lang.Init(g_strFarPath,true,MNewFileName)) { ControlObject::ShowCopyright(1); LPCWSTR LngMsg; switch(Lang.GetLastError()) { case LERROR_BAD_FILE: LngMsg = L"\nError: language data is incorrect or damaged.\n\nPress any key to exit..."; break; case LERROR_FILE_NOT_FOUND: LngMsg = L"\nError: cannot find language data.\n\nPress any key to exit..."; break; default: LngMsg = L"\nError: cannot load language data.\n\nPress any key to exit..."; break; } Console.Write(LngMsg,StrLength(LngMsg)); Console.FlushInputBuffer(); WaitKey(); // А стоит ли ожидать клавишу??? Стоит return 1; } WINPORT(SetEnvironmentVariable)(L"FARLANG",Opt.strLanguage); SetHighlighting(); initMacroVarTable(1); if (Opt.ExceptRules == -1) { GetRegKey(L"System",L"ExceptRules",Opt.ExceptRules,1); } //ErrorMode=SEM_FAILCRITICALERRORS|SEM_NOOPENFILEERRORBOX|(Opt.ExceptRules?SEM_NOGPFAULTERRORBOX:0)|(GetRegKey(L"System/Exception", L"IgnoreDataAlignmentFaults", 0)?SEM_NOALIGNMENTFAULTEXCEPT:0); //SetErrorMode(ErrorMode); int Result=MainProcessSEH(strEditName,strViewName,DestNames[0],DestNames[1],StartLine,StartChar); EmptyInternalClipboard(); doneMacroVarTable(1); VTShell_Shutdown();//ensure VTShell deinitialized before statics destructors called _OT(SysLog(L"[[[[[Exit of FAR]]]]]]]]]")); return Result; }
void ShellMakeDir(Panel *SrcPanel) { FarList ComboList={sizeof(FarList)}; FarListItem LinkTypeItems[3]={}; ComboList.ItemsNumber=ARRAYSIZE(LinkTypeItems); ComboList.Items=LinkTypeItems; ComboList.Items[0].Text=MSG(MMakeFolderLinkNone); ComboList.Items[1].Text=MSG(MMakeFolderLinkJunction); ComboList.Items[2].Text=MSG(MMakeFolderLinkSymlink); ComboList.Items[0].Flags|=LIF_SELECTED; #if 1 //Maximus: поддержка "узких" дисплеев if (ScrX < 10) { _ASSERTE(ScrX>=10); return; } int BorderW = (72<(ScrX-1))?72:(ScrX-1); // 72 int ElemW = BorderW - 2; // 70 #endif FarDialogItem MkDirDlgData[]= { #if 1 //Maximus: поддержка "узких" дисплеев {DI_DOUBLEBOX,3,1,BorderW,10,0,nullptr,nullptr,0,MSG(MMakeFolderTitle)}, #else {DI_DOUBLEBOX,3,1,72,10,0,nullptr,nullptr,0,MSG(MMakeFolderTitle)}, #endif {DI_TEXT, 5,2, 0,2,0,nullptr,nullptr,0,MSG(MCreateFolder)}, #if 1 //Maximus: поддержка "узких" дисплеев {DI_EDIT, 5,3,ElemW,3,0,L"NewFolder",nullptr,DIF_FOCUS|DIF_EDITEXPAND|DIF_HISTORY|DIF_USELASTHISTORY|DIF_EDITPATH,L""}, #else {DI_EDIT, 5,3,70,3,0,L"NewFolder",nullptr,DIF_FOCUS|DIF_EDITEXPAND|DIF_HISTORY|DIF_USELASTHISTORY|DIF_EDITPATH,L""}, #endif {DI_TEXT, -1,4, 0,4,0,nullptr,nullptr,DIF_SEPARATOR,L""}, {DI_TEXT, 5,5, 0,5,0,nullptr,nullptr,0,MSG(MMakeFolderLinkType)}, #if 1 //Maximus: поддержка "узких" дисплеев {DI_COMBOBOX,20,5,ElemW,5,0,nullptr,nullptr,DIF_DROPDOWNLIST|DIF_LISTNOAMPERSAND|DIF_LISTWRAPMODE,L""}, #else {DI_COMBOBOX,20,5,70,5,0,nullptr,nullptr,DIF_DROPDOWNLIST|DIF_LISTNOAMPERSAND|DIF_LISTWRAPMODE,L""}, #endif {DI_TEXT, 5,6, 0,6,0,nullptr,nullptr,0,MSG(MMakeFolderLinkTarget)}, #if 1 //Maximus: поддержка "узких" дисплеев {DI_EDIT, 20,6,ElemW,6,0,L"NewFolderLinkTarget",nullptr,DIF_DISABLE|DIF_EDITEXPAND|DIF_HISTORY|DIF_USELASTHISTORY|DIF_EDITPATH,L""}, #else {DI_EDIT, 20,6,70,6,0,L"NewFolderLinkTarget",nullptr,DIF_DISABLE|DIF_EDITEXPAND|DIF_HISTORY|DIF_USELASTHISTORY|DIF_EDITPATH,L""}, #endif {DI_CHECKBOX, 5,7, 0,7,Global->Opt->MultiMakeDir,nullptr,nullptr,0,MSG(MMultiMakeDir)}, {DI_TEXT, -1,8, 0,8,0,nullptr,nullptr,DIF_SEPARATOR,L""}, {DI_BUTTON, 0,9, 0,9,0,nullptr,nullptr,DIF_DEFAULTBUTTON|DIF_CENTERGROUP,MSG(MOk)}, {DI_BUTTON, 0,9, 0,9,0,nullptr,nullptr,DIF_CENTERGROUP,MSG(MCancel)}, }; auto MkDirDlg = MakeDialogItemsEx(MkDirDlgData); MkDirDlg[MKDIR_COMBOBOX_LINKTYPE].ListItems=&ComboList; std::vector<string> DirList; auto Dlg = Dialog::create(MkDirDlg, MkDirDlgProc, &DirList); #if 1 //Maximus: поддержка "узких" дисплеев Dlg->SetPosition(-1,-1,BorderW+4,12); #else Dlg->SetPosition(-1,-1,76,12); #endif Dlg->SetHelp(L"MakeFolder"); Dlg->SetId(MakeFolderId); Dlg->Process(); if (Dlg->GetExitCode()==MKDIR_OK) { string strDirName=MkDirDlg[MKDIR_EDIT].strData; string strOriginalDirName; bool SkipAll = false; FOR(const auto& i, DirList) { // TODO: almost the same code in dirmix::CreatePath() strDirName = i; strOriginalDirName = strDirName; ConvertNameToFull(strDirName, strDirName); DeleteEndSlash(strDirName); bool bSuccess = false; size_t DirOffset = 0; ParsePath(strDirName, &DirOffset); string Part; Part.reserve(strDirName.size()); for (size_t j = DirOffset; j <= strDirName.size(); ++j) { if (j == strDirName.size() || IsSlash(strDirName[j])) { Part = strDirName.substr(0, j); if (!os::fs::exists(Part) || j == strDirName.size()) // skip all intermediate dirs, but not last. { while(!(bSuccess=(os::CreateDirectory(Part, nullptr)!=FALSE)) && !SkipAll) { Global->CatchError(); int Ret = OperationFailed(strOriginalDirName, MError, MSG(MCannotCreateFolder)); if(Ret == 1) // skip { break; } else if(Ret == 2) { SkipAll = true; break; } else if (Ret < 0 || Ret == 3) // cancel { return; } } if(bSuccess) { TreeList::AddTreeName(Part); } } } } if (bSuccess) { if(MkDirDlg[MKDIR_COMBOBOX_LINKTYPE].ListPos) { string strTarget=MkDirDlg[MKDIR_EDIT_LINKPATH].strData; Unquote(strTarget); while(!CreateReparsePoint(strTarget, strDirName, MkDirDlg[MKDIR_COMBOBOX_LINKTYPE].ListPos==1?RP_JUNCTION:RP_SYMLINKDIR) && !SkipAll) { Global->CatchError(); int Ret = OperationFailed(strDirName, MError, MSG(MCopyCannotCreateLink)); if(Ret == 1) // skip { break; } else if(Ret == 2) { SkipAll = true; break; } else if (Ret < 0 || Ret == 3) // cancel { return; } } } } }
bool FileFilter::FilterEdit() { if (bMenuOpen) return false; Changed = true; bMenuOpen = true; MenuItemEx ListItem; int ExitCode; bool bNeedUpdate=false; VMenu FilterList(MSG(MFilterTitle),nullptr,0,ScrY-6); FilterList.SetHelp(L"FiltersMenu"); FilterList.SetPosition(-1,-1,0,0); FilterList.SetBottomTitle(MSG(MFilterBottom)); FilterList.SetFlags(/*VMENU_SHOWAMPERSAND|*/VMENU_WRAPMODE); for (size_t i=0; i<FilterData.getCount(); i++) { ListItem.Clear(); MenuString(ListItem.strName,FilterData.getItem(i)); if (!i) ListItem.Flags|=LIF_SELECTED; int Check = GetCheck(FilterData.getItem(i)); if (Check) ListItem.SetCheck(Check); FilterList.AddItem(&ListItem); } ListItem.Clear(); if (!FilterData.getCount()) ListItem.Flags|=LIF_SELECTED; FilterList.AddItem(&ListItem); if (m_FilterType != FFT_CUSTOM) { wchar_t *ExtPtr=nullptr; int ExtCount=0; { enumFileFilterFlagsType FFFT = GetFFFT(); for (size_t i=0; i<TempFilterData.getCount(); i++) { //AY: Будем показывать только те выбранные авто фильтры //(для которых нету файлов на панели) которые выбраны в области данного меню if (!TempFilterData.getItem(i)->GetFlags(FFFT)) continue; const wchar_t *FMask; TempFilterData.getItem(i)->GetMask(&FMask); string strMask = FMask; Unquote(strMask); if (!ParseAndAddMasks(&ExtPtr,strMask,0,ExtCount,GetCheck(TempFilterData.getItem(i)))) break; } } ListItem.Clear(); ListItem.Flags|=LIF_SEPARATOR; FilterList.AddItem(&ListItem); ListItem.Clear(); FoldersFilter.SetTitle(MSG(MFolderFileType)); MenuString(ListItem.strName,&FoldersFilter,false,L'0'); int Check = GetCheck(&FoldersFilter); if (Check) ListItem.SetCheck(Check); FilterList.AddItem(&ListItem); if (GetHostPanel()->GetMode()==NORMAL_PANEL) { string strCurDir, strFileName; FAR_FIND_DATA_EX fdata; GetHostPanel()->GetCurDir(strCurDir); ScanTree ScTree(FALSE,FALSE); ScTree.SetFindPath(strCurDir,L"*"); while (ScTree.GetNextName(&fdata,strFileName)) if (!ParseAndAddMasks(&ExtPtr,fdata.strFileName,fdata.dwFileAttributes,ExtCount,0)) break; } else { string strFileName; DWORD FileAttr; for (int i=0; GetHostPanel()->GetFileName(strFileName,i,FileAttr); i++) if (!ParseAndAddMasks(&ExtPtr,strFileName,FileAttr,ExtCount,0)) break; } far_qsort((void *)ExtPtr,ExtCount,MAX_PATH*sizeof(wchar_t),ExtSort); ListItem.Clear(); for (int i=0, h=L'1'; i<ExtCount; i++, (h==L'9'?h=L'A':(h==L'Z'||h?h++:h=0))) { wchar_t *CurExtPtr=ExtPtr+i*MAX_PATH; MenuString(ListItem.strName,nullptr,false,h,true,CurExtPtr,MSG(MPanelFileType)); int Length = StrLength(CurExtPtr)+1; ListItem.SetCheck(CurExtPtr[Length]); FilterList.SetUserData(CurExtPtr, Length*sizeof(wchar_t), FilterList.AddItem(&ListItem)); } xf_free(ExtPtr); } FilterList.Show(); while (!FilterList.Done()) { int Key=FilterList.ReadInput(); if (Key==KEY_ADD) Key=L'+'; else if (Key==KEY_SUBTRACT) Key=L'-'; else if (Key==L'i') Key=L'I'; else if (Key==L'x') Key=L'X'; switch (Key) { case L'+': case L'-': case L'I': case L'X': case KEY_SPACE: case KEY_BS: { int SelPos=FilterList.GetSelectPos(); if (SelPos<0 || SelPos==(int)FilterData.getCount()) break; int Check=FilterList.GetCheck(SelPos); int NewCheck; if (Key==KEY_BS) NewCheck = 0; else if (Key==KEY_SPACE) NewCheck = Check ? 0 : L'+'; else NewCheck = (Check == Key) ? 0 : Key; FilterList.SetCheck(NewCheck,SelPos); FilterList.SetSelectPos(SelPos,1); FilterList.SetUpdateRequired(TRUE); FilterList.FastShow(); FilterList.ProcessKey(KEY_DOWN); bNeedUpdate=true; break; } case KEY_SHIFTBS: { for (int I=0; I < FilterList.GetItemCount(); I++) { FilterList.SetCheck(FALSE, I); } FilterList.SetUpdateRequired(TRUE); FilterList.FastShow(); break; } case KEY_F4: { int SelPos=FilterList.GetSelectPos(); if (SelPos<0) break; if (SelPos<(int)FilterData.getCount()) { if (FileFilterConfig(FilterData.getItem(SelPos))) { ListItem.Clear(); MenuString(ListItem.strName,FilterData.getItem(SelPos)); int Check = GetCheck(FilterData.getItem(SelPos)); if (Check) ListItem.SetCheck(Check); FilterList.DeleteItem(SelPos); FilterList.AddItem(&ListItem,SelPos); FilterList.SetSelectPos(SelPos,1); FilterList.SetUpdateRequired(TRUE); FilterList.FastShow(); bNeedUpdate=true; } } else if (SelPos>(int)FilterData.getCount()) { Message(MSG_WARNING,1,MSG(MFilterTitle),MSG(MCanEditCustomFilterOnly),MSG(MOk)); } break; } case KEY_NUMPAD0: case KEY_INS: case KEY_F5: { int pos=FilterList.GetSelectPos(); if (pos<0) break; size_t SelPos=pos; size_t SelPos2=pos+1; SelPos = Min(FilterData.getCount(), SelPos); FileFilterParams *NewFilter = FilterData.insertItem(SelPos); if (!NewFilter) break; if (Key==KEY_F5) { if (SelPos2 < FilterData.getCount()) { *NewFilter = *FilterData.getItem(SelPos2); NewFilter->SetTitle(L""); NewFilter->ClearAllFlags(); } else if (SelPos2 == FilterData.getCount()+2) { *NewFilter = FoldersFilter; NewFilter->SetTitle(L""); NewFilter->ClearAllFlags(); } else if (SelPos2 > FilterData.getCount()+2) { NewFilter->SetMask(1,static_cast<const wchar_t*>(FilterList.GetUserData(nullptr, 0, static_cast<int>(SelPos2-1)))); //Авто фильтры они только для файлов, папки не должны к ним подходить NewFilter->SetAttr(1,0,FILE_ATTRIBUTE_DIRECTORY); } else { FilterData.deleteItem(SelPos); break; } } else { //AY: Раз создаём новый фильтр то думаю будет логично если он будет только для файлов NewFilter->SetAttr(1,0,FILE_ATTRIBUTE_DIRECTORY); } if (FileFilterConfig(NewFilter)) { ListItem.Clear(); MenuString(ListItem.strName,NewFilter); FilterList.AddItem(&ListItem,static_cast<int>(SelPos)); FilterList.SetSelectPos(static_cast<int>(SelPos),1); FilterList.SetPosition(-1,-1,0,0); FilterList.Show(); bNeedUpdate=true; } else FilterData.deleteItem(SelPos); break; } case KEY_NUMDEL: case KEY_DEL: { int SelPos=FilterList.GetSelectPos(); if (SelPos<0) break; if (SelPos<(int)FilterData.getCount()) { string strQuotedTitle=FilterData.getItem(SelPos)->GetTitle(); InsertQuote(strQuotedTitle); if (!Message(0,2,MSG(MFilterTitle),MSG(MAskDeleteFilter), strQuotedTitle,MSG(MDelete),MSG(MCancel))) { FilterData.deleteItem(SelPos); FilterList.DeleteItem(SelPos); FilterList.SetSelectPos(SelPos,1); FilterList.SetPosition(-1,-1,0,0); FilterList.Show(); bNeedUpdate=true; } } else if (SelPos>(int)FilterData.getCount()) { Message(MSG_WARNING,1,MSG(MFilterTitle),MSG(MCanDeleteCustomFilterOnly),MSG(MOk)); } break; } case KEY_CTRLUP: case KEY_RCTRLUP: case KEY_CTRLDOWN: case KEY_RCTRLDOWN: { int SelPos=FilterList.GetSelectPos(); if (SelPos<0) break; if (SelPos<(int)FilterData.getCount() && !((Key==KEY_CTRLUP || Key==KEY_RCTRLUP) && !SelPos) && !((Key==KEY_CTRLDOWN || Key==KEY_RCTRLDOWN) && SelPos==(int)(FilterData.getCount()-1))) { int NewPos = SelPos + ((Key == KEY_CTRLDOWN || Key == KEY_RCTRLDOWN) ? 1 : -1); MenuItemEx CurItem = *FilterList.GetItemPtr(SelPos); MenuItemEx NextItem = *FilterList.GetItemPtr(NewPos); FilterData.swapItems(NewPos,SelPos); if (NewPos<SelPos) { FilterList.DeleteItem(NewPos,2); FilterList.AddItem(&CurItem,NewPos); FilterList.AddItem(&NextItem,SelPos); } else { FilterList.DeleteItem(SelPos,2); FilterList.AddItem(&NextItem,SelPos); FilterList.AddItem(&CurItem,NewPos); } FilterList.SetSelectPos(NewPos,1); FilterList.SetUpdateRequired(TRUE); FilterList.FastShow(); bNeedUpdate=true; } break; } default: { FilterList.ProcessInput(); //заставляем хоткеи позиционировать курсор на пункте но не закрывать меню if (Key!=KEY_NUMENTER && Key!=KEY_ENTER && Key!=KEY_ESC && Key!=KEY_F10 && (IsAlphaNum(Key) || Key&(KEY_ALT|KEY_RALT))) FilterList.ClearDone(); } } } FilterList.Hide(); ExitCode=FilterList.Modal::GetExitCode(); if (ExitCode!=-1) ProcessSelection(&FilterList); if (Opt.AutoSaveSetup) SaveFilters(); if (ExitCode!=-1 || bNeedUpdate) { if (m_FilterType == FFT_PANEL) { GetHostPanel()->Update(UPDATE_KEEP_SELECTION); GetHostPanel()->Redraw(); } } bMenuOpen = false; return (ExitCode!=-1); }
// Returns true, if application was found in registry: // [HKCU|HKLM]\Software\Microsoft\Windows\CurrentVersion\App Paths // Also, function may change local process %PATH% variable bool SearchAppPaths(LPCWSTR asFilePath, CmdArg& rsFound, bool abSetPath, CmdArg* rpsPathRestore /*= NULL*/) { if (rpsPathRestore) rpsPathRestore->Empty(); if (!asFilePath || !*asFilePath) return false; LPCWSTR pszSearchFile = PointToName(asFilePath); LPCWSTR pszExt = PointToExt(pszSearchFile); // Lets try find it in "App Paths" // "HKCU\Software\Microsoft\Windows\CurrentVersion\App Paths\" // "HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\App Paths\" LPCWSTR pszRoot = L"SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\App Paths\\"; HKEY hk; LONG lRc; CmdArg lsName; lsName.Attach(lstrmerge(pszRoot, pszSearchFile, pszExt ? NULL : L".exe")); // Seems like 32-bit and 64-bit registry branches are the same now, but just in case - will check both DWORD nWOW[2] = {WIN3264TEST(KEY_WOW64_32KEY,KEY_WOW64_64KEY), WIN3264TEST(KEY_WOW64_64KEY,KEY_WOW64_32KEY)}; for (int i = 0; i < 3; i++) { bool bFound = false; DWORD nFlags = ((i && IsWindows64()) ? nWOW[i-1] : 0); if ((i == 2) && !nFlags) break; // This is 32-bit OS lRc = RegOpenKeyEx(i ? HKEY_LOCAL_MACHINE : HKEY_CURRENT_USER, lsName, 0, KEY_READ|nFlags, &hk); if (lRc != 0) continue; wchar_t szVal[MAX_PATH+1] = L""; DWORD nType, nSize = sizeof(szVal)-sizeof(szVal[0]); lRc = RegQueryValueEx(hk, NULL, NULL, &nType, (LPBYTE)szVal, &nSize); if (lRc == 0) { wchar_t *pszCheck = NULL; if (nType == REG_SZ) { pszCheck = szVal; } else if (nType == REG_EXPAND_SZ) { pszCheck = ExpandEnvStr(szVal); } // May be quoted if (pszCheck) { LPCWSTR pszPath = Unquote(pszCheck, true); if (FileExists(pszPath)) { // asFilePath will be invalid after .Set rsFound.Set(pszPath); bFound = true; if (pszCheck != szVal) free(pszCheck); // The program may require additional "%PATH%". So, if allowed... if (abSetPath) { nSize = 0; lRc = RegQueryValueEx(hk, L"PATH", NULL, &nType, NULL, &nSize); if (lRc == 0 && nSize) { wchar_t* pszCurPath = GetEnvVar(L"PATH"); wchar_t* pszAddPath = (wchar_t*)calloc(nSize+4,1); wchar_t* pszNewPath = NULL; if (pszAddPath) { lRc = RegQueryValueEx(hk, L"PATH", NULL, &nType, (LPBYTE)pszAddPath, &nSize); if (lRc == 0 && *pszAddPath) { // Если в "%PATH%" этого нет (в начале) - принудительно добавить int iCurLen = pszCurPath ? lstrlen(pszCurPath) : 0; int iAddLen = lstrlen(pszAddPath); bool bNeedAdd = true; if ((iCurLen >= iAddLen) && (pszCurPath[iAddLen] == L';' || pszCurPath[iAddLen] == 0)) { wchar_t ch = pszCurPath[iAddLen]; pszCurPath[iAddLen] = 0; if (lstrcmpi(pszCurPath, pszAddPath) == 0) bNeedAdd = false; pszCurPath[iAddLen] = ch; } // Если пути еще нет if (bNeedAdd) { if (rpsPathRestore) { rpsPathRestore->SavePathVar(pszCurPath); } pszNewPath = lstrmerge(pszAddPath, L";", pszCurPath); if (pszNewPath) { SetEnvironmentVariable(L"PATH", pszNewPath); } else { _ASSERTE(pszNewPath!=NULL && "Allocation failed?"); } } } } SafeFree(pszAddPath); SafeFree(pszCurPath); SafeFree(pszNewPath); } } } } } RegCloseKey(hk); if (bFound) return true; } return false; }
void ShellMakeDir(Panel *SrcPanel) { FarList ComboList={sizeof(FarList)}; FarListItem LinkTypeItems[3]={}; ComboList.ItemsNumber=ARRAYSIZE(LinkTypeItems); ComboList.Items=LinkTypeItems; ComboList.Items[0].Text=MSG(MMakeFolderLinkNone); ComboList.Items[1].Text=MSG(MMakeFolderLinkJunction); ComboList.Items[2].Text=MSG(MMakeFolderLinkSymlink); ComboList.Items[0].Flags|=LIF_SELECTED; FarDialogItem MkDirDlgData[]= { {DI_DOUBLEBOX,3,1,72,10,0,nullptr,nullptr,0,MSG(MMakeFolderTitle)}, {DI_TEXT, 5,2, 0,2,0,nullptr,nullptr,0,MSG(MCreateFolder)}, {DI_EDIT, 5,3,70,3,0,L"NewFolder",nullptr,DIF_FOCUS|DIF_EDITEXPAND|DIF_HISTORY|DIF_USELASTHISTORY|DIF_EDITPATH,L""}, {DI_TEXT, 0,4, 0,4,0,nullptr,nullptr,DIF_SEPARATOR,L""}, {DI_TEXT, 5,5, 0,5,0,nullptr,nullptr,0,MSG(MMakeFolderLinkType)}, {DI_COMBOBOX,20,5,70,5,0,nullptr,nullptr,DIF_DROPDOWNLIST|DIF_LISTNOAMPERSAND|DIF_LISTWRAPMODE,L""}, {DI_TEXT, 5,6, 0,6,0,nullptr,nullptr,0,MSG(MMakeFolderLinkTarget)}, {DI_EDIT, 20,6,70,6,0,L"NewFolderLinkTarget",nullptr,DIF_DISABLE|DIF_EDITEXPAND|DIF_HISTORY|DIF_USELASTHISTORY|DIF_EDITPATH,L""}, {DI_CHECKBOX, 5,7, 0,7,Opt.MultiMakeDir,nullptr,nullptr,0,MSG(MMultiMakeDir)}, {DI_TEXT, 0,8, 0,8,0,nullptr,nullptr,DIF_SEPARATOR,L""}, {DI_BUTTON, 0,9, 0,9,0,nullptr,nullptr,DIF_DEFAULTBUTTON|DIF_CENTERGROUP,MSG(MOk)}, {DI_BUTTON, 0,9, 0,9,0,nullptr,nullptr,DIF_CENTERGROUP,MSG(MCancel)}, }; MakeDialogItemsEx(MkDirDlgData,MkDirDlg); MkDirDlg[MKDIR_COMBOBOX_LINKTYPE].ListItems=&ComboList; UserDefinedList DirList(ULF_UNIQUE); Dialog Dlg(MkDirDlg,ARRAYSIZE(MkDirDlg),MkDirDlgProc,&DirList); Dlg.SetPosition(-1,-1,76,12); Dlg.SetHelp(L"MakeFolder"); Dlg.SetId(MakeFolderId); Dlg.Process(); if (Dlg.GetExitCode()==MKDIR_OK) { string strDirName=MkDirDlg[MKDIR_EDIT].strData; string strOriginalDirName; const wchar_t *OneDir; DirList.Reset(); bool SkipAll = false; while (nullptr!=(OneDir=DirList.GetNext())) { strDirName = OneDir; strOriginalDirName = strDirName; //Unquote(DirName); if (Opt.CreateUppercaseFolders && !IsCaseMixed(strDirName)) strDirName.Upper(); DeleteEndSlash(strDirName,true); wchar_t* lpwszDirName = strDirName.GetBuffer(); bool bSuccess = false; wchar_t *ChPtr; if(ParsePath(lpwszDirName, const_cast<const wchar_t **>(&ChPtr)) == PATH_UNKNOWN) { ChPtr = lpwszDirName; } for (; ; ChPtr++) { if (IsSlash(*ChPtr) || !*ChPtr) { WCHAR Ch=0; if(*ChPtr) { Ch = ChPtr[1]; ChPtr[1] = 0; } if (*lpwszDirName) { string _strDirName(lpwszDirName); if (apiGetFileAttributes(_strDirName) == INVALID_FILE_ATTRIBUTES || !*ChPtr) // skip all intermediate dirs, but not last. { while(!(bSuccess=(apiCreateDirectory(_strDirName, nullptr)!=FALSE)) && !SkipAll) { int Ret = OperationFailed(strOriginalDirName, MError, MSG(MCannotCreateFolder)); if(Ret == 1) // skip { break; } else if(Ret == 2) { SkipAll = true; break; } else if (Ret < 0 || Ret == 3) // cancel { return; } } if(bSuccess) { TreeList::AddTreeName(_strDirName); } } } if(*ChPtr) { ChPtr[1] = Ch; } else { break; } } } strDirName.ReleaseBuffer(); if (bSuccess) { if(MkDirDlg[MKDIR_COMBOBOX_LINKTYPE].ListPos) { string strTarget=MkDirDlg[MKDIR_EDIT_LINKPATH].strData; Unquote(strTarget); while(!CreateReparsePoint(strTarget, strDirName, MkDirDlg[MKDIR_COMBOBOX_LINKTYPE].ListPos==1?RP_JUNCTION:RP_SYMLINKDIR) && !SkipAll) { int Ret = OperationFailed(strDirName, MError, MSG(MCopyCannotCreateLink)); if(Ret == 1) // skip { break; } else if(Ret == 2) { SkipAll = true; break; } else if (Ret < 0 || Ret == 3) // cancel { return; } } } TreeList::AddTreeName(strDirName); } } SrcPanel->Update(UPDATE_KEEP_SELECTION); if (!strDirName.IsEmpty()) { size_t pos; if (FindSlash(pos,strDirName)) strDirName.SetLength(pos); if (!SrcPanel->GoToFile(strDirName) && strDirName.At(strDirName.GetLength()-1)==L'.') { strDirName.SetLength(strDirName.GetLength()-1); SrcPanel->GoToFile(strDirName); } } SrcPanel->Redraw(); Panel *AnotherPanel=CtrlObject->Cp()->GetAnotherPanel(SrcPanel); int AnotherType=AnotherPanel->GetType(); if (AnotherPanel->NeedUpdatePanel(SrcPanel) || AnotherType==QVIEW_PANEL) { AnotherPanel->Update(UPDATE_KEEP_SELECTION|UPDATE_SECONDARY); AnotherPanel->Redraw(); } } }
BOOL DoParseFile(LPVOID pvContents, DWORD dwSize) { ITEMVECTOR Items; LPWSTR pch, pchSep, pchStart = (LPWSTR)pvContents; pchStart[dwSize / sizeof(WCHAR)] = UNICODE_NULL; // check header const DWORD cbHeader = lstrlenW(g_pszFileHeader) * sizeof(WCHAR); if (memcmp(pchStart, g_pszFileHeader, cbHeader) != 0) return FALSE; pchStart += cbHeader / sizeof(WCHAR); // find the key WCHAR szKey[MAX_STRING]; wsprintfW(szKey, L"[HKEY_LOCAL_MACHINE\\%s]", g_pszKey); pch = wcsstr(pchStart, szKey); if (pch == NULL) return FALSE; pchStart = pch + lstrlenW(szKey); for (;;) { pchStart = SkipSpace(pchStart); if (*pchStart == UNICODE_NULL || *pchStart == L'[') break; pch = wcschr(pchStart, L'\n'); if (pch) *pch = UNICODE_NULL; pchSep = SkipQuoted(pchStart); if (*pchSep == L'=') { *pchSep = UNICODE_NULL; STRING key = pchStart; trim(key); key = Unquote(key); STRING value = pchSep + 1; trim(value); value = Unquote(value); BYTE CharSet1 = DEFAULT_CHARSET, CharSet2 = DEFAULT_CHARSET; size_t pos; pos = key.find(L','); if (pos != STRING::npos) { CharSet1 = (BYTE)_wtoi(&key[pos + 1]); key.resize(pos); trim(key); } pos = value.find(L','); if (pos != STRING::npos) { CharSet2 = (BYTE)_wtoi(&value[pos + 1]); value.resize(pos); trim(value); } ITEM Item(key, value, CharSet1, CharSet2); Items.push_back(Item); } if (pch == NULL) break; pchStart = pch + 1; } g_Items = Items; g_bModified = TRUE; LV_AddItems(g_hListView); return TRUE; }
static const wchar_t *_SubstFileName(const wchar_t *CurStr,TSubstData *PSubstData,string &strOut) { // рассмотрим переключатели активности/пассивности панели. if (!StrCmpN(CurStr,L"!#",2)) { CurStr+=2; PSubstData->PassivePanel=TRUE; return CurStr; } if (!StrCmpN(CurStr,L"!^",2)) { CurStr+=2; PSubstData->PassivePanel=FALSE; return CurStr; } // !! символ '!' if (!StrCmpN(CurStr,L"!!",2) && CurStr[2] != L'?') { strOut += L"!"; CurStr+=2; return CurStr; } // !.! Длинное имя файла с расширением if (!StrCmpN(CurStr,L"!.!",3) && CurStr[3] != L'?') { if (PSubstData->PassivePanel) strOut += PSubstData->strAnotherName; else strOut += PSubstData->Name; CurStr+=3; return CurStr; } // !~ Короткое имя файла без расширения if (!StrCmpN(CurStr,L"!~",2)) { strOut += PSubstData->PassivePanel ? PSubstData->strAnotherShortNameOnly : PSubstData->strShortNameOnly; CurStr+=2; return CurStr; } // !` Длинное расширение файла без имени if (!StrCmpN(CurStr,L"!`",2)) { const wchar_t *Ext; if (CurStr[2] == L'~') { Ext=wcsrchr((PSubstData->PassivePanel ? PSubstData->strAnotherShortName.CPtr():PSubstData->ShortName),L'.'); CurStr+=3; } else { Ext=wcsrchr((PSubstData->PassivePanel ? PSubstData->strAnotherName.CPtr():PSubstData->Name),L'.'); CurStr+=2; } if (Ext && *Ext) strOut += ++Ext; return CurStr; } // !& !&~ список файлов разделенных пробелом. if ((!StrCmpN(CurStr,L"!&~",3) && CurStr[3] != L'?') || (!StrCmpN(CurStr,L"!&",2) && CurStr[2] != L'?')) { string strFileNameL, strShortNameL; Panel *WPanel=PSubstData->PassivePanel?PSubstData->AnotherPanel:PSubstData->ActivePanel; DWORD FileAttrL; int ShortN0=FALSE; int CntSkip=2; if (CurStr[2] == L'~') { ShortN0=TRUE; CntSkip++; } WPanel->GetSelName(nullptr,FileAttrL); int First = TRUE; while (WPanel->GetSelName(&strFileNameL,FileAttrL,&strShortNameL)) { if (ShortN0) strFileNameL = strShortNameL; else // в список все же должно попасть имя в кавычках. QuoteSpaceOnly(strFileNameL); // Вот здесь фиг его знает - нужно/ненужно... // если будет нужно - раскомментируем :-) // if(FileAttrL & FILE_ATTRIBUTE_DIRECTORY) // AddEndSlash(FileNameL); // А нужен ли нам пробел в самом начале? if (First) First = FALSE; else strOut += L" "; strOut += strFileNameL; } CurStr+=CntSkip; return CurStr; } // !@ Имя файла, содержащего имена помеченных файлов // !$! Имя файла, содержащего короткие имена помеченных файлов // Ниже идет совмещение кода для разбора как !@! так и !$! //Вообще-то (по исторической справедливости как бы) - в !$! нужно выбрасывать модификаторы Q и A // Но нафиг нада:) if (!StrCmpN(CurStr,L"!@",2) || !StrCmpN(CurStr,L"!$",2)) { string *pListName; string *pAnotherListName; bool ShortN0 = FALSE; if (CurStr[1] == L'$') ShortN0 = TRUE; if (ShortN0) { pListName = PSubstData->pShortListName; pAnotherListName = PSubstData->pAnotherShortListName; } else { pListName = PSubstData->pListName; pAnotherListName = PSubstData->pAnotherListName; } wchar_t Modifers[32]=L""; const wchar_t *Ptr; if ((Ptr=wcschr(CurStr+2,L'!')) ) { if (Ptr[1] != L'?') { xwcsncpy(Modifers,CurStr+2,Min(ARRAYSIZE(Modifers),static_cast<size_t>(Ptr-(CurStr+2)+1))); if (pListName) { if (PSubstData->PassivePanel && (!pAnotherListName->IsEmpty() || PSubstData->AnotherPanel->MakeListFile(*pAnotherListName,ShortN0,Modifers))) { if (ShortN0) ConvertNameToShort(*pAnotherListName, *pAnotherListName); strOut += *pAnotherListName; } if (!PSubstData->PassivePanel && (!pListName->IsEmpty() || PSubstData->ActivePanel->MakeListFile(*pListName,ShortN0,Modifers))) { if (ShortN0) ConvertNameToShort(*pListName,*pListName); strOut += *pListName; } } else { strOut += CurStr; strOut += Modifers; strOut += L"!"; } CurStr+=Ptr-CurStr+1; return CurStr; } } } // !-! Короткое имя файла с расширением if (!StrCmpN(CurStr,L"!-!",3) && CurStr[3] != L'?') { if (PSubstData->PassivePanel) strOut += PSubstData->strAnotherShortName; else strOut += PSubstData->ShortName; CurStr+=3; return CurStr; } // !+! Аналогично !-!, но если длинное имя файла утеряно // после выполнения команды, FAR восстановит его if (!StrCmpN(CurStr,L"!+!",3) && CurStr[3] != L'?') { if (PSubstData->PassivePanel) strOut += PSubstData->strAnotherShortName; else strOut += PSubstData->ShortName; CurStr+=3; PSubstData->PreserveLFN=TRUE; return CurStr; } // !: Текущий диск if (!StrCmpN(CurStr,L"!:",2)) { string strCurDir; string strRootDir; if (*PSubstData->Name && PSubstData->Name[1]==L':') strCurDir = PSubstData->Name; else if (PSubstData->PassivePanel) PSubstData->AnotherPanel->GetCurDir(strCurDir); else strCurDir = PSubstData->strCmdDir; GetPathRoot(strCurDir,strRootDir); DeleteEndSlash(strRootDir); strOut += strRootDir; CurStr+=2; return CurStr; } // !\ Текущий путь // !/ Короткое имя текущего пути // Ниже идет совмещение кода для разбора как !\ так и !/ if (!StrCmpN(CurStr,L"!\\",2) || !StrCmpN(CurStr,L"!=\\",3) || !StrCmpN(CurStr,L"!/",2) || !StrCmpN(CurStr,L"!=/",3)) { string strCurDir; bool ShortN0 = FALSE; int RealPath= CurStr[1]==L'='?1:0; if (CurStr[1] == L'/' || (RealPath && CurStr[2] == L'/')) { ShortN0 = TRUE; } if (PSubstData->PassivePanel) PSubstData->AnotherPanel->GetCurDir(strCurDir); else strCurDir = PSubstData->strCmdDir; if (RealPath) { _MakePath1(PSubstData->PassivePanel?KEY_ALTSHIFTBACKBRACKET:KEY_ALTSHIFTBRACKET,strCurDir,L"",ShortN0); Unquote(strCurDir); } if (ShortN0) ConvertNameToShort(strCurDir,strCurDir); AddEndSlash(strCurDir); CurStr+=2+RealPath; if (*CurStr==L'!') { if (wcspbrk(PSubstData->PassivePanel?PSubstData->strAnotherName.CPtr():PSubstData->Name,L"\\:")) strCurDir.Clear(); } strOut += strCurDir; return CurStr; } // !?<title>?<init>! if (!StrCmpN(CurStr,L"!?",2) && wcschr(CurStr+2,L'!')) { int j; int i = IsReplaceVariable(CurStr); if (i == -1) // if bad format string { // skip 1 char j = 1; } else { j = i + 1; } strOut.Append(CurStr, j); CurStr += j; return CurStr; } // ! Длинное имя файла без расширения if (*CurStr==L'!') { strOut += PointToName(PSubstData->PassivePanel ? PSubstData->strAnotherNameOnly : PSubstData->strNameOnly); CurStr++; } return CurStr; }
void EnumFiles(VMenu2& Menu, const string& Str) { if(!Str.empty()) { string strStr(Str); size_t Pos = 0; if(std::count(ALL_CONST_RANGE(strStr), L'"') & 1) // odd quotes count { Pos = strStr.rfind(L'"'); } else { for(Pos=strStr.size()-1; Pos!=static_cast<size_t>(-1); Pos--) { if(strStr[Pos]==L'"') { Pos--; while(strStr[Pos]!=L'"' && Pos!=static_cast<size_t>(-1)) { Pos--; } } else if(strStr[Pos]==L' ') { Pos++; break; } } } if(Pos==static_cast<size_t>(-1)) { Pos=0; } bool StartQuote=false; if(Pos < strStr.size() && strStr[Pos]==L'"') { Pos++; StartQuote=true; } string strStart(strStr.data(),Pos); Unquote(strStr.erase(0, Pos)); if(!strStr.empty()) { string strExp = os::env::expand_strings(strStr); os::fs::enum_file Find(strExp+L"*"); bool Separator=false; std::for_each(CONST_RANGE(Find, i) { const wchar_t* FileName=PointToName(strStr); bool NameMatch=!StrCmpNI(FileName, i.strFileName.data(), StrLength(FileName)), AltNameMatch = NameMatch? false : !StrCmpNI(FileName, i.strAlternateFileName.data(), StrLength(FileName)); if(NameMatch || AltNameMatch) { strStr.resize(FileName-strStr.data()); string strAdd (strStr + (NameMatch ? i.strFileName : i.strAlternateFileName)); if (!StartQuote) QuoteSpace(strAdd); string strTmp(strStart+strAdd); if(StartQuote) strTmp += L'"'; if(!Separator) { if(Menu.GetItemCount()) { MenuItemEx Item; Item.strName = MSG(MCompletionFilesTitle); Item.Flags=LIF_SEPARATOR; Menu.AddItem(Item); } else { Menu.SetTitle(MSG(MCompletionFilesTitle)); } Separator=true; } Menu.AddItem(strTmp); } });
void FileFilter::ProcessSelection(VMenu *FilterList) { enumFileFilterFlagsType FFFT = GetFFFT(); FileFilterParams *CurFilterData; for (int i=0,j=0; i < FilterList->GetItemCount(); i++) { int Check=FilterList->GetCheck(i); CurFilterData=nullptr; if (i < (int)FilterData.getCount()) { CurFilterData = FilterData.getItem(i); } else if (i == (int)(FilterData.getCount() + 2)) { CurFilterData = &FoldersFilter; } else if (i > (int)(FilterData.getCount() + 2)) { const wchar_t *FMask=nullptr; string Mask(static_cast<const wchar_t*>(FilterList->GetUserData(nullptr, 0, i))); string strMask1(Mask); //AY: Так как в меню мы показываем только те выбранные авто фильтры //которые выбраны в области данного меню и TempFilterData вполне //может содержать маску которую тока что выбрали в этом меню но //она уже была выбрана в другом и так как TempFilterData //и авто фильтры в меню отсортированы по алфавиту то немного //поколдуем чтоб не было дубликатов в памяти. Unquote(strMask1); while ((CurFilterData=TempFilterData.getItem(j))) { string strMask2; CurFilterData->GetMask(&FMask); strMask2 = FMask; Unquote(strMask2); if (StrCmpI(strMask1,strMask2)<1) break; j++; } if (CurFilterData) { if (!StrCmpI(Mask,FMask)) { if (!Check) { bool bCheckedNowhere = true; for (int n=FFFT_FIRST; n < FFFT_COUNT; n++) { if (n != FFFT && CurFilterData->GetFlags((enumFileFilterFlagsType)n)) { bCheckedNowhere = false; break; } } if (bCheckedNowhere) { TempFilterData.deleteItem(j); continue; } } else { j++; } } else CurFilterData=nullptr; } if (Check && !CurFilterData) { FileFilterParams *NewFilter = TempFilterData.insertItem(j); if (NewFilter) { NewFilter->SetMask(1,Mask); //Авто фильтры они только для файлов, папки не должны к ним подходить NewFilter->SetAttr(1,0,FILE_ATTRIBUTE_DIRECTORY); j++; CurFilterData = NewFilter; } else continue; } } if (!CurFilterData) continue; CurFilterData->SetFlags(FFFT, FFF_NONE); if (Check==L'+') CurFilterData->SetFlags(FFFT, FFF_INCLUDE); else if (Check==L'-') CurFilterData->SetFlags(FFFT, FFF_EXCLUDE); else if (Check==L'I') CurFilterData->SetFlags(FFFT, FFF_INCLUDE|FFF_STRONG); else if (Check==L'X') CurFilterData->SetFlags(FFFT, FFF_EXCLUDE|FFF_STRONG); } }