Re: Навеяно Outlook-ом
От: Sinclair Россия https://github.com/evilguest/
Дата: 27.02.03 13:34
Оценка: 12 (2)
Здравствуйте, BaSergey, Вы писали:

BS>Respect всем!

BS>Классно придумано в этой проге — содержимое основной области имеет совершенно разный вид в зависимости от того, с чем работаем. Причем — не MDI. Ну, на MFC это ясно как делается — классический пример Document/View — а что Delphi?. Всяко приятнее (и продуктивнее) рисовать все в дизайне, чем писать всепую. Я знаю, в LMD Tools есть компонент TFormDisplay или как-то так — он позволяет отобразить форму так, как будто она TPanel. Красть неохота, а идея нравится. Есть какие-нибудь мысли? Мне только направление подскажите, я сам как-нибудь...
Есть такая вещь, называется TFrame. Делаешь панель, а в нее вставляешь frame с align=alClient. Подменяешь инстансы фреймов на ходу.
... << RSDN@Home 1.0 beta 6 >>
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Re: Навеяно Outlook-ом
От: mikkri Великобритания  
Дата: 27.02.03 13:34
Оценка: -2
Здравствуйте, BaSergey, Вы писали:

BS>Respect всем!

BS>Классно придумано в этой проге — содержимое основной области имеет совершенно разный вид в зависимости от того, с чем работаем. Причем — не MDI. Ну, на MFC это ясно как делается — классический пример Document/View — а что Delphi?. Всяко приятнее (и продуктивнее) рисовать все в дизайне, чем писать всепую. Я знаю, в LMD Tools есть компонент TFormDisplay или как-то так — он позволяет отобразить форму так, как будто она TPanel. Красть неохота, а идея нравится. Есть какие-нибудь мысли? Мне только направление подскажите, я сам как-нибудь...

При некотором желании содержание формы можно пропарсить и положить на TPanel (с сохранением значений свойств и обработчиков событий).
Но при этом ты теряешь:
1) все события связанные с созданием/отображением/закрытием формы и т.п.
2) возможность обращаться из обработчиков событий к переменным формы непосредственно, так как экземпляр элементов управления ИНЫЕ и по названиям переменных доступны не будут.

Т.е. возможное решение:
— создавать скрытый экзепляр формы или читать ее описание из ресурсов (можно, но как не помню, где-то статью видел, кажется).
— кодить ВСЕ обработчики аккуратно в предположении, что тебе доступны ТОЛЬКО те значения и объекты, которые тебе переданы в обработчик явно через его параметры.

P.S. Кстати, спасибо за идею. Возможно что-то похожее для себя буду использовать, только лень было возиться с полностью ручным рисованием формы. А вот нарисовать форму и загрузить ее в панельку — это другое дело.

P.P.S. В одном проекте мы извратились для этой же цели так: положили на форму TabbedPanel и Panel. В процессе написания программы ты с помощью TabbedPanel все очень мило настраиваешь, а при выполнении программы все элементы управления "перепрыгивают" на Panel. Работало нормально, только что-то мне этот подход разонравился. Была только одна проблема — размер поля для контролов в TabbedPanel меньше (по вертикали), чем в обычном Panel, поэтому приходилось расположение элементов тчательно перепроверять.
Навеяно Outlook-ом
От: BaSergey Россия  
Дата: 27.02.03 13:17
Оценка:
Respect всем!
Классно придумано в этой проге — содержимое основной области имеет совершенно разный вид в зависимости от того, с чем работаем. Причем — не MDI. Ну, на MFC это ясно как делается — классический пример Document/View — а что Delphi?. Всяко приятнее (и продуктивнее) рисовать все в дизайне, чем писать всепую. Я знаю, в LMD Tools есть компонент TFormDisplay или как-то так — он позволяет отобразить форму так, как будто она TPanel. Красть неохота, а идея нравится. Есть какие-нибудь мысли? Мне только направление подскажите, я сам как-нибудь...
ICQ 153965498
Re: Навеяно Outlook-ом
От: Рома Украина  
Дата: 27.02.03 16:24
Оценка:
Можно воспользоваться обычным PageControl, спрятав закладки и в зависимости от чегото переключать их програмно. Получается очень интересно !
Внимательность, внимательность и еще раз ..... забыл, про что я?
Re[2]: Навеяно Outlook-ом
От: Flamer Кипр http://users.livejournal.com/_flamer_/
Дата: 27.02.03 20:54
Оценка:
Здравствуйте, Рома, Вы писали:

Р>Можно воспользоваться обычным PageControl, спрятав закладки и в зависимости от чегото переключать их програмно. Получается очень интересно !


Ага, ооочень интересно... Только миргает и мигает достаточно заметно при прятании одной страницы и показе другой... Уж лучше несколько TPanel и для каждой для показа вызывать BringToFront().

А лучше всего, как сказал Sinclair — юзать TFrame.
Re[2]: Навеяно Outlook-ом
От: mikkri Великобритания  
Дата: 28.02.03 07:20
Оценка:
Признаю, извратились мы без оснований . Для тех же целей можно было использовать TFrame.
Re[3]: Навеяно Outlook-ом
От: Рома Украина  
Дата: 28.02.03 08:02
Оценка:
Здравствуйте, Flamer, Вы писали:

F>Здравствуйте, Рома, Вы писали:


F>Ага, ооочень интересно... Только миргает и мигает достаточно заметно при прятании одной страницы и показе другой... Уж лучше несколько TPanel и для каждой для показа вызывать BringToFront().

А ты уверен, что панели моргать и мигать не будут(особенно когда на них куча всего)! Ты попробуй ! А вот если правильно "Лочить" update окна то все выходит достойно и можно пользоваться PageControl.
F>А лучше всего, как сказал Sinclair — юзать TFrame.
А может еще более извратится и ActiveForm присандалить?
Внимательность, внимательность и еще раз ..... забыл, про что я?
Re[4]: Навеяно Outlook-ом
От: Sinclair Россия https://github.com/evilguest/
Дата: 28.02.03 08:51
Оценка:
Здравствуйте, Рома, Вы писали:
F>>А лучше всего, как сказал Sinclair — юзать TFrame.
Р>А может еще более извратится и ActiveForm присандалить?
А вот этого не надо. Поясняю: TFrame сделан специально для того, чтобы можно было дизайнить форму отдельно, а потом встраивать ее в другую.
Это позволит сделать модель расширяемой.
Всякие невидимые табы с копированием контролов делают тоже самое, только через... другой вход.
Делать модель нерасширяемой можно при помощи просто набора панелей, которые хайдятся/показываются (см. пост Flamerа)
ActiveForm в данном контексте является избыточным решением.
... << RSDN@Home 1.0 beta 6 >>
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Re[5]: Навеяно Outlook-ом
От: Рома Украина  
Дата: 28.02.03 09:09
Оценка:
Здравствуйте, Sinclair, Вы писали:

S>ActiveForm в данном контексте является избыточным решением.

По поводу Frame"ов я полностью с Вами согласен! Но для кол-ва вариантов отображенияы < 3 очень удобно пользоваться PageControl.

По поводу ЭктивФорм скажу, что очень удобно использовать в случаях, когда тебуется поменять вид и логику без компиляции проэкта.

А для достижения OutLook"оподобности советую пользоваться компонентами DeveloperExpress. Полная копия + очень много доп. возможностей + простота настройки и использования. Лучше этих компонент ничего не видел.
См. здесь о возможностях компонент! Просто улет. С выходом 4 версии ничего нет невозможного!
Внимательность, внимательность и еще раз ..... забыл, про что я?
Re[6]: Навеяно Outlook-ом
От: Рома Украина  
Дата: 28.02.03 09:11
Оценка:
Простите за плохой линк.
DevExpress

Исправил линк
Внимательность, внимательность и еще раз ..... забыл, про что я?
Re[6]: Навеяно Outlook-ом
От: Sinclair Россия https://github.com/evilguest/
Дата: 28.02.03 09:21
Оценка:
Здравствуйте, Рома, Вы писали:
Р>А для достижения OutLook"оподобности советую пользоваться компонентами DeveloperExpress. Полная копия + очень много доп. возможностей + простота настройки и использования. Лучше этих компонент ничего не видел.
Знаем таких. Рулят ребята. Хорошо поработали.
... << RSDN@Home 1.0 beta 6 >>
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Re[3]: Навеяно Outlook-ом
От: mikkri Великобритания  
Дата: 28.02.03 13:18
Оценка:
Здравствуйте, mikkri, Вы писали:

M>Признаю, извратились мы без оснований . Для тех же целей можно было использовать TFrame.


Вспомнил! Основания все же были.

Часть элементов управления нужно было отображать всегда, а остальные в зависимости от выбранного условия. Причем те, что отображались всегда, нужно было органично отображать среди тех, что отображались в зависимости от условия.

P.S. Хотя о наличие TFrame не знал
Re: Навеяно Outlook-ом
От: №One.  
Дата: 01.03.03 13:49
Оценка:
////////////////////
unit mkkClassPlacer;

interface
uses
  Windows, Messages, SysUtils, Classes, Controls, Forms, ExtCtrls, contnrs;

type
  EmkkException = class(Exception)
  end;{TmkkException}
  {TmkkControlClass}
  TmkkControlClass = class of TWinControl;

  {TmkkOnErrorEvent}
  TmkkErrorEvent = procedure(Sender: TObject; AClass: TmkkControlClass; AError: EmkkException; var ADoAbort: boolean) of object;

  TmkkPlacerChangeEvent = procedure (NewControl, OldControl: TWinControl) of object;
  {TmkkClassStack}
  TmkkClassStack = class(TClassList)
    function Pop: TClass;
    function Push(AClass: TClass): Integer;
    function IsEmpty: Boolean;
    function Peek: TClass;
  end;{TmkkClassStack}

  {TmkkClassPlacer}
  TmkkClassPlacer = class(TCustomPanel)
  private
    FIncludeList: boolean;
    FAlignClass: TAlign;
    FBackClasses: TmkkClassStack;
    FNextClasses: TmkkClassStack;
    FInplaceClass: TmkkControlClass;
    FInplaceControl: TWinControl;
    FRemoveFormBorders: Boolean;
    FOnError: TmkkErrorEvent;
    FOnAfterChange: TNotifyEvent;
    FOnBeforeChange: TNotifyEvent;
    FOnPlacerChange: TmkkPlacerChangeEvent;
    function GetEnableBack: Boolean;
    function GetEnableNext: Boolean;
    procedure SetAlignClass(const Value: TAlign);
    procedure SetIncludeList(const Value: boolean);
    procedure SetInplaceClass(const Value: TmkkControlClass);

  protected
    property BackClasses: TmkkClassStack
      read FBackClasses;

    property NextClasses: TmkkClassStack
      read FNextClasses;
    procedure AfterChange; virtual;
    procedure BeforeChange; virtual;
    procedure DoError(AClass: TmkkControlClass; AException: EmkkException; var ADoAbort: Boolean); virtual;
    procedure DoPlacerChange(NewControl, OldControl: TWinControl); virtual;
  public

    property EnableBack: Boolean
      read GetEnableBack;

    property EnableNext: Boolean
      read GetEnableNext;

    procedure Next; virtual;
    procedure Back; virtual;
    procedure ClearNext;
    procedure ClearBack;
    constructor Create(AOwner: TComponent); override;
    destructor Destroy; override;

  published
    property Align;
    property Constraints;
    property AlignClass: TAlign
      read FAlignClass
      write SetAlignClass default alClient;
    property BorderStyle;
    property BevelInner;
    property BevelOuter;
    property BorderWidth;
    property BevelWidth;
    property Color;
    property Caption;
    property Enabled;
    property ShowHint;
    property Hint;
    property ParentShowHint;
    property ParentColor;
    property Font;
    property InplaceClass: TmkkControlClass
      read FInplaceClass
      write SetInplaceClass default nil;

    property InplaceControl: TWinControl
      read FInplaceControl default nil;

    property IncludeInList: boolean
      read FIncludeList
      write SetIncludeList default False;

    property RemoveFormBorders: Boolean
      read FRemoveFormBorders
      write FRemoveFormBorders default True;

    property OnAfterChange: TNotifyEvent
      read FOnAfterChange
      write FOnAfterChange default nil;

    property OnBeforeChange: TNotifyEvent
      read FOnBeforeChange
      write FOnBeforeChange default nil;

    property OnError: TmkkErrorEvent
      read FOnError
      write FOnError default nil;

    property OnPlacerChange: TmkkPlacerChangeEvent
      read FOnPlacerChange
      write FOnPlacerChange default nil;

    property OnCanResize;
    property OnClick;
    property OnConstrainedResize;
    property OnContextPopup;
    property OnDblClick;
    property OnEnter;
    property OnExit;
    property OnMouseDown;
    property OnMouseMove;
    property OnMouseUp;
    property OnResize;
  end;{TmkkClassPlacer}

procedure Register;

implementation
uses mkkConsts;
procedure StackAlreadyEmpty;
begin
  raise EmkkException.Create(serrStackEmpty);
end;{StackAlreadyEmpty}

procedure Register;
begin
  RegisterComponents('Mkk', [TmkkClassPlacer]);
end;

{ TmkkClassStack }

function TmkkClassStack.IsEmpty: Boolean;
begin
  Result := Count = 0;
end;

function TmkkClassStack.Peek: TClass;
begin
  Result := nil;
  if not IsEmpty then
    Result := Items[(Count-1)]; 
end;

function TmkkClassStack.Pop: TClass;
var
  liIndex: Integer;
begin
  Result := nil;
  if IsEmpty then
    StackAlreadyEmpty;
  liIndex:= Count-1;
  Result := Items[liIndex];
  Delete(liIndex);
end;

function TmkkClassStack.Push(AClass: TClass): Integer;
begin
  Result := Add(AClass);
end;
{ TmkkClassPlacer }

procedure TmkkClassPlacer.Back;
var
  Value: TmkkControlClass;
  OldClass :TmkkControlClass;
  OldControl: TWinControl;
  NewClass: TmkkControlClass;
  NewControl: TWinControl;
  DoAbort: Boolean;
begin
  if not EnableBack then Exit;
  NewClass := nil;
  NewControl := nil;
  Value := TmkkControlClass(FBackClasses.Pop);
  if FInplaceClass <> Value then
  begin
    //FInplaceClass := Value;
    OldClass := FInplaceClass;
    OldControl := FInplaceControl;
    if Assigned(Value) then
    begin
      BeforeChange;
      try
        NewControl := Value.Create(Self);
        NewControl.Parent := self;
        NewControl.Align := AlignClass;
        if (NewControl is TCustomForm) and (FRemoveFormBorders)then
          (NewControl as TCustomForm).BorderStyle := bsNone;
        NewControl.Visible := True;
      except
        on E: Exception do
        begin
          DoAbort := True;
          DoError(Value, (E as EmkkException), DoAbort);
          if DoAbort then raise;
        end;{on .. do}
      end;{try .. except}
      DoPlacerChange(NewControl, OldControl);
      FInplaceControl.Free;
      FInplaceControl := NewControl;
      FInplaceClass := Value;
      if FIncludeList then
      begin
        if Assigned(OldClass) then
        begin
          FNextClasses.Push(OldClass);
        end;{if .. then}
      end;{if .. then}
      AfterChange;
    end{if .. then}
  end;
end;


procedure TmkkClassPlacer.ClearBack;
begin
  FBackClasses.Clear;
end;

procedure TmkkClassPlacer.ClearNext;
begin
  FNextClasses.Clear;
end;

constructor TmkkClassPlacer.Create(AOwner: TComponent);
begin
  inherited;
  FRemoveFormBorders := True;
  FBackClasses := TmkkClassStack.Create;
  FNextClasses := TmkkClassStack.Create;
  FInplaceClass := nil;
  FInplaceControl := nil;
  IncludeInList := False;
  FAlignClass := alClient;
  FOnBeforeChange := nil;
  FOnAfterChange := nil;
  FOnError := nil;
  FOnPlacerChange := nil;
end;

destructor TmkkClassPlacer.Destroy;
begin
  InplaceClass := nil;
  FOnBeforeChange := nil;
  FOnAfterChange := nil;
  FOnError := nil;
  FBackClasses.Free;
  FNextCLasses.Free;
  inherited;
end;

procedure TmkkClassPlacer.BeforeChange;
begin
  if Assigned(FOnBeforeChange) then
    FOnBeforeChange(self);
end;

procedure TmkkClassPlacer.DoError;
begin
  if Assigned(FOnError) then
    FOnError(self, AClass, AException, ADoAbort);
end;

function TmkkClassPlacer.GetEnableBack: Boolean;
begin
  Result := FBackClasses.Count <> 0;
end;

function TmkkClassPlacer.GetEnableNext: Boolean;
begin
  Result := FNextClasses.Count <> 0;
end;

procedure TmkkClassPlacer.Next;
var
  Value: TmkkControlClass;
  OldClass :TmkkControlClass;
  OldControl: TWinControl;
  NewClass: TmkkControlClass;
  NewControl: TWinControl;
  DoAbort: boolean;
begin
  if not EnableNext then Exit;
  NewClass := nil;
  NewControl := nil;
  Value := TmkkControlClass(FNextClasses.Pop);
  if FInplaceClass <> Value then
  begin
    //FInplaceClass := Value;
    OldClass := FInplaceClass;
    OldControl := FInplaceControl;
    if Assigned(Value) then
    begin
      BeforeChange;
      try
        NewControl := Value.Create(Self);
        NewControl.Parent := self;
        NewControl.Align := AlignClass;
        if (NewControl is TCustomForm) and (FRemoveFormBorders)then
             (NewControl as TCustomForm).BorderStyle := bsNone;
        NewControl.Visible := True;
      except
        on E: Exception do
        begin
          DoAbort := True;
          DoError(Value, (E as EmkkException), DoAbort);
          if DoAbort then raise;
        end;{on .. do}
      end;{try .. except}
      DoPlacerChange(NewControl, OldControl);
      FInplaceControl.Free;
      FInplaceControl := NewControl;
      FInplaceClass := Value;
      if FIncludeList then
      begin
        if Assigned(OldClass) then
        begin
          FBackClasses.Push(OldClass);
        end;{if .. then}
      end;{if .. then}
      AfterChange;
    end{if .. then}
  end;
end;


procedure TmkkClassPlacer.SetAlignClass(const Value: TAlign);
begin
  if FAlignClass <> Value then
  begin
    FAlignClass := Value;
    if Assigned(FInplaceControl) then
      FInplaceControl.Align := Value;
  end;{if .. then}
end;

procedure TmkkClassPlacer.SetIncludeList(const Value: boolean);
begin
  if FIncludeList <> Value then
    FIncludeList := Value;
end;

procedure TmkkClassPlacer.SetInplaceClass(const Value: TmkkControlClass);
var
  OldClass :TmkkControlClass;
  OldControl: TWinControl;
  NewClass: TmkkControlClass;
  NewControl: TWinControl;
  DoAbort: Boolean;
begin
  NewClass := nil;
  NewControl := nil;

  if FInplaceClass <> Value then
  begin
    //FInplaceClass := Value;
    OldClass := FInplaceClass;
    OldControl := FInplaceControl;
    BeforeChange;
    if Assigned(Value) then
    begin
      try
        NewControl := Value.Create(Self);
        NewControl.Parent := self;
        NewControl.Align := AlignClass;
        if (NewControl is TCustomForm) and (FRemoveFormBorders)then
             (NewControl as TCustomForm).BorderStyle := bsNone;
        NewControl.SendToBack;
        NewControl.Visible := True;
      except
        on E: Exception do
        begin
          DoAbort := True;
          DoError(Value, (E as EmkkException), DoAbort);
          if DoAbort then raise;
        end;{on .. do}
      end;{try .. except}
      DoPlacerChange(NewControl, OldControl);
      FInplaceControl.Free;
      FInplaceControl := NewControl;
      FInplaceClass := Value;
      FNextClasses.Clear;
      if FIncludeList then
      begin
        if Assigned(OldClass) then
        begin
          FBackClasses.Push(OldClass);
        end;{if .. then}
      end;{if .. then}
      NewControl.BringToFront;
      AfterChange;
    end{if .. then}
  end;
end;

procedure TmkkClassPlacer.AfterChange;
begin
  if Assigned(FOnAfterChange) then
    FOnAfterChange(self);
end;

procedure TmkkClassPlacer.DoPlacerChange(NewControl,
  OldControl: TWinControl);
begin
  if Assigned(FOnPlacerChange) then
    FOnPlacerChange(NewControl, OldControl);
end;

end.
/////////////

Устанавливаем сию хрень в палитру.

Пример использования
Кидаем на форму TmkkClassPlacer — получаем область в которой будут отображаться формы или фреймы.
Создаем формы которые надо отображать кидаем на них компоненты, убираем из списка Auto-Create Forms. Подключаем модули с формами к модулю с TmkkClassPlacer.

Для того чтобы отобразить нужную форму используем следующее
mkkClassPlacer1.InplaceClass := <класс формы>
например
mkkClassPlacer1.InplaceClass := TForm1; — создает отображает форму Form1
.....
mkkClassPlacer1.InplaceClass := TForm2;- создает отображает форму Form2

.....
mkkClassPlacer1.InplaceClass := nil; — удаляет текущую созданую форму

через mkkClassPlacer1.InplaceControl — получаем доступ к созданой форме.
........
Если необходимо сохранять состояние формы, то лучьше воспользоватся TMergeManager из RxLib
Если нужен пример мыльте
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.