Creating Ribbon Styled Applications

前端 未结 3 1439
滥情空心
滥情空心 2020-12-08 03:07

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 gl

3条回答
  •  庸人自扰
    2020-12-08 03:36

    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:

    
    
    
        
        
            
            
            
            
            
    
            
            
            
            
            
    
            
    
                
                    
                        Save and Close (Alt+S)
                        Saves the current ticket and closes the detail screen.
                        
                            
                        
                    
                    
                    
                    
    
                
                    
                    
                        
                            
                        
                    
                    
                    
                    
    
                
                    
                    
                    
                        
                            
                        
                        
                            
                        
                    
                    
                        
                            
                        
                    
    
                
                    
                    
                    
                    
    
        
    
        
        
            
    
                
                
                    
                        
                            

提交回复
热议问题