如何获取 MessageDlgPos 维度?
How do I get the MessageDlgPos dimensions?
我想将 MessageBox 放置在相对于字符串网格中的活动单元格的特定位置,使用 MessageDlgPos()
没问题,只是我想防止框 运行 关闭当活动单元格靠近右侧或底部时,屏幕的右侧或底部。我需要的是一种获取盒子尺寸的方法,但我看不到获取这些尺寸的简单方法。有人知道如何不创建我自己的盒子吗?
MessageDlg...()
函数不支持您的请求。在显示对话框之前,对话框的尺寸是未知的,并且您无法直接访问对话框 window 到 query/re-position,除非使用 WH_CBT
hook from SetWindowsHookEx()
.
话虽这么说...
在 Windows 带有 Vcl.Dialogs.UseLatestCommonDialogs=true
and Visual Styles enabled, the MessageDlg...()
functions call the Win32 TaskDialogIndirect()
API to display a message box. You have no control over that dialog's dimensions, so you would have to wait for that dialog to issue a TDN_DIALOG_CONSTRUCTED
notification to then query its actual dimensions before it is displayed, so you can then adjust its position as needed. However, the MessageDlg...()
functions do not provide access to any of TaskDialogIndirect()
's notifications (TCustomTaskDialog
, which is used internally, does have an OnDialogConstructed
event, amongst other events). So, if you wanted to reposition this dialog, you would have to call TaskDialogIndirect()
yourself with a custom callback function (or, use the VCL's TTaskDialog
包装器的 Vista+ 上。
在 pre-Vista 上,或禁用 [=23=] 或视觉样式时,MessageDlg...()
函数通过 Vcl.Dialogs.CreateMessageDialog()
显示自定义 VCL TForm
,您可以调用直接,然后根据需要查询、操作和显示返回的 TForm
。请务必在使用完后 Free()
它。
自己创建 MessageDlg。添加 OnActivate 或 OnShow 事件。在这个方法中,询问/更改对话框的属性。
unit Unit1;
interface
uses
Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics,
Vcl.Controls, Vcl.Forms, Vcl.StdCtrls;
type
Tfrm = class(TForm)
btn: TButton;
procedure btnClick(Sender: TObject);
private
procedure OnDlgActivate(Sender: TObject);
public
{ Public-Deklarationen }
end;
var
frm: Tfrm;
implementation
uses
Vcl.Dialogs, System.TypInfo;
{$R *.dfm}
procedure Tfrm.btnClick(Sender: TObject);
var
Ldlg : TForm;
LiRet : integer;
begin
Ldlg := CreateMessageDialog('Hallo World!', mtInformation,mbYesNo, mbYes);
try
Ldlg.OnActivate := OnDlgActivate;
LiRet := Ldlg.ShowModal;
finally
Ldlg.free;
end;
end;
procedure Tfrm.OnDlgActivate(Sender: TObject);
var
Lfrm: TForm;
LcTxt: string;
begin
Lfrm := Sender as TForm;
LcTxt := Format('%s %sLeft: %d / Top: %d', [Lfrm.ClassName, sLineBreak, Lfrm.Left, Lfrm.Top]);
ShowMessage(LcTxt);
end;
end.
您可以使用实际的 TTaskDialog。您可以创建自己的版本,添加 TaskDialogConstructed 过程并在 TaskDialogConstructed 过程中获取维度。大致如下。
type
TTaskDialog = class(Vcl.Dialogs.TTaskDialog)
protected
procedure TaskDialogConstructed(Sender: TObject);
end;
procedure TTaskDialog.TaskDialogConstructed(Sender: TObject);
var
TaskDialog: TTaskDialog;
R: TRect;
begin
TaskDialog := Sender as TTaskDialog;
Win32Check(GetWindowRect(TaskDialog.Handle, R));
{... Do whatever with R ...}
end;
function ExecuteTaskDialog(AOwner: TComponent; ATitle, AText: string; ACommonButtons: TTaskDialogCommonButtons = [tcbOK]): integer;
var
TaskDialog: TTaskDialog;
begin
TaskDialog := TTaskDialog.Create(AOwner);
with TaskDialog do
begin
Caption := Application.Title;
Title := ATitle;
Text := AText;
MainIcon := tdiNone;
Flags := Flags + [tfUseHiconMain];
CommonButtons := ACommonButtons;
CustomMainIcon.LoadFromResourceName(HInstance, 'MAINICON');
OnDialogConstructed := TaskDialogConstructed;
Execute;
Result := ModalResult;
Free;
end;
end;
我想将 MessageBox 放置在相对于字符串网格中的活动单元格的特定位置,使用 MessageDlgPos()
没问题,只是我想防止框 运行 关闭当活动单元格靠近右侧或底部时,屏幕的右侧或底部。我需要的是一种获取盒子尺寸的方法,但我看不到获取这些尺寸的简单方法。有人知道如何不创建我自己的盒子吗?
MessageDlg...()
函数不支持您的请求。在显示对话框之前,对话框的尺寸是未知的,并且您无法直接访问对话框 window 到 query/re-position,除非使用 WH_CBT
hook from SetWindowsHookEx()
.
话虽这么说...
在 Windows 带有 Vcl.Dialogs.UseLatestCommonDialogs=true
and Visual Styles enabled, the MessageDlg...()
functions call the Win32 TaskDialogIndirect()
API to display a message box. You have no control over that dialog's dimensions, so you would have to wait for that dialog to issue a TDN_DIALOG_CONSTRUCTED
notification to then query its actual dimensions before it is displayed, so you can then adjust its position as needed. However, the MessageDlg...()
functions do not provide access to any of TaskDialogIndirect()
's notifications (TCustomTaskDialog
, which is used internally, does have an OnDialogConstructed
event, amongst other events). So, if you wanted to reposition this dialog, you would have to call TaskDialogIndirect()
yourself with a custom callback function (or, use the VCL's TTaskDialog
包装器的 Vista+ 上。
在 pre-Vista 上,或禁用 [=23=] 或视觉样式时,MessageDlg...()
函数通过 Vcl.Dialogs.CreateMessageDialog()
显示自定义 VCL TForm
,您可以调用直接,然后根据需要查询、操作和显示返回的 TForm
。请务必在使用完后 Free()
它。
自己创建 MessageDlg。添加 OnActivate 或 OnShow 事件。在这个方法中,询问/更改对话框的属性。
unit Unit1;
interface
uses
Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics,
Vcl.Controls, Vcl.Forms, Vcl.StdCtrls;
type
Tfrm = class(TForm)
btn: TButton;
procedure btnClick(Sender: TObject);
private
procedure OnDlgActivate(Sender: TObject);
public
{ Public-Deklarationen }
end;
var
frm: Tfrm;
implementation
uses
Vcl.Dialogs, System.TypInfo;
{$R *.dfm}
procedure Tfrm.btnClick(Sender: TObject);
var
Ldlg : TForm;
LiRet : integer;
begin
Ldlg := CreateMessageDialog('Hallo World!', mtInformation,mbYesNo, mbYes);
try
Ldlg.OnActivate := OnDlgActivate;
LiRet := Ldlg.ShowModal;
finally
Ldlg.free;
end;
end;
procedure Tfrm.OnDlgActivate(Sender: TObject);
var
Lfrm: TForm;
LcTxt: string;
begin
Lfrm := Sender as TForm;
LcTxt := Format('%s %sLeft: %d / Top: %d', [Lfrm.ClassName, sLineBreak, Lfrm.Left, Lfrm.Top]);
ShowMessage(LcTxt);
end;
end.
您可以使用实际的 TTaskDialog。您可以创建自己的版本,添加 TaskDialogConstructed 过程并在 TaskDialogConstructed 过程中获取维度。大致如下。
type
TTaskDialog = class(Vcl.Dialogs.TTaskDialog)
protected
procedure TaskDialogConstructed(Sender: TObject);
end;
procedure TTaskDialog.TaskDialogConstructed(Sender: TObject);
var
TaskDialog: TTaskDialog;
R: TRect;
begin
TaskDialog := Sender as TTaskDialog;
Win32Check(GetWindowRect(TaskDialog.Handle, R));
{... Do whatever with R ...}
end;
function ExecuteTaskDialog(AOwner: TComponent; ATitle, AText: string; ACommonButtons: TTaskDialogCommonButtons = [tcbOK]): integer;
var
TaskDialog: TTaskDialog;
begin
TaskDialog := TTaskDialog.Create(AOwner);
with TaskDialog do
begin
Caption := Application.Title;
Title := ATitle;
Text := AText;
MainIcon := tdiNone;
Flags := Flags + [tfUseHiconMain];
CommonButtons := ACommonButtons;
CustomMainIcon.LoadFromResourceName(HInstance, 'MAINICON');
OnDialogConstructed := TaskDialogConstructed;
Execute;
Result := ModalResult;
Free;
end;
end;