-
Notifications
You must be signed in to change notification settings - Fork 19
Use Ribbon as External DLL
Using Windows Ribbon for WinForms just got a lot easier.
Warning: Boring post. Talks about changes in the ribbon library and their reasons.
But first, let me start by asking for your forgiveness. I’m trying to create a library which will be easy to use and so the last change to the library wasn’t backward compatible. Namely, classes names and interfaces have changed. Rest assured that every single change I made is making the library a little easier to use. However, for all those who have started using the library, I say: sorry. [This is what you get for using a project in BETA]
So, what have changed?
Classes names I’ve added a “Ribbon” prefix to all the ribbon controls helper classes. This is to prevent collision with the standard WinForms controls, like Button, ComboBox, etc.
Yea, I know, this is why we have namespaces. However, having a WinForms project with both a button and a ribbon button is not a rare case. When this happen, the user can’t add “using RibbonLib.Controls;” so almost every other line is cluttered with “RibbonLib.Controls” prefix, for example:
RibbonLib.Controls.Button ribbonButton = new RibbonLib.Controls.Button(_ribbon, commandId);
Instead of:
RibbonButton ribbonButton = new RibbonButton(_ribbon, commandId);
IUICommandHandler Implementation I’ve added a general implementation of IUICommandHandler (Execute and UpdateProperty functions) to the Ribbon class, so that these methods should not be implemented anymore by the user. This means the user doesn’t need to write anymore the following code in its Form class:
public HRESULT Execute(uint commandId, ExecutionVerb verb, PropertyKeyRef key, PropVariantRef currentValue, IUISimplePropertySet commandExecutionProperties)
{
switch (commandId)
{
case (uint)RibbonMarkupCommands.cmdDropDownColorPickerGroup:
_groupColors.Execute(verb, key, currentValue, commandExecutionProperties);
break;
case (uint)RibbonMarkupCommands.cmdButtonsGroup:
_groupButtons.Execute(verb, key, currentValue, commandExecutionProperties);
break;
case (uint)RibbonMarkupCommands.cmdButtonListColors:
_buttonListColors.Execute(verb, key, currentValue, commandExecutionProperties);
break;
case (uint)RibbonMarkupCommands.cmdDropDownColorPickerThemeColors:
_themeColors.Execute(verb, key, currentValue, commandExecutionProperties);
break;
case (uint)RibbonMarkupCommands.cmdDropDownColorPickerStandardColors:
_standardColors.Execute(verb, key, currentValue, commandExecutionProperties);
break;
case (uint)RibbonMarkupCommands.cmdDropDownColorPickerHighlightColors:
_highlightColors.Execute(verb, key, currentValue, commandExecutionProperties);
break;
}
return HRESULT.S_OK;
}
public HRESULT UpdateProperty(uint commandId, ref PropertyKey key, PropVariantRef currentValue, ref PropVariant newValue)
{
switch (commandId)
{
case (uint)RibbonMarkupCommands.cmdDropDownColorPickerGroup:
_groupColors.UpdateProperty(ref key, currentValue, ref newValue);
break;
case (uint)RibbonMarkupCommands.cmdButtonsGroup:
_groupButtons.UpdateProperty(ref key, currentValue, ref newValue);
break;
case (uint)RibbonMarkupCommands.cmdButtonListColors:
_buttonListColors.UpdateProperty(ref key, currentValue, ref newValue);
break;
case (uint)RibbonMarkupCommands.cmdDropDownColorPickerThemeColors:
_themeColors.UpdateProperty(ref key, currentValue, ref newValue);
break;
case (uint)RibbonMarkupCommands.cmdDropDownColorPickerStandardColors:
_standardColors.UpdateProperty(ref key, currentValue, ref newValue);
break;
case (uint)RibbonMarkupCommands.cmdDropDownColorPickerHighlightColors:
_highlightColors.UpdateProperty(ref key, currentValue, ref newValue);
break;
}
return HRESULT.S_OK;
}
The new implementation, which resides in the Ribbon class just delegates the call to the correct ribbon control, according to the command ID:
public virtual HRESULT Execute(uint commandID, ExecutionVerb verb, PropertyKeyRef key,
PropVariantRef currentValue,
IUISimplePropertySet commandExecutionProperties)
{
if (_mapRibbonControls.ContainsKey(commandID))
{
_mapRibbonControls[commandID].Execute(verb, key, currentValue,
commandExecutionProperties);
}
return HRESULT.S_OK;
}
public virtual HRESULT UpdateProperty(uint commandID, ref PropertyKey key,
PropVariantRef currentValue,
ref PropVariant newValue)
{
if (_mapRibbonControls.ContainsKey(commandID))
{
_mapRibbonControls[commandID].UpdateProperty(ref key, currentValue,
ref newValue);
}
return HRESULT.S_OK;
}
The _mapRibbonControls is an internal dictionary that contains all the ribbon controls helper classes the user have created in the main form.
!Note:
I’ve made these functions virtual so that if some user wants direct access to the notifications from the ribbon framework, he can still get them by deriving from the Ribbon class and overriding these methods.
Support for Ribbon External DLL Now you can have your ribbon resource reside in an external dll instead of inside the application executable, as a native resource. This issue was a problem for developers who needed the native resource for other uses (like setting the application icon).
In fact, I’ve made this the default behavior of the ribbon. So now when you call the simplest form of Ribbon.InitFramework, the ribbon library tries to load the ribbon from your_app_name.ribbon.dll and only if it fails to find this file it will revert back to the previous behavior, that is, try to load ribbon from your executable native resource.
Of course, you can provide your own dll name to load, or even load it yourself and pass the dll handle (=what returns from LoadLibrary) to the different overloads of Ribbon.InitFramework. This allows you to implement a custom ribbon loading mechanism which can be useful if you wish to load different ribbons on different scenarios, e.g. add localization support (different locale has different ribbon).
What this means for the user of the ribbon library is that he needs to add one more step to the pre-build event. This step will create the ribbon resource dll from the resource file created by previous steps. So, the pre-build events for projects that uses the ribbon library are now (example code, for building the RibbonMarkup.ribbon file use the RibbonTools):
"%PROGRAMFILES%\Microsoft SDKs\Windows\v7.0\Bin\UICC.exe" "$(ProjectDir)RibbonMarkup.xml" "$(ProjectDir)RibbonMarkup.bml" /res:"$(ProjectDir)RibbonMarkup.rc"
"%PROGRAMFILES%\Microsoft SDKs\Windows\v7.0\Bin\rc.exe" "$(ProjectDir)RibbonMarkup.rc"
cmd /c "("$(DevEnvDir)..\..\VC\bin\vcvars32.bat") && ("$(DevEnvDir)..\..\VC\bin\link.exe" /NOENTRY /DLL /OUT:"$(ProjectDir)$(OutDir)$(TargetName).ribbon.dll" "$(ProjectDir)RibbonMarkup.res")"
I know, this looks like a pile of junk, but actually what’s written is:
- UICC – please convert RibbonMarkup.xml to RibbonMarkup.rc
- rc – please convert RibbonMarkup.rc to RibbonMarkup.res
- link – please convert RibbonMarkup.res to RibbonMarkup.ribbon
I’ve updated all the ribbon library samples to use the ribbon resource dll.
-
Basics
- Introduction, Background on the windows ribbon
- Basic Ribbon Wrapper Basic .NET wrappers for windows ribbon.
- Quickstart Tutorial
- First WinForms Ribbon Application How to create an empty WinForms application with ribbon support.
-
Working with Ribbon Controls
- Application Menu with Buttons How to use the ribbon application menu.
- Application Menu with SplitButton and DropDownButton How to use the ribbon application menu with ribbon split button and ribbon dropdown button controls.
- Tabs, Groups and HelpButton How to use ribbon tabs, groups and the ribbon help button control.
- Spinner How to use the ribbon spinner control.
- ComboBox How to use the ribbon combo box control.
- DropDownGallery, SplitButtonGallery and InRibbonGallery How to use the ribbon drop down gallery, split button gallery and in ribbon gallery controls.
- CheckBox and ToggleButton How to use the ribbon check box and toggle button controls.
- DropDownColorPicker How to use the ribbon drop down color picker control.
- FontControl How to use the ribbon font control.
- ContextualTabs How to work with ribbon contextual tabs.
- ContextPopup How to work with ribbon context popup.
- RecentItems How to work with ribbon recent items control.
- QuickAccessToolbar How to work with the ribbon quick access toolbar.
- The Ribbon Class How to work with the ribbon class. Methods, Properties, Events
- EventLogger Since Windows 8: Logging ribbon events
- UICollectionChangedEvent How to work with the ChangedEvent in an IUICollection
-
Working with miscellany Ribbon features
- ApplicationModes How to work with ribbon application modes.
- SizeDefinition How to define custom size definitions for ribbon group elements.
- Localization How to localize a ribbon.
- Changing Ribbon Colors How to change the ribbon colors.
- Working with Images How to work with images in the ribbon.
- Use Ribbon as External DLL How to load ribbon resources from external DLLs.
- Wrapper class RibbonItems An auto generated wrapper class from the ribbon markup.
-
Designing, building, previewing Windows Ribbon with RibbonTools
- RibbonTools basics Settings, Command line, ...
- Create a new project Create a WordPad sample project
- Preview the Ribbon
- Specifying Ribbon Commands
- Designing Ribbon Views
- Convert Images to Alpha Bitmaps
-
Modeling Guidelines
-
How to ...