STDMETHODIMP CNativeRibbonApp::Execute(UINT32 commandId, UI_EXECUTIONVERB verb, const PROPERTYKEY* key, const PROPVARIANT* currentValue, IUISimplePropertySet* /*commandExecutionProperties*/)
{
	if (verb == UI_EXECUTIONVERB_EXECUTE)
	{
		if (key && IsEqualPropertyKey(*key, UI_PKEY_SelectedItem))
		{
			CComPtr<IUICollection> items = GetUICommandItemsSource(commandId);
			UINT32 selectedItemIdx = 0;
			UIPropertyToUInt32(UI_PKEY_SelectedItem, *currentValue, &selectedItemIdx);
			UINT32 count = 0;
			items->GetCount(&count);

			if (selectedItemIdx < count)
			{
				CComPtr<IUnknown> selectedItemUnk;
				items->GetItem(selectedItemIdx, &selectedItemUnk);
				CComQIPtr<IUISimplePropertySet> selectedItemPropSet(selectedItemUnk);
				if (selectedItemPropSet)
					m_pFrame->PostMessage(WM_COMMAND, GetCommandIdProperty(selectedItemPropSet));
			}
		}
		else
			m_pFrame->PostMessage(WM_COMMAND, commandId);

		return S_OK;
	}

	return S_FALSE;
}
UINT CNativeRibbonApp::GetCommandIdProperty(IUISimplePropertySet* propertySet)
{
	PROPVARIANT var = { 0 };
	UINT32 commandId = 0;

	if (propertySet->GetValue(UI_PKEY_CommandId, &var) == S_OK)
		UIPropertyToUInt32(UI_PKEY_CommandId, var, &commandId);

	return commandId;
}
IFACEMETHODIMP
touchmind::ribbon::handler::LineColorCommandHandler::Execute(UINT cmdID, UI_EXECUTIONVERB verb, const PROPERTYKEY *pKey,
                                                             const PROPVARIANT *pPropvarValue,
                                                             IUISimplePropertySet *pCommandExecutionProperties) {
  UNREFERENCED_PARAMETER(cmdID);
  UNREFERENCED_PARAMETER(pCommandExecutionProperties);

  LOG(SEVERITY_LEVEL_DEBUG) << L"key = " << *pKey;

  HRESULT hr = E_FAIL;
  if (pKey && *pKey == UI_PKEY_ColorType) {
    UINT color = 0;
    UINT type = UI_SWATCHCOLORTYPE_NOCOLOR;
    // The Ribbon framework passes color type as the primary property.
    if (pPropvarValue != nullptr) {
      // Retrieve color type.
      hr = UIPropertyToUInt32(UI_PKEY_ColorType, *pPropvarValue, &type);
      if (FAILED(hr)) {
        return hr;
      }
    }

    // The Ribbon framework passes color as additional property if the color type is RGB.
    if (type == UI_SWATCHCOLORTYPE_RGB && pCommandExecutionProperties != nullptr) {
      // Retrieve color.
      PROPVARIANT var;
      hr = pCommandExecutionProperties->GetValue(UI_PKEY_Color, &var);
      if (FAILED(hr)) {
        return hr;
      }
      UIPropertyToUInt32(UI_PKEY_Color, var, &color);
    }
    D2D1_COLOR_F colorF = touchmind::util::ColorUtil::ToColorF(static_cast<COLORREF>(color));
    m_pRibbonRequestDispatcher->Execute_LineColor(verb, colorF);
    m_pRibbonFramework->GetFramework()->InvalidateUICommand(cmdLineColor, UI_INVALIDATIONS_PROPERTY,
                                                            &UI_PKEY_LargeImage);
  }
  return hr;
}
STDMETHODIMP CNativeRibbonApp::UpdateProperty(UINT32 commandId, REFPROPERTYKEY key, const PROPVARIANT* /*currentValue*/, PROPVARIANT* newValue)
{
	if (key == UI_PKEY_TooltipTitle)
	{
		CString str;
		if (!str.LoadString(commandId))
			return S_FALSE;

		int nIndex = str.Find(L'\n');
		if (nIndex <= 0)
			return S_FALSE;

		str = str.Mid(nIndex + 1);

		CString strLabel;

		if (m_pFrame != NULL && (CKeyboardManager::FindDefaultAccelerator(commandId, strLabel, m_pFrame, TRUE) ||
			CKeyboardManager::FindDefaultAccelerator(commandId, strLabel, m_pFrame->GetActiveFrame(), FALSE)))
		{
			str += _T(" (");
			str += strLabel;
			str += _T(')');
		}

		return UIInitPropertyFromString(UI_PKEY_TooltipTitle, str, newValue);
	}
	else if (key == UI_PKEY_TooltipDescription)
	{
		CString str;
		if (!str.LoadString(commandId))
			return S_FALSE;

		int nIndex = str.Find(L'\n');
		if (nIndex <= 0)
			return S_FALSE;

		str = str.Left(nIndex);

		return UIInitPropertyFromString(UI_PKEY_TooltipDescription, str, newValue);
	}
	else if (key == UI_PKEY_Enabled)
	{
		CRibbonCmdUI ui(commandId);
		ui.DoUpdate(m_pFrame, TRUE);

		return UIInitPropertyFromBoolean(UI_PKEY_Enabled, ui.m_bOn, newValue);
	}
	else if (key == UI_PKEY_BooleanValue)
	{
		CRibbonCmdUI ui(commandId);
		ui.DoUpdate(m_pFrame, TRUE);

		return UIInitPropertyFromBoolean(UI_PKEY_BooleanValue, ui.m_nCheck, newValue);
	}
	else if (key == UI_PKEY_SelectedItem)
	{
		CComPtr<IUICollection> items = GetUICommandItemsSource(commandId);
		if (!items)
			return E_FAIL;

		UINT32 count;
		items->GetCount(&count);
		for (UINT32 idx = 0; idx < count; idx++)
		{
			CComPtr<IUnknown> item;
			items->GetItem(idx, &item);

			CComQIPtr<IUISimplePropertySet> simplePropertySet(item);
			if (simplePropertySet)
			{
				PROPVARIANT var = { 0 };
				UINT32 uiVal;
				simplePropertySet->GetValue(UI_PKEY_CommandId, &var);
				UIPropertyToUInt32(UI_PKEY_CommandId, var, &uiVal);

				CRibbonCmdUI ui(uiVal);
				ui.DoUpdate(m_pFrame, TRUE);

				if (ui.m_nCheck)
				{
					UIInitPropertyFromUInt32(UI_PKEY_SelectedItem, idx, newValue);
					return S_OK;
				}
			}
		}

		// No selected item.
		UIInitPropertyFromUInt32(UI_PKEY_SelectedItem, static_cast<UINT>(-1), newValue);

		return S_OK;
	}

	return E_NOTIMPL;
}