UnicodeString TStrings::ExtractName(const UnicodeString & S) const { UnicodeString Result = S; intptr_t P = ::AnsiPos(Result, L'='); if (P > 0) { Result.SetLength(P - 1); } else { Result.SetLength(0); } return Result; }
//--------------------------------------------------------------------- void __fastcall TFileSystemInfoDialog::ClipboardAddItem(TControl * Control, int Label, UnicodeString Value) { if (Control->Enabled && !Value.IsEmpty()) { if (FLastFeededControl != Control) { if (FLastFeededControl != NULL) { FClipboard += UnicodeString::StringOfChar(L'-', 60) + L"\r\n"; } FLastFeededControl = Control; } if (dynamic_cast<TListView *>(Control) == NULL) { TGroupBox * Group = dynamic_cast<TGroupBox *>(Control->Parent); assert(Group != NULL); if ((Value.Length() >= 2) && (Value.SubString(Value.Length() - 1, 2) == L"\r\n")) { Value.SetLength(Value.Length() - 2); } FClipboard += FORMAT(L"%s\r\n%s\r\n", (Group->Caption, Value)); } else { assert(dynamic_cast<TListView *>(Control) != NULL); FClipboard += FORMAT(L"%s = %s\r\n", (LoadStr(Label), Value)); } } }
UnicodeString TStrings::GetTextStr() const { UnicodeString Result; intptr_t Count = GetCount(); intptr_t Size = 0; UnicodeString LB = sLineBreak; for (intptr_t I = 0; I < Count; I++) { Size += GetString(I).Length() + LB.Length(); } Result.SetLength(Size); wchar_t * P = const_cast<wchar_t *>(Result.c_str()); for (intptr_t I = 0; I < Count; I++) { UnicodeString S = GetString(I); intptr_t L = S.Length() * sizeof(wchar_t); if (L != 0) { memmove(P, S.c_str(), L); P += S.Length(); } L = LB.Length() * sizeof(wchar_t); if (L != 0) { memmove(P, LB.c_str(), L); P += LB.Length(); } } return Result; }
void TStrings::SetTextStr(const UnicodeString & Text) { BeginUpdate(); SCOPE_EXIT { EndUpdate(); }; { Clear(); const wchar_t * P = Text.c_str(); if (P != nullptr) { while (*P != 0x00) { const wchar_t * Start = P; while (!((*P == 0x00) || (*P == 0x0A) || (*P == 0x0D))) { P++; } UnicodeString S; S.SetLength(P - Start); memmove(const_cast<wchar_t *>(S.c_str()), Start, (P - Start) * sizeof(wchar_t)); Add(S); if (*P == 0x0D) { P++; } if (*P == 0x0A) { P++; } } } } }
//--------------------------------------------------------------------------- UnicodeString MaskFileName(const UnicodeString & FileName, const UnicodeString & Mask) { UnicodeString Result = FileName; if (IsEffectiveFileNameMask(Mask)) { bool Masked; intptr_t P = Mask.LastDelimiter(L"."); if (P > 0) { intptr_t P2 = Result.LastDelimiter("."); // only dot at beginning of file name is not considered as // name/ext separator UnicodeString FileExt = P2 > 1 ? Result.SubString(P2 + 1, Result.Length() - P2) : UnicodeString(); FileExt = MaskFilePart(FileExt, Mask.SubString(P + 1, Mask.Length() - P), Masked); if (P2 > 1) { Result.SetLength(P2 - 1); } Result = MaskFilePart(Result, Mask.SubString(1, P - 1), Masked); if (!FileExt.IsEmpty()) { Result += L"." + FileExt; } } else { Result = MaskFilePart(Result, Mask, Masked); } } return Result; }
//--------------------------------------------------------------------------- UnicodeString __fastcall TConfiguration::TrimVersion(UnicodeString Version) { while ((Version.Pos(L".") != Version.LastDelimiter(L".")) && (Version.SubString(Version.Length() - 1, 2) == L".0")) { Version.SetLength(Version.Length() - 2); } return Version; }
/** * @brief Encoding multibyte to wide std::string * @param $src source char * * @param $cp code page * @return UnicodeString */ UnicodeString MB2W(const char * src, const UINT cp) { // assert(src); if (!src || !*src) { return UnicodeString(L""); } intptr_t reqLength = MultiByteToWideChar(cp, 0, src, -1, nullptr, 0); UnicodeString Result; if (reqLength) { Result.SetLength(reqLength); MultiByteToWideChar(cp, 0, src, -1, const_cast<LPWSTR>(Result.c_str()), static_cast<int>(reqLength)); Result.SetLength(Result.Length() - 1); //remove NULL character } return Result; // .c_str(); }
UnicodeString GetPersonalFolder() { UnicodeString Result; SpecialFolderLocation(CSIDL_PERSONAL, Result); if (IsWine()) { UnicodeString WineHostHome; int Len = ::GetEnvironmentVariable(L"WINE_HOST_HOME", nullptr, 0); if (Len > 0) { WineHostHome.SetLength(Len - 1); ::GetEnvironmentVariable(L"WINE_HOST_HOME", const_cast<LPWSTR>(WineHostHome.c_str()), Len); } if (!WineHostHome.IsEmpty()) { UnicodeString WineHome = L"Z:" + core::ToUnixPath(WineHostHome); if (::DirectoryExists(WineHome)) { Result = WineHome; } } else { // Should we use WinAPI GetUserName() instead? UnicodeString UserName; int Len = ::GetEnvironmentVariable(L"USERNAME", nullptr, 0); if (Len > 0) { UserName.SetLength(Len - 1); ::GetEnvironmentVariable(L"USERNAME", const_cast<LPWSTR>(UserName.c_str()), Len); } if (!UserName.IsEmpty()) { UnicodeString WineHome = L"Z:\\home\\" + UserName; if (::DirectoryExists(WineHome)) { Result = WineHome; } } } } return Result; }
UnicodeString ExcludeTrailingBackslash(const UnicodeString & Str) { UnicodeString Result = Str; if ((Str.Length() > 0) && ((Str[Str.Length()] == L'/') || (Str[Str.Length()] == L'\\'))) { Result.SetLength(Result.Length() - 1); } return Result; }
//--------------------------------------------------------------------------- UnicodeString TConfiguration::TrimVersion(const UnicodeString & Version) const { UnicodeString Result = Version; while ((Result.Pos(L".") != Result.LastDelimiter(L".")) && (Result.SubString(Result.Length() - 1, 2) == L".0")) { Result.SetLength(Result.Length() - 2); } return Result; }
UnicodeString StringOfChar(const wchar_t Ch, intptr_t Len) { UnicodeString Result; if (Len < 0) Len = 0; Result.SetLength(Len); for (intptr_t I = 1; I <= Len; I++) { Result[I] = Ch; } return Result; }
UnicodeString Format(const wchar_t * Format, va_list Args) { UnicodeString Result; if (Format && *Format) { intptr_t Len = _vscwprintf(Format, Args); Result.SetLength(Len + 1); // vswprintf(Buf, Len + 1, Format, args); vswprintf(const_cast<wchar_t *>(Result.c_str()), Len + 1, Format, Args); } return Result.c_str(); }
UnicodeString TrimRight(const UnicodeString & Str) { UnicodeString Result = Str; intptr_t Len = Result.Length(); while (Len > 0 && ((Result[Len] == L' ') || (Result[Len] == L'\n'))) { Len--; } Result.SetLength(Len); return Result; }
//--------------------------------------------------------------------------- UnicodeString TFileMasks::ComposeMaskStr( TStrings * MasksStr, bool Directory) { UnicodeString Result; UnicodeString ResultNoDirMask; for (intptr_t I = 0; I < MasksStr->GetCount(); ++I) { UnicodeString Str = MasksStr->GetString(I).Trim(); if (!Str.IsEmpty()) { for (intptr_t P = 1; P <= Str.Length(); P++) { if (Str.IsDelimiter(AllFileMasksDelimiters, P)) { Str.Insert(Str[P], P); P++; } } UnicodeString StrNoDirMask; if (Directory) { StrNoDirMask = Str; Str = MakeDirectoryMask(Str); } else { while (Str.IsDelimiter(DirectoryMaskDelimiters, Str.Length())) { Str.SetLength(Str.Length() - 1); } StrNoDirMask = Str; } AddToList(Result, Str, FileMasksDelimiterStr); AddToList(ResultNoDirMask, StrNoDirMask, FileMasksDelimiterStr); } } // For directories, the above will add slash ay the end of masks, // breaking size and time masks and thus circumverting their validation. // This performes as hoc validation to cover the scenario. // For files this makes no difference, but no harm either TFileMasks Temp(Directory ? 1 : 0); Temp = ResultNoDirMask; return Result; }
void TRegistry::GetKeyNames(TStrings * Strings) const { Strings->Clear(); TRegKeyInfo Info; UnicodeString S; if (GetKeyInfo(Info)) { S.SetLength(static_cast<intptr_t>(Info.MaxSubKeyLen) + 1); for (DWORD I = 0; I < Info.NumSubKeys; I++) { DWORD Len = Info.MaxSubKeyLen + 1; RegEnumKeyEx(GetCurrentKey(), static_cast<DWORD>(I), &S[1], &Len, nullptr, nullptr, nullptr, nullptr); Strings->Add(S.c_str()); } } }
void TRegistry::GetValueNames(TStrings * Strings) const { Strings->Clear(); TRegKeyInfo Info; UnicodeString S; if (GetKeyInfo(Info)) { S.SetLength(Info.MaxValueLen + 1); for (DWORD I = 0; I < Info.NumValues; I++) { DWORD Len = Info.MaxValueLen + 1; RegEnumValue(GetCurrentKey(), I, &S[1], &Len, nullptr, nullptr, nullptr, nullptr); Strings->Add(S.c_str()); } } }
UnicodeString TStrings::GetDelimitedText() const { UnicodeString Result; intptr_t Count = GetCount(); if ((Count == 1) && GetString(0).IsEmpty()) { Result = GetQuoteChar() + GetQuoteChar(); } else { for (intptr_t I = 0; I < GetCount(); I++) { UnicodeString line = GetString(I); Result += GetQuoteChar() + line + GetQuoteChar() + GetDelimiter(); } if (Result.Length() > 0) Result.SetLength(Result.Length() - 1); } return Result; }
UnicodeString TRegistry::ReadString(const UnicodeString & Name) { UnicodeString Result = L""; TRegDataType RegData = rdUnknown; intptr_t Len = GetDataSize(Name); if (Len > 0) { Result.SetLength(Len); GetData(Name, static_cast<void *>(const_cast<wchar_t *>(Result.c_str())), Len, RegData); if ((RegData == rdString) || (RegData == rdExpandString)) { PackStr(Result); } else { ReadError(Name); } } else { Result = L""; } return Result; }
bool FindFile(UnicodeString & APath) { bool Result = ::FileExists(APath); if (!Result) { intptr_t Len = ::GetEnvironmentVariable(L"PATH", nullptr, 0); if (Len > 0) { UnicodeString Paths; Paths.SetLength(Len - 1); ::GetEnvironmentVariable(L"PATH", reinterpret_cast<LPWSTR>(const_cast<wchar_t *>(Paths.c_str())), static_cast<DWORD>(Len)); UnicodeString NewPath = ::FileSearch(core::ExtractFileName(APath, true), Paths); Result = !NewPath.IsEmpty(); if (Result) { APath = NewPath; } } } return Result; }
bool TRegistry::DeleteKey(const UnicodeString & Key) { bool Result = false; UnicodeString S = Key; bool Relative = Classes::IsRelative(S); HKEY OldKey = GetCurrentKey(); HKEY DeleteKey = GetKey(Key); if (DeleteKey != 0) { auto cleanup = finally([&]() { SetCurrentKey(OldKey); RegCloseKey(DeleteKey); }); { SetCurrentKey(DeleteKey); TRegKeyInfo Info; if (GetKeyInfo(Info)) { UnicodeString KeyName; KeyName.SetLength(Info.MaxSubKeyLen + 1); for (intptr_t I = static_cast<intptr_t>(Info.NumSubKeys) - 1; I >= 0; I--) { DWORD Len = Info.MaxSubKeyLen + 1; if (RegEnumKeyEx(DeleteKey, static_cast<DWORD>(I), &KeyName[1], &Len, nullptr, nullptr, nullptr, nullptr) == ERROR_SUCCESS) { this->DeleteKey(KeyName); } } } } } Result = RegDeleteKey(GetBaseKey(Relative), S.c_str()) == ERROR_SUCCESS; return Result; }
//--------------------------------------------------------------------------- //--------------------------------------------------------------------------- HINSTANCE __fastcall TGUIConfiguration::LoadNewResourceModule(LCID ALocale, UnicodeString * FileName) { UnicodeString LibraryFileName; HINSTANCE NewInstance = 0; bool Internal = (ALocale == InternalLocale()); if (!Internal) { UnicodeString Module; UnicodeString LocaleName; Module = ModuleFileName(); if ((ALocale & AdditionaLanguageMask) != AdditionaLanguageMask) { wchar_t LocaleStr[4]; GetLocaleInfo(ALocale, LOCALE_SABBREVLANGNAME, LocaleStr, LENOF(LocaleStr)); LocaleName = LocaleStr; assert(!LocaleName.IsEmpty()); } else { LocaleName = AdditionaLanguagePrefix + char(ALocale & ~AdditionaLanguageMask); } Module = ChangeFileExt(Module, UnicodeString(L".") + LocaleName); // Look for a potential language/country translation NewInstance = LoadLibraryEx(Module.c_str(), 0, LOAD_LIBRARY_AS_DATAFILE); if (!NewInstance) { // Finally look for a language only translation Module.SetLength(Module.Length() - 1); NewInstance = LoadLibraryEx(Module.c_str(), 0, LOAD_LIBRARY_AS_DATAFILE); if (NewInstance) { LibraryFileName = Module; } } else { LibraryFileName = Module; } } if (!NewInstance && !Internal) { throw Exception(FMTLOAD(LOCALE_LOAD_ERROR, (int(ALocale)))); } else { if (Internal) { NewInstance = HInstance; } } if (FileName != NULL) { *FileName = LibraryFileName; } return NewInstance; }
//--------------------------------------------------------------------------- UnicodeString WrapText(const UnicodeString & Line, intptr_t MaxWidth) { UnicodeString Result; intptr_t LenBuffer = 0; intptr_t SpaceLeft = MaxWidth; if (MaxWidth == 0) { MaxWidth = 78; } if (MaxWidth < 5) { MaxWidth = 5; } /* two passes through the input. the first pass updates the buffer length. * the second pass creates and populates the buffer */ while (Result.Length() == 0) { intptr_t LineCount = 0; if (LenBuffer) { /* second pass, so create the wrapped buffer */ Result.SetLength(LenBuffer + 1); if (Result.Length() == 0) { break; } } wchar_t * w = const_cast<wchar_t *>(Result.c_str()); /* for each Word in Text if Width(Word) > SpaceLeft insert line break before Word in Text SpaceLeft := LineWidth - Width(Word) else SpaceLeft := SpaceLeft - Width(Word) + SpaceWidth */ const wchar_t * s = NextWord(Line.c_str()); while (*s) { SpaceLeft = MaxWidth; /* force the first word to always be completely copied */ while (*s) { if (Result.Length() == 0) { ++LenBuffer; } else { *(w++) = *s; } --SpaceLeft; ++s; } if (!*s) { s = NextWord(nullptr); } /* copy as many words as will fit onto the current line */ while (*s && static_cast<intptr_t>(wcslen(s) + 1) <= SpaceLeft) { if (Result.Length() == 0) { ++LenBuffer; } --SpaceLeft; /* then copy the word */ while (*s) { if (Result.Length() == 0) { ++LenBuffer; } else { *(w++) = *s; } --SpaceLeft; ++s; } if (!*s) { s = NextWord(nullptr); } } if (!*s) { s = NextWord(nullptr); } if (*s) { /* add a new line here */ if (Result.Length() == 0) { ++LenBuffer; } else { *(w++) = L'\n'; } // Skip whitespace before first word on new line while (iswspace(*s)) { ++s; } } ++LineCount; } LenBuffer += 2; if (w) { *w = 0; } } return Result; }
//--------------------------------------------------------------------------- void TFileMasks::CreateMask( const UnicodeString & MaskStr, intptr_t MaskStart, intptr_t /*MaskEnd*/, bool Include) { bool Directory = false; // shut up TMask Mask; Mask.MaskStr = MaskStr; Mask.UserStr = MaskStr; Mask.FileNameMask.Kind = TMaskMask::Any; Mask.FileNameMask.Mask = nullptr; Mask.DirectoryMask.Kind = TMaskMask::Any; Mask.DirectoryMask.Mask = nullptr; Mask.HighSizeMask = TMask::None; Mask.LowSizeMask = TMask::None; Mask.HighModificationMask = TMask::None; Mask.LowModificationMask = TMask::None; wchar_t NextPartDelimiter = L'\0'; intptr_t NextPartFrom = 1; while (NextPartFrom <= MaskStr.Length()) { wchar_t PartDelimiter = NextPartDelimiter; intptr_t PartFrom = NextPartFrom; UnicodeString PartStr = CopyToChars(MaskStr, NextPartFrom, L"<>", false, &NextPartDelimiter, true); intptr_t PartStart = MaskStart + PartFrom - 1; intptr_t PartEnd = MaskStart + NextPartFrom - 1 - 2; TrimEx(PartStr, PartStart, PartEnd); if (PartDelimiter != L'\0') { bool Low = (PartDelimiter == L'>'); TMask::TMaskBoundary Boundary; if ((PartStr.Length() >= 1) && (PartStr[1] == L'=')) { Boundary = TMask::Close; PartStr.Delete(1, 1); } else { Boundary = TMask::Open; } TFormatSettings FormatSettings = TFormatSettings::Create(GetDefaultLCID()); FormatSettings.DateSeparator = L'-'; FormatSettings.TimeSeparator = L':'; FormatSettings.ShortDateFormat = L"yyyy/mm/dd"; FormatSettings.ShortTimeFormat = L"hh:nn:ss"; TDateTime Modification; if (TryStrToDateTime(PartStr, Modification, FormatSettings) || TryRelativeStrToDateTime(PartStr, Modification)) { TMask::TMaskBoundary & ModificationMask = (Low ? Mask.LowModificationMask : Mask.HighModificationMask); if ((ModificationMask != TMask::None) || Directory) { // include delimiter into size part ThrowError(PartStart - 1, PartEnd); } ModificationMask = Boundary; (Low ? Mask.LowModification : Mask.HighModification) = Modification; } else { TMask::TMaskBoundary & SizeMask = (Low ? Mask.LowSizeMask : Mask.HighSizeMask); __int64 & Size = (Low ? Mask.LowSize : Mask.HighSize); if ((SizeMask != TMask::None) || Directory) { // include delimiter into size part ThrowError(PartStart - 1, PartEnd); } SizeMask = Boundary; Size = ParseSize(PartStr); } } else if (!PartStr.IsEmpty()) { intptr_t D = PartStr.LastDelimiter(DirectoryMaskDelimiters); Directory = (D > 0) && (D == PartStr.Length()); if (Directory) { do { PartStr.SetLength(PartStr.Length() - 1); Mask.UserStr.Delete(PartStart - MaskStart + D, 1); D--; } while (PartStr.IsDelimiter(DirectoryMaskDelimiters, PartStr.Length())); D = PartStr.LastDelimiter(DirectoryMaskDelimiters); if (FForceDirectoryMasks == 0) { Directory = false; Mask.MaskStr = Mask.UserStr; } } else if (FForceDirectoryMasks > 0) { Directory = true; Mask.MaskStr.Insert(DirectoryMaskDelimiters[1], PartStart - MaskStart + PartStr.Length()); } if (D > 0) { // make sure sole "/" (root dir) is preserved as is CreateMaskMask( UnixExcludeTrailingBackslash(ToUnixPath(PartStr.SubString(1, D))), PartStart, PartStart + D - 1, false, Mask.DirectoryMask); CreateMaskMask( PartStr.SubString(D + 1, PartStr.Length() - D), PartStart + D, PartEnd, true, Mask.FileNameMask); } else { CreateMaskMask(PartStr, PartStart, PartEnd, true, Mask.FileNameMask); } } } FMasks[MASK_INDEX(Directory, Include)].push_back(Mask); }