-
Здравствуйте, Сделал компонент наследник TWinControl. Он может создовать объекты(Похоже на TPageControl). Создаются так:
procedure TWizzardEditor.ExecuteVerb(Index: Integer);
begin
inherited;
case Index of
0:
begin
if Component is TCustomWizzard then
begin
(Component as TCustomWizzard).AddPage(Designer.UniqueName('WizzardPage'));
Designer.Modified;
end;
end;
end;
end;
function TCustomWizzard.AddPage(PageName: string): Integer;
var
TempPage: TCustomWizzardPage;
begin
TempPage := CreatePage;
InitializePage(TempPage, PageName);
Result := FPages.Add(TempPage);
end;
function TWizzard.CreatePage: TCustomWizzardPage;
begin
Result := TWizzardPage.Create(Self.Owner);
end;
Так вот если у созданых «страниц» Owner НЕ форма, то они не видны в окне «Structurte». Временно решил проблему так:
Result := TWizzardPage.Create(Self.Owner); Вопросы: 1. Почему если владелец НЕ форма их не видно? 2. Как сделать правильно, тк мой вариант явно неправильный, тк Self.Owner невсегда форма?
-
> TempPage := CreatePage; > InitializePage(TempPage, PageName); > Result := FPages.Add(TempPage);
А почему плюем на ОПП, и пишем не так: TempPage := TWizzardPage.Create(Self.Owner);;
TempPage.InitializePage(PageName);
Result := FPages.Add(TempPage);
-
1. Потому что дизайнер формы их не видит. 2. Result := Designer.CreateComponent(TCustomWizzardPage,Component,Left,Top,Width,Height);
TCustomWizzardPage(Result).Wizzard := (Component as TCustomWizzard);
А уж в SetWizard призвести добавление во внутренний список и инициализацию.
-
> TempPage.InitializePage(PageName);
С этим соглашусь. А с этим: TempPage := TWizzardPage.Create(Self.Owner);; Нет. Это что же мне всегда переписывать AddPage если надо создать наследника? Это кажись что-то вроде «фабрично метода»
> DimaBr © (13.04.07 08:53)
Понятно, благодарю.
-
TempPage := Designer.CreateComponent(TWizzardPage, Component, 0,0,0,0); Говорит: [Pascal Error] KSoftWareWizzardEditorUnit.pas(36): E2010 Incompatible types: 'TWizzardPage' and 'TComponent' Хотя: TWinControl
^
|
TCustomWizzardPage
^
|
TWizzardPage
-
TempPage := Designer.CreateComponent(TWizzardPage, Component, 0,0,0,0) as TWizzardPage;
-
var A: TControl;
B: TComponent;
begin
B := A;
A := B;
end;
-
Блин, я думал он на это ругается :(. Designer.CreateComponent(TWizzardPage , Component, 0,0,0,0) Понятно
-
Угу, получилось. Теперь еще вопрос. Вот у меня значится на однм контроле лежат несколько других. И в окне «structure» соответственно дерево: Wizzard:
WizzardPage1
WizzardPage2
WizzardPage3 Вопрос какое событие происходит при нажатии на дочерние элементы? Это нужно для того чтобы все кроме выбранного скрыть, чтобы был виден только он
-
Если вы говорите о дизайнере, то думаю можно попытаться отловить WM_SETFOCUS, но затея кажется глупая. Закройте окно «structure» и инспектор, и выберите потом другую панель !!!
-
> но затея кажется глупая
Ладно, вопрос. У меня вышел аналог TPageContol(по виду), но нет корешков. Как мен сделать возможность переключаться меж ними в дизанере. Те чтобы создать 3 штуки например, а потом накидать контролов?
-
Popup (Previous Page, Next Page)
-
> Popup
Дык это где должно быть? Механизм пказать/скрыть допустим есть. Но когда и кто будет вызывать?
-
> Как мен сделать возможность переключаться меж ними в дизанере.
Кинте на форму TPageControl, нажмите над ним правой кнопкой мыши. Вот вам и Popup с сменой страниц
-
А я понял. Соотв реализовать еще 2 «Verb'а»
Вроде понятно
-
Вот еще проблемма: В окре «структура» созданые TWizzardPage как-бы прозрачные. А если на них кинуть кнопку например, то получается, что кнопка лежит на форме, а не на TWizzardPage.
-
procedure TWizzardEditor.ExecuteVerb(Index: Integer);
begin
inherited;
case Index of
0: 1,2: begin TempPage := TWizzardPage(Component).GetNexPage(Index = 1);
Designer.SelectComponent(TempPage);
end;
end;
end; Не забудьте, то при выборе из окон «structure» и инспектор панель тоже должна почвится.
-
Попробуйте перетащить кинутую кнопку за пределы панели. Если это вам удалось, значит она(кнопка) действительно лежит не на панели. Тогда очевидно что ваша панель не принимает контролы в дизайнере. Скорее всего поможет constructor TMyPanel.Create(AOwner: TComponent); begin inherited Create(AOwner); ControlStyle := ControlStyle + [csAcceptsControls] ... end;
-
> DimaBr © (16.04.07 12:40)
Сделал. Но это тут не прием. Когда я их только создаю, они(пиктограмки страниц в окне «структура») уже какбы прозрачные
-
Может из-за этого
ControlStyle := ControlStyle + [csAcceptsControls, csNoDesignVisible];
-
> inherited Create(AOwner); > ControlStyle := ControlStyle + [csAcceptsControls]
Да помогло. Но не все еще в порядке. Вот код PreviousPage:
function TCustomWizzard.PreviousPage: TCustomWizzardPage;
begin
FCurrentPageIndex := FCurrentPageIndex — 1;
if FCurrentPageIndex < 0 then
FCurrentPageIndex := FPages.Count — 1;
ShowPage(FCurrentPageIndex);
Result := FPages[FCurrentPageIndex];
end; procedure TCustomWizzard.ShowPage(Index: Integer);
var
I: Integer;
begin
for I := 0 to FPages.Count — 1 do
if I = Index then
FPages[I].Visible := True
else
FPages[I].Visible := False;
end; Но оно не работает так как я хочу. Те допустим есть 3 страницы.На второй кнопка. В окне «структура» она действительно на второй странице. Но когда я начинаю щелкать NextPage, то кнопка идна всегда. Те FPages[I].Visible несрабатывает что-ли
Или наоборот выбрана вкладка с кнопками, а их невидно
И все равно они какие-то прозрачные странно. Скриншот: http://ksoftware.narod.ru/Struct.JPG
-
FPages[I].Visible прекрасно работает (но не в дизайнере) сделайте активной панели BringToFront
-
Сделал, но не помогло. И если просто правой кнопкой нажать, то пункты BringToFront(стандартные) «звдизэйблены».
-
Не, вы не поняли. У главного компонента должно быть свойтсво - ActivePage, при установке которого становится активной выбранная панель.
procedure TCustomWizzard.SetActivePage(APage: TCustomWizzardPages);
begin
if APage <> nil then
if APage.Wizzard <> self then Exit;
fActivePage := APage;
if fActivaPage <> nil then fActivaPage.BringToFront;
end;
-
Я сделал так. Смысл ессно разный, но работать имхо должно было и так
procedure TCustomWizzard.ShowPage(Index: Integer);
var
I: Integer;
begin
for I := 0 to FPages.Count — 1 do
if I = Index then
begin
if csDesigning in ComponentState then
BringToFront
else
FPages[I].Visible := True
end
else
FPages[I].Visible := False;
end; У главного компонента должно быть свойтсво ActivePage шас попробую
-
if csDesigning in ComponentState then
FPages[I].BringToFront
else
FPages[I].Visible := True
-
Ура работает
-
Поздравляю !!!
-
Блин криво получилось, ппц :). Ну хоть что-то первый раз такое делаю :)
-
Так, продалжаем разговор. В дизайнере еще рак-то рабоатет. А вот при запуске приложения получается что в FPage 0 станиц. Хотя в дизайнере они есть(NexPage работает нормально)
В чем может быть дело? Может их нао как-то сохранять
-
> В чем может быть дело?
Мне нравятся ваши вопросы. Дело может быть в чём угодно, я ж не провидец или телепат. Прежде всего вы должны добится чтобы при двойном Alt+F12 у вас небыло никаких ошибок, и всё было на своих местах. Скорее всего вы не разобрались с GetChildren.
-
> Скорее всего вы не разобрались с GetChildren.
Я даже незнаю что это :(
> Alt+F12
Это что за функция?
-
> GetChildren
Так его надо перекрыть? А как? Те что писать?
-
Alt+F12 - это комбинация клавиш на клавиатуре (Кнопочка ALT находится с боков от пробела - такая длинная клавиша, а F12 в конце верхнего ряда) Нажмите два раза это сочетание при выделенной форме. В первый раз форма перейдёт в режим текста, во второй раз обратно. Если всё останется на своих местах - вы Гений (обычно куча ошибок). В режиме такста ваш котнрол должен имет приблизительно такой вид
object Wizard1: TCustomWizzard
Left = 80
Top = 24
Width = 289
Height = 193
ActivePage = Page1
object Page1: TCustomWizzardPage
........
end
end то есть страница находится внутри компонента
-
> Alt+F12 это комбинация клавиш на клавиатуре
Что то нажимаю я эти «кнопочки» вообще нихрена :) Мож в BDS другое сочетание?
-
> [34] Kolan © (16.04.07 14:57)
Попробуй по форме правой кнопкой мыши>View as Text, затем в редакторе правой> View as Form....
-
Угу, по виду тоже самое осталось, но стал ругаться так же как и ран тайме (List out of bounds 0). Те скорее всего в FPages ниче нет сейчас. Наверно как-то сохранять/загружать надо
, как?
-
Наверно так [2]
-
> Наверно так [2]
Так я делаю: procedure TWizzardEditor.ExecuteVerb(Index: Integer);
var
TempPage: TCustomWizzardPage;
begin
inherited;
case Index of
0:
begin
if Component is TWizzard then
begin
TempPage := Designer.CreateComponent(TWizzardPage, Component, 0,0,0,0) as TWizzardPage;
TWizzardPage(TempPage).Wizzard := (Component as TWizzard);
Designer.Modified;
end;
end;
-
Но если я переключюсь текст/форма, то в дизайнере страницы есть, а вот FPages их нет
-
Вы невнимательно прочитали [2], особенно в конце. Что происходит в методе TWizzardPage.SetWizard ???
-
procedure TCustomWizzardPage.SetWizzard(const Value: TCustomWizzard);
begin
if FWizzard <> nil then
begin
FWizzard.DeletePage(Self);
end;
FWizzard := Value;
FWizzard.AddPage(Self);
end;
-
Ок, по аналогии так же ???
procedure TTabSheet.ReadState(Reader: TReader);
begin
inherited ReadState(Reader);
if Reader.Parent is TPageControl then
PageControl := TPageControl(Reader.Parent);
end;
-
> Ок, по аналогии так же ???
Черт, нихрена не понял. Объяснишь справку читаю
-
Метод ReadState вызывается в момент чтения компонента из ресурса, его нужно переопределить и произвести присвоение (заодно и добавление в список) FWizzard. procedure TCustomWizzardPage.ReadState(Reader: TReader);
begin
inherited ReadState(Reader);
if Reader.Parent is TCustomWizzard then
Wizard := TCustomWizzard(Reader.Parent);
end;
-
То же самое, главное непонятно как все это отлаживать :(
-
Переключитесь на Текст, поставьте брейк в ReadState и запускайте. Надеюсь вы в описании сделали так
TCustomWizzardPage = class() protected procedure ReadState(Reader: TReader);override; end;
-
Надеюсь вы в описании сделали так strict protected
procedure ReadState(Reader: TReader); Вроде да. > Переключитесь на Текст, поставьте брейк в ReadState и запускайте.
На точке не остановилось. Причем не важно текст или не текст.
-
Ой, стоп
-
Так это получилось. Еще: Где тот момент когда все уже загружено. При создании Wizzarda я написал такой код:
constructor TCustomWizzard.Create(AOwner: TComponent);
begin
inherited Create(AOwner);
FPages := TWizzardPageList.Create;
FCurrentPageIndex := 0;
if (not (csDesigning in ComponentState)) and (FPages.Count > 0) then
FPages[0].Show(nil);
end; Но страницы еще не загрузились, и FPages.Count = 0. А мне нужно показать 0-ую. Хотя в принципе работает
-
procedure TCustomWizzard.Loaded;override;
begin
CurrentPageIndex := 0;
end;
-
procedure TCustomWizzard.Loaded;override;
begin
inherited Loaded;
CurrentPageIndex := 0;
end;
-
Угу. Вот еще что: Почемуте, по всей видимосте в FPages страницы не в том порядке в коком они отображены в окне «структура». Те Вторя по счету в FPages 0. И сдледовательно ноказывается не то что нужно
-
> DimaBr © (16.04.07 16:52)
Смысл я понял
-
Потому что они сохраняются в ресур в порядке расположения на форме, для изменения порядка сделай так procedure TPageControl.GetChildren(Proc: TGetChildProc; Root: TComponent);
var I: Integer;
begin
for I := 0 to FPages.Count - 1 do Proc(TComponent(FPages[I]));
end; Ни в коем случае не нужен InheritedПока, до завтра !!!
-
Пока, до завтра !!!
Ок :)
Теперь выходит 0 это последняя. Пошет downto?
-
> Пошет
Может.
-
Да нет, всё должно быть нормально. Переключитесь на текст, отредактируйте DFM-ку (выставите страницы в нужном порядке), переключитесь на форму.
-
Удалено модератором
-
Удалено модератором
|