ucopy.pas
上传用户:yuandong
上传日期:2022-08-08
资源大小:954k
文件大小:14k
源码类别:

Delphi控件源码

开发平台:

C++ Builder

  1. unit ucopy;
  2. interface
  3. uses
  4.   Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
  5.   StdCtrls, Gauges;
  6.   type EMFheader = record
  7.          Signature: Integer;
  8.          EMFsize: Integer;
  9.        end;
  10.   const EMFheaderSignature = $0C;
  11.   type TForm1 = class(TForm)
  12.       Label1: TLabel;
  13.       Label2: TLabel;
  14.       Gauge: TGauge;
  15.   procedure FormActivate(Sender: TObject);
  16.   procedure FormDestroy(Sender: TObject);
  17.   private
  18.     { Private-Deklarationen }
  19.     nThreadsRunning : Integer;  // not used
  20.     nFileCounter : Integer;     // index for filename
  21.     StringList : TStrings;
  22.     strTempDir : string;        // the <temp> / source directory
  23.   public
  24.     { Public-Deklarationen }
  25.   end;
  26. var
  27.   Form1: TForm1;
  28.   strOSVer : string;     // OS version
  29. const
  30.   PMON_KEY = 'SYSTEMCurrentControlSetControlPrintEnvironmentsWindows NT x86Print Processors';
  31. implementation
  32. Uses
  33.   WinReg;
  34. {$R *.DFM}
  35. type
  36.     TWindowsVersion = (wvUnknown,
  37.                      wvWin95, wvWin95OSR2, wvWin98, wvWin98SE, wvWinME, wvWinNT3, wvWinNT4, wvWin2000, wvWinXP);
  38. //=================================================================================================================
  39. // Win32Platform        1           1           1        1         1        2         2          2           2
  40. // Win32MajorVersion    4           4           4        4         4        3         4          5           5
  41. // Win32MinorVersion    0           0           10       10        90       ?         0          0           1
  42. // Win32BuildNumber     ?        67109975    67766222  67766446  73010104   ?        1381       2195         ?
  43. // Win32CSDVersion      ?          'B'          ''       A         SP       SP        SP         ?           ?
  44. //
  45. // this nice function taken from http://www.delphi-fundgrube.de/faq12.htm (reinhardt@pics-software.de)
  46. //
  47. function GetWindowsVersion(var VerString:string): TWindowsVersion;
  48. var
  49.   osInfo : tosVersionInfo;
  50. begin
  51.   Result := wvUnknown;
  52.   osInfo.dwOSVersionInfoSize:= Sizeof( osInfo );
  53.   GetVersionEx( osInfo );
  54.   with osInfo do begin
  55.     VerString:='Version ' + IntToStr( osInfo.dwMajorVersion ) +
  56.                '.' + IntToStr( osInfo.dwMinorVersion ) + ', Build ';
  57.     case dwPlatformId of
  58.       VER_PLATFORM_WIN32_WINDOWS : begin
  59.         case dwMinorVersion of
  60.           0 : if Trim(szCSDVersion[1]) = 'B' then
  61.                 Result:= wvWin95OSR2
  62.               else
  63.                 Result:= wvWin95;
  64.          10 : if Trim(szCSDVersion[1]) = 'A' then
  65.                 Result:= wvWin98SE
  66.               else
  67.                 Result:= wvWin98;
  68.          90 : if (dwBuildNumber = 73010104) then
  69.                 Result:= wvWinME;
  70.         end;
  71.         VerString:=VerString + IntToStr(LoWord( osInfo.dwBuildNumber ));
  72.       end;
  73.       VER_PLATFORM_WIN32_NT : begin
  74.         case dwMajorVersion of
  75.           3 : Result:= wvWinNT3;
  76.           4 : Result:= wvWinNT4;
  77.           5 : case dwMinorVersion of
  78.                 0 : Result:= wvWin2000;
  79.                 1 : Result:= wvWinXP;
  80.               end;
  81.         end;
  82.         VerString:=VerString + IntToStr(osInfo.dwBuildNumber );
  83.       end;
  84.     end;
  85.   end;
  86. end;
  87. //
  88. // this nice function taken from http://www.delphi-fundgrube.de/faq12.htm (reinhardt@pics-software.de)
  89. //
  90. function GetOSName : string;
  91. var
  92.   osVerInfo : TOSVersionInfo;
  93.   majorVer,
  94.   minorVer  : Integer;
  95. begin
  96.   result := 'Unknown';
  97.   osVerInfo.dwOSVersionInfoSize := Sizeof(TOSVersionInfo);
  98.   if GetVersionEx(osVerInfo) then begin
  99.     majorVer := osVerInfo.dwMajorVersion;
  100.     minorVer := osVerInfo.dwMinorVersion;
  101.     case osVerInfo.dwPlatformId of
  102.       VER_PLATFORM_WIN32_NT : { Windows NT/2000 }
  103.         begin
  104.           if majorVer <= 4 then
  105.             result := 'Windows NT'
  106.           else if (majorVer = 5) and (minorVer= 0) then
  107.             result := 'Windows 2000'
  108.           else if (majorVer = 5) and (minorVer = 1) then
  109.             result := 'Windows XP'
  110.           else
  111.             result := 'Unknown';
  112.         end;
  113.       VER_PLATFORM_WIN32_WINDOWS :  { Windows 9x/ME }
  114.         begin
  115.           if (majorVer = 4) and (minorVer = 0) then
  116.             result := ' Windows 95'
  117.           else if (majorVer = 4) and (minorVer = 10) then begin
  118.             if osVerInfo.szCSDVersion[1] = 'A' then
  119.               result := 'Windows 98SE'
  120.             else
  121.               result := 'Windows 98';
  122.           end
  123.           else if (majorVer = 4) and (minorVer = 90) then
  124.             result := 'Windows ME'
  125.           else
  126.             result := 'Unknown';
  127.         end;
  128.     else
  129.       result := 'Unknown';
  130.     end;
  131.   end else
  132.     result := 'Unknown';
  133. end;
  134. //
  135. // this function by Alex Mokrov (almk@mail.ru)
  136. // detects six emf header bytes
  137. //
  138. function fDetectHeaderBytes(InFileName: String) : string;
  139. var i      : Integer;
  140.     F      : TFileStream; // spl file
  141.     Head   : EMFheader;
  142.     strTmp : string;
  143.     Buf    : array[0..5] of char; // six emf header bytes
  144. begin
  145.   F:= TFileStream.Create(InFileName, 0);
  146.   // Read SPL signature
  147.   F.Read(i, 4);
  148.   if i <> $00010000 then begin
  149.     // bad file -> abort
  150.     MessageBox(0, 'This is not a valid spooler file', 'Error', mb_Ok or mb_DefButton1);
  151.     F.Free;
  152.     Exit;
  153.   end;
  154.   // Read first emf chunk
  155.   F.Read(i, 4);
  156.   F.Position := i;
  157.   F.Read(Head, sizeof(Head));
  158.   if (Head.Signature <> EMFheaderSignature) or (Head.EMFsize = 0) then begin
  159.     // bad file
  160.     MessageBox(0, 'This is not a valid spooler file', 'Error', mb_Ok or mb_DefButton1);
  161.     Buf := '';
  162.   end else
  163.     f.ReadBuffer(Buf, SizeOf(Buf));
  164.   F.Free;
  165.   // Buf contains the six emf header bytes
  166.   for i:=0 to length(Buf) - 1 do
  167.     strTmp := strTmp + Buf[i];
  168.   fDetectHeaderBytes := strTmp;
  169. end;
  170. procedure ReadBinaryDataFile(strFilename : string; strDestDir : string);
  171. // this reads an nt spool file (.spl), extracts the emfs out of
  172. // it and writes *.emf files into strDestDir
  173. var
  174.   fFromF, fToF           : file; // input / output files
  175.   strEMFFileName, strTmp : string;
  176.   nRead, nWritten, i, nReadTotal, nNextFilePos : Integer;
  177.   Buf                    : array[1..2048] of Char; // buffer to read emf data into
  178.   nPixFound, test        : Integer; // # of pictures found
  179.   PosList                : TStringList; // list of emf's positions within spl file
  180.   strHeaderBytes         : string; // six emf header bytes read from fDetectHeaderBytes
  181. begin
  182.   if not FileExists(strFileName) then
  183.     raise Exception.Create('Cannot read ' + strFileName)
  184.   else begin
  185.     strHeaderBytes := fDetectHeaderBytes(strFileName);
  186.     AssignFile(fFromF, strFileName);
  187.   end;
  188.   Reset(fFromF, 1);
  189.   PosList := TStringList.Create;
  190.   nPixFound := 0;
  191.   nReadTotal := 0;
  192.   // check # of emf's in spl-file
  193.   repeat
  194.     // #s of files: nPixFound
  195.     // PosList: Positions of file beginnings in emf
  196.     BlockRead(fFromF, Buf, SizeOf(Buf), nRead);
  197.     test := Pos(strHeaderBytes, Buf);
  198.     if (test > 0) then begin
  199.       Inc(nPixFound);
  200.       if test<>0 then PosList.Add(IntToStr(test + nReadTotal));
  201.     end;
  202.     Inc(nReadTotal, nRead);
  203.   until (nRead = 0) ; // or (nWritten <> nRead);
  204.   // open output
  205.   for i:=1 to nPixFound do begin
  206.     // extract emfs
  207.     strTmp := IntToStr(i);
  208.     while Length(strTmp)< 8 do
  209.       Insert('0', strTmp, 1);
  210.     strEMFFileName := Concat(strDestDir, strTmp,'.EMF');
  211.     AssignFile(fToF, strEMFFileName);
  212.     Rewrite(fToF, 1);
  213.     try
  214.       Seek(fFromf, StrToInt(PosList.Strings[i-1])-1);
  215.       repeat
  216.         BlockRead(fFromF, Buf, SizeOf(Buf), nRead);
  217.         BlockWrite(fToF, Buf, nRead, nWritten);
  218.         if i<nPixFound then
  219.           nNextFilePos := StrToInt(PosList.Strings[i])
  220.         else
  221.           nNextFilePos := FileSize(fFromF);
  222.       until (FilePos(fFromF)>=nNextFilePos);
  223.     except
  224.       on EInOutError do ShowMessage('Read Error');
  225.     end;
  226.     CloseFile(fToF);
  227.   end;
  228.   CloseFile(fFromF);
  229.   PosList.Free;
  230.   // now delete *.spl file
  231.   DeleteFile(strFilename);
  232. end;
  233. //
  234. // preliminary stuff
  235. //
  236. procedure TForm1.FormActivate(Sender: TObject);
  237. var
  238.   reg       : TWinRegistry;
  239.   SearchRes : TSearchRec;// search structure
  240.   nGaugeCounter,         // makes nice gauge
  241.   nFound, i : Integer;   // # of files found (when searching)
  242.   strTemp : string[8];   // filename: <number>.emf
  243.   strCnt : string;       // <full path> + <emf-file>
  244.   strSpoolDir : string;  // spool-directory (NT only)
  245.   strOldFile, strNewFile : string; // filename (NT: spool file)
  246.   m_strTempVar : string; // registry entry holding destination dir for print jobs
  247.   strDestDir : string;   // destination directory for emfs
  248.   strSHDFile : string;   // instruction file
  249.   lpszTempDir : PChar;   // %TEMP% dir (w95 & nt)
  250.   lpszSpoolDir : PChar;  // spool dir (nt only)
  251. begin
  252.   // inits and allocs
  253.   nGaugeCounter := 0;
  254.   nThreadsRunning := 0;
  255.   GetMem(lpszTempDir, 255);
  256.   GetMem(lpszSpoolDir, 255);
  257.   // %temp%-var set?
  258.   if (GetEnvironmentVariable('temp', lpszTempDir, 255) = 0) then begin
  259.     MessageDlg('Environment Variable %temp% not set!' + #13 +
  260.                'Either install driver properly or' + #13 + 'define a %temp% environment variable.', mtError, [mbAbort], 0);
  261.     FreeMem(lpszTempDir);
  262.     Application.Terminate;
  263.   end;
  264.   strTempDir := string(lpszTempDir);
  265.   FreeMem(lpszTempDir);
  266.   // try to get registry settings for destdir
  267.   reg := TWinRegistry.CreateWithKey(HKEY_LOCAL_MACHINE, PMON_KEY);
  268.   m_strTempVar := reg.ReadString('vprproc', 'DestDir', '');
  269.   if (m_strTempVar = '') then
  270.     ShowMessage('vprproc registry settings not yet set!' + #13 + 'Please select destination directory for print jobs' + #13 +
  271.                 'using the Installer Tool!' + #13 + 'I will use your temp directory at' + #13 + strTempDir)
  272.   else
  273.     strTempDir := m_strTempVar;
  274.   if (strTempDir[Length(strTempDir)] <> '') then strTempDir := Concat(strTempDir, '');
  275.   //  ShowMessage(strTempDir);
  276.   reg.free;
  277.   nFileCounter := 1;
  278.   // get OS-Version
  279.   strOSVer := GetOSName;
  280.   if (strOSVer = 'Windows NT') or (strOSVer = 'Windows 2000') or (strOSVer = 'Windows XP') then begin
  281.     // NT or higher detected; locate spool-directory
  282.     GetEnvironmentVariable('windir', lpszSpoolDir, 255);
  283.     strSpoolDir := string(lpszSpoolDir) + 'system32spoolPRINTERS';
  284.     FreeMem(lpszSpoolDir);
  285.   end;
  286.   // delete old *.emf and *.spl files in temp-directory
  287.   nFound := FindFirst(strTempDir + '*.emf', faAnyFile, SearchRes);
  288.   while nFound = 0 do begin
  289.     DeleteFile(PChar(strTempDir + SearchRes.Name));
  290.     nFound := FindNext(SearchRes);
  291.   end;
  292.   FindClose(SearchRes);
  293.   nFound := FindFirst(strTempDir + '*.spl', faAnyFile, SearchRes);
  294.   while nFound = 0 do begin
  295.     DeleteFile(PChar(strTempDir + SearchRes.Name));
  296.     nFound := FindNext(SearchRes);
  297.   end;
  298.   FindClose(SearchRes);
  299.   if (strOSVer = 'Windows 95') or (strOSVer = 'Windows98') or (strOSVer = 'Windows 98SE') or (strOSVer = 'Windows ME') then begin
  300.     // op's for Win 95 and other DOS-based systems
  301.     // get # of files to be copied
  302.     nFound := FindFirst(strTempDir + '~emf*.tmp', faAnyFile, SearchRes);
  303.     while nFound = 0 do begin
  304.       Inc(nGaugeCounter);
  305.       nFound := FindNext(SearchRes);
  306.     end;
  307.     FindClose(SearchRes);
  308.     // copy files
  309.     nFound := FindFirst(strTempDir+ '~emf*.tmp', faAnyFile, SearchRes);
  310.     while nFound = 0 do begin
  311.       Str(nFileCounter:8, strTemp);
  312.       while Pos(' ', strTemp) > 0 do
  313.         strTemp[Pos(' ', strTemp)] := '0';
  314.       strCnt := strTempDir + strTemp + '.EMF';
  315.       CopyFile(PChar(strTempDir + SearchRes.Name), PChar(strCnt), False);
  316.       nFound := FindNext(SearchRes);
  317.       Gauge.AddProgress(Round(100 / nGaugeCounter));
  318.       Inc(nFileCounter);
  319.       strCnt := '';
  320.       strTemp := '';
  321.     end;
  322.     FindClose(SearchRes);
  323.   end else begin
  324.     // op's for Win NT
  325.     // get # of files to be copied
  326.     StringList := TStringList.Create;  // fill stringlist with possible *.spl files
  327.     nFound := FindFirst(strSpoolDir + '*.SPL', faAnyFile, SearchRes);
  328.     while nFound = 0 do begin
  329.       Inc(nGaugeCounter);
  330.       nFound := FindNext(SearchRes);
  331.     end;
  332.     FindClose(SearchRes);
  333.     nFileCounter := 0;
  334.     // copy *.spl file
  335.     nFound := FindFirst(strSpoolDir+ '*.SPL', faAnyFile, SearchRes);
  336.     if nFound = 0 then begin
  337.       {$I-}
  338.       DateSeparator := '-';
  339.       TimeSeparator := '-';
  340.       strDestDir := strTempDir + DateTimeToStr(Now);
  341.       MkDir(strDestDir);
  342.       // MessageDlg('Directory ' + strDestDir, mtInformation, [mbOk], 0);
  343.       if IOResult <> 0 then raise Exception.Create('Cannot create directory ' + strDestDir + ': ' + IntToStr(IOResult))
  344.     end;
  345.     while nFound = 0 do begin
  346.       strOldFile := strSpoolDir + SearchRes.Name;
  347.       strSHDFile := StringReplace(strOldFile, '.SPL', '.SHD', [rfIgnoreCase]);
  348.       strNewFile := strDestDir + '' + SearchRes.Name;
  349.       StringList.Add(strNewFile);
  350.       // MessageDlg('Add to StringList: ' + strNewFile, mtInformation, [mbok], 0);
  351.       // 1st copy .spl file to temp directory
  352.       if not FileExists(strOldFile) then
  353.         raise Exception.Create('Spool File not found: ' + strOldFile)
  354.       else begin
  355.         // MessageDlg('Copy ' + strOldFile + ' => ' + strNewFile, mtInformation, [mbok], 0);
  356.         if not CopyFile(PChar(strOldFile), PChar(strNewFile), False) then raise Exception.Create('Cannot copy ' + strOldFile);
  357.         // then delete original file
  358.         // if not DeleteFile(PChar(strOldFile)) then ShowMessage('Cannot delete ' + strOldFile + '. Please delete it manually!');
  359.       end;
  360.       // if FileExists(strSHDFile) then
  361.       //   if not DeleteFile(PChar(strSHDFile)) then ShowMessage('Cannot delete ' + strSHDFile + '. Please delete it manually!');
  362.       nFound := FindNext(SearchRes);
  363.       Inc(nFileCounter);
  364.       strCnt := '';
  365.       strTemp := '';
  366.     end;
  367.     FindClose(SearchRes);
  368.     // now that the file(s) is / are copied analyse them
  369.     for i:=0 to nFileCounter-1 do begin
  370.       Gauge.AddProgress(Round(100 / nGaugeCounter));
  371.       ReadBinaryDataFile(StringList.Strings[i], strDestDir + '');
  372.     end;
  373.   end;
  374.   // end
  375.   Application.Terminate;
  376. end;
  377. procedure TForm1.FormDestroy(Sender: TObject);
  378. begin
  379.   StringList.Free;
  380. end;
  381. end.