23.01.2007, 23:04
общий
это ответ
Здравствуйте, Lameruga!
> Такое впечатление, что этот прямоугольник "вырезан" из окна
Именно вырезан. Это пространство принадлежит другому окну.
Ваша кнопка, как и любой другой контрол вроде Edit или ComboBox, тоже является окном. Любое окно имеет свой класс. Оконные классы этих контролов - глобальные, их не нужно создавать самостоятельно, они существуют в системе. У каждого оконного класса - своя оконная процедура. У всех кнопок класса Button оконная процедура одна, но она не имеет ничего общего с вашей оконной процедурой родительского окна. Поэтому нет смысла ожидать, что сообщения WM_MOUSEMOVE будут приходить в вашу процедуру. Они приходят в процедуру класса Button, скрытую от ваших глаз. Существует способ подменить эту стандартную процедуру на созданную вами, путем сообщения системе о том, что данный оконный класс должен использовать адрес вашей процедуры, вместо старого адреса (используется функция SetClassLong с параметром GCL_WNDPROC). В этом случае создается специальная процедура, которая будет обрабатывать нужные сообщения класса Button, а все остальные - передавать в старую процедуру (но только через CallWindowProc, при этом сначала необходимо сохранить адрес старой процедуры). Или же можно сообщить системе, что отдельный экземпляр окна должен использовать адрес вашей процедуры, вместо старого адреса (используется функция SetWindowLong с параметром GWL_WNDPROC). Этот метод называется субклассированием (subclassing). Но для ваших целей достаточно воспользоваться методом, предложенным экспертом burbot. Дам некоторые пояснения. Сообщение WM_DRAWITEM будет посылаться системой в процедуру вашего родительского окна, в случае, если оно имеет дочерний контрол (Button, ComboBox и т.п.), созданный со стилем XX_OWNERDRAW, в тот момент, когда его экземпляр окна должен быть перерисован (например, при наведении курсора).
Будет лучше, если вы прочтете подробно о сообщении WM_DRAWITEM в справке.
Удачи!