最近用 WTL 写 Ribbon 界面,发现一个坑。
先看 WTL9.1 的代码
static void (CharFormat::*Getk_[])(IPropertyStore*) = { &CharFormat::Getk_Family, &CharFormat::Getk_FontProperties_Size, &CharFormat::Getk_MaskEffect, &CharFormat::Getk_MaskEffect , &CharFormat::Getk_MaskEffect , &CharFormat::Getk_MaskEffect , &CharFormat::Getk_VerticalPositioning, &CharFormat::Getk_Color , &CharFormat::Getk_Color , &CharFormat::Getk_ColorType , &CharFormat::Getk_ColorType ,};
其中 Getk_MaskEffect 是个模版函数,实现如下:
templatevoid Getk_MaskEffect(IPropertyStore* pStore){ if (SUCCEEDED(pStore->GetValue(key, &propvar))) { UIPropertyToUInt32(key, propvar, &uValue); if ((UI_FONTPROPERTIES)uValue != UI_FONTPROPERTIES_NOTAVAILABLE) { dwMask |= t_dwMask; dwEffects |= ((UI_FONTPROPERTIES) uValue == UI_FONTPROPERTIES_SET) ? t_dwEffects : 0; } } }
然后,在 VS2017 编译失败了……
1>X:\WTL91_5321_Final\Include\atlribbon.h(422): error C2440: 'initializing': cannot convert from 'overloaded-function' to 'void (__thiscall WTL::RibbonUI::CharFormat::* )(IPropertyStore *)'
1>X:\WTL91_5321_Final\Include\atlribbon.h(422): note: None of the functions with this name in scope match the target type
然后根据错误提示搜到:Cannot take address of template function,,翻译一下:模版函数的地址转化,分两步走,第一步先转具化,第二步转目标类型,这样可以;直接转过去不可以!
再来看看 WTL10 怎么解决这个问题的!
static void (CharFormat::*Getk_[])(IPropertyStore*) = { &CharFormat::Getk_Family, &CharFormat::Getk_FontProperties_Size, &CharFormat::Getk_MaskEffectBold, &CharFormat::Getk_MaskEffectItalic, &CharFormat::Getk_MaskEffectUnderline, &CharFormat::Getk_MaskEffectStrikeout, &CharFormat::Getk_VerticalPositioning, &CharFormat::Getk_Color, &CharFormat::Getk_ColorBack, &CharFormat::Getk_ColorType, &CharFormat::Getk_ColorTypeBack,};
原来的模版函数,已经替换成普通函数了……
void Getk_MaskEffectBold(IPropertyStore* pStore){ Getk_MaskEffectAll(pStore, CFM_BOLD, CFE_BOLD, UI_PKEY_FontProperties_Bold);}void Getk_MaskEffectItalic(IPropertyStore* pStore){ Getk_MaskEffectAll(pStore, CFM_ITALIC, CFE_ITALIC, UI_PKEY_FontProperties_Italic);}void Getk_MaskEffectUnderline(IPropertyStore* pStore){ Getk_MaskEffectAll(pStore, CFM_UNDERLINE, CFE_UNDERLINE, UI_PKEY_FontProperties_Underline);}void Getk_MaskEffectStrikeout(IPropertyStore* pStore){ Getk_MaskEffectAll(pStore, CFM_STRIKEOUT, CFE_STRIKEOUT, UI_PKEY_FontProperties_Strikethrough);}void Getk_MaskEffectAll(IPropertyStore* pStore, DWORD _dwMask, DWORD _dwEffects, REFPROPERTYKEY key){ if (SUCCEEDED(pStore->GetValue(key, &propvar))) { UIPropertyToUInt32(key, propvar, &uValue); if ((UI_FONTPROPERTIES)uValue != UI_FONTPROPERTIES_NOTAVAILABLE) { dwMask |= _dwMask; dwEffects |= ((UI_FONTPROPERTIES)uValue == UI_FONTPROPERTIES_SET) ? _dwEffects : 0; } }}