CTabCtrl ItemAction & ItemState

Posted

技术标签:

【中文标题】CTabCtrl ItemAction & ItemState【英文标题】: 【发布时间】:2018-11-07 07:39:36 【问题描述】:

我创建了自己的 CXTabCtrl,它扩展了 CTabCtrl 并覆盖了 DrawItem 函数。 在重写DrawItem函数的阶段,我无法区分CTabCtrl的这两种状态项目:

    CTabCtrl 项目被选中并获得焦点。 CTabctrl 项目被选中但没有焦点。

焦点是指焦点矩形未绘制。以下是有助于识别这两种状态的两张图片:

这是DrawItem 当前代码,我可以在其中检测到选定的状态,但仍然无法检测到焦点状态。

这是DrawItem当前代码的一部分,我可以在其中检测到选定的状态,但仍然无法检测到焦点状态。

void CXtabCtrl::DrawItem(LPDRAWITEMSTRUCT lpDrawItemStruct) 

    CDC* pDC = CDC::FromHandle(lpDrawItemStruct->hDC);
    BOOL bFontSuccess = FALSE;
    CFont* def_font = NULL;
    CFont font_italic;

    TC_ITEM tci;
    CRect rect(lpDrawItemStruct->rcItem); 
    wchar_t szTabText[256]; 
    wmemset(szTabText,_T('\0'),256);

    RECT rectComplet; 
    GetClientRect(&rectComplet);
    CBrush brtmp(ColorCategoryBackgroundTop);
    int nbItem = GetItemCount();

    tci.mask = TCIF_TEXT;
    tci.pszText = szTabText;
    tci.cchTextMax = sizeof(szTabText) -1;
    GetItem(lpDrawItemStruct->itemID, &tci);

    BOOL bSelect = (lpDrawItemStruct->itemState & ODS_SELECTED) &&
                   (lpDrawItemStruct->itemAction & (ODA_SELECT | ODA_DRAWENTIRE));
    BOOL bfocus = (lpDrawItemStruct->itemState & ODS_FOCUS) &&
                  (lpDrawItemStruct->itemAction & (ODA_FOCUS | ODA_DRAWENTIRE));

    if (bSelect)//Draw In a Specific Way
    if (bFocus) //Draw In a Specific Way

因此,如果有人能描述检测 CTabCtrl 项目“已选择和聚焦”、“已选择但未聚焦”的两种状态的正确方法,我将不胜感激

【问题讨论】:

当您单击 Alt 选项卡时,会自动为对话框中的选项卡绘制焦点矩形。所以你不必做任何事情!只需检查bSelect = (di->itemState & ODS_SELECTED); 以查看该项目是否被选中。检查bfocus = bSelect && (GetFocus() == this); 以查看项目是否具有焦点(但同样,焦点矩形已经在 ownerdraw 选项卡控件中为您绘制)。当没有请求焦点矩形时,您还想检查ODS_NOFOCUSRECT 感谢您的描述,但BOOL bfocus = (lpDrawItemStruct->itemState & ODS_NOFOCUSRECT); 没有给出预期的结果,它总是给出FALSE。然而if (pWinParent->IsKindOf(RUNTIME_CLASS(CWnd))) if (pWinParent->GetFocus() == this) 给了我我正在寻找的结果。所以谢谢你。 【参考方案1】:

对于标准选项卡控件,UI 不会总是绘制焦点矩形。要查看焦点矩形,选项卡控件必须具有WS_TABSTOP 标志。

当用户单击 Tab 键以浏览对话框的控件时,或者当按下 Alt 键并且选项卡控件具有焦点时,焦点矩形将可见。

如果适用,应为所有者绘制选项卡控件自动绘制焦点矩形。确保为选项卡控件设置WS_TABSTOP(在对话框编辑器中,转到选项卡控件的属性并设置"Tabstop = true"

当用户单击选项卡控件时,BOOL focused = selected && (GetFocus() == this); 将始终为 TRUEODS_NOFOCUSRECT 将指示 UI 是否未请求焦点矩形。请参阅下面的示例。

旁注,sizeof(szTabText)wchar_t 返回错误值。使用_countof(szTabText)sizeof(szTabText)/sizeof(*szTabText)

void CXtabCtrl::DrawItem(LPDRAWITEMSTRUCT di)

    CDC* pDC = CDC::FromHandle(di->hDC);

    TC_ITEM tci;
    wchar_t text[256] =  0 ;
    tci.mask = TCIF_TEXT;
    tci.pszText = text;
    tci.cchTextMax = _countof(text);
    GetItem(di->itemID, &tci);

    BOOL selected = di->itemState & ODS_SELECTED;

    BOOL focused = selected && (GetFocus() == this);

    //The UI may not be drawing focus rectangle, even if we click on the tab
    if(di->itemState & ODS_NOFOCUSRECT)
        focused = FALSE;

    CString str;
    if(selected) str += L"SEL ";//indicate selected
    if(focused) str += L"FOC ";//indicate focused

    CRect rect(di->rcItem);
    pDC->TextOut(rect.left, rect.top, str);

【讨论】:

以上是关于CTabCtrl ItemAction & ItemState的主要内容,如果未能解决你的问题,请参考以下文章

如何更改 CTabCtrl 选项卡颜色?

如何调整 CTabCtrl 的大小以适合其内容

如何更改CTabCtrl选项卡颜色?

我正在扩展 CTabCtrl 但无法插入任何选项卡

在 CTabCtrl 中,我可以在运行时更改选项卡的图标吗

如何通知 CTabCtrl 中的所有控件它们应该重绘啥(应该改变它们的大小)?