Компонент письменной форме, часть 3
эта статья является заключительной из трех частей статьи на компоненты. Эта заключительная часть будет охватывать собственность / редакторы компонент, как написать специальную редакцию для компонент / свойство, и как пишут "скрытые" компоненты.р><р класса="step_content ">
<границы таблицы="1"><элемента tbody><тр><тд> эта статья первоначально появилась в Delphi разработчикатд>тр>элемента tbody>Таблица>р><р класса="step_content "> Авторское право шедевре издание, Инк. Все права защищены. р> <р класса="step_content "> пользовательские редакторы компонентов
и как только мы начинаем писать дополнительные типы свойств для нашего компонентов, жизнь становится немного сложнее. Хотя инспекторе объектов, встроенная в Delphi способна распознавать большинство типов недвижимости, это невозможно, чтобы быть в состоянии иметь дело со всеми возможными пользовательский Тип мы можем писать в наших компонентов. Иногда инспекторе объектов не может справиться с нашими пользовательских типов, но монтаж такого сложного комплекса свойств в инспекторе объектов просто не достаточно понятный. Именно в этот момент мы можем быть обязаны писать собственность / редакторы компонентов. Делфи уже множество стандартных редакторов, эти редакторы в DsgnIntf.файл ССА в $(Делфи)\Источник\ToolsAPI каталог. Вам будет нужно список это устройство в использования пункт любого компонента редактор / редактор свойств можно написать, это также хорошая идея, чтобы держать этот файл открытым для справки, когда пишу свои собственные редакторы.р><р класса="step_content "> стандарты кодирования
для начала я расскажу о некоторых стандартов кодирования, которые используются при написании компонента или редакторы свойств. Есть только несколько, но это будет хорошая идея, чтобы придерживаться этих стандартов при написании вашего собственного редакторы, как это делает его легче для других людей, чтобы понять вашу работу.р><р класса="step_content ">
- при создании свойство редактора, закончить имя своего редактора со словом "собственность" например <ЭМ>TAnglePropertyем>
р><р класса="step_content "> - после создания компонента редактор, конец имя редактора со словом "редактор" например <ЭМ>TPieChartEditorем>
р><р класса="step_content "> - когда пишут редакторы, всегда пишу редактор в отдельный блок с вашей фактической составляющей. Это хорошо, чтобы отделить время разработки и во время выполнения кода и, помимо этого, это делает ваш получившийся exe Размер меньше (по некоторым версиям Delphi компонент может останавливать приложения от компиляции, если Вы не разделите их). Кроме того, отдельные пакеты, так что ваши пользователи могут строить с пакетами времени выполнения, если они хотят !
р><р класса="step_content "> - если имя вашего редактора блок с тем же именем, как составляющая единица, но добавить слово "рег" в конце например, компонент с группой название "компонент mycomponent.паск" приведет в редакторе именем быть "MyComponentreg.паск"
р><р класса="step_content "> - если при написании компонента редактор / Editor свойство для компонента, переместите ваш RegisterComponentsем> выписка из компонента, который и в код компонента редактора блока. Таким образом, ваш компонент не будет зарегистрирован без редактора и регистрации.
р><р класса="step_content ">
Р><Р класса="step_content "> свойство редактора
в собственность редакторы используются IDE, чтобы специальный редактирование отдельных свойств в компоненте. Некоторые редакторы очень просты, некоторые из них гораздо сложнее. Делфи уже есть несколько стандартных редакторов свойств, некоторые из них являются:
TIntegerProperty. Используется для ввода чисел.р><р класса="step_content "> TCharProperty. Используется для ввода одного символа.р><р класса="step_content "> TEnumProperty. Используется для выбора отдельных элементов перечислимого типа (алтоп, alClient и т. д.). <их>TBoolPropertyем>. Используется для выбора значения "True" или "false" для логических свойств.р><р класса="step_content "> TFloatProperty. Используется для ввода чисел с плавающей точкой (переменная типа float / Расширенная и т. д. "Реального" типа не следует использовать для свойства компонента).р><р класса="step_content "> TStringProperty. Используется для ввода строки до 255 символов.р><р класса="step_content "> TSetProperty. Используется для включения / исключения отдельных элементов из набора собственность. Каждый элемент отображается как логический подсвойства. Установив значение в "True" включает в себя элемент, устанавливая его в "false" исключает его.р><р класса="step_content "> TClassProperty. Это базовый класс для спуска, когда вы хотите создать пользовательский редактор, который будет вызван для свойства определенного класса (когда у вас есть Класс как свойство, например, TImage.Рисунок).р><р класса="step_content "> все эти редакторы свойств спускаются прямо или косвенно от TPropertyEditor. TPropertyEditor имеет много свойств и методов, наиболее значимыми являются.р><р класса="step_content "><границы таблицы="1" Ширина="100%" bgcolor в="#ffffcc">
<элемента tbody><тр> <тд> функция в AllEqual: логическое виртуальныеСтронг>
функция для запроса getattributes: TPropertyAttributes виртуальныеСтронг>
процедура изменить на виртуальныеСтронг>
функция Думою: строкасильная> виртуальныеСтронг>
процедура GetValues(прок: TGetStrProc) виртуальныесильные>
и ир><р класса="step_content "> тр>р><р класса="step_content "> элемента tbody>Таблица>р><р класса="step_content "> AllEqualСтронг>
Если выбрано несколько компонентов, инспектором объекта фильтрует список свойств только те, что все выбранные компоненты имеют в общем. Если значение в каждой компоненте для любого заданного свойства (например, Ширина) одинаковы, то значение будет отображаться, в противном случае значение не будет отображаться. AllEqual-это процедура, которая определяет, является ли каждое значение является идентичным.р><р класса="step_content "><границы таблицы="1" Ширина="100%" bgcolor в="#ffffcc">
<элемента tbody><тр> <тд> функция в TStringProperty.AllEqual: логическое
варсильные>
я: целое число
в: строкаСтронг>
начатьсильные>
как результат := ложь
В если в PropCount > 1 на тогдаСтронг>
начатьсильные>
и в := GetStrValue
длясильная> я := 1 на в PropCount - 1 на усильные>
В если в GetStrValueAt(я) <> в тогда для выезда в
в концесильные>
В результате := Правда
конецсильные>
и ир><р класса="step_content "> тр>р><р класса="step_content "> элемента tbody>Таблица>р><р класса="step_content "> в приведенном выше примере TStringProperty сравнивает каждое значение (используя GetStrValueAt) со значением первого компонента в списке (используя GetStrValue, GetStrValueAt(0) сделал бы то же самое). Размер списка определяется с помощью PropCount, это возвращает общее количество выбранных компонентов.р><р класса="step_content "> методы getattributesсильные>
и методы getattributes называется средой разработки, когда он должен собрать сведения о редакторе собственность. Инспектор объектов отображает соответствующий редактор, основанный на информации, предоставленной. Результат запроса getattributes (TPropertyAttributes) - это набор, поэтому может содержать комбинацию следующих значений (это не полный список)
тег в paDialogсильные>
как сообщает инспектор объектов, чтобы показать [...] после имени свойства, когда пользователь нажимает на эту кнопку изменить способ срабатывает.элемент blockquote>р><р класса="step_content "> paSubPropertiesсильные>
как сообщает инспектор объектов, чтобы показать [ ] кнопка перед свойство "имя", при нажатии этой кнопки показать расширенный список дополнительных свойств (как правило опубликованных свойств свойство класса).р><р класса="step_content "> paValueListсильные>
В инспекторе объектов появится выпадающий список значений, в этом списке определяется в IDE с помощью вызова метода GetValues.
<ем>Примечание: GetValues метод, а не метод getvalue, который полностью отличается от на сайтер><р класса="step_content "> paSortListсильные>
если в сочетании с paValueList, значения будут отсортированы в алфавитном порядке.р><р класса="step_content "> paMultiSelectсильные>
при этом указывает, что язь, что собственность будет отображаться при выборе нескольких компонентов. Этот пункт не является для редакторов такого TClassProperty.р><р класса="step_content "> paAutoUpdateСтронг>
вызывает метод setvalue метод, который должен вызываться каждый раз, когда значение изменяется в инспекторе объектов, а не ждал нажатия или изменить другого свойства. Это используется для "Заголовок" и "текст" свойств, чтобы дать прямую представления значения, введенные пользователем.р><р класса="step_content "> paReadOnlyсильные>
если этот элемент включен значение в инспекторе объект только для чтения. Это обычно используется в сочетании с paDialog. Думою будет переопределен для возврата описательное представление свойств. р><р класса="step_content "> редактироватьсильные>
этот метод вызывается при нажатии на кнопку [...] для свойства. Эта кнопка отображается, если элемент paDialog включается в результат запроса getattributes.р><р класса="step_content "> Думоюсильные>
этот метод вызывается, когда объект инспектор должен знать, как отобразить объект в виде строки. Это обычно используется, когда [paDialog, paReadOnly] определены в результате запроса getattributes.р><р класса="step_content "> GetValuesсильные>
этот метод вызывается при инспекторе объектов необходимо получить список значений для отображения, когда paValueList определяется в результате запроса getattributes. GetValues передает параметр под названием "прок", которая является TGetStrProc типа. GetStrProc объявлен TGetStrProc = процедура(константный ы: строкав) для объекта в р><р класса="step_content "> в IDE ожидает "прок" будет вызываться один раз для каждого значения, которые должны отображаться в инспекторе объектов это свойство.р><р класса="step_content "><границы таблицы="1" Ширина="100%" bgcolor в="#ffffcc">
<элемента tbody><тр> <тд> порядок в THintProperty.GetValues(прок: TGetStrProc)
начатьсильные>
В прок('первый элемент, чтобы отобразить')
В прок('второй элемент, чтобы отобразить')
конецсильные>
и ир><р класса="step_content "> тр>р><р класса="step_content "> элемента tbody>Таблица>р><р класса="step_content "> в следующем примере показано, как задать список значений по умолчанию для "Подсказка" свойства всех компонентов, в то же время позволяя пользователю ввести значение не в списке.р><р класса="step_content "><границы таблицы="1" Ширина="100%" bgcolor в="#ffffcc">
<элемента tbody><тр> <тд> Типсильные>
В THintProperty = класс(TStringProperty)
общественныесильные>
функция для запроса getattributes: TPropertyAttributes переопределитьСтронг>
процедура GetValues(прок: TGetStrProc) переопределитьСтронг>
конец в р><р класса="step_content "> процедура зарегистрировать р><р класса="step_content "> для реализациивр><р класса="step_content "> порядок в реестре
начатьсильные>
В RegisterPropertyEditor(Объект typeinfo(строка), Нил, в <шрифта цвет="синий"> "Подсказка" шрифт>, THintProperty)
конец в р><р класса="step_content "> <ем><шрифта цвет="синий">{ THintProperty }шрифт>ем>р><р класса="step_content "> функция в THintProperty.Методы getattributes: TPropertyAttributes
начатьсильные>
В результате := наследство для запроса getattributes [paValueList, paSortList]
и на конец в р><р класса="step_content "> порядок в THintProperty.GetValues(прок: TGetStrProc)
начатьсильные>
В прок(<шрифта цвет="синий">'это-обязательный параметр'шрифт>)
В прок(<шрифта цвет="синий">'Нажмите клавишу F1 для получения дополнительной информациишрифт>)
В прок(<шрифта цвет="синий">', это значение является только для чтения'шрифт>)
конецсильные>
и ир><р класса="step_content "> тр>р><р класса="step_content "> элемента tbody>Таблица>р><р класса="step_content "> первые методы getattributes переопределяется, и [paValueList, paSortList] включены в результат. Далее GetValues переопределяется и добавляются в выпадающий список по телефону "прок" порядка трех значений.р><р класса="step_content "> Регистрация собственности редакторов
и, наконец, свойство редактора Зарегистрирован через RegisterPropertyEditor. RegisterPropertyEditor принимает четыре параметра:р><р класса="step_content "> PropertyType: PTypeInfoсильные>
не требует указатель на TTypeInfo записи. Это звучит гораздо сложнее, чем есть на самом деле, все, что нам нужно сделать, это добавить TypInfo на использование пункта, и использовать функцию объект typeinfo для получения указателя для нас. Объект typeinfo(SomeVariableType)р><р класса="step_content "> ComponentClass: TClassсильные>
это базовый класс, что этот редактор должен обратиться. Редактор будет применить для этого класса и классов, которые происходят от нее. Если указан ноль, этот редактор будет применяться к любому классу.р><р класса="step_content "> константный Имя_свойства: строкасильные>
если этот редактор должен применяться только в отношении конкретного имущества, то имя свойства должно быть указано здесь. Если редактор должен обратиться к любому свойству типа, указанного в PropertyType это значение должно быть ".р><р класса="step_content "> EditorClass: TPropertyEditorClassсильные>
это класс, который был создан для борьбы с администрацией. В приведенном выше примере класс THintProperty.р><р класса="step_content "> используя RegisterPropertyEditor неправильно
это важно при использовании RegisterPropertyEditor, что вы предоставляете правильные сведения. Поставлять неверную информацию, может означать, что либо ваш редактор влияет на ошибочные свойства (например, все строковые свойства) или неправильные компоненты.р><р класса="step_content "> другая крайность, настройка параметров неправильно может означать, что только определенное имущество на определенный компонент (и их потомков) - это связано с редактором. Это не кажется большой проблемой на первый, но компоненты потомок, возможно, пожелают внедрить дополнительные свойства одинакового типа. Как эти свойства, очевидно, будет иметь другое имя, они не имеют правильного свойство редактора, возложенные на них.р><р класса="step_content "> пример плохо зарегистрированы редактор уже существует в в VCL. Стандартный редактор для TCollection было зарегистрировано для всех классов произошли от TComponent. Проблема в том, что низший класс может быть отображается в инспекторе объект компонент (класс TComponent, который спускается с).р><р класса="step_content "> если компонент имеет свойство типа компонент (который по умолчанию выставляет свои подсвойства в разворачиваемом списке), и одно из его свойств-это типа TCollection, в результате [...] кнопку в инспекторе объектов, который ничего не делает при нажатии (как мы видели во второй части этой серии статей).р><р класса="step_content "> решение этой проблемы кажется достаточно простым. А не наши суб-свойства произошли от компонент, мы могли бы спуститься от TComponent, а не. Однако, поведение по умолчанию для свойства типа TComponent (как определено редактор свойств редактор TComponentProperty) - Показать список других компонентов, а не суб-свойства встроенного компонента.р><р класса="step_content "> собственно решение очень простое, но только если вы знаете как написать редактор свойств.р><р класса="step_content "> Шаг 1в:
<границы таблицы="1" Ширина="100%" bgcolor в="#ffffcc">
<элемента tbody><тр> <тд> Типсильные>
В TExpandingRecord = класс(компонент)в
тд>р><р класса="step_content "> тр>р><р класса="step_content "> элемента tbody>Таблица>р><р класса="step_content "> было изменено на
<границы таблицы="1" Ширина="100%"для bgcolor="#ffffcc">
<элемента tbody><тр> <тд> Типсильные>
В TExpandingRecord = класс(TComponent)в
тд>р><р класса="step_content "> тр>р><р класса="step_content "> элемента tbody>Таблица>р><р класса="step_content "> Шаг 2: создать свойство редакторе, например так
<границы таблицы="1" Ширина="100%"для bgcolor="#ffffcc">
<элемента tbody><тр> <тд> Типсильные>
В TExpandingRecordProperty = класс(TClassProperty)
общественныесильные>
функция для запроса getattributes : TPropertyAttributes переопределитьСтронг>
конецсильные> тд>тр>элемента tbody>Таблица>р><р класса="step_content "> процедура зарегистрировать р><р класса="step_content "> для реализациивр><р класса="step_content "> порядок в реестре
начатьсильные>
В RegisterComponents(<шрифта цвет="синий">'статьи'шрифт>, [TExpandingComponent])
В RegisterPropertyEditor(typeinfo в(TExpandingRecord), Нил, в <шрифта цвет="синий">"шрифт>, TExpandingRecordProperty)
конец в р><р класса="step_content "> <ем><шрифта цвет="синий">{ TExpandingRecordProperty }шрифт>ем>р><р класса="step_content "> функция в TExpandingRecordProperty.Методы getattributes: TPropertyAttributes
начатьсильные>
В результате := [paReadOnly, paSubProperties]
и на конецсильные>
и р><р класса="step_content "> р><р класса="step_content "> р><р класса="step_content "> Шаг 3 в: снять RegisterComponents звонок из компонентов блока, и зарегистрировать его в блок вместо редактора. Таким образом мы можем гарантировать, что компонент не будет зарегистрирован без компонента.р><р класса="step_content "> теперь наша собственность Тип TExpandingRecord покажет как расширение собственность (за счет США, возвращающиеся paSubProperties из getattributes), и по умолчанию редактор для TCollection будет работать как владелец TCollection собственность является TComponent.р><р класса="step_content "> диалоговое окно "свойства" редакторов
В большинстве случаев, при создании пользовательского свойства редактора, цель-обеспечить графическое средство взаимодействия с администрацией.р><р класса="step_content "> это первый пример очень простой способ, позволяющий пользователю ввести несколько строк в "Заголовок" свойства названия. Хотя этот пример не очень сложная, она демонстрирует, как включить форму в редакторе.р><р класса="step_content "> Шаг 1:сильные>
и выберите файл, новое приложение из главного меню. Это позволит создать формы, название формы "fmLabelEdit", добавить Тметь в форме имени memCaption. Добавить две кнопки: "ОК" и "отмена" с свойства ModalResult значение mrCancel и сделаны соответственно.р><р класса="step_content "> Шаг 2:сильные>
и добавить DsgnIntf и TypInfo в своих целях пункт.р><р класса="step_content ">
р><р класса="step_content "> Шаг 3:сильные>
и добавьте следующее свойство редактора кода для Вашего аппарата.р><р класса="step_content "><границы таблицы="1" Ширина="100%" bgcolor в="#ffffcc">
<элемента tbody><тр> <тд> TCaptionProperty = класс(TStringProperty)
общественныесильные>
функция для запроса getattributes: TPropertyAttributes переопределитьСтронг>
процедура изменить на переопределитьСтронг>
конецсильные>
и ир><р класса="step_content "> тр>р><р класса="step_content "> элемента tbody>Таблица>р><р класса="step_content "> И реестр редакторе свойств как так
<границы таблицы="1" Ширина="100%"для bgcolor="#ffffcc">
<элемента tbody><тр> <тд> процедура зарегистрировать р><р класса="step_content "> для реализациисильные>
на <цвет шрифта="#000080"><ем>{$Р *.ДФМ}ем>шрифт>р><р класса="step_content "> порядок для регистрации
и начатьсильные>
В RegisterPropertyEditor(typeinfo в(TCaption), названия, 'Заголовок', TCaptionProperty)
конецсильные>
и ир><р класса="step_content "> тр>р><р класса="step_content "> элемента tbody>Таблица>р><р класса="step_content "> Шаг 4:сильные>
и добавьте следующий код для того, чтобы инспектор объектов для отображения [...] кнопку "Редактировать" после имени свойства.р><р класса="step_content "><границы таблицы="1" Ширина="100%" bgcolor в="#ffffcc">
<элемента tbody><тр> <тд> функция в TCaptionProperty.Методы getattributes: TPropertyAttributes
начатьсильные>
В результате := наследство для запроса getattributes [paDialog]
конецсильные>
и ир><р класса="step_content "> тр>р><р класса="step_content "> элемента tbody>Таблица>р><р класса="step_content "> Шаг 5:сильные>
и наконец, мы создаем экземпляр нашего редактора форм, установить содержание памятки для текущего субтитра, а затем показать форму модально.р><р класса="step_content "><границы таблицы="1" Ширина="100%" bgcolor в="#ffffcc">
<элемента tbody><тр> <тд> порядок в TCaptionProperty.Редактировать
варсильные>
я: целое число
начатьСтронг>
с TfmLabelEdit.Создание(применение) на усильные>
и попробоватьсильные>
В memCaption.Линии.Текст := GetStrValue
ShowModal
<див класс='embed_block_0'> <див ИД="блок-google_admanager-1" класса="блок блок-google_admanager области-другие области-количество-1 Количество-1 блок-Без названия "> <див класс="блок-топ">див> <див класс="блок-внутренний"> <див класс="содержание"> див> <див класс="блок-дно">див> див> див> див><див класс='embed_block_1'><див>див>див>
<ем><шрифта цвет="синий">{если ModalResult формы сделаны, нужно установить "подпись" собственность каждого названия.}шрифт>на сайтер><р класса="step_content "> если в ModalResult = сделаны на тогдаСтронг>
<Стронг>длясильная> я:=0 на в PropCount-1 на усильные>
Без названия(то getcomponent(я)).Заголовок := memCaption.Линии.Текст
в итогеСтронг>
бесплатные
в концеСтронг>
конецсильные>
и ир><р класса="step_content "> тр>р><р класса="step_content "> элемента tbody>Таблица>р><р класса="step_content "> шаг 6:сильные>
и установить блок в пакет, а затем опробовать новый редактор !р><р класса="step_content "> расширенные редакторы свойств
и всем, кто когда-либо использовал TActionList или над tdataset (таблицы / восстановить) будет иметь опыт в следующем примере, возможно, даже не осознавая.р><р класса="step_content "> в ActionList редактор, очевидно, настраиваемый редактор, так как позволяет группировать действия, в то время как в FieldsEditor над tdataset может показаться на первый взгляд как стандартный редактор, но при ближайшем рассмотрении можно вызвать всплывающее меню с пунктами, такими как "добавить поля". Однако, наиболее примечательной особенностью обоих этих редакторов не в том, что они являются пользовательские диалоговые редакторы (аналогично тому, как мы уже говорили), но то, что элементы, которые они создают включены в состав основных класса текущего блока.р><р класса="step_content "><границы таблицы="1" Ширина="100%" bgcolor в="#ffffcc">
<элемента tbody><тр> <тд> ТипСтронг>
TForm1 = класс(TForm)
В ActionList1: TActionList
В Действие1: Осязательных
В Действие2: Осязательных
ЧастнаяСтронг>
<ем><шрифта цвет="синий">{ частные объявления }шрифт>ем>
общественныесильные>
<ем><шрифта цвет="синий">{ публичных заявлений }шрифт>ем>
конецсильные>
и ир><р класса="step_content "> тр>р><р класса="step_content "> элемента tbody>Таблица>р><р класса="step_content "> преимущество этого заключается в том, что язь, знают об этих элементов, таким образом, позволяя им быть выбран из списка предметов, когда собственность компонента требует от них.р><р класса="step_content ">
р><р класса="step_content "> на рисунке выше, два действия будут добавлены в TActionList, нажав кнопку "действие" свойства кнопки button1 показывает список, состоящий из действий, добавил. Эти два действия также добавил в объявление класса формы, и, следовательно, может быть упомянут по имени (Действие1, Действие2).р><р класса="step_content "> хитрость тут лежит целиком в редакторе свойств, а не в компоненте. Когда редактор свойств срабатывает (т. е. метод редактирования называется) отель содержит действительную ссылку на IFormDesigner (TFormDesigner в Delphi 4). Многие функции этого интерфейса не входит в рамки этой статьи, если вы хотите узнать больше о возможностях этого интерфейса я бы порекомендовал книгу Справочник Дельфи разработчика Марко Канту.р><р класса="step_content "> некоторые методы включают в себяр><р класса="step_content "><границы таблицы="1" Ширина="100%" bgcolor в="#ffffcc">
<элемента tbody><тр> <тд> функция в MethodExists(константный Название: в строку): Логическое
порядок в RenameMethod(константный в CurName, Newназвание: строка в)
порядок в SelectComponent(пример: компонент)
порядок в ShowMethod(константный Название: в строку)
функция в то getcomponent(константный Название: в строку): TComponent
функция в CreateComponent(ComponentClass: TComponentClass родителей: TComponent слева, сверху, ширина, высота: целое число): TComponent и
тд>р><р класса="step_content "> тр>р><р класса="step_content "> элемента tbody>Таблица>р><р класса="step_content "> некоторые из перечисленных выше звонков довольно элементарно, MethodExists например будет возвращать True или false в зависимости от того, является ли способ именем уже существует в виде текущей части (FormCreate, Button1Click и т. д.). ShowMethod переместит курсор к имени метода, и RenameMethod будет изменить имя метода.р><р класса="step_content "> два метода, которые представляют интерес для использования на данный момент являются:
CreateComponentсильные>
и учитывая, компонент, класс, родитель, чтобы содержать компонент, и позиция / размеры, дизайнер будет создавать экземпляр класса, А В случае, если застройщик выбрал его из палитры компонентов и добавили ее к форма себе.р><р класса="step_content "> измененсильные>
как сообщает дизайнер, что что-то было изменено (недвижимость и т. д.). Это изменяет состояние блока, так что IDE знает, что он должен быть сохранен до закрытия (он также позволяет сохранить кнопка в IDE).р><р класса="step_content "> при добавлении элементов в нашем массиве все мы должны сделать, чтобы получить TMyProperty.Конструктор для создания компонента от нашего имени. Тогда этот компонент будет добавлен к форме и любое имущество, которое относится к классу этого типа автоматически будет знать об этом. В случае TActionList и над tdataset компоненты, которые добавляются в форме не видны во время разработки, владелец компонент выступает в качестве своеобразного "диспетчера" для компонентов.р><р класса="step_content "> во время разработки Вы не увидите осязания или TField компонент на палитру компонент, который, возможно, заставит вас подозревать, что они не зарегистрированы, но язь все еще в состоянии создавать экземпляры этих компонентов (и их тоже не видно). Ответ не в том, что они не зарегистрированы, такое поведение является результатом "как" компонент Зарегистрирован.р><р класса="step_content "> в то время как RegisterComponents будет добавить свои компоненты с палитры компонентов, в RegisterNoIcon способ зарегистрировать свой компонент, не добавив его в палитру компонент, регистрация в этом случае также говорит в IDE, что компонент не будет отображаться во время разработки.р><р класса="step_content "> в следующем примере мы создадим компонент, называемый TWavSound (дополнительный компонент, называемый TWavButton включен в исходный код, прилагаемый к данной статье в качестве примера). TWavSound просто хранить данные из WAV-файл, и воспроизведения звука на спрос. Хотя это было бы просто для нас, чтобы бросить один TWavSound на нашей форме для каждого WAV-файла мы требуем, наша форма вскоре может стать неуправляемой, поэтому мы будем создавать класс, менеджер позвонил TWavList.р><р класса="step_content ">
р><р класса="step_content "> каждый метод, используемый в исходный код для этих компонентов была освещена во второй части этой серии статей, так что исходный код не распространяется на любой большой уровень детализации. Тем не менее, я покажу классе деклараций этих компонентов, просто чтобы дать вам представление о том, как они структурированы.р><р класса="step_content "> <ем>Примечание: в нижней части блока, в секции инициализации устройства вы можете заметить следующий код:ем>р><р класса="step_content "> инициализациисильные>
и непредвиденное registerclass(TWavSound) р><р класса="step_content "> причина в том, что RegisterNoIcon не полную работу. Хотя это позволяет нам создавать экземпляры зарегистрированные от нашего редактора собственность что-то, кажется, идет не так, когда проект повторно загружены, содержащих эти компоненты. "Класс не зарегистрирован" отображается окно сообщения и проект поврежден. Кроме того, зарегистрировавшись класс таким образом, кажется, чтобы исправить проблему,
TWavSoundр><р класса="step_content "><границы таблицы="1" Ширина="100%"для bgcolor="#ffffcc">
<элемента tbody><тр> <тд> Типсильные>
В PWavData = ^TWavData
В TWavData = упакованныесильная> записьСтронг>
Размер: добавлены типы longint
для сведения: массивсильная>[0..0] на с байт
конец в р><р класса="step_content "> TWavSound = класс(TComponent)
Частнаясильные>
В FWavData: PWavData
В FWav: TWav
порядок в ReadWavData(трансляция: TStream)
порядок в WriteWavData(трансляция: TStream)
защищеныСтронг>
порядок в DefineProperties(filer и: TFiler) переопределитьСтронг>
общественныесильные>
и деструктор уничтожить переопределитьСтронг>
порядок это понятно
и процедура LoadFromFile(константный в именем: TFilename)
процедура LoadFromStream(трансляция: TStream)
порядок для игры
опубликованСтронг>
конецсильные>
и ир><р класса="step_content "> тр>р><р класса="step_content "> элемента tbody>Таблица>р><р класса="step_content "> FWavData
и будет использоваться для хранения содержимого WAV-файла после загрузки из потока или файла.р><р класса="step_content "> очиститьсильные>
будет освободить память держит FWavData.р><р класса="step_content "> игратьсильные>
будет использовать не sndplaysound вызова API в MMSystem.ССА т
Компонент письменной форме, часть 3
Компонент письменной форме, часть 3 : Несколько тысяч советов, которые сделают вашу жизнь проще.
эта статья является заключительной из трех частей статьи на компоненты. Эта заключительная часть будет охватывать собственность / редакторы компонент, как написать специальную редакцию для компонент / свойство, и как пишут "скрытые" компоненты.р><р класса="step_content ">
<границы таблицы="1"><элемента tbody><тр><тд> эта статья первоначально появилась в Delphi разработчикатд>тр>элемента tbody>Таблица>р><р класса="step_content "> Авторское право шедевре издание, Инк. Все права защищены. р> <р класса="step_content "> пользовательские редакторы компонентов
и как только мы начинаем писать дополнительные типы свойств для нашего компонентов, жизнь становится немного сложнее. Хотя инспекторе объектов, встроенная в Delphi способна распознавать большинство типов недвижимости, это невозможно, чтобы быть в состоянии иметь дело со всеми возможными пользовательский Тип мы можем писать в наших компонентов. Иногда инспекторе объектов не может справиться с нашими пользовательских типов, но монтаж такого сложного комплекса свойств в инспекторе объектов просто не достаточно понятный. Именно в этот момент мы можем быть обязаны писать собственность / редакторы компонентов. Делфи уже множество стандартных редакторов, эти редакторы в DsgnIntf.файл ССА в $(Делфи)\Источник\ToolsAPI каталог. Вам будет нужно список это устройство в использования пункт любого компонента редактор / редактор свойств можно написать, это также хорошая идея, чтобы держать этот файл открытым для справки, когда пишу свои собственные редакторы.р><р класса="step_content "> стандарты кодирования
для начала я расскажу о некоторых стандартов кодирования, которые используются при написании компонента или редакторы свойств. Есть только несколько, но это будет хорошая идея, чтобы придерживаться этих стандартов при написании вашего собственного редакторы, как это делает его легче для других людей, чтобы понять вашу работу.р><р класса="step_content ">
- при создании свойство редактора, закончить имя своего редактора со словом "собственность" например <ЭМ>TAnglePropertyем>
р><р класса="step_content "> - после создания компонента редактор, конец имя редактора со словом "редактор" например <ЭМ>TPieChartEditorем>
р><р класса="step_content "> - когда пишут редакторы, всегда пишу редактор в отдельный блок с вашей фактической составляющей. Это хорошо, чтобы отделить время разработки и во время выполнения кода и, помимо этого, это делает ваш получившийся exe Размер меньше (по некоторым версиям Delphi компонент может останавливать приложения от компиляции, если Вы не разделите их). Кроме того, отдельные пакеты, так что ваши пользователи могут строить с пакетами времени выполнения, если они хотят !
р><р класса="step_content "> - если имя вашего редактора блок с тем же именем, как составляющая единица, но добавить слово "рег" в конце например, компонент с группой название "компонент mycomponent.паск" приведет в редакторе именем быть "MyComponentreg.паск"
р><р класса="step_content "> - если при написании компонента редактор / Editor свойство для компонента, переместите ваш RegisterComponentsем> выписка из компонента, который и в код компонента редактора блока. Таким образом, ваш компонент не будет зарегистрирован без редактора и регистрации.
р><р класса="step_content ">
Р><Р класса="step_content "> свойство редактора
в собственность редакторы используются IDE, чтобы специальный редактирование отдельных свойств в компоненте. Некоторые редакторы очень просты, некоторые из них гораздо сложнее. Делфи уже есть несколько стандартных редакторов свойств, некоторые из них являются:
TIntegerProperty. Используется для ввода чисел.р><р класса="step_content "> TCharProperty. Используется для ввода одного символа.р><р класса="step_content "> TEnumProperty. Используется для выбора отдельных элементов перечислимого типа (алтоп, alClient и т. д.). <их>TBoolPropertyем>. Используется для выбора значения "True" или "false" для логических свойств.р><р класса="step_content "> TFloatProperty. Используется для ввода чисел с плавающей точкой (переменная типа float / Расширенная и т. д. "Реального" типа не следует использовать для свойства компонента).р><р класса="step_content "> TStringProperty. Используется для ввода строки до 255 символов.р><р класса="step_content "> TSetProperty. Используется для включения / исключения отдельных элементов из набора собственность. Каждый элемент отображается как логический подсвойства. Установив значение в "True" включает в себя элемент, устанавливая его в "false" исключает его.р><р класса="step_content "> TClassProperty. Это базовый класс для спуска, когда вы хотите создать пользовательский редактор, который будет вызван для свойства определенного класса (когда у вас есть Класс как свойство, например, TImage.Рисунок).р><р класса="step_content "> все эти редакторы свойств спускаются прямо или косвенно от TPropertyEditor. TPropertyEditor имеет много свойств и методов, наиболее значимыми являются.р><р класса="step_content "><границы таблицы="1" Ширина="100%" bgcolor в="#ffffcc">
<элемента tbody><тр> <тд> функция в AllEqual: логическое виртуальныеСтронг>
функция для запроса getattributes: TPropertyAttributes виртуальныеСтронг>
процедура изменить на виртуальныеСтронг>
функция Думою: строкасильная> виртуальныеСтронг>
процедура GetValues(прок: TGetStrProc) виртуальныесильные>
и ир><р класса="step_content "> тр>р><р класса="step_content "> элемента tbody>Таблица>р><р класса="step_content "> AllEqualСтронг>
Если выбрано несколько компонентов, инспектором объекта фильтрует список свойств только те, что все выбранные компоненты имеют в общем. Если значение в каждой компоненте для любого заданного свойства (например, Ширина) одинаковы, то значение будет отображаться, в противном случае значение не будет отображаться. AllEqual-это процедура, которая определяет, является ли каждое значение является идентичным.р><р класса="step_content "><границы таблицы="1" Ширина="100%" bgcolor в="#ffffcc">
<элемента tbody><тр> <тд> функция в TStringProperty.AllEqual: логическое
варсильные>
я: целое число
в: строкаСтронг>
начатьсильные>
как результат := ложь
В если в PropCount > 1 на тогдаСтронг>
начатьсильные>
и в := GetStrValue
длясильная> я := 1 на в PropCount - 1 на усильные>
В если в GetStrValueAt(я) <> в тогда для выезда в
в концесильные>
В результате := Правда
конецсильные>
и ир><р класса="step_content "> тр>р><р класса="step_content "> элемента tbody>Таблица>р><р класса="step_content "> в приведенном выше примере TStringProperty сравнивает каждое значение (используя GetStrValueAt) со значением первого компонента в списке (используя GetStrValue, GetStrValueAt(0) сделал бы то же самое). Размер списка определяется с помощью PropCount, это возвращает общее количество выбранных компонентов.р><р класса="step_content "> методы getattributesсильные>
и методы getattributes называется средой разработки, когда он должен собрать сведения о редакторе собственность. Инспектор объектов отображает соответствующий редактор, основанный на информации, предоставленной. Результат запроса getattributes (TPropertyAttributes) - это набор, поэтому может содержать комбинацию следующих значений (это не полный список)
тег в paDialogсильные>
как сообщает инспектор объектов, чтобы показать [...] после имени свойства, когда пользователь нажимает на эту кнопку изменить способ срабатывает.элемент blockquote>р><р класса="step_content "> paSubPropertiesсильные>
как сообщает инспектор объектов, чтобы показать [ ] кнопка перед свойство "имя", при нажатии этой кнопки показать расширенный список дополнительных свойств (как правило опубликованных свойств свойство класса).р><р класса="step_content "> paValueListсильные>
В инспекторе объектов появится выпадающий список значений, в этом списке определяется в IDE с помощью вызова метода GetValues.
<ем>Примечание: GetValues метод, а не метод getvalue, который полностью отличается от на сайтер><р класса="step_content "> paSortListсильные>
если в сочетании с paValueList, значения будут отсортированы в алфавитном порядке.р><р класса="step_content "> paMultiSelectсильные>
при этом указывает, что язь, что собственность будет отображаться при выборе нескольких компонентов. Этот пункт не является для редакторов такого TClassProperty.р><р класса="step_content "> paAutoUpdateСтронг>
вызывает метод setvalue метод, который должен вызываться каждый раз, когда значение изменяется в инспекторе объектов, а не ждал нажатия или изменить другого свойства. Это используется для "Заголовок" и "текст" свойств, чтобы дать прямую представления значения, введенные пользователем.р><р класса="step_content "> paReadOnlyсильные>
если этот элемент включен значение в инспекторе объект только для чтения. Это обычно используется в сочетании с paDialog. Думою будет переопределен для возврата описательное представление свойств. р><р класса="step_content "> редактироватьсильные>
этот метод вызывается при нажатии на кнопку [...] для свойства. Эта кнопка отображается, если элемент paDialog включается в результат запроса getattributes.р><р класса="step_content "> Думоюсильные>
этот метод вызывается, когда объект инспектор должен знать, как отобразить объект в виде строки. Это обычно используется, когда [paDialog, paReadOnly] определены в результате запроса getattributes.р><р класса="step_content "> GetValuesсильные>
этот метод вызывается при инспекторе объектов необходимо получить список значений для отображения, когда paValueList определяется в результате запроса getattributes. GetValues передает параметр под названием "прок", которая является TGetStrProc типа. GetStrProc объявлен TGetStrProc = процедура(константный ы: строкав) для объекта в р><р класса="step_content "> в IDE ожидает "прок" будет вызываться один раз для каждого значения, которые должны отображаться в инспекторе объектов это свойство.р><р класса="step_content "><границы таблицы="1" Ширина="100%" bgcolor в="#ffffcc">
<элемента tbody><тр> <тд> порядок в THintProperty.GetValues(прок: TGetStrProc)
начатьсильные>
В прок('первый элемент, чтобы отобразить')
В прок('второй элемент, чтобы отобразить')
конецсильные>
и ир><р класса="step_content "> тр>р><р класса="step_content "> элемента tbody>Таблица>р><р класса="step_content "> в следующем примере показано, как задать список значений по умолчанию для "Подсказка" свойства всех компонентов, в то же время позволяя пользователю ввести значение не в списке.р><р класса="step_content "><границы таблицы="1" Ширина="100%" bgcolor в="#ffffcc">
<элемента tbody><тр> <тд> Типсильные>
В THintProperty = класс(TStringProperty)
общественныесильные>
функция для запроса getattributes: TPropertyAttributes переопределитьСтронг>
процедура GetValues(прок: TGetStrProc) переопределитьСтронг>
конец в р><р класса="step_content "> процедура зарегистрировать р><р класса="step_content "> для реализациивр><р класса="step_content "> порядок в реестре
начатьсильные>
В RegisterPropertyEditor(Объект typeinfo(строка), Нил, в <шрифта цвет="синий"> "Подсказка" шрифт>, THintProperty)
конец в р><р класса="step_content "> <ем><шрифта цвет="синий">{ THintProperty }шрифт>ем>р><р класса="step_content "> функция в THintProperty.Методы getattributes: TPropertyAttributes
начатьсильные>
В результате := наследство для запроса getattributes [paValueList, paSortList]
и на конец в р><р класса="step_content "> порядок в THintProperty.GetValues(прок: TGetStrProc)
начатьсильные>
В прок(<шрифта цвет="синий">'это-обязательный параметр'шрифт>)
В прок(<шрифта цвет="синий">'Нажмите клавишу F1 для получения дополнительной информациишрифт>)
В прок(<шрифта цвет="синий">', это значение является только для чтения'шрифт>)
конецсильные>
и ир><р класса="step_content "> тр>р><р класса="step_content "> элемента tbody>Таблица>р><р класса="step_content "> первые методы getattributes переопределяется, и [paValueList, paSortList] включены в результат. Далее GetValues переопределяется и добавляются в выпадающий список по телефону "прок" порядка трех значений.р><р класса="step_content "> Регистрация собственности редакторов
и, наконец, свойство редактора Зарегистрирован через RegisterPropertyEditor. RegisterPropertyEditor принимает четыре параметра:р><р класса="step_content "> PropertyType: PTypeInfoсильные>
не требует указатель на TTypeInfo записи. Это звучит гораздо сложнее, чем есть на самом деле, все, что нам нужно сделать, это добавить TypInfo на использование пункта, и использовать функцию объект typeinfo для получения указателя для нас. Объект typeinfo(SomeVariableType)р><р класса="step_content "> ComponentClass: TClassсильные>
это базовый класс, что этот редактор должен обратиться. Редактор будет применить для этого класса и классов, которые происходят от нее. Если указан ноль, этот редактор будет применяться к любому классу.р><р класса="step_content "> константный Имя_свойства: строкасильные>
если этот редактор должен применяться только в отношении конкретного имущества, то имя свойства должно быть указано здесь. Если редактор должен обратиться к любому свойству типа, указанного в PropertyType это значение должно быть ".р><р класса="step_content "> EditorClass: TPropertyEditorClassсильные>
это класс, который был создан для борьбы с администрацией. В приведенном выше примере класс THintProperty.р><р класса="step_content "> используя RegisterPropertyEditor неправильно
это важно при использовании RegisterPropertyEditor, что вы предоставляете правильные сведения. Поставлять неверную информацию, может означать, что либо ваш редактор влияет на ошибочные свойства (например, все строковые свойства) или неправильные компоненты.р><р класса="step_content "> другая крайность, настройка параметров неправильно может означать, что только определенное имущество на определенный компонент (и их потомков) - это связано с редактором. Это не кажется большой проблемой на первый, но компоненты потомок, возможно, пожелают внедрить дополнительные свойства одинакового типа. Как эти свойства, очевидно, будет иметь другое имя, они не имеют правильного свойство редактора, возложенные на них.р><р класса="step_content "> пример плохо зарегистрированы редактор уже существует в в VCL. Стандартный редактор для TCollection было зарегистрировано для всех классов произошли от TComponent. Проблема в том, что низший класс может быть отображается в инспекторе объект компонент (класс TComponent, который спускается с).р><р класса="step_content "> если компонент имеет свойство типа компонент (который по умолчанию выставляет свои подсвойства в разворачиваемом списке), и одно из его свойств-это типа TCollection, в результате [...] кнопку в инспекторе объектов, который ничего не делает при нажатии (как мы видели во второй части этой серии статей).р><р класса="step_content "> решение этой проблемы кажется достаточно простым. А не наши суб-свойства произошли от компонент, мы могли бы спуститься от TComponent, а не. Однако, поведение по умолчанию для свойства типа TComponent (как определено редактор свойств редактор TComponentProperty) - Показать список других компонентов, а не суб-свойства встроенного компонента.р><р класса="step_content "> собственно решение очень простое, но только если вы знаете как написать редактор свойств.р><р класса="step_content "> Шаг 1в:
<границы таблицы="1" Ширина="100%" bgcolor в="#ffffcc">
<элемента tbody><тр> <тд> Типсильные>
В TExpandingRecord = класс(компонент)в
тд>р><р класса="step_content "> тр>р><р класса="step_content "> элемента tbody>Таблица>р><р класса="step_content "> было изменено на
<границы таблицы="1" Ширина="100%"для bgcolor="#ffffcc">
<элемента tbody><тр> <тд> Типсильные>
В TExpandingRecord = класс(TComponent)в
тд>р><р класса="step_content "> тр>р><р класса="step_content "> элемента tbody>Таблица>р><р класса="step_content "> Шаг 2: создать свойство редакторе, например так
<границы таблицы="1" Ширина="100%"для bgcolor="#ffffcc">
<элемента tbody><тр> <тд> Типсильные>
В TExpandingRecordProperty = класс(TClassProperty)
общественныесильные>
функция для запроса getattributes : TPropertyAttributes переопределитьСтронг>
конецсильные> тд>тр>элемента tbody>Таблица>р><р класса="step_content "> процедура зарегистрировать р><р класса="step_content "> для реализациивр><р класса="step_content "> порядок в реестре
начатьсильные>
В RegisterComponents(<шрифта цвет="синий">'статьи'шрифт>, [TExpandingComponent])
В RegisterPropertyEditor(typeinfo в(TExpandingRecord), Нил, в <шрифта цвет="синий">"шрифт>, TExpandingRecordProperty)
конец в р><р класса="step_content "> <ем><шрифта цвет="синий">{ TExpandingRecordProperty }шрифт>ем>р><р класса="step_content "> функция в TExpandingRecordProperty.Методы getattributes: TPropertyAttributes
начатьсильные>
В результате := [paReadOnly, paSubProperties]
и на конецсильные>
и р><р класса="step_content "> р><р класса="step_content "> р><р класса="step_content "> Шаг 3 в: снять RegisterComponents звонок из компонентов блока, и зарегистрировать его в блок вместо редактора. Таким образом мы можем гарантировать, что компонент не будет зарегистрирован без компонента.р><р класса="step_content "> теперь наша собственность Тип TExpandingRecord покажет как расширение собственность (за счет США, возвращающиеся paSubProperties из getattributes), и по умолчанию редактор для TCollection будет работать как владелец TCollection собственность является TComponent.р><р класса="step_content "> диалоговое окно "свойства" редакторов
В большинстве случаев, при создании пользовательского свойства редактора, цель-обеспечить графическое средство взаимодействия с администрацией.р><р класса="step_content "> это первый пример очень простой способ, позволяющий пользователю ввести несколько строк в "Заголовок" свойства названия. Хотя этот пример не очень сложная, она демонстрирует, как включить форму в редакторе.р><р класса="step_content "> Шаг 1:сильные>
и выберите файл, новое приложение из главного меню. Это позволит создать формы, название формы "fmLabelEdit", добавить Тметь в форме имени memCaption. Добавить две кнопки: "ОК" и "отмена" с свойства ModalResult значение mrCancel и сделаны соответственно.р><р класса="step_content "> Шаг 2:сильные>
и добавить DsgnIntf и TypInfo в своих целях пункт.р><р класса="step_content ">
р><р класса="step_content "> Шаг 3:сильные>
и добавьте следующее свойство редактора кода для Вашего аппарата.р><р класса="step_content "><границы таблицы="1" Ширина="100%" bgcolor в="#ffffcc">
<элемента tbody><тр> <тд> TCaptionProperty = класс(TStringProperty)
общественныесильные>
функция для запроса getattributes: TPropertyAttributes переопределитьСтронг>
процедура изменить на переопределитьСтронг>
конецсильные>
и ир><р класса="step_content "> тр>р><р класса="step_content "> элемента tbody>Таблица>р><р класса="step_content "> И реестр редакторе свойств как так
<границы таблицы="1" Ширина="100%"для bgcolor="#ffffcc">
<элемента tbody><тр> <тд> процедура зарегистрировать р><р класса="step_content "> для реализациисильные>
на <цвет шрифта="#000080"><ем>{$Р *.ДФМ}ем>шрифт>р><р класса="step_content "> порядок для регистрации
и начатьсильные>
В RegisterPropertyEditor(typeinfo в(TCaption), названия, 'Заголовок', TCaptionProperty)
конецсильные>
и ир><р класса="step_content "> тр>р><р класса="step_content "> элемента tbody>Таблица>р><р класса="step_content "> Шаг 4:сильные>
и добавьте следующий код для того, чтобы инспектор объектов для отображения [...] кнопку "Редактировать" после имени свойства.р><р класса="step_content "><границы таблицы="1" Ширина="100%" bgcolor в="#ffffcc">
<элемента tbody><тр> <тд> функция в TCaptionProperty.Методы getattributes: TPropertyAttributes
начатьсильные>
В результате := наследство для запроса getattributes [paDialog]
конецсильные>
и ир><р класса="step_content "> тр>р><р класса="step_content "> элемента tbody>Таблица>р><р класса="step_content "> Шаг 5:сильные>
и наконец, мы создаем экземпляр нашего редактора форм, установить содержание памятки для текущего субтитра, а затем показать форму модально.р><р класса="step_content "><границы таблицы="1" Ширина="100%" bgcolor в="#ffffcc">
<элемента tbody><тр> <тд> порядок в TCaptionProperty.Редактировать
варсильные>
я: целое число
начатьСтронг>
с TfmLabelEdit.Создание(применение) на усильные>
и попробоватьсильные>
В memCaption.Линии.Текст := GetStrValue
ShowModal
<див класс='embed_block_0'> <див ИД="блок-google_admanager-1" класса="блок блок-google_admanager области-другие области-количество-1 Количество-1 блок-Без названия "> <див класс="блок-топ">див> <див класс="блок-внутренний"> <див класс="содержание"> див> <див класс="блок-дно">див> див> див> див><див класс='embed_block_1'><див>див>див>
<ем><шрифта цвет="синий">{если ModalResult формы сделаны, нужно установить "подпись" собственность каждого названия.}шрифт>на сайтер><р класса="step_content "> если в ModalResult = сделаны на тогдаСтронг>
<Стронг>длясильная> я:=0 на в PropCount-1 на усильные>
Без названия(то getcomponent(я)).Заголовок := memCaption.Линии.Текст
в итогеСтронг>
бесплатные
в концеСтронг>
конецсильные>
и ир><р класса="step_content "> тр>р><р класса="step_content "> элемента tbody>Таблица>р><р класса="step_content "> шаг 6:сильные>
и установить блок в пакет, а затем опробовать новый редактор !р><р класса="step_content "> расширенные редакторы свойств
и всем, кто когда-либо использовал TActionList или над tdataset (таблицы / восстановить) будет иметь опыт в следующем примере, возможно, даже не осознавая.р><р класса="step_content "> в ActionList редактор, очевидно, настраиваемый редактор, так как позволяет группировать действия, в то время как в FieldsEditor над tdataset может показаться на первый взгляд как стандартный редактор, но при ближайшем рассмотрении можно вызвать всплывающее меню с пунктами, такими как "добавить поля". Однако, наиболее примечательной особенностью обоих этих редакторов не в том, что они являются пользовательские диалоговые редакторы (аналогично тому, как мы уже говорили), но то, что элементы, которые они создают включены в состав основных класса текущего блока.р><р класса="step_content "><границы таблицы="1" Ширина="100%" bgcolor в="#ffffcc">
<элемента tbody><тр> <тд> ТипСтронг>
TForm1 = класс(TForm)
В ActionList1: TActionList
В Действие1: Осязательных
В Действие2: Осязательных
ЧастнаяСтронг>
<ем><шрифта цвет="синий">{ частные объявления }шрифт>ем>
общественныесильные>
<ем><шрифта цвет="синий">{ публичных заявлений }шрифт>ем>
конецсильные>
и ир><р класса="step_content "> тр>р><р класса="step_content "> элемента tbody>Таблица>р><р класса="step_content "> преимущество этого заключается в том, что язь, знают об этих элементов, таким образом, позволяя им быть выбран из списка предметов, когда собственность компонента требует от них.р><р класса="step_content ">
р><р класса="step_content "> на рисунке выше, два действия будут добавлены в TActionList, нажав кнопку "действие" свойства кнопки button1 показывает список, состоящий из действий, добавил. Эти два действия также добавил в объявление класса формы, и, следовательно, может быть упомянут по имени (Действие1, Действие2).р><р класса="step_content "> хитрость тут лежит целиком в редакторе свойств, а не в компоненте. Когда редактор свойств срабатывает (т. е. метод редактирования называется) отель содержит действительную ссылку на IFormDesigner (TFormDesigner в Delphi 4). Многие функции этого интерфейса не входит в рамки этой статьи, если вы хотите узнать больше о возможностях этого интерфейса я бы порекомендовал книгу Справочник Дельфи разработчика Марко Канту.р><р класса="step_content "> некоторые методы включают в себяр><р класса="step_content "><границы таблицы="1" Ширина="100%" bgcolor в="#ffffcc">
<элемента tbody><тр> <тд> функция в MethodExists(константный Название: в строку): Логическое
порядок в RenameMethod(константный в CurName, Newназвание: строка в)
порядок в SelectComponent(пример: компонент)
порядок в ShowMethod(константный Название: в строку)
функция в то getcomponent(константный Название: в строку): TComponent
функция в CreateComponent(ComponentClass: TComponentClass родителей: TComponent слева, сверху, ширина, высота: целое число): TComponent и
тд>р><р класса="step_content "> тр>р><р класса="step_content "> элемента tbody>Таблица>р><р класса="step_content "> некоторые из перечисленных выше звонков довольно элементарно, MethodExists например будет возвращать True или false в зависимости от того, является ли способ именем уже существует в виде текущей части (FormCreate, Button1Click и т. д.). ShowMethod переместит курсор к имени метода, и RenameMethod будет изменить имя метода.р><р класса="step_content "> два метода, которые представляют интерес для использования на данный момент являются:
CreateComponentсильные>
и учитывая, компонент, класс, родитель, чтобы содержать компонент, и позиция / размеры, дизайнер будет создавать экземпляр класса, А В случае, если застройщик выбрал его из палитры компонентов и добавили ее к форма себе.р><р класса="step_content "> измененсильные>
как сообщает дизайнер, что что-то было изменено (недвижимость и т. д.). Это изменяет состояние блока, так что IDE знает, что он должен быть сохранен до закрытия (он также позволяет сохранить кнопка в IDE).р><р класса="step_content "> при добавлении элементов в нашем массиве все мы должны сделать, чтобы получить TMyProperty.Конструктор для создания компонента от нашего имени. Тогда этот компонент будет добавлен к форме и любое имущество, которое относится к классу этого типа автоматически будет знать об этом. В случае TActionList и над tdataset компоненты, которые добавляются в форме не видны во время разработки, владелец компонент выступает в качестве своеобразного "диспетчера" для компонентов.р><р класса="step_content "> во время разработки Вы не увидите осязания или TField компонент на палитру компонент, который, возможно, заставит вас подозревать, что они не зарегистрированы, но язь все еще в состоянии создавать экземпляры этих компонентов (и их тоже не видно). Ответ не в том, что они не зарегистрированы, такое поведение является результатом "как" компонент Зарегистрирован.р><р класса="step_content "> в то время как RegisterComponents будет добавить свои компоненты с палитры компонентов, в RegisterNoIcon способ зарегистрировать свой компонент, не добавив его в палитру компонент, регистрация в этом случае также говорит в IDE, что компонент не будет отображаться во время разработки.р><р класса="step_content "> в следующем примере мы создадим компонент, называемый TWavSound (дополнительный компонент, называемый TWavButton включен в исходный код, прилагаемый к данной статье в качестве примера). TWavSound просто хранить данные из WAV-файл, и воспроизведения звука на спрос. Хотя это было бы просто для нас, чтобы бросить один TWavSound на нашей форме для каждого WAV-файла мы требуем, наша форма вскоре может стать неуправляемой, поэтому мы будем создавать класс, менеджер позвонил TWavList.р><р класса="step_content ">
р><р класса="step_content "> каждый метод, используемый в исходный код для этих компонентов была освещена во второй части этой серии статей, так что исходный код не распространяется на любой большой уровень детализации. Тем не менее, я покажу классе деклараций этих компонентов, просто чтобы дать вам представление о том, как они структурированы.р><р класса="step_content "> <ем>Примечание: в нижней части блока, в секции инициализации устройства вы можете заметить следующий код:ем>р><р класса="step_content "> инициализациисильные>
и непредвиденное registerclass(TWavSound) р><р класса="step_content "> причина в том, что RegisterNoIcon не полную работу. Хотя это позволяет нам создавать экземпляры зарегистрированные от нашего редактора собственность что-то, кажется, идет не так, когда проект повторно загружены, содержащих эти компоненты. "Класс не зарегистрирован" отображается окно сообщения и проект поврежден. Кроме того, зарегистрировавшись класс таким образом, кажется, чтобы исправить проблему,
TWavSoundр><р класса="step_content "><границы таблицы="1" Ширина="100%"для bgcolor="#ffffcc">
<элемента tbody><тр> <тд> Типсильные>
В PWavData = ^TWavData
В TWavData = упакованныесильная> записьСтронг>
Размер: добавлены типы longint
для сведения: массивсильная>[0..0] на с байт
конец в р><р класса="step_content "> TWavSound = класс(TComponent)
Частнаясильные>
В FWavData: PWavData
В FWav: TWav
порядок в ReadWavData(трансляция: TStream)
порядок в WriteWavData(трансляция: TStream)
защищеныСтронг>
порядок в DefineProperties(filer и: TFiler) переопределитьСтронг>
общественныесильные>
и деструктор уничтожить переопределитьСтронг>
порядок это понятно
и процедура LoadFromFile(константный в именем: TFilename)
процедура LoadFromStream(трансляция: TStream)
порядок для игры
опубликованСтронг>
конецсильные>
и ир><р класса="step_content "> тр>р><р класса="step_content "> элемента tbody>Таблица>р><р класса="step_content "> FWavData
и будет использоваться для хранения содержимого WAV-файла после загрузки из потока или файла.р><р класса="step_content "> очиститьсильные>
будет освободить память держит FWavData.р><р класса="step_content "> игратьсильные>
будет использовать не sndplaysound вызова API в MMSystem.ССА т
Компонент письменной форме, часть 3
By russiatips
Компонент письменной форме, часть 3 : Несколько тысяч советов, которые сделают вашу жизнь проще.