source: trunk/NewView/StartupUnit.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: 10.0 KB
Line 
1Unit StartupUnit;
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
7// Code related to startup and finding help files.
8// Shared between NewView.exe and ViewStub.exe
9
10Interface
11
12uses
13 OS2Def,
14 Classes,
15 ACLString,
16 GlobalFilelistUnit,
17 SharedMemoryUnit,
18 CmdLineParameterUnit;
19
20const
21 OWN_HELP_MARKER = '[NVHELP]';
22
23
24function AccessSharedMemory: TSuballocatedSharedMemory;
25
26// Returns true if the program should be started as normal.
27// False if it should immediately exit.
28function Startup: boolean;
29
30function GetOwnHelpFileName: string;
31
32// Look for any items that are actually specifiying environment
33// variables, and expand them to the contents of the variables
34Procedure TranslateIPFEnvironmentVars( Items: TStrings;
35 ExpandedItems: TStrings );
36
37// Given a filename, which may or may not contain a path or extension,
38// finds the actual file. This can involve searching
39// the help and bookshelf paths.
40Function FindHelpFile( FileName: string ): string;
41
42var
43 CmdLineParameters: TCmdLineParameters;
44 SharedMemory: TSubAllocatedSharedMemory;
45 GlobalFilelist: TGlobalFilelist;
46
47Implementation
48
49uses
50 Dos,
51 SysUtils,
52 DebugUnit,
53 PMWin,
54 ACLUtility,
55 ACLStringUtility,
56 ACLFileUtility,
57 AStringUtilityUnit,
58 HelpManagerUnit;
59
60// Look for any items that are actually specifiying environment
61// variables, and expand them to the contents of the variables
62Procedure TranslateIPFEnvironmentVars( Items: TStrings;
63 ExpandedItems: TStrings );
64var
65 i: longint;
66 Item: string;
67 EnvironmentVarValue: string;
68begin
69 LogEvent(LogStartup, 'Translating environment vars' );
70 for i := 0 to Items.Count - 1 do
71 begin
72 Item := Items[ i ];
73
74 Item := StrUnQuote( Item ); // remove single quotes
75 Item := StrUnDoubleQuote( Item ); // remove double quotes
76
77 LogEvent(LogStartup, ' Item: ' + Item );
78 EnvironmentVarValue := GetEnv( Uppercase( Item ) );
79 if DosError = 0 then
80 begin
81 // environment var exists - use it's value
82 LogEvent(LogStartup, ' Translated: ' + EnvironmentVarValue );
83 while EnvironmentVarValue <> '' do
84 begin
85 Item := ExtractNextValue( EnvironmentVarValue, '+' );
86 ExpandedItems.Add( Item );
87 end;
88 end
89 else
90 begin
91 // not an environment var
92 ExpandedItems.Add( Item );
93 end;
94 end;
95end;
96
97// Given a filename, which may or may not contain a path or extension,
98// finds the actual file. This can involve searching
99// the help and bookshelf paths.
100Function FindHelpFile( FileName: string ): string;
101var
102 AlternativeFileName: string;
103begin
104 if FileName = OWN_HELP_MARKER then
105 begin
106 Result := GetOwnHelpFileName;
107 exit;
108 end;
109
110 Result := '';
111
112 AlternativeFileName := '';
113 if ExtractFileExt( Filename ) = '' then
114 begin
115 Filename := ChangeFileExt( Filename, '.inf' );
116 AlternativeFileName := ChangeFileExt( Filename, '.hlp' );
117 end;
118
119 if ExtractFilePath( FileName ) <> '' then
120 begin
121 // Path specified; just see if it exists
122
123 // expand out relative paths
124 Filename := ExpandFileName( FileName );
125 AlternativeFilename := ExpandFileName( AlternativeFilename );
126
127 if FileExists( Filename ) then
128 Result := Filename
129 else if FileExists( AlternativeFilename ) then
130 Result := AlternativeFilename;
131
132 end
133 else
134 begin
135 // Path not specified; search current
136 if FileExists( ExpandFileName( FileName ) ) then
137 begin
138 Result := ExpandFileName( FileName );
139 exit;
140 end;
141
142 if FileExists( ExpandFileName( AlternativeFilename ) ) then
143 begin
144 Result := ExpandFileName( AlternativeFilename );
145 exit;
146 end;
147
148 // Search help paths
149
150 if not SearchHelpPaths( FileName,
151 Result,
152 false // don't search our app dir
153 ) then
154 begin
155 // Didn't find as specified or as .inf, try .hlp
156 if AlternativeFilename <> '' then
157 begin
158 if not SearchHelpPaths( AlternativeFileName,
159 Result,
160 false // don't search our app dir
161 ) then
162 begin
163 Result := '';
164 end;
165 end;
166 end;
167 end;
168end;
169
170function GetOwnHelpFileName: string;
171begin
172 Result := FindDefaultLanguageHelpFile( 'NewView' );
173end;
174
175// Extract a single element of a window position spec
176// - take a value from comma-separated list
177// - convert to numeric
178// - if the number ends with P then take as
179// a percentage of given dimension
180Function ExtractPositionElement( Var ParamValue: string;
181 ScreenDimension: longint ): longint;
182var
183 Element: string;
184begin
185 Element := ExtractNextValue( ParamValue, ',' );
186 if Element = '' then
187 raise Exception.Create( 'Missing position element' );
188 if StrEnds( 'P', Element ) then
189 begin
190 Delete( Element, Length( Element ), 1 );
191 if Element = '' then
192 raise Exception.Create( 'Missing position element' );
193 Result := StrToInt( Element );
194 if Result < 0 then
195 Result := 0;
196 if Result > 100 then
197 Result := 100;
198 Result := Round( Result / 100 * ScreenDimension );
199 end
200 else
201 begin
202 Result := StrToInt( Element );
203 end;
204end;
205
206Function SystemMetrics(sm:LONG):LongInt;
207Begin
208 Result := WinQuerySysValue(HWND_DESKTOP,sm);
209end;
210
211// Extract a specified window position:
212// X,Y,W,H
213Function ExtractPositionSpec( ParamValue: string;
214 Var Position: TWindowPosition ): boolean;
215begin
216 try
217 Position.Left := ExtractPositionElement( ParamValue, SystemMetrics(SV_CXSCREEN) );
218 Position.Bottom := ExtractPositionElement( ParamValue, SystemMetrics(SV_CYSCREEN) );
219 Position.Width := ExtractPositionElement( ParamValue, SystemMetrics(SV_CXSCREEN) );
220 if Position.Width < 50 then
221 Position.Width := 50;
222 Position.Height := ExtractPositionElement( ParamValue, SystemMetrics(SV_CYSCREEN) );
223 if Position.Height < 50 then
224
225 Position.Height := 50;
226 Result := true;
227 except
228 Result := false;
229 end;
230end;
231
232
233// If another instance already has the files open
234// activate it and return true.
235function FindExistingWindow: HWND;
236var
237 FileItems: TStringList;
238 Filenames: TStringList;
239 FullFilePath: string;
240 i: longint;
241
242 FileWindow: HWND;
243begin
244 Result := NULLHANDLE;
245
246 if length(CmdLineParameters.getFileNames) = 0 then
247 // not loading files; nothing to check
248 exit;
249
250 FileItems := TStringList.Create;
251 Filenames := TStringList.Create;
252
253 StringToList(CmdLineParameters.getFileNames, FileItems, '+' );
254 TranslateIPFEnvironmentVars( FileItems, FileNames );
255
256 for i := 0 to FileNames.Count - 1 do
257 begin
258 FullFilePath := FindHelpFile( Filenames[ i ] );
259 if FullFilePath <> '' then
260 begin
261 FileWindow := GlobalFilelist.FindFile( FullFilePath );
262
263 if FileWindow = NULLHANDLE then
264 begin
265 // not found - stop searching.
266 Result := NULLHANDLE; // no match
267 break;
268 end;
269
270 // found it
271
272 // is it the same as any previous match?
273 if Result <> NULLHANDLE then
274 begin
275 if FileWindow <> Result then
276 begin
277 // no, so we don't have a match.
278 // NOTE: We just excluded something: if the same file is
279 // open in multiple windows then we may not check all combinations
280 Result := NULLHANDLE; // no match
281 break;
282 end;
283 end
284 else
285 begin
286 // no match yet - store this one
287 Result := FileWindow;
288 end;
289
290 end;
291 end;
292
293 Filenames.Destroy;
294 FileItems.Destroy;
295
296end;
297
298function AccessSharedMemory: TSuballocatedSharedMemory;
299begin
300 Result := TSuballocatedSharedMemory.Create( SharedMemName,
301 SharedMemSize,
302 SharedMemReserveSize );
303end;
304
305procedure PostNewViewTextMessage( Window: HWND;
306 MessageType: ULONG;
307 s: string );
308var
309 ps: pchar;
310begin
311 SharedMemory.Allocate( ps, length( s ) + 1 );
312 ps ^ := s;
313 WinPostMsg( Window,
314 MessageType,
315 LONG( ps ),
316 0 );
317end;
318
319function Startup: boolean;
320var
321 tmpCmdLine: String;
322 tmpRc : Integer;
323
324 ExistingWindow: HWND;
325begin
326 // open shared memory
327 SharedMemory := AccessSharedMemory;
328
329 // get access to the system-global filelist
330 GlobalFilelist := TGlobalFilelist.Create;
331
332 // parse parameters into Parameters object
333 tmpCmdLine := nativeOS2GetCmdLineParameter;
334
335 CmdLineParameters := TCmdLineParameters.Create;
336 CmdLineParameters.parseCmdLine(tmpCmdLine);
337
338 ExistingWindow := FindExistingWindow;
339
340 if ExistingWindow <> NULLHANDLE then
341 begin
342 // want to exit without running fully
343 Result := false;
344
345 // destroy global list - nobody else will
346 GlobalFilelist.Destroy;
347 // TODO rbri maybe we need the next line
348 // Parameters.FilenamesParam.Destroy;
349
350 WinSetFocus( HWND_DESKTOP, ExistingWindow );
351
352 // if CmdLineParameters.getTopics <> '' then
353 if not CmdLineParameters.getSearchFlag AND not CmdLineParameters.getGlobalSearchFlag then
354 begin
355 PostNewViewTextMessage( ExistingWindow,
356 NHM_SEARCH,
357 CmdLineParameters.getSearchText);
358 end;
359
360 if CmdLineParameters.getGlobalSearchFlag then
361 begin
362 PostNewViewTextMessage( ExistingWindow,
363 NHM_GLOBAL_SEARCH,
364 CmdLineParameters.getSearchText );
365 end;
366
367 if CmdLineParameters.getShowUsageFlag then
368 begin
369 WinPostMsg( ExistingWindow,
370 NHM_SHOW_USAGE,
371 0,
372 0 );
373 end;
374
375 if CmdLineParameters.getHelpManagerFlag then
376 begin
377 // tell the new help manager instance to talk to the
378 // other viewer
379 WinPostMsg( CmdLineParameters.getHelpManagerWindow,
380 NHM_VIEWER_READY,
381 ExistingWindow,
382 0 );
383 end;
384
385 end
386 else
387 begin
388 // run as normal
389 Result := true;
390 end;
391end;
392
393Initialization
394End.
Note: See TracBrowser for help on using the repository browser.