unit Main; { Main Form of the CHROMuLAN }
{
  (C) 2000 - 2001 Jindrich Jindrich, Pavel Pisa, PiKRON Ltd.

  Originators of the CHROMuLAN project:

  Jindrich Jindrich - http://www.jindrich.com
                      http://orgchem.natur.cuni.cz/Chromulan/
                      software developer, project coordinator
  Pavel Pisa        - http://cmp.felk.cvut.cz/~pisa
                      embeded software developer
  PiKRON Ltd.       - http://www.pikron.com
                      project initiator, sponsor, instrument developer

  The CHROMuLAN project is distributed under the GNU General Public Licence.
  See file COPYING for details.

  Originators reserve the right to use and publish sources
  under different conditions too. If third party contributors
  do not accept this condition, they can delete this statement
  and only GNU license will apply.
}

interface

uses
  WinTypes, WinProcs, SysUtils, Classes, Graphics, Forms, Controls, Menus,
  StdCtrls, Dialogs, Buttons, Messages, ExtCtrls, ComCtrls, Clipbrd,

  BomeOneInstance, IniObj, FileMenuHdl, ExtComDl,

  UtlType, WinUtl, Fileu, ExeLogu, Timersu, CommInt, CommFrm, Language,
  ApexType, UlanType, UlanGlob, ULObju,
  ULFObju, ULMaGlob, Modulu,

  FileNewDlg, Channelsu, DevMode, ExpImpu,
  ULRecTyp, ULPrgu, AAPrgu, AAAu, LogFrm,
  ULKeepFrm,
  ULSQType, Sequenceu, AAPGType
  {v0.47},ULObjUsrNodeu, ULObjUsrTreeFrm, ULScriptu, ULScriptFrm{/v0.47}
  {v0.49}
  ,USPType, SeqPrgu
  {/v0.49}
  {v0.50}
  ,FileEditFrm, ULDyAdr, Processoru
  {/v0.50}
  {v0.55}
  ,ControlFrm
  {/v0.55}
  {v0.61}
  ,FileDlg
  {/v0.61}
  {v0.65}
  ,CuLSharedMemu
  {/v0.65}
  {v0.67}
  ,CalibrationFrm, Attrib
  {/v0.67}
  {ulstringgrid xstringgrid}
  ;
{ See UlanDef/ulanrecs.lst for data structures definitions list }

type
  TMainForm = class(TForm)
    MainMenu1: TMainMenu;
    Panel1: TPanel;
    StatusLine: TPanel;
    File_Item: TMenuItem;
    FileNew_Item: TMenuItem;
    FileOpen_Item: TMenuItem;
    Panel2: TPanel;
    FileClose_Item: TMenuItem;
    Window_Item: TMenuItem;
    Help_Item: TMenuItem;
    N1: TMenuItem;
    FileExit_Item: TMenuItem;
    WindowCascade_Item: TMenuItem;
    WindowTile_Item: TMenuItem;
    WindowArrangeIcons_Item: TMenuItem;
    HelpAbout_Item: TMenuItem;
    OpenDialog: TOpenDialog;
    FileSave_Item: TMenuItem;
    FileSaveAs_Item: TMenuItem;
    Edit_Item: TMenuItem;
    EditCut_Item: TMenuItem;
    EditCopy_Item: TMenuItem;
    EditPaste_Item: TMenuItem;
    WindowMinimizeAll_Item: TMenuItem;
    SpeedPanel: TPanel;
    FileOpen_Btn: TSpeedButton;
    FileSave_Btn: TSpeedButton;
    EditCut_Btn: TSpeedButton;
    EditCopy_Btn: TSpeedButton;
    EditPaste_Btn: TSpeedButton;
    FileExit_Btn: TSpeedButton;
    Chromatogram_Btn: TSpeedButton;
    FileNew_Btn: TSpeedButton;
    Tools_Item: TMenuItem;
    ToolsDebug_Item: TMenuItem;
    ToolsComWindow_Item: TMenuItem;
    ToolsSetup_Btn: TSpeedButton;
    IniObject1: TIniObject;
    ToolsTest_Item: TMenuItem;
    Timer: TTimer;
    HelpOnHelp_Item: TMenuItem;
    HelpContents_Item: TMenuItem;
    HelpSearch_Item: TMenuItem;
    FMH: TFileMenuHandler;
    OneInstance: TOneInstance;
    ESaveDialog: TESaveDialog;
    Setup_Item: TMenuItem;
    Channels_Item: TMenuItem;
    DevicesAutodetect_Item: TMenuItem;
    DevicesBrowse_Item: TMenuItem;
    Autodetect1: TMenuItem;
    SetupOptions_Item: TMenuItem;
    SetupExpImp_Item: TMenuItem;
    ParentFileOpenDialog: TOpenDialog;
    AAPrograms_Item: TMenuItem;
    Application_Item: TMenuItem;
    AAA_Item: TMenuItem;
    LogWindow_Item: TMenuItem;
    ULKeeper_Item: TMenuItem;
    Programs_Item: TMenuItem;
    ULRootTree_Item: TMenuItem;
    Scripts_Item: TMenuItem;
    SequencePrograms_Item: TMenuItem;
    EnvVars_Item: TMenuItem;
    TestULPath_Item: TMenuItem;
    TestReplaceEnvVars_Item: TMenuItem;
    Dirs_Item: TMenuItem;
    ULServer_Item: TMenuItem;
    ControlWindowItem: TMenuItem;
    FileDialog_Item: TMenuItem;
    TNewCal_Item: TMenuItem;
    NewAcq_Item: TMenuItem;
    procedure FormCreate(Sender: TObject);
    procedure FileNew_ItemClick(Sender: TObject);
    procedure WindowCascade_ItemClick(Sender: TObject);
    procedure UpdateMenuItems(Sender: TObject);
    procedure WindowTile_ItemClick(Sender: TObject);
    procedure WindowArrangeIcons_ItemClick(Sender: TObject);
    procedure FileClose_ItemClick(Sender: TObject);
    procedure FileOpen_ItemClick(Sender: TObject);
    procedure FileExit_ItemClick(Sender: TObject);
    procedure FileSave_ItemClick(Sender: TObject);
    procedure FileSaveAs_ItemClick(Sender: TObject);
    procedure EditCut_ItemClick(Sender: TObject);
    procedure EditCopy_ItemClick(Sender: TObject);
    procedure EditPaste_ItemClick(Sender: TObject);
    procedure WindowMinimizeAll_ItemClick(Sender: TObject);
    procedure FormDestroy(Sender: TObject);
    procedure FileNew_BtnClick(Sender: TObject);
    procedure Chromatogram_BtnClick(Sender: TObject);
    procedure EditCut_BtnClick(Sender: TObject);
    procedure EditCopy_BtnClick(Sender: TObject);
    procedure EditPaste_BtnClick(Sender: TObject);
    procedure HelpAbout_ItemClick(Sender: TObject);
    procedure ToolsDebug_ItemClick(Sender: TObject);
    procedure ToolsComWindow_ItemClick(Sender: TObject);
    procedure ToolsSetup_BtnClick(Sender: TObject);
    procedure FormClose(Sender: TObject; var Action: TCloseAction);
    procedure DevicesAutodetect_ItemClick(Sender: TObject);
    procedure DevicesBrowse_ItemClick(Sender: TObject);
    procedure TimerTimer(Sender: TObject);
    procedure ToolsSetup_ItemClick(Sender: TObject);
    procedure HelpOnHelp_ItemClick(Sender: TObject);
    procedure HelpContents_ItemClick(Sender: TObject);
    procedure HelpSearch_ItemClick(Sender: TObject);
    procedure FormKeyDown(Sender: TObject; var Key: Word;
      Shift: TShiftState);
    function FMHOpen(var Filename: String): Boolean;
    function FMHNew(var Filename: String): Boolean;
    function FMHSave(var Filename: String): Boolean;
    procedure OneInstanceInstanceStarted(Sender: TObject;
      params: TStringList);
    function FMHBeforeSave(AIsNew: boolean; var AFilename: String): Boolean;
    procedure SaveDialogTypeChange(Sender: TObject);
    procedure Channels_ItemClick(Sender: TObject);
    procedure ChannelsSetDefault_ItemClick(Sender: TObject);
    procedure SetupOptions_ItemClick(Sender: TObject);
    procedure SetupExpImp_ItemClick(Sender: TObject);
    procedure AAPrograms_ItemClick(Sender: TObject);
    procedure AARun_ItemClick(Sender: TObject);
    procedure AAA_ItemClick(Sender: TObject);
    procedure LogWindow_ItemClick(Sender: TObject);
    procedure ULKeeper_ItemClick(Sender: TObject);
    procedure OpenDialogTypeChange(Sender: TObject);
    procedure Programs_ItemClick(Sender: TObject);
    procedure ULRootTree_ItemClick(Sender: TObject);
    procedure Scripts_ItemClick(Sender: TObject);
    procedure SequencePrograms_ItemClick(Sender: TObject);
    procedure EnvVars_ItemClick(Sender: TObject);
    procedure TestULPath_ItemClick(Sender: TObject);
    procedure TestReplaceEnvVars_ItemClick(Sender: TObject);
    procedure Dirs_ItemClick(Sender: TObject);
    procedure ULServer_ItemClick(Sender: TObject);
    procedure ControlWindowItemClick(Sender: TObject);
    procedure FileDialog_ItemClick(Sender: TObject);
    procedure TNewCal_ItemClick(Sender: TObject);
  private
    {v0.24}
    FDefAppStarted: boolean;
    {/v0.24}
    {v0.50}
    FTimerCallCount: integer;
    {/v0.50}
    {HHlp:THtmlHelp;}
    { Private declarations }
    {procedure CreateSpectrumForm(const Name: string; AMode:word);}
    procedure ShowHint(Sender: TObject);
    {procedure SetPortDefaults;}
    {v0.24}
    {v0.50}
    function AAAStart: boolean;
    {/v0.50
    procedure AAAStart;}
    {/v0.24}
    {v0.30}
    {procedure WMMdiTile(var Msg: TMessage); windows messages WM_MDITILE;}
    procedure Arrange(Msg: integer);
    {/v0.30}
  {v0.65}
  protected
    procedure WndProc(var Message: TMessage); override;//controls
    procedure WMCHROMuLANMessage(var Msg: TMessage);
  {/v0.65}
  public
    { Public declarations }
    {v0.43}{/v0.43
    ComPort: TComm;}
    procedure WMAppMessage(var Msg:TMessage);message WM_APPMESSAGE;{in globals}
    {procedure PeaksDefineCreateForm(AConnectedForm:TForm); windows getwincontrolstate}
    function AppOnHelp(Command: Word; Data: Longint; var CallHelp: Boolean): Boolean;
    {function AppOnHelp(Command: Word; Data: Longint): Boolean;}
    procedure WMHelp(var Msg:TMessage); message WM_HELP;
    procedure LoadCursors;
    {v0.09}
    { Called to open somehow the file selected in FMHOpen method }
    function FileOpen(var AFileName: string): boolean;
    procedure WMInitMenu(var Msg:TMessage);message WM_INITMENU;
    {/0.09}
    {v0.24}
    procedure ActiveFormChanged(Sender: TObject);
    {/v0.24}
    {v0.32}
    function CheckOpenByExt(const AFileName: string; AMode: TOpenMode): boolean;
    {/v0.32}
  end;

var
  MainForm: TMainForm;

implementation

{$R *.DFM}
{$R IMAGES.RES}

uses SpecForm, AboutFrm, DebugFrm, DevSetFr, PumpFrm{v0.23} , AAFrm,
  OptionsFrm{/v0.23};

{v0.23 moved to ulanConfigReadWrite, called from ulmaglob }{/v0.23
procedure ReadIni;
begin
  ConfigReadWriteValue(rwRead, EnvSectionName, 'ToolsAllowed', @ToolsAllowed, ptByte);
  ConfigReadWriteValue(rwRead, EnvSectionName, 'DebugToolsAllowed', @DebugToolsAllowed, ptByte);
  ConfigReadWriteValue(rwRead, EnvSectionName, 'TestAllowed', @TestAllowed, ptByte);
  UlanConfigReadWrite(rwRead);
end;

procedure WriteIni;
begin
  ConfigReadWriteValue(rwWrite, EnvSectionName, 'ToolsAllowed', @ToolsAllowed, ptByte);
  ConfigReadWriteValue(rwWrite, EnvSectionName, 'DebugToolsAllowed', @DebugToolsAllowed, ptByte);
  ConfigReadWriteValue(rwWrite, EnvSectionName, 'TestAllowed', @TestAllowed, ptByte);
  UlanConfigReadWrite(rwWrite);
end;
}
(*
procedure TMainForm.SetPortDefaults;
begin
  {$IFDEF WIN32}
  {commint}
  with ComPort do begin
    AfterOpenState := aoSpecified;
    BaudRate := br9600;
    DataBits := da8;
    DeviceName := 'Com2';
    FlowControl := fcDefault;
    MonitorEvents := [evRxChar];
    Options := [];
    Parity := paSpace;
    ReadBufSize := 4096;
    ReadTimeout := 1000;
    StopBits := sb10;
    WriteBufSize := 2048;
    WriteTimeout := 1000;
  end;
  {$ELSE}
  {comm}
  with ComPort do begin
    BaudRate := tbr9600;
    DataBits := tdbEight;
    Parity := tpSpace;
    ReadBufferSize := 2048;
    Stopbits := tsbOne;
    TxLowCount := 1024;
    WriteBufferSize := 1024;
    Events := [tceRxChar];
  end;
  {$ENDIF}
end;
*)
procedure TMainForm.FormCreate(Sender: TObject);
begin
  {v0.10}
  if not OneInstance.IsFirstInstance then
    exit;
  {/v0.10}
  {v0.65}
  //FSharedMem := TSharedMem.Create('CHROMuLAN', sizeof(TCuLGlobalMem));
  CHROMuLANMessage := RegisterWindowMessage(CHROMuLANName);
  CuLSharedMem^.CuLIsRunning := true;
  {/v0.65}
  Caption := 'CHROMuLAN v' + uLanVersion;
  HelpContext := 0{1000};
{  HHlp := THtmlHelp.Create(Self);}

  Application.OnHint := ShowHint;
  Application.OnHelp := AppOnHelp;{winhelp windows}
  Screen.OnActiveFormChange := {v0.24} ActiveFormChanged;{/v0.24 UpdateMenuItems;}
  {v0.43}{/v0.43
  ComPort := nil;}
  {v0.19}
  ulMInit(false);
  {/v0.19
  LogRegister;
  ConfigInit(Paramstr(0));}
  {v0.23}{/v0.23 ReadIni; }{chromulan.iss}
  Tools_Item.Visible := ToolsAllowed;
  ToolsDebug_Item.Visible := DebugToolsAllowed;
  ToolsTest_Item.Visible := TestAllowed;
  {v0.19 moved above}
  {/v0.19 ulMInit(false);}
{comm}
  LoadCursors;
  {v0.13}
  Application.UpdateFormatSettings := false;
    { ignore WM_INICHANGED, so that DecimalSeparator (set in UlanGlob to '.')
      value won't get changed }
  {/v0.13}
  {v0.14}
  FMH.SaveDialog := TSaveDialog(ESaveDialog);
  {v0.21}
  {ConfigClose;}
  {/v0.21}

  {v0.28}
  if UseLanguage then begin{ulanglob}
    LanguageInit(LanguageName);
    FLanguage.RegisterMode := true;{just during development}
    //FLanguage.ScanSourceFiles;
       //call only if added some {#} marks to source ulobjact xstringgrid
       //chromulan.lng
  end;
  {/v0.28 language}
  {v0.64}
  OpenDialog.InitialDir := DataDir;
  {/v0.64}
end;

procedure TMainForm.LoadCursors;
begin
  Screen.Cursors[crThinCross] := LoadCursor(HInstance, 'THINCROSS');
  Screen.Cursors[crZoomIn] := LoadCursor(HInstance, 'ZOOMIN');
  Screen.Cursors[crThinCrossUp] := LoadCursor(HInstance, 'THINCROSSUP');
end;

procedure TMainForm.ShowHint(Sender: TObject);
begin
  StatusLine.Caption := Application.Hint;
end;

procedure TMainForm.FileNew_ItemClick(Sender: TObject);
begin
{v0.09}
  FMH.New;
{  CreateSpectrumForm('', omCreate);}
end;

procedure TMainForm.FileOpen_ItemClick(Sender: TObject);
{v0.09}
begin
  FMH.Open;
end;
{/v0.09
var
  fn: string;
  m: TOpenMode;
begin
  if OpenDialog.Execute then begin
    FileOpen(OpenDialog.FileName);
  end;
end;
}

{v0.32}
function TMainForm.CheckOpenByExt(const AFileName: string; AMode: TOpenMode): boolean;
var
  ext: string;
begin
  Result := false;
  ext := UpperCase(ExtractFileExt(AFileName));

  if (ext = ULSExt) then begin
    Result := SequenceBrowserOpen(AFileName, AMode);
  end{v0.41} else if (ext = AAPGExt) then begin
    Result := AAPrgBrowserOpen(AFileName, AMode);
  end {v0.49} else if (ext = USPExt) then begin
    Result := SeqPrgBrowserOpen(AFileName, AMode);
  end{/v0.49}{v0.67} else if (ext = ULCExt) then begin
    Result := CalibrationFormOpen(AFileName, AMode) <> nil;
  end{/v0.67};
  {/v0.41};
end;
{/v0.32}

function TMainForm.FileOpen(var AFileName: string): boolean;
{v0.09}
var
  fn, ext: string;
{/v0.09}
var
  m: TOpenMode;
begin
  if ofReadOnly in OpenDialog.Options then
    m := omReadOnly
  else
    m := omRead;
  fn := AFileName;
  {v0.09}
  ext := GetExtFromFileDialogFilter(OpenDialog.Filter, OpenDialog.FilterIndex);
  fn := ReplaceExt(fn, ext, false);
  AFileName := fn;
  {/v0.09}
  {v0.32}
  if not CheckOpenByExt(fn, m) then begin
    CreateSpectrumForm(fn, m);
  end;
  {/v0.32
  CreateSpectrumForm(fn, m);}
  Result := true;
end;

procedure TMainForm.FileClose_ItemClick(Sender: TObject);
begin
  if ActiveMDIChild <> nil then
    ActiveMDIChild.Close;
end;

procedure TMainForm.FileSave_ItemClick(Sender: TObject);
begin
  { save current file (ActiveMDIChild points to the window) }
{  FileSaveAs_ItemClick(Sender);}
  FMH.Save;
end;

procedure TMainForm.FileSaveAs_ItemClick(Sender: TObject);
begin
  {v0.09}
  FMH.SaveAs;
  {/v0.09
  if Screen.ActiveForm is TSpectrumForm then begin
    with Screen.ActiveForm as TSpectrumForm  do begin
      DoSaveTo;
    end;
  end;
  }
end;

procedure TMainForm.FileExit_ItemClick(Sender: TObject);
begin
  Close;
end;

procedure TMainForm.EditCut_ItemClick(Sender: TObject);
var c:TWinControl;
begin
  if ActiveMDIChild <>  nil then begin
    {v0.24}
    c := ActiveMDIChild.ActiveControl;
    if c <> nil then
      SendMessage(c.Handle, WM_CUT, 0, 0)
    else
      SendMessage(ActiveMDIChild.Handle, WM_CUT, 0, 0);
  end;
    {/v0.24 SendMessage(ActiveMDIChild.Handle, WM_APPMESSAGE, cmClipCut, 0);
    SendMessage(ActiveMDIChild.Handle, WM_CUT, 0, 0);}
end;

procedure TMainForm.EditCopy_ItemClick(Sender: TObject);
var c:TWinControl;
begin
  if ActiveMDIChild <>  nil then begin
    {v0.24}{/v0.24 SendMessage(ActiveMDIChild.Handle, WM_APPMESSAGE, cmClipCopy, 0);}
    c := ActiveMDIChild.ActiveControl;
    if c <> nil then
      SendMessage(c.Handle, WM_COPY, 0, 0)
    else
      SendMessage(ActiveMDIChild.Handle, WM_COPY, 0, 0);
  end;
end;

procedure TMainForm.EditPaste_ItemClick(Sender: TObject);
var c: TWinControl;
begin
  if ActiveMDIChild <>  nil then begin
    {v0.24}
    c := ActiveMDIChild.ActiveControl;
    if c <> nil then
      SendMessage(c.Handle, WM_PASTE, 0, 0)
    else
      SendMessage(ActiveMDIChild.Handle, WM_PASTE, 0, 0);
    {/v0.24
    SendMessage(ActiveMDIChild.Handle, WM_PASTE, 0, 0);
    SendMessage(ActiveMDIChild.Handle, WM_APPMESSAGE, cmClipPaste, 0);}
    {SendMessage(ActiveMDIChild.Handle, WM_PASTE, 0, 0);}
  end;
end;

procedure TMainForm.WindowCascade_ItemClick(Sender: TObject);
begin
  {v0.30}
  Arrange(WM_MDICASCADE);
  {/v0.30
  Cascade;}
end;

procedure TMainForm.WindowTile_ItemClick(Sender: TObject);
begin
  {v0.30}
  Arrange(WM_MDITILE);
  {/v0.30 Tile;}
end;

{v0.30}
procedure TMainForm.Arrange(Msg: integer);
var
  i: integer;
  f: TForm;
  w: integer;
begin
  if ClientHandle = 0 then
    exit;
  try
    for i := 0 to MDIChildCount - 1 do begin
      f := MDIChildren[i];
      if f is TAAForm then
        f.Enabled := false;
    end;
//  MDITILE_VERTICAL = 0;
//  MDITILE_HORIZONTAL = 1;
//  MDITILE_SKIPDISABLED = 2;
  if msg = WM_MDITILE then
    w := MDITILE_HORIZONTAL
  else
    w := 0;
  SendMessage(ClientHandle, Msg, MDITILE_SKIPDISABLED + w, 0);

  finally
    for i := 0 to MDIChildCount - 1 do begin
      f := MDIChildren[i];
      if f is TAAForm then
        f.Enabled := true;
    end;
  end;
end;
{/v0.30}

procedure TMainForm.WindowArrangeIcons_ItemClick(Sender: TObject);
begin
  ArrangeIcons;
end;

procedure TMainForm.WindowMinimizeAll_ItemClick(Sender: TObject);
var
  I: Integer;
begin
  { Must be done backwards through the MDIChildren array }
  for I := MDIChildCount - 1 downto 0 do
    MDIChildren[I].WindowState := wsMinimized;
end;

procedure TMainForm.UpdateMenuItems(Sender: TObject);
var
  f: TForm;
  {v0.24}
  c: TWinControl;
  i: integer;
  {/v0.24}{activecontrol}
begin
  FileClose_Item.Enabled := MDIChildCount > 0;
  {v0.09}{/v0.09
  FileSave_Item.Enabled := MDIChildCount > 0;}
  FileSaveAs_Item.Enabled := MDIChildCount > 0;

  {v0.24}
  {/v0.24
  EditCut_Item.Enabled := MDIChildCount > 0;
  EditCopy_Item.Enabled := MDIChildCount > 0;
  EditPaste_Item.Enabled := MDIChildCount > 0;

  EditCut_Btn.Enabled := MDIChildCount > 0;
  EditCopy_Btn.Enabled := MDIChildCount > 0;
  EditPaste_Btn.Enabled := MDIChildCount > 0;}

  FileSave_Btn.Enabled := MDIChildCount > 0;

  WindowCascade_Item.Enabled := MDIChildCount > 0;
  WindowTile_Item.Enabled := MDIChildCount > 0;
  WindowArrangeIcons_Item.Enabled := MDIChildCount > 0;
  WindowMinimizeAll_Item.Enabled := MDIChildCount > 0;
  {v0.09}
  f := ActiveMDIChild;
  if (f <> nil) then begin
    if (f is TSpectrumForm) then with f as TSpectrumForm do begin
      FileSave_Item.Enabled := (ActiveAcqData <> nil) and ActiveAcqData.ULF.Modified;
    end else begin
      FileSave_Item.Enabled := false;
    end;

    {v0.24}
    c := f.ActiveControl;
    if c is TCustomEdit then begin {tmemo}
      i := 0;
      if Clipboard.HasFormat(CF_TEXT) then
        i := i or emPaste;
      if TCustomEdit(c).SelText <> '' then begin
        i := i or emCut or emCopy;
      end;
    end else begin
      i := SendMessage(f.Handle, WM_APPMESSAGE, cmQueryEditMenu, 0);
        { mytype}
    end;
    EditCut_Item.Enabled := (i and emCut) <> 0;
    EditCopy_Item.Enabled := (i and emCopy) <> 0;
    EditPaste_Item.Enabled := (i and emPaste) <> 0;
  end else begin
    FileSave_Item.Enabled := false;
    {v0.24}
    EditCut_Item.Enabled := false;
    EditCopy_Item.Enabled := false;
    EditPaste_Item.Enabled := false;
    {/v0.24}
  end;
  {v0.24}
  EditCut_Btn.Enabled := EditCut_Item.Enabled;
  EditCopy_Btn.Enabled :=  EditCopy_Item.Enabled;
  EditPaste_Btn.Enabled := EditPaste_Item.Enabled;
  {/v0.24}


  {v0.09}
end;

{v0.24}
procedure TMainForm.ActiveFormChanged(Sender: TObject);
begin
  UpdateMenuItems(Sender);
  {v0.28}
  LanguageCheckForms;
  {/v0.28}
end;
{/v0.24}

procedure TMainForm.FormDestroy(Sender: TObject);
begin
  {v0.65}
  CuLSharedMem^.CuLIsRunning := false;
  {/v0.65}
  {v0.10}
  if not OneInstance.IsFirstInstance then
    exit;
  {v0.10}
  Screen.OnActiveFormChange := nil;
  {HHlp.Free;}
  {ConfigInit(Paramstr(0));}
  Application.OnHelp := nil;
  Application.HelpCommand(HELP_QUIT, 0);
  {v0.14}
  FFileNewDialog.Free;
  {/v0.14}
  {v0.21}
  {ConfigOpen;}
  {/v0.21}
  {v0.23}{/0.23
  WriteIni;}
  {v0.21}{/v0.21 ConfigDone;}
  ulMDone;
end;

procedure TMainForm.WMHelp(var Msg:TMessage);
(*
var
  i: integer;
  hi: PHelpInfo;

  tagHELPINFO = packed record
    iContextType: Integer; { Either HELPINFO_WINDOW or HELPINFO_MENUITEM }
    iCtrlId: Integer;      { Control Id or a Menu item Id. }
    hItemHandle: THandle;  { hWnd of control or hMenu.     }
    dwContextId: DWORD;    { Context Id associated with this item }
    MousePos: TPoint;      { Mouse Position in screen co-ordinates }
  end; iditem windows messages wm_menuselect

  f: TComponent;*)

begin
(*  i := 0;{cm_invokehelp messages windows helpinfo uleditfr}
  hi := PHelpInfo(Msg.lParam);
  f := nil;

  with hi^ do begin
    for i := 0 to ComponentCount - 1 do begin
      c := Components[i];
      case iContextType of
        HELPINFO_WINDOW: begin
          if c is TWinControl then with c as TWinControl do begin
            if Handle = hItemHandle then begin
              f := c;
              break;
            end;
          end;
        end;
        HELPINFO_MENUITEM: begin
          if c is TMenuItem then with c as TMenuItem do begin
            {if c.Command =}
          end;
        end;
      end;
    end;
  end;
  *)
  inherited;
end;

procedure TMainForm.WMAppMessage(var Msg:TMessage);
var CurChild:integer;

  function ForwardMessage(var Msg:TMessage):longint;
  var i:integer;l:longint;
  begin{tform}
    ForwardMessage:= 0;
    for i := 0 to MDIChildCount - 1 do begin
      l := SendMessage(MDIChildren[i].Handle, Msg.Msg, Msg.WParam, Msg.LParam);
      if l > 0 then begin
        ForwardMessage := l;
        CurChild := i;
        exit;
      end;
    end;
  end;

begin
  case Msg.WParam of
    cmQueryRunning, cmULObjBeforeEdit,
    cmULEditFormCloseQuery, cmULObjAfterEdit, cmULObjAfterBrowseEdit:  begin
      if ForwardMessage(Msg) = 1 then begin
        Msg.Result := 1;
        exit;
      end;
    end;

  end;
  inherited;
end;

procedure TMainForm.FileNew_BtnClick(Sender: TObject);
begin
  FileNew_ItemClick(Sender);
end;

procedure TMainForm.Chromatogram_BtnClick(Sender: TObject);
begin
  PostMessage(ActiveMDIChild.Handle, WM_APPMESSAGE, cmLocalMenu, 0);{utltype}
end;

procedure TMainForm.EditCut_BtnClick(Sender: TObject);
begin
  EditCut_ItemClick(Sender);
end;

procedure TMainForm.EditCopy_BtnClick(Sender: TObject);
begin
  EditCopy_ItemClick(Sender);
end;

procedure TMainForm.EditPaste_BtnClick(Sender: TObject);
begin
  EditPaste_ItemClick(Sender);
end;

procedure TMainForm.HelpAbout_ItemClick(Sender: TObject);
begin
  ULAboutBox.ShowModal;
end;

procedure TMainForm.ToolsDebug_ItemClick(Sender: TObject);
begin
  if DebugForm = nil then begin
    DebugForm := TDebugForm.Create(Application);
  end;
  if not ToolsDebug_Item.Checked then begin
    ToolsDebug_Item.Checked := true;
    DebugForm.Show;
  end else begin
    ToolsDebug_Item.Checked := false;
    DebugForm.Hide;
  end;
end;

procedure TMainForm.ToolsComWindow_ItemClick(Sender: TObject);
{$IFDEF WIN32}
var f:TCommForm;
{$ENDIF}
begin
{$IFDEF WIN32}
  f := TCommForm.Create(Application);
  f.ShowModal;
  f.Free;
{$ENDIF}
end;

procedure TMainForm.ToolsSetup_BtnClick(Sender: TObject);
begin
  DevSetupForm.ShowModal;
end;

procedure TMainForm.FormClose(Sender: TObject; var Action: TCloseAction);
begin
{  IniObject1.Write;}
end;

{v0.23}
const
  testString: string = '';
{/v0.23}
procedure TMainForm.DevicesAutodetect_ItemClick(Sender: TObject);
{v0.14}
var
  dm: TDeviceMode;
{/v0.14}
begin
  {v0.14}
  dm := dmUlan;
  if not DeviceModeCheck(dm) then begin
    exit
  end else begin
    if Modules.DeviceMode <> dmUlan then begin
      Modules.DeviceMode := dmUlan;
    end;
    Modules.ULDrvFailed := false;
  end;
  {/v0.14}
  if Modules.ScanForModules > 0 then begin
    Modules.ULD.Browse
  end else
    ShowMessage(GetTxt({#}'No devices detected.'));
end;

procedure TMainForm.DevicesBrowse_ItemClick(Sender: TObject);
begin
  Modules.ULD.Browse;
end;

procedure TMainForm.TimerTimer(Sender: TObject);
begin
  {v0.43}
  {DebLog('MainForm.Timer begin');}
  try
  {/v0.43}

  if csDestroying in ComponentState then
    exit;
  {v0.24}
  if csCreating in ControlState then
    exit;
  {v0.50}
  if FTimerCallCount < 100 then
    inc(FTimerCallCount);
  if (not FDefAppStarted) {v0.50} and (FTimerCallCount > 2){/v0.50} then begin
    {v0.50}
    if DefaultApplication = 'AAA' then begin
      if not Modules.Autodetecting then begin
        FDefAppStarted := AAAStart;
      end;
    end else begin
      FDefAppStarted := true;
    end;
    {/v0.50
    FDefAppStarted := true;
    if DefaultApplication = 'AAA' then begin
      AAAStart;
    end;

    }
  end;
  {v0.25}
  {Timers.DoTimer(Sender);}
  {/v0.25}
  {/v0.24}
  ULMDoTimer;
  {v0.24}
  {v0.25}{/v0.25}
  Timers.DoTimer(Sender);
  {v0.43}
  finally
  {DebLog('MainForm.Timer end');}
  end;
  {/v0.43}
end;

procedure TMainForm.ToolsSetup_ItemClick(Sender: TObject);
begin
  DevSetupForm.ShowModal;
end;

procedure TMainForm.HelpOnHelp_ItemClick(Sender: TObject);
begin
  WinHelp(Handle, 'WINHELP.HLP', HELP_HELPONHELP, 0);
end;

function TMainForm.AppOnHelp(Command: Word; Data: Longint; var CallHelp: Boolean): Boolean;
begin
  {v0.11}
  Result := true;
  {/v0.11}
  CallHelp := true;{false; tapplication windows}
  if Command = HELP_CONTEXTPOPUP then begin
    CallHelp := false;
    Application.HelpContext(Data);
  end;
{  WinHelp(Handle, '',}
end;

procedure TMainForm.HelpContents_ItemClick(Sender: TObject);
begin
  Application.HelpCommand(Help_Contents, 0);
end;

procedure TMainForm.HelpSearch_ItemClick(Sender: TObject);
var
 P: PChar;
begin
{ Application.HelpFile := 'c:\delphi\bin\delphi.hlp';}
  P := StrNew('');
  Application.HelpCommand(Help_PartialKey, longint(P));
  StrDispose(P);
end;

procedure TMainForm.FormKeyDown(Sender: TObject; var Key: Word;
  Shift: TShiftState);
begin
  if Key <> vk_Return then begin
    Key := vk_Return;
  end;
end;

{v0.09}
function TMainForm.FMHOpen(var Filename: String): Boolean;
begin
  Result := FileOpen(FileName);
end;

function TMainForm.FMHNew(var Filename: String): Boolean;
{v0.13}
var
  s: string;
  li: TListItem;
{/v0.13}
{v0.32}
  fn: string;
{/v0.32}
begin
  {v0.13}
  if FileNewDialog.ShowModal = mrOK then begin
    s := FileNewDialog.ActivePageBaseName;
    {v0.32}
    li := FileNewDialog.ActiveListViewItem;
    if li <> nil then
      fn := TemplateDir + li.Caption
    else
      fn := '';
    if s = 'Anal' then begin
      CreateSpectrumForm(fn, omCreate);{ulatype}
    end else if s = 'Seq' then begin
      SequenceBrowserOpen(fn, omCreate);
    end;
    {/v0.32
    if s = 'Anal' then begin
      li := FileNewDialog.ActiveListViewItem;
      if li <> nil then
        s := TemplateDir + li.Caption
      else
        s := '';
      CreateSpectrumForm(s, omCreate);
    end;}
    Result := true;
  end else
    Result := false;
  {/v0.13
  Result := true;
  CreateSpectrumForm('', omCreate);}
end;

function TMainForm.FMHSave(var Filename: String): Boolean;
var fn, ext:string;
begin
  Result := false;
  fn := FileName;
  if Screen.ActiveForm is TSpectrumForm then begin
    with Screen.ActiveForm as TSpectrumForm  do begin{winutl}
      ext := GetExtFromFileDialogFilter({v0.14}FMH.{/v0.14}SaveDialog.Filter, FMH.SaveDialog.FilterIndex);
      fn := ReplaceExt(fn, ext, {v0.13}true{/v0.13 false});
      SaveTo(fn);
      Result := true;
    end;
  end;
  FileName := fn;
end;

procedure TMainForm.WMInitMenu(var Msg:TMessage);
begin
  UpdateMenuItems(Self);
  Msg.Result := 0;
end;
{/v0.09}

{v0.10}
procedure TMainForm.OneInstanceInstanceStarted(Sender: TObject;
  params: TStringList);
var
  i: integer;
  fn: string;
begin
  for i := 0 to params.Count - 1 do begin
    fn := params[i];
    FileOpen(fn);
  end;
end;
{/v0.10}

{v0.12}
function TMainForm.FMHBeforeSave(AIsNew: boolean; var AFilename: String): Boolean;
{v0.16}
var i: integer;
{/v0.16}
{v0.50}
var d: string;
{/v0.50}
begin
  Result := false;
  if Screen.ActiveForm is TSpectrumForm then begin
    with Screen.ActiveForm as TSpectrumForm  do begin
      if ActiveAcqData <> nil then begin
        {v0.50}
        d := ExtractFileDir(ActiveAcqData.ULF.FileName);
        if d <> '' then
          FMH.SaveDialog.InitialDir := d;
        {/v0.50}
        if AIsNew then begin
          AFileName := '';
          {v0.16}
          FMH.SaveDialog.FilterIndex := 1;
          {/v0.16}
        end else begin
          AFileName := ActiveAcqData.ULF.FileName;
          {v0.16}
          if not GetDialogFilterIndexFromExt(FMH.SaveDialog.Filter, ExtractFileExt(AFileName), i) then
            i := 1;
          FMH.SaveDialog.FilterIndex := i;
          {/v0.16}
        end;
        Result := true;
      end;
    end;
  end;
end;
{/v0.12}

procedure TMainForm.SaveDialogTypeChange(Sender: TObject);
begin
end;
{uLan Analysis File (*.ULF)|*.ULF|Raw Data (*.DAT)|*.DAT|Raw ASCII (*.TXT)|*.TXT|uLan Analysis ASCII (*.ASC)|*.ASC|uLan Analysis Template File (*.ULT)|*.ULT}
{[ofOverwritePrompt,ofHideReadOnly,ofEnableSizing]}
procedure TMainForm.Channels_ItemClick(Sender: TObject);
begin
  Channels.ULL.Browse;
end;

procedure TMainForm.ChannelsSetDefault_ItemClick(Sender: TObject);
begin
  Channels.ULL.Edit;
end;

procedure TMainForm.SetupOptions_ItemClick(Sender: TObject);
begin
  DevSetupForm.ShowModal;
end;

procedure TMainForm.SetupExpImp_ItemClick(Sender: TObject);
begin
  {v0.18}
  ExpImp.Browse;
  {/v0.18}
end;

{v0.22}
procedure TMainForm.AAPrograms_ItemClick(Sender: TObject);
var p:TAAPrg;
begin
{v0.23}
  p := TAAPrg.Load('');
  p.Obj.Browse;
{/v0.23  ULPrgs.Obj.Browse;}
end;
{/v0.22}

{v0.23}
procedure TMainForm.AARun_ItemClick(Sender: TObject);
begin

end;
{/v0.23}{ulantype}

procedure TMainForm.AAA_ItemClick(Sender: TObject);
begin
  AAAStart;
end;

{v0.24}

{v0.50}
function TMainForm.AAAStart: boolean;
{/v0.50
procedure TMainForm.AAAStart;}
{var a: TAAA;}
var
  namesOK:boolean;

begin
  {v0.50}
  Result := false;
  {/v0.50}

  if AAForm = nil then begin
    {v0.50}
    if Modules.Autodetecting then begin
      Application.MessageBox(
        PChar(GetTxt({#}'Devices are just beeing detected, please wait.')),
        PChar(GetTxt({#}'Information')),
        MB_OK
      );
      exit;
    end;

    if (not CheckAAADevices(false, namesOK)) then begin {language}

      if Application.MessageBox(
        PChar(GetTxt({#}'AAA Devices not found. Try to autodetect them (switch AAA ON first)?')),
        PChar(GetTxt('Error')),
        MB_YESNO) <> IDYES
      then
        exit;

      Modules.ULD.Browse;
      Modules.ScanForModules;
      exit;
    end else begin
      if not namesOK then begin
        if Application.MessageBox(
          PChar(GetTxt('Really setup devices for AAA-400?')),
          PChar(GetTxt('Confirm')),
          MB_YESNO) <> IDYES
        then
          exit;
        CheckAAADevices(true, namesOK);
      end {v0.62} else begin
        CheckAAADevices(true, namesOK);
          {makes sure the AAA-Channel is present (created if was not)}
      end {/v0.62};
    end;
    {/v0.50}
    {$HINTS OFF}
    {a := }
    AAA;
    {$HINTS ON}
    AAForm := TAAForm.Create(Application.MainForm);
  end;
  AAForm.Show;{aafrm ulfobju msgwaitformultipleobjects tthread }
  {v0.50}
  Result := true;
  {/v0.50}
end;
{/v0.24}

procedure TMainForm.LogWindow_ItemClick(Sender: TObject);
begin
  if FormStyle = fsMDIForm then
    LogForm.FormStyle := fsMDIChild;{exelogu}
  LogForm.Show;{semaphore}
end;

procedure TMainForm.ULKeeper_ItemClick(Sender: TObject);
begin
  ULKeeperForm.Show;
end;

{v0.30}
{
procedure TMainForm.WMMdiTile(var Msg: TMessage);
var
  i: integer;
  f: TForm;
begin
  Msg.WParam := MDITILE_SKIPDISABLED;
  for i := 0 to MDIChildCount - 1 do begin
    f := MDIChildren[i];
    if f is TAAForm then disabled
      f.Enabled := false;
  end;
  inherited;
  for i := 0 to MDIChildCount - 1 do begin
    f := MDIChildren[i];
    if f is TAAForm then
      f.Enabled := true;
  end;
end;}
{/v0.30}
{v0.41}
procedure TMainForm.OpenDialogTypeChange(Sender: TObject);
{var ext: string;}
begin
  {winutl}
{  ext := GetExtFromFileDialogFilter(OpenDialog.Filter, OpenDialog.FilterIndex);
  if ext = ULSExt then begin
    OpenDialog.InitialDir := ulanglob .SequenceDir;
  end;}
  {ulobjdes}
end;
{/v0.41}
procedure TMainForm.Programs_ItemClick(Sender: TObject);
begin
  ULPrgs.Browse;
end;

procedure TMainForm.ULRootTree_ItemClick(Sender: TObject);
var
  f: TULObjUsrTreeForm;
begin
  f := TULObjUsrTreeForm.Create(Application);
  {v0.62}
  f.ULObjUsr := ULRootTree;
  {/v0.62
  f.OwnsObjUsr := true;
  f.ULObjUsr := TULObjUsrTree.Create;}
  f.Show;
end;

{v0.47}
procedure TMainForm.Scripts_ItemClick(Sender: TObject);
begin
  {v0.50}
  ULScriptFormShow(Processors.ActiveProcessor);
  {/v0.50
  ULScriptFormShow(nil);}{channelsu}
end;
{/v0.47}

procedure TMainForm.SequencePrograms_ItemClick(Sender: TObject);
var p:TSeqPrg;
begin
  p := TSeqPrg.Load('');
  p.Obj.Browse;
end;

{getlasterror}

procedure TMainForm.EnvVars_ItemClick(Sender: TObject);
begin
  with TFileEditForm.Create(Application) do begin
    Caption := 'Environmental Variables';
    Memo.Lines := EnvVars;
  end;
end;

procedure TMainForm.TestULPath_ItemClick(Sender: TObject);
var
  o: TULObj;
  fo: TULRecFindOptions;
begin
  testString := InputBox('ULObjPath Test', 'Enter ULD.ULD ULObjPath', testString);
  fo := 0;
  if testString <> '' then begin
    if Modules.ULD.FindByULObjPath(testString, fo, o) then begin
      ShowMessage(testString + ' - found ' + TULObj(o.Owner).EfNameField.AsUsrString + '.' +
        o.EfNameField.AsUsrString);{uldrtype}
    end else
      ShowMessage(testString + ' not found.');
  end;
  {ULFObju.Test;}
end;

{v0.50}
const
  testenvs: string = '';
procedure TMainForm.TestReplaceEnvVars_ItemClick(Sender: TObject);
begin
  while InputQuery('Replacing EnvVars', 'Enter string containing EnvVars between "%"', testenvs) do
    ShowMessage(ReplaceEnvVars(testenvs));
end;

procedure TMainForm.Dirs_ItemClick(Sender: TObject);
begin
  OptionsForm.ShowModal;
end;

procedure TMainForm.ULServer_ItemClick(Sender: TObject);
begin
  ULDynAddrServer.RequestToSendID;
end;
{/v0.50}
{v0.55}
procedure TMainForm.ControlWindowItemClick(Sender: TObject);
begin
  ControlWindowShow;
end;
{/v0.55}

procedure TMainForm.FileDialog_ItemClick(Sender: TObject);
var fn: TFileName;
begin
  {v0.61}
  fn := '';
  if FileDialogExecute('', '*.*', fn) then
    ShowMessage('File selected: ' + fn);
  {/v0.61}
end;

{v0.65}
procedure TMainForm.WndProc(var Message: TMessage);
begin
  if Message.Msg = CHROMuLANMessage then begin
    WMCHROMuLANMessage(Message);
    exit;
  end;
  inherited WndProc(Message);
end;

{var
  FCuLGlobalStrings: TCuLGlobalStrings;
  CuLGlobalStrings: PCuLGlobalStrings = @FCuLGlobalStrings;
  CuLGlobalStringIndex: integer = 0;
}

procedure TMainForm.WMCHROMuLANMessage(var Msg: TMessage);


  {procedure wra;
  var
    cid, cmd: string;
    p: PShortString;
    i: integer;
  begin
    p := PShortString(Msg.LParam);
    i := pos(' ', p^);
    if i > 0 then begin
      cid := copy(p^, 1, i - 1);
      cmd := copy(p^, i + 1, length(p^));
      p^ := WebRequestAnswer(cid, cmd);
      Msg.Result := integer(p);
    end else begin
      Msg.Result := 0;
    end;
  end;}
  procedure SaveToBMP;
  var
    i: integer;
    p: PShortString;
    f: TForm;
    sf: TSpectrumForm absolute f;
  begin
    p := PShortString(Msg.LParam);
    for i := 0 to Screen.FormCount - 1 do begin
      f := Screen.Forms[i];
      if f is TSpectrumForm then begin
        if sf.ActiveChannelName = p^ then begin
          p^ := GetTempFileName;   //fileu
          sf.SaveSpectrumToBMP(p^);
          Msg.Result := longint(p);
        end;
      end;
    end;
  end;

  {v0.67}
  function FindSpecForm(AChannelIndex: integer; var AForm: TSpectrumForm): boolean;
  var
    i: integer;
    f: TForm;
    sf: TSpectrumForm absolute f;
  begin
    Result := false;
    for i := 0 to Screen.FormCount - 1 do begin
      f := Screen.Forms[i];
      if f is TSpectrumForm then begin
        if sf.ActiveChannelIndex = AChannelIndex then begin
          AForm := sf;
          Result := true;
        end;
      end;
    end;
  end;

  procedure ChannelUpdate;
  var
    pars: TStringList;
    //i,
    code: integer;
    p: PShortString;
    sf: TSpectrumForm;
    fn: string;
    acqs, chs: string;
    chi, acqi: integer;
  begin
    p := PShortString(Msg.LParam);
    Msg.Result := longint(p);
    sf := nil;
    pars := TStringList.Create;
    try
      { e.g.: p^ = 'channel=0 acq=0' }
      if p^ <> '' then begin
        if not AttrLineToStrings(p^, pars) then begin
          p^ := 'ER invalid command attributes line';
          exit;
        end;
      end;
      chs := pars.Values['channel'];
      acqs := pars.Values['acq'];

      if acqs <> '' then begin
        val(acqs, acqi, code);
        if (code <> 0) or (acqi < acqMin) or (acqi > acqMax) then begin
          p^ := 'ER invalid value of attribute acq: ' + acqs;
          exit;
        end;
      end else
        acqi := 0;

      if chs <> '' then begin
        val(chs, chi, code);
        if (code <> 0) or (chi < 0) or (chi >= Channels.Count) then begin
          p^ := 'ER invalid value of attribute channel: ' + chs;
          exit;
        end;

        if FindSpecForm(chi, sf) then begin
          if acqi = acqStart then begin
            sf.RunButtonClick(nil);
          end else if acqi = acqStop then begin
            sf.StopButtonClick(nil);
          end;
        end else begin
          // no form for wanted channel
          if acqi <> acqStart then begin
            p^ := 'ER the channel is not running: ' + chs;
          end else begin
            fn := TemplateDir + Channels[chi].DefTemplateFileName;
            if not FileExists(fn) then begin
              p^ := 'ER template file not found: ' + fn;
              exit;
            end;
            sf := CreateSpectrumForm(fn, omCreate);{ulatype}
            Application.ProcessMessages;
            sf.RunButtonClick(nil);
          end;
        end;

        if sf <> nil then begin
          Application.ProcessMessages;
          fn := GetTempFileName;
          if sf.SaveSpectrumToBMP(fn) then begin
            p^ := 'OK ' + fn;
          end;
        end;

      end else begin
        p^ := 'OK';
      end;
    finally
      pars.Free;
    end;
  end;

begin
  case Msg.WParam of
    {culWebRequestAnswer: wra;}
    // culUpdateChannelList: up;
    culSaveChannelToBMP: SaveToBMP;
    {v0.67}
    culChannelUpdate: begin
      try
        ChannelUpdate;
      except
      end;
    end;
    {/v0.67}
  end;
end;
{/v0.65}

{v0.67}
procedure TMainForm.TNewCal_ItemClick(Sender: TObject);
//var fn: string;
begin
  CalibrationFormOpen('', omCreate);
  //FileNameOpenSelect(var AFileName: string;
  //const ATitle: string; const AFilter: string; const ADefDir: string): boolean;
end;
{/v0.67}

end.

