![]() |
| ||
|
|
Новости |
Поиск |
FAQ |
Статьи |
Книги |
Новости VCL
| | Форумы ЧАТ |
Орешник |
|
| |||
| |||
« предыдущая ветвь | форум | следующая ветвь »
Control "has no parent window"
Arazel © (2005-11-04 20:51:00)У меня в компоненте TabControl (Моем)
которорый я сейчас создаю
автоматический должны сосздаваться
закладки по идее Но! Когда я бытаюсь
добавить закладку в обработчики Create
появляется окно с ошибкой
Control "has no parent window"
Как мне создать эти закладний
что бы эта ошибка не выходила?
Юрий Зотов (2005-11-07 14:55:00) [1]Просто перенести создание закладок в CreateWnd, вот и все.
gdaujk (2005-11-07 14:08:00) [2]reonid © (07.11.05 13:09) [11]
Вот теперь понял, к чему вы клоните.
reonid (2005-11-07 13:09:00) [3]Собственно, по существу вопроса:
автору, вероятно, следует перекрыть CreateHandle,
где после inherited проверить, созданы ли закладки
(CreateHandle может вызываться не один раз),
и если нет - то создать их.
reonid (2005-11-07 12:36:00) [4]GetHandle - это get-метод для свойства TWinControl.Handle.
Мне казалось, это очевидно.
Само код создания окна действительно расположен в CreateWindowHandle.
Но в данном случае существенный момент - в каком именно месте
программы вызывается код создания окна.
win := TWinControl.Create(form);
// окно ещё не создано
win.Parent := form;
// окно до сих пор не создано
PostMessage(win.Handle, WM_USER, 0, 0); // только тут окно будет создано.
Собственно, цепочка вызовов будет такая:
GetHandle => HandleNeeded => CreateHandle => CreateWnd => CreateWindowHandle => CreateWindowEx
gdaujk (2005-11-07 12:15:00) [5]reonid © (07.11.05 11:58) [9]
Окно компонента создаётся при первом обращении к GetHandle.
Что за GetHandle? Можно поподробнее?
PS: Я думал, 'окно компонента создаётся' методом TWinControl.CreateWindowHandle, в котором кстати вызывается CreateWindowEx. Я что не правильно думал?
reonid (2005-11-07 11:58:00) [6]На счёт парентов:
Окно компонента создаётся при первом обращении к GetHandle.
При создании окна компонент обращается к Parent.GetHandle,
что приводит к созданию окна Parent'a (если оно ещё не создано), и так далее.
Эта цепочка обычно заканчивается на форме,
которая имеет родительским окном Application.Handle.
(или на компоненте, созданном с помощью CreateParented).
Если эта цепочка в каком либо месте имеет обрыв
(компонент не имеет парента, парент компонента не имеет парента и т.д.),
при обращении к GetHandle
возникает пресловутый "Control "" has no parent window".
Назначение парента компонента происходит после его
выполнения его конструктора. Это означает, что
в теле конструктора компонента нельзя обращаться к его хэндлу,
обращаться к свойствам, которые обращаются к хэндлу,
обращаться к хэндлам дочерних компонент
(хотя им парент уже назначен)
и к их свойствам, которые обращаются к их хэндлам.
gdaujk (2005-11-07 10:14:00) [7]ANB © (07.11.05 09:55) [7]
И ничего не валится
А у меня почему-то валиться. И умные люди в книжках про это пишут. В справке по Delphi об этом говориться.
ANB (2005-11-07 09:55:00) [8]
> gdaujk © (07.11.05 09:50) [6]
Вообще то создавал я объекты контроллов без парента. И ничего не валится, просто пока парент не привяжешь - компонента не видно. Надо код смотреть.
ЗА. Парентом для закладки, скорее всего должен быть сам табконтролл. Имхо.
gdaujk (2005-11-07 09:50:00) [9]ANB © (07.11.05 09:36) [5]
сначала надо вызвать inherited
При отсутствии inheritedвылетает другая ошибка (не Control "has no parent window").
ANB (2005-11-07 09:36:00) [10]ИМХО, проблема вот в этом :
> в конструкторе "Create"
Если в конструкторе, то сначала надо вызвать inherited. Иначе объект просто не существует.
gdaujk (2005-11-07 07:07:00) [11]Иначе его можно заменить
Его = Self...
gdaujk (2005-11-07 07:04:00) [12]Arazel © (06.11.05 08:20) [2]
а япытаюсь это сделать в конструкторе "Create"
Я же написал: "не забывай присваивать св-ву Parent твоего компонента Self". То есть, если ты, например, создаёшь свой Tab при создании формы, то:
procedure TForm1.FormCreate(Sender: TObject);
begin
YourTab := TYourTab.Create(self);
YourTab.Parent:=(self);
end;
Self references the object in which the method is called...
PS: Это в случае, если ты создаёшь Tab в методе его родительского окна. Иначе его можно заменить на Form1, конечно, если Form1 - родитель.
Arazel (2005-11-06 08:20:00) [13]Нет. Я создаю в VCL
Я унаследовал TabControl что бы добавить ему скины!
Но теперь моя задача создавать коекакие закладки при созданий
TabControl...
Вобщем когда я нажму F9 и программа запустится
то я хочу чтобы все что мне нужно(Закладки) было уже созданно
а япытаюсь это сделать в конструкторе "Create"
И когда я ложу этот скомпелированый компонент на форму
то вылетает такая фишка: Control "has no parent window"
gdaujk (2005-11-05 03:17:00) [14]которорый я сейчас создаю
TabControl уже давно создан...
Что значит автоматический должны сосздаваться закладки? Либо ты их создашь, либо они не создаются вообще...
С помощью чего ты создаёшь VCL или Win API? Если Win API, то создать TabControl можно сл. способом:
uses CommCtrl;
var
Tab: HWND;
procedure CreateTab(Wnd: HWND);
procedure InsertTabItem(Text: string; Index: Integer);
var
I: tagTCITEMA;
begin
I.mask := TCIF_TEXT;
I.pszText := PChar(Text);
I.cchTextMax := StrLen(PChar(Text));
I.iImage := -1;
SendMessage(Tab, TCM_INSERTITEM, Index, LParam(@I));
end;
begin
InitCommonControls;
Tab := CreateWindow(WC_TABCONTROL, '', WS_CHILD or WS_VISIBLE or WS_GROUP or WS_TABSTOP or TCS_FOCUSONBUTTONDOWN,
5, 6, 320, 320, Wnd, 13, hInstance, nil);
InsertTabItem('Первая закладка', 0, 0);
InsertTabItem('Вторая закладка', 1);
end;
Это в общих чертах. Советую сменить у Таба шрифт. Но это уже детали...
Если же ты пользуешься VCL, то определись, чего тебе надобно: TabControl или PageControl. При динамическом созданнии (если оно конечно используется) не забывай присваивать св-ву Parent твоего компонента Self...
PS: Не очень понятно, в чём твоя проблемма...