Subversion Repositories fastphp

Rev

Rev 49 | Rev 67 | Go to most recent revision | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
2 daniel-mar 1
unit Functions;
2
 
3
interface
4
 
5
uses
6
  Windows, Messages, SysUtils, StrUtils, IniFiles, Classes, Forms, Variants, MsHTML,
25 daniel-mar 7
  StdCtrls, SynEdit, ActiveX;
2 daniel-mar 8
 
61 daniel-mar 9
type
10
  TContentCallBack = procedure(Content: string) of object;
11
 
12
function GetDosOutput(CommandLine: string; Work: string = ''; ContentCallBack: TContentCallBack=nil): string;
2 daniel-mar 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;
23 daniel-mar 17
function GetWordUnderPos(AMemo: TSynEdit; Line, Column: integer): string;
4 daniel-mar 18
function GetWordUnderCaret(AMemo: TSynEdit): string;
9 daniel-mar 19
function MyVarToStr(v: Variant): string;
22 daniel-mar 20
function FileSystemCaseSensitive: boolean;
29 daniel-mar 21
function HighColorWindows: boolean;
45 daniel-mar 22
function GetTempDir: string;
49 daniel-mar 23
function GetSpecialFolder(const aCSIDL: Integer): string;
24
function GetMyDocumentsFolder: string;
2 daniel-mar 25
 
26
implementation
27
 
49 daniel-mar 28
uses
29
  ShlObj; // Needed for the CSIDL constants
30
 
61 daniel-mar 31
function GetDosOutput(CommandLine: string; Work: string = ''; ContentCallBack: TContentCallBack=nil): string;
2 daniel-mar 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;
61 daniel-mar 76
            if Assigned(ContentCallBack) then ContentCallBack(Buffer);
2 daniel-mar 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
 
22 daniel-mar 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
 
2 daniel-mar 150
begin
22 daniel-mar 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);
2 daniel-mar 170
end;
171
 
172
// Template: http://stackoverflow.com/questions/6339446/delphi-get-the-whole-word-where-the-caret-is-in-a-memo
23 daniel-mar 173
function GetWordUnderPos(AMemo: TSynEdit; Line, Column: integer): string;
2 daniel-mar 174
 
175
  function ValidChar(c: char): boolean;
176
  begin
25 daniel-mar 177
    {$IFDEF UNICODE}
8 daniel-mar 178
    result := CharInSet(c, ['a'..'z', 'A'..'Z', '0'..'9', '_']);
25 daniel-mar 179
    {$ELSE}
180
    result := c in ['a'..'z', 'A'..'Z', '0'..'9', '_'];
181
    {$ENDIF}
2 daniel-mar 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
 
25 daniel-mar 195
   if LineText = '' then
196
   begin
197
     result := '';
198
     exit;
199
   end;
5 daniel-mar 200
 
2 daniel-mar 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
 
23 daniel-mar 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
 
9 daniel-mar 238
function MyVarToStr(v: Variant): string;
2 daniel-mar 239
var
9 daniel-mar 240
  _Lo, _Hi, i: integer;
2 daniel-mar 241
begin
9 daniel-mar 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;
2 daniel-mar 262
end;
263
 
22 daniel-mar 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}
25 daniel-mar 271
  result := false;
272
  exit;
22 daniel-mar 273
  {$ENDIF}
274
end;
275
 
29 daniel-mar 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
 
45 daniel-mar 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
 
49 daniel-mar 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
 
2 daniel-mar 329
end.