Mmdebug.pas
上传用户:hylc_2004
上传日期:2014-01-23
资源大小:46800k
文件大小:15k
源码类别:

Delphi控件源码

开发平台:

Delphi

  1. {========================================================================}
  2. {=                (c) 1995-98 SwiftSoft Ronald Dittrich                 =}
  3. {========================================================================}
  4. {=                          All Rights Reserved                         =}
  5. {========================================================================}
  6. {=  D 01099 Dresden             = Fax.: +49(0)351-8037944               =}
  7. {=  Loewenstr.7a                = info@swiftsoft.de                     =}
  8. {========================================================================}
  9. {=  Actual versions on http://www.swiftsoft.de/index.html               =}
  10. {========================================================================}
  11. {=  This code is for reference purposes only and may not be copied or   =}
  12. {=  distributed in any format electronic or otherwise except one copy   =}
  13. {=  for backup purposes.                                                =}
  14. {=                                                                      =}
  15. {=  No Delphi Component Kit or Component individually or in a collection=}
  16. {=  subclassed or otherwise from the code in this unit, or associated   =}
  17. {=  .pas, .dfm, .dcu, .asm or .obj files may be sold or distributed     =}
  18. {=  without express permission from SwiftSoft.                          =}
  19. {=                                                                      =}
  20. {=  For more licence informations please refer to the associated        =}
  21. {=  HelpFile.                                                           =}
  22. {========================================================================}
  23. {=  $Date: 11.10.98 - 19:25:53 $                                        =}
  24. {========================================================================}
  25. unit MMDebug;
  26. {$D-,L-}
  27. interface
  28. uses
  29. {$IFDEF WIN32}
  30.   Windows,
  31. {$ELSE}
  32.   WinTypes,
  33.   WinProcs,
  34. {$ENDIF}
  35.   MMUtils,
  36.   Messages,
  37.   SysUtils,
  38.   Classes;
  39. function  DB_Open: Boolean;             { open the debug terminal     }
  40. procedure DB_Clear;                     { clear the debug terminal    }
  41. procedure DB_Close;                     { close the debug terminal    }
  42. procedure DB_Level(Level: integer);     { set the general debug level }
  43. procedure DB_Enable(Enable: Boolean);   { enable the debug output     }
  44. procedure DB_Numerate(Enable: Boolean); { numerate messages or not    }
  45. procedure DB_Flush;                     { flushes all pending messages}
  46. { assertion: raise a exception and display string if condition False }
  47. procedure DB_Assert(Condition: Boolean; const S: String);
  48. { some debug output functions }
  49. procedure DB_Format(Level: integer; const Format: String; const Args: array of const);
  50. procedure DB_FormatLn(Level: integer; const Format: string; const Args: array of const);
  51. procedure DB_WriteBool(Level: integer; B: Boolean);
  52. procedure DB_WriteBoolLn(Level: integer; B: Boolean);
  53. procedure DB_WriteChar(Level: integer; C: Char);
  54. procedure DB_WriteCharLn(Level: integer; C: Char);
  55. procedure DB_WriteHexByte(Level: integer; B: Byte);
  56. procedure DB_WriteHexByteLn(Level: integer; B: Byte);
  57. procedure DB_WriteHex(Level: integer; L: LongInt);
  58. procedure DB_WriteHexLn(Level: integer; L: LongInt);
  59. procedure DB_WriteHexBuffer(Level: integer; const Buffer; BufLen: Cardinal);
  60. procedure DB_WriteHexBufferLn(Level: integer; const Buffer; BufLen: Cardinal);
  61. procedure DB_WriteInt(Level: integer; I: DWORD);
  62. procedure DB_WriteIntLn(Level: integer; I: DWORD);
  63. procedure DB_WriteInt64(Level: integer; I: int64);
  64. procedure DB_WriteInt64Ln(Level: integer; I: int64);
  65. procedure DB_WriteLn;
  66. procedure DB_WritePChar(Level: integer; Buf: PChar);
  67. procedure DB_WritePCharLn(Level: integer; Buf: PChar);
  68. procedure DB_WritePtr(Level: integer; P: Pointer);
  69. procedure DB_WritePtrLn(Level: integer; P: Pointer);
  70. procedure DB_WriteFloat(Level: integer; E: Extended);
  71. procedure DB_WriteFloatLn(Level: integer; E: Extended);
  72. procedure DB_WriteStr(Level: integer; const Str: String);
  73. procedure DB_WriteStrLn(Level: integer; const Str: String);
  74. {$IFDEF WIN32}
  75. procedure DB_WriteVar(Level: integer; V: Variant);
  76. procedure DB_WriteVarLn(Level: integer; V: Variant);
  77. {$ENDIF}
  78. implementation
  79. var
  80.    MM_CLOSE    : integer;
  81.    MM_LOGGIT   : integer;
  82.    MM_Clear    : integer;
  83.    DBEnabled   : Boolean;
  84.    DBLevel     : integer;
  85.    DBNumerate  : Boolean;
  86.    MsgNumber   : Longint;
  87.    MsgList     : TStringList;
  88.    NonLFMsg    : string;
  89. {------------------------------------------------------------------------}
  90. procedure LoggitEx(s: String; LF: Boolean);
  91. var
  92.    Buf: array[0..255] of Char;
  93.    aAtom: TAtom;
  94.    Wnd: HWND;
  95. begin
  96.    if DBEnabled then
  97.    begin
  98.       Wnd := FindWindow('TDebugForm',nil);
  99.       if (Wnd <> 0) then
  100.       begin
  101.          if DBNumerate and (s <> ' ') then
  102.          begin
  103.             s := IntToStr(MsgNumber)+': '+s;
  104.             inc(MsgNumber);
  105.          end;
  106.          if LF then s := s+#13#10;
  107.          aAtom := GlobalAddAtom(StrPLCopy(Buf,s,sizeOf(Buf)-1));
  108.          SendMessage(Wnd, MM_LOGGIT, aAtom, 0);
  109.          GlobalDeleteAtom(aAtom);
  110.       end;
  111.    end;
  112. end;
  113. {------------------------------------------------------------------------}
  114. procedure Loggit(Level: integer; s: String; LF: Boolean);
  115. begin
  116.    if DBEnabled and (Level <= DBLevel) or (DBLevel = -1) then
  117.    begin
  118.       if (DBLevel = -1) then
  119.       begin
  120.          if LF then
  121.          begin
  122.             MsgList.Add(NonLFMsg+s);
  123.             NonLFMsg := '';
  124.          end
  125.          else NonLFMsg := NonLFMsg+s;
  126.       end
  127.       else LoggitEx(s,LF);
  128.    end;
  129. end;
  130. {------------------------------------------------------------------------}
  131. function DB_Open: Boolean;
  132. var
  133.    {$IFDEF WIN32}
  134.    StartupInfo: TStartupInfo;
  135.    ProcessInfo: TProcessInformation;
  136.    {$ELSE}
  137.    hAppInstance: THandle;
  138.    {$ENDIF}
  139. begin
  140.    {$IFNDEF WIN32}
  141.    Result := (WinExec('MMDEBUG.EXE', SW_NORMAL) >= HINSTANCE_ERROR);
  142.    {$ELSE}
  143.    FillChar(StartupInfo, SizeOf(TStartupInfo), 0);
  144.    with StartupInfo do
  145.    begin
  146.       cb := SizeOf(TStartupInfo);
  147.       dwFlags := STARTF_USESHOWWINDOW;
  148.       wShowWindow := SW_NORMAL;
  149.    end;
  150.    Result := CreateProcess(nil,'MMDEBUG.EXE',nil,nil,False,NORMAL_PRIORITY_CLASS,
  151.                            nil,nil,StartupInfo,ProcessInfo);
  152.    {$ENDIF}
  153. end;
  154. {------------------------------------------------------------------------}
  155. procedure DB_CLose;
  156. var
  157.    Wnd: HWND;
  158. begin
  159.    Wnd := FindWindow('TDebugForm',nil);
  160.    if (Wnd <> 0) then
  161.       SendMessage(Wnd, MM_CLOSE, 0, 0);
  162. end;
  163. {------------------------------------------------------------------------}
  164. procedure DB_Clear;
  165. var
  166.    Wnd: HWND;
  167. begin
  168.    Wnd := FindWindow('TDebugForm',nil);
  169.    if (Wnd <> 0) then
  170.       SendMessage(Wnd, MM_CLEAR, 0, 0);
  171.    MsgNumber := 0;
  172. end;
  173. {------------------------------------------------------------------------}
  174. procedure DB_Enable(Enable: Boolean);
  175. begin
  176.    DBEnabled := Enable;
  177. end;
  178. {------------------------------------------------------------------------}
  179. procedure DB_Level(Level: integer);
  180. begin
  181.    if (Level < 0) then DBLevel := -1
  182.    else DBLevel := Level;
  183. end;
  184. {------------------------------------------------------------------------}
  185. procedure DB_Numerate(Enable: Boolean);
  186. begin
  187.    DBNumerate := Enable;
  188. end;
  189. {------------------------------------------------------------------------}
  190. procedure DB_Flush;
  191. var
  192.    i: integer;
  193. begin
  194.    for i := 0 to MsgList.Count-1 do
  195.    begin
  196.       LoggitEx(MsgList[i],True);
  197.    end;
  198.    MsgList.Clear;
  199.    if (NonLFMsg <> '') then
  200.    begin
  201.       LoggitEx(NonLFMsg,True);
  202.       NonLFMsg := '';
  203.    end;
  204. end;
  205. {$IFNDEF WIN32}
  206. function ConvertAddr(Address: Pointer): Pointer; assembler;
  207. { Convert physical address to logical address }
  208. asm
  209.         MOV     AX,Address.Word[0]
  210.         MOV     DX,Address.Word[2]
  211.         MOV     CX,DX                   { Don't convert 0000:0000 }
  212.         OR      CX,AX
  213.         JE      @@1
  214.         CMP     DX,0FFFFH               { Don't convert FFFF:xxxx }
  215.         JE      @@1
  216.         MOV     ES,DX
  217.         MOV     DX,ES:Word[0]
  218. @@1:
  219. end;
  220. {$ENDIF}
  221. {------------------------------------------------------------------------}
  222. procedure DB_Assert(Condition: Boolean; const S: String);
  223. var
  224.    Address: Pointer;
  225. begin
  226.    if not Condition then
  227.    begin
  228.       asm
  229.          {$IFDEF WIN32}
  230.          mov   eax, [ebp+04]
  231.          dec   eax
  232.          mov   [Address], eax
  233.          {$ELSE}
  234.          mov   ax, [bp+02]
  235.          mov   word ptr [Address], ax
  236.          mov   ax, [bp+04]
  237.          mov   word ptr [Address+2], ax
  238.          {$ENDIF}
  239.       end;
  240.       {$IFNDEF WIN32}
  241.       Address := ConvertAddr(Address);
  242.       {$ENDIF}
  243.       raise Exception.CreateFmt('Assertion at address $%p'#10#13'%s', [Address,S]);
  244.    end;
  245. end;
  246. {------------------------------------------------------------------------}
  247. procedure DB_Format(Level: integer; const Format: String; const Args: array of const);
  248. begin
  249.    Loggit(Level,Sysutils.Format(Format,Args),False);
  250. end;
  251. {------------------------------------------------------------------------}
  252. procedure DB_FormatLn(Level: integer; const Format: string; const Args: array of const);
  253. begin
  254.    Loggit(Level,Sysutils.Format(Format,Args),True);
  255. end;
  256. {------------------------------------------------------------------------}
  257. procedure DB_WriteBool(Level: integer; B: Boolean);
  258. begin
  259.    if B then
  260.       Loggit(Level,'True',False)
  261.    else
  262.       Loggit(Level,'False',False);
  263. end;
  264. {------------------------------------------------------------------------}
  265. procedure DB_WriteBoolLn(Level: integer; B: Boolean);
  266. begin
  267.    if B then
  268.       Loggit(Level,'True',True)
  269.    else
  270.       Loggit(Level,'False',True);
  271. end;
  272. {------------------------------------------------------------------------}
  273. procedure DB_WriteChar(Level: integer; C: Char);
  274. begin
  275.    Loggit(Level,C,False);
  276. end;
  277. {------------------------------------------------------------------------}
  278. procedure DB_WriteCharLn(Level: integer; C: Char);
  279. begin
  280.    Loggit(Level,C,True);
  281. end;
  282. {------------------------------------------------------------------------}
  283. procedure DB_WriteHexByte(Level: integer; B: Byte);
  284. begin
  285.    Loggit(Level,Format('%.2x',[B]),False);
  286. end;
  287. {------------------------------------------------------------------------}
  288. procedure DB_WriteHexByteLn(Level: integer; B: Byte);
  289. begin
  290.    Loggit(Level,Format('%.2x',[B]),True);
  291. end;
  292. {------------------------------------------------------------------------}
  293. procedure DB_WriteHex(Level: integer; L: LongInt);
  294. begin
  295.    Loggit(Level,Format('%.8x',[L]),False);
  296. end;
  297. {------------------------------------------------------------------------}
  298. procedure DB_WriteHexLn(Level: integer; L: LongInt);
  299. begin
  300.    Loggit(Level,Format('%.8x',[L]),True);
  301. end;
  302. {------------------------------------------------------------------------}
  303. procedure DB_WriteHexBuffer(Level: integer; const Buffer; BufLen: Cardinal);
  304. var
  305.    s: String;
  306.    i: integer;
  307. begin
  308.    s := '';
  309.    for i := 0 to BufLen-1 do s := s+Format('%.2x',[PByte(PChar(@Buffer)+i)^]);
  310.    Loggit(Level,s,False);
  311. end;
  312. {------------------------------------------------------------------------}
  313. procedure DB_WriteHexBufferLn(Level: integer; const Buffer; BufLen: Cardinal);
  314. var
  315.    s: String;
  316.    i: integer;
  317. begin
  318.    s := '';
  319.    for i := 0 to BufLen-1 do s := s+Format('%.2x',[PByte(PChar(@Buffer)+i)^]);
  320.    Loggit(Level,s,True);
  321. end;
  322. {------------------------------------------------------------------------}
  323. procedure DB_WriteInt(Level: integer; I: DWORD);
  324. begin
  325.    Loggit(Level,IntToStr(I),False);
  326. end;
  327. {------------------------------------------------------------------------}
  328. procedure DB_WriteIntLn(Level: integer; I: DWORD);
  329. begin
  330.    Loggit(Level,IntToStr(I),True);
  331. end;
  332. {------------------------------------------------------------------------}
  333. procedure DB_WriteInt64(Level: integer; I: int64);
  334. begin
  335.    Loggit(Level,Format('%g',[I]),False);
  336. end;
  337. {------------------------------------------------------------------------}
  338. procedure DB_WriteInt64Ln(Level: integer; I: int64);
  339. begin
  340.    Loggit(Level,Format('%g',[I]),True);
  341. end;
  342. {------------------------------------------------------------------------}
  343. procedure DB_WriteLn;
  344. begin
  345.    Loggit(0,'',True);
  346. end;
  347. {------------------------------------------------------------------------}
  348. procedure DB_WritePChar(Level: integer; Buf: PChar);
  349. begin
  350.    Loggit(Level,StrPas(Buf),False);
  351. end;
  352. {------------------------------------------------------------------------}
  353. procedure DB_WritePCharLn(Level: integer; Buf: PChar);
  354. begin
  355.    Loggit(Level,StrPas(Buf),True);
  356. end;
  357. {------------------------------------------------------------------------}
  358. procedure DB_WritePtr(Level: integer; P: Pointer);
  359. begin
  360.    Loggit(Level,Format('%p',[P]),False);
  361. end;
  362. {------------------------------------------------------------------------}
  363. procedure DB_WritePtrLn(Level: integer; P: Pointer);
  364. begin
  365.    Loggit(Level,Format('%p',[P]),True);
  366. end;
  367. {------------------------------------------------------------------------}
  368. procedure DB_WriteFloat(Level: integer; E: Extended);
  369. begin
  370.    Loggit(Level,Format('%g',[E]),False);
  371. end;
  372. {------------------------------------------------------------------------}
  373. procedure DB_WriteFloatLn(Level: integer; E: Extended);
  374. begin
  375.    Loggit(Level,Format('%g',[E]),True);
  376. end;
  377. {------------------------------------------------------------------------}
  378. procedure DB_WriteStr(Level: integer; const Str: String);
  379. begin
  380.    Loggit(Level,Str,False);
  381. end;
  382. {------------------------------------------------------------------------}
  383. procedure DB_WriteStrLn(Level: integer; const Str: String);
  384. begin
  385.    Loggit(Level,Str,True);
  386. end;
  387. {$IFDEF WIN32}
  388. {------------------------------------------------------------------------}
  389. procedure DB_WriteVar(Level: integer; V: Variant);
  390. var
  391.    vTyp: integer;
  392. begin
  393.    vTyp := VarType(V);
  394.    if (vTyp = varBoolean) then
  395.       DB_WriteBool(Level,VarAsType(V, varBoolean))
  396.    else
  397.       Loggit(Level,VarAsType(V, varString),False);
  398. end;
  399. procedure DB_WriteVarLn(Level: integer; V: Variant);
  400. var
  401.    vTyp: integer;
  402. begin
  403.    vTyp := VarType(V);
  404.    if vTyp = varBoolean then
  405.       DB_WriteBoolLn(Level,VarAsType(V, varBoolean))
  406.    else
  407.       Loggit(Level,VarAsType(V, varString),True);
  408. end;
  409. {$ENDIF}
  410. {------------------------------------------------------------------------}
  411. initialization
  412.   MM_CLOSE  := RegisterWindowMessage('MM_CLOSE');
  413.   MM_LOGGIT := RegisterWindowMessage('MM_LOGGIT');
  414.   MM_CLEAR  := RegisterWindowMessage('MM_CLEAR');
  415.   DBEnabled := True;
  416.   DBLevel   := 0;
  417.   DBNumerate:= False;
  418.   MsgNumber := 0;
  419.   MsgList   := TStringList.Create;
  420.   NonLFMsg  := '';
  421. {$IFDEF WIN32}
  422. finalization
  423.   MsgList.Free;
  424. {$ENDIF}
  425. end.