Текущий архив: 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
endprocedure 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.49 MB
Время: 0.01 c