带有嵌入式控件的 C++ MFC OwnerDrawn CListBox

问题描述 投票:0回答:0

使用 C++ MFC,并有一个所有者绘制的 CListBox,我在每个列表框项目中都有文本和 CLinkCtrl。我的问题是 CLinkCtrl 并不总是我希望在上下滚动时看到的控件,而所有者绘制的文本总是正确的。

存在另一个错误,底部的列表项之一几乎总是不显示链接控件。

以下是部分截图:

// 这是在滚动之前,列表项链接的顺序正确

// 这是在滚动之后,其中列表链接项 的顺序不正确

当我选择一个控件时,UI 有时会更新为正确的控件值。

我会尝试添加尽可能多的信息,希望能够看到错误。

分为三部分:

1: ListBox Configuration, 自己绘制

2:填充 ListBox,这会将“项目”添加到 CListBox:

std::thread t([=]() {
  myMutex.lock();  // acquire the mutex

  // Disable redrawing of the control...
  calListBox.EnableWindow(FALSE);
  calListBox.SetRedraw(FALSE);

  // clear all the items
  for (int i = 0; i < calListBox.GetCount(); i++)
  {
    LPARAM lpData = calListBox.GetItemData(i);
    CalListBoxItem* item = reinterpret_cast<CalListBoxItem*>(lpData);
    delete item;
  }
  calListBox.ResetContent();

  // for loop
    int index = calListBox.SendMessage(LB_ADDSTRING, 0, 0);
    if (index == LB_ERR) {
        DWORD dwError = GetLastError();
    }
    else {
        CalListBoxItem* pItem = new CalListBoxItem(description, htmllink, index);
        calListBox.SendMessage(LB_SETITEMDATA, index, reinterpret_cast<DWORD_PTR>(pItem));
        calListBox.SendMessage(LB_SETITEMHEIGHT, index, 100);
    }
  // end for loop

    calListBox.SetRedraw(TRUE); // Re-enable redrawing of the control
    calListBox.EnableWindow(TRUE);      

    myMutex.unlock();  // release the mutex
});
t.detach();

// here is the CalListBoxItem, it just holds the description, index and the htmllink control
public:
    ~CalListBoxItem();
    CalListBoxItem(const std::string& desc, const std::string& link, int index)
        : m_desc(desc), m_link(link), originalIndex(index)
    {
        linkCtrl = new CCustLinkCtrl();
    }

public:
    int originalIndex;
    CCustLinkCtrl* linkCtrl;

    std::string m_desc;
    std::string m_link;

3:有一个CListBox,大部分是绘制列表项, 其中一些绘制文本,100% 有效,只是我添加的控件具有一些随机性。

这里是扩展 CListBox 的 Custom CalListBox 的一些位

// The AddLinkCtrl function
void CalListBox::AddLinkControl(CLinkCtrl* linkCtrl, CRect& rect, int nItemIndex, CString text, CString htmlLink) {

    if (!linkCtrl) {
        return;
    }

    if (::IsWindow(linkCtrl->m_hWnd)) { 
        CString strIndex;
        strIndex.Format(_T(" u:%d"), nItemIndex);  // convert nItemIndex to CString
        CString strText = text + strIndex;      // concatenate text and strIndex

        linkCtrl->SetWindowTextW(strText);
        linkCtrl->Invalidate();
        linkCtrl->UpdateWindow();
        return; // the control has already been created
    }

    // Create the control as a child of the list box
    linkCtrl->Create(_T(""), WS_CHILD | WS_VISIBLE | DT_VCENTER | SS_NOTIFY, rect, this, IDC_LINK_CTRL_LIST_ITEM + nItemIndex);

    CString strIndex;
    strIndex.Format(_T(" %d"), nItemIndex);  // convert nItemIndex to CString
    CString strText = text + strIndex;      // concatenate text and strIndex

    linkCtrl->SetWindowTextW(strText);

    //linkCtrl->SetWindowTextW(text + nItemIndex);
    linkCtrl->SetItemUrl(0, htmlLink); // must be after text is set, else the link does not work

    linkCtrl->SetFont(linkFont);
    linkCtrl->Invalidate();
    linkCtrl->UpdateWindow();
}

这里是 DrawItem,显示了部分位

void CalListBox::DrawItem(LPDRAWITEMSTRUCT lpDrawItemStruct)
{
    if (lpDrawItemStruct->itemData == 0) {
        return;
    }

    /*
    CalListBoxItem* pItem = reinterpret_cast<CalListBoxItem*>(GetItemData(lpDrawItemStruct->itemID));
    if (pItem == nullptr) {
        return;
    }
    */

    CalListBoxItem* pItem = reinterpret_cast<CalListBoxItem*>(lpDrawItemStruct->itemData);
    if (pItem == nullptr) {
        return;
    }

    CDC* pDC = CDC::FromHandle(lpDrawItemStruct->hDC);
    if (pDC == nullptr) {
        return;
    }

    // Clip the region, not to draw outside of the boundary
    /*
    CRgn clipRgn;
    clipRgn.CreateRectRgnIndirect(&lpDrawItemStruct->rcItem);
    pDC->SelectClipRgn(&clipRgn);
    */

    CRect rect(lpDrawItemStruct->rcItem);

    // snip 

    AddLinkControl(pItem->linkCtrl, leftRect2, pItem->originalIndex, L"<a>Link</a>", leftText2);

c++11 visual-c++ mfc
© www.soinside.com 2019 - 2024. All rights reserved.