tom4ik85
|
|
« : 08-04-2008 13:07 » |
|
Нарисовал я себе простой контрол. Рисую в нем рамку. В конструкторе m_nThick = 1; void CMyButton::DrawItem(LPDRAWITEMSTRUCT lpDrawItemStruct) { CDC *dc; CRect rect; CPen pen; ......... CPoint point, dpoint;
pen.CreatePen(PS_SOLID, m_nThick, m_clrBorderColor); .........
dc->DrawRect(&rect, &CBrush(m_clrBgColor));
oldPen = dc->SelectObject((CPen*)&pen);
............. dc->SelectObject(oldPen); }
рисует так как надо. Хочу при наведении мішки рамка утолщалась: void CMyButton::OnMouseMove(UINT nFlags, CPoint point) { CRect rect; GetClientRect(&rect);
if(IsInRect(rect, point)) { if(m_nThick != 3) { m_nThick = 3; Invalidate(FALSE); } } else { if(m_nThick != 1) { m_nThick = 1; Invalidate(FALSE); } }
CButton::OnMouseMove(nFlags, point); }
а она становится только толще при наведении, а когда убираю курсор, то ничего не происходит. если ловить нажатие мышки. то работает. void CMyButton::OnLButtonDown(UINT nFlags, CPoint point) { SetStatusColor(m_clrBgColor); m_nThick = 1; CButton::OnLButtonDown(nFlags, point); }
Подскажите, пожалуйста, что не так.
|
|
|
Записан
|
|
|
|
Джон
просто
Администратор
Offline
Пол:
|
|
« Ответ #1 : 08-04-2008 14:34 » |
|
Очень просто. Когда мыш покидает твою кнопку, то его сообщения уже не приходят в твою кнопку. Даже твой тест IsInRect не нужен. Если сообщение пришло - значит "ин рект". Проще говоря твой код равносилен вот этому: void CMyButton::OnMouseMove(UINT nFlags, CPoint point) { CRect rect;
if(m_nThick != 3) { m_nThick = 3; Invalidate(FALSE); }
CButton::OnMouseMove(nFlags, point); }
|
|
« Последнее редактирование: 08-04-2008 14:37 от Джон »
|
Записан
|
Я вам что? Дурак? По выходным и праздникам на работе работать. По выходным и праздникам я работаю дома. "Just because the language allows you to do something does not mean that it’s the correct thing to do." Trey Nash "Physics is like sex: sure, it may give some practical results, but that's not why we do it." Richard P. Feynman "All science is either physics or stamp collecting." Ernest Rutherford "Wer will, findet Wege, wer nicht will, findet Gründe."
|
|
|
tom4ik85
|
|
« Ответ #2 : 08-04-2008 15:01 » |
|
Спасибо большое. А не подскажете, как тогда узнать что она ушла с моего контрола?
|
|
|
Записан
|
|
|
|
Джон
просто
Администратор
Offline
Пол:
|
|
« Ответ #3 : 08-04-2008 15:23 » |
|
Хммм... есть один способ. Для это надо зарегистрировать сообщение мыша MouseLeave. И реагировать на него. НО! Дело в том, что оно не всегда срабатывает. Например, если ОЧЕНЬ БЫСТРО убрать мыша с кнопки. Поэтому, если есть возможность, то лучше всего реагировать на WM_MOUSEMOVE в родительском окне. Тогда оставляешь свой код, с небольшим изменением: void CParentOfMyButton::OnMouseMove(UINT nFlags, CPoint point) { CRect rect; m_wndMyButton.GetWindowRect(&rect); ScreenToClient(&rect); // тут не уверен - посмотри в дебаггере значения и сравни их с координатами мыша
// >>>> if(IsInRect(rect, point)) // это что за ф-я? у CRect есть уже ф-я для проверки... if(rect.PtInRect(point)) { if(m_wndMyButton.GetThick() != 3) { m_wndMyButton.SetThick(3); m_wndMyButton.Invalidate(FALSE); } } else { if(m_wndMyButton.GetThick() != 1) { m_wndMyButton.SetThick(1); m_wndMyButton.Invalidate(FALSE); } }
_super::OnMouseMove(nFlags, point); }
Код ессно не тестировал, но думаю идея ясна. Лучше конечно всё засунуть в мембер ф-ю напр ShowHover(TRUE/FALSE) она сэкономит тебе Get/Set: void CMyButton::ShowHover(BOOL bShow) { ... }
тогда void CParentOfMyButton::OnMouseMove(UINT nFlags, CPoint point) { CRect rect; m_wndMyButton.GetWindowRect(&rect); ScreenToClient(&rect); // тут не уверен - посмотри в дебаггере значения и сравни их с координатами мыша
m_wndMyButton.ShowHover(rect.PtInRect(point));
_super::OnMouseMove(nFlags, point); }
|
|
|
Записан
|
Я вам что? Дурак? По выходным и праздникам на работе работать. По выходным и праздникам я работаю дома. "Just because the language allows you to do something does not mean that it’s the correct thing to do." Trey Nash "Physics is like sex: sure, it may give some practical results, but that's not why we do it." Richard P. Feynman "All science is either physics or stamp collecting." Ernest Rutherford "Wer will, findet Wege, wer nicht will, findet Gründe."
|
|
|
Алексей++
глобальный и пушистый
Глобальный модератор
Offline
Сообщений: 13
|
|
« Ответ #4 : 08-04-2008 16:40 » |
|
Джон, tom4ik85, а есть 100% вариант Когда по контролу маузмувнули - запустить таймер на 300...1000 мс и по таймеру проверить - не ушла ли мышь уже с контрола (::GetCursorPos). Если нет таймер тикает дальше, если да - гасим таймер. Джон, Джон, а что за _super:: , я почитал мсдн - так и не понял назначение, ведь всегда по имени класса можно мембер вызвать ...
|
|
« Последнее редактирование: 08-04-2008 16:44 от Алексей1153++ »
|
Записан
|
|
|
|
Джон
просто
Администратор
Offline
Пол:
|
|
« Ответ #5 : 08-04-2008 18:14 » |
|
Лёш, я тебе никогда не рассказывал, как один товарищ текущее время определял создавая файл, а потом считывая время его создания? "Через попу стеклорезом" (с) А чем тебе не нравится метод в родителе? 2. __super это очень забавная вещица. В данном случае, я понятия не имею от какого класса наследован родитель. Те по идее я должен был бы написать CDialog::OnMouseMove(nFlags, point); или что-то типа CMyDialog12345::OnMouseMove(nFlags, point); . А __super::OnMouseMove(nFlags, point); позволяет мне не обращать внимание на такие мелочи, ведь будет вызвана ближайшая доступная ф-я базового класса на любом уровне даже тогда когда явно она не видна (сложные случаи интерфейсов и/или шаблонов).
|
|
« Последнее редактирование: 08-04-2008 18:20 от Джон »
|
Записан
|
Я вам что? Дурак? По выходным и праздникам на работе работать. По выходным и праздникам я работаю дома. "Just because the language allows you to do something does not mean that it’s the correct thing to do." Trey Nash "Physics is like sex: sure, it may give some practical results, but that's not why we do it." Richard P. Feynman "All science is either physics or stamp collecting." Ernest Rutherford "Wer will, findet Wege, wer nicht will, findet Gründe."
|
|
|
Алексей++
глобальный и пушистый
Глобальный модератор
Offline
Сообщений: 13
|
|
« Ответ #6 : 08-04-2008 18:26 » |
|
метод в родителе не нравится, вообще. А контрол автономно всё делает, чем тебе так не нравится ? ) Не принимается пример со временем 2 - то есть __super - это как бызаменитель имени родителя ?
|
|
|
Записан
|
|
|
|
Джон
просто
Администратор
Offline
Пол:
|
|
« Ответ #7 : 08-04-2008 19:02 » |
|
>> не нравится, вообще Аааааа ну дык. Ну тогда сделай диалог с... ну скажем 5ю кнопками по твоему 100%-таймерному принципу. И как в водевиле было "Ты всё поймёшь, ты всё увидишь сам" (с) Заодно предусмотри возможность многократного вхождения на кнопку в течении одной секунды. Это так на вскидку. 2. нууу как бы. Если тебе так проще.
|
|
|
Записан
|
Я вам что? Дурак? По выходным и праздникам на работе работать. По выходным и праздникам я работаю дома. "Just because the language allows you to do something does not mean that it’s the correct thing to do." Trey Nash "Physics is like sex: sure, it may give some practical results, but that's not why we do it." Richard P. Feynman "All science is either physics or stamp collecting." Ernest Rutherford "Wer will, findet Wege, wer nicht will, findet Gründe."
|
|
|
Алексей++
глобальный и пушистый
Глобальный модератор
Offline
Сообщений: 13
|
|
« Ответ #8 : 08-04-2008 19:05 » |
|
Джон, имеются формы с 64000 такими контролами Одновременно на экране - около 320 , всё отлично работает. по курсору контрол меняет цвет, и остаётся такой шлейф из этого цвета, если мышой мувать ))
|
|
|
Записан
|
|
|
|
Алексей++
глобальный и пушистый
Глобальный модератор
Offline
Сообщений: 13
|
|
« Ответ #9 : 08-04-2008 19:09 » |
|
многократное вхождение на кнопку - ну и что ? ) Если таймер ещё не сработал, то просто перезапустить, а то и вообще не трогать его
|
|
|
Записан
|
|
|
|
Джон
просто
Администратор
Offline
Пол:
|
|
« Ответ #10 : 08-04-2008 19:09 » |
|
Не верю!!!! ПОкажи. Или ты 64000 разных таймера запускаешь?
|
|
|
Записан
|
Я вам что? Дурак? По выходным и праздникам на работе работать. По выходным и праздникам я работаю дома. "Just because the language allows you to do something does not mean that it’s the correct thing to do." Trey Nash "Physics is like sex: sure, it may give some practical results, but that's not why we do it." Richard P. Feynman "All science is either physics or stamp collecting." Ernest Rutherford "Wer will, findet Wege, wer nicht will, findet Gründe."
|
|
|
Джон
просто
Администратор
Offline
Пол:
|
|
« Ответ #11 : 08-04-2008 19:13 » |
|
Ну вот, шлейф... Грязная работёнка. Перелопачивать кучу ненеужных мессаджей. Задействовать тысячи хэндлов таймеров. Это 100% решение? Я же говорю "через попу стеклорезом"
А вот какие у тебя конкретные претензии к методу в родителе? Он кстати свободен от шлейфов.
|
|
|
Записан
|
Я вам что? Дурак? По выходным и праздникам на работе работать. По выходным и праздникам я работаю дома. "Just because the language allows you to do something does not mean that it’s the correct thing to do." Trey Nash "Physics is like sex: sure, it may give some practical results, but that's not why we do it." Richard P. Feynman "All science is either physics or stamp collecting." Ernest Rutherford "Wer will, findet Wege, wer nicht will, findet Gründe."
|
|
|
Алексей++
глобальный и пушистый
Глобальный модератор
Offline
Сообщений: 13
|
|
« Ответ #12 : 08-04-2008 19:16 » |
|
Джон, проект на работе ) Завтра напишу болванку с контролом , так как проект прислать не могу - оно с секретами фирмы >>64000 разных таймера запускаешь? О нет, ты наверное не понял идею - таймер запускается только тогда, когда мышь двинулась над контролом. Если мышь уехала - таймер через 300мс завянет (KillTimer) , если не уехала - будет раз в 300мс проверять, где курсор. Перезапускаться при этом он не будет - я взвёл флажок, что таймер уже запущен. Если юзер мувает мышь, то контролы, рядом стоящие (это в виде таблицы) по очереди шлейфом запустят по одному таймеру , который так же и подохнет через 300 с большой вероятностью. Даже если двигать курсор по кругу - ну сколько ты максимум таймеров одновременно запустишь ? ) А если это не 300 мс, а 100 ?
|
|
|
Записан
|
|
|
|
Алексей++
глобальный и пушистый
Глобальный модератор
Offline
Сообщений: 13
|
|
« Ответ #13 : 08-04-2008 19:18 » |
|
Джон, шлейф - это для красоты. Тормозов не наблюдается
Ну а поставить такие условия, когда тормоза начинаются - это возможно, наверное, но это же интерфейс, а не вычисляющая программа. Не страшно ) Не устроит - пишите в родителе, пжалста ) По мне, так в родителе - это и будет через стеклорез ))
|
|
« Последнее редактирование: 08-04-2008 19:20 от Алексей1153++ »
|
Записан
|
|
|
|
Алексей++
глобальный и пушистый
Глобальный модератор
Offline
Сообщений: 13
|
|
« Ответ #14 : 09-04-2008 04:04 » |
|
Джон, вот болванка. один экзешник - таймер 1000мс , другой - 100мс. контролов 255 - больше визард не дал на форму кинуть (у меня использовались контролы, которые на себе дочерние делали, поэтому у меня их и было гораздо больше , но для примера сойдёт и 255 - всё равно на экране не сильно много за раз помещается) нажимаем тремя пальцами известные кнопки , муваем по контролам и смотрим впухание процессора.
|
|
« Последнее редактирование: 09-04-2008 04:07 от Алексей1153++ »
|
Записан
|
|
|
|
Джон
просто
Администратор
Offline
Пол:
|
|
« Ответ #15 : 09-04-2008 08:35 » |
|
А код где?
|
|
|
Записан
|
Я вам что? Дурак? По выходным и праздникам на работе работать. По выходным и праздникам я работаю дома. "Just because the language allows you to do something does not mean that it’s the correct thing to do." Trey Nash "Physics is like sex: sure, it may give some practical results, but that's not why we do it." Richard P. Feynman "All science is either physics or stamp collecting." Ernest Rutherford "Wer will, findet Wege, wer nicht will, findet Gründe."
|
|
|
Алексей++
глобальный и пушистый
Глобальный модератор
Offline
Сообщений: 13
|
|
« Ответ #16 : 09-04-2008 08:43 » |
|
Джон, шас кину. Над кучей Create не ржать - лень делать массив ))) У меня мысль сейчас в другом проекте (и в самом классе контрола на скорую руку кое что просто забил, чтоб не разбираться) поиск кода, в который не верит Джон можно начать с обработчика таймера void CChecksGridStatic1153::OnTimer(UINT nIDEvent) { if(nIDEvent==TrackTimerID) { KillTimer(TrackTimerID);
//смотрим, где курсор POINT pnt; if(GetCursorPos(&pnt)) { if(WindowFromPoint(pnt)!=this) { m_wCheckTracked_nzb=0; } } Invalidate(0); }
CStatic::OnTimer(nIDEvent); }
|
|
« Последнее редактирование: 09-04-2008 09:08 от Алексей1153++ »
|
Записан
|
|
|
|
Алексей++
глобальный и пушистый
Глобальный модератор
Offline
Сообщений: 13
|
|
« Ответ #17 : 09-04-2008 08:49 » |
|
готово
|
|
|
Записан
|
|
|
|
Алексей++
глобальный и пушистый
Глобальный модератор
Offline
Сообщений: 13
|
|
« Ответ #18 : 09-04-2008 09:27 » |
|
забыл пояснить каждый контрольчик - это "одномерная" горизонтальная таблица, просто сейчас размер задан 1 ячейка. Каждая ячейка - это аналог чек-бокса. когда курсор двигается над контролом - void CChecksGridStatic1153::OnMouseMove(UINT nFlags, CPoint point) { if(GetCheckFromPoint(point,&m_wCheckTracked_nzb)) { } else { m_wCheckTracked_nzb=0; } Invalidate(0);
CStatic::OnMouseMove(nFlags, point); }
происходит проверка, над какой ячейкой контрола курсор (-> m_wCheckTracked_nzb). Номер ячейки - m_wCheckTracked_nzb , но, так как у насчейчас ячейка одна, то "ячейка" == "весь контрол". Если курсор лесом, то обнуляется m_wCheckTracked_nzb - "курсор не на контроле". Далее элемент перерисовывается. В перерисовке: в процессе отрисовки ячеек , проверяется, есть ли ячейка, над которой был недавно курсор void CChecksGridStatic1153::PaintElement(CDC *dc,long ldcW,long ldcH) { ... ... if(m_wCheckTracked_nzb==ci+1 ) { //курсор
if(m_wMarkedCell_nzb) { dc->FillSolidRect(&chkRect,RGB(255,128,64)); } else { dc->FillSolidRect(&chkRect,RGB(168,211,255)); }
SetTimer(TrackTimerID,TrackTimerTime,0); } else { //простой фон dc->FillSolidRect(&chkRect,m_dwdBkColor);//белый фон } ... ...
там же запустится таймер. Запускается здесь он каждый раз , флажка "поставленности" нет. в обработчике таймера: таймер останавливается сразу, затем , если курсор не над контролом - обнуляем номер ячейки, над которой мували. ---------------- Всё так путанно изза предназначения данного контрола, а когда надо тупо отследить выход за границу контрола - всё можно упростить
|
|
|
Записан
|
|
|
|
Джон
просто
Администратор
Offline
Пол:
|
|
« Ответ #19 : 09-04-2008 09:57 » |
|
Ок, попозже гляну. Ща времени нет. Кстати, красиво. В принципе вся анимация так и делается, если такая задача поставлена. Тебе надо было ещё fade сделать (чтоб цвет не сразу на белый менялся, а постепенно). Средняя реакция человеческого глаза 0,25 сек.
|
|
« Последнее редактирование: 09-04-2008 09:58 от Джон »
|
Записан
|
Я вам что? Дурак? По выходным и праздникам на работе работать. По выходным и праздникам я работаю дома. "Just because the language allows you to do something does not mean that it’s the correct thing to do." Trey Nash "Physics is like sex: sure, it may give some practical results, but that's not why we do it." Richard P. Feynman "All science is either physics or stamp collecting." Ernest Rutherford "Wer will, findet Wege, wer nicht will, findet Gründe."
|
|
|
tom4ik85
|
|
« Ответ #20 : 09-04-2008 12:00 » |
|
Спасибо всем огромное. Сделал о оба способа работают
|
|
|
Записан
|
|
|
|
Джон
просто
Администратор
Offline
Пол:
|
|
« Ответ #21 : 09-04-2008 13:38 » |
|
Пока читаю сообщения в теме, до кода ещё не добрался. Итак: поиск кода, в который не верит Джон можно начать с обработчика таймера Я не "не верю", в код. Я не верю, что это 100% решение для поставленной задачи. Вобще-то я не увидел запуска таймера в OnMouseMove... Собственно меня это интересовало. Когда по контролу маузмувнули - запустить таймер на 300...1000 мс Ладно будем посмотреть...
|
|
|
Записан
|
Я вам что? Дурак? По выходным и праздникам на работе работать. По выходным и праздникам я работаю дома. "Just because the language allows you to do something does not mean that it’s the correct thing to do." Trey Nash "Physics is like sex: sure, it may give some practical results, but that's not why we do it." Richard P. Feynman "All science is either physics or stamp collecting." Ernest Rutherford "Wer will, findet Wege, wer nicht will, findet Gründe."
|
|
|
tom4ik85
|
|
« Ответ #22 : 10-04-2008 08:18 » |
|
Я попробовал сделать Fade void CMyButton::OnTimer(UINT nIDEvent) { if(nIDEvent == 1) { CPoint p; GetCursorPos(&p); if(WindowFromPoint(p) != this) { InRect = FALSE; KillTimer(1); m_nFade = 0; SetTimer(3, 150, NULL); } else { KillTimer(3); } } else if(nIDEvent == 2) { if(m_nFade <= 6) { UINT temp = 255-5*m_nFade; m_nFade++; SetBgColor(RGB(temp,temp,temp)); } else { m_nFade = 0; KillTimer(2); } } else if(nIDEvent == 3) { if(m_nFade <= 6) { UINT temp = 225+5*m_nFade; m_nFade++; SetBgColor(RGB(temp,temp,temp)); } else { m_nFade = 0; KillTimer(3); } } CButton::OnTimer(nIDEvent); }
Но у мня кроме фона рисуется еще прямоугольничек другого цвета так вот, если уменьшить таймер хотя бы до 25мс, чтоб плавный переход был, заметно, что перерисовывается все И если быстро мышкой водить, то глючит Но я еще придумываю как правильно сделать
|
|
|
Записан
|
|
|
|
tom4ik85
|
|
« Ответ #23 : 10-04-2008 09:23 » |
|
если по срабатыванию таймера 2 и 3 (по входу и выходу мышки) дописать проверку, находится ли она на контроле, то не будет проблем с быстрым перемещение мышки. но все равно осталась проблемка перерисовки всего контрола - заметно мигание. Я думал, может завести несколько флажков, по которым выполняется перерисовка отдельных форм внутри контрола, но может есть более простое решение?
|
|
|
Записан
|
|
|
|
Джон
просто
Администратор
Offline
Пол:
|
|
« Ответ #24 : 10-04-2008 09:58 » |
|
fade лучше сделать в цикле пошагово с временной задержкой (50-100 мс) и управлением -> остановить цикл при повторном входе мыша в окно. Чтобы избавится от моргания - надо использовать двойной буфер. Можешь посмотреть в коде у Лёшки. Он там как раз его рализовал. Идея очень простая. Если каждый объект вырисовывать сразу на экран, то получается "моргание", тк все объекты прямоугольные и отрисовыаются по очереди. Выход: сначала рисовать в буфер (в память), а потом результат одним махом отображать на экран. Кстати я так кода с запуском таймера в OnMouseMove и не видел. Хитрый кот его просто закоментировал.
|
|
|
Записан
|
Я вам что? Дурак? По выходным и праздникам на работе работать. По выходным и праздникам я работаю дома. "Just because the language allows you to do something does not mean that it’s the correct thing to do." Trey Nash "Physics is like sex: sure, it may give some practical results, but that's not why we do it." Richard P. Feynman "All science is either physics or stamp collecting." Ernest Rutherford "Wer will, findet Wege, wer nicht will, findet Gründe."
|
|
|
tom4ik85
|
|
« Ответ #25 : 10-04-2008 10:07 » |
|
У меня так сделано void CMyButton::OnMouseMove(UINT nFlags, CPoint point) { if(InRect == FALSE) { SetTimer(1, 10, NULL); m_nFade = 0; SetTimer(2, 1, NULL); InRect = TRUE; } CButton::OnMouseMove(nFlags, point); }
А у него таймер запускается в PaintElement() по условию, которое меняется в OnMouseMove()
|
|
|
Записан
|
|
|
|
tom4ik85
|
|
« Ответ #26 : 10-04-2008 10:52 » |
|
Кидаю, что получилось. Здесь просто убрал background, поэтому не мигает. Пока не получается нарисовать в одном DC, а потом скопировать результат в другой Буду разбираться Таймер, который определяет на контроле ли еще мышка - 10мс 2 таймера для fade по 1 мс. 10 итераций. По-моему вполне нормально А в цикле с задержкой кажется сложнее будет. Хотя нужно попробовать.
|
|
|
Записан
|
|
|
|
Джон
просто
Администратор
Offline
Пол:
|
|
« Ответ #27 : 10-04-2008 11:15 » |
|
>> 2 таймера для fade по 1 мс. 10 итераций. Таймер никогда такую точность не даст... У него погрешность 20 мс.
|
|
|
Записан
|
Я вам что? Дурак? По выходным и праздникам на работе работать. По выходным и праздникам я работаю дома. "Just because the language allows you to do something does not mean that it’s the correct thing to do." Trey Nash "Physics is like sex: sure, it may give some practical results, but that's not why we do it." Richard P. Feynman "All science is either physics or stamp collecting." Ernest Rutherford "Wer will, findet Wege, wer nicht will, findet Gründe."
|
|
|
Джон
просто
Администратор
Offline
Пол:
|
|
« Ответ #28 : 10-04-2008 11:17 » |
|
Кидаю, что получилось. Опять 25, а код где?
|
|
|
Записан
|
Я вам что? Дурак? По выходным и праздникам на работе работать. По выходным и праздникам я работаю дома. "Just because the language allows you to do something does not mean that it’s the correct thing to do." Trey Nash "Physics is like sex: sure, it may give some practical results, but that's not why we do it." Richard P. Feynman "All science is either physics or stamp collecting." Ernest Rutherford "Wer will, findet Wege, wer nicht will, findet Gründe."
|
|
|
tom4ik85
|
|
« Ответ #29 : 10-04-2008 11:23 » |
|
Это не важно получается, потому что отрисовывает быстро. Ведь такая погрешность будет, если система сильно загружена и сообщения не успевают отрабатываться. Если я правильно понимаю конечно Даже если он за 200мс (10*20мс) отрисует все равно практически незаметно
|
temp.rar (11.74 Кб - загружено 954 раз.)
|
|
Записан
|
|
|
|
|