source: trunk/NewView/GlobalSearchForm.pas@ 43

Last change on this file since 43 was 43, checked in by RBRi, 19 years ago

% use new debug unit

  • Property svn:eol-style set to native
File size: 19.7 KB
Line 
1Unit GlobalSearchForm;
2
3// NewView - a new OS/2 Help Viewer
4// Copyright 2003 Aaron Lawrence (aaronl at consultant dot com)
5// This software is released under the Gnu Public License - see readme.txt
6
7Interface
8
9// Global search uses a thread to load helpfiles, search them, and
10// send the results to be displayed.
11
12Uses
13 PmWin,
14 Classes,
15 Forms,
16 Buttons,
17 StdCtrls,
18 ComCtrls,
19 Outline2,
20 GenericThread,
21 ACLLanguageUnit,
22 TextSearchQuery,
23 HelpFile,
24 ExtCtrls,
25 LED;
26
27const
28 // Custom window messages for this form
29 // NOTE! Sibyl uses WM_USER+1 and +2!
30 WM_OPENED = WM_USER + 10;
31
32Type
33 TViewTopicCallback = procedure( Filename: string;
34 TopicIndex: longint ) of object;
35
36 TSearchParameters = class
37 Query: TTextSearchQuery;
38 Directories: TStringList;
39 end;
40
41 // Returned by thread. (Note - helpfiles and topics are destroyed dynamically.)
42 TSearchResult = class
43 Filename: string;
44 FileTitle: string;
45 MatchingTopics: TList;
46 constructor Create;
47 destructor Destroy; override;
48 end;
49
50 TGlobalSearchForm = Class (TForm)
51 SearchTextEdit: TEdit;
52 SearchTextLabel: TLabel;
53 SelectDrivesButton: TButton;
54 SearchTextLabel1: TLabel;
55 ResultsLabel: TLabel;
56 Led: TLed;
57 LEDTimer: TTimer;
58 SearchLocationComboBox: TComboBox;
59 Bevel: TBevel;
60 HelpButton: TButton;
61 ResultsOutline: TOutline2;
62 SearchButton: TButton;
63 ViewTopicButton: TButton;
64 CancelButton: TButton;
65 ProgressBar: TProgressBar;
66 ProgressLabel: TLabel;
67 Procedure SearchLocationComboBoxOnItemSelect (Sender: TObject;
68 Index: LongInt);
69 Procedure LEDTimerOnTimer (Sender: TObject);
70 Procedure SearchInComboBoxOnChange (Sender: TObject);
71 Procedure ResultsOutlineOnEnter (Sender: TObject);
72 Procedure SearchTextEditOnEnter (Sender: TObject);
73 Procedure ViewHelpPathsButtonOnClick (Sender: TObject);
74 Procedure SelectDrivesButtonOnClick (Sender: TObject);
75 Procedure GlobalSearchFormOnSetupShow (Sender: TObject);
76 Procedure CancelButtonOnClick (Sender: TObject);
77 Procedure GlobalSearchFormOnClose (Sender: TObject;
78 Var Action: TCloseAction);
79 Procedure ResultsOutlineOnItemDblClick (Node: TNode);
80 Procedure ViewTopicButtonOnClick (Sender: TObject);
81 Procedure GlobalSearchFormOnCreate (Sender: TObject);
82 Procedure GlobalSearchFormOnCloseQuery (Sender: TObject;
83 Var CanClose: Boolean);
84 Procedure SearchButtonOnClick (Sender: TObject);
85 Procedure GlobalSearchFormOnShow (Sender: TObject);
86 Protected
87 Procedure OnSearchProgress ( n, outof: integer;
88 S: String );
89 Procedure OnMatchFound( SearchResult: TSearchResult );
90 Procedure OnThreadData( S: string; Data: TObject );
91 Procedure OnSearchFinished( Result: TObject );
92 Procedure SetProgressLabel( const S: String );
93
94 // Handle our own WM_OPENED message
95 Procedure WMOpened( Var Msg: TMessage ); Message WM_OPENED;
96 Procedure ClearResults;
97 Procedure ViewTopic;
98
99 ThreadManager: TGenericThreadManager;
100
101 Procedure UpdateButtons;
102
103
104 Procedure GetSelectedDirectories( List: TStringList );
105
106 // search thread context
107
108 Function Search( Parameters: TObject ): TObject;
109
110 protected
111 Procedure OnLanguageEvent( Language: TLanguageFile;
112 const Apply: boolean );
113
114 SearchCaption: string;
115 StopCaption: string;
116 NoResultsMsg: string;
117 ScanDirectoriesMsg: string;
118 SearchingFileMsg: string;
119 OfMsg: string;
120 DoneMsg: string;
121 SearchErrorTitle: string;
122 SearchError: string;
123
124 StandardHelpPathsLocation: string;
125 FixedDrivesLocation: string;
126 SelectedHelpPathsLocation: string;
127 CustomPathsLocation: string;
128
129 public
130 // set by caller
131 ViewTopicCallback: TViewTopicCallback;
132 Procedure DoSearch;
133 End;
134
135Var
136 GlobalSearchForm: TGlobalSearchForm;
137
138procedure EnsureGlobalSearchFormLoaded;
139
140Implementation
141
142uses
143 SysUtils,
144 DebugUnit,
145 ACLFileUtility,
146 ACLDialogs,
147 ControlsUtility,
148 DriveInfoUnit,
149 ACLStringUtility,
150 IPFFileFormatUnit,
151 HelpTopic,
152 SearchUnit,
153 SearchDirectoriesFormUnit,
154 SettingsUnit,
155 InformationFormUnit;
156
157type
158 // Used to store filenames in outline
159 THelpFileInfo = class
160 FileName: string;
161 end;
162
163constructor TSearchResult.Create;
164begin
165 inherited Create;
166 MatchingTopics := TList.Create;
167end;
168
169destructor TSearchResult.Destroy;
170begin
171 MatchingTopics.Destroy;
172 inherited Destroy;
173end;
174
175Procedure TGlobalSearchForm.SearchLocationComboBoxOnItemSelect (Sender: TObject; Index: LongInt);
176Begin
177 Settings.GlobalSearchLocation := TGlobalSearchLocation( SearchLocationComboBox.ItemIndex );
178End;
179
180Procedure TGlobalSearchForm.LEDTimerOnTimer (Sender: TObject);
181Begin
182 LED.LedCondition := not LED.LedCondition;
183End;
184
185Procedure TGlobalSearchForm.SearchInComboBoxOnChange (Sender: TObject);
186Begin
187End;
188
189Procedure TGlobalSearchForm.ResultsOutlineOnEnter (Sender: TObject);
190Begin
191 ViewTopicButton.Default := true;
192End;
193
194Procedure TGlobalSearchForm.SearchTextEditOnEnter (Sender: TObject);
195Begin
196 SearchButton.Default := true;
197End;
198
199Procedure TGlobalSearchForm.ViewHelpPathsButtonOnClick (Sender: TObject);
200var
201 Dirs: TStringList;
202Begin
203 Dirs := TStringList.Create;
204
205 with InformationForm.InformationMemo do
206 begin
207 Lines.Clear;
208
209 Lines.Add( 'HELP:' );
210 GetDirsInPath( 'HELP', Dirs );
211 Lines.AddStrings( Dirs );
212
213 Lines.Add( '' );
214 Lines.Add( 'BOOKSHELF:' );
215 GetDirsInPath( 'BOOKSHELF', Dirs );
216 Lines.AddStrings( Dirs );
217 end;
218 InformationForm.ShowModal;
219
220 Dirs.Destroy;
221End;
222
223Procedure TGlobalSearchForm.GetSelectedDirectories( List: TStringList );
224Var
225 DriveNumber: longint;
226 DriveType: TDriveType;
227 DriveLetter: char;
228 Dirs: TStringList;
229 i: longint;
230 Dir: string;
231 FoundIndex: longint;
232begin
233 List.Clear;
234 case SearchLocationComboBox.ItemIndex of
235 -1:
236 begin
237 // one custom dir...
238 List.Add( SearchLocationComboBox.Text );
239 end;
240
241 Ord( gsHelpPaths ),
242 Ord( gsSelectedHelpPaths ): // standard or selected help paths
243 Begin
244 Dirs := TStringList.Create;
245 List.Sorted := true;
246 List.Duplicates := dupIgnore;
247
248 GetDirsInPath( 'HELP', Dirs );
249 List.AddStrings( Dirs );
250
251 GetDirsInPath( 'BOOKSHELF', Dirs );
252 List.AddStrings( Dirs );
253
254 Dirs.Destroy;
255
256 if SearchLocationComboBox.ItemIndex = Ord( gsSelectedHelpPaths ) then
257 begin
258 // now mark some as non-selected...
259 for i := 0 to List.Count - 1 do
260 begin
261 Dir := List[ i ];
262 if not Settings.SearchDirectories.Find( Dir, FoundIndex ) then
263 List.Objects[ i ] := pointer( 1 );
264 end;
265 end;
266 end;
267
268 Ord( gsFixedDrives ):
269 begin
270 // drives
271 For DriveNumber := MinDriveNumber To MaxDriveNumber Do
272 Begin
273 DriveType := GetDriveType( DriveNumber );
274 DriveLetter := Chr( DriveNumber + Ord( 'A' ) - 1 );
275
276 if DriveType = dtHard then
277 begin
278 List.Add( DriveLetter + ':\...' );
279 end;
280 end;
281 end;
282
283 Ord( gsCustom ):
284 begin
285 // already custom...
286 List.Assign( Settings.SearchDirectories );
287 end;
288 end;
289end;
290
291Procedure TGlobalSearchForm.SelectDrivesButtonOnClick (Sender: TObject);
292Begin
293 GetSelectedDirectories( SearchDirectoriesForm.SelectedFolders );
294
295 SearchDirectoriesForm.ShowModal;
296 if SearchDirectoriesForm.ModalResult <> mrOK then
297 exit;
298
299 if SearchLocationComboBox.ItemIndex = Ord( gsHelpPaths ) then
300 SearchLocationComboBox.ItemIndex := Ord( gsSelectedHelpPaths );
301
302 if SearchLocationComboBox.ItemIndex = Ord( gsFixedDrives ) then
303 SearchLocationComboBox.ItemIndex := Ord( gsCustom );
304
305 if SearchDirectoriesForm.CustomDirAdded then
306 SearchLocationComboBox.ItemIndex := Ord( gsCustom );
307
308 Settings.SearchDirectories.Assign( SearchDirectoriesForm.SelectedFolders );
309
310 SaveSettings;
311End;
312
313Procedure TGlobalSearchForm.UpdateButtons;
314Begin
315 // HelpPathsRadioButton.Checked := SearchType = stHelpPaths;
316 // EverywhereRadioButton.Checked := SearchType = stDrives;
317// FolderRadioButton.Checked := SearchType = stFolder;
318
319End;
320
321Procedure TGlobalSearchForm.GlobalSearchFormOnSetupShow (Sender: TObject);
322Begin
323 ScaleForm( self, 11, 16 );
324 SearchButton.Align := alFixedRightTop;
325
326 if SearchLocationComboBox.Items.Count = 0 then
327 begin
328 // must match teh global search location enum...
329 SearchLocationComboBox.Items.Add( StandardHelpPathsLocation );
330 SearchLocationComboBox.Items.Add( FixedDrivesLocation );
331 SearchLocationComboBox.Items.Add( SelectedHelpPathsLocation );
332 SearchLocationComboBox.Items.Add( CustomPathsLocation );
333
334 SearchLocationComboBox.ItemIndex := Ord( Settings.GlobalSearchLocation );
335 end;
336
337End;
338
339Procedure TGlobalSearchForm.OnLanguageEvent( Language: TLanguageFile;
340 const Apply: boolean );
341begin
342 Language.LoadComponentLanguage( self, Apply );
343
344 Language.LL( Apply, SearchCaption, 'SearchCaption', '~Search' );
345 Language.LL( Apply, StopCaption, 'StopCaption', '~Stop' );
346 Language.LL( Apply, NoResultsMsg, 'NoResultsMsg', '(No results found)' );
347 Language.LL( Apply, ScanDirectoriesMsg, 'ScanDirectoriesMsg', 'Finding help files...' );
348 Language.LL( Apply, SearchingFileMsg, 'SearchingFileMsg', 'Searching ' );
349 Language.LL( Apply, OfMsg, 'OfMsg', ' of ' );
350 Language.LL( Apply, DoneMsg, 'DoneMsg', 'Done' );
351 Language.LL( Apply, SearchErrorTitle, 'SearchErrorTitle', 'Search' );
352 Language.LL( Apply, SearchError, 'SearchError', 'Error in search syntax: ' );
353
354 Language.LL( Apply, StandardHelpPathsLocation, 'StandardHelpPathsLocation', 'Standard Help Paths' );
355 Language.LL( Apply, FixedDrivesLocation, 'FixedDrivesLocation', 'All Hard Drives' );
356 Language.LL( Apply, SelectedHelpPathsLocation, 'SelectedHelpPathsLocation', 'Selected Help Paths' );
357 Language.LL( Apply, CustomPathsLocation, 'CustomPathsLocation', 'Directory List' );
358
359end;
360
361Procedure TGlobalSearchForm.CancelButtonOnClick (Sender: TObject);
362Begin
363 Close;
364End;
365
366Procedure TGlobalSearchForm.GlobalSearchFormOnClose (Sender: TObject;
367 Var Action: TCloseAction);
368Begin
369 ClearResults;
370
371 if SearchLocationComboBox.ItemIndex = -1 then
372 begin
373 Settings.GlobalSearchLocation := gsCustom;
374 Settings.SearchDirectories.Clear;
375 Settings.SearchDirectories.Add( SearchLocationComboBox.Text );
376 end;
377
378 Action := caFreeHandle; // DON'T release the form! (Default action for non-modal forms)
379End;
380
381Procedure TGlobalSearchForm.ResultsOutlineOnItemDblClick (Node: TNode);
382Begin
383 ViewTopic;
384End;
385
386Procedure TGlobalSearchForm.ViewTopicButtonOnClick (Sender: TObject);
387begin
388 ViewTopic;
389end;
390
391Procedure TGlobalSearchForm.ViewTopic;
392var
393 Node: TNode;
394 HelpFileInfo: THelpFileInfo;
395 TopicIndex: longint;
396Begin
397 Node := ResultsOutline.SelectedNode;
398 if Node = nil then
399 exit;
400 case Node.Level of
401 0:
402 begin
403 // file node
404 HelpFileInfo := Node.Data as THelpFileInfo;
405 TopicIndex := -1;
406 end;
407
408 1:
409 begin
410 // topic node
411 HelpFileInfo := Node.Parent.Data as THelpFileInfo;
412 TopicIndex := longint( Node.Data );
413 end;
414
415 else
416 assert( false, 'Invalid node level in ViewTopic!: ' + IntToStr( Node.Level ) );
417 end;
418
419 ViewTopicCallback( HelpFileInfo.FileName, TopicIndex );
420End;
421
422Procedure TGlobalSearchForm.GlobalSearchFormOnCreate (Sender: TObject);
423Begin
424 RegisterForLanguages( OnLanguageEvent );
425
426 UpdateButtons;
427
428 ThreadManager := TGenericThreadManager.Create( self );
429 ThreadManager.OnProgressUpdate := OnSearchProgress;
430 ThreadManager.OnDataFromThread := OnThreadData;
431 ThreadManager.OnJobComplete := OnSearchFinished;
432End;
433
434Procedure TGlobalSearchForm.OnSearchFinished( Result: TObject );
435Begin
436 SearchButton.Caption := SearchCaption;
437 ProgressBar.Hide;
438 LED.LedCondition := false;
439 LEDTimer.Stop;
440
441 if ResultsOutline.ChildCount > 0 then
442 begin
443 ResultsOutline.SelectedNode:= ResultsOutline.Children[ 0 ];
444 ResultsOutline.Focus;
445 SetProgressLabel( '' );
446 end
447 else
448 begin
449 SetProgressLabel( NoResultsMsg );
450 end;
451
452End;
453
454Procedure TGlobalSearchForm.GlobalSearchFormOnCloseQuery (Sender: TObject;
455 Var CanClose: Boolean);
456Begin
457 if ThreadManager.IsRunning then
458 begin
459 ThreadManager.Stop;
460 end;
461End;
462
463Procedure TGlobalSearchForm.SetProgressLabel( const S: String );
464begin
465 ProgressLabel.Text := S;
466 ProgressLabel.Refresh;
467end;
468
469Procedure TGlobalSearchForm.OnSearchProgress ( n, outof: integer;
470 S: String );
471Begin
472 ProgressBar.Position := n * 100 div outof;
473 SetProgressLabel( S );
474End;
475
476Function TGlobalSearchForm.Search( Parameters: TObject ): TObject;
477var
478 Files: TStringList;
479 FileIndex: longint;
480 Filename: string;
481 HelpFile: THelpFile;
482 SearchResult: TSearchResult;
483 MatchingTopics: TList;
484
485 SearchParameters: TSearchParameters;
486 Query: TTextSearchQuery;
487 i: longint;
488 Dir: string;
489
490Begin
491// StartProfile( GetLogFilesDir + 'NewViewSearch.prf' );
492
493 SearchParameters := Parameters as TSearchParameters;
494
495 Query := SearchParameters.Query;
496 Files := TStringList.Create;
497
498 // MatchingTopics.Add( nil ); // artificial crash
499 MatchingTopics := TList.Create;
500
501 LogEvent(LogParse, 'Getting files');
502
503 // make sure we ignore duplicate files...
504 Files.Sorted := true;
505 Files.CaseSensitive := false;
506 Files.Duplicates := dupIgnore;
507
508 for i := 0 to SearchParameters.Directories.Count - 1 do
509 begin
510 if ThreadManager.StopRequested then
511 break;
512 ThreadManager.UpdateProgress( i * 10 div SearchParameters.Directories.Count,
513 100,
514 ScanDirectoriesMsg );
515 Dir := SearchParameters.Directories[ i ];
516 if StrEnds( '...', Dir ) then
517 begin
518 Dir := StrLeftWithout( Dir, 3 );
519 ListDirectoryRecursiveAdditive2( Dir,
520 '*.inf;*.hlp',
521 Dir, // want full paths
522 Files,
523 nil, // don't care to know subdirs
524 ThreadManager.StopRequested,
525 true ); // check termination
526 end
527 else
528 begin
529 ListDirectoryAdditive( Dir,
530 '*.inf;*.hlp',
531 Dir, // want full paths
532 Files,
533 nil ); // don't care to know subdirs
534 end;
535 end;
536
537 LogEvent(LogParse, ' Searching ' + IntToStr( Files.Count ) + ' files');
538 for FileIndex := 0 to Files.Count - 1 do
539 begin
540 if ThreadManager.StopRequested then
541 break;
542 Filename := Files[ FileIndex ];
543 LogEvent(LogParse, Filename);
544 ThreadManager.UpdateProgress( 10 + FileIndex * 95 div Files.Count,
545 100,
546 SearchingFileMsg
547 + Filename
548 + ' ('
549 + IntToStr( FileIndex + 1 )
550 + OfMsg
551 + IntToStr( Files.Count )
552 + ')...' );
553
554 try
555 LogEvent(LogParse, ' Create THelpFile');
556 HelpFile := THelpFile.Create( FileName );
557
558 LogEvent(LogParse, ' Helpfile created');
559 MatchingTopics.Clear;
560
561 LogEvent(LogParse, ' Search file');
562 SearchHelpFile( HelpFile,
563 Query,
564 MatchingTopics,
565 nil // don't care about words matched
566 );
567
568 if MatchingTopics.Count > 0 then
569 begin
570 LogEvent(LogParse, ' Sort results');
571 // Create a searchresult object to send back to main thread.
572 SearchResult := TSearchResult.Create;
573 SearchResult.Filename := HelpFile.Filename;
574 SearchResult.FileTitle := HelpFile.Title;
575
576 SearchResult.MatchingTopics.Assign( MatchingTopics );
577
578 SearchResult.MatchingTopics.Sort( TopicRelevanceCompare );
579 LogEvent(LogParse, ' Display results');
580
581 ThreadManager.SendData( '', SearchResult );
582 end;
583
584 LogEvent(LogParse, 'Unload helpfile');
585 HelpFile.Destroy;
586
587 except
588 on E: EHelpFileException do
589 begin
590 ; // ignore exceptions
591 end;
592
593 on E: EWindowsHelpFormatException do
594 begin
595 ; // ignore Windows help files
596 end;
597 end;
598
599 end;
600 LogEvent(LogParse, 'search completed');
601 ThreadManager.UpdateProgress( 100, 100, DoneMsg );
602 Files.Destroy;
603
604 Query.Destroy;
605
606 SearchParameters.Directories.Destroy;
607 SearchParameters.Destroy;
608
609 Result := nil;
610 LogEvent(LogParse, 'done');
611End;
612
613Procedure TGlobalSearchForm.ClearResults;
614var
615 FileIndex: longint;
616begin
617 for FileIndex := 0 to ResultsOutline.ChildCount - 1 do
618 ResultsOutline.Children[ FileIndex ].Data.Free;
619 ResultsOutline.Clear;
620 ViewTopicButton.Enabled := false;
621end;
622
623Procedure TGlobalSearchForm.SearchButtonOnClick (Sender: TObject);
624begin
625 DoSearch;
626end;
627
628Procedure TGlobalSearchForm.DoSearch;
629var
630 SearchText: string;
631 Query: TTextSearchQuery;
632 SearchParameters: TSearchParameters;
633Begin
634 if ThreadManager.IsRunning then
635 begin
636 ThreadManager.Stop;
637 exit;
638 end;
639
640 SearchText := trim( SearchTextEdit.Text );
641 if SearchText = '' then
642 exit;
643
644 try
645 Query := TTextSearchQuery.Create( SearchText );
646 except
647 on e: ESearchSyntaxError do
648 begin
649 DoErrorDlg( SearchErrorTitle,
650 SearchError
651 + e.Message );
652 exit;
653 end;
654 end;
655
656 ClearResults;
657
658 SearchParameters := TSearchParameters.Create;
659 SearchParameters.Directories := TStringList.Create;
660
661 SearchParameters.Query := Query;
662
663 GetSelectedDirectories( SearchParameters.Directories );
664
665 ThreadManager.StartJob( Search, SearchParameters );
666 SearchButton.Caption := StopCaption;
667 ProgressBar.Show;
668
669 LED.LedCondition := true;
670 LEDTimer.Start;
671End;
672
673Procedure TGlobalSearchForm.GlobalSearchFormOnShow (Sender: TObject);
674Begin
675 // make search button default
676 SearchButton.Focus;
677 SearchTextEdit.Focus;
678 SetProgressLabel( '' );
679 PostMsg( Handle, WM_OPENED, 0, 0 );
680 SearchButton.Caption := SearchCaption;
681 ProgressBar.Hide;
682 ViewTopicButton.Enabled := false;
683End;
684
685Procedure TGlobalSearchForm.OnThreadData( S: string; Data: TObject );
686var
687 SearchResult: TSearchResult;
688begin
689 SearchResult := Data as TSearchResult;
690 OnMatchFound( SearchResult );
691 SearchResult.Destroy;
692end;
693
694Procedure TGlobalSearchForm.OnMatchFound( SearchResult: TSearchResult );
695var
696 Topic: TTopic;
697 HelpFileInfo: THelpFileInfo;
698 FileNode: TNode;
699 TopicIndex: longint;
700begin
701 ViewTopicButton.Enabled := true;
702
703 HelpFileInfo := THelpFileInfo.Create;
704 HelpFileInfo.FileName := SearchResult.FileName;
705 FileNode := ResultsOutline.AddChild( SearchResult.FileTitle
706 + ' ('
707 + SearchResult.FileName
708 + ')',
709 HelpFileInfo );
710 for TopicIndex := 0 to SearchResult.MatchingTopics.Count - 1 do
711 begin
712 Topic := SearchResult.MatchingTopics[ TopicIndex ];
713 FileNode.AddChild( Topic.Title,
714 TObject( Topic.Index ) );
715 end;
716end;
717
718Procedure TGlobalSearchForm.WMOpened( Var Msg: TMessage );
719begin
720 Bevel.XStretch := xsFrame;
721 Bevel.YAlign := yaTop;
722
723 LED.XAlign := xaRight;
724 LED.YAlign := yaTop;
725
726 SearchTextEdit.XStretch := xsFrame;
727 ProgressLabel.XStretch := xsFrame;
728 ResultsOutline.XStretch := xsFrame;
729 ResultsOutline.YStretch := ysFrame;
730 ProgressLabel.YAlign := yaTop;
731 ProgressBar.XStretch := xsFrame;
732 ProgressBar.YAlign := yaBottom;
733 SearchTextEdit.YAlign := yaTop;
734 SearchTextEdit.Focus;
735end;
736
737procedure EnsureGlobalSearchFormLoaded;
738begin
739 if GlobalSearchForm = nil then
740 GlobalSearchForm := TGlobalSearchForm.Create( nil );
741end;
742
743Initialization
744 RegisterClasses ([TGlobalSearchForm, TEdit, TLabel,
745 TProgressBar, TButton, TOutline2, TComboBox, TBevel, TLed, TTimer]);
746 RegisterUpdateProcForLanguages( EnsureGlobalSearchFormLoaded );
747End.
Note: See TracBrowser for help on using the repository browser.