Лена |
Отправлено: 08.11.2006, 17:17 |
|
Мастер участка
Группа: Участник
Сообщений: 501
|
У меня код, который создает форму:
CODE |
//показ модального окна при щелчке в гриде
void __fastcall TForm1::DBGrid1EditButtonClick(TObject *Sender)
{
if(Form1->DBGrid1->Fields[0]->IsNull==true || Form1->DBGrid1->Fields[2]->IsNull==true)
{
ShowMessage("Поля \"Код\" и \"Доступ\" необходимо заполнить");
return;
}
TField * Self;
Self = DBGrid1->SelectedField;
if(Self)
if(Self->FieldName == "man")
{
TFormVladelec *FormVladelec = new TFormVladelec(Application);
FormVladelec->ShowModal();
delete FormVladelec;
}
}
|
После того как окно появилось, мне бы хотелось иметь код в его обработчике события OnResize (или даже в OnShow):
CODE |
void __fastcall TFormVladelec::FormResize(TObject *Sender)
{
if (FormVladelec->Width<680)//ошибка!!!
{
FormVladelec->Width = 680;
}
if (FormVladelec->Height<480)
{
FormVladelec->Height=480;
}
}
|
Однако такой код генерирует ошибку. Очевидно, окно FormVladelec не до конца создано? Как в таком случае можно вставить мой код в OnResize? Можно отказаться от оператора new, но хочется разобраться.
Присоединить изображение
|
|
Valdemar |
Отправлено: 08.11.2006, 17:37 |
|
Мастер участка
Группа: Участник
Сообщений: 433
|
Если это нужно для ограничения размеров формы, то можно воспользоваться свойством формы Constraints, которое задать дизайн-тайме ну или в процессе выполнения.
Можно еще задать свой обработчик программно:
TFormVladelec->OnResize=твой обработчик
Твоя функция-обработчик должна иметь прототип как у нужного обработчика.
|
|
Лена |
Отправлено: 08.11.2006, 17:51 |
|
Мастер участка
Группа: Участник
Сообщений: 501
|
Cпасибо.
Наверное лучший способ в моем случае это определить TFormVladelec->OnResize= обработчик
В обработчике планируется добавить код...
В форме, которая будет создана, тоже находиться грид. Я хотела в нем при увелечении формы (при ее растягивании) менять ширину колонок этого грида.
|
|
AVC |
Отправлено: 08.11.2006, 17:56 |
|
Ветеран
Группа: Модератор
Сообщений: 1583
|
Откуда взялась переменная FormVladelec в TFormVladelec::FormResize? (Вспомните о её области видимости)
Если нет ошибок то все работает нормально. Я этим методом пользуюсь не один год, а формы (кроме первой) создаю через new.
CODE |
void __fastcall TF_Main::FormResize(TObject *Sender)
{ FormCheckMinHW (this, 470, 630); }
|
Перепишите так
CODE |
void __fastcall TFormVladelec::FormResize(TObject *Sender)
{
if (Width<680)//ошибка!!!
{
Width = 680;
}
if (Height<480)
{
Height=480;
}
}
|
И все станет не место. |
|
Лена |
Отправлено: 08.11.2006, 18:13 |
|
Мастер участка
Группа: Участник
Сообщений: 501
|
Да работает.
Однако не понятно помему я не могу обратиться через имя объекта...
Разве после FormVladelec->ShowModal(); переменная FormVladelec (имя формы) не существует? |
|
beginner |
Отправлено: 08.11.2006, 23:59 |
|
Дежурный стрелочник
Группа: Участник
Сообщений: 44
|
QUOTE (Лена @ 08.11.2006, 18:13) | Да работает.
Однако не понятно помему я не могу обратиться через имя объекта...
Разве после FormVladelec->ShowModal(); переменная FormVladelec (имя формы) не существует? |
FormVladelec имеется, напр. код FormVladelec->Width из FormResize
обращается к ней. Но созданная форма присваивается
другому FormVladelec, который определен в обработчике
DBGrid1EditButtonClick. Т.е. ошибка вызвана определением
нового объекта в DBGrid1EditButtonClick.
Вместо
TFormVladelec *FormVladelec = new TFormVladelec(Application);
нужно просто написать
FormVladelec = new TFormVladelec(Application);
И вместо имени формы можно еще использовать this.
Отредактировано beginner — 09.11.2006, 00:09 |
|
AVC |
Отправлено: 09.11.2006, 09:59 |
|
Ветеран
Группа: Модератор
Сообщений: 1583
|
QUOTE (Лена @ 08.11.2006, 17:13) | Однако не понятно помему я не могу обратиться через имя объекта...
|
Продублирую ответ beginner немного другими словами.
Основное — в данном случае вы НЕ обращаетесь к объекту через его имя, а просто есть переменная — указатель на экземпляр класса.
Так как компилятор пропустил ваш код значит у вас в FormVladelec есть такие строки (их обычно вставляет мастер построения формы)
TFormVladelec *FormVladelec;
и
extern PACKAGE TFormVladelec;
Это объявление глобального указателя на экземпляр формы FormVladelec. Если форма создается автоматически то этот указатель заполняется реальным знчением.
В вашем случае вы кодом
{
TFormVladelec *FormVladelec = new TFormVladelec(Application);
FormVladelec->ShowModal();
delete FormVladelec;
}
перекрыли одноименную глобальную переменную, но в пределах фигурных скобок все правильно (вспомните правила областей видимости переменных),
а вот код из формы FormVladelec
if (FormVladelec->Width<680)
пытается работать с той самой глобальной переменной, определенной в том же модуле формы.
И вообще считаю очень вредным внитри экземпляра класса обращаться к этому же экземпляру через внешнюю переменную. Если хотите подчеркнуть что обращение идет именно к этому экземпляру у вас есть this.
Второе — вы, конечно, можете писать в вызываущей функции
FormVladelec = new TFormVladelec(Application);
Но помните, что это всего лищь одна переменная, и если в ней уже был записан адрес экземпляра ранее созданной формы, то теперь указатель указывает на новый экземпляр. Это не криминально и поправимо, но может доставить несколько приятных и веселых минут при отладке приложения. |
|
Лена |
Отправлено: 09.11.2006, 11:21 |
|
Мастер участка
Группа: Участник
Сообщений: 501
|
Спасибо за объяснения. Теперь понятно.
>И вообще считаю очень вредным внутри экземпляра класса обращаться к этому же экземпляру через внешнюю переменную.
Я так делаю, потому что мне удобно набрав стрелочку "->" увидеть подсказку Builder и быстро выбрать нужное свойство. Поэтому я и писала: FormVladelec->"вижу список свойств."
Теперь знаю, что правильнее this->... |
|