Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате |
Форум программистов > C/C++: Системное программирование и WinAPI > Не поймать WM_MOUSEMOVE во время нажатия на кнопку |
Автор: Mapa3M 29.8.2008, 00:50 |
сабж. Хочу нажать на кнопку и перетащить ее в другую часть окна. Но, когда зажимаю левую кнопку мыши и перетаскиваю, окну приходят только WM_CTLCOLORBTN. А нужное мне WM_MOUSEMOVE, как показывает Spy++ приходят кнопке (тоесть когда ставлю хук на кнопку - ловлю, а когда на окно - нет) Я буквально только-что начал знакомится с Win API, не судите строго. Расскажите пожалуйста, как поймать WM_MOUSEMOVE? Возможно ли создать, если да то как, отдельную CALLBACK для кнопки ? |
Автор: BorisVorontsov 29.8.2008, 20:01 |
ReleaseCapture? |
Автор: Mapa3M 29.8.2008, 23:28 |
спасибо за вариант, сейчас попробую. Но всетаки хотелось бы разобраться теории. Как программой должно отслеживаться сообщение посылаемое кнопке? |
Автор: Mapa3M 30.8.2008, 04:18 |
Кстати, чегото неполучается поставить SetCapture по сообщению WM_PARENTNOTIFY. По другим сообщениям получается, здесь чота никак не срабатывает. Сообщение приходит что каптча поставлена на кнопку, хотя я ставлю на окно. Как так? |
Автор: 586 30.8.2008, 04:41 | ||
|
Автор: Mapa3M 30.8.2008, 04:55 |
586, Спасиб, то что надо! Буду пробовать... |
Автор: 586 30.8.2008, 15:45 | ||||
Это народный метод. Работает только для левой кнопки. Написал здесь просто для примера - твой вопрос же был, как перехватить оконную процедуру. Если хорошенько подумать, то можно и с координатами:
|
Автор: GremlinProg 30.8.2008, 16:26 | ||||||||||
мда уж, не думал, что тема до такого марадерства дойдет... Mapa3M, сообщение мыши приходят в окно, над которым она находится, т.е., если ты кликаешь на кнопку, то WM_LBUTTONDOWN и придет в кнопку, т.е. в процедуре диалога оно само не объявится. чтобы перехватить процедуру окна любого контрола, необходимо воспользоваться специально предназначенного для этого API, вот пример такого перехвата (корректная версия с поддержкой w64):
версия с включенной поддержкой w64, это 32-битная версия, (стандартная ошибка локализации, на x64 работать не будет!):
версия с выключенной поддержкой w64 (без ошибок и без x64):
NewWndProc - это процедура кнопки, которая после такого будет вызываться вместо стандартной (OldWndProc) стратегия NewWndProc должна составлять хотя бы такой минимум:
такой перехват нужно делать сразу после инициализации диалога, например в WM_INITDIALOG если нужен перехват WM_LBUTTONDOWN, то это можно сделать так:
вариант#1: перемещение кнопки нужно сопрягать по крайней мере с тремя сообщениями мыши: 1. WM_LBUTTONDOWN 2. WM_MOUSEMOVE 3. WM_LBUTTONUP в первом нужно запомнить позицию мыши относительно левого-верхнего угла кнопки (sx,sy) = (x - left,y - top) и включить флаг переноса во втором нужно тестировать флаг переноса, и если он включен, переместить кнопку в позицию (x - sx,y - sy) в третьем нужно сбросить флаг переноса флаг переноса - просто любая глобальная переменная, изначально проинициализированная нулем вариант#2: корректное перемещение включает еще дополнительное сообщение: 4. WM_CAPTURECHANGED при этом, на WM_LBUTTONDOWN нужно еще вызвать SetCapture, а на WM_LBUTTONUP вызвать ReleaseCapture, флаг переноса сбрасывать уже не на WM_LBUTTONUP, а в сообщении WM_CAPTURECHANGED, остальное - так же как в первом варианте. попробуй оба варианта, разницу сам увидишь тебе как нужно кнопку двигать? зажатую или не зажатую, или это не важно? если не зажатую, то во время перехвата WM_LBUTTONDOWN, не выполняй стандартную обработку окна, т.е. вместо break вызови return 0 этим ты предотвратишь стандартную инициализацию механизма нажатия (в том числе и SetCapture), но тогда уже и нажиматься кнопка не будет. |
Автор: Mapa3M 30.8.2008, 18:47 |
586, О, гуру, открой мне источник своей мудрости! (Не хочу по два дня ковырять ивзращенный код того, что делается в две строчки еще и лучше) =)) З.Ы. извиняюсь, подскажите книжку... хм, учту. Метод понравился, спасибо. вот примерно так я и делал. Только с координатами помучался, ибо GetParent функции не знал, и без SetCapture. Зачем он в таком коде? Чтоб с другими обектами конфуз не вышел? GremlinProg, спасибо за подробный разбор полетов. |