Estoy usando Delphi, y quiero mostrar texto personalizado en los botones de un MessageDlg, as described here. ¿Cuál es la mejor manera de hacer eso?¿Cuál es la mejor manera en Delphi para mostrar Diálogos de mensajes personalizados?
Respuesta
Respondiendo a mi propia pregunta .... Escribí la siguiente unidad que funciona bien para mí.
Delphi proporciona CreateMessageDialog() para darle una plantilla de diálogo, que puede modificar antes de mostrar. Lo utilicé para crear una función que llamé MessageDlgCustom, que toma los mismos parámetros que un MessageDlg estándar, pero agrega uno más para los títulos de los botones de reemplazo.
Maneja correctamente las fuentes personalizadas y ajusta automáticamente los botones para que sean lo suficientemente anchos para su mensaje. Si los botones desbordan el diálogo, entonces eso también se ajusta.
Después de usar esa unidad, el ejemplo siguiente funciona:
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
Si alguien sabe una mejor manera, por favor, comparta.
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.
Además, asegúrese de que sus controles de 3 ª parte también llame a su DLG mensaje personalizado y no estándar de la función MessageDlg . Eso es si realmente están usando el . Es posible que los controles de terceros no utilicen el mensaje de Delphi y llamen directamente al MessageBox API. Si ese es el caso, puede terminar con inconsistencias al mostrar el mensaje cajas.
Como alternativa, puede utilizar la unidad de código abierto SynTaskDialog. SynTaskDialog utiliza la API TaskDialog de Windows de forma nativa en las versiones más nuevas de Windows y la emula en versiones anteriores. Incluso puede use it with FireMonkey.
Para ver un ejemplo de una función MessageDlg personalizable echa un vistazo a this answer.
- 1. ¿Cuál es la mejor manera de mostrar 'mensajes flash' en kohana v3?
- 2. diálogos de mensajes simples
- 3. ¿Cuál es la mejor manera de mostrar HTML en Flex?
- 4. ¿Cuál es la mejor manera de mostrar un archivo PDF en Delphi 2009
- 5. Persistencia del objeto Delphi, ¿cuál es la mejor manera?
- 6. ¿Cuál es la mejor manera de ordenar la lista con parámetros de clasificación personalizados en Python?
- 7. ¿Cuál es la mejor manera de implementar Equals para tipos personalizados?
- 8. Cuál es la mejor IDE alternativa para Delphi (.NET)
- 9. ¿Cuál es la mejor manera de comparar programas en Windows?
- 10. ¿Cuál es la mejor manera de implementar atributos personalizados en dotnet/.NET?
- 11. ¿Cuál es la mejor manera de almacenar un conjunto de Delphi en un conjunto de datos?
- 12. Cuál es la mejor manera de paginar resultados en php
- 13. ¿Cuál es la mejor manera de serializar la configuración de la aplicación Delphi?
- 14. ¿Cuál es la mejor manera de implementar BackgroundWorker de C# en Delphi?
- 15. ¿Cuál es la mejor manera de reproducir archivos de video en Delphi?
- 16. ¿Cuál es la mejor manera de proporcionar localización para Enumeraciones?
- 17. ¿Cuál es la mejor manera de probar unidades los mensajes de registro SLF4J?
- 18. ¿Cuál es una buena manera de mostrar los errores/mensajes a los usuarios de php?
- 19. ¿Cuál es la mejor manera de dibujar en la consola?
- 20. ¿La mejor manera de mostrar notificaciones y mensajes en vivo en una página web?
- 21. ¿Cuál es la mejor manera de mostrar un indicador de 'carga' en un control de WPF
- 22. ¿Cuál es la mejor manera de comunicarse entre los AppDomains?
- 23. ¿Cuál es la forma más fácil de establecer mensajes de datos binarios personalizados en Java?
- 24. ¿Cuál es la mejor manera de mostrar ASCII en una cuadrícula con paneles usando Java?
- 25. ¿Cuál es la mejor manera de mostrar un icono animado en un QTableView?
- 26. ¿Cuál es la mejor forma de mostrar mensajes de error/advertencia en la aplicación del sitio web?
- 27. ¿Cuál es la mejor manera de compartir archivos fuente Delphi entre proyectos?
- 28. ¿Cuál es la mejor manera de reemplazar remote.origin.url en Git?
- 29. ¿Cuál es la mejor manera de manejar excepciones en Perl?
- 30. ¿Cuál es la mejor manera de depurar css en ie?
Bueno, si está utilizando al menos Delphi 2007, crearía una función MessageDlg() completamente nueva, verificando primero la versión de Windows, utilizando las nuevas clases de diálogo en Vista, y usaría una versión modificada del MessageDlg original () Funciona de otra manera. Eso le permitiría agregar fácilmente casillas de verificación "No volver a mostrar" también. – mghie
El código tal como está actualmente no se compila. Necesita reorganizar algunos de los métodos. GetTextWidth debe avanzar hasta la parte superior de la implementación y si mueve ModifiyDialog sobre el método MessageDlgCustom en la implementación, puede eliminar la declaración de la sección de interfaz. En WinXP, el último botón de los cuadros de diálogo modificados, utilizando su llamada de ejemplo, se encuentra casi en el borde del borde de la ventana. Por alguna razón, el método no recalcula correctamente el ancho del diálogo. –
@Ryan - gracias, lo reorganicé para poner lo más importante en la parte superior, olvidando que rompería la compilación. He restaurado el orden original. Debería compilar ahora. Tendré que probarlo en una máquina con XP, estoy usando Vista. Esperemos que el problema que describes solo ocurra en casos extremos, de todos modos ... – JosephStyons