function GetCaretPosition(var APoint: TPoint): Boolean;
var w: HWND;
aID, mID: DWORD;
begin
Result:= False;
w:= GetForegroundWindow;
if w <> 0 thenbegin
aID:= GetWindowThreadProcessId(w, nil);
mID:= GetCurrentThreadid;
if aID <> mID thenbeginif AttachThreadInput(mID, aID, True) thenbegin
w:= GetFocus;
if w <> 0 thenbegin
Result:= GetCaretPos(APoint);
Windows.ClientToScreen(w, APoint);
end;
AttachThreadInput(mID, aID, False);
end;
end;
end;
end;
//Small demo: set cursor to active caret position procedure TForm1.Timer1Timer(Sender: TObject);
var
Pt: TPoint;
beginif GetCaretPosition(Pt) thenbegin
ListBox1.Items.Add(Format('Caret position is %d %d', [Pt.x, Pt.y]));
SetCursorPos(Pt.X, Pt.Y);
end;
end;
Программный код на Delphi, предназначенный для обнаружения текущей позиции курсора (т.е., местоположения курсора) в системе Windows и отображения ее в списке.
Вот разбивка того, что код делает:
Функция GetCaretPosition принимает переменную типа TPoint в качестве входного параметра и возвращает булевое значение, указывающее, была ли успешно получена позиция курсора.
Внутри этой функции она сначала получает активное окно при помощи GetForegroundWindow. Если это возвращает 0, то это означает, что нет активного окна (т.е., система не фокусирована на каком-либо приложении), поэтому функция возвращает False.
Если активное окно найдено, она затем получает идентификатор процесса потока этого окна с помощью GetWindowThreadProcessId и текущий идентификатор потока с помощью GetCurrentThreadId.
Если эти два идентификатора отличаются, то это означает, что вызывающий поток не является тем же, который связан с активным окном. В этом случае она использует AttachThreadInput для привязки вызывающего потока к потоку активного окна. Это позволяет ей получить позицию курсора.
После привязки она получает фокусное окно при помощи GetFocus, и если это возвращает 0 (т.е., нет фокусированного контрола), она отключает потоки и возвращает False.
Если найден фокусный контроль, она затем использует GetCaretPos для получения позиции курсора и хранит ее в переменной входного типа TPoint.
Наконец, она использует ClientToScreen для преобразования позиции курсора из клиентских координат (относительно фокусного контрола) в экранные координаты.
В процедуре демонстрации (Timer1Timer) код вызывает GetCaretPosition каждый раз, когда таймер срабатывает, и если она возвращает True, он добавляет новый элемент в список с форматом "Позиция курсора X Y", где X и Y - координаты курсора. Он также использует SetCursorPos для установки курсора на эту позицию.
Альтернативное решение могло бы быть использовать функцию GetCaretPos напрямую, без привязки потоков:
В этом случае вам не нужно было бы привязывать и отключать потоки, потому что функция GetCaretPos автоматически обрабатывает переключение потоков для вас.
В статье описывается функция GetCaretPosition для определения позиции каретки в системе, а также пример ее использования в приложении на языке Delphi.
Комментарии и вопросы
Получайте свежие новости и обновления по Object Pascal, Delphi и Lazarus прямо в свой смартфон. Подпишитесь на наш Telegram-канал delphi_kansoftware и будьте в курсе последних тенденций в разработке под Linux, Windows, Android и iOS