Форум программистов, компьютерный форум, киберфорум
C++ Builder
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
 
Рейтинг 4.94/98: Рейтинг темы: голосов - 98, средняя оценка - 4.94
Покинул форум
3189 / 1368 / 109
Регистрация: 29.01.2010
Сообщений: 2,887

Создание событий MouseEnter и MouseLeave для TImage (решено)

11.06.2010, 17:16. Показов 19040. Ответов 31

Студворк — интернет-сервис помощи студентам
Раз на форуме появилось огромное количество желающих, которым нужно событие OnMouseEnter и OnMouseLeave для TImage, то почему бы этого не сделать?!
Сие краткое руководство (да что там руководство, просто пример) поможет вам разобраться в этой проблеме (надеюсь).
За основу был взять
пример из интернета
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
class TMyImage:public TImage
{
public:
       //Событие OnMouseEnter
       virtual void __fastcall Process_OnEnter(TMessage &msg){
               Picture = EnterPic;
       }
       //Событие OnMouseLeave
       virtual void __fastcall Process_OnLeave(TMessage &msg){
               Picture = LeavePic;
       }
         //Конструктор, принимающий в качестве аргументов 2 картинки (когда мышка попадает на объект и когда
         //покидает его) и объект TImage, события которого присваиваются потом нашему объекту.          
       _fastcall TMyImage::TMyImage(TPicture* Pic1, TPicture* Pic2, TImage* ParentImage, TComponent*Owner):TImage(Owner){
               Picture = ParentImage->Picture;//Задаём начальную картинку для изображения
               Left = ParentImage->Left;
               Top = ParentImage->Top;
               OnClick = ParentImage->OnClick;
               OnMouseDown = ParentImage->OnMouseDown;
               OnMouseUp = ParentImage->OnMouseUp;
               Visible = true;
               AutoSize = true;
 
               EnterPic=Pic1;
               LeavePic = Pic2;
 
       }
private:
 
       TPicture* EnterPic;
       TPicture* LeavePic;
 #pragma warn -8027
BEGIN_MESSAGE_MAP
       VCL_MESSAGE_HANDLER(CM_MOUSEENTER,TMessage,Process_OnEnter);
       VCL_MESSAGE_HANDLER(CM_MOUSELEAVE,TMessage,Process_OnLeave);
END_MESSAGE_MAP(TImage)
#pragma warn -8027
};
, но слегка модифицирован и упрощен, а также прокомментирован по мере возможности и знаний автора (я скорее практик, чем теоретик, поэтому за скупое описание прошу не судить).

1. Для начала нужно создать нашу кнопку. Оба состояние кнопки будут в одном изображении (левая часть изображения до середины отвечает за исходное состояние, а правая часть после середины за измененное). Размер кнопки может быть любой, но для начала сделайте размер 150*40, а при склеивании должно получится 300*40.

2. Теперь переходим к созданию своего класса! Делать мы его будем на основе TImage, так как это, по моему скромному мнению, самый идеальный вариант. Можно было бы использовать TButton, но он не имеет свойство TCanvas, которое нам необходимо:

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
class TFunnyButton: public TImage  //Собственно наш класс
     {
     Graphics::TBitmap *Source_Bitmap;  /*Создаем TBitmap, который будет хранить целое изображение кнопки,
         Так как в Picture у нас будет только выводится готовое "обрезанное" изображение*/
        public: 
            //Теперь обьявляем новые функции для нашего класса
        virtual void __fastcall  OnMouseEnter(TMessage &msg)   //Курсор на кнопке
        {
        Canvas->CopyRect(Rect(0,0,Width,Height),Source_Bitmap->Canvas,Rect(Width,0,Width*2,Height));  /*Так как изображение у нас состоит из 2 частей, где первая левая часть - это исходное изображение,
            а правая отрисовывается при попадании курсора на кнопку, то мы копируем соответственно правую часть исходного изображения (от Width до Width*2) */
        }
 
        virtual void __fastcall  OnMouseLeave(TMessage &msg)  //Курсор покидает кнопку
        {
 
        Canvas->CopyRect(Rect(0,0,Width,Height),Source_Bitmap->Canvas,Rect(0,0,Width,Height));
        //Делаем тоже самое что и при попадании крсора на кнопку, только в этот раз копируем левую часть
 
        }
 
        _fastcall TFunnyButton::TFunnyButton(AnsiString BitmapName):TImage(Owner){   //Конструктор обьекта, в качестве аргумента принимается только путь к файлу
 
 
            Width=150;  //Устанавливаем ширину кнопки по умолчанию
            Height=40;  //Устанавливаем высоту кнопки по умолчанию
           Source_Bitmap=new Graphics::TBitmap;
           Source_Bitmap->Width=Width*2;
           Source_Bitmap->Height=Height;
 
           Source_Bitmap->LoadFromFile(BitmapName);  //Загружаем само изображение из файла, указанного в BitmapName
           Canvas->CopyRect(Rect(0,0,Width,Height),Source_Bitmap->Canvas,Rect(0,0,Width,Height));  //Теперь отрисовываем левую часть изображения (исходную)
           Transparent=true;  //Включаем "прозрачность" кнопки, чтобы она приобрела округленный вид
        }
 
        private:
        #pragma warn -8027  //Своего рода игнорирование предупреждения - использовать по желанию
        BEGIN_MESSAGE_MAP  //Это таблица сообщений, она служит для отлавливания сообщений от Windows. Если честно, то мне самому не очень понятно что происходит далее, точнее смысл понятен, а обьяснить не могу...
         VCL_MESSAGE_HANDLER(CM_MOUSEENTER,TMessage,OnMouseEnter);  
         VCL_MESSAGE_HANDLER(CM_MOUSELEAVE,TMessage,OnMouseLeave);
         END_MESSAGE_MAP(TImage)
         #pragma warn -8027 
     };
Теперь пример использования класса:
C++
1
2
     TFunnyButton  *b=new TFunnyButton("F:\\button.bmp"); //Загружаем изображение из F:\button.bmp
       b->Parent=Form1; //Обязательно нужно указать родителя
Вот и все. Теперь ждем пожеланий и улучшений от форумчан!!!
(Изображение кнопки, использованной в примере)
Изображения
 
13
cpp_developer
Эксперт
20123 / 5690 / 1417
Регистрация: 09.04.2010
Сообщений: 22,546
Блог
11.06.2010, 17:16
Ответы с готовыми решениями:

SetTimeout для mouseenter/mouseleave
Как правильно повесить setTimeout на события mouseenter/mouseleave? Но с одним нюансом, если предположим, что setTimeout для обоих событий...

Альтернатива mouseenter/mouseleave для touch
Здравствуйте уважаемые форумчане. Посоветуйте как можно сделать функционал для устройств с тач... Смысл такой: Есть список комментариев и...

Поймать MouseEnter, MouseLeave для строчек ListView
пожалуйста, примерчик или ссылку на таковой. пару колонок и пару строчек. и как хэндлеры событий к строчкам присоединить. нахожу...

31
0 / 0 / 0
Регистрация: 11.01.2012
Сообщений: 4
11.01.2012, 14:37
Студворк — интернет-сервис помощи студентам
Спасибо, помогли
0
Модератор
 Аватар для vxg
3409 / 2181 / 354
Регистрация: 13.01.2012
Сообщений: 8,463
27.01.2012, 10:30
подскажите - обработчики объявленные в вашем классе используют механизм аналогичный обработчикам для TLabel? просто для TLabel есть родные обработчики MouseEnter и MouseLeave, но в одном из проектов я заметил, что при быстром перемещении мыши сообщения могут "пропускаться". то есть, например, сообщение о входе мыши не приходит, а о выходе - успевает. стрессовое тестирование делали?
0
Почемучка)
 Аватар для Ddv122
1244 / 304 / 30
Регистрация: 23.12.2010
Сообщений: 2,001
Записей в блоге: 1
16.03.2012, 01:30
скажите пожалуйста можно ли создать для этого класса на основе TImage, события OnClick и тп. чтобы было как полноценная кнопка ...
0
872 / 448 / 35
Регистрация: 25.10.2011
Сообщений: 910
16.03.2012, 01:36
Цитата Сообщение от EdarGp Посмотреть сообщение
скажите пожалуйста можно ли создать для этого класса на основе TImage, события OnClick и тп. чтобы было как полноценная кнопка ..
Да, учитывая, что у TImage и так есть события обрабатывающие нажатия клавиши мыши . Да и очень многие свойство могут быть использованы, просто объявив их:
C++
1
2
// ...
__property TabStop;
А вот графическое отображение нужно реализовывать самостоятельно.
1
Почемучка)
 Аватар для Ddv122
1244 / 304 / 30
Регистрация: 23.12.2010
Сообщений: 2,001
Записей в блоге: 1
16.03.2012, 02:30
как ее писать в программе при использовании .. ?
я вот дописал в классе

C++
1
2
3
4
...
__published:
__property OnClick;
...
и далее в проге

C++
1
2
3
4
void __fastcall TSimpleButton::OnClick(TObject *Sender)
{
Form1->Edit1->Text="1";
}
и выдает такую ​​вот ошибку

[BCC32 Error] Unit1.cpp(43): E2316 '_fastcall TSimpleButton::OnClick(TObject *)' is not a member of 'TSimpleButton'
0
872 / 448 / 35
Регистрация: 25.10.2011
Сообщений: 910
16.03.2012, 02:43
А зачем ты его объявляешь? Если родитель TImage, то у него есть свойство OnClick.
0
Почемучка)
 Аватар для Ddv122
1244 / 304 / 30
Регистрация: 23.12.2010
Сообщений: 2,001
Записей в блоге: 1
16.03.2012, 02:45
а. . разобрался.. )))
дописал в классе..
C++
1
DYNAMIC void __fastcall MouseDown(System::Uitypes::TMouseButton Button, System::Classes::TShiftState Shift, int X, int Y);
и сам обработчик стандартний
C++
1
2
3
4
void __fastcall TSimpleButton::MouseDown(TMouseButton Button, TShiftState Shift, int X, int Y)
{
Form1->Edit1->Text="1";
}
так работает .. =)

Добавлено через 1 минуту
Цитата Сообщение от DefineTrueFalse Посмотреть сообщение
А зачем ты его объявляешь? Если родитель TImage, то у него есть свойство OnClick.
есть то есть .. но если не объявить то говорит что он не является членом класса...
1
872 / 448 / 35
Регистрация: 25.10.2011
Сообщений: 910
16.03.2012, 02:45
Да и прописывается это не вручную, а через дизайнер. А если ты это пытался в файле самого компонента писать, то тогда надо перехватывать события, как это с MouseEnter и MouseLeave.
0
Почемучка)
 Аватар для Ddv122
1244 / 304 / 30
Регистрация: 23.12.2010
Сообщений: 2,001
Записей в блоге: 1
16.03.2012, 02:51
Цитата Сообщение от DefineTrueFalse Посмотреть сообщение
Да и прописывается это не вручную, а через дизайнер. А если ты это пытался в файле самого компонента писать, то тогда надо перехватывать события, как это с MouseEnter и MouseLeave.
через дизайнер не получится .. нашего элемента же на форме нет .. мы же класс создаем .. а как ты переменную класса в дизайнер засунеш?) .. это не готовый компонент ...
писал я это в этом же классе но подобно тому как в файлах компонента прописывают .. собственно в другом компоненте и посмотрел)
0
872 / 448 / 35
Регистрация: 25.10.2011
Сообщений: 910
16.03.2012, 02:55
Цитата Сообщение от EdarGp Посмотреть сообщение
через дизайнер не получится .. нашего элемента же на форме нет .. мы же класс создаем .. а как ты переменную класса в дизайнер засунеш?) .. это не готовый компонент ...
писал я это в этом же классе но подобно тому как в файлах компонента прописывают .. собственно в другом компоненте и посмотрел)
Все, понятно, меня немного декларация OnClick'а смутила, которая уже с готовым компонентом используется. В этом плане, конечно в перехват событий смотреть нужно.
0
DG
0 / 0 / 0
Регистрация: 23.11.2014
Сообщений: 3
06.04.2013, 00:00
Вариант создания кнопки из TImage в C++ Builder 6:

Т.к. события MouseEnter и MouseLeave для TImage отсутствуют в C++ Builder 6, можно воспользоваться элементом TLabel (у него такие события есть).
Итак, делаем 3 картинки и загружаем их в три объекта TImage через Properties Picture:
Image1 - картинка кнопки до наведения курсора
Image2 - картинка кнопки после наведения курсора
Image3 - картинка кнопки при нажатии
Делаем у них одинаковые размеры и положение, располагаем одну под другой: сверху Image1, снизу Image3.
Над ними располагаем Label1 с такими же размерами.
Чтобы картинки были видны, делаем в свойствах Label1:
Label1->AutoSize=false
Label1->Caption=ничего
Label1->Transparent=true
Дальше используем события Label1:
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
void __fastcall TForm1::Label1MouseEnter(TObject *Sender)
{
 Image2->Visible=true;
 Image1->Visible=false;
}
//---------------------------------------------------------------------------
void __fastcall TForm1::Label1MouseLeave(TObject *Sender)
{
 Image1->Visible=true;
}
//---------------------------------------------------------------------------
void __fastcall TForm1::Label1MouseDown(TObject *Sender, TMouseButton Button, TShiftState Shift, int X, int Y)
{
 Image3->Visible=true;
 Image2->Visible=false;
 Image1->Visible=false;
}
//---------------------------------------------------------------------------
void __fastcall TForm1::Label1MouseUp(TObject *Sender, TMouseButton Button,  TShiftState Shift, int X, int Y)
{
 Image2->Visible=true;
}
//---------------------------------------------------------------------------
void __fastcall TForm1::Label1Click(TObject *Sender)
{
 //ФУНКЦИИ КНОПКИ
}
0
Эксперт С++
 Аватар для Avazart
8489 / 6156 / 615
Регистрация: 10.12.2010
Сообщений: 28,683
Записей в блоге: 30
06.04.2013, 00:05
Цитата Сообщение от NiTan Посмотреть сообщение
OnMouseLeave
Я не замарачивался такими проблемами в свое время и обрабатывал вместо него событие MouseMove формы ( или другого Owner-a) и соседних компонентов.
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
raxper
Эксперт
30234 / 6612 / 1498
Регистрация: 28.12.2010
Сообщений: 21,154
Блог
06.04.2013, 00:05
Помогаю со студенческими работами здесь

События MouseEnter и MouseLeave
У меня на форме не большой Splitter, ширика 3-4 пикселя, на его события MouseEnter и MouseLeave повешены обработчики, но если очень быстро...

MouseLeave и MouseEnter(Gradient)
Привет форумчане, пытаюсь изучить wpf и при изучение материала с этими событиями создал себе практическую задачу, на эту тематику и уже...

Обработчики mouseenter() и mouseleave()
Всем здравствуйте! Подскажите как изолировать обработчики друг от друга. В принципе все работает, но если быстро двигать мышью по углу...

Многоразовое событие mouseenter / mouseleave
Проблема в том, что если человек быстро и много раз будет водить курсором по элементу, то после этого, элемент будет и дальше выполнять...

Избавится от артефактов MouseEnter/MouseLeave
Есть такой кусочек кода... var png: TPngImage; .... procedure TForm1.Image4MouseEnter(Sender: TObject); begin Png :=...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
32
Ответ Создать тему
Новые блоги и статьи
Валидация и контроль данных табличной части документа перед записью
Maks 22.04.2026
Алгоритм из решения ниже реализован на примере нетипового документа, разработанного в КА2. Задача: контроль и валидация данных табличной части документа перед записью с учетом регламента компании. . .
Отчёт о затраченных материалах за определенный период с макетом печатной формы
Maks 21.04.2026
Отчёт из решения ниже размещён в конфигурации КА2. Задача: разработка отчёта по затраченным материалам за определённый период, с возможностью вывода печатной формы отчёта с шапкой и подвалом. В. . .
Отчёт о спецтехнике находящейся в ремонте
Maks 20.04.2026
Отчёт из решения ниже размещен в конфигурации КА2. Задача: отобразить спецтехнику, которая на данный момент находится в ремонте. Есть нетиповой документ "Заявка на ремонт спецтехники" который. . .
Памятка для бота и "визитка" для читателей "Semantic Universe Layer (Слой семантической вселенной)"
Hrethgir 19.04.2026
Сгенерировано для краткого описания по случаю сборки и компиляции скелета серверного приложения. И пусть после этого скажут, что статьи сгенерированные AI - туфта и не интересно. И это не реклама -. . .
Запрет удаления строк ТЧ документа при определённом условии
Maks 19.04.2026
Алгоритм из решения ниже реализован на примере нетипового документа "Аккумуляторы", разработанного в конфигурации КА2. У данного документа есть ТЧ, в которой в зависимости от прав доступа. . .
Модель заражения группы наркоманов
alhaos 17.04.2026
Условия задачи сформулированы тут Суть: - Группа наркоманов из 10 человек. - Только один инфицирован ВИЧ. - Колются одной иглой. - Колются раз в день. - Колются последовательно через. . .
Мысли в слух. Про "навсегда".
kumehtar 16.04.2026
Подумалось тут, что наверное очень глупо использовать во всяких своих установках понятие "навсегда". Это очень сильное понятие, и я только начинаю понимать край его смысла, не смотря на то что давно. . .
My Business CRM
MaGz GoLd 16.04.2026
Всем привет, недавно возникла потребность создать CRM, для личных нужд. Собственно программа предоставляет из себя базу данных клиентов, в которой можно фиксировать звонки, стадии сделки, а также. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru