Subversion Repositories fastphp

Rev

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