Прилипание окон
От: Rusland  
Дата: 15.04.05 13:27
Оценка:
Нужно реализовать "прилипание" окон к границам desktopa на Delphi или Builder-e как в Winampe-e (то есть при приближении окна к границе ближе чем на 20 пикселей нужно переместить окно на край). Нужен готовый код, а не примерные объяснения как это делается. Вопрос вроде простой, но сколько не ищу примеров, ничего пока не нашел. Фактически координаты определить не трудно, например для левого края:

private
{ Private declarations }
procedure SlideWindow(var Message: TMessage); message WM_WINDOWPOSCHANGING;
....
procedure TForm1.SlideWindow(var Message: TMessage);
var WorkArea:TRect;
WinPos:TRect;
StickAt:Integer;
begin
StickAt:=20; // расстояние до границы
GetWindowRect(Form1.Handle,WinPos); //определяем left, top, width, height окна
SystemParametersInfo(SPI_GETWORKAREA,0,@WorkArea,0); // получаем свободное пространство десктопа
if(abs(WorkArea.Left — WinPos.Left)<=StickAt) then // если до левой границы меньше 20 пикселей
begin
WinPos.Left:=WorkArea.Left; // WinPos.Left получает значение границы — 0
end;
// а что вот дальше делать?
....
Re: Прилипание окон
От: Danchik Украина  
Дата: 15.04.05 14:24
Оценка: 5 (3)
Здравствуйте, Rusland, Вы писали:

R>Нужно реализовать "прилипание" окон к границам desktopa на Delphi или Builder-e как в Winampe-e (то есть при приближении окна к границе ближе чем на 20 пикселей нужно переместить окно на край). Нужен готовый код, а не примерные объяснения как это делается. Вопрос вроде простой, но сколько не ищу примеров, ничего пока не нашел. Фактически координаты определить не трудно, например для левого края:


Сомневаюсь что ты нормально пробовал.
Смотри как надо делать:


procedure WMWindowPosChanging (var Message: TWMWindowPosChanging); message WM_WINDOWPOSCHANGING;
......

procedure TForm1.WMWindowPosChanging(var Message: TWMWindowPosChanging);
const
  StickAt = 20;
var
  aWorkArea : TRect;
  aWindowRect : TRect;
begin
  if Message.WindowPos.flags and (SWP_NOMOVE or SWP_NOSIZE) = 0 then begin
    GetWindowRect(Handle, aWindowRect);

    if Message.WindowPos.flags and SWP_NOMOVE = 0 then begin
      OffSetRect (aWindowRect, - aWindowRect.Left, - aWindowRect.Top);
      OffSetRect (aWindowRect, Message.WindowPos.x, Message.WindowPos.y);
    end;

    if Message.WindowPos.flags and SWP_NOSIZE = 0 then begin
      aWindowRect.Bottom := aWindowRect.Top  + Message.WindowPos.cy;
      aWindowRect.Right  := aWindowRect.Left + Message.WindowPos.cx;
    end;

    SystemParametersInfo (SPI_GETWORKAREA, 0, @aWorkArea, 0);

    if Abs (aWindowRect.Right - aWorkArea.Right) <= StickAt then
      Message.WindowPos.x := aWorkArea.Right - (aWindowRect.Right - aWindowRect.Left)
    else
      if Abs (aWindowRect.Left - aWorkArea.Left) <= StickAt then
        Message.WindowPos.x := aWorkArea.Left;

    if Abs (aWindowRect.Top - aWorkArea.Top) <= StickAt then
      Message.WindowPos.y := aWorkArea.Top
    else
      if Abs (aWindowRect.Bottom - aWorkArea.Bottom) <= StickAt then
        Message.WindowPos.y := aWorkArea.Bottom - (aWindowRect.Bottom - aWindowRect.Top);

  end;
  inherited;
end;
Re: Прилипание окон
От: Slava Antonov Россия http://deadbeef.narod.ru
Дата: 16.04.05 00:18
Оценка:
Hello Rusland, you wrote:

> Нужно реализовать "прилипание" окон к границам desktopa на Delphi или Builder-e как в Winampe-e (то есть при приближении окна к границе ближе чем на 20 пикселей нужно переместить окно на край). Нужен готовый код, а не примерные объяснения как это делается.


Готовый компонент для этого дела входит с состав JVCL.

--
Всего хорошего, Слава
Posted via RSDN NNTP Server 1.9
Re[2]: Прилипание окон
От: Rusland  
Дата: 18.04.05 08:16
Оценка:
Здравствуйте, Danchik, Вы писали:

D>Здравствуйте, Rusland, Вы писали:


R>>Нужно реализовать "прилипание" окон к границам desktopa на Delphi или Builder-e как в Winampe-e (то есть при приближении окна к границе ближе чем на 20 пикселей нужно переместить окно на край). Нужен готовый код, а не примерные объяснения как это делается. Вопрос вроде простой, но сколько не ищу примеров, ничего пока не нашел. Фактически координаты определить не трудно, например для левого края:


D>Сомневаюсь что ты нормально пробовал.

D>Смотри как надо делать:


D>
D>procedure WMWindowPosChanging (var Message: TWMWindowPosChanging); message WM_WINDOWPOSCHANGING;
D>......

D>procedure TForm1.WMWindowPosChanging(var Message: TWMWindowPosChanging);
D>const
D>  StickAt = 20;
D>var
D>  aWorkArea : TRect;
D>  aWindowRect : TRect;
D>begin
D>  if Message.WindowPos.flags and (SWP_NOMOVE or SWP_NOSIZE) = 0 then begin
D>    GetWindowRect(Handle, aWindowRect);

D>    if Message.WindowPos.flags and SWP_NOMOVE = 0 then begin
D>      OffSetRect (aWindowRect, - aWindowRect.Left, - aWindowRect.Top);
D>      OffSetRect (aWindowRect, Message.WindowPos.x, Message.WindowPos.y);
D>    end;

D>    if Message.WindowPos.flags and SWP_NOSIZE = 0 then begin
D>      aWindowRect.Bottom := aWindowRect.Top  + Message.WindowPos.cy;
D>      aWindowRect.Right  := aWindowRect.Left + Message.WindowPos.cx;
D>    end;

D>    SystemParametersInfo (SPI_GETWORKAREA, 0, @aWorkArea, 0);

D>    if Abs (aWindowRect.Right - aWorkArea.Right) <= StickAt then
D>      Message.WindowPos.x := aWorkArea.Right - (aWindowRect.Right - aWindowRect.Left)
D>    else
D>      if Abs (aWindowRect.Left - aWorkArea.Left) <= StickAt then
D>        Message.WindowPos.x := aWorkArea.Left;

D>    if Abs (aWindowRect.Top - aWorkArea.Top) <= StickAt then
D>      Message.WindowPos.y := aWorkArea.Top
D>    else
D>      if Abs (aWindowRect.Bottom - aWorkArea.Bottom) <= StickAt then
D>        Message.WindowPos.y := aWorkArea.Bottom - (aWindowRect.Bottom - aWindowRect.Top);

D>  end;
D>  inherited;
D>end;
D>


Большое спасибо
Re[3]: Прилипание окон
От: Rusland  
Дата: 18.04.05 08:21
Оценка:
Только вот при нахождении окна у границы десктопа когда отпускаю мышку окно иногда возвращается на старое место. Как это поправить?
Re[4]: Прилипание окон
От: Danchik Украина  
Дата: 18.04.05 09:05
Оценка: 2 (1)
Здравствуйте, Rusland, Вы писали:

R>Только вот при нахождении окна у границы десктопа когда отпускаю мышку окно иногда возвращается на старое место. Как это поправить?


Попробуй это

  if Message.WindowPos.flags and (SWP_NOMOVE{ or SWP_NOSIZE}) = 0 then begin
    GetWindowRect(Handle, aWindowRect);
...
Re: Прилипание окон
От: Spaider Верблюд  
Дата: 18.04.05 10:39
Оценка:
Здравствуйте, Rusland, Вы писали:

  myForm.SnapBuffer := 20;
  myForm.ScreenSnap := true;
... << RSDN@Home 1.1.4 beta 4 rev. 303>>
--
К вашим услугам,
Re[2]: Прилипание окон
От: Rusland  
Дата: 18.04.05 10:45
Оценка:
Здравствуйте, Spaider, Вы писали:

S>Здравствуйте, Rusland, Вы писали:


S>
S>  myForm.SnapBuffer := 20;
S>  myForm.ScreenSnap := true;
S>


Это наверное для дельфи 7-ой версии, я пользуюсь 6-ой
Re[5]: Прилипание окон
От: Rusland  
Дата: 18.04.05 10:46
Оценка:
Здравствуйте, Danchik, Вы писали:

D>Здравствуйте, Rusland, Вы писали:


R>>Только вот при нахождении окна у границы десктопа когда отпускаю мышку окно иногда возвращается на старое место. Как это поправить?


D>Попробуй это


D>
D>  if Message.WindowPos.flags and (SWP_NOMOVE{ or SWP_NOSIZE}) = 0 then begin
D>    GetWindowRect(Handle, aWindowRect);
D>...
D>



Помогите перевести
if Message.WindowPos.flags and SWP_NOMOVE = 0 then begin...
на язык C++
Re[3]: Прилипание окон
От: Spaider Верблюд  
Дата: 18.04.05 10:54
Оценка:
Здравствуйте, Rusland, Вы писали:

R>Это наверное для дельфи 7-ой версии, я пользуюсь 6-ой


Дык, в исходных данный сия информация отсутствует. Может, кусок кода поможет:

procedure TCustomForm.WMWindowPosChanging(var Message: TWMWindowPosChanging);

  procedure HandleEdge(var Edge: Integer; SnapToEdge: Integer;
    SnapDistance: Integer = 0);
  begin
    if (Abs(Edge + SnapDistance - SnapToEdge) < FSnapBuffer) then
      Edge := SnapToEdge - SnapDistance;
  end;

begin
  if FScreenSnap and ((Message.WindowPos^.X <> 0) or (Message.WindowPos^.Y <> 0)) then
    with Message.WindowPos^, Monitor.WorkareaRect do
    begin
      HandleEdge(x, Left, Monitor.WorkareaRect.Left);
      HandleEdge(y, Top, Monitor.WorkareaRect.Top);
      HandleEdge(x, Right, Width);
      HandleEdge(y, Bottom, Height);
    end;
  inherited;
end;
... << RSDN@Home 1.1.4 beta 4 rev. 303>>
--
К вашим услугам,
Re[6]: Прилипание окон
От: Danchik Украина  
Дата: 18.04.05 11:04
Оценка: 2 (1)
Здравствуйте, Rusland, Вы писали:


R>Помогите перевести

R>if Message.WindowPos.flags and SWP_NOMOVE = 0 then begin...
R>на язык C++

if (!(Message->WindowPos->flags & SWP_NOMOVE)) 
{
.....
}
Re[7]: Прилипание окон
От: Rusland  
Дата: 18.04.05 11:13
Оценка:
Здравствуйте, Danchik, Вы писали:

D>Здравствуйте, Rusland, Вы писали:



R>>Помогите перевести

R>>if Message.WindowPos.flags and SWP_NOMOVE = 0 then begin...
R>>на язык C++

D>
D>if (!(Message->WindowPos->flags & SWP_NOMOVE)) 
D>{
D>.....
D>}
D>


куль
спасибо
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.