PMyBaseDebug

Unit PMyBaseDebug;
{
单元名:PMyBaseDebug
创建者:马敏钊
创建日期:20050407
类:TBaseDebug
功能描述:
   提供基本的Debug方法 和日志显示记录的功能
   本单元自己维护一个全局变量Gob_Debug
20050412
  添加了TBaseDebug 的自动注册热键的能力
  将公开的 方法 InitDebugSystem(ImainForm: TForm)改为私有
  添加了窗体透明的拖动条
  添加了一个方法
  Function AddLogShower(IStrings:TStringList): Variant; Overload;
  将 FShower: TMemo;改为私有
  将 AutoSaveLog: boolean; 改名为 WantAutoSaveLog: boolean; 
}


Interface
Uses Windows,SysUtils,Classes, Controls, Forms,  StdCtrls,ExtCtrls,ComCtrls;
Const
   {分割符号}
  CSplitStr = '==========';
  ClogFileName = 'Log.log';
Type
  TMyInterfaceObject = Class(TObject, IInterface)
  Protected
    Function QueryInterface(Const IID: TGUID; Out Obj): HResult; Stdcall;
    Function _AddRef: Integer; Stdcall;
    Function _Release: Integer; Stdcall;
  Public


  End;
  TDebugLogFile = Class
  Private
    FFileParth: String; //路径
    FText: Text;
    FIsCreateToNew: boolean; //是否是每次启动程序都创建新的记录文件 否则就是当天只会有1个文件
  Public
    {带入日志文件存放的目录位置}
    Constructor Create(Iparth: String);
    Destructor Destroy; Override;
    {写入内容即可自动记录}
    Procedure AddLog(Icon: String);
    Property IsCreateToNew: boolean Read FIsCreateToNew Write FIsCreateToNew;
  End;
  {
   显示接口
  }
  IShower = Interface
    ['{DFDA0AC0-0534-4FD6-A216-E278E93668B3}']
    {
      函数  AddShow
      参数  Icon:string 要显示或者记录的内容
      返回  记录组件Item的当前条数
    }
    Function AddShow(ICon: String): Integer;
  End;


  TEventShowed = Procedure(ILogCon: String) Of Object;
  TDebuglog = Class(TMyInterfaceObject, IShower)
  Private
    FShower: TComponent; //容器
    FClearTager: Word; //显示多少条后清空一下
    FIsAddTime: boolean; //是否在每条显示前加时间
    FAfterShowed: TEventShowed; //显示后触发的事件 可以用来做日志
    FIsNeedSplt: boolean; //是否需要分割字符
    FSplitChar: String; //分割的字符
    FShow: IShower;
    FLog: TDebugLogFile;
  Protected
    Function DoAdd(Icon: String): Integer; Virtual;
    Function AddShow(ICon: String): Integer;
  Published
    Property AfterShowed: TEventShowed Read FAfterShowed Write FAfterShowed;
  Public
    {如果带入记录文件存放路径的话就自动生成记录类}
    Constructor Create(IShower: TComponent; IlogFIleDir: String = '');
    Destructor Destroy; Override;
    Property ClearTager: Word Read FClearTager Write FClearTager;
    Property IsAddTime: boolean Read FIsAddTime Write FIsAddTime;
    Property IsNeedSplitChar: boolean Read FIsNeedSplt Write FIsNeedSplt;
    Property SplitChar: String Read FSplitChar Write FSplitChar;
    Property Shower: IShower Read FShow Write FShow;
  End;


Type
  TBaseDebug = Class
  Private
    FStartTime,
      FEndTime: Cardinal;
    FBugShowForm: TForm;
    FLoger: TDebugLog;
    FTimer:TTimer;
    FtrackBar: TTrackBar;
    FGroupBox:TGroupBox;
    FShower: TMemo;
    Procedure FormKeyDown(Sender: TObject; Var Key: Word;
      Shift: TShiftState);
    Procedure TimerOnTimer(Iobj:TObject);//自动设置快捷键的Timer事件
    {加载热键系统 Alt+Shift+ctrl+o 是打开debug窗体 +p是打开/关闭自动记录功能-1开 0关}
    Procedure InitDebugSystem(ImainForm: TForm);
    Procedure TrackOnTrack(Iobj:TObject);
  Public
    {是否在程序结束的时候自动保存除错信息 默认是False}
    WantAutoSaveLog: boolean;
    {开始记录时间}
    Procedure StartLogTime;
    {停止记录并且返回时间差单位毫秒}
    Function EndLogTIme: Cardinal;
    {弹出变量的值}
    Function ShowVar(Ivar: Variant): Variant;
    {添加到Log容器}
    Function AddLogShower(Ivar: Variant): Variant; Overload;
    Function AddLogShower(IDesc: String; Ivar: Variant): Variant; Overload;
    Function AddLogShower(IStrings:TStringList): Variant; Overload;
    {显示Debug窗体}
    Procedure ShowDebugform;
    {将所有记录的东东保存成日志}
    Procedure SaveLog(IfileName: String = 'LogFile.log');
    Constructor Create;
    Destructor Destroy; Override;
  End;
Var
  Gob_Debug: TBaseDebug;
Implementation


{ TMyInterfacedObject }


Function TMyInterfaceObject._AddRef: Integer;
Begin
  Result := 0;
End;


Function TMyInterfaceObject._Release: Integer;
Begin
  Result := 0;
End;


Function TMyInterfaceObject.QueryInterface(Const IID: TGUID;
  Out Obj): HResult;
Begin
  Result := 0;
End;


{ TDebugLog }


Function TDebugLog.AddShow(ICon: String): Integer;
Begin
  If FIsAddTime Then
    ICon := DateTimeToStr(Now) + ' ' + Icon;
  If FIsNeedSplt Then
    ICon := ICon + #13#10 + FSplitChar;
  Result := DoAdd(ICon);
  If assigned(FLog) Then
    FLog.AddLog(ICon);
  If Assigned(FAfterShowed) Then
    FAfterShowed(ICon);
End;


Constructor TDebugLog.Create(IShower: TComponent; IlogFIleDir: String = '');
Begin
  FClearTager := 1000;
  IsAddTime := True;
  FIsNeedSplt := True;
  FSplitChar := CSplitStr;
  FShower := IShower;
  Shower := Self;
  If IlogFIleDir <> '' Then
    FLog := TDebugLogFile.Create(IlogFIleDir);
End;


Destructor TDebugLog.Destroy;
Begin
  If assigned(FLog) Then
    FLog.Free;
  Inherited;
End;


Function TDebugLog.DoAdd(Icon: String): Integer;
Begin
  If (FShower Is TMemo) Then Begin
    Result := TMemo(FShower).Lines.Add(Icon);
    If Result >= FClearTager Then TMemo(FShower).Clear
  End
  Else If (FShower Is TListBox) Then Begin
    Result := TListBox(FShower).Items.Add(Icon);
    If Result >= FClearTager Then TListBox(FShower).Clear
  End
  Else
    Raise Exception.Create('默认容器错误:' + FShower.ClassName);


End;


{ TDebugLogFile }


Procedure TDebugLogFile.AddLog(Icon: String);
Begin
  Try
    Append(FText);
    Writeln(FText, icon);
  Except
    IOResult;
  End;
End;


Constructor TDebugLogFile.Create(Iparth: String);
Var
  Ltep: String;
Begin
  FIsCreateToNew := True;
  FFileParth := Iparth;
  If Not DirectoryExists(FFileParth) Then
    If Not CreateDir(FFileParth) Then Begin
      Raise Exception.Create('错误的路径,日志类对象不能被创建');
      exit;
    End;
  Ltep := FormatDateTime('yyyymmddhhnnss', Now);
  FileClose(FileCreate(FFileParth + ltep + ClogFileName));
  AssignFile(FText, FFileParth + ltep + ClogFileName);
End;


Destructor TDebugLogFile.Destroy;
Begin
  Try
    CloseFile(FText);
  Except
  End;
  Inherited;
End;


{ TBaseDebug }


Function TBaseDebug.AddLogShower(Ivar: Variant): Variant;
Begin
  Try
    Result := Ivar;
    FLoger.Shower.AddShow(Ivar);
  Except
    On e: Exception Do
      AddLogShower(e.Message);
  End;
End;


Function TBaseDebug.AddLogShower(IDesc: String; Ivar: Variant): Variant;
Var
  Ltep: String;
Begin
  Try
    Ltep := Ivar;
    Result := Ivar;
    FLoger.Shower.AddShow('描述<' + IDesc + '> <值: ' + Ltep + '>');
  Except
    On e: Exception Do
      AddLogShower(e.Message);
  End;
End;


Constructor TBaseDebug.Create;
Begin
  FBugShowForm := TForm.Create(FBugShowForm);
  FBugShowForm.FormStyle := fsStayOnTop;
  FBugShowForm.Caption := 'Debug窗口';
  FBugShowForm.Visible := False;
  FBugShowForm.Position := poScreenCenter;
  FBugShowForm.OnKeyDown := FormKeyDown;
  FBugShowForm.AlphaBlend:=True;
  FBugShowForm.Width:=430;
  FBugShowForm.Height:=300;
  FShower := TMemo.Create(FBugShowForm);
  FShower.Parent := FBugShowForm;
  FShower.Align := alClient;
  FShower.ScrollBars := ssBoth;
  FShower.OnKeyDown := FormKeyDown;
  FLoger := TDebugLog.Create(FShower);
  FLoger.IsNeedSplitChar := False;
  FLoger.ClearTager := 10000;
  FTimer:=TTimer.Create(Nil);
  FTimer.OnTimer:=TimerOnTimer;
  FGroupBox:=TGroupBox.Create(FBugShowForm);
  FGroupBox.Parent:=FBugShowForm;
  FGroupBox.Align:=alBottom;
  FGroupBox.Height:=40;
  FGroupBox.Caption:='透明度';
  FtrackBar:=TTrackBar.Create(nil);
  FtrackBar.Min:=50;
  FtrackBar.Max:=255;
  FtrackBar.Parent:=FGroupBox;
  FtrackBar.Position:=200;
  FtrackBar.Align:=alClient;
  FtrackBar.TickStyle:=tsNone;
  FtrackBar.OnChange:=TrackOnTrack;
  FtrackBar.OnChange(FtrackBar);
  WantAutoSaveLog := True;
  AddLogShower(Format('程序启动...', []));
  AddLogShower(Format('程序标题(%s)', [Application.Title]));
  AddLogShower(Format('程序名(%s)',[Application.ExeName]));
End;


Destructor TBaseDebug.Destroy;
Begin
  AddLogShower(Format('程序结束时间(%s)', [DateTimeToStr(now)]));
  If WantAutoSaveLog Then
    SaveLog();
  FtrackBar.Free;
  FGroupBox.Free;
  FLoger.Free;
  FShower.Free;
  FBugShowForm.Free;
  Inherited;
End;


Function TBaseDebug.EndLogTIme: Cardinal;
Begin
  FEndTime := GetTickCount;
  Result := FEndTime - FStartTime;
End;


Procedure TBaseDebug.FormKeyDown(Sender: TObject; Var Key: Word;
  Shift: TShiftState);
Begin
  If (ssAlt In Shift) Then Begin
    Case Key Of //
      ord('o'), Ord('O'): Begin
          FBugShowForm.Visible := Not FBugShowForm.Visible;
          Application.MainForm.SetFocus;
        End;
      ord('P'), ord('p'): Begin
          WantAutoSaveLog := Not WantAutoSaveLog;
          AddLogShower('当前自动保存的状态改为: ');
          AddLogShower(WantAutoSaveLog)
        End;
    End; // case
  End;
End;


Procedure TBaseDebug.InitDebugSystem(ImainForm: TForm);
Begin
  ImainForm.KeyPreview := True;
  ImainForm.OnKeyDown := FormKeyDown;
End;


procedure TBaseDebug.TimerOnTimer(Iobj:TObject);
begin
  If Application.MainForm<>nil Then Begin
    InitDebugSystem(Application.MainForm);
    TTimer(Iobj).Enabled:=False;
    TTimer(Iobj).Free;
  End;    
end;


Procedure TBaseDebug.SaveLog(IfileName: String);
Begin
  Try
    CreateDir(ExtractFilePath(Application.ExeName) + 'DebugLog\');
    FShower.Lines.SaveToFile(ExtractFilePath(Application.ExeName) + 'DebugLog\' + Format('%s', [FormatDateTime('yyyymmddhhnnss', now) + IfileName]));
  Except
    Raise Exception.Create('保存Debug日志失败');
  End;
End;


Procedure TBaseDebug.ShowDebugform;
Begin
  FBugShowForm.Show;
End;


Function TBaseDebug.ShowVar(Ivar: Variant): Variant;
Var
  S: String;
Begin
  Try
    Result := Ivar;
    s := Ivar;
    MessageBox(0, Pchar(s), 'Debug', 0);
  Except
    On e: Exception Do
      AddLogShower(e.Message);
  End;
End;


Procedure TBaseDebug.StartLogTime;
Begin
  FStartTime := GetTickCount;
End;


procedure TBaseDebug.TrackOnTrack(Iobj: TObject);
begin
  FBugShowForm.AlphaBlendValue:=TTrackBar(Iobj).Position;
end;


function TBaseDebug.AddLogShower(IStrings: TStringList): Variant;
Var
  I: Integer;
begin
  AddLogShower('>>>开始显示StringList');
  For I := 0 To IStrings.Count - 1 Do
    AddLogShower(IStrings.Strings[i]);
  AddLogShower('显示StringList结束<<<'); 
end;


Initialization
  Gob_Debug := TBaseDebug.Create;
Finalization
  Gob_Debug.Free;
End.

 

你可能感兴趣的:(delphi)