Форум: "Основная";
Текущий архив: 2003.07.21;
Скачать: [xml.tar.bz2];
ВнизMDI Окошки Найти похожие ветки
← →
Smok_er (2003-07-08 14:18) [0]Привет Мастера! МОжет кто-нибудь знает ответ на мои вопросы:
1) Есть форма, на которой расположен тулбар, статусбар, панель слева, справа и т.д. У каждого компонента выставлено свойство Align. Как можно определить размеры ДОСТУПНОЙ части формы?
Вариант MyWidth := Form.Width - Panel1.Width - Panel2.Width; не подходит, т.к. неизвестно, сколько будет панелей.
2) В цикле я расставляю MDI окошки в некой аккуратной последовательности. Но к сожалению потом можно изменить размер окна или перенести окошко в другое место. Как можно запретить эти действия пользователю? Пробовал обрабатывать сообщения, подставлять в обработчике сообщения WM_MOVE сообщение WM_NULL - не получается.
Заранее большое спасибо за внимание и помощь!
← →
Radionov Alexey (2003-07-08 14:48) [1]Доступная чать - clientrect
OnCanResize - размеры
wm_moving - контроль положения
Но, насколько я понял, проблема в том, что ты не хочешь чтобы "дети бегали по грядкам"?
Если так, то сделать можно наподобие следующего:
Procedure TMainForm.FormCreate(Sender: TObject);
Var
Rgn: HRgn;
Rect: TRect;
Begin
Rect := ClientRect; // здесь получаем область, где могут ходить дети
Rect.Bottom := Rect.Bottom - Panel1.Height; // Я кинул вниз панель, поэтому то место, где лежит панель не должно быть доступным (грядка)
With rect Do
Rgn := CreateRectRgn(Left, top, right, bottom); // Создаю регион
SetWindowRgn(ClientHandle, Rgn, false); // И назначаю новую область, где могут ходить дети
DeleteObject(Rgn);
End;
Сию операцию надо проводить и при изменении рамеров родителя.
Для того, чтобы не запоминать где кто лежит, достаточно пробежаться по Controlам на форме и вырезать их прямоугольники из доступной для детей области с помощью CombineRgn
← →
Radionov Alexey (2003-07-08 14:52) [2]Хотя, то что я написал и так происходит автоматически. Сорри. Замкнул...
← →
wl (2003-07-08 15:04) [3]Событие WM_MOVE появляется _после_ изменения положения формы.
можно попробовать отловить WM_MOVING
← →
Smok_er (2003-07-08 15:08) [4]Большое спасибо! Но...
>>Rect.Bottom := Rect.Bottom - Panel1.Height;
Вы вычисляете вручную доступную область, а хотелось бы этого избежать.
Если можно, приведите пожалуйста пример запрета перемещения при перехвате сообщения WM_MOVING
Большое спасибо!
← →
Radionov Alexey (2003-07-08 15:19) [5]>Вы вычисляете вручную доступную область, а хотелось бы этого
>избежать.
Я уже написал, что это происходит автоматически. Тот код, что я привел ранее - толчение воды в ступе.
Вот пример на wm_moving:
TMdiChildForm= Class(TForm)
.........
procedure wmMoving(Var Msg : TMessage); message wm_moving;
............
end;
procedure TMdiChildForm.wmMoving(var Msg: TMessage);
Var Rc : TRect;
begin
Rc := Rect(100,100,400,400);
with Application.MainForm.ClientOrigin do
OffsetRect(Rc,x,y);
TRect(Pointer(Msg.LParam)^):= Rc;
end;
← →
Smok_er (2003-07-08 15:41) [6]Видимо это не тот код
Все, что мне надо - это не дать возможность юзеру вручную перенсти дочернюю форму.
← →
Игорь Шевченко (2003-07-08 15:44) [7]Размер доступной для MDI-child"ов области можно определить через var ARect : TRect;
GetClientRect(MainFrom.ClientHandle, ARect);
← →
Radionov Alexey (2003-07-08 15:50) [8]>Smok_er (08.07.03 15:41)
>Все, что мне надо - это не дать возможность юзеру вручную
>перенсти дочернюю форму.
Именно это и делается
← →
Smok_er (2003-07-08 16:00) [9]Игорь Шевченко © (08.07.03 15:44)
var ARect : TRect;
GetClientRect(MainFrom.ClientHandle, ARect);
Не работает :(
Во-первых у этой функции нет аргументов, а во-вторых - неверно передает данные :(
Radionov Alexey © (08.07.03 15:50)
>Все, что мне надо - это не дать возможность юзеру вручную
>перенсти дочернюю форму.
Именно это и делается
А при здесь тогда Rc := Rect(100,100,400,400); ?
← →
Radionov Alexey (2003-07-08 16:10) [10]просто вставил конкретный прямоугольник.
На код, который гвоздями прибивает форму (правда, она реагирует на все, что не руками):
Procedure TMDIChildForm.wmMoving(Var Msg: TMessage);
Var
Rc: TRect;
Pt : TPoint;
Begin
Rc := BoundsRect;
Pt := BoundsRect.TopLeft;
Windows.ClientToScreen(Application.MainForm.clientHandle,Pt);
With Pt Do
OffsetRect(Rc, x, y);
TRect(Pointer(Msg.LParam)^) := Rc;
End;
← →
Игорь Шевченко (2003-07-08 16:13) [11]Smok_er (08.07.03 16:00)
Windows.GetClientRect
← →
Smok_er (2003-07-08 16:39) [12]Игорь Шевченко © (08.07.03 16:13)
Windows.GetClientRect
Игорь, большое спасибо!
Работает!
Radionov Alexey © (08.07.03 16:10)
With Pt Do
OffsetRect(Rc, x, y);
TRect(Pointer(Msg.LParam)^) := Rc; // Error: Object or class type required
Я вот думаю... Неужели не предусмотрено просто игнорирование сообщений WM_MOVING? Чтобы не перерисовывать итак уже установленный порядок форм...
← →
Radionov Alexey (2003-07-08 16:49) [13]>Smok_er
Странно. Дело в том, что я обычно проверяю свой код у себя. Твой случай - не исключение. У меня на D6 все компилируется, работает и форма не стаскивается...
← →
Smok_er (2003-07-08 17:01) [14]Radionov Alexey © (08.07.03 16:49)
Ой, извиняюсь :(
Отвлекли и я напутал здесь.
Все компилится, только работает не совсем правильно :(
Когда у меня больше одного окошка, то при попытке перетащить не первое по порядку окно оно улетает за пределы видимой области клиентской части окна. И так все кроме первого :(
← →
Radionov Alexey (2003-07-08 17:03) [15]Просто надо для одного чилда сделать этот обработчик. Остальные чилды - сделать наследниками первого
← →
Smok_er (2003-07-08 17:55) [16]У меня есть форма, все создающиеся чилды являются ее экземплярами.
← →
Игорь Шевченко (2003-07-08 18:01) [17]
> 2) В цикле я расставляю MDI окошки в некой аккуратной последовательности.
> Но к сожалению потом можно изменить размер окна или перенести
> окошко в другое место. Как можно запретить эти действия
> пользователю?
Глупый вопрос: а зачем так пользователю руки связывать ?
← →
Smok_er (2003-07-08 19:46) [18]Игорь Шевченко © (08.07.03 18:01)
Отвечаю...
Для компании, в кторой я работаю я разрабатываю систему видеонаблюдения за представительствами посредством вебкамер. Решил использовать для отображения MDI окошки. Теперь хочется их так зафиксировать, чтобы невозможно было их перемещать (естественно, возможность перемещения программным путем должна остаться)
← →
Smok_er (2003-07-09 10:19) [19]Неужели никто не знает, как запретить пользователю перемещение формы?
← →
Radionov Alexey (2003-07-09 10:29) [20]Я же тебе писал уже.
Ты ответил:
"У меня есть форма, все создающиеся чилды являются ее экземплярами" - вообще непонятно. Экземпляры класса, может быть, а не конкретной формы, которая сама чей-то экземпляр?
Приведи код, где написан обработчик wmMoving а также код, где ты создаешь MDIChild
← →
Игорь Шевченко (2003-07-09 11:27) [21]Я очень извиняюсь, а не проще ли SDI было бы сделать ?
← →
Smok_er (2003-07-09 12:57) [22]>"У меня есть форма, все создающиеся чилды являются ее экземплярами" - вообще непонятно. Экземпляры класса, может быть, а не конкретной формы, которая сама чей-то экземпляр?
Ну конечно, экземпляр _класса_ формы. Просто решил что это будет и так понятно.
procedure TfmMain.CreateMDIChild;
var
fmChild: TfmChild;
begin
fmChild := TfmChild.Create(Application);
fmChild.DoubleBuffered := True;
fmChild.Caption := FTitle;
fmChild.lStatus.Caption := FStatusString;
fmChild.Tag := FClientNumber;
end;
procedure TfmChild.OnMDIMove(var Mes: TMessage);
var
Rc: TRect;
Pt : TPoint;
begin
Rc := BoundsRect;
Pt := BoundsRect.TopLeft;
Windows.ClientToScreen(Application.MainForm.clientHandle,Pt);
With Pt Do
OffsetRect(Rc, x, y);
TRect(Pointer(Mes.LParam)^) := Rc;
end;
Я думал сделать SDI, но мало ли что... Может потом придется дать большую гибкость. А потом переделывать на MDI вовсе не хочется.
← →
Radionov Alexey (2003-07-09 13:10) [23]Извини, ошибку у себя нашел.
Исправь на это вот:
Procedure TMdiChild.wmMoving(Var Msg: TMessage);
Var
Rc: TRect;
Pt : TPoint;
Begin
Rc := BoundsRect;
Pt := BoundsRect.TopLeft;
Windows.ClientToScreen(Application.MainForm.clientHandle,Pt);
With Pt Do
OffsetRect(Rc, x-rc.Left, y-rc.Top);
TRect(Pointer(Msg.LParam)^) := Rc;
End;
← →
Nevermind (2003-07-09 13:15) [24]
TForm2 = class(TForm)
private
procedure HitTest(var M: TWMNCHitTest); message WM_NCHITTEST;
procedure TForm2.HitTest(var M: TWMNCHitTest);
begin
inherited;
if M.Result = HTCAPTION then M.Result := HTCLIENT;
end;
← →
Smok_er (2003-07-09 15:00) [25]Radionov Alexey © (09.07.03 13:10)
Большое спасибо! Так работает!
Еще раз спасибо всем, кто помогал разобраться!
← →
Radionov Alexey (2003-07-09 15:10) [26]>Smok_er (09.07.03 15:00)
Не за что.
Но странно вот что: почему ты не хочешь вместо MDIChild поставить панели на одну форму? Какя функциональность осталась от MdiChild? Способность minimize и maximize?
Страницы: 1 вся ветка
Форум: "Основная";
Текущий архив: 2003.07.21;
Скачать: [xml.tar.bz2];
Память: 0.51 MB
Время: 0.008 c