Калессин
Гость
|
|
« : 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++ »
|
Записан
|
|
|
|
Гром
Птычк. Тьфу, птычник... Вот!
Готовлюсь к пенсии
Offline
Пол:
Бодрый птах
|
|
« Ответ #1 : 01-07-2003 05:16 » |
|
А перехватить вызов WM_MESSAGE нельзя??? Или в Билдере такого нет.
Если есть то WM_LBOTTONCLICK такое события генерится на левую кнопку мыши, на него надо повесить свой обработчик и не вызывать из него стандартный, вот собственно и все.
|
|
|
Записан
|
А птичку нашу прошу не обижать!!!
|
|
|
Diletant
Помогающий
Offline
|
|
« Ответ #2 : 01-07-2003 09:30 » |
|
Не совсем понятно изложено. Даже не придираясь к неккорректностям в изложении, остаются вопросы: На что, вообще говоря, кликаем? Класс TExample является наследником какого-нибудь Window-класса или?
|
|
|
Записан
|
|
|
|
Aleck D.Shadow
|
|
« Ответ #3 : 01-07-2003 12:42 » |
|
Проще всего в конструкторе класса TExample написать так Edit0->OnClick = Modification;
или скорее всего так не пойдет, нужна будет промежуточная процедура, но примерно так.
|
|
|
Записан
|
|
|
|
Diletant
Помогающий
Offline
|
|
« Ответ #4 : 02-07-2003 11:39 » |
|
Edit0->OnClick = Modification; Неужели и правда можно таким образом методы класса переопределять? Даже хотя бы в ВСВ? Вот уж никогда бы не подумал...
|
|
|
Записан
|
|
|
|
Гром
Птычк. Тьфу, птычник... Вот!
Готовлюсь к пенсии
Offline
Пол:
Бодрый птах
|
|
« Ответ #5 : 02-07-2003 11:48 » |
|
Везде можно переопределять не только в ВС...
|
|
|
Записан
|
А птичку нашу прошу не обижать!!!
|
|
|
Diletant
Помогающий
Offline
|
|
« Ответ #6 : 02-07-2003 13:15 » |
|
Везде можно переопределять не только в ВС...
"Не верю !!!" К.Станиславский. :? Нельзя ли кусочек компилирующегося кода или ссылочку на таковой?
|
|
|
Записан
|
|
|
|
baldr
|
|
« Ответ #7 : 02-07-2003 13:19 » |
|
Это называется "перегрузка". Или, если метод - виртуальный, то просто определение метода... class ABC { virtual int Get(); };
И любая прога, юзающая объекты класса ABC должна по-своему переопределить этот метод, если она его использует.
|
|
|
Записан
|
Приличный компьютер всегда будет стоить дороже 1000 долларов, потому что 500 долларов - это не вполне прилично
|
|
|
Diletant
Помогающий
Offline
|
|
« Ответ #8 : 02-07-2003 13:25 » |
|
Это называется "перегрузка". Или, если метод - виртуальный, то просто определение метода... class ABC { virtual int Get(); };
И любая прога, юзающая объекты класса ABC должна по-своему переопределить этот метод, если она его использует.
А вот этого не надо. Не любая прога, а любой класс-наследник класса АВС может (но не должен) переопределить виртуальный метод... Здесь же речь идет о совершенно постороннем классе и совершенно левой функции.
|
|
|
Записан
|
|
|
|
baldr
|
|
« Ответ #9 : 02-07-2003 13:38 » |
|
Ну, не обязательно наследник. Может и просто сам этот класс... А в данном случае (Edit0->OnClick = Modification;) у нас присутствует просто указатель на метод. И ты сам пишешь обработчик (который потом будет этим методом) и его адрес даешь указателю. А объект потом его вызывает.
|
|
|
Записан
|
Приличный компьютер всегда будет стоить дороже 1000 долларов, потому что 500 долларов - это не вполне прилично
|
|
|
Diletant
Помогающий
Offline
|
|
« Ответ #10 : 02-07-2003 13:51 » |
|
А в данном случае (Edit0->OnClick = Modification;) у нас присутствует просто указатель на метод. И ты сам пишешь обработчик (который потом будет этим методом) и его адрес даешь указателю. А объект потом его вызывает.
Все написанное не соответствует моему представлению о предмете. Так же как до сих пор я считал, что указатель на функцию не имеет права стоять в левой части равенства. Но так как я отнюдь не претендую на абсолютное знание предмета, а подобная возможность существенно упрощает ряд задач, то код - в студию!
|
|
|
Записан
|
|
|
|
Гром
Птычк. Тьфу, птычник... Вот!
Готовлюсь к пенсии
Offline
Пол:
Бодрый птах
|
|
« Ответ #11 : 02-07-2003 14:18 » |
|
Нуууу - тут явный пробел в знаниях - тут мне прислал Слава С++ стандарт надеюсь там будет подробно - а пока вот что... Любой сайт и любой его наследник обладают определенными правами и свойствами в зависимости от типа наследования и вида фукций.... Одной из лучших ИХО сторон объектного программинга можно считать возможность создавать класс отэц который будет иметь пустую функцию с объявлением типа virtual void XXX(void); Эта функция в самом классе предусматривает обладание какими либо свойствами, скажем она умеет определять какой из элементов БД больше - по типу переданных параметров. Ее можно будет использовать для сортировки, если класс наследник перепропишет ее так как нужно ему и внутри напишет алгоритм сравнения, о котором класс отэц и понятия не имеет. Но не глядя на такие вот вещеи папаша имея такую функцию с легкостью будет сортировать на базе этой функции как набор чисел так и сложнейшую структуру ключей БД....
|
|
|
Записан
|
А птичку нашу прошу не обижать!!!
|
|
|
baldr
|
|
« Ответ #12 : 02-07-2003 14:31 » |
|
Любой сайт и любой его наследник... Зарапортовались, батенька!
|
|
|
Записан
|
Приличный компьютер всегда будет стоить дороже 1000 долларов, потому что 500 долларов - это не вполне прилично
|
|
|
Гром
Птычк. Тьфу, птычник... Вот!
Готовлюсь к пенсии
Offline
Пол:
Бодрый птах
|
|
« Ответ #13 : 02-07-2003 14:37 » |
|
КЛАСС - конечно.... Да эти переезды до добра не доведут
|
|
|
Записан
|
А птичку нашу прошу не обижать!!!
|
|
|
Diletant
Помогающий
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
|
|
« Ответ #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
Помогающий
Offline
|
|
« Ответ #16 : 02-07-2003 14:58 » |
|
А где аналог:
Edit0->OnClick = Modification;
Можно изменять код как угодно, но но нужен пример с указателем на фукцию as left operand.
|
|
|
Записан
|
|
|
|
Гром
Птычк. Тьфу, птычник... Вот!
Готовлюсь к пенсии
Offline
Пол:
Бодрый птах
|
|
« Ответ #17 : 02-07-2003 15:22 » |
|
Тут разница видимо в понимании указателей на функцию в Дельфи и в С++.
То что ты показал - сработает если скажем я напишу так...
LPVOID WINAPI AAA(VOID * pParam); { // Тело }
.....
{
VOID * pFunc; INT Param
pFunc = AAA;
pFunc((void *)&Param); // Вызов функции...
}
По идее может быть слева и поинтер на функцию - но вот конкретного примера нету...и компилятор только завтра под руку попадется.
|
|
|
Записан
|
А птичку нашу прошу не обижать!!!
|
|
|
Lex
|
|
« Ответ #18 : 02-07-2003 15:32 » |
|
Edit0->OnClick = Modification;
Этоименно так и делается, только Modification должна быть определенного вида, какого это надо в хелпе смотреть.
Реализуется это перегрузкой оператора =
|
|
|
Записан
|
Megabyte be with you!
|
|
|
Diletant
Помогающий
Offline
|
|
« Ответ #19 : 02-07-2003 15:43 » |
|
{
VOID * pFunc; INT Param
pFunc = AAA;
pFunc((void *)&Param); // Вызов функции...
}
По идее может быть слева и поинтер на функцию - но вот конкретного примера нету...и компилятор только завтра под руку попадется.
Так как ты написал я и сам иногда делаю. В данном случае это локальная или глобальная переменная, которой присваивают указатель на существующую функцию. Здесь же функция (в данном случае, метод) уже определена (описана в определении класса), и указатель на нее как-то пытаются переопределить. Это не зависит никак от типа компилятора. В VC не сработает так же, как и в ВС. IMHO, естественно.
|
|
|
Записан
|
|
|
|
Diletant
Помогающий
Offline
|
|
« Ответ #20 : 02-07-2003 15:44 » |
|
Edit0->OnClick = Modification;
Этоименно так и делается, только Modification должна быть определенного вида, какого это надо в хелпе смотреть.
Реализуется это перегрузкой оператора = Могу только повторить: Код в студию
|
|
|
Записан
|
|
|
|
Гром
Птычк. Тьфу, птычник... Вот!
Готовлюсь к пенсии
Offline
Пол:
Бодрый птах
|
|
« Ответ #21 : 02-07-2003 15:59 » |
|
{
VOID * pFunc; INT Param
pFunc = AAA;
pFunc((void *)&Param); // Вызов функции...
}
По идее может быть слева и поинтер на функцию - но вот конкретного примера нету...и компилятор только завтра под руку попадется.
Так как ты написал я и сам иногда делаю. В данном случае это локальная или глобальная переменная, которой присваивают указатель на существующую функцию. Здесь же функция (в данном случае, метод) уже определена (описана в определении класса), и указатель на нее как-то пытаются переопределить. Это не зависит никак от типа компилятора. В VC не сработает так же, как и в ВС. IMHO, естественно. Нет - виртуальная функция еще не определена как таковая и должна быть определена, точнее скажу как добирусь до полного описания...
|
|
|
Записан
|
А птичку нашу прошу не обижать!!!
|
|
|
Diletant
Помогающий
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; И этот код должен работать? Не верю! См. выше.
|
|
|
Записан
|
|
|
|
Гром
Птычк. Тьфу, птычник... Вот!
Готовлюсь к пенсии
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(); .... }
При обычном описании....
Если я тебя правильно понял .....
|
|
|
Записан
|
А птичку нашу прошу не обижать!!!
|
|
|
Гром
Птычк. Тьфу, птычник... Вот!
Готовлюсь к пенсии
Offline
Пол:
Бодрый птах
|
|
« Ответ #24 : 02-07-2003 17:03 » |
|
Иначе можно сделать и не так, т.е. предствавив что много таких функций, то все равно тебе придется привязывать указатели, я не уверен (уже говорил - проверю скажу, ))) но имхо - можно перепрописать массив указателей на функции и в цикле их переназначить...
|
|
|
Записан
|
А птичку нашу прошу не обижать!!!
|
|
|
Diletant
Помогающий
Offline
|
|
« Ответ #25 : 02-07-2003 17:20 » |
|
Если я тебя правильно понял .....
Это был не мой вопрос, и я не пользую сейчас BC. Единственное, что меня интересовало, так это работает ли эта странная конструкция с достаточно странным переприсвоениесм указателя на существующую функцию. После некоторого размышления и текущего обсуждения, я уверен, что такого не может быть никогда. А жаль, могли быть очень интересные варианты применения.
|
|
|
Записан
|
|
|
|
Калессин
Гость
|
|
« Ответ #26 : 03-07-2003 02:45 » |
|
Спасибо, Aleck D.Shadow-у, работает даже стыдно стало, что сам не додумался
|
|
|
Записан
|
|
|
|
PSD
Главный специалист
Offline
Пол:
|
|
« Ответ #27 : 03-07-2003 04:55 » |
|
Edit0->OnClick = Modification;
А какой физический смыс несет такая конструкция? По идее ее можно интепритировать как попытку записать в таблицу виртуальных функций новый адрес. Это так?
|
|
|
Записан
|
Да да нет нет все остальное от лукавого.
|
|
|
Lex
|
|
« Ответ #28 : 03-07-2003 05:14 » |
|
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!
|
|
|
Гром
Птычк. Тьфу, птычник... Вот!
Готовлюсь к пенсии
Offline
Пол:
Бодрый птах
|
|
« Ответ #29 : 03-07-2003 06:18 » |
|
Diletant, мы спорили спорили вот тебе и ответ...
|
|
|
Записан
|
А птичку нашу прошу не обижать!!!
|
|
|
|