Top.Mail.Ru
Мастера DELPHI, Delphi programming community Титульная страница Поиск, карта сайта Написать письмо 
| Новости | Поиск | FAQ | Статьи | Книги | Новости VCL |
| Форумы ЧАТ | Орешник | KOL и MCK |
Форумы -» Основная («Начинающим»)/ Базы / WinAPI / Компоненты / Сети / Media / Игры / Corba и COM / KOL / FreePascal / .Net / Прочее / RSDN.ORG

« предыдущая ветвь | форум | следующая ветвь »

Не работает метод EndDrag [D5, Win2k]


pusrg ©   (2002-06-06 22:56:00) 

Уважаемые мастера! Не откажите в помощи.

Проблема в следующем:
Для динамически создаваемого TListView обрабатываю следующие события: OnMouseDown и OnDblClick.
OnMouseDown мне нужен для запуска перетаскивания пункта списка. Но когда выполняется двойной щелчок, происходит вызов модального окна, при этом естественно нужно процесс перетаскивания отменить.
Что я и пытаюсь сделать вызовом метода EndDrag. Но по закрытию модального окна, процесс перетаскивания не прекращается - пункт списка отрисовывается в состоянии Drag, хотя клавиша мыши уже давно отпущена.

Привожу исходный код:

procedure TFormTimetable.LvOrderMouseDown(Sender: TObject; Button: TMouseButton;Shift: TShiftState; X, Y: Integer);
begin
if Button = mbLeft then
(Sender as TListView).BeginDrag(false);
...
end;

procedure TFormTimetable.LvOrderDblClick(Sender: TObject);
var CurClick, CurClickControl:TPoint;
CurItem:TListItem;
begin
(Sender as TListView).EndDrag(false);//Пробовал указывать параметр true - бестолку.
...
Form.ShowModal;//По закрытию этой формы перетаскивание остается.
end;


Заранее спасибо за помощь.


pusrg   (2002-06-07 15:21:00) [1]

Пожалуй да.


Игорь Шевченко   (2002-06-07 15:01:00) [2]

Есть решение несколько более сложное, через Timer, но если вас устраивает ваше, то наверное, можно оставить, как есть ?


pusrg   (2002-06-07 14:52:00) [3]

To Игорь Шевченко
Спасибо за Ваш ответ.

Как показало изучение стека вызовов процедур, проблема в следующем. Для класса TControl метод WMLButtonDblClk определен следующим образом:


procedure TControl.WMLButtonDblClk(var Message: TWMLButtonDblClk);
begin
SendCancelMode(Self);
inherited;
if csCaptureMouse in ControlStyle then MouseCapture := True;
if csClickEvents in ControlStyle then DblClick;
DoMouseDown(Message, mbLeft, [ssDouble]);//В этой строке после вызова метода DblClick, вызывается MouseDown еще раз и перетаскивание просто запускается по новой.
end;

Пришлось поставить ограничивающий флаг, следующим образом:


var SanctionDragging:boolean;
...

procedure TFormTimetable.LvOrderMouseDown(Sender: TObject; Button: TMouseButton;Shift: TShiftState; X, Y: Integer);
begin
if Button = mbLeft then
if SanctionDragging then (Sender as TListView).BeginDrag(false)
else SanctionDragging:=true;
...
end;

procedure TFormTimetable.LvOrderDblClick(Sender: TObject);
var CurClick, CurClickControl:TPoint;
CurItem:TListItem;
begin
SanctionDragging:=false;
(Sender as TListView).EndDrag(false...
Form.ShowModal;
end;


Вроде все нормально. Кому известны другие решения этой проблемы, с удовольствием их выслушаю.

P.S.
//Я бы советовал изменить интерфейс, чем мучиться с различением Click и DblClick.

Я бы сам с удовольствием использовал другой интерфейс, не привык с такими извратами программировать. Но к сожалению от меня в данном проекте это не зависит. Получаю указания сверху :)


Игорь Шевченко   (2002-06-07 11:29:00) [4]

При щелчке мышью на ListView ВСЕГДА возникает событие OnClick, даже если это двойной щелчок. Я бы советовал изменить интерфейс, чем мучиться с различением Click и DblClick. Если очень хочется помучиться, то у Пачеко "D5 руководство разработчика" есть пример определения истинных Click и DblClick. Или самому таймер поставить на время GetDoubleClickTime()


Наверх

Титульная страница Поиск, карта сайта Написать письмо