Subversion Repositories fastphp

Rev

Rev 75 | Blame | Compare with Previous | Last modification | View Log | RSS feed

  1. unit Functions;
  2.  
  3. interface
  4.  
  5. uses
  6.   Windows, Messages, SysUtils, StrUtils, IniFiles, Classes, Forms, Variants, MsHTML,
  7.   StdCtrls, SynEdit, ActiveX;
  8.  
  9. type
  10.   TContentCallBack = procedure(Content: string) of object;
  11.  
  12. function GetDosOutput(CommandLine: string; Work: string = ''; ContentCallBack: TContentCallBack=nil): String;
  13. function StrIPos(const SubStr, S: string): Integer;
  14. function LoadFileToStr(const FileName: TFileName): AnsiString;
  15. function LastPos(const SubStr, S: string): integer;
  16. function IsTextHTML(s: string): boolean;
  17. function GetWordUnderPos(AMemo: TSynEdit; Line, Column: integer): string;
  18. function GetWordUnderCaret(AMemo: TSynEdit): string;
  19. function MyVarToStr(v: Variant): string;
  20. function FileSystemCaseSensitive: boolean;
  21. function HighColorWindows: boolean;
  22. function GetTempDir: string;
  23. function GetSpecialFolder(const aCSIDL: Integer): string;
  24. function GetMyDocumentsFolder: string;
  25. function MD5(const str: string): string;
  26. function MD5Stream(const s: TStream): string;
  27.  
  28. implementation
  29.  
  30. uses
  31.   ShlObj, // Needed for the CSIDL constants
  32.   IdGlobal, IdHash, IdHashMessageDigest; // used for MD5 calculation
  33.  
  34. function GetDosOutput(CommandLine: string; Work: string = ''; ContentCallBack: TContentCallBack=nil): String;
  35. var
  36.   SA: TSecurityAttributes;
  37.   SI: TStartupInfo;
  38.   PI: TProcessInformation;
  39.   StdOutPipeRead, StdOutPipeWrite: THandle;
  40.   WasOK: Boolean;
  41.   Buffer: array[0..255] of AnsiChar;
  42.   BytesRead: Cardinal;
  43.   WorkDir: string;
  44.   Handle: Boolean;
  45. begin
  46.   if Work = '' then Work := ExtractFilePath(ParamStr(0));
  47.  
  48.   Result := '';
  49.   with SA do begin
  50.     nLength := SizeOf(SA);
  51.     bInheritHandle := True;
  52.     lpSecurityDescriptor := nil;
  53.   end;
  54.   CreatePipe(StdOutPipeRead, StdOutPipeWrite, @SA, 0);
  55.   try
  56.     with SI do
  57.     begin
  58.       FillChar(SI, SizeOf(SI), 0);
  59.       cb := SizeOf(SI);
  60.       dwFlags := STARTF_USESHOWWINDOW or STARTF_USESTDHANDLES;
  61.       wShowWindow := SW_HIDE;
  62.       hStdInput := GetStdHandle(STD_INPUT_HANDLE); // don't redirect stdin
  63.       hStdOutput := StdOutPipeWrite;
  64.       hStdError := StdOutPipeWrite;
  65.     end;
  66.     WorkDir := Work;
  67.     Handle := CreateProcess(nil, PChar('cmd.exe /C "' + CommandLine + '"'),
  68.                             nil, nil, True, 0, nil,
  69.                             PChar(WorkDir), SI, PI);
  70.     CloseHandle(StdOutPipeWrite);
  71.     if Handle then
  72.       try
  73.         repeat
  74.           WasOK := ReadFile(StdOutPipeRead, Buffer, 255, BytesRead, nil);
  75.           if BytesRead > 0 then
  76.           begin
  77.             Buffer[BytesRead] := #0;
  78.             Result := Result + string(Buffer);
  79.             if Assigned(ContentCallBack) then ContentCallBack(string(Buffer));
  80.           end;
  81.         until not WasOK or (BytesRead = 0);
  82.         WaitForSingleObject(PI.hProcess, INFINITE);
  83.       finally
  84.         CloseHandle(PI.hThread);
  85.         CloseHandle(PI.hProcess);
  86.       end;
  87.   finally
  88.     CloseHandle(StdOutPipeRead);
  89.   end;
  90. end;
  91.  
  92. function StrIPos(const SubStr, S: string): Integer;
  93. begin
  94.   Result := Pos(UpperCase(SubStr), UpperCase(S));
  95. end;
  96.  
  97. function LoadFileToStr(const FileName: TFileName): AnsiString;
  98. var
  99.   FileStream : TFileStream;
  100.  
  101. begin
  102.   Result := '';
  103.   FileStream := TFileStream.Create(FileName, fmOpenRead or fmShareDenyWrite);
  104.   try
  105.     if FileStream.Size>0 then begin
  106.       SetLength(Result, FileStream.Size);
  107.       FileStream.Read(Result[1], FileStream.Size);
  108.     end;
  109.   finally
  110.     FileStream.Free;
  111.   end;
  112. end;
  113.  
  114. function LastPos(const SubStr, S: string): integer;
  115. var
  116.   I, J, K: integer;
  117. begin
  118.   Result := 0;
  119.   I := Length(S);
  120.   K := Length(SubStr);
  121.   if (K = 0) or (K > I) then
  122.     Exit;
  123.   while (Result = 0) and (I >= K) do
  124.   begin
  125.     J := K;
  126.     if S[I] = SubStr[J] then
  127.     begin
  128.       while (J > 1) and (S[I + J - K - 1] = SubStr[J - 1]) do
  129.         Dec(J);
  130.       if J = 1 then
  131.         Result := I - K + 1;
  132.     end;
  133.     Dec(I);
  134.   end;
  135. end;
  136.  
  137. function IsTextHTML(s: string): boolean;
  138.  
  139.   function _Tag(const tag: string): integer;
  140.   begin
  141.     result := 0;
  142.     if (StrIPos('<'+tag+'>', s) > 0) then Inc(result);
  143.     if (StrIPos('</'+tag+'>', s) > 0) then Inc(result);
  144.     if (StrIPos('<'+tag+' />', s) > 0) then Inc(result);
  145.     if (StrIPos('<'+tag+' ', s) > 0) then Inc(result);
  146.   end;
  147.  
  148.   procedure _Check(const tag: string; pair: boolean);
  149.   begin
  150.     if (pair and (_Tag(tag) >= 2)) or (not pair and (_Tag(tag) >= 1)) then result := true;
  151.   end;
  152.  
  153. begin
  154.   result := false;
  155.   _Check('html', true);
  156.   _Check('body', true);
  157.   _Check('p', false{end tag optional});
  158.   _Check('a', true);
  159.   _Check('b', true);
  160.   _Check('i', true);
  161.   _Check('u', true);
  162.   _Check('li', false{end tag optional});
  163.   _Check('ol', true);
  164.   _Check('ul', true);
  165.   _Check('img', false);
  166.   _Check('div', false);
  167.   _Check('hr', false);
  168.   _Check('code', true);
  169.   _Check('pre', true);
  170.   _Check('blockquote', true);
  171.   _Check('span', true);
  172.   _Check('br', false);
  173. end;
  174.  
  175. // Template: http://stackoverflow.com/questions/6339446/delphi-get-the-whole-word-where-the-caret-is-in-a-memo
  176. function GetWordUnderPos(AMemo: TSynEdit; Line, Column: integer): string;
  177.  
  178.   function ValidChar(c: char): boolean;
  179.   begin
  180.     {$IFDEF UNICODE}
  181.     result := CharInSet(c, ['a'..'z', 'A'..'Z', '0'..'9', '_']);
  182.     {$ELSE}
  183.     result := c in ['a'..'z', 'A'..'Z', '0'..'9', '_'];
  184.     {$ENDIF}
  185.   end;
  186.  
  187. var
  188.    LineText: string;
  189.    InitPos : Integer;
  190.    EndPos  : Integer;
  191. begin
  192.    //Validate the line number
  193.    if AMemo.Lines.Count-1 < Line then Exit;
  194.  
  195.    //Get the text of the line
  196.    LineText := AMemo.Lines[Line];
  197.  
  198.    if LineText = '' then
  199.    begin
  200.      result := '';
  201.      exit;
  202.    end;
  203.  
  204.    // Column zeigt auf das Zeichen LINKS vom Cursor!
  205.  
  206.    InitPos := Column;
  207.    if not ValidChar(LineText[InitPos]) then Inc(InitPos);
  208.    while (InitPos-1 >= 1) and ValidChar(LineText[InitPos-1]) do Dec(InitPos);
  209.  
  210.    EndPos := Column;
  211.    while (EndPos+1 <= Length(LineText)) and ValidChar(LineText[EndPos+1]) do Inc(EndPos);
  212.  
  213.    //Get the text
  214.    Result := Copy(LineText, InitPos, EndPos - InitPos + 1);
  215. end;
  216.  
  217. function GetWordUnderCaret(AMemo: TSynEdit): string;
  218. var
  219.    Line    : Integer;
  220.    Column  : Integer;
  221. begin
  222.    //Get the caret position
  223.    (*
  224.    if AMemo is TMemo then
  225.    begin
  226.      Line   := AMemo.Perform(EM_LINEFROMCHAR,AMemo.SelStart, 0);
  227.      Column := AMemo.SelStart - AMemo.Perform(EM_LINEINDEX, Line, 0);
  228.    end;
  229.    if AMemo is TSynEdit then
  230.    begin
  231.    *)
  232.      Line := AMemo.CaretY-1;
  233.      Column := AMemo.CaretX-1;
  234.    (*
  235.    end;
  236.    *)
  237.  
  238.    result := GetWordUnderPos(AMemo, Line, Column);
  239. end;
  240.  
  241. function MyVarToStr(v: Variant): string;
  242. var
  243.   _Lo, _Hi, i: integer;
  244. begin
  245.   if VarIsNull(v) then
  246.   begin
  247.     result := '';
  248.   end
  249.   else if VarIsArray(v) then
  250.   begin
  251.     _Lo := VarArrayLowBound(v, 1);
  252.     _Hi := VarArrayHighBound(v, 1);
  253.     result := '';
  254.     for i := _Lo to _Hi do
  255.     begin
  256.       if v[i] = 0 then break;
  257.       result := result + chr(integer(v[i]));
  258.     end;
  259.   end
  260.   else
  261.   begin
  262.     // At least try it...
  263.     result := VarToStr(v);
  264.   end;
  265. end;
  266.  
  267. function FileSystemCaseSensitive: boolean;
  268. begin
  269.   // TODO: This code is not very reliable. At MAC OSX, the file system HFS can be switched
  270.   //       between case sensitivity and insensitivity.
  271.   {$IFDEF LINUX}
  272.   exit(true);
  273.   {$ELSE}
  274.   result := false;
  275.   exit;
  276.   {$ENDIF}
  277. end;
  278.  
  279. function HighColorWindows: boolean;
  280. var
  281.   ver: Cardinal;
  282.   dwMajorVersion, dwMinorVersion: integer;
  283. begin
  284.   ver := GetVersion();
  285.   dwMajorVersion := Lo(ver);
  286.   dwMinorVersion := Hi(ver);
  287.  
  288.   // Gradient fitting in:
  289.   // 5.1 = XP
  290.   // 5.2 = Windows Server 2003
  291.   // 6.0 = Vista
  292.   // 6.1 = Win7
  293.  
  294.   result := ((dwMajorVersion = 5) and (dwMinorVersion >= 1)) or
  295.             ((dwMajorVersion = 6) and (dwMinorVersion <= 1));
  296. end;
  297.  
  298. function GetTempDir: string;
  299. var
  300.   Dir: string;
  301.   Len: DWord;
  302. begin
  303.   SetLength(Dir,MAX_PATH);
  304.   Len:=GetTempPath(MAX_PATH, PChar(Dir));
  305.   if Len>0 then
  306.   begin
  307.     SetLength(Dir,Len);
  308.     Result:=Dir;
  309.   end
  310.   else
  311.     RaiseLastOSError;
  312. end;
  313.  
  314. function SHGetFolderPath(hwnd: HWND; csidl: Integer; hToken: THandle;
  315.   dwFlags: DWord; pszPath: LPWSTR): HRESULT; stdcall;
  316.   external 'SHFolder.dll' name 'SHGetFolderPathW';
  317.  
  318. function GetSpecialFolder(const aCSIDL: Integer): string;
  319. var
  320.   FolderPath: array[0 .. MAX_PATH] of Char;
  321. begin
  322.   SetLastError(ERROR_SUCCESS);
  323.   if SHGetFolderPath(0, aCSIDL, 0, 0, @FolderPath) = S_OK then
  324.     Result := FolderPath;
  325. end;
  326.  
  327. function GetMyDocumentsFolder: string;
  328. begin
  329.   Result := GetSpecialFolder(CSIDL_PERSONAL);
  330. end;
  331.  
  332.  
  333. {$IF gsIdVersion <> '10.1.5'} // Delphi 2007 built-in Indy10; gsIdVersion requires idGlobal.pas
  334. {$DEFINE NewIndy}
  335. {$IFEND}
  336.  
  337. function MD5Stream(const s: TStream): string;
  338. var
  339.   idmd5: TIdHashMessageDigest5;
  340. begin
  341.   idmd5 := TIdHashMessageDigest5.Create;
  342.   try
  343.     {$IFDEF NewIndy}
  344.     result := idmd5.HashStreamAsHex(s);
  345.     {$ELSE}
  346.     result := idmd5.AsHex(idmd5.HashValue(s));
  347.     {$ENDIF}
  348.   finally
  349.     idmd5.Free;
  350.   end;
  351. end;
  352.  
  353. function MD5(const str: string): string;
  354. {$IFDEF NewIndy}
  355. var
  356.   idmd5: TIdHashMessageDigest5;
  357. begin
  358.   idmd5 := TIdHashMessageDigest5.Create;
  359.   try
  360.     result := idmd5.HashStringAsHex(str,IndyTextEncoding_OSDefault);
  361.   finally
  362.     idmd5.Free;
  363.   end;
  364. {$ELSE}
  365. var
  366.   ss: TStringStream;
  367. begin
  368.   ss := TStringStream.Create(str);
  369.   try
  370.     result := MD5Stream(ss);
  371.   finally
  372.     ss.Free;
  373.   end;
  374. {$ENDIF}
  375. end;
  376.  
  377.  
  378. end.
  379.