#include <vcl.h>
#include <windows.hpp>
#pragma hdrstop
#include "Romain.h"
#include "RichAbt.h"
const float RulerAdj = 4.0/3.0; // цена деления линейки
const int GutterWid = 6; // ширина поля подшивки
#pragma resource "*.dfm"
TMainForm *MainForm;
// Конструктор главной формы приложения _
fastcall TMainForm::TMainForm(TComponent *0wner)
: TFormfOwner) {
SetFileName((AnsiString)"Untitled");
}
// Установка текущих атрибутов Форматирования текста
void _fastcall TMainForm::SelectionChange(TObject*) {
char sizebuf[6];
try {
FUpdating = true;
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)
;
BoldButton->Down = // состояние кнопки "жирный"
RichEdit1->SelAttributes->Style.Contains(fsBold) ;
ItalicButton->Down = //состояние кнопки "курсив"
RichEdit1->SelAttributes->Style.Contains(fsltalic) ;
UnderlineButton->Down = // состояние кнопки "подчерк."
RichEdit1->SelAttributes->Style.Contains(fsUnderline) ;
BulletsButton->Down = // состояние кнопки "нумерация"
bool(RichEdit1->Paragraph->Numbering) ;
FontSize->Text = // размер шрифта
itoa(RichEdit1->SelAttributes->Size, sizebuf, 10);
FontName->Text = // название шрифта
RichEdit1->SelAttributes->Name;
// Состояние кнопок выравнивания параграфа
switch((int)RichEdit1->Paragraph->Alignment) {
case 0: LeftAlign->Down = true; break;
case 1: RightAlign->Down = true; break;
case 2: CenterAlign->Down = true; break;
}
}
catch (...){
FUpdating = false;
} // ошибка (поймано исключение) FUpdating = false;
}
// функция возвращает установленные атрибуты текущего текста
TTextAttributes *_fastcall TMainForm::CurrText(void) {
return RichEdit1->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 (RichEdit1->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, RichEdit1->ClientWidth-GutterWid,
ClientHeight) ;
SendMessage(RichEdit1->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*/) {
CheckFileSave(); // сохранить изменения?
SetFileName((AnsiString)"Untitled") ;
RichEdit1->Lines->Clear() ;
RichEdit1->Modified = false;
}
// Загрузка выбранного Файла командой File I Open или кнопкой
void _fastcall TMainForm::FileOpenClick(TObject*) {
CheckFileSave(); // сохранить изменения?
if (OpenDialog->Execute()) {
RichEdit1->Lines->LoadFromFile(OpenDialog->FileName) ;
SetFileName(OpenDialog->FileName) ;
RichEdit1->SetFocus() ;
RichEdit1->Modified = false;
RichEdit1->ReadOnly = OpenDialog->Options.Contains(ofReadOnly)
;
}
}
// Запись Файла командой File I Save или кнопкой
void*_fastcall TMainForm::FileSaveClick(TObject* Sender) {
if (!strcmp(FFileName.c_str(), "Untitled"))
FileSaveAsClick(Sender); // нет имени
else
{
RichEdit1->Lines->SaveToFile(FFileName); // то же имя
RichEdit1->Modified = false;
}
}
// Запись Файла под выбранным именем командой FilelSaveAs
void _fastcall TMainForm::FileSaveAsClick(TObject*) {
if (SaveDialog->Execute()) {
RichEdit1->Lines->SaveToFile(SaveDialog->FileName) ;
SetFileName(SaveDialog->FileName) ;
RichEdit1->Modified = false;
}
}
// Диалог печати Файла по команде File I Print или кнопкой
void _fastcall TMainForm::FilePrintClick(TObject*) {
if (PrintDialog->Execute()) RichEdit1->Print( FFileName
);
}
// Выход из программы по команде File I Exit
void _fastcall TMainForm::FileExitClick(TObject*) {
Close() ;
}
// Отмена редактирования командой Edit I Undo или кнопкой
void _fastcall TMainForm::EditUndoClick(TObject*) {
if (RichEdit1->HandleAllocated())
SendMessage(RichEdit1->Handle, EM_UNDO, 0, 0) ;
}
// Вырезка выбранного текста командой Edit I Cut или кнопкой
void _fastcall TMainForm::EditCutClick(TObject*) {
RichEdit1->CutToClipboard();
}
// Копирование текста командой Edit I Copy или кнопкой
void _fastcall TMainForm::EditCopyClick(TObject*) {
RichEdit1->CopyToClipboard();
}
// Вставка текста командой Edit I Paste или кнопкой
void _fastcall TMainForm::EditPasteClick(TObject*) {
RichEdit1->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 Ноw to...
void _fastcall TMainForm::HelpHowToClick(TObject*) {
Application->HelpCommand(HELP_HELPONHELP, 0) ;
}
// Диалог с логотипом редактора по команде Help I About
void_fastcall TMainForm::HelpAboutClick(TObject*) {
Form2 = new TPorm2(Application); // создать объект формы
Form2->ShowModal(); // активировать диалог
delete Porm2; // уничтожить объект
}
// Диалог выбора шрифта и его атрибутов по команде Edit I
font
void _fastcall TMainPorm::SelectFont(TObject*) {
FontDialog1->Font->Assign(RichEdit1->SelAttributes);
if (FontDialog1->Execute()) CurrText()->Assign(FontDialog1->Font)
;
RichEdit1->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);
RichEdit1->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) RichEdit1->Paragraph->Numbering = (TNumberingStyle)BulletsButton->Down;
}
// Типовая проверка возможности выхода из приложения
void _fastcall TMainForm::FormCloseQuery(TObject*, bool &
CanClose) {
try { CheckFileSave(); } // сохранить изменения?
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;
RichEdit1->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;
RichEdit1->Paragraph->LeftIndent = int((LeftInd->Left+FDragOfs-GutterWid)
/ RulerAdj)-RichEdit1->Paragraph->FirstIndent;
SelectionChange(Sender); // атрибуты форматирования
}
// Определение позиции регулятора правого отступа параграфа
void_fastcall TMainForm::RightIndMouseUp(TObject* Sender, TMouseButton,
TShiftState, int, int) {
FDragging = false;
RichEdit1->Paragraph->RightIndent = int((Ruler->ClientWidth-Rightlnd->Left+FDragOfs-2)
/ RulerAdj)-2*GutterWid;
SelectionChange(Sender); // атрибуты форматирования
}
// Активизация Файла помощи на Форме
void _fastcall TMainForm::FormActivate(TObject* /*Sender*/) {
Application->HelpFile = "RICHEDIT.HLP";
RichEdit1->SetFocus() ;
}
Листинг 4.1. Кодовый файл Romain.cpp модуля редактора.
|