Другие вопросы здесь не ответили на вашу часть 2, поэтому я попробую:
2. How does windows do this? (I'm more curious then anything, but if it's not to complex, maybe I could implement something similar in my own program?)
Следует понимать, что даже если у вас открыты десятки окон, в каждом из которых много панелей инструментов, в каждой много элементов и т. Д., Каждый раз, когда вы перемещаете мышь, окнам не нужно проверять все < / em>.
Windows в основном имеет двухуровневую структуру: есть HWND, с помощью которых сама Windows управляет разделением пространства на рабочем столе; и обычно в каждом HWND есть элемент управления, который управляет своим собственным пространством внутри этого HWND: список, управляющий своими собственными элементами списка, элемент управления вкладками, управляющий своими собственными вкладками, элемент управления HTML, управляющий собственным макетом HTML-страницы, и так далее. (Или, в вашем случае, код, управляющий примерно 50 прямоугольниками.)
Когда мышь перемещается, Windows сначала определяет правильный HWND для отправки этого WM_MOUSEMOVE. И делает это путем обхода HWND. HWND хранятся в виде дерева, представляющего сдерживание, и порядок между братьями и сестрами, представляющий Z-порядок, поэтому Windows может выполнить простой спуск в глубину в это дерево, чтобы найти самый нижний HWND в любой заданной точке. Если вы запустите приложение Spy ++, вы сможете сами увидеть, как выглядит это дерево HWND. Обратите внимание, что Windows не выполняет полного исчерпывающего обхода: при обходе окон приложений верхнего уровня, например, чтобы узнать, в каком приложении находится точка, как только Windows находит первый HWND верхнего уровня, содержащий точку, он углубится в это, полностью игнорируя все другие приложения, которые находятся ниже / после него, и все элементы управления в них. Это ключ, который означает, что окнам нужно пройти только относительно небольшое количество HWND, даже если на экране сразу много видимых.
Как только Windows определяет правильный HWND, она отправляет ему соответствующее сообщение (WM_NCHITTEST, WM_MOUSEMOVE и т. Д.), И затем этот элемент управления должен делать то же самое для своего собственного содержимого. Для списка, содержащего элементы фиксированного размера, определение элемента в конкретной точке может быть таким же простым, как операция деления; или для элемента управления HTML, элемент управления может иметь свой собственный эквивалент «дереву макета», который он может использовать для быстрого перехода и быстрого определения элемента в этой точке. В вашем случае цикл по списку прямоугольников может быть прекрасным.
Это несколько упрощенная версия: она немного сложнее, чем указано выше - например. windows не только для проверки «точка в прямоугольнике», есть и другие проверки, позволяющие создавать прозрачные окна нечетной формы (а также невидимые и отключенные окна); но применима основная идея спуска по дереву.
Другой важный момент, о котором следует помнить, заключается в том, что все это происходит довольно быстро: перемещение мыши происходит в «человеческое время», и современный ЦП может выполнять множество операций за то время, которое требуется мыши, чтобы переместить пару пикселей на экран. И, наконец, обратите внимание, что когда вы перемещаете мышь из точки A в точку B на экране, мышь не всегда проходит через каждый пиксель между ними, особенно если вы перемещаете мышь быстро.
person
BrendanMcK
schedule
04.03.2012