Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Форум: "Основная";
Текущий архив: 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
14-67964
Marser
2003-06-28 11:54
2003.07.21
---|Ветка была без названия|---


7-68090
OpoloXAI
2003-05-12 17:49
2003.07.21
Как переключить ракладку клавиатуры на Украинский язык?


1-67813
sergio_serg
2003-07-09 14:50
2003.07.21
dbgrid


7-68084
GD
2003-05-07 01:04
2003.07.21
Как передать данные ввода пользователя и пароля WinLogonу


3-67698
SCORPION ZP
2003-06-24 11:43
2003.07.21
Реструктурирование таблиц dBASE программным путем





Afrikaans Albanian Arabic Armenian Azerbaijani Basque Belarusian Bulgarian Catalan Chinese (Simplified) Chinese (Traditional) Croatian Czech Danish Dutch English Estonian Filipino Finnish French
Galician Georgian German Greek Haitian Creole Hebrew Hindi Hungarian Icelandic Indonesian Irish Italian Japanese Korean Latvian Lithuanian Macedonian Malay Maltese Norwegian
Persian Polish Portuguese Romanian Russian Serbian Slovak Slovenian Spanish Swahili Swedish Thai Turkish Ukrainian Urdu Vietnamese Welsh Yiddish Bengali Bosnian
Cebuano Esperanto Gujarati Hausa Hmong Igbo Javanese Kannada Khmer Lao Latin Maori Marathi Mongolian Nepali Punjabi Somali Tamil Telugu Yoruba
Zulu
Английский Французский Немецкий Итальянский Португальский Русский Испанский