當(dāng)我努力為顯示和編輯現(xiàn)有表中的數(shù)據(jù)而使用 CListCtrl 到了極限之后,我意識(shí)到我所需要的只不過(guò)是一個(gè)專(zhuān)用的Grid控件而已。于是我開(kāi)始著手寫(xiě)自己的Grid控件,但為了節(jié)省時(shí)間我決定修改Joe Willcoxson's的免費(fèi)控件 WorldCom,你可以在以下站點(diǎn) http://users.aol.com/chinajoe/wcmfclib.html 找到這個(gè)東東。為了讓它能做我要做的事情,我分解了他的代碼,并且重新修改。由于代碼經(jīng)過(guò)太多的修改,我甚至不能確信最終是否還存在最初的代碼。但無(wú)論如何,Joe的代碼是一個(gè)大框架,而我只是在上面進(jìn)行加工而已。
工程一開(kāi)始的時(shí)候是計(jì)劃盡可能的簡(jiǎn)單但是當(dāng)我不斷發(fā)現(xiàn)我不得不考慮新特色的時(shí)候,它迅速的膨脹成為一個(gè)夢(mèng)魘。雖然測(cè)試并不是沒(méi)有遺漏--但是我還是堅(jiān)信情形不會(huì)變得太壞J。Joe很善意的允許我開(kāi)放這個(gè)資源而不附加任何的語(yǔ)句(畢竟那是基于他的代碼),但是由于工程象馬拉松似的,所以我在這段代碼中使用了兩個(gè)非常不成熟的條件:
這段代碼可以以任何方式用于已編譯的形式中(包括商業(yè)用途)。只要代碼不適用,即使沒(méi)有作者同意,作者姓名和所有版權(quán)信息都原封不動(dòng),你可以對(duì)代碼進(jìn)行任何形式的使用。但是,如果沒(méi)有作者的同意,這篇文章和附帶的源代碼都不能放在任何網(wǎng)站或論壇上。
你就把它當(dāng)作是沒(méi)有任何擔(dān)保的軟件,隨意使用吧!
我已經(jīng)盡量除去任何不良的" 特征",對(duì)由它引起的任何損害,時(shí)間的浪費(fèi)或者數(shù)據(jù)丟失等,我不負(fù)任何責(zé)任。
希望不要問(wèn)太多關(guān)于繼續(xù)開(kāi)發(fā)下去的到底有多大工作量的問(wèn)題。如果你真的要用于商業(yè)場(chǎng)合,請(qǐng)給我發(fā)email讓我知道。如果沒(méi)有多少人使用的話,開(kāi)放和維護(hù)/升級(jí)代碼就沒(méi)有任何意義。
</P><P>控件的特點(diǎn):
●使用鼠標(biāo)可以進(jìn)行單元格的選擇,還可以輔助ctrl和shift的組合鍵進(jìn)行選
擇。也可以取消選擇。
● 行和列可以按照大小進(jìn)行重排,還可以取消對(duì)行、列或兩者的排序。
● 雙擊區(qū)分點(diǎn),行或者列可以按照大小自動(dòng)排序
● 可以對(duì)任何列或行固定
● 單元格可以有不同文本和背景顏色的個(gè)性化設(shè)置
● 單元格可以有字體的個(gè)性化設(shè)置
● 單元格可以標(biāo)注"只讀"或者其他的狀態(tài)設(shè)置及檢測(cè)
● OLE的拖放動(dòng)作
● Ctrl-C, Ctrl-X和Ctrl-V執(zhí)行拷貝、剪切、粘貼操作,Ctrl-A全選
● 當(dāng)單元格成為焦點(diǎn),并且在單元格的編輯區(qū)域按下字符鍵,就意味著在
那個(gè)單元格進(jìn)行編輯了
● 支持微軟的智能鼠標(biāo)
● 可以在單元格中加入圖片
● 對(duì)大型數(shù)據(jù)可以使用"虛擬"模式
● 充分的打印支持,支持文檔/瀏覽環(huán)境(包括打印預(yù)覽)或是基于會(huì)話的應(yīng)用(不支持打印預(yù)覽)
● 可選的"列表模式",包括對(duì)行的全選或單選,還有單擊列標(biāo)題提示進(jìn)行插入的操作。
● 眾多的虛函數(shù)可以很容易對(duì)控件進(jìn)行功能擴(kuò)充
● 支持UNICODE
● 支持WinCE
● 單元格的標(biāo)題提示太小不能顯示數(shù)據(jù)
● 可以隱藏行和列
● 在VC4.2、5.0、6.0和CE工具箱2.0、3.0下編譯通過(guò)</P><P>示例中示范了grid控件中大部分特征</P><P>文檔
如果想在你的工程中使用這個(gè)Grid控件的話,你還得在你的工程中添加一些文件:
gridctrl.cpp, gridctrl.h Grid控件資源文件和頭文件
gridcellbase.cpp, gridcellbase.h 單元格的基礎(chǔ)類(lèi)
gridcell.cpp, gridcell.h 單元格的默認(rèn)執(zhí)行文件
CellRange.h CcellID和CcellRange類(lèi)的定義
MemDC.h Keith Rule's的直接存儲(chǔ)類(lèi)
InPlaceEdit.cpp, InPlaceEdit.h 定位編輯窗口的源文件和頭文件
GridDropTarget.cpp, GridDropTarget.h Grid容器的drag和drop對(duì)象 只有在gridctrl.h中沒(méi)有定義 GRIDCONTROL_NO_DRAGDROP的時(shí)候才有必要使用。
Titletip.cpp, Titletip.h 從Zafir Anjum那里的到的單元格標(biāo)題提示. 只有在gridctrl.h中沒(méi)有定義 GRIDCONTROL_NO_TITLETIPS 的時(shí)候才有必要使用</P><P>結(jié)構(gòu)
這個(gè)Grid是基于一種框架(CgridCtrl工程),這種框架組織和控制那些容納數(shù)據(jù)、執(zhí)行某些操作如畫(huà)圖、句柄方法如按鈕的點(diǎn)擊事件的單元格的動(dòng)作。 Grid工程本身的句柄事件如點(diǎn)擊是在單元格之前響應(yīng),如果它認(rèn)為有必要的話,它還會(huì)發(fā)送某種鼠標(biāo)信息。它還包含一個(gè)拖曳對(duì)象(CGridDropTarget)和一個(gè)標(biāo)題提示對(duì)象(CTitleTip),前者處理拖曳操作,后者在單元格物理空間在最大限度內(nèi)不足以顯示其內(nèi)容時(shí)可以顯示出其內(nèi)容。Grid單元格可以是任何類(lèi)型,其長(zhǎng)度與源自CgridBaseCell的類(lèi)的長(zhǎng)度一樣。包含這個(gè)包的是一個(gè)CgridCell類(lèi),它能處理基本的數(shù)據(jù)存儲(chǔ)和編輯操作。擴(kuò)充的兩個(gè)類(lèi)CgridCellCombo和CGridURLCell示范了如何創(chuàng)建自己的單元格類(lèi)。
單元格有兩種主要狀態(tài)即固定和非固定。固定的單元格通常在Grid的左上方,并且不會(huì)隨著Grid的卷動(dòng)而移動(dòng)。通常這些單元格包含列和行的標(biāo)題部分,并且不能進(jìn)行編輯。而非固定的單元格構(gòu)成了Grid的內(nèi)部,你可以對(duì)它進(jìn)行編輯和選擇。
Grid的各種不同屬性的默認(rèn)值存放在CgridDefaultCell中。每個(gè)Grid中通常有四種屬性--每個(gè)Grid中含有非固定、列固定、行固定以及行列同時(shí)固定的單元格的默認(rèn)值。因此,為了實(shí)現(xiàn)設(shè)置Grid的默認(rèn)屬性,首先得使用CGridCtrL::GetDefaultCell來(lái)取得單元格的默認(rèn)實(shí)現(xiàn),然后你就可以直接設(shè)置了
單元格的屬性除字體屬性外都很明確。每一個(gè)單元格都有一個(gè)指向字體結(jié)構(gòu)體的指針,這個(gè)指針只有當(dāng)你的自行設(shè)置單元格的字體屬性時(shí)才會(huì)被分配和使用。
Grid還有一種虛擬模式阻止Grid創(chuàng)建實(shí)際的格子,每當(dāng)它需要單元格的信息時(shí),允許你的指定一種回收函數(shù)或者消息機(jī)制來(lái)獲得。這樣當(dāng)工作輕微減少時(shí)可以節(jié)省大量的內(nèi)存費(fèi)用。發(fā)送給Grid父類(lèi)的消息GVN_ODCACHEHINT可以幫助你的在Grid的單元格發(fā)送信息請(qǐng)求時(shí)預(yù)先進(jìn)行數(shù)據(jù)緩沖。
Grid的數(shù)據(jù)是以行為單位進(jìn)行存儲(chǔ)的,所以,對(duì)于大量單元格而言,所有的操作都必須以行為單位進(jìn)行的。</P><P>解說(shuō)
好了--那么,現(xiàn)在如何使用它呢?
Grid的基本類(lèi)是源于CWnd的CgridCtrl。為了使用它,你可以使用微軟的VC++的對(duì)話框編輯器,把一個(gè)普通的控件放在對(duì)話框上,并且輸入"MFCGridCtrl"(不包括引號(hào))作為類(lèi)名。Grid的子類(lèi)使用DDX機(jī)制(可以通過(guò)ClassWizard來(lái)進(jìn)行默認(rèn)設(shè)置),使用DDX_GridControl函數(shù)代替DDX_Control(可以通過(guò)手動(dòng)設(shè)置ClassWizard的輸入來(lái)實(shí)現(xiàn))。這些保證你的控件作為一個(gè)注冊(cè)對(duì)象而不會(huì)產(chǎn)生一些莫名其妙的WIN95問(wèn)題。
你也可以選擇使用CGridCtrl::Create
CGridCtrl grid;
grid.Create(rect, pParentWnd, nID);
其中的rect是大小,pParentWnd是父窗口,nID是標(biāo)志符。</P><P>列和行的數(shù)目
int GetRowCount() const 返回行(包括固定行)的數(shù)目
int GetColumnCount() const 返回列(包括固定列)的數(shù)目
int GetFixedRowCount() const 返回固定行的數(shù)目
int GetFixedColumnCount() const 返回固定行的數(shù)目
BOOL SetRowCount(int nRows) 設(shè)置行的數(shù)目(包括固定行),如果成功,返回TRUE
BOOL SetColumnCount(int nCols) 設(shè)置列的數(shù)目(包括固定列),如果成功,返回TRUE
BOOL SetFixedRowCount(int nFixedRows = 1) 設(shè)置固定行的數(shù)目,如果成功,返回TRUE
BOOL SetFixedColumnCount(int nFixedCols = 1) 設(shè)置固定列的數(shù)目,如果成功,返回TRUE</P><P>大小和位置函數(shù)
int GetRowHeight(int nRow) const 獲取由nRow指定行的高度
BOOL SetRowHeight(int row, int height) 設(shè)定由row指定行的高度為height
int GetColumnWidth(int nCol) const 獲取由nCol指定列的寬度
BOOL SetColumnWidth(int col, int width) 設(shè)定由col指定列的寬度為width
int GetFixedRowHeight() const 獲取固定行的高度
int GetFixedColumnWidth() const 獲取固定列的高度
long GetVirtualHeight() const 獲取所有行的合并高度
long GetVirtualWidth() const 獲取所有列的合并寬度
BOOL GetCellOrigin(int nRow, int nCol, LPPOINT p) 取出單元格(nRow,nCol)的左上角點(diǎn),成功返回TRUE(單元格必須是可見(jiàn)的)
BOOL GetCellOrigin(const CCellID& cell, LPPOINT p) 獲取給定單元格的左上角點(diǎn),成功則返回TRUE,也可以參照 CCellID.
BOOL GetCellRect(int nRow, int nCol, LPRECT pRect) 獲取給定單元格的邊框,成功則返回TRUE(單元格必須是可見(jiàn)的)
BOOL GetCellRect(const CCellID& cell, LPRECT pRect) 獲取給定單元格的邊框成功則返回TRUE(單元格必須是可見(jiàn)的) 也可以 參照CCellID.
BOOL GetTextRect(int nRow, int nCol, LPRECT pRect)t 獲取給定單元格中的文本框,成功則返回TRUE(單元格必須是可見(jiàn)的)
BOOL GetTextRect(const CCellID& cell, LPRECT pRect) 獲取給定單元格中的文本框,成功則返回TRUE(單元格必須是可見(jiàn)的)也可以參照 CCellID.
BOOL GetTextExtent(int nRow, int nCol, LPCTSTR str) 獲取給定單元格中的指定的文本內(nèi)容的邊框,成功則返回TRUE
BOOL GetCellTextExtent(int nRow, int nCol) 獲取給定單元格中的文本框,成功則返回TRUE</P><P>虛擬模式
虛擬模式允許Grid在不存儲(chǔ)數(shù)據(jù)的情況下,能夠顯示大量數(shù)據(jù)。在虛擬模式下,不用產(chǎn)生單元格,也不用存儲(chǔ)數(shù)據(jù),列寬和行高除外。
由于Grid本身并不存儲(chǔ)數(shù)據(jù),所以它必須有一些方法讓其它程序幫助它存儲(chǔ)這些數(shù)據(jù)。這些是通過(guò)Grid本身的回收函數(shù)或者其父類(lèi)的一個(gè)句柄GVN_GETDISPINFO的申明來(lái)實(shí)現(xiàn)的。
void SetVirtualMode(BOOL bVirtual) 設(shè)置Grid是否使用虛擬模式
BOOL GetVirtualMode() 當(dāng)使用虛擬模式時(shí)返回TRUE
void SetCallbackFunc(GRIDCALLBACK pCallback, LPARAM lParam) 當(dāng)Grid為虛擬模式時(shí),設(shè)置回調(diào)函數(shù)
GRIDCALLBACK GetCallbackFunc() 當(dāng)Grid為虛擬模式時(shí),返回回調(diào)函數(shù)
如果沒(méi)有指定回調(diào)函數(shù),Grid就會(huì)向其父窗口發(fā)送一個(gè)GVN_GETDISPINFO信息,這個(gè)申明部分如同GV_DISPINFO結(jié)構(gòu),GV_DISPINFO機(jī)構(gòu)體就象下面所示:</P><P>
typedef struct tagGV_DISPINFO {
NMHDR hdr;
GV_ITEM item;
} GV_DISPINFO;</P><P>
顯而易見(jiàn)的是,它有一個(gè)很好的暗示就是允許Grid所需要的數(shù)據(jù)進(jìn)入高速緩存。因此,在顯示某一頁(yè)單元格內(nèi)容之前,Grid首先會(huì)發(fā)送一個(gè)GVN_ODCACHEHINT信息,結(jié)構(gòu)體GV_CACHEHINT會(huì)作為消息的一部分,其結(jié)構(gòu)如下:</P><P>
typedef struct tagGV_CACHEHINT {
NMHDR hdr;
CCellRange range;
} GV_CACHEHINT;</P><P>
下面有一個(gè)處理這個(gè)消息的例子:
//處理這個(gè)消息的是對(duì)話框的一個(gè)成員變量m_Gri
BOOL CGridCtrlDemoDlg::OnNotify(WPARAM wParam, LPARAM lParam,
LRESULT* pResult)
{
if (wParam == (WPARAM)m_Grid.GetDlgCtrlID())
{
*pResult = 1;
GV_DISPINFO *pDispInfo = (GV_DISPINFO*)lParam;
if (GVN_GETDISPINFO == pDispInfo->hdr.code)
{
//TRACE2("Getting Display info for cell %d,%d\n",
pDispInfo->item.row, pDispInfo->item.col);
pDispInfo->item.strText.Format(_T("Message %d,%d"),
pDispInfo->item.row, pDispInfo->item.col);
return TRUE;
}
else if (GVN_ODCACHEHINT == pDispInfo->hdr.code)
{
GV_CACHEHINT *pCacheHint = (GV_CACHEHINT*)pDispInfo;
TRACE(_T("Cache hint received for cell range %d,%d - %d,%d\n"),
pCacheHint->range.GetMinRow(),
pCacheHint->range.GetMinCol(),
pCacheHint->range.GetMaxRow(),
pCacheHint->range.GetMaxCol());
}
}</P><P>return CDialog::OnNotify(wParam, lParam, pResult);
}
也可以使用SetCallbackFunc來(lái)設(shè)置回收函數(shù)代替發(fā)送GVN_GETDISPINFO消息,而且,Grid可以直接調(diào)用這個(gè)回收函數(shù),當(dāng)然了,即使調(diào)用了回收函數(shù),GVN_ODCACHEHINT消息還會(huì)照常發(fā)送。
回收函數(shù)應(yīng)當(dāng)是如下形式:
BOOL CALLBACK CallbackFunction(GV_DISPINFO * pDispInfo, LPARAM lParam);
例如:
BOOL CALLBACK CGridCtrlDemoDlg::GridCallback(GV_DISPINFO *pDispInfo,
LPARAM /*lParam*/)
{
pDispInfo->item.strText.Format(_T("Callback %d,%d"),
pDispInfo->item.row, pDispInfo->item.col);
return TRUE;
}
當(dāng)調(diào)用SetCallbackFunc的時(shí)候,你可以定義一個(gè)LPARAM,這樣當(dāng)每次調(diào)用回收函數(shù)時(shí)可以將這個(gè)值傳遞給這個(gè)回收函數(shù)。注意這個(gè)回收函數(shù)必須是一個(gè)靜態(tài)或全局函數(shù)。</P><P>總體的外觀和特征
void SetImageList(CImageList* pList) 設(shè)置Grid的當(dāng)前圖形列表,它拷貝的只是列表的指針而非列表本身。
CImageList* GetImageList() 取出Grid當(dāng)前圖形列表
void SetGridLines(int nWhichLines = GVL_BOTH) 設(shè)置哪些(如果有的話)線條不可見(jiàn),從 here 可以找到一些可能的取值。
int GetGridLines() 取出那些(如果有的話)不可見(jiàn)線條,從 here 可以找到一些可能的返回值。
void SetEditable(BOOL bEditable = TRUE) 設(shè)置Grid是否可以編輯。
BOOL IsEditable() 判斷Grid是否可編輯。.
void SetListMode(BOOL bEnableListMode = TRUE) 將Grid設(shè)置成(或不是)排序模式,當(dāng)Grid處于排序模式時(shí),將啟動(dòng)所有行選,并且這時(shí)如果點(diǎn)擊列表頭時(shí),將會(huì)對(duì)Grid按行進(jìn)行排序。
BOOL GetListMode() 判斷Grid是否處于排序模式。
void SetSingleRowSelection(BOOL bSing = TRUE) 將G rid設(shè)置成(或不是)單行選擇模式,這種模式只有在排序模式下有效。 當(dāng)處在這種模式下,每次只能選擇一行,所以整個(gè)Grid表現(xiàn)看起來(lái)就好象是一個(gè)多列的列表框。
BOOL GetSingleRowSelection() 判斷Grid是否處于單行選擇模式。
void SetSingleColSelection(BOOL bSing = TRUE) 將Grid設(shè)置成(或不是)單列選擇模式,在這種模式下,每次只能選擇一列。
BOOL GetSingleColSelection() 判斷Grid是否處于單列選擇模式。
void EnableSelection(BOOL bEnable = TRUE) 設(shè)置Grid的單元格是否可選。
BOOL IsSelectable() 判斷Grid的單元格是否可選。
void SetFixedRowSelection(BOOL bSelect) 設(shè)置當(dāng)點(diǎn)擊固定行時(shí),是否選擇其旁邊的單元格。
BOOL GetFixedRowSelection() 判斷當(dāng)點(diǎn)擊固定行時(shí),是否選擇其旁邊的單元格。
void SetFixedColumnSelection(BOOL bSelect) 設(shè)置當(dāng)點(diǎn)擊固定列時(shí),是否選擇其下面的單元格
BOOL GetFixedColumnSelection() 判斷當(dāng)點(diǎn)擊固定列時(shí),是否選擇其下面的單元格
void EnableDragAndDrop(BOOL bAllow = TRUE) 設(shè)置是否開(kāi)啟拖曳動(dòng)作。
BOOL GetDragAndDrop() 判斷拖曳動(dòng)作是否開(kāi)啟。
void SetRowResize(BOOL bResize = TRUE) 設(shè)置是否可設(shè)置行的大小。
BOOL GetRowResize() 判斷是否可設(shè)置行的大小。
void SetColumnResize(BOOL bResize = TRUE) 設(shè)置是否可設(shè)置列的大小。
BOOL GetColumnResize() 判斷是否可設(shè)置列的大小。
void SetHandleTabKey(BOOL bHandleTab = TRUE) 設(shè)置是否啟用TAB鍵來(lái)移動(dòng)選擇單元格
BOOL GetHandleTabKey() 判斷是否啟用TAB鍵來(lái)移動(dòng)選擇單元格。
void SetDoubleBuffering(BOOL bBuffer = TRUE) 設(shè)置畫(huà)圖時(shí)是否使兩級(jí)緩沖(不支持閃爍)。
BOOL GetDoubleBuffering() 判斷畫(huà)圖時(shí)是否使用了兩級(jí)緩沖。
void EnableTitleTips(BOOL bEnable = TRUE) 設(shè)置是否使用標(biāo)題提示
BOOL GetTitleTips() 判斷是否使用標(biāo)題提示
void SetTrackFocusCell(BOOL bTrack) 設(shè)置同行/列中的固定單元格作為焦點(diǎn)單元格時(shí)是否高亮顯示并且使用凹陷邊緣。
BOOL GetTrackFocusCell() 判斷同行/列中的固定單元格作為焦點(diǎn)單元格時(shí)是否高亮顯示并且使用凹陷邊緣。
void SetFrameFocusCell(BOOL bFrame) 設(shè)置焦點(diǎn)單元格是否高亮顯示并且加上外邊框。
BOOL GetFrameFocusCell() 判斷是否對(duì)焦點(diǎn)單元格高亮顯示并且加上外邊框。
void SetAutoSizeStyle(int nStyle = GVS_BOTH) 設(shè)置單元格如何自動(dòng)調(diào)整大小GVS_BOTH = 固定和非固定單元格都可以自動(dòng)調(diào)整; GVS_HEADER = 僅固定單元格可以; GVS_DATA = 僅非固定單元格可以
int GetAutoSizeStyle() 獲取自動(dòng)排序的執(zhí)行模式。
void EnableHiddenColUnhide(BOOL bEnable = TRUE) 設(shè)置當(dāng)用戶調(diào)整列的寬度時(shí)隱藏列(寬度為0)是否顯現(xiàn)出來(lái)。
BOOL GetHiddenColUnhide() 判斷當(dāng)用戶調(diào)整列的寬度時(shí)隱藏列(寬度為0)是否顯現(xiàn)出來(lái)。
void EnableHiddenRowUnhide(BOOL bEnable = TRUE) 設(shè)置當(dāng)用戶調(diào)整行的高度時(shí)隱藏行(高度為0)是否顯現(xiàn)出來(lái)。
BOOL GetHiddenRowUnhide() 判斷當(dāng)用戶調(diào)整行的高度時(shí)隱藏行(高度為0)是否顯現(xiàn)出來(lái)。
void EnableColumnHide(BOOL bEnable = TRUE) 設(shè)置是否可以通過(guò)鼠標(biāo)將列的寬度壓縮為0。
BOOL GetColumnHide() 判斷是否可以通過(guò)鼠標(biāo)將列的寬度壓縮為0。
void EnableRowHide(BOOL bEnable = TRUE) 設(shè)置是否可以通過(guò)鼠標(biāo)將行的高度壓縮為0。
BOOL GetRowHide() 判斷是否可以通過(guò)鼠標(biāo)將行的高度壓縮為0。</P><P>顏色
void SetGridBkColor(COLORREF clr) 設(shè)置控件的背景顏色(固定和非固定單元格之外的區(qū)域)。
COLORREF GetGridBkColor() 獲取控件的背景顏色。
void SetGridLineColor(COLORREF clr) 設(shè)置網(wǎng)格線的顏色。
COLORREF GetGridLineColor() 獲取網(wǎng)格線的顏色。
COLORREF GetTitleTipBackClr() 獲取標(biāo)題提示的背景顏色。
void SetTitleTipBackClr(COLORREF clr = CLR_DEFAULT) 設(shè)置標(biāo)題提示的背景顏色。
COLORREF GetTitleTipTextClr() 獲取標(biāo)題提示的文本顏色。
void SetTitleTipTextClr(COLORREF clr = CLR_DEFAULT) 設(shè)置標(biāo)題提示的文本顏色。
不再支持如下的函數(shù)了。你應(yīng)當(dāng)使用GetDefaultCell來(lái)獲取默認(rèn)單元格實(shí)現(xiàn)你所感興趣的單元格類(lèi)型,然后就可以直接設(shè)置單元格的屬性了。如果給定單元格是默認(rèn)設(shè)置值,那么為匹配你的單元格類(lèi)型,就得在默認(rèn)的單元格實(shí)現(xiàn)中使用這些值。
void SetTextColor(COLORREF clr) 設(shè)置非固定單元格中的文本顏色。
COLORREF GetTextColor() 獲取非固定單元格中的文本顏色。
void SetTextBkColor(COLORREF clr) 設(shè)置非固定單元格的背景顏色。
COLORREF GetTextBkColor() 獲取非固定單元格的背景顏色。
void SetFixedTextColor(COLORREF clr) 設(shè)置固定單元格的文本顏色。
COLORREF GetFixedTextColor() 獲取固定單元格的文本顏色。
void SetFixedBkColor(COLORREF clr) 設(shè)置固定單元格的背景顏色。
COLORREF GetFixedBkColor() 獲取固定單元格的背景顏色。
void SetBkColor(COLORREF clr) 設(shè)置控件的背景顏色 (單元格之外的區(qū)域).
COLORREF GetBkColor() 獲取控件的背景顏色。
void SetGridColor(COLORREF clr) 設(shè)置網(wǎng)格線的顏色。.
COLORREF GetGridColor() 獲取網(wǎng)格線的顏色。.
也可以參照Individual Cell colour functions,它允許改變Grid中某一個(gè)單元格的顏色以不同于其它單元格。</P><P>普通的單元格信息
CGridCellBase* GetDefaultCell(BOOL bFixedRow, BOOL bFixedCol) const 為要?jiǎng)?chuàng)建的單元格類(lèi)型獲取一個(gè)默認(rèn)的單元格實(shí)現(xiàn)的指針. bFixedRow 和 bFixedCol 用來(lái)申明單元格是否固定(行、列、或者兩者) 或非固定. 使用它來(lái)定義Grid的默認(rèn)屬性. 事實(shí)上Grid中的單元格在它們創(chuàng)建的時(shí)候就有了自己的默認(rèn)屬性. 它們使用 GetDefaultCell查詢(xún)Grid的默認(rèn)單元格屬性,并且用這些值來(lái)勾畫(huà)自己。.
CGridCellBase* GetCell(int nRow, int nCol) const 根據(jù)行/列來(lái)獲取相應(yīng)的單元格 (或者不存在的時(shí)候返回NULL)
BOOL SetCellType(int nRow, int nCol, CRuntimeClass* pRuntimeClass); 定義響應(yīng)單元格類(lèi)的類(lèi)型。
BOOL SetDefaultCellType(CRuntimeClass* pRuntimeClass); 為新的單元格設(shè)置默認(rèn)屬性。
void SetModified(BOOL bModified = TRUE, int nRow = -1, int nCol = -1) 為單元格設(shè)置一個(gè)標(biāo)志符. 如果沒(méi)有指明某行或某列,將對(duì)整個(gè)Grid進(jìn)行設(shè)置。
BOOL GetModified(int nRow = -1, int nCol = -1) 為單元格設(shè)置一個(gè)標(biāo)志符,如果沒(méi)有相應(yīng)的單元格,就返回整個(gè)Grid的狀態(tài)。
BOOL IsCellFixed(int nRow, int nCol) 如果單元格固定就返回TRUE.
BOOL IsItemEditing(int nRow, int nCol) 如果單元格正處在編輯狀態(tài)就返回TRUE.
BOOL SetItem(const GV_ITEM* pItem) 用 GV_ITEM 結(jié)構(gòu)體中的值來(lái)設(shè)置單元格的內(nèi)容. 注意掩碼字段中的值決定到底哪些值是真正改變了(比較 CListCtrl::SetItem).
BOOL GetItem(GV_ITEM* pItem) 從指定的單元格獲取其內(nèi)容來(lái)填充 GV_ITEM 結(jié)構(gòu)體. 注意掩碼字段中的只將決定哪些值真正取回了 (比較CListCtrl::GetItem).
BOOL SetItemText(int nRow, int nCol, LPCTSTR str) 設(shè)置指定單元格的文本內(nèi)容.成功則返回TRUE。
virtual CString GetItemText(int nRow, int nCol) 取出指定單元格的文本內(nèi)容,為有利于擴(kuò)展,這個(gè)函數(shù)設(shè)置成虛擬函數(shù). 不要和LVN_GETDISPINFO消息或字符串共享弄混了。
BOOL SetItemData(int nRow, int nCol, LPARAM lParam) 為指定單元格設(shè)置Iparam字段(用戶自定義的數(shù)據(jù))。成功則返回TRUE,也可參考GV_ITEM.
LPARAM GetItemData(int nRow, int nCol) const 獲取指定單元格的Iparam字段(用戶自定義的數(shù)據(jù))。成功則返回TRUE,也可參考GV_ITEM.
BOOL SetItemImage(int nRow, int nCol, int iImage) 設(shè)置指定單元格的圖形索引,成功則返回TRUE,也可參考 GV_ITEM.
int GetItemImage(int nRow, int nCol) const 獲取指定單元格的圖形索引。
BOOL SetItemState(int nRow, int nCol, UINT state) 設(shè)置給定單元格的狀態(tài).成功則返回TRUE,也可參考GV_ITEM.
UINT GetItemState(int nRow, int nCol) const 獲取指定單元格的狀態(tài),也可參考 GV_ITEM.
BOOL SetItemFormat(int nRow, int nCol, UINT nFormat) 設(shè)置指定單元格的格式,成功則返回TRUE。 單元格的默認(rèn)實(shí)現(xiàn)是使用 CDC::DrawText, 所以,任何的DT_*格式都可以使用. 也可參考 GV_ITEM.
UINT GetItemFormat(int nRow, int nCol) const 獲取給定單元格的格式(默認(rèn)返回CDC::DrawText DT_*格式). 也可參考 GV_ITEM.
int GetSelectedCount() 獲取被選單元格的數(shù)量。.
CCellID GetFocusCell() 獲取焦點(diǎn)單元格,可參考 CCellID.
CCellID SetFocusCell(CCellID cell);CCellID SetFocusCell(int nRow, int nCol); 設(shè)置焦點(diǎn)單元格。
BOOL SetItemBkColour(int nRow, int nCol, COLORREF cr = CLR_DEFAULT) 設(shè)置指定單元格的背景顏色,成功則返回TRUE,可參考 GV_ITEM.
COLORREF GetItemBkColour(int nRow, int nCol) const 獲取指定單元格的背景顏色,可參考 GV_ITEM.
BOOL SetItemFgColour(int nRow, int nCol, COLORREF cr = CLR_DEFAULT) 設(shè)置指定單元格的前景顏色,成功則返回TRUE,可參考 GV_ITEM.
COLORREF GetItemFgColour(int nRow, int nCol) const 獲取指定單元格的前景顏色,可參考 GV_ITEM.
BOOL SetItemFont(int nRow, int nCol, LOGFONT* lf) 設(shè)置指定單元格的字體,成功則返回TRUE,可參考GV_ITEM.
LOGFONT* GetItemFont(int nRow, int nCol) const 獲取指定單元格的字體,可參考 GV_ITEM.
BOOL IsItemEditing(int nRow, int nCol) 如果單元格處于編輯狀態(tài),則返回TRUE.
void EnsureVisible(CCellID &cell) 確保指定單元格可見(jiàn)。.
BOOL IsCellVisible(CCellID &cell) constBOOL IsCellVisible(CCellID cell) const 如果單元格可見(jiàn)則返回TRUE.
BOOL IsCellEditable(CCellID &cell) constBOOL IsCellEditable(CCellID cell) const 如果單元格可編輯則返回TRUE.
BOOL IsCellSelected(CCellID &cell) constBOOL IsCellSelected(CCellID cell) const 如果單元格已選,則返回TRUE。
void EnsureVisible(int nRow, int nCol) 確保指定單元格可見(jiàn).
BOOL IsCellFixed(int nRow, int nCol) 如果單元格是固定的,則返回TRUE。
int GetDefCellHeight() const 返回單元格的默認(rèn)高度 (對(duì)于新創(chuàng)建的單元格)
void SetDefCellHeight(int nHeight) 設(shè)置默認(rèn)單元格高度(對(duì)于新創(chuàng)建的單元格). 如果調(diào)用了SetFont就將被忽略
int GetDefCellWidth() const 返回單元格的默認(rèn)寬度 (對(duì)于新創(chuàng)建的單元格)
void SetDefCellWidth(int nWidth) 設(shè)置默認(rèn)單元格寬度(對(duì)于新創(chuàng)建的單元格). 如果調(diào)用了SetFont就將被忽略
int GetDefCellMargin() const Returns the default cell internal margin
void SetDefCellMargin(int nMargin) Sets the default cell internal margin.</P><P>操作
int InsertColumn(LPCTSTR strHeading, UINT nFormat, int nColumn = -1) 在nCol指定的地方插入一列,如果 nCol<0則在末尾插入一列. StrHeading就是列標(biāo)題頭nFormat 是列的格式.返回插入列的位置.
int InsertRow(LPCTSTR strHeading, int nRow = -1) 在nRow處插入一行,如果nRow<0則在末尾插入一行. strHeading 是行標(biāo)題頭. 此行的單元格的格式與其同列的第一行單元格格式相同. 返回插入行的位置.
BOOL DeleteColumn(int nColumn) 刪除"nColumn"指定的列,成功則返回TRUE.
BOOL DeleteRow(int nRow) 刪除"nRow"指定的行, 成功則返回TRUE.
BOOL DeleteAllItems() 刪除Grid中的所有行和內(nèi)容.
BOOL DeleteNonFixedRows() 刪除所有非固定行。
BOOL AutoSizeRow(int nRow, BOOL bResetScroll=TRUE) 自動(dòng)調(diào)整行的大小與最大行一樣. 如果bResetScroll是 TRUE那么滾動(dòng)條也會(huì)被重置。
BOOL AutoSizeColumn(int nCol, UINT nAutoSizeStyle = GVS_DEFAULT, BOOL bResetScroll = TRUE) 自動(dòng)調(diào)整列的大小與最大列一樣. NAutoSizeStyle設(shè)置了調(diào)整的方式(參考 AutoSizing options). 如果bResetScroll是TRUE那么滾動(dòng)條將會(huì)被重置.
void AutoSizeRows() 自動(dòng)調(diào)整所有行的大小。
void AutoSizeColumns(UINT nAutoSizeStyle=GVS_DEFAULT) 自動(dòng)調(diào)整所有列的大小. nAutoSizeStyle 設(shè)置了調(diào)整的方式(參考AutoSizing options)
void AutoSize(UINT nAutoSizeStyle = GVS_DEFAULT) 自動(dòng)調(diào)整所有行和列的大小. nAutoSizeStyle設(shè)置了調(diào)整的方式(參考 AutoSizing options)
void ExpandColumnsToFit(BOOL bExpandFixed=TRUE) 為添滿Grid區(qū)域,擴(kuò)大列寬.如果 bExpandFixed是TRUE固定列也會(huì)調(diào)整, 否則不受影響.
void ExpandLastColumn() 調(diào)整最后一列的寬度以添滿grid區(qū)域.
void ExpandRowsToFit(BOOL bExpandFixed=TRUE) 為添滿Grid區(qū)域,擴(kuò)大行高. 如果 bExpandFixed是TRUE固定行也會(huì)調(diào)整, 否則不受影響.
void ExpandToFit(BOOL bExpandFixed = TRUE) 為添滿Grid區(qū)域,擴(kuò)大行高和列寬. 如果 bExpandFixed是TRUE固定單元格也會(huì)調(diào)整, 否則不受影響.<
CSize GetTextExtent(int nRow, int nCol, LPCTSTR str) 獲取指定單元格中由str指定的文本大小。
CSize GetCellTextExtent(int nRow, int nCol) 獲取指定單元格的文本大小。
void SetRedraw(BOOL bAllowDraw, BOOL bResetScrollBars = FALSE) 在行或列數(shù)量改變或者自動(dòng)調(diào)整大小的時(shí)候關(guān)閉/啟動(dòng)重畫(huà)功能,但對(duì)用戶的動(dòng)作如重新調(diào)整大小不起作用。
BOOL RedrawCell(int nRow, int nCol, CDC* pDC = NULL) 重畫(huà)指定單元格。如果提供了pDC則通過(guò)它來(lái)描畫(huà)。
BOOL RedrawCell(const CCellID& cell, CDC* pDC = NULL) 重畫(huà)指定單元格。如果提供了pDC則通過(guò)它來(lái)描畫(huà)。
BOOL RedrawRow(int row) 重畫(huà)指定行.
BOOL RedrawColumn(int col) 重畫(huà)指定列
BOOL Refresh() 重畫(huà)整個(gè)Grid.
CCellRange GetCellRange() 獲取整個(gè)Grid中的單元格的范圍. 可參考 CCellRange.
void SetSelectedRange(const CCellRange& Range, BOOL bForceRepaint = FALSE); 設(shè)置選定單元格的范圍. 可參考 CCellRange.
void SetSelectedRange(int nMinRow, int nMinCol, int nMaxRow, int nMaxCol, BOOL bForceRepaint = FALSE); 設(shè)置選定單元格的范圍.
BOOL IsValid(int nRow, int nCol) 如果指定行和列有效,則返回TRUE.
BOOL IsValid(const CCellID& cell) 如果指定單元格有效,則返回TRUE.
BOOL IsValid(const CCellRange& range) 如果指定單元格范圍有效,則返回TRUE.
CCellID GetNextItem(CCellID& cell, int nFlags) const 查找具有特定屬性并且和指定內(nèi)容有特定關(guān)系的單元格. (也可參考 CListCtrl::GetNextItem 和Cell Searching options)</P><P>排序操作
void SetHeaderSort(BOOL bSortOnClick = TRUE) 設(shè)置在ListMode下,點(diǎn)擊列標(biāo)題頭時(shí),是否對(duì)行進(jìn)行排序.
BOOL GetHeaderSort() 判斷在ListMode下,點(diǎn)擊列標(biāo)題頭時(shí),是否對(duì)行進(jìn)行排序.
SetSortColumn(int nCol 設(shè)置當(dāng)前已排序列的索引。
int GetSortColumn() 獲取當(dāng)前已排序列的索引。
void SetSortAscending(BOOL bAscending) 設(shè)置當(dāng)前排序列是否按升序排序。
BOOL GetSortAscending() 判斷當(dāng)前排序列是否按升序排序。
BOOL SortTextItems(int nCol, BOOL bAscending, LPARAM data = 0) 根據(jù)單元格文本內(nèi)容對(duì)指定列排序. 成功則返回TRUE.
BOOL SortItems(int nCol, BOOL bAscending, LPARAM data = 0) 使用比較函數(shù)在指定列進(jìn)行排序.如果沒(méi)有指定函數(shù),則對(duì)行按文本進(jìn)行排序.成功則返回TRUE.可參考SetCompareFunction()
void SetCompareFunction(PFNLVCOMPARE pfnCompare) 設(shè)置對(duì)進(jìn)行排序的回調(diào)函數(shù). 可從下面的到更多的細(xì)節(jié)。
BOOL SortItems(PFNLVCOMPARE pfnCompare, int nCol, BOOL bAscending, LPARAM data = 0) 使用比較函數(shù)pfnCompare在指定的列進(jìn)行排序.從函數(shù)CListCtrl::SortItems中可以尋求一些關(guān)于這個(gè)函數(shù)的形式的信息成功則返回TRUE.
排序是通過(guò)使用變量SortItems, SortTextItems中的一個(gè)或者在listmode下點(diǎn)擊列標(biāo)題頭來(lái)實(shí)現(xiàn)。
注意:在虛擬模式下不能進(jìn)行排序。這是因?yàn)樵谔摂M模式下,Grid不能存儲(chǔ)單元格中的任何信息,因此,也就不能存儲(chǔ)任何對(duì)單元格進(jìn)行排序的信息。
處理排序的最簡(jiǎn)單方法是先設(shè)置單元格的比較函數(shù)(調(diào)用SetCompareFunction),接著調(diào)用SortItems(int nCol, BOOL bAscending, LPARAM data = 0)。nCol是要排序的列,bAscending設(shè)置是按升序還是按降序排序,data是應(yīng)用中將要傳遞給比較函數(shù)的的一個(gè)特殊數(shù)據(jù)。
比較函數(shù)必須是一個(gè)全局或靜態(tài)函數(shù),其格式如下:
int CALLBACK pfnCellCompare(LPARAM lParam1, LPARAM lParam2, LPARAM lParamSort)
lParam1和 lParam2是CGridCellBase的指針,而lParamSort就是應(yīng)用中作為參數(shù)變量傳遞給函數(shù)SortItems的特殊數(shù)據(jù)。如果第一個(gè)單元格的值小于第二個(gè)單元格的值,函數(shù)返回-1,相等返回0,否則返回1。
下面就是一個(gè)排序比較函數(shù)的例子:
int CALLBACK MyClass::pfnCellNumericCompare(LPARAM lParam1,
LPARAM lParam2,
LPARAM lParamSort)
{
CGridCellBase* pCell1 = (CGridCellBase*) lParam1;
CGridCellBase* pCell2 = (CGridCellBase*) lParam2;
if (!pCell1 || !pCell2) return 0;</P><P>int nValue1 = _ttol(pCell1->GetText());
int nValue2 = _ttol(pCell2->GetText());</P><P>if (nValue1 < nValue2)
return -1;
else if (nValue1 == nValue2)
return 0;
else
return 1;
}
還提供了兩個(gè)有用的函數(shù):
int CALLBACK CGridCtrl::pfnCellTextCompare(LPARAM lParam1,
LPARAM lParam2,
LPARAM lParamSort)
int CALLBACK CGridCtrl::pfnCellNumericCompare(LPARAM lParam1,
LPARAM lParam2,
LPARAM lParamSort)
這兩個(gè)函數(shù)是通過(guò)文本內(nèi)容和數(shù)值進(jìn)行排序的(分別使用itoa)。為Grid設(shè)置比較函數(shù),僅僅需要調(diào)用:
m_Grid.SetCompareFunction(CGridCtrl::pfnCellNumericCompare);
如果這個(gè)比較函數(shù)設(shè)置為空,那么將默認(rèn)調(diào)用函數(shù)CGridCtrl::pfnCellTextCompare</P><P>打印
void EnableWysiwygPrinting(BOOL bEnable = TRUE) 設(shè)置WYSIWYG 打印
BOOL GetWysiwygPrinting() 如果設(shè)置了WYSIWYG打印則返回TRUE。
void Print() 在用戶選擇的設(shè)備上打印G rid (控件在對(duì)話框中有用)
virtual void OnBeginPrinting(CDC *pDC, CPrintInfo *pInfo) 用于文檔/瀏覽環(huán)境下,在 CView dervied class' OnBeginPrinting中調(diào)用
virtual void OnPrint(CDC *pDC, CPrintInfo *pInfo) 用于文檔/瀏覽環(huán)境下. 在CView dervied class' OnPrint中調(diào)用
virtual void OnEndPrinting(CDC *pDC, CPrintInfo *pInfo) 用于文檔/瀏覽環(huán)境下. 在CView dervied class' OnEndPrinting中調(diào)用。
void SetShadedPrintOut(BOOL bEnable = TRUE) 如果為TRUE,則近似打印彩色單元格。如果為FALSE ,則所有文本按照白紙黑字的形式打印出來(lái)。.
BOOL GetShadedPrintOut() 判斷單元格是否陰影或近似打印。.
void SetPrintMarginInfo(int nHeaderHeight, int nFooterHeight, int nLeftMargin, int nRightMargin, int nTopMargin, int nBottomMargin, int nGap) 設(shè)置打印邊緣信息。.
void GetPrintMarginInfo(int &nHeaderHeight, int &nFooterHeight, int &nLeftMargin, int &nRightMargin, int &nTopMargin, int &nBottomMargin, int &nGap) 獲取打印邊緣信息.</P><P>結(jié)構(gòu)、定義和消息
CGridCellBase類(lèi)
這個(gè)類(lèi)是所有Grid單元格類(lèi)的基類(lèi),包含有每個(gè)單元格的信息。同時(shí),它還定義了大量的方法供Grid調(diào)用,例如畫(huà)圖和打印。幾乎所有的方法和函數(shù)都是虛擬模式,類(lèi)本身不能直接使用--只能被引用。作為Grid控件的默認(rèn)單元格類(lèi)CGridCell就是基于CGridCellBase的。
屬性
virtual void SetText(LPCTSTR szText);
virtual void SetImage(int nImage);
virtual void SetData(LPARAM lParam);
virtual void SetState(DWORD nState);
virtual void SetFormat(DWORD nFormat);
virtual void SetTextClr(COLORREF clr);
virtual void SetBackClr(COLORREF clr);
virtual void SetFont(const LOGFONT* plf);
virtual void SetGrid(CGridCtrl* pGrid);
virtual void SetCoords(int nRow, int nColumn);
virtual void SetMargin(UINT nMargin);</P><P>virtual LPCTSTR GetText() const // 返回單元格的文本內(nèi)容
virtual LPCTSTR GetTipText() const // 根據(jù)意愿返回標(biāo)題提示文本
virtual int GetImage() const // 返回單元格的圖形索引
virtual LPARAM GetData() const // 返回單元格的關(guān)聯(lián)數(shù)據(jù)
virtual DWORD GetState() const // 返回單元格的狀態(tài)
virtual DWORD GetFormat() const // 返回單元格的格式
virtual COLORREF GetTextClr() const // 返回單元格文本顏色
virtual COLORREF GetBackClr() const // 返回單元格背景顏色
virtual LOGFONT* GetFont() const // 以LOGFONT的形式返回單元格的字體
virtual CFont* GetFontObject() const // 將單元格的字體返回成Cfont對(duì)象
virtual UINT GetMargin() const // returns internal margin for cell
virtual CGridCtrl* GetGrid() const // 返回與單元格關(guān)聯(lián)的Grid
virtual CWnd* GetEditWnd() const // 返回NULL或單元格的編輯窗口</P><P>virtual BOOL IsEditing() const
virtual BOOL IsFocused() const
virtual BOOL IsFixed() const
virtual BOOL IsFixedCol() const
virtual BOOL IsFixedRow() const
virtual BOOL IsSelected() const
virtual BOOL IsReadOnly() const
virtual BOOL IsModified() const
virtual BOOL IsDropHighlighted() const
virtual BOOL IsDefaultFont() const // 如果單元格使用的是默認(rèn)字體,返回TRUE</P><P>virtual CGridCellBase* GetDefaultCell() const;
操作符
virtual void operator=(CGridCellBase& cell);</P><P>操作
virtual void Reset();</P><P>virtual BOOL Draw(CDC* pDC, int nRow, int nCol, CRect rect,
BOOL bEraseBkgnd = TRUE);
virtual BOOL GetTextRect( LPRECT pRect) - 單元格內(nèi)部文本框
virtual BOOL GetTipTextRect( LPRECT pRect) - 工具提示的邊框
virtual CSize GetTextExtent(LPCTSTR str) -文本大小
virtual CSize GetCellExtent(CDC* pDC) - 單元格大小</P><P>// 開(kāi)啟和終止對(duì)單元格的編輯
virtual BOOL Edit(int nRow, int nCol, CRect rect,
CPoint point, UINT nID, UINT nChar)
virtual void EndEdit()</P><P>// 確認(rèn)編輯的結(jié)果.如果"str"不是一個(gè)有效的值,那么返回FALSE并且編輯無(wú)效
virtual BOOL ValidateEdit(LPCTSTR str);</P><P>virtual BOOL PrintCell(CDC* pDC, int nRow, int nCol, CRect rect);</P><P>//僅僅只能被基類(lèi)CgridCellBase調(diào)用而不是CgridCellBase本身.
LRESULT SendMessageToParent(int nRow, int nCol, int nMessage);</P><P>重載
virtual void OnEndEdit();
virtual void OnMouseEnter();
virtual void OnMouseOver();
virtual void OnMouseLeave();
virtual void OnClick( CPoint PointCellRelative);
virtual void OnClickDown( CPoint PointCellRelative);
virtual void OnRClick( CPoint PointCellRelative);
virtual void OnDblClick( CPoint PointCellRelative);
virtual BOOL OnSetCursor();</P><P>重載使得制作普通單元格變的極為簡(jiǎn)單。為創(chuàng)建自己的單元格類(lèi),既可以重載CGridCtrl::CreateCell也可以創(chuàng)建自己的源于CGridCellBase的單元格,或者使用CGridCtrl::SetCellType 和 CGridCtrl::SetDeafaultCellType自動(dòng)產(chǎn)生。
僅僅需要?jiǎng)?chuàng)建一個(gè)源于CGridCellBase 或CGridCell (如CMyGridCell)的新單元格類(lèi),然后在Grid中調(diào)用如下函數(shù)代替原來(lái)的單元格就可以了。
MyGrid.SetCellType(row, column, RUNTIME_CLASS(CMyGridCell));
現(xiàn)在的單元格(行、列)就是CMyGridCell類(lèi)型的</P><P>CGridCell類(lèi)
這個(gè)類(lèi)起源于CGridCellBase并且提供一個(gè)使用CGridCtrl的默認(rèn)實(shí)現(xiàn)。</P><P>CcellID類(lèi)
這是一個(gè)用來(lái)參考個(gè)別單元格的便利的輔助類(lèi)。所有的成員都是公共的。這個(gè)類(lèi)是根據(jù)Joe Willcoxsons的最初實(shí)現(xiàn)改寫(xiě)的。
class CCellID
{
public:
int row, col; // 基于0的單元格的行和列.</P><P>CCellID(int nRow = -1, int nCol = -1)</P><P>int IsValid();
int operator==(const CCellID& rhs);
int operator!=(const CCellID& rhs);
}</P><P>CCellRange類(lèi)
這是一個(gè)用來(lái)參考單元格范圍的便利的輔助類(lèi)。這是一個(gè)從Joe Willcoxsons最初實(shí)現(xiàn)改寫(xiě)的類(lèi)。
class CCellRange
{
public:
CCellRange(int nMinRow = -1, int nMinCol = -1,
int nMaxRow = -1, int nMaxCol = -1);
void Set(int nMinRow = -1, int nMinCol = -1,
int nMaxRow = -1, int nMaxCol = -1);</P><P>int IsValid() const;
int InRange(int row, int col) const; // 判斷行/列是否在范圍之內(nèi)
int InRange(const CCellID& cellID) const; // 判斷單元格是否在范圍之內(nèi)</P><P>CCellID GetTopLeft() const; //取出左上角單元格
CCellRange Intersect(const CCellRange& rhs) const;
//返回兩個(gè)區(qū)域的交集</P><P>int GetMinRow() const; // 下面的容易理解
void SetMinRow(int minRow);
int GetMinCol() const;
void SetMinCol(int minCol);
int GetMaxRow() const;
void SetMaxRow(int maxRow);
int GetMaxCol() const;
void SetMaxCol(int maxCol);</P><P>int GetRowSpan() const; // 行的跨度
int GetColSpan() const; // 列的跨度</P><P>void operator=(const CCellRange& rhs);
int operator==(const CCellRange& rhs);
int operator!=(const CCellRange& rhs);
}</P><P>結(jié)構(gòu)體GV_ITEM,它在調(diào)用Get/SetItem時(shí)使用]
typedef struct _GV_ITEM {
int row,col; //對(duì)象的行和列
UINT mask; // 用于設(shè)置/獲取單元格數(shù)據(jù)的一種掩碼
UINT state; //單元格狀態(tài) (如焦點(diǎn)/突出顯示)
UINT nFormat; //單元格格式.默認(rèn)使用CDC::DrawText格式
CString szText; // 單元格的文本
int iImage; // 系列可視對(duì)象圖標(biāo)的索引
COLORREF crBkClr; // 背景顏色 (或者 CLR_DEFAULT)
COLORREF crFgClr; // 前景顏色(或者 CLR_DEFAULT)
LPARAM lParam; // 與對(duì)象有聯(lián)系的32位值
LOGFONT lfFont; // 單元格的字體
} GV_ITEM;</P><P>網(wǎng)格線或者滾動(dòng)條的選擇
GVL_NONE // 無(wú)網(wǎng)格線
GVL_HORZ // 僅僅有水平網(wǎng)格線
GVL_VERT //僅僅有垂直網(wǎng)格線
GVL_BOTH // 水平和垂直網(wǎng)格線都有</P><P>
自動(dòng)調(diào)整大小選項(xiàng)
GVS_DEFAULT //默認(rèn)
GVS_HEADER //僅用于列的固定單元格數(shù)據(jù)
GVS_DATA //僅用于列的非固定單元格數(shù)據(jù)
GVS_BOTH // 固定列和非固定列都適用</P><P>單元格數(shù)掩碼
GVIF_TEXT // 存取單元格文本
GVIF_IMAGE // 存取單元格圖片數(shù)量
GVIF_PARAM // 存取單元格用戶數(shù)據(jù)(lParam)
GVIF_STATE // 存取單元格狀態(tài)
GVIF_BKCLR //存取單元格背景顏色
GVIF_FGCLR // 存取單元格前景顏色
GVIF_FORMAT // 存取單元格格式
GVIF_FONT // 存取單元格邏輯字體
GVIF_MARGIN // 存取單元格邊緣信息
GVIF_ALL // 存取所有信息 </P><P>
單元格狀態(tài)
GVIS_FOCUSED // 單元格成為焦點(diǎn)
GVIS_SELECTED // 選擇單元格
GVIS_DROPHILITED // Cell is drop highlighted
GVIS_READONLY // 設(shè)置只讀,不能編輯
GVIS_FIXED // 單元格鎖定
GVIS_FIXEDROW // 單元格是鎖定行的一部分
GVIS_FIXEDCOL //單元格是鎖定列的一部分
GVIS_MODIFIED // 單元格被修改過(guò)</P><P>
單元格查找選項(xiàng)
GVNI_FOCUSED //查找焦點(diǎn)單元格
GVNI_SELECTED // 查找已選單元格
GVNI_DROPHILITED // Search for drop highlighted cells
GVNI_READONLY // 查找只讀單元格
GVNI_FIXED // 查找鎖定單元格
GVNI_MODIFIED // 查找修改過(guò)的單元格</P><P>GVNI_ABOVE // 在初始單元格上方查找
GVNI_BELOW //在初始單元格下方查找
GVNI_TOLEFT // 向左查找初始單元格
GVNI_TORIGHT //向右查找初始單元格
GVNI_ALL // 從指定單元格開(kāi)始查找全部單元格
GVNI_AREA // 從指定單元格右下方查找單元格</P><P>
通知消息
GVN_BEGINDRAG // 拖曳發(fā)生時(shí)發(fā)送
GVN_BEGINLABELEDIT // 定位編輯開(kāi)始時(shí)發(fā)送
GVN_ENDLABELEDIT //定位編輯停止時(shí)發(fā)送
GVN_SELCHANGING // 單元格選擇改變之前發(fā)送
GVN_SELCHANGED // 單元格選擇改變之后發(fā)送
GVN_GETDISPINFO //當(dāng)Grid處在虛擬模式下的一個(gè)單元格信息請(qǐng)求
GVN_ODCACHEHINT // 虛擬模式下的隱藏提示
當(dāng)不使用NM_GRIDVIEW機(jī)構(gòu)體時(shí),這些消息就很象它們的LVN_...副本
typedef struct tagNM_GRIDVIEW {
NMHDR hdr;
int iRow;
int iColumn;
} NM_GRIDVIEW;</P><P>Protect類(lèi)型的重載函數(shù)
這些函數(shù)作成虛擬的以便于擴(kuò)展。
Printing - 在OnPrint事件中調(diào)用.
virtual void PrintColumnHeadings(CDC *pDC, CPrintInfo *pInfo);
virtual void PrintHeader(CDC *pDC, CPrintInfo *pInfo);
virtual void PrintFooter(CDC *pDC, CPrintInfo *pInfo);
virtual void PrintRowButtons(CDC *pDC, CPrintInfo* pInfo);
Drag n' drop
//雖然沒(méi)什么必要,但是我覺(jué)得這些代碼很酷,所以還是保留了。:).
virtual CImageList* CreateDragImage(CPoint *pHotSpot)
Mouse Clicks
virtual void OnFixedColumnClick(CCellID& cell);
virtual void OnFixedRowClick(CCellID& cell);
Editing
//開(kāi)始編輯
virtual void OnEditCell(int nRow, int nCol, CPoint point,
UINT nChar)
// 結(jié)束編輯
virtual void OnEndEditCell(int nRow, int nCol, CString str)
//創(chuàng)建定位編輯控件
virtual void CreateInPlaceEditControl(CRect& rect, DWORD dwStyle,
int nRow, int nCol,
LPCTSTR szText, int nChar)
Drawing
virtual void OnDraw(CDC& origDC); //畫(huà)任何東西
Construction and Cleanup
//創(chuàng)建一個(gè)新的單元格并初始化.
virtual CGridCellBase* CreateCell(int nRow, int nCol)</P><P>// 刪除一個(gè)單元格并作必要的清除工作
virtual void DestroyCell(int nRow, int nCol)</P><P>剪貼板
其中還還包含了很多剪貼板函數(shù)
virtual void OnEditCut() 將所選單元格內(nèi)容拷貝到剪貼板,并刪除單元格中的響應(yīng)內(nèi)容. (Ctrl-X)
virtual void OnEditCopy() 將所選單元格內(nèi)容拷貝到剪貼板 (Ctrl-C)
virtual void OnEditPaste() 將剪貼板中的內(nèi)容粘貼到Grid中. (Ctrl-V)
virtual void OnEditSelectAll() 雖然不是一個(gè)真正的剪貼板函數(shù),但會(huì)經(jīng)常用到. 這個(gè)程序全選Grid中的單元格 (Ctrl-A)</P><P>單元格的編輯和確認(rèn)
控制單元格是否可以編輯,或者是否保存或放棄修改的方法有好幾種。
最簡(jiǎn)單的方法就是使用SetEditable(BOOL)。這個(gè)函數(shù)決定了Grid中的單元格是否可以編輯。可以通過(guò)在特定單元格中使用GVIS_READONLY來(lái)實(shí)現(xiàn)更好的控制。
int row = 1;
int col = 10;
m_Grid.SetItemState(row,col, m_Grid.GetItemState(row,col) | GVIS_READONLY);
深層的控制可以通過(guò)處理GVN_BEGINLABELEDIT消息來(lái)實(shí)現(xiàn)。如果消息的返回值小于0,那么試圖對(duì)指定單元格所做的修改將被取消同時(shí),這個(gè)單元格將被看作是只讀屬性的。當(dāng)每次試圖編輯某一個(gè)單元格時(shí)都會(huì)發(fā)送一個(gè)這種消息。
為處理這個(gè)消息,需要在主窗口中增加一個(gè)句柄:
BEGIN_MESSAGE_MAP(CGridCtrlDemoDlg, CDialog)
...
// 增加句柄
ON_NOTIFY(GVN_ENDLABELEDIT, IDC_GRID, OnGridEndEdit)
END_MESSAGE_MAP()</P><P>...</P><P>// GVN_ENDLABELEDIT
void CGridCtrlDemoDlg::OnGridStartEdit(NMHDR *pNotifyStruct,
LRESULT* pResult)
{
NM_GRIDVIEW* pItem = (NM_GRIDVIEW*) pNotifyStruct;</P><P>// 如果你允許對(duì)單元格進(jìn)行編輯,那么虛構(gòu)函數(shù)AllowCellToBeEdited將返回TRUE
BOOL bAllowEdit = AllowCellToBeEdited(pItem->iRow, pItem->iColumn);</P><P>*pResult = (bAllowEdit)? 0 : -1;
}
可以通過(guò)相同的方法處理GVN_ENDLABELEDIT消息來(lái)實(shí)現(xiàn)是保存還是放棄對(duì)單元格的編輯行為。
// GVN_ENDLABELEDIT
void CGridCtrlDemoDlg::OnGridEndEdit(NMHDR *pNotifyStruct,
LRESULT* pResult)
{
NM_GRIDVIEW* pItem = (NM_GRIDVIEW*) pNotifyStruct;</P><P>// 如果你想保存對(duì)單元格的修改,那么虛構(gòu)函數(shù)AcceptChange將返回TRUE
BOOL bAcceptChange = AcceptChange(pItem->iRow, pItem->iColumn);</P><P>*pResult = (bAcceptChange)? 0 : -1;
}
你所能用的最終的確認(rèn)方法是源于CGridCellBase類(lèi),并重載ValidateEdit方法的。如果它返回的是TRUE,那么表示保存修改,否則表示放棄修改。</P><P>聲名
如果沒(méi)有下面這些作者的免費(fèi)代碼,這些工作將不會(huì)成功。
Joe Willcoxson:我的工作依賴(lài)于 Joe的原始代碼,它提供了這個(gè)控件的基本結(jié)構(gòu)。
Keith Rule:Keith有一個(gè)很靈巧的類(lèi)CMemDC,它能很容易的處理閃爍顯示工作。他還提供了copy/paste/drag/drop對(duì)象源代碼。
Ravi Reddy:我使用了Ravi的一個(gè)列表瀏覽打印代碼。
Zafir Anjum:他為我提供了CInPlaceEdit的切入點(diǎn),并且提供了排序程序和標(biāo)題提示的源代碼。
Eric Woodruff, Brian V. Shifrin, Scot Reed, Aqiruse, Ken Bertelson, Martin Daly幫助我把控件升級(jí)到2.X版本--還有很多在以前版本中提供幫助的人。