{ FUpdating = false; } // ошибка (поймано исключение) FUpdating = false;
}
// функция возвращает установленные атрибуты текущего текста TTextAttributes *_ fastcall TMainForm::CurrText(void) { return RichEditl->SelAttributes;
}
// функция добавляет указанный шрифт к списку имеющихся int EnumFontsProc(TLogFontA &LogFont, TTextMetricA &, int,
Pointer Data) { ((TStrings *)Data)->Add((AnsiString)LogFont.IfFaceName);
return 1;
}
// функция выбирает имена имеющихся шрифтов void _fastcall TMainForm::GetFontNames (void) { HDC hDC = GetDC(O);
void * cTmp = (void *)FontName->Items;
EnumFonts(hDC, NULL, (FONTENUMPROC) EnumFontsProc, (long) cTmp);
ReleaseDC(0,hDC);
FontName->Sorted = true;
}
// Включение имени Файла в строку заголовка приложения void _fastcall TMainForm::SetFileName(const AnsiString
FileName) (LPSTR IpBuf = new char[MAX_pATH];
sprintf(IpBuf, "%s-%s", ExtractFileName(FileName).c_str(), Application->Title.c_str());
Caption = (AnsiString)IpBuf;
FFileName = FileName;
delete IpBuf;
}
// Реакция в диалоге "Сохранить изменения?" void _fastcall TMainForm::CheckFileSave(void) { if (RichEditl->Modified) {
switch(M&ssageBox(Handle, "Save Changes?", "Confimation",
MB_YESNOCANCEL I MB_ICONQUESTION)) { case ID_YES: FileSaveClick(this);
case ID_CANCEL: Abort();
};
) }
// Запись рисок измерительной линейки ширины параграфов void _fastcall TMainPorm::SetupRuler(void) { int iCtr = 1;
char sTmp[201];
while (iCtr < 200) (
sTmp[iCtr++] = 9; // табулятор sTmp[iCtr++] = 'I'; // риска } Ruler->Caption = (AnsiString)sTmp;
}
// Информирует Windows о текущем размере окна редактирования void _fastcall TMainForm::SetEditRect (void) (TRect Ret = Rect(GutterWid, 0,
RichEditl->ClientWidth-GutterWid, ClientHeight);
SendMessage(RichEditl->Handle, EM_SETRECT, 0, long(&Rct));
}
// Инициализирует компонентные объекты формы приложения void _fastcall TMainForm::FormCreate(TObject* /*Sender*/) { Application->OnHint = &ShowHint;
OpenDialog->InitialDir = ExtractFilePath(ParamStr(0));
SaveDialog->InitialDir = OpenDialog->InitialDir;
GetFontNames();
SetupRuler();
SelectionChange(this); // атрибуты форматирования
}
// Выдает пояснения к командам меню в строку состояния void_fastcall TMainForm::ShowHint(TObject* /*Sender*/) { StatusBar->SimpleText = Application->Hint;
}
// Создание пустого безымянного Файла по команде File I New void_fastcall TMainForm::FileNewClick(TObject* /*Sender*/) { CheckFileSavef); // сохранить изменения? SetFileName((AnsiString)"Untitled");
RichEditl->Lines->Clear();
RichEditl->Modified = false;
}
// Загрузка выбранного Файла командой File I Open или кнопкой void _fastcall TMainForm::FileOpenClick(TObject*) { CheckFileSave(); // сохранить изменения? if (OpenDialog->Execute()) {
RichEditl->Lines->LoadFromFile(OpenDialog->FileName);
SetFileName(OpenDialog->FileName);
RichEditl->SetFocus();
RichEditl->Modified = false;
RichEditl->ReadOnly =
OpenDialog->Options.Contains(ofReadOnly);
} }
// Запись Файла командой File I Save или кнопкой void?*_fastcall TMainForm::FileSaveClick(TObject* Sender) { if (!strcmp(FFileName.c_str(), "Untitled"))
FileSaveAsClick(Sender); // нет имени else
{ RichEditl->Lines->SaveToFile(FFileName); // то же имя RichEditl->Modified = false;
})
// Запись Файла под выбранным именем командой FilelSaveAs void _fastcall TMainForm::FileSaveAsClick(TObject*) { if (SaveDialog->Execute()) {
RichEditl->Lines->SaveToFile(SaveDialog->FileName);
SetFileName(SaveDialog->FileName);
RichEditl->Modified = false;
} }
// Диалог печати Файла по команде File I Print или кнопкой void _fastcall TMainForm::FilePrintClick(TObject*) { if (PrintDialog->Execute()) RichEditl->Print(FFileName);
}
// Выход из программы по команде File I Exit void _fastcall TMainForm::FileExitClick(TObject*) { Close();
}
// Отмена редактирования командой Edit I Undo или кнопкой void _fastcall TMainForm::EditUndoClick(TObject*) (if (RichEditl->HandleAllocated())
SendMessage(RichEditl->Handle, EM_UNDO, 0, 0);
}
// Вырезка выбранного текста командой Edit I Cut или кнопкой void _fastcall TMainForm::EditCutClick(TObject*) { RichEditl->CutToClipboard();
}
// Копирование текста командой Edit I Copy или кнопкой void _fastcall TMainForm::EditCopyClick(TObject*) { RichEditl->CopyToClipboard();
}
// Вставка текста командой Edit I Paste или кнопкой void _fastcall TMainForm::EditPasteClick(TObject*) { RichEditl->PasteFromClipboard();
}
// Вывод указателя Файла помощи по команде Help I Contents void _fastcall TMainForm::HelpContentsClick(TObject*) { Application->HelpCommand(HELP_CONTENTS, 0);
}
// Поиск заданной справки по команде Help I Search...
void _fastcall TMainForm::HelpSearchClick(TObject*)
{ Application->HelpCommand(HELP_PARTIALKEY, (long) "");
)
// Вывод оглавления Файла помощи по команде Help I Нои to... void _fastcall TMainForm::HelpHowToClick(TObject*) { Application->HelpCommand(HELP_HELPONHELP, 0);
}
// Диалог с логотипом редактора по команде Help I About
void_fastcall TMainForm::HelpAboutClick(TObject*)
{ Porm2 = new TPorm2(Application); // создать объект формы
Form2->ShowModal(); // активировать диалог
delete Porm2; // уничтожить объект }
// Диалог выбора шрифта и его атрибутов по команде Edit I font void _fastcall TMainPorm::SelectFont(TObject*) { FontDialogl->Font->Assign(RichEditl->SelAttributes);
if (FontDialogl->Execute())
CurrText()->Assign(FontDialogl->Font);
RichEditl->SetFocus();
}
// Адаптация длины линейки к текущему окну редактирования void _fastcall TMainForm::RulerResize(TObject*) { RulerLine->Width =
(int)Ruler->ClientWidth-(RulerLine->Left*2);
}
// Реакция на изменение пользователем размеров формы
void _fastcall TMainForm::FormResize(TObject* Sender)
{ SetEditRect(); // послать сообщение Windows
SelectionChange(Sender); // атрибуты форматирования
)
// Перерисовка формы
void _fastcall TMainForm::FormPaint(TObject* Sender) { SetEditRect(); // послать сообщение Windows
}
// Реакция на нажатие кнопки "Стиль шрифта жирный" void _fastcall TMainForm::BoldButtonClick(TObject*) { if (iFUpdating)
{ if (BoldButton->Down) // изменить данный стиль CurrText()->Style = CurrText()->Style “ fsBold;
else // сбросить данный стиль CurrText()->Style = CurrText()->Style ” fsBold;
} }
// Реакция на нажатие кнопки "Стиль шрифта курсив" void _fastcall TMainForm::ItalicButtonClick(TObject*) { if (iFUpdating)
{ if (ItalicButton->Down) // изменить данный стиль CurrText()->Style = CurrText()->Style “ fsltalic;
else // сбросить данный стиль CurrText()->Style = CurrText()->Style ” fsltalic;
} }
// Реакция на нажатие кнопки "Стиль шрифта подчеркнутый" void _fastcall TMainForm::UnderlineButtonClick(TObject*) { if (iFUpdating)
{ if (UnderlineButton->Down) // изменить данный стиль
CurrText()->Style = CurrText()->Style “ fsUnderline;
else // сбросить данный стиль CurrText()->Style = CurrText()->Style ” fsUnderline;
) }
// Изменение размера шрифта в допустимом интервале значений void _fastcall TMainForm::FontSizeChange(TObject*) {
int fontsize = atoi(FontSize->Text.c_str());
if ((iFUpdating) && (fontsize)) { if (fontsize < 1)
{ ShowMessage("Number must be between 1 and 1638.");
FontSize->Text =1; } else if (fontsize > 1638)
{ ShowMessage("Number must be between 1 and 1638");
FontSize->Text = 1638; } CurrText()->Size = atoi(FontSize->Text.c_str());
} }
// Реакция на нажатие одной из кнопок выравнивания текста void _fastcall TMainForm::AlignClick(TObject* Sender) { if (IFUpdating)
{ TControl *oAliBtn = (TControl*)(Sender);
RichEditl->Paragraph->Alignment = (TAlignment)oAliBtn->Tag;
} }
// Реакция на выбор нового названия шрифта из списка void _fastcall TMainForm::FontNameChange(TObject*) { if (iFUpdating)
{ CurrText()->Name =
FontName->Items->Strings[FontName->ItemIndex];
} }
// Реакция на нажатие кнопки "Нумерованный список" void _fastcall TMainForm::BulletsButtonClick(TObject*) { if (iFUpdating)
RichEditl->Paragraph->Numbering =
(TNumberingStyle)BulletsButton->Down;
}
// Типовая проверка возможности выхода из приложения void _fastcall TMainForm::FormCloseQuery(TObject*, bool & CanClose)
{ try
{ CheckFileSaveO; } // сохранить изменения? catch (...)
{ CanClose = false; } // ошибка (поймано исключение) }
// Определение позиции регулятора линейки, выбранного мышью void_fastcall TMainForm::RulerItemMouseDown(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 TMainForm:':RulerItemMouseMove(TObject* Sender,
TShiftState Shift, int X, int /*Y*/) (if (FDragging)
{ TLabel * oTmpLabel = (TLabel *)Sender;
oTmpLabel->Left = oTmpLabel->Left+X-FDragOfs;
) }
// Определение позиции регулятора ширины красной строки void_fastcall TMainForm::FirstIndMouseUp(TObject* Sender,
TMouseButton Button, TShiftState Shift, int X, int Y) { FDragging = false;
RichEditl->Paragraph->FirstIndent =
int((FirstInd->Left+FDragOfs-GutterWid) / RulerAdj);
LeftIndMouseUp(Sender, Button, Shift, X, Y);
}
// Определение позиции регулятора левого отступа параграфа void _fastcall TMainForm::LeftIndMouseUp(TObject* Sender,
TMouseButton, TShiftState, int, int) { FDragging = false;
RichEditl->Paragraph->LeftIndent =
int ((LeftInd->Left+FDragOfs-GutterWid) / RulerAdj)-RichEditl->Paragraph->FirstIndent;
SelectionChange(Sender); // атрибуты форматирования
}
// Определение позиции регулятора правого отступа параграфа
void_fastcall TMainForm::RightIndMouseUp(TObject* Sender,
TMouseButton, TShiftState, int, int) { FDragging = false;
RichEditl->Paragraph->RightIndent =
int( (Ruler->ClientWidth-Rightlnd->Left+FDragOfs-2) / RulerAdj)-2*GutterWid;
SelectionChange(Sender); // атрибуты форматирования }
// Активизация Файла помощи на Форме void _fastcall TMainForm::FormActivate(TObject* /*Sender*/) { Application->HelpFile = "RICHEDIT.HLP";
RichEditl->SetFocus();
Листинг 4.1. Кодовый файл Romain.cpp модуля редактора.
Рис. 4.22 демонстрирует работу со встроенным отладчиком на примере приложения редактора. Предположим, вы хотите узнать, правильно ли занеслось имя открытого файла в переменную FFileName. В процессе отладки вы будете пользоваться опциями контекстного меню Редактора кода, активизируемого нажатием правой кнопки мыши:
=> Найдите инструкцию, за работой которой вы хотите проследить, и нажмите клавишу F5 (или щелкните мышью слева от выбранной инструкции). Красный цвет отмечает строку останова программы. Повторное нажатие клавиши или повторный щелчок мышью снимет точку останова. => Командами меню Run [ Run (клавиша F9), Run | Run to Cursor (клавиша
F4) или одноименной опцией запустите приложение.
=> Если программа дошла до точки останова (а это должно случиться при работе отлаженных приложений), строка окрасится синим цветом, а перед ней появится символ " ^ ".
; => Командой Run | Step Over (клавиша F8) выполните выбранную инструк-; цию в пошаговом режиме.
=> Двойным щелчком мышью выберите переменную FFileName в тексте ин-|§ струкции и опцией Inspect (клавиши Alt+F5) проинспектируйте начальное ti4' значение - "Untitled".
Рис. 4.22. Некоторые приемы отладки.
=> Продолжите отладку (клавиша F9) и откройте любой файл в диалоге команды File | Open меню редактора.
=> Снова выполните выбранную инструкцию в пошаговом режиме. => Проинспектируйте новое значение выбранной переменной - она должна
содержать имя открытого файла и полный путь к нему. => Продолжите работу в режиме отладки или завершите ее командой
Run | Program Reset.
4.6.8 Системные компоненты
Компоненты вкладки System палитры компонент
осуществляют включение в вашу программу 12 специализированных системных элементов управления.
TTimer
Эта компонента инкапсулирует таймерные функции Windows API: SetTimer и KillTimer и сама обрабатывает сообщения WM_TIMER.
Свойство Interval задает частоту возникновения события OnTimer. По умолчанию Interval=1000 (одна секунда). Временной интервал передается функции SetTimer в качестве параметра.
Для каждого таймера вашей программы заведите отдельную компоненту.