OSDN Git Service

・スレ立てを実装。
[gikonavigoeson/gikonavi.git] / ExternalBoardManager.pas
1 unit ExternalBoardManager;
2
3 interface
4
5 uses
6         Windows, Classes, SysUtils,
7         IdHTTP, IdComponent, IdGlobal, IdException,
8         ExternalBoardPlugInMain, ExternalFilePath, ExternalThreadItem, ExternalBoardItem;
9
10 type
11         // =========================================================================
12         // \83v\83\89\83O\83C\83\93\82ð\8aÇ\97\9d\82·\82é TBoardPlugin \83N\83\89\83X
13         // =========================================================================
14         TBoardPlugIn = class( TObject )
15         private
16                 FFilePath                                               : string;               // \83v\83\89\83O\83C\83\93\82ð\8e¦\82·\83p\83X
17                 FModule                                                 : HMODULE;      // \83v\83\89\83O\83C\83\93\82Ì\83\82\83W\83\85\81[\83\8b\83n\83\93\83h\83\8b
18
19                 FVersionInfo                            : TOnVersionInfo;
20                 FAcceptURL                                      : TOnAcceptURL;
21
22                 FCreateThreadItem               : TThreadItemCreate;
23                 FDisposeThreadItem      : TThreadItemDispose;
24                 FDownloadThread                 : TThreadItemOnDownload;
25                 FWriteThread                            : TThreadItemOnWrite;
26                 FGetRes                                                 : TThreadItemOnGetRes;
27                 FGetHeader                                      : TThreadItemOnGetHeader;
28                 FGetFooter                                      : TThreadItemOnGetFooter;
29                 FGetBoardURL                            : TThreadItemOnGetBoardURL;
30
31                 FCreateBoardItem                : TBoardItemCreate;
32                 FDisposeBoardItem               : TBoardItemDispose;
33                 FDownloadBoard                  : TBoardItemOnDownload;
34                 FCreateThread                           : TBoardItemOnCreateThread;
35                 FEnumThread                                     : TBoardItemOnEnumThread;
36                 FFileName2ThreadURL     : TBoardItemOnFileName2ThreadURL;
37
38         public
39                 // \83R\83\93\83X\83g\83\89\83N\83^
40                 constructor     Create;
41                 // \83v\83\89\83O\83C\83\93\82Ì\83p\83X\82ð\8ew\92è\82µ\82Ä\8dì\90¬
42                 constructor     CreateFromPath( inPath : string );
43                 // \83v\83\89\83O\83C\83\93\96¼\82ð\8ew\92è\82µ\82Ä\8dì\90¬
44                 constructor     CreateFromName( inName : string );
45                 // \83\82\83W\83\85\81[\83\8b\83n\83\93\83h\83\8b\82ð\8ew\92è\82µ\82Ä\8dì\90¬
46                 constructor     CreateFromModule( inModule : HMODULE );
47
48                 // \83v\83\89\83O\83C\83\93\82Ì\83p\83X\82ð\8ew\92è\82µ\82Ä\83\8d\81[\83h
49                 procedure       LoadFromPath( inPath : string );
50                 // \83v\83\89\83O\83C\83\93\96¼\82ð\8ew\92è\82µ\82Ä\83\8d\81[\83h
51                 procedure       LoadFromName( inName : string );
52                 // \83\82\83W\83\85\81[\83\8b\83n\83\93\83h\83\8b\82ð\8ew\92è\82µ\82Ä\83\8d\81[\83h
53                 procedure       LoadFromModule( inModule : HMODULE );
54
55                 //===== PlugInMain \8aÖ\98A
56                 // \83o\81[\83W\83\87\83\93\8fî\95ñ
57                 procedure       VersionInfo(    var outAgent : string;
58                         var outMajor : DWORD; var outMinor : DWORD;
59                         var outRelease : string; var outRevision : DWORD );
60                 // \8ew\92è\82µ\82½ URL \82ð\82±\82Ì\83v\83\89\83O\83C\83\93\82Å\8eó\82¯\95t\82¯\82é\82©\82Ç\82¤\82©
61                 function        AcceptURL( inURL : string ) : Boolean;
62
63                 //===== TThreadItem \8aÖ\98A
64                 // TThreadItem \82ª\90\90¬\82³\82ê\82½
65                 procedure       CreateThreadItem( threadItem : DWORD );
66                 // TThreadItem \82ª\94j\8aü\82³\82ê\82½
67                 procedure       DisposeThreadItem( threadItem : DWORD );
68                 // \83_\83E\83\93\83\8d\81[\83h\82ð\8ew\8e¦
69                 function        DownloadThread( threadItem : DWORD ) : TDownloadState;
70                 // \8f\91\82«\8d\9e\82Ý\82ð\8ew\8e¦
71                 function        WriteThread( threadItem : DWORD; inName : string; inMail : string; inMessage : string ) : TDownloadState;
72                 // \83\8c\83X\94Ô\8d\86 n \82É\91Î\82·\82é html \82ð\97v\8b\81
73                 function        GetRes( threadItem : DWORD; inNo : DWORD ) : string;
74                 // \83X\83\8c\83b\83h\82Ì\83w\83b\83_ html \82ð\97v\8b\81
75                 function        GetHeader( threadItem : DWORD; inOptionalHeader : string ) : string;
76                 // \83X\83\8c\83b\83h\82Ì\83t\83b\83^ html \82ð\97v\8b\81
77                 function        GetFooter( threadItem : DWORD; inOptionalFooter : string ) : string;
78                 // \82±\82Ì ThreadItem \82ª\91®\82·\82é\94Â\82Ì URL \82ð\97v\8b\81
79                 function        GetBoardURL( threadItem : DWORD ) : string;
80
81                 //===== TBoardItem \8aÖ\98A
82                 // TBoard \82ª\90\90¬\82³\82ê\82½
83                 procedure       CreateBoardItem( boardItem : DWORD );
84                 // TBoardItem \82ª\94j\8aü\82³\82ê\82½
85                 procedure       DisposeBoardItem( boardItem : DWORD );
86                 // \83_\83E\83\93\83\8d\81[\83h\82ð\8ew\8e¦
87                 function        DownloadBoard( boardItem : DWORD ) : TDownloadState;
88                 // \83X\83\8c\97§\82Ä\82ð\8ew\8e¦
89                 function        CreateThread( boardItem : DWORD; inSubject : string; inName : string; inMail : string; inMessage : string ) : TDownloadState;
90                 // \82±\82Ì\94Â\82É\95Û\97L\82µ\82Ä\82¢\82é\83X\83\8c\82ð\97ñ\8b\93
91                 procedure EnumThread( boardItem : DWORD; inCallBack : TBoardItemEnumThreadCallBack );
92                 // \83t\83@\83C\83\8b\96¼\82©\82ç\83X\83\8c\83b\83h\82Ì URL \82ð\97v\8b\81
93                 function        FileName2ThreadURL( boardItem : DWORD; inFileName : string ) : string;
94
95         private
96                 procedure       LoadPlugInAPI;
97
98         public
99                 property        FilePath        : string        read FFilePath;
100                 property        Module          : HMODULE       read FModule;
101         end;
102
103 var
104         OnWork                          : TWorkEvent;
105         OnWorkBegin             : TWorkBeginEvent;
106         OnWorkEnd                       : TWorkEndEvent;
107
108         BoardPlugIns    : array of TBoardPlugIn;
109
110 procedure InitializeBoardPlugIns;
111
112 implementation
113
114 uses GikoSystem;
115
116 // *************************************************************************
117 // BoardPlugin \83t\83H\83\8b\83_\82É\82 \82é\83v\83\89\83O\83C\83\93\82ð\91S\82Ä\83\8d\81[\83h
118 // *************************************************************************
119 procedure InitializeBoardPlugIns;
120 var
121         i, bound                : Integer;
122         pluginNames     : TStringList;
123 begin
124
125         pluginNames := TStringList.Create;
126         try
127                 GikoSys.GetFileList( GikoSys.Setting.GetBoardPlugInDir, '*', pluginNames, False, False );
128                 SetLength( BoardPlugIns, pluginNames.Count );
129
130                 bound := pluginNames.Count - 1;
131                 for i := 0 to bound do
132                         BoardPlugIns[ i ] := TBoardPlugIn.CreateFromName( pluginNames.Strings[ i ] );
133         finally
134                 pluginNames.Free;
135         end;
136
137 end;
138
139
140
141 // =========================================================================
142 // \83v\83\89\83O\83C\83\93\82ð\8aÇ\97\9d\82·\82é TBoardPlugin \83N\83\89\83X
143 // =========================================================================
144
145 // *************************************************************************
146 // \83R\83\93\83X\83g\83\89\83N\83^
147 // *************************************************************************
148 constructor     TBoardPlugIn.Create;
149 begin
150
151         inherited;
152
153         FVersionInfo                            := nil;
154         FAcceptURL                                      := nil;
155
156         FCreateThreadItem               := nil;
157         FDisposeThreadItem      := nil;
158         FDownloadThread                 := nil;
159         FWriteThread                            := nil;
160         FGetRes                                                 := nil;
161         FGetHeader                                      := nil;
162         FGetFooter                                      := nil;
163
164         FCreateBoardItem                := nil;
165         FDisposeBoardItem               := nil;
166         FDownloadBoard                  := nil;
167         FCreateThread                           := nil;
168         FEnumThread                                     := nil;
169         FFileName2ThreadURL     := nil;
170
171 end;
172
173 // *************************************************************************
174 // \83v\83\89\83O\83C\83\93\82Ì\83p\83X\82ð\8ew\92è\82µ\82Ä\8dì\90¬
175 // *************************************************************************
176 constructor     TBoardPlugIn.CreateFromPath(
177         inPath : string
178 );
179 begin
180
181         Create;
182
183         LoadFromPath( inPath );
184
185 end;
186
187 // *************************************************************************
188 // \83v\83\89\83O\83C\83\93\96¼\82ð\8ew\92è\82µ\82Ä\8dì\90¬
189 // *************************************************************************
190 constructor     TBoardPlugIn.CreateFromName(
191         inName : string
192 );
193 begin
194
195         Create;
196
197         LoadFromName( inName );
198
199 end;
200
201 // *************************************************************************
202 // \83\82\83W\83\85\81[\83\8b\83n\83\93\83h\83\8b\82ð\8ew\92è\82µ\82Ä\8dì\90¬
203 // *************************************************************************
204 constructor     TBoardPlugIn.CreateFromModule(
205         inModule : HMODULE
206 );
207 begin
208
209         inherited Create;
210
211         LoadFromModule( inModule );
212
213 end;
214
215 // *************************************************************************
216 // \83v\83\89\83O\83C\83\93\82Ì\83p\83X\82ð\8ew\92è\82µ\82Ä\83\8d\81[\83h
217 // *************************************************************************
218 procedure TBoardPlugIn.LoadFromPath(
219         inPath : string
220 );
221 begin
222
223         FFilePath := inPath;
224         if FileExists( inPath ) then
225                 FModule := LoadLibrary( PChar( inPath ) )
226         else if FileExists( inPath + '.dll' ) then
227                 FModule := LoadLibrary( PChar( inPath + '.dll' ) );
228
229         LoadPlugInAPI;
230
231 end;
232
233 // *************************************************************************
234 // \83v\83\89\83O\83C\83\93\96¼\82ð\8ew\92è\82µ\82Ä\83\8d\81[\83h
235 // *************************************************************************
236 procedure TBoardPlugIn.LoadFromName(
237         inName : string
238 );
239 begin
240
241         LoadFromPath( GikoSys.Setting.GetBoardPlugInDir + inName );
242
243 end;
244
245 // *************************************************************************
246 // \83\82\83W\83\85\81[\83\8b\83n\83\93\83h\83\8b\82ð\8ew\92è\82µ\82Ä\83\8d\81[\83h
247 // *************************************************************************
248 procedure TBoardPlugIn.LoadFromModule(
249         inModule        : HMODULE
250 );
251 var
252         tmp                             : array [0..MAX_PATH] of Char;
253 begin
254
255         GetModuleFileName( inModule, tmp, SizeOf( tmp ) );
256         FFilePath       := tmp;
257         FModule         := inModule;
258
259         LoadPlugInAPI;
260
261 end;
262
263 // *************************************************************************
264 // \83o\81[\83W\83\87\83\93\8fî\95ñ
265 // *************************************************************************
266 procedure TBoardPlugIn.VersionInfo(
267         var outAgent            : string;               // \83o\81[\83W\83\87\83\93\82ð\88ê\90Ø\8aÜ\82Ü\82È\82¢\8f\83\90\88\82È\96¼\8fÌ
268         var outMajor            : DWORD;                // \83\81\83W\83\83\81[\83o\81[\83W\83\87\83\93
269         var outMinor            : DWORD;                // \83}\83C\83i\81[\83o\81[\83W\83\87\83\93
270         var outRelease  : string;               // \83\8a\83\8a\81[\83X\92i\8aK\96¼
271         var outRevision : DWORD                 // \83\8a\83r\83W\83\87\83\93\83i\83\93\83o\81[
272 );
273 var
274         agent                                           : PChar;
275         release                                 : PChar;
276 begin
277
278         if Assigned( FVersionInfo ) then begin
279                 FVersionInfo( agent, outMajor, outMinor, release, outRevision );
280                 outAgent                := string( agent );
281                 outRelease      := string( release );
282                 DisposeResultString( agent );
283                 DisposeResultString( release );
284         end;
285
286 end;
287
288 // *************************************************************************
289 // \8ew\92è\82µ\82½ URL \82ð\82±\82Ì\83v\83\89\83O\83C\83\93\82Å\8eó\82¯\95t\82¯\82é\82©\82Ç\82¤\82©
290 // *************************************************************************
291 function        TBoardPlugIn.AcceptURL(
292         inURL : string
293 ) : Boolean;
294 begin
295
296         if Assigned( FAcceptURL ) then
297                 Result := FAcceptURL( PChar( inURL ) )
298         else
299                 Result := False;
300
301 end;
302
303 // *************************************************************************
304 // TThreadItem \82ª\90\90¬\82³\82ê\82½
305 // *************************************************************************
306 procedure       TBoardPlugIn.CreateThreadItem(
307         threadItem : DWORD      // ThreadItem \82Ì\83C\83\93\83X\83^\83\93\83X
308 );
309 begin
310
311         if Assigned( FCreateThreadItem ) then
312                 FCreateThreadItem( threadItem );
313
314 end;
315
316 // *************************************************************************
317 // TThreadItem \82ª\94j\8aü\82³\82ê\82½
318 // *************************************************************************
319 procedure       TBoardPlugIn.DisposeThreadItem(
320         threadItem : DWORD      // ThreadItem \82Ì\83C\83\93\83X\83^\83\93\83X
321 );
322 begin
323
324         if Assigned( FDisposeThreadItem ) then
325                 FDisposeThreadItem( threadItem );
326
327 end;
328
329 // *************************************************************************
330 // \83_\83E\83\93\83\8d\81[\83h\82ð\8ew\8e¦
331 // *************************************************************************
332 function        TBoardPlugIn.DownloadThread(
333         threadItem : DWORD      // ThreadItem \82Ì\83C\83\93\83X\83^\83\93\83X
334 ) : TDownloadState;
335 begin
336
337         if Assigned( FDownloadThread ) then
338                 Result := FDownloadThread( threadItem )
339         else
340                 Result := dsError;
341
342 end;
343
344 // *************************************************************************
345 // \8f\91\82«\8d\9e\82Ý\82ð\8ew\8e¦
346 // *************************************************************************
347 function        TBoardPlugIn.WriteThread(
348         threadItem      : DWORD;        // ThreadItem \82Ì\83C\83\93\83X\83^\83\93\83X
349         inName                  : string;       // \96¼\91O(\83n\83\93\83h\83\8b)
350         inMail                  : string;       // \83\81\81[\83\8b\83A\83h\83\8c\83X
351         inMessage               : string        // \96{\95
352 ) : TDownloadState;                     // \8f\91\82«\8d\9e\82Ý\82ª\90¬\8c÷\82µ\82½\82©\82Ç\82¤\82©
353 begin
354
355         if Assigned( FWriteThread ) then
356                 Result := FWriteThread( threadItem, PChar( inName ), PChar( inMail ), PChar( inMessage ) )
357         else
358                 Result := dsError;
359
360 end;
361
362 // *************************************************************************
363 // \83\8c\83X\94Ô\8d\86 n \82É\91Î\82·\82é html \82ð\97v\8b\81
364 // *************************************************************************
365 function TBoardPlugIn.GetRes(
366         threadItem      : DWORD;                // ThreadItem \82Ì\83C\83\93\83X\83^\83\93\83X
367         inNo                            : DWORD                 // \95\\8e¦\82·\82é\83\8c\83X\94Ô\8d\86
368 ) : string;                                                     // \95\\8e¦\82·\82é HTML
369 var
370         tmp                                     : PChar;
371 begin
372
373         if Assigned( FGetRes ) then begin
374                 tmp                     := FGetRes( threadItem, inNo );
375                 Result  := string( tmp );
376                 DisposeResultString( tmp );
377         end;
378
379 end;
380
381 // *************************************************************************
382 // \83X\83\8c\83b\83h\82Ì\83w\83b\83_ html \82ð\97v\8b\81
383 // *************************************************************************
384 function TBoardPlugIn.GetHeader(
385         threadItem                              : DWORD;        // ThreadItem \82Ì\83C\83\93\83X\83^\83\93\83X
386         inOptionalHeader        : string        // \92Ç\89Á\82Ì\83w\83b\83_
387 ) : string;                                                                             // \90®\8c`\82³\82ê\82½ HTML
388 var
389         tmp                                                             : PChar;
390 begin
391
392         if Assigned( FGetHeader ) then begin
393                 tmp                     := FGetHeader( threadItem, PChar( inOptionalHeader ) );
394                 Result  := string( tmp );
395                 DisposeResultString( tmp );
396         end;
397
398 end;
399
400 // *************************************************************************
401 // \83X\83\8c\83b\83h\82Ì\83t\83b\83^ html \82ð\97v\8b\81
402 // *************************************************************************
403 function TBoardPlugIn.GetFooter(
404         threadItem                              : DWORD;        // ThreadItem \82Ì\83C\83\93\83X\83^\83\93\83X
405         inOptionalFooter        : string        // \92Ç\89Á\82Ì\83t\83b\83^
406 ) : string;                                                                             // \90®\8c`\82³\82ê\82½ HTML
407 var
408         tmp                                                             : PChar;
409 begin
410
411         if Assigned( FGetFooter ) then begin
412                 tmp                     := FGetFooter( threadItem, PChar( inOptionalFooter ) );
413                 Result  := string( tmp );
414                 DisposeResultString( tmp );
415         end;
416
417 end;
418
419 // *************************************************************************
420 // \82±\82Ì ThreadItem \82ª\91®\82·\82é\94Â\82Ì URL \82ð\97v\8b\81
421 // *************************************************************************
422 function        TBoardPlugIn.GetBoardURL(
423         threadItem      : DWORD // ThreadItem \82Ì\83C\83\93\83X\83^\83\93\83X
424 ) : string;
425 var
426         tmp                                     : PChar;
427 begin
428
429         if Assigned( FGetBoardURL ) then begin
430                 tmp                     := FGetBoardURL( threadItem );
431                 Result  := string( tmp );
432                 DisposeResultString( tmp );
433         end;
434
435 end;
436
437 // *************************************************************************
438 // TBoardItem \82ª\90\90¬\82³\82ê\82½
439 // *************************************************************************
440 procedure       TBoardPlugIn.CreateBoardItem(
441         boardItem : DWORD       // BoardItem \82Ì\83C\83\93\83X\83^\83\93\83X
442 );
443 begin
444
445         if Assigned( FCreateBoardItem ) then
446                 FCreateBoardItem( boardItem );
447
448 end;
449
450 // *************************************************************************
451 // TBoardItem \82ª\94j\8aü\82³\82ê\82½
452 // *************************************************************************
453 procedure       TBoardPlugIn.DisposeBoardItem(
454         boardItem : DWORD       // BoardItem \82Ì\83C\83\93\83X\83^\83\93\83X
455 );
456 begin
457
458         if Assigned( FDisposeBoardItem ) then
459                 FDisposeBoardItem( boardItem );
460
461 end;
462
463 // *************************************************************************
464 // \83_\83E\83\93\83\8d\81[\83h\82ð\8ew\8e¦
465 // *************************************************************************
466 function        TBoardPlugIn.DownloadBoard(
467         boardItem : DWORD       // BoardItem \82Ì\83C\83\93\83X\83^\83\93\83X
468 ) : TDownloadState;
469 begin
470
471         if Assigned( FDownloadBoard ) then
472                 Result := FDownloadBoard( boardItem )
473         else
474                 Result := dsError;
475
476 end;
477
478 // *************************************************************************
479 // \83X\83\8c\97§\82Ä\82ð\8ew\8e¦
480 // *************************************************************************
481 function        TBoardPlugIn.CreateThread(
482         boardItem               : DWORD;        // BoardItem \82Ì\83C\83\93\83X\83^\83\93\83X
483         inSubject               : string;       // \83X\83\8c\83^\83C
484         inName                  : string;       // \96¼\91O(\83n\83\93\83h\83\8b)
485         inMail                  : string;       // \83\81\81[\83\8b\83A\83h\83\8c\83X
486         inMessage               : string        // \96{\95
487 ) : TDownloadState;                     // \8f\91\82«\8d\9e\82Ý\82ª\90¬\8c÷\82µ\82½\82©\82Ç\82¤\82©
488 begin
489
490         if Assigned( FCreateThread ) then
491                 Result := FCreateThread( boardItem, PChar( inSubject ), PChar( inName ), PChar( inMail ), PChar( inMessage ) )
492         else
493                 Result := dsError;
494
495 end;
496
497 // *************************************************************************
498 // \82±\82Ì\94Â\82É\95Û\97L\82µ\82Ä\82¢\82é\83X\83\8c\82ð\97ñ\8b\93
499 // *************************************************************************
500 procedure TBoardPlugIn.EnumThread(
501         boardItem               : DWORD;        // BoardItem \82Ì\83C\83\93\83X\83^\83\93\83X
502         inCallBack      : TBoardItemEnumThreadCallBack
503 );
504 begin
505
506         if Assigned( FEnumThread ) then
507                 FEnumThread( boardItem, inCallBack );
508
509 end;
510
511 // *************************************************************************
512 // \83t\83@\83C\83\8b\96¼\82©\82ç\83X\83\8c\83b\83h\82Ì URL \82ð\97v\8b\81
513 // *************************************************************************
514 function        TBoardPlugIn.FileName2ThreadURL(
515         boardItem               : DWORD;        // BoardItem \82Ì\83C\83\93\83X\83^\83\93\83X
516         inFileName      : string
517 ) : string;
518 var
519         tmp                                                             : PChar;
520 begin
521
522         if Assigned( FFileName2ThreadURL ) then begin
523                 tmp                     := FFileName2ThreadURL( boardItem, PChar( inFileName ) );
524                 Result  := string( tmp );
525                 DisposeResultString( tmp );
526         end;
527
528 end;
529
530 // *************************************************************************
531 // \83v\83\89\83O\83C\83\93\82Ì API \82ð\8eæ\93¾
532 // *************************************************************************
533 procedure TBoardPlugIn.LoadPlugInAPI;
534 begin
535
536         try
537                 if Assigned( Pointer( FModule ) ) then begin
538                         FVersionInfo                            := GetProcAddress( FModule, 'OnVersionInfo' );
539                         FAcceptURL                                      := GetProcAddress( FModule, 'OnAcceptURL' );
540
541                         FCreateThreadItem               := GetProcAddress( FModule, 'ThreadItemCreate' );
542                         FDisposeThreadItem      := GetProcAddress( FModule, 'ThreadItemDispose' );
543                         FDownloadThread                 := GetProcAddress( FModule, 'ThreadItemOnDownload' );
544                         FWriteThread                            := GetProcAddress( FModule, 'ThreadItemOnWrite' );
545                         FGetRes                                                 := GetProcAddress( FModule, 'ThreadItemOnGetRes' );
546                         FGetHeader                                      := GetProcAddress( FModule, 'ThreadItemOnGetHeader' );
547                         FGetFooter                                      := GetProcAddress( FModule, 'ThreadItemOnGetFooter' );
548                         FGetBoardURL                            := GetProcAddress( FModule, 'ThreadItemOnGetBoardURL' );
549
550                         FCreateBoardItem                := GetProcAddress( FModule, 'BoardItemCreate' );
551                         FDisposeBoardItem               := GetProcAddress( FModule, 'BoardItemDispose' );
552                         FDownloadBoard                  := GetProcAddress( FModule, 'BoardItemOnDownload' );
553                         FCreateThread                           := GetProcAddress( FModule, 'BoardItemOnCreateThread' );
554                         FEnumThread                                     := GetProcAddress( FModule, 'BoardItemOnEnumThread' );
555                         FFileName2ThreadURL     := GetProcAddress( FModule, 'BoardItemOnFileName2ThreadURL' );
556                 end;
557         except
558         end;
559
560 end;
561
562 end.
563