Ignore:
Timestamp:
Jan 2, 2007, 8:29:23 PM (19 years ago)
Author:
RBRi
Message:

% command line parser

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/NewView/CmdLineParameterUnit.pas

    r32 r42  
    33// NewView - a new OS/2 Help Viewer
    44// Copyright 2006 Ronald Brill (rbri at rbri dot de)
    5 // This software is released under the Gnu Public License - see readme.txt
     5// This software is released under the GNU Public License - see readme.txt
    66
    77// Helper functions to address the command line parameters newview
     
    1717  Classes,
    1818  PMWIN,
    19   ACLStringUtility,
    20   ACLProfile,
    21   ACLFileUtility;
     19  StringUtilsUnit,
     20  DebugUnit;
    2221
    2322 CONST
    2423     SUCCESS = 0;
    2524     ERROR_UNMATCHED_QUOTE = -1;
     25
     26 TYPE EParsingFailed=CLASS(Exception);
    2627
    2728 TYPE
     
    3536     TCmdLineParameters = class
    3637     private
     38       commandLine : String;
    3739       showUsageFlag : boolean;
    38        searchTextFlag : boolean;
    39        searchText : string;
    40        globalSearchTextFlag : boolean;
    41        globalSearchText : string;
     40       searchFlag : boolean;
     41       globalSearchFlag : boolean;
    4242       language : string;
    4343       helpManagerFlag : boolean;
     
    4848       windowTitle : string;
    4949       fileNames : string;
    50        topics : string;
     50       searchText : string;
     51
     52       currentParsePosition : integer;
     53
     54       FUNCTION ReadNextPart(const aParseString : String; const aSetOfDelimiterChars : TSetOfChars): String;
     55       FUNCTION handleParamWithValue(const aCmdLineString : String; const aSwitch : String; var aValue : String) : Boolean;
    5156
    5257     public
     58       PROPERTY getCommandLine : String read commandLine;
    5359       PROPERTY getShowUsageFlag : boolean read showUsageFlag;
    54        PROPERTY getSearchTextFlag : boolean read searchTextFlag;
    55        PROPERTY getSearchText : string read searchText;
    56        PROPERTY getGlobalSearchTextFlag : boolean read globalSearchTextFlag;
    57        PROPERTY getGlobalSearchText : string read globalSearchText;
     60       PROPERTY getSearchFlag : boolean read searchFlag;
     61       PROPERTY getGlobalSearchFlag : boolean read globalSearchFlag;
    5862       PROPERTY getLanguage : string read language;
    5963       PROPERTY getHelpManagerFlag : boolean read helpManagerFlag;
     
    6569       PROPERTY getWindowTitle : string read windowTitle;
    6670       PROPERTY getFileNames : string read fileNames;
    67        PROPERTY getTopics : string read topics;
    68        PROCEDURE parseCmdLine(aSplittedCmdLine : TStringList);
    69   end;
    70 
    71  // returns a string containing the whole
    72  // command line parametes
    73  FUNCTION nativeOS2GetCmdLineParameter : STRING;
    74 
    75  // returns a string containing the whole
    76  // command line parametes
    77  FUNCTION splitCmdLineParameter(aCmdLineString : String; var aResult : TStringList) : integer;
    78 
    79  // Return true if param matches the form
    80  // /Flag:value
    81  // dash (-) can be used instead of slash (/)
    82  // colon can be omitted
    83  FUNCTION MatchValueParam( const aParam: string; const aFlag: string; var aValue: string): boolean;
    84 
    85  // Return true if param matches the form
    86  // /Flag
    87  // dash (-) can be used instead of slash (/)
    88  FUNCTION MatchFlagParam( const aParam: string; const aFlag: string): boolean;
    89 
    90  // Extract a single element of a window position spec
    91  // - take a value from comma-separated list
    92  // - convert to numeric
    93  // - if the number ends with P then take as
    94  //   a percentage of given dimension
    95  FUNCTION ExtractPositionElement(Var aParamValue: string; aScreenDimension: longint) : longint;
    96 
    97  // Extract a specified window position:
    98  // X,Y,W,H
    99  FUNCTION ExtractPositionSpec(aParamValue: string; Var aPosition: TWindowPosition ): boolean;
     71       PROPERTY getSearchText : string read searchText;
     72
     73       PROCEDURE parseCmdLine(aCmdLineString : String);
     74     private
     75       PROCEDURE parseSwitch(aCmdLineString : String);
     76  end;
     77
     78  // returns a string containing the whole
     79  // command line parametes
     80  FUNCTION nativeOS2GetCmdLineParameter : STRING;
     81
     82
    10083Implementation
    10184
     
    10790
    10891
    109   procedure TCmdLineParameters.parseCmdLine(aSplittedCmdLine : TStringList);
     92  procedure TCmdLineParameters.parseCmdLine(aCmdLineString : String);
    11093  var
    111       tmpParamIndex : integer;
    112       tmpParameter  : string;
    113       tmpParameterValue : string;
     94    tmpState : (SWITCH, FILENAME, FILENAME_QUOTE, TEXT);
     95    tmpCurrentChar : char;
    11496  begin
    115       ProfileEvent( 'ParseCommandLineParameters started' );
    116 
    117       // reset the whole object
    118       showUsageFlag := false;
    119       searchTextFlag := false;
    120       searchText := '';
    121       globalSearchTextFlag := false;
    122       globalSearchText := '';
    123       language := '';
    124       helpManagerFlag := false;
    125       helpManagerWindow := 0;
    126       windowPositionFlag := false;
    127       // windowPosition;
    128       ownerWindow := 0;
    129       windowTitle := '';
    130 
    131       filenames := '';
    132       topics := '';
    133 
    134       // start parsing
    135       for tmpParamIndex := 0 to aSplittedCmdLine.Count -1 do
    136       begin
    137           tmpParameter := aSplittedCmdLine[tmpParamIndex];
    138 
    139           if    MatchFlagParam(tmpParameter, '?')
    140                 or MatchFlagParam(tmpParameter, 'H')
    141                 or MatchFlagParam(tmpParameter, 'HELP') then
    142           begin
    143               showUsageFlag := true
    144           end
    145           else if MatchValueParam(tmpParameter, 'G', globalSearchText) then
    146           begin
    147               globalSearchTextFlag := true;
    148           end
    149           else if MatchValueParam(tmpParameter, 'S', searchText) then
    150           begin
    151               searchTextFlag := true;
    152           end
    153           else if MatchValueParam(tmpParameter, 'LANG', language) then
    154           begin
    155               // nothing to do
    156           end
    157           else if MatchValueParam(tmpParameter, 'HM', tmpParameterValue) then
    158           begin
    159               try
    160                   helpManagerWindow := StrToInt(tmpParameterValue);
    161                   helpManagerFlag := true;
    162               except
    163                   // ignore invalid window value
    164               end;
    165           end
    166           else if MatchValueParam(tmpParameter, 'OWNER', tmpParameterValue) then
    167           begin
    168               try
    169                   ownerWindow := StrToInt(tmpParameterValue);
    170               except
    171                   // ignore invalid owner value
    172               end;
    173           end
    174           else if MatchValueParam(tmpParameter, 'TITLE', windowTitle) then
    175           begin
    176               // nothing to do
    177           end
    178           else if MatchFlagParam(tmpParameter, 'PROFILE') then
    179           begin
    180               StartProfile(GetLogFilesDir + 'newview.prf' );
    181           end
    182           else if MatchValueParam(tmpParameter, 'POS', tmpParameterValue ) then
    183           begin
    184                // set window position/size
    185                if ExtractPositionSpec(tmpParameterValue, windowPosition) then
    186                begin
    187                    windowPositionFlag := true;
    188                end
     97     LogEvent(LogStartup, 'ParseCommandLine: "' + aCmdLineString + '"');
     98
     99     // store the original string for debugging
     100     commandLine := aCmdLineString;
     101
     102     // reset the whole object
     103     showUsageFlag := false;
     104     searchFlag := false;
     105     globalSearchFlag := false;
     106     language := '';
     107     helpManagerFlag := false;
     108     helpManagerWindow := 0;
     109     windowPositionFlag := false;
     110     ownerWindow := 0;
     111     windowTitle := '';
     112     searchText := '';
     113     filenames := '';
     114
     115     try
     116       // start parsing
     117       tmpState := FILENAME;
     118       currentParsePosition := 1;
     119       while currentParsePosition <= length(aCmdLineString) do
     120       begin
     121         tmpCurrentChar := aCmdLineString[currentParsePosition];
     122
     123         Case tmpCurrentChar of
     124           ' ' :
     125             begin
     126               Case tmpState of
     127                 SWITCH :
     128                 begin
     129                   tmpState := FILENAME;
     130                   inc(currentParsePosition);
     131                 end;
     132                 FILENAME :
     133                 begin
     134                   if length(fileNames) > 0 then
     135                   begin
     136                     tmpState := TEXT;
     137                   end;
     138                   inc(currentParsePosition);
     139                 end;
     140                 FILENAME_QUOTE :
     141                 begin
     142                   filenames := filenames + tmpCurrentChar;
     143                   inc(currentParsePosition);
     144                 end;
     145                 TEXT :
     146                 begin
     147                   searchText := searchText + tmpCurrentChar;
     148                   inc(currentParsePosition);
     149                 end;
     150               end;
     151             end;
     152
     153           '/', '-' :
     154             begin
     155               Case tmpState of
     156                 SWITCH :
     157                 begin
     158                   tmpState := SWITCH;
     159                   parseSwitch(aCmdLineString);
     160                 end;
     161                 FILENAME :
     162                 begin
     163                   if length(fileNames) < 1 then
     164                   begin
     165                     tmpState := SWITCH;
     166                     parseSwitch(aCmdLineString);
     167                   end
     168                   else
     169                   begin
     170                     filenames := filenames + tmpCurrentChar;
     171                     inc(currentParsePosition);
     172                   end;
     173                 end;
     174                 FILENAME_QUOTE :
     175                 begin
     176                   filenames := filenames + tmpCurrentChar;
     177                   inc(currentParsePosition);
     178                 end;
     179               else
     180                 begin
     181                   searchText := searchText + tmpCurrentChar;
     182                   inc(currentParsePosition);
     183                 end;
     184               end;
     185             end;
     186
     187           '"' :
     188             begin
     189               Case tmpState of
     190                 SWITCH :
     191                 begin
     192                   // syntax error
     193                   raise EParsingFailed.Create('Unsupported switch');
     194                 end;
     195                 FILENAME :
     196                 begin
     197                   tmpState := FILENAME_QUOTE;
     198                   inc(currentParsePosition);
     199                 end;
     200                 FILENAME_QUOTE :
     201                 begin
     202                   tmpState := FILENAME;
     203                   inc(currentParsePosition);
     204                 end;
     205                 TEXT :
     206                 begin
     207                   searchText := searchText + tmpCurrentChar;
     208                   inc(currentParsePosition);
     209                 end;
     210               end;
     211             end;
     212
     213           else
     214             begin
     215               Case tmpState of
     216                 SWITCH :
     217                 begin
     218                   // syntax error
     219                   raise EParsingFailed.Create('Unsupported switch');
     220                 end;
     221                 FILENAME :
     222                 begin
     223                   fileNames := fileNames + tmpCurrentChar;
     224                   inc(currentParsePosition);
     225                 end;
     226                 FILENAME_QUOTE :
     227                 begin
     228                   filenames := filenames + tmpCurrentChar;
     229                   inc(currentParsePosition);
     230                 end;
    189231               else
    190232               begin
    191                    // invalid...
    192                    showUsageFlag := true;
     233                 searchText := searchText + tmpCurrentChar;
     234                 inc(currentParsePosition);
    193235               end;
    194           end
    195           else
     236             end;
     237           end;
     238        end;
     239      end;
     240
     241    except
     242        on e:EParsingFailed do
     243        begin
     244          showUsageFlag := true;
     245        end;
     246    end;
     247
     248    // remove leading blanks from search text
     249    searchText := StrTrim(searchText);
     250
     251    LogEvent(LogStartup, 'Parameters parsed');
     252    LogEvent(LogStartup, '  Filename(s): "' + fileNames + '"');
     253    LogEvent(LogStartup, '  Search Text: "' + searchText + '"');
     254  end;
     255
     256
     257  FUNCTION TCmdLineParameters.ReadNextPart(const aParseString : String; const aSetOfDelimiterChars : TSetOfChars): String;
     258  VAR
     259    i : integer;
     260    tmpChar : char;
     261  BEGIN
     262    result := '';
     263    for i:= currentParsePosition to length(aParseString) do
     264    begin
     265      tmpChar := aParseString[i];
     266      if tmpChar in aSetOfDelimiterChars then
     267      begin
     268        i := length(aParseString); // stop parsing
     269      end
     270      else
     271      begin
     272        result := result + tmpChar;
     273      end;
     274    end;
     275  END;
     276
     277
     278
     279  Function TCmdLineParameters.handleParamWithValue(const aCmdLineString : String; const aSwitch : String; var aValue : String) : Boolean;
     280  var
     281    tmpText : String;
     282    tmpSwitchLength : integer;
     283  begin
     284    tmpSwitchLength := Length(aSwitch);
     285    tmpText := copy(aCmdLineString, currentParsePosition + 1, tmpSwitchLength);
     286    tmpText := lowercase(tmpText);
     287
     288    if (lowercase(aSwitch) = tmpText) then
     289    begin
     290      currentParsePosition := currentParsePosition + 1 + tmpSwitchLength;
     291      if aCmdLineString[currentParsePosition] = ':' then
     292      begin
     293        inc(currentParsePosition);
     294      end;
     295
     296      aValue := readNextPart(aCmdLineString, [' ', '-', '/']);
     297      currentParsePosition := currentParsePosition + length(aValue);
     298      result := true;
     299      exit;
     300    end;
     301    result := false;
     302  end;
     303
     304
     305  Function ParseWindowPositionPart(const aPart: String; const aScreenDimension: longint): longint;
     306  Var
     307    tmpPart : String;
     308  Begin
     309    if aPart = '' then
     310      raise EParsingFailed.Create('Missing position element');
     311
     312    if StrEndsWithIgnoringCase(aPart, 'P') then
     313    begin
     314      tmpPart := copy(aPart, 1, length(aPart)-1);
     315      if tmpPart = '' then
     316        raise EParsingFailed.Create('Missing position element');
     317
     318      Result := StrToInt(tmpPart);
     319      if Result < 0 then
     320        Result := 0;
     321      if Result > 100 then
     322        Result := 100;
     323      Result := Round(Result / 100 * aScreenDimension);
     324    end
     325    else
     326    begin
     327      Result := StrToInt(aPart);
     328    end;
     329  end;
     330
     331  Function ParseWindowPosition(const aParamValue: String): TWindowPosition;
     332  Var
     333    tmpParts : TStringList;
     334  Begin
     335    tmpParts := TStringList.Create;
     336    StrExtractStrings(tmpParts, aParamValue, [','], '\');
     337
     338    result.Left := ParseWindowPositionPart(tmpParts[0], WinQuerySysValue(HWND_DESKTOP, SV_CXSCREEN));
     339    result.Bottom := ParseWindowPositionPart(tmpParts[1], WinQuerySysValue(HWND_DESKTOP, SV_CYSCREEN));
     340
     341    result.Width := ParseWindowPositionPart(tmpParts[2], WinQuerySysValue(HWND_DESKTOP, SV_CXSCREEN));
     342    if result.Width < 50 then
     343      result.Width := 50;
     344
     345    result.Height := ParseWindowPositionPart(tmpParts[3], WinQuerySysValue(HWND_DESKTOP, SV_CYSCREEN));
     346    if result.Height < 50 then
     347      result.Height := 50;
     348
     349    tmpParts.Destroy;
     350  end;
     351
     352
     353  Procedure TCmdLineParameters.parseSwitch(aCmdLineString : String);
     354  var
     355    tmpCurrentChar : char;
     356    tmpText : String;
     357    tmpValue : String;
     358  begin
     359    // lang
     360    if handleParamWithValue(aCmdLineString, 'lang', tmpValue) then
     361    begin
     362      language := tmpValue;
     363      exit;
     364    end;
     365
     366    // title
     367    if handleParamWithValue(aCmdLineString, 'title', tmpValue) then
     368    begin
     369      windowTitle := tmpValue;
     370      exit;
     371    end;
     372
     373    // HM
     374    if handleParamWithValue(aCmdLineString, 'hm', tmpValue) then
     375    begin
     376      try
     377        helpManagerWindow := StrToInt(tmpValue);
     378        helpManagerFlag := true;
     379      except
     380        on e:Exception do
     381        begin
     382          showUsageFlag := true;
     383        end;
     384      end;
     385      exit;
     386    end;
     387
     388    // owner
     389    if handleParamWithValue(aCmdLineString, 'owner', tmpValue) then
     390    begin
     391      try
     392        ownerWindow := StrToInt(tmpValue);
     393      except
     394        on e:Exception do
     395        begin
     396          showUsageFlag := true;
     397        end;
     398      end;
     399      exit;
     400    end;
     401
     402    // pos
     403    if handleParamWithValue(aCmdLineString, 'pos', tmpValue) then
     404    begin
     405      windowPosition := ParseWindowPosition(tmpValue);
     406      windowPositionFlag := true;
     407      exit;
     408    end;
     409
     410    // check the next char
     411    tmpCurrentChar := aCmdLineString[currentParsePosition + 1];
     412    Case tmpCurrentChar of
     413      'h', 'H', '?' :
     414        begin
     415          currentParsePosition := currentParsePosition + 2;
     416          showUsageFlag := true;
     417
     418          // check for 'help'
     419          tmpText := copy(aCmdLineString, currentParsePosition, 3);
     420          tmpText := lowercase(tmpText);
     421
     422          if ('elp' = tmpText) then
    196423          begin
    197                if length(filenames) = 0 then
    198                begin
    199                    // filename
    200                    fileNames := tmpParameter;
    201                end
    202                else
    203                begin
    204                    // search (topic) parameter... append all remaining thingies
    205                    if topics <> '' then
    206                    begin
    207                        topics := topics + ' ';
    208                    end;
    209                    topics := topics + tmpParameter;
    210                end;
     424            currentParsePosition := currentParsePosition + 3;
    211425          end;
    212       end;
    213 
    214       ProfileEvent('Parameters parsed');
    215       ProfileEvent('  Filename(s): ' + fileNames);
    216       ProfileEvent('  Topic(s): ' + topics);
    217       ProfileEvent( '...done' );
    218   end;
    219 
    220 
    221 FUNCTION nativeOS2GetCmdLineParameter : STRING;
     426        end;
     427
     428      's', 'S' :
     429        begin
     430          currentParsePosition := currentParsePosition + 2;
     431          searchFlag := true;
     432        end;
     433
     434      'g', 'G' :
     435        begin
     436          currentParsePosition := currentParsePosition + 2;
     437          globalSearchFlag := true;
     438        end;
     439
     440      else
     441        begin
     442          raise EParsingFailed.Create('Unsupported switch');
     443        end;
     444      end;
     445  end;
     446
     447
     448  FUNCTION nativeOS2GetCmdLineParameter : STRING;
    222449  VAR
    223      tmpPtib : PTIB;       /* thread information block */
    224      tmpPpib : PPIB;       /* process information block */
    225      tmpCmd  : PCHAR;
    226      tmpResult : PCHAR;
     450    tmpPtib : PTIB;       // thread information block
     451    tmpPpib : PPIB;       // process information block
     452    tmpCmd  : PCHAR;
     453    tmpResult : PCHAR;
    227454
    228455  BEGIN
    229      DosGetInfoBlocks(tmpPtib, tmpPpib);
    230      tmpCmd := tmpPpib^.pib_pchcmd;
    231      tmpResult := tmpCmd + StrLen(tmpCmd) + 1;
    232      nativeOS2GetCmdLineParameter := StrPas(tmpResult);
     456    // ask the system
     457    DosGetInfoBlocks(tmpPtib, tmpPpib);
     458    tmpCmd := tmpPpib^.pib_pchcmd;
     459    // the fist element (null terminated) is the
     460    // called command itself
     461    // skip to the next null terminated string
     462    // these are the parameters
     463    tmpResult := tmpCmd + StrLen(tmpCmd) + 1;
     464    result := StrPas(tmpResult);
    233465  END;
    234 
    235 
    236 FUNCTION splitCmdLineParameter(aCmdLineString : String; var aResult : TStringList) : integer;
    237  CONST
    238      STATE_BEFORE = 0;
    239      STATE_INSIDE = 1;
    240      STATE_START_QUOTE = 2;
    241      STATE_INSIDE_QUOTED = 3;
    242      STATE_INSIDE_QUOTED_START_QUOTE = 4;
    243   VAR
    244      i : Integer;
    245      tmpCurrentChar : char;
    246      tmpState : INTEGER;
    247      tmpCurrentCommand : String;
    248 
    249   BEGIN
    250      result := SUCCESS;
    251      aResult.Clear;
    252 
    253      tmpState := STATE_BEFORE;
    254      tmpCurrentCommand := '';
    255      for i:=1 to length(aCmdLineString) do
    256      begin
    257           tmpCurrentChar := aCmdLineString[i];
    258 
    259           Case tmpCurrentChar of
    260           ' ' :
    261             begin
    262                Case tmpState of
    263                STATE_BEFORE : {do nothing};
    264                STATE_INSIDE :
    265                  begin
    266                     aResult.add(tmpCurrentCommand);
    267                     tmpCurrentCommand := '';
    268                     tmpState := STATE_BEFORE;
    269                  end;
    270                STATE_INSIDE_QUOTED_START_QUOTE :
    271                  begin
    272                     aResult.add(tmpCurrentCommand);
    273                     tmpCurrentCommand := '';
    274                     tmpState := STATE_BEFORE;
    275                  end;
    276                ELSE
    277                  begin
    278                     tmpCurrentCommand := tmpCurrentCommand + tmpCurrentChar;
    279                  end;
    280                end;
    281             end;
    282 
    283           '"' :
    284             begin
    285                Case tmpState of
    286                STATE_START_QUOTE :
    287                  begin
    288                     tmpState := STATE_INSIDE_QUOTED_START_QUOTE;
    289                  end;
    290                STATE_INSIDE_QUOTED :
    291                     tmpState := STATE_INSIDE_QUOTED_START_QUOTE;
    292                STATE_INSIDE_QUOTED_START_QUOTE :
    293                  begin
    294                     tmpState := STATE_INSIDE_QUOTED;
    295                     tmpCurrentCommand := tmpCurrentCommand + tmpCurrentChar;
    296                  end;
    297                ELSE
    298                     tmpState := STATE_START_QUOTE;
    299                end;
    300             end;
    301           ELSE
    302             begin
    303                Case tmpState of
    304                STATE_BEFORE :
    305                  begin
    306                     tmpState := STATE_INSIDE;
    307                     tmpCurrentCommand := tmpCurrentCommand + tmpCurrentChar;
    308                  end;
    309                STATE_INSIDE :
    310                  begin
    311                     tmpState := STATE_INSIDE;
    312                     tmpCurrentCommand := tmpCurrentCommand + tmpCurrentChar;
    313                  end;
    314                STATE_START_QUOTE :
    315                  begin
    316                     tmpState := STATE_INSIDE_QUOTED;
    317                     tmpCurrentCommand := tmpCurrentCommand + tmpCurrentChar;
    318                  end;
    319                STATE_INSIDE_QUOTED :
    320                  begin
    321                     tmpCurrentCommand := tmpCurrentCommand + tmpCurrentChar;
    322                  end;
    323                STATE_INSIDE_QUOTED_START_QUOTE :
    324                  begin
    325                     tmpState := STATE_INSIDE;
    326                     tmpCurrentCommand := tmpCurrentCommand + tmpCurrentChar;
    327                  end;
    328                end;
    329             end;
    330           end;
    331      end;
    332 
    333      Case tmpState of
    334      STATE_BEFORE : { nothing to do};
    335      STATE_INSIDE :
    336        begin
    337           aResult.add(tmpCurrentCommand);
    338        end;
    339      STATE_START_QUOTE :
    340        begin
    341           result := ERROR_UNMATCHED_QUOTE;
    342        end;
    343      STATE_INSIDE_QUOTED_START_QUOTE :
    344        begin
    345           if (0 < length(tmpCurrentCommand)) then
    346           begin
    347             aResult.add(tmpCurrentCommand);
    348           end;
    349        end;
    350      STATE_INSIDE_QUOTED :
    351        begin
    352           result := ERROR_UNMATCHED_QUOTE;
    353           if (0 < length(tmpCurrentCommand)) then
    354           begin
    355             aResult.add(tmpCurrentCommand);
    356           end;
    357        end;
    358      ELSE
    359        begin
    360           result := ERROR_UNMATCHED_QUOTE;
    361           if (0 < length(tmpCurrentCommand)) then
    362           begin
    363             aResult.add(tmpCurrentCommand);
    364           end;
    365        end;
    366      end;
    367   END;
    368 
    369 
    370 FUNCTION MatchValueParam( const aParam: string; const aFlag: string; var aValue: string ): boolean;
    371 begin
    372   Result := false;
    373 
    374   if aParam = '' then
    375     exit;
    376 
    377   if     ( aParam[ 1 ] <> '/' )
    378      and ( aParam[ 1 ] <> '-' ) then
    379     exit;
    380 
    381   if CompareText(copy(aParam, 2, length(aFlag)), aFlag) <> 0 then
    382     exit;
    383 
    384   Result := true;
    385 
    386   aValue := copy(aParam, 2 + length(aFlag), length(aParam));
    387   if aValue <> '' then
    388     if aValue[ 1 ] = ':' then
    389       delete(aValue, 1, 1 );
    390 end;
    391 
    392 
    393 FUNCTION MatchFlagParam(const aParam: string; const aFlag: string ): boolean;
    394 begin
    395   Result := false;
    396 
    397   if aParam = '' then
    398     exit;
    399 
    400   if     (aParam[ 1 ] <> '/' )
    401      and (aParam[ 1 ] <> '-' ) then
    402     exit;
    403   Result := CompareText(copy(aParam, 2, length(aParam)-1), aFlag) = 0;
    404 end;
    405 
    406 
    407 FUNCTION ExtractPositionElement(Var aParamValue: string; aScreenDimension: longint ): longint;
    408 var
    409   tmpElement: string;
    410 begin
    411   tmpElement := ExtractNextValue(aParamValue, ',' );
    412   if tmpElement = '' then
    413     raise Exception.Create('Missing position element');
    414   if StrEnds('P', tmpElement) then
    415   begin
    416     Delete(tmpElement, length(tmpElement), 1);
    417     if tmpElement = '' then
    418       raise Exception.Create('Missing position element');
    419     Result := StrToInt(tmpElement);
    420     if Result < 0 then
    421       Result := 0;
    422     if Result > 100 then
    423       Result := 100;
    424     Result := Round(Result / 100 * aScreenDimension);
    425   end
    426   else
    427   begin
    428     Result := StrToInt(tmpElement);
    429   end;
    430 end;
    431 
    432 FUNCTION SystemMetrics(aSystemMetric : LONG) : LongInt;
    433 Begin
    434   Result := WinQuerySysValue(HWND_DESKTOP, aSystemMetric);
    435 end;
    436 
    437 FUNCTION ExtractPositionSpec(aParamValue: string; Var aPosition: TWindowPosition ): boolean;
    438 begin
    439   try
    440     aPosition.Left := ExtractPositionElement(aParamValue, SystemMetrics(SV_CXSCREEN));
    441     aPosition.Bottom := ExtractPositionElement(aParamValue, SystemMetrics(SV_CYSCREEN));
    442     aPosition.Width := ExtractPositionElement(aParamValue, SystemMetrics(SV_CXSCREEN));
    443     if aPosition.Width < 50 then
    444       aPosition.Width := 50;
    445     aPosition.Height := ExtractPositionElement(aParamValue, SystemMetrics(SV_CYSCREEN));
    446     if aPosition.Height < 50 then
    447       aPosition.Height := 50;
    448     Result := true;
    449   except
    450     Result := false;
    451   end;
    452 end;
    453 
    454 
    455466END.
Note: See TracChangeset for help on using the changeset viewer.