| 12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667 | //---------------------------------------------------------------------------#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"#ifndef NO_RESOURCES#pragma resource "*.dfm"#endif//---------------------------------------------------------------------------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));    }  }}//---------------------------------------------------------------------------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;  }}
 |