Форум — Ответы     (  К темам )
 ?  Fred: Взаимное расположение двух форм на экране. (11-12-2002 04:55:33)
Задачка следующая:
На экране есть две формы Form1 и Form2. Form1 может свободно перемещаться по экрану, а положение Form2 жестко привязано к Form1 (например, всегда справа). Я не нашел у TForm события срабатывающего при перемещении формы. Поэтому чтобы привязать положение Form2 к Form1 мне пришлось ставить обработчик OnTimer, который постоянно анализирует взаимное расположение Form1 и Form2, и в случае необходимости пересчитывает координаты Form2.
Существуют ли другие, более простые, решения этой проблемы и несвязанные с таймером ?

С уважением. Fred.
 Devnvd (11-12-2002 14:08:08)
Выйти из положения вы сможете так:

//-------- Это для Form1 которая должна быть слева -------
__fastcall TForm1::TForm1(TComponent* Owner)
: TForm(Owner)
{
WindowProc=MyWindowProc;
}
//---------------------------------------------------------------------------
void __fastcall TForm1::MyWindowProc(TMessage &msg)
{
if(msg.Msg==WM_MOVE)
{
if(Form2->Visible)
{
RECT R;
GetWindowRect(Handle,&R);
Form2->Left=R.right;
Form2->Top=R.top;
}
}
//Стандартная обработка сообщений
WndProc(msg);
}

//-------- Это для Form2 которая должна быть справа -------
__fastcall TForm2::TForm2(TComponent* Owner)
: TForm(Owner)
{
WindowProc=MyWindowProc;
}
//---------------------------------------------------------------------------
void __fastcall TForm2::MyWindowProc(TMessage &msg)
{
if(msg.Msg==WM_MOVE)
{
if(Form1->Visible)
{
RECT R1,R2;
GetWindowRect(Form1->Handle,&R1);
GetWindowRect(Form2->Handle,&R2);
Form1->Left=R2.left-(R1.right-R1.left);
Form1->Top=R2.top;
}
}
//Стандартная обработка сообщений
WndProc(msg);
}
 Fred (13-12-2002 01:47:48)
Спасибо, Devnvd.
 Fred (13-12-2002 02:53:17)
Если не трудно, еще один, попутный в тему вопрос.

1) Я попробовал немного изменить код:

void __fastcall TForm1::MyWindowProc(TMessage &msg)
{
if(msg.Msg==WM_MOVE)
{
if(Form2->Visible)
{
//RECT R;
//GetWindowRect(Handle,&R);
//Form2->Left=R.right;
//Form2->Top=R.top;

Form2->Left=Left+Width; // Моя вставка
Form2->Top =Top; // Моя вставка

}
}
//Стандартная обработка сообщений
WndProc(msg);
}

Мне казалось, что это выглядит эквивалентно, однако, работает только при перемещении Form1 по горизонтали. Чем это можно объяснить ?
 Devnvd (13-12-2002 10:04:20)
Когда вы обращаетесь Left,Width,Top, то вы получаете те значения которые были до перемещения. Только после выполнения WndProc(msg); эти величины примут реальные значения. Так как в отработчике WMMove будут получены с помощью GetWindowRect реальное положение и размеры.
Здесь же возникают два неявных сообщения WM_MOVE когда вы делаете Form2->Left= и когда Form2->Top= . Чтобы уменьшить длину цепочку спровоцированных вами сообщений изменяйте размеры и положения окон одной функцией SetBounds.