Как проверить, находится ли мышь над элементом управления

Как проверить, находится ли мышь над определенным HWND? Я пытался использовать сообщения WM_MOUSELEAVE и WM_MOUSEMOVE для отслеживания, но если вы нажмете кнопку и перетащите мышь из кнопки, она не получит WM_MOUSELEAVE до тех пор, пока мышь не будет отпущена, что уже слишком поздно, потому что:

Когда вы нажимаете кнопку, сообщение WM_COMMAND отправляется только в следующих случаях:
1. Мышь изначально была нажата над кнопкой
2. Мышь находится над кнопкой
3. Мышь отпущена над кнопкой

Мне нужно воспроизвести эту функцию.


person John Zane    schedule 21.12.2010    source источник


Ответы (2)


Чтобы дублировать эту функциональность, просто вызовите SetCapture(), чтобы сообщения мыши отправлялись в ваше окно, даже если мышь покидает его. Вы можете прочитать текущую позицию мыши по мере ее перемещения и определить, находится ли она все еще над вашим окном/кнопкой (я все еще не уверен на 100%, что вы делаете). И, когда кнопка мыши отпущена, вы можете вызвать ReleaseCapture(), чтобы восстановить, куда отправляются сообщения мыши.

EDIT: Да, и вы можете использовать функцию Windows API WindowFromPoint(), чтобы определить, над каким окном находится мышь.

person Jonathan Wood    schedule 21.12.2010
comment
setCapture не является допустимым решением, потому что несколько кнопок должны знать об этом одновременно. Я также почти уверен, что SetCapture - это не то, как WndProc класса Button делает это, и это то, что мне нужно подражать. - person John Zane; 21.12.2010
comment
Что ж, это действительно, хотя в вашем случае это не сработает из-за ограничения, о котором вы не упомянули. О, и я могу гарантировать вам, что управление кнопкой Windows использует SetCapture(). Я дублировал эту функцию несколько раз. - person Jonathan Wood; 21.12.2010
comment
@ Джонатан, спасибо, и, пожалуйста, см. мой вопрос Хансу Пассанту. - person John Zane; 21.12.2010
comment
@John: Windows не поддерживает одновременный выбор нескольких кнопок. Я снова гарантирую, что кнопки Windows используют SetCapture(). Вот как они узнают, как перерисовывать себя, когда мышь движется над кнопкой и от нее, пока кнопка мыши удерживается нажатой. - person Jonathan Wood; 21.12.2010
comment
Если у вас есть две кнопки, для какой из них вы вызываете SetCapture? Простите мое невежество. - person John Zane; 21.12.2010
comment
Тот, над которым нажата кнопка мыши. Это то, что делает Windows. Если вы хотите сделать что-то отличное от того, что делает Windows, вам нужно быть более явным. - person Jonathan Wood; 21.12.2010
comment
Хорошо, я думал, что вы вызываете setCapture до того, как с кнопкой произойдет какое-либо событие. Спасибо. - person John Zane; 21.12.2010

Это встроено в Windows, это называется "захват мыши", SetCapture(hWnd). Это гарантирует, что вы получите сообщения мыши, даже если мышь переместилась за пределы окна. Вы вызываете его в уведомлении о сообщении WM_LBUTTONDOWN.

person Hans Passant    schedule 21.12.2010
comment
Мне все равно, если я получаю сообщения мыши за окном. - person John Zane; 21.12.2010
comment
Если вас не волнует сообщение о нажатии кнопки, не вызывайте SetCapture(). Что странно, важно показать, что кнопка больше не нажата. Об этом, как правило, заботятся библиотеки классов без каких-либо хлопот. Это делает даже собственный класс Windows BUTTON. - person Hans Passant; 21.12.2010
comment
@Hans, значит, BUTTON использует SetCapture? Как работают несколько кнопок одновременно? - person John Zane; 21.12.2010
comment
Не совсем уверен, есть ли у вас пример пользовательского интерфейса, который позволяет нажимать более одной кнопки одновременно? - person Hans Passant; 21.12.2010
comment
SetCapture принимает HWND. Как несколько кнопок работают одновременно, если вы должны указать один HWND? - person John Zane; 21.12.2010
comment
Вы не ответили на мой предыдущий комментарий. Я просто никогда не видел ни одного пользовательского интерфейса, в котором работало бы нажатие более одной кнопки одним щелчком мыши. Или имеет смысл для пользователя. - person Hans Passant; 21.12.2010
comment
Я неправильно сформулировал свой вопрос. Если есть две кнопки, за которыми нужно следить, как можно использовать setCapture? - person John Zane; 21.12.2010
comment
Неважно, сколько кнопок. Вы начинаете обращать внимание, когда видите уведомление о нажатии мыши на одном из них. Указывает, что пользователь нажал одну кнопку. Захватите мышь. Теперь посмотрите на сообщение о поднятии мыши. Все еще на той же кнопке? Нажмите. Избегайте повторного изобретения этого. - person Hans Passant; 21.12.2010
comment
Хорошо, и было бы достаточно использовать GetWindowFromPoint, чтобы увидеть, тот же ли это HWND в печальном событии? - person John Zane; 21.12.2010
comment
Нет, вы знаете, что координаты относительные из управления кнопкой, вы захватили мышь в конце концов. Они всегда относительные от кнопки управления. Все, что вам нужно сделать, это проверить ›= 0 && ‹ size. Выбранный вами ответ - единственный скорбный бит здесь. - person Hans Passant; 21.12.2010
comment
Спасибо, а что значит скорбная часть? - person John Zane; 21.12.2010