Главная страница
Top.Mail.Ru    Яндекс.Метрика
Текущий архив: 2006.06.25;
Скачать: CL | DM;

Вниз

Перенос и отлов панели.   Найти похожие ветки 

 
RUNaum ©   (2006-05-13 21:59) [0]

Тривиальная задача стоит. Необходимо мышкой перетащить панель и во время переноса отлавливать ее новые координаты.

С первой частью задачи справился без проблем с помощью кода, который приводится во всех без исключения FAQ"ах:

procedure TForm1.pnZoomMouseDown(Sender: TObject;
 Button: TMouseButton; Shift: TShiftState; X, Y: Integer);
const
SC_DragMove = $F012;  
begin
ReleaseCapture;
pnZoom.Perform(WM_SysCommand, SC_DragMove, 0);
end;

Но тут встает проблема. Отловить позицию панели я могу лишь в MouseDown"e, до передачи WM_SysCommand. Когда компонент находится в "режиме" переноса я не могу контролировать OnMouseMove :( Посоветуйте, как лучше поступить.

p.s. может и стоит забыть про такой способ drag"a панели...


 
Мефисто   (2006-05-13 22:27) [1]

DockSite
DragMode
DragKind
UseDockManager
OnDrag... & Ko
OnDock... & Ko

\D7\Demos\Docking


 
RUNaum ©   (2006-05-14 12:59) [2]

Огромное спасибо )

Есть маленький нюанс.


 object Panel1: TPanel
   Left = 216
   Top = 200
   Width = 73
   Height = 81
   Caption = "Panel1"
   DragMode = dmAutomatic
   TabOrder = 3
   OnEndDrag = Panel1EndDrag
   OnStartDrag = Panel1StartDrag
 end


procedure TMainForm.FormDragOver(Sender, Source: TObject; X, Y: Integer;
 State: TDragState; var Accept: Boolean);
begin
if Source=Panel1 then
begin
 Panel1.Left:=X;
 Panel1.Top:=Y;
end;
end;


Вот при таком раскладе, Drag"n"drop выполняется как надо, но с некоторой периодичностью панель "застряет" на форме, т.е. движение панели перестает быть плавным и она дергается. С чем это может быть связано?


 
Мефисто   (2006-05-14 18:31) [3]

Непонимаю, нафиг ты панельке позицию назначаешь при перетаскивании? Какой в этом умысел? Опиши задачу в целом...


 
RUNaum ©   (2006-05-14 20:30) [4]

Я возможно не совсем корректно понял как работать с D"n"D :)
Но без указания новых координат панели при драге не выйдет ее видимого перемещения.

Если указать:

procedure TMainForm.FormDragOver(Sender, Source: TObject; X, Y: Integer;
State: TDragState; var Accept: Boolean);
begin
if Source=Panel1 then
 Accept:=True;
end;


то панель не сдвинется с места, не смотря на то что драг "как бы работает".


 
RUNaum ©   (2006-05-14 20:32) [5]

Задача стоит, как я уже говорил, тривиальная. Необходимо на форме мышью "плавно" позиционировать панель, постоянно обрабатывая ее текущие координаты.


 
Мефисто   (2006-05-14 21:54) [6]

>> RUNaum  ©   (14.05.06 20:32) [5]

Тогда так :)

У формы:

 public
   { Public declarations }
   FDrag: Boolean;
   FX, FY: Integer;
 end;

TForm.OnMouseUp:

begin
 if FDrag then
 begin
   TWinControl(Sender).Left  := FX;
   TWinControl(Sender).Top   := FY;
   ReleaseCapture;
   FDrag := False;
 end;
end;

TForm.OnMouseMove:

begin
 if FDrag then
 begin
   TWinControl(Sender).Left := X - FX;
   TWinControl(Sender).Top := Y - FY;
 end;
end;

TForm.OnMouseDown:

begin
 FDrag := True;
 FX := X;
 FY := Y;
 SetCapture(TWinControl(Sender).Handle);
end;

В событии панели:

TPanel.OnMouseDown:

const
 SC_DragMove = $F012;
begin
 ReleaseCapture;
 TWinControl(Sender).Perform(WM_SysCommand, SC_DragMove, 0);
end;


 
REA   (2006-05-15 10:37) [7]

SetCapture - см. MouseCapture


 
RUNaum ©   (2006-05-15 12:53) [8]

Мефисто   (14.05.06 21:54) [6]
я так понимаю, вы привели два разных варианта =) первый "ручной" таксть ) второй "панельный". т.к. приведенные вами задумки вместе просто не совместимы и не имеют смысла.

const
SC_DragMove = $F012;
begin
ReleaseCapture;
TWinControl(Sender).Perform(WM_SysCommand, SC_DragMove, 0);
end;


отличное решение, но как отлавливать координаты? в этом режиме я никак не могу ( ни событиями формы, ни событиями панели. уже мысли дуратские о таймере закрадываются, но это ужасно и убого.

REA   (15.05.06 10:37) [7]
не понял. MouseCapture - лишь сигнализирует нам о том, что компонент был захвачен мышью, не более. как это может помочь?


 
REA   (2006-05-15 13:11) [9]

Это почему же? Очень даже и наоборот. ReleaseCapture и SetCapture можно делать через это свойство.


 
RUNaum ©   (2006-05-15 13:19) [10]

Ааа! Я понял, мне че-то в голову стукнуло что это ReadOnly. ясно. но сути дела не меняет.

Мастера, помогите. Задача простая в доску, я уже двое суток не могу допереть =(


 
REA   (2006-05-15 14:42) [11]

Как нибудь так:

Procedure TForm1.Panel1MouseDown(Sender: TObject; Button: TMouseButton;
 Shift: TShiftState; X, Y: Integer);
Begin
 MouseCapture := True;
 Ofs := Point(X, Y);
End;

Procedure TForm1.FormMouseMove(Sender: TObject; Shift: TShiftState; X,
 Y: Integer);
Begin
 If MouseCapture And (Ofs.X > 0) Then
 Begin
   Panel1.Top := Y - Ofs.Y;
   Panel1.Left := X - Ofs.X;
 End;
End;

Procedure TForm1.FormMouseUp(Sender: TObject; Button: TMouseButton;
 Shift: TShiftState; X, Y: Integer);
Begin
 Ofs.X := -1;
End;


 
Мефисто   (2006-05-15 18:20) [12]

RUNaum  ©   (15.05.06 12:53) [8]

Здрастье приехали :)

>> т .к. приведенные вами задумки вместе просто не совместимы и не имеют смысла.

Можно потробней?

>> я так понимаю, вы привели два разных варианта =) первый "ручной" таксть ) второй "панельный".

Вообще-то все один пример (один вариант).

>> отличное решение, но как отлавливать координаты?

Координаты и отлавливаются в событии формы.


 
RUNaum ©   (2006-05-16 04:38) [13]

Мефисто   (15.05.06 18:20) [12]
вся проблема в том, что данный пример не работает =) обратите внимание, что что-то в нем точно не так ) первая часть (до обработки панели) примера по сути привязана к форме и срабатывает довольно "забавно", когда начинаешь drag самой формы ) понятное дело что никак иначе она сработать то и не может.

а вариант с панелью работает как и должен. либо в приведенном примере опечатка и вы гдя-то перепутали панель с формой, а я не допонял вашу задумку и не смог найти опечатку (а заниматься комбинаторикой как то грустно =).


 
REA   (2006-05-16 10:23) [14]

Ну а мой то работает? Принцип то же что и у Мефисто, но немного короче.


 
RUNaum ©   (2006-05-16 17:02) [15]

REA   (15.05.06 14:42) [11]
Прошу прощение, не заметил поста. Огромное спасибо, именно то что нужно - все работает. C MouseCapture разобрался )


 
RUNaum ©   (2006-05-16 17:18) [16]

В догонку вопрос, который меня всегда волновал.

Если рассматривать вариант с

const
SC_DragMove = $F012;  
begin
ReleaseCapture;
pnZoom.Perform(WM_SysCommand, SC_DragMove, 0);


то перерисовка контента панели НЕ заметна глазом )

если мы указываем же ее Left/Top то перерисовка контента заметна. Как при мануальном изменении позиции панели избавиться от этой "ненужной" перерисовки?


 
REA   (2006-05-17 10:31) [17]

Способ с SC_DRAGMOVE использует функцию windows по перетаскиванию окон. Вероятно при этом отрисовка блокируется средствами Windows, но константа не определена (Magic Number), поэтому есть некоторая вероятность, что в следующих версиях windows это не сработает.
Попробуй поставить Panel1.DoubleBuffered := True;


 
REA   (2006-05-17 11:00) [18]

И еще так попробуй:

Procedure TForm1.FormMouseMove(Sender: TObject; Shift: TShiftState; X, Y: Integer);
Begin
 If MouseCapture And (Ofs.X > 0) Then
 Begin
   SetWindowPos(Panel1.Handle, 0, X - Ofs.X, Y - Ofs.Y, 0, 0,
     SWP_NOZORDER Or SWP_NOSENDCHANGING Or SWP_NOSIZE);
 End;
End;

Procedure TForm1.FormMouseUp(Sender: TObject; Button: TMouseButton;
 Shift: TShiftState; X, Y: Integer);
Begin
 If (Ofs.X > 0) Then
 Begin
   Ofs.X := -1;
   SetWindowPos(Panel1.Handle, 0, X - Ofs.X, Y - Ofs.Y, 0, 0,
   SWP_NOZORDER Or SWP_NOSIZE);
 End;
End;


 
RUNaum ©   (2006-05-17 16:30) [19]

большое спасибо ) вроде все как надо ))



Страницы: 1 вся ветка

Текущий архив: 2006.06.25;
Скачать: CL | DM;

Наверх




Память: 0.52 MB
Время: 0.043 c
3-1146121628
Ильичев С.А.
2006-04-27 11:07
2006.06.25
SELECT после INSERT


8-1135810572
MIDI
2005-12-29 01:56
2006.06.25
Как проиграть MIDI ?


2-1149596976
mfender
2006-06-06 16:29
2006.06.25
TWebBrowser: найти и удалить элемент


2-1149588259
D@Nger
2006-06-06 14:04
2006.06.25
Ошибка при поиске методом Locate


2-1149663296
Fiallo4ka
2006-06-07 10:54
2006.06.25
Ado