合同续签申请书:使用ListControl控件显示数据表

来源:百度文库 编辑:偶看新闻 时间:2024/04/29 14:00:08

一、在Windows应用程序中添加ListControl控件的几种方法

    1、在对话框中添加控件:

    创建对话框应用程序,在资源视图中添加对话框。如下图所示,在控件工具条中选择ListControl控件添加到对话框中,并调整控件尺寸。在ListControl控件的属性页中设置控件样式(Styles)和扩展样式等。为了显示详细数据信息,可以设置控件的显示风格为报表视图(Report)。

    为了在对话框中使用控件,需要在ClassWizard中为对话框类添加控件成员变量,如下图所示:

 

    执行以上操作后,系统自动添加了一个ClistControl对象,并与ListControl控件资源关联,相关代码如下:

    // ListDialogDlg.h : header file

    ......

    public

       CListCtrl m_cListCtrl;

    ......

    // ListDialogDlg.cpp : implementation file

    ......

    void CListDialogDlg::DoDataExchange(CDataExchange* pDX)
    {
       CDialog::DoDataExchange(pDX);
       //{{AFX_DATA_MAP(CListDialogDlg)
       DDX_Control(pDX, IDC_LIST_CTRL, m_cListCtrl);
       //}}AFX_DATA_MAP
    }

    ......

    因为本例只为演示在对话框中添加ListControl控件,所以只在对话框初始化消息函数中添加了以下显示控件的示例代码(代码含义请参照MSDN文献):

    BOOL CListDialogDlg::OnInitDialog()
    {
       CDialog::OnInitDialog();

       ......

       // TODO: Add extra initialization here
       DWORD exstyle = m_cListCtrl.GetExtendedStyle();
       m_cListCtrl.SetExtendedStyle(exstyle | LVS_EX_FULLROWSELECT | LVS_EX_GRIDLINES |

           LVS_EX_CHECKBOXES | WS_EX_STATICEDGE );

       CRect rect;
       m_cListCtrl.GetClientRect(&rect);
       int nColInterval = rect.Width()/5;

       m_cListCtrl.InsertColumn(0, _T("Item Name"), LVCFMT_LEFT, nColInterval*3);
       m_cListCtrl.InsertColumn(1, _T("Value"), LVCFMT_LEFT, nColInterval);
       m_cListCtrl.InsertColumn(2, _T("Time"), LVCFMT_LEFT, rect.Width()-4*nColInterval);

       m_cListCtrl.InsertItem(0,"name");
       m_cListCtrl.SetItemText(0,1,"value");
       m_cListCtrl.SetItemText(0,2,"time");

       ......
 
       return TRUE;  // return TRUE  unless you set the focus to a control

    }

    2、在单文档视图中自行添加ListControl控件:

    创建单文档应用程序,如下图所示为视图类添加CListCtrl对象成员变量:

    如下图所示,在资源视图中打开String Table资源,在右键菜单中选择new string,为将要创建的ListControl控件添加资源编号:

    为创建和显示控件,在视图的初始化消息函数中添加如下代码:

    void CAddListView::OnInitialUpdate()
    {
       CView::OnInitialUpdate(); 
       // TODO: Add your specialized code here and/or call the base class
       m_cListCtrl.Create( LVS_REPORT,CRect(0,0,800,600),this,IDC_LISTCTRL);
       m_cListCtrl.ModifyStyle(0,LVS_REPORT|LVS_SHOWSELALWAYS|LVS_SORTASCENDING);
       //m_cListCtrl.SendMessage(LVM_SETEXTENDEDLISTVIEWSTYLE,0,

          LVS_EX_GRIDLINES|LVS_EX_FULLROWSELECT|LVS_EX_CHECKBOXES);
       m_cListCtrl.ShowWindow(SW_SHOW);

       CRect rect;
       m_cListCtrl.GetClientRect(&rect);
       int nColInterval = rect.Width()/5;

       m_cListCtrl.InsertColumn(0, _T("Item Name"), LVCFMT_LEFT, nColInterval*3);
       m_cListCtrl.InsertColumn(1, _T("Value"), LVCFMT_LEFT, nColInterval);
       m_cListCtrl.InsertColumn(2, _T("Time"), LVCFMT_LEFT, rect.Width()-4*nColInterval);

       m_cListCtrl.InsertItem(0,"name");
       m_cListCtrl.SetItemText(0,1,"value");
       m_cListCtrl.SetItemText(0,2,"time");
    }

    3、在ListView视图中显示ListControl控件:

    创建单文档应用程序,如下图所示,在选择窗口视图类型时,选择CListView视图:


 

    在视图类的初始化消息函数中添加如下显示控件的代码:

    void CTestlistView::OnInitialUpdate()
    {
        CListView::OnInitialUpdate();
        CDC* dc = GetDC();
        TEXTMETRIC tm;
        dc->GetTextMetrics(&tm);
        GetListCtrl().ModifyStyle(0,LVS_REPORT|LVS_SHOWSELALWAYS|LVS_SORTASCENDING);
        GetListCtrl().SendMessage(LVM_SETEXTENDEDLISTVIEWSTYLE,0,

             LVS_EX_GRIDLINES|LVS_EX_FULLROWSELECT|LVS_EX_CHECKBOXES|LVS_EX_TRACKSELECT);
        GetListCtrl().InsertColumn(0,"Name",LVCFMT_LEFT,30*tm.tmAveCharWidth,0);
        GetListCtrl().InsertColumn(1,"Comment",LVCFMT_LEFT,70*tm.tmAveCharWidth,1);

        // TODO: You may populate your ListView with items by directly accessing
        //  its list control through a call to GetListCtrl().
    }

二、为ListControl控件添加消息处理函数

    1、关于ListControl控件消息

    ListControl控件中有以下消息(通知)可以发送:NM_CLICKNM_DBLCLKNM_RCLICKLVN_COLUMNCLICKHDN_ITEMCLICK等。

    其中HDN_ITEMCLICKList Control的子控件ListCtrl发给它的ParentCListCtrl)的;LVN_COLUMNCLICKHeaderCtrl发给它的Parent的。所以在Dialog里面,试图通过ClassWizard产生的ON_NOTIFY宏:ON_NOTIFY(HDN_ITEMCLICK, IDC_LIST_CTRLOnItemClick),来接收HDN_ITEMCLICK消息是无法成功的。要解决这个问题,可以从CListCtrl派生一个新的类,并在CListCtrl派生类中处理HDN_ITEMCLICK消息。注意消息映射的时候,Header的控件ID0,类似如下消息映射宏代码:
    ON_NOTIFY(HDN_ITEMCLICK, 0, OnItemClick)
   
另外,可以使用NM_CLICKNM_RCLICK等消息,以NM打头的消息是可以在Dialog里处理的。

    2、关于ListControl控件的行选择:

    要在控件中选择行,需要设置控件的扩展属性LVS_EX_FULLROWSELECT。右键或左键都可以选择行,而且,List Control控件默认可以一次选择(使用Ctrl键)多行,被选择的行默认以蓝色背景显示。

    3、为ListControl控件添加NM_CLICK消息:

    以前面创建的对话框应用程序为例,在ClassWizard中选择List Control控件,在对话框类中添加NM_CLICK消息处理函数。如下图所示:

    系统自动添加的消息映射与消息处理函数代码如下:

    // ListDialogDlg.h : header file

    protected:

       ......

       afx_msg void OnClickListCtrl(NMHDR* pNMHDR, LRESULT* pResult);

    ......

    // ListDialogDlg.cpp : implementation file

    BEGIN_MESSAGE_MAP(CListDialogDlg, CDialog)
        //{{AFX_MSG_MAP(CListDialogDlg)

        ......
        ON_NOTIFY(NM_CLICK, IDC_LIST_CTRL, OnClickListCtrl)
        //}}AFX_MSG_MAP
    END_MESSAGE_MAP()

    void CListDialogDlg::OnClickListCtrl(NMHDR* pNMHDR, LRESULT* pResult)
    {
       // TODO: Add your control notification handler code here
        NM_LISTVIEW* pNMListView = (NM_LISTVIEW*)pNMHDR;
       CString str;
       str.Format(_T("Item index: %d,SubItem:%d"), pNMListView->iItem,

            pNMListView->iSubItem);
       MessageBox(str);
       *pResult = 0;
    }

    其中黑体部分代码为自行添加的测试代码,主要为了获取选择的行编号与列编号,有了行编号和就可以使用m_cListCtrl.GetItemText(选择的行编号,某一列的列编号)获取某行某字段的值(如数据库表表示字段的值),可以定义一个对话框类成员变量存储该值,用于菜单或按钮命令,如修改记录、显示备注型(或图片型)字段内容、删除记录等。

    4、添加NM_RCLICK消息和右键菜单:

    NM_CLICK类似,添加NM_RCLICK消息处理函数。如下图所示创建菜单资源:

    NM_RCLICK消息处理函数中添加如下显示右键菜单的代码:

    void CListDialogDlg::OnRclickListCtrl(NMHDR* pNMHDR, LRESULT* pResult)
    {
       // TODO: Add your control notification handler code here
       //CPoint point;
       //::GetCursorPos(&point);//::
可以提示全局函数和当前类成员函数
        DWORD dwPos = GetMessagePos();
       CPoint point( LOWORD(dwPos), HIWORD(dwPos) );   
       CMenu menu;
       VERIFY( menu.LoadMenu( IDR_MENU1 ) );       //IDR_MENU1
是新建菜单ID
       CMenu* popup = menu.GetSubMenu(0);
       //ASSERT( popup != NULL );
       popup->TrackPopupMenu(TPM_LEFTALIGN | TPM_RIGHTBUTTON, point.x, point.y,

             this );//TPM_RIGHTBUTTON使右键点击菜单也起作用   

       *pResult = 0;
    }

    ClassWizard中为菜单项ID_DELETE添加删除命令消息处理函数。以下是测试代码:

    void CListDialogDlg::OnDelete()
    {
       // TODO: Add your command handler code here
       int iItemSel = m_cListCtrl.GetNextItem(-1, LVIS_SELECTED);
       CString str="";
       while(iItemSel != -1)
       {
          //m_cListCtrl.DeleteItem(iItemSel);//delete selected item in the list control
          str=str+m_cListCtrl.GetItemText(iItemSel,0);//
利用该方法可以获取数据记录编号列
          iItemSel = m_cListCtrl.GetNextItem(iItemSel, LVIS_SELECTED);        
       } 
       MessageBox(str);
    }

    代码中的循环是为了处理同时选择了多行的情况。可以在代码中添加根据选择的行编号iItemSel获得数据记录编号的代码,在控件中删除行的同时,删除数据库表中的相应记录。

 

 

 

 

List Control控件技巧总汇<修订版>(1)

2008-09-06 21:53

以下未经说明,listctrl默认view 风格为report
-------------------------------------------------------------------------------
1. CListCtrl 风格
       LVS_ICON: 为每个item显示大图标
       LVS_SMALLICON: 为每个item显示小图标
       LVS_LIST: 显示一列带有小图标的item
       LVS_REPORT: 显示item详细资料
直观的理解:windows资源管理器,"查看"标签下的"大图标,小图标,列表,详细资料
--------------------------------------------------------------------------------
2. 设置listctrl 风格及扩展风格
       LONG lStyle;
       lStyle = GetWindowLong(m_list.m_hWnd, GWL_STYLE);//获取当前窗口style
       lStyle &= ~LVS_TYPEMASK; //清除显示方式位
       lStyle |= LVS_REPORT; //设置style
       SetWindowLong(m_list.m_hWnd, GWL_STYLE, lStyle);//设置style
       DWORD dwStyle = m_list.GetExtendedStyle();
       dwStyle |= LVS_EX_FULLROWSELECT;//选中某行使整行高亮(只适用与report风格的listctrl)
dwStyle |= LVS_EX_GRIDLINES;//网格线(只适用与report风格的listctrl)
dwStyle |= LVS_EX_CHECKBOXES;//item前生成checkbox控件
m_list.SetExtendedStyle(dwStyle); //设置扩展风格
注:listview的style请查阅msdn      
http://msdn.microsoft.com/library/default.asp?url=/library/en-us/wceshellui5/html/wce50lrflistviewstyles.asp
--------------------------------------------------------------------------------
3. 插入数据
       m_list.InsertColumn( 0, "ID", LVCFMT_LEFT, 40 );//插入列
       m_list.InsertColumn( 1, "NAME", LVCFMT_LEFT, 50 );

      //新插入的在上面
       int nRow = m_list.InsertItem(0, "11");// 插入行
       m_list.SetItemText(nRow, 1, "jacky");//设置其它列数据

    //新插入的数据在下面

   int nIndex = m_list.GetItemCount();
    LV_ITEM lvItem;
    lvItem.mask = LVIF_TEXT ;
    lvItem.iItem = nIndex;     //行数
    lvItem.iSubItem = 0;
    lvItem.pszText = (char*)(LPCTSTR)strCount;   //第一列
    //在最后一行插入记录值.
         m_list.InsertItem(&lvItem);
    //插入其它列
    m_list.SetItemText(nIndex,1,strLat);
--------------------------------------------------------------------------------
4. 一直选中item
选中style中的Show selection always,或者在上面第2点中设置LVS_SHOWSELALWAYS
--------------------------------------------------------------------------------
5. 选中和取消选中一行
int nIndex = 0;
//选中
m_list.SetItemState(nIndex, LVIS_SELECTED|LVIS_FOCUSED, LVIS_SELECTED|LVIS_FOCUSED);
//取消选中
     m_list.SetItemState(nIndex, 0, LVIS_SELECTED|LVIS_FOCUSED);
--------------------------------------------------------------------------------
6. 得到listctrl中所有行的checkbox的状态
m_list.SetExtendedStyle(LVS_EX_CHECKBOXES);
CString str;
for(int i=0; i{
if( m_list.GetItemState(i, LVIS_SELECTED) == LVIS_SELECTED || m_list.GetCheck(i))
{
str.Format(_T("第%d行的checkbox为选中状态"), i);
AfxMessageBox(str);
}
}
--------------------------------------------------------------------------------
7. 得到listctrl中所有选中行的序号
方法一:
       CString str;
       for(int i=0; i       {
           if( m_list.GetItemState(i, LVIS_SELECTED) == LVIS_SELECTED )
           {
                 str.Format(_T("选中了第%d行"), i);
                 AfxMessageBox(str);
           }
       }
方法二:
       POSITION pos = m_list.GetFirstSelectedItemPosition();
       if (pos == NULL)
           TRACE0("No items were selected!\n");
       Else
       {
           while (pos)
           {
                 int nItem = m_list.GetNextSelectedItem(pos);
                 TRACE1("Item %d was selected!\n", nItem);
                 // you could do your own processing on nItem here
           }
       }
--------------------------------------------------------------------------------
8. 得到item的信息
       TCHAR szBuf[1024];
       LVITEM lvi;
       lvi.iItem = nItemIndex;
       lvi.iSubItem = 0;
       lvi.mask = LVIF_TEXT;
       lvi.pszText = szBuf;
       lvi.cchTextMax = 1024;
       m_list.GetItem(&lvi);
关于得到设置item的状态,还可以参考msdn文章
       Q173242: Use Masks to Set/Get Item States in ClistCtrl
http://support.microsoft.com/kb/173242/en-us
--------------------------------------------------------------------------------
9. 得到listctrl的所有列的header字符串内容
       LVCOLUMN lvcol;
       char   str[256];
       int   nColNum;
       CString   strColumnName[4];//假如有4列
       nColNum = 0;
       lvcol.mask = LVCF_TEXT;
       lvcol.pszText = str;
       lvcol.cchTextMax = 256;
       while(m_list.GetColumn(nColNum, &lvcol))
       {
           strColumnName[nColNum] = lvcol.pszText;
           nColNum++;
       }
--------------------------------------------------------------------------------
10. 使listctrl中一项可见,即滚动滚动条
m_list.EnsureVisible(i, FALSE);
--------------------------------------------------------------------------------
11. 得到listctrl列数
int nHeadNum = m_list.GetHeaderCtrl()->GetItemCount();
--------------------------------------------------------------------------------
12. 删除所有列
方法一:
         while ( m_list.DeleteColumn (0))
因为你删除了第一列后,后面的列会依次向上移动。
方法二:
       int nColumns = 4;
       for (int i=nColumns-1; i>=0; i--)
           m_list.DeleteColumn (i);

    删除所有行
直接用第7点的方法得到所有选中的行号,然后用DeleteItem(i)想删除所有行,这样是行不通的。因为ListCtrl的行号是从上往下排列的,你删除了上面的行后,下面的行号也随之改变,所以用此方法无法删除所有行。正确的方法是从下往上删除行。如下所示:
for(int i=m_list.GetItemCount()-1; i>=0;i--)
{
     if( m_list.GetItemState(i, LVIS_SELECTED) == LVIS_SELECTED )
     {
         m_list.DeleteItem(i);
     }
}
--------------------------------------------------------------------------------
13. 得到单击的listctrl的行列号
添加listctrl控件的NM_CLICK消息相应函数
       void CTest6Dlg::OnClickList1(NMHDR* pNMHDR, LRESULT* pResult)
       {
           // 方法一:
           /*
           DWORD dwPos = GetMessagePos();
           CPoint point( LOWORD(dwPos), HIWORD(dwPos) );
           m_list.ScreenToClient(&point);
           LVHITTESTINFO lvinfo;
           lvinfo.pt = point;
           lvinfo.flags = LVHT_ABOVE;
           int nItem = m_list.SubItemHitTest(&lvinfo);
           if(nItem != -1)
           {
                 CString strtemp;
                 strtemp.Format("单击的是第%d行第%d列", lvinfo.iItem, lvinfo.iSubItem);
                 AfxMessageBox(strtemp);
           }
           */
         // 方法二:
           /*
           NM_LISTVIEW* pNMListView = (NM_LISTVIEW*)pNMHDR;
           if(pNMListView->iItem != -1)
           {
                 CString strtemp;
                 strtemp.Format("单击的是第%d行第%d列",
                                 pNMListView->iItem, pNMListView->iSubItem);
                 AfxMessageBox(strtemp);
           }
           */
           *pResult = 0;
       }
--------------------------------------------------------------------------------
14. 判断是否点击在listctrl的checkbox上
添加listctrl控件的NM_CLICK消息相应函数
       void CTest6Dlg::OnClickList1(NMHDR* pNMHDR, LRESULT* pResult)      
{          
DWORD dwPos = GetMessagePos();
           CPoint point( LOWORD(dwPos), HIWORD(dwPos) );  
           m_list.ScreenToClient(&point);
           LVHITTESTINFO lvinfo;
           lvinfo.pt = point;
           lvinfo.flags = LVHT_ABOVE;
           UINT nFlag;
           int nItem = m_list.HitTest(point, &nFlag);
           //判断是否点在checkbox上
           if(nFlag == LVHT_ONITEMSTATEICON)
           {
                 AfxMessageBox("点在listctrl的checkbox上");
           }
           *pResult = 0;
       }
--------------------------------------------------------------------------------
15. 右键点击listctrl的item弹出菜单
添加listctrl控件的NM_RCLICK消息相应函数
       void CTest6Dlg::OnRclickList1(NMHDR* pNMHDR, LRESULT* pResult)
       {
           NM_LISTVIEW* pNMListView = (NM_LISTVIEW*)pNMHDR;
           if(pNMListView->iItem != -1)
           {
                 DWORD dwPos = GetMessagePos();
                 CPoint point( LOWORD(dwPos), HIWORD(dwPos) );
                 CMenu menu;
                 VERIFY( menu.LoadMenu( IDR_MENU1 ) );
                 CMenu* popup = menu.GetSubMenu(0);
                 ASSERT( popup != NULL );
               popup->TrackPopupMenu(TPM_LEFTALIGN | TPM_RIGHTBUTTON, point.x, point.y, this );
           }
           *pResult = 0;
   }

16. item切换焦点时(包括用键盘和鼠标切换item时),状态的一些变化顺序
添加listctrl控件的LVN_ITEMCHANGED消息相应函数
       void CTest6Dlg::OnItemchangedList1(NMHDR* pNMHDR, LRESULT* pResult)
       {
           NM_LISTVIEW* pNMListView = (NM_LISTVIEW*)pNMHDR;
           // TODO: Add your control notification handler code here
           CString sTemp;
           if((pNMListView->uOldState & LVIS_FOCUSED) == LVIS_FOCUSED && (pNMListView->uNewState & LVIS_FOCUSED) == 0)
           {
                 sTemp.Format("%d losted focus",pNMListView->iItem);
           }
           else if((pNMListView->uOldState & LVIS_FOCUSED) == 0 &&
               (pNMListView->uNewState & LVIS_FOCUSED) == LVIS_FOCUSED)
           {
                 sTemp.Format("%d got focus",pNMListView->iItem);
           }
           if((pNMListView->uOldState & LVIS_SELECTED) == LVIS_SELECTED &&
             (pNMListView->uNewState & LVIS_SELECTED) == 0)
           {
                 sTemp.Format("%d losted selected",pNMListView->iItem);
           }
else if((pNMListView->uOldState & LVIS_SELECTED) == 0 && (pNMListView->uNewState & LVIS_SELECTED) == LVIS_SELECTED)
           {
sTemp.Format("%d got selected",pNMListView->iItem);
}
*pResult = 0;
--------------------------------------------------------------------------------
17. 得到另一个进程里的listctrl控件的item内容
http://www.codeproject.com/threads/int64_memsteal.asp

--------------------------------------------------------------------------------
18. 选中listview中的item
Q131284: How To Select a Listview Item Programmatically
http://support.microsoft.com/kb/131284/en-us

--------------------------------------------------------------------------------
19. 如何在CListView中使用CListCtrl的派生类
http://www.codeguru.com/cpp/controls/listview/introduction/article.php/c919/

--------------------------------------------------------------------------------
20. listctrl的subitem添加图标
       m_list.SetExtendedStyle(LVS_EX_SUBITEMIMAGES);
       m_list.SetItem(..); //具体参数请参考msdn

--------------------------------------------------------------------------------