1-1. 기본 화면구성 및 로그 DB 서버를 외부로 노출하지않기 위해서 윈도우즈 서비스로 동작하는 미들웨어를 만들어 보자. DB 서버의 이름은 Simple Middleware - Lazarus를 줄여서 SIMLaz로 한다. 윈도우즈 서비스를 만들기 위해서는 라자루스 "Package" 메뉴에 있는 "Install/Uninstall Package"를 선택하고 "lazdeamon"을 설치해야 한다. "lazdeamon"이 설치되었으면 "File" 메뉴에서 "New"를 선택하고 "Daemon (service) application"을 생성한다. 그러면 "TDaemon" 과 "TDaemonMapper" 폼이 생성 된다. "TDaemon"의 "Name"을 dmnSIMLaz로, 파일명은 "simlaz_dmn.pas"로 저장하고, "TDaemonMapper"의 "Name"을 "dmmSIMLaz"로, 파일명은 "simlaz_dmm.pas"로 저장한다. GUI 프로그램이 아닌 경우 컴파일 시 WSRegister...라고 붙은 수십개의 에러가 발생하는데 그것을 막기위해서 "TDaemonMapper" 소스의 uses에 "Interfaces"를 추가해준다.
    unit simlaz_dmm;

    {$mode objfpc}{$H+}

    interface

    uses
      Interfaces, Classes, SysUtils, DaemonApp;
서비스 관련 정보는 "TDaemonMapper"의 "DaemonDefs" 속성 창을 띄워서 추가한 다음 필요한 정보를 등록한다. "DaemonClassName"에는 "TDaemon"의 "ClassName"인 "TdmnSIMLaz"를, "Name"과 "DisplayName"은 윈도우즈 서비스에 사용할 명칭을 등록한다. "TDaemon"에는 아래와 같이 "TIdTCPServer"와 "TIdSchedulerOfThreadDefault", "TTimer"를 올려놓고 "TIdTCPServer"에 "TIdSchedulerOfThreadDefault"를 연결한 후 각각의 "Name"을 지정한다. "TTimer"는 일정시간마다 요청시간이 초과된 클라이언트를 제거하는데 사용한다. 디자인 시에는 "Enabled"를 "False"로 한 후, 서비스가 시작될 때 Timer를 켜고, 서비스가 내려가면 Timer를 끈다. 각종 오류나 프로그램의 진행상황 등을 잡아내기위해 로그 파일을 생성할 객체를 만든다. 로그 파일은 동시에 여러 클라이언트가 사용할 수 있기때문에 기록시에 "Lock"을 걸어 중복 사용이 안 되게끔 한다.("TCriticalSection")
    // simlaz_log.pas
    unit simlaz_log;

    {$mode objfpc}{$H+}

    interface

    uses
      Classes, SysUtils, syncobjs;

    type

      { TSIMLazLog }

      TSIMLazLog = class
      private
        FFile: TextFile;
        FLock: TCriticalSection;
        FName: string;
        FPath: string;
      public
        constructor Create(AName: string);
        destructor Destroy; override;
        procedure Append(AValue: string);
      end;

    implementation

    { TSIMLazLog }

    constructor TSIMLazLog.Create(AName: string);
    begin
      inherited Create;
      FLock := TCriticalSection.Create;
      FName := AName;
      FPath := ExtractFilePath(ParamStr(0)) + 'log\';
      if not DirectoryExists(FPath) then CreateDir(FPath);
    end;

    destructor TSIMLazLog.Destroy;
    begin
      FLock.Free;
      inherited Destroy;
    end;

    procedure TSIMLazLog.Append(AValue: string);
    var
      l_FileName: string;
    begin
      FLock.Enter;
      try
        l_FileName := FPath + FName + '-' + FormatDateTime('yyyymmdd', Date) + '.log';
        AssignFile(FFile, l_FileName);
        if FileExists(l_FileName) then Append(FFile)
        else Rewrite(FFile);
        WriteLn(FLog, AValue);
      finally
        CloseFile(FFile);
        FLock.Leave;
      end;
    end;

    end.