私はDelphiを使用しており、MessageDlgのボタンにカスタムテキストを表示したい、as described here。それをする最善の方法は何ですか?カスタマイズされたメッセージダイアログを表示するための最良の方法は何ですか?
12
A
答えて
10
私自身の質問に答える...私は私のためにうまくいく以下のユニットを書いた。
Delphiはダイアログテンプレートを表示するためにCreateMessageDialog()を提供しています。ダイアログテンプレートは表示する前に変更することができます。私はこれを使ってMessageDlgCustomと呼ばれる関数を作成しました。これは標準のMessageDlgと同じパラメータを取りますが、置き換えボタンのタイトルを1つ追加します。
カスタムフォントを正しく処理し、メッセージに十分な幅のボタンを自動的に調整します。ボタンがダイアログをオーバーフローすると、それも調整されます。そのユニットを使用した後
、以下のサンプルは動作します:
case MessageDlgCustom('Save your changes?',mtConfirmation,
[mbYes,mbNo,mbCancel],
['&Yes, I would like to save them with this absurdly long button',
'&No, I do not care about my stupid changes',
'&Arg! What are you talking about? Do not close the form!'],
nil) //nil = no custom font
of
mrYes:
begin
SaveChanges;
CloseTheForm;
end; //mrYes (save & close)
mrNo:
begin
CloseForm;
end; //mrNo (close w/o saving)
mrCancel:
begin
//do nothing
end; //mrCancel (neither save nor close)
end; //case
他の誰かがより良い方法を知っている場合、それを共有してください。
unit CustomDialog;
interface
uses
Dialogs, Forms, Graphics, StdCtrls;
function MessageDlgCustom(const Msg: string; DlgType: TMsgDlgType;
Buttons: TMsgDlgButtons; ToCaptions: array of string;
customFont: TFont) : integer;
procedure ModifyDialog(var frm: TForm; ToCaptions : array of string;
customFont : TFont = nil);
implementation
uses
Windows, SysUtils;
function GetTextWidth(s: string; fnt: TFont; HWND: THandle): integer;
var
canvas: TCanvas;
begin
canvas := TCanvas.Create;
try
canvas.Handle := GetWindowDC(HWND);
canvas.Font := fnt;
Result := canvas.TextWidth(s);
finally
ReleaseDC(HWND,canvas.Handle);
FreeAndNil(canvas);
end; //try-finally
end;
function MessageDlgCustom(const Msg: string;
DlgType: TMsgDlgType; Buttons: TMsgDlgButtons; ToCaptions: array of string;
customFont: TFont): integer;
var
dialog : TForm;
begin
try
dialog := CreateMessageDialog(Msg, DlgType, Buttons);
dialog.Position := poScreenCenter;
ModifyDialog(dialog,ToCaptions,customFont);
Result := dialog.ShowModal;
finally
dialog.Release;
end; //try-finally
end;
procedure ModifyDialog(var frm: TForm; ToCaptions: array of string;
customFont: TFont);
const
c_BtnMargin = 10; //margin of button around caption text
var
i,oldButtonWidth,newButtonWidth,btnCnt : integer;
begin
oldButtonWidth := 0;
newButtonWidth := 0;
btnCnt := 0;
for i := 0 to frm.ComponentCount - 1 do begin
//if they asked for a custom font, assign it here
if customFont <> nil then begin
if frm.Components[i] is TLabel then begin
TLabel(frm.Components[i]).Font := customFont;
end;
if frm.Components[i] is TButton then begin
TButton(frm.Components[i]).Font := customFont;
end;
end;
if frm.Components[i] is TButton then begin
//check buttons for a match with a "from" (default) string
//if found, replace with a "to" (custom) string
Inc(btnCnt);
//record the button width *before* we changed the caption
oldButtonWidth := oldButtonWidth + TButton(frm.Components[i]).Width;
//if a custom caption has been provided use that instead,
//or just leave the default caption if the custom caption is empty
if ToCaptions[btnCnt - 1]<>'' then
TButton(frm.Components[i]).Caption := ToCaptions[btnCnt - 1];
//auto-size the button for the new caption
TButton(frm.Components[i]).Width :=
GetTextWidth(TButton(frm.Components[i]).Caption,
TButton(frm.Components[i]).Font,frm.Handle) + c_BtnMargin;
//the first button can stay where it is.
//all other buttons need to slide over to the right of the one b4.
if (1 < btnCnt) and (0 < i) then begin
TButton(frm.Components[i]).Left :=
TButton(frm.Components[i-1]).Left +
TButton(frm.Components[i-1]).Width + c_BtnMargin;
end;
//record the button width *after* changing the caption
newButtonWidth := newButtonWidth + TButton(frm.Components[i]).Width;
end; //if TButton
end; //for i
//whatever we changed the buttons by, widen/shrink the form accordingly
frm.Width := Round(frm.Width + (newButtonWidth - oldButtonWidth) +
(c_BtnMargin * btnCnt));
end;
end.
1
また、お使いのサードパーティ製のコントロールも カスタムメッセージDLGはなく、標準 MessageDlg関数を呼び出すことを確認してください。つまり、実際には を使用している場合です。サードパーティのコントロール は、Delphi messagedlgを使用せず、 MessageBox APIを直接呼び出すことが可能です。その場合、メッセージ が表示されると、 が矛盾してしまうことがあります。
2
また、オープンソースSynTaskDialogを使用することもできます。 SynTaskDialogはWindowsのTaskDialog APIを新しいWindowsバージョンでネイティブに使用し、古いバージョンでエミュレートします。あなたもuse it with FireMonkeyすることができます。
カスタマイズ可能なMessageDlg関数の例は、this answerです。
関連する問題
- 1. グラフィックスを表示するための最良の方法
- 2. のListBox WPFやSilverlightで画像を表示するための最良の方法は何ですか
- 3. concatenting stringそれを行うための最良の方法は何ですか?
- 4. モバイルアプリケーションを作成するための最良の方法は何ですか
- 5. Googleスクリプトアプリケーションを表示するためのカスタマイズされた権限
- 6. z-indexスタッキングコンテキスト - 子オーバーラップ親w /オーバーフロー:非表示?これを達成するための最良の方法は何
- 7. Amazon Webサービス使用状況レポートをカスタマイズして表示する最良の方法は何ですか?
- 8. RouteconfigでカスタマイズされたURLを表示する方法
- 9. Android; ListViewは複数の独立したプログレスバーを表示するための最良の方法ですか?
- 10. 文書を手渡すための最良の方法は何ですか?
- 11. グリッド内の「フォーカス」を表示する最良の方法は何ですか?
- 12. データのパッケージ化されたグラフィック表現をExcelから作成する最良の方法は何ですか?
- 13. バイナリデータを表現する最良の方法は何ですか?
- 14. Express.jsにFlashメッセージを表示する最良の方法は何ですか?
- 15. ビルド前テストを書くための最良の方法は何ですか
- 16. レール上にルビーサービスを置くための最良の方法は何ですか?
- 17. アンドロイドクライアント間のリアルタイムコミュニケーションのための最良の方法は何ですか?
- 18. 何時間前の何かを得るためのMySQLの最良の方法は何ですか?
- 19. プロンプトが表示されたらパス名を入力する最良の方法
- 20. 車両検索のための最良のデータマイニング方法は何ですか?
- 21. ブラックベリーのための最良の認証方法は何ですか
- 22. アプリケーション全体に「No Connection」メッセージを表示するための最良の方法
- 23. 親ウィンドウをカスタマイズされたコントロールから通知するための好ましい方法は何ですか?
- 24. nosetests:カスタマイズされたログを表示する方法
- 25. mvcでメニューを表示する最も良い方法は何ですか?
- 26. ページングされたインターフェイスを設計するための最良の方法
- 27. 単一のWinformで異なるフォームを表示するための最良のアクションコースは何でしょうか?
- 28. テーブル内の「完了したまたは取り消されたアイテム」を非表示にする最良の方法は何ですか?
- 29. IE6/7とFirefoxで同じディスプレイを表示するための最良のツールやテクニックは何ですか?
- 30. 還元状態のサイズを小さくするための最良の方法は何ですか?
少なくとも、Delphi 2007を使用している場合は、完全に新しいMessageDlg()関数を作成し、まずWindowsバージョンをチェックし、Vistaで新しいダイアログクラスを使用し、元のMessageDlgの修正バージョンを使用します)関数を使用します。これにより、「再度表示しない」チェックボックスも簡単に追加できます。 – mghie
現在のコードはコンパイルされません。いくつかの方法を再構成する必要があります。 GetTextWidthは実装の先頭に移動する必要があります。実装でMessageDlgCustomメソッドの上にあるModifiyDialogを移動すると、インターフェイスセクションから宣言を削除できます。 WinXPでは、変更されたダイアログボックスが最後のボタンとして表示されます。例の呼び出しを使用すると、ほとんどウィンドウ境界の端に位置します。何らかの理由で、このメソッドはダイアログの幅を正しく再計算しません。 –
@ライアン - ありがとう、私はそれがコンパイルを壊すことを忘れて、一番重要なものを一番上に置くように再編成した。元の注文を復元しました。今すぐコンパイルする必要があります。 私はXPマシンで試してみる必要があります - 私はVistaを使用しています。うまくいけば、あなたが記述する問題は、とにかく極端な場合にのみ発生します。 – JosephStyons