我们在MFC中显示数据库数据时都使用CListCtrl控件,虽说实现并不难,但个人觉得这样每次都要写那些无聊且同样的代码,实在是在浪费资源,所以无聊之际将一些MFC控件组合起来实现一个简单的数据库分页显示控件,可以简单快捷地实现数据库数据读取显示
使用方法:
m_Page.Create(100, 10, _fRect, this);
m_Page.AddItem(_T("RecordId"), 50);
m_Page.AddItem(_T("LogoffTime"), 130);
100是用来计算数据库分页显示控件上个控件的ID所用
列表控件 100
刷新 101
上一页 102
下一页 103
组合框 104
可在数据库分页显示控件父窗口中相应这些控件的消息,并执行下列函数
m_Page.Flash();
m_Page.Front();
m_Page.Next();
m_Page.GoToPage();
m_Page.SetConnectIfo("127.0.0.1", "HRMS2011", "HRMS", "123456");
设置数据库消息 分别为IP、数据库名、登陆名和密码
_bstr_t a = "select * from tb_laborage";
m_Page.SetSql(a);
设置SQL语句
m_Page.ShowData();
实例下载地址:http://download.csdn.net/source/2440604
具体实现如下:
CpaginationCtrl.h
#include "ADOConn.h"
#include <vector>
using namespace std;
class CPaginationCtrl
{
public:
void SetSql(_bstr_t& _bstrSQL);
void SetConnectIfo(_bstr_t _Ip, _bstr_t _DataBase, _bstr_t _Id, _bstr_t _Passwd);
void SetPageItemNum(UINT _ItemNum);
void GoToPage();
void Next(void);
void Front(void);
void Flash(void);
bool ShowData();
void AddItem(const CString& _string, UINT _Width);
virtual bool Create(UINT _Id, UINT _ItemNum, CRect &_Rect, CWnd* _parent = NULL);
CPaginationCtrl();
virtual ~CPaginationCtrl();
CListCtrl* GetCurrentList();
private:
bool Execute(_RecordsetPtr& _pRecordset);
virtual CListCtrl* CreateList(UINT _Id, CWnd *_parent, const CRect &_Rect);
void ShowList();
void SetCCombIfo(UINT _PageNum);
void ShowOrHideList(UINT);
private:
CWnd *m_Parent; //父窗口指针
CRect m_Rect; //控件区域
BUTTON m_front; //上一页按钮
BUTTON m_Next; //下一页按钮
BUTTON m_flash; //刷新按钮
CComboBox m_Page; //页数控件
UINT m_Id; //控件ID
UINT m_PageItemNum; //每页显示的数据数目
UINT m_ColumnNum; //列数
UINT m_PageNum; //页数
UINT m_currentPage; //当前页数
vector<CListCtrl*> m_DataPage; //CListCtrl 列表
ADOConn m_ADoConn; //ADO连接数据库对象
_bstr_t m_bstrSQL; //连接用的SQL语句
public:
void DeleteAll(void);
};
#endif // !defined(AFX_PAGINATIONCTRL1_H__17A6C5F4_9A7B_4B4F_8ECA_E615DC51E914__INCLUDED_)
// PaginationCtrl1.cpp: implementation of the CPaginationCtrl class.
//
//
#include "stdafx.h"
#include "PaginationCtrl.h"
#ifdef _DEBUG
#undef THIS_FILE
static char THIS_FILE[]=__FILE__;
#define new DEBUG_NEW
#endif
//
// Construction/Destruction
//
CPaginationCtrl::CPaginationCtrl():m_ColumnNum(0), m_Parent(NULL),
m_currentPage(0),m_bstrSQL("")
{
}
CPaginationCtrl::~CPaginationCtrl()
{
/*删除在堆上创建的列表控件对象*/
vector<CListCtrl*>::iterator i= m_DataPage.end();
for(vector<CListCtrl*>::iterator j = m_DataPage.begin(); j < i; j ++)
{
delete (*j);
}
}
bool CPaginationCtrl::Create(UINT _Id, UINT _ItemNum, CRect &_Rect, CWnd *_parent)
{
m_Id = _Id;
m_Parent = _parent;
m_Rect = _Rect;
m_PageItemNum = _ItemNum;
/*计算按钮的宽度*/
int _fWidth
= (_Rect.right - _Rect.left) / 8;
/*建立按钮的局域*/
CRect _fRect(_Rect.left, _Rect.bottom - 30, _Rect.left + _fWidth, _Rect.bottom);
/*创建刷新按钮*/
if ( !m_flash.Create(_T("刷新"),WS_CHILD /*| BS_CENTER*/ |
WS_VISIBLE /*| WS_EX_CLIENTEDGE*/, _fRect, _parent, _Id + 1))
{
return false;
}
/*创建上一页按钮*/
_fRect.OffsetRect(_fWidth * 3, 0);
if ( !m_front.Create(_T("上一页"),WS_CHILD | BS_CENTER |
WS_VISIBLE | WS_EX_CLIENTEDGE, _fRect, _parent, _Id + 2) )
{
return false;
}
/*创建下一页按钮*/
_fRect.OffsetRect(_fWidth * 2, 0);
if ( !m_Next.Create(_T("下一页"),WS_CHILD | BS_CENTER |
WS_VISIBLE | WS_EX_CLIENTEDGE, _fRect, _parent, _Id + 3))
{
return false;
}
/*创建页码组合框*/
_fRect.OffsetRect(_fWidth * 2, 0);
_fRect.bottom = _fRect.bottom + 100;
if ( !m_Page.Create(CBS_DROPDOWN | CBS_SORT | WS_VISIBLE|
WS_VSCROLL | WS_TABSTOP, _fRect, _parent, _Id + 4) )
{
return false;
}
/*创建列表控件*/
CListCtrl *_fList = CreateList(m_Id , _parent,
CRect(m_Rect.left, m_Rect.top, m_Rect.right, m_Rect.bottom - 40));
if (!_fList)
return false;
_fList->ShowWindow(SW_SHOW);
/*put in vector*/
m_DataPage.push_back(_fList);
return true;
}
void CPaginationCtrl::AddItem(const CString &_string, UINT _Width)
{
vector<CListCtrl*>::iterator i = m_DataPage.end();
/*设置各列的标题和宽度*/
for (vector<CListCtrl*>::iterator j = m_DataPage.begin(); j < i; j ++)
{
(*j) -> InsertColumn(m_ColumnNum, _string);
(*j) -> SetColumnWidth(m_ColumnNum, _Width);
}
++m_ColumnNum;
}
bool CPaginationCtrl::ShowData()
{
/*打开数据库*/
m_ADoConn.OnInitADOConn();
/*获取记录集*/
_RecordsetPtr _pRecordset = m_ADoConn.GetRecordSet(m_bstrSQL);
if (!_pRecordset->adoEOF &&
m_ColumnNum != _pRecordset->Fields->GetCount())
{
AfxMessageBox(_T("Column != Count"));
m_ADoConn.ExitConnect();
return false;
}
DeleteAll();
Execute(_pRecordset);
m_ADoConn.ExitConnect();
return true;
}
bool CPaginationCtrl::Execute(_RecordsetPtr& _pRecordset)
{
/*获取记录数*/
long _fRecordset = 0;
_fRecordset = _pRecordset->GetRecordCount();
if ( _fRecordset <= 0 )
{
return false;
}
/*计算页数*/
m_PageNum = _fRecordset % m_PageItemNum == 0 ? _fRecordset / m_PageItemNum
: _fRecordset / m_PageItemNum + 1;
LVCOLUMN _fLVCOLUMN;
TCHAR str[256];
_fLVCOLUMN.mask=LVCF_TEXT | LVCF_WIDTH;
_fLVCOLUMN.pszText=str;
_fLVCOLUMN.cchTextMax=256;
UINT _fColumn = 0;
CListCtrl *_fList = NULL;
/*新建一些列表控件*/
if(m_PageNum > m_DataPage.size())
for(int i = m_DataPage.size(); i < m_PageNum; i ++)
{
_fList = CreateList(m_Id, m_Parent,
CRect(m_Rect.left, m_Rect.top, m_Rect.right, m_Rect.bottom - 40));
if (!_fList)
return false;
m_DataPage.push_back(_fList);
for(int j = 0; j < m_ColumnNum; j ++ )
{
if(!(m_DataPage.at(0) -> GetColumn(j, &_fLVCOLUMN)))
return false;
_fList -> InsertColumn(j, _fLVCOLUMN.pszText);
_fList -> SetColumnWidth(j, _fLVCOLUMN.cx);
}
}
SetCCombIfo(m_PageNum);
variant_t vt;
/*读取记录并显示在列表控件上*/
long _fShowRecordset = 0;
_pRecordset->MoveFirst();
for(int i = 0; i < m_PageNum; i ++)
{
_fList = m_DataPage.at(i);
for(int j = 0; j < m_PageItemNum; j ++)
{
_fList->InsertItem(j,_T(""));
for(int k = 0; k < m_ColumnNum; k ++)
{
/*设置每一列的数据*/
// vt = _pRecordset->GetCollect(_variant_t((long)k))->Value;
vt = _pRecordset->Fields->GetItem(_variant_t((long)k))->Value;
if (vt.vt != VT_NULL)
{
_fList->SetItemText(j, k,(TCHAR*)(_bstr_t)vt);
}
}
_pRecordset->MoveNext();
if(_pRecordset->adoEOF)
{
return true;
}
}
}
return true;
}
void CPaginationCtrl::Flash(void)
{
DeleteAll();
/*重新设定数据*/
m_flash.EnableWindow(false);
ShowData();
m_flash.EnableWindow(true);
}
void CPaginationCtrl::Front(void)
{
ShowOrHideList(SW_HIDE);
/*计算页数*/
m_currentPage = m_currentPage != 0 ? m_currentPage - 1 : m_PageNum - 1;
/*显示列表控件*/
ShowList();
}
void CPaginationCtrl::Next(void)
{
ShowOrHideList(SW_HIDE);
/*计算页数*/
m_currentPage = (m_currentPage + 1) % m_PageNum == 0 ? 0 : ++m_currentPage;
/*计算页数*/
ShowList();
}
void CPaginationCtrl::GoToPage()
{
ShowOrHideList(SW_HIDE);
/*获得页数*/
m_currentPage = m_Page.GetCurSel();
ShowOrHideList(SW_SHOW);
}
void CPaginationCtrl::SetPageItemNum(UINT _ItemNum)
{
m_PageItemNum = _ItemNum;
}
CListCtrl* CPaginationCtrl::CreateList(UINT _Id, CWnd *_parent, const CRect& _Rect)
{
CListCtrl *_fList = new CListCtrl();
/*创建列表控件*/
if ( !_fList -> Create(LVS_EDITLABELS | LVS_REPORT | LVS_SHOWSELALWAYS | LVS_SINGLESEL,
_Rect, _parent, _Id) )
{
return NULL;
}
/*设置列表控件的扩展风格*/
_fList ->SetExtendedStyle(_fList ->GetExtendedStyle() | LVS_EX_FULLROWSELECT | LVS_EX_GRIDLINES);
return _fList;
}
void CPaginationCtrl::SetConnectIfo(_bstr_t _Ip, _bstr_t _DataBase, _bstr_t _Id, _bstr_t _Passwd)
{
/*设置访问数据库信息*/
m_ADoConn.AddConnectIfo(_Ip, _DataBase, _Id, _Passwd);
}
void CPaginationCtrl::SetCCombIfo(UINT _PageNum)
{
CString _fpage('1');
m_Page.ResetContent();
m_Page.SetWindowText(_fpage);
/*设置组合框的项*/
for(int i = 1; i <= _PageNum; i ++ )
{
_fpage.Format(_T("%d"),i);
m_Page.InsertString(-1, _fpage);
}
}
void CPaginationCtrl::ShowList()
{
CString _fpage;
ShowOrHideList(SW_SHOW);
_fpage.Format(_T("%d"),m_currentPage + 1);
m_Page.SetWindowText(_fpage);
}
void CPaginationCtrl::SetSql(_bstr_t& _bstrSQL)
{
m_bstrSQL = _bstrSQL;
}
void CPaginationCtrl::ShowOrHideList(UINT _TYPE)
{
m_DataPage.at(m_currentPage)->ShowWindow(_TYPE);
}
CListCtrl* CPaginationCtrl::GetCurrentList()
{
return m_DataPage.at(m_currentPage);
}
void CPaginationCtrl::DeleteAll(void)
{
/*删除列表控件所有数据*/
vector<CListCtrl*>::iterator i= m_DataPage.end();
for(vector<CListCtrl*>::iterator j = m_DataPage.begin(); j < i; j ++)
{
(*j)->DeleteAllItems();
}
}