home *** CD-ROM | disk | FTP | other *** search
/ PC World 2000 October / PCWorld_2000-10_cd2.bin / Borland / interbase / IBConsole_src.ZIP / ibconsole / frmuDBShutdown.pas < prev    next >
Pascal/Delphi Source File  |  2000-07-24  |  21KB  |  597 lines

  1. {
  2.  * The contents of this file are subject to the InterBase Public License
  3.  * Version 1.0 (the "License"); you may not use this file except in
  4.  * compliance with the License.
  5.  * 
  6.  * You may obtain a copy of the License at http://www.Inprise.com/IPL.html.
  7.  * 
  8.  * Software distributed under the License is distributed on an "AS IS"
  9.  * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
  10.  * the License for the specific language governing rights and limitations
  11.  * under the License.  The Original Code was created by Inprise
  12.  * Corporation and its predecessors.
  13.  * 
  14.  * Portions created by Inprise Corporation are Copyright (C) Inprise
  15.  * Corporation. All Rights Reserved.
  16.  * 
  17.  * Contributor(s): ______________________________________.
  18. }
  19.  
  20. {****************************************************************
  21. *
  22. *  f r m u D B S h u t D o w n
  23. *
  24. ****************************************************************
  25. *  Author: The Client Server Factory Inc.
  26. *  Date:   March 1, 1999
  27. *
  28. *  Description:  This unit provides an interface to shutdown
  29. *                a specified database.
  30. *
  31. *****************************************************************
  32. * Revisions:
  33. *
  34. *****************************************************************}
  35.  
  36. unit frmuDBShutdown;
  37.  
  38. interface
  39.  
  40. uses
  41.   Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
  42.   zluibcClasses, StdCtrls, ComCtrls, ExtCtrls, IBServices, IB, Grids, frmuDlgClass;
  43.  
  44. type
  45.   TfrmDBShutdown = class(TDialog)
  46.     bvlLine1: TBevel;
  47.     lblDatabaseName: TLabel;
  48.     lblOptions: TLabel;
  49.     sgOptions: TStringGrid;
  50.     btnOK: TButton;
  51.     btnCancel: TButton;
  52.     stxDatabaseName: TLabel;
  53.     pnlOptionName: TPanel;
  54.     cbOptions: TComboBox;
  55.     function FormHelp(Command: Word; Data: Integer; var CallHelp: Boolean): Boolean;
  56.     procedure FormCreate(Sender: TObject);
  57.     procedure btnCancelClick(Sender: TObject);
  58.     procedure btnOKClick(Sender: TObject);
  59.     procedure cbOptionsDblClick(Sender: TObject);
  60.     procedure cbOptionsExit(Sender: TObject);
  61.     procedure cbOptionsKeyDown(Sender: TObject; var Key: Word; Shift: TShiftState);
  62.     procedure sgOptionsDrawCell(Sender: TObject; ACol, ARow: Integer; Rect: TRect; State: TGridDrawState);
  63.     procedure sgOptionsSelectCell(Sender: TObject; ACol, ARow: Integer; var CanSelect: Boolean);
  64.   private
  65.     { Private declarations }
  66.     function VerifyInputData(): boolean;
  67.     procedure WMNCLButtonDown( var Message: TWMNCLBUTTONDOWN ); message WM_NCLBUTTONDOWN ;
  68.   public
  69.     { Public declarations }
  70.   end;
  71.  
  72. function DoDBShutdown(const CurrSelServer : TibcServerNode; const CurrSelDatabase: TibcDatabaseNode): integer;
  73.  
  74. implementation
  75.  
  76. uses
  77.   zluGlobal, zluUtility, frmuMessage, zluContextHelp, fileCtrl, IBErrorCodes,
  78.   frmuMain;
  79.  
  80. {$R *.DFM}
  81.  
  82. const
  83.   OPTION_NAME_COL = 0;                 // option name column position
  84.   OPTION_VALUE_COL = 1;                // option value column position
  85.   SHUTDOWN_OPTIONS_ROW = 0;            // shutdown option row position
  86.   SHUTDOWN_TIMEOUT_ROW = 1;            // shutdown timeout row position
  87.  
  88. {****************************************************************
  89. *
  90. *  D o D B S h u t d o w n ( )
  91. *
  92. ****************************************************************
  93. *  Author: The Client Server Factory Inc.
  94. *  Date:   March 1, 1999
  95. *
  96. *  Input:  TibcServerNode   - specifies the currently selected
  97. *                             server
  98. *          TibcDatabaseNode - specifies the database to be
  99. *                             shutdown
  100. *
  101. *  Return: Integer - indicates a success or failure during the
  102. *                    create database task
  103. *
  104. *  Description: This procedure performs the task of shutting
  105. *               down the specified database.
  106. *
  107. *****************************************************************
  108. * Revisions:
  109. *
  110. *****************************************************************}
  111. function DoDBShutdown(const CurrSelServer : TibcServerNode; const CurrSelDatabase: TibcDatabaseNode): integer;
  112. var
  113.   frmDBShutdown : TfrmDBShutdown;
  114.   lConfig       : TIBConfigService;
  115.   lShutdownMode : TShutdownMode;
  116.   iWait         : Integer;
  117.   lReconnect    : Boolean;
  118. begin
  119.   // create form and config service objects
  120.   frmDBShutdown := TfrmDBShutdown.Create(Application);
  121.   lConfig := TIBConfigService.Create(Nil);
  122.   lReconnect := False;
  123.  
  124.   try
  125.     frmDBShutdown.stxDatabaseName.Caption := MinimizeName (CurrSelDatabase.NodeName,
  126.       frmDBShutdown.stxDatabaseName.Canvas,
  127.       (frmDBShutdown.stxDatabaseName.ClientRect.Left - frmDBShutdown.stxDatabaseName.ClientRect.Right));
  128.     frmDBShutdown.stxDatabaseName.Hint := CurrSelDatabase.NodeName;
  129.     frmDBShutdown.ShowModal;
  130.  
  131.     // show form as modal dialog box
  132.     if (frmDBShutdown.ModalResult = mrOK) and
  133.        (not frmDBShutdown.GetErrorState) then
  134.     begin
  135.       // repaint the screen
  136.       Application.ProcessMessages;
  137.       Screen.Cursor := crHourGlass;
  138.  
  139.       // attempt to login to server
  140.       try
  141.         lConfig.LoginPrompt:=False;
  142.         lConfig.ServerName:=CurrSelServer.ServerName;
  143.         lConfig.Protocol:=CurrSelServer.Server.Protocol;
  144.         lConfig.DatabaseName := CurrSelDatabase.DatabaseFiles.Strings[0];
  145.  
  146.         {
  147.         case CurrSelServer.Server.Protocol of
  148.           TCP       : lConfig.DatabaseName := Format('%s:%s',[CurrSelServer.ServerName,CurrSelDatabase.DatabaseFiles.Strings[0]]);
  149.           NamedPipe : lConfig.DatabaseName := Format('\\%s\%s',[CurrSelServer.ServerName,CurrSelDatabase.DatabaseFiles.Strings[0]]);
  150.           SPX       : lConfig.DatabaseName := Format('%s@%s',[CurrSelServer.ServerName,CurrSelDatabase.DatabaseFiles.Strings[0]]);
  151.           Local     : lConfig.DatabaseName := CurrSelDatabase.DatabaseFiles.Strings[0];
  152.         end;
  153.         }
  154.  
  155.         lConfig.Params.Assign(CurrSelServer.Server.Params);
  156.         lConfig.Attach;
  157.       except                           // if an error occurs
  158.         on E:EIBError do               // trap it and show
  159.         begin                          // error message
  160.           DisplayMsg(ERR_SERVER_LOGIN, E.Message);
  161.           result := FAILURE;           // set result as false
  162.           if (E.IBErrorCode = isc_lost_db_connection) or
  163.              (E.IBErrorCode = isc_unavailable) or
  164.              (E.IBErrorCode = isc_network_error) then
  165.             frmMain.SetErrorState;
  166.           Exit;
  167.         end;
  168.       end;
  169.  
  170.       // if ConfigService is avtive then
  171.       if lConfig.Active then
  172.       begin
  173.         // assign shutdown mode options
  174.         if frmDBShutdown.sgOptions.Cells[1,0] = 'Deny new connections while waiting' then
  175.         begin
  176.           lShutdownMode := DenyAttachment;
  177.         end
  178.         else if frmDBShutdown.sgOptions.Cells[1,0] = 'Deny new transactions while waiting' then
  179.         begin
  180.           lShutdownMode := DenyTransaction;
  181.         end
  182.         else  // if frmDBShutdown.sgOptions.Cells[1,0] = 'Force shutdown after timeout' then
  183.         begin
  184.           lShutdownMode := Forced;
  185.         end;
  186.  
  187.         // assign timeout
  188.         iWait := StrToInt(frmDBShutdown.sgOptions.Cells[1,1]);
  189.  
  190.         // check if IBConsole is connected, if so then close connection to db
  191.         if CurrSelDatabase.Database.TestConnected then
  192.         begin
  193.           CurrSelDatabase.Database.ForceClose;
  194.           lReconnect := True;
  195.         end;
  196.  
  197.         try
  198.           // try to shutdown the database
  199.           lConfig.ShutdownDatabase(lShutDownMode, iWait);
  200.  
  201.           // wait while processing
  202.           while (lConfig.IsServiceRunning) and (not gApplShutdown) do
  203.           begin
  204.             Application.ProcessMessages;
  205.             Screen.Cursor := crHourGlass;
  206.           end;
  207.  
  208.           // if ConfigService is no longer active then detach
  209.           if lConfig.Active then
  210.             lConfig.Detach();
  211.  
  212.           // try to reconnect to the database using the username
  213.           // and password supplied for the server
  214.           try
  215.             if (lReconnect) and (not CurrSelDatabase.Database.TestConnected) then
  216.             begin
  217.               CurrSelDatabase.Database.Params.Clear;
  218.               CurrSelDatabase.Database.Params.Add(Format('isc_dpb_user_name=%s',[CurrSelServer.UserName]));
  219.               CurrSelDatabase.Database.Params.Add(Format('isc_dpb_password=%s',[CurrSelServer.Password]));
  220.               CurrSelDatabase.Database.Connected := True;
  221.             end;
  222.  
  223.             DisplayMsg(INF_DATABASE_SHUTDOWN, 'The database has been shut down and is currently in single-user mode.');
  224.  
  225.           // check for an exception
  226.           except                         // if an exception occurs when reattaching then
  227.             on E:EIBInterBaseError do    // show message
  228.             begin
  229.               DisplayMsg(INF_DATABASE_SHUTDOWN, E.Message);
  230.             end;
  231.           end;
  232.         except
  233.           on E:EIBError do
  234.           begin
  235.             DisplayMsg(ERR_DB_SHUTDOWN, E.Message);
  236.             Result := Failure;
  237.             if (E.IBErrorCode = isc_lost_db_connection) or
  238.                (E.IBErrorCode = isc_unavailable) or
  239.                (E.IBErrorCode = isc_network_error) then
  240.               frmMain.SetErrorState;
  241.             Exit;
  242.           end
  243.         end;
  244.         result := SUCCESS;             // set result as true
  245.       end
  246.       else                             // if ConfigService is not active
  247.         result := FAILURE;             // set result as false
  248.     end
  249.     else                               // if form can't be shown
  250.       result := FAILURE;               // set result as false
  251.   finally
  252.     // reconnect to db if it was connected before shutdown occured
  253.     if (lReconnect) and (not CurrSelDatabase.Database.TestConnected) then
  254.     begin
  255.       CurrSelDatabase.Database.Params.Clear;
  256.       CurrSelDatabase.Database.Params.Add(Format('isc_dpb_user_name=%s',[CurrSelServer.UserName]));
  257.       CurrSelDatabase.Database.Params.Add(Format('isc_dpb_password=%s',[CurrSelServer.Password]));
  258.       CurrSelDatabase.Database.Connected := True;
  259.     end;
  260.  
  261.     Screen.Cursor := crDefault;
  262.     // deallocate memory
  263.     if lConfig.Active then
  264.       lConfig.Detach();
  265.     lConfig.Free;
  266.     frmDBShutdown.Free;
  267.   end;
  268. end;
  269.  
  270. function TfrmDBShutdown.FormHelp(Command: Word; Data: Integer; var CallHelp: Boolean): Boolean;
  271. begin
  272.   CallHelp := False;
  273.   Result := WinHelp(WindowHandle,CONTEXT_HELP_FILE,HELP_CONTEXT,DATABASE_SHUTDOWN);
  274. end;
  275.  
  276. {****************************************************************
  277. *
  278. *  F o r m C r e a t e
  279. *
  280. ****************************************************************
  281. *  Author: The Client Server Factory Inc.
  282. *  Date:   March 1, 1999
  283. *
  284. *  Input:  TObject - object that initiated the event
  285. *
  286. *  Return: None
  287. *
  288. *
  289. *  Description: This procedure is triggered when the form is
  290. *               created.  It is responsible for populating the
  291. *               string grids with default values.
  292. *
  293. *****************************************************************
  294. * Revisions:
  295. *
  296. *****************************************************************}
  297.  
  298. procedure TfrmDBShutdown.FormCreate(Sender: TObject);
  299. begin
  300.   inherited;
  301.   sgOptions.DefaultRowHeight := cbOptions.Height;
  302.   cbOptions.Visible := True;
  303.   pnlOptionName.Visible := True;
  304.  
  305.   sgOptions.RowCount := 2;
  306.  
  307.   sgOptions.Cells[OPTION_NAME_COL,SHUTDOWN_OPTIONS_ROW] := 'Shutdown';
  308.   sgOptions.Cells[OPTION_VALUE_COL,SHUTDOWN_OPTIONS_ROW] := 'Force shutdown after timeout';
  309.  
  310.   sgOptions.Cells[OPTION_NAME_COL,SHUTDOWN_TIMEOUT_ROW] := 'Shutdown Timeout';
  311.   sgOptions.Cells[OPTION_VALUE_COL,SHUTDOWN_TIMEOUT_ROW] := '5';
  312.  
  313.   pnlOptionName.Caption := 'Shutdown';
  314.   cbOptions.Items.Add('Deny new connections while waiting');
  315.   cbOptions.Items.Add('Deny new transactions while waiting');
  316.   cbOptions.Items.Add('Force shutdown after timeout');
  317.   cbOptions.ItemIndex := 2;
  318. end;
  319.  
  320. procedure TfrmDBShutdown.btnCancelClick(Sender: TObject);
  321. begin
  322.   ModalResult := mrCancel;
  323. end;
  324.  
  325. procedure TfrmDBShutdown.btnOKClick(Sender: TObject);
  326. begin
  327.   if VerifyInputData() then
  328.     ModalResult := mrOK;
  329. end;
  330.  
  331. procedure TfrmDBShutdown.cbOptionsDblClick(Sender: TObject);
  332. begin
  333.   if (sgOptions.Col = OPTION_VALUE_COL) or (sgOptions.Col = OPTION_NAME_COL) then
  334.   begin
  335.     if cbOptions.ItemIndex = cbOptions.Items.Count - 1 then
  336.       cbOptions.ItemIndex := 0
  337.     else
  338.       cbOptions.ItemIndex := cbOptions.ItemIndex + 1;
  339.  
  340.     if sgOptions.Col = OPTION_VALUE_COL then
  341.       sgOptions.Cells[sgOptions.Col,sgOptions.Row] := cbOptions.Items[cbOptions.ItemIndex];
  342.  
  343.     // cbOptions.Visible := True;
  344.     // sgOptions.SetFocus;
  345.   end;
  346. end;
  347.  
  348. procedure TfrmDBShutdown.cbOptionsExit(Sender: TObject);
  349. var
  350.   lR     : TRect;
  351.   iIndex : Integer;
  352. begin
  353.   iIndex := cbOptions.Items.IndexOf(cbOptions.Text);
  354.  
  355.   if (iIndex = -1) and (sgOptions.Row <> SHUTDOWN_TIMEOUT_ROW) then
  356.   begin
  357.     MessageDlg('Invalid option value', mtError, [mbOK],0);
  358.  
  359.     cbOptions.ItemIndex := 0;
  360.     //Size and position the combo box to fit the cell
  361.     lR := sgOptions.CellRect(OPTION_VALUE_COL, sgOptions.Row);
  362.     lR.Left := lR.Left + sgOptions.Left;
  363.     lR.Right := lR.Right + sgOptions.Left;
  364.     lR.Top := lR.Top + sgOptions.Top;
  365.     lR.Bottom := lR.Bottom + sgOptions.Top;
  366.     cbOptions.Left := lR.Left + 1;
  367.     cbOptions.Top := lR.Top + 1;
  368.     cbOptions.Width := (lR.Right + 1) - lR.Left;
  369.     cbOptions.Height := (lR.Bottom + 1) - lR.Top;
  370.     cbOptions.Visible := True;
  371.     cbOptions.SetFocus;
  372.   end
  373.   else if (sgOptions.Row = SHUTDOWN_TIMEOUT_ROW) then
  374.   begin
  375.     sgOptions.Cells[OPTION_VALUE_COL,sgOptions.Row] := cbOptions.Text;
  376.   end
  377.   else if (sgOptions.Col <> OPTION_NAME_COL) then
  378.   begin
  379.     sgOptions.Cells[sgOptions.Col,sgOptions.Row] := cbOptions.Items[iIndex];
  380.   end
  381.   else
  382.   begin
  383.     sgOptions.Cells[OPTION_VALUE_COL,sgOptions.Row] := cbOptions.Items[iIndex];
  384.   end;
  385. end;
  386.  
  387. procedure TfrmDBShutdown.cbOptionsKeyDown(Sender: TObject; var Key: Word;
  388.   Shift: TShiftState);
  389. begin
  390.   if (Key = VK_DOWN) then
  391.     cbOptions.DroppedDown := true;
  392. end;
  393.  
  394. {****************************************************************
  395. *
  396. *  s g O p t i o n s D r a w C e l l
  397. *
  398. ****************************************************************
  399. *  Author: The Client Server Factory Inc.
  400. *  Date:   March 1, 1999
  401. *
  402. *  Input:  TObject - object that initiated the event
  403. *          Integer - currently selected column
  404. *          Integer - currently selected row
  405. *          TRect   - coordinates
  406. *          TGridDrawState - drawing state of grid
  407. *
  408. *  Return: None
  409. *
  410. *
  411. *  Description: This procedure draws contents to a specified cell in
  412. *               the options string grid.
  413. *
  414. *****************************************************************
  415. * Revisions:
  416. *
  417. *****************************************************************}
  418. procedure TfrmDBShutdown.sgOptionsDrawCell(Sender: TObject; ACol,
  419.   ARow: Integer; Rect: TRect; State: TGridDrawState);
  420. const
  421.   INDENT = 2;
  422. var
  423.   lLeft: integer;
  424.   lText: string;
  425. begin
  426.   with sgOptions.canvas do
  427.   begin
  428.     if (ACol = OPTION_VALUE_COL) then
  429.     begin
  430.       font.color := clBlue;
  431.       if brush.color = clHighlight then
  432.         font.color := clWhite;
  433.       lText := sgOptions.Cells[ACol,ARow];
  434.       lLeft := Rect.Left + INDENT;
  435.       TextRect(Rect, lLeft, Rect.top + INDENT, lText);
  436.     end;
  437.   end;
  438. end;
  439.  
  440. {****************************************************************
  441. *
  442. *  s g O p t i o n s S e l e c t C e l l
  443. *
  444. ****************************************************************
  445. *  Author: The Client Server Factory Inc.
  446. *  Date:   March 1, 1999
  447. *
  448. *  Input:  TObject - object that initiated the event
  449. *          Integer - currently selected column
  450. *          Integer - currently selected row
  451. *          Boolean - inidicates whether or not the grid may
  452. 8                    selected
  453. *
  454. *  Return: None
  455. *
  456. *
  457. *  Description: This procedure determines whether or not the
  458. *               currently selected cell may be selected in the
  459. *               Options string grid.  it then shows the combo
  460. *               box and populates it
  461. *               with the appropriate values.
  462. *
  463. *****************************************************************
  464. * Revisions:
  465. *
  466. *****************************************************************}
  467. procedure TfrmDBShutdown.sgOptionsSelectCell(Sender: TObject; ACol,
  468.   ARow: Integer; var CanSelect: Boolean);
  469. var
  470.   lR, lName : TRect;
  471. begin
  472.   cbOptions.Items.Clear;
  473.   case ARow of
  474.     SHUTDOWN_OPTIONS_ROW:              // if shutdown mode row then
  475.     begin                              // show combo box and populate it
  476.       cbOptions.Style:=csDropDown;
  477.       cbOptions.Items.Add('Deny new connections while waiting');
  478.       cbOptions.Items.Add('Deny new transactions while waiting');
  479.       cbOptions.Items.Add('Force shutdown after timeout');
  480.     end;
  481.     SHUTDOWN_TIMEOUT_ROW:              // if timeout row then
  482.     begin                              // show combo as edit box
  483.       cbOptions.Style:=csSimple;
  484.       cbOptions.Text:=sgOptions.Cells[1,SHUTDOWN_TIMEOUT_ROW];
  485.     end;
  486.   end;
  487.  
  488.   pnlOptionName.Caption := sgOptions.Cells[OPTION_NAME_COL, ARow];
  489.  
  490.   if ACol = OPTION_NAME_COL then       // copy selected combo item to proper grid location
  491.     cbOptions.ItemIndex := cbOptions.Items.IndexOf(sgOptions.Cells[ACol+1,ARow])
  492.   else if ACol = OPTION_VALUE_COL then
  493.   begin
  494.     cbOptions.ItemIndex := cbOptions.Items.IndexOf(sgOptions.Cells[ACol,ARow]);
  495.     if (cbOptions.ItemIndex = -1) or (ARow = SHUTDOWN_TIMEOUT_ROW) then
  496.       cbOptions.Text := sgOptions.Cells[ACol,ARow];
  497.   end;
  498.  
  499.   if ACol = OPTION_NAME_COL then
  500.   begin
  501.     lName := sgOptions.CellRect(ACol, ARow);
  502.     lR := sgOptions.CellRect(ACol + 1, ARow);
  503.   end
  504.   else
  505.   begin
  506.     lName := sgOptions.CellRect(ACol - 1, ARow);
  507.     lR := sgOptions.CellRect(ACol, ARow);
  508.   end;
  509.  
  510.   // lName := sgOptions.CellRect(ACol, ARow);
  511.   lName.Left := lName.Left + sgOptions.Left;
  512.   lName.Right := lName.Right + sgOptions.Left;
  513.   lName.Top := lName.Top + sgOptions.Top;
  514.   lName.Bottom := lName.Bottom + sgOptions.Top;
  515.   pnlOptionName.Left := lName.Left + 1;
  516.   pnlOptionName.Top := lName.Top + 1;
  517.   pnlOptionName.Width := (lName.Right + 1) - lName.Left;
  518.   pnlOptionName.Height := (lName.Bottom + 1) - lName.Top;
  519.   pnlOptionName.Visible := True;
  520.  
  521.   // lR := sgOptions.CellRect(ACol, ARow);
  522.   lR.Left := lR.Left + sgOptions.Left;
  523.   lR.Right := lR.Right + sgOptions.Left;
  524.   lR.Top := lR.Top + sgOptions.Top;
  525.   lR.Bottom := lR.Bottom + sgOptions.Top;
  526.   cbOptions.Left := lR.Left + 1;
  527.   cbOptions.Top := lR.Top + 1;
  528.   cbOptions.Width := (lR.Right + 1) - lR.Left;
  529.   cbOptions.Height := (lR.Bottom + 1) - lR.Top;
  530.   cbOptions.Visible := True;
  531.   cbOptions.SetFocus;
  532. end;
  533.  
  534. {****************************************************************
  535. *
  536. *  V e r i f y I n p u t D a t a ( )
  537. *
  538. ****************************************************************
  539. *  Author: The Client Server Factory Inc.
  540. *  Date:   March 1, 1999
  541. *
  542. *  Input:  None
  543. *
  544. *  Return: Boolean - indicates whether or not all necessary
  545. *                    data was supplied and is correct.
  546. *
  547. *  Description: This procedure performs the task of validating
  548. *               the user entered data.
  549. *
  550. *****************************************************************
  551. * Revisions:
  552. *
  553. *****************************************************************}
  554. function TfrmDBShutdown.VerifyInputData(): boolean;
  555. var
  556.   iWait : Integer;
  557. begin
  558.   result := true;                      // assume there are no errors
  559.  
  560.   // try to convert timeout to a numeric format
  561.   try
  562.     iWait:=StrToInt(sgOptions.Cells[1,1]);
  563.     // check value and make sure it's within range
  564.     if (iWait < 0) or (iWait > 32767) then
  565.     begin                              // show error message
  566.       DisplayMsg(ERR_NUMERIC_VALUE,'Value out of range!');
  567.       result := false;                 // set result as false
  568.       Exit;
  569.     end;
  570.   except
  571.     on EConvertError do
  572.     begin                              // if not a number, show error message
  573.       DisplayMsg(ERR_NUMERIC_VALUE,'');
  574.       result := false;                 // set result as false
  575.       Exit;
  576.     end;
  577.   end
  578. end;
  579.  
  580. procedure TfrmDBShutdown.WMNCLButtonDown( var Message: TWMNCLButtonDown );
  581. var
  582.   ScreenPt: TPoint;
  583.   ClientPt: TPoint;
  584. begin
  585.   ScreenPt.X := Message.XCursor;
  586.   ScreenPt.Y := Message.YCursor;
  587.   ClientPt := ScreenToClient( ScreenPt );
  588.   if( ClientPt.X > Width-45 )and (ClientPt.X < Width-29) then
  589.    begin
  590.     WinHelp(WindowHandle,CONTEXT_HELP_FILE,HELP_CONTEXT,DATABASE_SHUTDOWN);
  591.     Message.Result := 0;
  592.   end else
  593.    inherited;
  594. end;
  595.  
  596. end.
  597.