Наши проекты:
Журнал · Discuz!ML · Wiki · DRKB · Помощь проекту |
||
ПРАВИЛА | FAQ | Помощь | Поиск | Участники | Календарь | Избранное | RSS |
[3.133.153.110] |
|
Сообщ.
#1
,
|
|
|
Прошу прощения, если получится дубликат -
Пробую создать класс от TTabControl(Шаблон брал из М. Фленова - Библия Делфи - создание графических часов). Объявляю published-свойство типа TBitmap Прописываю для него read,write. Компилится, устанавливается новым компонентом на мою вкладку. При попытке задать в диспетчере объектов стартовую картинку через редактор рисунков дает Acsess violation. Спинной мозг подсказывает, что память еще не назначена и машине трудно что-либо записать в адрес 0х00000000. Чего я не учел? |
Сообщ.
#2
,
|
|
|
Цитата rdx0 @ Чего я не учел? FBitmap := TBitmap.Create в конструкторе? |
Сообщ.
#3
,
|
|
|
Неет... А разве до конструктора доходит ход в дизайнтайме?
|
Сообщ.
#4
,
|
|
|
ясен пень доходит. Как же контролы на форме появляются?
|
Сообщ.
#5
,
|
|
|
То есть, если я Вас правильно понял, в конструкторе моего TChild (TTabControl) нужно FBitMap·у уже что-то присвоить? И не ссылку на файл, который мне хотелось бы задать из диспетчера объектов?
|
Сообщ.
#6
,
|
|
|
Цитата rdx0 @ нужно FBitMap·у уже что-то присвоить? И не ссылку на файл, Чтобы загрузить файл в битмап, надо этот битмап создать сначала. Наиболее логично это делать в конструкторе компонента-владельца. |
Сообщ.
#7
,
|
|
|
Уверен, не понимаю, что делаю . Пробовал в конструкторе вбить Picture:=TBitmap.Create- вообще не дает поместить компонент на форму - Acsess violation. Создал в классе заглушечный битмэп, откриэйтил его в конструкторе и присвоил его значение моему свойству. Теперь проект вроде бы и не возражает, но на месте моего битмэпа рисует серый квадрат малевича... (Кстати, моя версия хэлпа утверждает, что TBitmap.Create - исключительно для рантайма) Может, его нужно как-то на канве отрисовать? invalidate и refresh не помогают...
|
Сообщ.
#8
,
|
|
|
Цитата rdx0 @ Picture:=TBitmap.Create- вообще не дает поместить компонент на форму - Acsess violation Picture - это что? |
Сообщ.
#9
,
|
|
|
Это как раз мной создаваемое published-свойство. То есть, без проставки заставить заработать не сумел..
|
Сообщ.
#10
,
|
|
|
Код в студию, зачем угадывать что вы там написали
|
Сообщ.
#11
,
|
|
|
Цитата rdx0 @ Это как раз мной создаваемое published-свойство. То есть, без проставки заставить заработать не сумел.. TBitmap - это не визуальный контрол, и даже не TComponent. Поэтому при загрузке формы он автоматически не создается, его нужно самому создавать в конструкторе родительского компонента. К тому же это просто хранилище картинки со средствами ее программного "рисования" в памяти, а выводить\копировать эту картинку на экран нужно либо самому "ручками", либо использовать для этого стандартный компонент TImage. Для чего тебе понадобился именно TBitmap? Используй TImage и не парься |
Сообщ.
#12
,
|
|
|
To DimaBr:
Если я верно понял, код компонента, пытающегося использовать битмэп? To Guru: С TImage тоже не срослось, та же попытка чтения с адреса 0 |
Сообщ.
#13
,
|
|
|
Конечно код компонента, хотя бы те места где вы объявляете свойство, создаёте и назначаете его
|
Сообщ.
#14
,
|
|
|
Боюсь замусорить тему, но затрудняюсь ркшить, что значимо- а что нет. Поэтому вот:
unit MnSch; interface uses SysUtils, Classes, Controls, ComCtrls, StdCtrls, Graphics, ExtCtrls; type EnumStates=(eOff,eReady,eStart,eOper,eStop,eFault,eMan); TMnSch = class(TPageControl) private { Private declarations } fStates: EnumStates; fItemList: TList; procedure SetBGBitmap(Value:TBitmap); procedure SetBGImage(Value:TImage); protected { Protected declarations } public { Public declarations } fDBChanged: TNotifyEvent; BGBitmap: TBitmap; BGImage: TImage; fInt :integer; fField: TEdit; constructor Create(Aowner:TComponent); override; destructor Destroy; override; procedure GetState; Procedure SetState; procedure Proc1(par1:integer); published { Published declarations } PROPERTY fView: TBitmap read BGBitmap write SetBGBitmap; PROPERTY fBG: TImage read BGImage write SetBGImage; property OnDBChanged: TNotifyEvent read fDBChanged write fDBChanged; end; procedure Register; implementation uses Amber_it, Amber_log, Amber_wr; procedure Register; begin RegisterComponents('RZ', [TMnSch]); end; constructor TMnSch.Create; begin inherited Create(AOwner); BGBitmap:=TBitmap.Create; fView:= BGBitmap; fBG:=TImage.Create(AOwner); invalidate; fField:=nil; end; destructor TMnSch.Destroy; begin inherited Destroy; end; procedure TMnSch.SetBGBitmap(Value: TBitmap); begin fView.Assign(Value); invalidate; end; procedure TMnSch.SetBGImage(Value:TImage); begin fBG.Assign(Value); invalidate; end; //******************************************************* procedure TMnSch.GetState; begin; end; procedure TMnSch.SetState; begin; end; procedure TMnSch.Proc1(par1:integer); begin; fField.Text:=IntToStr(par1); end; end. |
Сообщ.
#15
,
|
|
|
Ужасно. Даже не вникая что тут вообще происходит видно, что битмап не уничтожается, в случае установки битмапа снаружи, внутренний так же потерян. с BG тоже самое. Инвалидейт в конструкторе... хм...
В общем, в топку. Только сейчас обратил внимание... BGBitmap: TBitmap; BGImage: TImage; в паблике! Зачем? короче, нафиг. |
Сообщ.
#16
,
|
|
|
Что в топку - это я понимаю.Процентов сорок - неубитые следы неудачных экспериментов(Это к вопросу "зачем?") То же самое с инвалидейтом. А можно поподробнее об "видно, что битмап не уничтожается, в случае установки битмапа снаружи, внутренний так же потерян."?
Добавлено Виноват, недостаточно грамотен, прошу уточнения - теги [сode=pas] ... [/сode] -скобки ставим? |
Сообщ.
#17
,
|
|
|
Итак, разберём конструктор
constructor TMnSch.Create; begin inherited Create(AOwner); BGBitmap:=TBitmap.Create; // создаём BitMap fView:= BGBitmap; // назначаем картинку картинке (не понятно зачем) fBG:=TImage.Create(AOwner); // создаём рисунок, причём сразу же назначаем его // поскольку записываем не в поле а в свойство // по идее нужно BGImage := TImage.Create(AOwner); invalidate; // перерисовываем компонент (это вообще не нужно) fField:=nil; end; Разберитесь с наименованием объектов. поля нужно именовать с буквы "f", а свойства без префикса. У вас же почему-то наоборот procedure TMnSch.SetBGBitmap(Value: TBitmap); begin fView.Assign(Value); // здесь нужно присваивать не СВОЙСТВУ а ПОЛЮ invalidate; end; |
Сообщ.
#18
,
|
|
|
Ну-у... По крайней мере, не пытается читать с нулевого адреса, сглатывает и запоминает файл, назначенный битмэпу.НО НЕ ОТОБРАЖАЕТ!!На экране - тот же пустой серенький квадратик. И насчет полей: у Фленова, с которого я бессовестно копировал исходники, это слово не упоминается в разделе "разработка компонентов". Так что я не в теме - что есть "поле", а что есть "свойство". Если не напряжет, просветите?
|
Сообщ.
#19
,
|
|
|
TMyComponent = class(TComponent) private fIntVal: integer; // поле, поля начинаются с буквы "f" published property IntVal: integer read fIntVal write fIntVal; // свойство, которое ссылается на поле end; И не верю я что у Феленова в разработке компонентов этого нет Добавлено Что значит "НО ОТОБРАЖАЕТ" ? А где он должен его отображать ? Опишите вашу задачу, что вы хотите получить вообще, а то получается диалог слепого и глухого. |
Сообщ.
#20
,
|
|
|
Цитата rdx0 @ сглатывает и запоминает файл, назначенный битмэпу.НО НЕ ОТОБРАЖАЕТ!!На экране - тот же пустой серенький квадратик. Тебе уже русским языком объяснили, что 1) TBitmap это просто хранилище картинки, которая сама по себе нигде и никак не отображается. 2) Для отображения картинок есть компонент TImage, но у него уже есть свое собственное хранилище bmp-картинки - TImage.Picture.Bitmap. Поэтому отдельное\независимое поле BGBitmap:TBitmap тут вообще не нужно - достаточно только TImage (с загрузкой картинки через св-во Picture в дизайне или рантайме). и еще 3) Чтобы TImage отображал загруженную картинку, ему нужно назначить св-во Parent - оконный контрол, на канве которого будет рисоваться изображение. Если св-во Parent не установлено, или Parent-контрол не видим (Visible:=false или закрыт другим контролом), то соотв-но и никакая картинка рисоваться не будет. 4) Но в качестве контейнера ты используешь TPageControl, который хоть и является оконным, но предназначен только для отображения своих ярлычков и вкладок Pages:TTabSheet. Поэтому непосредственно на TPageControl поместить какой-то контрол в дизайнере просто невозможно, а если в рантайме назначить этому контролу Parent:=PageControl, то он будет просто не видимым. Поэтому, чтобы твой Image нормально отображался в PageControl ему нужно установить в качестве Parent какой-то конкретный TabSheet этого PageControl-а. |
Сообщ.
#21
,
|
|
|
Цитата rdx0 @ Так что я не в теме - что есть "поле", а что есть "свойство". Свойство это property, для которого заданы способы\методы чтения (read) и записи (write). Если ты присваиваешь значение полю, например BGImage:=TImage.Create(AOwner), то присваиваемое значение непосредственно записывается в это поле (как в переменную), а если свойству fBG, для которого определен метод записи SetBGImage, то присваиваемое значение передается в этот метод, а там: опаньки - вместо простой записи стоит fBG.Assign(Value), но т.к. в конструкторе все неинициализированные поля, включая fBG, равны nil, то получается обращение к nil-объекту и соотв-но: Цитата rdx0 @ - присваивал бы не свойству, а полю - все срослось бы С TImage тоже не срослось, та же попытка чтения с адреса 0 |
Сообщ.
#22
,
|
|
|
1. To Moderator:
У Фленова я даже текстовый поиск включал... Забыл обложку, но файл, по-моему, называется DelphyBib.rar. Руководство называет это мнемосхемой. Т.е. подложенная картинка, отображающая схему производственного процесса, на которую мне нужно набросать активные управляемые элементы. Добавлено 2.To Guru: Да битмэп я уже выкинул, имиджу парент проверю.(См.выше - нужен именно дизайн-тайм). Спасибо за понимание, на работе завал, раньше понедельника не успею осознать.. |
Сообщ.
#23
,
|
|
|
Вот только сегодня дотянулись руки.. Нет у имиджа парентов, только парентшоухинт! А в дизайнере самому TImage сопоставлен комбобокс, но если я пытаюсь 1)положить на TForm заранее заготовленный имидж 2)Для свойства моего компонента класса TImage выбрть его из комбобокса, где он появился 3)Наблюдаю окно с ошибкой "Не могу присвоить класс TImage классу TImage"
Перечитал текст - полный бред, прошу прощения за квадратную голову (( |
Сообщ.
#24
,
|
|
|
Ещё раз ! Объясните, что ваш компонент ДОЛЖЕН делать.
|
Сообщ.
#25
,
|
|
|
Так. Это сущность, унаследованная от TPageControl, на первом листе которого должнра быть нарисована картинка, содержащая схему испытательного стенда. И на эту схему в дизайн тайме мне нужно накидать в нужных местах нужных размеров управляемых элементов. Чессслово, я не знаю, что Вас не устраивает в объяснении
|
Сообщ.
#26
,
|
|
|
Цитата rdx0 @ Нет у имиджа парентов, только парентшоухинт! Parent есть у всех контролов, только это не published-свойство, а public, которое устанавливается в рантйме. Для контролов, созданных в дизайнере, оно присваивается автоматически при загрузке формы из dfm в зависимости от того на каком родительском конроле расположен данный контрол. Раз ты сам создаешь Image, то и сам должен установить ему свойство Parent или вызвать метод InsertControl его родителя. А также Цитата rdx0 @ в дизайнере самому TImage сопоставлен комбобокс - это поведение по умолчанию для присваивания свойству внешнего контрола. Если контрол у тебя уже создан, и тебе нужно обеспечить доступ к его свойствам в дизайнере, то нужно сразу после создания этого контрола (в конструкторе панели) вызвать его метод SetSubComponent(true) ... FBGImage:=TImage.Create(Self); FBGImage.SetSubComponent(true); FBGImage.Parent:=Pages[0]; ... //установка прочих св-в, например Align:=alClient; |
Сообщ.
#27
,
|
|
|
То есть вы хотите, что бы при заброске компонента на форму (наследника TPageControl), в нём уже была одна страница, на которой был TImage ?
Идея прогрессивная, реализация возможна, но возникает несколько вопросов: 1. А нужен ли такой КОМПОНЕНТ ? 2. Вы собираетесь его использовать в нескольких местах ? 3. Почему именно TPageControl, а не TPanel ? 4. Что будет если удалить первую страницу ? |
Сообщ.
#28
,
|
|
|
To Guru:
Мне нужен именно дизайн-тайм. Если можно, поподробнее об "метод SetSubComponent(true)", а то мне справка какую-то фигню несет (( To Moderator^ 1.Ну, а чем плохо? 2.Пока в одном, но есть перспективы. Расчитываю, как на тематический рост 3.Пэйдж, ибо хотелось бы на соседних вкладках иметь графики, протокол событий и настройку железа 4.Зачем? И кому я это разрешу? |
Сообщ.
#29
,
|
|
|
Цитата rdx0 @ Если можно, поподробнее об "метод SetSubComponent(true)", а то мне справка какую-то фигню несет (( В справке помимо основного описания есть еще ссылки See also на ту же тему... Суть в том, что (по умолчанию) в dfm-файл сохраняются свойства только тех компонентов, Owner-ом которых является форма. К ним относятся все компоненты "брошенные" на форму в дизайне. Если какой-то из компонентов формы имеет св-во также являющееся компонентом, то по умолчанию предполагается, что это ссылка на некий другой компонент формы. Соотв-но в инспекторе объектов для этого свойства отображается комбобокс, в котором перечислены все компоненты формы данного типа, которые можно присвоить в качестве ссылки данному свойству. Чтобы изменить такое поведение по умолчанию, у TComponent предусмотрен ComponentStyle = csSubComponent и метод SetSubComponent, который устанавливает этот стиль. Если установить этот стиль у компонента, являющегося свойством другого компонента, то это св-во рассматривается уже не как внешняя ссылка, а как встроенный суб-компонент, для которого нужно отображать\редактировать его свойства в дизайне и сохранять их в dfm-файл. Простейшим примером такого встроенного компонента является EditLabel:TBoundLabel компонента TLabeledEdit. В конструкторе TBoundLabel вызывается метод SetSubComponent(true), устанавливающий у EditLabel стиль csSubComponent. Поэтому в дизайне этому свойству сопоставляется не комбобокс, а раскрывающийся список свойств EditLabel. |
Сообщ.
#30
,
|
|
|
1.Ну, а чем плохо?
Плохо то, что вы пытаетесь единовременную задачу заключить в компонент, при этом не обладаете даже минимумом знаний 3.Пэйдж, ибо хотелось бы на соседних вкладках иметь графики, протокол событий и настройку железа Что мешает забросить ВАШ новоявленный компонент на TPageControl или куда либо ещё ? 4.Зачем? И кому я это разрешу? Если компонент будет установлен в дизайнере, то любой сможет добавить новые страницы (это же TPageControl) и соответственно удалить их |
Сообщ.
#31
,
|
|
|
Цитата DimaBr @ 4.Зачем? И кому я это разрешу? Если компонент будет установлен в дизайнере, то любой сможет добавить новые страницы (это же TPageControl) и соответственно удалить их Все же это не TPageControl, а его наследник, для которого можно запретить добавление\удаление страниц и написать свой ComponentEditor для дизайна (следуя твоему же примеру ) rdx0 С другой стороны, действительно: А нужен ли такой КОМПОНЕНТ? Чем, например, фрэйм не устраивает? |
Сообщ.
#32
,
|
|
|
С созданием наследника от TPageControl с добавленной страницей могут возникнуть несколько сложностей непосильных начинающему программисту.
1. С одной стороны нужно будет создавать первую страницу в конструкторе при заброске на форму и в Run-Time, а с другой стороны не создавать её, а читать из ресурса при создании компонента в режиме загрузки формы из ресурса 2. Нужно будет запретить пользователю компонента удалить ОПРЕДЕЛЁННУЮ страницу компонента, так как порядок страниц легко поменять И это мы ещё не дошли до основного функционала компонента Цитата И на эту схему в дизайн тайме мне нужно накидать в нужных местах нужных размеров управляемых элементов. Следующий шаг - взаимодействие вашего компонента со сторонними контролами, "накиданными" на него. Не думаю что это имеет простое решение, по крайней мере так как вы это описали. По предоставленному описанию это очень похоже на Редактор Блок Схем. Написать такой редактор с уровнем не знания что такое Parent - невозможно. |
Сообщ.
#33
,
|
|
|
To Guru: Что-то я уже начинаю понимать, но оно же не отказывается, а просто не прорисовывает!
To Mooderator: Плохо то, что вы пытаетесь единовременную задачу заключить в компонент, при этом не обладаете даже минимумом знаний Если Вам не сложно, воздержитесь от оценок IQ 3.Пэйдж, ибо хотелось бы на соседних вкладках иметь графики, протокол событий и настройку железа Что мешает забросить ВАШ новоявленный компонент на TPageControl или куда либо ещё ? Мне нужно от него еще много чего 4.Зачем? И кому я это разрешу? Если компонент будет установлен в дизайнере, то любой сможет добавить новые страницы (это же TPageControl) и соответственно удалить их В .exe-файле? |
Сообщ.
#34
,
|
|
|
Imsorry - в обращении - To moderator лишняя ·o·
|
Сообщ.
#35
,
|
|
|
Цитата rdx0 @ Если Вам не сложно, воздержитесь от оценок IQ IQ <> количество знаний Делфи Судя по тому, что я здесь прочитал, вам не нужен пейджконтрол. Вы не понимаете сути Компонентов в целом. Вы пишите КОНЕЧНЫЙ компонент, который не сможете использовать повторно без внесения в него изменений, а так же, плохо расширяемый. Точнее, вообще не расширяемый. Вам достаточно взять TWinControl как контейнер для "управляемых элементов", а уже его размещать хоть где, хоть на форме, хоть на пейдже. Если вы настаиваете на "нужно от него еще много чего", то сделайте TMyCustomContainer = class(TWinControl) и в нем опишите общий функционал для "еще много чего". Но это уже напрямую к компонентам не относится, это ООП. |
Сообщ.
#36
,
|
|
|
Мне б такой компонент... Мечта! Нужен для такой штуки: .exe можно глянуть тут
Исходники, если надо, то тоже дам... Когда получится сделать, сообщите. |
Сообщ.
#37
,
|
|
|
> rdx0
Вы обратились сюда за советом ? Вот вам и советуют отказаться от TPageControl. Цитата а просто не прорисовывает! Повторяю, вы не понимаете сущности свойства Parent. Графические контролы с точки зрения Windows не существуют. Чтобы они смогли себя отрисовать им нужно ОКНО. Предоставьте TImage окно и всё начнёт рисоваться. Попробуйте создать то, что вы хотите без создания компонента. На пустой форме в OnCreate написать всё что вам нужно. Когда вы добьётесь нужного эффекта, вот тогда и переходите к оформлению в виде компонента, если конечно к этому времени у вас останется желание |
Сообщ.
#38
,
|
|
|
To AndyBitoff:
Еще раз прошу прощения. мне нужна картинка, настройка ее, возможность просмотра логов, отображение записанных данных и все это на соседних листках. Чем это не пэйджконтрол? To zvygin1964: сорри, если там ссылка, то я ее не вижу. А когда(если ...) получится, обязательно сообщу! To DimaBr: Если Я ничего не путаю, ОнКриейт - это рантайм |
Сообщ.
#39
,
|
|
|
Цитата To zvygin1964: сорри, если там ссылка, то я ее не вижу. А когда(если ...) получится, обязательно сообщу! Ссылка была удалена, как вредоносная Цитата ОнКриейт - это рантайм Совершенно верно. Для начала попробуйте создать TImage в режиме Run-Time и загнать в него картинку |
Сообщ.
#40
,
|
|
|
Цитата rdx0 @ мне нужна картинка, настройка ее, возможность просмотра логов, отображение записанных данных и все это на соседних листках. Чем это не пэйджконтрол? Пусть это будет пэйджконтрол. Но зачем для него создавать отдельный компонент (толком не представляя себе как его создавать, и будет ли он удобен для настройки в дизайн-тайме)? Ты так и не ответил, чем тебя не устраивает TFrame, на который можно легко и просто бросить и настроить в дизайне тот же пэйджконтрол, табшиты, картинку (можно вместе с дефолтным изображением) и прочие нужные компоненты. А уж затем этот фрейм можно вставлять в любые формы и проекты, и также легко и привычно редактировать в дизайне и сам пэйджконтрол, и все его компоненты. А как ты себе представляешь создание отдельного компонента с кучей суб-компонентов, который не является наследником TFrame и TForm, и соотв-но не поддерживает автосохранение и автозагрузку настроек из dfm? Этот компонент должен создавать сам себя со всеми своими суб-компонентами в конструкторе Create, т.е. в рантайме. (Примечание: дизайнер форм при перетаскивании компонента с палитры на форму создает реальный экземпляр этого компонента вызовом его Create, поэтому первоначально все новые компоненты выглядят так, как прописано в их конструкторе). Поэтому тебе придется в конструкторе своего пэйджконтрола самому создавать все его суб-компоненты в таком виде\состоянии, в каком ты их хочешь видеть при перетаскивании твоего компонента на форму (в частности, не забывая про установку Parent-ов, чтобы эти суб-компоненты вообще отображались на экране). Как ты это собираешься делать? Ручками методом тыка? Типа написал конструктор, скомпилировал компонент, бросил на форму, не понравилось, переписал, перекомпилировал и т.д. (до посинения)? Вот тебе DimaBr и предлагает для начала "потренероваться на кошках", т.е. Цитата DimaBr @ Да, "ОнКриейт - это рантайм", это именно то, что тебе нужно отработать\отладить, а затем перенести в Create твоего пэйджконтрола. (Хотя можно и непосредственно этот Create отлаживать, а в OnCreate формы просто создавать и добавлять на форму сам пэйджконтрол и смотреть, что получается).создать то, что вы хотите без создания компонента. На пустой форме в OnCreate написать всё что вам нужно. Когда вы добьётесь нужного эффекта, вот тогда и переходите к оформлению в виде компонента, если конечно к этому времени у вас останется желание Однако отладка создания компонента, это еще не все (что может отбить желание вообще его создавать и использовать). Нужно еще посмотреть насколько удобно будет редактировать св-ва его суб-компонентов в дизайн-тайме. Ведь эти субкомпоненты нельзя выделить и редактировать индивидуально, как обычные компоненты формы или фрейма. Их св-ва будут доступны для просмотра и редактирования только через раскрывающиеся (по плюсику) списки в свойствах самого пэйджконтрола. В том же TLabeledEdit раскрытие списка кучи ненужных свойств EditLabel выгдядит как-то э-э-э..., а у тебя этих субкомпонентов, судя по замыслам, будет N-е количество. Не запутаешься во всех этих "портянках" раскрытых в общем списке свойств? Или предпримешь доп.усилия для сокрытия части ненужных свойств субкомпонентов? |
Сообщ.
#41
,
|
|
|
Я боюсь, что наследование от ТФрейм существенно превышает мою квалификацию...
Вот тебе DimaBr и предлагает для начала "потренероваться на кошках" - Д на не пустой-то форме я ушибусь, но добьюсь,желание останется, Но КАК это оформить компонентом?(Замечу в скобках, - если бы я с легкостью владел тематикой, сидел бы здесь не в спрашивающих, а в отвечающих...) |