Subversion Repositories fastphp

Rev

Rev 45 | Rev 61 | 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
 
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;
23 daniel-mar 14
function GetWordUnderPos(AMemo: TSynEdit; Line, Column: integer): string;
4 daniel-mar 15
function GetWordUnderCaret(AMemo: TSynEdit): string;
9 daniel-mar 16
function MyVarToStr(v: Variant): string;
22 daniel-mar 17
function FileSystemCaseSensitive: boolean;
29 daniel-mar 18
function HighColorWindows: boolean;
45 daniel-mar 19
function GetTempDir: string;
49 daniel-mar 20
function GetSpecialFolder(const aCSIDL: Integer): string;
21
function GetMyDocumentsFolder: string;
2 daniel-mar 22
 
23
implementation
24
 
49 daniel-mar 25
uses
26
  ShlObj; // Needed for the CSIDL constants
27
 
2 daniel-mar 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
 
22 daniel-mar 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
 
2 daniel-mar 146
begin
22 daniel-mar 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);
2 daniel-mar 166
end;
167
 
168
// Template: http://stackoverflow.com/questions/6339446/delphi-get-the-whole-word-where-the-caret-is-in-a-memo
23 daniel-mar 169
function GetWordUnderPos(AMemo: TSynEdit; Line, Column: integer): string;
2 daniel-mar 170
 
171
  function ValidChar(c: char): boolean;
172
  begin
25 daniel-mar 173
    {$IFDEF UNICODE}
8 daniel-mar 174
    result := CharInSet(c, ['a'..'z', 'A'..'Z', '0'..'9', '_']);
25 daniel-mar 175
    {$ELSE}
176
    result := c in ['a'..'z', 'A'..'Z', '0'..'9', '_'];
177
    {$ENDIF}
2 daniel-mar 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
 
25 daniel-mar 191
   if LineText = '' then
192
   begin
193
     result := '';
194
     exit;
195
   end;
5 daniel-mar 196
 
2 daniel-mar 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
 
23 daniel-mar 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
 
9 daniel-mar 234
function MyVarToStr(v: Variant): string;
2 daniel-mar 235
var
9 daniel-mar 236
  _Lo, _Hi, i: integer;
2 daniel-mar 237
begin
9 daniel-mar 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;
2 daniel-mar 258
end;
259
 
22 daniel-mar 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}
25 daniel-mar 267
  result := false;
268
  exit;
22 daniel-mar 269
  {$ENDIF}
270
end;
271
 
29 daniel-mar 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
 
45 daniel-mar 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
 
49 daniel-mar 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
 
2 daniel-mar 325
end.