|
Вопрос # 5 377/ вопрос открыт / |
|
Здравствуйте, эксперты!
У меня такая страння ситуация. В процедуре форми А динамично создаю форму Б. Далее пишу что-то в эдит на форме Б и в событии chenge этого эдита мне пишет, чтоо форма А = nil.
 |
Вопрос задал: diamond (статус: Посетитель)
Вопрос отправлен: 6 июня 2011, 12:51
Состояние вопроса: открыт, ответов: 0.
|
Мини-форум вопроса
Всего сообщений: 22; последнее сообщение — 6 июня 2011, 23:05; участников в обсуждении: 4.
Страницы: [1] [2] [Следующая »]
|
min@y™ (статус: Доктор наук), 6 июня 2011, 13:00 [#1]:
Код показывай. Телепатов тут нету.
Делаю лабы и курсачи по Delphi и Turbo Pascal. За ПИВО! Пишите в личку, а лучше в аську. А ещё лучше - звоните в скайп!
|
|
diamond (статус: Посетитель), 6 июня 2011, 13:11 [#2]:
Особо показыва то и нечего.
Вот создаю форму:
RedForm := TFSettingField.Create(form1);
RedForm.EIDField.Text := 'test';
...
Событие Эдита:
implementation
uses
UForm1;
procedure TFSettingField.EIDFieldChange(Sender: TObject);
begin
If not Assigned(Form1) then
ShowMessage('nil');
If not Assigned(Self.Owner) then
ShowMessage('nil');
end;
Что Form1, что Owner по неизвесным мне причинам равны nil
|
|
min@y™ (статус: Доктор наук), 6 июня 2011, 13:20 [#3]:
А как и где создаётся Form1? Это главная форма приложения? Нет ли дублирования этой переменной в разнях модулях?
Делаю лабы и курсачи по Delphi и Turbo Pascal. За ПИВО! Пишите в личку, а лучше в аську. А ещё лучше - звоните в скайп!
|
|
diamond (статус: Посетитель), 6 июня 2011, 13:32 [#4]:
Нет, Form1 не главная форма приложения, она также создается динамически. Дублирования не думаю, имена я осмысленные делаю. Это здесь для простоты я напислал Form1. Кстати, главную форму видит.
|
|
DNK (статус: Студент), 6 июня 2011, 13:41 [#5]:
Очень похоже на то, что Form1 действительно = nil. Либо при создании формы в неё ничего не помещается, либо где-то затирается. Уверен будет один раз nil выводитья, если написать так:
RedForm := TFSettingField.Create(Application);
"Digital Networked Knight"
|
|
min@y™ (статус: Доктор наук), 6 июня 2011, 13:45 [#6]:
Цитата (DNK):
Либо при создании формы в неё ничего не помещается, либо где-то затирается.
Добавить нечего. Показывай код создания и освобождания Form1. А также места, откуда это всё вызывается.
Переменная либо не инициализируется, либо где-то у тебя FreeAndNil(Form1).
Делаю лабы и курсачи по Delphi и Turbo Pascal. За ПИВО! Пишите в личку, а лучше в аську. А ещё лучше - звоните в скайп!
|
|
diamond (статус: Посетитель), 6 июня 2011, 13:52 [#7]:
Я не верю своим глазам.
RedForm := TFSettingField.Create(Self), где Self- это Form1
Теперь хоть так TForm1(Self.Owner) видит.
А почему иначе не работает не пойму.
|
|
min@y™ (статус: Доктор наук), 6 июня 2011, 14:04 [#8]:
Цитата (diamond):
А почему иначе не работает не пойму.
Экспериментируй дальше, мы за тебя болеем! О-ле о-ле о-ле о-ле! О результатах доложишь.
Хрень какая-то...
Делаю лабы и курсачи по Delphi и Turbo Pascal. За ПИВО! Пишите в личку, а лучше в аську. А ещё лучше - звоните в скайп!
|
|
min@y™ (статус: Доктор наук), 6 июня 2011, 14:12 [#9]:
Кстати, всё-таки хотелось бы глянуть, как создаётся Form1. Причём блок кода полностью (функция/процедура/метод), в котором вызывается конструктор. Нет ли там локальной переменной Form1?
Делаю лабы и курсачи по Delphi и Turbo Pascal. За ПИВО! Пишите в личку, а лучше в аську. А ещё лучше - звоните в скайп!
|
6 июня 2011, 14:44: Вопрос перемещён из тематического раздела Delphi » Оболочка Delphi, компилятор, версии среды и т.д. в раздел Delphi » Прочее модератором Ерёмин А.А.
|
diamond (статус: Посетитель), 6 июня 2011, 14:49 [#10]:
Вот создаем ту самую Form1))
AddForm := TFrmListField.Create(Application);
AddForm.Top := ETCMainForm.Top + Panel1.Top;
AddForm.Left := ETCMainForm.Left + SBChange.Left;
// показываем форму
AddForm.ShowModal;
// Убиваем
FreeAndNil(AddForm)
На форме AddForm при собитии двойного клика создается другая форма
procedure TFrmListField.ListDblClick(Sender: TObject);
var
RedForm: TFSettingField;
Index: Byte;
begin
RedForm := TFSettingField.Create(Self);
// Êîïèðóåì âûáðàíîå ïîëå â ñïèñîê ìîä. ïîëåé
Index := NewAndModField.AddProp(ETCMainForm.ListProp[List.ItemIndex]);
NewAndModField[Index].OldField := List.ItemIndex;
NewAndModField[Index].NewField := False;
// Çàïîëíÿåì ôîðìó
with RedForm, NewAndModField[Index] do
begin
DisableComp;
EName.Text := NameField;
// Вот здесь пишем в эдит
EIDField.Text := IDField;
CBType.Text := TypeField;
CBEmpty.Checked := Empty;
CBSearch.Checked := SearchField;
Set2.Enabled := True;
if CBType.Text = 'Boolean' then begin chkCB.Checked := StrToBool(TextDefault); chkCB.Enabled := True end else
if CBType.Text = 'Date' then begin dtp1.Date := StrToDate(TextDefault); dtp1.Enabled := True end else
if (CBType.Text = 'Float') or (CBType.Text = 'Integer') or (CBType.Text = 'String') then begin EPole.Text := TextDefault; EPole.Enabled := True end else
if CBType.Text = 'List' then begin EList.Text := TextDefault; EList.Enabled := True end else
if CBType.Text = 'File' then
begin
EFile.Text := TextDefault;
BDFile.Enabled := True;
if EFile.Text <> '' then
BDelFile.Enabled := True
end
else
if CBType.Text = 'Picture' then
begin
EPict.Text := TextDefault;
BDLPict.Enabled := True;
if EPict.Text <> '' then
BDelPict.Enabled := True
end
end;
if RedForm.ShowModal = mrOk then
with NewAndModField[Index], RedForm do
begin
NameField := EName.Text;
IDField := EIDField.Text;
TypeField := CBType.Text;
Empty := CBEmpty.Checked;
SearchField := CBSearch.Checked;
if TypeField = 'Boolean' then TextDefault := BoolToStr(chkCB.Checked, True) else
if TypeField = 'Date' then TextDefault := DateToStr(dtp1.Date) else
if TypeField = 'File' then TextDefault := EFile.Text else
if TypeField = 'Picture' then TextDefault := EPict.Text else
if TypeField = 'List' then TextDefault := EList.Text else
if (TypeField = 'Float') or (TypeField = 'Integer') or (TypeField = 'String') then TextDefault := EPole.Text
end;
FreeAndNil(RedForm)
end;
Собитие эдита
procedure TFSettingField.EIDFieldChange(Sender: TObject);
var
str: string;
begin
str := EIDField.Text;
if (str = '') or (str[1] in ['0'..'9','À'..'ÿ']) or SearchIDNameIndex(str) then
begin
EIDField.Font.Color := clRed;
BOk.Enabled := False;
end
else
begin
BOk.Enabled := True;
EIDField.Font.Color := clBlack
end
end;
Функция SearchIDNameIndex
function TFSettingField.SearchIDNameIndex(AIDName: string): Boolean;
var
i, j: Byte;
B: Boolean;
begin
Result := False;
if ETCMainForm.ListProp.Count > 0 then
for i := 0 to ETCMainForm.ListProp.Count - 1 do
begin
with TFrmListField(Self.Owner) do
if NewAndModField.Count > 0 then
for j := 0 to NewAndModField.Count - 1 do
begin
B := False;
if NewAndModField[j].OldField = i then
B := True;
if NewAndModField[j].IDField = AIDName then
begin
Result := True;
Exit
end
end;
if not B then
if ETCMainForm.ListProp[i].IDField = AIDName then
begin
Result := True;
Break
end
end
end;
|
|
diamond (статус: Посетитель), 6 июня 2011, 14:51 [#11]:
Что ж оно всё как под линеечку выровняло текст?
|
|
min@y™ (статус: Доктор наук), 6 июня 2011, 15:12 [#12]:
Цитата (diamond):
Что ж оно всё как под линеечку выровняло текст?
У тебя (пока) нет прав на вставку форматированного кода. Это не я придумал.
Цитата (diamond):
Вот создаем ту самую Form1))
AddForm := TFrmListField.Create(Application);
AddForm.Top := ETCMainForm.Top + Panel1.Top;
AddForm.Left := ETCMainForm.Left + SBChange.Left;
// показываем форму
AddForm.ShowModal;
// Убиваем
FreeAndNil(AddForm)
Ну вот как с тобой дальше разговаривать? Ты ж ни хрена не понимаешь, что от тебя хотят. Я ж просил блок кода целиком!
Делаю лабы и курсачи по Delphi и Turbo Pascal. За ПИВО! Пишите в личку, а лучше в аську. А ещё лучше - звоните в скайп!
|
|
diamond (статус: Посетитель), 6 июня 2011, 15:33 [#13]:
Это будее очень много кода. Плюс формы в разных модулях. А как файлик выложить?
|
|
min@y™ (статус: Доктор наук), 6 июня 2011, 15:40 [#14]:
Цитата (diamond):
Это будее очень много кода.
Чо, процедура, в которой вызывается конструктор формы, - это 100500 строк кода?
Цитата (diamond):
А как файлик выложить?
Код можно вываливать сюда.
Делаю лабы и курсачи по Delphi и Turbo Pascal. За ПИВО! Пишите в личку, а лучше в аську. А ещё лучше - звоните в скайп!
|
|
diamond (статус: Посетитель), 6 июня 2011, 15:54 [#15]:
Это и есть вся процедура.
procedure TETCMainForm.SBChangeClick(Sender: TObject);
var
AddForm: TFrmListField;
begin
AddForm := TFrmListField.Create(Application);
AddForm.Top := ETCMainForm.Top + Panel1.Top;
AddForm.Left := ETCMainForm.Left + SBChange.Left;
// ïîêàçûâàåì ôîðìó
AddForm.ShowModal;
// Óáèâàåì ôîðìó
FreeAndNil(AddForm)
end;
Процедура с вызовом другой формы выше в коде.
|
|
min@y™ (статус: Доктор наук), 6 июня 2011, 16:11 [#16]:
Ну вот, теперь понятно всё. Я так и думал, что используется локальная переменная. Убери вот это:
var
AddForm: TFrmListField;
Дальше я скажу, как делаю я. Это не значит, что так делать 100% правильно, это просто мой стиль программирования.
Для начала надо убрать AddForm из списка Autocreate forms в Project/Options. Затем:
procedure TETCMainForm.SBChangeClick(Sender: TObject);
begin
if not Assigned(AddForm)
then AddForm := TFrmListField.Create(Application);
try
// ... инициализация полей формы ...
AddForm.ShowModal();
// ... другая нужная работа ...
finally
FreeAndNil(AddForm)
end;
end;
З.Ы. Всю эту хрень я всегда оформляю отдельной функцией прямо в модуле той самой формы, которая и должна быть создана, показана и убита. Щас пример покажу..
type
TFormatsForm = class(TForm)
ListView: TListView;
AddButton: TButton;
EditButton: TButton;
DeleteButton: TButton;
CloseButton: TButton;
FormStorage: TFormStorage;
SysImageList: TSysImageList;
procedure FormatManagerChange(Sender: TObject);
procedure CloseButtonClick(Sender: TObject); // Обработчик события изменения менеджера
procedure ManageButtonClick(Sender: TObject);
procedure ListViewClick(Sender: TObject);
procedure ListViewDblClick(Sender: TObject);
procedure FormKeyPress(Sender: TObject; var Key: Char);
private
procedure EnableControls();
procedure UpdateSelected(); // Обновление информации на выделенной строке
public
constructor Create(AOwner: TComponent); override;
end;
var
FormatsForm: TFormatsForm;
procedure ShowFormatsForm();
implementation
{$R *.dfm}
procedure ShowFormatsForm();
begin
if not Assigned(FormatsForm)
then FormatsForm:= TFormatsForm.Create(Application);
try
FormatsForm.ShowModal();
finally
FreeAndNil(FormatsForm);
end;
end;
{ TFormatsForm }
constructor TFormatsForm.Create(AOwner: TComponent);
begin
inherited;
FormStorage.IniSection:= Name;
FormatManager.OnChange:= FormatManagerChange;
FormatManagerChange(nil);
EnableControls();
end;
Делаю лабы и курсачи по Delphi и Turbo Pascal. За ПИВО! Пишите в личку, а лучше в аську. А ещё лучше - звоните в скайп!
|
|
diamond (статус: Посетитель), 6 июня 2011, 16:29 [#17]:
Интересный подход. Сейчас попробую.
|
|
DNK (статус: Студент), 6 июня 2011, 16:47 [#18]:
min@y™: Уточни, пожалуйста, для чего нужно Assigned-условие?
"Digital Networked Knight"
|
|
min@y™ (статус: Доктор наук), 6 июня 2011, 16:55 [#19]:
Цитата (DNK):
Уточни, пожалуйста, для чего нужно Assigned-условие?
Для проверки, не создана ли форма.
Естественно, при всех соблюдённых условиях оно не нужно. Просто я эту кострукцию добавил в автокомплит и по Ctrl+J вызываю. Редактировать влом.
Делаю лабы и курсачи по Delphi и Turbo Pascal. За ПИВО! Пишите в личку, а лучше в аську. А ещё лучше - звоните в скайп!
|
|
bugmenot (статус: 3-ий класс), 6 июня 2011, 16:56 [#20]:
Цитата (DNK):
для чего нужно Assigned-условие?
там следовало бы не хакать, а инициализировать глобальную переменную явно:
var FormatsForm: TFormatsForm = nil;
собственно глобальной она там особо не нужна
виконання програми розпочинається з того самого мiсця, де призупинилося.
|
Страницы: [1] [2] [Следующая »]
Чтобы оставлять сообщения в мини-форумах, Вы должны авторизироваться на сайте.
|