Delphi 3.Библиотека программиста

Самая актуальная информация купить минет здесь.

Вопросы безопасности


Вопросы безопасности
Безопасность считается одной из самых больших проблем в Internet. В программе KEEPER32 я реализовал лишь самые примитивные меры по обеспечению безопасности доступа. Если вы захотите усовершенствов...
Список нежелательных IPадресов
Информационные сообщения для клиентовИногда бывает нужно сообщить подключающимся FTP-клиентам об изменениях в FTP-услугах, предоставляемых KEEPER32, вывести другие информационные сообщения или инс...
Где и как хранится конфигурация
Все параметры конфигурации, не считая текстовых файлов с приветственным и прощальным сообщениями, хранятся в системном реестре Windows 95 или NT4.0. Для загрузки и сохранения этих сообщений исполь...
Листинг 7 2 Процедура LoadSettings
procedure TfrmMain.LoadSettings; var Reg : TRegistry; Count : Integer; IPName : String; begin Reg := TRegistry.Create; // Чтение параметров try Reg.OpenKey(FtpServerKey, TRUE); if Reg.ValueExists...
Открываемся!
После завершения конфигурирования компонента FTP-сервера можно запускать KEEPER32. При нажатии кнопки Start вызывается метод CsKeeper1.Start Server. На Рисунок 7.6 показан вид приложения, готового...
Вывод списка каталогов и файлов
После запуска сервера вызывается метод GetDirList, который создает текстовый файл INDEX.TXT со списком всех каталогов и файлов, находящихся в основном каталоге. Для построения списка используются...
Листинг 7 3 Процедура GetDirList
procedure TCsKeeper.GetDirList; var F : TextFile; SearchRec : TSearchRec; SizeStr, FileName, S : String; TDate : TDateTime; Result, K, L : Integer; begin AssignFile(F, DirListFile); Rewrite(F); i...
Создание прослушивающего сокета
До настоящего момента мы занимались подготовкой, причем вся работа в основном сводилась к созданию текстовых файлов. Теперь настало время воспользоваться Windows Sockets. Прежде всего необходимо в...
Листинг 7 4 Метод CsSocket GetServer
procedure TCsSocket.GetServer; begin GetServ; if Status = Failure then Exit; FSockAddress.sin_family := PF_INET; FSockAddress.sin_port := FServ^.s_port; FSockAddress.sin_addr.s_addr := htonl(INAD...
Как вас обслуживают?
Когда FTP-клиент соединяется с TCP-портом 21, Winsock DLL посылает сообщение FTP_EVENT. В результате процедура FtpEvent активизируется и начинает ожидать от сокета информационное сообщение FD_ACCE...
Вход строго по одному
Чтобы предотвратить попытки соединения со стороны новых FTP-клиентов, LoginUser вызывает функцию WSAAsyncSelect с последним параметром, равным 0 — при этом Winsock DLL перестает оповещать прослуши...
Листинг 7 5 Метод DecodeFTPCmd
procedure TCsKeeper.DecodeFTPCmd (SockNo : TSocket; CmdStr : CharArray; S : String); var FtpCmd, Selector : TFtpCmds; DirStr, FileName, Line, Port1Str, Port2Str, S1, TempStr : String; Finished :...
Мне пожалуйста вот это…
Разумеется, raison d'кtre всего протокола FTP — пересылка файлов, поэтому нет ничего удивительного в том, что из полного набора FTP-команд чаще всего используются команды выборки и сохранения RETR...
Сохраните пожалуйста…
STOR — зеркальное отражение команды RETR. Вместо того чтобы передавать файл клиенту, CsKeeper сохраняет (stores) полученный файл, отсюда и название команды. При получении компонентом CsKeeper кома...
Закрыто на переучет
Теперь у вас появился собственный, вполне работоспособный FTP-сервер, и создать его было не так уж сложно. Более того, как показывает мой собственный опыт, написать компонент для FTP-сервера значи...
Трехмерные фрактальные ландшафты
Джон ШемитцПолотна великих сюрреалистов вам не по карману? Тогда создайте виртуальный сюрреалистический пейзаж по своему вкусу (ведь он может быть сколь угодно велик). Для этого потребуется лишь ф...
Разделяй и сгибай
Чтобы сгенерировать ландшафт, достаточно присвоить случайные высоты трем вершинам равностороннего треугольника, а затем «изогнуть» каждое ребро, поднимая или опуская его середину на случайную вели...
Проблема общих сторон
Конечно, в действительности генерация фрактальных ландшафтов не сводится к примитивному рецепту «изогнуть, разделить, повторить по вкусу». Вам придется проследить за тем, чтобы каждая линия изгиба...
Вот что получается когда стороны не совпадают
Возможно, Рисунок 8.5 поможет разобраться в происходящем. Внутренние стороны принадлежат сразу двум треугольникам, мнения которых насчет величины изгиба могут не совпасть. Вершина I является серед...
Так треугольники «спорят» изза вершин
Намного проще определить специальное значение координаты, которое будет присутствовать только у неинициализированных вершин, и заставить FractureTriangle() проверять, не было ли положение середины...
Треугольный массив
При изгибании отрезка мы изменяем лишь z-координату его середины, поэтому теоретически можно использовать пару координат [x, y] как индекс в таблице со значениями z. Однако такой массив получится...
Листинг 8 1 Модуль GLOBAL PAS
unit Global; {Fractal Landscapes 3.0 - Copyright © 1987..1996, Джон Шемитц} interface uses WinTypes; type Int16 = {$ifdef Ver80} integer {$else} SmallInt {$endif} ; const MaxPlys = 8; MaxEdgeLeng...
Сохранение вершин в «квадратном» массиве
Впрочем, когда дело доходит до базы данных вершин, третья координата действительно игнорируется. Как видно из правой половины Рисунок 8.6, координаты вершин сохранятся и в том случае, если равност...
Листинг 8 2 Модуль DATABASE PAS
unit Database; { Fractal Landscapes 3.0 - Copyright © 1987..1997, Джон Шемитц } { База данных и генерация ландшафта } interface uses SysUtils, Global; { Вспомогательные математические функции } f...
Изгибы
Существует и другая тонкость, которую я обнаружил лишь после написания программы, — при изгибе длинных линий нельзя использовать ту же величину случайных отклонений, что и для коротких. В противно...
Сначала построить потом выводить
В первом воплощении этой программы за отображение ландшафта отвечала та же рекурсивная функция, в которой он рассчитывался. Если аргумент Plys (число итераций) превышал 1, функция разбивала получе...
Генерация и отображение ландшафта
После такого внушительного пролога код для генерации ландшафта выглядит на удивление просто. Процедура FractureTriangle() (см. листинг 8.2) получает треугольник и количество остающихся итераций Pl...
Листинг 8 3 Модуль DISPLAY PAS
unit Display; { Fractal Landscapes 3.0 - Copyright © 1987..1997, Джон Шемитц } interface uses WinTypes, WinProcs, SysUtils, Graphics, Forms, Global, Database; const DrawingNow: boolean = False; A...
Процедура Project()
Проекционная процедура Project() — «рабочая лошадка», от которой зависят все операции графического вывода. Она преобразует трехмерные координаты TTriple в плоские TPixel с использованием одноточеч...
Каркасный режим
Из всех режимов отображения проще всего реализован каркасный режим. В нем рисуются лишь контуры треугольников: «земля» — зеленым цветом, а «вода» — синим. Если здесь что и заслуживает внимания, та...
Режим с заполнением
Каркасный режим работает относительно быстро и неплохо обрисовывает общую структуру поверхности, но обладает большим недостатком: сетка получается прозрачной. Другими словами, задний склон холма в...
Режим со светотенью
В светотеневом режиме мы пытаемся воспроизвести изображение более реалистично и выбираем цвет каждого треугольника в зависимости от угла между его поверхностью и лучами «солнца». Треугольники, рас...
Создавайте собственные миры
FL3 демонстрирует принципы построения простейших фрактальных ландшафтов. Возможно, вам захочется улучшить распределение случайных чисел, изменить блок визуализации или модифицировать алгоритм для...
Проблемы TPersistent и несколько полезных советов
Джон Шемитц и Эд ДжорданИногда можно обнаружить, что Delphi присваивает значение свойству компонента, используя метод read, а не write. Неосторожность при написании таких методов может привести к...
Читаем чтобы записывать?
На самом деле происходит следующее: в большинстве случаев действительно применима простая модель, описанная выше. Однако, если свойство является потомком TPersistent (например, TBitmap или TFont),...
Разумные решения
Несмотря на то что это странное поведение (чтение вместо записи) наблюдается уже в трех версиях Delphi, нельзя исключить возможность, что Borland когда-нибудь все же сочтет его ошибочным и исправи...
Листинг 9 1 PERSIST SRC
{interface} type DemoComponent = class(TComponent) private fGlyph: TBitmap; fGlyphWritten: boolean; procedure SetGlyph(Glyph: TBitmap); { снаружи не видно } protected constructor Create(Owner: TC...
Листинг 9 2 PERSIST2 SRC
if fProperty <> NewPropertyValue then begin fProperty.Free; { Assign 'через' TPersistent } fProperty := TPropertyType.Create; { может и не пройти: } fProperty.Assign(NewPropertyValue); { Fr...
Использование RDTSC для измерения
В доисторическую эпоху написание быстрых программ не сводилось к правильному выбору алгоритма; программисту приходилось помнить временные характеристики различных команд и измерять время выполнени...
Листинг 9 3 RDTSC SRC
const D32 = $66; function RDTSC: comp; var TimeStamp: record case byte of 1: (Whole: comp); 2: (Lo, Hi: LongInt); end; begin asm db $0F; db $31; // BASM не поддерживает команду RDTSC {$ifdef Cpu3...
Листинг 9 4 COMP2STR SRC
function CompToStr(N: comp): string; begin Result := Format('%.0n', [N]); end;Напоследок скажу лишь следующее. Потребность в измерении временных интервалов сейчас возникает намного реже, чем в бы...
Перетаскивание текста в списках
Спасибо, Джон. При перетаскивании объекта в Delphi вид курсора изменяется; по умолчанию курсор принимает вид стрелки, к которой присоединена небольшая рамка. Такое визуальное обозначение перетаски...
Листинг 9 5 Модуль TXTDRGBX PAS
unit TxtDrgBx; interface uses Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs, StdCtrls, ExtCtrls; type TTextDragListBox = class( TListBox ) private FDragImage: TImageLis...
Строковые коллекции и списки
Когда я переходил с Borland Pascal на Delphi, мне хотелось, чтобы строковые списки (TStringList) были похожи на строковые коллекции (TStringCollection) — ну как можно обойтись без итераторов ForEa...
Листинг 9 6 Модуль STRLIST PAS
{ Создание удобных строковых коллекций в стиле TStringList. } unit StrList; interface uses Objects; type PStrListCollection = ^TStrListCollection; TStrListCollection = object(TStringCollection) f...
Установка приложений — дело рук самих приложений
Поскольку я занимаюсь написанием shareware-программ на Delphi, мне захотелось создать простейшую установочную программу для тех людей, которые получают мои творения через онлайновые службы или BBS...
Листинг 9 7 BEFORE SRC
{ Основной блок DPR-файла приложения до внесения изменений, предназначенных для работы в установочном режиме. } begin Application.Initialize; Application.CreateForm( TMainForm, MainForm ); Applic...
Листинг 9 8 AFTER SRC
{ Основной блок DPR-файла приложения после внесения изменений, предназначенных для работы в установочном режиме. } { Обратите внимание, что в строку USES модуля необходимо включить SYSUTILS.PAS....
Использование inheritedс переопределенными свойствами
Предположим, вы разрабатываете VCL-компонент Delphi (например, потомок TDrawGrid) и хотите предпринять некоторые особые действия в тот момент, когда пользователь (в нашем случае — программист) изм...
Листинг 9 9 SIZECHAN SRC
{ Потомок TDrawGrid с переопределенным методом SizeChanged. Это позволяет компоненту-потомку узнавать об изменении количества столбцов или строк. } { В секции interface... } type TMyGrid = class(...
Листинг 9 10 SETCOLCT SRC
{ Потомок TDrawGrid, переопределяющий свойство ColCountс новыми методами доступа. Это позволяет компоненту-потомкууправлять количеством столбцов. }{ В секции interface... } type TMyGrid = class(TD...
Копирование экрана
Для копирования изображений, находящихся в клиентской части формы,в Delphi используется метод GetFormImage. Но иногда бывает нужно «сфотографировать» всю форму вместе с заголовком, рамкой и т. д....
Листинг 9 11 Модуль SCRNCAP PAS
{ Функции копирования экрана в Delphi } unit ScrnCap; interface uses WinTypes, WinProcs, Forms, Classes, Graphics, Controls; function CaptureScreenRect( ARect: TRect ): TBitmap; function CaptureS...
Группы переключателей с индивидуальной блокировкой
Ничто так не радует во время конструирования форм, как элементы, которые автоматически выравниваются, масштабируются и выстраивают свое содержимое в аккуратные столбики. Возникает впечатление, буд...
Листинг 9 12 Модуль RBTNGRPS PAS
{ Группа переключателей с возможностью блокировки отдельных кнопок } unit RBtnGrps; interface uses StdCtrls, ExtCtrls, Classes; type TRadioBtnGroup = class( TRadioGroup ) private function GetItem...
Захват системной палитры
В этой главе я показал, как с помощью Delphi скопировать содержимое экрана. Все замечательно работает, если вы используете растровое изображение вскоре после его создания. Если же попытаться сохра...
Листинг 9 13 SYSPAL SRC
function GetSystemPalette: HPalette; var PaletteSize: Integer; LogSize: Integer; LogPalette: PLogPalette; DC: HDC; Focus: HWND; begin Result := 0; Focus := GetFocus; { ...это необходимо для GetDC...
Работа с буфером как с потоком
До своего знакомства с Delphi я пользовался для записи и чтения данных двоичного файла методами BlockWrite и BlockRead. Теперь наступили просвещен ные времена, и я предпочитаю работать с потоками...
Листинг 9 14 Модуль CLIPSTRM PAS
unit ClipStrm; interface uses Classes, Clipbrd, Consts, WinProcs, WinTypes; type TClipboardMode = ( cmRead, cmWrite ); TClipboardStream = class( TMemoryStream ) private FMode: TClipboardMode; FFo...
Оперативное изменение подсказок
Иногда для различных частей элемента желательно выводить различные экранные подсказки (hints). Это в наибольшей степени относится к разного рода сеткам (grids), поскольку характер информации может...
Листинг 9 15 HINTPROC SRC
{ Пример изменения подсказок в объекте TStringGrid } procedure TForm1.StringGrid1MouseMove ( Sender: TObject; Shift: TShiftState; X, Y: Integer ); const LastMCol: LongInt = -2; LastMRow: LongInt...
Использование макросов в редакторе Delphi
В редакторе Delphi можно записывать макросы, автоматизирующие ввод повторяющихся фрагментов — но узнать об этом можно разве что случайно; в справочных файлах Delphi это средство не документировано...
Листинг 9 16 HEADING TXT
{ Ниже приведена последовательность нажатий клавиш для вставки заголовкаметода в секцию implementation модуля и добавления пары begin..end.Управляющие сочетания клавиш заключены в фигурные скобки....
Потоки и TPersistent
«Устойчивостью» (persistence) называется способность объекта продолжать свое существование в течение некоторого времени. В Delphi имя TPersistent было присвоено классу, специально разработанному т...
Листинг 9 17 Модуль STRMPERS PAS
unit StrmPers; interface uses Classes; procedure WritePersistent( Stream: TStream; Persistent: TPersistent ); { ЗАМЕЧАНИЕ: Объект TPersistent должен быть создан до его передачи этой процедуре......
Отображение перетаскиваемого объектав Delphi 2 и 3
При перетаскивании объекта из элемента TreeView или ListView вместе с курсором мыши перемещается полупрозрачное изображение объекта. Этот замечательный визуальный признак существует до тех пор, по...
Листинг 9 18 Модуль ENABDISP PAS
unit EnabDisp; interface uses Controls; procedure EnableDisplayDragImage( Control: TControl; ChildrenToo: Boolean ); implementation procedure EnableDisplayDragImage( Control: TControl; ChildrenTo...
Модели виды и фреймы
Джон ШемитцВ этой главе развивается творческий подход к функциональности программ, который позволяет внедрять одну форму внутрь другой. Новые интерфейсы Delphi 3 заметно упрощают эту задачу.В числ...
Список свойств использующий код
Ваши объекты могут отображаться в нескольких различных контекстах. Например, один и тот же человек может быть и подчиненным, и начальником. Если для просмотра информации о начальнике будет исполь...
Практическая реализация видов
До настоящего момента эта глава выглядела несколько абстрактно. День за днем вы работаете с объектами, компонентами, формами и обработчиками событий — никаких моделей, видов или фреймов. Однако эт...
Шаблоны компонентов и составные компоненты
Возможное решение заключается в использовании такой новинки Delphi 3, как шаблоны компонентов (component templates). Шаблоны позволяют объединить в группу взаимосвязанные компоненты (вместе с имен...
Наследование форм
Вместо использования описанной выше методики я создаю самые обычные формы, производные от TEmbeddedForm. Как видно из листинга 10.1 (фрагмент модуля EMBEDDED.PAS), у внедренных форм имеется специа...
Листинг 10 1 Специальный конструктор для внедренных форм
type EmbeddedFormMode = (efmZoomed, efmTopLeft, efmCentered); function ALZ(Number: integer): Cardinal; // Проверка положительности begin if Number > 0 then Result := Number else Result := 0; e...
Во время выполнения вид не похож
Несомненно, возможность использования форм как элементов — хорошее начало. Теперь мы можем разместить форму там, где считаем нужным, и сделать сколько угодно копий. В объект формы можно включить м...
Листинг 10 2 Поведение модели вида и фрейма
type TModel = TObject; // И IView, и IModelEdit обладают свойством ReadOnly IReadOnly = interface function GetReadOnly: boolean; procedure SetReadOnly(Value: boolean); property ReadOnly: boolean...
Почему интерфейсы?
Перед тем как следовать дальше, я хотел бы объяснить, почему я пользуюсь интерфейсами Delphi 3, вместо того чтобы просто определить классы вида и фрейма и создавать объекты на их основе. Не вызван...
Интерфейсные формы
Когда я занялся реализацией интерфейсов из листинга 10.3, неожидан новозникли проблемы — моя система «зависала» при каждом вызове AddNotifiee(Self) из формы, реализующей IFrame. Хотя решение оказа...
Листинг 10 3 Модуль INTERFACEDFORMS PAS
unit InterfacedForms; // Copyright © 1997 by Jon //Shemitz, all rights reserved. // Permission is hereby granted to freely //use, modify, and // distribute this source code PROVIDED //that all si...
Проблемы с подсчетом ссылок в Delphi 3
Ссылки на интерфейсы, как и ссылки на длинные строки, подсчитываются. Каждый раз, когда вы создаете копию переменной, содержащей интерфейсную ссылку (непосредственным присваиванием или при передач...
Абстрактные контролируемые и неконтролируемые виды
Как видно из дерева наследования на Рисунок 10.5, интерфейсные формы используются в проекте EmbeddedForms для создания двух категорий видов: неконтролируемы х (TValidView), для которых свойство Va...
Интерфейсные формы в проекте
Обе категории видов происходят от класса TAbstractView (листинг 10.4)....
Листинг 10 4 Модуль VIEWS PAS
unit Views; // Copyright © 1997 by Jon Shemitz, //all rights reserved. // Permission is hereby granted to //freely use, modify, and // distribute this source code PROVIDED //that all six lines of...
Листинг 10 5 Методы проверки корректности
function TValidView.GetValid: boolean; begin Result := True; end; // TValidView.GetValid procedure TValidView.SetValid(Value: boolean); begin // TValidView всегда корректен - //игнорируем Value e...
Листинг 10 6 Фрагмент модуля FICKLEVIEW PAS
type TFickleView = class(TAbstractView) private { Private declarations } fValid: boolean; fNotify: IFrame; // В данной реализации проверки //корректности поддерживается // всего один получатель у...
Редакторы моделей
Мастера и списки свойств являются редакторами моделей — вы передаете им объект модели, они выполняются и затем возвращают управление. Если пользователь нажал кнопку OK и изменил модель, возвращаем...
Листинг 10 7 Запуск редакторов моделей
procedure TTestForm.EditModel(Editor: IModelEdit; Model: TModel); begin {$ifdef ReadOnly} Editor.ReadOnly := True; {$endif} // ReadOnly if Editor.EditModel(Model) then ShowMessage('OK!') else Sho...
Листинг 10 8 Метод TAbstractPropertySheet InitializeSheet
// из файла PropertySheets.pas procedure TAbstractPropertySheet.InitializeSheet( Captions: array of string; Views: array of TViewClass ); var MaxSpan: TSpan; Index: integer; Sheet: TTabSheet; Actu...
Листинг 10 9 Метод TAbstractVizard SetCurrentPage
// из файла Wizards.pas property CurrentPage: integer read fCurrentPage write SetCurrentPage; procedure TAbstractWizard.SetCurrentPage (Value: integer); var LastPage, PageIsValid: boolean; begin A...
Пример модели
Хотя файл EMBEDDEDFORMS.PAS прежде всего демонстрирует, как внедренные формы применяются на практике, и предоставляет работоспособную основу для построения мастеров и списков свойств, в нем также...
Листинг 10 10 Модуль EMPLOYEEIDVIEWS PAS
unit EmployeeIdViews; // Copyright © 1997 by Jon Shemitz, //all rights reserved. // Permission is hereby granted to freely use, //modify, and // distribute this source code PROVIDED that //all si...
Другие применения
EMBEDDEFORMS.DPR демонстрирует лишь два первых сценария из четырех, описанных в начале этой главы, — использование одной и той же формы для мастера и списка свойств, а также использование форм как...
Таинственный модуль Math
Теренс ГоггинИсследуем новый модуль Delphi, о котором мало кто знает, а заодно попробуем переложить на него всю черную работу по статисти ческой обработке данных.Вторая и третья версии Delphi соде...
Три веских довода в пользу модуля Math
Существует три веских довода в пользу работы с модулем Math. Первый и самый главный — скорость. Процедуры и функции модуля Math работают быстро. Большинство из них написано на языке ассемблера, сп...
Динамические данные и статические объявления
Модуль Math быстро работает и обладает широким набором функций, но таит в себе и ловушки. Чтобы получить максимум пользы от статистических функций, необходимо знать пару фокусов. Видите ли, многие...
Slice спешит на помощь
Похоже, объявление «с запасом» нас не спасет. Так как же передать динамические данные этим, во всех остальных отношениях замечательным функциям? Ответ кроется в малоизвестной функции Slice, спрята...
Создание компонента DBStatistics
Мы только что научились передавать динамические данные функциям модуля Math с помощью Slice. Теперь нужно придумать способ эффективного применения имеющихся средств для анализа баз данных. Самый п...
Получение доступа к данным
Чтобы новый класс TDBStatistics мог извлечь анализируемые данные, он должен прежде всего подключиться к компоненту TTable или TQuery. Для этого проще и удобнее всего снабдить наш компонент свойств...
Извлечение данных
Два следующих фрагмента TDBStatistics очень тесно связаны, поэтому мы постараемся работать над ними одновременно. Первый — процедура проверки ошибок GetRange. Во время извлечения данных компоненто...
Статистическая обработка
Вся подготовительная работа закончена, осталось лишь предоставить средства для получения статистических показателей. Для этого существуют две возможности:Метод, извлекающий все 13 показателей сраз...
Тестирование компонента DBStatistics
Наш великолепный компонент готов, пора испытать его на практике. В этом разделе мы напишем программу, которая позволяет выбрать любое поле в таблице и получить по нему полный статистический отчет,...
Программа StatsProject во время выполнения
Все начинается с вызова метода Execute. Если был выбран файл с допусти мым именем, работа продолжается: with OpenDialog1 do begin Execute; if FileName = '' then exit;Затем мы устанавливаем свойств...
Ошибки в модуле Math второй версии Delphi
Хотите верьте, хотите нет, но в модуле Math из поставки Delphi 2 действитель но присутствует ошибка. Лучше услышать о ней сейчас, чем столкнуться с ней во время работы, не правда ли? (А еще лучше...
Пропавшая функция Poly
При подготовке полного списка функций модуля Math, приведенного в конце главы, я намеренно пропустил одну из функций. Почему? Потому что фирма Borland тоже не документировала ее! Непонятно, должна...
Графическое представление
Программа PolyProject (она находится на CD-ROM в подкаталоге этой главы) как раз и является таким интерфейсным приложением. Она позволяет задать полином, а затем выводит его график. Обратите внима...
Сводка функций модуля Math
В завершение этой главы я привожу полный список всех функций и процедур модуля Math. При переходе от Delphi 2 к Delphi 3 модуль Math почти не изменился, фирма Borland ввела в него только три новые...
Тригонометрические функции и процедуры
ArcCos АрккосинусArcCosh Гиперболический арккосинусArcSin АрксинусArcSinh Гиперболический арксинусArcTahn Гиперболический арктангенсArcTan2 Арктангенс с учетом квадранта (функция ArcTan, не учитыв...
Арифметические функции и процедуры
Ceil Округление вверхFloor Округление внизFrexp Вычисление мантиссы и порядка заданной величиныIntPower Возведение числа в целую степень. Если вы не собираетесь пользо-ваться экспонентами с плаваю...
Финансовые функции и процедуры
DoubleDecliningBalance Вычисление амортизации методом двойного балансаFutureValue Будущее значение вложенияInterestPayment Вычисление процентов по ссудеInterestRate Норма прибыли, необходимая для...
Статистические функции и процедуры
MaxIntValue Максимальное значение в наборе целых чисел. Функция по-явилась в Delphi 3, ее не существует в Delphi 2MaxValue Максимальное значение в наборе чисел. В Delphi 2 функциявозвращает минима...
Динамический пользовательский интерфейс
Теренс ГоггинЕсли пользователям не нравится тот интерфейс, который вы им предлагаете, то почему бы не позволить им самостоятельно переделать его во время работы программы? Имитировать режим констр...
Пример приложения «Настрой меня сам»
На Рисунок 12.1 представлена «сборная» копия экрана простейшего приложения, демонстрирующая все возможности, которые вы можете предложить конечному пользователю.Раскрытое меню содержит три команды...
Строим «миниDelphi» для пользователей
При проектировании программы в среде Delphi вы используете ряд инструментов для настройки внешнего вида программы и ее поведения. Чтобы пользователи смогли переделать вашу программу на свой лад, и...
Перемещение элементов
Хотя перемещать элементы во время выполнения программы можно несколькими способами, для наших целей лучше всего подойдет трюк с почти недокументированным сообщением WM_SYSCOMMAND. Для перемещения...
Перемещение кнопки Windows
Результат этого фрагмента с точки зрения пользователя изображен на Рисунок 12.2.Внешне все выглядит, как при перемещении модального диалогового окна — тонкий пунктирный контур элемента следует за...
Перетаскивание в режиме конструирования Delphi
Прозрачный прямоугольник появляется только над перемещаемым элементом. С того момента, когда вы щелкнули на «выделенном» элементе, и до отпускания кнопки мыши прозрачный прямоугольник следует за к...
Листинг 12 1 Метод TSizingRect CreateParams
procedure TSizingRect.CreateParams(var Params: TCreateParams); begin inherited CreateParams(Params); Params.ExStyle := Params.ExStyle + WS_EX_TRANSPARENT; end;Метод Paint (см. листинг 12.2) рисуе...
Листинг 12 2 Метод TSizingRect Paint
procedure TSizingRect.Paint; begin inherited Paint; if fVisible = False then Exit; Canvas.Pen.Mode := pmNot; Canvas.Pen.Width := 3; Canvas.Brush.Style := bsClear; Canvas.Rectangle(0, 0, Width, He...
Масштабирование элементов
Масштабировать элементы еще проще, чем перемещать их. За образец мы снова возьмем соответствующий механизм режима конструирования Delphi. Чтобы изменить размер выделенного элемента, вы щелкаете на...
Листинг 12 3 Обработчик события
procedure TFrmMain.SizingRect1MouseMove(Sender: TObject; Shift: TShiftState; X, Y: Integer); begin { ControlDC и ControlRect - глобальные переменные, используемые в нескольких процедурах. } Contr...
Работа с контекстным меню
В нашем приложении компонент TSizingRect активизируется с помощью меню PopupMenu1, которое назначено контекстным меню для каждого элемента на форме. На Рисунок 12.4 изображено меню PopupMenu1 во в...
Листинг 12 4 Обработчик события
procedure TFrmMain.AdjustClick(Sender: TObject); begin if (Adjust.Checked = True) then begin if ((PopupMenu1.PopupComponent <> ComponentBeingAdjusted) and (PopupMenu1.PopupComponent <>...
Сохранение или отмена изменений
Если пользователь захочет сохранить результаты настройки и выберет вторую команду (Adjust Size & Position), то изменяемый элемент перемещается и масштабируется в соответствии с новыми параметр...
Отмена изменений
Если пользователь не захочет сохранять внесенные изменения и выберет первую команду меню, прямоугольник TSizingRect скрывается, а выделенный элемент остается в прежнем состоянии. Это происходит в...
Листинг 12 5 Обработчик события
procedure TFrmMain.Escape1Click(Sender: TObject); begin if (Adjust.Checked = True) then begin Adjust.Checked := False; SizingRect1.Cursor := crDefault; SizingRect1.Visible := False; SizingRect1.T...
Изменение порядка перебора элементов во время выполнения
Если пользователи смогут перемещать элементы, скорее всего, они также захотят изменить и порядок их перебора . Более того, наш дизайн «сделай сам» не пройдет тест на простоту использования, если п...
Листинг 12 6 Обработчик события OnClick команды Tab Order
procedure TFrmMain.TabOrder1Click(Sender: TObject); var i : Integer; begin FrmTabOrder.LBControls.Items.Clear; for i := 0 to ComponentCount -1 do begin if ((Components[i] is TWinControl) and not...
Изменение других свойств
Мы вплотную подошли к проблеме изменения других свойств элементов. Например, что делать, если пользователь захочет изменить шрифт или цвет некоторых компонентов DBEdit, чтобы выделить их как обяза...
Изменение шрифтов во время выполнения
В нашем приложении-примере пользователи могут изменить шрифт всех элементов командой Adjust All Fonts из главного меню. Как видно из листинга12.7, сделать это не слишком сложно....
Листинг 12 7 Изменение шрифта для всех элементов формы
procedure TFrmMain.AdjustMenu2Click(Sender: TObject); var i : Integer; begin { Изменяем шрифт для всех элементов } if FontDialog1.Execute then begin for i := 0 to ComponentCount - 1 do begin try...
Листинг 12 8 Изменение шрифта
procedure TFrmMain.ChangeFont1Click (Sender: TObject); begin if FontDialog1.Execute then try TMagic(PopupMenu1.PopupComponent).Font := FontDialog1.Font; except Exit; end; end;ЗамечаниеДаже примен...
Миниинспектор во время выполнения программы
Когда в нашем примере пользователь выбирает команду Show Properties из главного меню или View Properties из контекстного меню, инспектор объектов отображается простым вызовом метода Show:MiniInspe...
Сохранение внесенных изменений
Теперь мы располагаем средствами для изменения практически любой составляющей пользовательского интерфейса. Желательно найти способ сохране ния этих изменений, чтобы они становились постоянными. П...
Загвоздка компоненты со свойствамикомпонентами
Единственное ограничение этих методов заключается в том, что некоторые типы компонентов нельзя сохранить напрямую. Речь идет о компонентах, которые содержат другие компоненты в качестве свойств.Пр...
Листинг 12 9 Обработчик события FormCloseQuery
procedure TFrmMain.FormCloseQuery(Sender: TObject; var CanClose: Boolean); var Writer : TWriter; FileStream : TFileStream; i : Integer; TempRect : TRect; begin { Расширение файла .HPD == High Per...
Другой подход к потокам
Возможно, вы заметили, что класс TFileStream тоже содержит методы для сохранения и загрузки свойств компонента. Хотя TFileStream содержит целых два набора методов для сохранения и загрузки компоне...
На пути к гибким пользовательским интерфейсам
Для полноценного рассмотрения настраиваемых пользовательских интерфейсов одной главы явно недостаточно. Мы узнали, как предоставить пользователям контроль над большинством стандартных составляющих...
Иерархические структуры в реляционных базах данных
Ричард ХейвенДанные не всегда удается представить в виде таблицы, состоящей из строк и столбцов. В этой главе приведены рекомендации по работе с иерархическими структурами в базах данных Delphi и...
Иерархия «одинкомногим»
Delphi обладает удобными средствами для работы с реляционными базами данных. Такие базы данных представляют собой таблицы (иногда также называемые отношениями — relations), состоящие из строк (зап...
Базовая и подчиненная таблицы
Любую модель следует оценивать по тому, насколько она облегчает труд разработчика при создании базы данных. Реляционная модель хорошо подходит для многих реальных структур данных: нескольких счето...
Простейший пример иерархических рекурсивных данных
Реляционная модель хорошо работает для базовых/подчиненных записей в пределах одной таблицы, если в ней существует лишь один уровень принадлежности — другими словами, если каждая запись либо прина...
Листинг 13 1 Эквивалентный код
procedure TForm1.DataSource1DataChange (Sender : TObject; Field : TField); begin if (Field = nil) or (Field.FieldName = 'Emp_ID') then Table2.SetRange([Table1.FieldByName ('Emp_ID').AsString]), [...
Использование TQuery для определения
С помощью TQuery можно определить набор подчиненных записей, для этого базовый набор данных (TTable или TQuery) передает свои значения свойству SQL в качестве параметров динамического запроса. В п...
Листинг 13 2 Добавление записей
procedure TForm1.DataSource1DataChange (Sender : TObject; Field : TField); begin if (Field = nil) or (Field.FieldName = 'Emp_ID') then begin Query2.DisableControls; Query2.Close; with Query2.SQL...
Вложенные рекурсивные иерархические данные
Термин «рекурсивные иерархические данные» означает, что базовые и подчиненные записи находятся в одной таблице: одно неключевое поле записи содержит ключевое значение другой записи, и это означает...
Рекурсивная связь между записями одной таблицы
Такой «пошаговый» интерфейс подходит для небольших деревьев, но в сильно разветвленной иерархии легко заблудиться. Для облегчения ориентации на форму можно поместить надпись (TLabel), в которой пе...
Перемещение по иерархии
Для перемещения вверх и вниз по иерархии потребуются две дополнитель ные функции. В рассматриваемом примере пользователь перемещается вниз, когда он делает двойной щелчок на подчиненной записи (сп...
Листинг 13 3 Обработчик OnDoubleClick
procedure TForm2.DBGrid2DblClick(Sender : TObject); var NewRangeID, SelectedEmployeeID : String; begin { Выводим информацию о текущей записи } if Table1.FieldByName('Boss_ID').AsString = '' then...
Отображение данных
Перемещения вверх и вниз по иерархическому дереву неизбежны, однако вы можете воспользоваться средствами, которые автоматизируют эту задачу. Подумайте, как пользователи будут работать с данными. В...
Листинг 13 4 Заполнение компонента
procedure LoadItemStringsFromTop(ListOfItems : TListOfItems); var Counter : Integer; procedure LoadOutline(StartIndex : Integer; StartItem : TItem); var NewIndex : Integer; begin NewIndex := MyOu...
Использование данных
Цель любого пользовательского интерфейса — организация эффективного взаимодействия с пользователем. Пользователь должен видеть достаточно данных, чтобы принять и реализовать решение (или по крайне...


Начало