Using the standard Delphi TRibbon components I noticed they are not that brilliant.
Firstly they dont look as nice as the Microsoft ones, for example the glow effects and colors in the TRibbon dont look as impressive as the ones used in Wordpad or Paint in Windows 7.
Secondly if you want to create Ribbon Styled interfaces, I noticed that there is no Ribbon style menus or popup menus independent of the TRibbon. For the actual Ribbon there is, but if say for continuity purposes you wanted the Ribbon style popup menus assigned to a TListbox or TListView for example, there doesnt appear to be one.
Thirdly, sometimes when a Ribbon Action is disabled, it still shows the Hot glow effect as if hovering over the Action, even though it is disabled.
Finally I find it very fiddly trying to place container components such as a TCombobox in a group. It is really awkward sizing the controls and position etc.
I guess my point is that using the standard Delphi TRibbon components appears to be not the best approach both visually and useably. How can I make a Ribbon styled Application look and work as neatly as the Microsoft ones do just like I said before the way that Wordpad and Paint do in Windows 7?
Have a look at this comparison screenshot to get a better idea:
The Delphi Ribbon seems incomplete, unless I am expecting too much. I believed the Ribbon Components are to provide your Application with a better experience for the end user both visually and better workspace etc.
What suggestions could you give to enhance or make the TRibbon work and look like the Microsoft ones?
I dont use Ribbon Style Interfaces all the time so purchasing 3rd Party Components is not something I really want to do. I have looked at the TMS and DevExpress ones but for the price of them, th开发者_Python百科ey dont look as good either. The TMS ones look worse than the standard Delphi TRibbon.
For a native look and feel, check the Windows Ribbon Framework for Delphi.
This is an Open Source wrapper around the Windows Ribbon Framework available since Windows 7 (and Vista after some official update is installed). This is the API used by the Windows 7 Word Pad.
Note also that you have two kind of layout: Office 2007 and Office 2010. The Delphi VCL Ribbon implements Office 2007 style, whereas the Windows Seven WordPad uses an Office 2010 style.
In some of our projects for some clients, we used TMS software Ribbon components. The code is a bit over-sized (a lot of duplicates or bad written stuff like component persistence) but it works and renders well, supporting both 2007 and 2010 Ribbon styles. For our Clients, rendering was what mattered. For our Open Source framework, we published a dual solution for building a Ribbon-like GUI, generated from code: it will use either standard VCL components for a basic layout, either the TMS components for a full Office 2007/2010 rendering. We just defined some classes, implemented by either libraries. If you use the generic components as defined in SQLite3ToolBar (i.e. the TSynForm, TSynToolBar, TSynToolButton, TSynPopupMenu, TSynPage, TSynPager, TSynBodyPager
and TSynBodyPage
classes) and SynTaskDialog (for TSynButton
) in your own code, the USETMSPACK conditional will do all the magic for you.
We didn't use yet the Ribbon component as was introduced in Delphi 2009. Its action-driven design won't make it easy to interface with the event-driven design of our User Interface handling, and we have to confess that this component has rather bad reputation (at least in the Delphi 2009 version).
The great Windows Ribbon Framework for Delphi won't fit our need of a on-the-fly generated Ribbon from code. Its design, from the Microsoft implementation itself, is to create the UI from an XML resource, linked at compilation... so it won't fit our needs, but it probably fit yours, for a more "static" application UI design.
If you use a Office-like Ribbon in your application, be aware of the Office UI Licensing.
The pragmatic answer is to use another component set. The TMS Software version appears good but I use the DevExpress ExpressBars one which works very well for me.
i use the Windows Ribbon Framework - the native component that ships with Windows (7).
Here's a super-short primer on the Windows Ribbon Framework from Delphi; copy-paste of important parts of code, without much explanation:
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;
But it starts to get hairy, since you have to follow Microsoft's API.
{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;
And then you have to implement them:
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;
And then you also have to
- implement
IUICommandHandler
- author a ribbon XML file
- compile the ribbon XML file with the ribbon compiler
include the compiled ribbon as a resource:
{$RESOURCE '..\Resource\UIRibbon\Ribbon_frmTicketDetails.res'}
Here's a dump of the ribbon xml i have for my app:
<?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>
精彩评论