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

  • Рекомендуем проверить настройки временной зоны в вашем профиле (страница "Внешний вид форума", пункт "Часовой пояс:").
  • У нас больше нет рассылок. Если вам приходят письма от наших бывших рассылок mail.ru и subscribe.ru, то знайте, что это не мы рассылаем.
   Начало  
Наши сайты
Помощь Поиск Календарь Почта Войти Регистрация  
 
Страниц: [1] 2  Все   Вниз
  Печать  
Автор Тема: Вопрос: События, классы CBuilder  (Прочитано 45555 раз)
0 Пользователей и 6 Гостей смотрят эту тему.
Калессин
Гость
« : 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
Опытный

tr
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
Команда клуба

cy
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
Команда клуба

cy
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
Команда клуба

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


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

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

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

Приличный компьютер всегда будет стоить дороже 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
Команда клуба

cy
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, мы спорили спорили Улыбаюсь вот тебе и ответ...  Ага
Записан

А птичку нашу прошу не обижать!!!
Страниц: [1] 2  Все   Вверх
  Печать  
 

Powered by SMF 1.1.21 | SMF © 2015, Simple Machines