Subversion Repositories fastphp

Rev

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