Recent

Author Topic: [SOLVED] Showing a message dialog centered in underlying TForm  (Read 3670 times)

Adri

  • New Member
  • *
  • Posts: 23
How do I show a Message Dialog fully CENTERED on a underlying TForm?
Currently I am using this:

Reply:=MessageDlgPos('Game ended!'+sLineBreak+'Play again?',
         mtInformation, [mbYes, mbNo], 0,
         GameForm.Left+(GameForm.Width-99)div 2,                                { Numbers to be calculated, not fixed }
         GameForm.Top+(GameForm.Height-50)div 2);


As you understand the numbers currently used (99, 50) are a guess. I would like these calculated from the actual message box size, but have no clue where and how to find these. Anyone able to help and answer?
« Last Edit: July 26, 2017, 11:06:59 pm by Adri »

rvk

  • Hero Member
  • *****
  • Posts: 6056
Re: Showing a message dialog centered in underlying TForm
« Reply #1 on: July 26, 2017, 10:40:36 pm »
You can't with MessageDlgPos. Because the width of the dialog itself is determined internally you can't know it beforehand. You could just set it in the middle of the screen and do the same with your gameform but if it's moved you can't set it in the exact center with that function.

You could try using the CreateMessageDialog function. It will return a TForm for which you can set the exact position and you know the size of that dialog at that point. But it's a but more work.

rvk

  • Hero Member
  • *****
  • Posts: 6056
Re: Showing a message dialog centered in underlying TForm
« Reply #2 on: July 26, 2017, 10:57:03 pm »
Here, I did some work for you.
It's a MyDialog function which works the same as MessageDlgPos.
Only the X and Y you provide are Center-position for the dialog.
(and I didn't implement HelpCtx).

Enjoy :)

Code: Pascal  [Select][+][-]
  1. function MyDialog(const aMsg: string; DlgType: TMsgDlgType;
  2.   Buttons: TMsgDlgButtons; HelpCtx: longint; Center_X, Center_Y: integer): TModalResult;
  3. var
  4.   F: TForm;
  5. begin
  6.   Result := 0;
  7.   F := CreateMessageDialog(aMsg, DlgType, Buttons);
  8.   try
  9.     F.Position := poDesigned;
  10.     F.Left := Center_X - F.Width div 2;
  11.     F.Top := Center_Y - F.Height div 2;
  12.     Result := F.ShowModal;
  13.   finally
  14.     F.Free;
  15.   end;
  16. end;
  17.  
  18. procedure TForm1.Button1Click(Sender: TObject);
  19. var
  20.   Reply:  TModalResult;
  21. begin
  22.   Reply := MyDialog('Game ended!' + sLineBreak + 'Play again?',
  23.     mtInformation, [mbYes, mbNo], 0,
  24.     Self.Left + Self.Width div 2, Self.Top + Self.Height div 2);
  25.   // do something with Reply
  26. end;
« Last Edit: July 26, 2017, 10:58:49 pm by rvk »

Adri

  • New Member
  • *
  • Posts: 23
Re: Showing a message dialog centered in underlying TForm
« Reply #3 on: July 26, 2017, 10:59:41 pm »
RVK, thanks. Did such initially indeed with this code:

if Finished then
  begin
    f:=CreateMessageDialog('Game ended!'+sLineBreak+'Play again?', mtInformation, [mbYes, mbNo]);
    f.Position:=poDesigned;                                                     { Game over... }
    f.Left:=Left+(Width-f.Width)div 2;
    f.Top:=Top+(Height-f.Height)div 2;
    f.ShowModal;
  end;       


It does work nicely, but I was looking for a better way of doing this. With more control over the box, like e.g. a 'Caption'. Unfortunately I cannot find a way to have AND a 'Caption', AND a 'Position' AND a 'Default'.... Of course I want it ALL and I want it YESTERDAY!

While I was replying you answered again! Cool!
Many thanks, I will implement this asap.


RAW

  • Hero Member
  • *****
  • Posts: 868
Re: [SOLVED] Showing a message dialog centered in underlying TForm
« Reply #4 on: July 27, 2017, 10:30:15 pm »
If you like it customized then why don't you use your own dialog?
You can create whatever you like...

For example...
Code: Pascal  [Select][+][-]
  1. Function TForm1.DialogWnd
  2. (strWndTxt, strTxt: String; wndCalcPos: TForm; booOkBtn: Boolean): String;
  3.   Const
  4.    MyFont = 'Arial';
  5.   Var
  6.    Wnd: TForm; Memo: TMemo;
  7.    btnYes, btnNo, btnCancel: TButton;
  8.  
  9.    iBtnX, iBtnY, iDlgX, iDlgY, iDlgTop, iDlgLeft,
  10.    iWorkAreaX, iWorkAreaY, iWALeft, iWATop: Integer;
  11.  Begin
  12.   Try
  13.    Result:= '';
  14.     wnd:= TForm.Create(Nil);
  15.      Try
  16.       wnd.Color         := clBtnFace;
  17.       wnd.Caption       := strWndTxt;
  18.       wnd.BorderStyle   := bsSizeable;
  19.       wnd.DoubleBuffered:= True;
  20.       wnd.BorderIcons   := [];
  21.  
  22.       iDlgX:= wndCalcPos.Width;
  23.       iDlgY:= wndCalcPos.Height;
  24.  
  25.       If iDlgX < 300 Then iDlgX:= 300;
  26.       If iDlgY < 200 Then iDlgY:= 200;
  27.  
  28.       If iDlgX >= 800 Then iDlgX:= iDlgX Div 2;
  29.       If iDlgY >= 550 Then iDlgY:= iDlgY Div 2;
  30.  
  31.       iDlgLeft:= wndCalcPos.Left+((wndCalcPos.Width -iDlgX) Div 2);
  32.       iDlgTop := wndCalcPos.Top +((wndCalcPos.Height-iDlgY) Div 2);
  33.  
  34.       iWorkAreaX:= Screen.WorkAreaWidth;
  35.       iWorkAreaY:= Screen.WorkAreaHeight;
  36.       iWALeft   := Screen.WorkAreaLeft;
  37.       iWATop    := Screen.WorkAreaTop;
  38.  
  39.       If iDlgLeft < iWALeft Then iDlgLeft:= iWALeft+40;
  40.       If iDlgTop  < iWATop  Then iDlgTop := iWATop +40;
  41.  
  42.       If iDlgTop   > (iWorkAreaY-iDlgY)
  43.       Then iDlgTop:= (iWorkAreaY-iDlgY-40);
  44.  
  45.       If iDlgLeft   > (iWorkAreaX-iDlgX)
  46.       Then iDlgLeft:= (iWorkAreaX-iDlgX-40);
  47.  
  48.       wnd.SetBounds(iDlgLeft, iDlgTop, iDlgX, iDlgY);
  49.  
  50.       wnd.Constraints.MinHeight:= wnd.Height;
  51.       wnd.Constraints.MaxHeight:= wnd.Height;
  52.       wnd.Constraints.MinWidth := wnd.Width;
  53.       wnd.Constraints.MaxWidth := wnd.Width;
  54.  
  55.       btnYes               := TButton.Create(wnd);
  56.       btnYes.Caption       := 'YES';
  57.       btnYes.Font.Name     := MyFont;
  58.       btnYes.Font.Quality  := fqAntialiased;
  59.       btnYes.Font.Style    := [fsBold];
  60.       btnYes.DoubleBuffered:= True;
  61.       btnYes.ModalResult   := mrYes;
  62.       btnYes.Parent        := wnd;
  63.  
  64.       btnNo               := TButton.Create(wnd);
  65.       btnNo.Caption       := 'NO';
  66.       btnNo.Font.Name     := MyFont;
  67.       btnNo.Font.Quality  := fqAntialiased;
  68.       btnNo.Font.Style    := [fsBold];
  69.       btnNo.DoubleBuffered:= True;
  70.       btnNo.ModalResult   := mrNo;
  71.       btnNo.Parent        := wnd;
  72.  
  73.       btnCancel               := TButton.Create(wnd);
  74.       btnCancel.Caption       := 'CANCEL';
  75.       btnCancel.Font.Name     := MyFont;
  76.       btnCancel.Font.Quality  := fqAntialiased;
  77.       btnCancel.Font.Style    := [fsBold];
  78.       btnCancel.DoubleBuffered:= True;
  79.       btnCancel.ModalResult   := mrCancel;
  80.       btnCancel.Parent        := wnd;
  81.  
  82.       iBtnX:= (wnd.ClientWidth-20) Div 3;
  83.       iBtnY:= iBtnX Div 5;
  84.  
  85.       btnYes.SetBounds(5, wnd.ClientHeight-iBtnY, iBtnX, iBtnY);
  86.       btnNo.SetBounds((wnd.ClientWidth-iBtnX) Div 2, btnYes.Top, iBtnX, iBtnY);
  87.       btnCancel.SetBounds(wnd.ClientWidth-iBtnX-5, btnYes.Top, iBtnX, iBtnY);
  88.  
  89.       Canvas.Font.Size   := 1;
  90.       Canvas.Font.Name   := MyFont;
  91.       Canvas.Font.Style  := btnCancel.Font.Style;
  92.       Canvas.Font.Quality:= fqAntialiased;
  93.  
  94.       While Not (Canvas.TextWidth('CANCEL') > iBtnX-20)
  95.       Do Canvas.Font.Size:= Canvas.Font.Size+1;
  96.  
  97.       While (Canvas.TextHeight('CANCEL') > btnCancel.ClientHeight)
  98.       Do Canvas.Font.Size:= Canvas.Font.Size-1;
  99.  
  100.       btnYes.Font.Size   := Canvas.Font.Size;
  101.       btnNo.Font.Size    := btnYes.Font.Size;
  102.       btnCancel.Font.Size:= btnYes.Font.Size;
  103.  
  104.       Memo               := TMemo.Create(wnd);
  105.       Memo.Font.Name     := MyFont;
  106.       Memo.Font.Size     := wnd.ClientWidth Div 20;
  107.       Memo.Font.Style    := [fsBold];
  108.       Memo.Font.Quality  := fqAntialiased;
  109.       Memo.Font.Color    := clBtnText;
  110.       Memo.Color         := clBtnFace;
  111.       Memo.Alignment     := taCenter;
  112.       Memo.BorderStyle   := bsNone;
  113.       Memo.HideSelection := True;
  114.       Memo.Text          := strTxt;
  115.       Memo.ReadOnly      := True;
  116.       Memo.WordWrap      := True;
  117.       Memo.WantTabs      := False;
  118.       Memo.DoubleBuffered:= True;
  119.       Memo.WantReturns   := False;
  120.       Memo.ScrollBars    := ssAutoVertical;
  121.       Memo.SetBounds     (0, 0, wnd.ClientWidth, wnd.ClientHeight-iBtnY-10);
  122.       Memo.Parent        := wnd;
  123.  
  124.       If booOkBtn
  125.       Then
  126.        Begin
  127.         btnYes.Hide;
  128.         btnCancel.Hide;
  129.         btnNo.Caption:= 'OK';
  130.         wnd.ActiveControl:= btnNo;
  131.        End
  132.       Else wnd.ActiveControl:= btnYes;
  133.  
  134.       wnd.ShowModal;
  135.  
  136.       Case wnd.ModalResult
  137.       Of
  138.        mrYes   : Result:= 'YES';
  139.        mrNo    : Result:= 'NO';
  140.        mrCancel: Result:= 'CANCEL';
  141.       End;
  142.      Finally
  143.       wnd.Release;
  144.       wnd:= Nil;
  145.      End;
  146.   Except
  147.   End;
  148.  End;

OK-Dialog:
Code: Pascal  [Select][+][-]
  1. Procedure TForm1.FormClick(Sender: TObject);
  2.  Begin
  3.   DialogWnd('MyProgram', strText, Self, True);
  4.  End;

Choice-Dialog:
Code: Pascal  [Select][+][-]
  1. Procedure TForm1.FormClick(Sender: TObject);
  2.  Begin
  3.   Case DialogWnd('MyProgram', strText, Self, False)
  4.   Of
  5.    'YES'   : ShowMessage('YES');
  6.    'NO'    : ShowMessage('NO');
  7.    'CANCEL': ShowMessage('CANCEL');
  8.   End;
  9.  End;
« Last Edit: October 04, 2017, 01:57:13 am by RAW »
Windows 7 Pro (x64 Sp1) & Windows XP Pro (x86 Sp3).

Adri

  • New Member
  • *
  • Posts: 23
Re: [SOLVED] Showing a message dialog centered in underlying TForm
« Reply #5 on: July 28, 2017, 11:42:42 pm »
On RVK's solution I added an "aCaption" which is shown now too. The full solution reads now:

function MyDialog(const aCaption: String;
                  const aMsg: string;
                  DlgType: TMsgDlgType;
                  Buttons: TMsgDlgButtons;
                  HelpCtx: longint;
                  Center_X, Center_Y: integer): TModalResult;
var f: TForm;
begin
  Result := 0;
  f:=CreateMessageDialog(aMsg, DlgType, Buttons);
  try
    f.Caption:=aCaption;
    f.Position:=poDesigned;
    f.Left:=Center_X-f.Width div 2;
    f.Top:=Center_Y-f.Height div 2;
    Result:=f.ShowModal;
  finally
    f.Free;
  end;
end;     


Thanks again all for help and suggestions!     :D

 

TinyPortal © 2005-2018