Subversion Repositories fastphp

Rev

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