Вниз
Скачать: CL | DM;

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 вся ветка

Скачать: CL | DM;



Память: 0.51 MB
Время: 0.011 c
14-68067
Makhanev A.S.
2003-07-06 01:50
2003.07.21
WinXP...жуть какая-то...


14-68057
Dign
2003-07-04 17:17
2003.07.21
Как открыть визуальную компоненту в консольном приложении


1-67912
Mishenka
2003-07-07 19:56
2003.07.21
Свойство Enabled для UpDown...


1-67826
Bill
2003-07-06 17:00
2003.07.21
Вызов hlp файла


6-67947
paul_77
2003-05-15 17:51
2003.07.21
передача файла из html на сервер




   Наверх