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

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

11.06.2010, 17:16. Показов 19032. Ответов 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 Кб, 150 просмотров)
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
Ответ Создать тему
Новые блоги и статьи
Модель заражения группы наркоманов
alhaos 17.04.2026
Условия задачи сформулированы тут Суть: - Группа наркоманов из 10 человек. - Только один инфицирован ВИЧ. - Колются одной иглой. - Колются раз в день. - Колются последовательно через. . .
Мысли в слух. Про "навсегда".
kumehtar 16.04.2026
Подумалось тут, что наверное очень глупо использовать во всяких своих установках понятие "навсегда". Это очень сильное понятие, и я только начинаю понимать край его смысла, не смотря на то что давно. . .
My Business CRM
MaGz GoLd 16.04.2026
Всем привет, недавно возникла потребность создать CRM, для личных нужд. Собственно программа предоставляет из себя базу данных клиентов, в которой можно фиксировать звонки, стадии сделки, а также. . .
Знаешь почему 90% людей редко бывают счастливыми?
kumehtar 14.04.2026
Потому что они ждут. Ждут выходных, ждут отпуска, ждут удачного момента. . . а удачный момент так и не приходит.
Фиксация колонок в отчете СКД
Maks 14.04.2026
Фиксация колонок в СКД отчета типа Таблица. Задача: зафиксировать три левых колонки в отчете. Процедура ПриКомпоновкеРезультата(ДокументРезультат, ДанныеРасшифровки, СтандартнаяОбработка) / / . . .
Настройки VS Code
Loafer 13.04.2026
{ "cmake. configureOnOpen": false, "diffEditor. ignoreTrimWhitespace": true, "editor. guides. bracketPairs": "active", "extensions. ignoreRecommendations": true, . . .
Оптимизация кода на разграничение прав доступа к элементам формы
Maks 13.04.2026
Алгоритм из решения ниже реализован на нетиповом документе, разработанного в конфигурации КА2. Задачи, как таковой, поставлено не было, проделанное ниже исключительно моя инициатива. Было так:. . .
Контроль заполнения и очистка дат в зависимости от значения перечислений
Maks 12.04.2026
Алгоритм из решения ниже реализован на примере нетипового документа "ПланированиеПерсонала", разработанного в конфигурации КА2. Задача: реализовать контроль корректности заполнения дат назначения. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru