我创建了一个SDI工程
加入了CColorListBox类
在CColorLBoxLxDoc中增加成员变量
CColorListBox *pListBox;增加如下代码到下面这个成员函数中
void CColorLBoxLxView::OnInitialUpdate()
{
CScrollView::OnInitialUpdate(); CSize sizeTotal;
// TODO: calculate the total size of this view
sizeTotal.cx = sizeTotal.cy = 100;
SetScrollSizes(MM_TEXT, sizeTotal); CString szTitle = "Info Window";
CWnd *pWnd=new CWnd;
DWORD dwExStyle=WS_EX_OVERLAPPEDWINDOW; DWORD dwStyle=WS_HSCROLL|WS_VSCROLL | LBS_OWNERDRAWFIXED|LBS_HASSTRINGS|LBS_NOTIFY; RECT rect;
rect.bottom = 150;
rect.right = 150;
rect.left = 0;
rect.top = 0;
pWnd->CreateEx( dwExStyle,
"LISTBOX",
szTitle,
dwStyle,
rect,
NULL,//AfxGetMainWnd(),//->m_hWnd,
NULL);
GetDocument()->pListBox = (CColorListBox*)pWnd;
((CListBox*)pWnd)->SetHorizontalExtent(200);
GetDocument()->pListBox->SetWindowText(szTitle);
((CListBox*)GetDocument()->pListBox)->AddString("RED");//,RGB(255,0,0));
GetDocument()->pListBox->ShowWindow(SW_SHOW);
}我是想在动态创建的这个LISTBOX窗口()中显示彩色文本,已经设置了LBS_OWNERDRAWFIXED风格,但是不能进行自绘制,显示不出来彩色文本,请问应该如何解决?

解决方案 »

  1.   

    CColorListBox类
    #if !defined(AFX_COLORLISTBOX_H__5529A6B1_584A_11D2_A41A_006097BD277B__INCLUDED_)
    #define AFX_COLORLISTBOX_H__5529A6B1_584A_11D2_A41A_006097BD277B__INCLUDED_#if _MSC_VER >= 1000
    #pragma once
    #endif // _MSC_VER >= 1000// ColorListBox.h : header file//-------------------------------------------------------------------
    //
    // CColorListBox class - 
    // A CListBox-derived class with optional colored items.
    //
    // Version: 1.0 01/10/1998 Copyright ?Patrice Godard
    //
    // Version: 2.0 09/17/1999 Copyright ?Paul M. Meidinger
    //
    //-------------------------------------------------------------------/////////////////////////////////////////////////////////////////////////////
    // CColorListBox windowclass CColorListBox : public CListBox
    {
    // Construction
    public:
    CColorListBox();// Attributes
    public:// Operations
    public:
    int AddString(LPCTSTR lpszItem); // Adds a string to the list box
    int AddString(LPCTSTR lpszItem, COLORREF rgb); // Adds a colored string to the list box
    int InsertString(int nIndex, LPCTSTR lpszItem); // Inserts a string to the list box
    int InsertString(int nIndex, LPCTSTR lpszItem, COLORREF rgb); // Inserts a colored string to the list box
    void SetItemColor(int nIndex, COLORREF rgb); // Sets the color of an item in the list box
    // Overrides
    // ClassWizard generated virtual function overrides
    //{{AFX_VIRTUAL(CColorListBox)
    public:
    virtual void DrawItem(LPDRAWITEMSTRUCT lpDrawItemStruct);
    virtual void MeasureItem(LPMEASUREITEMSTRUCT lpMeasureItemStruct);
    protected:
    //}}AFX_VIRTUAL// Implementation
    public:
    virtual ~CColorListBox(); // Generated message map functions
    protected:
    //{{AFX_MSG(CColorListBox)
    //}}AFX_MSG DECLARE_MESSAGE_MAP()
    };///////////////////////////////////////////////////////////////////////////////{{AFX_INSERT_LOCATION}}
    // Microsoft Developer Studio will insert additional declarations immediately before the previous line.#endif // !defined(AFX_COLORLISTBOX_H__5529A6B1_584A_11D2_A41A_006097BD277B__INCLUDED_)
      

  2.   

    // ColorListBox.cpp : implementation file//-------------------------------------------------------------------
    //
    // CColorListBox class - 
    // A CListBox-derived class with optional colored items.
    //
    // Version: 1.0 01/10/1998 Copyright ?Patrice Godard
    //
    // Version: 2.0 09/17/1999 Copyright ?Paul M. Meidinger
    //
    //-------------------------------------------------------------------#include "stdafx.h"
    #include "ColorListBox.h"#ifdef _DEBUG
    #define new DEBUG_NEW
    #undef THIS_FILE
    static char THIS_FILE[] = __FILE__;
    #endif/////////////////////////////////////////////////////////////////////////////
    // CColorListBox//-------------------------------------------------------------------
    //
    CColorListBox::CColorListBox()
    //
    // Return Value: None.
    //
    // Parameters : None.
    //
    // Res : Standard constructor.
    //
    {
    } // CColorListBox//-------------------------------------------------------------------
    //
    CColorListBox::~CColorListBox()
    //
    // Return Value: None.
    //
    // Parameters : None.
    //
    // Res : Destructor.
    //
    {
    } // ~CColorListBox()
    BEGIN_MESSAGE_MAP(CColorListBox, CListBox)
    //{{AFX_MSG_MAP(CColorListBox)
    //}}AFX_MSG_MAP
    END_MESSAGE_MAP()/////////////////////////////////////////////////////////////////////////////
    // CColorListBox message handlers//-------------------------------------------------------------------
    //
    void CColorListBox::DrawItem(LPDRAWITEMSTRUCT lpDIS) 
    //
    // Return Value: None.
    //
    // Parameters : lpDIS - A long pointer to a DRAWITEMSTRUCT structure 
    // that contains information about the type of drawing required.
    //
    // Res : Called by the framework when a visual aspect of 
    // an owner-draw list box changes. 
    //
    {
    if ((int)lpDIS->itemID < 0)
    return;  CDC* pDC = CDC::FromHandle(lpDIS->hDC); COLORREF crText;
    CString sText;
    COLORREF crNorm = (COLORREF)lpDIS->itemData; // Color information is in item data.
    COLORREF crHilite = RGB(255-GetRValue(crNorm), 255-GetGValue(crNorm), 255-GetBValue(crNorm)); // If item has been selected, draw the highlight rectangle using the item's color.
    if ((lpDIS->itemState & ODS_SELECTED) &&
     (lpDIS->itemAction & (ODA_SELECT | ODA_DRAWENTIRE)))
    {
    CBrush brush(crNorm);
    pDC->FillRect(&lpDIS->rcItem, &brush);
    } // If item has been deselected, draw the rectangle using the window color.
    if (!(lpDIS->itemState & ODS_SELECTED) && (lpDIS->itemAction & ODA_SELECT))
    {
    CBrush brush(::GetSysColor(COLOR_WINDOW));
    pDC->FillRect(&lpDIS->rcItem, &brush);
    }   // If item has focus, draw the focus rect.
    if ((lpDIS->itemAction & ODA_FOCUS) && (lpDIS->itemState & ODS_FOCUS))
    pDC->DrawFocusRect(&lpDIS->rcItem);  // If item does not have focus, redraw (erase) the focus rect.
    if ((lpDIS->itemAction & ODA_FOCUS) && !(lpDIS->itemState & ODS_FOCUS))
    pDC->DrawFocusRect(&lpDIS->rcItem); 
    // Set the background mode to TRANSPARENT to draw the text.
    int nBkMode = pDC->SetBkMode(TRANSPARENT); // If the item's color information is set, use the highlight color
    // gray text color, or normal color for the text.
    if (lpDIS->itemData)
    {
    if (lpDIS->itemState & ODS_SELECTED)
    crText = pDC->SetTextColor(crHilite);
    else if (lpDIS->itemState & ODS_DISABLED)
    crText = pDC->SetTextColor(::GetSysColor(COLOR_GRAYTEXT));
    else
    crText = pDC->SetTextColor(crNorm);
    }
    // Else the item's color information is not set, so use the
    // system colors for the text.
    else
    {
    if (lpDIS->itemState & ODS_SELECTED)
    crText = pDC->SetTextColor(::GetSysColor(COLOR_HIGHLIGHTTEXT));
    else if (lpDIS->itemState & ODS_DISABLED)
    crText = pDC->SetTextColor(::GetSysColor(COLOR_GRAYTEXT));
    else
    crText = pDC->SetTextColor(::GetSysColor(COLOR_WINDOWTEXT));
    }
    // Get and display item text.
    GetText(lpDIS->itemID, sText);
    CRect rect = lpDIS->rcItem; // Setup the text format.
    UINT nFormat = DT_LEFT | DT_SINGLELINE | DT_VCENTER;
    if (GetStyle() & LBS_USETABSTOPS)
    nFormat |= DT_EXPANDTABS;

    // Calculate the rectangle size before drawing the text.
    pDC->DrawText(sText, -1, &rect, nFormat | DT_CALCRECT);
    pDC->DrawText(sText, -1, &rect, nFormat); pDC->SetTextColor(crText); 
    pDC->SetBkMode(nBkMode);
    } // DrawItem
      

  3.   

    //-------------------------------------------------------------------
    //
    void CColorListBox::MeasureItem(LPMEASUREITEMSTRUCT lpMIS)
    //
    // Return Value: None.
    //
    // Parameters : lpMIS - A long pointer to a 
    // MEASUREITEMSTRUCT structure.
    //
    // Res : Called by the framework when a list box with 
    // an owner-draw style is created. 
    //
    {
    // ### Is the default list box item height the same as
    // the menu check height???
    lpMIS->itemHeight = ::GetSystemMetrics(SM_CYMENUCHECK);
    } // MeasureItem//-------------------------------------------------------------------
    //
    int CColorListBox::AddString(LPCTSTR lpszItem)
    //
    // Return Value: The zero-based index to the string in the list box. 
    // The return value is LB_ERR if an error occurs; the 
    // return value is LB_ERRSPACE if insufficient space 
    // is available to store the new string.
    //
    // Parameters : lpszItem - Points to the null-terminated 
    // string that is to be added.
    //
    // Res : Call this member function to add a string to a list 
    // box. Provided because CListBox::AddString is NOT
    // a virtual function.
    //
    {
    return ((CListBox*)this)->AddString(lpszItem);
    } // AddString//-------------------------------------------------------------------
    //
    int CColorListBox::AddString(LPCTSTR lpszItem, COLORREF rgb)
    //
    // Return Value: The zero-based index to the string in the list box. 
    // The return value is LB_ERR if an error occurs; the 
    // return value is LB_ERRSPACE if insufficient space 
    // is available to store the new string.
    //
    // Parameters : lpszItem - Points to the null-terminated 
    // string that is to be added.
    // rgb - Specifies the color to be associated with the item.
    //
    // Res : Call this member function to add a string to a list 
    // box with a custom color.
    //
    {
    int nItem = AddString(lpszItem);
    if (nItem >= 0)
    SetItemData(nItem, rgb);
    return nItem;
    } // AddString//-------------------------------------------------------------------
    //
    int CColorListBox::InsertString(int nIndex, LPCTSTR lpszItem)
    //
    // Return Value: The zero-based index of the position at which the 
    // string was inserted. The return value is LB_ERR if 
    // an error occurs; the return value is LB_ERRSPACE if 
    // insufficient space is available to store the new string.
    //
    // Parameters : nIndex - Specifies the zero-based index of the position
    // to insert the string. If this parameter is ?, the string
    // is added to the end of the list.
    // lpszItem - Points to the null-terminated string that 
    // is to be inserted.
    //
    // Res : Inserts a string into the list box. Provided because 
    // CListBox::InsertString is NOT a virtual function.
    //
    {
    return ((CListBox*)this)->InsertString(nIndex, lpszItem);
    } // InsertString//-------------------------------------------------------------------
    //
    int CColorListBox::InsertString(int nIndex, LPCTSTR lpszItem, COLORREF rgb)
    //
    // Return Value: The zero-based index of the position at which the 
    // string was inserted. The return value is LB_ERR if 
    // an error occurs; the return value is LB_ERRSPACE if 
    // insufficient space is available to store the new string.
    //
    // Parameters : nIndex - Specifies the zero-based index of the position
    // to insert the string. If this parameter is ?, the string
    // is added to the end of the list.
    // lpszItem - Points to the null-terminated string that 
    // is to be inserted.
    // rgb - Specifies the color to be associated with the item.
    //
    // Res : Inserts a colored string into the list box.
    //
    {
    int nItem = ((CListBox*)this)->InsertString(nIndex,lpszItem);
    if (nItem >= 0)
    SetItemData(nItem, rgb);
    return nItem;
    } // InsertString//-------------------------------------------------------------------
    //
    void CColorListBox::SetItemColor(int nIndex, COLORREF rgb)
    //
    // Return Value: None.
    //
    // Parameters : nIndex - Specifies the zero-based index of the item.
    // rgb - Specifies the color to be associated with the item.
    //
    // Res : Sets the 32-bit value associated with the specified
    // item in the list box.
    //
    {
    SetItemData(nIndex, rgb);
    RedrawWindow();
    } // SetItemColor
      

  4.   

    直接使用继承自CListBox的自定义类,比如上面的CColorListBox类,在CColorLBoxLxView中声明一个成员变量,然后Create即可。
      

  5.   

    如下改就可以了:
    void CColorLBoxLxView::OnInitialUpdate()
    {
    CScrollView::OnInitialUpdate(); CSize sizeTotal;
    // TODO: calculate the total size of this view
    sizeTotal.cx = sizeTotal.cy = 100;
    SetScrollSizes(MM_TEXT, sizeTotal); CString szTitle = "Info Window";
    DWORD dwExStyle=WS_EX_OVERLAPPEDWINDOW; DWORD dwStyle=WS_CHILD | WS_HSCROLL|WS_VSCROLL | LBS_OWNERDRAWFIXED|LBS_HASSTRINGS|LBS_NOTIFY; RECT rect;
    rect.bottom = 150;
    rect.right = 150;
    rect.left = 0;
    rect.top = 0;
             GetDocument()->pListBox = new CColorListBox();
    GetDocument()->pListBox ->CreateEx( dwExStyle,
    "LISTBOX",
    szTitle,
    dwStyle,
    rect,
    NULL,//AfxGetMainWnd(),//->m_hWnd,
    NULL);
    GetDocument()->pListBox ->SetHorizontalExtent(200);
    GetDocument()->pListBox->SetWindowText(szTitle);
    GetDocument()->pListBox ->AddString("RED",RGB(255,0,0));
    GetDocument()->pListBox ->AddString("GREEN",RGB(0,255,0));
    GetDocument()->pListBox->ShowWindow(SW_SHOW);
    }
      

  6.   

    GetDocument()->pListBox ->CreateEx( dwExStyle,
    "LISTBOX",
    szTitle,
    dwStyle,
    rect,
    this,//AfxGetMainWnd(),//->m_hWnd,
    NULL);
      

  7.   

    谢谢两位的建议。可是,我不想使其成为子窗口,因为View还要显示别的方面。
      

  8.   

    你可以建个对话框, 然后在对话框里创建ListBox, 你再在视类里创建对话框就可以了
      

  9.   

    ymbymb(毛病大哥)的方法也可行。但我现在是通过封装在DLL中,最好还是能subclass化。Mackz(在相互) 
    不成为子窗口,就是不想成为象在对话框中的那样的子控件窗口而是创建一个"LISTBOX"类的窗口,overlapped风格的窗口
      

  10.   

    直接创建一个"LISTBOX"类的窗口是不行的, 你不用对话框, 可以用CreateWindow创建一个窗口, 然后再在窗口里创建ListBox
      

  11.   

    可以的,我用CreateEx已经创建出来了。