Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > C++ Builder > Функция события для созданного объекта


Автор: Mpak 14.1.2007, 21:06
Я создаю объект:
Код

TCSpinEdit *idx;
idx=new TCSpinEdit (mes);
idx->Parent=mes;
idx->Top=8;
idx->Left=230;
idx->Height=22;
idx->Width=49;


И мне нужна функция OnChange() этого объекта. Как, где и что мне нужно опистаь?  smile 

 smile 

Автор: Anikmar 14.1.2007, 21:53
Самый простой метод (чтобы руками много не писать)
Кидаешь на форму такой компонент, создаешь обработчик события.
Пишешь внутри него какой-нить комментарий, чтобы не удалился при солхранении, удаляешь сам объект. У тебя появится метод формы строго соответствующий прототипу нужного обработчика. Затем просто присваиваешь его имя свойству OnChange созданного объекта и пишешь туда собственно реализацию

idx->OnChange = // Имя сгенерированного обработчика

Автор: Mpak 15.1.2007, 10:23
Хмм......способ интересный....попробую, но меня интересует еще следующее:
smile
У меня генерируется объект на сгенерированной форме,

А я на сколько знаю, если создается новая форма, создается хедеровский файл и там описываются подобные функции...

Добавлено @ 10:32 
Anikmar,
Цитата(Anikmar @  15.1.2007,  00:53 Найти цитируемый пост)
 // Имя сгенерированного обработчика

Понял, что не понял что ты имеешь ввиду....

Автор: Vyacheslav 15.1.2007, 10:39
А что сложного? Много раз уже обсасывали
Декларируешь и определяешь соответствующий опбработчик прямо ручками.  Хотя бы в хидере и реализации той же формы 
Код

class TYourForm : public TForm
//...
public:
void __fastcall CSpinEditChange(TObject* Sender);
//...

Код

void __fastcall TYourForm::CSpinEditChange(TObject* Sender)
{
//...
}

Код

idx->OnChange = CSpinEditChange;



Автор: Mpak 15.1.2007, 10:46
Vyacheslav, Дело в том, что уже пробовал подобное...
В чем у меня различее с Вашим примером?
Код

class TFormmes : public TForm
{
__published:
         TLabel *Label1;
         TCSpinEdit *idx;

private:
public:
         void __fastcall idxChange(TObject *Sender);
         __fastcall TFormmes(TComponent* Owner);
};


Код

idx->OnChange=idxChange;


Код

void __fastcall TFormmes::idxChange(TObject *Sender)
{
 Label1->Caption=idx->Text;
}


Добавлено @ 10:48 
Пишет ошибку:
Undefined simbol 'idxChange'

На строку
idx->OnChange=idxChange;

Автор: Anikmar 15.1.2007, 11:09
Цитата(Mpak @  15.1.2007,  10:46 Найти цитируемый пост)
Пишет ошибку:
Undefined simbol 'idxChange'

На строку
idx->OnChange=idxChange; 


Эта строка точно в методе TFormmes?

Автор: Mpak 15.1.2007, 11:26
Anikmar, то есть?
Вроде да...

Автор: Anikmar 15.1.2007, 11:27
Цитата(Mpak @  15.1.2007,  10:23 Найти цитируемый пост)
Понял, что не понял что ты имеешь ввиду.... 


Я имел в виду имя, автоматическои сгенерированное при моем подходе.
Разницы никакой - я просто не люблю много ручками писать.
Можно просто добавить метод - тогда имя из головы.
Я предпочитаю автосгенерированное.

Добавлено @ 11:29 
Цитата(Mpak @  15.1.2007,  11:26 Найти цитируемый пост)
Anikmar, то есть?
Вроде да... 

Вроде или да?
Если внутри класса - то idxChange виден, а если нет, то что-то вроде этого: MyForm->idxChange

Добавлено @ 11:30 
Мой совет:
Все динамические компоненты создавая в конструкторе формы - меньше ошибок будет.

Лично я динамически компоненты очень редко создаю - только в навороченных диалогах. В большинстве случаев контролы можно предусмотреть заранее и создавать динамически только саму форму. Но это, конечно от задач конкретных зависит.

Автор: Mpak 15.1.2007, 12:05
Цитата(Anikmar @  15.1.2007,  14:27 Найти цитируемый пост)
 Но это, конечно от задач конкретных зависит.

Я просто учусь  smile 

Вот где я ее описал:
Код

class TFormmes : public TForm
{
__published:
         TLabel *Label1;
         TCSpinEdit *idx;

private:
public:
         void __fastcall idxChange(TObject *Sender);
         __fastcall TFormmes(TComponent* Owner);
};


У меня еще сомнения где ее описать правильнее в __published или в public...

Автор: pandrew 15.1.2007, 12:14
Цитата(Mpak @  15.1.2007,  12:05 Найти цитируемый пост)
У меня еще сомнения где ее описать правильнее в __published или в public... 

Можно в private, но только не в __published 

Автор: Mpak 15.1.2007, 12:24
Все равно для него моя функция нехороший символ smile

Автор: GIK 15.1.2007, 12:42
Цитата

Все равно для него моя функция нехороший символ 

От руки пишешь? 
Если делать с помошью програмки, то все нормально выходит..
А в __published : неужно заносить если хочешь чтобы свойства компонента были доступны через окно свойста среды булдера. 

Автор: Mpak 15.1.2007, 13:01
GIK, а как с помощью программки?
Формы то не существует...smile
Я хочу научится так вещи делать...
помогут жеsmile
Вот только застопорился....

Автор: Anikmar 15.1.2007, 13:18
Цитата(Mpak @  15.1.2007,  13:01 Найти цитируемый пост)
Формы то не существует...

Что значит не существует? Будешь всю форму динамически отрисовывать?! Это же муторно!

Рисуется форма - такая какая нужна, в опциях проекта она переносится из раздела AutoCreate в раздел Available. Потом динамически создается - все нарисованные на этапе проектирования контролы будут автоматически созданы. 

Автор: Vyacheslav 15.1.2007, 13:21
Судя по ошибке строка 
Код

idx->OnChange=idxChange;

точно располжена не в методах TFormmes.

Попробуй  так
Код

idx->OnChange= TFormmes::idxChange;

Автор: Mpak 15.1.2007, 13:34
Anikmar, понимаю, что муторно....но если это возможно, значит надо уметь smile


Vyacheslav, теперь ошибка
Cannot convert 'void (_fastcall TFormmes::*)(TObject *)' to 'void (_fastcall *(_closure)(TObject *))(TObject *)'

Не могу понять, что неправильно.... вот мой header'овский файл полностью:
Код

//---------------------------------------------------------------------------

#ifndef UGenerateH
#define UGenerateH
//---------------------------------------------------------------------------
#include <Classes.hpp>
#include <Controls.hpp>
#include <StdCtrls.hpp>
#include <Forms.hpp>
#include <ComCtrls.hpp>
#include <DBCtrls.hpp>
#include <ExtCtrls.hpp>
#include "CSPIN.h"
//---------------------------------------------------------------------------
class TForm1 : public TForm     //Это программой создано
{
__published:    // IDE-managed Components
        TButton *Button1;
        TButton *Button2;
        TCSpinEdit *CSpinEdit1;
        TLabel *Label1;
        void __fastcall Button1Click(TObject *Sender);
        void __fastcall Button2Click(TObject *Sender);
        void __fastcall CSpinEdit1Change(TObject *Sender);
private:    // User declarations
public:        // User declarations
        __fastcall TForm1(TComponent* Owner);
};
//---------------------------------------------------------------------------
extern PACKAGE TForm1 *Form1;
//---------------------------------------------------------------------------
class TFormmes : public TForm //это я сам вручную писал
{
__published:
         TLabel *lbl;
         TCSpinEdit *idx;
private:
public:
         void __fastcall idxChange(TObject *Sender);
         __fastcall TFormmes(TComponent* Owner);
};
//---------------------------------------------------------------------------
extern PACKAGE TFormmes *mes;
//---------------------------------------------------------------------------

#endif


Добавлено @ 13:38 
Созданные объекты:

Код

TFormmes *mes;
mes=new TFormmes(this);
mes->Left=554;
mes->Top=411;
mes->Height=160;
mes->Width=329;

TCSpinEdit *idx;
idx=new TCSpinEdit (mes);
idx->Parent=mes;
idx->Top=8;
idx->Left=230;
idx->Height=22;
idx->Width=49;
idx->OnChange=TFormmes::idxChange;

Автор: Anikmar 15.1.2007, 13:39
Vyacheslav, 
Я думаю не стоит так делать - теряется прозрачность и читаемость.

Если человек учится, то лучше сразу писать по-человечески:

Если компонент на форме, то и создавать его надо в конструкторе формы, а обработчик - метод этой формы. Так проще отлаживаться и читать код легче.

Например:
Код

__fastcall TF_DynamicForm::TF_DynamicForm(TComponent* Owner)
    : TForm(Owner)
{
    CSpinEditMy = new TCSpinEdit(this);
    CSpinEditMy->Parent = this;
    CSpinEditMy->OnChange = CSpinEdit1Change;
    CSpinEditMy->Left = 10;
    CSpinEditMy->Top = 50;
    CSpinEditMy->Width = 100;
    CSpinEditMy->Height = 20;
    CSpinEditMy->Enabled = true;
    CSpinEditMy->Visible = true;
}
//---------------------------------------------------------------------------
void __fastcall TF_DynamicForm::CSpinEdit1Change(TObject *Sender)
{
    ShowMessage("Обработчик OnChange");
}


Автор: Vyacheslav 15.1.2007, 13:51
Код

idx->OnChange=mes->idxChange;


Добавлено @ 14:04 
Цитата(Mpak @  15.1.2007,  13:34 Найти цитируемый пост)

Код

class TFormmes : public TForm //это я сам вручную писал



Цитата(Mpak @  15.1.2007,  13:34 Найти цитируемый пост)
//это я сам вручную писал

Это не будет работать. При запуске программы получишь ошибку.
Resource TFormmes not found smile

Автор: Anikmar 15.1.2007, 14:35
Цитата(Mpak @  15.1.2007,  13:34 Найти цитируемый пост)
Anikmar, понимаю, что муторно....но если это возможно, значит надо уметь 


Vyacheslav, теперь ошибка
Cannot convert 'void (_fastcall TFormmes::*)(TObject *)' to 'void (_fastcall *(_closure)(TObject *))(TObject *)'

Не могу понять, что неправильно.... вот мой header'овский файл полностью:


На сколько я помню свои собственные эксперименты, у меня не получилось ввести обрработчик из другого класса (точно не помню). Дело в том, что обработчик обязательно имеет модификатор (_closure) - это означает, что в функцию передается адрес конкретного объекта.
Просто я в свое время прекратил эксперементировать с этим - так как практической пользы не увидел. Методы класса и все компоненты этого класса должны быть в одном месте - это удобнее и правильнее. Думаю, увидев это, кто-нибудь ответит более конкретно.

Добавлено @ 14:42 
Хм... Не, я не прав.
Делал - и все работает.
Можно обработчик вешать из другого объекта, тут я сам на себя наврал.

Но всетаки лучше все в одном классе делать

Добавлено @ 14:45 
Думаю ошибка здесь:
idx->OnChange=TFormmes::idxChange;
тут обработчику присваивается метод класса. Но это не _closure - это просто функция.
Чтобы она стала _closure надо передавать именно метод конкретного объекта, т.е.
idx->OnChange=mes->idxChange;

Автор: Mpak 15.1.2007, 14:45
Спсасибо за информацию smile

Автор: Vyacheslav 15.1.2007, 15:07
Цитата(Anikmar @  15.1.2007,  14:35 Найти цитируемый пост)
Думаю ошибка здесь:
idx->OnChange=TFormmes::idxChange;
тут обработчику присваивается метод класса. Но это не _closure - это просто функция.
Чтобы она стала _closure надо передавать именно метод конкретного объекта, т.е.
idx->OnChange=mes->idxChange;

Все правильно ... Только с учетом того, что эта строка 
Цитата(Vyacheslav @  15.1.2007,  13:51 Найти цитируемый пост)

Код

 idx->OnChange=mes->idxChange;


была вывешена за полчаса до этого объяснения, зачем править уже исправленные ошибки?  smile
 


Автор: Anikmar 15.1.2007, 15:18
Vyacheslav, Все правильно, просто иногда посты появляются быстрее, чем набиваешь ответ  smile 

Я просто это не увидел.  smile 

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)