📄 gridctrl.h
字号:
#pragma once
#include "AdvComboBox.h"
#include <vector>
#include <deque>
#define G_BKGND 0xC9DBC8
#define G_GHEAD_CLR 0x9EC29B
#define G_IHEAD_CLR 0xACC2AB
#define G_EDIT_RDNL_CLR 0xE7EEE7
/////// Grid style ////////////////////
#define GS_AUTOVSIZE 0x01
/////// Layout style /////////
#define GLS_NR 0x000000
#define GLS_NC 0x010000
#define GIL_MASK 0xff0000
/////// Grid edit style //////////////
#define GES_PASS 0x1
#define GES_NUMB 0x2
#define GES_MASK 0xf
/////// Grid combo style /////////////
#define GCS_DRDNL 0x0
#define GCS_DRDN 0x1
#define GCS_MASK 0xf
/////// Grid custom style ////////////
#define GCSS_CSBT 0x0100
#define GCSS_MASK 0xff00
/////// Grid shared style ////////////
#define GSS_RDNL 0x10000000
#define GSS_MASK 0xff000000
///////////// Grid edit //////////////////////
class CGEdit : public CEdit{
DECLARE_DYNAMIC(CGEdit)
public:
CGEdit();
virtual ~CGEdit();
CBrush m_bkBrush;
protected:
DECLARE_MESSAGE_MAP()
virtual BOOL PreCreateWindow(CREATESTRUCT& cs);
public:
BOOL SetReadOnly(bool bReadOnly=true);
afx_msg void OnEnable(BOOL bEnable);
afx_msg void OnNcPaint();
afx_msg HBRUSH CtlColor(CDC* pDC, UINT nCtlColor);
};
//////////// Grid static //////////////////////
class CGStatic : public CStatic{
DECLARE_DYNAMIC(CGStatic)
public:
CGStatic();
virtual ~CGStatic();
protected:
DECLARE_MESSAGE_MAP()
protected:
virtual LRESULT WindowProc(UINT message, WPARAM wParam, LPARAM lParam);
};
/////////////////////
enum GI_TYPE{
GI_HEADER,
GI_EDIT,
GI_COMBO
};
struct grid_item{
const char* m_pcName;
DWORD m_dwStyle;
DWORD m_dwID;
void* m_pvData;
GI_TYPE m_giType;
grid_item(const char* pcName,DWORD dwStyle,DWORD dwID,void* pvData,GI_TYPE giType):
m_pcName(pcName),m_dwStyle(dwStyle),m_dwID(dwID),m_pvData(pvData),m_giType(giType){
}
};
#ifndef GI_CONSTR_TYPE
#define GI_CONSTR_TYPE 0x01
#endif
struct gi_hdr:public grid_item{
#if GI_CONSTR_TYPE==0x00
gi_hdr(const char* pcName=0,DWORD dwStyle=0,DWORD dwID=-1,void* pvData=0):grid_item(pcName,dwStyle,dwID,pvData,GI_HEADER){}
#else if GI_CONSTR_TYPE==0x01
gi_hdr(const char* pcName=0,void* pvData=0,DWORD dwStyle=0,DWORD dwID=-1):grid_item(pcName,dwStyle,dwID,pvData,GI_HEADER){}
#endif
};
struct gi_edit:public grid_item{
#if GI_CONSTR_TYPE==0x00
gi_edit(const char* pcName,DWORD dwStyle=0,DWORD dwID=-1,void* pvData=0):grid_item(pcName,dwStyle,dwID,pvData,GI_EDIT){}
#else if GI_CONSTR_TYPE==0x01
gi_edit(const char* pcName,void* pvData=0,DWORD dwStyle=0,DWORD dwID=-1):grid_item(pcName,dwStyle,dwID,pvData,GI_EDIT){}
#endif
};
struct gi_combo:public grid_item{
#if GI_CONSTR_TYPE==0x00
gi_combo(const char* pcName,DWORD dwStyle=0,DWORD dwID=-1,void* pvData=0):grid_item(pcName,dwStyle,dwID,pvData,GI_COMBO){}
#else if GI_CONSTR_TYPE==0x01
gi_combo(const char* pcName,void* pvData=0,DWORD dwStyle=0,DWORD dwID=-1):grid_item(pcName,dwStyle,dwID,pvData,GI_COMBO){}
#endif
};
#define GI_GHEAD_ID 0xfffffffe
#define GI_IHEAD_ID 0xfffffffd
#define GITEM_HEIGHT 16
#define GITEM_X_SEP 2
#define GITEM_Y_SEP 1
#define GHDR_X_SEP 5
#define GHDR_Y_SEP 5
template<class THeader>
struct SGHeader{
THeader* m_pHdr;
const GI_TYPE m_giType;
DWORD m_dwStyle;
DWORD m_dwID;
void* m_pvData;
SGHeader(CWnd* pParent,grid_item& gi):
m_pHdr(0),m_giType(gi.m_giType),m_dwStyle(gi.m_dwStyle),m_dwID(gi.m_dwID),m_pvData(gi.m_pvData){
if(m_giType==GI_HEADER&&!gi.m_pcName)return;
else{
m_pHdr=new THeader;
m_pHdr->Create(CString(" ")+gi.m_pcName,WS_VISIBLE|WS_CHILD|WS_CLIPCHILDREN|WS_CLIPSIBLINGS|SS_CENTERIMAGE|SS_ENDELLIPSIS,
CRect(0,0,0,0),pParent,m_giType==GI_HEADER?GI_GHEAD_ID:GI_IHEAD_ID);
}
}
virtual ~SGHeader(){
delete m_pHdr;
}
void SetFont(CFont& rFont){
if(m_pHdr)m_pHdr->SetFont(&rFont);
}
void SetName(const char* pcName){
if(m_pHdr)m_pHdr->SetWindowText(pcName);
}
CString GetName(){
CString strName;
if(m_pHdr)m_pHdr->GetWindowText(strName);
return strName;
}
};
template<class TCombo>
class CSubItemMgr{
TCombo* m_pCombo;
public:
CSubItemMgr(TCombo* pCombo):m_pCombo(pCombo){}
public:
void Insert(const char* pcText,LPARAM lData=-1,int nIndex=-1){m_pCombo->SetItemData(m_pCombo->InsertString(nIndex,pcText),(DWORD)lData);}
void Delete(int nIndex=-1){
if(nIndex==-1)m_pCombo->ResetContent();
else m_pCombo->DeleteString(nIndex);
}
int Find(const char* pcText){
return m_pCombo->FindString(-1,pcText);
}
int Find(LPARAM lData){
const int nCount(Count);
for(int i=0;i<nCount;i++)if(m_pCombo->GetItemData(i)==lData)return i;
return -1;
}
__declspec(property(get=get_Count))int Count;
int get_Count(){return m_pCombo->GetCount();}
__declspec(property(put=put_Select,get=get_Select))int Select;
void put_Select(int nIndex){m_pCombo->SetCurSel(nIndex);}
int get_Select(){return m_pCombo->GetCurSel();}
__declspec(property(get=get_Text))CString Text[];
CString get_Text(){return m_pCombo->GetStyle()&CBS_DROPDOWNLIST?m_pCombo->GetLBText(Select):m_pCombo->GetText(Select);}
CString get_Text(int nIndex){return m_pCombo->GetStyle()&CBS_DROPDOWNLIST?m_pCombo->GetLBText(nIndex):m_pCombo->GetText(nIndex);}
__declspec(property(get=get_Data))LPARAM Data[];
LPARAM get_Data(){return m_pCombo->GetItemData(Select);}
LPARAM get_Data(int nIndex){return m_pCombo->GetItemData(nIndex);}
};
template<class THeader,class TEdit,class TCombo,class TCstmBtn=CButton>
struct SGItem:public SGHeader<THeader>{
CWnd* m_pCtrl;
TCstmBtn* m_pCstmBtn;
CSubItemMgr<TCombo>* m_pSubItemMgr;
SGItem(CWnd* pParent,grid_item& gi,const int& rnXSprt):SGHeader<THeader>(pParent,gi),m_rnXSprt(rnXSprt),m_pCstmBtn(0),m_pSubItemMgr(0){
DWORD dwStyle(WS_VISIBLE|WS_CHILD|WS_TABSTOP|WS_CLIPCHILDREN|WS_CLIPSIBLINGS);
if((m_dwStyle&GCSS_MASK)==GCSS_CSBT){
m_pCstmBtn=new TCstmBtn;
m_pCstmBtn->Create("...",dwStyle,CRect(0,0,0,0),pParent,m_dwID);
if((m_dwStyle&GSS_MASK)&GSS_RDNL)m_pCstmBtn->EnableWindow(0);
}
if(gi.m_giType==GI_EDIT){
dwStyle|=ES_AUTOHSCROLL;
if((m_dwStyle&GSS_MASK)&GSS_RDNL)dwStyle|=ES_READONLY;
if((m_dwStyle&GES_MASK)&GES_NUMB)dwStyle|=ES_NUMBER;
if((m_dwStyle&GES_MASK)&GES_PASS)dwStyle|=ES_PASSWORD;
m_pCtrl=new TEdit;
static_cast<TEdit*>(m_pCtrl)->Create(dwStyle,CRect(0,0,0,0),pParent,m_dwID);
}else if(gi.m_giType==GI_COMBO){
if((m_dwStyle&GCS_MASK)==GCS_DRDNL)dwStyle|=CBS_DROPDOWNLIST;
else if((m_dwStyle&GCS_MASK)==GCS_DRDN)dwStyle|=CBS_DROPDOWN|CBS_AUTOHSCROLL;
m_pCtrl=new TCombo;
static_cast<TCombo*>(m_pCtrl)->Create(dwStyle,CRect(0,0,0,0),pParent,m_dwID);
if((m_dwStyle&GSS_MASK)&GSS_RDNL)static_cast<TCombo*>(m_pCtrl)->EnableWindow(0);
m_pSubItemMgr=new CSubItemMgr<TCombo>(static_cast<TCombo*>(m_pCtrl));
}else ASSERT(false);
}
virtual ~SGItem(){
if(m_giType==GI_EDIT)delete static_cast<TEdit*>(m_pCtrl);
else if(m_giType==GI_COMBO)delete static_cast<TCombo*>(m_pCtrl);
delete m_pCstmBtn;
delete m_pSubItemMgr;
}
const int& m_rnXSprt;
RECT m_rct;
virtual void Recalc(){
m_rct.bottom=m_rct.top+GITEM_HEIGHT;
m_pHdr->MoveWindow(CRect(m_rct.left,m_rct.top,m_rct.left+m_rnXSprt,m_rct.bottom));
m_pHdr->Invalidate();
m_pCtrl->MoveWindow(CRect(m_rct.left+m_rnXSprt+GITEM_X_SEP,m_rct.top,m_rct.right-(m_pCstmBtn?GITEM_HEIGHT:0),m_rct.bottom));
if(m_pCstmBtn)m_pCstmBtn->MoveWindow(CRect(m_rct.right-GITEM_HEIGHT,m_rct.top,m_rct.right,m_rct.bottom));
m_rct.bottom+=GITEM_Y_SEP;
}
void SetFont(CFont& rFont){
SGHeader<THeader>::SetFont(rFont);
m_pCtrl->SetFont(&rFont);
if(m_pCstmBtn)m_pCstmBtn->SetFont(&rFont);
}
void SetText(const char* pcText){
if(m_giType==GI_EDIT)static_cast<TEdit*>(m_pCtrl)->SetWindowText(pcText);
else if(m_giType==GI_COMBO){
if((m_dwStyle&GCS_MASK)==GCS_DRDNL)static_cast<TCombo*>(m_pCtrl)->SelectString(0,pcText);
else
static_cast<TCombo*>(m_pCtrl)->SetText(pcText);
}
}
CString GetText(){
CString strText;
if(m_giType==GI_EDIT)static_cast<TEdit*>(m_pCtrl)->GetWindowText(strText);
else if(m_giType==GI_COMBO){
if((m_dwStyle&GCS_MASK)==GCS_DRDNL)static_cast<TCombo*>(m_pCtrl)->GetLBText(static_cast<TCombo*>(m_pCtrl)->GetCurSel(),strText);
else static_cast<TCombo*>(m_pCtrl)->GetText(strText);
}
return strText;
}
void SetReadOnly(bool bReadOnly){
if(m_giType==GI_EDIT)static_cast<TEdit*>(m_pCtrl)->SetReadOnly(bReadOnly);
else if(m_giType==GI_COMBO){
static_cast<TCombo*>(m_pCtrl)->EnableWindow(!bReadOnly);
}
if(bReadOnly)m_dwStyle|=GSS_RDNL;
else m_dwStyle&=(-1^GSS_RDNL);
}
};
template<class TObj>
struct SObjImpl{
RECT m_rct;
std::deque<TObj*> m_ObjCnt;
typedef class std::deque<TObj*>::iterator ObjItr;
virtual ~SObjImpl(){
ObjItr itr(m_ObjCnt.begin());
while(itr!=m_ObjCnt.end())delete *itr++;
m_ObjCnt.clear();
}
virtual void Recalc()=0;
};
template<class TObj>
struct SColImpl:public SObjImpl<TObj>{
typedef struct SColImpl<TObj> _ThisObj;
void Recalc(){
m_rct.bottom=m_rct.top;
for(ObjItr itr=m_ObjCnt.begin();itr!=m_ObjCnt.end();itr++){
(*itr)->m_rct.top=m_rct.bottom;
(*itr)->m_rct.left=m_rct.left;
(*itr)->m_rct.right=m_rct.right;
(*itr)->Recalc();
if((*itr)->m_rct.bottom>m_rct.bottom)m_rct.bottom=(*itr)->m_rct.bottom;
}
}
};
template<class TObj>
struct SRowImpl:public SObjImpl<TObj>{
typedef struct SRowImpl<TObj> _ThisObj;
virtual void Recalc(){
m_rct.bottom=m_rct.top;
if(!m_ObjCnt.size())return;
double dWidthObj(double(m_rct.right-m_rct.left+GHDR_X_SEP)/m_ObjCnt.size()-GHDR_X_SEP);
double dXPos(m_rct.left);
for(ObjItr itr=m_ObjCnt.begin();itr!=m_ObjCnt.end();itr++){
(*itr)->m_rct.top=m_rct.top;
(*itr)->m_rct.left=(int)dXPos;
dXPos+=dWidthObj;
(*itr)->m_rct.right=(long)dXPos;
(*itr)->Recalc();
if((*itr)->m_rct.bottom>m_rct.bottom)m_rct.bottom=(*itr)->m_rct.bottom;
dXPos+=GHDR_X_SEP;
}
}
};
struct SItemCol:public SColImpl<SGItem<CGStatic,CGEdit,CAdvComboBox> >{
int m_nXSprtPercent;
int m_nXSprtPixel;
virtual void Recalc(){
m_nXSprtPixel=int(double(m_rct.right-m_rct.left)/100.*m_nXSprtPercent);
_ThisObj::Recalc();
m_rct.bottom+=GHDR_Y_SEP;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -