Розробка текстового редактора
Введення
Кілька років тому дослідники помітили, що програмісти протягом
певного часу пишуть і налагоджують приблизно однаковий за обсягом
код, незалежно від мови програмування. Обсяг роботи приблизно
той самий, але результати різні. Написання 100 рядків на С вимагає стільки ж
витрат, скільки і 100 рядків коду на асемблері, але можливості коду на С набагато
ширше. Зрозумівши це, дослідники почали розробляти мови високого рівня,
які збільшували б потенціал окремого програміста, скорочуючи тим самим
рядки і вартість розробки проектів.
У 70-х роках серед творців мов програмування придбала популярність
концепція об'єкта. Об'єкт є сукупністю коду і даних, створеної для
відтворення властивостей фізичних об'єктів або абстрактних понять.
Об'єктно-орієнтоване програмування - це методологія, яка
концентрується більше на зв'язках між об'єктами, ніж на деталях реалізації.
Дані зв'язку зазвичай розвиваються за принципом дерев, при цьому нові типи
об'єктів утворюються вже з існуючих. Приховування реалізації об'єкта веде до
тому, що користувача більше хвилює зв'язок з іншими об'єктами, ніж
поведінку об'єкта. Дане відміну дуже важливо, оскільки воно означає
принципова відмова від "імперативних" мов (таких як С), в яких функції і
виклики функцій складають основу діяльності.
У С + + деякі об'єкти є частиною самої мови. Але в цілому завдання створення
нових об'єктів лягає на користувача. У C + + Builder є безліч типів
об'єктів, але реальне використання мови вимагає створення нових типів.
Ефективність ООП виявляється тільки при створенні і застосуванні груп пов'язаних
між собою об'єктів. Такі групи називають ієрархіями класів. Розвиток цих
ієрархій класів є основою діяльності в ООП.
C + + Builder є об'єктно-орієнтованою мовою програмування і на
прикладі створення текстового редактора я хочу продемонструвати всю міць і
швидкість візуального об'єктно-орієнтованого програмування.
1 Опис програми
Основні характеристики
Розглянута програма має можливість редагування текстових файлів типу
TXT і RTF, а також їм подібні.
Програма є EXE файл; програма вміє відкривати та зберігати
текстові файли, редагувати їх, змінювати шрифт і розмір тексту, має пошук і
заміну тексту. Опис функцій і клавіш буде наведено нижче.
Керівництво для користувача
Виконуваний файл називається WORD.EXE. Після його запуску на екрані з'являється
вікно, показане на Малюнок 1. 1
Малюнок 1. 1 - Вікно програми, що виникає після запуску
Після того як програма запуститься її можна використовувати.
Кнопки панелі управління
-створення нового документа.
- Відкриття документа
- Збереження документа
- Вирізування виділеного тексту
- Копіювання виділеного тексту
- Вставка тексту з буфера обміну
- Скасування останньої дії
- Пошук в тексті
- Заміна в тексті
- Друк документа
- Вибір шрифту для виділеного тексту
- Зміна розміру обраного тексту
- Напівжирний шрифт
- Курсивний шрифт
- Підкреслений шрифт
- Рівняння тексту по лівому краю
- Рівняння тексту по центру
- Рівняння тексту по правому краю
- Маркування виділеного абзацу
Робота з документами
Створення нового документа
У меню Файл виберіть команду Новий.
Почніть введення тексту.
Щоб зберегти новий файл, виберіть у меню Файл команду Зберегти як і введіть
ім'я в полі Ім'я файлу.
Збереження зміненого документа
У меню Файл виберіть команду Зберегти.
Примітка
Щоб зберегти існуючий документ під іншим іменем, виберіть команду
Зберегти як і введіть нове ім'я в полі Ім'я файлу.
Відкриття документа
У меню Файл виберіть команду Відкрити.
Малюнок 1.2 - Вікно відкриття файлу.
У діалоговому вікні (рис 1.2), в полі зі списком Папка виберіть диск, що містить
документ, який потрібно відкрити.
Двічі клацніть папку, яка містить потрібний документ.
Оберіть документ і натисніть кнопку Відкрити.
Примітки
Якщо ви не бачите потрібний документ, спробуйте вибрати інший тип документів в
поле зі списком Тип файлів.
Щоб відкрити один з недавно відкритих документів, виберіть його ім'я в меню
Файл.
Налаштування вікна MAGWord
Виведення на екран або приховування лінійки
У меню Вигляд виберіть команду Лінійка.
Якщо ліворуч від цієї команди в меню стоїть позначка, лінійка знаходиться на екрані.
Виведення на екран або приховування панелі інструментів
У меню Вигляд виберіть команду Панель інструментів.
Якщо ліворуч від цієї команди в меню стоїть позначка, панель інструментів знаходиться на
екрані.
Примітки
Панель форматування містить кнопки, що прискорюють форматування тексту,
наприклад, що змінюють накреслення тексту або стиль абзацу. Щоб відформатувати
текст, виділіть його, а потім натисніть відповідну кнопку на панелі
форматування.
Робота з текстом
Скасування останньої дії
У меню Правка виберіть команду Скасувати.
Видалення тексту
Виділіть текст, який потрібно видалити.
Щоб перемістити частину тексту в іншу частину документа, виберіть у меню Правка команду
Вирізати.
Щоб просто видалити текст з документа, натисніть клавішу DELETE.
Примітки
Щоб зняти виділення, клацніть будь-яке місце в документі.
Щоб скасувати видалення, виберіть у меню Правка команду Скасувати.
Щоб виділити для видалення весь текст в документі натисніть Ctrl + A.
Пошук тексту
У документі клацніть місце, з якого слід почати пошук тексту.
У меню Правка виберіть команду Пошук. У вікні (Малюнок 1.3)
встановити параметри пошуку.
У полі Зразок введіть зразок тексту для пошуку та натисніть кнопку Знайти далі.
Малюнок 1.3 - Вікно пошуку тексту
Щоб знайти наступні входження шуканого тексту, натисніть кнопку Знайти далі.
Примітки
Для пошуку та заміни тексту виберіть у меню Правка команду Замінити.
Пошук і заміна тексту
У меню Правка виберіть команду Замінити.
У полі Зразок введіть зразок тексту для пошуку і заміни.
У полі Замінити на введіть новий текст.
Примітки
Щоб замінити всі входження шуканого тексту, натисніть кнопку Замінити все.
Щоб замінювати кожне входження зразка окремо, натисніть кнопку Знайти
далі, а потім кнопку Замінити.
Форматування тексту
Створення маркованого списку
Клацніть місце в документі, з якого слід почати маркований список.
У меню Формат виберіть команду Маркер, а потім починайте введення тексту. При кожному
натисканні клавіші ENTER на наступному рядку буде з'являтися новий маркер.
Щоб завершити маркований список, виберіть команду Маркер ще раз.
Зміна шрифту, накреслення і розміру символів
Виділіть текст, формат якого слід змінити.
У меню Правка виберіть команду Шрифт. З'явиться діалогове вікно показане на
малюнку 1.4.
Малюнок 1.4 - Вікно вибору шрифту.
Виберіть потрібні параметри та натисніть кнопку застосувати.
Примітки
Щоб задати шрифт для оформлення нового тексту, змініть його до початку введення
тексту.
Щоб змінити шрифт всього документа, натисніть Ctrl + A, а потім у меню Правка
виберіть Шрифт.
Форматування абзацу
Клацніть будь-яке місце всередині абзацу, який потрібно відформатувати.
На панелі інструментів клацніть по одній з кнопок вирівнювання тексту і задайте
параметри відступу за допомогою лінійки.
Друк
Зміна принтера і зміна параметрів друку
Щоб змінити принтер, натисніть кнопку Друк. З'явиться діалогове вікно
показане на малюнку 1.5. Виберіть ім'я принтера в полі зі списком Ім'я.
Малюнок 1.5 - Діалогове вікно друку документа.
Щоб почати друк клацніть на кнопці OK.
Константи
C + + дає можливість запису значень основних типів: символьних констант, цілих
констант і констант з плаваючою точкою. Крім того, нуль (0) може
використовуватися як константа будь-якого вказівного типу, і символьні рядки
є константами типу char []. Можна також задавати символічні константи.
Символічна константа - це ім'я, значення якого не може бути змінено в
його області видимості. У C + + є три види символічних констант: (1) будь-якій
значенням будь-якого типу можна дати ім'я і використовувати його як константу, додавши до
його опису ключове слово const; (2) безліч цілих констант може бути
визначено як перерахування; і (3) будь-яке ім'я вектора або функції є
константою.
Цілі Константи
Цілі константи постають у чотирьох обличчях: десяткові, вісімкові,
шістнадцяткові і символьні константи. Десяткові використовуються найчастіше і
виглядають так, як можна було б очікувати:
0, 1234, 976, 12345678901234567890
Десяткова константа має тип int, за умови, що вона влазить в int, в
Інакше її тип long. Компілятор повинен попереджати про константах,
які занадто довгі для представлення в машині. Константа, яка починається
нулем за яким йде x (0x), є шістнадцятковим числом (з основою
16), а константа, яка починається нулем за яким іде цифра, є
вісімкові числом (з основою 8). Ось приклади вісімкових констант:
0, 02, 077, 0123
їх десяткові еквіваленти - це 0, 2, 63, 83. У шістнадцятковій записи ці
константи виглядають так:
0x0, 0x2, 0x3f, 0x53
Літери a, b, c, d, e і f, або їх еквіваленти у верхньому регістрі, використовуються для
представлення чисел 10, 11. 12, 13, 14 і 15, відповідно. Вісімкова і
шістнадцяткова запису найбільш корисні для запису набору бітів; застосування
цих записів для вираження звичайних чисел може привести до несподіванок.
Наприклад, на машині, де int представляється як двійкове додаткове
шістнадцяткове ціле, 0xffff є від'ємним десятковим числом -1;
якби для представлення цілого використовувалося більше число бітів, то воно було
б числом 65535.
Константи з плаваючою Точкою
Константи з плаваючою точкою мають тип double. Як і в попередньому випадку, />
великі, щоб їх можна було уявити. Ось деякі константи з плаваючою
точкою:
1.23 .23 0.23 1. 1.0 1.2e10 1.23e-15
Зауважте, що в середині константи з плаваючою точкою не може зустрічатися
пробіл. Наприклад, 65.43 e-21 є не константою з плаваючою точкою, а
чотирма окремими лексичними символами (лексемами):
65.43 e - 21
і викличе синтаксичну помилку.
Якщо ви хочете мати константу з плаваючою точкою типу float, ви можете
визначити її так:
const float pi = 3.14159265;
Символьні Константи
Хоча у C + + і немає окремого символьного типу даних, точніше, символ може
зберігатися в цілому типі, у ньому для символів є спеціальна і зручна запис.
Символьна константа - це символ, укладений в одинарні лапки; наприклад,
'a' або '0 '. Такі символьні константи в дійсності є
символічними константами для цілого значення символів у наборі символів тієї
машини, на якій буде виконуватися програма (який не обов'язково збігається
з набором символів, що застосовується на тому комп'ютері, де програма компілюється).
Тому, якщо ви виконуєте на машині, яка використовує набір символів ASCII, то
значенням '0 'буде 48, але якщо ваша машина використовує EBCDIC, то воно буде 240.
Вживання символьних констант замість десяткового запису робить програму більш
переноситься. Кілька символів також мають стандартні імена, в яких
зворотна коса використовується як escape-символ: 'b' повернення назад
'f' переклад формату
'n' новий рядок
'r' повернення каретки
't' горизонтальна табуляція
'v' вертикальна табуляція
''Зворотна коса (зворотний слеш)
'' 'Одинарна лапки
' "' Лапки
'? бути обчислено на стадії компіляції. Однак для вектора констант
зазвичай доводиться виділяти пам'ять, оскільки компілятор в загальному випадку не може
обчислити, на які елементи вектора зроблено посилання у висловах. Однак на
багатьох машинах навіть у цьому випадку може досягатися підвищення ефективності
шляхом розміщення векторів констант в пам'ять, доступну лише для читання.
Використання покажчика залучає два об'єкти: сам вказівник і що указується
об'єкт. Постачання опису вказівника "префіксом" const робить об'єкт, але не сам
покажчик, константою. Наприклад:
const char * pc = "asdf";// покажчик на константу
pc [3] = 'a';// помилка
pc = "ghjk";// ok
Щоб описати сам покажчик, а не указується об'єкт, як константних,
використовується операція const *. Наприклад:
char * const cp = "asdf";// константних покажчик
cp [3] = 'a';// ok
cp = "ghjk";// помилка
Щоб зробити константами обидва об'єкти, їх обидва потрібно описати const. Наприклад:
const char * const cpc = "asdf";// const покажчик на const
cpc [3] = 'a';// помилка
cpc = "ghjk";// помилка
Об'єкт, який є константою при доступі до нього через один покажчик, може
бути змінною, коли доступ здійснюється іншими шляхами. Це зокрема
корисно для параметрів функції. За допомогою опису параметра покажчика як
const функції забороняється змінювати об'єкт, на який він вказує. Наприклад:
char * strcpy (char * p, const char * q);// не може змінити q
Вказівником на константу можна привласнювати адреса змінної, оскільки ніякого
шкоди від цього бути не може. Однак не можна привласнити адресу константи вказівником,
на який не було накладено обмеження, оскільки це дозволило б змінити
значення об'єкта. Наприклад:
int a = 1;
const c = 2;
const * p1 = &c;// ok
const * p2 = &a;// ok
int * p3 = &c;// помилка
* p3 = 7;// змінює значення c
Як звичайно, якщо тип в описі опущений, то він передбачається int.
Перерахування
Є інший метод визначення цілих констант, який іноді більш зручний, ніж
застосування const. Наприклад:
enum (ASM, AUTO, BREAK);
визначає три цілих константи, звані перечіслітелямі, і присвоює їм
значення. Оскільки значення перечіслітелей за замовчуванням присвоюються починаючи з
0 в порядку зростання, це еквівалентно запису:
const ASM = 0;
const AUTO = 1;
const BREAK = 2;
Перерахування може бути іменованих. Наприклад:
enum keyword (ASM, AUTO, BREAK);
Назва перерахування стає синонімом int, а не новим типом. Опис змінної
keyword, а не просто int, може дати як програмісту, так і компілятору
підказку про те, що використання навмисне. Наприклад:
keyword key;
switch (key) (
case ASM:
//Щось робить
break;
case BREAK:
//Щось робить
break;
)
спонукає компілятор видати попередження, оскільки тільки два значення
keyword з трьох використовуються. Можна також задавати значення перечіслітелей явно.
Наприклад:
enum int16 (
sign = 0100000,// знак
most_significant = 040000,// найвідоміший
least_significant = 1// найменш значущий
);
Такі значення не обов'язково повинні бути різними, зростаючими або
позитивними.
Додаток А
# include
# pragma hdrstop
# include "About.h"
# include "AlexWord.h"
# include "LogoStrs.h"
const float RulerAdj = 4.0/3.0;
const int GutterWid = 6;
# pragma link "CGRID"
# pragma resource "*. dfm"
TForm1 * Form1;
__fastcall TForm1:: TForm1 (TComponent * Owner)
: TForm (Owner)
(
)
void __fastcall TForm1:: RichEdit1SelectionChange (TObject * Sender)
(
char sizebuf [6];
try (
FUpdating = True;
ComboBox1-> Text = RichEdit1-> SelAttributes-> Name;
FirstInd-> Left = int (RichEdit1-> Paragraph-> FirstIndent * RulerAdj) -4 + GutterWid;
LeftInd-> Left = int ((RichEdit1-> Paragraph-> LeftIndent +
RichEdit1-> Paragraph-> FirstIndent) * RulerAdj) -4 + GutterWid;
RightInd-> Left = Ruler-> ClientWidth-6-int (
(RichEdit1-> Paragraph-> RightIndent + GutterWid) * RulerAdj);
if (CurrText () -> Style == CurrText () -> Style>> fsItalic)
ToolButton17-> Down = false;
else ToolButton17-> Down = true;
if (CurrText () -> Style == CurrText () -> Style>> fsBold)
ToolButton15-> Down = false;
else ToolButton15-> Down = true;
if (CurrText () -> Style == CurrText () -> Style>> fsUnderline)
ToolButton3-> Down = false;
else ToolButton3-> Down = true;
Edit2-> Text = itoa (RichEdit1-> SelAttributes-> Size, sizebuf, 10);
if (RichEdit1-> Paragraph-> Alignment == taLeftJustify)
LeftAlign-> Down = true;
else LeftAlign-> Down = false;
if (RichEdit1-> Paragraph-> Alignment == taCenter)
CenterAlign-> Down = true;
else CenterAlign-> Down = false;
if (RichEdit1-> Paragraph-> Alignment == taRightJustify)
RightAlign-> Down = true;
else RightAlign-> Down = false;
if (RichEdit1-> Paragraph-> Numbering == TNumberingStyle (nsBullet))
ToolButton14-> Down = true;
else ToolButton14-> Down = false;
)
catch (...) (
FUpdating = False;
)
FUpdating = False;
)
TTextAttributes * __fastcall TForm1:: CurrText (void)
(
return RichEdit1-> SelAttributes;
)
void __fastcall TForm1:: FileNew1Execute (TObject * Sender)
(
FFileName = LoadStr (sUntitled);
RichEdit1-> Lines-> Clear ();
RichEdit1-> Modified = false;
)
void __fastcall TForm1:: FileOpen1Execute (TObject * Sender)
(
if (OpenDialog-> Execute ())
(
RichEdit1-> Lines-> LoadFromFile (OpenDialog-> FileName);
FFileName = OpenDialog-> FileName;
RichEdit1-> SetFocus ();
RichEdit1-> Modified = false;
RichEdit1-> ReadOnly = OpenDialog-> Options.Contains (ofReadOnly);
Form1-> Caption = OpenDialog-> FileName;
)
)
void __fastcall TForm1:: FileSave1Execute (TObject * Sender)
(
if (FFileName == LoadStr (sUntitled))
(
FileSaveAs1Execute (Sender);
Form1-> Caption = SaveDialog-> FileName;)
else
(
RichEdit1-> Lines-> SaveToFile (FFileName);
RichEdit1-> Modified = false;)
)
void __fastcall TForm1:: FileSaveAs1Execute (TObject * Sender)
(
String str;
TVarRec vrs [1];
if (SaveDialog-> Execute ())
(
if (FileExists (SaveDialog-> FileName))
(
str = FmtLoadStr (sOverwrite, OPENARRAY (TVarRec, (SaveDialog-> FileName )));< br />
if (MessageDlg (str, mtConfirmation, TMsgDlgButtons () FileName);
FFileName = SaveDialog-> FileName;
RichEdit1-> Modified = false;
)
)
void __fastcall TForm1:: CheckFileSave (void)
(
if (RichEdit1-> Modified) (
switch (MessageBox (Handle, "Save Changes?",
"Confirmation", MB_YESNOCANCEL MB_ICONQUESTION))
(Case ID_YES: FileSave1Execute (this);
case ID_CANCEL: Abort ();
)
)
)
void __fastcall TForm1:: FileExit1Execute (TObject * Sender)
(
Close ();
)
void __fastcall TForm1:: HelpAbout1Execute (TObject * Sender)
(
AboutBox-> ShowModal ();
)
void __fastcall TForm1:: UndoClick (TObject * Sender)
(
if (RichEdit1-> HandleAllocated ())
SendMessage (RichEdit1-> Handle, EM_UNDO, 0, 0);
)
void __fastcall TForm1:: PrintClick (TObject * Sender)
(
if (PrintDialog1-> Execute ()) RichEdit1-> Print (OpenDialog-> FileName);
)
void __fastcall TForm1:: Print_SetupClick (TObject * Sender)
(
PrinterSetupDialog1-> Execute ();
)
void __fastcall TForm1:: FindClick (TObject * Sender)
(
FindDialog1-> FindText = RichEdit1-> SelText;
FindDialog1-> Execute ();
)
void __fastcall TForm1:: FindDialog1Find (TObject * Sender)
(
int FoundAt, StartPos, ToEnd;
if (RichEdit1-> SelLength)
StartPos = RichEdit1-> SelStart + RichEdit1-> SelLength;
else
StartPos = 0;
ToEnd = RichEdit1-> Text.Length () - StartPos;
FoundAt = RichEdit1-> FindText (FindDialog1-> FindText, StartPos, ToEnd,
TSearchTypes ()
if (FoundAt! = -1)
(
RichEdit1-> SetFocus ();
RichEdit1-> SelStart = FoundAt;
RichEdit1-> SelLength = FindDialog1-> FindText.Length ();
)
)
void __fastcall TForm1:: ReplaceDialog1Replace (TObject * Sender)
(
if (RichEdit1-> SelLength == 0)
FindDialog1Find (Sender);
else
(
RichEdit1-> SelText = ReplaceDialog1-> ReplaceText;
FindDialog1Find (Sender);
)
if (ReplaceDialog1-> Options.Contains (frReplaceAll))
while (RichEdit1-> SelLength! = 0)
ReplaceDialog1Replace (Sender);
)
void __fastcall TForm1:: ReplaceClick (TObject * Sender)
(
ReplaceDialog1-> Execute ();
)
void __fastcall TForm1:: N5Click (TObject * Sender)
(
FontDialog1-> Options
FontDialog1-> Execute ();
)
void __fastcall TForm1:: FontDialog1Apply (TObject * Sender, HWND Wnd)
(
if (ActiveControl-> ClassNameIs ( "TEdit"))
((TEdit *) ActiveControl) -> Font-> Assign (FontDialog1-> Font);
else if (ActiveControl-> ClassNameIs ( "TRichEdit"))
((TRichEdit *) ActiveControl) -> SelAttributes-> Assign (FontDialog1-> Font);
else
MessageBeep (0);
)
void __fastcall TForm1:: prClick (TObject * Sender)
(
ToolButton8-> Visible = false;
)
void __fastcall TForm1:: rp1Click (TObject * Sender)
(
ToolButton8-> Visible = true;
)
void __fastcall TForm1:: CenterAlignClick (TObject * Sender)
(
RichEdit1-> Paragraph-> Alignment = taCenter;
)
void __fastcall TForm1:: LeftAlignClick (TObject * Sender)
(
RichEdit1-> Paragraph-> Alignment = taLeftJustify;
)
void __fastcall TForm1:: RightAlignClick (TObject * Sender)
(
RichEdit1-> Paragraph-> Alignment = taRightJustify;
)
void __fastcall TForm1:: SetupRuler (void)
(Int iCtr = 1;
char sTmp [201];
while (iCtr <200) (>
sTmp [iCtr] = 9;
iCtr + +;
sTmp [iCtr] ='';
iCtr + +;
)
Ruler-> Caption = (AnsiString) sTmp;
)
void __fastcall TForm1:: FormCreate (TObject * Sender)
(
OpenDialog-> InitialDir = ExtractFilePath (ParamStr (0));
SaveDialog-> InitialDir = OpenDialog-> InitialDir;
SetupRuler ();
for (int i = 0; i
Fonts-> Count; i + +)
ComboBox1-> Items-> Add (Screen-> Fonts-> Strings [i]);
RichEdit1-> SelStart = 0;
)
void __fastcall TForm1:: ToolButton14Click (TObject * Sender)
(
if (RichEdit1-> Paragraph-> Numbering == TNumberingStyle (nsBullet))
RichEdit1-> Paragraph-> Numbering = TNumberingStyle (nsNone);
else
RichEdit1-> Paragraph-> Numbering = TNumberingStyle (nsBullet);
)
void __fastcall TForm1:: ComboBox1Change (TObject * Sender)
(
TCharsetObject * ChasrsetObject;
if (! FUpdating) (
ChasrsetObject =
(TCharsetObject *) ComboBox1-> Items-> Objects [ComboBox1-> ItemIndex];
CurrText () -> Name = ComboBox1-> Items-> Strings [ComboBox1-> ItemIndex];
)
)
void __fastcall TForm1:: ToolButton15Click (TObject * Sender)
(
if (CurrText () -> Style == CurrText () -> Style>> fsBold)
CurrText () -> Style = CurrText () -> Style
else
CurrText () -> Style = CurrText () -> Style>> fsBold;
)
void __fastcall TForm1:: ToolButton17Click (TObject * Sender)
(
if (CurrText () -> Style == CurrText () -> Style>> fsItalic)
CurrText () -> Style = CurrText () -> Style
else
CurrText () -> Style = CurrText () -> Style>> fsItalic;
)
void __fastcall TForm1:: Edit2Change (TObject * Sender)
(
int fontsize = atoi (Edit2-> Text.c_str ());< br />
if ((! FUpdating) & & (fontsize))
(
CurrText () -> Size = atoi (Edit2-> Text.c_str ());< br />
)
)
void __fastcall TForm1:: ToolButton3Click (TObject * Sender)
(
if (CurrText () -> Style == CurrText () -> Style>> fsUnderline)
CurrText () -> Style = CurrText () -> Style
else
CurrText () -> Style = CurrText () -> Style>> fsUnderline;
)
void __fastcall TForm1:: FirstIndMouseDown (TObject * Sender,
TMouseButton Button, TShiftState Shift, int X, int Y)
(
TLabel * oTmpLabel = (TLabel *) Sender;
FDragOfs = oTmpLabel-> Width/2;
oTmpLabel-> Left = oTmpLabel-> Left + X-FDragOfs;
FDragging = True;
)
void __fastcall TForm1:: FirstIndMouseUp (TObject * Sender,
TMouseButton Button, TShiftState Shift, int X, int Y)
(
FDragging = False;
RichEdit1-> Paragraph-> FirstIndent = int ((FirstInd-> Left + FDragOfs-GutterWid)/
RulerAdj);
LeftIndMouseUp (Sender, Button, Shift, X, Y);
)
void __fastcall TForm1:: LeftIndMouseUp (TObject * Sender,
TMouseButton Button, TShiftState Shift, int X, int Y)
(
FDragging = False;
RichEdit1-> Paragraph-> LeftIndent = int ((LeftInd-> Left + FDragOfs-GutterWid)/
RulerAdj)-RichEdit1-> Paragraph-> FirstIndent;
RichEdit1SelectionChange (Sender);
)
void __fastcall TForm1:: FirstIndMouseMove (TObject * Sender,
TShiftState Shift, int X, int Y)
(
if (FDragging) (
TLabel * oTmpLabel = (TLabel *) Sender;
oTmpLabel-> Left = oTmpLabel-> Left + X-FDragOfs;
)
)
void __fastcall TForm1:: RightIndMouseUp (TObject * Sender,
TMouseButton Button, TShiftState Shift, int X, int Y)
(
FDragging = False;
RichEdit1-> Paragraph-> RightIndent =
int ((Ruler-> ClientWidth-RightInd-> Left + FDragOfs-2)/
RulerAdj) -2 * GutterWid;
RichEdit1SelectionChange (Sender);
)
void __fastcall TForm1:: RulerResize (TObject * Sender)
(
RulerLine-> Width = (int) Ruler-> ClientWidth - (RulerLine-> Left * 2);
)
void __fastcall TForm1:: FormPaint (TObject * Sender)
(
TRect Rct = Rect (GutterWid, 0, RichEdit1-> ClientWidth-GutterWid,
ClientHeight);
SendMessage (RichEdit1-> Handle, EM_SETRECT, 0, long (& Rct ));;< br />
)
void __fastcall TForm1:: FormResize (TObject * Sender)
(
RichEdit1SelectionChange (Sender);
)
void __fastcall TForm1:: FormActivate (TObject * Sender)
(
FileNew1Execute (Sender);
RichEdit1-> SetFocus ();
)
void __fastcall TForm1:: FormCloseQuery (TObject * Sender, bool & CanClose)
(
try (
CheckFileSave ();
)
catch (...) (
CanClose = False;
)
)
void __fastcall TForm1:: NRulerClick (TObject * Sender)
(
if (Ruler-> Visible == false)
(
Ruler-> Visible = true;
NRuler-> Checked = true;)
else (Ruler-> Visible = false; NRuler-> Checked = false;
)
)
void __fastcall TForm1:: NPanelClick (TObject * Sender)
(
if (Panel1-> Visible == false)
(
Panel1-> Visible = true;
NPanel-> Checked = true;
)
else (Panel1-> Visible = false;
NPanel-> Checked = false;
)
)
void __fastcall TForm1:: NBarClick (TObject * Sender)
(
if (StatusBar-> Visible == false)
(StatusBar-> Visible = true;
NBar-> Checked = true;)
else (StatusBar-> Visible = false;
NBar-> Checked = false;
)
)