Subversion Repositories fastphp

Rev

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