• 外部调用接口不成功发现原来窗口还没创建(CTabCtrl开发记录2)


    问题:在父窗口中调用CTabCtrl控件的接口SetItemSel()不起作用。
    原因:调试发现,获取GetClientRect不起作用 因为窗口还没创建 要么说用CDialogImpl啊 有个OnInitDialog函数好办些
    这个时候只能给一些成员变量 复制  而不能调用函数(例如GetClientRect)  而且就算使用CDialogImpl  也可能出现这种情况

    解决方法:
    把设置当前选中的item接口分为内部(SetItemSel)、外部(SetCurSelItem)两种。 内部还负责重绘之类的,外部只负责传值。然后再OnPaint里面最后再调用一下内部的SetItemSel即可。当然内部这个接口需要能够判断无效值的情形,例如如果传进来-1,那么None selected.

    外部接口:

    void CTabBtn::SetCurSelItem(int nItem)// for user to call
    {
        m_nCurSel = nItem;
    }

    内部接口:

    void CTabBtn::SetItemSel(int nItem, BOOL bSel)//internal interface
    {
        if(nItem < 0 || nItem >= m_arrItems.size())
        {
            m_nCurSel = -1;  //if nItem == -1, then none is selected.
            return;
        }
    
        if(m_nItemWidth <= 0 || m_nItemHeight <= 0)
            return;
    
        
        m_nCurSel = nItem;
        m_arrItems[m_nCurSel]->bDown = TRUE;
    
    
        if(m_nCurSel == m_nPrevSel)
        {
            ::SetCursor(::LoadCursor(NULL, IDC_ARROW));
            return;
        }
        else
        {
            ::SetCursor(::LoadCursor(NULL, IDC_HAND));
    
            //redraw current selected item
            RECT rcItem;
            rcItem.left = m_nCurSel * m_nItemWidth;
            rcItem.right = (m_nCurSel + 1) * m_nItemWidth;
            rcItem.top = 0;
            rcItem.bottom = m_nItemHeight;
            m_arrItems[m_nCurSel]->bDown = (bSel==TRUE);
            ::PostMessage(GetMsgReceiver(), WM_TABBTN, 0, MAKELPARAM(m_nCurSel, 0));
            ::InvalidateRect(m_hWnd, &rcItem, FALSE);
    
            //redraw previous selected item
            if(m_nPrevSel != -1)
            {
                rcItem.left = m_nPrevSel * m_nItemWidth;
                rcItem.right = (m_nPrevSel + 1) * m_nItemWidth;
    
                m_arrItems[m_nPrevSel]->bDown = FALSE;
                ::InvalidateRect(m_hWnd, &rcItem, FALSE);
            }
        }
    
        m_nPrevSel = m_nCurSel;
    
    }

    关键一步,让外部传进来的值起作用:

    void CTabBtn::DoPaint(CDCHandle dc)
    {
        RECT rect;
        GetClientRect(&rect);
    
        Graphics graphics(dc);
        DrawTabBtn(&graphics);
        //graphics.DrawRectangle(new Pen(Color::Green), rect.left, rect.top, rect.right-rect.left, rect.bottom-rect.top);
    
    
        HRGN hClientRgn = CreateRoundRectRgn(rect.left, rect.top, rect.right, rect.bottom, 20, 20);
        SetWindowRgn(hClientRgn, TRUE);
    
        SetItemSel(m_nCurSel, TRUE);//here
    }

     最后需要注意的是:保证原子操作,此例中,要保证所有设置当前选中的功能都调用内部接口SetItemSel。

  • 相关阅读:
    NFS-网络文件共享服务
    CentOS7.5基础优化与常用配置
    29张截图-全新安装CentOS7.5-超详细!
    VMware跨电脑移动Linux虚拟机
    搭建markdown图床-腾讯云COS
    tcpdump-抓包工具-Linux
    vmware克隆虚拟机
    CentOS6.9安装httpd并正确配置静态IP地址
    区块链核心技术与应用
    docker安装jenkins自动化部署
  • 原文地址:https://www.cnblogs.com/tupx/p/3453964.html
Copyright © 2020-2023  润新知