Subversion Repositories fastphp

Rev

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