|
C++5.0下CGridCtrl类的建立与应用
|
|
摘要
本文较为详细地介绍了CGridCtrl类的建立,并利用该类实现了在一单文档界面上
对一数据库内容的显示、修改、添加、删除及打印等功能。 关键词 CGridCtrl类,电子表格,数据库 一、前言 在数据库的操作系统中,经常要遇到对数据库的内容进行显示、修改、添加和删除等功能,而一般情况下数据库的容量都是很大的,为此我们通常选用以电子表格的形式来显示数据库的内容,并在其上完成对数据库的修改、添加和删除,使对数据库的操作既直观又方便;如用VB5.0下DB Grid Control来实现以上功能是较为方便的,但由于VB的通信速度和数据的处理速度较慢,特别对于要处理和显示的数据量较大时,其速度较慢表现得尤为明显,为此我们选用在VC++5.0下用CGridCtrl[1]类来实现。 CGridCtrl[1]类派生于CWnd类,该类主要包含以下八个方面的函数,其函数形式如下: class CGridCtrl : public CWnd { // 1. CGridCtrl类的构造函数 CGridCtrl(int nRows = 0, int nCols = 0, int nFixedRows = 0, int nFixedCols = 0); BOOL Create(const RECT& rect, CWnd* parent, UINT nID, DWORD dwStyle = WS_CHILD | WS_BORDER | WS_TABSTOP | WS_VISIBLE); BOOL SetRowCount(int nRows); /设置表的行数 BOOL SetColumnCount(int nCols); //设置表的列数 BOOL SetFixedRowCount(int nFixedRows = 1); //设置表的固定行数 BOOL SetFixedColumnCount(int nFixedCols = 1); //设置表的固定列数 int GetFixedRowCount() const; // 取表的固定行数 int GetFixedColumnCount() const; //取表的固定列数 …… // 3. 表格尺寸大小方面的函数 BOOL SetRowHeight(int row, int height); //设置表格单元的高度 BOOL SetColumnWidth(int col, int height); //设置表格单元的宽度 int GetRowHeight(int nRow) const; //获取表格单元的高度 int GetColumnWidth(int nCol) const; //获取表格单元的宽度 void AutoSize(); //对表格单元的高度与宽度进行自动设置 …… // 4. 表格显示与特征方面的函数 void SetImageList(CImageList* pList); //设置列表图标 void SetEditable(BOOL bEditable = TRUE); //设置表格的编辑状态 BOOL SetColumnType(int nCol, int nType); //设置表格的列状态 …… // 5. 颜色方面的函数 void SetTextColor(COLORREF clr); //设置输入表格的文本颜色 void SetTextBkColor(COLORREF clr); //设置可供输入文本的表格颜色 void SetFixedTextColor(COLORREF clr); //设置输入固定表格的文本颜色 void SetFixedBkColor(COLORREF clr); //设置固定表格颜色 …… // 6. 表格信息函数 BOOL SetItem(const GV_ITEM* pItem); // 向表格中输入信息 BOOL SetItemText(int nRow, int nCol, LPCTSTR str); //向某一单元表格中输入文本 BOOL SetItemImage(int nRow, int nCol, int iImage); //在某一单元表格中设置图标 …… // 7. 编辑方面的函数 virtual void OnEditCell(int nRow, int nCol, UINT nChar) //开始对表格进行编辑 virtual void OnEndEditCell(int nRow, int nCol, CString str) //结束对表格编辑 …… // 8. 表格打印函数 void Print(); //打印表格 …… } CGridCtrl[1]类的构造函数形式如下: CGridCtrl::CGridCtrl(int nRows, int nCols, int nFixedRows, int nFixedCols) { m_crWindowText = ::GetSysColor(COLOR_WINDOWTEXT); m_crWindowColour = ::GetSysColor(COLOR_WINDOW); m_cr3DFace = ::GetSysColor(COLOR_3DFACE); m_nRows = 0; //初始电子表格的行数 m_nCols = 0; //初始电子表格的列数 m_nFixedRows = 0; //初始化固定表格的行数 m_nFixedCols = 0; //初始化固定表格的列数 m_bEditable = TRUE; //初始化表格为可编辑状态 …… //初始化设置表格的行列数 SetRowCount(nRows); SetColumnCount(nCols); SetFixedRowCount(nFixedRows); SetFixedColumnCount(nFixedCols); // 初始化表格的背景颜色及输入表格的文本颜色 SetTextColor(m_crWindowText); SetTextBkColor(m_crWindowColour); SetFixedTextColor(m_crWindowText); SetFixedBkColor(m_cr3DFace); …… } 对表格中所输入信息属性的描述,是通过定义一结构体函数来实现,该结构体函数形式如下: typedef struct _GV_ITEM { int row,col; // 输入信息的位置 UINT mask; //输入信息的灰度值 UINT state; // 表格单元的状态 UINT nFormat; // 信息的输入形式 CString szText; // 输入表格单元的文本 } GV_ITEM; 将CGridCtrl类与以下类结合起来,即可构造成在其上可进行编辑和修改的电子表格,这些类分别为: 1.用于单元表格范围的两个类:CCellRange[2]类和CCellID[3]类; 2.单元表格状态属性的类:CGridCell[4]类; 3.对表格进行编辑的两个类:CInplaceEdit[5]类和CInplaceList[6]类; 三、CGridCtrl类的应用 1.CGridCtrl类实现对数据库内容的显示
图1
在单文档的界面上以电子表格形式对一工资表的显示 在MyGridCtrlTestView.h中,我们将CGridCtrlEx类(该类为CGriCtrl类的派生)嵌入到CMyGridCtrlTestView类中,其形式如下: class CMyGridCtrlTestView : public CView { class CGridEx : public CGridCtrl { // Override this function to fill InPlaceListBoxes void FillListItems(int nCol, LPARAM cltList); …… }; public: CDemo_ui_devstudioDoc* GetDocument(); CGridEx m_Grid; CSize m_OldSize; int *Iarray; CString *Csarray; CImageList m_ImageList; …… public: virtual void OnDraw(CDC* pDC); // overridden to draw this view …… protected: afx_msg void OnGridCtrlDelete(); //对表格进行删除的函数 afx_msg void OnGridCtrlPrint(); //对表格进行打印的函数 …… }; 在CMyGridCtrlTestView类的OnDraw()函数中,我们实现对工资表的电子表格显示,该函数的形式如下: void CMyGridCtrlTestView ::OnDraw(CDC* pDC) { CMyGridCtrlTestDoc* pDoc = GetDocument(); ASSERT_VALID(pDoc); // TODO: add draw code for native data here int s,r; // 建立一显示CGridCtrl类的矩形 RECT rect; GetClientRect(&rect); m_OldSize = CSize(rect.right-rect.left, rect.bottom-rect.top); m_Grid.Create(rect, (CWnd*)this, 111); // 打开工资表并将工资表的内容读入数组中 …… s:为工资表的行数; r:为工资表的列数; 申请两个数组空间,用于存放工资表的内容,分别为: Csarray=new CString[(s+2)*1]; //用于存放姓名 Iarray=new int[(s+2)*9]; //用于存放工资表中的其他项目 所申请两个数组空间比实际所需的空间要多两行,对于多出的最末两行中,如为字符串型变量,将以“0”代替,如为整型变量将以0代替,以供操作员在最末的两行实现对工资表的添加,如图1所示, //创造列表图标 m_ImageList.Create(MAKEINTRESOURCE(IDB_IMAGES), 16, 1, RGB(255,255,255)); m_Grid.SetImageList(&m_ImageList); //设置表格的属性特征 m_Grid.SetEditable(TRUE); //设置表格为可编辑状态 m_Grid.SetTextBkColor(RGB(0xFF, 0xFF, 0xE0)); //设置表格的背景颜色 //设置表格的行列数 try { m_Grid.SetRowCount(s+3); m_Grid.SetColumnCount(r+1); m_Grid.SetFixedRowCount(1); m_Grid.SetFixedColumnCount(1); } catch (CMemoryException* e) { e->ReportError(); e->Delete(); } // 将工资表的内容填入表格中 for (int row = 0; row < (s+3); row++) for (int col = 0; col < (r+1); col++) { GV_ITEM Item; //输入信息结构体变量的声明 Item.mask = GVIF_TEXT|GVIF_FORMAT; //所输入信息的灰度 Item.row = row; //输入信息的行位置 Item.col = col; //输入信息的列位置 if (row < 1) { Item.nFormat = DT_LEFT|DT_WORDBREAK; //输入信息的格式 if (col == 0 ) { m_Grid.SetColumnType(col, GVET_NOEDIT); //设置表格列为可编辑状态 Item.szText.Format(_T("不能编辑")); //设置表格的文本形式 } else if (col == 1 ) { m_Grid.SetColumnType(col, GVET_EDITBOX); Item.szText.Format(_T("姓名")); } else if (col == 2 ) { m_Grid.SetColumnType(col, GVET_EDITBOX); Item.szText.Format(_T("固定工资")); } else if (col == 3 ) { m_Grid.SetColumnType(col, GVET_LISTBOX); //设置表格列为下拉可选状态 Item.szText.Format(_T("住房补贴")); } //以下均为对表格第一行标题的设定, 情况与以上相类似,在此将col==4,5,6,7,8,9时略去。 …… else if(col==10){ m_Grid.SetColumnType(col, GVET_EDITBOX); Item.szText.Format(_T("公积金")); } else { } } else if (col < 1) { Item.nFormat = DT_RIGHT|DT_VCENTER|DT_SINGLELINE|DT_END_ELLIPSIS; Item.szText.Format(_T("行 %d"),row); } else { Item.nFormat = DT_CENTER|DT_VCENTER|DT_SINGLELINE|DT_END_ELLIPSIS; if(col==1) Item.szText.Format(_T("%s"),Csarray[(row-1)]); else if(col==2) { Item.szText.Format(_T("%d"),*(Iarray+(row-1)*9)); } else if(col==3) { Item.szText.Format(_T("%d"),*(Iarray+1+(row-1)*9)); } //以下为col==4,5,6,7,8,9时的填写,情况与以上相类似,在此省略。 else if(col==10) { Item.szText.Format(_T("%d"),*(Iarray+8+(row-1)*9)); } else { } } m_Grid.SetItem(&Item); //将输入信息填入表格 if (col == (m_Grid.GetFixedColumnCount()-1) && row >= m_Grid.GetFixedRowCount()) m_Grid.SetItemImage(row, col, row%2); //将图标填入表格的第一列中 } m_Grid.AutoSize(); //对单元表格的高度与宽度进行自动设置 m_Grid.SetRowHeight(0, 3*m_Grid.GetRowHeight(0)/2); //设置第一行表格的高度 delete []Csarray; delete []Iarray; } 2.表格的编辑、添加与删除 我们可以对表格的内容直接进行编辑,对于表格中的某一项值是固定的几个取值时,我们以一下拉的方式让操作员选择某一值进行编辑,这样更有利于操作员的操作,如图1的第四列,该功能的实现是通过CGridCtrlEx类中的 FillListItems()函数来实现,该函数的形式如下: void CMyGridCtrlTestView ::CGridEx::FillListItems(int nCol, LPARAM cltList) { CListBox* pList = (CListBox*)cltList; if (nCol == 3) { pList->AddString("0"); pList->AddString("20"); pList->AddString("30"); pList->AddString("40"); pList->AddString("50"); pList->AddString("60"); } } 我们可以在表格的最末两行对工资表的内容进行添加,如图1所示,对表格中的内容进行修改和添加的结果都将自动地保存在工资表中,这是通过调用CGridCtrl[1]类的OnEndEditCell()函数来实现,该函数的形式如下: void CGridCtrl::OnEndEditCell(int nRow, int nCol, CString str) { SetItemText(nRow, nCol, str); //打开工资表,读取工资表的总行数为 T …… if(nRow==(T+1)) //所操作表格的行位置数大于工资表的总行数,是对表进行添加操作 { //对工资表进行添加操作 } else if(nRow<=T) //所操作表格的行位置数不大于工资表的总行数,是对表进行编辑操作 { //对工资表进行编辑操作 } else { MessageBox(“nRow error!”); } } 我们在编辑菜单(Edit)下设置一对表格进行删除的子菜单 “删除(工资表)”,单击该子菜单,即可弹出一对话框以供操作员输入要删除人的姓名,在确认无误以后,即可在工资表中将该人的工资信息自动删除,最后将删除后的工资表以电子表格的形式重新显示出来,该功能的实现是在CMyGridCtrlTestView类中OnGridCtrlDelete()函数来完成的。 3. 表格的打印 在文件菜单(File)下设置一对表格进行打印的子菜单 “打印(工资表)”,单击该子菜单,将调用CMyGridCtrlTestView类中OnPrintGridCell()函数,实现对表格的打印,该函数的形式如下: void CMyGridCtrlTestView :: OnGridCtrlPrint () { // TODO: Add your command handler code here m_Grid.Print(); }
四、小结 本篇是对VC++5.0下CGridCtrl[1]类建立与应用的一个初步探讨,CGridCtrl[1]类本身是很复杂,其所能实现的功能也是很强大的,除了我们给大家介绍CGridCtrl[1]类几个基本而又常用的函数之外,CGridCtrl[1]类还有很多用于其他方面的功能函数,在此我们不可能给大家一一介绍,我们利用CGridCtrl[1]类这些基本而又常用的函数,实现了对数据库内容的显示、修改、添加、删除及打印等功能,基本上满足了数据库操作人员的需求。
参考文献 1、http://users.aol.com/chinajoe,
Written by Chris Maunder. 2、http://users.aol.com/chinajoe,written
by Joe Willcoxson. 3、http://users.aol.com/chinajoe,written
by Joe Willcoxson. 4、http://users.aol.com/chinajoe,
Written by Chris Maunder. 5、http://www.codeguru.com/listview/edit_subitems.shtml,
Written by Chris Maunder. 6、http://www.codeguru.com/listview/edit_subitems.shtml,
Written by Motty Cohen.
|