Для органов управления Windows, если Вы не используете VCL, требуется
обрабатывать сообщение WM_NCHITTEST.
Here's the translation of the content into Russian:
Проблема, с которой вы столкнулись, является общей проблемой при попытке поймать события мыши для custom-контрола, такого как линия, в Delphi.
Решение, которое вы предложили, используя событие CMHitTest и проверку, лежит ли точка внутри области линии (PointInLineReg), является правильным. Однако, есть некоторые дополнительные соображения и альтернативы, которые могут быть полезны знать:
Используйте WM_НЧИТТЕСТ вместо TWMNCHitTest: Поскольку вы упомянули, что не используете VCL, лучше использовать raw-окружение Windows WM_НЧИТТЕСТ (0x007B) вместо обертки Delphi TWMNCHitTest. Вы можете сделать это, перезаписав метод WndProc и проверяя сообщение WM_НЧИТТЕСТ.
Проверьте, находится ли мышь под линией: В вашем текущем реализации вы только проверяете, лежит ли точка внутри области линии. Однако, вам также нужно проверить, находится ли мышь под линией (т.е., не перекрывает ли она другие контролы). Вы можете сделать это, используя функцию GetCursorPos и проверяя, является ли позиция курсора близкой к линии.
Вот пример реализации:
type
TLine = class(TControl)
private
procedure WndProc(var Message: TMessage); override;
public
constructor Create(AOwner: TComponent); override;
end;
constructor TLine.Create(AOwner: TComponent);
begin
inherited Create(AOwner);
ParentWndProc := ClassParent.WndProc; // Сохраняем оригинальный wnd proc
end;
procedure TLine.WndProc(var Message: TMessage);
begin
if (Message.Msg = WM_НЧИТТЕСТ) then
begin
Point := MouseToScreen(Point(Message.XPos, Message.YPos));
if PointInLineReg(Point.X, Point.Y) then
Result := HTCAPTION // Поймать мышь под линией
else
Result := 0; // Не поймать мышь в других местах
end
else
ParentWndProc(Message);
end;
Перезаписав WndProc и проверяя сообщение WM_НЧИТТЕСТ, вы можете напрямую обрабатывать сообщение и определять, поймать или нет мышь. Этоapproach более эффективен, чем использовать отдельный обработчик событий.
Помните, что это реализация предполагает, что ваш контролл линии имеет свой собственный окон (HWND). Если он не имеет, вам нужно будет адаптировать код соответствующим образом.
Автор Nomadic предлагает обрабатывать сообщения CM_HITTEST для TGraphicsControl и WM_NCHITTEST для организаций управления Windows, чтобы реализовать функцию захвата только за определенный контур линии и пропуска мыши под себя в других местах.
Комментарии и вопросы
Получайте свежие новости и обновления по Object Pascal, Delphi и Lazarus прямо в свой смартфон. Подпишитесь на наш Telegram-канал delphi_kansoftware и будьте в курсе последних тенденций в разработке под Linux, Windows, Android и iOS