Develop and Download Open Source Software

Browse Subversion Repository

Contents of /WebModuleUnit1.pas

Parent Directory Parent Directory | Revision Log Revision Log


Revision 17 - (show annotations) (download) (as text)
Wed Sep 28 14:30:22 2016 UTC (7 years, 6 months ago) by yamat0jp
File MIME type: text/x-pascal
File size: 20631 byte(s)
Error occurred while calculating annotation data.
localappはローカルにdata.sdbファイルをダウンロードして再設定を行うためのソフトです
1 unit WebModuleUnit1;
2
3
4 interface
5
6 uses System.SysUtils, System.Classes, Web.HTTPApp, FireDAC.Stan.Intf,
7 FireDAC.Stan.Option, FireDAC.Stan.Param, FireDAC.Stan.Error, FireDAC.DatS,
8 FireDAC.Phys.Intf, FireDAC.DApt.Intf, FireDAC.Stan.Async, FireDAC.DApt,
9 FireDAC.UI.Intf, FireDAC.Stan.Def, FireDAC.Stan.Pool, FireDAC.Phys,
10 FireDAC.Phys.SQLite, FireDAC.Phys.SQLiteDef, FireDAC.Stan.ExprFuncs, Data.DB,
11 FireDAC.Comp.Client, FireDAC.Comp.DataSet, Web.HTTPProd, Web.DSProd,
12 AnsiStrings, System.DateUtils, System.Types, Vcl.AppEvnts, System.NetEncoding;
13
14 type
15 TWebModule1 = class(TWebModule)
16 FDTable1: TFDTable;
17 FDConnection1: TFDConnection;
18 FDTable2: TFDTable;
19 FDTable2home: TWideMemoField;
20 FDTable2title: TWideMemoField;
21 FDTable2title2: TWideMemoField;
22 FDTable2pass: TWideMemoField;
23 PageProducer1: TPageProducer;
24 DataSetPageProducer2: TDataSetPageProducer;
25 FDTable1name: TWideMemoField;
26 FDTable1no: TIntegerField;
27 FDTable1date: TWideMemoField;
28 FDTable1sub: TWideMemoField;
29 FDTable1com: TWideMemoField;
30 FDTable1pass: TWideMemoField;
31 adminDS: TDataSetPageProducer;
32 FDTable2ngwords: TWideMemoField;
33 FDTable3: TFDTable;
34 FDTable3link: TIntegerField;
35 FDTable3count: TIntegerField;
36 FDTable1line: TIntegerField;
37 FDTable3line: TIntegerField;
38 FDTable2mente: TBooleanField;
39 procedure WebModule1DefaultHandlerAction(Sender: TObject;
40 Request: TWebRequest; Response: TWebResponse; var Handled: Boolean);
41 procedure PageProducer1HTMLTag(Sender: TObject; Tag: TTag;
42 const TagString: string; TagParams: TStrings; var ReplaceText: string);
43 procedure WebModule1registAction(Sender: TObject; Request: TWebRequest;
44 Response: TWebResponse; var Handled: Boolean);
45 procedure DataSetPageProducer2HTMLTag(Sender: TObject; Tag: TTag;
46 const TagString: string; TagParams: TStrings; var ReplaceText: string);
47 procedure WebModule1userdelAction(Sender: TObject; Request: TWebRequest;
48 Response: TWebResponse; var Handled: Boolean);
49 procedure WebModule1adminAction(Sender: TObject; Request: TWebRequest;
50 Response: TWebResponse; var Handled: Boolean);
51 procedure WebModule1admindelAction(Sender: TObject; Request: TWebRequest;
52 Response: TWebResponse; var Handled: Boolean);
53 procedure WebModule1loginAction(Sender: TObject; Request: TWebRequest;
54 Response: TWebResponse; var Handled: Boolean);
55 procedure WebModuleBeforeDispatch(Sender: TObject; Request: TWebRequest;
56 Response: TWebResponse; var Handled: Boolean);
57 procedure WebModule1setupAction(Sender: TObject; Request: TWebRequest;
58 Response: TWebResponse; var Handled: Boolean);
59 procedure WebModule1searchAction(Sender: TObject; Request: TWebRequest;
60 Response: TWebResponse; var Handled: Boolean);
61 procedure WebModuleCreate(Sender: TObject);
62 procedure WebModuleDestroy(Sender: TObject);
63 procedure WebModule1adminsetAction(Sender: TObject; Request: TWebRequest;
64 Response: TWebResponse; var Handled: Boolean);
65 procedure WebModule1cssAction(Sender: TObject; Request: TWebRequest;
66 Response: TWebResponse; var Handled: Boolean);
67 procedure WebModuleAfterDispatch(Sender: TObject; Request: TWebRequest;
68 Response: TWebResponse; var Handled: Boolean);
69 private
70 { private ���� }
71 public
72 { public ���� }
73 user: string;
74 time: Int64;
75 words: TStringList;
76 position: integer;
77 uri: string;
78 er: string;
79 foo: string;
80 function footer(const path: string): string;
81 procedure regist(var com: string);
82 end;
83
84 var
85 WebModuleClass: TComponentClass = TWebModule1;
86
87 implementation
88
89 { %CLASSGROUP 'Vcl.Controls.TControl' }
90
91 {$R *.dfm}
92
93 procedure TWebModule1.DataSetPageProducer2HTMLTag(Sender: TObject; Tag: TTag;
94 const TagString: string; TagParams: TStrings; var ReplaceText: string);
95 begin
96 ReplaceText := FDTable1.FieldByName(TagString).AsString;
97 if TagString = 'com' then
98 regist(ReplaceText);
99 end;
100
101 function TWebModule1.footer(const path: string): string;
102 var
103 s1, s2, t1, t2: string;
104 home: string;
105 i, k, count: integer;
106 function linkcontent: string;
107 var
108 j, link: integer;
109 begin
110 result := '';
111 link := FDTable3.FieldByName('link').AsInteger;
112 if position > link div 2 then
113 begin
114 if (FDTable1.RecordCount - 1) div count < position + link div 2 then
115 i := FDTable1.RecordCount div count - link - position
116 else
117 i := -(link div 2)
118 end
119 else if position = -1 then
120 i := -position + FDTable1.RecordCount div count - link
121 else
122 i := -position;
123 for j := 0 to link do
124 begin
125 if FDTable1.RecordCount <= (position + i + j) * count then
126 break;
127 if position + i + j < 0 then
128 continue;
129 if i + j = 0 then
130 result := result + ' ' + IntToStr(position + 1) + ' '
131 else
132 result := result + Format(' <a href="' + home + path +
133 '?pos=%d#article">%d</a> ',
134 [position + i + j, position + 1 + i + j]);
135 end;
136 end;
137
138 begin
139 count := FDTable3.FieldByName('count').AsInteger;
140 home := FDTable2.FieldByName('home').AsString;
141 if position <= -1 then
142 begin
143 s1 := '<nav>���V%d�����L�����\��<br><center>Pages : [<b>';
144 s2 := '<<' + linkcontent + '>></b>] <b>���V</b><br></center></nav>';
145 result := Format(s1, [count]) + s2;
146 end
147 else
148 begin
149 if position = 0 then
150 t1 := '?pos=0'
151 else
152 t1 := '?pos=' + IntToStr(position - 1);
153 i := (FDTable1.RecordCount - 1) div count;
154 if position > i then
155 position := i;
156 if position = i then
157 begin
158 t2 := '?pos=' + position.ToString + '#article';
159 k := FDTable1.RecordCount;
160 end
161 else
162 begin
163 t2 := '?pos=' + IntToStr(position + 1) + '#article';
164 k := (position + 1) * count;
165 end;
166 s1 := '<nav>%d ���� %d ������ %d �������\��<br><center>Page : [<b>';
167 s2 := '<a href="' + home + path + t1 + '#article"><<</a>' + linkcontent +
168 '<a href="' + home + path + t2 + '">>></a></b>] <b><a href="' + home +
169 path + '#article">���V</a></b></center></nav>';
170 result := Format(s1, [FDTable1.RecordCount, position * count + 1, k]) + s2;
171 end;
172 end;
173
174 procedure TWebModule1.PageProducer1HTMLTag(Sender: TObject; Tag: TTag;
175 const TagString: string; TagParams: TStrings; var ReplaceText: string);
176 var
177 i, j, count: integer;
178 s: TDataSetPageProducer;
179 begin
180 if TagString = 'home' then
181 ReplaceText := FDTable2.FieldByName('home').AsString;
182 if (TagString = 'title') or (TagString = 'title2') then
183 ReplaceText := FDTable2.FieldByName(TagString).AsString;
184 if TagString = 'username' then
185 ReplaceText := user;
186 if TagString = 'main' then
187 begin
188 if FDTable1.RecordCount = 0 then
189 begin
190 if uri = '/index' then
191 ReplaceText := '<hr>�������e������������.<hr>';
192 end
193 else
194 begin
195 count := FDTable3.FieldByName('count').AsInteger;
196 if uri = '/admin' then
197 s := adminDS
198 else
199 s := DataSetPageProducer2;
200 if position < -1 then
201 position := -1;
202 if (position + 1) * count > FDTable1.RecordCount then
203 position := (FDTable1.RecordCount - 1) div count;
204 if position = -1 then
205 begin
206 if FDTable1.RecordCount < count then
207 j := FDTable1.RecordCount mod count
208 else
209 j := count;
210 end
211 else if FDTable1.RecordCount < (position + 1) * count then
212 j := FDTable1.RecordCount - position * count
213 else
214 j := count;
215 if position = -1 then
216 FDTable1.Last
217 else
218 FDTable1.RecNo := (position + 1) * count;
219 for i := 1 to j do
220 begin
221 ReplaceText := ReplaceText + s.Content;
222 FDTable1.Prior;
223 end;
224 ReplaceText := '<article>' + ReplaceText + '</article>' + '<hr>';
225 end;
226 end;
227 if TagString = 'footer' then
228 if foo <> '' then
229 ReplaceText := foo
230 else
231 begin
232 foo := footer(uri);
233 ReplaceText := foo;
234 end;
235 if TagString = 'text' then
236 if FDTable1.Filtered = false then
237 ReplaceText := '����������'
238 else
239 ReplaceText := '�Y������ ' + IntToStr(FDTable1.RecordCount) + ' ��' +
240 '<br><#main>';
241 if TagString = 'pass' then
242 ReplaceText := FDTable2.FieldByName('pass').AsString;
243 if TagString = 'content' then
244 ReplaceText := er;
245 if (TagString = 'mente') and (FDTable2.FieldByName('mente').AsBoolean = True)
246 then
247 ReplaceText := 'checked="checked"';
248 end;
249
250 procedure TWebModule1.regist(var com: string);
251 var
252 i: integer;
253 begin
254 i := 1;
255 while True do
256 begin
257 i := Pos(#$D#$A, com, i);
258 if i = 0 then
259 break;
260 Delete(com, i, Length(#$D#$A));
261 Insert('<br>', com, i);
262 inc(i, 4);
263 end;
264 end;
265
266 procedure TWebModule1.WebModule1adminAction(Sender: TObject;
267 Request: TWebRequest; Response: TWebResponse; var Handled: Boolean);
268 var
269 t: string;
270 x: Boolean;
271 procedure something;
272 var
273 s: TResourceStream;
274 begin
275 x := false;
276 s := TResourceStream.Create(HInstance, 'admin', RT_RCDATA);
277 try
278 uri := '/admin';
279 Response.ContentType := 'text/html; charset=utf-8;';
280 Response.Content := PageProducer1.ContentFromStream(s)
281 finally
282 s.Free;
283 end;
284 end;
285 procedure addcookie(day: integer; pass: string);
286 begin
287 with Response.Cookies.Add do
288 begin
289 path := '/';
290 Expires := Now + day;
291 Name := 'psw';
292 Value := AnsiString(pass);
293 end;
294 end;
295
296 begin
297 if Request.Query = 'del' then
298 begin
299 addcookie(-3, '');
300 Response.SendRedirect(FDTable2.FieldByName('home').AsAnsiString + '/index');
301 Exit;
302 end;
303 x := True;
304 t := Request.ContentFields.Values['password'];
305 position := StrToIntDef(Request.QueryFields.Values['pos'], -1);
306 if t <> '' then
307 begin
308 addcookie(14, t);
309 if t = FDTable2.FieldByName('pass').AsString then
310 something;
311 end
312 else if Request.CookieFields.Values['psw'] = FDTable2.FieldByName('pass').AsString
313 then
314 something;
315 if x = True then
316 Response.SendRedirect(FDTable2.FieldByName('home').AsAnsiString + '/login');
317 end;
318
319 procedure TWebModule1.WebModule1admindelAction(Sender: TObject;
320 Request: TWebRequest; Response: TWebResponse; var Handled: Boolean);
321 var
322 i: integer;
323 begin
324 for i := 0 to Request.ContentFields.count - 1 do
325 if FDTable1.Locate('no', Request.ContentFields.ValueFromIndex[i], []) = True
326 then
327 FDTable1.Delete;
328 Response.SendRedirect(FDTable2.FieldByName('home').AsAnsiString + '/admin');
329 end;
330
331 procedure TWebModule1.WebModule1adminsetAction(Sender: TObject;
332 Request: TWebRequest; Response: TWebResponse; var Handled: Boolean);
333 var
334 s: string;
335 x: Boolean;
336 begin
337 s := Request.ContentFields.Values['pass'];
338 if FDTable2.FieldByName('pass').AsString <> s then
339 begin
340 FDTable2.Edit;
341 FDTable2.FieldByName('pass').AsString := s;
342 FDTable2.Post;
343 with Response.Cookies.Add do
344 begin
345 path := AnsiString(FDTable2.FieldByName('home').AsAnsiString + '/admin');
346 Expires := Now + 14;
347 Name := 'psw';
348 Value := AnsiString(s);
349 end;
350 end;
351 x := Request.ContentFields.Values['mente'] = 'on';
352 if FDTable2.FieldByName('mente').AsBoolean <> x then
353 begin
354 FDTable2.Edit;
355 FDTable2.FieldByName('mente').AsBoolean := x;
356 FDTable2.Post;
357 end;
358 Response.SendRedirect(FDTable2.FieldByName('home').AsAnsiString + '/admin');
359 end;
360
361 procedure TWebModule1.WebModule1cssAction(Sender: TObject; Request: TWebRequest;
362 Response: TWebResponse; var Handled: Boolean);
363 var
364 s: string;
365 begin
366 s := Request.QueryFields.Values['css'];
367 if (s = 'main') or (s = 'pc') or (s = 'smart') or (s = 'tablet') then
368 begin
369 Response.ContentType := 'text/css';
370 Response.ContentStream := TResourceStream.Create(HInstance, s, RT_RCDATA);
371 end;
372 end;
373
374 procedure TWebModule1.WebModule1DefaultHandlerAction(Sender: TObject;
375 Request: TWebRequest; Response: TWebResponse; var Handled: Boolean);
376 var
377 s: TResourceStream;
378 t: TURLEncoding;
379 begin
380 if FDTable2.FieldByName('mente').AsBoolean = True then
381 begin
382 s := TResourceStream.Create(HInstance, 'mente', RT_RCDATA);
383 try
384 uri := '/mente';
385 Response.ContentType := 'text/html; charset=utf-8;';
386 Response.Content := PageProducer1.ContentFromStream(s);
387 finally
388 s.Free;
389 end;
390 Exit;
391 end;
392 position := StrToIntDef(Request.QueryFields.Values['pos'], -1);
393 s := TResourceStream.Create(HInstance, 'index', RT_RCDATA);
394 t := TURLEncoding.Create;
395 try
396 user := t.Decode(Request.CookieFields.Values['UID']);
397 uri := '/index';
398 Response.ContentType := 'text/html; charset=utf-8;';
399 Response.Content := PageProducer1.ContentFromStream(s);
400 finally
401 s.Free;
402 end;
403 end;
404
405 procedure TWebModule1.WebModule1loginAction(Sender: TObject;
406 Request: TWebRequest; Response: TWebResponse; var Handled: Boolean);
407 var
408 s: TResourceStream;
409 begin
410 s := TResourceStream.Create(HInstance, 'login', RT_RCDATA);
411 try
412 uri := '/login';
413 Response.ContentType := 'text/html; charset=utf-8;';
414 Response.Content := PageProducer1.ContentFromStream(s);
415 finally
416 s.Free;
417 end;
418 end;
419
420 procedure TWebModule1.WebModule1registAction(Sender: TObject;
421 Request: TWebRequest; Response: TWebResponse; var Handled: Boolean);
422 var
423 na, sub, com, pass: string;
424 s1: string;
425 no, line: integer;
426 i: integer;
427 s: TResourceStream;
428 t: TURLEncoding;
429 begin
430 with Request.ContentFields do
431 begin
432 na := Values['name'];
433 sub := Values['title'];
434 com := Values['comment'];
435 pass := Values['password'];
436 end;
437 er := '';
438 line := 0;
439 if na = '' then
440 na := '�N������';
441 if sub = '' then
442 sub := '�^�C�g������';
443 if com = '' then
444 er := '�{��������������.'#$D#$A
445 else
446 for i := 1 to Length(com) do
447 if Copy(com, i, i + 2) = #$D#$A then
448 inc(line);
449 for i := 0 to words.count - 1 do
450 if ContainsText(AnsiString(com), AnsiString(words[i])) = True then
451 begin
452 s1 := words[i];
453 if s1[1] = '<' then
454 begin
455 if Pos(' ', s1) = 0 then
456 s1 := Copy(s1, 2, Length(s1))
457 else
458 s1 := Copy(s1, 2, Pos(' ', s1) - 1);
459 er := er + '���~�^�O������������. ���:' + s1 + #$D#$A;
460 end
461 else
462 begin
463 er := er + '���~����������������.';
464 break;
465 end;
466 end;
467 if FDTable1.RecordCount = 0 then
468 no := 1
469 else
470 begin
471 FDTable1.Last;
472 no := FDTable1.FieldByName('no').AsInteger + 1;
473 if SecondsBetween(Now, StrToDateTime(FDTable1.FieldByName('date').AsString))
474 < time then
475 er := '����������������.';
476 end;
477 if er <> '' then
478 begin
479 Response.ContentType := 'text/html; charset=utf-8;';
480 s := TResourceStream.Create(HInstance, 'regist', RT_RCDATA);
481 try
482 Response.Content := PageProducer1.ContentFromStream(s);
483 finally
484 s.Free;
485 end;
486 Exit;
487 end;
488 t := TURLEncoding.Create;
489 try
490 FDTable1.AppendRecord([na, no, DateTimeToStr(Now), sub, com, pass, line]);
491 finally
492 t.Free;
493 end;
494 with Response.Cookies.Add do
495 begin
496 path := '/';
497 Name := 'UID';
498 Value := AnsiString(na);
499 Expires := Now + 1;
500 end;
501 Response.SendRedirect(FDTable2.FieldByName('home').AsAnsiString +
502 '/index#article');
503 end;
504
505 procedure TWebModule1.WebModule1searchAction(Sender: TObject;
506 Request: TWebRequest; Response: TWebResponse; var Handled: Boolean);
507 var
508 s: TStringList;
509 t1, t2, t3: string;
510 i, j: integer;
511 m: TResourceStream;
512 begin
513 t1 := Request.ContentFields.Values['filter'];
514 t3 := '';
515 s := TStringList.Create;
516 try
517 s.DelimitedText := Request.ContentFields.Values['word1'];
518 for i := 0 to s.count - 1 do
519 begin
520 t2 := Trim(s[i]);
521 if t2 = '' then
522 continue;
523 if t3 <> '' then
524 t3 := t3 + ' and ';
525 t3 := t3 + t1 + ' LIKE ''%' + t2 + '%''';
526 end;
527 finally
528 s.Free;
529 end;
530 if t3 = '' then
531 begin
532 m := TResourceStream.Create(HInstance, 'search', RT_RCDATA);
533 try
534 Response.ContentType := 'text/html; charset=utf-8;';
535 Response.Content := PageProducer1.ContentFromStream(m);
536 finally
537 m.Free;
538 end;
539 Exit;
540 end;
541 FDTable1.Filter := t3;
542 FDTable1.Filtered := True;
543 m := TResourceStream.Create(HInstance, 'search', RT_RCDATA);
544 try
545 j := 0;
546 for i := 1 to FDTable1.RecordCount - 1 do
547 begin
548 inc(j, FDTable1.FieldByName('line').AsInteger);
549 FDTable1.Next;
550 end;
551 PageProducer1.HTMLDoc.LoadFromStream(m);
552 Response.ContentType := 'text/html; charset=utf-8;';
553 if (t3 <> '') and (j > FDTable3.FieldByName('line').AsInteger) then
554 begin
555 t1 := PageProducer1.Content;
556 i := Pos('<#main>', t1);
557 Delete(t1, i, Length('<#main>'));
558 Response.Content := t1 + Format('�\���s����%d�s��������������.',
559 [FDTable3.FieldByName('line').AsInteger]);
560 end
561 else
562 Response.Content := PageProducer1.ContentFromString
563 (PageProducer1.Content);
564 finally
565 FDTable1.Filtered := false;
566 m.Free;
567 end;
568 end;
569
570 procedure TWebModule1.WebModule1setupAction(Sender: TObject;
571 Request: TWebRequest; Response: TWebResponse; var Handled: Boolean);
572 var
573 i: integer;
574 s: string;
575 begin
576 FDTable2.Edit;
577 for i := 0 to Request.ContentFields.count - 1 do
578 begin
579 s := Request.ContentFields.Names[i];
580 FDTable2.FieldByName(s).AsString := Request.ContentFields.ValueFromIndex[i]
581 end;
582 FDTable2.Post;
583 Handled := false;
584 end;
585
586 procedure TWebModule1.WebModule1userdelAction(Sender: TObject;
587 Request: TWebRequest; Response: TWebResponse; var Handled: Boolean);
588 var
589 s: string;
590 i: integer;
591 begin
592 i := StrToIntDef(Request.ContentFields.Values['number'], 0);
593 if (i > 0) and (FDTable1.Locate('no', i, []) = True) then
594 begin
595 s := FDTable1.FieldByName('pass').AsString;
596 if (s <> '') and (s = Request.ContentFields.Values['password']) then
597 FDTable1.Delete;
598 end;
599 Handled := false;
600 end;
601
602 procedure TWebModule1.WebModuleAfterDispatch(Sender: TObject;
603 Request: TWebRequest; Response: TWebResponse; var Handled: Boolean);
604 begin
605 foo := '';
606 end;
607
608 procedure TWebModule1.WebModuleBeforeDispatch(Sender: TObject;
609 Request: TWebRequest; Response: TWebResponse; var Handled: Boolean);
610 var
611 m: TResourceStream;
612 begin
613 if FDTable1.Exists = false then
614 FDTable1.CreateTable(false, [tpTable]);
615 if FDTable2.Exists = false then
616 begin
617 FDTable2.CreateTable(false, [tpTable]);
618 FDTable2.Active := True;
619 FDTable2.AppendRecord([Request.ScriptName, 'pbbs clone',
620 '<h1 align=center style=font:Verdana;color:gray;font-weight:bold>P-BBS CLONE</h1>',
621 'admin', '����,����,����,<style,<script,<link', false]);
622 m := TResourceStream.Create(HInstance, 'setup', RT_RCDATA);
623 try
624 uri := '/setup';
625 Response.ContentType := 'text/html; charset=utf-8;';
626 Response.Content := PageProducer1.ContentFromStream(m);
627 finally
628 m.Free;
629 end;
630 Handled := True;
631 end
632 else
633 FDTable2.Active := True;
634 if FDTable3.Exists = false then
635 begin
636 FDTable3.CreateTable(false, [tpTable]);
637 FDTable3.Active := True;
638 FDTable3.AppendRecord([5, 20, 500]);
639 end
640 else
641 FDTable3.Active := True;
642 words.DelimitedText := FDTable2.FieldByName('ngwords').AsString;
643 FDTable1.Active := True;
644 {
645 t:='';
646 ssl:=TStringList.Create;
647 try
648 ssl.Add('/login');
649 ssl.Add('/admin');
650 if (ssl.IndexOf(Request.PathInfo) > -1)and(StartsText('https',FDTable2.FieldByName('home').AsString) = false) then
651 begin
652 s:=FDTable2.FieldByName('home').AsAnsiString;
653 Delete(s,Length(s),1);
654 t:='https'+Copy(s,5,Length(s))+Request.PathInfo;
655 end;
656 finally
657 ssl.Free;
658 end;
659 if t <> '' then
660 begin
661 Response.SendRedirect(t);
662 Exit;
663 end;
664 }
665 end;
666
667 procedure TWebModule1.WebModuleCreate(Sender: TObject);
668 begin
669 FDConnection1.Open('Database=data.sdb;LockingMode=Normal;DriverID=SQLite');
670 time := 1;
671 words := TStringList.Create;
672 end;
673
674 procedure TWebModule1.WebModuleDestroy(Sender: TObject);
675 begin
676 words.Free;
677 end;
678
679 end.
680

Back to OSDN">Back to OSDN
ViewVC Help
Powered by ViewVC 1.1.26