home *** CD-ROM | disk | FTP | other *** search
/ Softwarová Záchrana 3 / Softwarova-zachrana-3.bin / ArsClip / source.zip / UnitMisc.pas < prev    next >
Pascal/Delphi Source File  |  2003-10-03  |  6KB  |  260 lines

  1. unit UnitMisc;
  2. {
  3.     Purpose:
  4.         "Put all the orphans in one bed"
  5.  
  6.     Updates:
  7.         Handle error case for WindowHandleToEXEName
  8.         Routine to save the debug log
  9.  
  10. }
  11.  
  12. { TODO: Further optimize log usage - possibly to file }
  13. interface
  14.  
  15. uses Windows;
  16.  
  17. procedure MyFree(var o);
  18. function WindowHandleToEXEName(handle : THandle) : string;
  19. function DupHandle(h : Thandle; var sizeh : cardinal; SizeLimit : boolean = false) : Thandle;
  20. procedure AppendLog( s : string; IncludeLastError : boolean = false);
  21. procedure DumpLog(filename : string);
  22. procedure FlushLog;
  23. procedure MyDestroyIcon(h : HICON);
  24. procedure TimerStart;
  25. procedure TimerEndAt(milliseconds : cardinal);
  26.  
  27. function GetCliptypeSymbol( Format: Cardinal ) : string;
  28.  
  29. const EXENAME_ERROR = '[error]';
  30. implementation
  31.  
  32.  
  33. uses Tlhelp32, UnitFrmMainPopup, SysUtils, Classes, Forms,
  34.   UnitFrmClipboardManager;
  35. var AppendCount : cardinal;
  36. var AppendStr : string;
  37. var TimerSnapshot : cardinal;
  38.  
  39.  
  40.  
  41. procedure TimerStart;
  42. begin
  43.     TimerSnapshot := Windows.GetTickCount;
  44. end;
  45.  
  46. procedure TimerEndAt(milliseconds : cardinal);
  47. begin
  48.     while (Windows.GetTickCount - TimerSnapshot) < milliseconds do begin
  49.         // this procedures purposely stalls the program, so ProcessMessages
  50.         // is NOT used here
  51.     end;
  52. end;
  53.  
  54. //
  55. // I want "free" object references to be nil for easy testing
  56. // Notes: The .Free documenation is very misleading, this function
  57. // make it 100% clear
  58. //
  59. // - Free only if not null
  60. // - Make null when freed
  61. //
  62.  
  63. procedure MyFree(var o);
  64. begin
  65.     if (Pointer(o) <> nil) then begin
  66.         TObject(o).free;
  67.         Pointer(o) := nil;
  68.     end;
  69. end;
  70.  
  71.  
  72. procedure MyDestroyIcon(h : HICON);
  73. begin
  74.     if (h <> 0) then begin
  75.         UnitMisc.AppendLog('^DestroyIcon^');
  76.         if not Windows.DestroyIcon(h) then begin
  77.             UnitMisc.AppendLog('Icon not destroyed', true);
  78.         end;
  79.     end;
  80. end;
  81.  
  82.  
  83. //
  84. // Only returns Empty String when the handle is not found,
  85. // not on an error
  86. //
  87. function WindowHandleToEXEName(handle : THandle) : string;
  88. var snap : THandle;
  89.     pe : tagPROCESSENTRY32;
  90.     pid : THandle;
  91.     found : boolean;
  92. begin
  93.     Windows.SetLastError(ERROR_SUCCESS);
  94.  
  95.     result := '';
  96.     if (handle = 0) then begin
  97.         EXIT;
  98.     end;
  99.     snap := TLHelp32.CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
  100.     if (snap = Cardinal(-1)) then begin
  101.         result := EXENAME_ERROR;
  102.         EXIT;
  103.     end;
  104.  
  105.     Windows.GetWindowThreadProcessId(handle, pid);
  106.     pe.dwSize := Sizeof(pe);
  107.     found := TLHelp32.Process32First(snap, pe);
  108.  
  109.     while found do begin
  110.         if (pe.th32ProcessID = pid) then begin
  111.             result := String(pe.szExeFile);
  112.             break;
  113.         end;
  114.  
  115.         found := TLHelp32.Process32Next(snap, pe);
  116.     end;
  117.     CloseHandle(snap);
  118. end;
  119.  
  120.  
  121. function DupHandle(h : Thandle; var sizeh : cardinal; SizeLimit : boolean = false) : Thandle;
  122. var sz : Cardinal;
  123.     newh : Thandle;
  124.     p1, p2 : pointer;
  125.     b : boolean;
  126. begin
  127.     Windows.SetLastError(ERROR_SUCCESS);
  128.  
  129.     result := 0;
  130.     if (h = 0) then begin
  131.         AppendLog('<DupHandle - Empty handle>');
  132.         EXIT;
  133.     end;
  134.     //
  135.     // make sure size is non-zero
  136.     // and not bigger than size restrictions
  137.     //
  138.     sz := Windows.GlobalSize(h);
  139.     if (sz = 0) then begin
  140.         AppendLog('<DupHandle - GlobalSize failed >', true);
  141.         sizeh := 0;
  142.         EXIT;
  143.     end;
  144.  
  145.     // abort if too big
  146.     // make sure to return size of item
  147.     if (SizeLimit) and (sz > sizeh) then begin
  148.         AppendLog('<DupHandle - too big, size limit>');
  149.         sizeh := sz;
  150.         EXIT;
  151.     end else begin
  152.         sizeh := sz;
  153.     end;
  154.  
  155.     //
  156.     // Lock and copy
  157.     //
  158.  
  159.     newh := Windows.GlobalAlloc(GMEM_MOVEABLE or GMEM_ZEROINIT, sizeh);
  160.     if (newh=0) then begin
  161.         AppendLog('<DupHandle - GlobalAlloc failed >', true);
  162.         EXIT;
  163.     end;
  164.     p1 := Windows.GlobalLock(newh);
  165.     if (p1=nil) then begin
  166.         AppendLog('<DupHandle lock1 >', true);
  167.         EXIT;
  168.     end;
  169.  
  170.     p2 := Windows.GlobalLock(h);
  171.     if (p2=nil) then begin
  172.         Windows.GlobalUnlock(newh);
  173.         AppendLog('<DupHandle lock2 >', true);
  174.         EXIT;
  175.     end;
  176.     
  177.     MoveMemory(p1, p2, sizeh);
  178.  
  179.     //
  180.     // This should never occur, maybe hardware failure might cause this
  181.     //
  182.     b := CompareMem(p1, p2, sizeh);
  183.     AppendLog('<DupHandle compare=>' + BoolToStr(b));
  184.     if ( not b) then begin
  185.         Application.ShowException(Exception.Create('DupHandle - Failed to copy memory'));
  186.         Application.Terminate;
  187.     end;
  188.  
  189.  
  190.     Windows.GlobalUnlock(h);
  191.     Windows.GlobalUnlock(newh);
  192.  
  193.     result := newh;
  194. end;
  195.  
  196. procedure AppendLog( s : string; IncludeLastError : boolean = false);
  197. begin
  198.     if (IncludeLastError) then begin
  199.         s := s + ' : ' + SysErrorMessage(GetLastError);
  200.     end;
  201.     if (AppendStr = '') then begin
  202.         AppendStr := TimeToStr(Now) + ': ' + s;
  203.     end else begin
  204.         AppendStr :=  TimeToStr(Now) + ': ' + s +  #13#10 + AppendStr;
  205.     end;
  206.  
  207.  
  208.     AppendCount := (AppendCount + 1) mod 5;
  209.     if (AppendCount = 0) then begin
  210.         FrmMainPopup.AppendLog(AppendStr);
  211.         AppendStr := '';
  212.     end;
  213. end;
  214. procedure FlushLog;
  215. begin
  216.     FrmMainPopup.AppendLog(AppendStr);
  217.     AppendCount := 0;
  218. end;
  219.  
  220.  
  221. procedure DumpLog(filename : string);
  222. begin
  223.     FlushLog;
  224.     filename := IncludeTrailingPathDelimiter(
  225.             ExtractFilePath(Application.ExeName)
  226.         ) + filename;
  227.  
  228.     FrmMainPopup.Memo1.Lines.SaveToFile(filename);
  229. end;
  230.  
  231.  
  232. function GetCliptypeSymbol(Format : Cardinal) : string;
  233. begin
  234.     case Format of
  235.         CF_UNICODETEXT : begin
  236.             result := '[U]';
  237.         end;
  238.         CF_HDROP : begin
  239.             result := '[F]' ;
  240.         end;
  241.         CF_TEXT : begin
  242.             result := '[T]' ;
  243.         end;
  244.         CF_DIB : begin
  245.             result := '[P]' ;
  246.         end;
  247.     end;
  248.     if (Format = frmClipboardManager.CF_RICHTEXT) then begin
  249.         result := '[R]' ;
  250.     end else if (Format = frmClipboardManager.CF_HTML) then begin
  251.         result := '[H]' ;
  252.     end;
  253. end;
  254.  
  255. initialization
  256. begin
  257.     AppendCount := 1;
  258. end;
  259. end.
  260.