// 转载请注明出处,谢谢!
映射成员变量CListCtrl m_listCtrl;
头文件中添加静态变量和静态函数
static WNDPROC m_pfnOrgListCtrlProc;
static LRESULT CALLBACK SubClassListCtrlProc(HWND hwnd, UINT message, WPARAM wparam, LPARAM lparam);
// list控件初始化
// 位置:如果是对话框,在OnInitDialog函数中进行;如果是视图,在OnCreate函数中进行
// 这里假设是在对话框中
// 在实现文件的头部对静态变量初始化
WNDPROC CListctrlDlg::m_pfnOrgListCtrlProc = NULL;
BOOL CTestDialog::OnInitDialog()
{
    .... // 省略
    // 子类化listctrl控件
    // 限制只显示垂直滚动条
    CListctrlDlg::m_pfnOrgListCtrlProc = (WNDPROC)SetWindowLong(m_listCtrl.GetSafeHwnd(), GWL_WNDPROC, (LONG)SubClassListCtrlProc);
    // 为listctrl添加基本样式
    m_listCtrl.ModifyStyle(0, LVS_REPORT | LVS_SINGLESEL | LVS_SHOWSELALWAYS);
    // 为listctrl添加扩展样式
    m_listCtrl.SetExtendedStyle(m_listCtrl.GetExtendedStyle() | LVS_EX_GRIDLINES | LVS_EX_FULLROWSELECT);
    // 插入列头
    CRect rect;
    m_listCtrl.GetWindowRect(rect);
    m_listCtrl.InsertColumn(1, _T("UserID"), LVCFMT_CENTER, rect.Width() / 2 - 15);   // 小技巧,可以让第一列的标题居中显示
    m_listCtrl.InsertColumn(2, _T("UserName"), LVCFMT_CENTER, rect.Width() / 2 + 15);
    // 添加数据
    m_listCtrl.DeleteAllItems();
    m_listCtrl.InsertItem(0, _T("001"));                // 第一行,第一列
    m_listCtrl.SetItemText(0, 1, _T("刘德华"));       // 第一行,第二列
    m_listCtrl.InsertItem(1, _T("002"));                 // 第二行,第一列
    m_listCtrl.SetItemText(1, 1, _T("范冰冰"));        // 第二行,第二列
    return TRUE;
}
// 子类化listctrl控件过程函数
LRESULT CTestlDlg::SubClassListCtrlProc( HWND hwnd, UINT message, WPARAM wparam, LPARAM lparam )
{
     CWnd* pListCtrl = CWnd::FromHandle(hwnd);
     if(pListCtrl)
     {
         pListCtrl->ShowScrollBar(SB_HORZ, FALSE);  // 取消水平滚动条
     }
     return CallWindowProc(CTestDlg::m_pfnOrgListCtrlProc, hwnd, message, wparam, lparam);
}
// 注:取消水平滚动条的实现是有点遗憾的,因为直接对所有的消息都执行了pListCtrl->ShowScrollBar(SB_HORZ, FALSE)操作
//       因为我还不知道哪些消息会影响水平滚动条的出现,只有对所有消息都执行一遍这个操作了
//       但是,您无需担心的是:经测试,目标功能能够实现,且不会影响到用户体验(比如界面闪烁的问题)。
// 选择选中行的数据
// 这里是通过临时变量来获取,只是起到演示作用
BOOL GetSelItemData()
{
     int iIndex = m_listctrl.GetNextItem(-1, LVSI_SELECTED);
     if(-1 != iIndex)
    {
         CString cstrUserID = m_listctrl.GetItemText(iIndex, 0);      // 取得选中行第一列的数据
         CString cstrUserName = m_listctrl.GetItemText(iIndex, 1);  // 取得选中行第二列的数据
         return TRUE;
    }
    return FALSE;
}