Subversion Repositories fastphp

Rev

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