// XTable.cpp : implementation file
#include "stdafx.h"
#include "YLGL.h"
#include "XTable.h"
#include "InputDate.h"
#include "MemDC.h"
#include "TodayForm2.h"
#define XTABLE_CLASSNAME    _T("XTableCtrl")  // Window class name

#ifdef _DEBUG
#define new DEBUG_NEW
#endif
// XTable

IMPLEMENT_DYNAMIC(XTable, CWnd)
BEGIN_MESSAGE_MAP(XTable, CWnd)
	ON_WM_PAINT()
	ON_WM_KEYDOWN()
	ON_WM_LBUTTONDOWN()
	ON_WM_LBUTTONDBLCLK()
	ON_MESSAGE(WM_USER_EDIT_END,OnEditEnd) 
	ON_WM_ERASEBKGND()
END_MESSAGE_MAP()
XTable::XTable(int rows, int cols)
{
	RegisterWindowClass ();

	defaultCell.table = this;

	defaultHeight = 20;
	defaultWidth = 80;

	cells = NULL;
	rowHeight = NULL;
	colWidth = NULL;

	this->rows = 0;
	this->cols = 0;
	SetRows (rows);
	SetCols (cols);	

	focusRow = 0;
	focusCol = 0;
	m_bFocusFrame=1;
	m_nCurShow=-1;
	m_nticks=::GetTickCount ();
	m_mode=0;
}

XTable::~XTable()
{
	if(cells)delete [] cells;
	if(rowHeight)delete [] rowHeight;
	if(colWidth)delete [] colWidth;
}

// creates the control - use like any other window create control
BOOL XTable::Create(const RECT& rect, CWnd* pParentWnd, UINT nID, DWORD dwStyle)
{
    ASSERT(pParentWnd->GetSafeHwnd());

    if (!CWnd::Create(XTABLE_CLASSNAME, NULL, dwStyle, rect, pParentWnd, nID))
        return FALSE;

    return TRUE;
}

int XTable::ToXML (CMarkup& markup)
{
	markup.AddChildElem ("table");
	markup.AddChildAttr("border", "1"); 

	markup.IntoElem (); 

	for (int i = 0; i < GetRows (); i ++)
	{
		markup.AddChildElem ("tr");
		markup.IntoElem(); 
		for (int j = 0; j < GetCols (); j ++)
		{
			XCell* cell = GetCells (i, j);

			if (cell->colSpan > 0 && cell->rowSpan > 0)
			{
				markup.AddChildElem ("td");

				if (cell->colSpan == 1 && i == 0)
					markup.AddChildAttr ("width", GetColWidth (j));

				if (cell->rowSpan == 1 && j == 0)
					markup.AddChildAttr ("height", GetRowHeight (i));

				cell->ToXML (markup);
			}
		}
		markup.OutOfElem();
	}

	markup.OutOfElem();

	return 0;
}

int XTable::FromXML (CMarkup& markup)
{
	markup.IntoElem ();

	int maxCol = 0;
	int maxRow = 0;
	int row = 0;
	int col = 0;

	SetCols (MAX_COLS);
	SetRows (MAX_ROWS);
	while (markup.FindChildElem("tr"))
	{
		markup.IntoElem();

		col = 0;
		while (markup.FindChildElem("td"))
		{
			XCell* cell;
			
			while (true)
			{
				cell = GetCells (row, col);

				if (!cell) 
					break;

				if (cell->colSpan >= 1 && cell->rowSpan >= 1)
					break;

				col ++;
			}

			cell->FromXML (markup);

			if (cell->colSpan > 1 || cell->rowSpan > 1)
				JoinCells (row, col, row+cell->rowSpan-1, col+cell->colSpan-1);

			if (cell->colSpan == 1 && markup.GetChildAttr("width") != "")
			{
				int width = atoi (markup.GetChildAttr("width"));
				if (row == 0 || width > GetColWidth(col))
					SetColWidth (col, width);
			}
			if (cell->rowSpan == 1 && markup.GetChildAttr("height") != "")
			{
				int height = atoi (markup.GetChildAttr("height"));
				if (col == 0 || height > GetRowHeight(row))
					SetRowHeight (row, height);
			}

			col += cell->colSpan;
			if (col > maxCol) maxCol = col;

			if (row + cell->rowSpan > maxRow) maxRow = row + cell->rowSpan;
		}

		markup.OutOfElem();

		row ++;
	}

	markup.OutOfElem();
	
	SetRows (maxRow);
	SetCols (maxCol);

	return 0;
}

int XTable::SetRows(int newRows)
{
	if (rows < 0 || rows > MAX_ROWS) return -1;
	
	if (rows == newRows) return 0;

	int cellsSize = cols * rows;

	XCell* newCells =  cells;
	int* newRowHeight = new int [newRows];

	if ( rows < newRows)
	{
		if (cellsSize < newRows * cols)
		{
			cellsSize *= 2;
			if (cellsSize < newRows * cols)
				cellsSize = newRows * cols;

			newCells = new XCell [cellsSize];

			//���ƾ�����
			for (int i = 0; i < rows; i++)
			{
				for(int j = 0; j < cols ; j++)
				{
					newCells [i * cols +j] = cells [i * cols +j];
				}

				newRowHeight [i] = rowHeight [i];
			}
		}

		//��ʼ��������
		for (int i = rows; i < newRows; i++)
		{
			for (int j = 0; j < cols; j++)
			{
				newCells [i * cols + j] = defaultCell;
				newCells [i * cols + j].SetSpan (1, 1);
			}

			newRowHeight [i] = defaultHeight; 
		}

		delete [] rowHeight;
		rowHeight = newRowHeight;
	}
	else
	{
		if (cellsSize > newRows * cols * 2) 
		{
			cellsSize = newRows * cols;

			newCells = new XCell [cellsSize];
		}

		//��������
		for (int i = 0; i < newRows; i ++)
		{
			for (int j = 0; j < cols; j++)
				newCells [i * cols + j] = cells[i * cols +j];
		}
	}

	if (newCells != cells)
	{
		delete [] cells;
		cells = newCells;
	}

	rows = newRows;

	return 0;   
}

int XTable::GetRows()
{
	return rows;
}

int XTable::SetCols(int newCols)
{
	if (newCols < 0 || newCols > MAX_COLS) return -1;

	if (this->cols == newCols) return 0;

	int cellsSize = cols * rows;

	XCell* newCells =  cells;
	int* newColWidth = new int [newCols];

	if ( cols < newCols)
	{
		if (cellsSize < newCols * rows)
		{
			cellsSize *= 2;
			if (cellsSize < newCols * rows)
				cellsSize = newCols * rows;

			newCells = new XCell [cellsSize];

			//���ƾ�����
			for (int i = 0; i < rows; i++)
			{
				for(int j = 0; j < cols ; j++)
				{
					newCells [i * newCols +j] = cells [i * cols +j];
					newColWidth[j] = colWidth [j];
				}
			}
		}
		//��ʼ��������
		for (int i = 0; i < rows; i++)
		{
			for (int j = cols; j < newCols; j++)
			{
				newCells [i * newCols + j] = defaultCell;
				newCells [i * newCols + j].SetSpan (1, 1);
				newColWidth[j] = defaultWidth;
			}
		}

		delete [] colWidth;
		colWidth = newColWidth;
	}
	else
	{
		if (cellsSize > newCols * rows * 2) 
		{
			cellsSize = newCols * rows;

			newCells = new XCell [cellsSize];
		}

		//��������
 		for (int i = 0; i < rows; i ++)
		{
			for (int j = 0; j <  newCols; j++)
				newCells [i * newCols + j] = cells[i * cols +j];
		}
	}


	if (newCells != cells)
	{
		delete [] cells;
		cells = newCells;
	}

	cols = newCols;

	return 0;
}

int XTable::GetCols()
{
	return cols;
}

int XTable::JoinCells (int startRow, int startCol, int endRow, int endCol)
{
	if (startRow < 0 || startRow >= rows) return -1;
	if (endRow < 0 || startRow >= rows) return -1;

	if (startCol < 0 || startCol >= cols) return -1;
	if (endCol < 0 || endCol >= cols) return -1;

	if (startRow > endRow || startCol > endCol) return -1;

	for (int i = startRow; i <= endRow; i++)
	{
		for (int j = startCol; j <=endCol;  j++)
		{
			cells [i * cols + j].SetSpan(0,0);
		}
	}
	
	cells [startRow * cols + startCol].SetSpan(endRow - startRow+1, endCol - startCol+1);
	
	return 0;
}

int XTable::UnjoinCells (int row, int col)
{
	if (row < 0 || row >= this->rows) return -1;
	if (col < 0 || col >= this->cols) return -1;

	if (cells [row * cols + col].rowSpan <= 1 && cells [row * cols + col].colSpan <= 1 ) return -1;

	for (int i = row; i <= row + cells [row * cols + col].rowSpan; i++)
	{
		for (int j = col; j <= cells [row * cols + col].colSpan; j++)
		{
			cells[i*cols+j] = defaultCell;

			cells [i * cols + j].SetSpan(1,1);
		}
	}

	return 0;
}

int XTable::SetRowHeight(int row, int height)
{
	rowHeight [row] = height;

	return 0;
}

int XTable::GetRowHeight(int row)
{
	return rowHeight [row];
}

int XTable::SetColWidth(int col, int width)
{
	colWidth [col] = width;

	return 0;
}

int XTable::GetColWidth(int col)
{
	return colWidth [col];
}

int XTable::GetRowsHeight(int startRow, int endRow)
{
	if (startRow < 0 || startRow >= rows) return -1;
	if (endRow < 0 || endRow >= rows) return -1;
	if (startRow > endRow) return -1;

	int height = 0;
	for (int i = startRow; i <= endRow; i++)
	{
		height += rowHeight[i];
	}

	return height;
}

int XTable::GetColsWidth(int startCol, int endCol)
{
	if (startCol < 0 || startCol >= cols) return -1;
	if (endCol < 0 || endCol >= cols) return -1;
	if (startCol > endCol) return -1;

	int width = 0;
	for (int i = startCol; i <= endCol; i++)
	{
		width += colWidth[i];
	}

	return width;
}

int XTable::SetCells(int row, int col, XCell& cell)
{
	cells[row * cols + col] = cell;

	return 0;
}

XCell* XTable::GetCells(int row, int col)
{
	return &cells [row * cols + col];
}

int XTable::SetText(int row, int col, CString str)
{

	XCell* cell = GetCells (row, col);
	if (!cell) return -1;

	return cell->SetText (str);
}

CString XTable::GetText(int row, int col)
{
	return	cells[row * cols + col].GetText();
}

int XTable::SetTextColor(int row, int col, COLORREF color)
{
	cells[row * cols + col].SetTextColor(color);

	return 0;
}

COLORREF XTable::GetTextColor(int row, int col)
{
	return 	cells[row * cols + col].GetTextColor();
}

int XTable::SetTextFont(int row, int col, CFont& font)
{
	cells[row * cols + col].SetTextFont(&font);

	return 0;

}
CFont* XTable::GetTextFont(int row, int col)
{
	return	cells[row * cols + col].GetTextFont();
}

int XTable::SetTextFontSize(int row, int col, int size)
{
	cells[row * cols + col].SetTextFontSize(size);

	return 0;
}

int XTable::GetTextFontSize(int row, int col)
{
	return 	cells[row * cols + col].GetTextFontSize();
}

int XTable::SetOverlap (int row, int col, bool enable)
{
	XCell* cell = GetCells (row, col);
	if (!cell) return -1;

	return cell->SetOverlap (enable);
}

bool XTable::GetOverlap (int row, int col)
{
	XCell* cell = GetCells (row, col);
	if (!cell) return false;

	return cell->GetOverlap ();
}

int XTable::SetAlignment (int row, int col, int align)
{
	XCell* cell = GetCells (row, col);
	if (!cell) return -1;

	return cell->SetAlignment (align);
}

int XTable::GetAlignment (int row, int col)
{
	XCell* cell = GetCells (row, col);
	if (!cell) return -1;

	return cell->GetAlignment ();
}

int XTable::SetWordbreak (int row, int col, bool wordbreak)
{
	XCell* cell = GetCells (row, col);
	if (!cell) return -1;

	return cell->SetWordbreak (wordbreak);
}

bool XTable::GetWordbreak (int row, int col)
{
	XCell* cell = GetCells (row, col);
	if (!cell) return false;

	return cell->GetWordbreak ();
}

int XTable::SetBackColor(int row, int col, COLORREF color)
{
	cells[row * cols + col].SetBackColor(color);

	return 0;
}

COLORREF XTable::GetBackColor(int row, int col)
{
	return 	cells[row * cols + col].GetBackColor();
}

int XTable::SetBackMode(int row, int col, int mode)
{
	cells[row * cols + col].SetBackMode(mode);

	return 0;
}

int XTable::GetBackMode(int row, int col)
{
	return 	cells[row * cols + col].GetBackMode();
}

RECT XTable::GetRect(int row, int col)
{
	RECT rect;
	try
	{
	int rowSpan = GetCells(row, col)->rowSpan;
	int colSpan = GetCells(row, col)->colSpan;
	rect.top = GetRowsHeight(0, row-1);
	rect.left = GetColsWidth(0, col-1);

	rect.bottom = rect.top + GetRowsHeight (row, row + rowSpan-1);
	rect.right = rect.left + GetColsWidth (col, col + colSpan-1);
	}
	catch(...)
	{
	}
	return rect;
}

bool XTable::HitTest (CPoint point, int& row, int& col)
{
	try
	{
	for (int i= 0; i < rows; i++) 
	{
		for(int j=0; j < rows; j++)
		{
			RECT rect = GetRect (i,j);
			if (rect.top <= point.y && rect.bottom > point.y && rect.left <= point.x && rect.right > point.x)
			{
				row = i;
				col = j;

				return true;
			}
		}
	}
	}
	catch(...)
	{
	}
	return false;
}

void XTable::OnDraw(CDC* pDC)
{
	static bool lock = false;

	if (lock) return;

	if (!::IsWindow(m_hWnd)) return;

	lock = true;

	Draw (pDC);

	lock = false;
}

int XTable::Draw(CDC* pDC)
{
	try
	{
	for (int i = 0; i < rows; i++)
	{
		for (int j = 0; j < cols; j++)
		{
			XCell& cell = cells[i*cols+j];

			if (cell.colSpan !=0 && cell.rowSpan != 0)
			{
				RECT rect = GetRect(i,j);

				if (cell.GetOverlap())
				{
					RECT textRect = GetRect(i,j);

					cell.CalcTextRect(pDC, &textRect);

					if (textRect.right > rect.right)
					{
						for (j = j+1; j < cols; j ++)
						{
							if (cells[i*cols+j].text != "")
								break;
							rect.right += colWidth [j];
							if (rect.right > textRect.right)
								break;
						}
						j --;
					}

				}

				cell.Draw(pDC,rect);
			}
		}
	}
 
	if (focusCol && m_bFocusFrame && focusRow < rows && focusCol < cols) //**
	{
		RECT rect = GetRect (focusRow, 1);
		RECT rect2 = GetRect (focusRow, cols-1);
		RECT rect3=rect;
		if(rect2.right>rect3.right)
		rect3.right =rect2.right ;
		GetCells (focusRow, focusCol)->DrawHitBorder(pDC, rect3, RGB(255, 0, 20));
	}
	}
	catch(...)
	{
	}
	return 0;
}

// XTable message handlers
void XTable::OnPaint()
{
	CPaintDC dc(this);      // device context for painting

	CMemDC MemDC(&dc);
	OnDraw(&MemDC);
}

BOOL XTable::OnEraseBkgnd(CDC* pDC)
{
	return TRUE;
}


void XTable::OnKeyDown(UINT nChar, UINT nRepCnt, UINT nFlags)
{
	CPoint point;

	RECT rect = GetRect(focusRow,focusCol);
	point.x = rect.left;
	point.y = rect.top;

	switch (nChar)
	{
		case VK_DOWN:
			point.y =rect.bottom + 1;
			break;

		case VK_UP:
			point.y =point.y -2;
			break;

		case VK_LEFT:
			point.x = point.x - 2;
			break;

		case VK_RIGHT:
			point.x =rect.right + 1;
			break;

		default:
			return ;
	}

	HitTest (point,focusRow,focusCol);
	Invalidate();
	
	CWnd::OnKeyDown(nChar, nRepCnt, nFlags);
}

void XTable::OnLButtonDown(UINT nFlags, CPoint point)
{
	::PostMessage(this->GetSafeHwnd(),WM_USER_EDIT_END,1,1);
	if(!m_bFocusFrame)return;
	HitTest (point,focusRow,focusCol);
	
	SetFocus ();
	Invalidate();

	CWnd::OnLButtonDown(nFlags, point);
}
void XTable::OnEditEnd(WPARAM wParam,LPARAM lParam)
{
	if(m_nCurShow==-1)return;
	int nAdd=0;
	if(m_mode==4)nAdd=1;

	if(m_nCurShow==0)
	{
	if(wParam == TRUE)
	{
		CString strText(_T(""));
		m_edit.GetWindowText(strText);
		DWORD dwData = m_edit.GetCtrlData();
		int nItem= dwData>>16;
		int nIndex = dwData&0x0000ffff;
		CString oldtext=GetText(nItem,nIndex);
		SetText(nItem,nIndex,strText);
		AddName(nItem,11+nAdd, g_user.name);
	//	SetText(nItem,11+nAdd, g_user.name);

		if(nIndex==9+nAdd)
		{
		if(atoi(GetText(nItem,9+nAdd))>0 )
			{
				SetBackColor (nItem,9+nAdd, RGB(255,0,0));
			}
			else  SetBackColor (nItem,9+nAdd, RGB(0,255,0));
		}
		if(nIndex==12+nAdd)
		{
		   if(GetText(nItem,12+nAdd)=="�" )
			{
				SetBackColor (nItem,12+nAdd, RGB(255,0,0));
			}
			else  
				SetBackColor (nItem,12+nAdd, RGB(0,255,0));
		}



		if(oldtext!=strText)
		   Save(nItem);

	}   
	m_edit.ShowWindow(SW_HIDE);	m_nCurShow=-1;	CalRowHeight();
	}
	else if(m_nCurShow==1)
	{
	if(wParam == TRUE)
	{
		CString strText(_T(""));
		m_combobox.GetWindowText(strText);
		if(strText.IsEmpty ())
		{
			m_combobox.ShowWindow(SW_HIDE);	m_nCurShow=-1;
			return;
		}
		int pos=m_combobox.GetCurSel ();
		if(pos==-1)
		{ 
			m_combobox.ShowWindow(SW_HIDE);	m_nCurShow=-1;
		DWORD dwData = m_combobox.GetCtrlData();
		int nItem= dwData>>16;
		int nIndex = dwData&0x0000ffff;
		CString oldtext=GetText(nItem,nIndex);
		SetText(nItem,nIndex,strText);
  
 
        AddName(nItem,11+nAdd, g_user.name);
		SetText(nItem,12+nAdd,"�");
		if(oldtext!=strText)
		   Save(nItem);
			m_combobox.ShowWindow(SW_HIDE);	m_nCurShow=-1;	CalRowHeight();
			return;
		}
		if(m_acCombo.m_posarray.GetSize ()<=pos)
		{	 
				m_combobox.ShowWindow(SW_HIDE);	m_nCurShow=-1;

 
		DWORD dwData = m_combobox.GetCtrlData();
		int nItem= dwData>>16;
		int nIndex = dwData&0x0000ffff;
		CString oldtext=GetText(nItem,nIndex);
		SetText(nItem,nIndex,strText);
  
 
        AddName(nItem,11+nAdd, g_user.name);
		SetText(nItem,12+nAdd,"�");
		if(oldtext!=strText)
		   Save(nItem);
		}
		else
		{
		int pos2=m_acCombo.m_posarray.ElementAt (pos);
		m_id=m_pClientArray->ElementAt (pos2).ElementAt (0);
		DWORD dwData = m_combobox.GetCtrlData();
		int nItem= dwData>>16;
		int nIndex = dwData&0x0000ffff;
		CString oldtext=GetText(nItem,nIndex);
		SetText(nItem,nIndex,strText);

		if(!m_pClientArray->ElementAt (pos2).ElementAt (3).IsEmpty ())
		    SetText(nItem,2,m_pClientArray->ElementAt (pos2).ElementAt (3)+" "+m_pClientArray->ElementAt (pos2).ElementAt (4));
		else
		    SetText(nItem,2,m_pClientArray->ElementAt (pos2).ElementAt (4));
 
		if(m_mode==4)
		{
			g_sendhead.bsql=0;
			CString filter="id='"+m_id+"' and kind<>'5'";
			g_sendhead.code[0]=56;
			g_sendhead.tabcount=1;
			g_bNoConnDlg=1;
			g_pMainWnd->ProcessChatMessageRequest2(filter);	g_bNoConnDlg=0;
		    if(g_bSendOK)
			{
				DataToArray(&g_List1array);	
				CString str;
				for(int i=0; i<g_List1array.GetSize (); i++)
				{		if(g_List1array.ElementAt (i).ElementAt (20)!="2")continue;
					str+=g_List1array.ElementAt (i).ElementAt (0);
					str+=",";
				}
				str.TrimRight (",");
				SetText(nItem,4,str);
			}
		}


		SetText(nItem,4+nAdd,m_pClientArray->ElementAt (pos2).ElementAt (5));
		SetText(nItem,5+nAdd,m_pClientArray->ElementAt (pos2).ElementAt (6));
		SetText(nItem,6+nAdd,m_pClientArray->ElementAt (pos2).ElementAt (7));
		SetText(nItem,7+nAdd,m_pClientArray->ElementAt (pos2).ElementAt (8));
		SetText(nItem,8+nAdd,m_pClientArray->ElementAt (pos2).ElementAt (9));
		SetText(nItem,9+nAdd,m_pClientArray->ElementAt (pos2).ElementAt (10));

			if(atoi(GetText(nItem,9+nAdd))>0 )
			{
				SetBackColor (nItem,9+nAdd, RGB(255,0,0));
			}
			else  SetBackColor (nItem,9+nAdd, RGB(0,255,0));


			if(!m_pClientArray->ElementAt (pos2).ElementAt (11).IsEmpty ())
				SetText(nItem,10+nAdd,"��װ:"+m_pClientArray->ElementAt (pos2).ElementAt (11));
 
        AddName(nItem,11+nAdd, g_user.name);
		SetText(nItem,12+nAdd,"�");
		if(oldtext!=strText)
		   Save(nItem);
		}
	}
	m_combobox.ShowWindow(SW_HIDE);	m_nCurShow=-1;	CalRowHeight();
	}
	else if(m_nCurShow==2)
	{
	if(wParam == TRUE)
	{
		CString strText(_T(""));
		m_combobox2.GetWindowText(strText);
		DWORD dwData = m_combobox2.GetCtrlData();
		int nItem= dwData>>16;
		int nIndex = dwData&0x0000ffff;
		CString oldtext=GetText(nItem,nIndex);
		SetText(nItem,nIndex,strText);
	//	SetText(nItem,11+nAdd, g_user.name);
		AddName(nItem,11+nAdd, g_user.name);

		if(nIndex==12+nAdd)
		{
		   if(GetText(nItem,12+nAdd)=="�" )
			{
				SetBackColor (nItem,12+nAdd, RGB(255,0,0));
			}
			else  
				SetBackColor (nItem,12+nAdd, RGB(0,255,0));
		}

		if(oldtext!=strText)
		   Save(nItem);
	//Invalidate();
	}
	m_combobox2.ShowWindow(SW_HIDE);	m_nCurShow=-1;	CalRowHeight();
	}
	 

}

void XTable::ShowEdit(BOOL bShow,int nItem,int nIndex,CRect rcCtrl)
{
	try
	{
    if(m_edit.m_hWnd == NULL)
	{
		m_edit.Create(ES_AUTOHSCROLL|WS_CHILD|ES_LEFT|ES_WANTRETURN|WS_BORDER,CRect(0,0,0,0),this,IDC_EDIT1);
		m_edit.ShowWindow(SW_HIDE);

		CFont tpFont;
		tpFont.CreateStockObject(DEFAULT_GUI_FONT);
		m_edit.SetFont(&tpFont);
		tpFont.DeleteObject();
	}
	if(bShow == TRUE)
	{
	  	CString strItem = GetText(nItem,nIndex);
		m_edit.MoveWindow(rcCtrl);
		m_edit.ShowWindow(SW_SHOW);
		m_edit.SetWindowText(strItem);
		::SetFocus(m_edit.GetSafeHwnd());
		m_edit.SetSel(-1);  
		m_edit.SetCtrlData(MAKEWPARAM(nIndex,nItem)); 
	}
	else
		m_edit.ShowWindow(SW_HIDE);
	}
	catch(...)
	{
	}
}

void XTable::ShowSearchClientComboBox(BOOL bShow,int nItem,int nIndex,CRect rcCtrl)
{
	try
	{
    if(m_combobox.m_hWnd == NULL)
	{
		m_combobox.Create(WS_VSCROLL|WS_CHILD|CBS_DROPDOWN,CRect(0,0,0,0),this,100);
 	    m_combobox.ShowWindow(SW_HIDE);
		m_acCombo.m_mode =1;
		m_acCombo.Init(&m_combobox);
		m_acCombo.m_pArray=m_pClientArray;
		m_combobox.SetFocus ();
	}
	if(bShow == TRUE)
	{
	  	CString strItem = GetText(nItem,nIndex);
		rcCtrl.bottom+=300;
		m_combobox.MoveWindow(rcCtrl);
		m_combobox.ShowWindow(SW_SHOW);
		m_combobox.SetWindowText(strItem);
		::SetFocus(m_combobox.GetSafeHwnd());
 	 	m_combobox.SetCtrlData(MAKEWPARAM(nIndex,nItem)); 
	}
	else
		m_combobox.ShowWindow(SW_HIDE);
	}
	catch(...)
	{
	}
}
void XTable::ShowSearchClientComboBoxTime(BOOL bShow,int nItem,int nIndex,int type,CRect rcCtrl)
{
	try
	{
    if(m_combobox2.m_hWnd == NULL)
	{
		m_combobox2.Create(WS_VSCROLL|WS_CHILD|CBS_DROPDOWN,CRect(0,0,0,0),this,100);
 	    m_combobox2.ShowWindow(SW_HIDE);
		m_combobox2.SetFocus ();
	}
	m_combobox2.ResetContent ();
	if(type==0)
	{
		m_combobox2.AddString ("9:00");
		m_combobox2.AddString ("9:30");
		m_combobox2.AddString ("10:00");
		m_combobox2.AddString ("10:30");
		m_combobox2.AddString ("11:00");
		m_combobox2.AddString ("11:30");
		m_combobox2.AddString ("12:00");
		m_combobox2.AddString ("13:00");
		m_combobox2.AddString ("14:00");
		m_combobox2.AddString ("15:00");
		m_combobox2.AddString ("16:00");
		m_combobox2.AddString ("17:00");
		m_combobox2.AddString ("18:00");
		m_combobox2.AddString ("19:00");
		m_combobox2.AddString ("20:00");
		m_combobox2.AddString ("21:00");
	}
	else if(type==1)
	{
		for(int i=0; i<pTxtypearray->GetSize (); i++)
		   m_combobox2.AddString (pTxtypearray->ElementAt (i).ElementAt (0));
	}
	else if(type==2)
	{
		for(int ii=0; ii<g_userarray.GetSize (); ii++)
		{
			 if("��Ӱ��"== g_userarray.ElementAt (ii).ElementAt(2) )
				 m_combobox2.AddString ( g_userarray.ElementAt (ii).ElementAt(1) );
		}
	}
	else if(type==3)
	{
		for(int ii=0; ii<g_userarray.GetSize (); ii++)
		{
			 if("��ױ��"== g_userarray.ElementAt (ii).ElementAt(2) )
				 m_combobox2.AddString ( g_userarray.ElementAt (ii).ElementAt(1) );
		}
	}
	else if(type==4)
	{
		for(int ii=0; ii<g_userarray.GetSize (); ii++)
		{
		//	 if("��ױ��"== g_userarray.ElementAt (ii).ElementAt(2) )
				 m_combobox2.AddString ( g_userarray.ElementAt (ii).ElementAt(1) );
		}
	}
	else if(type==5)
	{
		m_combobox2.AddString ("�");
		m_combobox2.AddString ("�ѵ�");
	}
	if(bShow == TRUE)
	{
	  	CString strItem = GetText(nItem,nIndex);
		rcCtrl.bottom+=300;
		m_combobox2.MoveWindow(rcCtrl);
		m_combobox2.ShowWindow(SW_SHOW);
		m_combobox2.SetWindowText(strItem);
		::SetFocus(m_combobox2.GetSafeHwnd());
 	 	m_combobox2.SetCtrlData(MAKEWPARAM(nIndex,nItem)); 
	}
	else
		m_combobox2.ShowWindow(SW_HIDE);
	}
	catch(...)
	{
	}
}
void XTable::OnLButtonDblClk(UINT nFlags, CPoint point)
{
	try
	{
	if(!m_bFocusFrame)return;
	if(HitTest (point,focusRow,focusCol)==0)return;
	if(IsDateRow(focusRow))return;
	RECT rect = GetRect (focusRow,focusCol);
	if(focusCol==0)return;

	int nAdd=0;
	if(m_mode==4)nAdd=1;
	if(focusRow>0)
	{
		for(int i=0; i<focusRow; i++)
		{
		    if(""==GetText(i,1))
			{
				AfxMessageBox("����Ϸ��հ״���ʼ����!", MB_ICONINFORMATION);
				return;
			}
		}
	}
	if(focusCol==1)
	{		m_nCurShow=1;
 	    ShowSearchClientComboBox(TRUE,focusRow,focusCol,rect);

	}
	else if(""==GetText(focusRow,1))		
	{
		AfxMessageBox("�������������!", MB_ICONINFORMATION);
		return;
	}
	if(focusCol==11+nAdd)return;

	if(focusCol==3)
	{		m_nCurShow=2;
 	    ShowSearchClientComboBoxTime(TRUE,focusRow,focusCol,0,rect);

	}
 	else if(focusCol==4+nAdd)
	{		m_nCurShow=2;
 	    ShowSearchClientComboBoxTime(TRUE,focusRow,focusCol,1,rect);

	}
 	else if(focusCol==6+nAdd)
	{	m_nCurShow=2;
 	    ShowSearchClientComboBoxTime(TRUE,focusRow,focusCol,2,rect);
	
	}
 	else if(focusCol==7+nAdd)
	{	m_nCurShow=2;
 	    ShowSearchClientComboBoxTime(TRUE,focusRow,focusCol,3,rect);
	
	}
 	else if(focusCol==8+nAdd)
	{	m_nCurShow=2;
 	    ShowSearchClientComboBoxTime(TRUE,focusRow,focusCol,4,rect);
	
	} 
 	else if(focusCol==12+nAdd)
	{	m_nCurShow=2;
 	    ShowSearchClientComboBoxTime(TRUE,focusRow,focusCol,5,rect);
	
	}
	else if(focusCol!=1)
	{	m_nCurShow=0;
		ShowEdit(TRUE,focusRow,focusCol,rect);
	
	}
	}
	catch(...)
	{
	}
	CWnd::OnLButtonDown(nFlags, point);
}

BOOL XTable::RegisterWindowClass()
{
    WNDCLASS wndcls;
    HINSTANCE hInst = AfxGetInstanceHandle();

    if (!(::GetClassInfo(hInst, XTABLE_CLASSNAME, &wndcls)))
    {
        // otherwise we need to register a new class
        wndcls.style            = CS_DBLCLKS | CS_HREDRAW | CS_VREDRAW;
        wndcls.lpfnWndProc      = ::DefWindowProc;
        wndcls.cbClsExtra       = wndcls.cbWndExtra = 0;
        wndcls.hInstance        = hInst;
        wndcls.hIcon            = NULL;
        wndcls.hCursor          = AfxGetApp()->LoadStandardCursor(IDC_ARROW);
        wndcls.hbrBackground    = (HBRUSH) (COLOR_3DFACE + 1);
        wndcls.lpszMenuName     = NULL;
        wndcls.lpszClassName    = XTABLE_CLASSNAME;

        if (!AfxRegisterClass(&wndcls))
        {
            AfxThrowResourceException();
            return FALSE;
        }
    }

    return TRUE;
}


int XTable::Test2 ()
{
	defaultHeight = 20;
	CStringArray array;


	if(m_mode==4)
	{
	array.Add ("����");
 	array.Add ("�绰");
	array.Add ("ʱ��");
	array.Add ("��������");
 	array.Add ("���");
	array.Add ("�۸�");
 	array.Add ("��Ӱ");
#ifdef CHILD_VERSION
 	array.Add ("����");
#else
 	array.Add ("��ױ");
#endif
 	array.Add ("����");
 	array.Add ("Ƿ��");
 	array.Add ("��ע");
 	array.Add ("¼��"); 
	array.Add ("�Ƿ񵽵�");
	}
	else
	{
	array.Add ("����");
 	array.Add ("�绰");
	array.Add ("ʱ��");
 	array.Add ("���");
	array.Add ("�۸�");
 	array.Add ("��Ӱ");
#ifdef CHILD_VERSION
 	array.Add ("����");
#else
 	array.Add ("��ױ");
#endif
 	array.Add ("����");
 	array.Add ("Ƿ��");
 	array.Add ("��ע");
 	array.Add ("¼��"); 
	array.Add ("�Ƿ񵽵�");
	}
	int cols=array.GetSize();

	CRect rc;
	GetClientRect(rc);
	defaultWidth = (rc.Width()-10)/cols;
	SetCols (1);
	SetRows (2);
	SetCols (cols+1);

	COLORREF col1=RGB(0xC8, 0x96, 0x96);
	COLORREF col2=RGB(0x64,0x96,0xC8);
	for (int i = 0; i < 2; i ++)
		SetBackColor (i, 0, col1);
	for (  i = 0; i < cols+1; i ++)
		SetBackColor (0, i, col1);
 
    SetRowHeight (0, 10);
 	SetColWidth (0, 10);

	for(i=0; i<cols; i++)
	{
		SetBackColor (1,i+1, col2);
		SetText (1,i+1, array.ElementAt (i));
	}

 
	Invalidate();
	return 0;
}
///edit

XTableEdit::XTableEdit()
{
}

XTableEdit::~XTableEdit()
{
}


BEGIN_MESSAGE_MAP(XTableEdit, CEdit)
	//{{AFX_MSG_MAP(XTableEdit)
	ON_WM_KILLFOCUS()
	ON_WM_SETFOCUS()
	//}}AFX_MSG_MAP
END_MESSAGE_MAP()

/////////////////////////////////////////////////////////////////////////////
// XTableEdit message handlers
void XTableEdit::SetCtrlData(DWORD dwData)
{
	m_dwData = dwData;
}

DWORD XTableEdit::GetCtrlData()
{
   return m_dwData;
}

void XTableEdit::OnKillFocus(CWnd* pNewWnd) 
{
	CEdit::OnKillFocus(pNewWnd);
	CWnd* pParent = this->GetParent();
	::PostMessage(pParent->GetSafeHwnd(),WM_USER_EDIT_END,m_bExchange,0);
}

BOOL XTableEdit::PreTranslateMessage(MSG* pMsg) 
{
	
	if(pMsg->message == WM_KEYDOWN)
	{
		if(pMsg->wParam == VK_RETURN)
		{
			CWnd* pParent = this->GetParent();
			m_bExchange = TRUE;
			::PostMessage(pParent->GetSafeHwnd(),WM_USER_EDIT_END,m_bExchange,0);
		}
		else if(pMsg->wParam == VK_ESCAPE)
		{
           CWnd* pParent = this->GetParent();
		   m_bExchange = FALSE;
			::PostMessage(pParent->GetSafeHwnd(),WM_USER_EDIT_END,m_bExchange,0);
		}
	}
	
	return CEdit::PreTranslateMessage(pMsg);
}

void XTableEdit::OnSetFocus(CWnd* pOldWnd) 
{
	CEdit::OnSetFocus(pOldWnd);
    m_bExchange = TRUE;	
}
 
XTableComboBox::XTableComboBox()
{
}

XTableComboBox::~XTableComboBox()
{
}
BEGIN_MESSAGE_MAP(XTableComboBox, CComboBox)
	//{{AFX_MSG_MAP(XTableComboBox)
	ON_WM_KILLFOCUS()
	ON_WM_SETFOCUS()
	ON_CONTROL_REFLECT(CBN_CLOSEUP, OnCloseup)
	//}}AFX_MSG_MAP
END_MESSAGE_MAP()

/////////////////////////////////////////////////////////////////////////////
// XTableComboBox message handlers
void XTableComboBox::SetCtrlData(DWORD dwData)
{
	m_dwData = dwData;
}

DWORD XTableComboBox::GetCtrlData()
{
   return m_dwData;
}

void XTableComboBox::OnKillFocus(CWnd* pNewWnd) 
{ 
	CComboBox::OnKillFocus(pNewWnd);
/*	CWnd* pParent = this->GetParent();
	if(((XTable*)pParent)->m_nCurShow!=-1)
	::PostMessage(pParent->GetSafeHwnd(),WM_USER_EDIT_END,m_bExchange,1);*/
}

BOOL XTableComboBox::PreTranslateMessage(MSG* pMsg) 
{
	if(pMsg->message == WM_KEYDOWN)
	{
		if(pMsg->wParam == VK_RETURN)
		{
			CWnd* pParent = this->GetParent();
			m_bExchange = TRUE;
			::PostMessage(pParent->GetSafeHwnd(),WM_USER_EDIT_END,m_bExchange,1);
		}
		else if(pMsg->wParam == VK_ESCAPE)
		{
           CWnd* pParent = this->GetParent();
		   m_bExchange = FALSE;
			::PostMessage(pParent->GetSafeHwnd(),WM_USER_EDIT_END,m_bExchange,1);
		}
	}
	
	return CComboBox::PreTranslateMessage(pMsg);
}

void XTableComboBox::OnSetFocus(CWnd* pOldWnd) 
{
 	CComboBox::OnSetFocus(pOldWnd);
    m_bExchange = TRUE;	
}

void XTableComboBox::OnCloseup() 
{
	// TODO: Add your control notification handler code here
	CWnd* pParent = this->GetParent();
	::PostMessage(pParent->GetSafeHwnd(),WM_USER_EDIT_END,m_bExchange,1);	
}

//
XTableTreeComboBox::XTableTreeComboBox()
{
}

XTableTreeComboBox::~XTableTreeComboBox()
{
}
BEGIN_MESSAGE_MAP(XTableTreeComboBox, CTreeComboBox)
	//{{AFX_MSG_MAP(XTableTreeComboBox)
	ON_WM_KILLFOCUS()
	ON_WM_SETFOCUS()
	ON_CONTROL_REFLECT(CBN_CLOSEUP, OnCloseup)
	//}}AFX_MSG_MAP
END_MESSAGE_MAP()

/////////////////////////////////////////////////////////////////////////////
// XTableTreeComboBox message handlers
void XTableTreeComboBox::SetCtrlData(DWORD dwData)
{
	m_dwData = dwData;
}

DWORD XTableTreeComboBox::GetCtrlData()
{
   return m_dwData;
}

void XTableTreeComboBox::OnKillFocus(CWnd* pNewWnd) 
{ 
	CTreeComboBox::OnKillFocus(pNewWnd);
/*	CWnd* pParent = this->GetParent();
	if(((XTable*)pParent)->m_nCurShow!=-1)
	::PostMessage(pParent->GetSafeHwnd(),WM_USER_EDIT_END,m_bExchange,1);*/
}

BOOL XTableTreeComboBox::PreTranslateMessage(MSG* pMsg) 
{
	if(pMsg->message == WM_KEYDOWN)
	{
		if(pMsg->wParam == VK_RETURN)
		{
			CWnd* pParent = this->GetParent();
			m_bExchange = TRUE;
			::PostMessage(pParent->GetSafeHwnd(),WM_USER_EDIT_END,m_bExchange,1);
		}
		else if(pMsg->wParam == VK_ESCAPE)
		{
           CWnd* pParent = this->GetParent();
		   m_bExchange = FALSE;
			::PostMessage(pParent->GetSafeHwnd(),WM_USER_EDIT_END,m_bExchange,1);
		}
	}
	
	return CTreeComboBox::PreTranslateMessage(pMsg);
}

void XTableTreeComboBox::OnSetFocus(CWnd* pOldWnd) 
{
 	CTreeComboBox::OnSetFocus(pOldWnd);
    m_bExchange = TRUE;	
}

void XTableTreeComboBox::OnCloseup() 
{
	// TODO: Add your control notification handler code here
	CWnd* pParent = this->GetParent();
	::PostMessage(pParent->GetSafeHwnd(),WM_USER_EDIT_END,m_bExchange,1);	
}

//
void XTable::CalRowHeight()
{ 
	CString str;		CPaintDC dc(this);  
	for(int i=0; i<GetRows(); i++)
	{
    	SetRowHeight (i, 20);
		for(int j=1; j<GetCols(); j++)
		{
			str=GetText(i, j);
		
			RECT rect = GetRect(i,j);
			RECT textRect=rect;

			this->SetWordbreak (i, j, 0);
			XCell* cell = GetCells (i, j);
			cell->CalcTextRect(&dc, &textRect);
			if (textRect.right > rect.right || textRect.bottom > rect.bottom)
			{
				this->SetWordbreak (i, j, 1);
				textRect=rect;
				cell->CalcTextRect(&dc, &textRect);
				rect.bottom =textRect.bottom+2;
			//	if(rect.bottom-rect.top>100)rect.bottom=rect.top+100;
				SetRowHeight (i, rect.bottom-rect.top); 
			}
		}
	}
	Invalidate();
}

void XTable::Save(int row)
{
	if(m_mode==4)
	{
		Save2(row);return;
	}
	if(IsHasRightsnew(2)==0)return;
	if(::GetTickCount ()-m_nticks<1000)return;
	m_nticks=::GetTickCount ();

	int oldrow=row;
	BOOL bFind=0;
	for(int i=0; i<m_daterowposarray.GetSize (); i++)
	{
		if(row<m_daterowposarray.ElementAt (i))
		{
			row-=i;bFind=1;
			break;
		}
		if(row==m_daterowposarray.ElementAt (i))
			return;
	}
	if(bFind==0)row-=m_daterowposarray.GetSize ();

	if(row>=m_pListArray->GetSize())//��ԤԼ
	{
	CString	name=GetText(oldrow, 1);
	CString	phone=GetText(oldrow, 2);
	CString	time=GetText(oldrow, 3);
	CString	type=GetText(oldrow, 4);
	CString	price=GetText(oldrow, 5);
	CString	waiter1=GetText(oldrow, 6);
	CString	waiter2=GetText(oldrow, 7);
	CString	receptionist=GetText(oldrow, 8);
	CString	arrearage=GetText(oldrow, 9);
	CString	remark=GetText(oldrow, 10);
	CString	clerk=GetText(oldrow, 11);
	CString	arrive=GetText(oldrow, 12);
	CString	timestamp=CTime::GetCurrentTime ().Format ("%Y%m%d%H%M%S");
	CString	date=((TodayForm2*)(GetParent()->GetParent()))->GetDate();
	if(name.IsEmpty())return;
	CString sql,sql2;
sql.Format ("insert into todaytake([name],[phone],[time],[type],[price],[waiter1],[waiter2],[receptionist],\
[arrearage],[remark],[clerk],[timestamp],[date],[mode],[arrive],[id])values('%s','%s','%s','%s','%s','%s','%s','%s','%s','%s','%s','%s','%s','%d','%s','%s')", \
name,phone,time,type,price,waiter1,waiter2,receptionist,arrearage,remark,clerk,timestamp,date,m_mode,arrive,m_id);
    if(m_mode==0)
	{
		sql2.Format ("***update dindan set [time2]='%s' where [id]='%s'", date, m_id);
	}
    else if(m_mode==1)
	{
		sql2.Format ("***update dindan set [time4]='%s' where [id]='%s'", date, m_id);
	}
    else if(m_mode==2)
	{
		sql2.Format ("***update dindan set [time6]='%s' where [id]='%s'", date, m_id);
	}
    else if(m_mode==3)
	{
		sql2.Format ("***update dindan set [time5]='%s' where [id]='%s'", date, m_id);
	}
	sql+=sql2;
	g_sendhead.bsql=1;
	g_pMainWnd->ProcessChatMessageRequest2(sql); //if(g_bSendOK==0)return;
     ((TodayForm2*)(GetParent()->GetParent()))->ReLoad1();
	}
	else
	{ 
	CString	name=GetText(oldrow, 1);
	CString	phone=GetText(oldrow, 2);
	CString	time=GetText(oldrow, 3);
	CString	type=GetText(oldrow, 4);
	CString	price=GetText(oldrow, 5);
	CString	waiter1=GetText(oldrow, 6);
	CString	waiter2=GetText(oldrow, 7);
	CString	receptionist=GetText(oldrow, 8);
	CString	arrearage=GetText(oldrow, 9);
	CString	remark=GetText(oldrow, 10);
	CString	clerk=GetText(oldrow, 11);
	CString	arrive=GetText(oldrow, 12);
	CString	timestamp=m_pListArray->ElementAt(row).ElementAt(13);
 
	if(name.IsEmpty())return;
	CString sql;
sql.Format ("update todaytake set [name]='%s',[phone]='%s',[time]='%s',[type]='%s',[price]='%s',[waiter1]='%s',\
[waiter2]='%s',[receptionist]='%s',[arrearage]='%s',[remark]='%s',[clerk]='%s',[arrive]='%s' where [timestamp]='%s'", \
name,phone,time,type,price,waiter1,waiter2,receptionist,arrearage,remark,clerk,arrive,timestamp);

 

	g_sendhead.bsql=1;
	g_pMainWnd->ProcessChatMessageRequest2(sql); 
	}
}

void XTable::Save2(int row)
{
	if(IsHasRightsnew(2)==0)return;
	if(::GetTickCount ()-m_nticks<1000)return;
	m_nticks=::GetTickCount ();

	int oldrow=row;
	BOOL bFind=0;
	for(int i=0; i<m_daterowposarray.GetSize (); i++)
	{
		if(row<m_daterowposarray.ElementAt (i))
		{
			row-=i;bFind=1;
			break;
		}
		if(row==m_daterowposarray.ElementAt (i))
			return;
	}
	if(bFind==0)row-=m_daterowposarray.GetSize ();

	if(row>=m_pListArray->GetSize())//��ԤԼ
	{
	CString	name=GetText(oldrow, 1);
	CString	phone=GetText(oldrow, 2);
	CString	time=GetText(oldrow, 3);
	CString	content=GetText(oldrow, 4);
	CString	type=GetText(oldrow, 5);
	CString	price=GetText(oldrow, 6);
	CString	waiter1=GetText(oldrow, 7);
	CString	waiter2=GetText(oldrow, 8);
	CString	receptionist=GetText(oldrow, 9);
	CString	arrearage=GetText(oldrow, 10);
	CString	remark=GetText(oldrow, 11);
	CString	clerk=GetText(oldrow, 12);
	CString	arrive=GetText(oldrow, 13);
	CString	timestamp=CTime::GetCurrentTime ().Format ("%Y%m%d%H%M%S");
	CString	date=((TodayForm2*)(GetParent()->GetParent()))->GetDate();
	if(name.IsEmpty())return;
	CString sql;
sql.Format ("insert into todaytake([name],[phone],[time],[type],[price],[waiter1],[waiter2],[receptionist],\
[arrearage],[remark],[clerk],[timestamp],[date],[mode],[content],[arrive],[id])values('%s','%s','%s','%s','%s','%s','%s','%s','%s','%s','%s','%s','%s','%d','%s','%s','%s')", \
name,phone,time,type,price,waiter1,waiter2,receptionist,arrearage,remark,clerk,timestamp,date,m_mode,content,arrive,m_id);

  

	g_sendhead.bsql=1;
	g_pMainWnd->ProcessChatMessageRequest2(sql); //if(g_bSendOK==0)return;
     ((TodayForm2*)(GetParent()->GetParent()))->ReLoad1();
	}
	else
	{ 
	CString	name=GetText(oldrow, 1);
	CString	phone=GetText(oldrow, 2);
	CString	time=GetText(oldrow, 3);
	CString	content=GetText(oldrow, 4);
	CString	type=GetText(oldrow, 5);
	CString	price=GetText(oldrow, 6);
	CString	waiter1=GetText(oldrow, 7);
	CString	waiter2=GetText(oldrow, 8);
	CString	receptionist=GetText(oldrow, 9);
	CString	arrearage=GetText(oldrow, 10);
	CString	remark=GetText(oldrow, 11);
	CString	clerk=GetText(oldrow, 12);
	CString	arrive=GetText(oldrow, 13);
	CString	timestamp=m_pListArray->ElementAt(row).ElementAt(14);
 
	if(name.IsEmpty())return;
	CString sql;
sql.Format ("update todaytake set [name]='%s',[phone]='%s',[time]='%s',[type]='%s',[price]='%s',[waiter1]='%s',\
[waiter2]='%s',[receptionist]='%s',[arrearage]='%s',[remark]='%s',[clerk]='%s',[content]='%s',[arrive]='%s' where [timestamp]='%s'", \
name,phone,time,type,price,waiter1,waiter2,receptionist,arrearage,remark,clerk,content,arrive,timestamp);
	g_sendhead.bsql=1;
	g_pMainWnd->ProcessChatMessageRequest2(sql); 
	}
}

void XTable::DeleteCur()
{
	int row=focusRow;
	CString	name=GetText(row, 1);
 
	BOOL bFind=0;
	for(int i=0; i<m_daterowposarray.GetSize (); i++)
	{
		if(row<m_daterowposarray.ElementAt (i))
		{
			row-=i;bFind=1;
			break;
		}
		if(row==m_daterowposarray.ElementAt (i))
			return;
	}
	if(bFind==0)row-=m_daterowposarray.GetSize ();

	if(row>=m_pListArray->GetSize())
		return;

 

	if(AfxMessageBox("ȷ��ɾ������"+name+"��ԤԼ������?", MB_YESNO|MB_ICONINFORMATION)!=IDYES)return;



	int size=m_pListArray->ElementAt(row).GetSize ();
	CString	timestamp=m_pListArray->ElementAt(row).ElementAt(size-2);
	CString sql;
sql.Format ("delete from todaytake where [timestamp]='%s'", timestamp);
	g_sendhead.bsql=1;
	g_pMainWnd->ProcessChatMessageRequest2(sql);  
    ((TodayForm2*)(GetParent()->GetParent()))->ReLoad1();
}

void XTable::OtherDate()
{
	int row=focusRow;
	CString	name=GetText(row, 1);
	BOOL bFind=0;
	for(int i=0; i<m_daterowposarray.GetSize (); i++)
	{
		if(row<m_daterowposarray.ElementAt (i))
		{
			row-=i;bFind=1;
			break;
		}
		if(row==m_daterowposarray.ElementAt (i))
			return;
	}
	if(bFind==0)row-=m_daterowposarray.GetSize ();

	if(row>=m_pListArray->GetSize())
		return;

	int size=m_pListArray->ElementAt(row).GetSize ();
	CString	date=m_pListArray->ElementAt(row).ElementAt(size-3);
	CString	timestamp=m_pListArray->ElementAt(row).ElementAt(size-2);
	CString	id=m_pListArray->ElementAt(row).ElementAt(size-1);
	InputDate dlg;
	dlg.m_date =date;
	dlg.m_name =name;
	dlg.m_name =m_pListArray->ElementAt(row).ElementAt(0);

	if(dlg.DoModal ()!=IDOK)return;

 

	CString sql,sql2;
sql.Format ("update todaytake set [date]='%s' where [timestamp]='%s'", dlg.m_date, timestamp);
	g_sendhead.bsql=1;

    if(m_mode==0)
	{
		sql2.Format ("***update dindan set [time2]='%s' where [id]='%s'", dlg.m_date, id);
	}
    else if(m_mode==1)
	{
		sql2.Format ("***update dindan set [time4]='%s' where [id]='%s'", dlg.m_date, id);
	}
    else if(m_mode==2)
	{
		sql2.Format ("***update dindan set [time6]='%s' where [id]='%s'", dlg.m_date, id);
	}
    else if(m_mode==3)
	{
		sql2.Format ("***update dindan set [time5]='%s' where [id]='%s'", dlg.m_date, id);
	}
	sql+=sql2;

	g_pMainWnd->ProcessChatMessageRequest2(sql);  
    ((TodayForm2*)(GetParent()->GetParent()))->ReLoad1();
}

BOOL XTable::IsDateRow(int row)
{
	try
	{
	for(int i=0; i<m_daterowposarray.GetSize (); i++)
	{
		if(row==m_daterowposarray.ElementAt (i))
			return 1;
	}
	}
	catch(...)
	{
	}
	return 0;
}

CString XTable::GetWeek(CString date)
{
	if(date.GetLength ()!=10)return "";
	COleDateTime   dtDay(atoi(date.Mid (0,4)),atoi(date.Mid (5,2)),atoi(date.Mid (8,2)), 0, 0, 0); 
	int nDayWeek   =   dtDay.GetDayOfWeek()-1;     //�õ����ڼ���1=Sunday,   2=Monday, 
	CString DayOfWeek[7]={"������","����һ","���ڶ�","������","������","������","������"};
	CString sdate;
	if(nDayWeek>=0 && nDayWeek<=6)
		sdate=DayOfWeek[nDayWeek];
	else
		sdate="������";
	return sdate;
}

int XTable::Test()
{
	CStringArray array;
	if(m_mode==4)
	{
	array.Add ("����");
 	array.Add ("�绰");
	array.Add ("ʱ��");
	array.Add ("��������");
 	array.Add ("���");
	array.Add ("�۸�");
 	array.Add ("��Ӱ");
#ifdef CHILD_VERSION
 	array.Add ("����");
#else
 	array.Add ("��ױ");
#endif
 	array.Add ("����");
 	array.Add ("Ƿ��");
 	array.Add ("��ע");
 	array.Add ("¼��");
 	array.Add ("�Ƿ񵽵�");
	}
	else
	{
	array.Add ("����");
 	array.Add ("�绰");
	array.Add ("ʱ��");
 	array.Add ("���");
	array.Add ("�۸�");
 	array.Add ("��Ӱ");
#ifdef CHILD_VERSION
 	array.Add ("����");
#else
 	array.Add ("��ױ");
#endif
 	array.Add ("����");
 	array.Add ("Ƿ��");
 	array.Add ("��ע");
 	array.Add ("¼��"); 
	array.Add ("�Ƿ񵽵�");
	}
	int cols=array.GetSize();

	int nAdd=0;
	if(m_mode==4)nAdd=1;


	CRect rc;
	GetClientRect(rc);
	defaultWidth = (rc.Width()-10)/cols;
	int halfwid=defaultWidth;

 	SetCols (1);
	SetRows (256);
	SetCols (cols+1);

	for(int i=0; i<rows; i++)
	{
		for(int j=0; j<cols; j++)
		{
			SetText (i, j+1, "");
		}
	}

	COLORREF col1=RGB(0xC8, 0x96, 0x96);
	COLORREF col2=RGB(0x64,0x96,0xC8);
	COLORREF yellow=RGB(255,255,0);
	COLORREF green=RGB(0,255,255);
	for (  i = 0; i < 46; i ++)
		SetBackColor (i, 0, col1);
	SetColWidth ( 0, 10);

	m_datearray.RemoveAll ();
	m_daterowposarray.RemoveAll ();
	int datesize=0;
	int aa=0;
	CString curdate;

	CStringArray typearray;
	CArray<int,int>typecountarray;
	int pos;
	int oldpos;
	for(i=0; i<m_pListArray->GetSize()+datesize; i++)
	{
		if(m_pListArray->ElementAt(aa).ElementAt(12+nAdd)!=curdate && curdate!="")
		{
			//������
			CString str="    ����ԤԼ:  ";
			CString temp;
			for(int a=0; a<typearray.GetSize (); a++)
			{
				temp.Format ("%s:%d   ", typearray.ElementAt (a), typecountarray.ElementAt (a));
				str+=temp;
			} 	
			SetText (oldpos, 1, GetText(oldpos, 1)+str );
 
			typearray.RemoveAll ();	typecountarray.RemoveAll ();
		}
		if(::FindArray (&m_datearray, m_pListArray->ElementAt(aa).ElementAt(12+nAdd))==-1)
		{
			curdate=m_pListArray->ElementAt(aa).ElementAt(12+nAdd);
			m_datearray.Add ( curdate );
			m_daterowposarray.Add (i);
			datesize=m_datearray.GetSize ();
			JoinCells (i,1,i,12+nAdd);
			SetAlignment (i,1,DT_CENTER);
			SetBackColor (i,1, green);
			SetText (i, 1, curdate+" "+GetWeek(curdate) );
			oldpos=i;
			continue;
		}
		pos=::FindArray (&typearray, m_pListArray->ElementAt(aa).ElementAt(3+nAdd));
	    if(pos==-1)
		{
			typearray.Add (m_pListArray->ElementAt(aa).ElementAt(3+nAdd));
			typecountarray.Add (1);
		}
		else
		{
			int size=typecountarray.ElementAt (pos);
			typecountarray.SetAt (pos, size+1);
		}

		for(int j=0; j<cols; j++)
		{
			SetText (i, j+1, m_pListArray->ElementAt(aa).ElementAt(j));
			if(j==8+nAdd && atoi(m_pListArray->ElementAt(aa).ElementAt(j))>0 )
			{
				SetBackColor (i,j+1, RGB(255,0,0));
			}
			else if(j==8+nAdd)SetBackColor (i,j+1, RGB(0,255,0));

			if(j==11+nAdd && m_pListArray->ElementAt(aa).ElementAt(j)=="�" )
			{
				SetBackColor (i,j+1, RGB(255,0,0));
			}
			else if(j==11+nAdd)SetBackColor (i,j+1, RGB(0,255,0));
		}
		aa++;
	}
 
	if(m_pListArray->GetSize())
	{
 			//������
			CString str="    ����ԤԼ:  ";
			CString temp;
			for(int a=0; a<typearray.GetSize (); a++)
			{
				temp.Format ("%s:%d   ", typearray.ElementAt (a), typecountarray.ElementAt (a));
				str+=temp;
			} 	
			SetText (oldpos, 1, GetText(oldpos, 1)+str );
	}
    CalRowHeight();
 	return 0;


	JoinCells (3,5,4,6);
	SetText (3,5, "This cell contains multiline text, which provides multiline edit.����, ����, ����Using default font����, ����, ����Using default font");
	SetWordbreak (3,5,true);
return 0;
	JoinCells (3,7,5,8);
	SetText (3,7, "This cell contains multiline text, which provides multiline edit.");
	SetWordbreak (3,7,true);

	SetText (4,1, "You can even edit a long (cell overlapping) string.");
	SetOverlap(4,1,true);

	SetText (4,3, "Test");

	JoinCells (5,1,6,2);
	SetText (5,1, "Enter your name here.");

	JoinCells (5,3,5,4);
	SetText (5,3, "Enter your text here ...");

	JoinCells (8,1,8,8);
	SetBackColor (8,1, RGB(0x64,0x96,0xC8));
	SetText (8,1, "Default edit controls also allow us to customize user's editing experience by:");

	JoinCells (10,1,10,2);
	SetBackColor (10,1, RGB(0xDC,0xC8,0xB4));
	SetText (10,1, "Converting input to upper case:");

	SetText (10,3, "TYPE HERE ...");

	JoinCells (10,5,10,6);
	SetBackColor (10,5, RGB(0xDC,0xC8,0xB4));
	SetText (10,5, "Converting input to lower case:");

	SetText (10,7, "type here ...");

	JoinCells (11,1,11,2);
	SetBackColor (11,1, RGB(0xDC,0xC8,0xB4));
	SetText (11,1, "Allowing password input:");

	SetText (11,3, "*********");

	SetText (11,5, "Entered password was:*********");
	SetOverlap(11,5,true);

	JoinCells (12,1,12,2);
	SetBackColor (12,1, RGB(0xDC,0xC8,0xB4));
	SetText (12,1, "Allowing aligned input:");

	SetText (12,3, "Left aligned");
	SetText (12,5, "Centered");
	SetAlignment (12,5,DT_CENTER);
	SetText (12,7, "Right aligned");
	SetAlignment (12,7,DT_RIGHT);

	JoinCells (14,1,14,8);
	SetBackColor (14,1, RGB(0x64,0x96,0xC8));
	SetText (14,1, "Ultimate Grid allow us to process user's input with various notifications.");

	JoinCells (16,1,16,5);
	SetBackColor (16,1, RGB(0xDC,0xC8,0xB4));
	SetText (16,1, "We can verify data it is entered, for example to limit number of char to 4:");

	SetText (16,6, "<Type here>");

	JoinCells (17,1,17,5);
	SetBackColor (17,1, RGB(0xDC,0xC8,0xB4));
	SetText (17,1, "or that the numeric value entered is under 500 (number < 500):");

	SetText (17,6, "<Type here>");

	JoinCells (18,1,18,5);
	SetBackColor (18,1, RGB(0xDC,0xC8,0xB4));
	SetText (18,1, "We can also test user's input after it is completed, or force user's input:");

	SetText (18,6, "<Type here>");

	JoinCells (20,1,20,8);
	SetBackColor (20,1, RGB(0x64,0x96,0xC8));
	SetText (20,1, "The Ultimate Grid also allows us to use other edit controls when needed:");

	JoinCells (22,1,23,5);
	SetBackColor (22,1, RGB(0xDC,0xC8,0xB4));
	SetText (22,1, "Just by setting a mask on a cell, the grid will change edit controls to use a mask edit. By default Ultimate Grid creates an instance of CUGMEdit to use as mask edit control.");
	SetWordbreak (22,1,true);

	JoinCells (22,6,22,7);
	SetText (22,6, "<Select mask>");
	JoinCells (23,6,23,7);
	SetText (23,6, "<Type here>");

	JoinCells (25,1,27,5);
	SetBackColor (25,1, RGB(0xDC,0xC8,0xB4));
	SetText (25,1, "The Ultimate Grid 5 also comes with a set of advanced edit control previosly only found in Ultimate ToolBox. We can now easily incorporate powerful controls like COXMaskEdit, COXNumericEdit, and COXCurrencyEdit into our applications.");
	SetWordbreak (25,1,true);

	JoinCells (29,1,30,5);
	SetBackColor (29,1, RGB(0xDC,0xC8,0xB4));
	SetText (29,1, "The COXMaskEdit works very similarly to the default mask edit control, to use it just set a mask on a cell and inform the grid that you want to use different edit control.");
	SetWordbreak (29,1,true);

	JoinCells (29,6,29,8);
	SetText (29,6, "<Select mask>");
	JoinCells (30,6,30,8);
	SetText (30,6, "<Type here>");

	JoinCells (32,1,33,5);
	SetBackColor (32,1, RGB(0xDC,0xC8,0xB4));
	SetText (32,1, "The COXNumericEdit and COXCurrencyEdit on the other hand allow us to provide additional setup information that will drive the way the edit control will behave.");
	SetWordbreak (32,1,true);

	JoinCells (35,1,35,2);
	SetBackColor (35,1, RGB(0xDC,0xC8,0xB4));
	SetText (35,1, "Using COXNumericEdit:");

	JoinCells (35,3,35,4);
	SetText (35,3, "<Type here>");

	JoinCells (35,5,35,6);
	SetBackColor (35,5, RGB(0xDC,0xC8,0xB4));
	SetText (35,5, "Using COXCurrencyEdit:");

	JoinCells (35,7,35,8);
	SetText (35,7, "<Type here>");

	JoinCells (36,1,36,3);
	SetBackColor (36,1, RGB(0x64,0x96,0xC8));
	SetText (36,1, "Following are properties we can set.");

	JoinCells (36,5,36,7);
	SetBackColor (36,5, RGB(0x64,0x96,0xC8));
	SetText (36,5, "Following are properties we can set.");

	JoinCells (37,1,37,2);
	SetBackColor (37,1, RGB(0xDC,0xC8,0xB4));
	SetText (37,1, "Decimal digit count :");

	JoinCells (37,5,37,6);
	SetBackColor (37,5, RGB(0xDC,0xC8,0xB4));
	SetText (37,5, "Decimal digit count :");

	JoinCells (38,1,38,2);
	SetBackColor (38,1, RGB(0xDC,0xC8,0xB4));
	SetText (38,1, "Decimal Separator :");

	JoinCells (38,5,38,6);
	SetBackColor (38,5, RGB(0xDC,0xC8,0xB4));
	SetText (38,5, "Decimal Separator :");

	JoinCells (39,1,39,2);
	SetBackColor (39,1, RGB(0xDC,0xC8,0xB4));
	SetText (39,1, "Fractional digit count :");

	JoinCells (39,5,39,6);
	SetBackColor (39,5, RGB(0xDC,0xC8,0xB4));
	SetText (39,5, "Fractional digit count :");

	JoinCells (40,1,40,2);
	SetBackColor (40,1, RGB(0xDC,0xC8,0xB4));
	SetText (40,1, "Group Separator :");

	JoinCells (40,5,40,6);
	SetBackColor (40,5, RGB(0xDC,0xC8,0xB4));
	SetText (40,5, "Group Separator :");

	JoinCells (41,1,41,2);
	SetBackColor (41,1, RGB(0xDC,0xC8,0xB4));
	SetText (41,1, "Digits in group :");

	JoinCells (41,5,41,6);
	SetBackColor (41,5, RGB(0xDC,0xC8,0xB4));
	SetText (41,5, "Digits in group :");

	JoinCells (42,1,42,2);
	SetBackColor (42,1, RGB(0xDC,0xC8,0xB4));
	SetText (42,1, "Negative Format :");

	JoinCells (42,5,42,6);
	SetBackColor (42,5, RGB(0xDC,0xC8,0xB4));
	SetText (42,5, "Positive Format :");

	JoinCells (43,1,43,2);
	SetBackColor (43,1, RGB(0xDC,0xC8,0xB4));
	SetText (43,1, "Show leading zero :");

	JoinCells (43,5,43,6);
	SetBackColor (43,5, RGB(0xDC,0xC8,0xB4));
	SetText (43,5, "Negative Format :");

	JoinCells (44,5,44,6);
	SetBackColor (44,5, RGB(0xDC,0xC8,0xB4));
	SetText (44,5, "Currency name :");

	JoinCells (45,5,45,6);
	SetBackColor (45,5, RGB(0xDC,0xC8,0xB4));
	SetText (45,5, "Show leading zero :");

	return 0;
}

void XTable::ModeChange(int mode)
{
	m_mode=mode;
}

void XTable::AddName(int row, int col, CString str)
{
	CString oldtext=GetText(row,col);
	if(oldtext.IsEmpty ())
	{
		SetText(row,col, str);
		return;
	}
	if(oldtext.Find (str)!=-1)return;
	SetText(row,col, oldtext+","+str);
}
//��ױʦ