Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > Delphi: Общие вопросы > MDI или SDI?


Автор: PILOT 17.11.2002, 21:29
Пишу программу расчета дозы облучения злокачественных опухолей :(, суть перевести старую программу 92-го года написанную на Фортране естественно под ДОС на Win9x/NTs с инсталлерами и прочими вещами...
Имеется иерархическая структура расчетов типа:
Код

Основное меню
|
- Дистанционное облучение
|   |
|    - Головной мозг
|   |   |
|   |    - 1000 см2
|   |   |
|   |    ...
|   |   |
|   |    - 100 см2
|    - Печень
|   |  
|    ...
|   |  
|    - Почки
|
- Внутретканевое облучение
|  
- Внутриполостное облучение
|  ...
- Оценка вероятности (появления новообразований)

Короче дофига пунктов читая каждый сходишь с ума.
В принципе, реализовано сейчас это мной как MDI приложение каждый документ которого содержит слева TreeView (это это самое меню) а справа PageControl заголовки которого состоят из "бездетных" (конечных) пунктов TreeView а в заголовок документа добавляется  единственный родитель этих конечных пунктов. Но суть то в том, что расчеты разные в зависимости от того что считаем: мозг ли, либо яички (Брррр), поэтому возник вопрос о правомерности использования MDI. Но с другой стороны пользователь должен иметь возможность посмотреть результаты других расчетов, например, про печень. Это и осуществляется открытием другого окна в котором пользователь уже смотрит то, что ему надо, не теряя при этом то место где он сейчас считает.
Может кто чего умного посоветует, либо совсем по другому делать, либо тут что перелопатить?
Ну и кроме того как логичнее (не через GlobalIndex) сделать проверку какой из пунктов TreeView выбран (чтобы менять содержимое PageControl и как ЭТО сделать грамотно)?

СУВ.

Автор: Vit 18.11.2002, 00:29
Я бы советовал использовать TPageControl. А с деревом есть очень удобный метод работы - пишешь свой класс, свою структуру или чего-нибудь такое, узел дерева может хранить указатель на этот класс, в любой момент по узлу можно обратиться к этому классу.

Автор: PILOT 18.11.2002, 01:08
А как это сделать  :withstupid

СУВ.

Автор: Vit 18.11.2002, 03:34
Например у тебя на форме стоит TreeView, PageControl и кнопка:

Код

unit Unit1;

interface

uses
 Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
 StdCtrls, ComCtrls;

type
 TForm1 = class(TForm)
   TreeView1: TTreeView;
   Button1: TButton;
   PageControl1: TPageControl;
   procedure Button1Click(Sender: TObject);
   procedure TreeView1Change(Sender: TObject; Node: TTreeNode);
   procedure PageControl1Change(Sender: TObject);
 private
   procedure addItem(t: String);
   { Private declarations }
 public
   { Public declarations }
 end;

var
 Form1: TForm1;

implementation

{$R *.DFM}

Procedure TForm1.addItem(t:String);
 var TabSheet:TTabSheet;
     Node:TTreenode;
begin
 TabSheet:=TTabSheet.Create(Self);
 TabSheet.PageControl:=PageControl1;
 TabSheet.caption:=t;
 Node:=TreeView1.Items.Add(nil, t);
 Node.data:=TabSheet; //ассоциируем узел с страницей
 TabSheet.tag:=Integer(Node); // ассоциируем страницу с узлом

end;

procedure TForm1.Button1Click(Sender: TObject);
begin
 TreeView1.HideSelection:=false;
 addItem('Item1');
 addItem('Item2');
 addItem('Item3');
 addItem('Item4');
end;

procedure TForm1.TreeView1Change(Sender: TObject; Node: TTreeNode);
begin
 PageControl1.ActivePage:=TTabSheet(Node.data);// Доступ к ассоциированной странице через узел
end;

procedure TForm1.PageControl1Change(Sender: TObject);
begin
 TreeView1.Selected:=TTreeNode(Pointer(PageControl1.ActivePage.tag));// Доступ к ассоциированному узлу через страницу
end;

end.



Теперь при смене страницы - меняется текущий узел, а при смене узла меняется страница. Таким же образом можно подшить любую функциональность - ты просто подшиваешь класс который реализует какую-либо другую функциональность и всё.


Автор: PILOT 18.11.2002, 07:01
Стоп!
Помедленнее :)
Чего мы теперь имеем:
Имеем TreeView при изменении которого (т.е. при выделении пункта) меняется PageControl и наоборот.
Но вот с функциональностью не понял: у меня содержимое PageControl (т.е. TabSheet'ов) разное для каждого из Нодов, как мне подставлять соответствующее содержимое и где лучше всего хранить его.
Для взаимопонимания пусть:
Код

[-]Нод0
|
 -Нод0_0
|  |
|   -Нод0_0_0
|  |
|   -Нод0_0_1
|
 -Нод0_1

т.е. имеем такую структуру, допустим что Нод0_0_0 вызывает (как и говорилось где-то в начале) появления двух табов в PageControl один из которых выден (а именно соответствующий Ноду0_0_0, в то время как НОД0_0_1 лишь доступен). Два Таба потому, что у соответствующих им Нодам общий "родитель", и именно Ноды без "детей" и Ноды их "родители" вызывают изменение PageControl.
Т.е. при выделении Нода0 ничего не произойдет, при выделении Нода0_0 появятся два таба соответствующие Ноду0_0_0 и Ноду0_0_1 и видимым станет первый из них. И изменения произойдут и в случае выделения появится именно тот таб который выделен.
Вопрос как это реализовать?

СУв.

Автор: Vit 18.11.2002, 07:13
Реализация зависит от 2х факторов:

1) Насколько много узлов
2) Насколько страницы должны быть разные

В зависимости от сочетаний варианты оптимальных решений:

1) Узлов не много (не более 10-20), содержимое страниц очень разное
  В дизайне делаем все страницы, при проходе дерева управляем только тем какие страницы видны

2) Узлов много, содержимое страниц очень разное - создаём страницы в Run-time вместе с ними создаём все нужные для них компоненты. При переходе на другой узел уничтожаем эти страницы, создаём вместо них новые. Работает несколько медленно, но на больших структурах намного стабильнее и память не так жрётся

3) содержимое страниц весьма сходное - создаём свои классы, которые инкапсулируют компоенты на страницах, создаём  в run-time страницы и заполняем их потомками компоентов

Ещё вариант - использовать вложенные PageControl которые тоже делать в Run-time

Автор: PILOT 18.11.2002, 08:29
Спасибо.
3-й вариант не подойдет, т.к. слишком уж разное содержимое, а вот первые очень даже ничего.
1-ый вариант - вопросов нет, кроме как сильно ли испортит жизнь ОС 50-ти табный PаgeControl?
2-й вариант: иными словами создавать табы в PageControl+их содержимое? Думаю да.
Теперь другой вопрос: ипользую формулы (т.е. на форме должны быть формулы). Их я получаю в ворде, а затем  по клавише PrintScreen получаю скажем BMP - на белом фоне черным начертаны расчетные формулы. Но естественно я бы не хотел бы видеть этот белый фон на форме а только лишь формулы. Пробовал экспериментировать с Transparent'ом, на моей машине все ОК, но стоит запуститься на другой то вместо хотябы белого фона просто Малевичевские черные квадраты. Бороться с этим можно?
Еще вопрос: хотелось бы добавлять имена открытых окон в качестве Check пункта меню &Окно. Это ручками делать или есть готовые, включаемые механизмы?

СУВ.

Автор: PILOT 18.11.2002, 08:33
Кстати о BMP.
Это даже не TIFF а хуже (больше занимает). JPG делает кайму рядом с констрастными участками. Есть ли поддерживаемый Delphi графический формат, который бы внедрялся бы в exe-шник с малой кровью (не раздувал исполняемый файл)?
Или лучше создать (другой программой) типизированный DAT файл со всеми картинками и качать их оттуда по мере необходимости?

СУВ.

Автор: Vit 18.11.2002, 14:24
Давай ты будешь каждый новый вопрос в новом топике писать, а то если сюда ещё пару человек решит свои замечания или соображения положить то тут уже будет такая каша что не разберёшь.

Цитата
1-ый вариант - вопросов нет, кроме как сильно ли испортит жизнь ОС 50-ти табный PаgeControl?


Ну сейчас память дешёвая, машины в целом выносливые, сами по себе 50 Tab это не страшно, но если ты на каждый повесишь по десяток контролов - это будет перебор. Возможны проблемы - например прога говорит что нехватает ресурсов, или при открытиии второй такой же навороченной проги начинаются чудеса - например такие программы очень плохо реагируют на попытки открыть параллельно Photoshop, Delphi или HomeSite в среде 9х. На NT/2000/XP проблем не должно быть. В общем я бы не рекомендовал такого монстра делать - самому же трудно будет потом разобраться с таким. В Run-time создавать компоненты при таких количествах будет легче и код понятнее.

Цитата
Их я получаю в ворде, а затем  по клавише PrintScreen получаю скажем BMP


Вообще-то формат BMP не имеет Transparent, хотя Дельфи эмулирует его беря за прозрачный цвет - цвет верхнего левого пиксела. Используй GIF - он поддерживает истинный Transparent, намного меньше размером. Для вывода в Дельфи можно использовать компоненты от RxLib

Цитата
Еще вопрос: хотелось бы добавлять имена открытых окон в качестве Check пункта меню &Окно. Это ручками делать или есть готовые, включаемые механизмы?


Только для MDI. Прийдётся ручками, но это пустяки - пара строчек кода.


Автор: Vit 18.11.2002, 14:29
Цитата(PILOTIK @ 17.11.2002, 15:33)
Кстати о BMP.
Это даже не TIFF а хуже (больше занимает). JPG делает кайму рядом с констрастными участками. Есть ли поддерживаемый Delphi графический формат, который бы внедрялся бы в exe-шник с малой кровью (не раздувал исполняемый файл)?
Или лучше создать (другой программой) типизированный DAT файл со всеми картинками и качать их оттуда по мере необходимости?

СУВ.

Как я тебе говорил, используй GIF. Типизированный файл займёт слишком много места, ведь тебе прийдётся делать его под размер самого большого файла, есть 2 гораздо лучших варианта.

1) Оставь их как есть файлами и подгружай как файлы (просто скинь их в подкаталог)
2) Я бы предпочёл именно этот способ: сделай простейшую таблицу (Paradox, DBase, Access - не имеет значения), загони их всех в Blob поля, показывай через TDBImage (а если им формат не поддерживается то загружай из таблицы в какой-нибудь другой компонент)

Автор: Vit 18.11.2002, 14:34
Цитата(PILOTIK @ 17.11.2002, 15:33)
Это даже не TIFF а хуже (больше занимает).

Ну ты сказанул - TIFF - это ж вообще для полиграфии формат, он не только рисунок хранит, но ещё и цветовые профайлы, номера полиграфических красок, какую-то дрянь о мониторе, драйвере принтера и т.п. муть. Забудь о нём - пусть те кто журналы верстает с TIFF мучаются. Для твоих целей идеально подходит GIF - высокая компрессия на небольшом количестве цветов, поддержка прозрачности, компрессия без потери качества - т.е. нет Mpeg-муара по контурам и т.п. мелкие удобства.

Автор: PILOT 18.11.2002, 20:35
Цитата(Vit @ 18.11.2002, 06:24)
Для вывода в Дельфи можно использовать компоненты от RxLib

А где можно найти эти самые компоненты?

СУВ.
ЗЫ. Ну напутал я с TIFF, чего ж теперь...

Автор: Vit 18.11.2002, 22:43
www.torry.net

Ищи пакет компонентов - RX VCL Extension

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)