ООП и формы

Общие вопросы программирования, алгоритмы и т.п.

Модератор: Модераторы

Re: ООП и формы

Сообщение S_Gur » 13.09.2019 19:27:20

Мне важно, чтобы изменения в предках отражались на потомках. Все без исключения - от контролов до обработчиков. У меня удаленные с предка экшены не удалялись в потомках, приходилось удалять вручную. У меня обработчик в предке не работал в потомке, этот же код, прописанный в потомке в полностью перекрытом методе предка работал прекрасно. Возможно, я то-то делаю не так, но что - я не знаю. В Дельфях у меня таких проблем нет
S_Gur
постоялец
 
Сообщения: 130
Зарегистрирован: 30.12.2018 22:17:42

Re: ООП и формы

Сообщение iskander » 13.09.2019 19:59:34

Глюков у Лазаря предостаточно(как, впрочем, полагаю и у Delphi), про форум и багтрекер я уже упомянул. Лично мне сравнение Lazarus с Delphi режет слух по причине разных весовых категорий. К тому же Delphi у меня ассоциируется с чередой коммерческих компаний, которые в припадке жадности за последние 15 лет сделали почти всё возможное, чтобы угробить в общем-то неплохой язык Pascal.
И всё же сравнение имхо не в пользу Delphi, хотя бы потому, что когда я устанавливаю Лазарь на свою машину, он принадлежит мне, а не какой-то абракадабре.
iskander
энтузиаст
 
Сообщения: 606
Зарегистрирован: 08.01.2012 18:43:34

Re: ООП и формы

Сообщение S_Gur » 13.09.2019 20:51:53

iskander, насчет языка Pascal не согласен абсолютно. Как минимум потому, что это мой первый проект на Лазарусе (не считая некоторых мелких тестовых программ), но очень много проектов на Дельфях. Поэтому при написании этого проекта я просто копипастил код огромными кусками из дельфовых проектов. Расхождения были столь незначительны, что можно считать, что их практически и нет. Ни в коде, ни в наборе компонентов, во всяком случае, на уровне стандартной поставки, хотя основные библиотеки, которые я использую - UniDAC, EhLib, FastReport - уже давно распространяются и под Лазарус тоже. В остальном не могу не согласиться, опенсорсная среда разработки, конечно, штука приятная, но есть куда более неприятная вещь - сроки написания проекта. С Лазарусом я бился неделю, все, что я сделал за эту неделю, я поднял на Дельфях за сутки. Очень рекомендую хотя бы пощупать последнюю Rio 10.3.2, тем более, что Community версия - это абсолютно бесплатная полнофункциональная Professional редакция, ограничения чисто юридические. По большому счету Лазарь мне понравился, надеюсь, что еще через несколько обновлений наиболее критичные глюки будут исправлены и я с большим удовольствием снова его заюзаю. Пока что, к моему большому сожалению, писать то, что делаю я, на нем не представляется возможным.
S_Gur
постоялец
 
Сообщения: 130
Зарегистрирован: 30.12.2018 22:17:42

Re: ООП и формы

Сообщение iskander » 13.09.2019 21:12:14

S_Gur писал(а):насчет языка Pascal не согласен абсолютно

С этого места поподробнее, пожалуйста. :)
S_Gur писал(а): надеюсь, что еще через несколько обновлений наиболее критичные глюки будут исправлены

Если вы не будете долбиться в багтрекер, то вряд-ли. Глюки в какой-либо фиче обычно следствие её малой востребованности.
iskander
энтузиаст
 
Сообщения: 606
Зарегистрирован: 08.01.2012 18:43:34

Re: ООП и формы

Сообщение S_Gur » 13.09.2019 21:24:31

iskander писал(а):Глюки в какой-либо фиче обычно следствие её малой востребованности


Если объектно-ориентированное проектирование и дизайн в Лазарусе маловостребовано, то даже не знаю, для чего его вообще использовать... :D Для разработки мелких однооконных приложений?

С этого места поподробнее, пожалуйста


Пожалуйста.

Вот код на Лазарусе:

Код: Выделить всё
unit U_Main;

{$mode objfpc}{$H+}

interface

uses
  Classes, SysUtils, Forms, Controls, Graphics, Dialogs, ExtCtrls, ComCtrls, ActnList, Menus, Messages;

type

  { TFmMain }

  TFmMain = class(TForm)
    MainMenu: TMainMenu;
    MenuItem1: TMenuItem;
    MenuItem10: TMenuItem;
    MenuItem11: TMenuItem;
    MenuItem12: TMenuItem;
    MenuItem13: TMenuItem;
    MenuItem14: TMenuItem;
    MenuItem15: TMenuItem;
    MenuItem16: TMenuItem;
    MenuItem17: TMenuItem;
    MenuItem18: TMenuItem;
    MenuItem19: TMenuItem;
    MenuItem20: TMenuItem;
    MenuItem21: TMenuItem;
    MenuItem22: TMenuItem;
    MenuItem23: TMenuItem;
    MenuItem24 : TMenuItem;
    MenuItem25 : TMenuItem;
    MenuItem26 : TMenuItem;
    MenuItem27 : TMenuItem;
    N8 : TMenuItem;
    N7 : TMenuItem;
    N6: TMenuItem;
    N5: TMenuItem;
    N4: TMenuItem;
    N3: TMenuItem;
    MenuItem2: TMenuItem;
    MenuItem3: TMenuItem;
    MenuItem4: TMenuItem;
    MenuItem5: TMenuItem;
    MenuItem6: TMenuItem;
    MenuItem7: TMenuItem;
    MenuItem8: TMenuItem;
    MenuItem9: TMenuItem;
    N2: TMenuItem;
    N1: TMenuItem;
    MPMenu: TPopupMenu;
    MPControl: TPageControl;
    Pbar: TProgressBar;
    PopEngItem: TMenuItem;
    PopRusItem: TMenuItem;
    StBar: TStatusBar;
    ToolBar1: TToolBar;
    ToolButton1: TToolButton;
    ToolButton10: TToolButton;
    ToolButton11: TToolButton;
    ToolButton12: TToolButton;
    ToolButton13: TToolButton;
    ToolButton14: TToolButton;
    ToolButton15 : TToolButton;
    ToolButton16 : TToolButton;
    ToolButton2: TToolButton;
    ToolButton3: TToolButton;
    ToolButton4: TToolButton;
    ToolButton5: TToolButton;
    ToolButton6: TToolButton;
    ToolButton7: TToolButton;
    ToolButton8: TToolButton;
    ToolButton9: TToolButton;
    TrIcon: TTrayIcon;
    TrMenu: TPopupMenu;
    procedure FormActivate(Sender: TObject);
    procedure FormClose(Sender: TObject; var CloseAction: TCloseAction);
    procedure FormCloseQuery(Sender: TObject; var CanClose: boolean);
    procedure FormCreate(Sender: TObject);
    procedure StBarDrawPanel(StatusBar: TStatusBar; Panel: TStatusPanel;
      const Rect: TRect);
    procedure TrIconClick(Sender: TObject);
  private
    fCurrentLanguage : String;
    Procedure SetCurrentLanguage(AValue : String);
    Procedure LoadConfig;
    Procedure SaveConfig;
    Procedure DefLanguage;
    Procedure SetLanguage;
    Procedure SetEnabledActions;
  protected
    Procedure WMGETSYSCOMMAND(var Msg : TMessage); message WM_SYSCOMMAND;
  public
    Property CurrentLanguage : String  Read fCurrentLanguage Write SetCurrentLanguage;
    Procedure ShowTask(AClassName : String; AAction : TAction);
    Procedure CloseTask(AIndex : Integer);
  end;

var
  FmMain: TFmMain;

implementation

Uses
  LanguageResManEh, U_AppIni, U_Dlgs, U_DM, U_FrmPos, U_MConst, U_MLForm, U_MLang, U_PForm, U_TxtLog, Windows;

{$R *.lfm}

{ TFmMain }

Procedure TFmMain.SetEnabledActions;

Begin
  With DM Do
  Begin
    CloseTaskAction.Enabled := MPControl.ActivePageIndex > - 1;
    MenuItem26.Enabled      := CloseTaskAction.Enabled
  End
End;

procedure TFmMain.DefLanguage;

Var
  I : Integer;

Begin
  DefComponentLanguage(Self);
  DefComponentLanguage(MPControl);
  DM.DefLanguage;
  With TrIcon Do
  Begin
    BalloonTitle       := TFmMain(Owner).Caption;
    BalloonHint        := TFmMain(Owner).Hint
  End;
  With Screen Do For I := 0 To FormCount - 1 Do If Forms[I] Is TMLForm Then Forms[I].Perform(WM_CLLANG, 0, 0)
End;

procedure TFmMain.SetLanguage;

Var
  I : Integer;

Begin
  SetComponentLanguage(Self);
  SetComponentLanguage(MPControl);
  DM.SetLanguage;
  With TrIcon Do
  Begin
    BalloonTitle       := TFmMain(Owner).Caption;
    BalloonHint        := TFmMain(Owner).Hint
  End;
  With Screen Do For I := 0 To FormCount - 1 Do If Forms[I] Is TMLForm Then Forms[I].Perform(WM_CHLANG, 0, 0)
End;

Procedure TFmMain.LoadConfig;

Var
  S : String;

Begin
  If Not LoadIniFile Then
  Begin
    ErrMsg('Error When Accessing System Settings');
    SaveToLog('Error When Accessing System Settings');
    Exit
  End;
  S                      := MD5Str(Name);
  With IniFile Do
  Begin
    SaveOnExit           := ReadBool(S, MD5Str('SaveOnExit'), False);
    If SaveOnExit Then
    Begin
      CurrentLanguage    := ReadString(S, MD5Str('CurrentLanguage'), 'LNG_ENG');
      NormalCalc         := ReadBool(S, MD5Str('NormalCalc'), False);
      MinimizeToTray     := ReadBool(S, MD5Str('MinimizeToTray'), False);
      FieldsMultiLang    := ReadBool(S, MD5Str('FieldsMultiLang'), False);
      SaveFormPosition   := ReadBool(S, MD5Str('SaveFormPosition'), False);
      With DM.DBase Do
      Begin
        Server           := CryptString(ReadString(S, MD5Str('DBaseServer'), ''), True);
        Database         := CryptString(ReadString(S, MD5Str('DBaseDatabase'), ''), True);
        Username         := CryptString(ReadString(S, MD5Str('DBaseUsername'), ''), True);
        Password         := CryptString(ReadString(S, MD5Str('DBasePassword'), ''), True);
        Port             := ReadInteger(S, MD5Str('DBasePort'), 3306)
      End
    End
    Else CurrentLanguage := 'LNG_ENG'
  End;
  LoadPosition(Self)
End;

Procedure TFmMain.SaveConfig;

Var
  S : String;

Begin
  If Not LoadIniFile(True) Then
  Begin
    ErrMsg('Error When Accessing System Settings');
    SaveToLog('Error When Accessing System Settings');
    Exit
  End;
  SavePosition(Self);
  S := MD5Str(Name);
  With INIFile Do
  Begin
    WriteBool(S, MD5Str('SaveOnExit'), SaveOnExit);
    If SaveOnExit Then
    Begin
      WriteString(S, MD5Str('CurrentLanguage'), CurrentLanguage);
      WriteBool(S, MD5Str('NormalCalc'), NormalCalc);
      WriteBool(S, MD5Str('MinimizeToTray'), MinimizeToTray);
      WriteBool(S, MD5Str('FieldsMultiLang'), FieldsMultiLang);
      WriteBool(S, MD5Str('SaveFormPosition'), SaveFormPosition);
      With DM.DBase Do
      Begin
        WriteString(S, MD5Str('DBaseServer'), CryptString(Server));
        WriteString(S, MD5Str('DBaseDatabase'), CryptString(Database));
        WriteString(S, MD5Str('DBaseUsername'), CryptString(Username));
        WriteString(S, MD5Str('DBasePassword'), CryptString(Password));
        WriteInteger(S, MD5Str('DBasePort'), Port)
      End
    End;
    SaveIniFile
  End
End;

Procedure TFmMain.SetCurrentLanguage(AValue : String);

Begin
  If fCurrentLanguage = AValue Then Exit;
  fCurrentLanguage                                                                := AValue;
  DefLanguage;
  If LoadLang(AValue) Then SetLanguage;
  With DM Do
  Begin
    EngAction.Checked                                                             := AValue = 'LNG_ENG';
    RusAction.Checked                                                             := AValue = 'LNG_RUS'
  End;
  {With LanguageResourceManagerEh Do If AValue = 'LNG_ENG' Then ActiveLanguageAbbr := 'ENU'
  Else ActiveLanguageAbbr                                                         := 'RUS'}
End;

Procedure TFmMain.WMGETSYSCOMMAND(var Msg :TMessage);

Begin
  If MinimizeToTray And (Msg.wParam = SC_CLOSE) Or (Msg.wParam = SC_MINIMIZE) Then
  Begin
    Hide;
    With TrIcon Do
    Begin
      Visible := True;
      ShowBalloonHint
    End
  End
  Else Inherited
End;

procedure TFmMain.FormActivate(Sender: TObject);
begin
  If Not FirstRun Then Exit;
  FirstRun := False;
  LoadConfig;
  With DM.DBase Do
  Repeat
    Try
      Connect
    Except
      With Application Do
      Begin
        ProcessMessages;
        ErrMsg(GetLanguageValue('NotDBConnMsg'));
        With TFormClass(GetClass('TFmDBSettings')).Create(Self) Do If ShowModal = mrCancel Then
        Begin
          Terminate;
          Exit
        End
      End
    End
  Until Connected;
  SetEnabledActions
end;

procedure TFmMain.FormClose(Sender: TObject; var CloseAction: TCloseAction);

Var
  I : Integer;

begin
  With MPControl Do If PageCount > 0 Then For I := PageCount - 1 DownTo 0 Do CloseTask(I);
  With DM.DBase Do If Connected Then Disconnect;
  SaveConfig;
  DM.Free;
  FreeMultiLang;
  CloseAction                                   := caFree
end;

procedure TFmMain.FormCloseQuery(Sender: TObject; var CanClose: boolean);
begin
  CanClose := Not TrIcon.Visible And (ConfirmMsg(GetLanguageValue('QuitConfMsg')) = mrYes)
end;

procedure TFmMain.FormCreate(Sender: TObject);

begin
  DM                 := TDM.Create(Self);
  With FormatSettings Do
  Begin
    DecimalSeparator := '.';
    ShortDateFormat  := 'dd.mm.yyyy'
  End;
  With TrIcon Do
  Begin
    Icon             := Application.Icon;
    BalloonTitle     := FmMain.Caption;
    BalloonHint      := FmMain.Hint;
    Hint             := FmMain.Hint
  End;
  With LanguageResourceManagerEh Do
  Begin
    ResourcePlacement                                  := lrpEmbeddedEh;
    LoadListOfAvailableLanguages('TEhLibLanguageConsts')
  End;
  CreateMultiLang;
  FirstRun           := True
end;

procedure TFmMain.StBarDrawPanel(StatusBar: TStatusBar; Panel: TStatusPanel;
  const Rect: TRect);
begin
  If Panel = StatusBar.Panels[ProgressPanelNumber] Then
  Begin
    PBar.Left   := Rect.Left - 1;
    PBar.Top    := StatusBar.Top + 3;
    PBar.Width  := Rect.Width - 1;
    PBar.Height := Rect.Height
  End
end;

procedure TFmMain.TrIconClick(Sender: TObject);
begin
  TrIcon.ShowBalloonHint
end;

Procedure TFmMain.ShowTask(AClassName : String; AAction : TAction);

Var
  I   : Integer;
  Frm : TFmPanel;
  Ts  : TTabSheet;

Begin
  With MPControl Do
  Begin
    If PageCount > 0 Then For I := 0 To PageCount - 1 Do If (Pages[I].Controls[0].ClassName = AClassName) Then
    Begin
      ActivePage                := Pages[I];
      Exit
    End;
    Frm                         := TFormPanelClass(GetClass(AClassName)).Create(Self);
    TS                          := TTabSheet.Create(MPControl);
    With TS Do
    Begin
      Caption                   := AAction.Caption;
      Hint                      := AAction.Hint;
      ImageIndex                := AAction.ImageIndex;
      PageControl               := MPControl
    End;
    With Frm Do
    Begin
      Parent                    := TS;
      IsPanel                   := True;
      Align                     := alClient;
      BorderStyle               := bsNone;
      Show
    End;
    ActivePage := Ts;
    If PageCount > 1 Then
    Begin
      ActivePageIndex           := ActivePageIndex - 1;
      ActivePageIndex           := ActivePageIndex + 1
    End
  End;
  SetEnabledActions
End;

Procedure TFmMain.CloseTask(AIndex : Integer);

Var
  I : Integer;

Begin
  With MPControl Do
  Begin
    I                                                                             := ActivePage.PageIndex;
    With ActivePage Do
    Begin
      (Controls[0] As TFmPanel).Close;
      Free
    End;
    If (PageCount > 0) And (ActivePage.PageIndex = 0) And (I > 0) Then ActivePage := Pages[I - 1];
  End;
  SetEnabledActions
End;

end.


А это почти тот же юнит на Дельфи:

Код: Выделить всё
unit U_Main;

interface

uses
  Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics, Vcl.Controls, Vcl.Forms,
  Vcl.Dialogs, Vcl.ComCtrls, System.Win.TaskbarCore, Vcl.Taskbar, Vcl.ToolWin, Vcl.ActnList;

type
  TFmMain = class(TForm)
    StBar: TStatusBar;
    PBar: TProgressBar;
    TskBar: TTaskbar;
    MenuBar: TToolBar;
    ToolButton1: TToolButton;
    ToolBar: TToolBar;
    ToolButton2: TToolButton;
    ToolButton3: TToolButton;
    ToolButton4: TToolButton;
    ToolButton5: TToolButton;
    ToolButton6: TToolButton;
    ToolButton7: TToolButton;
    ToolButton8: TToolButton;
    ToolButton9: TToolButton;
    ToolButton10: TToolButton;
    ToolButton11: TToolButton;
    ToolButton12: TToolButton;
    ToolButton13: TToolButton;
    ToolButton14: TToolButton;
    MPControl: TPageControl;
    ToolButton15: TToolButton;
    ToolButton16: TToolButton;
    ToolButton17: TToolButton;
    ToolButton18: TToolButton;
    ToolButton19: TToolButton;
    DataBtn: TToolButton;
    procedure FormCloseQuery(Sender: TObject; var CanClose: Boolean);
    procedure FormCreate(Sender: TObject);
    procedure FormClose(Sender: TObject; var Action: TCloseAction);
    procedure FormActivate(Sender: TObject);
    procedure StBarDrawPanel(StatusBar: TStatusBar; Panel: TStatusPanel;
      const Rect: TRect);
    procedure MPControlChange(Sender: TObject);
  private
    { Private declarations }
    fCurrentLanguage : String;
    Procedure SetCurrentLanguage(AValue : String);
    Procedure DefLanguage;
    Procedure SetLanguage;
    Procedure LoadConfig;
    Procedure SaveConfig;
    Procedure SetEnabledActions;
  protected
    { Protected declarations }
    Procedure WMGETSYSCOMMAND(var Msg :TMessage); message WM_SYSCOMMAND;
  public
    { Public declarations }
    Property CurrentLanguage : String Read fCurrentLanguage Write SetCurrentLanguage;
    Procedure ShowTask(AClassName : String; AAction : TAction);
    Procedure CloseTask(AIndex : Integer);
  end;

var
  FmMain: TFmMain;

implementation

Uses
  LanguageResManEh, U_AppIni, U_DBSett, U_Dlgs, U_BForm, U_FrmPos, U_MConst, U_MDM, U_MLang, U_MLForm, U_PForm;

{$R *.dfm}
{$R EhLibLangConsts.RUS.dfm}
{$R EhLibLangConsts.ENU.dfm}

Procedure TFmMain.SetEnabledActions;

Begin
  With MDM Do
  Begin
    CloseTaskAction.Enabled := MPControl.ActivePageIndex > - 1
  End
End;

Procedure TFmMain.SetCurrentLanguage(AValue : String);

Begin
  If fCurrentLanguage = AValue Then Exit;
  fCurrentLanguage                                                                := AValue;
  DefLanguage;
  If LoadLang(AValue) Then SetLanguage;
  With MDM Do
  Begin
    EngAction.Checked                                                             := AValue = 'LNG_ENG';
    RusAction.Checked                                                             := AValue = 'LNG_RUS'
  End;
  With LanguageResourceManagerEh Do If AValue = 'LNG_ENG' Then ActiveLanguageAbbr := 'ENU'
  Else ActiveLanguageAbbr                                                         := 'RUS'
End;

Procedure TFmMain.DefLanguage;

Var
  I : Integer;

Begin
  DefComponentLanguage(Self);
  DefComponentLanguage(MPControl);
  DefComponentLanguage(MDM);
  With MDM.TrIcon Do
  Begin
    BalloonTitle       := FmMain.Caption;
    BalloonHint        := FmMain.Hint
  End;
  With Screen Do For I := 0 To FormCount - 1 Do If Forms[I] Is TFmMultiLang Then Forms[I].Perform(WM_CLLANG, 0, 0)
End;

Procedure TFmMain.SetLanguage;

Var
  I : Integer;

Begin
  SetComponentLanguage(Self);
  SetComponentLanguage(MPControl);
  SetComponentLanguage(MDM);
  With MDM.TrIcon Do
  Begin
    BalloonTitle       := FmMain.Caption;
    BalloonHint        := FmMain.Hint
  End;
  With Screen Do For I := 0 To FormCount - 1 Do If Forms[I] Is TFmMultiLang Then Forms[I].Perform(WM_CHLANG, 0, 0);
End;

Procedure TFmMain.LoadConfig;

Var
  S : String;

Begin
  If Not LoadIniFile Then
  Begin
    ErrMsg('Error When Accessing System Settings');
    Exit
  End;
  S                      := MD5(Name);
  With IniFile Do
  Begin
    SaveOnExit           := ReadBool(S, MD5('SaveOnExit'), False);
    If SaveOnExit Then
    Begin
      CurrentLanguage    := ReadString(S, MD5('CurrentLanguage'), 'LNG_ENG');
      MinimizeToTray     := ReadBool(S, MD5('MinimizeToTray'), False);
      FieldsMultiLang    := ReadBool(S, MD5('FieldsMultiLang'), False);
      StartOfTheWeek     := ReadInteger(S, MD5('StartOfTheWeek'), 1);
      SaveFormPosition   := ReadBool(S, MD5('SaveFormPosition'), False);
      SaveGridParams     := ReadBool(S, MD5('SaveGridParams'), False);
      SPFilter           := ReadBool(S, MD5('SPFilter'), False);
      SPInputSearch      := ReadBool(S, MD5('SPInputSearch'), False);
      With MDM.DBase Do
      Begin
        Server           := CryptString(ReadString(S, MD5('DBaseServer'), ''), True);
        Database         := CryptString(ReadString(S, MD5('DBaseDatabase'), ''), True);
        Username         := CryptString(ReadString(S, MD5('DBaseUsername'), ''), True);
        Password         := CryptString(ReadString(S, MD5('DBasePassword'), ''), True);
        Port             := ReadInteger(S, MD5('DBasePort'), 3306)
      End
    End
    Else CurrentLanguage := 'LNG_RUS'
  End;
  LoadPosition(Self)
End;

procedure TFmMain.MPControlChange(Sender: TObject);
begin
  With DataBtn Do
  Begin
    Enabled                      := MPControl.PageCount > 0;
    If Enabled Then DropDownMenu := (MPControl.Pages[MPControl.ActivePageIndex].Controls[0] As TFmFormBrowse).PDataMenu
    Else DropDownMenu            := Nil
  End
end;

Procedure TFmMain.SaveConfig;

Var
  S : String;

Begin
  If Not LoadIniFile(True) Then
  Begin
    ErrMsg('Error When Accessing System Settings');
    Exit
  End;
  SavePosition(Self);
  S := MD5(Name);
  With INIFile Do
  Begin
    WriteBool(S, MD5('SaveOnExit'), SaveOnExit);
    If SaveOnExit Then
    Begin
      WriteString(S, MD5('CurrentLanguage'), CurrentLanguage);
      WriteBool(S, MD5('MinimizeToTray'), MinimizeToTray);
      WriteBool(S, MD5('FieldsMultiLang'), FieldsMultiLang);
      WriteInteger(S, MD5('StartOfTheWeek'), StartOfTheWeek);
      WriteBool(S, MD5('SaveFormPosition'), SaveFormPosition);
      WriteBool(S, MD5('SaveGridParams'), SaveGridParams);
      WriteBool(S, MD5('SPFilter'), SPFilter);
      WriteBool(S, MD5('SPInputSearch'), SPInputSearch);
      With MDM.DBase Do
      Begin
        WriteString(S, MD5('DBaseServer'), CryptString(Server));
        WriteString(S, MD5('DBaseDatabase'), CryptString(Database));
        WriteString(S, MD5('DBaseUsername'), CryptString(Username));
        WriteString(S, MD5('DBasePassword'), CryptString(Password));
        WriteInteger(S, MD5('DBasePort'), Port)
      End
    End;
    SaveIniFile
  End
End;

procedure TFmMain.StBarDrawPanel(StatusBar: TStatusBar;
  Panel: TStatusPanel; const Rect: TRect);
begin
  If Panel = StBar.Panels[ProgressPanelNumber] Then
  Begin
    PBar.Left   := Rect.Left;
    PBar.Top    := Rect.Top;
    PBar.Width  := Rect.Width - 2;
    PBar.Height := Rect.Height
  End
end;

Procedure TFmMain.WMGETSYSCOMMAND(var Msg :TMessage);

Begin
  If MinimizeToTray And (Msg.wParam = SC_CLOSE) Or (Msg.wParam = SC_MINIMIZE) Then
  Begin
    Hide;
    With MDM.TrIcon Do
    Begin
      Visible := True;
      ShowBalloonHint
    End
  End
  Else Inherited
End;

procedure TFmMain.FormActivate(Sender: TObject);
begin
  If Not FirstRun Then Exit;
  FirstRun := False;
  LoadConfig;
  With MDM.DBase Do
  Repeat
    Try
      Connect
    Except
      With Application Do
      Begin
        ProcessMessages;
        ErrMsg(GetLanguageValue('NotDBConnMsg'));
        With TFmDBSettings.Create(Self) Do If ShowModal = mrCancel Then
        Begin
          Terminate;
          Exit
        End
      End
    End
  Until Connected;
  SetEnabledActions
end;

procedure TFmMain.FormClose(Sender: TObject; var Action: TCloseAction);

Var
  I : Integer;

begin
  With MPControl Do If PageCount > 0 Then For I := PageCount - 1 DownTo 0 Do CloseTask(I);
  With MDM.DBase Do If Connected Then Disconnect;
  SaveConfig;
  FreeMultiLang;
  MDM.Free
end;

procedure TFmMain.FormCloseQuery(Sender: TObject; var CanClose: Boolean);
begin
  CanClose := Not MDM.TrIcon.Visible And (ConfirmMsg(GetLanguageValue('QuitConfMsg')) = mrYes)
end;

procedure TFmMain.FormCreate(Sender: TObject);
begin
  With FormatSettings Do
  Begin
    DecimalSeparator  := '.';
    ShortDateFormat   := 'dd.mm.yyyy'
  End;
  MDM                 := TMDM.Create(Self);
  With MDM.TrIcon Do
  Begin
    Icon              := Application.Icon;
    BalloonTitle      := FmMain.Caption;
    BalloonHint       := FmMain.Hint;
    Hint              := BalloonHint
  End;
  CreateMultiLang;
  VersionNumber       := '1.0';
  MinimizeToTray      := False;
  SaveFormPosition    := False;
  SaveToReg           := False;
  SaveOnExit          := False;
  PBar.Parent         := StBar;
  HintPanelNumber     := 0;
  ProgressPanelNumber := 1;
  TimerPanelNumber    := 2;
  ProgressPanelWidth  := 100;
  StartOfTheWeek      := 0;
  SetLanguage;
  FirstRun            := True;
  With LanguageResourceManagerEh Do
  Begin
    ResourcePlacement := lrpEmbeddedEh;
    LoadListOfAvailableLanguages('TEhLibLanguageConsts')
  End;
  SetEnabledActions
end;

Procedure TFmMain.ShowTask(AClassName : String; AAction : TAction);

Var
  I  : Integer;
  Ts : TTabSheet;

Begin
  With MPControl Do
  Begin
    If PageCount > 0 Then For I := 0 To PageCount - 1 Do If (Pages[I].Controls[0].ClassName = AClassName) Then
    Begin
      ActivePage                := Pages[I];
      Exit
    End;
    TS                          := TTabSheet.Create(MPControl);
    With TS Do
    Begin
      Caption                   := AAction.Caption;
      Hint                      := AAction.Hint;
      ImageIndex                := AAction.ImageIndex;
      PageControl               := MPControl
    End;
    With TFormPanelClass(GetClass(AClassName)).Create(Self) Do
    Begin
      Parent                    := TS;
      PanelMode                 := True;
      Show
    End;
    ActivePage                  := Ts
  End;
  MPControlChange(Nil);
  SetEnabledActions
//  With TFormPanelClass(GetClass(AClassName)).Create(Self) Do ShowModal
End;

Procedure TFmMain.CloseTask(AIndex : Integer);

Begin
  With MPControl Do
  Begin
    With Pages[AIndex] Do
    Begin
      (Controls[0] As TFmFormPanel).Close;
      Free
    End;
    If AIndex > 0 Then ActivePageIndex := AIndex - 1
  End;
  MPControlChange(Nil);
  SetEnabledActions
End;

end.


Как говорится, найдите 10 отличий... :D
S_Gur
постоялец
 
Сообщения: 130
Зарегистрирован: 30.12.2018 22:17:42

Re: ООП и формы

Сообщение iskander » 13.09.2019 21:35:10

S_Gur писал(а):даже не знаю, для чего его вообще использовать...

Вас кто-то заставляет это делать?

Добавлено спустя 56 минут 48 секунд:
Хмм, когда я отправлял свой пост, в вашем сообщении было одно предложение. Вы их правите по мере необходимости?
Впрочем, неважно, я увидел. Так вот, говоря "угробить Pascal"я имел в в виду популярность и востребованность языка.
iskander
энтузиаст
 
Сообщения: 606
Зарегистрирован: 08.01.2012 18:43:34

Re: ООП и формы

Сообщение S_Gur » 13.09.2019 22:55:44

Как по мне, так Лазарус уж точно ситуацию с популярностью и востребованностью не улучшает... Жалко, конечно. Идея уж точно хорошая
S_Gur
постоялец
 
Сообщения: 130
Зарегистрирован: 30.12.2018 22:17:42

Re: ООП и формы

Сообщение Снег Север » 14.09.2019 06:27:14

S_Gur, я, например, программирую на Делфи уже четверть века, есть проекты по 300-400 тыс. строк собственного кода с полусотней форм, но мне никогда не доводилось создавать в проектах унаследованные формы от изменяемого предка. Как-то обходился без этого. Это к тому, что есть куча мало кем востребованных фичей.
Аватара пользователя
Снег Север
долгожитель
 
Сообщения: 3038
Зарегистрирован: 27.11.2007 16:14:47

Re: ООП и формы

Сообщение S_Gur » 16.09.2019 09:01:22

Снег Север, я так понимаю, что вы тоже не вникли в суть проблемы. Нет никакого изменяемого предка, речь идет исключительно о дизайне. Я создаю всю цепочку наследников и при дальнейшей разработке на основе функционального назначения каждого из них принимаю решение, в какую из форм-предков нужно вносить те или иные доработки. Как эти доработки функционируют, я, само собой, должен видеть именно в потомке, поэтому при проектировании сложной системы довольно трудно (во всяком случае, мне лично) полностью прописать предка перед тем, как создавать от него потомка. Приведу пример на основе именно этого проекта, не вдаваясь в конкретику. Моя система многоязычная, поэтому самый старший уровень - это форма, имеющая функционал для изменения текущего языка. Моя программа открывает большинство рабочих форм на открывающихся динамически страницах расположенного на главной форме TPageControl, поэтому от мультиязычной формы я рожаю потомка, способного различать, открывается он как обычная форма или на главной форме. Следующий уровень - форма, работающая с наборами данных, поэтому на ней размещены датасеты, датасорсы и их программная обвязка. Дальше идет форма, показывающая этот набор данных в гриде (в частности, EhLib-овском), поэтому на потомка от предыдущей я кидаю грид. Ну и последняя форма - это форма, работающая с конкретным набором данных - в ней я задаю селект для показа данный, форму редактирования записи, процедуру удаления записи и некоторые дополнительные мелочи. Есть еще некоторые частности - например, у меня есть таблица, содержащая списковые справочники, поэтому ее редактор я рожаю от вышеописанной, передавая ей в качестве параметра только тип конкретного справочника. В результате у меня получается 5 или 6 форм, унаследованных друг от друга. Соответственно, когда я открываю конкретный списковый справочник не на главной форме и в процессе отладки понимаю, что хочу все подобные формы закрывать по клавише Esc, я должен обработать OnKeyDown на форме, работающей со страницами PageControl - а это получается прадедушка моей конечной формы. Именно эту конструкцию я пытался реализовать на Лазарусе и в частности столкнулся с тем, что когда я на форме с гридом на OnShow пишу Grid.SetFocus, конечная форма на это дело просто плюет. Обработка того же OnShow на ней работает правильно. Проблемы с самым стандартным использованием ООП. С ActionList было еще хуже - я создал его на второй форме, создал несколько экшенов, породил от нее сына и внука, а затем понял, что пара экшенов лишняя и убил их из предка. Убитые экшены остались во всех потомках и я убивал их руками в каждой форме отдельно. Это все далеко не маловостребованные фичи, это абсолютно стандартное ООП
S_Gur
постоялец
 
Сообщения: 130
Зарегистрирован: 30.12.2018 22:17:42

Пред.

Вернуться в Общее

Кто сейчас на конференции

Сейчас этот форум просматривают: нет зарегистрированных пользователей и гости: 10

Рейтинг@Mail.ru