Input and Message Dialogs in Delphi

Delphi Provides many procedures and function to show a message or to get some data from users by input box.

ShowMessage
ShowMessage procedure displays a string of Text in a simple dialog with an OK button. It is used to inform the user of some information - no decision is needed by the user. Insert carriage return and line feed characters (#13#10) into the string to generate multi line message display.

begin
  // Show a simple message
  ShowMessage('Hello World');

  // Show a blank message
  ShowMessage('');

  // Split this into two lines
  ShowMessage('Hello '+#13#10+'World');
end;

ShowMessageFmt
The ShowMessageFmt procedure provides 'C' like formatting of multiple of simple data types into a string that is displayed in a single. It provides very precise control over this formatting. The Formatting parameter defines how the Data array is manipulated into the displayed string. The dialog has an OK button to allow the user to register the message and close the dialog. The Formatting string can comprise a mix of ordinary characters (that are passed unchanged to the result string), and data formatting characters. This formatting is best explained by the example code. In simple terms, each data formatting substring starts with a % and ends with a data type indicator : 

d = Decimal (integer)
e = Scientific
f = Fixed
g = General
m = Money
n = Number (floating)
p = Pointer
s = String
u = Unsigned decimal
x = Hexadecimal

The general format of each formatting substring is as follows:  
%[Index:][-][Width][.Precision]Type 
where the square brackets refer to optional parameters, and the : . - characters are literals, the first 2 of which are used to identify two of the optional 
arguments.

var
  sText : string;
begin
  // Just 1 data item
  ShowMessageFmt('%s', ['Hello']);

  // A mix of literal text and a data item
  ShowMessageFmt('String = %s', ['Hello']);

  sText := 'This is for test.';
  // Examples of each of the data types
  ShowMessageFmt('Decimal          = %d', [-123]);
  ShowMessageFmt('Exponent         = %e', [12345.678]);
  ShowMessageFmt('Fixed            = %f', [12345.678]);
  ShowMessageFmt('General          = %g', [12345.678]);
  ShowMessageFmt('Number           = %n', [12345.678]);
  ShowMessageFmt('Money            = %m', [12345.678]);
  ShowMessageFmt('Pointer          = %p', [addr(sText)]);
  ShowMessageFmt('String           = %s', ['Hello']);
  ShowMessageFmt('Unsigned decimal = %u', [123]);
  ShowMessageFmt('Hexadecimal      = %x', [140]);
end;

ShowMessagePos
The ShowMessagePos procedure displays a string of Text in a simple dialog with an OK button at the given XPos, YPos screen coordinates. The dialog is positioned with its top left at the given screen pixel coordinates. 

begin
  // Show a simple message at the default coordinates
  ShowMessage('Hello World');

  // Show a simple message at screen position 100, 200
  ShowMessagePos('Hello World', 100, 200);
end;

MessageDlg 
The MessageDlg() function is the VCL's enhanced message box and it provides a good alternative to the Win32's MessageBox() function. The MessageDlg function is used to display messages to the user. These messages may be informational, or warnings or whatever. There is complete freedom over the choice of buttons that the user may press to acknowledge the dialog. 
function MessageDlg(const Msg: string;
   DlgType: TMsgDlgType;
   Buttons: TMsgDlgButtons;
   HelpCtx: Integer): Integer; overload;

function MessageDlg(const Msg: string;
   DlgType: TMsgDlgType;
   Buttons: TMsgDlgButtons;
   HelpCtx: Integer;
   DefaultButton: TMsgDlgBtn): Integer; overload;
values:  
mtWarning Displays a exclamation symbol
mtError         Displays a red 'X'
mtInformation Displays an 'i' in a bubble
mtConfirmation Displays an question mark
mtCustom     Displays just the message

The Buttons value may be one or more of the following enumerated values : 
mbYes          Displays a 'Yes' button
mbNo       Displays a 'No' button
mbOK       Displays an 'OK' button
mbCancel       Displays a 'Cancel' button
mbAbort       Displays an 'Abort' button
mbRetry       Displays a 'Retry' button
mbIgnore       Displays an 'Ignore' button
mbAll       Displays an 'All' button
mbNoToAll       Displays a 'No to all' button
mbYesToAll      Displys a 'Yes to all' button
mbHelp       Displays a 'Help' button

Delphi provides a number of predefined button combinations:
mbYesNoCancel              = [mbYes,mbNO,mbCancel]
mbYesAllNoAllCancel = [mbYes,mbYesToAll, mbNo,mbNoToAll,mbCancel]
mbOKCancel         = [mbOK,mbCancel]
mbAbortRetryCancel = [mbAbort,mbRetry,mbCancel]
mbAbortIgnore         = [mbAbort,mbIgnore]

Return values....
mrYes = 6
mrNo = 7
mrOK = 1
mrCancel = 2
mrAbort = 3
mrRetry = 4
mrIgnore = 5
mrAll = 8
mrNoToAll = 9
mrYesToAll= 10

Example
var
  buttonSelected : Integer;
begin
  // Show a custom dialog
  buttonSelected := MessageDlg('Custom dialog',mtCustom, 
                              [mbYes,mbAll,mbCancel], 0);
  // Show the button type selected
  if buttonSelected = mrYes    then ShowMessage('Yes pressed');
  if buttonSelected = mrAll    then ShowMessage('All pressed');
  if buttonSelected = mrCancel then ShowMessage('Cancel pressed');
  
  // Show a confirmation dialog
  buttonSelected := MessageDlg('Confirmation',mtError, mbOKCancel, 0);

  // Show the button type selected
  if buttonSelected = mrOK     then ShowMessage('OK pressed');
  if buttonSelected = mrCancel then ShowMessage('Cancel pressed');  
end;

MessageDlgPos 
The MessageDlgPos() function provides extra possibilities to the programmer. 
It behaves exactly like the MessageDlg() function. To create a message box based on this function, use the syntaxes:
function MessageDlgPos( const Msg: string;
      DlgType: TMsgDlgType;
Buttons: TMsgDlgButtons;
HelpCtx: Integer;
X: Integer;
Y: Integer ): Integer; overload;

function MessageDlgPos( const Msg: string;
DlgType: TMsgDlgType;
Buttons: TMsgDlgButtons;
HelpCtx: Integer;
X: Integer;
Y: Integer;
DefaultButton: TMsgDlgBtn ): Integer; overload;
Example
begin
  // Show a confirmation dialog at 20,100
  buttonSelected := MessageDlgPos('Confirmation',mtError, mbOKCancel, 0, 20, 100);
    // Show a custom dialog at 20,100 coordinates
  buttonSelected := MessageDlgPos('Custom dialog',mtCustom, [mbYes,mbAll,mbCancel], 0, 20, 100);
end;

MessageBox
To support message boxes, the Win32 library provides a function named MessageBox(). The MessageBox() function takes three arguments. The first argument, Message, is a string representing the message that the user would read. The Message string could be a static sentence. It could be constructed from another control. Or it could be a combination of different string functions and operations.

procedure TForm1.btnMessageBoxClick(Sender: TObject);
begin
    Application.MessageBox('This operation can only be ' +
  'performed by an administrator.',
  0, 0);
end;

Messagebox buttons....
Constant         Buttons
MB_OK OK
MB_OKCANCEL OK  Cancel
MB_ABORTRETRYIGNORE Abort  Retry  Ignore
MB_YESNOCANCEL         Yes  No Cancel
MB_YESNO Yes  No
MB_RETRYCANCEL   Cancel
MB_HELP   Help
Message Icons.....
Value      Suited when
MB_ICONEXCLAMATION
MB_ICONWARNING     Warning the user of an action performed on the application
MB_ICONINFORMATION
MB_ICONASTERISK     Informing the user of a non-critical situation
MB_ICONQUESTION    Asking a question that expects a Yes or No, or a Yes, No, or Cancel answer
MB_ICONSTOP
MB_ICONERROR
MB_ICONHAND    A critical situation or error has occurred. This icon is appropriate when informing the user of a termination or deniability of an action
Default button...
Value         the default button would be
MB_DEFBUTTON1         The first button
MB_DEFBUTTON2         The second button
MB_DEFBUTTON3         The third button
MB_DEFBUTTON4         The fourth button
Return values...
If the user clicked  The return value is
OK IDOK
Cancel IDCANCEL
Abort IDABORT
Retry IDRETRY
Ignore IDIGNORE
Yes IDYES
No IDNO

InputBox
The inputbox function displays a simple dialog box with the given Caption and Prompt message. It asks the user to enter data in a text box on the dialog. A Default value is displayed in the text box. If the user presses OK, the default or user entered data is stored in the return string, otherwise an empty string is returned. If the user cancels the dialog, then the return . If the user cancels the dialog, then the return value is the default string. Use to ask the user for a data value, where you can give a sensible default value, to save the user unnecessary typing. This function returns a string value.

function InputBox(const ACaption: string;
 const APrompt: string;
 const ADefault: string): string;
Example....
var
  sValue : string;
begin
  // Keep asking the user for Country
  repeat
    sValue := inputbox('Enter Data', 'Please Enter Country', 'India');
  until sValue <> '';
  // Show Country
  ShowMessage('Country is '+sValue);
end;

InputQuery
Like the InputBox() function, the InputQuery() function is used to display a prompting dialog box to the user with the given Caption and Prompt message. 
If the user presses OK, the entered data is stored in the UserValue variable and the return value is True. If the user cancels the dialog, then the 
return value is False and any entered data is lost. Use to ask the user for simple data such as a name. This function returns a boolean value.

function InputQuery(const ACaption: string;
   const APrompt: string;
   var Value: string): Boolean;
var
  sValue : string;
begin
  // Keep asking the user for Country
  repeat
    if not InputQuery('Enter Data', 'Please Enter Country', sValue) then 
ShowMessage('User cancelled the dialog');
  until sValue <> '';
  // Show Country
  ShowMessage('Country is '+sValue);
end;

PromptForFileName 
The PromptForFileName function presents a dialog to the user allowing navigation to, and selection of a file. If the user presses OK the FileName variable is updated with the full drive/path/filename value for the selected file, and the return value is True. If the user presses Cancel, no updates are done, and the return value is False. The remaining parameters are all optional (although parameters used on the right mandate use of the preceding parameters) : 
Filter         = Used to limit the types of file displayed. The format is as follows : 
'Description|filter{|...}' 
For example, to show only .txt and .pas files : 
Text files (*.txt)|*.txt|Delphi files (*.pas)|*.pas 

DefaultExt = Used to define an extension to add to a new file name (if SaveDialog is True). 

Title     = Used to give a title to the dialog. 

InitialDir = Positions the dialog at a given directory. For example : 'C:Program Files' 

SaveDialog = Determines whether a new file can be selected for saving.
Example
var
  selectedFile   : string;
begin
  // Ask the user to select a file
  if promptforfilename(selectedFile,
                       'Text files (*.txt)|*.txt',
                       '',
                       'Select your project file',
                       'C:\',
                       False)  // Means not a Save dialog
  then
    // Display this full file/path value
    ShowMessage('Selected file = '+selectedFile)
  else
    ShowMessage('Cancel pressed');
end;

Developing our own dialog
I have used two example how to create our own dialogs by using TForm.
1.
We can design our own dialogs, that will work just like the Delphi dialogs that we discussed on above. In this example we will try to get User Name by using a our own dialog.
Example...
unit UserDlg;
interface
uses
  Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
  StdCtrls, Buttons;
type
  TUserDialog = class(TForm)
  edUserName: TEdit;
  btnOK: TBitBtn;
  btnCancel: TBitBtn;
  private
  { Private declarations }
  public
  { Public declarations }
  UserName: string;          // added by you   
  function Execute: Boolean; // added by you
  end;
var
  UserDialog: TUserDialog;
.....
function TUserDialog.Execute: Boolean;
begin
  Result := (ShowModal = mrOK);
  UserName := edUserName.Text;
end;
.....

Use of above dialog...
procedure TFormMain.Button1Click(Sender: TObject);
begin
  if UserDialog.Execute then
    Label1.Caption := UserDialog.UserName
  else
    Label1.Caption := 'Error: no User ID entered';
end;  

2. 
In this example we will create an input dialog with Combo.

function InputCombo(const ACaption, APrompt: string; const AList: TStrings): string;
  function GetCharSize(Canvas: TCanvas): TPoint;
  var
    I: Integer;
    Buffer: array[0..51] of Char;
  begin
    for I := 0 to 25 do Buffer[I] := Chr(I + Ord('A'));
    for I := 0 to 25 do Buffer[I + 26] := Chr(I + Ord('a'));
    GetTextExtentPoint(Canvas.Handle, Buffer, 52, TSize(Result));
    Result.X := Result.X div 52;
  end;   
var
  Form: TForm;
  Prompt: TLabel;
  Combo: TComboBox;
  DialogUnits: TPoint;
  ButtonTop, ButtonWidth, ButtonHeight: Integer;
begin
  Result := '';
  Form   := TForm.Create(Application);
  with Form do
    try
      Canvas.Font := Font;
      DialogUnits := GetCharSize(Canvas);
      BorderStyle := bsDialog;
      Caption     := ACaption;
      ClientWidth := MulDiv(180, DialogUnits.X, 4);
      Position    := poScreenCenter;
      Prompt      := TLabel.Create(Form);
      with Prompt do
      begin
        Parent   := Form;
        Caption  := APrompt;
        Left     := MulDiv(8, DialogUnits.X, 4);
        Top      := MulDiv(8, DialogUnits.Y, 8);
        Constraints.MaxWidth := MulDiv(164, DialogUnits.X, 4);
        WordWrap := True;
      end;
      Combo := TComboBox.Create(Form);
      with Combo do
      begin
        Parent := Form;
        Style  := csDropDownList;
        //For input possibility in combo uses
        //Style := csDropDown;
        Items.Assign(AList);
        ItemIndex := 0;
        Left      := Prompt.Left;
        Top       := Prompt.Top + Prompt.Height + 5;
        Width     := MulDiv(164, DialogUnits.X, 4);
      end;
      ButtonTop    := Combo.Top + Combo.Height + 15;
      ButtonWidth  := MulDiv(50, DialogUnits.X, 4);
      ButtonHeight := MulDiv(14, DialogUnits.Y, 8);
      with TButton.Create(Form) do
      begin
        Parent      := Form;
        Caption     := 'OK';
        ModalResult := mrOk;
        default     := True;
        SetBounds(MulDiv(38, DialogUnits.X, 4), ButtonTop, ButtonWidth,
          ButtonHeight);
      end;
      with TButton.Create(Form) do
      begin
        Parent      := Form;
        Caption     := 'Cancel';
        ModalResult := mrCancel;
        Cancel      := True;
        SetBounds(MulDiv(92, DialogUnits.X, 4), Combo.Top + Combo.Height + 15,
          ButtonWidth, ButtonHeight);
        Form.ClientHeight := Top + Height + 13;
      end;
      if ShowModal = mrOk then
      begin
        Result := Combo.Text;
      end;
    finally
      Form.Free;
    end;
end;

Use of above dialog .....
procedure TForm1.Button1Click(Sender: TObject);
var
  List: TStringList;
begin
  List := TStringList.Create;
  try
    List.Add('India');
    List.Add('USA');
    List.Add('UK');
    //Example call of the function
    Label1.Caption := InputCombo('Input Combo', 'Caption', List);
  finally
    List.Free;
  end;
end;

Comments

Popular posts from this blog

MS Excel Automation in Delphi

ShellExecute in Delphi

Drawing Shapes in Delphi