Справочник функций

Ваш аккаунт

Войти через: 
Забыли пароль?
Регистрация
Информацию о новых материалах можно получать и без регистрации:

Почтовая рассылка

Подписчиков: -1
Последний выпуск: 19.06.2015

Не перехватываются события OnExit и OnEnter

493
07 апреля 2002 года
Taras
24 / / 20.09.2000
Создаю класс TExtEdit на базе ТЕdit.
В нем переопределяю обработчики событий OnExit, OnEnter и DblClick.
Динамически размещаю массив текстовых полей класса TExtEdit на TScrollBox.

Событие DblClick в классе TExtEdit перехватывается, а OnExit, OnEnter нет.

Если размещать элемент Edit на ScrollBox в ручную, события OnExit, OnEnter им перехватываються.


Вот класс TextEdit:
Заголовочный файл:

#include <Classes.hpp>
#include <Controls.hpp>

class TExtEdit : public TEdit
{
public:
__fastcall TExtEdit(TComponent* Owner);
private:
DYNAMIC void __fastcall Exit(void);
DYNAMIC void __fastcall Enter(void);
DYNAMIC void __fastcall DblClick(void);
protected:
};

Файл реализации:

#include <vcl.h>
#include &quot;TExtEdit.h&quot;
//----------------------------------------------------------------------------
__fastcall TExtEdit::TExtEdit(TComponent* Owner) : TEdit(Owner)
{
}
//----------------------------------------------------------------------------
void __fastcall TExtEdit::Exit(void)
{
ShowMessage(&quot;OnExit&quot;);
}
//----------------------------------------------------------------------------
void __fastcall TExtEdit::Enter(void)
{
ShowMessage(&quot;OnEnter&quot;);
}
//----------------------------------------------------------------------------
void __fastcall TExtEdit::DblClick(void)
{
ShowMessage(&quot;DBClick&quot;);
}


Массив текстовых полей на TscrollBox создаю так:

Заголовочный файл формы::

class TExtEdit;

typedef vector<TExtEdit*> tagArEdit;
typedef tagArEdit::iterator tagIterEdt;
……..
public:
tagArEdit ArrayEditInd;
……..

файл реализации формы:

……..
//Задаем длину массива
const int size = DM->DS1->RecordCount;
ArrayEditInd.resize(size);

//Создаем массив текстовых полей
for(begEdt = ArrayEditInd.begin(), endEdt = ArrayEditInd.end(); begEdt != endEdt; ++begEdt)
{ *begEdt = new TExtEdit((TComponent*)NULL);
(*begEdt)->Parent = ScrollBox1;
}
....
493
08 апреля 2002 года
Taras
24 / / 20.09.2000
С помощью карты сообщений удалось перехватывать событие OnEnter и OnExit (аналоги в Windows: WM_SETFOCUS WM_KILLFOCUS):

#include <Classes.hpp>
#include <Controls.hpp>

Class TExtEdit : public TEdit
{
public:

__fastcall TExtEdit(TComponent* Owner);

BEGIN_MESSAGE_MAP
VCL_MESSAGE_HANDLER(WM_KILLFOCUS, TWMKillFocus, OnExit)
END_MESSAGE_MAP(TComponent)

private:
protected:
void OnExit(TWMKillFocus&amp; Message);
};

Но, при перемещении между текстовыми полями происходить три «глюка»:

1. Автоматически не снимается выделение текста в текстовых полях.
2. При передаче фокуса другому текстовому полю, текстовый курсор не перемещается.
3. Событие OnExit происходит два раза, а не один.

295
20 августа 2002 года
gray_k
356 / / 20.12.1999
а если попробовать связать дочерний и родительский классы с помощью виртуальной функции?
8.2K
31 января 2006 года
TheMaster
32 / / 23.12.2005
Мне вообще-то надо только с событием OnExit справиться, которое возникает в компоненте TEdit. Ну, в смысле, переопределить. Умная книжка (Архангельский написал, про C++ Builder 5) говорит, что надо искать названия методов в справке сишки. В справке приводится метод DoExit, а по книжке, должен быть или просто Exit, или OnExit, сейчас не помню (дома Нета нету :-(.. )

Ладно, проблема не в этом. Посмотрел на пример, сделал, как умные люди сказали:
 
Код:
protected:
        DYNAMIC void __fastcall Exit(void);


//---------------------------------------------------------------------------
void __fastcall Exit(void)
{
MessageBox(NULL,"Потерян фокус ввода","Что-то случилось:",NULL);
}


Не работает! В смысле, когда я в пробной программе событие назначаю, и такой же код пишу, только с другим сообщением, то другое сообщение у меня и показывается. А вот то, которое в компоненте откомпилено - молчит, как партизан. Было предложение юзать MESSAGE_MAP. Оно меня, однако, не возбудило: я достаточно слабо представляю себе, как это реализовать на Builder'e (хотя пробовал и на TASM 5.0 приложения для форточек писать, так что о сообщениях наслышан), но не в этом дело. Этот метод работает тоже не так, как хочется! А первый должен работать (вроде бы...), но не работает! Может, кто-нибудь подскажет, почему?
1
31 января 2006 года
kot_
7.3K / / 20.01.2000
Цитата:
Originally posted by TheMaster
Мне вообще-то надо только с событием OnExit справиться, которое возникает в компоненте TEdit. Ну, в смысле, переопределить. Умная книжка (Архангельский написал, про C++ Builder 5) говорит, что надо искать названия методов в справке сишки. В справке приводится метод DoExit, а по книжке, должен быть или просто Exit, или OnExit, сейчас не помню (дома Нета нету :-(.. )

Ладно, проблема не в этом. Посмотрел на пример, сделал, как умные люди сказали:
 
Код:
protected:
        DYNAMIC void __fastcall Exit(void);


//---------------------------------------------------------------------------
void __fastcall Exit(void)
{
MessageBox(NULL,"Потерян фокус ввода","Что-то случилось:",NULL);
}


Не работает! В смысле, когда я в пробной программе событие назначаю, и такой же код пишу, только с другим сообщением, то другое сообщение у меня и показывается. А вот то, которое в компоненте откомпилено - молчит, как партизан. Было предложение юзать MESSAGE_MAP. Оно меня, однако, не возбудило: я достаточно слабо представляю себе, как это реализовать на Builder'e (хотя пробовал и на TASM 5.0 приложения для форточек писать, так что о сообщениях наслышан), но не в этом дело. Этот метод работает тоже не так, как хочется! А первый должен работать (вроде бы...), но не работает! Может, кто-нибудь подскажет, почему?


Не очень понятно что собственно у тебя не работает - советую посмотреть примеры работы с сообщениями - они нормально работают в билдере и проблем никаких быть у тебя не должно, или же четко сформулировать - что ты делаешь что бы оно работало :). Если необходимо назначить обработку сообщения для динамически созданного компонента делается это так - объявить функцию в разделе __published

 
Код:
void __fastcall MyOnClick(TObject *Sender);

за тем в коде пишешь:
 
Код:
TEdit *MyEdit = new TEdit(this);
 MyEdit->Parent = this;
 MyEdit->OnClick = MyOnClick;

Все работает без всяких проблем. Я думаю применить это к массиву компонентов труда не составит. Единственное не забывайте устанавливать параметры компонента Top & Left - иначе компоненты будут налазить друг на друга.
Кстати если забито так как написано -
Цитата:
Originally posted by TheMaster

 
Код:
protected:
        DYNAMIC void __fastcall Exit(void);


//---------------------------------------------------------------------------
void __fastcall Exit(void)
{
MessageBox(NULL,"Потерян фокус ввода","Что-то случилось:",NULL);
}


то и не удивительно что не работает. Функция объявлена в классе а реализована вне класса.

8.2K
01 февраля 2006 года
TheMaster
32 / / 23.12.2005
Я - тупень. Всем спасибо. Надо читать help и юзать поиск по форуму.
Реклама на сайте | Обмен ссылками | Ссылки | Экспорт (RSS) | Контакты
Добавить статью | Добавить исходник | Добавить хостинг-провайдера | Добавить сайт в каталог