delphi - Creación de aplicaciones con estilo de cinta
ribbon (3)
Usando los componentes estándar de Delphi TRibbon noté que no son tan brillantes.
En primer lugar, no se ven tan bonitos como los de Microsoft, por ejemplo, los efectos de brillo y los colores del TRibbon no son tan impresionantes como los que se usan en Wordpad o Paint en Windows 7.
En segundo lugar, si desea crear interfaces estilo Ribbon, noté que no hay menús de estilo Ribbon o menús emergentes independientes del TRibbon. Para la cinta de opciones real existe, pero si, por ejemplo, para fines de continuidad, desea que los menús emergentes de estilo de cinta asignados a un TListbox o TListView, por ejemplo, no parezca haber uno.
En tercer lugar, a veces, cuando se desactiva una acción de cinta de opciones, todavía muestra el efecto de luz caliente como si se moviera sobre la acción, aunque esté desactivada.
Finalmente, me parece muy difícil tratar de colocar componentes de contenedor como un TCombobox en un grupo. Es realmente incómodo dimensionar los controles y la posición, etc.
Supongo que mi punto es que el uso de los componentes Delphi TRibbon estándar parece no ser el mejor enfoque tanto visual como utilizable. ¿Cómo puedo hacer que una aplicación de estilo Ribbon se vea y funcione tan bien como las de Microsoft hacen como dije antes de la forma en que lo hacen Wordpad y Paint en Windows 7?
Echa un vistazo a esta captura de pantalla de comparación para obtener una mejor idea:
La cinta de Delphi parece incompleta, a menos que esté esperando demasiado. Creo que los Ribbon Components deben proporcionar a su aplicación una mejor experiencia para el usuario final, tanto visual como un mejor espacio de trabajo, etc.
¿Qué sugerencias podría dar para mejorar o hacer que el TRibbon funcione y se parezca a los de Microsoft?
No uso Interfaces de estilo de cinta todo el tiempo, así que comprar componentes de terceros no es algo que realmente quiera hacer. He visto los TMS y DevExpress, pero por el precio de ellos, tampoco se ven tan bien. Los TMS se ven peor que el Delphi TRibbon estándar.
La respuesta pragmática es usar otro conjunto de componentes. La versión del software TMS parece buena, pero uso DevExpress ExpressBars, que funciona muy bien para mí.
utilizo Windows Ribbon Framework, el componente nativo que se incluye con Windows (7).
Aquí hay una cartilla súper corta sobre el Marco Ribbon de Windows de Delphi; copiar y pegar partes importantes del código, sin mucha explicación:
procedure TfrmTicketDetail.ShowScenicRibbon;
begin
try
Fframework := UIRibbon.CoUIRibbonFramework.Create;
Fframework.Initialize(Self.Handle, Self); //Give the ribbon the hwnd, and our implementation of uiapplication for callbacks
OleCheck(Fframework.LoadUI(hInstance, ''APPLICATION_RIBBON''));
except
on e:Exception do
begin
if DebugHook > 0 then
raise;
Exit;
end;
end;
end;
Pero comienza a ponerse peludo, ya que debes seguir la API de Microsoft.
{IUIApplication}
function OnViewChanged(viewId: SYSUINT; typeID: UI_VIEWTYPE; const view: IUnknown;
verb: UI_VIEWVERB; uReasonCode: SYSINT): HResult; stdcall;
function OnCreateUICommand(commandId: SYSUINT; typeID: UI_COMMANDTYPE;
out commandHandler: IUICommandHandler): HResult; stdcall;
function OnDestroyUICommand(commandId: SYSUINT; typeID: UI_COMMANDTYPE;
const commandHandler: IUICommandHandler): HResult; stdcall;
Y luego debes implementarlos:
function TfrmTicketDetail.OnViewChanged(viewId: SYSUINT;
typeID: UI_VIEWTYPE; const view: IUnknown; verb: UI_VIEWVERB;
uReasonCode: SYSINT): HResult;
var
cy: integer;
begin
Result := S_OK;
//viewID: The ID for the view. Only a value of zero is valid.
if viewID <> 0 then
Exit;
//typeID: The only declared typeID is UI_VIEWTYPE_RIBBON
if typeID <> UI_VIEWTYPE_RIBBON then
Exit;
case verb of //there are only 4 verbs: create, destroy, size, error
UI_VIEWVERB_CREATE:
begin
{ The view was resized.
In the case of the Ribbon view, the application should call
GetHeight() to determine the height of the Ribbon.}
(view as IUIRibbon).GetHeight(cy);
bvTopSpacer.Height := cy;
end;
UI_VIEWVERB_SIZE:
begin
{ The view was resized.
In the case of the Ribbon view, the application should call
GetHeight() to determine the height of the Ribbon.}
(view as IUIRibbon).GetHeight(cy);
bvTopSpacer.Height := cy;
end;
UI_VIEWVERB_DESTROY: {nop};
UI_VIEWVERB_ERROR: {nop};
end;
Result := S_OK;
end;
function TfrmTicketDetail.OnCreateUICommand(commandId: SYSUINT;
typeID: UI_COMMANDTYPE; out commandHandler: IUICommandHandler): HResult;
begin
commandHandler := Self; //this form will handle all commands on the ribbon;
Result := S_OK;
end;
function TfrmTicketDetail.OnDestroyUICommand(commandId: SYSUINT; typeID: UI_COMMANDTYPE;
const commandHandler: IUICommandHandler): HResult;
begin
Result := E_NOTIMPL;
end;
Y luego también tienes que
- implementar
IUICommandHandler
- crear un archivo XML de cinta
- compilar el archivo XML de cinta con el compilador de cinta
incluir la cinta compilada como recurso:
{$RESOURCE ''../Resource/UIRibbon/Ribbon_frmTicketDetails.res''}
Aquí hay un volcado de la cinta xml que tengo para mi aplicación:
<?xml version="1.0" encoding="utf-8"?>
<Application xmlns="http://schemas.microsoft.com/windows/2009/Ribbon">
<!-- Commands are like actions, with a name, a numeric ID, caption (LabelTitle), Large and Small images, etc -->
<Application.Commands>
<Command Name="cmdNew" Id="0xE100" Symbol="ID_CMD_NEW" LabelTitle="New document" />
<Command Name="cmdSaveAs" Id="0xE102" Symbol="ID_CMD_SAVEAS" LabelTitle="Save as" />
<Command Name="cmdOpen" Id="0xE103" Symbol="ID_CMD_OPEN" LabelTitle="Open" />
<Command Name="cmdExit" Id="0xE104" Symbol="ID_CMD_EXIT" LabelTitle="Exit" />
<Command Name="cmdUndo" Id="0xE105" Symbol="ID_CMD_UNDO" LabelTitle="Undo" />
<Command Name="cmdCut" Id="0xE110" Symbol="ID_CMD_CUT" LabelTitle="Cut" />
<Command Name="cmdCopy" Id="0xE111" Symbol="ID_CMD_COPY" LabelTitle="Copy" />
<Command Name="cmdPaste" Id="0xE112" Symbol="ID_CMD_PASTE" LabelTitle="Paste" />
<Command Name="cmdDelete" Id="0xE113" Symbol="ID_CMD_DELETE" LabelTitle="Delete" />
<Command Name="cmdZoom" Id="0xE114" Symbol="ID_CMD_ZOOM" LabelTitle="Zoom" />
<Command Name="tabHome" LabelTitle="Home" />
<Command Name="grpActions" LabelTitle="Actions" />
<Command Name="cmdSaveAndClose" Id="1101" Symbol="ID_ACTION_SAVEANDCLOSE" LabelTitle="Save and Close">
<Command.TooltipTitle>Save and Close (Alt+S)</Command.TooltipTitle>
<Command.TooltipDescription>Saves the current ticket and closes the detail screen.</Command.TooltipDescription>
<Command.LargeImages>
<Image Source="SaveAndClose.bmp" />
</Command.LargeImages>
</Command>
<Command Name="cmdBack" Id="1102" LabelTitle="Back" />
<Command Name="cmdControlPanel" Id="1103" LabelTitle="Control Panel" />
<Command Name="cmdSave" Id="1104" LabelTitle="Save" />
<Command Name="grpShow" Id="1201" LabelTitle="Show" />
<Command Name="cmdShowTicket" Id="1202" LabelTitle="Ticket" ></Command>
<Command Name="cmdShowDiaryEntries" Id="1203" LabelTitle="Diary Entries" >
<Command.LargeImages>
<Image Source="PencilLog_32x32.bmp" />
</Command.LargeImages>
</Command>
<Command Name="cmdShowAttachments" Id="1204" LabelTitle="Attachments" />
<Command Name="cmdShowAuditLog" Id="1205" LabelTitle="Audit Log" />
<Command Name="cmdShowAdditional" Id="1206" LabelTitle="Additional" />
<Command Name="grpActivity" LabelTitle="Activity" />
<Command Name="cmdStartWorking" Id="1301" LabelTitle="Start Working"></Command>
<Command Name="cmdStopWorking" Id="1302" LabelTitle="Stop Working"></Command>
<Command Name="cmdPrint" Id="1303" LabelTitle="Print" >
<Command.LargeImages>
<Image Source="Printer - 256x256.bmp" />
</Command.LargeImages>
<Command.SmallImages>
<Image Source="Printer_16x16.bmp" />
</Command.SmallImages>
</Command>
<Command Name="cmdDuplicateTicket" Id="1304" LabelTitle="Duplicate Ticket" >
<Command.SmallImages>
<Image Source="DuplicateTicket16.bmp" />
</Command.SmallImages>
</Command>
<Command Name="grpTicketStatus" LabelTitle="Ticket Status" />
<Command Name="cmdCloseTicket" Id="1402" LabelTitle="Close Ticket" />
<Command Name="cmdOnHold" Id="1403" LabelTitle="On Hold" />
<Command Name="cmdReadyForInstall" Id="1404" LabelTitle="Ready for install" />
<Command Name="cmdReopenTicket" Id="1405" LabelTitle="Reopen Ticket" />
</Application.Commands>
<!-- Above is all the commands (i.e. Actions). Now we get to the tool on screen (i.e. a DFM) -->
<Application.Views>
<Ribbon>
<!-- Items that appear under the "round button" menu -->
<Ribbon.ApplicationMenu>
<ApplicationMenu CommandName="cmdFileMenu">
<MenuGroup>
<Button CommandName="cmdNew" />
<Button CommandName="cmdOpen" />
<Button CommandName="cmdSave" />
<Button CommandName="cmdSaveAs" />
</MenuGroup>
<MenuGroup>
<Button CommandName="cmdExit" />
</MenuGroup>
</ApplicationMenu>
</Ribbon.ApplicationMenu>
<!--What commands to add to the quick access toolbar
Right now only Save and Undo, just for fun-->
<Ribbon.QuickAccessToolbar>
<QuickAccessToolbar>
<QuickAccessToolbar.ApplicationDefaults>
<Button CommandName="cmdSave" />
<Button CommandName="cmdUndo" />
</QuickAccessToolbar.ApplicationDefaults>
</QuickAccessToolbar>
</Ribbon.QuickAccessToolbar>
<!-- And now finally the actual tabs -->
<Ribbon.Tabs>
<!--Our one and only tab is "Home" -->
<Tab CommandName="tabHome">
<Tab.ScalingPolicy>
<ScalingPolicy>
<ScalingPolicy.IdealSizes>
<Scale Group="grpActions" Size="Medium"/>
<Scale Group="grpShow" Size="Medium"/>
<Scale Group="grpActivity" Size="Medium"/>
<Scale Group="grpTicketStatus" Size="Medium"/>
</ScalingPolicy.IdealSizes>
<Scale Group="grpActions" Size="Small"/>
<Scale Group="grpShow" Size="Small"/>
<Scale Group="grpActivity" Size="Small"/>
<Scale Group="grpTicketStatus" Size="Small"/>
</ScalingPolicy>
</Tab.ScalingPolicy>
<!-- Home/Actions -->
<Group CommandName="grpActions" SizeDefinition="FourButtons">
<Button CommandName="cmdSaveAndClose" />
<Button CommandName="cmdBack" />
<Button CommandName="cmdControlPanel" />
<Button CommandName="cmdSave" />
</Group>
<!-- Home/Show group -->
<Group CommandName="grpShow" SizeDefinition="FiveButtons">
<ToggleButton CommandName="cmdShowTicket" />
<ToggleButton CommandName="cmdShowDiaryEntries" />
<ToggleButton CommandName="cmdShowAttachments" />
<ToggleButton CommandName="cmdShowAuditLog" />
<ToggleButton CommandName="cmdShowAdditional" />
</Group>
<!-- Home/Activity group, with a custom sizing definition
so i get my "FourButtons-TwoBigTwoSmall" look -->
<Group CommandName="grpActivity" >
<SizeDefinition>
<ControlNameMap>
<ControlNameDefinition Name="button1"/>
<ControlNameDefinition Name="button2"/>
<ControlNameDefinition Name="button3"/>
<ControlNameDefinition Name="button4"/>
</ControlNameMap>
<GroupSizeDefinition Size="Large">
<ControlSizeDefinition ControlName="button1" ImageSize="Large" IsLabelVisible="true" />
<ControlSizeDefinition ControlName="button2" ImageSize="Large" IsLabelVisible="true" />
<ColumnBreak ShowSeparator="true"/>
<ControlSizeDefinition ControlName="button3" ImageSize="Large" IsLabelVisible="true" />
<ControlSizeDefinition ControlName="button4" ImageSize="Large" IsLabelVisible="true" />
</GroupSizeDefinition>
<GroupSizeDefinition Size="Medium">
<ControlSizeDefinition ControlName="button1" ImageSize="Large" IsLabelVisible="true" />
<ControlSizeDefinition ControlName="button2" ImageSize="Large" IsLabelVisible="true" />
<ColumnBreak ShowSeparator="true"/>
<Row>
<ControlSizeDefinition ControlName="button3" ImageSize="Small" IsLabelVisible="true" />
</Row>
<Row>
<ControlSizeDefinition ControlName="button4" ImageSize="Small" IsLabelVisible="true" />
</Row>
</GroupSizeDefinition>
<GroupSizeDefinition Size="Small">
<Row>
<ControlSizeDefinition ControlName="button1" ImageSize="Small" IsLabelVisible="true" />
<ControlSizeDefinition ControlName="button3" ImageSize="Small" IsLabelVisible="false" />
</Row>
<Row>
<ControlSizeDefinition ControlName="button2" ImageSize="Small" IsLabelVisible="true" />
<ControlSizeDefinition ControlName="button4" ImageSize="Small" IsLabelVisible="false" />
</Row>
</GroupSizeDefinition>
</SizeDefinition>
<Button CommandName="cmdStartWorking" />
<Button CommandName="cmdStopWorking" />
<Button CommandName="cmdPrint" />
<Button CommandName="cmdDuplicateTicket" />
</Group>
<!-- Home/Ticket Status group -->
<Group CommandName="grpTicketStatus" SizeDefinition="FourButtons">
<Button CommandName="cmdCloseTicket" />
<Button CommandName="cmdOnHold" />
<Button CommandName="cmdReadyForInstall" />
<Button CommandName="cmdReopenTicket" />
</Group>
</Tab>
</Ribbon.Tabs>
<!-- End of the actual tabs -->
</Ribbon>
</Application.Views>
</Application>
Para una apariencia nativa, consulte el Marco de cinta de Windows para Delphi .
Este es un contenedor de código abierto alrededor del marco de trabajo de cinta de Windows disponible desde Windows 7 (y Vista después de que se haya instalado alguna actualización oficial). Esta es la API utilizada por Windows 7 Word Pad.
Tenga en cuenta también que tiene dos tipos de diseño: Office 2007 y Office 2010. Delphi VCL Ribbon implementa el estilo de Office 2007, mientras que Windows Seven WordPad usa un estilo de Office 2010.
En algunos de nuestros proyectos para algunos clientes, utilizamos los componentes Ribbon del software TMS . El código es un poco demasiado grande (muchos duplicados o material escrito incorrecto, como la persistencia de los componentes), pero funciona y funciona bien, y es compatible con los estilos de cinta de 2007 y 2010. Para nuestros clientes, el renderizado era lo que importaba. Para nuestro framework Open Source, publicamos una solución dual para construir una GUI similar a Ribbon , generada a partir del código: utilizará los componentes estándar VCL para un diseño básico, ya sea los componentes TMS para una representación completa de Office 2007/2010. Acabamos de definir algunas clases, implementadas por cualquiera de las bibliotecas. Si utiliza los componentes genéricos definidos en SQLite3ToolBar (es decir, las TSynForm, TSynToolBar, TSynToolButton, TSynPopupMenu, TSynPage, TSynPager, TSynBodyPager
y TSynBodyPage
) y SynTaskDialog (para TSynButton
) en su propio código, el condicional USETMSPACK hará toda la magia para tú.
Todavía no utilizamos el componente Ribbon como se presentó en Delphi 2009. Su diseño impulsado por la acción no hará que sea fácil interactuar con el diseño impulsado por eventos de nuestro manejo de la interfaz de usuario, y tenemos que confesar que este componente tiene bastante mala reputación (al menos en la versión Delphi 2009).
El gran Marco Ribbon de Windows para Delphi no se ajustará a nuestra necesidad de una Cinta generada sobre la marcha a partir del código. Su diseño, desde la implementación de Microsoft en sí, es crear la UI a partir de un recurso XML, vinculado en compilación ... por lo que no se ajustará a nuestras necesidades, pero probablemente se ajuste al suyo, para un diseño de interfaz de usuario de aplicación más "estático".
Si usa una cinta tipo Office en su aplicación, tenga en cuenta la Licencia de UI de Office .