Другие вопросы здесь не ответили на вашу часть 2, так что я дам, что выстрел:
2. Как окна сделать это? (Мне больше любопытно, чем угодно, но если это не сложно, может быть, я смогу реализовать что-то подобное в своей собственной программе?)
Следует понимать, что даже если у вас открыто несколько десятков окон, много панелей инструментов, каждый со многими элементами в нем и т. д., каждый раз, когда вы перемещаете мышь, окна не нужно проверять все.
Windows в основном структурирована в двух слоях: есть HWND, а именно, как сама ОС Windows управляет подразделением пространства на рабочем столе; и обычно внутри каждого HWND есть элемент управления, который управляет своим собственным пространством внутри этого HWND: список управления, управляющий своими собственными элементами списка, элемент управления вкладками, управляющий своими собственными вкладками, элемент управления HTML, управляющий собственной компоновкой HTML-страницы, и так далее. (Или, в вашем случае, код управляет 50 или около того прямоугольников.)
Когда мышь перемещается, Windows сначала определяет правильный HWND для отправки этого WM_MOUSEMOVE в. И он делает это, пересекая HWND. HWND хранятся в виде дерева, представляющего сдерживание, и порядка среди братьев и сестер, представляющих Z-Order, поэтому Windows может выполнить простой спуск по глубине в это дерево, чтобы узнать самый нижний HWND в любой заданной точке. Если вы запустите приложение Spy ++, вы сами увидите, как выглядит это дерево HWND. Обратите внимание, что Windows не выполняет полный исчерпывающий обход: при прохождении окон приложений верхнего уровня, например, чтобы узнать, в каком приложении находится точка, как только окна обнаруживают первый HWND верхнего уровня, который содержит точку, это будет работать в этом, прямо игнорируя все другие приложения, которые находятся ниже/после него, и все элементы управления внутри них. Это ключ, который означает, что только окна должны проходить относительно немного HWND, даже если на экране есть много видимых объектов.
Как только Windows определит правильный HWND, он отправит соответствующее сообщение (WM_NCHITTEST, WM_MOUSEMOVE и т. Д.), А затем до этого элемента управления будет действовать аналогично для собственного контента. Для списка, содержащего элементы фиксированного размера, определение элемента в определенной точке может быть таким же простым, как операция деления; или для элемента управления HTML, элемент управления может иметь свой собственный эквивалент «дерева макетов», который он может использовать для быстрого пересечения элемента в этой точке. В вашем случае прокрутка списка прямоугольников может быть совершенно прекрасной.
Это несколько упрощенная версия: она немного сложнее, чем выше - например. окна не просто проверены на точечную проверку, есть и другие проверки, позволяющие использовать нечетные и прозрачные окна (и невидимые и отключенные окна); но основная идея спуска дерева.
Другая важная проблема, которую следует помнить, заключается в том, что все это довольно быстро: перемещение мыши происходит в «человеческом времени», а современный процессор может выполнять множество операций за время, которое требуется мыши для перемещения пары пикселей на экране. И, наконец, обратите внимание, что когда вы перемещаете мышь из точки A в точку B на экране, мышь не всегда пересекает каждый отдельный пиксель между ними - особенно если вы быстро перемещаете мышь.
Использовать PtInRect. Если есть проблема с эффективностью, профиль и измените ее. –