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

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

11.06.2010, 17:16. Показов 18858. Ответов 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
 Аватар для Tree
74 / 74 / 4
Регистрация: 31.05.2009
Сообщений: 243
12.06.2010, 13:44
Так можно сделать уже и компонент с вкладкой "киберфорум"...)))
0
8 / 9 / 0
Регистрация: 26.03.2010
Сообщений: 108
25.06.2010, 23:02
Классно придумал! Спасибо!
0
 Аватар для Storm255
0 / 0 / 0
Регистрация: 17.10.2009
Сообщений: 46
29.03.2011, 22:41
А как вместо тяжелого Bitmap сделать так, чтоб читал JPEG?
0
 Аватар для cpp_developer
20124 / 5691 / 417
Регистрация: 09.04.2010
Сообщений: 22,546
Записей в блоге: 1
29.03.2011, 22:44
Цитата Сообщение от Storm255 Посмотреть сообщение
чтоб читал JPEG?
инклюдить заголовочный файл jpeg
0
 Аватар для Storm255
0 / 0 / 0
Регистрация: 17.10.2009
Сообщений: 46
30.03.2011, 00:04
Цитата Сообщение от LK Посмотреть сообщение
инклюдить заголовочный файл jpeg
не совсем понятна данная фраза. в смысле библиотеку прописать, #include? или что вы имели в ввиду?

А строчку Source_Bitmap, нельзя заменить на что либо подобное для чтения JPEG?
0
 Аватар для cpp_developer
20124 / 5691 / 417
Регистрация: 09.04.2010
Сообщений: 22,546
Записей в блоге: 1
30.03.2011, 02:37
1.
C++
1
#include <jpeg.hpp>
2. нет:
//*Создаем TBitmap, который будет хранить целое изображение кнопки,
с таким же успехом вы можете указать "MyBitmap", "this_bitmam", "bitmap" и т.д.
0
Покинул форум
3189 / 1368 / 109
Регистрация: 29.01.2010
Сообщений: 2,887
30.03.2011, 16:14  [ТС]
Storm255, jpeg читать-то будет, только вот все равно придется попутно программно конвертировать в BMP.
0
 Аватар для Storm255
0 / 0 / 0
Регистрация: 17.10.2009
Сообщений: 46
30.03.2011, 21:22
Понятно, спасибо.
0
2 / 2 / 0
Регистрация: 22.03.2010
Сообщений: 146
10.01.2012, 18:41
А картинка получается не активной в итоге? т.е. её нельзя использовать как кнопку???
0
 Аватар для cpp_developer
20124 / 5691 / 417
Регистрация: 09.04.2010
Сообщений: 22,546
Записей в блоге: 1
10.01.2012, 18:44
Посмотрите в Инспекторе объектов события для TImage - и все станет понятно.
0
 Аватар для Samrisbe
1365 / 732 / 67
Регистрация: 28.01.2011
Сообщений: 2,069
10.01.2012, 19:30
При всем моем уважении Nitan но есть вариант куда проще...
срр
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
TForm1 *Form1;
TWndMethod OldWindowProc;
bool z=0;
//---------------------------------------------------------------------------
__fastcall TForm1::TForm1(TComponent* Owner)
        : TForm(Owner)
{
OldWindowProc=Panel1->WindowProc;
Panel1->WindowProc=NewWndProc;
}
//---------------------------------------------------------------------------
 
void __fastcall TForm1::NewWndProc(TMessage &Message)
{
if(Message.Msg==CM_MOUSEENTER&&z)
{
z=0;
Memo1->Lines->Add("Mouse Enter");
}
 
if(Message.Msg==CM_MOUSELEAVE&&!z)
{
z=1;
Memo1->Lines->Add("Mouse Leave");
}
OldWindowProc(Message);
}
h
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
#include <ExtCtrls.hpp>
//---------------------------------------------------------------------------
class TForm1 : public TForm
{
__published:    // IDE-managed Components
        TPanel *Panel1;
        TMemo *Memo1;
private:    // User declarations
public:     // User declarations
     void __fastcall TForm1::NewWndProc(Messages::TMessage &Message);
        __fastcall TForm1(TComponent* Owner);
};
//---------------------------------------------------------------------------
extern PACKAGE TForm1 *Form1;
//---------------------------------------------------------------------------
#endif
и ненадо писать километровый код...
3
2 / 2 / 0
Регистрация: 22.03.2010
Сообщений: 146
10.01.2012, 23:00
может кто-нить залить программу, а то у меня что-то не получается собрать всё в кучу) заранее благодарен)
0
 Аватар для cpp_developer
20124 / 5691 / 417
Регистрация: 09.04.2010
Сообщений: 22,546
Записей в блоге: 1
10.01.2012, 23:01
Maratwp, вы покажите для начала свою кучу, будет кому-нить от чего отталкиваться
0
2 / 2 / 0
Регистрация: 22.03.2010
Сообщений: 146
10.01.2012, 23:35
я просто хочу понять как это работает... и переделать под то что мне надо.
Хочу что бы кто-нить залил программу..которую описывал Samrisbe. так как сам я это собрать не могу)
0
 Аватар для Samrisbe
1365 / 732 / 67
Регистрация: 28.01.2011
Сообщений: 2,069
10.01.2012, 23:40
Цитата Сообщение от Maratwp Посмотреть сообщение
Хочу что бы кто-нить залил программу..которую описывал Samrisbe.
Samrisbe сам зальёт...
Вложения
Тип файла: rar MouseLeave.rar (28.4 Кб, 142 просмотров)
1
2 / 2 / 0
Регистрация: 22.03.2010
Сообщений: 146
11.01.2012, 00:12
спасибо)

Добавлено через 27 минут
не могу переделать на появление и исчезновение картинки(ну или хотябы что бы мемо иссчезало и появлялось). вроде и изменять почти негде, а не получается.
0
 Аватар для Samrisbe
1365 / 732 / 67
Регистрация: 28.01.2011
Сообщений: 2,069
11.01.2012, 00:29
Цитата Сообщение от LK Посмотреть сообщение
Maratwp, вы покажите для начала свою кучу, будет кому-нить от чего отталкиваться
Тебя напрвляют на путь истенный а ты не бачеш, покажи что там у тебя получилось а мы посмотрим что не так...
0
2 / 2 / 0
Регистрация: 22.03.2010
Сообщений: 146
11.01.2012, 00:53
заменил просто вот эти строчки:
C++
1
2
3
4
5
6
Memo1->Lines->Add("Mouse Enter");
}
if(Message.Msg==CM_MOUSELEAVE&&!z)
{
  z=1;
  Memo1->Lines->Add("Mouse Leave");
на вот эти:
C++
1
2
3
4
5
6
Memo1->Visible=false;
}
if(Message.Msg==CM_MOUSELEAVE&&!z)
{
  z=1;
  Memo1->Visible=true;
А изменений никаких(

Добавлено через 5 минут
а вообще хочу что бы при наведении мышки на кнопку(ну или картинку), появлялась картинка..а при отведении курсора снова исчезала.

 Комментарий модератора 
Maratwp, Вы не первый день на форуме - используйте тег вставки кода :
[CPP ]без пробелов[ /CPP] или кнопка на панели окна редактирования сообщения
Правила
2.8. Используйте тэги форматирования текста для удобства восприятия ваших сообщений другими пользователями.
Устное предупреждение.
0
wtf!?
 Аватар для Flyer
750 / 281 / 25
Регистрация: 21.05.2010
Сообщений: 732
11.01.2012, 02:47
ну то поставь себе среду поновее и сделай как я говорил. геморроя меньше как по мне
1
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
raxper
Эксперт
30234 / 6612 / 1498
Регистрация: 28.12.2010
Сообщений: 21,154
Блог
11.01.2012, 02:47
Помогаю со студенческими работами здесь

События 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 :=...


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

Или воспользуйтесь поиском по форуму:
20
Ответ Создать тему
Новые блоги и статьи
PhpStorm 2025.3: WSL Terminal всегда стартует в ~
and_y87 14.12.2025
PhpStorm 2025. 3: WSL Terminal всегда стартует в ~ (home), игнорируя директорию проекта Симптом: После обновления до PhpStorm 2025. 3 встроенный терминал WSL открывается в домашней директории. . .
Access
VikBal 11.12.2025
Помогите пожалуйста !! Как объединить 2 одинаковые БД Access с разными данными.
Новый ноутбук
volvo 07.12.2025
Всем привет. По скидке в "черную пятницу" взял себе новый ноутбук Lenovo ThinkBook 16 G7 на Амазоне: Ryzen 5 7533HS 64 Gb DDR5 1Tb NVMe 16" Full HD Display Win11 Pro
Музыка, написанная Искусственным Интеллектом
volvo 04.12.2025
Всем привет. Некоторое время назад меня заинтересовало, что уже умеет ИИ в плане написания музыки для песен, и, собственно, исполнения этих самых песен. Стихов у нас много, уже вышли 4 книги, еще 3. . .
От async/await к виртуальным потокам в Python
IndentationError 23.11.2025
Армин Ронахер поставил под сомнение async/ await. Создатель Flask заявляет: цветные функции - провал, виртуальные потоки - решение. Не threading-динозавры, а новое поколение лёгких потоков. Откат?. . .
Поиск "дружественных имён" СОМ портов
Argus19 22.11.2025
Поиск "дружественных имён" СОМ портов На странице: https:/ / norseev. ru/ 2018/ 01/ 04/ comportlist_windows/ нашёл схожую тему. Там приведён код на С++, который показывает только имена СОМ портов, типа,. . .
Сколько Государство потратило денег на меня, обеспечивая инсулином.
Programma_Boinc 20.11.2025
Сколько Государство потратило денег на меня, обеспечивая инсулином. Вот решила сделать интересный приблизительный подсчет, сколько государство потратило на меня денег на покупку инсулинов. . . .
Ломающие изменения в C#.NStar Alpha
Etyuhibosecyu 20.11.2025
Уже можно не только тестировать, но и пользоваться C#. NStar - писать оконные приложения, содержащие надписи, кнопки, текстовые поля и даже изображения, например, моя игра "Три в ряд" написана на этом. . .
Мысли в слух
kumehtar 18.11.2025
Кстати, совсем недавно имел разговор на тему медитаций с людьми. И обнаружил, что они вообще не понимают что такое медитация и зачем она нужна. Самые базовые вещи. Для них это - когда просто люди. . .
Создание Single Page Application на фреймах
krapotkin 16.11.2025
Статья исключительно для начинающих. Подходы оригинальностью не блещут. В век Веб все очень привыкли к дизайну Single-Page-Application . Быстренько разберем подход "на фреймах". Мы делаем одну. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2025, CyberForum.ru