3926 lines
88 KiB
C++
3926 lines
88 KiB
C++
#include "..\stdafx.h"
|
||
#include "..\resource.h"
|
||
#include "earthwormdef.h"
|
||
#include <afxcmn.h> // MFC support for Windows Common Controls
|
||
#include "WDGrid.h"
|
||
#include "TListQuene.h"
|
||
#include "TDualPtrList.h"
|
||
|
||
namespace
|
||
{
|
||
int ACmpLabel(const char* sLabel1, const char* sLabel2)
|
||
{
|
||
TAString s1(sLabel1), s2(sLabel2);
|
||
TAString sName1(s1.Length()), sName2(s2.Length());
|
||
TAString sDigit1(s1.Length()), sDigit2(s2.Length());
|
||
|
||
long len1 = s1.Length();
|
||
for (long i = 0; i<len1; i++)
|
||
{
|
||
char c = s1.GetAt(i);
|
||
if (c >= '0'&&c <= '9')
|
||
{//数字
|
||
sDigit1 << c;
|
||
}
|
||
else
|
||
{//字符
|
||
sName1 << c;
|
||
if (c<0)
|
||
{//汉字占两位
|
||
sName1 << s1[++i];
|
||
}
|
||
}
|
||
}
|
||
|
||
long len2 = s2.Length();
|
||
for (i = 0; i<len2; i++)
|
||
{
|
||
char c = s2.GetAt(i);
|
||
if (c >= '0'&&c <= '9')
|
||
{//数字
|
||
sDigit2 << c;
|
||
}
|
||
else//字符
|
||
{
|
||
sName2 << c;
|
||
if (c<0)
|
||
{//汉字占两位
|
||
sName2 << s2[++i];
|
||
}
|
||
}
|
||
}
|
||
int iRet = strcmp(sName1, sName2);
|
||
if (iRet<0)
|
||
{
|
||
return -1;
|
||
}
|
||
else if (iRet>0)
|
||
{
|
||
return 1;
|
||
}
|
||
else
|
||
{
|
||
int num1 = atoi(sDigit1), num2 = atoi(sDigit2);
|
||
if (num1<num2)
|
||
{
|
||
return -1;
|
||
}
|
||
else if (num1>num2)
|
||
{
|
||
return 1;
|
||
}
|
||
else
|
||
{
|
||
return 0;
|
||
}
|
||
}
|
||
}
|
||
|
||
int UCmpLabel(const wchar_t* sLabel1, const wchar_t* sLabel2)
|
||
{
|
||
TUString s1(sLabel1), s2(sLabel2);
|
||
TUString sName1(s1.Length()), sName2(s2.Length());
|
||
TUString sDigit1(s1.Length()), sDigit2(s2.Length());
|
||
|
||
long len1 = s1.Length();
|
||
for (long i = 0; i<len1; i++)
|
||
{
|
||
wchar_t c = s1.GetAt(i);
|
||
if (c >= '0'&&c <= '9')
|
||
{//数字
|
||
sDigit1 << c;
|
||
}
|
||
else//字符
|
||
{
|
||
sName1 << c;
|
||
if (c<0)
|
||
{//汉字占两位
|
||
sName1 << s1[++i];
|
||
}
|
||
}
|
||
}
|
||
|
||
long len2 = s2.Length();
|
||
for (i = 0; i<len2; i++)
|
||
{
|
||
wchar_t c = s2.GetAt(i);
|
||
if (c >= '0'&&c <= '9')
|
||
{//数字
|
||
sDigit2 << c;
|
||
}
|
||
else//字符
|
||
{
|
||
sName2 << c;
|
||
if (c<0)
|
||
{//汉字占两位
|
||
sName2 << s2[++i];
|
||
}
|
||
}
|
||
}
|
||
int iRet = wcscmp(sName1, sName2);
|
||
if (iRet<0)
|
||
{
|
||
return -1;
|
||
}
|
||
else if (iRet>0)
|
||
{
|
||
return 1;
|
||
}
|
||
else
|
||
{
|
||
int num1 = _wtoi(sDigit1), num2 = _wtoi(sDigit2);
|
||
if (num1<num2)
|
||
{
|
||
return -1;
|
||
}
|
||
else if (num1>num2)
|
||
{
|
||
return 1;
|
||
}
|
||
else
|
||
{
|
||
return 0;
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
/////////////////////////////////////////////////////////////////////////////////////////////////
|
||
// WDGridRow
|
||
WDGridRow::WDGridRow(WDGrid &parent):grid(parent),style(0),index(-1),pData(NULL)//ok
|
||
{
|
||
for(int i=0;i<parent.GetColNum();i++)
|
||
AppendCol(parent.GetCol(i));
|
||
}
|
||
void WDGridRow::SetExtendData(WRowData*p)//ok
|
||
{
|
||
if(pData!=NULL)
|
||
DELETE_PTR(pData);
|
||
pData=p;
|
||
}
|
||
WDGridRow::~WDGridRow()//ok
|
||
{
|
||
if(pData!=NULL)
|
||
DELETE_PTR(pData);
|
||
}
|
||
//未使用默认函数,因index不需要相同
|
||
WDGridRow& WDGridRow::operator =(WDGridRow&row)//ok
|
||
{
|
||
style=row.style;
|
||
for(long i=0;i<grid.GetColNum();i++)
|
||
*(cellList[i])=row[i];
|
||
return *this;
|
||
}
|
||
void WDGridRow::InsertCol(long i,WDGridCol&col)//ok
|
||
{
|
||
WDGridCell*pCell=new WDGridCell(grid,*this,col);
|
||
cellList.Insert(i,pCell);
|
||
}
|
||
void WDGridRow::AppendCol(WDGridCol&col)//ok
|
||
{
|
||
WDGridCell*pCell=new WDGridCell(grid,*this,col);
|
||
cellList.AddTail(pCell);
|
||
}
|
||
void WDGridRow::Refresh()//ok
|
||
{
|
||
if(!grid.IsValidWnd())
|
||
return;
|
||
if(!grid.OnRefresh(*this))
|
||
return;
|
||
for(cellList.MoveToFirst();!cellList.IsOut();cellList.MoveToNext())
|
||
cellList.GetCurData()->Refresh();
|
||
}
|
||
void WDGridRow::Select(bool bSel)//ok
|
||
{
|
||
if(!grid.IsValidWnd())
|
||
return;
|
||
CDC&dc=grid.GetDC();
|
||
CRect rect;
|
||
GetRect(rect);
|
||
dc.InvertRect(&rect);
|
||
}
|
||
|
||
bool WDGridRow::operator <(WDGridRow&row)//ok
|
||
{
|
||
if(!IsParentRow()&&row.IsParentRow())
|
||
return false;
|
||
else if(IsParentRow()&&!row.IsParentRow())
|
||
return true;
|
||
|
||
if(grid.IsLabelSort())
|
||
{
|
||
if(!grid.keyList.IsEmpty())
|
||
{
|
||
TList<long>&kList=grid.keyList;
|
||
for(kList.MoveToFirst();!kList.IsOut();kList.MoveToNext())
|
||
{
|
||
long i=kList.GetCurData();
|
||
int cmp=CmpLabel((*this)[i].GetText(),row[i]);
|
||
if(cmp>0)
|
||
return false;
|
||
else if(cmp<0)
|
||
return true;
|
||
}
|
||
return false;
|
||
}
|
||
TList<long>&kList=grid.colSelList;
|
||
for(kList.MoveToFirst();!kList.IsOut();kList.MoveToNext())
|
||
{
|
||
long i=kList.GetCurData();
|
||
int cmp=CmpLabel((*this)[i].GetText(),row[i]);
|
||
if(cmp>0)
|
||
return false;
|
||
else if(cmp<0)
|
||
return true;
|
||
}
|
||
}
|
||
else
|
||
{
|
||
if(!grid.keyList.IsEmpty())
|
||
{
|
||
TList<long>&kList=grid.keyList;
|
||
for(kList.MoveToFirst();!kList.IsOut();kList.MoveToNext())
|
||
{
|
||
long i=kList.GetCurData();
|
||
int cmp=(*this)[i].GetText()-row[i];
|
||
if(cmp>0)
|
||
return false;
|
||
else if(cmp<0)
|
||
return true;
|
||
}
|
||
return false;
|
||
}
|
||
TList<long>&kList=grid.colSelList;
|
||
for(kList.MoveToFirst();!kList.IsOut();kList.MoveToNext())
|
||
{
|
||
long i=kList.GetCurData();
|
||
int cmp=(*this)[i].GetText()-row[i];
|
||
if(cmp>0)
|
||
return false;
|
||
else if(cmp<0)
|
||
return true;
|
||
}
|
||
}
|
||
return false;
|
||
}
|
||
bool WDGridRow::operator >(WDGridRow&row)//ok
|
||
{
|
||
if(!IsParentRow()&&row.IsParentRow())
|
||
return true;
|
||
else if(IsParentRow()&&!row.IsParentRow())
|
||
return false;
|
||
|
||
if(grid.IsLabelSort())
|
||
{
|
||
if(!grid.keyList.IsEmpty())
|
||
{
|
||
TList<long>&kList=grid.keyList;
|
||
for(kList.MoveToFirst();!kList.IsOut();kList.MoveToNext())
|
||
{
|
||
long i=kList.GetCurData();
|
||
int cmp=CmpLabel((*this)[i].GetText(),row[i]);
|
||
if(cmp<0)
|
||
return false;
|
||
else if(cmp>0)
|
||
return true;
|
||
}
|
||
return false;
|
||
}
|
||
TList<long>&kList=grid.colSelList;
|
||
for(kList.MoveToFirst();!kList.IsOut();kList.MoveToNext())
|
||
{
|
||
long i=kList.GetCurData();
|
||
int cmp=CmpLabel((*this)[i].GetText(),row[i]);
|
||
if(cmp<0)
|
||
return false;
|
||
else if(cmp>0)
|
||
return true;
|
||
}
|
||
}
|
||
else
|
||
{
|
||
if(!grid.keyList.IsEmpty())
|
||
{
|
||
TList<long>&kList=grid.keyList;
|
||
for(kList.MoveToFirst();!kList.IsOut();kList.MoveToNext())
|
||
{
|
||
long i=kList.GetCurData();
|
||
int cmp=(*this)[i].GetText()-row[i];
|
||
if(cmp<0)
|
||
return false;
|
||
else if(cmp>0)
|
||
return true;
|
||
}
|
||
return false;
|
||
}
|
||
TList<long>&kList=grid.colSelList;
|
||
for(kList.MoveToFirst();!kList.IsOut();kList.MoveToNext())
|
||
{
|
||
long i=kList.GetCurData();
|
||
int cmp=(*this)[i].GetText()-row[i];
|
||
if(cmp<0)
|
||
return false;
|
||
else if(cmp>0)
|
||
return true;
|
||
}
|
||
}
|
||
return false;
|
||
}
|
||
//////////////////////////////////////////////////////////////////////////////////////////////
|
||
WDGridTreeRow::WDGridTreeRow(WDGrid&grid):WDGridRow(grid),pParent(NULL)//ok
|
||
{
|
||
}
|
||
WDGridTreeRow::WDGridTreeRow(WDGridTreeRow*parent):WDGridRow(parent->grid),pParent(parent)//ok
|
||
{
|
||
}
|
||
WDGridTreeRow& WDGridTreeRow::operator =(WDGridTreeRow&row)//ok
|
||
{
|
||
WDGridRow::operator =(row);
|
||
for(long i=0;i<row.GetChildNum();i++)
|
||
{
|
||
WDGridTreeRow*pRow=new WDGridTreeRow(grid);
|
||
*pRow=row.GetChild(i);
|
||
AppendChild(pRow);
|
||
}
|
||
return *this;
|
||
}
|
||
void WDGridTreeRow::operator<<(WDGridTreeRow&row)//ok
|
||
{
|
||
WDGridRow::operator =(row);
|
||
SetExtendData(row.pData);
|
||
row.pData=NULL;
|
||
for(long i=0;i<row.GetChildNum();i++)
|
||
{
|
||
WDGridTreeRow*pRow=new WDGridTreeRow(grid);
|
||
*pRow<<row.GetChild(i);
|
||
AppendChild(pRow);
|
||
}
|
||
}
|
||
void WDGridTreeRow::InsertCol(long i,WDGridCol&col)//ok
|
||
{
|
||
WDGridRow::InsertCol(i,col);
|
||
for(childRow.MoveToFirst();!childRow.IsOut();childRow.MoveToNext())
|
||
childRow.GetCurData()->InsertCol(i,col);
|
||
}
|
||
void WDGridTreeRow::AppendCol(WDGridCol&col)//ok
|
||
{
|
||
WDGridRow::AppendCol(col);
|
||
for(childRow.MoveToFirst();!childRow.IsOut();childRow.MoveToNext())
|
||
childRow.GetCurData()->AppendCol(col);
|
||
}
|
||
void WDGridTreeRow::DelCol(long i)//ok
|
||
{
|
||
WDGridRow::DelCol(i);
|
||
for(childRow.MoveToFirst();!childRow.IsOut();childRow.MoveToNext())
|
||
childRow.GetCurData()->DelCol(i);
|
||
}
|
||
void WDGridTreeRow::MoveCol(long from,long to)//ok
|
||
{
|
||
WDGridRow::MoveCol(from,to);
|
||
for(childRow.MoveToFirst();!childRow.IsOut();childRow.MoveToNext())
|
||
childRow.GetCurData()->MoveCol(from,to);
|
||
}
|
||
WDGridTreeRow* WDGridTreeRow::RootRow()//ok
|
||
{
|
||
WDGridTreeRow* p=this;
|
||
while(p->IsChildRow())
|
||
p=p->Parent();
|
||
return p;
|
||
}
|
||
void WDGridTreeRow::InsertChild(long i,WDGridTreeRow*pRow)//ok
|
||
{//无限制插入(i正确时)
|
||
if(pRow==NULL)
|
||
pRow=new WDGridTreeRow(grid);
|
||
else
|
||
pRow->SetIndex(-1);
|
||
pRow->SetParent(this);
|
||
childRow.Insert(i,pRow);
|
||
if(IsVisible())
|
||
{
|
||
if(!IsFold())//子行可见
|
||
{
|
||
grid.InsertRow(GetGlobalChildIndex(i),pRow);
|
||
if(!pRow->IsFold())
|
||
pRow->UnFold();
|
||
}
|
||
else if(GetChildNum()==1)
|
||
Refresh();//显示父方块标志
|
||
}
|
||
}
|
||
void WDGridTreeRow::DelChild(long i)//ok
|
||
{//无限制删除(i正确时)
|
||
bool bChildVisible=IsChildVisible();
|
||
if(bChildVisible)//子行可见
|
||
{
|
||
childRow[i]->Fold();//将后代从GRID中取回
|
||
grid.SelectRow(childRow[i]->GetIndex(),false);
|
||
grid.rowList[childRow[i]->GetIndex()]=NULL;
|
||
grid.DelRow(childRow[i]->GetIndex());
|
||
}
|
||
childRow.Del(i);
|
||
if(!bChildVisible&&IsVisible()&&childRow.IsEmpty())//子行已空
|
||
Refresh();//不再显示父方块标志
|
||
}
|
||
void WDGridTreeRow::Fold()//ok
|
||
{//无限制调用
|
||
if(!IsParentRow())//无子行
|
||
{
|
||
SetUnFoldFlag(false);
|
||
return;
|
||
}
|
||
|
||
long oldCur=grid.GetCur();
|
||
if(IsChildVisible())
|
||
for(long i=1;i<GetRowNum();i++)
|
||
{//从GRID中取回所有后代,不改变其展开标志,使下次展开时可以恢复原展开状态
|
||
long nextRow=1+GetIndex();
|
||
grid.rowList[nextRow]->SetIndex(-1);//设不可见标志
|
||
grid.SelectRow(nextRow,false);
|
||
grid.rowList[nextRow]=NULL;
|
||
grid.DelRow(nextRow);
|
||
}
|
||
grid.MoveTo(oldCur);
|
||
SetUnFoldFlag(false);
|
||
}
|
||
void WDGridTreeRow::UnFold()//ok
|
||
{//无限制调用
|
||
if(!IsParentRow())//无子行
|
||
{
|
||
SetUnFoldFlag();
|
||
return;
|
||
}
|
||
long oldCur=grid.GetCur();
|
||
if(IsVisible()&&!IsChildVisible())
|
||
{
|
||
//将子行插入GRID
|
||
for(childRow.MoveToFirst();!childRow.IsOut();childRow.MoveToNext())
|
||
grid.InsertRow(GetIndex()+childRow.GetCur()+1,childRow.GetCurData());
|
||
//恢复后代的历史展开状态
|
||
for(childRow.MoveToFirst();!childRow.IsOut();childRow.MoveToNext())
|
||
if(!childRow.GetCurData()->IsFold())
|
||
childRow.GetCurData()->UnFold();
|
||
}
|
||
grid.MoveTo(oldCur);
|
||
SetUnFoldFlag();
|
||
}
|
||
void WDGridTreeRow::UnFoldAll()//ok
|
||
{
|
||
UnFold();
|
||
for(childRow.MoveToFirst();!childRow.IsOut();childRow.MoveToNext())
|
||
childRow.GetCurData()->UnFoldAll();
|
||
}
|
||
void WDGridTreeRow::FoldAll()//ok
|
||
{
|
||
Fold();
|
||
for(childRow.MoveToFirst();!childRow.IsOut();childRow.MoveToNext())
|
||
childRow.GetCurData()->FoldAll();
|
||
}
|
||
void WDGridTreeRow::ArrangeChild(bool bIncrease)//ok
|
||
{
|
||
if(!IsParentRow())
|
||
return;
|
||
childRow.Arrange(bIncrease);
|
||
for(childRow.MoveToFirst();!childRow.IsOut();childRow.MoveToNext())
|
||
childRow.GetCurData()->ArrangeChild(bIncrease);
|
||
}
|
||
long WDGridTreeRow::GetParentNum()//ok
|
||
{
|
||
return IsChildRow()?pParent->GetParentNum()+1:0;
|
||
}
|
||
void WDGridTreeRow::ClearChild()//ok
|
||
{
|
||
if(!IsParentRow())
|
||
return;
|
||
Fold();
|
||
childRow.Clear();
|
||
}
|
||
long WDGridTreeRow::GetOffspringNum()//ok
|
||
{
|
||
long oldCur=childRow.GetCur();
|
||
long num=GetChildNum();
|
||
for(childRow.MoveToFirst();!childRow.IsOut();childRow.MoveToNext())
|
||
num+=childRow.GetCurData()->GetOffspringNum();
|
||
childRow.MoveTo(oldCur);
|
||
return num;
|
||
}
|
||
long WDGridTreeRow::GetRowNum()//ok
|
||
{
|
||
long oldCur=childRow.GetCur();
|
||
long num=1;
|
||
if(!IsFold())
|
||
for(childRow.MoveToFirst();!childRow.IsOut();childRow.MoveToNext())
|
||
num+=childRow.GetCurData()->GetRowNum();
|
||
childRow.MoveTo(oldCur);
|
||
return num;
|
||
}
|
||
long WDGridTreeRow::GetChildIndex(WDGridTreeRow*pRow)//ok
|
||
{
|
||
long oldCur=childRow.GetCur();
|
||
long res=-1;
|
||
for(childRow.MoveToFirst();!childRow.IsOut();childRow.MoveToNext())
|
||
if(childRow.GetCurData()==pRow)
|
||
{
|
||
res=childRow.GetCur();
|
||
break;
|
||
}
|
||
childRow.MoveTo(oldCur);
|
||
return res;
|
||
}
|
||
long WDGridTreeRow::GetGlobalChildIndex(long i)//ok
|
||
{
|
||
long oldCur=childRow.GetCur();
|
||
long rowNum=1;
|
||
for(childRow.MoveToFirst();childRow.GetCur()<i;childRow.MoveToNext())
|
||
rowNum+=childRow.GetCurData()->GetRowNum();
|
||
childRow.MoveTo(oldCur);
|
||
return GetIndex()+rowNum;
|
||
}
|
||
void WDGridTreeRow::GetTreeQuad(CRect&rect)//ok
|
||
{
|
||
if(!IsParentRow())
|
||
return;
|
||
long oldCur=cellList.GetCur();
|
||
cellList[0]->GetRect(rect);
|
||
cellList.MoveTo(oldCur);
|
||
rect.top+=2;
|
||
rect.left+=2;
|
||
rect.left+=GetParentNum()*(grid.GetRowHeight()-3);
|
||
rect.right=rect.left+grid.GetRowHeight()-3;
|
||
rect.bottom-=1;
|
||
}
|
||
bool WDGridTreeRow::FindAndSel(const TCHAR*s,long iCol)//ok
|
||
{
|
||
for(childRow.MoveToFirst();!childRow.IsOut();childRow.MoveToNext())
|
||
{
|
||
WDGridTreeRow*pRow=childRow.GetCurData();
|
||
if(_tcscmp((*pRow)[iCol],s)==0)
|
||
{
|
||
WDGridTreeRow*pRow0=pRow->pParent;
|
||
while(pRow0!=NULL)
|
||
{
|
||
pRow0->UnFold();
|
||
pRow0=pRow0->pParent;
|
||
}
|
||
grid.UnSelect();
|
||
grid.SelectRow(pRow->GetIndex(),true);
|
||
return true;
|
||
}
|
||
else if(pRow->FindAndSel(s,iCol))
|
||
return true;
|
||
}
|
||
return false;
|
||
}
|
||
///////////////////////////////////////////////////////////////////////////////////////////////
|
||
//WDGridCol
|
||
WDGridCol::WDGridCol(const TCHAR *n,WDGrid &parent)//ok
|
||
:grid(parent),name(n),style(0),backColor(RGB(255,255,255)),textColor(RGB(0,0,0))
|
||
{
|
||
brush.CreateSolidBrush(backColor);
|
||
}
|
||
void WDGridCol::Select(bool bSel)//ok
|
||
{
|
||
if(!grid.IsValidWnd())
|
||
return;
|
||
CDC&dc=grid.GetDC();
|
||
CRect rect;
|
||
GetRect(rect);
|
||
dc.InvertRect(&rect);
|
||
}
|
||
////////////////////////////////////////////////////////////////////////////////////////////////
|
||
//WDGridCell
|
||
WDGridCell::WDGridCell(WDGrid&g,WDGridRow&r,WDGridCol&c):grid(g),row(r),col(c),style(0)//ok
|
||
{
|
||
}
|
||
WDGridCell& WDGridCell::operator =(WDGridCell&cell)//ok
|
||
{
|
||
style=cell.style;
|
||
text=cell.GetText();
|
||
return *this;
|
||
}
|
||
void WDGridCell::Refresh()//ok
|
||
{
|
||
if(!grid.IsValidWnd())
|
||
return;
|
||
if(!grid.OnRefresh(*this))
|
||
return;
|
||
CDC&dc=grid.GetDC();
|
||
grid.OnBeforeRefresh(*this);
|
||
|
||
CRect rect;
|
||
GetRect(rect);
|
||
rect.bottom++;
|
||
rect.right++;
|
||
dc.Rectangle(&rect);
|
||
GetTextRect(rect);
|
||
dc.FillSolidRect(&rect,dc.GetBkColor());
|
||
if(GetColIndex()==0)
|
||
{
|
||
if(row.IsParentRow())
|
||
{
|
||
WDGridTreeRow&treeRow=(WDGridTreeRow&)row;
|
||
CRect quad;
|
||
treeRow.GetTreeQuad(quad);
|
||
rect.left=quad.right;
|
||
dc.Rectangle(&quad);
|
||
CPoint pt=quad.CenterPoint();
|
||
if(treeRow.IsFold())
|
||
{
|
||
dc.MoveTo(quad.left+2,pt.y);
|
||
dc.LineTo(quad.right-2,pt.y);
|
||
dc.MoveTo(pt.x,quad.top+2);
|
||
dc.LineTo(pt.x,quad.bottom-2);
|
||
}
|
||
else
|
||
{
|
||
dc.MoveTo(quad.left+2,pt.y);
|
||
dc.LineTo(quad.right-2,pt.y);
|
||
if(grid.IsNeedTreeLine())
|
||
{
|
||
dc.MoveTo(pt.x,quad.bottom);
|
||
dc.LineTo(pt.x,rect.bottom);
|
||
}
|
||
}
|
||
}
|
||
if(row.IsChildRow())
|
||
{
|
||
WDGridTreeRow&treeRow=(WDGridTreeRow&)row;
|
||
CRect quad;
|
||
WDGridTreeRow &parentRow = treeRow.GetParent();
|
||
parentRow.GetTreeQuad(quad);
|
||
if(!treeRow.IsParentRow())
|
||
rect.left=quad.right+quad.Width();
|
||
if(grid.IsNeedTreeLine())
|
||
{
|
||
CPoint pt=quad.CenterPoint();
|
||
dc.MoveTo(pt.x,rect.top);
|
||
dc.LineTo(pt.x,rect.CenterPoint().y);
|
||
if(treeRow.IsParentRow())
|
||
dc.LineTo(quad.right,rect.CenterPoint().y);
|
||
else
|
||
dc.LineTo(quad.right+quad.Width()/2,rect.CenterPoint().y);
|
||
if(&(parentRow.GetLastChild())!=&treeRow)
|
||
{
|
||
dc.MoveTo(pt.x,rect.CenterPoint().y);
|
||
dc.LineTo(pt.x,rect.bottom);
|
||
}
|
||
WDGridTreeRow *pChild=&(treeRow.GetParent());
|
||
while(pChild && pChild->IsChildRow())
|
||
{
|
||
WDGridTreeRow*pParent=&(pChild->GetParent());
|
||
if(pChild!=&(pParent->GetLastChild()))
|
||
{
|
||
pParent->GetTreeQuad(quad);
|
||
CPoint pt=quad.CenterPoint();
|
||
dc.MoveTo(pt.x,rect.top);
|
||
dc.LineTo(pt.x,rect.bottom);
|
||
}
|
||
pChild=pParent;
|
||
}
|
||
}
|
||
}
|
||
}
|
||
rect.left+=2;//首字符与左边界间隔2象素。
|
||
rect.top+=grid.GetRowSpace();//行与上边界的间隔
|
||
int style;
|
||
if(GetCol().IsCenterAlign())
|
||
style=DT_TOP|DT_CENTER|DT_SINGLELINE|DT_EDITCONTROL;
|
||
else
|
||
style=DT_TOP|DT_LEFT|DT_SINGLELINE|DT_EDITCONTROL;
|
||
dc.DrawText((const TCHAR*)text,&rect,style);
|
||
}
|
||
void WDGridCell::Select(bool bSel)//ok
|
||
{
|
||
if(!grid.IsValidWnd())
|
||
return;
|
||
CDC&dc=grid.GetDC();
|
||
CRect rect;
|
||
GetRect(rect);
|
||
dc.InvertRect(&rect);
|
||
}
|
||
//////////////////////////////////////////////////////////////////////////////////////////////
|
||
//WDGrid
|
||
IMPLEMENT_DYNAMIC(WDGrid, CWnd)
|
||
WDGrid::WDGrid(bool bTree,long colWidth)//ok
|
||
:bTreeGrid(bTree),defaultWidth(colWidth),style(0),
|
||
pDC(NULL),pen(0,1,RGB(168,168,168)),bHScroll(false),bVScroll(false),rowSpace(3),
|
||
pSelCell(NULL),pCurEdit(NULL),pSelCell2(NULL),
|
||
pRowSelector(NULL),pColSelector(NULL),pActiveQuad(NULL),m_pAppendRow(NULL),
|
||
m_iCurCol(-1),m_iCurRow(-1),m_bModified(false)
|
||
{
|
||
brush.CreateSolidBrush(RGB(255,255,255));
|
||
}
|
||
WDGrid::~WDGrid()//ok
|
||
{
|
||
if(IsTreeGrid())
|
||
//将所有根行折叠,使所有子行的析构权由父行行使
|
||
for(rowList.MoveToFirst();!rowList.IsOut();rowList.MoveToNext())
|
||
{
|
||
WDGridTreeRow*pTreeRow=(WDGridTreeRow*)rowList.GetCurData();
|
||
if(pTreeRow && pTreeRow->IsParentRow())
|
||
pTreeRow->Fold();
|
||
}
|
||
if(pActiveQuad!=NULL)
|
||
DELETE_PTR(pActiveQuad);
|
||
if(pRowSelector!=NULL)
|
||
DELETE_PTR(pRowSelector);
|
||
if(pColSelector!=NULL)
|
||
DELETE_PTR(pColSelector);
|
||
if(pDC!=NULL)
|
||
DELETE_PTR(pDC);
|
||
if(m_pAppendRow!=NULL)
|
||
DELETE_PTR(m_pAppendRow);
|
||
}
|
||
void WDGrid::Clear()//ok
|
||
{
|
||
ClearSel();
|
||
if(IsTreeGrid())
|
||
//将所有根行折叠,使所有子行的析构权由父行行使
|
||
for(rowList.MoveToFirst();!rowList.IsOut();rowList.MoveToNext())
|
||
{
|
||
WDGridTreeRow*pTreeRow=(WDGridTreeRow*)rowList.GetCurData();
|
||
if(pTreeRow && pTreeRow->IsParentRow())
|
||
pTreeRow->Fold();
|
||
}
|
||
rowList.Clear();
|
||
RecalcLayout();
|
||
}
|
||
void WDGrid::InsertRow(long i,WDGridRow*pR)//ok
|
||
{//插入行的基操作,不能用之直接插入子行
|
||
EndEditCell();
|
||
WDGridRow*pRow=pR;
|
||
if(pRow==NULL)
|
||
{
|
||
if(IsTreeGrid())
|
||
pRow=new WDGridTreeRow(*this);
|
||
else
|
||
pRow=new WDGridRow(*this);
|
||
}
|
||
|
||
|
||
pRow->SetIndex(i);
|
||
rowList.MoveTo(i);
|
||
rowList.InsertCur(pRow);
|
||
//新插入行后的行索引需要加1
|
||
for(rowList.MoveTo(i+1);!rowList.IsOut();rowList.MoveToNext())
|
||
{
|
||
WDGridRow &row=*rowList.GetCurData();
|
||
row.SetIndex(row.GetIndex()+1);
|
||
}
|
||
//保持原先行选定内容
|
||
for(rowSelList.MoveToLast();!rowSelList.IsOut();rowSelList.MoveToPre())
|
||
{
|
||
if(rowSelList.GetCurData()>=i)
|
||
rowSelList.SetCurData(rowSelList.GetCurData()+1);
|
||
else
|
||
break;
|
||
}
|
||
RecalcLayout();
|
||
}
|
||
void WDGrid::AppendRow(WDGridRow*pR)//ok
|
||
{
|
||
EndEditCell();
|
||
WDGridRow*pRow=pR;
|
||
if(pRow==NULL)
|
||
{
|
||
if(IsTreeGrid())
|
||
pRow=new WDGridTreeRow(*this);
|
||
else
|
||
pRow=new WDGridRow(*this);
|
||
}
|
||
|
||
rowList.AddTail(pRow);
|
||
pRow->SetIndex(rowList.GetCur());
|
||
RecalcLayout();
|
||
}
|
||
void WDGrid::DelRow(long i)//ok
|
||
{//删行基操作,不能用来删除子行或展开根行
|
||
EndEditCell();
|
||
SelectRow(i,false);//确认当前行未选定
|
||
rowList.Del(i);
|
||
//后行索引需要减1
|
||
for(rowList.MoveTo(i);!rowList.IsOut();rowList.MoveToNext())
|
||
{
|
||
WDGridRow &row=*rowList.GetCurData();
|
||
row.SetIndex(row.GetIndex()-1);
|
||
}
|
||
//保持原先行选定内容
|
||
for(rowSelList.MoveToLast();!rowSelList.IsOut();rowSelList.MoveToPre())
|
||
{
|
||
if(rowSelList.GetCurData()>i)
|
||
rowSelList.SetCurData(rowSelList.GetCurData()-1);
|
||
else
|
||
break;
|
||
}
|
||
RecalcLayout();
|
||
}
|
||
void WDGrid::MoveRow(long from,long to)//ok
|
||
{
|
||
if(from==to||from==to-1)
|
||
return;
|
||
rowList.Move(from,to);
|
||
//重新建立索引
|
||
long count=0;
|
||
for(rowList.MoveToFirst();!rowList.IsOut();rowList.MoveToNext(),count++)
|
||
rowList.GetCurData()->SetIndex(count);
|
||
Invalidate();
|
||
}
|
||
void WDGrid::DelRowEx(long i)//ok
|
||
{//删除一般行或树行
|
||
WDGridTreeRow&curRow=(WDGridTreeRow&)GetRow(i);
|
||
if(!curRow.IsChildRow()&&!curRow.IsParentRow())//不是子行或父行
|
||
DelRow(i);
|
||
else if(curRow.IsChildRow())//子行交由父行删除
|
||
{
|
||
WDGridTreeRow&parentRow=curRow.GetParent();
|
||
parentRow.DelChild(parentRow.GetChildIndex(&curRow));
|
||
}
|
||
else//根行折叠后删除
|
||
{
|
||
curRow.Fold();
|
||
DelRow(i);
|
||
}
|
||
}
|
||
void WDGrid::InsertCol(long i,WDGridCol*pCol,long width)//ok
|
||
{
|
||
EndEditCell();
|
||
if(width==0)
|
||
width=defaultWidth;
|
||
if(pCol==NULL)
|
||
pCol=new WDGridCol(NULL,*this);
|
||
if(IsColEmpty())
|
||
pCol->SetLeft(GetLeft());
|
||
else if(i==GetColNum())
|
||
pCol->SetLeft(GetRight());
|
||
else
|
||
pCol->SetLeft(GetCol(i).GetLeft());
|
||
pCol->SetRight(pCol->GetLeft()+width);
|
||
pCol->SetIndex(i);
|
||
colList.Insert(i,pCol);
|
||
//移动后续列位置和索引加1
|
||
for(colList.MoveTo(i+1);!colList.IsOut();colList.MoveToNext())
|
||
{
|
||
WDGridCol&col=*colList.GetCurData();
|
||
col.Move(width);
|
||
col.SetIndex(col.GetIndex()+1);
|
||
}
|
||
//所有行插入新列,子行的插入由父行执行
|
||
for(rowList.MoveToFirst();!rowList.IsOut();rowList.MoveToNext())
|
||
if(!rowList.GetCurData()->IsChildRow())
|
||
rowList.GetCurData()->InsertCol(i,*pCol);
|
||
//保持原列选定
|
||
for(colSelList.MoveToLast();!colList.IsOut();colList.MoveToPre())
|
||
{
|
||
if(colSelList.GetCurData()>=i)
|
||
colSelList.SetCurData(colSelList.GetCurData()+1);
|
||
else
|
||
break;
|
||
}
|
||
RecalcLayout();
|
||
}
|
||
void WDGrid::InsertCol(long i,const TCHAR*name,long width)//ok
|
||
{
|
||
InsertCol(i,new WDGridCol(name,*this),width);
|
||
}
|
||
void WDGrid::AppendCol(WDGridCol*pCol,long width)//ok
|
||
{
|
||
EndEditCell();
|
||
if(width==0)
|
||
width=defaultWidth;
|
||
if(pCol==NULL)
|
||
pCol=new WDGridCol(NULL,*this);
|
||
pCol->SetLeft(GetRight());
|
||
pCol->SetRight(pCol->GetLeft()+width);
|
||
pCol->SetIndex(GetColNum());
|
||
colList.AddTail(pCol);
|
||
//所有行加新列,子行的插入由父行执行
|
||
for(rowList.MoveToFirst();!rowList.IsOut();rowList.MoveToNext())
|
||
if(!rowList.GetCurData()->IsChildRow())
|
||
rowList.GetCurData()->AppendCol(*pCol);
|
||
RecalcLayout();
|
||
}
|
||
void WDGrid::AppendCol(const TCHAR*name,long width)//ok
|
||
{
|
||
AppendCol(new WDGridCol(name,*this),width);
|
||
}
|
||
void WDGrid::MoveCol(long from,long to)//ok
|
||
{
|
||
if(from==to||from==to-1)
|
||
return;
|
||
long cx=colList[from]->GetWidth();
|
||
int pos;
|
||
if(from>to)
|
||
{
|
||
colList[from]->SetLeft(pos=colList[to]->GetLeft());
|
||
colList[from]->SetRight(pos+cx);
|
||
for(colList.MoveTo(to);!colList.IsOut()&&colList.GetCur()<from;colList.MoveToNext())
|
||
colList.GetCurData()->Move(cx);
|
||
}
|
||
else
|
||
{
|
||
colList[from]->SetRight(pos=colList[to-1]->GetRight());
|
||
colList[from]->SetLeft(pos-cx);
|
||
for(colList.MoveTo(from+1);!colList.IsOut()&&colList.GetCur()<to;colList.MoveToNext())
|
||
colList.GetCurData()->Move(-cx);
|
||
}
|
||
//所有行内进行列移动,子行的移动由父行执行
|
||
for(rowList.MoveToFirst();!rowList.IsOut();rowList.MoveToNext())
|
||
if(!rowList.GetCurData()->IsChildRow())
|
||
rowList.GetCurData()->MoveCol(from,to);
|
||
|
||
colList.Move(from,to);
|
||
long count=0;
|
||
for(colList.MoveToFirst();!colList.IsOut();colList.MoveToNext(),count++)
|
||
colList.GetCurData()->SetIndex(count);
|
||
|
||
Invalidate();
|
||
}
|
||
void WDGrid::DelCol(long i)//ok
|
||
{
|
||
EndEditCell();
|
||
SelectCol(i,false);
|
||
long width=GetCol(i).GetWidth();
|
||
colList.Del(i);
|
||
for(colList.MoveTo(i);!colList.IsOut();colList.MoveToNext())
|
||
{
|
||
WDGridCol&col=*colList.GetCurData();
|
||
col.Move(-width);
|
||
col.SetIndex(col.GetIndex()-1);
|
||
}
|
||
for(rowList.MoveToFirst();!rowList.IsOut();rowList.MoveToNext())
|
||
if(!rowList.GetCurData()->IsChildRow())
|
||
rowList.GetCurData()->DelCol(i);
|
||
RecalcLayout();
|
||
//保持原列选定
|
||
for(colSelList.MoveToLast();!colList.IsOut();colList.MoveToPre())
|
||
{
|
||
if(colSelList.GetCurData()>i)
|
||
colSelList.SetCurData(colSelList.GetCurData()-1);
|
||
else
|
||
break;
|
||
}
|
||
}
|
||
void WDGrid::SetRowNum(long n)//ok
|
||
{
|
||
while(GetRowNum()>n)
|
||
DelRow(GetRowNum()-1);
|
||
while(GetRowNum()<n)
|
||
AppendRow();
|
||
}
|
||
void WDGrid::SetColNum(long n)//ok
|
||
{
|
||
while(GetColNum()>n)
|
||
DelCol(GetColNum()-1);
|
||
while(GetColNum()<n)
|
||
AppendCol();
|
||
}
|
||
void WDGrid::GetSel(TTable<WDGridRow*>&table)//ok
|
||
{
|
||
for(rowSelList.MoveToFirst();!rowSelList.IsOut();rowSelList.MoveToNext())
|
||
{
|
||
MoveTo(rowSelList.GetCurData());
|
||
table.AddTail(CurRow());
|
||
}
|
||
}
|
||
void WDGrid::GetSel(TTable<WDGridCol*>&table)//ok
|
||
{
|
||
for(colSelList.MoveToFirst();!colSelList.IsOut();colSelList.MoveToNext())
|
||
table.AddTail(colList[colSelList.GetCurData()]);
|
||
}
|
||
void WDGrid::Arrange(bool bIncrease)//ok
|
||
{
|
||
for(rowList.MoveToFirst();!rowList.IsOut();rowList.MoveToNext())
|
||
{
|
||
WDGridTreeRow&treeRow=(WDGridTreeRow&)(*rowList.GetCurData());
|
||
if(treeRow.IsParentRow())
|
||
{
|
||
bool bFold=treeRow.IsFold();
|
||
treeRow.Fold();
|
||
treeRow.ArrangeChild(bIncrease);
|
||
if(!bFold)
|
||
treeRow.SetUnFoldFlag();
|
||
}
|
||
}
|
||
rowList.Arrange(bIncrease);
|
||
|
||
long i=0;
|
||
for(rowList.MoveToFirst();!rowList.IsOut();rowList.MoveToNext(),i++)
|
||
CurRow()->SetIndex(i);
|
||
for(rowList.MoveToFirst();!rowList.IsOut();rowList.MoveToNext())
|
||
if(CurRow()->IsParentRow()&&!CurTreeRow()->IsFold())
|
||
CurTreeRow()->UnFold();
|
||
|
||
OnDataChanged();
|
||
|
||
Invalidate();
|
||
}
|
||
BOOL WDGrid::Create(const RECT& rect,DWORD wStyle,CWnd* pParent)//ok
|
||
{
|
||
const TCHAR* pszClassName
|
||
= AfxRegisterWndClass(CS_HREDRAW|CS_VREDRAW|CS_SAVEBITS|CS_DBLCLKS,
|
||
LoadCursor(NULL,IDC_ARROW),HBRUSH(brush.GetSafeHandle()));
|
||
return CWnd::CreateEx(NULL,pszClassName,NULL,wStyle,rect,pParent,NULL,NULL);
|
||
}
|
||
BOOL WDGrid::Create(CWnd*pParent,UINT ID,DWORD wStyle)//ok
|
||
{
|
||
CWnd *pStatic=pParent->GetDlgItem(ID);
|
||
if(pStatic!=NULL)
|
||
{
|
||
DWORD dwStyle=pStatic->GetExStyle();
|
||
CRect rect;
|
||
pStatic->GetWindowRect(rect);
|
||
pParent->ScreenToClient(rect);
|
||
pStatic->DestroyWindow();
|
||
const TCHAR* pszClassName
|
||
= AfxRegisterWndClass(CS_HREDRAW|CS_VREDRAW|CS_SAVEBITS|CS_DBLCLKS,
|
||
LoadCursor(NULL,IDC_ARROW),HBRUSH(brush.GetSafeHandle()));
|
||
return CWnd::CreateEx(0,pszClassName,NULL,wStyle,rect,pParent,ID,NULL);
|
||
}
|
||
return FALSE;
|
||
}
|
||
void WDGrid::RecalcLayout(BOOL bRedraw)//ok
|
||
{
|
||
if(!IsValidWnd())
|
||
return;
|
||
|
||
static bool bIn=false;
|
||
if(bIn)
|
||
return;
|
||
bIn=true;
|
||
|
||
bool bOldVScroll=bVScroll;
|
||
EndEditCell();
|
||
CRect rect,rect0;
|
||
GetClientRect(&rect);
|
||
GetRect(rect0);
|
||
int x0=0,y0=0;
|
||
|
||
int cx=GetSystemMetrics(SM_CXVSCROLL);
|
||
int cy=GetSystemMetrics(SM_CYHSCROLL);
|
||
if(bVScroll)
|
||
{
|
||
rect.right+=cx;
|
||
y0=GetScrollPos(SB_VERT);
|
||
}
|
||
if(bHScroll)
|
||
{
|
||
rect.bottom+=cy;
|
||
x0=GetScrollPos(SB_HORZ);
|
||
}
|
||
bHScroll=rect0.Width()>rect.Width();
|
||
bVScroll=rect0.Height()>rect.Height();
|
||
if(bVScroll&&bHScroll)
|
||
{
|
||
rect.right-=cx;
|
||
rect.bottom-=cy;
|
||
}
|
||
else if(!bVScroll&&bHScroll)
|
||
{
|
||
rect.bottom-=cy;
|
||
if(bVScroll=rect0.Height()>rect.Height())
|
||
rect.right-=cx;
|
||
}
|
||
else if(!bHScroll&&bVScroll)
|
||
{
|
||
rect.right-=cx;
|
||
if(bHScroll=rect0.Width()>rect.Width())
|
||
rect.bottom-=cy;
|
||
}
|
||
|
||
if(bHScroll)
|
||
{
|
||
EnableScrollBarCtrl(SB_HORZ);
|
||
SetScrollRange(SB_HORZ,GetLeft(),rect0.Width()-rect.Width());
|
||
if(x0<=rect0.Width()-rect.Width())
|
||
SetScrollPos(SB_HORZ,x0);
|
||
else
|
||
SetScrollPos(SB_HORZ,rect0.Width()-rect.Width());
|
||
}
|
||
else
|
||
EnableScrollBarCtrl(SB_HORZ,FALSE);
|
||
if(bVScroll)
|
||
{
|
||
EnableScrollBarCtrl(SB_VERT);
|
||
SetScrollRange(SB_VERT,GetTop(),rect0.Height()-rect.Height());
|
||
if(y0<=rect0.Height()-rect.Height())
|
||
SetScrollPos(SB_VERT,y0);
|
||
else
|
||
SetScrollPos(SB_VERT,rect0.Height()-rect.Height());
|
||
}
|
||
else
|
||
EnableScrollBarCtrl(SB_VERT,FALSE);
|
||
|
||
//更新全局CClientDC对象
|
||
ClearDC();
|
||
PrepareDC();
|
||
|
||
if(m_pAppendRow!=NULL)
|
||
DELETE_PTR(m_pAppendRow);
|
||
m_pAppendRow=IsTreeGrid()?new WDGridTreeRow(*this):new WDGridRow(*this);
|
||
m_pAppendRow->SetIndex(GetRowNum());
|
||
|
||
if(bRedraw)
|
||
Invalidate();
|
||
|
||
bIn=false;
|
||
}
|
||
void WDGrid::PrepareDC(CDC*pD)//ok
|
||
{
|
||
if(pD==NULL)//prepare global CClientDC
|
||
{
|
||
if(pDC!=NULL)//be ready
|
||
return;
|
||
pDC=new CClientDC(this);
|
||
}
|
||
else//prepare CPaintDC, global CClientDC object must be destroyed!
|
||
pDC=pD;
|
||
pDC->SetROP2(R2_COPYPEN);
|
||
pDC->SelectObject(&font);
|
||
pDC->SelectObject(&pen);
|
||
CPoint pt;
|
||
GetUpCorner(pt);
|
||
pDC->SetViewportOrg(pt.x-1,pt.y-1);//不显示左上边界
|
||
}
|
||
void WDGrid::OnBeforeRefresh(WDGridCell&cell)//ok
|
||
{
|
||
CDC&dc=GetDC();
|
||
WDGridCol&col=cell.GetCol();
|
||
dc.SetBkColor(col.GetBackColor());
|
||
dc.SetTextColor(col.GetTextColor());
|
||
dc.SetBkMode(TRANSPARENT);
|
||
}
|
||
long WDGrid::GetColHeaderHeight()//ok
|
||
{
|
||
int count=1;
|
||
for(colList.MoveToFirst();!colList.IsOut();colList.MoveToNext())
|
||
{
|
||
TString text=colList.GetCurData()->GetName();
|
||
TListQuene<long>quene;
|
||
long c=text.Find(_T("\n"),quene)+1;
|
||
if(c>count)
|
||
count=c;
|
||
}
|
||
return count*GetRowHeight();
|
||
}
|
||
void WDGrid::Invalidate(BOOL bErase)//ok
|
||
{
|
||
if(IsValidWnd())
|
||
{
|
||
CWnd::Invalidate(bErase);
|
||
if(pActiveQuad!=NULL)
|
||
pActiveQuad->Invalidate();
|
||
if(pColSelector!=NULL)
|
||
pColSelector->Invalidate();
|
||
if(pRowSelector!=NULL)
|
||
pRowSelector->Invalidate();
|
||
}
|
||
}
|
||
void WDGrid::Refresh()//ok
|
||
{
|
||
if(!IsValidWnd())
|
||
return;
|
||
CRect rect;
|
||
GetClientRect(&rect);
|
||
long firstRow=0,firstCol=0,lastRow=GetRowNum()-1,lastCol=GetColNum()-1;
|
||
CPoint pt0(rect.left,rect.top),pt1(rect.right,rect.bottom);
|
||
PtToCell(pt0,firstRow,firstCol);
|
||
PtToCell(pt1,lastRow,lastCol);
|
||
for(rowList.MoveToFirst();!rowList.IsOut();rowList.MoveToNext())
|
||
{
|
||
WDGridRow&row=*rowList.GetCurData();
|
||
if(row.GetIndex()>=firstRow&&row.GetIndex()<=lastRow)
|
||
row.Refresh();
|
||
}
|
||
|
||
if(GetRowNum()<=lastRow&&!IsNoAppendButton())
|
||
m_pAppendRow->Refresh();
|
||
|
||
if(IsColSelected())
|
||
for(colSelList.MoveToFirst();!colSelList.IsOut();colSelList.MoveToNext())
|
||
GetCol(colSelList.GetCurData()).Select();
|
||
else if(IsRowSelected())
|
||
for(rowSelList.MoveToFirst();!rowSelList.IsOut();rowSelList.MoveToNext())
|
||
GetRow(rowSelList.GetCurData()).Select();
|
||
}
|
||
void WDGrid::OnPaint()//ok
|
||
{
|
||
ClearDC();//清除可能存在的全局CClientDC对象,避免与CPaintDC对象冲突。
|
||
{
|
||
CPaintDC dc(this);
|
||
PrepareDC(&dc);
|
||
Refresh();
|
||
}
|
||
//重建全局CClientDC对象。
|
||
pDC=NULL;
|
||
PrepareDC();
|
||
}
|
||
bool WDGrid::FitLastCol()//ok
|
||
{
|
||
if(!IsValidWnd())
|
||
return false;
|
||
if(colList.IsEmpty())
|
||
return false;
|
||
CRect rect,cRect;
|
||
GetRect(rect);
|
||
GetClientRect(&cRect);
|
||
int cx=cRect.Width()-rect.Width();
|
||
colList.MoveToLast();
|
||
if(cx==0||(cx<0&&cx<GetRowHeight()-colList.GetCurData()->GetWidth()))
|
||
return false;
|
||
colList.GetCurData()->SetRight(colList.GetCurData()->GetRight()+cx);
|
||
RecalcLayout();
|
||
return true;
|
||
}
|
||
void WDGrid::UnSelect()//ok
|
||
{
|
||
for(colSelList.MoveToFirst();!colSelList.IsOut();colSelList.MoveToNext())
|
||
GetCol(colSelList.GetCurData()).Select(false);
|
||
for(rowSelList.MoveToFirst();!rowSelList.IsOut();rowSelList.MoveToNext())
|
||
GetRow(rowSelList.GetCurData()).Select(false);
|
||
ClearSel();
|
||
|
||
OnCurChanged();
|
||
}
|
||
void WDGrid::SelectAll()//ok
|
||
{
|
||
EndEditCell();
|
||
ClearSel();
|
||
for(long i=0;i<GetRowNum();i++)
|
||
rowSelList.AddTail(i);
|
||
|
||
OnCurChanged();
|
||
Invalidate();
|
||
}
|
||
void WDGrid::SelectCol(long i,bool bSel)//ok
|
||
{
|
||
if(!IsValidCol(i))
|
||
return;
|
||
if(bSel)
|
||
{
|
||
EndEditCell();
|
||
if(IsRowSelected())
|
||
{
|
||
for(rowSelList.MoveToFirst();!rowSelList.IsOut();rowSelList.MoveToNext())
|
||
GetRow(rowSelList.GetCurData()).Select(false);
|
||
rowSelList.Clear();
|
||
}
|
||
if(NOT_FOUND==colSelList.Find(i))
|
||
{
|
||
colSelList.AddTail(i);
|
||
colSelList.Arrange();
|
||
//GetCol(i).Select();// lgd 13/09/26
|
||
|
||
if(IsValidWnd())
|
||
{
|
||
//根据左右线位置移动视图,尽量使当前选定列显示
|
||
CRect rect;
|
||
GetClientRect(&rect);
|
||
CPoint pt=rect.CenterPoint();
|
||
pDC->DPtoLP(&pt);
|
||
GetCol(i).GetRect(rect);
|
||
rect.top=rect.bottom=pt.y;
|
||
ShowRect(rect);
|
||
}
|
||
GetCol(i).Select(); // lgd 13/09/26
|
||
|
||
}
|
||
}
|
||
else if(colSelList.FindAndDel(i))
|
||
GetCol(i).Select(false);
|
||
|
||
OnCurChanged();
|
||
}
|
||
void WDGrid::SelectRow(long i,bool bSel)//ok
|
||
{
|
||
if(!IsValidRow(i))
|
||
return;
|
||
if(bSel)
|
||
{
|
||
EndEditCell();
|
||
if(IsColSelected())
|
||
{
|
||
for(colSelList.MoveToFirst();!colSelList.IsOut();colSelList.MoveToNext())
|
||
GetCol(colSelList.GetCurData()).Select(false);
|
||
colSelList.Clear();
|
||
}
|
||
if(NOT_FOUND==rowSelList.Find(i))
|
||
{
|
||
rowSelList.AddTail(i);
|
||
rowSelList.Arrange();
|
||
//GetRow(i).Select();// lgd 13/09/26
|
||
//根据上下线位置上下移动视图,尽量使当前选定行显示
|
||
if(IsValidWnd())
|
||
{
|
||
CRect rect;
|
||
GetClientRect(&rect);
|
||
CPoint pt=rect.CenterPoint();
|
||
pDC->DPtoLP(&pt);
|
||
GetRow(i).GetRect(rect);
|
||
rect.left=rect.right=pt.x;
|
||
ShowRect(rect);
|
||
}
|
||
GetRow(i).Select();// lgd 13/09/26
|
||
}
|
||
}
|
||
else if(rowSelList.FindAndDel(i))
|
||
GetRow(i).Select(false);
|
||
OnCurChanged();
|
||
}
|
||
bool WDGrid::IsSelConnect()//ok
|
||
{
|
||
if(IsColSelected()&&
|
||
colSelList[colSelList.GetLastIndex()]-colSelList[0]+1==colSelList.GetLength())
|
||
return true;
|
||
else if(IsRowSelected()&&
|
||
rowSelList[rowSelList.GetLastIndex()]-rowSelList[0]+1==rowSelList.GetLength())
|
||
return true;
|
||
return false;
|
||
}
|
||
bool WDGrid::IsSelFold()//ok
|
||
{
|
||
if(!IsTreeGrid())
|
||
return true;
|
||
for(rowSelList.MoveToFirst();!rowSelList.IsOut();rowSelList.MoveToNext())
|
||
{
|
||
WDGridRow& row=*rowList[rowSelList.GetCurData()];
|
||
if(row.IsParentRow())
|
||
if(!((WDGridTreeRow&)row).IsFold())
|
||
return false;
|
||
}
|
||
return true;
|
||
}
|
||
WCellCtrl* WDGrid::OnGetCellEdit(WDGridCell&cell)//ok
|
||
{
|
||
WDGridCol&col=cell.GetCol();
|
||
if(col.IsComboEdit())
|
||
return new WCellCombo(cell,true);
|
||
else if(col.IsComboSel())
|
||
return new WCellCombo(cell,false);
|
||
else if(col.IsRightButton())
|
||
return new WCellButtonEdit(cell);
|
||
else if(col.IsRightSpin())
|
||
return new WCellSpinEdit(cell);
|
||
else
|
||
return new WCellEdit(cell);
|
||
}
|
||
void WDGrid::OnCurChanged()
|
||
{
|
||
if(IsEditing())
|
||
m_iCurCol=pSelCell->GetColIndex();
|
||
else if(GetColSelNum()==1)
|
||
m_iCurCol=GetSelCol(0).GetIndex();
|
||
else
|
||
m_iCurCol=-1;
|
||
|
||
long iOldCur=m_iCurRow;
|
||
if(IsEditing())
|
||
m_iCurRow=pSelCell->GetRowIndex();
|
||
else if(GetRowSelNum()==1)
|
||
m_iCurRow=GetSelRow(0).GetIndex();
|
||
else
|
||
m_iCurRow=-1;
|
||
if(pRowSelector)
|
||
pRowSelector->OnCurRowChanged();
|
||
}
|
||
|
||
void WDGrid::SetCurRowIndex(long iRow)
|
||
{
|
||
m_iCurRow=iRow;
|
||
if(pRowSelector)
|
||
pRowSelector->OnCurRowChanged();
|
||
}
|
||
|
||
void WDGrid::BeginEditCell(long i,long j)//ok
|
||
{
|
||
if(!IsValidWnd())
|
||
return;
|
||
UnSelect();
|
||
EndEditCell();
|
||
|
||
WDGridCell*pCell=i==GetRowNum()?&((*m_pAppendRow)[j]):&(GetRow(i)[j]);
|
||
if(pCell->IsReadOnly())
|
||
return;
|
||
|
||
bool bModified=false;
|
||
if(!OnBeforeEdit(*pCell,bModified))
|
||
{
|
||
if(i==GetRowNum()&&bModified)//已经在OnBeforeEdit中修改了cell,并且是AppendRow
|
||
{
|
||
if(OnBeforeInsertRow(GetRowNum(),m_pAppendRow))
|
||
{
|
||
rowList.AddTail(m_pAppendRow);
|
||
|
||
OnInsertRow(*m_pAppendRow);
|
||
OnDataChanged();//<内容改变事件>
|
||
}
|
||
|
||
m_pAppendRow=NULL;
|
||
RecalcLayout();
|
||
}
|
||
return;
|
||
}
|
||
|
||
if(pCurEdit!=NULL)
|
||
pCurEdit->Destroy();//PostNcDestroy() delete!
|
||
|
||
CRect rect;
|
||
pCell->GetRect(rect);
|
||
ShowRect(rect);//if possible ,make cell rect visible.
|
||
pSelCell=pCell;
|
||
pSelCell->GetTextRect(rect);
|
||
if(j==0)
|
||
{
|
||
if(pSelCell->row.IsParentRow())
|
||
{
|
||
WDGridTreeRow&treeRow=(WDGridTreeRow&)(pSelCell->row);
|
||
CRect quad;
|
||
treeRow.GetTreeQuad(quad);
|
||
rect.left=quad.right;
|
||
}
|
||
else if(pSelCell->row.IsChildRow())
|
||
{
|
||
WDGridTreeRow&treeRow=(WDGridTreeRow&)(pSelCell->row);
|
||
CRect quad;
|
||
treeRow.GetParent().GetTreeQuad(quad);
|
||
rect.left=quad.right+quad.Width();
|
||
}
|
||
}
|
||
pDC->LPtoDP(&rect);
|
||
|
||
pCurEdit=OnGetCellEdit(*pSelCell);
|
||
|
||
if(pCurEdit!=NULL)
|
||
{
|
||
pCurEdit->Create(rect);
|
||
|
||
OnCurChanged();
|
||
}
|
||
else
|
||
pSelCell=NULL;
|
||
}
|
||
void WDGrid::EndEditCell()//ok
|
||
{
|
||
static bool bIn=false;
|
||
if(bIn)//防止重复进入
|
||
return;
|
||
bIn=true;
|
||
|
||
if(IsEditing())
|
||
{
|
||
if(pCurEdit->IsModified())
|
||
{
|
||
CString text;
|
||
pCurEdit->GetNewText(text);
|
||
if(OnModified(*pSelCell,text))//<修改事件响应>
|
||
{
|
||
pSelCell->SetText(text);
|
||
pSelCell->Refresh();
|
||
|
||
if(IsNewRow(pSelCell->GetRowIndex()))//新行
|
||
{
|
||
if(OnBeforeInsertRow(GetRowNum(),m_pAppendRow))
|
||
{
|
||
rowList.AddTail(m_pAppendRow);
|
||
|
||
OnInsertRow(*m_pAppendRow);
|
||
OnDataChanged();//<内容改变事件>
|
||
}
|
||
|
||
m_pAppendRow=NULL;
|
||
}
|
||
else
|
||
OnDataChanged();//<内容改变事件>
|
||
}
|
||
}
|
||
pSelCell=NULL;//1!
|
||
pCurEdit->Hide();//2!
|
||
|
||
if(m_pAppendRow==NULL)
|
||
RecalcLayout();
|
||
}
|
||
|
||
|
||
bIn=false;
|
||
}
|
||
void WDGrid::CancelEditCell()//ok
|
||
{
|
||
if(IsEditing())
|
||
{
|
||
pSelCell=NULL;//1!
|
||
pCurEdit->Hide();//2!
|
||
}
|
||
}
|
||
void WDGrid::PtToCell(CPoint pt,long &row,long &col)//ok
|
||
{
|
||
if(pDC==NULL)
|
||
return;
|
||
pDC->DPtoLP(&pt);
|
||
CRect rect;
|
||
GetRect(rect);
|
||
row=(pt.y-GetTop())/GetRowHeight();
|
||
col=0;
|
||
for(colList.MoveToFirst();!colList.IsOut();colList.MoveToNext(),col++)
|
||
{
|
||
WDGridCol&col=*colList.GetCurData();
|
||
if(pt.x<col.GetRight()&&pt.x>=col.GetLeft())
|
||
break;
|
||
}
|
||
}
|
||
void WDGrid::ShowRect(CRect rect)//ok
|
||
{//左上角优先
|
||
if(!IsValidWnd())
|
||
return;
|
||
CRect cRect;
|
||
GetClientRect(&cRect);
|
||
pDC->DPtoLP(&cRect);
|
||
int x0=GetLeft();
|
||
if(bHScroll)
|
||
x0=GetScrollPos(SB_HORZ);
|
||
int y0=GetTop();
|
||
if(bVScroll)
|
||
y0=GetScrollPos(SB_VERT);
|
||
int cx=0,cy=0;
|
||
if(rect.top<cRect.top||rect.Height()>cRect.Height())//上界在上
|
||
cy=rect.top-y0;
|
||
else if((rect.bottom>cRect.bottom&&rect.Height()<=cRect.Height())||rect.top>cRect.bottom)
|
||
//下界在下并且高度足够,或全在下
|
||
cy=rect.bottom-cRect.bottom+1;
|
||
if(rect.left<cRect.left||rect.Width()>cRect.Width())//左界在左
|
||
cx=rect.left-x0;
|
||
else if((rect.right>cRect.right&&rect.Width()<=cRect.Width())||rect.left>cRect.right)
|
||
//右界在右并且宽度足够,或全在右
|
||
cx=rect.right-cRect.right+1;
|
||
MoveView(cx,cy);
|
||
}
|
||
void WDGrid::ShowAppendRow()
|
||
{
|
||
CRect rect;
|
||
GetClientRect(&rect);
|
||
CPoint pt=rect.CenterPoint();
|
||
pDC->DPtoLP(&pt);
|
||
m_pAppendRow->GetRect(rect);
|
||
rect.left=rect.right=pt.x;
|
||
ShowRect(rect);
|
||
}
|
||
bool WDGrid::FindAndSel(const TCHAR*s,long iCol)//ok
|
||
{
|
||
if(IsTreeGrid())
|
||
{
|
||
for(MoveToFirst();!IsOut();MoveToNext())
|
||
if(_tcscmp((*CurRow())[iCol],s)==0)
|
||
{
|
||
UnSelect();
|
||
SelectRow(GetCur(),true);
|
||
return true;
|
||
}
|
||
else if(CurTreeRow()->FindAndSel(s,iCol))
|
||
return true;
|
||
}
|
||
else
|
||
for(MoveToFirst();!IsOut();MoveToNext())
|
||
if(_tcscmp((*CurRow())[iCol],s)==0)
|
||
{
|
||
UnSelect();
|
||
SelectRow(GetCur(),true);
|
||
return true;
|
||
}
|
||
return false;
|
||
}
|
||
void WDGrid::MoveView(int cx,int cy)//ok
|
||
{//无限制调用
|
||
if(!IsValidWnd())
|
||
return;
|
||
|
||
CRect rect;
|
||
GetClientRect(&rect);
|
||
int x0=GetScrollPos(SB_HORZ);
|
||
int y0=GetScrollPos(SB_VERT);
|
||
if(bHScroll)
|
||
{
|
||
if(cx+x0<GetLeft())
|
||
cx=GetLeft()-x0;
|
||
else if(cx+x0>GetRight()-rect.Width())
|
||
cx=GetRight()-rect.Width()-x0;
|
||
}
|
||
if(bVScroll)
|
||
{
|
||
if(cy+y0<GetTop())
|
||
cy=GetTop()-y0;
|
||
else if(cy+y0>GetBottom()-rect.Height())
|
||
cy=GetBottom()-rect.Height()-y0;
|
||
}
|
||
if(cx==0&&cy==0)
|
||
return;
|
||
|
||
SetScrollPos(SB_HORZ,x0+cx);
|
||
SetScrollPos(SB_VERT,y0+cy);
|
||
|
||
//更新全局CClientDC对象
|
||
ClearDC();
|
||
PrepareDC();
|
||
|
||
EndEditCell();
|
||
CWnd::ScrollWindow(-cx,-cy,&rect);
|
||
|
||
// lgd 13/09/26
|
||
if(IsColSel())
|
||
{
|
||
pColSelector->ScrollWindow(-cx,0);
|
||
pColSelector->Invalidate();
|
||
}
|
||
if(IsRowSel())
|
||
{
|
||
pRowSelector->ScrollWindow(0,-cy);
|
||
pRowSelector->Invalidate();
|
||
}
|
||
}
|
||
BEGIN_MESSAGE_MAP(WDGrid, CWnd)
|
||
ON_WM_SIZE()
|
||
ON_MESSAGE (WM_SETFONT, OnSetFont)
|
||
ON_MESSAGE (WM_SETTEXT, OnSetText)
|
||
ON_WM_CANCELMODE()
|
||
ON_WM_GETDLGCODE()
|
||
ON_WM_PAINT()
|
||
ON_WM_VSCROLL()
|
||
ON_WM_HSCROLL()
|
||
ON_WM_MOUSEWHEEL()
|
||
ON_WM_CREATE()
|
||
ON_WM_CTLCOLOR()
|
||
ON_WM_LBUTTONDBLCLK()
|
||
ON_WM_LBUTTONDOWN()
|
||
ON_WM_KEYDOWN()
|
||
ON_WM_SETCURSOR()
|
||
ON_WM_ERASEBKGND()
|
||
ON_WM_KILLFOCUS()
|
||
ON_WM_SETFOCUS()
|
||
ON_WM_DESTROY()
|
||
ON_WM_RBUTTONUP()
|
||
ON_WM_TIMER()
|
||
END_MESSAGE_MAP()
|
||
int WDGrid::OnCreate(LPCREATESTRUCT lpCreateStruct)//ok
|
||
{
|
||
if (CWnd::OnCreate(lpCreateStruct) == -1)
|
||
return -1;
|
||
|
||
CreateFont();
|
||
RecalcLayout();
|
||
EnableToolTips();
|
||
if(IsColSel())
|
||
pColSelector=new WColSelector(*this);
|
||
if(IsRowSel())
|
||
pRowSelector=new WRowSelector(*this);
|
||
if(IsRowSel()&&IsColSel())
|
||
pActiveQuad=new WDGActiveQuad(*this);
|
||
return 0;
|
||
}
|
||
void WDGrid::OnTimer(UINT_PTR nIDEvent)
|
||
{
|
||
CWnd::OnTimer(nIDEvent);
|
||
if(nIDEvent==0)
|
||
{
|
||
KillTimer(0);
|
||
if(pSelCell2!=NULL)
|
||
{
|
||
long i=pSelCell2->GetRowIndex(),j=pSelCell2->GetColIndex();
|
||
pSelCell2=NULL;
|
||
CancelEditCell();
|
||
BeginEditCell(i,j);
|
||
}
|
||
}
|
||
else if(nIDEvent==1)
|
||
{
|
||
KillTimer(1);
|
||
EndEditCell();
|
||
}
|
||
}
|
||
void WDGrid::AutoEditCell(WDGridCell*pCell)
|
||
{
|
||
if(IsCellLocking())
|
||
return;
|
||
|
||
if(pCell==NULL&&IsEditing())
|
||
pSelCell2=pSelCell;
|
||
else
|
||
pSelCell2=pCell;
|
||
SetTimer(0,0,0);
|
||
}
|
||
void WDGrid::AutoCloseCell(int iTime)
|
||
{
|
||
SetTimer(1,iTime,0);
|
||
}
|
||
void WDGrid::OnSize(UINT nType, int cx, int cy)//ok
|
||
{
|
||
CWnd::OnSize(nType, cx, cy);
|
||
RecalcLayout(false);
|
||
}
|
||
void WDGrid::CreateFont (void)//ok
|
||
{
|
||
if (font.GetSafeHandle() == 0)
|
||
{
|
||
CWnd* pwndParent = GetParent();
|
||
if (pwndParent)
|
||
{
|
||
LOGFONT logFont;
|
||
CFont* pfontParent = pwndParent->GetFont();
|
||
pfontParent->GetObject (sizeof (logFont),&logFont);
|
||
logFont.lfWidth = 0;
|
||
logFont.lfQuality = DEFAULT_QUALITY;
|
||
font.CreateFontIndirect (&logFont);
|
||
rowHeight=abs(logFont.lfHeight)+1;//这个象素为与下边界线之间的空隙
|
||
}
|
||
}
|
||
}
|
||
LRESULT WDGrid::OnSetText (WPARAM wParam, LPARAM lParam)//ok
|
||
{
|
||
Default();
|
||
RecalcLayout();
|
||
return (0);
|
||
}
|
||
LRESULT WDGrid::OnSetFont (WPARAM wParam, LPARAM lParam)//ok
|
||
{
|
||
LOGFONT logFont;
|
||
Default();
|
||
HFONT hFont = (HFONT) wParam;
|
||
CFont* pfontDisplay = CFont::FromHandle (hFont);
|
||
pfontDisplay->GetObject (sizeof (logFont), &logFont);
|
||
logFont.lfWidth = 0;
|
||
logFont.lfQuality = PROOF_QUALITY;
|
||
font.DeleteObject();
|
||
font.CreateFontIndirect(&logFont);
|
||
rowHeight=abs(logFont.lfHeight)+1;//这个象素为与下边界线之间的空隙
|
||
RecalcLayout();
|
||
return (0L);
|
||
}
|
||
void WDGrid::OnCancelMode (void)//ok
|
||
{
|
||
if (GetCapture() == this)
|
||
ReleaseCapture();
|
||
CWnd::OnCancelMode();
|
||
}
|
||
UINT WDGrid::OnGetDlgCode(void)//ok
|
||
{
|
||
return (DLGC_WANTALLKEYS);//DLGC_BUTTON;//
|
||
}
|
||
void WDGrid::OnVScroll(UINT nSBCode, UINT nPos, CScrollBar* pScrollBar)//ok
|
||
{
|
||
CRect rect;
|
||
GetClientRect(&rect);
|
||
int yMin,yMax;
|
||
GetScrollRange(SB_VERT,&yMin,&yMax);
|
||
int y0=GetScrollPos(SB_VERT);
|
||
int y=y0;
|
||
switch (nSBCode)
|
||
{
|
||
case SB_TOP:
|
||
y = yMin;
|
||
break;
|
||
case SB_BOTTOM:
|
||
y = yMax;
|
||
break;
|
||
case SB_LINEUP:
|
||
y -=GetRowHeight();
|
||
break;
|
||
case SB_LINEDOWN:
|
||
y +=GetRowHeight();
|
||
break;
|
||
case SB_PAGEUP:
|
||
y -=rect.Height();
|
||
break;
|
||
case SB_PAGEDOWN:
|
||
y +=rect.Height();
|
||
break;
|
||
case SB_THUMBTRACK:
|
||
{
|
||
SCROLLINFO si;
|
||
GetScrollInfo(SB_VERT,&si);
|
||
y = si.nTrackPos;
|
||
}
|
||
break;
|
||
}
|
||
if(y<yMin)
|
||
y=yMin;
|
||
else if(y>yMax)
|
||
y=yMax;
|
||
MoveView(0,y-y0);
|
||
CWnd::OnVScroll(nSBCode, nPos, pScrollBar);
|
||
SetFocus();
|
||
}
|
||
void WDGrid::OnHScroll(UINT nSBCode, UINT nPos, CScrollBar* pScrollBar)//ok
|
||
{
|
||
CRect rect;
|
||
GetClientRect(&rect);
|
||
|
||
int xMin,xMax;
|
||
GetScrollRange(SB_HORZ,&xMin,&xMax);
|
||
int x0=GetScrollPos(SB_HORZ);
|
||
int x=x0;
|
||
switch (nSBCode)
|
||
{
|
||
case SB_TOP:
|
||
x = xMin;
|
||
break;
|
||
case SB_BOTTOM:
|
||
x = xMax;
|
||
break;
|
||
case SB_LINEUP:
|
||
x-= defaultWidth;
|
||
break;
|
||
case SB_LINEDOWN:
|
||
x+= defaultWidth;
|
||
break;
|
||
case SB_PAGEUP:
|
||
x-=rect.Width();
|
||
break;
|
||
case SB_PAGEDOWN:
|
||
x+=rect.Width();
|
||
break;
|
||
case SB_THUMBTRACK:
|
||
{
|
||
SCROLLINFO si;
|
||
GetScrollInfo(SB_HORZ,&si);
|
||
x = si.nTrackPos;
|
||
}
|
||
break;
|
||
}
|
||
if(x<xMin)
|
||
x=xMin;
|
||
else if(x>xMax)
|
||
x=xMax;
|
||
MoveView(x-x0,0);
|
||
CWnd::OnHScroll(nSBCode, nPos, pScrollBar);
|
||
SetFocus();
|
||
}
|
||
BOOL WDGrid::OnMouseWheel(UINT nFlags, short zDelta, CPoint pt)//ok
|
||
{
|
||
//if(bVScroll)
|
||
//{
|
||
// int y0=GetScrollPos(SB_VERT);
|
||
// OnVScroll(SB_THUMBTRACK,(y0-GetRowHeight()*zDelta/120), NULL);
|
||
//}
|
||
//return CWnd::OnMouseWheel(nFlags, zDelta, pt);
|
||
|
||
//axc add 2015-05-04 支持垂直滚动条使用鼠标滚轮进行快速变化
|
||
if(bVScroll)
|
||
{
|
||
int y0=GetScrollPos(SB_VERT);
|
||
if (zDelta > 0)
|
||
OnVScroll(SB_LINEUP,(y0-GetRowHeight()*zDelta/120), NULL);
|
||
else
|
||
OnVScroll(SB_LINEDOWN,(y0-GetRowHeight()*zDelta/120), NULL);
|
||
}
|
||
return CWnd::OnMouseWheel(nFlags, zDelta, pt);
|
||
}
|
||
HBRUSH WDGrid::OnCtlColor(CDC* pDC, CWnd* pWnd, UINT nCtlColor)//ok
|
||
{
|
||
HBRUSH hbr = CWnd::OnCtlColor(pDC, pWnd, nCtlColor);
|
||
if(pCurEdit!=NULL&&pWnd==pCurEdit->GetWnd())
|
||
{
|
||
WDGridCol&col=GetCol(pSelCell->GetColIndex());
|
||
pDC->SetTextColor(col.GetTextColor());
|
||
pDC->SetBkColor(col.GetBackColor());
|
||
pDC->SelectObject(&col.GetBrush());
|
||
return (HBRUSH)(col.GetBrush().GetSafeHandle());
|
||
}
|
||
return hbr;
|
||
}
|
||
bool WDGrid::IsMyFocus(const CWnd*pWnd)const//ok
|
||
{
|
||
return pWnd==this||IsChild(pWnd);
|
||
}
|
||
void WDGrid::OnKillFocus(CWnd*pNewWnd)//ok
|
||
{
|
||
CWnd::OnKillFocus(pNewWnd);
|
||
if(!IsMyFocus(pNewWnd))
|
||
ShowActive(false);
|
||
}
|
||
void WDGrid::OnSetFocus(CWnd*pOldWnd)//ok
|
||
{
|
||
CWnd::OnSetFocus(pOldWnd);
|
||
ShowActive();
|
||
}
|
||
void WDGrid::OnLButtonDblClk(UINT nFlags, CPoint point)//ok
|
||
{
|
||
//if(!IsMyFocus(GetFocus()))removed on 050323
|
||
SetFocus();
|
||
|
||
EndEditCell();
|
||
long col,row;
|
||
PtToCell(point,row,col);//point changed
|
||
if(row>=0&&col>=0&&col<GetColNum())
|
||
{
|
||
if(row<GetRowNum())
|
||
{
|
||
if(col==0&&GetRow(row).IsTreeRow())
|
||
{
|
||
WDGridTreeRow&treeRow=(WDGridTreeRow&)GetRow(row);
|
||
pDC->DPtoLP(&point);
|
||
if(treeRow.IsParentRow()&&treeRow.IsPtInTreeQuad(point))
|
||
{
|
||
UnSelect();
|
||
if(treeRow.IsFold())
|
||
treeRow.UnFold();
|
||
else
|
||
treeRow.Fold();
|
||
}
|
||
else
|
||
BeginEditCell(row,col);
|
||
}
|
||
else
|
||
BeginEditCell(row,col);
|
||
}
|
||
else if(!IsNoAppendButton()&&row==GetRowNum())//点击AppendRow
|
||
BeginEditCell(row,col);
|
||
else
|
||
UnSelect();
|
||
}
|
||
else
|
||
UnSelect();
|
||
|
||
CWnd::OnLButtonDblClk(nFlags, point);
|
||
}
|
||
void WDGrid::OnLButtonDown(UINT nFlags, CPoint point)//ok
|
||
{
|
||
//if(!IsMyFocus(GetFocus()))removed on 050323
|
||
SetFocus();
|
||
|
||
EndEditCell();
|
||
long col,row;
|
||
PtToCell(point,row,col);//point changed
|
||
if(row>=0&&col>=0&&col<GetColNum())
|
||
{
|
||
if(row<GetRowNum())
|
||
{
|
||
if(col==0&&GetRow(row).IsTreeRow())
|
||
{
|
||
WDGridTreeRow&treeRow=(WDGridTreeRow&)GetRow(row);
|
||
pDC->DPtoLP(&point);
|
||
if(treeRow.IsParentRow()&&treeRow.IsPtInTreeQuad(point))
|
||
{
|
||
UnSelect();
|
||
if(treeRow.IsFold())
|
||
treeRow.UnFold();
|
||
else
|
||
treeRow.Fold();
|
||
}
|
||
else
|
||
BeginEditCell(row,col);
|
||
}
|
||
else
|
||
BeginEditCell(row,col);
|
||
}
|
||
else if(!IsNoAppendButton()&&row==GetRowNum())//点击AppendRow
|
||
BeginEditCell(row,col);
|
||
else
|
||
UnSelect();
|
||
}
|
||
else
|
||
UnSelect();
|
||
|
||
CWnd::OnLButtonDown(nFlags, point);
|
||
}
|
||
void WDGrid::OnRButtonUp(UINT nFlags, CPoint point)//ok
|
||
{
|
||
CWnd::OnRButtonUp(nFlags, point);
|
||
SetFocus();
|
||
long col,row;
|
||
PtToCell(point,row,col);
|
||
if(IsValidRow(row)&&IsValidCol(col))
|
||
{
|
||
ClientToScreen(&point);
|
||
OnRClickCell(GetCell(row,col),point);
|
||
}
|
||
}
|
||
void WDGrid::FilterDelUnable()//ok
|
||
{
|
||
for(rowSelList.MoveToFirst();!rowSelList.IsOut();rowSelList.MoveToNext())
|
||
if(GetRow(rowSelList.GetCurData()).IsDelUnable())
|
||
rowSelList.DelCur();
|
||
Invalidate();
|
||
}
|
||
bool WDGrid::IsSelDelUnable()//ok
|
||
{
|
||
for(rowSelList.MoveToFirst();!rowSelList.IsOut();rowSelList.MoveToNext())
|
||
if(GetRow(rowSelList.GetCurData()).IsDelUnable())
|
||
return true;
|
||
return false;
|
||
}
|
||
void WDGrid::ClipSelect()//ok
|
||
{
|
||
pasteList.Clear();
|
||
for(long i=0;i<rowSelList.GetLength();i++)
|
||
{
|
||
WDGridRow&row=GetRow(rowSelList[i]);
|
||
if(row.IsParentRow())
|
||
((WDGridTreeRow&)row).Fold();
|
||
}
|
||
TArray<long> rowSel(rowSelList);
|
||
ClearSel();
|
||
for(i=rowSel.GetLastIndex();i>=0;i--)
|
||
{
|
||
long cur=rowSel[i];
|
||
if(!rowList[cur]->IsTreeRow())
|
||
{
|
||
pasteList.InsertHead(rowList[cur]);
|
||
SelectRow(cur,false);
|
||
rowList[cur]=NULL;
|
||
DelRow(cur);
|
||
}
|
||
else
|
||
{
|
||
WDGridTreeRow*pNewRow=new WDGridTreeRow(*this);
|
||
*pNewRow<<(WDGridTreeRow&)GetRow(cur);//需要同时取走扩展数据
|
||
DelRowEx(cur);
|
||
pasteList.InsertHead(pNewRow);
|
||
}
|
||
}
|
||
}
|
||
void WDGrid::Paste(long i)//ok
|
||
{
|
||
UnSelect();
|
||
|
||
int num=pasteList.GetLength();
|
||
for(pasteList.MoveToLast();!pasteList.IsEmpty();)
|
||
{
|
||
WDGridRow*pRow=pasteList.FetchCur();
|
||
if(i==GetRowNum())
|
||
AppendRow(pRow);
|
||
else if(!GetRow(i).IsChildRow())//不是子行
|
||
InsertRow(i,pRow);
|
||
else//由父行来执行插入
|
||
{
|
||
WDGridTreeRow&curRow=GetTreeRow(i);
|
||
WDGridTreeRow&parentRow=curRow.GetParent();
|
||
parentRow.InsertChild(parentRow.GetChildIndex(&curRow),(WDGridTreeRow*)pRow);
|
||
}
|
||
}
|
||
|
||
for(int j=0;j<num;j++)
|
||
SelectRow(i+j);
|
||
}
|
||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||
//command
|
||
bool WDGrid::DoInsertCol()
|
||
{
|
||
if(IsColFixLength())
|
||
return false;
|
||
if(colSelList.GetLength()==1)
|
||
{
|
||
long cur=colSelList[0];
|
||
WDGridCol*pCol=NULL;
|
||
if(OnBeforeInsertCol(cur,pCol))
|
||
{
|
||
InsertCol(cur,pCol);
|
||
SelectCol(cur+1,false);
|
||
SelectCol(cur);
|
||
|
||
OnInsertCol(GetCol(cur));
|
||
OnDataChanged();
|
||
return true;
|
||
}
|
||
}
|
||
return false;
|
||
}
|
||
bool WDGrid::DoAppendCol()
|
||
{
|
||
if(!IsColFixLength())
|
||
{
|
||
WDGridCol*pCol=NULL;
|
||
long cur=GetColNum();
|
||
if(OnBeforeInsertCol(cur,pCol))
|
||
{
|
||
UnSelect();
|
||
|
||
AppendCol(pCol);
|
||
SelectCol(cur,true);
|
||
|
||
OnInsertCol(GetCol(cur));
|
||
OnDataChanged();
|
||
return true;
|
||
}
|
||
}
|
||
return false;
|
||
}
|
||
bool WDGrid::DoInsertColAfter()
|
||
{
|
||
if(IsColFixLength())
|
||
return false;
|
||
if(colSelList.GetLength()==1)
|
||
{
|
||
long cur=colSelList[0]+1;
|
||
WDGridCol*pCol=NULL;
|
||
if(OnBeforeInsertCol(cur,pCol))
|
||
{
|
||
InsertCol(cur,pCol);
|
||
SelectCol(cur-1,false);
|
||
SelectCol(cur);
|
||
|
||
OnInsertCol(GetCol(cur));
|
||
OnDataChanged();
|
||
return true;
|
||
}
|
||
}
|
||
return false;
|
||
}
|
||
bool WDGrid::DoInsertRow()
|
||
{
|
||
if(IsRowFixLength())
|
||
return false;
|
||
if(rowSelList.GetLength()==1)
|
||
{
|
||
long cur=rowSelList[0];
|
||
WDGridRow*pRow=NULL;
|
||
if(IsTreeGrid()&&GetRow(cur).IsChildRow())
|
||
{
|
||
WDGridTreeRow&curRow=GetTreeRow(cur);
|
||
WDGridTreeRow&parentRow=curRow.GetParent();
|
||
long iChild=parentRow.GetChildIndex(&curRow);
|
||
WDGridTreeRow*pTreeRow=NULL;
|
||
if(OnBeforeInsertChild(parentRow,iChild,pTreeRow))
|
||
{
|
||
parentRow.InsertChild(iChild,pTreeRow);
|
||
SelectRow(cur+1,false);
|
||
SelectRow(cur);
|
||
|
||
OnInsertRow(GetRow(cur));
|
||
OnDataChanged();
|
||
return true;
|
||
}
|
||
}
|
||
else if(OnBeforeInsertRow(cur,pRow))
|
||
{
|
||
InsertRow(cur,pRow);
|
||
SelectRow(cur+1,false);
|
||
SelectRow(cur);
|
||
|
||
OnInsertRow(GetRow(cur));
|
||
OnDataChanged();
|
||
return true;
|
||
}
|
||
}
|
||
return false;
|
||
}
|
||
bool WDGrid::DoInsertRowAfter()
|
||
{
|
||
if(IsRowFixLength())
|
||
return false;
|
||
if(rowSelList.GetLength()==1)
|
||
{
|
||
long cur=rowSelList[0]+1;
|
||
WDGridRow*pRow=NULL;
|
||
if(IsTreeGrid()&&GetRow(cur-1).IsChildRow())
|
||
{
|
||
WDGridTreeRow&curRow=GetTreeRow(cur-1);
|
||
WDGridTreeRow&parentRow=curRow.GetParent();
|
||
long iChild=parentRow.GetChildIndex(&curRow)+1;
|
||
WDGridTreeRow*pTreeRow=NULL;
|
||
if(OnBeforeInsertChild(parentRow,iChild,pTreeRow))
|
||
{
|
||
GetTreeRow(cur-1).Fold();
|
||
parentRow.InsertChild(iChild,pTreeRow);
|
||
SelectRow(cur-1,false);
|
||
SelectRow(cur);
|
||
|
||
OnInsertRow(GetRow(cur));
|
||
OnDataChanged();
|
||
return true;
|
||
}
|
||
}
|
||
else if(OnBeforeInsertRow(cur,pRow))
|
||
{
|
||
if(IsTreeGrid())
|
||
GetTreeRow(cur-1).Fold();
|
||
InsertRow(cur,pRow);
|
||
SelectRow(cur-1,false);
|
||
SelectRow(cur);
|
||
|
||
OnInsertRow(GetRow(cur));
|
||
OnDataChanged();
|
||
return true;
|
||
}
|
||
}
|
||
return false;
|
||
}
|
||
bool WDGrid::DoInsertTree()
|
||
{
|
||
if(IsRowFixLength()||!IsTreeGrid())
|
||
return false;
|
||
if(rowSelList.GetLength()==1)
|
||
{
|
||
long cur=rowSelList[0];
|
||
WDGridTreeRow*pTreeRow=new WDGridTreeRow(*this);
|
||
pTreeRow->AppendChild();
|
||
WDGridRow*pRow=pTreeRow;
|
||
if(IsTreeGrid()&&GetRow(cur).IsChildRow())
|
||
{
|
||
WDGridTreeRow&curRow=GetTreeRow(cur);
|
||
WDGridTreeRow&parentRow=curRow.GetParent();
|
||
long iChild=parentRow.GetChildIndex(&curRow);
|
||
WDGridTreeRow*pChild=pTreeRow;
|
||
if(OnBeforeInsertChild(parentRow,iChild,pChild))
|
||
{
|
||
parentRow.InsertChild(iChild,pChild);
|
||
SelectRow(cur+1,false);
|
||
SelectRow(cur);
|
||
|
||
OnInsertRow(GetRow(cur));
|
||
OnDataChanged();
|
||
return true;
|
||
}
|
||
}
|
||
else if(OnBeforeInsertRow(cur,pRow))
|
||
{
|
||
InsertRow(cur,pRow);
|
||
SelectRow(cur+1,false);
|
||
SelectRow(cur);
|
||
|
||
OnInsertRow(GetRow(cur));
|
||
OnDataChanged();
|
||
return true;
|
||
}
|
||
}
|
||
return false;
|
||
}
|
||
bool WDGrid::DoInsertTreeAfter()
|
||
{
|
||
if(IsRowFixLength()||!IsTreeGrid())
|
||
return false;
|
||
if(rowSelList.GetLength()==1)
|
||
{
|
||
long cur=rowSelList[0]+1;
|
||
WDGridTreeRow*pTreeRow=new WDGridTreeRow(*this);
|
||
pTreeRow->AppendChild();
|
||
WDGridRow*pRow=pTreeRow;
|
||
if(IsTreeGrid()&&GetRow(cur-1).IsChildRow())
|
||
{
|
||
WDGridTreeRow&curRow=GetTreeRow(cur-1);
|
||
WDGridTreeRow&parentRow=curRow.GetParent();
|
||
long iChild=parentRow.GetChildIndex(&curRow)+1;
|
||
WDGridTreeRow*pChild=pTreeRow;
|
||
if(OnBeforeInsertChild(parentRow,iChild,pChild))
|
||
{
|
||
GetTreeRow(cur-1).Fold();
|
||
parentRow.InsertChild(iChild,pChild);
|
||
SelectRow(cur-1,false);
|
||
SelectRow(cur);
|
||
|
||
OnInsertRow(GetRow(cur));
|
||
OnDataChanged();
|
||
return true;
|
||
}
|
||
}
|
||
else if(OnBeforeInsertRow(cur,pRow))
|
||
{
|
||
if(IsTreeGrid())
|
||
GetTreeRow(cur-1).Fold();
|
||
InsertRow(cur,pRow);
|
||
SelectRow(cur-1,false);
|
||
SelectRow(cur);
|
||
|
||
OnInsertRow(GetRow(cur));
|
||
OnDataChanged();
|
||
return true;
|
||
}
|
||
}
|
||
return false;
|
||
}
|
||
bool WDGrid::DoAppendRow(bool bSel)
|
||
{
|
||
if(!IsRowFixLength())
|
||
{
|
||
WDGridRow*pRow=NULL;
|
||
long cur=GetRowNum();
|
||
if(OnBeforeInsertRow(cur,pRow))
|
||
{
|
||
UnSelect();//add on 050324
|
||
|
||
AppendRow(pRow);
|
||
if(bSel)
|
||
SelectRow(cur,true);
|
||
else if(!IsNoAppendButton())
|
||
ShowAppendRow();
|
||
|
||
OnInsertRow(GetRow(cur));
|
||
OnDataChanged();
|
||
return true;
|
||
}
|
||
}
|
||
return false;
|
||
}
|
||
bool WDGrid::DoAppendTree()
|
||
{
|
||
if(!IsRowFixLength()&&IsTreeGrid())
|
||
{
|
||
WDGridTreeRow*pTreeRow=new WDGridTreeRow(*this);
|
||
pTreeRow->AppendChild();
|
||
WDGridRow*pRow=pTreeRow;
|
||
long cur=GetRowNum();
|
||
if(OnBeforeInsertRow(cur,pRow))
|
||
{
|
||
AppendRow(pRow);
|
||
SelectRow(cur,true);
|
||
|
||
OnInsertRow(GetRow(cur));
|
||
OnDataChanged();
|
||
return true;
|
||
}
|
||
}
|
||
return false;
|
||
}
|
||
bool WDGrid::DoAppendChild()
|
||
{
|
||
if(IsTreeGrid()&&rowSelList.GetLength()==1&&!IsRowFixLength())
|
||
{
|
||
long cur=rowSelList[0];
|
||
WDGridTreeRow&treeRow=(WDGridTreeRow&)GetRow(cur);
|
||
if(treeRow.IsTreeRow())
|
||
{
|
||
WDGridTreeRow*pRow=NULL;
|
||
if(OnBeforeInsertChild(treeRow,treeRow.GetChildNum(),pRow))
|
||
{
|
||
treeRow.AppendChild(pRow);
|
||
SelectRow(cur,false);
|
||
treeRow.UnFold();
|
||
WDGridRow&newRow=treeRow.GetLastChild();
|
||
SelectRow(newRow.GetIndex(),true);
|
||
|
||
OnInsertRow(newRow);
|
||
OnDataChanged();
|
||
return true;
|
||
}
|
||
}
|
||
}
|
||
return false;
|
||
}
|
||
bool WDGrid::DoDelete()
|
||
{
|
||
if((IsRowSelected()&&!IsRowFixLength()))
|
||
{
|
||
FilterDelUnable();
|
||
if(OnBeforeDeleteRow())
|
||
{
|
||
TArray<long> rowSel(rowSelList);
|
||
ClearSel();
|
||
for(long i=rowSel.GetLastIndex();i>=0;i--)
|
||
DelRowEx(rowSel[i]);
|
||
|
||
OnEndDeleteRow();
|
||
OnDataChanged();
|
||
return true;
|
||
}
|
||
}
|
||
else if((IsColSelected()&&!IsColFixLength()))
|
||
{
|
||
if(OnBeforeDeleteCol())
|
||
{
|
||
TArray<long> colSel(colSelList);
|
||
ClearSel();
|
||
for(long i=colSel.GetLastIndex();i>=0;i--)
|
||
DelCol(colSel[i]);
|
||
|
||
OnEndDeleteCol();
|
||
OnDataChanged();
|
||
return true;
|
||
}
|
||
}
|
||
return false;
|
||
}
|
||
bool WDGrid::DoClip()
|
||
{
|
||
if(IsRowFixLength()||!OnBeforeClip())
|
||
return false;
|
||
FilterDelUnable();
|
||
ClipSelect();
|
||
|
||
OnEndClip();
|
||
OnDataChanged();
|
||
return true;
|
||
}
|
||
bool WDGrid::DoCopy()
|
||
{
|
||
if(!OnBeforeCopy())
|
||
return false;
|
||
|
||
pasteList.Clear();
|
||
for(rowSelList.MoveToFirst();!rowSelList.IsOut();rowSelList.MoveToNext())
|
||
{
|
||
WDGridRow*pRow=&GetRow(rowSelList.GetCurData());
|
||
if(pRow->IsTreeRow()&&((WDGridTreeRow*)pRow)->IsFold())
|
||
{
|
||
WDGridTreeRow*pNewRow=new WDGridTreeRow(*this);
|
||
*pNewRow=*((WDGridTreeRow*)pRow);
|
||
pNewRow->Fold();
|
||
pasteList.AddTail(pNewRow);
|
||
}
|
||
else
|
||
{
|
||
WDGridRow*pNewRow;
|
||
if(pRow->IsTreeRow())
|
||
pNewRow=new WDGridTreeRow(*this);
|
||
else
|
||
pNewRow=new WDGridRow(*this);
|
||
*pNewRow=*pRow;
|
||
pasteList.AddTail(pNewRow);
|
||
}
|
||
}
|
||
|
||
OnEndCopy();
|
||
return true;
|
||
}
|
||
bool WDGrid::DoPaste()
|
||
{
|
||
if(IsRowFixLength()||rowSelList.GetLength()>1||IsNoPaste()||pasteList.IsEmpty())
|
||
return false;
|
||
|
||
int i=rowSelList.IsEmpty()?GetRowNum():rowSelList[0];
|
||
if(!OnBeforePaste(i))
|
||
return false;
|
||
|
||
Paste(i);
|
||
|
||
OnEndPaste();
|
||
OnDataChanged();
|
||
return true;
|
||
}
|
||
bool WDGrid::DoPasteChild()
|
||
{
|
||
if(IsRowFixLength()||!IsTreeGrid()||rowSelList.GetLength()!=1||IsNoPaste()||pasteList.IsEmpty())
|
||
return false;
|
||
int i=rowSelList[0];
|
||
WDGridTreeRow&treeRow=GetTreeRow(i);
|
||
if(!OnBeforePasteChild(treeRow))
|
||
return false;
|
||
|
||
UnSelect();
|
||
|
||
treeRow.UnFold();
|
||
i+=treeRow.GetRowNum();
|
||
|
||
int num=pasteList.GetLength();
|
||
for(pasteList.MoveToFirst();!pasteList.IsEmpty();pasteList.MoveToNext())
|
||
{
|
||
treeRow.AppendChild((WDGridTreeRow*)pasteList.GetCurData());
|
||
pasteList.SetCurData(NULL);
|
||
pasteList.DelCur();
|
||
}
|
||
|
||
for(int j=0;j<num;j++)
|
||
SelectRow(i+j);
|
||
|
||
OnEndPaste();
|
||
OnDataChanged();
|
||
return true;
|
||
}
|
||
void WDGrid::OnKeyDown(UINT nChar, UINT nRepCnt, UINT nFlags)
|
||
{
|
||
bool bCtrl=(GetKeyState(VK_CONTROL)&-128)!=0;
|
||
switch(nChar)
|
||
{
|
||
case VK_RIGHT:
|
||
{
|
||
if(IsEditing()&&GetColNum()>1)
|
||
BeginEditCell(pSelCell->GetRowIndex(),(pSelCell->GetColIndex()+1)%GetColNum());
|
||
else if(colSelList.GetLength()==1&&GetColNum()>1)
|
||
{
|
||
long col=colSelList[0];
|
||
SelectCol(col,false);
|
||
SelectCol((col+1)%GetColNum());
|
||
}
|
||
else if(bHScroll)
|
||
OnHScroll(SB_LINEDOWN,0,NULL);
|
||
}
|
||
break;
|
||
case VK_LEFT:
|
||
{
|
||
if(IsEditing()&&GetColNum()>1)
|
||
BeginEditCell(pSelCell->GetRowIndex(),(pSelCell->GetColIndex()-1+GetColNum())%GetColNum());
|
||
else if(colSelList.GetLength()==1&&GetColNum()>1)
|
||
{
|
||
long col=colSelList[0];
|
||
SelectCol(col,false);
|
||
SelectCol((col-1+GetColNum())%GetColNum());
|
||
}
|
||
else if(bHScroll)
|
||
OnHScroll(SB_LINEUP,0,NULL);
|
||
}
|
||
break;
|
||
case VK_UP:
|
||
{
|
||
if(IsEditing())
|
||
{
|
||
if(IsNoAppendButton())
|
||
{
|
||
if(GetRowNum()>1)
|
||
BeginEditCell((pSelCell->GetRowIndex()-1+GetRowNum())%GetRowNum(),pSelCell->GetColIndex());
|
||
}
|
||
else if(GetRowNum()>0)
|
||
BeginEditCell((pSelCell->GetRowIndex()+GetRowNum())%(GetRowNum()+1),pSelCell->GetColIndex());
|
||
}
|
||
else if(rowSelList.GetLength()==1&&GetRowNum()>1)
|
||
{
|
||
long row=rowSelList[0];
|
||
SelectRow(row,false);
|
||
SelectRow((row-1+GetRowNum())%GetRowNum());
|
||
}
|
||
else if(bVScroll)
|
||
OnVScroll(SB_LINEUP,0,NULL);
|
||
}
|
||
break;
|
||
case VK_DOWN:
|
||
if(IsEditing())
|
||
{
|
||
if(IsNoAppendButton())
|
||
{
|
||
if(GetRowNum()>1)
|
||
BeginEditCell((pSelCell->GetRowIndex()+1)%GetRowNum(),pSelCell->GetColIndex());
|
||
}
|
||
else
|
||
{
|
||
if(pSelCell->GetRowIndex()==GetRowNum())
|
||
{
|
||
long oldNum=GetRowNum(),colIndex=pSelCell->GetColIndex();
|
||
EndEditCell();
|
||
if(GetRowNum()==oldNum)
|
||
DoAppendRow(false);
|
||
BeginEditCell(GetRowNum(),colIndex);
|
||
}
|
||
else
|
||
BeginEditCell(pSelCell->GetRowIndex()+1,pSelCell->GetColIndex());
|
||
}
|
||
}
|
||
else if(rowSelList.GetLength()==1&&GetRowNum()>1)
|
||
{
|
||
long row=rowSelList[0];
|
||
SelectRow(row,false);
|
||
SelectRow((row+1)%GetRowNum());
|
||
}
|
||
else if(bVScroll)
|
||
OnVScroll(SB_LINEDOWN,0,NULL);
|
||
break;
|
||
case VK_PRIOR:
|
||
if(bVScroll)
|
||
OnVScroll(SB_PAGEUP,0,NULL);
|
||
break;
|
||
case VK_NEXT:
|
||
if(bVScroll)
|
||
OnVScroll(SB_PAGEDOWN,0,NULL);
|
||
break;
|
||
case VK_DELETE:
|
||
DoDelete();
|
||
break;
|
||
case VK_INSERT://插入行或目录(带有一个子行),或插入列
|
||
if(IsRowSelected())
|
||
{
|
||
if(bCtrl)
|
||
DoInsertTree();
|
||
else
|
||
DoInsertRow();
|
||
}
|
||
else if(IsColSelected())
|
||
DoInsertCol();
|
||
break;
|
||
case 78://N,新建行或目录(带有一个子行),或新建列
|
||
if(IsColSelected())
|
||
DoInsertColAfter();
|
||
else if(IsRowSelected())
|
||
{
|
||
if(bCtrl)
|
||
DoInsertTreeAfter();
|
||
else
|
||
DoInsertRowAfter();
|
||
}
|
||
else
|
||
{
|
||
if(bCtrl)
|
||
DoAppendTree();
|
||
else
|
||
DoAppendRow();
|
||
}
|
||
break;
|
||
case 84://T,为树行新建一子行
|
||
DoAppendChild();
|
||
break;
|
||
case VK_TAB:
|
||
if(IsEditing())
|
||
{
|
||
if(GetColNum()>1)
|
||
BeginEditCell(pSelCell->GetRowIndex(),(pSelCell->GetColIndex()+1)%GetColNum());
|
||
else
|
||
EndEditCell();
|
||
}
|
||
break;
|
||
case VK_RETURN:
|
||
if(IsEditing())
|
||
{
|
||
if(IsNoAppendButton())
|
||
{
|
||
if(GetRowNum()>1)
|
||
BeginEditCell((pSelCell->GetRowIndex()+1)%GetRowNum(),pSelCell->GetColIndex());
|
||
else
|
||
EndEditCell();
|
||
}
|
||
else
|
||
{
|
||
if(pSelCell->GetRowIndex()==GetRowNum())
|
||
{
|
||
long oldNum=GetRowNum(),colIndex=pSelCell->GetColIndex();
|
||
EndEditCell();
|
||
if(GetRowNum()==oldNum)
|
||
DoAppendRow(false);
|
||
BeginEditCell(GetRowNum(),colIndex);
|
||
}
|
||
else
|
||
BeginEditCell(pSelCell->GetRowIndex()+1,pSelCell->GetColIndex());
|
||
}
|
||
}
|
||
else if(rowSelList.GetLength()==1&&GetColNum()>0)
|
||
BeginEditCell(rowSelList[0],0);
|
||
break;
|
||
case VK_ESCAPE:
|
||
if(IsEditing())
|
||
{
|
||
CancelEditCell();
|
||
SetFocus();
|
||
}
|
||
else
|
||
UnSelect();
|
||
break;
|
||
case VK_HOME:
|
||
{
|
||
int cx=bHScroll?GetLeft()-GetScrollPos(SB_HORZ):0;
|
||
int cy=bVScroll?GetTop()-GetScrollPos(SB_VERT):0;
|
||
MoveView(cx,cy);
|
||
}
|
||
break;
|
||
case 82://"R"
|
||
if(IsSortEnable())
|
||
Arrange();
|
||
break;
|
||
case 85://"U"
|
||
if(IsSortEnable())
|
||
Arrange(false);
|
||
break;
|
||
case 65://"A"
|
||
if(!IsSingleSelRow()||GetRowNum()==1)//可以多选或当前行只有一行
|
||
SelectAll();
|
||
break;
|
||
case 88://"X"
|
||
DoClip();
|
||
break;
|
||
case 86://"V"
|
||
if(bCtrl)
|
||
DoPasteChild();
|
||
else
|
||
DoPaste();
|
||
break;
|
||
case 67://"C"
|
||
DoCopy();
|
||
break;
|
||
}
|
||
CWnd::OnKeyDown(nChar, nRepCnt, nFlags);
|
||
}
|
||
BOOL WDGrid::PreTranslateMessage(MSG* pMsg)
|
||
{
|
||
if(pMsg->message==WM_KEYDOWN)
|
||
{
|
||
int nVirtKey = (int)pMsg->wParam; // virtual-key code
|
||
if(IsEditing())
|
||
{
|
||
if(nVirtKey==VK_RETURN||
|
||
nVirtKey==VK_ESCAPE||
|
||
nVirtKey==VK_PRIOR||
|
||
nVirtKey==VK_NEXT||
|
||
nVirtKey==VK_TAB||
|
||
(nVirtKey==VK_UP&&pCurEdit->IsUpEnd())||
|
||
(nVirtKey==VK_DOWN&&pCurEdit->IsDownEnd())||
|
||
(nVirtKey==VK_LEFT&&pCurEdit->IsLeftEnd())||
|
||
(nVirtKey==VK_RIGHT&&pCurEdit->IsRightEnd()))
|
||
{
|
||
OnKeyDown((UINT)nVirtKey,NULL,NULL);
|
||
return true;
|
||
}
|
||
}
|
||
else if(VK_TAB==nVirtKey&&GetFocus()==this)
|
||
{
|
||
GetParent()->SetFocus();
|
||
return true;
|
||
}
|
||
else if(nVirtKey==VK_RETURN||nVirtKey==VK_ESCAPE)
|
||
{
|
||
CWnd *pWnd=GetParent();
|
||
if(pWnd->IsKindOf(RUNTIME_CLASS(CDialog))||
|
||
pWnd->IsKindOf(RUNTIME_CLASS(CPropertySheet))||
|
||
pWnd->IsKindOf(RUNTIME_CLASS(CPropertyPage)))
|
||
{
|
||
pWnd->PostMessage(pMsg->message,pMsg->wParam,pMsg->lParam);
|
||
return true;
|
||
}
|
||
}
|
||
}
|
||
else if(pMsg->message==WM_COMMAND&&HIWORD(pMsg->wParam)==0)//菜单命令
|
||
{
|
||
switch(LOWORD(pMsg->wParam))
|
||
{
|
||
case ID_WDGRID_INS_ROW:
|
||
{
|
||
DoInsertRow();
|
||
return true;
|
||
}
|
||
case ID_WDGRID_DEL_ROW:
|
||
{
|
||
DoDelete();
|
||
return true;
|
||
}
|
||
case ID_WDGRID_ADD_ROW:
|
||
{
|
||
DoAppendRow();
|
||
return true;
|
||
}
|
||
case ID_WDGRID_SELECT_ALL:
|
||
{
|
||
SelectAll();
|
||
return true;
|
||
}
|
||
case ID_WDGRID_COPY_ROW:
|
||
{
|
||
DoCopy();
|
||
return true;
|
||
}
|
||
case ID_WDGRID_CUT_ROW:
|
||
{
|
||
DoClip();
|
||
return true;
|
||
}
|
||
case ID_WDGRID_PASTE_ROW:
|
||
{
|
||
DoPaste();
|
||
return true;
|
||
}
|
||
case ID_WDGRID_INS_COL:
|
||
{
|
||
DoInsertCol();
|
||
return true;
|
||
}
|
||
case ID_WDGRID_DEL_COL:
|
||
{
|
||
DoDelete();
|
||
return true;
|
||
}
|
||
case ID_WDGRID_ADD_COL:
|
||
{
|
||
DoAppendCol();
|
||
return true;
|
||
}
|
||
}
|
||
}
|
||
return CWnd::PreTranslateMessage(pMsg);
|
||
}
|
||
BOOL WDGrid::OnSetCursor(CWnd* pWnd, UINT nHitTest, UINT message)
|
||
{
|
||
BOOL result=CWnd::OnSetCursor(pWnd, nHitTest, message);
|
||
return result;
|
||
}
|
||
BOOL WDGrid::OnEraseBkgnd(CDC* pDC)
|
||
{
|
||
if(bVScroll&&bHScroll)
|
||
return true;
|
||
return CWnd::OnEraseBkgnd(pDC);
|
||
}
|
||
INT_PTR WDGrid::OnToolHitTest(CPoint point,TOOLINFO*pTI)const
|
||
{
|
||
CString sTip;
|
||
long row,col;
|
||
((WDGrid*)this)->PtToCell(point,row,col);
|
||
if(IsValidRow(row)&&IsValidCol(col)&&OnCellTip(row,col,sTip))
|
||
{
|
||
pTI->hwnd = m_hWnd;
|
||
pTI->uId =(UINT_PTR)m_hWnd;
|
||
pTI->uFlags |= TTF_IDISHWND|TTF_NOTBUTTON|TTF_ALWAYSTIP;
|
||
pTI->lpszText=new TCHAR[20];
|
||
wsprintf(pTI->lpszText,sTip);
|
||
return row*10+col;
|
||
}
|
||
return -1;
|
||
}
|
||
|
||
void WDGrid::OnRClickRow(WDGridRow &row, CPoint point)
|
||
{
|
||
if(IsNoDefaultMenu()||IsReadOnly()||IsRowFixLength())
|
||
return;
|
||
|
||
CMenu popup;
|
||
popup.CreatePopupMenu();
|
||
|
||
if(GetRowSelNum() > 1 && IsRowSelected(row.GetIndex()))
|
||
{
|
||
popup.AppendMenu(MF_STRING, ID_WDGRID_DEL_ROW, _T("删除(Del)"));
|
||
popup.AppendMenu(MF_STRING, ID_WDGRID_ADD_ROW, _T("新建行(N)"));
|
||
if(!IsNoPaste())
|
||
{
|
||
popup.AppendMenu(MF_STRING, ID_WDGRID_COPY_ROW, _T("复制(C)"));
|
||
popup.AppendMenu(MF_STRING, ID_WDGRID_CUT_ROW, _T("剪切(X)"));
|
||
}
|
||
}
|
||
else
|
||
{
|
||
UnSelect();
|
||
SelectRow(row.GetIndex(), true);
|
||
popup.AppendMenu(MF_STRING, ID_WDGRID_INS_ROW, _T("插入行(Ins)"));
|
||
if(!row.IsDelUnable())
|
||
popup.AppendMenu(MF_STRING, ID_WDGRID_DEL_ROW, _T("删除行(Del)"));
|
||
popup.AppendMenu(MF_STRING, ID_WDGRID_ADD_ROW, _T("新建行(N)"));
|
||
if(!IsNoPaste())
|
||
{
|
||
popup.AppendMenu(MF_STRING, ID_WDGRID_COPY_ROW, _T("复制(C)"));
|
||
popup.AppendMenu(MF_STRING, ID_WDGRID_CUT_ROW, _T("剪切(X)"));
|
||
if(GetRowSelNum() == 1 && pasteList.GetDataNum() > 0)
|
||
popup.AppendMenu(MF_STRING, ID_WDGRID_PASTE_ROW, _T("粘贴(V)"));
|
||
}
|
||
}
|
||
|
||
popup.TrackPopupMenu(TPM_LEFTALIGN | TPM_RIGHTBUTTON, point.x, point.y, this);
|
||
}
|
||
void WDGrid::OnRClickCol(WDGridCol &col, CPoint point)
|
||
{
|
||
if(IsNoDefaultMenu()||IsReadOnly()||IsColFixLength())
|
||
return;
|
||
|
||
CMenu popup;
|
||
popup.CreatePopupMenu();
|
||
|
||
if(GetColSelNum() > 1 && IsColSelected(col.GetIndex()))
|
||
{
|
||
popup.AppendMenu(MF_STRING, ID_WDGRID_DEL_COL, _T("删除(Del)"));
|
||
popup.AppendMenu(MF_STRING, ID_WDGRID_ADD_COL, _T("新建列(N)"));
|
||
}
|
||
else
|
||
{
|
||
UnSelect();
|
||
SelectCol(col.GetIndex(), true);
|
||
popup.AppendMenu(MF_STRING, ID_WDGRID_INS_COL, _T("插入列(Ins)"));
|
||
popup.AppendMenu(MF_STRING, ID_WDGRID_DEL_COL, _T("删除列(Del)"));
|
||
popup.AppendMenu(MF_STRING, ID_WDGRID_ADD_COL, _T("新建列(N)"));
|
||
}
|
||
|
||
popup.TrackPopupMenu(TPM_LEFTALIGN | TPM_RIGHTBUTTON, point.x, point.y, this);
|
||
}
|
||
void WDGrid::OnRClickQuad(CPoint point)
|
||
{
|
||
if(IsNoDefaultMenu()||IsReadOnly()||IsRowFixLength())
|
||
return;
|
||
|
||
CMenu popup;
|
||
popup.CreatePopupMenu();
|
||
if(!IsRowSelected())
|
||
{
|
||
UnSelect();
|
||
popup.AppendMenu(MF_STRING, ID_WDGRID_ADD_ROW, _T("新建行(N)"));
|
||
if(pasteList.GetDataNum() > 0)
|
||
popup.AppendMenu(MF_STRING, ID_WDGRID_PASTE_ROW, _T("粘贴(V)"));
|
||
}
|
||
else
|
||
{
|
||
popup.AppendMenu(MF_STRING, ID_WDGRID_DEL_ROW, _T("删除(Del)"));
|
||
popup.AppendMenu(MF_STRING, ID_WDGRID_ADD_ROW, _T("新建行(N)"));
|
||
popup.AppendMenu(MF_STRING, ID_WDGRID_COPY_ROW, _T("复制(C)"));
|
||
popup.AppendMenu(MF_STRING, ID_WDGRID_CUT_ROW, _T("剪切(X)"));
|
||
if(GetRowSelNum() == 1 && pasteList.GetDataNum() > 0)
|
||
popup.AppendMenu(MF_STRING, ID_WDGRID_PASTE_ROW, _T("粘贴(V)"));
|
||
}
|
||
if(!IsEmpty())
|
||
popup.AppendMenu(MF_STRING, ID_WDGRID_SELECT_ALL, _T("全选(A)"));
|
||
|
||
popup.TrackPopupMenu(TPM_LEFTALIGN | TPM_RIGHTBUTTON, point.x, point.y, this);
|
||
}
|
||
//////////////////////////////////////////////////////////////////////////////////////////////
|
||
bool WCellCtrl::IsMyFocus(CWnd*pNewWnd)
|
||
{
|
||
return pNewWnd==GetWnd()||GetWnd()->IsChild(pNewWnd);
|
||
}
|
||
void WCellCtrl::Destroy()
|
||
{
|
||
GetWnd()->DestroyWindow();
|
||
}
|
||
void WCellCtrl::Hide()
|
||
{
|
||
GetWnd()->ShowWindow(SW_HIDE);
|
||
GetWnd()->EnableWindow(FALSE);
|
||
}
|
||
//WCellEdit
|
||
BEGIN_MESSAGE_MAP(WCellEdit, CEdit)
|
||
ON_WM_KILLFOCUS()
|
||
ON_WM_SETFOCUS()
|
||
END_MESSAGE_MAP()
|
||
WCellEdit::WCellEdit(WDGridCell&c):WCellCtrl(c)
|
||
{
|
||
}
|
||
CWnd* WCellEdit::GetWnd()
|
||
{
|
||
return this;
|
||
}
|
||
void WCellEdit::Create(CRect&rect)
|
||
{
|
||
WDGrid&grid=cell.GetGrid();
|
||
int style=WS_VISIBLE|WS_CHILD|WS_CLIPCHILDREN | WS_CLIPSIBLINGS|ES_AUTOHSCROLL|ES_MULTILINE;
|
||
if(cell.GetCol().IsCenterAlign())
|
||
style|=ES_CENTER;
|
||
CEdit::Create(style,CRect(0,0,0,0),&grid,101);
|
||
SetFont(&grid.GetFont());
|
||
rect.left+=2;//首字符与左边界间隔2象素。
|
||
SetWindowPos(NULL,rect.left,rect.top,rect.Width(),rect.Height(),SWP_SHOWWINDOW);
|
||
GetClientRect(&rect);
|
||
rect.top+=grid.GetRowSpace();
|
||
SetRect(&rect);
|
||
SetWindowText(cell.GetText());
|
||
SetSel(0,-1);
|
||
SetFocus();
|
||
}
|
||
bool WCellEdit::IsModified()
|
||
{
|
||
return GetModify()==TRUE;
|
||
}
|
||
void WCellEdit::SetModified(bool bM)
|
||
{
|
||
if(bM)
|
||
CEdit::SetModify();
|
||
else
|
||
CEdit::SetModify(FALSE);
|
||
}
|
||
void WCellEdit::SetNewText(const TCHAR*text)
|
||
{
|
||
SetWindowText(text);
|
||
}
|
||
void WCellEdit::GetNewText(CString&text)
|
||
{
|
||
GetWindowText(text);
|
||
}
|
||
bool WCellEdit::IsLeftEnd()
|
||
{
|
||
int s,e;
|
||
GetSel(s,e);
|
||
return e==0;
|
||
}
|
||
bool WCellEdit::IsRightEnd()
|
||
{
|
||
int s,e;
|
||
GetSel(s,e);
|
||
return e==LineLength();
|
||
}
|
||
bool WCellEdit::IsUpEnd()
|
||
{
|
||
return true;
|
||
}
|
||
bool WCellEdit::IsDownEnd()
|
||
{
|
||
return true;
|
||
}
|
||
void WCellEdit::PostNcDestroy()
|
||
{
|
||
delete this;
|
||
}
|
||
void WCellEdit::OnKillFocus(CWnd*pNewWnd)
|
||
{
|
||
WDGrid&grid=cell.GetGrid();
|
||
if(IsMyFocus(pNewWnd))
|
||
return;
|
||
CEdit::OnKillFocus(pNewWnd);
|
||
if(!grid.IsMyFocus(pNewWnd))
|
||
grid.ShowActive(false);
|
||
grid.EndEditCell();
|
||
}
|
||
void WCellEdit::OnSetFocus(CWnd*pOldWnd)
|
||
{
|
||
WDGrid&grid=cell.GetGrid();
|
||
CEdit::OnSetFocus(pOldWnd);
|
||
grid.ShowActive();
|
||
}
|
||
////////////////////////////////////////////////////////////////////////////////////////
|
||
void WCellButton::SetCellEdit(WCellCtrl *pEdit)
|
||
{
|
||
pCellEdit=pEdit;
|
||
}
|
||
bool WCellButton::Create()
|
||
{
|
||
CWnd*pParent=pCellEdit->GetWnd();
|
||
CRect rect;
|
||
pParent->GetClientRect(&rect);
|
||
if(rect.Height()>rect.Width())
|
||
return false;
|
||
rect.left=rect.Width()-rect.Height();
|
||
if(CButton::Create(_T(""),WS_CHILD|WS_VISIBLE|WS_BORDER,rect,pParent,105))
|
||
{
|
||
EnableToolTips();
|
||
return true;
|
||
}
|
||
return false;
|
||
}
|
||
|
||
INT_PTR WCellButton::OnToolHitTest(CPoint point,TOOLINFO*pTI)const
|
||
{
|
||
CString sTip;
|
||
WDGridCell &cell=pCellEdit->GetCell();
|
||
if(cell.GetGrid().OnCellButtonTip(cell.GetRowIndex(),cell.GetColIndex(),sTip))
|
||
{
|
||
pTI->hwnd = m_hWnd;
|
||
pTI->uId =(UINT_PTR)m_hWnd;
|
||
pTI->uFlags |= TTF_IDISHWND|TTF_NOTBUTTON|TTF_ALWAYSTIP|TTF_CENTERTIP;
|
||
pTI->lpszText=new TCHAR[20];
|
||
wsprintf(pTI->lpszText,sTip);
|
||
return cell.GetRowIndex();
|
||
}
|
||
return -1;
|
||
}
|
||
BEGIN_MESSAGE_MAP(WCellButton, CButton)
|
||
ON_CONTROL_REFLECT(BN_CLICKED, OnBnClicked)
|
||
END_MESSAGE_MAP()
|
||
void WCellButton::OnBnClicked()
|
||
{
|
||
WDGridCell& cell=pCellEdit->GetCell();
|
||
WDGrid&grid=cell.GetGrid();
|
||
CString text;
|
||
pCellEdit->GetNewText(text);
|
||
if(grid.OnCellButtonDown(cell,text))
|
||
{
|
||
pCellEdit->SetNewText(text);
|
||
pCellEdit->SetModified();
|
||
}
|
||
Invalidate();
|
||
pCellEdit->GetWnd()->SetFocus();
|
||
}
|
||
WCellButtonEdit::WCellButtonEdit(WDGridCell&c):WCellEdit(c)
|
||
{
|
||
button.SetCellEdit(this);
|
||
}
|
||
void WCellButtonEdit::Create(CRect&rect)
|
||
{
|
||
int h=rect.Height();
|
||
WCellEdit::Create(rect);
|
||
if(rect.Width()>h)//防止按钮遮挡
|
||
{
|
||
rect.right-=h;
|
||
SetRect(&rect);
|
||
}
|
||
button.Create();
|
||
}
|
||
//////////////////////////////////////////////////////////////////////////////////////////////
|
||
void WCellSpin::SetCellEdit(WCellCtrl*pEdit)
|
||
{
|
||
pCellEdit=pEdit;
|
||
}
|
||
bool WCellSpin::Create()
|
||
{
|
||
CWnd*pParent=pCellEdit->GetWnd();
|
||
CRect rect;
|
||
pParent->GetClientRect(&rect);
|
||
if(rect.Height()>rect.Width())
|
||
return false;
|
||
rect.left=rect.Width()-rect.Height();
|
||
return CSpinButtonCtrl::Create(WS_CHILD|WS_VISIBLE,rect,pParent,105)==TRUE;
|
||
}
|
||
WCellSpinEdit::WCellSpinEdit(WDGridCell&c):WCellEdit(c)
|
||
{
|
||
spin.SetCellEdit(this);
|
||
}
|
||
void WCellSpinEdit::Create(CRect&rect)
|
||
{
|
||
int h=rect.Height();
|
||
WCellEdit::Create(rect);
|
||
if(rect.Width()>h)//防止按钮遮挡
|
||
{
|
||
rect.right-=h;
|
||
SetRect(&rect);
|
||
}
|
||
spin.Create();
|
||
WDGrid&grid=cell.GetGrid();
|
||
spin.SetRange32(0,100000);
|
||
grid.OnCellSpinInit(cell,spin);
|
||
int s,e;
|
||
spin.GetRange32(s,e);
|
||
int cur=_ttoi(cell);
|
||
if(cur>=s&&cur<=e)
|
||
spin.SetPos(cur);
|
||
else
|
||
spin.SetPos(s);
|
||
}
|
||
BEGIN_MESSAGE_MAP(WCellSpinEdit,WCellEdit)
|
||
ON_WM_VSCROLL()
|
||
ON_CONTROL_REFLECT(EN_CHANGE, OnEnChange)
|
||
END_MESSAGE_MAP()
|
||
void WCellSpinEdit::OnVScroll(UINT nSBCode, UINT nPos, CScrollBar* pScrollBar)
|
||
{
|
||
WCellEdit::OnVScroll(nSBCode, nPos, pScrollBar);
|
||
CString temp;
|
||
temp.Format(_T("%d"),nPos);
|
||
SetNewText(temp);
|
||
SetModified();
|
||
SetSel(0,-1);
|
||
}
|
||
void WCellSpinEdit::OnEnChange()
|
||
{
|
||
if(spin.GetSafeHwnd()==NULL)
|
||
return;
|
||
CString temp;
|
||
GetNewText(temp);
|
||
int cur=_ttoi(temp);
|
||
int s,e;
|
||
spin.GetRange32(s,e);
|
||
if(cur>=s&&cur<=e)
|
||
spin.SetPos(cur);
|
||
}
|
||
//////////////////////////////////////////////////////////////////////////////////////////////
|
||
//WCellCombo
|
||
BEGIN_MESSAGE_MAP(WCellCombo, CComboBox)
|
||
ON_CONTROL_REFLECT(CBN_KILLFOCUS, OnCbnKillfocus)
|
||
ON_CONTROL_REFLECT(CBN_SETFOCUS, OnCbnSetfocus)
|
||
ON_CONTROL_REFLECT(CBN_EDITCHANGE, OnCbnEditchange)
|
||
ON_CONTROL_REFLECT(CBN_SELCHANGE, OnCbnSelchange)
|
||
END_MESSAGE_MAP()
|
||
WCellCombo::WCellCombo(WDGridCell&c,bool bE):WCellCtrl(c),bEditable(bE)
|
||
{
|
||
}
|
||
void WCellCombo::Create(CRect&rect)
|
||
{
|
||
WDGrid&grid=cell.GetGrid();
|
||
bModified=false;
|
||
CRect rect1(rect.left-1,rect.top-1,rect.left+rect.Width(),rect.top-1+12*rect.Height());
|
||
if(bEditable)
|
||
CComboBox::Create(WS_VISIBLE|WS_CHILD|WS_VSCROLL|CBS_DROPDOWN,rect1,&grid,101);
|
||
else
|
||
CComboBox::Create(WS_VISIBLE|WS_CHILD|WS_VSCROLL|CBS_AUTOHSCROLL|CBS_DROPDOWNLIST,rect1,&grid,101);
|
||
SetItemHeight(-1,grid.GetRowHeight()-4);
|
||
grid.OnCellComboString(cell,*this);
|
||
SetFont(&grid.GetFont());
|
||
if(!bEditable)
|
||
SetCurSel(FindString(-1,cell.GetText()));
|
||
SetWindowText(cell.GetText());
|
||
SetFocus();
|
||
}
|
||
void WCellCombo::GetNewText(CString&text)
|
||
{
|
||
GetWindowText(text);
|
||
}
|
||
bool WCellCombo::IsModified()
|
||
{
|
||
return bModified;
|
||
}
|
||
CWnd* WCellCombo::GetWnd()
|
||
{
|
||
return this;
|
||
}
|
||
bool WCellCombo::IsLeftEnd()
|
||
{
|
||
if(!bEditable)
|
||
return true;
|
||
DWORD sel=GetEditSel();
|
||
return HIWORD(sel)==0;
|
||
}
|
||
bool WCellCombo::IsRightEnd()
|
||
{
|
||
if(!bEditable)
|
||
return true;
|
||
DWORD sel=GetEditSel();
|
||
CString s;
|
||
GetWindowText(s);
|
||
return HIWORD(sel)==s.GetLength();
|
||
}
|
||
bool WCellCombo::IsUpEnd()
|
||
{
|
||
return false;
|
||
}
|
||
bool WCellCombo::IsDownEnd()
|
||
{
|
||
return false;
|
||
}
|
||
void WCellCombo::PostNcDestroy()
|
||
{
|
||
delete this;
|
||
}
|
||
void WCellCombo::OnCbnKillfocus()
|
||
{
|
||
WDGrid&grid=cell.GetGrid();
|
||
if(!grid.IsMyFocus(GetFocus()))
|
||
grid.ShowActive(false);
|
||
grid.EndEditCell();
|
||
}
|
||
void WCellCombo::OnCbnSetfocus()
|
||
{
|
||
cell.GetGrid().ShowActive();
|
||
}
|
||
void WCellCombo::OnCbnEditchange()
|
||
{
|
||
bModified=true;
|
||
}
|
||
void WCellCombo::OnCbnSelchange()
|
||
{
|
||
bModified=true;
|
||
}
|
||
///////////////////////////////////////////////////////////////////////////////////////////////
|
||
//WDGActiveQuad
|
||
BEGIN_MESSAGE_MAP(WDGActiveQuad, CWnd)
|
||
ON_WM_PAINT()
|
||
ON_WM_LBUTTONDOWN()
|
||
ON_WM_LBUTTONDBLCLK()
|
||
ON_WM_RBUTTONUP()
|
||
END_MESSAGE_MAP()
|
||
WDGActiveQuad::WDGActiveQuad(WDGrid&g):grid(g),bActive(false)
|
||
{
|
||
CWnd::Create(NULL,NULL,WS_VISIBLE|WS_CHILD,
|
||
CRect(0,0,grid.GetRowHeight(),grid.GetColHeaderHeight()),&grid,102);
|
||
EnableToolTips();
|
||
}
|
||
INT_PTR WDGActiveQuad::OnToolHitTest(CPoint point,TOOLINFO*pTI)const
|
||
{
|
||
CString sTip;
|
||
if(grid.OnActiveQuadTip(sTip))
|
||
{
|
||
pTI->hwnd = m_hWnd;
|
||
pTI->uId =(UINT_PTR)m_hWnd;
|
||
pTI->uFlags |= TTF_IDISHWND|TTF_NOTBUTTON|TTF_ALWAYSTIP|TTF_CENTERTIP;
|
||
pTI->lpszText=new TCHAR[20];
|
||
wsprintf(pTI->lpszText,sTip);
|
||
return 0;
|
||
}
|
||
return -1;
|
||
}
|
||
void WDGActiveQuad::OnPaint()
|
||
{
|
||
CPaintDC dc(this);
|
||
CRect rect;
|
||
GetClientRect(&rect);
|
||
if(grid.IsFlatButton())
|
||
dc.Draw3dRect(&rect,RGB(240,240,240),RGB(80,80,80));
|
||
else
|
||
dc.DrawFrameControl(&rect,DFCS_BUTTON3STATE,0);
|
||
rect.left+=1;
|
||
rect.top+=1;
|
||
rect.right-=2;
|
||
rect.bottom-=2;
|
||
dc.FillSolidRect(&rect,GetSysColor(bActive?COLOR_ACTIVECAPTION:COLOR_3DFACE));
|
||
}
|
||
void WDGActiveQuad::OnLButtonDblClk(UINT nFlags,CPoint point)
|
||
{
|
||
grid.SetFocus();
|
||
bActive=true;
|
||
Invalidate();
|
||
grid.SelectAll();
|
||
CWnd::OnLButtonDblClk(nFlags,point);
|
||
}
|
||
void WDGActiveQuad::OnRButtonUp(UINT nFlags, CPoint point)
|
||
{
|
||
CWnd::OnRButtonUp(nFlags,point);
|
||
grid.SetFocus();
|
||
ClientToScreen(&point);
|
||
grid.OnRClickQuad(point);
|
||
}
|
||
void WDGActiveQuad::OnLButtonDown(UINT nFlags,CPoint point)
|
||
{
|
||
grid.SetFocus();
|
||
bActive=true;
|
||
Invalidate();
|
||
CWnd::OnLButtonDown(nFlags,point);
|
||
}
|
||
//////////////////////////////////////////////////////////////////////////////////////////////
|
||
//WColSelector
|
||
WColSelector::WColSelector(WDGrid&g):grid(g),bDragCol(false),bDragEdge(false)
|
||
{
|
||
brush.CreateSolidBrush(GetSysColor(COLOR_3DFACE));
|
||
const TCHAR* pszClassName
|
||
= AfxRegisterWndClass(CS_HREDRAW|CS_VREDRAW|CS_SAVEBITS|CS_DBLCLKS,
|
||
LoadCursor(NULL,IDC_ARROW),HBRUSH(brush.GetSafeHandle()));
|
||
CRect rect(0,0,10000,grid.GetColHeaderHeight());
|
||
if(grid.IsRowSel())
|
||
rect.left=grid.GetRowHeight();
|
||
CWnd::Create(pszClassName,NULL,WS_VISIBLE|WS_CHILD,rect,&grid,103);
|
||
EnableToolTips();
|
||
}
|
||
BEGIN_MESSAGE_MAP(WColSelector, CWnd)
|
||
ON_WM_PAINT()
|
||
ON_WM_LBUTTONDOWN()
|
||
ON_WM_MOUSEMOVE()
|
||
ON_WM_SETCURSOR()
|
||
ON_WM_LBUTTONUP()
|
||
ON_WM_RBUTTONUP()
|
||
END_MESSAGE_MAP()
|
||
INT_PTR WColSelector::OnToolHitTest(CPoint point,TOOLINFO*pTI)const
|
||
{
|
||
CString sTip;
|
||
long col=PtToCol(point);
|
||
if(grid.IsValidCol(col)&&grid.OnColTip(col,sTip))
|
||
{
|
||
pTI->hwnd = m_hWnd;
|
||
pTI->uId =(UINT_PTR)m_hWnd;
|
||
pTI->uFlags |= TTF_IDISHWND|TTF_NOTBUTTON|TTF_ALWAYSTIP;
|
||
pTI->lpszText=new TCHAR[20];
|
||
wsprintf(pTI->lpszText,sTip);
|
||
return col;
|
||
}
|
||
return -1;
|
||
}
|
||
|
||
void WColSelector::OnPaint()
|
||
{
|
||
//其坐标系横向与grid重合
|
||
CPaintDC dc(this); // device context for painting
|
||
CPoint pt;
|
||
grid.GetUpCorner(pt);
|
||
if(grid.IsRowSel())
|
||
dc.SetViewportOrg(pt.x-grid.GetRowHeight(),0);//对齐。
|
||
else
|
||
dc.SetViewportOrg(pt.x,0);//对齐。
|
||
long colNum=grid.GetColNum();
|
||
for(long i=0;i<colNum;i++)
|
||
{
|
||
WDGridCol&col=grid.GetCol(i);
|
||
CRect rect(col.GetLeft(),0,col.GetRight(),grid.GetColHeaderHeight());
|
||
if(grid.IsFlatButton())
|
||
dc.Draw3dRect(rect,RGB(240,240,240),RGB(80,80,80));
|
||
else
|
||
dc.DrawFrameControl(&rect,DFCS_BUTTON3STATE,0);
|
||
dc.SetTextColor(RGB(0,0,0));
|
||
dc.SetBkMode(TRANSPARENT);
|
||
rect.bottom--;
|
||
rect.top=grid.GetRowSpace();//行与上边界线的空隙
|
||
rect.left+=2;//首字符与左边界间隔2象素。
|
||
dc.SelectObject(&grid.GetFont());
|
||
int style;
|
||
if(col.IsCenterAlign())
|
||
style=DT_CENTER|DT_TOP|DT_EDITCONTROL;
|
||
else
|
||
style=DT_LEFT|DT_TOP|DT_EDITCONTROL;
|
||
dc.DrawText((const TCHAR*)(col.GetName()),&rect,style);
|
||
}
|
||
}
|
||
|
||
void WColSelector::OnLButtonDown(UINT nFlags, CPoint point)
|
||
{
|
||
SetFocus();
|
||
SetCapture();
|
||
CClientDC dc(this); // device context for painting
|
||
CPoint pt;
|
||
grid.GetUpCorner(pt);
|
||
if(grid.IsRowSel())
|
||
dc.SetViewportOrg(pt.x-grid.GetRowHeight(),0);//对齐。
|
||
else
|
||
dc.SetViewportOrg(pt.x,0);//对齐。
|
||
dc.DPtoLP(&point);
|
||
if(!grid.IsColFixWidth())
|
||
{
|
||
for(long i=0;i<grid.GetColNum();i++)
|
||
{
|
||
WDGridCol&col=grid.GetCol(i);
|
||
if(point.x==col.GetRight()-1||point.x==col.GetRight())
|
||
{
|
||
dragColIndex=i;
|
||
oldPoint.x=-1;
|
||
bDragEdge=true;
|
||
}
|
||
}
|
||
}
|
||
if(!bDragEdge)
|
||
{
|
||
dc.LPtoDP(&point);
|
||
long col=PtToCol(point);
|
||
if(grid.IsValidCol(col))
|
||
{
|
||
bool bCtrl=(GetKeyState(VK_CONTROL)&-128)!=0;
|
||
bool bShift=(GetKeyState(VK_SHIFT)&-128)!=0;
|
||
if(grid.IsColSelected(col))
|
||
{
|
||
if(!bCtrl&&!grid.IsColPosFix())
|
||
{
|
||
bDragCol=grid.IsSelConnect()&&grid.OnBeginMoveCol();
|
||
oldPoint.x=-1;
|
||
}
|
||
else if(bCtrl)
|
||
grid.SelectCol(col,false);
|
||
}
|
||
else
|
||
{
|
||
if(bShift)
|
||
{
|
||
TDualPtrList<long>&selList=grid.colSelList;
|
||
if(selList.GetLength()==1)
|
||
{
|
||
if(selList[0]>col)
|
||
for(long i=selList[0]-1;i>=col;i--)
|
||
grid.SelectCol(i);
|
||
else
|
||
for(long i=selList[0]+1;i<=col;i++)
|
||
grid.SelectCol(i);
|
||
}
|
||
}
|
||
else if(bCtrl)
|
||
grid.SelectCol(col);
|
||
else
|
||
{
|
||
grid.UnSelect();
|
||
grid.SelectCol(col);
|
||
}
|
||
}
|
||
}
|
||
}
|
||
CWnd::OnLButtonDown(nFlags, point);
|
||
}
|
||
void WColSelector::OnRButtonUp(UINT nFlags, CPoint point)
|
||
{
|
||
CWnd::OnRButtonUp(nFlags,point);
|
||
grid.SetFocus();
|
||
long col;
|
||
col=PtToCol(point);
|
||
if(grid.IsValidCol(col))
|
||
{
|
||
ClientToScreen(&point);
|
||
if(!grid.IsColSelected(col))
|
||
{
|
||
grid.UnSelect();
|
||
grid.SelectCol(col);
|
||
}
|
||
grid.OnRClickCol(grid.GetCol(col),point);
|
||
}
|
||
}
|
||
void WColSelector::OnMouseMove(UINT nFlags, CPoint point)
|
||
{
|
||
if(bDragEdge||bDragCol)
|
||
{
|
||
if(grid.bHScroll)
|
||
{
|
||
CRect rect;
|
||
grid.GetClientRect(&rect);
|
||
int cx=0;
|
||
if(grid.GetScrollPos(SB_HORZ)!=grid.GetLeft())
|
||
{
|
||
int col=PtToCol(point);
|
||
if(grid.IsValidCol(col))
|
||
{
|
||
CPoint pt0(grid.GetCol(col).GetLeft(),0);
|
||
grid.GetDC().LPtoDP(&pt0);
|
||
if(pt0.x<rect.left)
|
||
cx=grid.GetCol(col).GetWidth();
|
||
}
|
||
}
|
||
if(grid.IsRowSel())
|
||
{
|
||
rect.left-=grid.GetRowHeight();
|
||
rect.right-=grid.GetRowHeight();
|
||
}
|
||
if(point.x>=rect.right)
|
||
{
|
||
grid.MoveView(5,0);
|
||
grid.UpdateWindow();
|
||
return;
|
||
}
|
||
else if(point.x<=rect.left+cx)
|
||
{
|
||
grid.MoveView(-5,0);
|
||
grid.UpdateWindow();
|
||
return;
|
||
}
|
||
}
|
||
|
||
CClientDC dc(this); // device context for painting
|
||
CPoint pt;
|
||
grid.GetUpCorner(pt);
|
||
if(grid.IsRowSel())
|
||
dc.SetViewportOrg(pt.x-grid.GetRowHeight(),0);//对齐。
|
||
else
|
||
dc.SetViewportOrg(pt.x,0);//对齐。
|
||
|
||
CDC&gdc=grid.GetDC();
|
||
if(bDragCol)
|
||
{
|
||
SetCursor(LoadCursor(NULL,IDC_SIZEWE));
|
||
long col=PtToCol(point);
|
||
if(col>=0&&col<=grid.GetColNum()&&grid.OnMovingCol(col))
|
||
{
|
||
if(col==grid.GetColNum())
|
||
point.x=grid.GetRight();
|
||
else
|
||
point.x=grid.GetCol(col).GetLeft();
|
||
if(point.x!=oldPoint.x)
|
||
{
|
||
if(oldPoint.x!=-1)
|
||
gdc.InvertRect(CRect(oldPoint.x,0,oldPoint.x+3,10000));
|
||
gdc.InvertRect(CRect(point.x,0,point.x+3,10000));
|
||
oldPoint=point;
|
||
}
|
||
}
|
||
}
|
||
else
|
||
{
|
||
dc.DPtoLP(&point);
|
||
gdc.InvertRect(CRect(oldPoint.x,0,oldPoint.x+1,10000));
|
||
gdc.InvertRect(CRect(point.x,0,point.x+1,10000));
|
||
oldPoint=point;
|
||
}
|
||
}
|
||
CWnd::OnMouseMove(nFlags, point);
|
||
}
|
||
BOOL WColSelector::OnSetCursor(CWnd* pWnd, UINT nHitTest, UINT message)
|
||
{
|
||
if(!grid.IsColFixWidth())
|
||
{
|
||
CPoint point;
|
||
GetCursorPos(&point);
|
||
ScreenToClient(&point);
|
||
CClientDC dc(this); // device context for painting
|
||
CPoint pt;
|
||
grid.GetUpCorner(pt);
|
||
if(grid.IsRowSel())
|
||
dc.SetViewportOrg(pt.x-grid.GetRowHeight(),0);//对齐。
|
||
else
|
||
dc.SetViewportOrg(pt.x,0);//对齐。
|
||
dc.DPtoLP(&point);
|
||
for(long i=0;i<grid.GetColNum();i++)
|
||
{
|
||
WDGridCol&col=grid.GetCol(i);
|
||
if(point.x==col.GetRight()-1||point.x==col.GetRight())
|
||
{
|
||
SetCursor(LoadCursor(NULL,IDC_SIZEWE));
|
||
return true;
|
||
}
|
||
}
|
||
}
|
||
return CWnd::OnSetCursor(pWnd, nHitTest, message);
|
||
}
|
||
void WColSelector::OnLButtonUp(UINT nFlags, CPoint point)
|
||
{
|
||
ReleaseCapture();
|
||
if(bDragEdge||bDragCol)
|
||
{
|
||
CClientDC dc(this); // device context for painting
|
||
CPoint pt;
|
||
grid.GetUpCorner(pt);
|
||
if(grid.IsRowSel())
|
||
dc.SetViewportOrg(pt.x-grid.GetRowHeight(),0);//对齐。
|
||
else
|
||
dc.SetViewportOrg(pt.x,0);//对齐。
|
||
|
||
CDC&gdc=grid.GetDC();
|
||
if(oldPoint.x!=-1)
|
||
{
|
||
if(bDragCol)
|
||
gdc.InvertRect(CRect(oldPoint.x,0,oldPoint.x+3,10000));
|
||
else
|
||
gdc.InvertRect(CRect(oldPoint.x,0,oldPoint.x+1,10000));
|
||
}
|
||
if(bDragEdge)
|
||
{
|
||
dc.DPtoLP(&point);
|
||
TPDList<WDGridCol>&colList=grid.colList;
|
||
colList.MoveTo(dragColIndex);
|
||
if(point.x>colList.GetCurData()->GetLeft()+1)
|
||
{
|
||
int cx=point.x-colList.GetCurData()->GetRight();
|
||
colList.GetCurData()->SetRight(point.x);
|
||
for(colList.MoveToNext();!colList.IsOut();colList.MoveToNext())
|
||
colList.GetCurData()->Move(cx);
|
||
grid.RecalcLayout();
|
||
}
|
||
bDragEdge=false;
|
||
}
|
||
else
|
||
{
|
||
long destCol=PtToCol(point);
|
||
if(destCol>=0&&destCol<=grid.GetColNum()&&
|
||
grid.OnMoveCol(destCol))
|
||
{
|
||
TDualPtrList<long>&selList=grid.colSelList;
|
||
long firstCol=selList[0];
|
||
long lastCol=selList[selList.GetLastIndex()];
|
||
long col;
|
||
if(destCol<firstCol)
|
||
{
|
||
for(selList.MoveToFirst(),col=firstCol;col<=lastCol;selList.MoveToNext(),col++)
|
||
{
|
||
grid.MoveCol(col,destCol+col-firstCol);
|
||
selList.SetCurData(destCol+col-firstCol);
|
||
}
|
||
Invalidate();
|
||
|
||
grid.OnEndMoveCol();
|
||
grid.OnDataChanged();
|
||
}
|
||
else if(destCol>lastCol+1)
|
||
{
|
||
for(col=lastCol;col>=firstCol;col--)
|
||
grid.MoveCol(col,destCol+col-lastCol);
|
||
for(selList.MoveToFirst();!selList.IsOut();selList.MoveToNext())
|
||
selList.SetCurData(selList.GetCurData()+destCol-lastCol-1);
|
||
Invalidate();
|
||
|
||
grid.OnEndMoveCol();
|
||
grid.OnDataChanged();
|
||
}
|
||
}
|
||
bDragCol=false;
|
||
}
|
||
oldPoint.x=-1;
|
||
}
|
||
grid.SetFocus();
|
||
CWnd::OnLButtonUp(nFlags, point);
|
||
}
|
||
///////////////////////////////////////////////////////////////////////////////////////////////
|
||
//WRowSelector
|
||
WRowSelector::WRowSelector(WDGrid&g):grid(g),bDragRow(false),oldPoint(0,-1),m_iCurRow(-1)
|
||
{
|
||
brush.CreateSolidBrush(GetSysColor(COLOR_3DFACE));
|
||
const TCHAR* pszClassName
|
||
= AfxRegisterWndClass(CS_HREDRAW|CS_VREDRAW|CS_SAVEBITS|CS_DBLCLKS,
|
||
LoadCursor(NULL,IDC_ARROW),HBRUSH(brush.GetSafeHandle()));
|
||
CRect rect(0,0,grid.GetRowHeight(),10000);
|
||
if(grid.IsColSel())
|
||
rect.top=grid.GetColHeaderHeight();
|
||
CWnd::Create(pszClassName,NULL,WS_VISIBLE|WS_CHILD,rect,&grid,104);
|
||
EnableToolTips();
|
||
}
|
||
BEGIN_MESSAGE_MAP(WRowSelector, CWnd)
|
||
ON_WM_PAINT()
|
||
ON_WM_LBUTTONDOWN()
|
||
ON_WM_MOUSEMOVE()
|
||
ON_WM_LBUTTONUP()
|
||
ON_WM_RBUTTONUP()
|
||
ON_WM_LBUTTONDBLCLK()
|
||
END_MESSAGE_MAP()
|
||
void WRowSelector::OnLButtonDblClk(UINT nFlags,CPoint point)
|
||
{
|
||
CWnd::OnLButtonDblClk(nFlags,point);
|
||
long row=PtToRow(point);
|
||
if(grid.IsValidRow(row))
|
||
grid.OnDblClick(grid.GetRow(row));
|
||
}
|
||
INT_PTR WRowSelector::OnToolHitTest(CPoint point,TOOLINFO*pTI)const
|
||
{
|
||
CString sTip;
|
||
long row=PtToRow(point);
|
||
if(grid.IsValidRow(row)&&grid.OnRowTip(row,sTip))
|
||
{
|
||
pTI->hwnd = m_hWnd;
|
||
pTI->uId =(UINT_PTR)m_hWnd;
|
||
pTI->uFlags |= TTF_IDISHWND|TTF_NOTBUTTON|TTF_ALWAYSTIP|TTF_CENTERTIP;
|
||
pTI->lpszText=new TCHAR[20];
|
||
wsprintf(pTI->lpszText,sTip);
|
||
return row;
|
||
}
|
||
return -1;
|
||
}
|
||
void WRowSelector::OnPaint()
|
||
{
|
||
CAcModuleResourceOverride vTemp;
|
||
//其坐标系纵向与grid重合
|
||
CPaintDC dc(this); // device context for painting
|
||
CPoint pt;
|
||
grid.GetUpCorner(pt);
|
||
if(grid.IsColSel())
|
||
dc.SetViewportOrg(0,pt.y-grid.GetColHeaderHeight());//对齐。
|
||
else
|
||
dc.SetViewportOrg(0,pt.y);//对齐。
|
||
int rowHeight=grid.GetRowHeight();
|
||
long rowNum=grid.GetRowNum();
|
||
for(long i=0;i<rowNum;i++)
|
||
{
|
||
CRect rect(0,i*rowHeight,rowHeight,(i+1)*rowHeight);
|
||
if(grid.IsFlatButton())
|
||
dc.Draw3dRect(&rect,RGB(240,240,240),RGB(80,80,80));
|
||
else
|
||
dc.DrawFrameControl(&rect,DFCS_BUTTON3STATE,0);
|
||
|
||
if(i==m_iCurRow)
|
||
DrawIconEx(dc.GetSafeHdc(),0,i*rowHeight,AfxGetApp()->LoadIcon(IDI_CUR_ROW),rowHeight,rowHeight,
|
||
NULL,NULL,DI_NORMAL);
|
||
}
|
||
|
||
if(!grid.IsNoAppendButton())
|
||
{
|
||
CRect rect(0,i*rowHeight,rowHeight,(i+1)*rowHeight);
|
||
if(grid.IsFlatButton())
|
||
dc.Draw3dRect(&rect,RGB(240,240,240),RGB(80,80,80));
|
||
else
|
||
dc.DrawFrameControl(&rect,DFCS_BUTTON3STATE,0);
|
||
DrawIconEx(dc.GetSafeHdc(),0,i*rowHeight,AfxGetApp()->LoadIcon(IDI_LAST_ROW),rowHeight,rowHeight,
|
||
NULL,NULL,DI_NORMAL);
|
||
}
|
||
}
|
||
void WRowSelector::OnCurRowChanged()
|
||
{
|
||
// add by gjm
|
||
if (!::IsWindowVisible(grid.GetSafeHwnd()))
|
||
return;
|
||
//其坐标系纵向与grid重合
|
||
CClientDC dc(this); // device context for painting
|
||
CPoint pt;
|
||
grid.GetUpCorner(pt);
|
||
if(grid.IsColSel())
|
||
dc.SetViewportOrg(0,pt.y-grid.GetColHeaderHeight());//对齐。
|
||
else
|
||
dc.SetViewportOrg(0,pt.y);//对齐。
|
||
int rowHeight=grid.GetRowHeight();
|
||
if(grid.IsValidRow(m_iCurRow))
|
||
{
|
||
long i=m_iCurRow;
|
||
CRect rect(0,i*rowHeight,rowHeight,(i+1)*rowHeight);
|
||
if(grid.IsFlatButton())
|
||
dc.Draw3dRect(&rect,RGB(240,240,240),RGB(80,80,80));
|
||
else
|
||
dc.DrawFrameControl(&rect,DFCS_BUTTON3STATE,0);
|
||
}
|
||
|
||
m_iCurRow=grid.GetCurRowIndex();
|
||
if(grid.IsValidRow(m_iCurRow))
|
||
{
|
||
long i=m_iCurRow;
|
||
CRect rect(0,i*rowHeight,rowHeight,(i+1)*rowHeight);
|
||
if(grid.IsFlatButton())
|
||
dc.Draw3dRect(&rect,RGB(240,240,240),RGB(80,80,80));
|
||
else
|
||
dc.DrawFrameControl(&rect,DFCS_BUTTON3STATE,0);
|
||
DrawIconEx(dc.GetSafeHdc(),0,i*rowHeight,AfxGetApp()->LoadIcon(IDI_CUR_ROW),rowHeight,rowHeight,
|
||
NULL,NULL,DI_NORMAL);
|
||
}
|
||
}
|
||
void WRowSelector::OnRButtonUp(UINT nFlags, CPoint point)
|
||
{
|
||
//CWnd::OnRButtonUp(nFlags,point);
|
||
grid.SetFocus();
|
||
|
||
long row=PtToRow(point);
|
||
if(grid.IsValidRow(row))
|
||
{
|
||
ClientToScreen(&point);
|
||
if(!grid.IsRowSelected(row))
|
||
{
|
||
grid.UnSelect();
|
||
grid.SelectRow(row);
|
||
}
|
||
grid.OnRClickRow(grid.GetRow(row),point);
|
||
}
|
||
}
|
||
void WRowSelector::OnLButtonDown(UINT nFlags, CPoint point)
|
||
{
|
||
long row=PtToRow(point);
|
||
if(grid.IsNewRow(row)&&!grid.IsNoAppendButton())
|
||
{
|
||
grid.EndEditCell();
|
||
if(grid.GetRowNum()==row)
|
||
grid.DoAppendRow(false);
|
||
else
|
||
grid.ShowAppendRow();
|
||
return;
|
||
}
|
||
|
||
SetFocus();
|
||
SetCapture();
|
||
if(grid.IsValidRow(row))
|
||
{
|
||
bool bCtrl=!grid.IsSingleSelRow()&&(GetKeyState(VK_CONTROL)&-128)!=0;
|
||
bool bShift=!grid.IsSingleSelRow()&&(GetKeyState(VK_SHIFT)&-128)!=0;
|
||
if(grid.IsRowSelected(row))
|
||
{
|
||
if(!bCtrl&&!grid.IsRowPosFix())
|
||
{
|
||
//选择集中树行必须全部折叠、且不包含禁上删除行。
|
||
bDragRow=grid.IsSelFold()&&!grid.IsSelDelUnable()&&grid.OnBeginMoveRow();
|
||
oldPoint.y=-1;
|
||
if(bDragRow)
|
||
rowStart=row;
|
||
}
|
||
else if(bCtrl)
|
||
grid.SelectRow(row,false);
|
||
}
|
||
else
|
||
{
|
||
if(bShift)
|
||
{
|
||
TDualPtrList<long>&selList=grid.rowSelList;
|
||
if(grid.IsSelConnect())
|
||
{
|
||
if(selList[0]>row)
|
||
for(long i=selList[0]-1;i>=row;i--)
|
||
grid.SelectRow(i);
|
||
else if(selList[selList.GetLastIndex()]<row)
|
||
for(long i=selList[selList.GetLastIndex()]+1;i<=row;i++)
|
||
grid.SelectRow(i);
|
||
}
|
||
}
|
||
else if(bCtrl)
|
||
grid.SelectRow(row);
|
||
else
|
||
{
|
||
grid.UnSelect();
|
||
grid.SelectRow(row);
|
||
}
|
||
}
|
||
}
|
||
else
|
||
grid.UnSelect();
|
||
|
||
CWnd::OnLButtonDown(nFlags, point);
|
||
}
|
||
void WRowSelector::OnMouseMove(UINT nFlags, CPoint point)
|
||
{
|
||
int rowHeight=grid.GetColHeaderHeight();
|
||
if(bDragRow)
|
||
{
|
||
if(grid.bVScroll)
|
||
{
|
||
CRect rect;
|
||
grid.GetClientRect(&rect);
|
||
int cy=grid.GetRowHeight();
|
||
if(grid.GetScrollPos(SB_VERT)==grid.GetTop())
|
||
cy=0;
|
||
if(grid.IsColSel())
|
||
{
|
||
rect.top-=rowHeight;
|
||
rect.bottom-=rowHeight;
|
||
}
|
||
if(point.y>=rect.bottom)
|
||
{
|
||
grid.MoveView(0,5);
|
||
grid.UpdateWindow();
|
||
return;
|
||
}
|
||
else if(point.y<=rect.top+cy)
|
||
{
|
||
grid.MoveView(0,-5);
|
||
grid.UpdateWindow();
|
||
return;
|
||
}
|
||
}
|
||
SetCursor(LoadCursor(NULL,IDC_SIZENS));
|
||
CClientDC dc(this); // device context for painting
|
||
CPoint pt;
|
||
grid.GetUpCorner(pt);
|
||
if(grid.IsColSel())
|
||
dc.SetViewportOrg(0,pt.y-rowHeight);//对齐。
|
||
else
|
||
dc.SetViewportOrg(0,pt.y);//对齐。
|
||
|
||
long row=PtToRow(point);
|
||
if(row!=rowStart//目标行与起始行不能相同
|
||
&&row>=0&&row<=grid.GetRowNum()&&grid.OnMovingRow(row))
|
||
{
|
||
if(row==grid.GetRowNum())
|
||
{
|
||
if(grid.IsNoAppendButton())
|
||
point.y=grid.GetBottom();
|
||
else
|
||
point.y=grid.GetBottom()-grid.GetRowHeight();
|
||
}
|
||
else
|
||
point.y=grid.GetRow(row).GetTop();
|
||
if(point.y!=oldPoint.y)
|
||
{
|
||
CDC&gdc=grid.GetDC();
|
||
if(oldPoint.y!=-1)
|
||
gdc.InvertRect(CRect(0,oldPoint.y,10000,oldPoint.y+3));
|
||
gdc.InvertRect(CRect(0,point.y,10000,point.y+3));
|
||
oldPoint=point;
|
||
}
|
||
}
|
||
}
|
||
CWnd::OnMouseMove(nFlags, point);
|
||
}
|
||
void WRowSelector::OnLButtonUp(UINT nFlags,CPoint point)
|
||
{
|
||
ReleaseCapture();
|
||
if(bDragRow)
|
||
{
|
||
CClientDC dc(this); // device context for painting
|
||
CPoint pt;
|
||
grid.GetUpCorner(pt);
|
||
if(grid.IsColSel())
|
||
dc.SetViewportOrg(0,pt.y-grid.GetColHeaderHeight());//对齐。
|
||
else
|
||
dc.SetViewportOrg(0,pt.y);//对齐。
|
||
|
||
CDC&gdc=grid.GetDC();
|
||
if(oldPoint.y!=-1)
|
||
gdc.InvertRect(CRect(0,oldPoint.y,10000,oldPoint.y+3));
|
||
|
||
long destRow=PtToRow(point);
|
||
if(destRow!=rowStart//目标行与起始行不能相同
|
||
&&destRow>=0&&destRow<=grid.GetRowNum()&&
|
||
grid.OnMoveRow(destRow))
|
||
{
|
||
TTable<long>& selList=grid.rowSelList;
|
||
long count=0;
|
||
for(selList.MoveToLast();!selList.IsOut();selList.MoveToPre())
|
||
if(selList.GetCurData()<destRow)
|
||
{
|
||
count=selList.GetCur()+1;
|
||
break;
|
||
}
|
||
TPDList<WDGridRow> backup;
|
||
backup.Conbine(grid.pasteList);
|
||
grid.ClipSelect();
|
||
grid.Paste(destRow-count);
|
||
grid.pasteList.Conbine(backup);
|
||
|
||
grid.OnEndMoveRow();
|
||
grid.OnDataChanged();
|
||
}
|
||
|
||
bDragRow=false;
|
||
oldPoint.y=-1;
|
||
}
|
||
grid.SetFocus();
|
||
CWnd::OnLButtonUp(nFlags,point);
|
||
}
|