CGridCtrl学习指南.docx
《CGridCtrl学习指南.docx》由会员分享,可在线阅读,更多相关《CGridCtrl学习指南.docx(24页珍藏版)》请在冰豆网上搜索。
![CGridCtrl学习指南.docx](https://file1.bdocx.com/fileroot1/2022-12/6/2c3de94d-b0f4-4738-9922-fc64b8fbc6a2/2c3de94d-b0f4-4738-9922-fc64b8fbc6a21.gif)
CGridCtrl学习指南
CGridCtrl学习指南
当我努力为显示和编辑现有表中的数据而使用CListCtrl到了极限之后,我意识到我所需要的只不过是一个专用的Grid控件而已。
于是我开始着手写自己的Grid控件,但为了节省时间我决定修改JoeWillcoxson's的免费控件WorldCom,你可以在以下站点找到这个东东。
为了让它能做我要做的事情,我分解了他的代码,并且重新修改。
由于代码经过太多的修改,我甚至不能确信最终是否还存在最初的代码。
但无论如何,Joe的代码是一个大框架,而我只是在上面进行加工而已。
工程一开始的时候是计划尽可能的简单但是当我不断发现我不得不考虑新特色的时候,它迅速的膨胀成为一个梦魇。
虽然测试并不是没有遗漏--但是我还是坚信情形不会变得太坏J。
Joe很善意的允许我开放这个资源而不附加任何的语句(毕竟那是基于他的代码),但是由于工程象马拉松似的,所以我在这段代码中使用了两个非常不成熟的条件:
这段代码可以以任何方式用于已编译的形式中(包括商业用途)。
只要代码不适用,即使没有作者同意,作者姓名和所有版权信息都原封不动,你可以对代码进行任何形式的使用。
但是,如果没有作者的同意,这篇文章和附带的源代码都不能放在任何网站或论坛上。
你就把它当作是没有任何担保的软件,随意使用吧!
我已经尽量除去任何不良的"特征",对由它引起的任何损害,时间的浪费或者数据丢失等,我不负任何责任。
希望不要问太多关于继续开发下去的到底有多大工作量的问题。
如果你真的要用于商业场合,请给我发email让我知道。
如果没有多少人使用的话,开放和维护/升级代码就没有任何意义。
控件的特点:
●使用鼠标可以进行单元格的选择,还可以辅助ctrl和shift的组合键进行选
择。
也可以取消选择。
●行和列可以按照大小进行重排,还可以取消对行、列或两者的排序。
●双击区分点,行或者列可以按照大小自动排序
●可以对任何列或行固定
●单元格可以有不同文本和背景颜色的个性化设置
●单元格可以有字体的个性化设置
●单元格可以标注"只读"或者其他的状态设置及检测
●OLE的拖放动作
●Ctrl-C,Ctrl-X和Ctrl-V执行拷贝、剪切、粘贴操作,Ctrl-A全选
●当单元格成为焦点,并且在单元格的编辑区域按下字符键,就意味着在
那个单元格进行编辑了
●支持微软的智能鼠标
●可以在单元格中加入图片
●对大型数据可以使用"虚拟"模式
●充分的打印支持,支持文档/浏览环境(包括打印预览)或是基于会话的应用(不支持打印预览)
●可选的"列表模式",包括对行的全选或单选,还有单击列标题提示进行插入的操作。
●众多的虚函数可以很容易对控件进行功能扩充
●支持UNICODE
●支持WinCE
●单元格的标题提示太小不能显示数据
●可以隐藏行和列
●在VC4.2、5.0、6.0和CE工具箱2.0、3.0下编译通过
示例中示范了grid控件中大部分特征
文档
如果想在你的工程中使用这个Grid控件的话,你还得在你的工程中添加一些文件:
gridctrl.cpp,gridctrl.hGrid控件资源文件和头文件
gridcellbase.cpp,gridcellbase.h单元格的基础类
gridcell.cpp,gridcell.h单元格的默认执行文件
CellRange.hCcellID和CcellRange类的定义
MemDC.hKeithRule's的直接存储类
InPlaceEdit.cpp,InPlaceEdit.h定位编辑窗口的源文件和头文件
GridDropTarget.cpp,GridDropTarget.hGrid容器的drag和drop对象只有在gridctrl.h中没有定义GRIDCONTROL_NO_DRAGDROP的时候才有必要使用。
Titletip.cpp,Titletip.h从ZafirAnjum那里的到的单元格标题提示.只有在gridctrl.h中没有定义GRIDCONTROL_NO_TITLETIPS的时候才有必要使用
结构
这个Grid是基于一种框架(CgridCtrl工程),这种框架组织和控制那些容纳数据、执行某些操作如画图、句柄方法如按钮的点击事件的单元格的动作。
Grid工程本身的句柄事件如点击是在单元格之前响应,如果它认为有必要的话,它还会发送某种鼠标信息。
它还包含一个拖曳对象(CGridDropTarget)和一个标题提示对象(CTitleTip),前者处理拖曳操作,后者在单元格物理空间在最大限度内不足以显示其内容时可以显示出其内容。
Grid单元格可以是任何类型,其长度与源自CgridBaseCell的类的长度一样。
包含这个包的是一个CgridCell类,它能处理基本的数据存储和编辑操作。
扩充的两个类CgridCellCombo和CGridURLCell示范了如何创建自己的单元格类。
单元格有两种主要状态即固定和非固定。
固定的单元格通常在Grid的左上方,并且不会随着Grid的卷动而移动。
通常这些单元格包含列和行的标题部分,并且不能进行编辑。
而非固定的单元格构成了Grid的内部,你可以对它进行编辑和选择。
Grid的各种不同属性的默认值存放在CgridDefaultCell中。
每个Grid中通常有四种属性--每个Grid中含有非固定、列固定、行固定以及行列同时固定的单元格的默认值。
因此,为了实现设置Grid的默认属性,首先得使用CGridCtrL:
:
GetDefaultCell来取得单元格的默认实现,然后你就可以直接设置了
单元格的属性除字体属性外都很明确。
每一个单元格都有一个指向字体结构体的指针,这个指针只有当你的自行设置单元格的字体属性时才会被分配和使用。
Grid还有一种虚拟模式阻止Grid创建实际的格子,每当它需要单元格的信息时,允许你的指定一种回收函数或者消息机制来获得。
这样当工作轻微减少时可以节省大量的内存费用。
发送给Grid父类的消息GVN_ODCACHEHINT可以帮助你的在Grid的单元格发送信息请求时预先进行数据缓冲。
Grid的数据是以行为单位进行存储的,所以,对于大量单元格而言,所有的操作都必须以行为单位进行的。
解说
好了--那么,现在如何使用它呢?
Grid的基本类是源于CWnd的CgridCtrl。
为了使用它,你可以使用微软的VC++的对话框编辑器,把一个普通的控件放在对话框上,并且输入"MFCGridCtrl"(不包括引号)作为类名。
Grid的子类使用DDX机制(可以通过ClassWizard来进行默认设置),使用DDX_GridControl函数代替DDX_Control(可以通过手动设置ClassWizard的输入来实现)。
这些保证你的控件作为一个注册对象而不会产生一些莫名其妙的WIN95问题。
你也可以选择使用CGridCtrl:
:
Create
CGridCtrlgrid;
grid.Create(rect,pParentWnd,nID);
其中的rect是大小,pParentWnd是父窗口,nID是标志符。
列和行的数目
intGetRowCount()const返回行(包括固定行)的数目
intGetColumnCount()const返回列(包括固定列)的数目
intGetFixedRowCount()const返回固定行的数目
intGetFixedColumnCount()const返回固定行的数目
BOOLSetRowCount(intnRows)设置行的数目(包括固定行),如果成功,返回TRUE
BOOLSetColumnCount(intnCols)设置列的数目(包括固定列),如果成功,返回TRUE
BOOLSetFixedRowCount(intnFixedRows=1)设置固定行的数目,如果成功,返回TRUE
BOOLSetFixedColumnCount(intnFixedCols=1)设置固定列的数目,如果成功,返回TRUE
大小和位置函数
intGetRowHeight(intnRow)const获取由nRow指定行的高度
BOOLSetRowHeight(introw,intheight)设定由row指定行的高度为height
intGetColumnWidth(intnCol)const获取由nCol指定列的宽度
BOOLSetColumnWidth(intcol,intwidth)设定由col指定列的宽度为width
intGetFixedRowHeight()const获取固定行的高度
intGetFixedColumnWidth()const获取固定列的高度
longGetVirtualHeight()const获取所有行的合并高度
longGetVirtualWidth()const获取所有列的合并宽度
BOOLGetCellOrigin(intnRow,intnCol,LPPOINTp)取出单元格(nRow,nCol)的左上角点,成功返回TRUE(单元格必须是可见的)
BOOLGetCellOrigin(constCCellID&cell,LPPOINTp)获取给定单元格的左上角点,成功则返回TRUE,也可以参照CCellID.
BOOLGetCellRect(intnRow,intnCol,LPRECTpRect)获取给定单元格的边框,成功则返回TRUE(单元格必须是可见的)
BOOLGetCellRect(constCCellID&cell,LPRECTpRect)获取给定单元格的边框成功则返回TRUE(单元格必须是可见的)也可以参照CCellID.
BOOLGetTextRect(intnRow,intnCol,LPRECTpRect)t获取给定单元格中的文本框,成功则返回TRUE(单元格必须是可见的)
BOOLGetTextRect(constCCellID&cell,LPRECTpRect)获取给定单元格中的文本框,成功则返回TRUE(单元格必须是可见的)也可以参照CCellID.
BOOLGetTextExtent(intnRow,intnCol,LPCTSTRstr)获取给定单元格中的指定的文本内容的边框,成功则返回TRUE
BOOLGetCellTextExtent(intnRow,intnCol)获取给定单元格中的文本框,成功则返回TRUE
虚拟模式
虚拟模式允许Grid在不存储数据的情况下,能够显示大量数据。
在虚拟模式下,不用产生单元格,也不用存储数据,列宽和行高除外。
由于Grid本身并不存储数据,所以它必须有一些方法让其它程序帮助它存储这些数据。
这些是通过Grid本身的回收函数或者其父类的一个句柄GVN_GETDISPINFO的申明来实现的。
voidSetVirtualMode(BOOLbVirtual)设置Grid是否使用虚拟模式
BOOLGetVirtualMode()当使用虚拟模式时返回TRUE
voidSetCallbackFunc(GRIDCALLBACKpCallback,LPARAMlParam)当Grid为虚拟模式时,设置回调函数
GRIDCALLBACKGetCallbackFunc()当Grid为虚拟模式时,返回回调函数
如果没有指定回调函数,Grid就会向其父窗口发送一个GVN_GETDISPINFO信息,这个申明部分如同GV_DISPINFO结构,GV_DISPINFO机构体就象下面所示:
typedefstructtagGV_DISPINFO{
NMHDRhdr;
GV_ITEMitem;
}GV_DISPINFO;
显而易见的是,它有一个很好的暗示就是允许Grid所需要的数据进入高速缓存。
因此,在显示某一页单元格内容之前,Grid首先会发送一个GVN_ODCACHEHINT信息,结构体GV_CACHEHINT会作为消息的一部分,其结构如下:
typedefstructtagGV_CACHEHINT{
NMHDRhdr;
CCellRangerange;
}GV_CACHEHINT;
下面有一个处理这个消息的例子:
//处理这个消息的是对话框的一个成员变量m_Gri
BOOLCGridCtrlDemoDlg:
:
OnNotify(WPARAMwParam,LPARAMlParam,
LRESULT*pResult)
{
if(wParam==(WPARAM)m_Grid.GetDlgCtrlID())
{
*pResult=1;
GV_DISPINFO*pDispInfo=(GV_DISPINFO*)lParam;
if(GVN_GETDISPINFO==pDispInfo->hdr.code)
{
//TRACE2("GettingDisplayinfoforcell%d,%d\n",
pDispInfo->item.row,pDispInfo->item.col);
pDispInfo->item.strText.Format(_T("Message%d,%d"),
pDispInfo->item.row,pDispInfo->item.col);
returnTRUE;
}
elseif(GVN_ODCACHEHINT==pDispInfo->hdr.code)
{
GV_CACHEHINT*pCacheHint=(GV_CACHEHINT*)pDispInfo;
TRACE(_T("Cachehintreceivedforcellrange%d,%d-%d,%d\n"),
pCacheHint->range.GetMinRow(),
pCacheHint->range.GetMinCol(),
pCacheHint->range.GetMaxRow(),
pCacheHint->range.GetMaxCol());
}
}
returnCDialog:
:
OnNotify(wParam,lParam,pResult);
}
也可以使用SetCallbackFunc来设置回收函数代替发送GVN_GETDISPINFO消息,而且,Grid可以直接调用这个回收函数,当然了,即使调用了回收函数,GVN_ODCACHEHINT消息还会照常发送。
回收函数应当是如下形式:
BOOLCALLBACKCallbackFunction(GV_DISPINFO*pDispInfo,LPARAMlParam);
例如:
BOOLCALLBACKCGridCtrlDemoDlg:
:
GridCallback(GV_DISPINFO*pDispInfo,
LPARAM/*lParam*/)
{
pDispInfo->item.strText.Format(_T("Callback%d,%d"),
pDispInfo->item.row,pDispInfo->item.col);
returnTRUE;
}
当调用SetCallbackFunc的时候,你可以定义一个LPARAM,这样当每次调用回收函数时可以将这个值传递给这个回收函数。
注意这个回收函数必须是一个静态或全局函数。
总体的外观和特征
voidSetImageList(CImageList*pList)设置Grid的当前图形列表,它拷贝的只是列表的指针而非列表本身。
CImageList*GetImageList()取出Grid当前图形列表
voidSetGridLines(intnWhichLines=GVL_BOTH)设置哪些(如果有的话)线条不可见,从here可以找到一些可能的取值。
intGetGridLines()取出那些(如果有的话)不可见线条,从here可以找到一些可能的返回值。
voidSetEditable(BOOLbEditable=TRUE)设置Grid是否可以编辑。
BOOLIsEditable()判断Grid是否可编辑。
.
voidSetListMode(BOOLbEnableListMode=TRUE)将Grid设置成(或不是)排序模式,当Grid处于排序模式时,将启动所有行选,并且这时如果点击列表头时,将会对Grid按行进行排序。
BOOLGetListMode()判断Grid是否处于排序模式。
voidSetSingleRowSelection(BOOLbSing=TRUE)将Grid设置成(或不是)单行选择模式,这种模式只有在排序模式下有效。
当处在这种模式下,每次只能选择一行,所以整个Grid表现看起来就好象是一个多列的列表框。
BOOLGetSingleRowSelection()判断Grid是否处于单行选择模式。
voidSetSingleColSelection(BOOLbSing=TRUE)将Grid设置成(或不是)单列选择模式,在这种模式下,每次只能选择一列。
BOOLGetSingleColSelection()判断Grid是否处于单列选择模式。
voidEnableSelection(BOOLbEnable=TRUE)设置Grid的单元格是否可选。
BOOLIsSelectable()判断Grid的单元格是否可选。
voidSetFixedRowSelection(BOOLbSelect)设置当点击固定行时,是否选择其旁边的单元格。
BOOLGetFixedRowSelection()判断当点击固定行时,是否选择其旁边的单元格。
voidSetFixedColumnSelection(BOOLbSelect)设置当点击固定列时,是否选择其下面的单元格
BOOLGetFixedColumnSelection()判断当点击固定列时,是否选择其下面的单元格
voidEnableDragAndDrop(BOOLbAllow=TRUE)设置是否开启拖曳动作。
BOOLGetDragAndDrop()判断拖曳动作是否开启。
voidSetRowResize(BOOLbResize=TRUE)设置是否可设置行的大小。
BOOLGetRowResize()判断是否可设置行的大小。
voidSetColumnResize(BOOLbResize=TRUE)设置是否可设置列的大小。
BOOLGetColumnResize()判断是否可设置列的大小。
voidSetHandleTabKey(BOOLbHandleTab=TRUE)设置是否启用TAB键来移动选择单元格
BOOLGetHandleTabKey()判断是否启用TAB键来移动选择单元格。
voidSetDoubleBuffering(BOOLbBuffer=TRUE)设置画图时是否使两级缓冲(不支持闪烁)。
BOOLGetDoubleBuffering()判断画图时是否使用了两级缓冲。
voidEnableTitleTips(BOOLbEnable=TRUE)设置是否使用标题提示
BOOLGetTitleTips()判断是否使用标题提示
voidSetTrackFocusCell(BOOLbTrack)设置同行/列中的固定单元格作为焦点单元格时是否高亮显示并且使用凹陷边缘。
BOOLGetTrackFocusCell()判断同行/列中的固定单元格作为焦点单元格时是否高亮显示并且使用凹陷边缘。
voidSetFrameFocusCell(BOOLbFrame)设置焦点单元格是否高亮显示并且加上外边框。
BOOLGetFrameFocusCell()判断是否对焦点单元格高亮显示并且加上外边框。
voidSetAutoSizeStyle(intnStyle=GVS_BOTH)设置单元格如何自动调整大小GVS_BOTH=固定和非固定单元格都可以自动调整;GVS_HEADER=仅固定单元格可以;GVS_DATA=仅非固定单元格可以
intGetAutoSizeStyle()获取自动排序的执行模式。
voidEnableHiddenColUnhide(BOOLbEnable=TRUE)设置当用户调整列的宽度时隐藏列(宽度为0)是否显现出来。
BOOLGetHiddenColUnhide()判断当用户调整列的宽度时隐藏列(宽度为0)是否显现出来。
voidEnableHiddenRowUnhide(BOOLbEnable=TRUE)设置当用户调整行的高度时隐藏行(高度为0)是否显现出来。
BOOLGetHiddenRowUnhide()判断当用户调整行的高度时隐藏行(高度为0)是否显现出来。
voidEnableColumnHide(BOOLbEnable=TRUE)设置是否可以通过鼠标将列的宽度压缩为0。
BOOLGetColumnHide()判断是否可以通过鼠标将列的宽度压缩为0。
voidEnableRowHide(BOOLbEnable=TRUE)设置是否可以通过鼠标将行的高度压缩为0。
BOOLGetRowHide()判断是否可以通过鼠标将行的高度压缩为0。
颜色
voidSetGridBkColor(COLORREFclr)设置控件的背景颜色(固定和非固定单元格之外的区域)。
COLORREFGetGridBkColor()获取控件的背景颜色。
voidSetGridLineColor(COLORREFclr)设置网格线的颜色。
COLORREFGetGridLineColor()获取网格线的颜色。
COLORREFGetTitleTipBackClr()获取标题提示的背景颜色。
voidSetTitleTipBackClr(COLORREFclr=CLR_DEFAULT)设置标题提示的背景颜色。
COLORREFGetTitleTipTextClr()获取标题提示的文本颜色。
voidSetTitleTipTextClr(COLORREFclr=CLR_DEFAULT)设置标题提示的文本颜色。
不再支持如下的函数了。
你应当使用GetDefaultCell来获取默认单元格实现你所感兴趣的单元格类型,然后就可以直接设置单元格的属性了。
如果给定单元格是默认设置值,那么为匹配你的单元格类型,就得在默认的单元格实现中使用这些值。
voidSetTextColor(COLORREFclr)设置非固定单元格中的文本颜色。
COLORREFGetTextColor()获取非