Subversion Repositories fastphp

Rev

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