| 1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666 | //---------------------------------------------------------------------------#include <vcl.h>#pragma hdrstop#include <Common.h>#include "Editor.h"#include "TextsWin.h"#include "Tools.h"#include <CoreMain.h>#include "VCLCommon.h"#include "WinConfiguration.h"#include "HelpWin.h"#include <BaseUtils.hpp>#include <GUITools.h>//---------------------------------------------------------------------------#pragma package(smart_init)#pragma link "TB2Dock"#pragma link "TBX"#pragma link "TB2Item"#pragma link "TB2Toolbar"#pragma link "TBXStatusBars"#pragma link "PngImageList"#pragma link "TBXExtItems"#pragma resource "*.dfm"//---------------------------------------------------------------------------TForm * __fastcall ShowEditorForm(const UnicodeString FileName, TForm * ParentForm,  TNotifyEvent OnFileChanged, TNotifyEvent OnFileReload, TFileClosedEvent OnClose,  TNotifyEvent OnSaveAll, TAnyModifiedEvent OnAnyModified,  const UnicodeString Caption, bool StandaloneEditor, TColor Color, int InternalEditorEncodingOverride,  bool NewFile){  TEditorForm * Dialog = new TEditorForm(Application);  try  {    Dialog->FileName = FileName;    Dialog->ParentForm = ParentForm;    UnicodeString ACaption = Caption.IsEmpty() ? FileName : Caption;    Dialog->Caption = ACaption + L" - " + LoadStr(EDITOR_CAPTION) + L" - " + AppName;    Dialog->OnFileChanged = OnFileChanged;    Dialog->OnFileReload = OnFileReload;    Dialog->OnSaveAll = OnSaveAll;    Dialog->OnAnyModified = OnAnyModified;    Dialog->StandaloneEditor = StandaloneEditor;    Dialog->BackgroundColor = Color;    Dialog->InternalEditorEncodingOverride = InternalEditorEncodingOverride;    Dialog->NewFile = NewFile;    // load before showing, so when loading failes,    // we do not show an empty editor    Dialog->LoadFile();    Dialog->Show();    // make sure editor closing is announced only if it was ever successfully shown    // (at least current implementation of the events cannot handle that)    Dialog->OnWindowClose = OnClose;  }  catch(...)  {    delete Dialog;    throw;  }  return Dialog;}//---------------------------------------------------------------------------void __fastcall ReconfigureEditorForm(TForm * Form){  TEditorForm * Editor = dynamic_cast<TEditorForm *>(Form);  DebugAssert(Editor != NULL);  Editor->ApplyConfiguration();}//---------------------------------------------------------------------------void __fastcall EditorFormFileUploadComplete(TForm * Form){  DebugNotNull(dynamic_cast<TEditorForm *>(Form))->FileUploadComplete();}//---------------------------------------------------------------------------void __fastcall EditorFormFileSave(TForm * Form){  DebugNotNull(dynamic_cast<TEditorForm *>(Form))->SaveFile();}//---------------------------------------------------------------------------bool __fastcall IsEditorFormModified(TForm * Form){  return DebugNotNull(dynamic_cast<TEditorForm *>(Form))->IsFileModified();}//---------------------------------------------------------------------------class TPreambleFilteringFileStream : public TFileStream{public:  __fastcall TPreambleFilteringFileStream(const UnicodeString AFileName, System::Word Mode,    TEncoding * Encoding, bool AllowPreamble);  virtual int __fastcall Write(const void * Buffer, int Count);  virtual int __fastcall Write(const System::DynamicArray<System::Byte> Buffer, int Offset, int Count);private:  TBytes FPreamble;  bool FDisallowPreamble;};//---------------------------------------------------------------------------__fastcall TPreambleFilteringFileStream::TPreambleFilteringFileStream(    const UnicodeString AFileName, System::Word Mode,    TEncoding * Encoding, bool AllowPreamble) :  TFileStream(AFileName, Mode){  FDisallowPreamble = (Encoding != NULL) && !AllowPreamble;  if (FDisallowPreamble)  {    FPreamble = Encoding->GetPreamble();  }}//---------------------------------------------------------------------------int __fastcall TPreambleFilteringFileStream::Write(const void * Buffer, int Count){  bool IsDisallowedPreamble = false;  if (FDisallowPreamble && (Count > 0) && (FPreamble.Length == Count))  {    int Index = 0;    IsDisallowedPreamble = true;    const unsigned char * ByteBuffer = reinterpret_cast<const unsigned char *>(Buffer);    while (IsDisallowedPreamble && (Index < Count))    {      IsDisallowedPreamble = (ByteBuffer[Index] == FPreamble[Index]);      Index++;    }  }  // only on the first write  FDisallowPreamble = false;  int Result;  if (IsDisallowedPreamble)  {    Result = Count;  }  else  {    Result = TFileStream::Write(Buffer, Count);  }  return Result;}//---------------------------------------------------------------------------int __fastcall TPreambleFilteringFileStream::Write(  const System::DynamicArray<System::Byte> /*Buffer*/, int /*Offset*/, int /*Count*/){  DebugFail();  EXCEPTION;}//---------------------------------------------------------------------------class TEditorRichEdit : public TNewRichEdit{public:  virtual __fastcall TEditorRichEdit(TComponent * AOwner);  bool __fastcall LoadFromStream(TStream * Stream, TEncoding * Encoding, bool & EncodingError);  void __fastcall SetFormat(const TFontConfiguration & FontConfiguration,    TColor FontColor, unsigned int TabSize, bool AWordWrap);  void __fastcall ResetFormat();  int __fastcall FindText(const UnicodeString SearchStr, int StartPos, int Length,    TSearchTypes Options, bool Down);  void __fastcall Redo();  void __fastcall ApplyFont();  __property bool CanRedo = { read = GetCanRedo };  __property bool LoadedWithPreamble = { read = FLoadedWithPreamble };protected:  friend unsigned long __stdcall StreamLoad(DWORD_PTR Cookie, unsigned char * Buff, long Read, long * WasRead);  virtual void __fastcall CreateParams(TCreateParams & Params);  void __fastcall Dispatch(void * Message);  bool __fastcall GetCanRedo();  void __fastcall SetTabSize(unsigned int TabSize);  void __fastcall WMPaste();  void __fastcall EMStreamIn(TMessage & Message);  bool __stdcall StreamLoad(TRichEditStreamInfo * StreamInfo,    unsigned char * Buff, long Read, long & WasRead);private:  HINSTANCE FLibrary;  bool FWordWrap;  unsigned int FTabSize;  bool FInitialized;  bool FStreamLoadEncodingError;  bool FStreamLoadError;  bool FLoadedWithPreamble;  TFontConfiguration FFontConfiguration;  TColor FFontColor;};//---------------------------------------------------------------------------__fastcall TEditorRichEdit::TEditorRichEdit(TComponent * AOwner) :  TNewRichEdit(AOwner),  FLibrary(0),  FTabSize(0),  FWordWrap(true),  FInitialized(false),  FLoadedWithPreamble(false){}//---------------------------------------------------------------------------void __fastcall TEditorRichEdit::ApplyFont(){  std::unique_ptr<TFont> NewFont(new TFont());  TWinConfiguration::RestoreFont(FFontConfiguration, NewFont.get());  NewFont->Size = ScaleByPixelsPerInchFromSystem(NewFont->Size, this);  NewFont->Color = GetWindowTextColor(Color, FFontColor);  // setting DefAttributes may take quite time, even if the font attributes  // do not change, so avoid that if not necessary  if (!FInitialized ||      !SameFont(Font, NewFont.get()) ||      (Font->Color != NewFont->Color))  {    Font->Assign(NewFont.get());    DefAttributes->Assign(Font);  }}//---------------------------------------------------------------------------void __fastcall TEditorRichEdit::SetFormat(  const TFontConfiguration & FontConfiguration, TColor FontColor, unsigned int TabSize,  bool AWordWrap){  if (!FInitialized)  {    // for efficiency we should be creating handle here    DebugAssert(!HandleAllocated());  }  // setting DefAttributes is noop if we do not have a handle  // (btw code below would create one anyway)  HandleNeeded();  LockWindowUpdate(Handle);  FFontConfiguration = FontConfiguration;  FFontColor = FontColor;  ApplyFont();  if (!FInitialized ||      (FTabSize != TabSize))  {    SetTabSize(TabSize);    FTabSize = TabSize;  }  if (!FInitialized ||      (FWordWrap != AWordWrap))  {    DebugAssert(HandleAllocated());    // Undocumented usage of EM_SETTARGETDEVICE.    // But note that it is used by MFC in CRichEditView::WrapChanged()    SendMessage(Handle, EM_SETTARGETDEVICE, 0, (AWordWrap ? 0 : 1));    FWordWrap = AWordWrap;  }  LockWindowUpdate(NULL);  FInitialized = true;}//---------------------------------------------------------------------------void __fastcall TEditorRichEdit::ResetFormat(){  // tabs are paragraph attributes, which default values cannot be set,  // so we need to reapply them after loading file  SetTabSize(FTabSize);}//---------------------------------------------------------------------------int __fastcall TEditorRichEdit::FindText(const UnicodeString SearchStr, int StartPos,  int /*Length*/, TSearchTypes Options, bool Down){  ::FINDTEXTEX Find;  memset(&Find, 0, sizeof(Find));  Find.chrg.cpMin = StartPos;  Find.chrg.cpMax = -1;  Find.lpstrText = UnicodeString(SearchStr).c_str();  unsigned int Flags =    FLAGMASK(Options.Contains(stWholeWord), FR_WHOLEWORD) |    FLAGMASK(Options.Contains(stMatchCase), FR_MATCHCASE) |    FLAGMASK(Down, FR_DOWN);  int Result = SendMessage(Handle, EM_FINDTEXTEX, Flags, (LPARAM)&Find);  return Result;}//---------------------------------------------------------------------------void __fastcall TEditorRichEdit::Redo(){  SendMessage(Handle, EM_REDO, 0, 0);}//---------------------------------------------------------------------------void __fastcall TEditorRichEdit::CreateParams(TCreateParams & Params){  TNewRichEdit::CreateParams(Params);  Params.Style = Params.Style |    (HideScrollBars ? 0 : ES_DISABLENOSCROLL) |    (HideSelection ? 0 : ES_NOHIDESEL);  Params.WindowClass.style = Params.WindowClass.style &    ~(CS_HREDRAW | CS_VREDRAW);}//---------------------------------------------------------------------------void __fastcall TEditorRichEdit::WMPaste(){  // override default pasting to prevent inserting formatted text (RTF).  const wchar_t * Text = NULL;  HANDLE Handle = OpenTextFromClipboard(Text);  if (Handle != NULL)  {    try    {      // replacement for EM_PASTESPECIAL,      // which ignores trailing line end for some reason      Perform(EM_REPLACESEL, true, reinterpret_cast<int>(Text));    }    __finally    {      CloseTextFromClipboard(Handle);    }  }}//---------------------------------------------------------------------------// VCLCOPY Vcl.ComCtrls.passtatic int __fastcall AdjustLineBreaks(unsigned char * Dest, const TBytes & Source, int Start, int Len){  unsigned char * P = Dest;  int I = Start; // Position in Source  while (I < (Len - 1))  {    if ((Source[I] == 10) && (Source[I + 1] == 0))    {      // Convert #10 to #13#10      *P = 13;      P++;      *P = 0;      P++;      *P = 10;      P++;      *P = 0;      P++;    }    else    {      *P = Source[I];      P++;      *P = Source[I + 1];      P++;      if ((Source[I] == 13) && (Source[I + 1] == 0))      {        // Convert #13 to #13#10        *P = 10;        P++;        *P = 0;        P++;        // Skip #10 if preceeded by #13        if ((I < (Len - 3)) &&            (Source[I + 2] == 10) && (Source[I + 3] == 0))        {          I += 2;        }      }    }    I += 2;  }  if (I == Len - 1)  {    *P = Source[I];    P++;  }  return (P - Dest);}//---------------------------------------------------------------------------struct TStreamLoadInfo{  TRichEditStreamInfo * StreamInfo;  TEditorRichEdit * RichEdit;};//---------------------------------------------------------------------------// VCLCOPY Vcl.ComCtrls.pas,// WORKAROUND for bug in BCB XE2-XE6 VCL// Fixes conversion from UTF-8, when read buffer ends in the middle of UTF-8 charstatic unsigned long __stdcall StreamLoad(DWORD_PTR Cookie, unsigned char * Buff, long Read, long * WasRead){  TStreamLoadInfo * LoadInfo = reinterpret_cast<TStreamLoadInfo *>(Cookie);  unsigned long Result =    LoadInfo->RichEdit->StreamLoad(LoadInfo->StreamInfo, Buff, Read, *WasRead) ? 0 : 1;  return Result;}//---------------------------------------------------------------------------void __fastcall TEditorRichEdit::EMStreamIn(TMessage & Message){  TEditStream * EditStream = reinterpret_cast<TEditStream *>(Message.LParam);  EditStream->pfnCallback = &::StreamLoad;  TStreamLoadInfo LoadInfo;  LoadInfo.StreamInfo = reinterpret_cast<TRichEditStreamInfo *>(EditStream->dwCookie);  LoadInfo.RichEdit = this;  EditStream->dwCookie = reinterpret_cast<DWORD_PTR>(&LoadInfo);  TNewRichEdit::Dispatch(&Message);}//---------------------------------------------------------------------------void __fastcall TEditorRichEdit::Dispatch(void * Message){  TMessage * M = static_cast<TMessage *>(Message);  switch (M->Msg)  {    case WM_PASTE:      WMPaste();      break;    case EM_STREAMIN:      EMStreamIn(*M);      break;    default:      TNewRichEdit::Dispatch(Message);      break;  }}//---------------------------------------------------------------------------bool __fastcall TEditorRichEdit::GetCanRedo(){  return (SendMessage(Handle, EM_CANREDO, 0, 0) != 0);}//---------------------------------------------------------------------------void __fastcall TEditorRichEdit::SetTabSize(unsigned int TabSize){  DebugAssert(TabSize > 0);  HDC DC = GetDC(Handle);  SaveDC(DC);  SetMapMode(DC, MM_TEXT);  SelectObject(DC, Font->Handle);  int LogPixelsX = GetDeviceCaps(DC, LOGPIXELSX);  SIZE Size;  GetTextExtentPoint(DC, UnicodeString::StringOfChar(L'X', TabSize).c_str(),    TabSize, &Size);  RestoreDC(DC, -1);  ReleaseDC(Handle, DC);  unsigned int TabTwips = MulDiv(Size.cx, 1440, LogPixelsX);  // save selection  CHARRANGE CharRange;  SendMessage(Handle, EM_EXGETSEL, 0, (LPARAM)&CharRange);  CHARRANGE CharRangeAll;  CharRangeAll.cpMin = 0;  CharRangeAll.cpMax = -1;  SendMessage(Handle, EM_EXSETSEL, 0, (LPARAM)&CharRangeAll);  PARAFORMAT2 ParaFormat;  ParaFormat.cbSize = sizeof(ParaFormat);  ParaFormat.dwMask = PFM_TABSTOPS;  ParaFormat.cTabCount = MAX_TAB_STOPS;  for (int i = 0; i < ParaFormat.cTabCount; i++)  {    ParaFormat.rgxTabs[i] = (i + 1) * TabTwips;  }  SendMessage(Handle, EM_SETPARAFORMAT, 0, (LPARAM)&ParaFormat);  // restore selection  SendMessage(Handle, EM_EXSETSEL, 0, (LPARAM)&CharRange);}//---------------------------------------------------------------------------bool __stdcall TEditorRichEdit::StreamLoad(  TRichEditStreamInfo * StreamInfo, unsigned char * Buff, long Read, long & WasRead){  WasRead = 0;  // VCLCOPY StreamLoad  bool Result;  try  {    if (StreamInfo->Converter != NULL)    {      TBytes Buffer;      Buffer.Length = Read + 1;      Read = Read / 2;      if ((Read % 2) > 0)      {        Read--;      }      WasRead = StreamInfo->Converter->ConvertReadStream(StreamInfo->Stream, Buffer, Read);      if (WasRead > 0)      {        Buffer[WasRead] = 0;        if (Buffer[WasRead - 1] == 13)        {          Buffer[WasRead - 1] = 0;          WasRead--;        }        int StartIndex = 0;        // Convert from desired Encoding to Unicode        if (StreamInfo->PlainText)        {          if (StreamInfo->Encoding == NULL)          {            Buffer = TEncoding::Convert(TEncoding::Default, TEncoding::Unicode, Buffer, 0, WasRead);            WasRead = Buffer.Length;          }          else          {            if (!TEncoding::Unicode->Equals(StreamInfo->Encoding))            {              int MaxTries = StreamInfo->Encoding->GetMaxByteCount(1);              while ((WasRead > 0) &&                     (StreamInfo->Encoding->GetCharCount(Buffer, 0, WasRead)  == 0))              {                WasRead--;                StreamInfo->Stream->Seek(-1, soFromCurrent);                MaxTries--;                if ((MaxTries == 0) || (WasRead == 0))                {                  FStreamLoadEncodingError = true;                  Abort();                }              }              Buffer = TEncoding::Convert(StreamInfo->Encoding, TEncoding::Unicode, Buffer, 0, WasRead);              WasRead = Buffer.Length;            }            // If Unicode preamble is present, set StartIndex to skip over it            TBytes Preamble = TEncoding::Unicode->GetPreamble();            if (DebugAlwaysTrue(Preamble.Length == 2) &&                (WasRead >= 2) && (Buffer[0] == Preamble[0]) && (Buffer[1] == Preamble[1]))            {              StartIndex = 2;              // beware that this is also called from CreateWnd with some              // dummy contents that always have BOM, so FLoadedWithPreamble              // is true, unless overriden by LoadFromStream              FLoadedWithPreamble = true;            }          }        }        WasRead = AdjustLineBreaks(Buff, Buffer, StartIndex, WasRead);      }    }    Result = true;  }  catch (EEncodingError & E)  {    FStreamLoadError = true;    FStreamLoadEncodingError = true;    Result = false;  }  catch (Exception & E)  {    FStreamLoadError = true;    Result = false;  }  return Result;}//---------------------------------------------------------------------------bool __fastcall TEditorRichEdit::LoadFromStream(TStream * Stream, TEncoding * Encoding, bool & EncodingError){  FStreamLoadEncodingError = false;  FStreamLoadError = false;  FLoadedWithPreamble = false;  Lines->LoadFromStream(Stream, Encoding);  if (FStreamLoadError)  {    EncodingError = FStreamLoadEncodingError;  }  return !FStreamLoadError;}//---------------------------------------------------------------------------class TFindDialogEx : public TFindDialog{public:  __fastcall virtual TFindDialogEx(TComponent * AOwner) : TFindDialog(AOwner)  {    FHelpMsg = RegisterWindowMessage(HELPMSGSTRING);  }protected:  unsigned int FHelpMsg;  virtual bool __fastcall MessageHook(TMessage & Msg)  {    bool Result = false;    if (Msg.Msg == FHelpMsg)    {      Application->HelpKeyword(HELP_EDITOR_FIND);      Result = true;    }    if (!Result)    {      Result = TFindDialog::MessageHook(Msg);    }    return Result;  }};//---------------------------------------------------------------------------class TReplaceDialogEx : public TReplaceDialog{public:  __fastcall virtual TReplaceDialogEx(TComponent * AOwner) : TReplaceDialog(AOwner)  {    FHelpMsg = RegisterWindowMessage(HELPMSGSTRING);  }protected:  unsigned int FHelpMsg;  virtual bool __fastcall MessageHook(TMessage & Msg)  {    bool Result = false;    if (Msg.Msg == FHelpMsg)    {      Application->HelpKeyword(HELP_EDITOR_REPLACE);      Result = true;    }    if (!Result)    {      Result = TReplaceDialog::MessageHook(Msg);    }    return Result;  }};//---------------------------------------------------------------------------unsigned int TEditorForm::FInstances = 0;//---------------------------------------------------------------------------__fastcall TEditorForm::TEditorForm(TComponent* Owner)  : TForm(Owner){  FAnsiEncoding = TEncoding::Default;  if (!FAnsiEncoding->IsSingleByte)  {    // We need the GetCharCount to fail for multibyte Ansi encoding (e.g. Japanese Shift-JIS CP592) like the    // TUTF8Encoding does, see the TUTF8Encoding.Create.    // We could use this for single-byte encodings too without any harm probably.    // But for now, try to limit an impact of this change.    // Based on TEncoding.GetANSI.    FAnsiEncoding = new TMBCSEncoding(GetACP(), MB_ERR_INVALID_CHARS, 0);  }  EditorMemo = new TEditorRichEdit(this);  EditorMemo->Parent = this;  EditorMemo->Align = alClient;  EditorMemo->HideSelection = false;  EditorMemo->PlainText = true;  EditorMemo->PopupMenu = EditorPopup;  EditorMemo->ScrollBars = ssBoth;  EditorMemo->WantTabs = true;  EditorMemo->OnChange = EditorMemoChange;  EditorMemo->OnKeyUp = EditorMemoKeyUp;  EditorMemo->OnMouseUp = EditorMemoMouseUp;  // By default the TEditAction's reflect state of the currently focused edit.  // Even if the edit is on a different window.  // This way we explicitly bind them to our editor.  for (int Index = 0; Index < EditorActions->ActionCount; Index++)  {    TEditAction * EditAction = dynamic_cast<TEditAction* >(EditorActions->Actions[Index]);    if (EditAction != NULL)    {      EditAction->Control = EditorMemo;    }  }  FParentForm = NULL;  FCaretPos = TPoint(-1, -1);  FLastFindDialog = NULL;  FCloseAnnounced = false;  ApplyConfiguration();  FFindDialog = new TFindDialogEx(this);  FFindDialog->OnFind = FindDialogFind;  FReplaceDialog = new TReplaceDialogEx(this);  FReplaceDialog->OnFind = FindDialogFind;  FReplaceDialog->OnReplace = FindDialogFind;  FEncoding = NULL;  FSaving = false;  FStandaloneEditor = false;  FClosePending = false;  FReloading = false;  FInternalEditorEncodingOverride = -1;  SetSubmenu(ColorItem);  InitCodePage();  SelectScaledImageList(EditorImages);  UseSystemSettings(this);  UseDesktopFont(StatusBar);  FixFormIcons(this);}//---------------------------------------------------------------------------__fastcall TEditorForm::~TEditorForm(){  DebugAssert(FInstances > 0);  FInstances--;  if (FInstance == 0)  {    UnicodeString WindowParams = StoreForm(this);    // this is particularly to prevent saving the form state    // for the first time, keeping default positioning by a system    if (!FWindowParams.IsEmpty() && (FWindowParams != WindowParams))    {      TEditorConfiguration EditorConfiguration = WinConfiguration->Editor;      EditorConfiguration.WindowParams = StoreForm(this);      WinConfiguration->Editor = EditorConfiguration;    }  }  // see FormClose for explanation  if (!FCloseAnnounced)  {    BackupSave();    DoWindowClose(true);  }  if (FAnsiEncoding != TEncoding::Default)  {    delete FAnsiEncoding;    FAnsiEncoding = NULL;  }  if (FStandaloneEditor)  {    TerminateApplication();  }}//---------------------------------------------------------------------------UnicodeString __fastcall TEditorForm::GetCodePageName(TEncoding * Encoding){  if (Encoding == TEncoding::UTF8)  {    return LoadStr(UTF8_NAME);  }  else  {    return DefaultEncodingName();  }}//---------------------------------------------------------------------------void __fastcall TEditorForm::InitCodePage(){  DefaultEncodingAction->Caption = DefaultEncodingName();  DefaultEncodingAction->Hint = FORMAT(DefaultEncodingAction->Hint, (DefaultEncodingName()));}//---------------------------------------------------------------------------void __fastcall TEditorForm::SetFileName(const UnicodeString value){  if (value != FFileName)  {    FFileName = value;    if (Visible)    {      LoadFile();    }  }}//---------------------------------------------------------------------------void __fastcall TEditorForm::EditorActionsUpdate(TBasicAction *Action,      bool &Handled){  Handled = true;  if (Action == SaveAction)  {    SaveAction->Enabled = IsFileModified();  }  else if (Action == SaveAllAction2)  {    bool Enabled = !EditorMemo->ReadOnly && !FStandaloneEditor;    if (Enabled)    {      Enabled = IsFileModified();      // optimization      if (!Enabled)      {        FOnAnyModified(this, Enabled);      }    }    SaveAllAction2->Enabled = Enabled;  }  else if (Action == ReplaceAction)  {    ReplaceAction->Enabled = !EditorMemo->ReadOnly;  }  else if (Action == FindNextAction)  {    FindNextAction->Enabled =      FLastFindDialog != NULL || !FFindDialog->FindText.IsEmpty();  }  else if (Action == EditRedo)  {    EditRedo->Enabled = EditorMemo->CanRedo;  }  else if (Action == PreferencesAction ||    Action == FindAction || Action == ReplaceAction || Action == GoToLineAction ||    Action == HelpAction || Action == ColorAction)  {    ((TAction *)Action)->Enabled = true;  }  else if (Action == ReloadAction)  {    ReloadAction->Enabled = !FReloading && !NewFile;  }  else if (Action == DefaultEncodingAction)  {    DefaultEncodingAction->Enabled = true;    DefaultEncodingAction->Checked = (FEncoding == FAnsiEncoding);  }  else if (Action == UTF8EncodingAction)  {    UTF8EncodingAction->Enabled = true;    UTF8EncodingAction->Checked = (FEncoding == TEncoding::UTF8);  }  else  {    Handled = false;  }}//---------------------------------------------------------------------------void __fastcall TEditorForm::SaveToFile(){  std::unique_ptr<TStream> Stream(    new TPreambleFilteringFileStream(      ApiPath(FFileName), fmCreate, FEncoding, EditorMemo->LoadedWithPreamble));  EditorMemo->Lines->SaveToStream(Stream.get(), FEncoding);}//---------------------------------------------------------------------------void __fastcall TEditorForm::SaveFile(){  // Test is needed for "Save all" and is redundant for "Save"  if (IsFileModified())  {    DebugAssert(!FFileName.IsEmpty());    SaveToFile();    if (FOnFileChanged)    {      FOnFileChanged(this);    }    FSaving = true;    EditorMemo->Modified = false;    NewFile = false;    UpdateControls();  }}//---------------------------------------------------------------------------bool __fastcall TEditorForm::IsFileModified(){  return EditorMemo->Modified;}//---------------------------------------------------------------------------void __fastcall TEditorForm::EditorActionsExecute(TBasicAction *Action,      bool &Handled){  Handled = true;  if (Action == SaveAction)  {    SaveFile();  }  else if (Action == SaveAllAction2)  {    OnSaveAll(this);  }  else if (Action == PreferencesAction)  {    DoPreferencesDialog(pmEditorInternal);  }  else if (Action == ReloadAction)  {    Reload();  }  else if (Action == FindAction || Action == ReplaceAction)  {    StartFind(Action == FindAction);  }  else if (Action == FindNextAction)  {    if (!FLastFindDialog)    {      FLastFindDialog = FFindDialog;    }    Find();  }  else if (Action == GoToLineAction)  {    GoToLine();  }  else if (Action == EditRedo)  {    EditorMemo->Redo();  }  else if (Action == HelpAction)  {    FormHelp(this);  }  else if (Action == DefaultEncodingAction)  {    ChangeEncoding(FAnsiEncoding);  }  else if (Action == UTF8EncodingAction)  {    ChangeEncoding(TEncoding::UTF8);  }  else if (Action == ColorAction)  {    if (DebugAlwaysTrue(Action->ActionComponent != NULL))    {      CreateEditorBackgroundColorMenu(Action->ActionComponent, BackgroundColor,        SetBackgroundColor);    }  }  else  {    Handled = false;  }}//---------------------------------------------------------------------------void __fastcall TEditorForm::BackupSave(){  if (IsFileModified())  {    int Uniq = 0;    while (true)    {      UnicodeString FileName = FFileName + L".bak" + (Uniq == 0 ? UnicodeString() : IntToStr(Uniq));      UnicodeString ApiFileName = ApiPath(FileName);      if (!FileExists(ApiFileName))      {        EditorMemo->Lines->SaveToFile(ApiFileName, FEncoding);        break;      }      Uniq++;    }  }}//---------------------------------------------------------------------------void __fastcall TEditorForm::ChangeEncoding(TEncoding * Encoding){  if (FEncoding != Encoding)  {    if (!IsFileModified() ||        (MessageDialog(MainInstructions(LoadStr(EDITOR_MODIFIED_ENCODING)), qtConfirmation,          qaOK | qaCancel) != qaCancel))    {      TEncoding * PrevEncoding = FEncoding;      try      {        FEncoding = Encoding;        LoadFile();      }      catch(...)      {        // try to restore        FEncoding = PrevEncoding;        LoadFile();        throw;      }    }  }}//---------------------------------------------------------------------------void __fastcall TEditorForm::FormCloseQuery(TObject * /*Sender*/,      bool &CanClose){  if (IsFileModified())  {    SetFocus();    UnicodeString Message = MainInstructions(LoadStr(SAVE_CHANGES));    unsigned int Answer = MessageDialog(Message, qtConfirmation,      qaYes | qaNo | qaCancel);    CanClose = (Answer != qaCancel);    if (Answer == qaYes)    {      SaveAction->Execute();      if (FStandaloneEditor)      {        CanClose = false;        FClosePending = true;      }    }  }}//---------------------------------------------------------------------------void __fastcall TEditorForm::ApplyConfiguration(){  Color = GetBtnFaceColor();  bool PrevModified = IsFileModified();  DebugAssert(Configuration);  EditorMemo->SetFormat(WinConfiguration->Editor.Font,    WinConfiguration->Editor.FontColor,    WinConfiguration->Editor.TabSize,    WinConfiguration->Editor.WordWrap);  UpdateBackgroundColor();  EditorMemo->Modified = PrevModified;  EditorMemo->ClearUndo();  Enabled = !WinConfiguration->LockedInterface;  UpdateControls();}//---------------------------------------------------------------------------void __fastcall TEditorForm::FileUploadComplete(){  DebugAssert(FSaving);  FSaving = false;  UpdateControls();  if (FClosePending && DebugAlwaysTrue(FStandaloneEditor))  {    Close();  }}//---------------------------------------------------------------------------void __fastcall TEditorForm::UpdateControls(){  // To disable saving, e.g. in encryption mode (no queue support) - both OnFileChanged and OnSaveAll are NULL.  // But internal editors have (OnFileChanged == NULL), but OnSaveAll set, so we use OnSaveAll for dicision  EditorMemo->ReadOnly = (OnSaveAll == NULL);  TPoint ACaretPos = EditorMemo->CaretPos;  if (ACaretPos.x != FCaretPos.x || ACaretPos.y != FCaretPos.y)  {    FCaretPos = ACaretPos;    int Count = EditorMemo->Lines->Count;    StatusBar->Panels->Items[0]->Caption = FMTLOAD(EDITOR_LINE_STATUS,      ((int)FCaretPos.y+1, Count));    int Column = 0;    UnicodeString Character;    if (FCaretPos.y >= 0 && FCaretPos.y < EditorMemo->Lines->Count)    {      UnicodeString Line = EditorMemo->Lines->Strings[FCaretPos.y];      int TabSize = WinConfiguration->Editor.TabSize;      for (int Index = 1; Index <= FCaretPos.x + 1; Index++)      {        if ((Index - 1 >= 1) && (Index - 1 <= Line.Length()) && (Line[Index - 1] == L'\t') &&            (TabSize > 0)) // sanity check        {          Column = (((Column / TabSize) + 1) * TabSize) + 1;        }        else        {          Column++;        }      }      if (FCaretPos.x+1 <= Line.Length())      {        int Code;        wchar_t Ch = Line[FCaretPos.x + 1];        if (FEncoding == FAnsiEncoding)        {          char Buf[10];          BOOL UsedDefaultChar = FALSE;          int Conversion =            WideCharToMultiByte(CP_ACP, WC_NO_BEST_FIT_CHARS, &Ch, 1,              Buf, sizeof(Buf), NULL, &UsedDefaultChar);          // actually with multibyte encoding it may be > 1,          if ((Conversion == 1) && !UsedDefaultChar)          {            Code = static_cast<int>(static_cast<unsigned char>(Buf[0]));          }          else          {            Code = -1;          }        }        else        {          Code = static_cast<int>(Ch);        }        if (Code >= 0)        {          Character = FMTLOAD(EDITOR_CHARACTER_STATUS2, (Code, Code));        }      }    }    StatusBar->Panels->Items[1]->Caption =      (Column > 0) ? FMTLOAD(EDITOR_COLUMN_STATUS, (Column)) : UnicodeString();    StatusBar->Panels->Items[2]->Caption = Character;  }  StatusBar->Panels->Items[3]->Caption = FMTLOAD(EDITOR_ENCODING_STATUS, (FEncodingName));  UnicodeString Status;  if (EditorMemo->ReadOnly)  {    Status = LoadStr(EDITOR_READONLY);  }  else if (FSaving)  {    Status = LoadStr(EDITOR_SAVING);  }  else if (NewFile)  {    Status = LoadStr(EDITOR_NEW);  }  else if (IsFileModified())  {    Status = LoadStr(EDITOR_MODIFIED);  }  StatusBar->Panels->Items[4]->Caption = Status;  EditorActions->UpdateAction(SaveAction);  Encoding->Enabled = !NewFile;}//---------------------------------------------------------------------------void __fastcall TEditorForm::EditorMemoMouseUp(TObject * /*Sender*/,      TMouseButton /*Button*/, TShiftState /*Shift*/, int /*X*/, int /*Y*/){  UpdateControls();}//---------------------------------------------------------------------------void __fastcall TEditorForm::EditorMemoKeyUp(TObject * /*Sender*/,    WORD & /*Key*/, TShiftState /*Shift*/){  UpdateControls();}//---------------------------------------------------------------------------void __fastcall TEditorForm::EditorMemoChange(TObject * /*Sender*/){  UpdateControls();}//---------------------------------------------------------------------------void __fastcall TEditorForm::FindDialogFind(TObject * /*Sender*/){  Find();}//---------------------------------------------------------------------------void __fastcall TEditorForm::Find(){  int NewPos;  int Replacements = 0;  do  {    DebugAssert(FLastFindDialog);    TSearchTypes SearchTypes;    // length condition is there to improve performance when large    // block is selected in editor    if (FLastFindDialog == FReplaceDialog &&        (FReplaceDialog->Options.Contains(frReplace) ||         FReplaceDialog->Options.Contains(frReplaceAll)) &&        FReplaceDialog->FindText.Length() == EditorMemo->SelLength &&        AnsiSameText(FReplaceDialog->FindText, EditorMemo->SelText))    {      EditorMemo->SelText = FReplaceDialog->ReplaceText;      Replacements++;    }    TEditorConfiguration EditorConfiguration = WinConfiguration->Editor;    EditorConfiguration.FindText = FLastFindDialog->FindText;    EditorConfiguration.ReplaceText = FReplaceDialog->ReplaceText;    EditorConfiguration.FindMatchCase = FLastFindDialog->Options.Contains(frMatchCase);    EditorConfiguration.FindWholeWord = FLastFindDialog->Options.Contains(frWholeWord);    EditorConfiguration.FindDown = FLastFindDialog->Options.Contains(frDown);    WinConfiguration->Editor = EditorConfiguration;    if (EditorConfiguration.FindMatchCase)    {      SearchTypes << stMatchCase;    }    if (EditorConfiguration.FindWholeWord)    {      SearchTypes << stWholeWord;    }    NewPos = EditorMemo->FindText(EditorConfiguration.FindText,      EditorMemo->SelLength ? EditorMemo->SelStart+1 : EditorMemo->SelStart,      EditorMemo->Text.Length(), SearchTypes, EditorConfiguration.FindDown);    if (NewPos >= 0)    {      EditorMemo->SelStart = NewPos;      EditorMemo->SelLength = EditorConfiguration.FindText.Length();    }    if (FLastFindDialog->Handle)    {      PositionFindDialog(true);    }    if (NewPos < 0)    {      if ((Replacements == 0) || FReplaceDialog->Options.Contains(frReplaceAll))      {        // now Screen->ActiveForm can be NULL when other form was meanwhile        // activated and then focus was returned back to "find" dialog        // (non VCL form)        if (Screen->ActiveForm != this)        {          SetFocus();          FLastFindDialog->Execute();        }        if (Replacements == 0)        {          UnicodeString Message = MainInstructions(FMTLOAD(EDITOR_FIND_END, (EditorConfiguration.FindText)));          MessageDialog(Message, qtInformation, qaOK, HELP_NONE);        }        else if (FReplaceDialog->Options.Contains(frReplaceAll))        {          UnicodeString Message = MainInstructions(FMTLOAD(EDITOR_REPLACE_END, (Replacements)));          MessageDialog(Message, qtInformation, qaOK, HELP_NONE);        }      }    }  }  while (NewPos >= 0 && FLastFindDialog == FReplaceDialog &&         FReplaceDialog->Options.Contains(frReplaceAll));}//---------------------------------------------------------------------------void __fastcall TEditorForm::FormShow(TObject * /*Sender*/){  if (DebugAlwaysTrue(FParentForm != NULL))  {    // Forms should be at the same monitor    DebugAssert(PixelsPerInch == FParentForm->PixelsPerInch);    Width = MulDiv(FParentForm->BoundsRect.Width(), PixelsPerInch, FParentForm->PixelsPerInch);    Height = MulDiv(FParentForm->BoundsRect.Height(), PixelsPerInch, FParentForm->PixelsPerInch);  }  CutFormToDesktop(this);  DebugAssert(FWindowParams.IsEmpty());  if (FWindowParams.IsEmpty())  {    FWindowParams = StoreForm(this);  }}//---------------------------------------------------------------------------// VCLCOPY ComCtrls.pasbool __fastcall TEditorForm::ContainsPreamble(TStream * Stream, const TBytes & Signature){  bool Result;  TBytes Buffer;  int LBufLen;  int LSignatureLen = Signature.Length;  __int64 LPosition = Stream->Position;  try  {    Buffer.Length = LSignatureLen;    LBufLen = Stream->Read(&Buffer[0], LSignatureLen);  }  __finally  {    Stream->Position = LPosition;  }  if (LBufLen == LSignatureLen)  {    Result = true;    for (int I = 1; I <= LSignatureLen; I++)    {      if (Buffer[I - 1] != Signature[I - 1])      {        Result = false;        break;      }    }  }  else  {    Result = false;  }  return Result;}//---------------------------------------------------------------------------void __fastcall TEditorForm::LoadFromFile(bool PrimaryEncoding){  TStream * Stream = new TFileStream(ApiPath(FFileName), fmOpenRead | fmShareDenyWrite);  try  {    bool CanTrySecondary;    if (FEncoding == NULL)    {      int Encoding;      if (ContainsPreamble(Stream, TEncoding::UTF8->GetPreamble()))      {        Encoding = CP_UTF8;        CanTrySecondary = false;      }      else      {        if (InternalEditorEncodingOverride >= 0)        {          Encoding = InternalEditorEncodingOverride;        }        else        {          Encoding = WinConfiguration->Editor.Encoding;        }        CanTrySecondary = true;      }      switch (Encoding)      {        case CP_UTF8:          FEncoding = PrimaryEncoding ? TEncoding::UTF8 : FAnsiEncoding;          break;        default:          CanTrySecondary = false;          DebugFail();          // fallthru        case CP_ACP:          FEncoding = PrimaryEncoding ? FAnsiEncoding : TEncoding::UTF8;          break;      }    }    else    {      CanTrySecondary = false;    }    FEncodingName = GetCodePageName(FEncoding);    bool EncodingError;    if (!EditorMemo->LoadFromStream(Stream, FEncoding, EncodingError))    {      if (EncodingError)      {        UnicodeString Message = FMTLOAD(EDITOR_ENCODING_ERROR, (FFileName, FEncodingName));        if (PrimaryEncoding && CanTrySecondary)        {          TEncoding * EncodingBackup = FEncoding;          UnicodeString EncodingNameBackup = FEncodingName;          try          {            FEncoding = NULL;            LoadFromFile(false);            TEditorConfiguration EditorConfiguration = WinConfiguration->Editor;            if (EditorConfiguration.WarnOnEncodingFallback)            {              // by now the FEncodingName is the secondary encoding              Message = Message + L" " + FMTLOAD(EDITOR_ENCODING_REVERTED, (FEncodingName));              TMessageParams Params(mpNeverAskAgainCheck);              unsigned int Answer =                MessageDialog(MainInstructions(Message), qtInformation, qaOK, HELP_NONE, &Params);              if (Answer == qaNeverAskAgain)              {                EditorConfiguration.WarnOnEncodingFallback = false;                WinConfiguration->Editor = EditorConfiguration;              }            }          }          catch(...)          {            // restored values are never used anyway, as this can get here only            // when opening editor and this is fatal error preventing the editor from opening            FEncoding = EncodingBackup;            FEncodingName = EncodingNameBackup;            throw Exception(Message);          }        }        else        {          throw Exception(Message);        }      }      else      {        throw Exception(MainInstructions(FMTLOAD(EDITOR_LOAD_ERROR, (FFileName))));      }    }  }  __finally  {    delete Stream;  }  SendMessage(EditorMemo->Handle, EM_EXLIMITTEXT, 0, 0x7FFFFFF0);}//---------------------------------------------------------------------------void __fastcall TEditorForm::CheckFileSize(){  TEditorConfiguration EditorConfiguration = WinConfiguration->Editor;  TWin32FileAttributeData FileAttributeData;  if (GetFileAttributesEx(ApiPath(FFileName).c_str(), GetFileExInfoStandard, &FileAttributeData))  {    const __int64 MaxSize = 100 * 1024 * 1024;    __int64 Size =      (static_cast<__int64>(FileAttributeData.nFileSizeHigh) << 32) +      FileAttributeData.nFileSizeLow;    if (Size > MaxSize)    {      if (EditorConfiguration.WarnOrLargeFileSize)      {        TMessageParams Params(mpNeverAskAgainCheck);        unsigned int Answer =          MoreMessageDialog(            FMTLOAD(INTERNAL_EDITOR_LARGE_FILE, (FormatBytes(Size))), NULL,            qtConfirmation, qaOK | qaCancel, HELP_NONE, &Params);        switch (Answer)        {          case qaOK:            // noop;            break;          case qaCancel:            Abort();            break;          case qaNeverAskAgain:            EditorConfiguration.WarnOrLargeFileSize = false;            WinConfiguration->Editor = EditorConfiguration;            break;          default:            DebugFail();        }      }      // Those are actually nearly all internal exceptions we ever practically get      IgnoreException(typeid(EOutOfMemory));      IgnoreException(typeid(EAccessViolation));      IgnoreException(typeid(EExternalException));    }  }}//---------------------------------------------------------------------------void __fastcall TEditorForm::LoadFile(){  CheckFileSize();  HandleNeeded();  LoadFromFile(true);  EditorMemo->ResetFormat();  EditorMemo->Modified = false;  FCaretPos.x = -1;  // this is important particularly after reload  UpdateControls();}//---------------------------------------------------------------------------bool __fastcall TEditorForm::CursorInUpperPart(){  HFONT OldFont;  HDC DC;  TTextMetric TM;  TRect Rect;  DC = GetDC(EditorMemo->Handle);  OldFont = (HFONT)SelectObject(DC, EditorMemo->Font->Handle);  try  {    GetTextMetrics(DC, &TM);    EditorMemo->Perform(EM_GETRECT, 0, ((int)&Rect));  }  __finally  {    SelectObject(DC, OldFont);    ReleaseDC(EditorMemo->Handle, DC);  }  int VisibleLines = (Rect.Bottom - Rect.Top) / (TM.tmHeight + TM.tmExternalLeading);  int FirstLine = SendMessage(EditorMemo->Handle, EM_GETFIRSTVISIBLELINE, 0, 0);  TPoint CaretPos = EditorMemo->CaretPos;  return (CaretPos.y - FirstLine) < VisibleLines / 2;}//---------------------------------------------------------------------------void __fastcall TEditorForm::PositionFindDialog(bool VerticalOnly){  DebugAssert(FLastFindDialog);  if (!VerticalOnly)  {    FLastFindDialog->Left = Left + EditorMemo->Left + EditorMemo->Width / 2 - ScaleByTextHeight(this, 100);  }  FLastFindDialog->Top = Top + EditorMemo->Top + (EditorMemo->Height / 4) +    (CursorInUpperPart() ? (EditorMemo->Height / 2) : 0) - ScaleByTextHeight(this, 40);}//---------------------------------------------------------------------------void __fastcall TEditorForm::StartFind(bool Find){  UnicodeString Text = EditorMemo->SelText;  TFindOptions Options;  Options << frShowHelp;  if (Text.IsEmpty())  {    Text = WinConfiguration->Editor.FindText;  }  TFindDialog * Dialog = Find ? FFindDialog : FReplaceDialog;  if (FLastFindDialog && Dialog != FLastFindDialog && FLastFindDialog->Handle)  {    FLastFindDialog->CloseDialog();  }  FLastFindDialog = Dialog;  if (!Text.IsEmpty())  {    FLastFindDialog->FindText = Text;  }  FReplaceDialog->ReplaceText = WinConfiguration->Editor.ReplaceText;  if (WinConfiguration->Editor.FindMatchCase)  {    Options << frMatchCase;  }  if (WinConfiguration->Editor.FindWholeWord)  {    Options << frWholeWord;  }  if (WinConfiguration->Editor.FindDown)  {    Options << frDown;  }  FLastFindDialog->Options = Options;  if (!FLastFindDialog->Handle)  {    PositionFindDialog(false);  }  FLastFindDialog->Execute();}//---------------------------------------------------------------------------void __fastcall TEditorForm::GoToLine(){  UnicodeString Str;  if (InputDialog(LoadStr(EDITOR_GO_TO_LINE), LoadStr(EDITOR_LINE_NUMBER), Str))  {    int Line = StrToIntDef(Str, -1);    if (Line <= 0 || Line > EditorMemo->Lines->Count)    {      throw Exception(MainInstructions(LoadStr(EDITOR_INVALID_LINE)));    }    else    {      EditorMemo->CaretPos = TPoint(0, Line-1);    }  }}//---------------------------------------------------------------------------void __fastcall TEditorForm::FormClose(TObject * /*Sender*/,  TCloseAction & Action){  // Preferably announce closure here as this is called from within TForm::Close(),  // so the annoucement will be synchronous (and editor manager thus  // will consider the form to be really closed and will not block  // application closure).  // However FormClose is not called when form is closed due to  // application exit, so there is last resort call from destructor.  DoWindowClose(false);  FCloseAnnounced = true;  Action = caFree;}//---------------------------------------------------------------------------void __fastcall TEditorForm::DoWindowClose(bool Forced){  if (FOnWindowClose != NULL)  {    try    {      FOnWindowClose(this, Forced);    }    catch(Exception & E)    {      ShowExtendedException(&E);    }  }}//---------------------------------------------------------------------------void __fastcall TEditorForm::CreateParams(TCreateParams & Params){  // this is called for the first time from parent's constructor.  // FFormRestored is set to false implicitly  if (!FFormRestored)  {    FInstance = FInstances;    FInstances++;    FFormRestored = true;    UnicodeString WindowParams = WinConfiguration->Editor.WindowParams;    if ((FInstance == 0) && !WindowParams.IsEmpty())    {      RestoreForm(WindowParams, this);    }  }  TForm::CreateParams(Params);  Params.WndParent = GetDesktopWindow();}//---------------------------------------------------------------------------void __fastcall TEditorForm::Reload(){  TAutoFlag ReloadingFlag(FReloading);  if (!IsFileModified() ||      (MessageDialog(MainInstructions(LoadStr(EDITOR_MODIFIED_RELOAD)), qtConfirmation,        qaOK | qaCancel) != qaCancel))  {    if (FOnFileReload)    {      FOnFileReload(this);    }    LoadFile();  }}//---------------------------------------------------------------------------void __fastcall TEditorForm::FormKeyDown(TObject * /*Sender*/, WORD & Key, TShiftState Shift){  if (((Key == VK_ESCAPE) || (Key == VK_F10)) && Shift.Empty())  {    Key = 0;    Close();  }}//---------------------------------------------------------------------------void __fastcall TEditorForm::SetBackgroundColor(TColor Color){  if (BackgroundColor != Color)  {    FBackgroundColor = Color;    UpdateBackgroundColor();  }}//---------------------------------------------------------------------------void __fastcall TEditorForm::UpdateBackgroundColor(){  TColor Color = FBackgroundColor;  if (Color == 0)  {    // double default, first our preferred default, then system default    Color = GetWindowColor(WinConfiguration->Editor.BackgroundColor);  }  ColorItem->Color = Color;  if (EditorMemo->Color != Color)  {    EditorMemo->Color = Color;    EditorMemo->ApplyFont();    // does not seem to have any effect (nor is needed), but just in case    ForceColorChange(EditorMemo);  }}//---------------------------------------------------------------------------void __fastcall TEditorForm::CMDpiChanged(TMessage & Message){  bool WasModified = EditorMemo->Modified;  EditorMemo->ApplyFont();  EditorMemo->Modified = WasModified;  // we do not want this, but we want to prevent undo of the font change too, should be improved  EditorMemo->ClearUndo();  // Clear "modified" status in the status bar, invoked by font change  UpdateControls();  TForm::Dispatch(&Message);}//---------------------------------------------------------------------------void __fastcall TEditorForm::Dispatch(void * Message){  TMessage * M = static_cast<TMessage*>(Message);  switch (M->Msg)  {    case CM_DPICHANGED:      CMDpiChanged(*M);      break;    default:      TForm::Dispatch(Message);      break;  }}
 |