在界面数据显示时一般使用ListBox或支持分列显示的ListCtrl,如果同一个界面中有两个以上关联数据表格要显示,那么使用ListBox的好处在任何时候都可以清晰的表明数据行选中/未选中状态,从而表示表格之间的关系,而使用ListCtrl中则状态不明显,比如MFC类向导,其中的数据显示使用ListBox,在多个ListBox窗口中可以同时显示每个窗口的数据选中状态,注意一点,MFC类向导使用的ListBox是分列显示的。那么我们能否也实现一个分列显示的ListBox。在WTL可以轻易实现这一点。代码队在最后:
如何使用:在WTL使用时,需要注意的是在资源编辑器中将ListBox属性设计为LBS_OWNERDRAWFIXED和LBS_HASSTRINGS,需要在消息宏添加REFLECT_NOTIFICATION()以支持自画消息。
BEGIN_MSG_MAP(CMainDlg)
    ...
    REFLECT_NOTIFICATION()
END_MSG_MAP()在添加数据时数据之间使用“;”来进行列之间分开,当然你也可以修改源代码使用其他分隔符或者定义一个变量来指示分隔符,CDevListBoxImpl中的m_nDivider 用来控制列的宽度,如果某一行的列宽超过这个宽度将自动增加宽度来容纳内容,就象MFC的类向导所做的一样,我并没有指定具体一列的宽度,对于我来言,两列足够了。然后需要的话你也可以修改代码使用一个int数组来保存列宽,我相信这对你来言相当容易。
CDevListBoxImpl m_list
m_list.SubclassWindow(GetDlgItem(IDC_LISTBOX1);
m_list.AddString(_T("Item0;True");
m_lsit.AddString(_T("Item1;False");
....
CDevListBoxImpl的代码
class CDevListBoxImpl : public CWindowImpl<CDevListBoxImpl, CListBox>,                        public COwnerDraw<CDevListBoxImpl>
...{
public:
    CDevListBoxImpl()
    ...{
        m_nDivider = 200; 
    }
    BEGIN_MSG_MAP(CDevListBoxImpl)
    MESSAGE_HANDLER(WM_CREATE, OnCreate)
    CHAIN_MSG_MAP_ALT(COwnerDraw<CDevListBoxImpl>, 1)
                     DEFAULT_REFLECTION_HANDLER()
    END_MSG_MAP()
    // overridden to provide proper initialization
    BOOL SubclassWindow(HWND hWnd)
    ...{
        BOOL bRet = CWindowImpl<CDevListBoxImpl, CListBox>::SubclassWindow(hWnd);
        if(bRet)
            Init();
        return bRet;
    }
    LRESULT OnCreate(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
    ...{
        // TODO : Add Code for message handler. Call DefWindowProc if necessary.
        Init();
        bHandled = FALSE;
        return 1;
    }
// Implementation
    void Init()
    ...{
        // We need this style to prevent Windows from painting the button
        ModifyStyle(0, BS_OWNERDRAW | LBS_OWNERDRAWFIXED | LBS_HASSTRINGS );
    }
    void DrawItem ( LPDRAWITEMSTRUCT lpDIS )
    ...{
        CDCHandle dc = lpDIS->hDC;
        CRect rect = lpDIS->rcItem;
        if (m_nDivider==0)
            m_nDivider = rect.Width() / 2;
        
        if (lpDIS->itemID != (UINT) -1)
        ...{
            TCHAR sz[128] = ...{0};
            CListBox::GetText(lpDIS->itemID,sz);
            COLORREF oldColor;
            //draw two rectangles, one for each row column
            if (lpDIS->itemState & ODS_SELECTED  == ODS_SELECTED )
            ...{
                dc.FillSolidRect(&lpDIS->rcItem,RGB(0,0,128));
                oldColor = dc.SetTextColor(RGB(255,255,255));
            }
            else
            ...{
                dc.FillSolidRect(&lpDIS->rcItem,RGB(255,255,255));
                oldColor = dc.SetTextColor(RGB(0,0,0));
            }
            dc.SetBkMode(TRANSPARENT);
            TCHAR * tok = ::_tcstok(sz,_T(";"));
            while (tok != NULL)
            ...{
                dc.DrawText(tok,lstrlen(tok),rect,DT_LEFT | DT_SINGLELINE);
                rect.left += m_nDivider;
                SIZE sz;
                dc.GetTextExtent(tok,-1,&sz);
                if (sz.cx >= 2*m_nDivider)
                ...{
                    rect.left = rect.left-m_nDivider+sz.cx+20;
                }
                else if (sz.cx >= m_nDivider)
                ...{
                    rect.left += m_nDivider;
                }
                tok = ::_tcstok(NULL,_T(";"));
            }
            dc.SetTextColor(oldColor);
        }
        SetMsgHandled(FALSE);
    }
    int    m_nDivider;
};
                  
                  
                  
                  
本文介绍如何在WTL中创建一个类似MFC类向导中分列显示的ListBox。通过设置ListBox属性为LBS_OWNERDRAWFIXED和LBS_HASSTRINGS,并在消息宏中添加REFLECT_NOTIFICATION()支持自画消息。数据列通过‘;’分隔,源代码中的m_nDivider控制列宽,当内容超宽时会自动调整。你可以根据需求修改代码以适应更多列数或自定义分隔符。
          
      
          
                
                
                
                
              
                
                
                
                
                
              
                
                
              
            
                  
					1574
					
被折叠的  条评论
		 为什么被折叠?
		 
		 
		
    
  
    
  
            


            