Migrando para a Estrutura da Faixa de Opções do Windows
Um aplicativo que depende de menus tradicionais, barras de ferramentas e caixas de diálogo pode ser migrado para a interface do usuário avançada, dinâmica e controlada por contexto do sistema de comandos da estrutura da Faixa de Opções do Windows. Essa é uma maneira fácil e eficaz de modernizar e revitalizar o aplicativo, melhorando também a acessibilidade, a usabilidade e a capacidade de descoberta de sua funcionalidade.
Introdução
Em geral, a migração de um aplicativo existente para a estrutura da Faixa de Opções envolve o seguinte:
- Criar uma organização de layout e controle da Faixa de Opções que expõe a funcionalidade do aplicativo existente e é flexível o suficiente para dar suporte a novas funcionalidades.
- Adaptando o código do aplicativo existente.
- Migrando recursos de aplicativo existentes (cadeias de caracteres e imagens) para a estrutura da Faixa de Opções.
Observação
As Diretrizes de Experiência do Usuário da Faixa de Opções devem ser revisadas para determinar se o aplicativo é um candidato adequado para uma interface do usuário da faixa de opções.
Projetar o layout da faixa de opções
Possíveis designs de interface do usuário da Faixa de Opções e layouts de controle podem ser identificados executando estas etapas:
- Fazendo inventário de todas as funcionalidades existentes.
- Traduzindo essa funcionalidade em Comandos da Faixa de Opções.
- Organizando os comandos em grupos lógicos.
Fazer Inventário
Na estrutura faixa de opções, a funcionalidade exposta por um aplicativo que manipula o estado ou a exibição de um workspace ou documento é considerada um comando. O que constitui um comando pode variar e depende da natureza e do domínio do aplicativo existente.
A tabela a seguir lista um conjunto de comandos básicos para um aplicativo hipotético de edição de texto:
Símbolo | ID | Descrição |
---|---|---|
ID_FILE_NEW | 0xE100 | Novo documento |
ID_FILE_SAVE | 0xE103 | Salvar documento |
ID_FILE_SAVEAS | 0xE104 | Salvar como... (caixa de diálogo) |
ID_FILE_OPEN | 0xE101 | Aberto... (caixa de diálogo) |
ID_FILE_EXIT | 0xE102 | Sair do aplicativo |
ID_EDIT_UNDO | 0xE12B | Desfazer |
ID_EDIT_CUT | 0xE123 | Recortar texto selecionado |
ID_EDIT_COPY | 0xE122 | Copiar texto selecionado |
ID_EDIT_PASTE | 0xE125 | Colar texto da área de transferência |
ID_EDIT_CLEAR | 0xE120 | Excluir texto selecionado |
ID_VIEW_ZOOM | 1242 | Zoom... (caixa de diálogo) |
Olhe além dos menus e barras de ferramentas existentes ao criar um inventário de comandos. Considere todas as maneiras pelas quais um usuário pode interagir com o workspace. Embora nem todos os comandos sejam adequados para inclusão na Faixa de Opções, este exercício pode muito bem expor comandos que foram obscurecidos anteriormente por camadas de interface do usuário.
Tradução
Nem todos os comandos precisam ser representados na interface do usuário da Faixa de Opções. Por exemplo, inserir texto, alterar uma seleção, rolar ou mover o ponto de inserção com o mouse se qualificam como comandos no editor de texto hipotético, no entanto, eles não são adequados para expor em uma barra de comandos, pois cada um envolve uma interação direta com a interface do usuário do aplicativo.
Por outro lado, algumas funcionalidades podem não ser consideradas como um comando no sentido tradicional. Por exemplo, em vez de serem enterrados em uma caixa de diálogo, os ajustes de margem de página da impressora podem ser representados na Faixa de Opções como um grupo de controles Spinner em uma guia contextual ou no modo de aplicativo.
Observação
Anote a ID numérica que pode ser atribuída a cada comando. Algumas estruturas de interface do usuário, como o MFC (Microsoft Foundation Classes), definem IDs para comandos como o arquivo e o menu de edição (0xE100 para 0xE200).
Organizar
Antes de tentar organizar o inventário de comandos, as Diretrizes de Experiência do Usuário da Faixa de Opções devem ser examinadas quanto às práticas recomendadas ao implementar uma interface do usuário da faixa de opções.
Em geral, as seguintes regras podem ser aplicadas à organização do Comando da Faixa de Opções:
- Os comandos que operam no arquivo ou no aplicativo geral provavelmente pertencem ao Menu do Aplicativo.
- Comandos usados com frequência, como Recortar, Copiar e Colar (como no exemplo do editor de texto) normalmente são colocados em uma guia inicial padrão. Em aplicativos mais complexos, eles podem ser duplicados em outro lugar na interface do usuário da faixa de opções.
- Comandos importantes ou usados com frequência podem justificar a inclusão padrão na Barra de Ferramentas de Acesso Rápido.
A estrutura da Faixa de Opções também fornece controles ContextMenu e MiniToolbar por meio do Modo de Exibição ContextPopup. Esses recursos não são obrigatórios, mas se o aplicativo tiver um ou mais menus de contexto existentes, migrar os comandos que eles contêm poderá permitir a reutilização da base de código existente com associação automática a recursos existentes.
Como cada aplicativo é diferente, leia as diretrizes e tente aplicá-las ao máximo possível. Uma das metas da estrutura da Faixa de Opções é fornecer uma experiência de usuário familiar e consistente e essa meta será mais alcançável se os designs para novos aplicativos espelho aplicativos existentes da Faixa de Opções tanto quanto possível.
Adaptar seu código
Depois que os Comandos da Faixa de Opções tiverem sido identificados e organizados em agrupamentos lógicos, o número de etapas envolvidas ao incorporar a estrutura da Faixa de Opções no código do aplicativo existente depende da complexidade do aplicativo original. Em geral, há três etapas básicas:
- Crie a marcação da Faixa de Opções com base na organização de comando e na especificação de layout.
- Substitua o menu herdado e a funcionalidade da barra de ferramentas pela funcionalidade da Faixa de Opções.
- Implemente um adaptador IUICommandHandler.
Criar a marcação
A lista de comandos, bem como sua organização e layout são declarados por meio do arquivo de marcação da Faixa de Opções que é consumido pelo compilador de marcação da Faixa de Opções.
Observação
Muitas das etapas necessárias para adaptar um aplicativo existente são semelhantes às necessárias para iniciar um novo aplicativo da Faixa de Opções. Para obter mais informações, consulte o tutorial Criando um aplicativo de faixa de opções para um novo passo a passo do aplicativo da Faixa de Opções.
Há duas seções primárias para a marcação da Faixa de Opções. A primeira seção é um manifesto de Comandos e seus recursos associados (cadeias de caracteres e imagens). A segunda seção especifica a estrutura e o posicionamento de controles na Faixa de Opções.
A marcação do editor de texto simples pode ser semelhante ao exemplo a seguir:
Observação
Os recursos de imagem e cadeia de caracteres são abordados posteriormente neste artigo.
<?xml version="1.0" encoding="utf-8"?>
<Application xmlns="http://schemas.microsoft.com/windows/2009/Ribbon">
<Application.Commands>
<Command Name="cmdNew" Id="0xE100" Symbol="ID_CMD_NEW" LabelTitle="New document" />
<Command Name="cmdSave" Id="0xE103" Symbol="ID_CMD_SAVE" LabelTitle="Save" />
<Command Name="cmdSaveAs" Id="0xE104" Symbol="ID_CMD_SAVEAS" LabelTitle="Save as" />
<Command Name="cmdOpen" Id="0xE101" Symbol="ID_CMD_OPEN" LabelTitle="Open" />
<Command Name="cmdExit" Id="0xE102" Symbol="ID_CMD_EXIT" LabelTitle="Exit" />
<Command Name="cmdUndo" Id="0xE12B" Symbol="ID_CMD_UNDO" LabelTitle="Undo" />
<Command Name="cmdCut" Id="0xE123" Symbol="ID_CMD_CUT" LabelTitle="Cut" />
<Command Name="cmdCopy" Id="0xE122" Symbol="ID_CMD_COPY" LabelTitle="Copy" />
<Command Name="cmdPaste" Id="0xE125" Symbol="ID_CMD_PASTE" LabelTitle="Paste" />
<Command Name="cmdDelete" Id="0xE120" Symbol="ID_CMD_DELETE" LabelTitle="Delete" />
<Command Name="cmdZoom" Id="1242" Symbol="ID_CMD_ZOOM" LabelTitle="Zoom" />
</Application.Commands>
<Application.Views>
<Ribbon>
<Ribbon.ApplicationMenu>
<ApplicationMenu>
<MenuGroup>
<Button CommandName="cmdNew" />
<Button CommandName="cmdOpen" />
<Button CommandName="cmdSave" />
<Button CommandName="cmdSaveAs" />
</MenuGroup>
<MenuGroup>
<Button CommandName="cmdExit" />
</MenuGroup>
</ApplicationMenu>
</Ribbon.ApplicationMenu>
<Ribbon.QuickAccessToolbar>
<QuickAccessToolbar>
<QuickAccessToolbar.ApplicationDefaults>
<Button CommandName="cmdSave" />
<Button CommandName="cmdUndo" />
</QuickAccessToolbar.ApplicationDefaults>
</QuickAccessToolbar>
</Ribbon.QuickAccessToolbar>
<Ribbon.Tabs>
<Tab>
<Group CommandName="grpClipboard" SizeDefinition="FourButtons">
<Button CommandName="cmdPaste" />
<Button CommandName="cmdCut" />
<Button CommandName="cmdCopy" />
<Button CommandName="cmdDelete" />
</Group>
</Tab>
<Tab>
<Group CommandName="grpView" SizeDefinition="OneButton">
<Button CommandName="cmdZoom" />
</Group>
</Tab>
</Ribbon.Tabs>
</Ribbon>
</Application.Views>
</Application>
Para evitar a redefinição de símbolos definidos por uma estrutura de interface do usuário, como MFC, o exemplo anterior usa nomes de símbolo ligeiramente diferentes para cada Comando (ID_FILE_NEW versus ID_CMD_NEW). No entanto, a ID numérica atribuída a cada Comando deve permanecer a mesma.
Para integrar o arquivo de marcação a um aplicativo, configure uma etapa de build personalizada para executar o compilador de marcação da Faixa de Opções, UICC.exe. Os arquivos de cabeçalho e recurso resultantes são incorporados ao projeto existente. Se o aplicativo de Faixa de Opções do editor de texto de exemplo for chamado de "RibbonPad", será necessária uma linha de comando de build personalizado semelhante à seguinte:
UICC.exe res\RibbonPad_ribbon.xml res\RibbonPad_ribbon.bin
/header:res\RibbonPad_ribbon.h /res:res\RibbonPad_ribbon.rc2
O compilador de marcação cria um arquivo binário, um arquivo de cabeçalho (H) e um arquivo RC (recurso). Como o aplicativo existente provavelmente tem um arquivo RC existente, inclua os arquivos H e RC gerados nesse arquivo RC, conforme mostrado no exemplo a seguir:
#ifndef APSTUDIO_INVOKED
/////////////////////////////////////////////////////////////////////////////
//
// Generated from the TEXTINCLUDE 3 resource.
//
#define _AFX_NO_SPLITTER_RESOURCES
#define _AFX_NO_OLE_RESOURCES
#define _AFX_NO_TRACKER_RESOURCES
#define _AFX_NO_PROPERTY_RESOURCES
#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU)
LANGUAGE 9, 1
#pragma code_page(1252)
#include "res\RibbonPad_ribbon.h" // Ribbon resources
#include "res\RibbonPad_ribbon.rc2" // Ribbon resources
#include "res\RibbonPad.rc2" // non-Microsoft Visual C++ edited resources
#include "afxres.rc" // Standard components
#include "afxprint.rc" // printing/print preview resources
#endif
#endif // not APSTUDIO_INVOKED
Substituir menus herdados e barras de ferramentas
Substituir menus padrão e barras de ferramentas por uma faixa de opções em um aplicativo herdado requer o seguinte:
- Remova as referências de recurso da barra de ferramentas e do menu do arquivo de recurso do aplicativo.
- Exclua todos os códigos de inicialização da barra de ferramentas e da barra de menus.
- Exclua qualquer código usado para anexar uma barra de ferramentas ou barra de menus à janela de nível superior do aplicativo.
- Instancie a estrutura da Faixa de Opções.
- Anexe a faixa de opções à janela de nível superior do aplicativo.
- Carregue a marcação compilada.
Importante
As tabelas de atalho de barra de status e teclado existentes devem ser preservadas, pois a estrutura da Faixa de Opções não substitui esses recursos.
O exemplo a seguir demonstra como inicializar a estrutura usando IUIFramework::Initialize:
int CMainFrame::OnCreate(LPCREATESTRUCT lpCreateStruct)
{
if (CFrameWnd::OnCreate(lpCreateStruct) == -1)
return -1;
if (!m_RibbonBar.Create(this, WS_CHILD|WS_DISABLED|WS_VISIBLE|CBRS_TOP|CBRS_HIDE_INPLACE,0))
return -1; // fail to create
if (!m_wndStatusBar.Create(this) || !m_wndStatusBar.SetIndicators(indicators,sizeof(indicators)/sizeof(UINT)))
return -1; // fail to create
// Ribbon initialization
InitRibbon(this, &m_spUIFramework);
return 0;
}
O exemplo a seguir demonstra como usar IUIFramework::LoadUI para carregar a marcação compilada:
HRESULT InitRibbon(CMainFrame* pMainFrame, IUnknown** ppFramework)
{
// Create the IUIFramework instance.
CComPtr<IUIFramework> spFramework;
HRESULT hr = ::CoCreateInstance(CLSID_UIRibbonFramework, NULL, CLSCTX_INPROC_SERVER, IID_PPV_ARGS(&spFramework));
if (FAILED(hr))
return hr;
// Instantiate the CApplication object.
CComObject<CApplication>* pApplication;
hr = CComObject<CApplication>::CreateInstance(&pApplication); // Refcount is 0
// Call AddRef on the CApplication object. The smart pointer will release the refcount when it is out of scope.
CComPtr< CComObject<CApplication> > spApplication(pApplication);
if (FAILED(hr))
return hr;
// Initialize and load the Ribbon.
spApplication->Initialize(pMainFrame);
hr = spFramework->Initialize(*pMainFrame, spApplication);
if (FAILED(hr))
return hr;
hr = spFramework->LoadUI(GetModuleHandle(NULL), L"APPLICATION_RIBBON");
if (FAILED(hr))
return hr;
// Return IUIFramework interface to the caller.
hr = spFramework->QueryInterface(ppFramework);
return hr;
}
A classe CApplication, referida acima, deve implementar um par de interfaces COM (Component Object Model) definidas pela estrutura da Faixa de Opções: IUIApplication e IUICommandHandler.
IUIApplication fornece a interface de retorno de chamada main entre a estrutura e o aplicativo (por exemplo, a altura da faixa de opções é comunicada por meio de IUIApplication::OnViewChanged), enquanto os retornos de chamada para comandos individuais são fornecidos em resposta a IUIApplication::OnCreateUICommand.
Ponta: Algumas estruturas de aplicativo, como o MFC, exigem que a altura da barra de faixa de opções seja levada em conta ao renderizar o espaço do documento do aplicativo. Nesses casos, é necessária a adição de uma janela oculta para sobrepor a barra de faixa de opções e forçar o espaço do documento à altura desejada. Para obter um exemplo dessa abordagem, em que uma função de layout é chamada com base na altura da faixa de opções retornada pelo método IUIRibbon::GetHeight , consulte o Exemplo HTMLEditRibbon.
O exemplo de código a seguir demonstra uma implementação IUIApplication::OnViewChanged :
// This is the Ribbon implementation that is done by an application.
// Applications have to implement IUIApplication and IUICommandHandler to set up communication with the Windows Ribbon.
class CApplication
: public CComObjectRootEx<CComSingleThreadModel>
, public IUIApplication
, public IUICommandHandler
{
public:
BEGIN_COM_MAP(CApplication)
COM_INTERFACE_ENTRY(IUIApplication)
COM_INTERFACE_ENTRY(IUICommandHandler)
END_COM_MAP()
CApplication() : _pMainFrame(NULL)
{
}
void Initialize(CMainFrame* pFrame)
{
// Hold a reference to the main frame.
_pMainFrame = pFrame;
}
void FinalRelease()
{
// Release the reference.
_pMainFrame = NULL;
__super::FinalRelease();
}
STDMETHOD(OnViewChanged)(UINT32 nViewID, __in UI_VIEWTYPE typeID, __in IUnknown* pView, UI_VIEWVERB verb, INT32 uReasonCode)
{
HRESULT hr;
// The Ribbon size has changed.
if (verb == UI_VIEWVERB_SIZE)
{
CComQIPtr<IUIRibbon> pRibbon = pView;
if (!pRibbon)
return E_FAIL;
UINT ulRibbonHeight;
// Get the Ribbon height.
hr = pRibbon->GetHeight(&ulRibbonHeight);
if (FAILED(hr))
return hr;
// Update the Ribbon bar so that the main frame can recalculate the child layout.
_pMainFrame->m_RibbonBar.SetRibbonHeight(ulRibbonHeight);
_pMainFrame->RecalcLayout();
}
return S_OK;
}
STDMETHOD(OnCreateUICommand)(UINT32 nCmdID,
__in UI_COMMANDTYPE typeID,
__deref_out IUICommandHandler** ppCommandHandler)
{
// This application uses one command handler for all ribbon commands.
return QueryInterface(IID_PPV_ARGS(ppCommandHandler));
}
STDMETHOD(OnDestroyUICommand)(UINT32 commandId, __in UI_COMMANDTYPE typeID, __in_opt IUICommandHandler *commandHandler)
{
return E_NOTIMPL;
}
private:
CMainFrame* _pMainFrame;
};
Implementar um adaptador IUICommandHandler
Dependendo do design do aplicativo original, pode ser mais fácil ter várias implementações de manipulador de comando ou um único manipulador de comando de ponte que invoca a lógica de comando do aplicativo existente. Muitos aplicativos usam mensagens WM_COMMAND para essa finalidade, em que é suficiente fornecer um único manipulador de comando para todos os fins que simplesmente encaminha mensagens WM_COMMAND para a janela de nível superior.
No entanto, essa abordagem requer tratamento especial para comandos como Sair ou Fechar. Como a Faixa de Opções não pode ser destruída enquanto está processando uma mensagem de janela, a mensagem WM_CLOSE deve ser postada no thread da interface do usuário do aplicativo e não deve ser processada de forma síncrona, conforme mostrado no exemplo a seguir:
// User action callback, with transient execution parameters.
STDMETHODIMP Execute(UINT nCmdID,
UI_EXECUTIONVERB verb,
__in_opt const PROPERTYKEY* key,
__in_opt const PROPVARIANT* ppropvarValue,
__in_opt IUISimplePropertySet* pCommandExecutionProperties)
{
switch(nCmdID)
{
case cmdExit:
::PostMessage(*_pMainFrame, WM_CLOSE, nCmdID, 0);
break;
default:
::SendMessage(*_pMainFrame, WM_COMMAND, nCmdID, 0);
}
return S_OK;
}
STDMETHODIMP UpdateProperty(UINT32 nCmdID,
__in REFPROPERTYKEY key,
__in_opt const PROPVARIANT *currentValue,
__out PROPVARIANT *newValue)
{
return S_OK;
}
Migrando recursos
Quando o manifesto dos comandos foi definido, a estrutura da Faixa de Opções foi declarada e o código do aplicativo adaptado para hospedar a estrutura da Faixa de Opções, a etapa final é a especificação de recursos de cadeia de caracteres e imagem para cada Comando.
Observação
Normalmente, os recursos de cadeia de caracteres e imagem são fornecidos no arquivo de marcação. No entanto, eles podem ser gerados ou substituídos programaticamente implementando o método de retorno de chamada IUICommandHandler::UpdateProperty .
Recursos de cadeia de caracteres
Command.LabelTitle é a propriedade de cadeia de caracteres mais comum definida para um Command. Eles são renderizados como rótulos de texto para guias, grupos e controles individuais. Uma cadeia de caracteres de rótulo de um item de menu herdado normalmente pode ser reutilizado para um Command.LabelTitle sem muita edição.
No entanto, as seguintes convenções foram alteradas com o advento da Faixa de Opções:
- O sufixo de reticências (...), usado para indicar um comando de inicialização de caixa de diálogo, não é mais necessário.
- O e comercial (&) ainda pode ser usado para indicar um atalho de teclado para um Comando que aparece em um menu, mas a propriedade Command.Keytip compatível com a estrutura atende a uma finalidade semelhante.
Fazendo referência ao exemplo do editor de texto, as seguintes cadeias de caracteres para LabelTitle e Keytip podem ser especificadas:
Símbolo | Cadeia de caracteres original | Cadeia de caracteres LabelTitle | Cadeia de caracteres de dica de chave |
---|---|---|---|
ID_FILE_NEW | &Novo | &Novo | N |
ID_FILE_SAVE | &Salvar | &Salvar | S |
ID_FILE_SAVEAS | Salvar &como... | Salvar &como | A |
ID_FILE_OPEN | &Aberto... | &Aberto | O |
ID_FILE_EXIT | E&xit | E&xit | X |
ID_EDIT_UNDO | &Desfazer | Desfazer | Z |
ID_EDIT_CUT | Cu&t | Cu&t | X |
ID_EDIT_COPY | &Copiar | &Copiar | C |
ID_EDIT_PASTE | &Colar | &Colar | V |
ID_EDIT_CLEAR | &Excluir | &Excluir | D |
ID_VIEW_ZOOM | &Zoom... | Zoom | Z |
Veja a seguir uma lista de outras propriedades de cadeia de caracteres que devem ser definidas na maioria dos Comandos:
Guias, Grupos e outros recursos da interface do usuário da Faixa de Opções agora podem ser declarados com todos os recursos de cadeia de caracteres e imagem especificados.
O exemplo de marcação da Faixa de Opções a seguir demonstra vários recursos de cadeia de caracteres:
<Application.Commands>
<!-- Tabs -->
<Command Name="tabHome" LabelTitle="Home" Keytip="H" />
<Command Name="tabView" LabelTitle="View" Keytip="V" />
<!-- Groups -->
<Command Name="grpClipboard" LabelTitle="Clipboard" />
<Command Name="grpZoom" LabelTitle="Zoom" />
<!-- App menu commands -->
<Command Name="cmdNew" Id="0xE100" Symbol="ID_CMD_NEW" LabelTitle="New document" Keytip="N" >
<Command.TooltipTitle>New (Ctrl+N)</Command.TooltipTitle>
<Command.TooltipDescription>Create a new document.</Command.TooltipDescription>
</Command>
<Command Name="cmdSave" Id="0xE103" Symbol="ID_CMD_SAVE" LabelTitle="Save" Keytip="S">
<Command.TooltipTitle>Save (Ctrl+S)</Command.TooltipTitle>
<Command.TooltipDescription>Save the current document.</Command.TooltipDescription>
</Command>
<Command Name="cmdSaveAs" Id="0xE104" Symbol="ID_CMD_SAVEAS" LabelTitle="Save as" Keytip="A">
<Command.TooltipDescription>Save the current document with a new name.</Command.TooltipDescription>
</Command>
<Command Name="cmdOpen" Id="0xE101" Symbol="ID_CMD_OPEN" LabelTitle="Open" Keytip="O">
<Command.TooltipTitle>Open (Ctrl+O)</Command.TooltipTitle>
<Command.TooltipDescription>Open a document.</Command.TooltipDescription>
</Command>
<Command Name="cmdExit" Id="0xE102" Symbol="ID_CMD_EXIT" LabelTitle="Exit" Keytip="X">
<Command.TooltipDescription>Exit the application.</Command.TooltipDescription>
</Command>
<!-- ...other commands -->
</Application.Commands>
Recursos de imagem
A estrutura da Faixa de Opções dá suporte a formatos de imagem que fornecem uma aparência muito mais rica do que os formatos de imagem compatíveis com componentes anteriores do menu e da barra de ferramentas.
Para Windows 8 e posteriores, a estrutura da Faixa de Opções dá suporte aos seguintes formatos gráficos: arquivos BMP (bitmap ARGB) de 32 bits e arquivos PNG (Portable Network Graphics) com transparência.
Para o Windows 7 e anteriores, os recursos de imagem devem estar em conformidade com o formato gráfico BMP padrão usado no Windows.
Observação
Os arquivos de imagem existentes podem ser convertidos em qualquer um dos formatos. No entanto, os resultados poderão ser menos satisfatórios se os arquivos de imagem não deem suporte à suavização e à transparência.
Não é possível especificar um único tamanho padrão para recursos de imagem na estrutura da Faixa de Opções. No entanto, para dar suporte ao layout adaptável de controles, as imagens podem ser especificadas em dois tamanhos (grandes e pequenos). Todas as imagens na estrutura da Faixa de Opções são dimensionadas de acordo com a resolução de pontos por polegada (dpi) da exibição com o tamanho renderizado exato dependente dessa configuração de dpi. Consulte Especificando recursos de imagem da faixa de opções para obter mais informações.
O exemplo a seguir demonstra como um conjunto de imagens específicas do dpi são referenciadas na marcação:
<Command Name="cmdNew" Id="0xE100" Symbol="ID_CMD_NEW" LabelTitle="New document" Keytip="N" >
<Command.TooltipTitle>New (Ctrl+N)</Command.TooltipTitle>
<Command.TooltipDescription>Create a new document.</Command.TooltipDescription>
<Command.LargeImages>
<Image Source="cmdNew-32px.png" MinDPI="96" />
<Image Source="cmdNew-40px.png" MinDPI="120" />
<Image Source="cmdNew-48px.png" MinDPI="144" />
<Image Source="cmdNew-64px.png" MinDPI="192" />
</Command.LargeImages>
<Command.SmallImages>
<Image Source="cmdNew-16px.png" MinDPI="96" />
<Image Source="cmdNew-20px.png" MinDPI="120" />
<Image Source="cmdNew-24px.png" MinDPI="144" />
<Image Source="cmdNew-32px.png" MinDPI="192" />
</Command.SmallImages>
</Command>
Tópicos relacionados