Обработчик события
procedure TDDDemoForm.EditBoxMouseDown( Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer);
begin if (Button = mbLeft) and (EditBox.Text <>
"") and not (ssDouble in Shift) then TEdit(Sender).BeginDrag(False);
end;
При тестировании исходной версии обработчика я обнаружил, что перетаскивание можно начать двумя способами. Если аргумент метода BeginDrag равен True, перетаскивание начинается сразу же после нажатия кнопки мыши, а если False — откладывается до тех пор, пока мышь не сдвинется на несколько пикселей. Второй вариант показался мне более естественным. Кроме того, я добавил проверку, которая блокировала попытки перетащить пустую строку. Преобразование типа, используемое при вызове метода BeginDrag, почти всегда необходимо при работе со ссылками на объекты Sender и Source, которые передаются обработчикам событий.
Настало время заняться шагом 2. Обработчику события OnDragOver передается несколько параметров. Параметр Source определяет объект, в котором началось перетаскивание (в нашем случае — текстовое поле). Параметр Sender обозначает объект, вызвавший событие, потенциальный приемник для операции перетаскивания (в нашем случае — календарь). Параметры X и Y
содержат относительные координаты курсора мыши внутри Sender, а State определяет состояние перетаскиваемого объекта (объект входит в границы Sender, покидает их или перемещается внутри Sender). Хотя для процесса перетаски вания предоставляется курсор по умолчанию, информация о состоянии позволяет легко выбрать собственный курсор для каждой стадии процесса. Наконец, присутствует логический параметр Accept, передаваемый по ссылке.
Цель игры — на основании представленной информации принять решение о том, можно ли завершить операцию перетаскивания. Ситуация выглядит так, словно пилот маленького самолета (Source) обращается к наземному наблюдателю: «Сообщаю свои координаты относительно поля, где вы находитесь. Можно ли сбрасывать груз?»
Как оказалось, выбор OvcCalendar сделал мою работу тривиальной: для сбрасывания подходит любая точка внутри клиентской области календаря. Исходный текст приведен в листинге 14.2.