Главная страница | Инфа по реестру и биосу | Соц опрос | Реклама на сайте | ||||||||||||||||||||||||||||||||||||||||||||||||
Гостевая книга | Учебники по программированию | Немного о операционных системах | Наш форум | ||||||||||||||||||||||||||||||||||||||||||||||||
Вы можете отредактировать (например, с помощью того же Microsoft Word) исходный справочный файл RICHEDIT.RTF из каталога \...\CBuilder\Examples\Apps\RichEdit\Help, а затем собрать новую версию RICHEDIT.HLP с помощью утилиты BUILDHLP.BAT. Наличие действующей команды меню Help придает программе профессиональный облик и облегчает работу пользователя. После того, как вы запустите редактор и испытаете что он умеет, придет черед разобраться в том как он это делает. Листинг 4.1 содержит полный текст файла кодового модуля Romain.cpp с необходимыми комментариями. Несмотря на большой размер, целесообразно привести текст целиком, поскольку им вполне можно руководствоваться при создании собственных стилизованных приложений профессионального уровня с меню, быстрыми кнопками, диалогами и контекстной помощью. ttinclude <vcl.h> ttinclude <windows.hpp> ftpragma 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(RichEditl->Paragraph->FirstIndent*RulerAdj)- 4+GutterWid; LeftInd->Left = // левый отступ параграфа int((RichEditl->Paragraph->LeftIndent+ RichEditl->Paragraph->FirstIndent)*RulerAdj)- 4+GutterWid; RightInd->Le?t = II правый отступ параграфа •" Ruler->ClientWidth-6-
int((RichEditl->Paragraph->RightIndent+GutterWid)* RulerAdj) ; BoldButton->Down = // состояние кнопки "жирный" RichEditl->SelAttributes->Style.Contains(fsBold) ; ItalicButton->Down = //состояние кнопки "курсив" RichEditl->SelAttributes->Style.Contains(fsltalic) ; UnderlineButton->Down = // состояние кнопки "подчерк." RichEditl->SelAttributes->Style.Contains(fsUnderline) ; BulletsButton->Down = // состояние кнопки "нумерация" bool(RichEditl->Paragraph->Numbering) ; FontSize->Text = // размер шрифта itoa(RichEditl->SelAttributes->Size, sizebuf, 10); FontName->Text = // название шрифта RichEditl->SelAttributes->Name; // Состояние кнопок выравнивания параграфа switch((int)RichEditl->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 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 специализированных системных элементов управления. 4.6.8.1 TTimer Эта компонента инкапсулирует таймерные функции Windows API: SetTimer и KillTimer и сама обрабатывает сообщения WM_TIMER. Свойство Interval задает частоту возникновения события OnTimer. По умолчанию Interval=1000 (одна секунда). Временной интервал передается функции SetTimer в качестве параметра. Для каждого таймера вашей программы заведите отдельную компоненту. 4.6.8.2 TPaintBox Предоставляет вашей программе возможность рисования на форме только внутри заданной прямоугольной области, предотвращая выход за границы поля рисования. Если компонента TPaintBox перенесена на форму, ваша программа может рисовать на поверхности поля рисования (канве) с помощью обработчика события OnPciinl. Цвет и шрифт, используемые при инициализации объектов канвы (TCanvas), определяются свойствами Color и Font. Если вы хотите рисовать на всей форме, воспользуйтесь обработчиком события OnPaint самой формы. Чтобы сохранить относительное положение поля рисования неизменным, даже если пользователь изменит размеры формы, установите значение true свойства Align.
4.6.8.3 TFileListBox Отображает список файлов в текущем каталоге, доступных программе во время ее работы. Смена текущего каталога отражается значением свойства Directory. Свойство Mask задает типы, а свойство FileType - атрибуты файлов, которые появятся в списке файлов. Имя и расширение выбранного файла можно будет вводить в область редактируемого ввода, если свойство FileEdit указывает на соответствующий объект класса TEdit. Чтобы снабдить имена файлов пиктограммами. установите значение true свойства ShowGlyphs. TFileListBox является производной от класса TCustomListBox, причем ее функционирование определяется, в основном, компонентой TListBox. 4.6.8.4 TDirectoryListBox Отображает древовидную структуру каталогов текущего диска, доступных программе во время ее работы. Смена текущего каталога отражается значением свойства Directory, а смена текущего дисковода - значением свойства Drive. TDirectoryListBox является производной от класса TCustomListBox, причем ее функционирование определяется, в основном, компонентой TListBox. 4.6.8.5 TDriveComboBox Отображает комбинированный редактируемый список дисков, доступных программе во время ее работы. Смена текущего дисковода отражается значением свойства Drive. Синхронизировать работу трех компонент TDriveComboBox, TDirectoryListBox и TFileListBox можно обработчиками событий OnChange первой и второй компоненты: TForml->DriveComboBoxl->Change(Sender: TObject); TForml->DirectoryListBoxl->Change(Sender: TObject); Теперь, когда пользователь меняет дисковод в списке дисков, содержимое списков каталогов и файлов также обновится. Другой способ решения проблемы синхронизации связан с установкой значения DirectoryListBoxl свойства DirList в списке дисков, а также значения TFileListBox 1 свойства FileList в списке файлов". 4.6.8.6 TFilterComboBox Представляет комбинированный редактируемый список фильтров для выбора имен файлов с расширениями. Свойство Filter задает фильтры, которые появятся в списке фильтров, а свойство Mask - конкретный фильтр, выбранный пользователем в поле редактируемого ввода. Обычно, список фильтров сопровождается списком файлов. Синхронизировать работу этих компонент можно обработчиком события OnChange первой компоненты: TForml->FilterComboBoxl->Change(Sender: TObject) ; Теперь, когда пользователь меняет фильтр, содержимое списка файлов обновится соответственно. Другой способ решения той же проблемы связан с установкой значения FileListBoxl свойства FileList списка фильтров. 4.6.8.7 TMediaPlayer Элемент управления устройствами мультимедиа, которые поддерживаются MCI-драйверами (Media Control Interface) операционной системы Windows. Данная компонента отображает стандартную панель (Рис. 4.23) с кнопками (Play, Stop, Eject и др.), позволяющими управлять такими устройствами как звуковая плата, компакт диск, видеокамера, AVI плеер, MIDI секвенсор.
Рис. 4.23. Петель управления устройствами мультимедиа. Конкретное устройство задается свойством DeviceType (например, dtWaveAudio или dtVideodisc). Значение dtAutoSelect свойства DeviceType вызовет попытку автоматически выбрать тип устройства, а значение true свойства AutoOpen - открыть его вызовом метода Open. Если устройство сохраняет свои данные в файле, задайте имя этого файла в свойстве FileName.
4.6.8.8 TOleContainer Организует связь с OLE объектами (Object Linking and Embedding) или непосредственно включает их в вашу программу. Механизм OLE, являющийся расширением операционных систем Windows, реализует передачу данных от программы-сервера к другой программе-контейнеру. Например, ячейки электронной таблицы можно переносить в документ текстового процессора. Передача данных осуществляется через динамически отводимую память. В отличие от механизма обмена данными через доску объявлений (Clipboard), контейнеру OLE не требуются знания формата принимаемых данных. Любой сервер может выдавать свои данные любому контейнеру, который принимает их, без какой бы то ни было интерпретации формата. Чтобы дать возможность пользователю создать OLE объект в режиме диалога, достаточно обратиться к методу InsertObjectDialog. Методы CreateObject и CreateObjectFromFile отвечают за создание включенного объекта, а метод CreateLinkToFile - за создание связанного с файлом объекта. TOleContainer автоматически обслуживает процесс слияния меню, т.е. объединения контейнера элемента меню вашей формы с объектом замещения, который активизируется OLE сервером. 4.6.8.9 TDdeClientConv Устанавливает режим динамического обмена данными (Dynamic Data Exchange) для программы DDE клиента. Используйте эту компоненту совместно с TDdeClientIlem, чтобы сделать ваше приложение DDE клиентом. Механизм DDE, являющийся расширением операционных систем Windows, реализует асинхронный обмен элементами данных между программой сервера (которая должна быть запущена первой) и программой клиента. Элементом обмена может быть любая выбранная порция текста, например, ячейка таблицы базы данных. Клиент инициирует соединение с сервером и выдает запросы на обмены элементами данных между двумя участниками "разговора". Для соединения с сервером и превращения вашего приложения в DDE клиента на этапе проектирования, установите имя программы сервера в свойстве DdeService, а тему разговора (имя формы или имя текстового файла) - в свойстве DdeTopic. В окне диалога установок режима DDE Info нажмите кнопку Paste Link. Во время работы программы эти действия реализует метод Setlink. Чтобы послать текстовую строку связанному элементу сервера, воспользуйтесь методом PokeData, а для посылки макрокоманды на исполнения сервером обратитесь к методу ExecuteMacro. Если значением свойства ConnectMode задан автоматический режим разговора ddeAutomatic, клиент попытается установить связь при создании компоненты в момент исполнения программы. Если значением свойства ConnectMode задан режим разговора ddeManual, то для установки связи вы должны написать обработчик события ОпОреп, который вызывает метод OpenLink.
4.6.8.10 TDdeClientltem Определяет элемент динамического обмена данными DDE клиента. Укажите имя объекта компоненты TDdeClientConv в свойстве DdeConv, a элемент обмена - в свойстве Ddeltem. Если компонента TDdeClientConv установила связь с DDE сервером, он будет автоматически и последовательно обновлять данные клиента, пока разговор не завершится. Каждый раз, когда сервер производит обновление данных клиента, новая текстовая строка автоматически заносится в свойство Text, и возникает событие OnChange. При обмене строками длиннее 255 символов они будут передаваться через список свойства Lines, причем первая строка Lines переносится в Text.
4.6.8.11 TDdeServerConv Устанавливает режим динамического обмена данными для программы DDE сервера. Используйте эту компоненту совместно с TDdeServerItem, чтобы сделать ваше приложение DDE сервером. Тема разговора является значением свойства Name. Если клиент посылает макрокоманды серверу, вы должны написать обработчик события OnExecuteMacro, которое возникает при приеме запроса на ее исполнение. Использование компоненты TDdeServerConv не обязательно: если вы не поместили ее на форме, клиент будет по-прежнему посылать запросы на обновление своих данных непосредственно из компоненты TDdeServerItem. В этом случае темой разговора является имя формы, на которой находится компонента TDdeServerItem.
4.6.8.12 TDdeServerltem Определяет элемент динамического обмена данными DDE сервера. При использовании этой компоненты вместе с TDdeServerConv имя сервера указывается значением свойства ServerConv. Каждый раз. когда клиент посылает запрос на обновление своих данных. сервер посылает ему содержимое свойства Text, и возникает событие OnCliange. При обмене строками длиннее 255 символов они будут передаваться через список свойства Lines, причем первая строка Lines переносится в Text. Чтобы протестировать связь с DDE клиентом, воспользуйтесь методом CopyToClipboard, который будет копировать содержимое свойства Text (или Lines) и информацию о связи на доску объявлений. При активизации клиента вы сможете забрать DDE данные с доски объявлений в программу клиента. 4.6.9 Компоненты отчетов Вкладка QReport палитры компонент содержит 11 компонент для создания и манипуляций с предварительно определенными отчетами. Эти компоненты позволяют визуально конструировать стилизованные отчеты по данным, поставляемым любым источником, включая таблицы и запросы компонент доступа к базам данных TTable и TQuery. Отчеты могут содержать поля заголовков, колонтитулов, сносок и итогов. QReport предоставляет мощные средства отображения отчетов в разных видах, автоматического подведения итогов и подсчета полей - на любом уровне группировки данных отчета. 4.6.9.1 TQuickReport Представляет и распечатывает данные в виде стилизованных отчетов QuickReport. Это основная компонента используется совместно с TDataSource и одной или несколькими TQRBand. Дважды щелкнув мышью по компоненте или выбрав опцию Preview Report из контекстного меню, вы откроете окно просмотра отчета. Укажите источник данных в свойстве DataSource. Чтобы заполнить окно просмотра отчета или напечатать его, обратитесь к методам Preview или Print.
4.6.9.2 TQRBand Каждый образец этой компоненты отвечает за представление и печать своего поля (полосы) отчета. Свойство BandType содержит выпадающий список вариантов полос отчета (заголовки, колонтитулы, сноски, вложенные поля деталировок, итоги и т.д.), из которого вы выбираете ту полосу, которую будет обсуживать данная компонента. Распечатка одних полос отчета будет происходить автоматически, а распечатка других потребует связи с компонентами TQRGroup или TQRDetailLink.
4.6.9.3 TQRGroup Поддерживает работу с групповой полосой отчета. 4.6.9.4 TQRDetailLink Поддерживает работу с перекрестными ссылками на вложенные полосы деталировки, осуществляя связь по принципу master-detail.
4.6.9.5 TQRLabel Отображает текст в виде заголовков столбцов отчета. Вы можете менять статический текст заголовка в свойстве Caption в любой момент во время подготовки отчета. Если вам требуется выводить текст поля записи некоторого набора базы данных, следует воспользоваться компонентой QRDBText.
4.6.9.6 TQRMeino Отображает, по аналогии с компонентой TDBMemo, многострочный текст поля текущей записи в наборе данных источника. 4.6.9.7 MTQRDBText Отображает, по аналогии с компонентой TDBText, однострочный текст поля текущей записи в наборе данных источника. 4.6.9.8 TQRDBCalc Автоматизирует процесс суммирования и подсчета полей в наборе данных источника. 4.6.9.9 TQRSysData Включает в отчет системную информацию определенного вида, выбираемого из выпадающего списка свойства Data.
4.6.9.10TQRShape Отображает в отчете прямые линии, рамки и простые геометрические фигуры (прямоугольник, эллипс), выбираемые из выпадающего списка свойства Shape.
4.6.9.11 TQRPreview Облегчает процесс создания различных видов просмотра отчета, включая операции прокрутки и масштабирования. Несколько компонентных методов позволяют управлять поведением отчета во время просмотра. Например, вызов метода ZoomToFit в обработчике события OnClick по нажатию некоторой кнопки будет масштабировать страницу в установленное поле просмотра.
4.6.9.12 Пример использования компонент отчетов C++Builder поставляется вместе с примером, который демонстрирует следующие разновидности работы с компонентами отчетов: • создание этикеток для почтовых отправлений; • создание простого отчета; • модификация оригинальных предварительных видов печати; • разработка отчетов по принципу master-detail; • сохранение выборочных текстовых файлов детализации.
Рис. 4.24. Форма приложения для работы с отчетами. Удостоверьтесь предварительно, что локальный псевдоним (alias) демонстрационной базы данных BCDEMOS установлен с помощью утилиты конфигурации BDE Configutation. Чтобы вызвать проект приложения, выполните следующие действия: =? По команде главного меню File | Open Project откройте диалог выбора проектов. => Войдите в каталог \.. .\CBuilder\Examples\Dbtasks\Quickrpt. => Выберите проектный файл с именем Qrdemo и нажмите кнопку Open. Рис. 4.24 показывает форму демонстрационного приложения Quick Report. => Командой главного меню Run | Run запустите процесс компиляции и сборки приложения. => После вызова программы поэкспериментируйте с разными опциями. 4.6.10 Компонента ActiveX Входящие в варианты поставки C++Builder Professional и C++Builder Client/Server Suite компоненты обеспечивают поддержку промышленного стандарта ActiveX/OCX. Созданные вами или третьими лицами компоненты Delphi ActiveX можно интегрировать в среду так, чтобы они вошли в Палитру компонент для немедленного использования. В частности, вы можете расширить стандартный вариант Палитры новыми компонентами ActiveX, включив пакет NetManage для обучения и разработки приложений в сети Internet. В конце главы 6 вы найдете подробную инструкцию того, как это делается. В типовом варианте поставки C++Builder Standard вкладка ActiveX палитры компонент содержит единственную компоненту ChartFX для построения на вашей форме разнообразных диаграмм, графиков, таблиц и проверки правописания на многих языках. 4.6.10.1 ChartFX Дважды щелкнув мышью по компоненте или выбрав опцию Properties из ее контекстного меню. вы откроете диалоговое окно установок вида и множества других характеристик диаграммы. Свойства, методы и события компоненты ChartFX обеспечивают выполнение следующих основных операций над диаграммами: • Создание простых диаграмм. • Передача исходных данных в новую диаграмму. • Редактирование данных в существующей диаграмме. • Изменение легенд, заголовков и других визуальных атрибутов диаграммы (видов, цветов, орнаментов заливки, шрифтов, координатных сеток и т.д.). • Создание инструментов и других визуальных элементов управления диаграммой. Подробное руководство по использованию компоненты ChartFX можно вызвать из справочной службы при нажатии клавиши CtrI+Fl. 4.7 Дизайнер меню Дизайнер меню (Menu Designer) облегчает процесс создания меню для вашей формы. Вы можете легко добавлять, вычеркивать и переупорядочивать команды меню непосредственно в окне дизайнера.
Чтобы начать процесс создания меню: __ 1. Поместите значок компоненты MainMenu или PopUpMenu из вкладки стандартных компонент на вашу форму. 2. Откройте окно дизайнера меню. Оставив значок компоненты выбранным, дважды щелкните на нем левой кнопкой мыши или выберите опцию Menu Designer из контекстного меню компоненты. (Открыть контекстное меню дизайнера можно щелчком правой кнопкой мыши в любом месте его окна или нажатием клавиш Alt+FlO). 3. Введите имя меню и нажмите клавишу Enter, если желаете изменить имя, установленное по умолчанию (MainMenul). Чтобы добавить команды в меню: 1. Выберите позицию, в которую вы хотите поместить новую команду. 2. Введите название команды (или символ "-", если вы хотите добавить разделительную черту в выпадающий список команд) и нажмите клавишу Enter. Указанному названию (Caption) C++Builder автоматически поставит в соответствие некоторый идентификатор (Name) и занесет в Инспектор объектов. Так команде меню File ставится в соответствие идентификатор Filel, а русскоязычному названию Файл - порядковый номер идентификатора с префиксом N. Если названию предшествует символ "&", то обращение к соответствующей команде меню можно выполнять совместным нажатием клавиш Alt+первая (подчеркнутая) буква названия. Можно задать любую комбинацию "горячих" клавиш или выбрать ее из списка ShortCut Инспектора объектов. 3. Нажмите клавишу Enter, чтобы перейти к добавлению следующей команды выпадающего списка или клавишу Esc, чтобы вернуться в главное меню. С помощью левой кнопки мыши или клавиш позиционирования <-, ->, Г, ^ можно перемещаться по списку и переходить в главное меню. Повторное нажатие клавиши Enter завершает процесс.
Чтобы вставить поле для новой команды в меню: 1. Выберите элемент меню, рядом с которым вы собираетесь сделать вставку. 2. Нажмите клавишу Ins или выберите опцию Insert из контекстного меню. Поле новой команды вставляется над выбранным элементом в выпадающем списке или слева от выбранного элемента в главном меню.
Чтобы удалить команду из меню: 1. Выберите команду, которую вы собираетесь удалить. 2. Нажмите клавишу Del или выберите опцию Delete из контекстного меню.
Чтобы создать поле для вложенного подменю: 1. Выберите элемент, для которого вы хотите создать подменю. 2. Нажмите клавиши Ctrl+-> или выберите опцию SubMenu из контекстного меню.
Чтобы переместить элемент: 1. Выберите элемент меню и, удерживая левую кнопку мыши, перенесите его на новое место. Вид курсора поможет вам выбрать разрешенную позицию. 2. Отпустите кнопку мыши. Вы можете конструировать меню, включая в него те элементы, которые вам требуются, или начать конструирование с шаблонов, содержащих часто употребляемые команды.
Чтобы добавить шаблон к вашему меню: 1. Выберите опцию Insert From Template из контекстного меню. 2. Выберите нужный шаблон из предложенного списка и нажмите кнопку ОК или клавишу Enter. Элементы шаблона образуют подменю элемента, на который указывал курсор в выпадающем списке команд, или создадут новый элемент в главном меню.
Чтобы сохранить ваше меню в виде шаблона: 1. Выберите опцию Save As Template из контекстного меню. 2. Введите имя шаблона и нажмите кнопку ОК или клавишу Enter. Чтобы удалить шаблон: 1. Выберите опцию Delete Templates из контекстного меню. 2. Выберите нужный шаблон из списка и нажмите кнопку ОК или клавишу Enter. Внимание: Данный шаблон будет удален не только из списка, но и из файла шаблонов BCB.DMT на жестком диске. В процессе работы программы можно динамически добавлять в меню новые исполняемые или информационные команды. Операции с множественными меню позволяют динамически менять порядок расположения элементов активного (главного) меню, вводя или замещая альтернативные элементы.
Чтобы организовать слияние меню во время выполнения: 1. Выберите меню, которое вы хотите активизировать из выпадающего списка свойства Menu вашей формы. Операции слияния применимы только к активному меню. Если форма содержит несколько компонент меню, вы можете переключать активное меню во время выполнения программы, устанавливая новые значения свойства Menu, например: Forml->Menu = ВтороеМеню; 2. Определите порядок, в котором команды меню из разных форм будут выстраиваться на разделяемой панели главного меню: чем меньше номер свойства Grouplndex, тем левее располагается соответствующая команда. Пусть главное (активное) меню содержит только две команды: "Файл" (Grouplndex=0) и "Справка" (5). Тогда между ними разрешается вставить до четырех команд из меню другой формы-потомка с номерами 1,2,3, и 4, например, "Редактор" (1) и "Формат" (3). Далее можно заместить команду "Формат" (3) на команду "Работа" (3) из меню другой формы-потомка. Рис. 4.25 иллюстрирует процесс проектирования меню на форме прототипа тестового приложения, предназначенного для обработки файлов. Открыв контекстное меню дизайнера, обратите внимание на опцию Insert From Resource. Судя по названию, она должна давать возможность создавать меню на базе ресурсных файлов с расширением .гс. К сожалению, автору не удалось заставить дизайнер использовать ресурсы приложений, ранее написанных на Borland C++ версии 4.5. Будем надеяться, что в широко рекламируемой версии 5.02 эта недоработка будет исправлена.
Рис. 4.25. Проектирование меню с помощью дизсшчера. Сконструированное вами меню всегда отображается на вашей форме в том виде, в котором оно появится при запуске программы, поэтому нет необходимости компилировать и запускать программу, чтобы увидеть результат проектирования. Вы можете продолжить редактирование меню в окне Инспектора объектов, активизировав его щелчком левой кнопки мыши.
4.8 Итоги Мы научились пользоваться основными инструментами интегрированной среды визуальной разработки C++Builder, уделив основное внимание назначению элементов Палитры компонент - "кирпичей", составляющих основу вашего приложения.
Сайт создан в системе uCoz
|