Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > Delphi: Общие вопросы > Перетаскивание панели за пределы формы


Автор: TP@MB@Y 10.5.2006, 23:35
В своей программ я реализовал панель, которую таскаю мышкой куда захочу... Но только в пределах формы. Но было бы просто замечательно, если бы сделать возможным перетаскивать панельку за пределы формы, т.е. в любую точку экрана(это сэкономит мне много рабочего места в интерфейсе)

Вот как я реализовываю перетаскивание:
Код

procedure TfMain.gbGrifMouseDown(Sender: TObject; Button: TMouseButton;
  Shift: TShiftState; X, Y: Integer);
const
  SC_DRAGMOVE = $F012;
begin
  ReleaseCapture;
  gbGrif.Perform(WM_SYSCOMMAND, SC_DRAGMOVE, 0);
end;
  

Автор: Rouse_ 10.5.2006, 23:42
Говори что ты на заголовке, и будешь таскать куда хочешь... 

Автор: TP@MB@Y 11.5.2006, 00:18
Rouse_, поясни пожалуста smile 

Автор: Poseidon 11.5.2006, 02:18
Цитата(TP@MB@Y @  10.5.2006,  23:35 Найти цитируемый пост)
реализовал панель
 Это TPanel что-ли? Если так, то почему бы просто не установить
Код
Panel1.DockSite:= True;
Panel1.DragKind:= dkDock;
Panel1.DragMode:= dmAutomatic;

и сможешь тягать эту панель даже за пределы формы 

Автор: TP@MB@Y 11.5.2006, 11:55
Poseidon, спасибо, работает  smile  А можно как то убрать крестик(верхний правый угол) на панели.  

Автор: Snowy 11.5.2006, 12:26
Можно. Через SetWindowLong - изменить Style при окончании драгэндока. 

Автор: Alexeis 11.5.2006, 14:28
Snowy, это здесь не пройдет. После создания окна такие стили не работают. VCL стили окна меняет так
Код

procedure TCustomPanel.SetBorderStyle(Value: TBorderStyle);
begin
  if FBorderStyle <> Value then
  begin
    FBorderStyle := Value;
    RecreateWnd;
  end;
end;

т.е. пересоздает окно
для Value разрешены только два варианта bsNone и bsSingle
так что нужно создовать наследника и перекрыть функцию. 

Автор: Snowy 11.5.2006, 16:20
Цитата(alexeis1 @  11.5.2006,  14:28 Найти цитируемый пост)
Snowy, это здесь не пройдет.
Позволю себе с Вами не согласиться.
То, что окно пересоздается, совсем не значит, что оно перестает существовать.
Просто меняет владельца.
Код

procedure TForm1.PanelkaEndDock(Sender, Target: TObject; X, Y: Integer);
var wnd: HWND;
begin
  wnd := GetParent(Panelka.Handle);
  if wnd = Handle then Exit;
  SetWindowLong(wnd, GWL_STYLE, GetWindowLong(wnd, GWL_STYLE) xor WS_DLGFRAME);
end;


Добавлено @ 16:21 
Здесь Panelka - это панель с установленным драгэндоком. 

Автор: Alexeis 11.5.2006, 16:38
Snowy, 
Цитата(Snowy @  11.5.2006,  15:20 Найти цитируемый пост)
То, что окно пересоздается, совсем не значит, что оно перестает существовать.
Просто меняет владельца.


Очень интересно! Не знал...

Однако этот код делает заглоловок неактивным, не удаляя его, тоже самое происходит если применить подобный код к форме. Напимер, во время работы программы (после application.run) уже нельзя удалить таким образом кнопки свернуть и развернуть. 

Автор: Snowy 11.5.2006, 16:53
Цитата(alexeis1 @  11.5.2006,  16:38 Найти цитируемый пост)
Однако этот код делает заглоловок неактивным, не удаляя его
???
Какой заголовок? У меня после этого кода не остается никакого заголовка.

Добавлено @ 16:58 
Прикладываю проект для D7  

Автор: Alexeis 12.5.2006, 09:05
Snowy, пробовал ваш экзешник - ситуация анологичная заголовок неактивный, но вполне видимый (синяя полоска с крестиком) 

Тестировал на Microsof Windows 2000 5.00.2195 Service Pack 4. 

Автор: Snowy 12.5.2006, 10:19
Тогда немного поправим - сделаем по честному.
Код

procedure TForm1.PanelkaEndDock(Sender, Target: TObject; X, Y: Integer);
var wnd: HWND;
begin
  wnd := GetParent(Panelka.Handle);
  if wnd = Handle then Exit;
  SetWindowLong(wnd, GWL_STYLE, GetWindowLong(wnd, GWL_STYLE) and not WS_DLGFRAME);
end;

У меня на 2003 отлично работает.

Добавлено @ 10:30 
Пришиваю новый вариант.
В нем панелька еще и обратно ставится.  

Автор: Yanis 12.5.2006, 10:32
У меня как и у Snowy, всё работает как требуется. 

Автор: Alexeis 12.5.2006, 10:32
Snowy, тот же эффект !
Кстати, вариант с "and not WS_DLGFRAME" - я уже раньше пробовал с тем же результатом. 

Автор: Snowy 12.5.2006, 10:36
Под XP и 2003 на D7 работает корректно.
Я бы рад поправить, но у меня данная проблема не возникает... 

Автор: Alexeis 12.5.2006, 10:37
Yanis, какая винда smile  

Автор: Yanis 12.5.2006, 10:39
Win XP sp2 

Автор: Snowy 12.5.2006, 10:39
Ага. Нашел. Если отключить стили - заголовок остается.
Щас посмотрим...

Добавлено @ 10:49 
Без стилей нужно ресайзнуть маленько, чтобы эффект сработал.
Код

procedure TForm1.PanelkaEndDock(Sender, Target: TObject; X, Y: Integer);
var wnd: HWND;
begin
  wnd := GetParent(Panelka.Handle);
  if wnd = Handle then Exit;
  SetWindowLong(wnd, GWL_STYLE, GetWindowLong(wnd, GWL_STYLE) and not WS_CAPTION);
  Panelka.Parent.Width := Panelka.Parent.Width + 1;
end;


Добавлено @ 10:50 
Можно и более аккуратно сделать, просто этот способ самый короткий. 

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)