Форум программистов «Весельчак У»
  *
Добро пожаловать, Гость. Пожалуйста, войдите или зарегистрируйтесь.
Вам не пришло письмо с кодом активации?

  • Рекомендуем проверить настройки временной зоны в вашем профиле (страница "Внешний вид форума", пункт "Часовой пояс:").
  • У нас больше нет рассылок. Если вам приходят письма от наших бывших рассылок mail.ru и subscribe.ru, то знайте, что это не мы рассылаем.
   Начало  
Наши сайты
Помощь Поиск Календарь Почта Войти Регистрация  
 
Страниц: 1 2 [Все]   Вниз
  Печать  
Автор Тема: Вопрос: События, классы CBuilder  (Прочитано 29269 раз)
0 Пользователей и 1 Гость смотрят эту тему.
Калессин
Гость
« : 01-07-2003 03:19 » 

Начальные условия:
пользователем СBuilder создан класс, одним из атрибутов которого является класс VCL, пусть для примера будет TEdit:

Код:
class TExample
{
 TEdit *Edit0;
 ...
 void Modification();
 ...
} *Example0;

Создается экземпляр данного класса и ему передается указатель на экземпляр класса TEdit, созданный в начале работы приложения.

Вопрос:
Возможно ли написать класс так, чтобы функция Modification() вызывалась при событии OnClick ?
Т.е. если считать за данное, что обычный способ: щелкнуть мышкой на нужную кнопку и прописать в сгенерированной CBuilder процедуре Example0->Modification(); - не устраивает (Представьте что таких ExampleX много)
« Последнее редактирование: 18-11-2007 05:53 от Алексей1153++ » Записан
Гром
Птычк. Тьфу, птычник... Вот!
Готовлюсь к пенсии

il
Offline Offline
Пол: Мужской
Бодрый птах


« Ответ #1 : 01-07-2003 05:16 » 

А перехватить вызов WM_MESSAGE нельзя???
Или в Билдере такого нет.

Если есть то WM_LBOTTONCLICK такое события генерится на левую кнопку мыши, на него надо повесить свой обработчик и не вызывать из него стандартный, вот собственно и все.
Записан

А птичку нашу прошу не обижать!!!
Diletant
Помогающий

de
Offline Offline

« Ответ #2 : 01-07-2003 09:30 » 

Не совсем понятно изложено. Даже не придираясь к неккорректностям в изложении, остаются вопросы:
На что, вообще говоря, кликаем?
Класс TExample является наследником какого-нибудь Window-класса или?
Записан
Aleck D.Shadow
Опытный

ru
Offline Offline
Пол: Мужской

« Ответ #3 : 01-07-2003 12:42 » 

Проще всего в конструкторе класса TExample написать
так
Edit0->OnClick = Modification;

или скорее всего так не пойдет, нужна будет промежуточная процедура, но примерно так.
Записан
Diletant
Помогающий

de
Offline Offline

« Ответ #4 : 02-07-2003 11:39 » 

Цитата
Edit0->OnClick = Modification;


Неужели и правда можно таким образом методы класса переопределять? Даже хотя бы в ВСВ? Вот уж никогда бы не подумал...
Записан
Гром
Птычк. Тьфу, птычник... Вот!
Готовлюсь к пенсии

il
Offline Offline
Пол: Мужской
Бодрый птах


« Ответ #5 : 02-07-2003 11:48 » 

Везде можно переопределять не только в ВС...  Ага
Записан

А птичку нашу прошу не обижать!!!
Diletant
Помогающий

de
Offline Offline

« Ответ #6 : 02-07-2003 13:15 » 

Цитата

Везде можно переопределять не только в ВС...


"Не верю !!!" К.Станиславский. :?
Нельзя ли кусочек компилирующегося кода или ссылочку на таковой?
Записан
baldr
Команда клуба

ru
Offline Offline
Пол: Мужской
Дорогие россияне


WWW
« Ответ #7 : 02-07-2003 13:19 » 

Это называется "перегрузка".
Или, если метод - виртуальный, то просто определение метода...
class ABC
{
  virtual int Get();
};

И любая прога, юзающая объекты класса ABC должна по-своему переопределить этот метод, если она его использует.
Записан

Приличный компьютер всегда будет стоить дороже 1000 долларов, потому что 500 долларов - это не вполне прилично
Diletant
Помогающий

de
Offline Offline

« Ответ #8 : 02-07-2003 13:25 » 

Цитата

Это называется "перегрузка".
Или, если метод - виртуальный, то просто определение метода...
class ABC
{
virtual int Get();
};

И любая прога, юзающая объекты класса ABC должна по-своему переопределить этот метод, если она его использует.


А вот этого не надо.  Не любая прога, а любой класс-наследник класса АВС может (но не должен) переопределить виртуальный метод... Здесь же речь идет о совершенно постороннем классе и совершенно левой функции.
Записан
baldr
Команда клуба

ru
Offline Offline
Пол: Мужской
Дорогие россияне


WWW
« Ответ #9 : 02-07-2003 13:38 » 

Ну, не обязательно наследник. Может и просто сам этот класс...
А в данном случае (Edit0->OnClick = Modification;) у нас присутствует просто указатель на метод. И ты сам пишешь обработчик (который потом будет этим методом) и его адрес даешь указателю. А объект потом его вызывает.
Записан

Приличный компьютер всегда будет стоить дороже 1000 долларов, потому что 500 долларов - это не вполне прилично
Diletant
Помогающий

de
Offline Offline

« Ответ #10 : 02-07-2003 13:51 » 

Цитата
А в данном случае (Edit0->OnClick = Modification;) у нас присутствует просто указатель на метод. И ты сам пишешь обработчик (который потом будет этим методом) и его адрес даешь указателю. А объект потом его вызывает.


Все написанное не соответствует моему представлению о предмете. Так же как до сих пор я считал, что указатель на функцию не имеет права стоять в левой части равенства. Но так как я отнюдь не претендую на абсолютное знание предмета, а подобная возможность существенно упрощает ряд задач, то код - в студию! Отлично
Записан
Гром
Птычк. Тьфу, птычник... Вот!
Готовлюсь к пенсии

il
Offline Offline
Пол: Мужской
Бодрый птах


« Ответ #11 : 02-07-2003 14:18 » 

Нуууу - тут явный пробел в знаниях - тут мне прислал Слава С++ стандарт надеюсь там будет подробно - а пока вот что...

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

Одной из лучших ИХО сторон объектного программинга можно считать возможность создавать класс отэц Улыбаюсь который будет иметь пустую функцию с объявлением типа virtual void XXX(void);
Эта функция в самом классе предусматривает обладание какими либо свойствами, скажем она умеет определять какой из элементов БД больше - по типу переданных параметров.

Ее можно будет использовать для сортировки, если класс наследник перепропишет ее так как нужно ему и внутри напишет алгоритм сравнения, о котором класс отэц и понятия не имеет.

Но не глядя на такие вот вещеи папаша имея такую функцию с легкостью будет сортировать на базе этой функции как набор чисел так и сложнейшую структуру ключей БД....
Записан

А птичку нашу прошу не обижать!!!
baldr
Команда клуба

ru
Offline Offline
Пол: Мужской
Дорогие россияне


WWW
« Ответ #12 : 02-07-2003 14:31 » 

Цитата: Гром
Любой сайт и любой его наследник...

Зарапортовались, батенька! Улыбаюсь Улыбаюсь Улыбаюсь
Записан

Приличный компьютер всегда будет стоить дороже 1000 долларов, потому что 500 долларов - это не вполне прилично
Гром
Птычк. Тьфу, птычник... Вот!
Готовлюсь к пенсии

il
Offline Offline
Пол: Мужской
Бодрый птах


« Ответ #13 : 02-07-2003 14:37 » 

Отлично КЛАСС - конечно....
Да эти переезды до добра не доведут
  Здесь была моя ладья...
Записан

А птичку нашу прошу не обижать!!!
Diletant
Помогающий

de
Offline Offline

« Ответ #14 : 02-07-2003 14:39 » 

Уважаемый Гром.
Все, о чем ты тут  излагаешь,  вещи известные даже мне, но речь здесь немного не о том. Автору предлагают сделать прмерно следующее:
Цитата

class a
{
public:
   virtual int a1 (){return 19;};
};
class b
{
public:
   a* ao;
   b();
   int  b1(){return 25;};
};
b::b()
{
   ao->a1 = b1;
}


Так по моему мнению, выделенное компилятор не пропустит. Если я неправ, примерчик, пожалуйста.
Записан
baldr
Команда клуба

ru
Offline Offline
Пол: Мужской
Дорогие россияне


WWW
« Ответ #15 : 02-07-2003 14:49 » 

Нет, конечно!
Я ж говорю - указатель в таком случае на функцию надо!
А в твоем случае можно сделать так:
Код:
class a
{
public:
virtual int a1 ();              //{return 19;};
};
class b
{
public:
a* ao;
b();
int b1(){return 25;};
};

int a::a1() { return 1;}

Но заметь - у a1 не должно быть тела! Иначе - только наследованием и перегрузкой поможет...
« Последнее редактирование: 18-11-2007 05:57 от Алексей1153++ » Записан

Приличный компьютер всегда будет стоить дороже 1000 долларов, потому что 500 долларов - это не вполне прилично
Diletant
Помогающий

de
Offline Offline

« Ответ #16 : 02-07-2003 14:58 » 

А где аналог:

Edit0->OnClick = Modification;

Можно изменять код как угодно, но но нужен пример с указателем на фукцию as left operand.
Записан
Гром
Птычк. Тьфу, птычник... Вот!
Готовлюсь к пенсии

il
Offline Offline
Пол: Мужской
Бодрый птах


« Ответ #17 : 02-07-2003 15:22 » 

Тут разница видимо в понимании указателей на функцию в Дельфи и в С++.

То что ты показал - сработает если скажем я напишу так...

LPVOID WINAPI AAA(VOID * pParam);
{
// Тело
}


.....


{

VOID * pFunc;
INT Param

pFunc = AAA;

pFunc((void *)&Param);   // Вызов функции...

}

По идее может быть слева и поинтер на функцию - но вот конкретного примера нету...и компилятор только завтра под руку попадется.
Записан

А птичку нашу прошу не обижать!!!
Lex
Специалист

ru
Offline Offline

WWW
« Ответ #18 : 02-07-2003 15:32 » 

Edit0->OnClick = Modification;

Этоименно так и делается, только Modification должна быть определенного вида, какого это надо в хелпе смотреть.

Реализуется это перегрузкой оператора =
Записан

Megabyte be with you!
Diletant
Помогающий

de
Offline Offline

« Ответ #19 : 02-07-2003 15:43 » 

Цитата: Гром


{

VOID * pFunc;
INT Param

pFunc = AAA;

pFunc((void *)&Param);   // Вызов функции...

}

По идее может быть слева и поинтер на функцию - но вот конкретного примера нету...и компилятор только завтра под руку попадется.


Так как ты написал я и сам иногда делаю. В данном случае это локальная или глобальная переменная, которой присваивают указатель на существующую функцию. Здесь же функция (в данном случае, метод) уже определена (описана в определении класса), и указатель на нее как-то пытаются переопределить. Это не зависит никак от типа компилятора. В VC не сработает так же, как и в ВС. IMHO, естественно.
Записан
Diletant
Помогающий

de
Offline Offline

« Ответ #20 : 02-07-2003 15:44 » 

Цитата: Lex
Edit0->OnClick = Modification;

Этоименно так и делается, только Modification должна быть определенного вида, какого это надо в хелпе смотреть.

Реализуется это перегрузкой оператора =


Могу только повторить: Код в студию  Улыбаюсь
Записан
Гром
Птычк. Тьфу, птычник... Вот!
Готовлюсь к пенсии

il
Offline Offline
Пол: Мужской
Бодрый птах


« Ответ #21 : 02-07-2003 15:59 » 

Цитата: Diletant
Цитата: Гром


{

VOID * pFunc;
INT Param

pFunc = AAA;

pFunc((void *)&Param);   // Вызов функции...

}

По идее может быть слева и поинтер на функцию - но вот конкретного примера нету...и компилятор только завтра под руку попадется.


Так как ты написал я и сам иногда делаю. В данном случае это локальная или глобальная переменная, которой присваивают указатель на существующую функцию. Здесь же функция (в данном случае, метод) уже определена (описана в определении класса), и указатель на нее как-то пытаются переопределить. Это не зависит никак от типа компилятора. В VC не сработает так же, как и в ВС. IMHO, естественно.


Нет - виртуальная функция еще не определена как таковая и должна быть определена, точнее скажу как добирусь до полного описания...
Записан

А птичку нашу прошу не обижать!!!
Diletant
Помогающий

de
Offline Offline

« Ответ #22 : 02-07-2003 16:32 » 

Цитата

Нет - виртуальная функция еще не определена как таковая и должна быть определена, точнее скажу как добирусь до полного описания...


Да что ты вцепился так в виртуальные функции? Хорошо, попытаюсь перевести на язык MFC
Цитата

class TExample
{
 СDialog *ModDlg;
 ...
 void Modification();
 ...
} *Example0;

Создается экземпляр данного класса и ему передается указатель на наследник класса , созданный в начале работы приложения.
Вопрос:
Возможно ли написать класс так, чтобы функция Modification() вызывалась при событии OnOK ?
Т.е. если считать за данное, что обычный способ: щелкнуть мышкой на нужную кнопку и прописать в сгенерированной CBuilder процедуре Example0->Modification(); - не устраивает (Представьте что таких ExampleX много)



Так вот, в качестве решения предлагается в конструктор класса TЕxample записать ModDlg->OnOK = Modification;
И этот код должен работать? Не верю! См. выше.  Улыбаюсь
Записан
Гром
Птычк. Тьфу, птычник... Вот!
Готовлюсь к пенсии

il
Offline Offline
Пол: Мужской
Бодрый птах


« Ответ #23 : 02-07-2003 17:00 » 

Ну так как BC я не пользова л - отвечу - да можно...
Делается это так....

MFC

Описание

afx_msg void Modification();
----------------------------------
...
ON_MESSAGE(WM_CLICK, Modification);
...


При любом  нажатии на кнопку - будет делаться вызов функции


В API

......

switch (message)
{

....

case WM_CLICK:
Modification();
....
}


При обычном описании....


Если я тебя правильно понял .....
Записан

А птичку нашу прошу не обижать!!!
Гром
Птычк. Тьфу, птычник... Вот!
Готовлюсь к пенсии

il
Offline Offline
Пол: Мужской
Бодрый птах


« Ответ #24 : 02-07-2003 17:03 » 

Иначе можно сделать и не так, т.е. предствавив что много таких функций, то все равно тебе придется привязывать указатели, я не уверен (уже говорил - проверю скажу, ))) но имхо - можно перепрописать массив указателей на функции и в цикле их переназначить...
Записан

А птичку нашу прошу не обижать!!!
Diletant
Помогающий

de
Offline Offline

« Ответ #25 : 02-07-2003 17:20 » 

Цитата: Гром


Если я тебя правильно понял .....


Это был не мой вопрос, и я не пользую сейчас BC. Единственное, что меня интересовало, так это работает ли эта странная конструкция с достаточно странным переприсвоениесм указателя на существующую функцию. После некоторого размышления и текущего обсуждения, я уверен, что такого не может быть никогда. А жаль, могли быть очень интересные варианты применения. Улыбаюсь
Записан
Калессин
Гость
« Ответ #26 : 03-07-2003 02:45 » 

Спасибо, Aleck D.Shadow-у,
работает  Улыбаюсь
даже стыдно стало, что сам не додумался   Вот такой я вот
Записан
PSD
Главный специалист

ru
Offline Offline
Пол: Мужской

« Ответ #27 : 03-07-2003 04:55 » 

Цитата

Edit0->OnClick = Modification;

А какой физический смыс несет такая конструкция?
По идее ее можно интепритировать как попытку записать в таблицу виртуальных функций новый адрес.
Это так?
Записан

Да да нет нет все остальное от лукавого.
Lex
Специалист

ru
Offline Offline

WWW
« Ответ #28 : 03-07-2003 05:14 » 

Цитата: Diletant
Цитата: Lex
Edit0->OnClick = Modification;

Этоименно так и делается, только Modification должна быть определенного вида, какого это надо в хелпе смотреть.

Реализуется это перегрузкой оператора =


Могу только повторить: Код в студию  Улыбаюсь


Event OnClick  объявляется как:
__property Classes::TNotifyEvent OnClick

TNotifyEvent объявлен вот так:
typedef void __fastcall (__closure *TNotifyEvent)(System::TObject* Sender);

Идет чесное присвоение указателя на функцию.
Только Message должна объявляться как
void Message(TObject *Sender);
Записан

Megabyte be with you!
Гром
Птычк. Тьфу, птычник... Вот!
Готовлюсь к пенсии

il
Offline Offline
Пол: Мужской
Бодрый птах


« Ответ #29 : 03-07-2003 06:18 » 

Diletant, мы спорили спорили Улыбаюсь вот тебе и ответ...  Ага
Записан

А птичку нашу прошу не обижать!!!
Антон (LogRus)
Глобальный модератор

ru
Offline Offline
Пол: Мужской
Внимание! Люблю сахар в кубиках!


WWW
« Ответ #30 : 05-07-2003 19:46 » 

Вот вам типичный примет приработе с БД!
Код:

  tmpfield=new TBCDField(Form1->ADOQuery1);
  tmpfield->FieldName="ProductSumm};
  tmpfield->FieldKind=fkCalculated;
  tmpfield->DataSet=((TADOQuery *)tmpfield->Owner);
  tmpfield->Name=tmpfield->Owner->Name+tmpfield->FieldName;
  tmpfield->DisplayLabel="Сумма};
  tmpfield->DisplayWidth=15;

  Form1->ADOQuery1->OnCalcFields=SummCalcFields;

А вот метод SummCalcFields:
Код:
void __fastcall TForm1::SummCalcFields(TDataSet *DataSet)
{
  int count=DataSet->FieldByName("ProductStore")->AsInteger;
  float price=DataSet->FieldByName("ProductPrice")->AsFloat;

  DataSet->FieldByName("ProductSumm")->AsFloat=count*price;
}
« Последнее редактирование: 18-11-2007 06:01 от Алексей1153++ » Записан

Странно всё это....
Калессин
Гость
« Ответ #31 : 07-07-2003 03:20 » 

не народ, вы так еще долго спорить будете:)
пишу код:
class TExample
{
TEdit *Edit0;

void Init(TEdit *E0);
void Modification(void);
...
...
}
void TExample::Init(TEdit *E0)
{
TNotifyEvent PtrFunc;
PtrFunc = TNotifyEvent (&this->Modification);
Edit0 = E0;
Edit0->OnClick = PtrFunc;
}
...

где-то в программе:
TExample *Example0;
Example0 = new (TExample);
Example0->Init(Edit1);
Записан
sss
Специалист

ru
Offline Offline

« Ответ #32 : 07-07-2003 08:44 » 

Короче та же тема что и "как получить метод виртуального класса в VC".
Посмотрите, я тут с Borland компиляторов перелезть пытаюсь. Определение
of object нет в стандартном С++
Записан

while (8==8)
Lex
Специалист

ru
Offline Offline

WWW
« Ответ #33 : 07-07-2003 09:01 » 

Цитата

не народ, вы так еще долго спорить будете


Уже давно никто не спорит. Решение было дано почти сразу, объяснение, почему оно работает, чуть позже.

Цитата

Короче та же тема что и "как получить метод виртуального класса в VC".
Посмотрите, я тут с Borland компиляторов перелезть пытаюсь. Определение
of object нет в стандартном С++


Не совсем. Здесь используется вполне стандартные вещи из С++(может быть и С, но голый С я давно не пользую, поэтому утверждать не буду)
Записан

Megabyte be with you!
Страниц: 1 2 [Все]   Вверх
  Печать  
 

Powered by SMF 1.1.21 | SMF © 2015, Simple Machines