Click here to Skip to main content
15,897,518 members
Articles / Desktop Programming / WTL

A fast and lightweight cell control

Rate me:
Please Sign up or sign in to vote.
4.42/5 (31 votes)
11 Mar 2008CPOL1 min read 91.1K   4.5K   81  
A fast and lightweight cell control for displaying tabular data. The cell is a custom control derived from ATL::CWindow.
/* -------------------------------------------------------------------------
//MyCell Library - MyCell version 1.0
//
// This file is a part of the MyCell Library.
// The use and distribution terms for this software are covered by the
// Common Public License 1.0 (http://opensource.org/licenses/cpl.php)
// which can be found in the file CPL.txt at this distribution. By using
// this software in any fashion, you are agreeing to be bound by the terms
// of this license. You must not remove this notice, or any other, from
// this software.
//
// Creator: yanxueming
// Email: xueming.yan@gmail.com
// Create time:2008��1��2�� 14:52:49
// -----------------------------------------------------------------------*/

#include "stdafx.h"
#include <set>
#include "../include/BorderPropertyPage.h"
#include "../include/worksheet.h"
#include "../include/misc.h"
#include "../include/DrawGhost.h"
using namespace std;
namespace mycell{namespace BorderPP{
	void GradientRectXP(HDC hDC, LPRECT pRect, COLORREF pColor[4])
	{
		TRIVERTEX			v[4]; 
		GRADIENT_RECT		grect;
		GRADIENT_TRIANGLE	gtri;
		int i = 0;
		for (; i < 4; i++)
		{
			v[i].Red   = ((COLOR16) GetRValue(pColor[i])) << 8;
			v[i].Green = ((COLOR16) GetGValue(pColor[i])) << 8;
			v[i].Blue  = ((COLOR16) GetBValue(pColor[i])) << 8;
			v[i].Alpha = ((COLOR16) (pColor[i] >> 24)) << 8;
		}

		v[0].x = pRect->left;
		v[0].y = pRect->top;
		v[1].x = pRect->right;
		v[1].y = pRect->top;
		v[2].x = pRect->left;
		v[2].y = pRect->bottom;
		v[3].x = pRect->right;
		v[3].y = pRect->bottom;

		if ((pColor[0] == pColor[2]) &&	(pColor[1] == pColor[3]))
			i = GRADIENT_FILL_RECT_H;

		if ((pColor[0] == pColor[1]) &&
			(pColor[2] == pColor[3]))
		{
			i = GRADIENT_FILL_RECT_V;
		}
		else
		{
			i = GRADIENT_FILL_TRIANGLE;
		}

		if (i == GRADIENT_FILL_TRIANGLE)
		{
			gtri.Vertex1 = 0;
			gtri.Vertex2 = 1;
			gtri.Vertex3 = 2;
		}
		else
		{
			grect.UpperLeft = 0;
			grect.LowerRight = 3;
		}

		GradientFill(hDC, v, 4, ((i == GRADIENT_FILL_TRIANGLE) ? ((PVOID)&gtri) : ((PVOID)&grect)), 1, i);

		if (i == GRADIENT_FILL_TRIANGLE)
		{
			gtri.Vertex1 = 3;
			GradientFill(hDC, v, 4, &gtri, 1, GRADIENT_FILL_TRIANGLE);
		}
	}
	void DrawPushButton(LPDRAWITEMSTRUCT lpdis)
	{
		HDC hdc=lpdis->hDC;
		HDC			memdc;
		CBitmap		bitmap;
		HBRUSH		brush;
		RECT		rc=lpdis->rcItem;
		COLORREF	color;
		//HGDIOBJ		handle;

		static COLORREF GradientLUT[][4] =
		{
			{0x00C1CCD1, 0x00C1CCD1, 0x00EEF1F2, 0xFFEEF1F2},
			{0x00CFF0FF, 0x00CFF0FF, 0x000097E5, 0xFF0097E5},
			{0x00BDCBD6, 0x00C6CFD6, 0x00EFF3F7, 0xFFEFF3F7},
			{0x00FFE7CE, 0x00FFE7CE, 0x00EE8269, 0xFFEE8269},
			{0x00FFFFFF, 0x00FFFFFF, 0x00D6DFE2, 0xFFD6DFE2},

			{0x00DEE3E7, 0x00E7E7E7, 0x00DEE3E7, 0xFFDEE3E7},
			{0x00FBFCFC, 0x00FBFCFC, 0x00E6EBEC, 0xFFE6EBEC},
		};

		//GetWindowRect(hWnd, &rc);

		int w = rc.right - rc.left;
		int h = rc.bottom - rc.top;

		rc.left   = 0;
		rc.top    = 0;
		rc.right  = w;
		rc.bottom = h;

		//hdc   = GetWindowDC(hWnd);
		memdc = CreateCompatibleDC(hdc);
		SetBkMode(memdc, TRANSPARENT);

		bitmap.CreateCompatibleBitmap(hdc, w, h);
		HGDIOBJ hOldBitmap=SelectObject(memdc, bitmap);

		// ���߿�
		//lpdis->itemState & ODS_SELECTED
		brush = CreateSolidBrush((lpdis->itemState & ODS_DISABLED) ? (GetSysColor(COLOR_BTNFACE) - 0x00202020) : 0x00733C00);
		FrameRect(memdc, &rc, brush);
		DeleteObject(brush);

		// ���ȵ�򽥱䱳��
		InflateRect(&rc, -1, -1);
		if (lpdis->itemState & ODS_DISABLED)
		{
			brush = CreateSolidBrush(0x00EAF4F5);
			FillRect(memdc, &rc, brush);
			DeleteObject(brush);
		}
		else
		{
			if (/*xp->m_state & XPS_PRESSED*/lpdis->itemState & ODS_SELECTED)
				GradientRectXP(memdc, &rc, GradientLUT[0]);
			else if (lpdis->itemState & ODS_HOTLIGHT/*xp->m_state & XPS_HOTLIGHT*/)
				GradientRectXP(memdc, &rc, GradientLUT[1]);
			else if ((lpdis->itemState & ODS_CHECKED/*xp->m_state & XPS_CHECKED*/) /*|| (xp->m_state & XPS_INDETERMINATE)*/)
				GradientRectXP(memdc, &rc, GradientLUT[2]);
			else if (lpdis->itemState & ODS_FOCUS/*xp->m_state & XPS_FOCUS*/)
				GradientRectXP(memdc, &rc, GradientLUT[3]);
			else
				GradientRectXP(memdc, &rc, GradientLUT[4]);
		}

		// ���������򽥱䱳��
		InflateRect(&rc, -2, -2);
		if ((/*xp->m_state & XPS_PRESSED*/lpdis->itemState & ODS_SELECTED) ||
			(/*xp->m_state & XPS_CHECKED*/lpdis->itemState & ODS_CHECKED) //||
			//(xp->m_state & XPS_INDETERMINATE)
			)
		{
			GradientRectXP(memdc, &rc, GradientLUT[5]);
		}
		else if (!(lpdis->itemState & ODS_DISABLED))
		{
			GradientRectXP(memdc, &rc, GradientLUT[6]);
		}

		// ����ϵͳ��ťһֱ����ɫ�ڶ���߿���Ľ�����
		color = GetSysColor(COLOR_BTNFACE);
		SetPixel(memdc, 0, 0, color);
		SetPixel(memdc, 0, h-1, color);
		SetPixel(memdc, w-1, h-1 , color);
		SetPixel(memdc, w-1, 0, color);

		// ���ڶ���߿�Ĺս�����
		color = (lpdis->itemState & ODS_DISABLED) ? (GetSysColor(COLOR_BTNFACE) - 0x00151515) : 0x00A57D52;
		SetPixel(memdc, 1, 1, color);
		SetPixel(memdc, 1, h-2, color);
		SetPixel(memdc, w-2, h-2, color);
		SetPixel(memdc, w-2, 1, color);

		color = (lpdis->itemState & ODS_DISABLED) ? (GetSysColor(COLOR_BTNFACE) - 0x00111111) : 0x00AD967B;
		SetPixel(memdc, 0, 1, color);
		SetPixel(memdc, 1, 0, color);
		SetPixel(memdc, w-2, 0, color);
		SetPixel(memdc, w-1, 1, color);
		SetPixel(memdc, 0, h-2, color);
		SetPixel(memdc, 1, h-1, color);
		SetPixel(memdc, w-1, h-2, color);
		SetPixel(memdc, w-2, h-1, color);

		// ����н��㣬���������
		if (lpdis->itemState & ODS_FOCUS)
		{
			InflateRect(&rc, 1, 1);
			DrawFocusRect(memdc, &rc);
		}

		//// ������
		//OffsetRect(&rc, 0, -1);
		//char value[1024];
		//if (GetWindowText(hWnd, value, sizeof(value)))
		//{
		//	if (xp->m_state & XPS_PRESSED)
		//		OffsetRect(&rc, 1, 1);

		//	SetTextColor(memdc, ((xp->m_state & XPS_INDETERMINATE) || (xp->m_state & XPS_DISABLED)) ? 0x0094A2A5: 0x00000000);

		//	handle = SelectObject(memdc, (HGDIOBJ)SendMessage(hWnd, WM_GETFONT, 0, 0));

		//	if (xp->m_state & XPS_MULTILINE)
		//		DrawText(memdc, value, -1, &rc, DT_CENTER | DT_VCENTER);
		//	else
		//		DrawText(memdc, value, -1, &rc, DT_SINGLELINE | DT_CENTER | DT_VCENTER);

		//	SelectObject(memdc, handle);
		//}

		BitBlt(hdc, 0, 0, w, h, memdc, 0, 0, SRCCOPY);
		SelectObject(memdc, hOldBitmap);
		//DeleteObject(SelectObject(memdc,bitmap));
		DeleteDC(memdc);
		//ReleaseDC(hWnd, hdc);
	}

	Border BorderSelectorWindow::GetBorder()const
	{
		int const focusRow=(short)LOWORD(focus_);
		int const focusCol=(short)HIWORD(focus_);
		Border bdr;
		ColorTable::TIndex const iClr=ColorTable::Instance().find_color(color_);
		bdr.put_ColorIndex(max(iClr>55?0:iClr,0));
		if(0==focusCol){
			switch(focusRow)
			{
			case 0:
				bdr.put_LineStyle(xlLineStyleNone);
				break;
			case 1:
				bdr.put_LineStyle(xlContinuous);
				bdr.put_Weight(0);
				break;
			case 2:
				bdr.put_LineStyle(xlDot);
				bdr.put_Weight(1);
				break;
			case 3:
				bdr.put_LineStyle(xlDashDotDot);
				bdr.put_Weight(1);
				break;
			case 4:
				bdr.put_LineStyle(xlDashDot);
				bdr.put_Weight(1);
				break;
			case 5:
				bdr.put_LineStyle(xlDash);
				bdr.put_Weight(1);
				break;
			case 6:
				bdr.put_LineStyle(xlContinuous);
				bdr.put_Weight(1);
				break;
			}
		}else{
			switch(focusRow)
			{
			case 0:
				bdr.put_LineStyle(xlDashDotDot);
				bdr.put_Weight(2);
				break;
			case 1:
				bdr.put_LineStyle(xlSlantDashDot);
				bdr.put_Weight(2);
				break;
			case 2:
				bdr.put_LineStyle(xlDashDot);
				bdr.put_Weight(2);
				break;
			case 3:
				bdr.put_LineStyle(xlDash);
				bdr.put_Weight(2);
				break;
			case 4:
				bdr.put_LineStyle(xlContinuous);
				bdr.put_Weight(2);
				break;
			case 5:
				bdr.put_LineStyle(xlContinuous);
				bdr.put_Weight(3);
				break;
			case 6:
				bdr.put_LineStyle(xlDouble);
				bdr.put_Weight(3);
				break;
			}
		}
		return bdr;
	}
	HPEN BorderSelectorWindow::GetPen(int row,int col)const
	{
		LOGBRUSH lbr;
		lbr.lbColor=color_;
		lbr.lbStyle=BS_SOLID;
		lbr.lbHatch=0;
		if(0==col){
			switch(row)
			{
			case 1:
				return ExtCreatePen(PS_COSMETIC|PS_ALTERNATE,1,&lbr,0,NULL);//2,style);
			case 2:
				{
					DWORD style[]={1,3};
					return ExtCreatePen(PS_GEOMETRIC|PS_USERSTYLE,1,&lbr,2,style);
				}break;
			case 3:
				{
					DWORD style[]={3,4,3,4,9,4};
					return ExtCreatePen(PS_GEOMETRIC|PS_USERSTYLE,1,&lbr,sizeof(style)/sizeof(DWORD),style);
				}break;
			case 4:
				{
					DWORD style[]={3,4,9,4};
					return ExtCreatePen(PS_GEOMETRIC|PS_USERSTYLE,1,&lbr,sizeof(style)/sizeof(DWORD),style);
				}break;
			case 5:
				{
					DWORD style[]={3,2};
					return ExtCreatePen(PS_GEOMETRIC|PS_USERSTYLE,1,&lbr,sizeof(style)/sizeof(DWORD),style);
				}break;
			case 6:
				return CreatePen(PS_SOLID,0,color_);
			}
		}else{
			switch(row)
			{
			case 0:
				{
					DWORD style[]={3,4,3,4,9,4};
					return ExtCreatePen(PS_GEOMETRIC|PS_USERSTYLE|PS_ENDCAP_SQUARE,2,&lbr,sizeof(style)/sizeof(DWORD),style);
				}break;
			case 1:
				return ExtCreatePen(PS_COSMETIC|PS_ALTERNATE,1,&lbr,0,NULL);
			case 2:
				{
					DWORD style[]={9,4,3,4};
					return ExtCreatePen(PS_GEOMETRIC|PS_USERSTYLE|PS_ENDCAP_SQUARE,2,&lbr,sizeof(style)/sizeof(DWORD),style);
				}break;
			case 3:
				{
					DWORD style[]={9,4};
					return ExtCreatePen(PS_GEOMETRIC|PS_USERSTYLE|PS_ENDCAP_SQUARE,2,&lbr,sizeof(style)/sizeof(DWORD),style);
				}break;
			case 4:
				return ExtCreatePen(PS_GEOMETRIC|PS_SOLID|PS_ENDCAP_SQUARE,2,&lbr,0,NULL);
			case 5:
				return ExtCreatePen(PS_GEOMETRIC|PS_SOLID|PS_ENDCAP_SQUARE,3,&lbr,0,NULL);
			case 6:
				return CreatePen(PS_SOLID,0,0);
			}
		}
		return CreatePen(PS_SOLID,0,0);
	}
	void BorderSelectorWindow::DrawCell(HDC hDC,int row,int col,LPRECT lprc)const
	{
		CDCHandle dc(hDC);

		int const focusRow=(short)LOWORD(focus_);
		int const focusCol=(short)HIWORD(focus_);
		if(focusRow==row && focusCol==col){
			CRect rc=lprc;
			rc.DeflateRect(6,2);
			dc.DrawFocusRect(&rc);
		}

		int const yCenter=lprc->top+((lprc->bottom-lprc->top)>>1);
		if(!row && !col){
			LPCTSTR lpsz=_T("��");
			int const nCount=lstrlen(lpsz);
			dc.DrawText(lpsz,nCount,lprc,DT_SINGLELINE|DT_CENTER|DT_VCENTER);
		}else{
			LOGBRUSH lbr;
			lbr.lbColor=color_;
			lbr.lbStyle=BS_SOLID;
			lbr.lbHatch=0;

			if(1==row && 1==col){
				InflateRect(lprc,-8,0);
				DWORD style[]={11,2,6,2};
				HPEN hPen=dc.SelectPen(ExtCreatePen(PS_GEOMETRIC|PS_USERSTYLE|PS_ENDCAP_SQUARE,1,&lbr,sizeof(style)/sizeof(DWORD),style));
				dc.MoveTo(lprc->left+2,yCenter-1);
				dc.LineTo(lprc->right,yCenter-1);
				DeleteObject(dc.SelectPen(hPen));

				DWORD style1[]={10,3,4,3};
				hPen=dc.SelectPen(ExtCreatePen(PS_GEOMETRIC|PS_USERSTYLE|PS_ENDCAP_SQUARE,1,&lbr,sizeof(style1)/sizeof(DWORD),style1));
				dc.MoveTo(lprc->left,yCenter);
				dc.LineTo(lprc->right,yCenter);
				DeleteObject(dc.SelectPen(hPen));
			}else if(6==row && 1==col){
				HPEN hOldPen=dc.SelectPen(CreatePen(PS_SOLID,1,color_));
				InflateRect(lprc,-6,0);
				dc.MoveTo(lprc->left,yCenter-1);
				dc.LineTo(lprc->right,yCenter-1);
				dc.MoveTo(lprc->left,yCenter+1);
				dc.LineTo(lprc->right,yCenter+1);
				DeleteObject(dc.SelectPen(hOldPen));
			}else{
				InflateRect(lprc,-8,0);
				HPEN hOldPen=dc.SelectPen(GetPen(row,col));//CreatePen(PS_DOT,1,0));
				dc.MoveTo(lprc->left,yCenter);
				dc.LineTo(lprc->right,yCenter);
				DeleteObject(dc.SelectPen(hOldPen));
			}
		}
	}
	int BorderSelectorWindow::HitTest(POINT pt)const
	{
		CRect rc;
		GetClientRect(rc);
		rc.DeflateRect(2,2);
		WORD const col=pt.x<(rc.left+(rc.Width()>>1))?0:1;

		WORD row=0;
		int const height=int(rc.Height()/7.0f+.5f);
		if(pt.y>height){
			int hi=height<<1;
			for(row=1;row<6;++row,hi+=height){
				if(pt.y<hi)
					return MAKELONG(row,col);
			}
		}
		return MAKELONG(row,col);
	}
	LRESULT BorderSelectorWindow::OnPaint(UINT,WPARAM,LPARAM,BOOL&)
	{
		CPaintDC dc(m_hWnd);
		dc.SelectFont(GetFont());
		CRect rc;
		GetClientRect(rc);
		dc.DrawEdge(&rc,BDR_SUNKENINNER,BF_LEFT|BF_TOP);
		dc.DrawEdge(&rc,BDR_SUNKENOUTER,BF_RIGHT|BF_BOTTOM);
		rc.DeflateRect(2,2);
		CBrush br(CreateSolidBrush(RGB(0xff,0xff,0xff)));
		dc.FillRect(rc,br);
		int const height=int(rc.Height()/7.0f+.5f);
		int const xCenter=rc.left+(rc.Width()>>1);
		for(int i=0;i<7;++i){
			RECT rcCell={rc.left,rc.top+i*height,xCenter,rc.top+(1+i)*height};
			DrawCell(dc,i,0,&rcCell);
			rcCell.left=xCenter;
			rcCell.right=rc.right;
			DrawCell(dc,i,1,&rcCell);
		}
		return 0;
	}

	//------------------------------------------------------------------------------------------------
	void BorderPropertyPage::CreateDlg()
	{
		CreateDlgTemplate("�Ի���", DS_SETFONT|WS_CHILD, 0, 0, 0, 186, 100, 9, "����", "", "");
		//AddButton("ȷ��", 0|BS_DEFPUSHBUTTON, 0, 74, 20, 50, 14, IDOK);
		// Start generated dialog
		//CreateDlgTemplate("", 0, 0, 0, 0, 257, 170, WS_CHILD | DS_SETFONT, 9, "����", "", "");
		AddStatic("Ԥ��", 0, 0, 2, 7, 17, 8, IDC_STATIC);
		//AddStatic("Ԥ��", 0 | BS_GROUPBOX, 0, 10, 10, 125, 0, IDC_STATIC);

		AddDlgItem("", SS_ETCHEDHORZ, 0, 25, 10, 125, 1, IDC_STATIC, "Static", 0, NULL);
		AddButton("b1", BS_OWNERDRAW|WS_TABSTOP, 0, 28, 17, 24, 23, __IDC_BUTTON1);
		AddButton("b2", BS_OWNERDRAW|WS_TABSTOP, 0, 70, 17, 24, 23, __IDC_BUTTON2);
		AddButton("b3", BS_OWNERDRAW|WS_TABSTOP, 0, 111, 17, 24, 23, __IDC_BUTTON3);
		AddStatic("��(&N)", 0, 0, 37, 42, 19, 8, IDC_STATIC);
		AddStatic("��߿�(&O)", 0, 0, 69, 42, 36, 8, IDC_STATIC);
		AddStatic("�ڲ�(&I)", 0, 0, 112, 42, 33, 8, IDC_STATIC);
		AddStatic("�߿�", 0, 0, 3, 52, 17, 8, IDC_STATIC);
		AddDlgItem("", SS_ETCHEDHORZ, 0, 25, 54, 124, 1, IDC_STATIC, "Static", 0, NULL);
		AddButton("IDC_STATIC_1", BS_OWNERDRAW|WS_TABSTOP, 0, 30, 62, 110, 68, __IDC_BTN_SCRATCH);
		AddButton("b4", BS_OWNERDRAW|WS_TABSTOP, 0, 9, 62, 15, 0xf, __IDC_BUTTON4);
		AddButton("b5", BS_OWNERDRAW|WS_TABSTOP, 0, 9, 87, 15, 0xf, __IDC_BUTTON5);
		AddButton("b6", BS_OWNERDRAW|WS_TABSTOP, 0, 9, 112, 15, 0xf, __IDC_BUTTON6);
		AddButton("b7", BS_OWNERDRAW|WS_TABSTOP, 0, 9, 136, 15, 0xf, __IDC_BUTTON7);
		AddButton("b8", BS_OWNERDRAW|WS_TABSTOP, 0, 37, 136, 15, 0xf, __IDC_BUTTON8);
		AddButton("b9", BS_OWNERDRAW|WS_TABSTOP, 0, 65, 136, 15, 0xf, __IDC_BUTTON9);
		AddButton("b10", BS_OWNERDRAW|WS_TABSTOP, 0, 93, 136, 15, 0xf, __IDC_BUTTON10);
		AddButton("b11", BS_OWNERDRAW|WS_TABSTOP, 0, 121, 136, 15, 0xf, __IDC_BUTTON11);
		AddStatic("����Ԥ��ѡ�Ԥ����ͼ������İ�ť������ӱ߿���ʽ��", 0, 0, 7, 166, 209, 8,  IDC_STATIC);
		AddButton("����", 0 | BS_GROUPBOX, 0, 163, 7, 90, 147, IDC_STATIC);
		AddStatic("��ʽ(&S):", 0, 0, 169, 19, 38, 8, IDC_STATIC);
		AddButton("IDC_STATIC_STYLE", WS_TABSTOP, 0, 169, 30, 78, 90, __IDC_STATIC_STYLE);
		AddStatic("��ɫ(&C):", 0, 0, 170, 125, 38, 8, IDC_STATIC);
		AddButton("IDC_BTNCOLOR", 0, 0, 169, 136, 78, 14, __IDC_BUTTON12);
		// End generated dialog
	}
	/*
	void BorderPropertyPage::SetLeftBorder(int row0,int row1,int col,Border bdr)
	{
	for(int r=row0;r<=row1;++r){
	CCell cell(r,col);
	style::StyleDesc style=pSheet_->Style_GetCellStyle(cell);
	style.GetBorders()->left=bdr;
	pSheet_->Style_SetCellStyle(cell,style);

	//	if(col>0){
	//		cell.col=col-1;
	//		style=pSheet_->Style_GetCellStyle(cell);
	//		style.GetBorders()->right.SetNull();
	//		pSheet_->Style_SetCellStyle(cell,style);
	//	}
	}
	}
	void BorderPropertyPage::SetRightBorder(int row0,int row1,int col,Border bdr)
	{
	const int cols=pSheet_->get_ColHeader().get_cols();
	for(int r=row0;r<=row1;++r){
	CCell cell(r,col);
	style::StyleDesc style=pSheet_->Style_GetCellStyle(cell);
	style.GetBorders()->right=bdr;
	pSheet_->Style_SetCellStyle(cell,style);
	//if(col<cols-1)
	//{
	//	cell.col=col+1;
	//	style=pSheet_->Style_GetCellStyle(cell);
	//	style.GetBorders()->left.SetNull();
	//	pSheet_->Style_SetCellStyle(cell,style);
	//}
	}
	}
	void BorderPropertyPage::SetTopBorder(int col0,int col1,int row,Border bdr)
	{
	for(int c=col0;c<=col1;++c){
	CCell cell(row,c);
	style::StyleDesc style=pSheet_->Style_GetCellStyle(cell);
	style.GetBorders()->top=bdr;
	pSheet_->Style_SetCellStyle(cell,style);

	//if(row>0){
	//	cell.row=row-1;
	//	style=pSheet_->Style_GetCellStyle(cell);
	//	style.GetBorders()->bottom.SetNull();
	//	pSheet_->Style_SetCellStyle(cell,style);
	//}
	}
	}
	void BorderPropertyPage::SetBottomBorder(int col0,int col1,int row,Border bdr)
	{
	const int rows=pSheet_->get_RowHeader().get_rows();
	for(int c=col0;c<=col1;++c){
	CCell cell(row,c);
	style::StyleDesc style=pSheet_->Style_GetCellStyle(cell);
	style.GetBorders()->bottom=bdr;
	pSheet_->Style_SetCellStyle(cell,style);
	//if(row<rows-1)
	//{
	//	cell.row=row+1;
	//	style=pSheet_->Style_GetCellStyle(cell);
	//	style.GetBorders()->top.SetNull();
	//	pSheet_->Style_SetCellStyle(cell,style);
	//}
	}
	}
	*/
	STDMETHODIMP BorderPropertyPage::Apply(void)
	{
		//ATLTRACE(atlTraceControls,2,_T("PropertyPageBase::Apply\n"));
		const row_t rows=pSheet_->get_RowHeader().get_rows();
		style::StyleDesc style;
		Ranges rngs;
		vector<CCellRange>& vec=rngs.vec_;
		pSheet_->get_Selection(rngs);
		sort(vec.begin(),vec.end(),BorderRangeSorter());
		vector<pair<col_t,StyleID_t> > mapCols;
		pSheet_->get_ColHeader().Style_EnumCols(mapCols);
		vector<pair<row_t,StyleID_t> > mapRows;
		pSheet_->get_RowHeader().Style_EnumRows(mapRows);

		UINT nMask=0;
		if(scratch_.cellBorder_.left.fDirty)
			nMask|=xlEdgeLeft;
		if(scratch_.cellBorder_.top.fDirty)
			nMask|=xlEdgeTop;
		if(scratch_.cellBorder_.right.fDirty)
			nMask|=xlEdgeRight;
		if(scratch_.cellBorder_.bottom.fDirty)
			nMask|=xlEdgeBottom;
		if(scratch_.cellBorder_.DiagonalDown.fDirty)
			nMask|=xlDiagonalDown;
		if(scratch_.cellBorder_.DiagonalUp.fDirty)
			nMask|=xlDiagonalUp;
		if(scratch_.hasInsideVertical_ && scratch_.cellBorder_.InsideVertical.fDirty)
			nMask|=xlInsideVertical;
		if(scratch_.hasInsideHorizontal_ && scratch_.cellBorder_.InsideHorizontal.fDirty)
			nMask|=xlInsideHorizontal;

		vector<pair<CCell,const CellStore*> > vecCells;
		pSheet_->EnumCells(vecCells);
		for(vector<CCellRange>::const_iterator it=vec.begin();it!=vec.end();++it)
		{
			pSheet_->Range_SetBorder(*it,scratch_.cellBorder_.ToCellBorder(),scratch_.cellBorder_.InsideHorizontal.get(),scratch_.cellBorder_.InsideVertical.get(),nMask);
			continue;
			if(HEADER_COL==it->LeftCol() && HEADER_ROW==it->TopRow()){
				/*
				style=pSheet_->Style_GetTableStyle();
				Borders* pBdrs=style.GetBorders();
				pBdrs->left=scratch_.cellBorder_.InsideVertical.get();
				pBdrs->top=scratch_.cellBorder_.InsideHorizontal.get();
				pBdrs->right=scratch_.cellBorder_.InsideVertical.get();
				pBdrs->bottom=scratch_.cellBorder_.InsideHorizontal.get();
				pSheet_->Style_SetTableStyle(style);

				for(vector<pair<col_t,StyleID_t> >::const_iterator i=mapCols.begin();i!=mapCols.end();++i){
					if(i->second){
						const StyleDesc sd=pSheet_->Style_GetColStyle(i->first);
						if(!sd.style.GetBorders()->empty()){
							style=sd.style;
							Borders* pBdrs=style.GetBorders();
							pBdrs->left=scratch_.cellBorder_.InsideVertical.get();
							pBdrs->top=scratch_.cellBorder_.InsideHorizontal.get();
							pBdrs->right=scratch_.cellBorder_.InsideVertical.get();
							pBdrs->bottom=scratch_.cellBorder_.InsideHorizontal.get();
							pSheet_->Style_SetColStyle(i->first,style);
						}
					}
				}

				for(vector<pair<CCell,const CellStore*> >::const_iterator i=vecCells.begin();i!=vecCells.end();++i){
					if(i->second->nStyleID){
						const StyleDesc& sd=pSheet_->Style_GetCellStyle(i->first).style;
						if(!sd.GetBorders()->empty()){
							style=sd;
							//style.GetBorders()->clear();
							Borders* pBdrs=style.GetBorders();
							pBdrs->left=scratch_.cellBorder_.InsideVertical.get();
							pBdrs->top=scratch_.cellBorder_.InsideHorizontal.get();
							pBdrs->right=scratch_.cellBorder_.InsideVertical.get();
							pBdrs->bottom=scratch_.cellBorder_.InsideHorizontal.get();
							pSheet_->Style_SetCellStyle(i->first,style);
						}
					}
				}

				for(vector<pair<row_t,StyleID_t> >::const_iterator i=mapRows.begin();i!=mapRows.end();++i){
					if(i->second){
						const StyleDesc& sd=pSheet_->Style_GetRowStyle(i->first);
						if(!sd.GetBorders()->empty()){
							style=sd;
							//style.GetBorders()->clear();
							Borders* pBdrs=style.GetBorders();
							pBdrs->left=scratch_.cellBorder_.InsideVertical.get();
							pBdrs->top=scratch_.cellBorder_.InsideHorizontal.get();
							pBdrs->right=scratch_.cellBorder_.InsideVertical.get();
							pBdrs->bottom=scratch_.cellBorder_.InsideHorizontal.get();

							pSheet_->Style_SetRowStyle(i->first,style);
						}
					}
				}
				*/
			}else if(HEADER_COL==it->LeftCol()){
				/*
				const int topRow=max(0,it->TopRow());
				const int bottomRow=it->BottomRow();
				const int leftCol=max(0,it->LeftCol());
				const int rightCol=it->RightCol();

				for(vector<pair<CCell,const CellStore*> >::const_iterator i=vecCells.begin();i!=vecCells.end();++i){
					if(i->second->nStyleID){
						if(it->Inside(i->first)){
							//pSheet_->Style_ClearCellStyle(i->first);
							const StyleDesc& sd=pSheet_->Style_GetStyleByID(i->second->nStyleID);
							if(!sd.GetBorders()->empty()){
								style=sd;
								style.GetBorders()->clear();
								pSheet_->Style_SetCellStyle(i->first,style);
							}
						}else if(i->first.row==topRow-1){
							const StyleDesc& sd=pSheet_->Style_GetStyleByID(i->second->nStyleID);
							if(!sd.GetBorders()->bottom.IsNull()){
								style=sd;
								style.GetBorders()->bottom.SetNull();
								pSheet_->Style_SetCellStyle(i->first,style);
							}
						}else if(i->first.row==bottomRow+1){
							const StyleDesc& sd=pSheet_->Style_GetStyleByID(i->second->nStyleID);
							if(!sd.GetBorders()->top.IsNull()){
								style=sd;
								style.GetBorders()->top.SetNull();
								pSheet_->Style_SetCellStyle(i->first,style);
							}
						}
					}
				}

				for(int r=topRow;r<=bottomRow;++r){
					style=pSheet_->Style_GetRowStyle(r);
					Borders* pbdrs=style.GetBorders();
					if(topRow==r){
						pbdrs->top=scratch_.cellBorder_.top.get();
						if(bottomRow!=r)
							pbdrs->bottom=scratch_.cellBorder_.InsideHorizontal.get();
					}
					if(bottomRow==r){
						pbdrs->bottom=scratch_.cellBorder_.bottom.get();
						if(topRow!=r)
							pbdrs->top=scratch_.cellBorder_.InsideHorizontal.get();
					}
					if(r>topRow && r<bottomRow){
						pbdrs->top=scratch_.cellBorder_.InsideHorizontal.get();
						pbdrs->bottom=scratch_.cellBorder_.InsideHorizontal.get();
					}
					pbdrs->left=pbdrs->right=scratch_.cellBorder_.InsideVertical.get();
					pSheet_->Style_SetRowStyle(r,style);
				}
				*/
			}else if(HEADER_ROW==it->TopRow()){
				/*
				const int topRow=max(0,it->TopRow());
				const int bottomRow=it->BottomRow();
				const int leftCol=max(0,it->LeftCol());
				const int rightCol=it->RightCol();
				for(vector<pair<CCell,const CellStore*> >::const_iterator i=vecCells.begin();i!=vecCells.end();++i){
					if(i->second->nStyleID){
						if(it->Inside(i->first)){
							//pSheet_->Style_ClearCellStyle(i->first);
							const StyleDesc& sd=pSheet_->Style_GetStyleByID(i->second->nStyleID);
							if(!sd.GetBorders()->empty()){
								style=sd;
								style.GetBorders()->clear();
								pSheet_->Style_SetCellStyle(i->first,style);
							}
						}else if(i->first.col==leftCol-1){
							const StyleDesc& sd=pSheet_->Style_GetStyleByID(i->second->nStyleID);
							if(!sd.GetBorders()->right.IsNull()){
								style=sd;
								style.GetBorders()->right.SetNull();
								pSheet_->Style_SetCellStyle(i->first,style);
							}
						}else if(i->first.col==rightCol+1){
							const StyleDesc& sd=pSheet_->Style_GetStyleByID(i->second->nStyleID);
							if(!sd.GetBorders()->left.IsNull()){
								style=sd;
								style.GetBorders()->left.SetNull();
								pSheet_->Style_SetCellStyle(i->first,style);
							}
						}
					}
				}
				for(int c=leftCol;c<=rightCol;++c){
					style=pSheet_->Style_GetColStyle(c).style;
					Borders* pbdrs=style.GetBorders();
					if(leftCol==c){
						pbdrs->left=scratch_.cellBorder_.left.get();
						pbdrs->right=rightCol==c?scratch_.cellBorder_.right.get():scratch_.cellBorder_.InsideVertical.get();
					}
					if(rightCol==c && leftCol!=c){
						pbdrs->right=scratch_.cellBorder_.right.get();
						pbdrs->left=scratch_.cellBorder_.InsideVertical.get();
					}
					if(c>leftCol && c<rightCol){
						pbdrs->left=scratch_.cellBorder_.InsideVertical.get();
						pbdrs->right=scratch_.cellBorder_.InsideVertical.get();
					}
					pbdrs->top=pbdrs->bottom=scratch_.cellBorder_.InsideHorizontal.get();
					pSheet_->Style_SetColStyle(c,style);
				}
				*/
			}else{
				pSheet_->Range_SetBorder(*it,scratch_.cellBorder_.ToCellBorder(),scratch_.cellBorder_.InsideHorizontal.get(),scratch_.cellBorder_.InsideVertical.get(),nMask);
				//const int topRow=max(0,it->TopRow());
				//const int bottomRow=it->BottomRow();
				//const int leftCol=max(0,it->LeftCol());
				//const int rightCol=it->RightCol();
				//StyleDesc style;
				//for(int r=topRow;r<=bottomRow;++r){
				//	for(int c=leftCol;c<=rightCol;++c){
				//		CCell cell(r,c);
				//		const CCellRange* pMerge=((const Worksheet*)pSheet_)->GetMergeCells(cell);
				//		/*
				//		if(pMerge && pMerge->FullInside(r,c))
				//			continue;
				//		if(pMerge && cell!=pMerge->TopLeft())
				//			cell=pMerge->TopLeft();
				//			*/
				//		if(pMerge && cell!=pMerge->TopLeft())
				//			continue;
				//		/*
				//		if(pMerge && cell==pMerge->TopLeft()){
				//			style=pSheet_->Style_GetCellStyle(cell);
				//			Borders bdrs=style.GetBorders();
				//			if(leftCol==c && scratch_.cellBorder_.left.fDirty){
				//				bdrs.left=scratch_.cellBorder_.left.get();
				//			}
				//			if(rightCol==pMerge->RightCol() && scratch_.cellBorder_.right.fDirty){
				//				bdrs.right=scratch_.cellBorder_.right.get();
				//			}
				//			if(topRow==r && scratch_.cellBorder_.top.fDirty){
				//				bdrs.top=scratch_.cellBorder_.top.get();
				//			}
				//			if(bottomRow==r && scratch_.cellBorder_.bottom.fDirty)
				//				bdrs.bottom=scratch_.cellBorder_.bottom.get();
				//			if(c>leftCol && scratch_.hasInsideVertical_ && scratch_.cellBorder_.InsideVertical.fDirty){
				//				bdrs.left=scratch_.cellBorder_.InsideVertical.get();
				//			}
				//			if(r>topRow && scratch_.hasInsideHorizontal_ && scratch_.cellBorder_.InsideHorizontal.fDirty)
				//				bdrs.top=scratch_.cellBorder_.InsideHorizontal.get();
				//			if(bdrs!=*style.GetBorders()){
				//				*style.GetBorders()=bdrs;
				//				pSheet_->Style_SetCellStyle(cell,style);
				//			}
				//		}else*/
				//		{
				//			style=pSheet_->Style_GetCellStyle(cell);
				//			Borders bdrs=style.GetBorders();
				//			if(leftCol==c && scratch_.cellBorder_.left.fDirty){
				//				bdrs.left=scratch_.cellBorder_.left.get();
				//			}
				//			if(scratch_.cellBorder_.right.fDirty && (rightCol==c || pMerge && rightCol==pMerge->RightCol())){
				//				bdrs.right=scratch_.cellBorder_.right.get();
				//			}
				//			if(topRow==r && scratch_.cellBorder_.top.fDirty){
				//				bdrs.top=scratch_.cellBorder_.top.get();
				//			}
				//			if(scratch_.cellBorder_.bottom.fDirty && (bottomRow==r||pMerge && bottomRow==pMerge->BottomRow()))
				//				bdrs.bottom=scratch_.cellBorder_.bottom.get();
				//			if(c>leftCol && scratch_.hasInsideVertical_ && scratch_.cellBorder_.InsideVertical.fDirty){
				//				bdrs.left=scratch_.cellBorder_.InsideVertical.get();
				//			}
				//			if(r>topRow && scratch_.hasInsideHorizontal_ && scratch_.cellBorder_.InsideHorizontal.fDirty)
				//				bdrs.top=scratch_.cellBorder_.InsideHorizontal.get();
				//			if(bdrs!=*style.GetBorders()){
				//				*style.GetBorders()=bdrs;
				//				pSheet_->Style_SetCellStyle(cell,style);
				//			}
				//		}
				//		/*
				//		if(pMerge && cell!=pMerge->TopLeft())
				//			continue;
				//		if(r>topRow && r<bottomRow && scratch_.hasInsideHorizontal_ && scratch_.cellBorder_.InsideHorizontal.fDirty){
				//			pbdrs->top=scratch_.cellBorder_.InsideHorizontal.get();
				//			pbdrs->bottom=scratch_.cellBorder_.InsideHorizontal.get();
				//		}
				//		if(topRow==r && scratch_.cellBorder_.top.fDirty){
				//			pbdrs->top=scratch_.cellBorder_.top.get();
				//			if(bottomRow!=r && scratch_.hasInsideHorizontal_ && scratch_.cellBorder_.InsideHorizontal.fDirty)
				//				pbdrs->bottom=scratch_.cellBorder_.InsideHorizontal.get();
				//		}
				//		if(bottomRow==r && scratch_.cellBorder_.bottom.fDirty){
				//			if(topRow!=r && scratch_.hasInsideHorizontal_ && scratch_.cellBorder_.InsideHorizontal.fDirty)
				//				pbdrs->top=scratch_.cellBorder_.InsideHorizontal.get();
				//			pbdrs->bottom=scratch_.cellBorder_.bottom.get();
				//		}
				//		if(c>leftCol && c<rightCol && scratch_.cellBorder_.InsideVertical.fDirty){
				//			pbdrs->left=scratch_.cellBorder_.InsideVertical.get();
				//			pbdrs->right=scratch_.cellBorder_.InsideVertical.get();
				//		}
				//		if(leftCol==c && scratch_.cellBorder_.left.fDirty){
				//			pbdrs->left=scratch_.cellBorder_.left.get();
				//			if(rightCol!=c && scratch_.hasInsideVertical_ &&scratch_.cellBorder_.InsideVertical.fDirty)
				//				pbdrs->right=scratch_.cellBorder_.InsideVertical.get();
				//		}
				//		if(rightCol==c && scratch_.cellBorder_.right.fDirty){
				//			if(leftCol!=c && scratch_.hasInsideVertical_ &&scratch_.cellBorder_.InsideVertical.fDirty)
				//				pbdrs->left=scratch_.cellBorder_.InsideVertical.get();
				//			pbdrs->right=scratch_.cellBorder_.right.get();
				//		}
				//		pSheet_->Style_SetCellStyle(cell,style);
				//		*/
				//	}
				//}
			}
		}
		pSheet_->RedrawWindow();
		return S_OK;
	}
	Border BorderPropertyPage::GetTopBorder(CCell cell)const
	{
		Border bdr=  pSheet_->Style_GetCellStyle(cell).GetBorders()->top;
		if(bdr.IsNull() && cell.row>0)
			bdr=pSheet_->Style_GetCellStyle(CCell(cell.row-1,cell.col)).GetBorders()->bottom;
		return bdr;
	}
	Border BorderPropertyPage::GetLeftBorder(CCell cell)const
	{
		Border bdr= pSheet_->Style_GetCellStyle(cell).GetBorders()->left;
		if(bdr.IsNull() && cell.col>0)
			bdr=pSheet_->Style_GetCellStyle(CCell(cell.row,cell.col-1)).GetBorders()->right;
		return bdr;
	}
	Border BorderPropertyPage::GetRightBorder(CCell cell)const
	{
		Border bdr= pSheet_->Style_GetCellStyle(cell).GetBorders()->right;
		if(bdr.IsNull() && cell.col<pSheet_->get_ColHeader().get_cols()-1)
			bdr=pSheet_->Style_GetCellStyle(CCell(cell.row,cell.col+1)).GetBorders()->left;
		return bdr;
	}
	Border BorderPropertyPage::GetBottomBorder(CCell cell)const
	{
		Border bdr= pSheet_->Style_GetCellStyle(cell).GetBorders()->bottom;
		if(bdr.IsNull() && cell.row<pSheet_->get_RowHeader().get_rows()-1)
			bdr=pSheet_->Style_GetCellStyle(CCell(cell.row+1,cell.col)).GetBorders()->top;
		return bdr;
	}

	BOOL Range_HasVCenter(const Worksheet* pSheet,const CCellRange& cr)
	{
		if(cr.TopRow()==cr.BottomRow())
			return FALSE;
		for(int col=cr.LeftCol();col<=cr.RightCol();){
			const CCell cell(cr.BottomRow(),col);
			const CCellRange* pMerge=pSheet->GetMergeCells(cell);
			if(!pMerge)
				return TRUE;
			if(pMerge->TopRow()!=cr.TopRow())
				return TRUE;
			col=pMerge->RightCol()+1;
		}
		return FALSE;
	}
	BOOL Range_HasHCenter(const Worksheet* pSheet,const CCellRange& cr)
	{
		if(cr.LeftCol()==cr.RightCol())
			return FALSE;
		for(int row=cr.TopRow();row<=cr.BottomRow();){
			const CCell cell(row,cr.RightCol());
			const CCellRange* pMerge=pSheet->GetMergeCells(cell);
			if(!pMerge)
				return TRUE;
			if(pMerge->LeftCol()!=cr.LeftCol())
				return TRUE;
			row=pMerge->BottomRow()+1;
		}
		return FALSE;
	}
	/*
	void BorderPropertyPage::InitScratchsLeftBorder(const vector<CCellRange>& vec)
	{
		bool bFirst=true;
		for(vector<CCellRange>::const_iterator it=vec.begin();it!=vec.end();++it){
			Border _bdr;
			if(!pSheet_->Range_GetLeftBorder(*it,_bdr)){
				scratch_.cellBorder_.left.fDrawGhost=TRUE;
				break;
			}else{
				if(bFirst){
					scratch_.cellBorder_.left=_bdr;
					bFirst=false;
				}else{
					if(scratch_.cellBorder_.left.get()!=_bdr){
						scratch_.cellBorder_.left.fDrawGhost=TRUE;
						break;
					}
				}
			}
		}
	}
	void BorderPropertyPage::InitScratchsTopBorder(const vector<CCellRange>& vec)
	{
		bool bFirst=true;
		for(vector<CCellRange>::const_iterator it=vec.begin();it!=vec.end();++it){
			Border _bdr;
			if(!pSheet_->Range_GetTopBorder(*it,_bdr)){
				scratch_.cellBorder_.top.fDrawGhost=TRUE;
				break;
			}else{
				if(bFirst){
					scratch_.cellBorder_.top=_bdr;
					bFirst=false;
				}else{
					if(scratch_.cellBorder_.top.get()!=_bdr){
						scratch_.cellBorder_.top.fDrawGhost=TRUE;
						break;
					}
				}
			}
		}
	}
	*/
#define INIT_SCRATCHS_BORDER(Edge,edge,vec){\
			bool bFirst=true;\
			for(vector<CCellRange>::const_iterator it=vec.begin();it!=vec.end();++it){\
				Border _bdr;\
				if(!pSheet_->Range_Get##Edge##Border(*it,_bdr)){\
					scratch_.cellBorder_.##edge##.fDrawGhost=TRUE;\
					break;\
				}else{\
					if(bFirst){\
						scratch_.cellBorder_.##edge##=_bdr;\
						bFirst=false;\
					}else{\
						if(scratch_.cellBorder_.##edge##.get()!=_bdr){\
							scratch_.cellBorder_.##edge##.fDrawGhost=TRUE;\
							break;\
						}\
					}\
				}\
			}\
		}

	void BorderPropertyPage::InitScratchsBorders(const vector<CCellRange>& vec)
	{
		INIT_SCRATCHS_BORDER(Left,left,vec);
		INIT_SCRATCHS_BORDER(Top,top,vec);
		INIT_SCRATCHS_BORDER(Right,right,vec);
		INIT_SCRATCHS_BORDER(Bottom,bottom,vec);
		INIT_SCRATCHS_BORDER(InsideHorizontal,InsideHorizontal,vec);
		INIT_SCRATCHS_BORDER(InsideVertical,InsideVertical,vec);
	}
		/*
	{
		vector<Border> vecTopBdr,vecLeftBdr,vecRightBdr,vecBottomBdr,
			vecInsideVerticalBdr,vecInsideHorizontalBdr;
		for(vector<CCellRange>::const_iterator it=vec.begin();it!=vec.end();++it){
			Border bdr;
			
			if(!scratch_.cellBorder_.top.fDrawGhost){
				if(!pSheet_->Range_GetTopBorder(*it,bdr)){
					scratch_.cellBorder_.top.fDrawGhost=TRUE;
				}else{
					if(vecTopBdr.end()==find(vecTopBdr.begin(),vecTopBdr.end(),bdr)){
						if(vecTopBdr.empty())
							vecTopBdr.push_back(bdr);
						else
							scratch_.cellBorder_.top.fDrawGhost=TRUE;
					}
				}
			}
			if(!scratch_.cellBorder_.bottom.fDrawGhost){
				if(pSheet_->Range_GetBottomBorder(*it,bdr)){
					if(vecBottomBdr.end()==find(vecBottomBdr.begin(),vecBottomBdr.end(),bdr)){
						if(vecBottomBdr.empty())
							vecBottomBdr.push_back(bdr);
						else
							scratch_.cellBorder_.bottom.fDrawGhost=TRUE;
					}
				}else{
					scratch_.cellBorder_.bottom.fDrawGhost=TRUE;
				}
			}

			if(!scratch_.cellBorder_.left.fDrawGhost){
				if(pSheet_->Range_GetLeftBorder(*it,bdr)){
					if(vecLeftBdr.end()==find(vecLeftBdr.begin(),vecLeftBdr.end(),bdr)){
						if(vecLeftBdr.empty())
							vecLeftBdr.push_back(bdr);
						else
							scratch_.cellBorder_.left.fDrawGhost=TRUE;
					}
				}else{
					scratch_.cellBorder_.left.fDrawGhost=TRUE;
				}
			}
			if(!scratch_.cellBorder_.right.fDrawGhost){
				if(pSheet_->Range_GetRightBorder(*it,bdr)){
					if(vecRightBdr.end()==find(vecRightBdr.begin(),vecRightBdr.end(),bdr)){
						if(vecRightBdr.empty())
							vecRightBdr.push_back(bdr);
						else
							scratch_.cellBorder_.right.fDrawGhost=TRUE;
					}
				}else{
					scratch_.cellBorder_.right.fDrawGhost=TRUE;
				}
			}
		}

		if(!scratch_.cellBorder_.top.fDrawGhost){
			scratch_.cellBorder_.top=vecTopBdr[0];
		}else{
		}
		if(!scratch_.cellBorder_.bottom.fDrawGhost){
			scratch_.cellBorder_.bottom=vecBottomBdr[0];
		}else{
		}
		if(!scratch_.cellBorder_.left.fDrawGhost){
			scratch_.cellBorder_.left=vecLeftBdr[0];
		}else{
		}
		if(!scratch_.cellBorder_.right.fDrawGhost){
			scratch_.cellBorder_.right=vecRightBdr[0];
		}else{
		}
	}
	*/
	LRESULT BorderPropertyPage::OnInitDialog(UINT,WPARAM,LPARAM,BOOL&)
	{
		bsw_.SubclassWindow(GetDlgItem(__IDC_STATIC_STYLE));
		colorBtn_.SubclassWindow(GetDlgItem(__IDC_BUTTON12));
		//colorBtn_.SetDefaultText(_T("�Զ�"));
		//colorBtn_.SetCustomText(_T(""));
		ColorButton_t::ColorPopup_t& cp=colorBtn_.GetColorPopup();
		cp.SetDefaultText(_T("�Զ�"));

		//cp.SetCustomText(_T(""));
		//pair<ColorEntry*,int> p=mycell::ColorTable::GetColorTable();
		//cp.SetColourTable((ColorButton_t::ColorPopup_t::ColourTableEntry*)p.first,p.second);

		//SetDirty(TRUE);

		Ranges rngs;
		const vector<CCellRange>& vec=rngs.vec_;
		pSheet_->get_Selection(rngs);
		scratch_.hasInsideHorizontal_=FALSE;
		scratch_.hasInsideVertical_=FALSE;
		for(vector<CCellRange>::const_iterator it=vec.begin();it!=vec.end();++it){
			if(!scratch_.hasInsideVertical_ && Range_HasHCenter(pSheet_,*it))
				scratch_.hasInsideVertical_=TRUE;
			if(!scratch_.hasInsideHorizontal_&&Range_HasVCenter(pSheet_,*it))
				scratch_.hasInsideHorizontal_=TRUE;
			if(scratch_.hasInsideVertical_ && scratch_.hasInsideHorizontal_)
				break;
		}
		if(!scratch_.hasInsideVertical_){
			CWindow wnd(GetDlgItem(__IDC_BUTTON9));
			wnd.EnableWindow(FALSE);
		}
		if(!scratch_.hasInsideHorizontal_){
			CWindow wnd(GetDlgItem(__IDC_BUTTON5));
			wnd.EnableWindow(FALSE);
		}
		if(!scratch_.hasInsideHorizontal_ && !scratch_.hasInsideVertical_){
			CWindow wnd(GetDlgItem(__IDC_BUTTON3));
			wnd.EnableWindow(FALSE);
		}

		{//create scratch window
			CButton wndScratch=GetDlgItem(__IDC_BTN_SCRATCH);
			RECT rc={30, 62, 110, 68};
			wndScratch.GetWindowRect(&rc);
			ScreenToClient(&rc);
			wndScratch.ShowWindow(SW_HIDE);
			scratch_.wb_.Create(m_hWnd,rc,NULL,WS_CHILD|WS_VISIBLE|WS_CLIPSIBLINGS|WS_CLIPCHILDREN,WS_EX_CLIENTEDGE);
			scratch_.AfterCreate();
		}
		InitScratchsBorders(vec);
		scratch_.ApplyBorders();
		return 0;
	}
	LRESULT BorderPropertyPage::OnCommand(UINT,WPARAM wParam,LPARAM,BOOL&)
	{
		WORD		const wID=LOWORD(wParam);
		Border		bdr=bsw_.GetBorder();
		_border* pbdr=NULL;
		switch(wID)
		{
		case __IDC_BUTTON1: 
			{
				bdr.put_LineStyle(xlLineStyleNone);
				scratch_.cellBorder_.SetBorder(bdr);
				//scratch_.cellBorder_.InsideVertical=scratch_.cellBorder_.InsideHorizontal=bdr;
				scratch_.ApplyBorders();
				SetDirty(TRUE);
			}return 0;
		case __IDC_BUTTON2:
			{
				scratch_.cellBorder_.left=scratch_.cellBorder_.top=scratch_.cellBorder_.right=scratch_.cellBorder_.bottom=bdr;
				scratch_.ApplyBorders();
				SetDirty(TRUE);
			}return 0;
		case __IDC_BUTTON3:
			{
				scratch_.cellBorder_.InsideVertical=scratch_.cellBorder_.InsideHorizontal=bdr;
				scratch_.ApplyBorders();
				SetDirty(TRUE);
			}return 0;
		case __IDC_BUTTON4:
			pbdr=&scratch_.cellBorder_.top;
			break;
		case __IDC_BUTTON5:
			pbdr=&scratch_.cellBorder_.InsideHorizontal;
			break;
		case __IDC_BUTTON6:
			pbdr=&scratch_.cellBorder_.bottom;
			break;

		case __IDC_BUTTON8:
			pbdr=&scratch_.cellBorder_.left;
			break;
		case __IDC_BUTTON9:
			pbdr=&scratch_.cellBorder_.InsideVertical;
			break;
		case __IDC_BUTTON10:
			pbdr=&scratch_.cellBorder_.right;
			break;
		}
		if(pbdr){
			if(*pbdr==bdr){
				pbdr->put_LineStyle(xlLineStyleNone);
			}else{
				*pbdr=bdr;
			}
		}
		scratch_.ApplyBorders();
		SetDirty(TRUE);
		return 0;
	}
	void GetDistinctColWichHasStyle(const Worksheet* pSheet,const CCellRange& cr,set<col_t>& setCol)
	{
		vector<pair<CCell,const CellStore*> > v;
		pSheet->EnumCells(v,&cr);
		for(vector<pair<CCell,const CellStore*> >::const_iterator i=v.begin();i!=v.end();++i){
			_ASSERT(i->second!=NULL);
			if(i->second->GetStyleID()){
				setCol.insert(i->first.col);
			}
		}
		const ColHeader& ch=pSheet->get_ColHeader();
		vector<pair<col_t,StyleID_t> > vecColStyle;
		ch.Style_EnumCols(vecColStyle);
		for(vector<pair<col_t,StyleID_t> >::const_iterator it=vecColStyle.begin();it!=vecColStyle.end();++it){
			const StyleID_t sid=it->second;
			if(sid && it->first>=cr.LeftCol() && it->first<=cr.RightCol()){
				setCol.insert(it->first);
			}
		}
		if((int)setCol.size()<cr.cols()){
			col_t preCol=-1,findCol=-1;
			for(set<col_t>::const_iterator it=setCol.begin();it!=setCol.end();++it){
				col_t col=*it;
				if(-1!=preCol){
					if(col-preCol>1){
						findCol=col-1;
						break;
					}
				}
				preCol=col;
			}
			setCol.insert(findCol);
		}
	}
	void GetDistinctRowWichHasStyle(const Worksheet* pSheet,const CCellRange& cr,set<row_t>& setRow)
	{
		vector<pair<CCell,const CellStore*> > v;
		pSheet->EnumCells(v,&cr);
		for(vector<pair<CCell,const CellStore*> >::const_iterator i=v.begin();i!=v.end();++i){
			_ASSERT(i->second!=NULL);
			if(i->second->GetStyleID()){
				setRow.insert(i->first.row);
			}
		}
		const RowHeader& rh=pSheet->get_RowHeader();
		vector<pair<row_t,StyleID_t> > vecRowStyle;
		rh.Style_EnumRows(vecRowStyle);
		for(vector<pair<row_t,StyleID_t> >::const_iterator it=vecRowStyle.begin();it!=vecRowStyle.end();++it){
			const StyleID_t sid=it->second;
			if(sid && it->first>=cr.TopRow() && it->first<=cr.BottomRow()){
				setRow.insert(it->first);
			}
		}
		if((int)setRow.size()<cr.rows()){
			row_t preRow=-1,findRow=-1;
			for(set<row_t>::const_iterator it=setRow.begin();it!=setRow.end();++it){
				const row_t row=*it;
				if(-1!=preRow){
					if(row-preRow>1){
						findRow=row-1;
						break;
					}
				}
				preRow=row;
			}
			setRow.insert(findRow);
		}
	}

	//�ڸ����ķ�Χ��ȡ���������ͬ����Border����vec��
	void BorderPropertyPage::HGet2DistinctTopBorder(int row,int leftcol,int rightcol,vector<Border>& vec)const
	{
		if(vec.size()>1)
			return;
		set<col_t> setCol;
		CCellRange cr(max(0,row-1),leftcol,max(0,row),rightcol);
		GetDistinctColWichHasStyle(pSheet_,cr,setCol);
		for(set<col_t>::const_iterator it=setCol.begin();it!=setCol.end();++it){
			const Border bdr=GetTopBorder(CCell(row,*it));
			if(vec.end()==find(vec.begin(),vec.end(),bdr)){
				vec.push_back(bdr);
				if(vec.size()>1)
					return;
			}
		}
		//const Border bdr=pSheet_->Style_GetTableStyle().GetBorders()->top;
		//if(vec.end()==find(vec.begin(),vec.end(),bdr))
		//	vec.push_back(bdr);
		/*
		int ncol=0;
		CCellRange cr(row,leftcol,row,rightcol);
		vector<pair<CCell,const CellStore*> > v;
		pSheet_->EnumCells(v,&cr);
		for(vector<pair<CCell,const CellStore*> >::const_iterator i=v.begin();i!=v.end();++i){
			_ASSERT(i->second!=NULL);
			const StyleID_t sid=i->second->nStyleID;
			if(sid){
				++ncol;
				const StyleDesc& sd=pSheet_->Style_GetStyleByID(sid);
				Border bdr=sd.GetBorders()->top;
				if(bdr.IsNull() && row>0){
					bdr=pSheet_->Style_GetCellStyle(CCell(row-1,i->first.col)).GetBorders()->bottom;
				}
				if(vec.end()==find(vec.begin(),vec.end(),bdr)){
					vec.push_back(bdr);
					if(vec.size()>1)
						return;
				}
			}
		}
		if(rightcol-leftcol+1==ncol)
			return;
		const ColHeader& ch=pSheet_->get_ColHeader();
		vector<pair<col_t,StyleID_t> > vecColStyle;
		ch.Style_EnumCols(vecColStyle);
		for(vector<pair<col_t,StyleID_t> >::const_iterator it=vecColStyle.begin();it!=vecColStyle.end();++it){
			const StyleID_t sid=it->second;
			if(sid && it->first>=leftcol && it->first<=rightcol){
				++ncol;
				const StyleDesc& sd=pSheet_->Style_GetStyleByID(sid);
				Border bdr=sd.GetBorders()->top;
				if(vec.end()==find(vec.begin(),vec.end(),bdr)){
					vec.push_back(bdr);
					if(vec.size()>1)
						return;
				}
			}
		}
		if(rightcol-leftcol+1==ncol)
			return;
		const Border bdr=pSheet_->Style_GetTableStyle().GetBorders()->top;
		if(vec.end()==find(vec.begin(),vec.end(),bdr))
			vec.push_back(bdr);
		*/
	}
	//�ڸ����ķ�Χ��ȡ���������ͬ����Border����vec��
	void BorderPropertyPage::HGet2DistinctBottomBorder(int row,int leftcol,int rightcol,vector<Border>& vec)const
	{
		if(vec.size()>1)
			return;
		set<col_t> setCol;
		CCellRange cr(max(0,row),leftcol,min(pSheet_->get_RowHeader().get_rows()-1,row+1),rightcol);
		GetDistinctColWichHasStyle(pSheet_,cr,setCol);
		for(set<col_t>::const_iterator it=setCol.begin();it!=setCol.end();++it){
			const Border bdr=GetBottomBorder(CCell(row,*it));
			if(vec.end()==find(vec.begin(),vec.end(),bdr)){
				vec.push_back(bdr);
				if(vec.size()>1)
					return;
			}
		}
		/*
		if(vec.size()>1)
			return;
		CCellRange cr(row,leftcol,row,rightcol);
		vector<pair<CCell,const CellStore*> > v;
		pSheet_->EnumCells(v,&cr);
		const int rows=pSheet_->get_RowHeader().get_rows();
		for(vector<pair<CCell,const CellStore*> >::const_iterator i=v.begin();i!=v.end();++i){
			_ASSERT(i->second!=NULL);
			const StyleID_t sid=i->second->nStyleID;
			if(sid){
				const StyleDesc& sd=pSheet_->Style_GetStyleByID(sid);
				Border bdr=sd.GetBorders()->bottom;
				if(bdr.IsNull() && row<rows-1){
					bdr=pSheet_->Style_GetCellStyle(CCell(row+1,i->first.col)).GetBorders()->top;
				}
				if(vec.end()==find(vec.begin(),vec.end(),bdr)){
					vec.push_back(bdr);
					if(vec.size()>1)
						return;
				}
			}
		}
		if(rightcol-leftcol+1==v.size())
			return;
		int ncol=0;
		const ColHeader& ch=pSheet_->get_ColHeader();
		vector<pair<col_t,StyleID_t> > vecColStyle;
		ch.Style_EnumCols(vecColStyle);
		for(vector<pair<col_t,StyleID_t> >::const_iterator it=vecColStyle.begin();it!=vecColStyle.end();++it){
			const StyleID_t sid=it->second;
			if(sid && it->first>=leftcol && it->first<=rightcol){
				++ncol;
				const StyleDesc& sd=pSheet_->Style_GetStyleByID(sid);
				Border bdr=sd.GetBorders()->bottom;
				if(vec.end()==find(vec.begin(),vec.end(),bdr)){
					vec.push_back(bdr);
					if(vec.size()>1)
						return;
				}
			}
		}
		if(rightcol-leftcol+1+ncol==v.size())
			return;
		const Border bdr=pSheet_->Style_GetTableStyle().GetBorders()->bottom;
		if(vec.end()==find(vec.begin(),vec.end(),bdr))
			vec.push_back(bdr);
		//const StyleDesc& sd=pSheet_->Style_GetTableStyle();
		//vec.push_back(sd.GetBorders()->bottom);
		*/
	}
	
	//�ڸ����ķ�Χ��ȡ���������ͬ����Border����vec��
	void BorderPropertyPage::VGet2DistinctLeftBorder(int col,int topRow,int bottomRow,vector<Border>& vec)const
	{
		if(vec.size()>1)
			return;
		if(col<0)
			col=0;
		const CCellRange cr(topRow,max(0,col-1),bottomRow,col);
		set<row_t> setRow;
		GetDistinctRowWichHasStyle(pSheet_,cr,setRow);
		for(set<row_t>::const_iterator it=setRow.begin();it!=setRow.end();++it){
			const Border bdr=GetLeftBorder(CCell(*it,col));
			if(vec.end()==find(vec.begin(),vec.end(),bdr)){
				vec.push_back(bdr);
				if(vec.size()>1)
					return;
			}
		}
		/*
		vector<pair<CCell,const CellStore*> > v;
		pSheet_->EnumCells(v,&cr);
		for(vector<pair<CCell,const CellStore*> >::const_iterator i=v.begin();i!=v.end();++i){
			_ASSERT(i->second!=NULL);
			const StyleID_t sid=i->second->nStyleID;
			if(sid){
				const StyleDesc& sd=pSheet_->Style_GetStyleByID(sid);
				Border bdr=sd.GetBorders()->left;
				if(bdr.IsNull() && col>0){
					bdr=pSheet_->Style_GetCellStyle(CCell(i->first.row,col-1)).GetBorders()->right;
				}
				if(vec.end()==find(vec.begin(),vec.end(),bdr)){
					vec.push_back(bdr);
					if(vec.size()>1)
						return;
				}
			}
		}
		if(bottomRow-topRow+1==v.size())
			return;
		int nrow=0;
		const RowHeader& rh=pSheet_->get_RowHeader();
		vector<pair<row_t,StyleID_t> > vecRowStyle;
		rh.Style_EnumRows(vecRowStyle);
		for(vector<pair<row_t,StyleID_t> >::const_iterator it=vecRowStyle.begin();it!=vecRowStyle.end();++it){
			const StyleID_t sid=it->second;
			if(sid && it->first>=topRow && it->first<=bottomRow){
				++nrow;
				const StyleDesc& sd=pSheet_->Style_GetStyleByID(sid);
				Border bdr=sd.GetBorders()->left;
				if(vec.end()==find(vec.begin(),vec.end(),bdr)){
					vec.push_back(bdr);
					if(vec.size()>1)
						return;
				}
			}
		}
		if(bottomRow-topRow+1+nrow==v.size())
			return;
		const Border bdr=pSheet_->Style_GetTableStyle().GetBorders()->bottom;
		if(vec.end()==find(vec.begin(),vec.end(),bdr))
			vec.push_back(bdr);
		//const StyleDesc& sd=pSheet_->Style_GetTableStyle();
		//vec.push_back(sd.GetBorders()->left);
		*/
	}
	//�ڸ����ķ�Χ��ȡ���������ͬ����Border����vec��
	void BorderPropertyPage::VGet2DistinctRightBorder(int col,int topRow,int bottomRow,vector<Border>& vec)const
	{
		if(vec.size()>1)
			return;
		if(col<0)
			col=0;
		const CCellRange cr(topRow,col,bottomRow,min(pSheet_->get_ColHeader().get_cols()-1,col+1));
		set<row_t> setRow;
		GetDistinctRowWichHasStyle(pSheet_,cr,setRow);
		for(set<row_t>::const_iterator it=setRow.begin();it!=setRow.end();++it){
			const Border bdr=GetRightBorder(CCell(*it,col));
			if(vec.end()==find(vec.begin(),vec.end(),bdr)){
				vec.push_back(bdr);
				if(vec.size()>1)
					return;
			}
		}		/*
		if(vec.size()>1)
			return;
		CCellRange cr(topRow,col,bottomRow,col);
		const int cols=pSheet_->get_ColHeader().get_cols();
		vector<pair<CCell,const CellStore*> > v;
		pSheet_->EnumCells(v,&cr);
		for(vector<pair<CCell,const CellStore*> >::const_iterator i=v.begin();i!=v.end();++i){
			_ASSERT(i->second!=NULL);
			const StyleID_t sid=i->second->nStyleID;
			if(sid){
				const StyleDesc& sd=pSheet_->Style_GetStyleByID(sid);
				Border bdr=sd.GetBorders()->right;
				if(bdr.IsNull() && col<cols-1){
					bdr=pSheet_->Style_GetCellStyle(CCell(i->first.row,col+1)).GetBorders()->left;
				}
				if(vec.end()==find(vec.begin(),vec.end(),bdr)){
					vec.push_back(bdr);
					if(vec.size()>1)
						return;
				}
			}
		}
		if(bottomRow-topRow+1==v.size())
			return;
		const RowHeader& rh=pSheet_->get_RowHeader();
		vector<pair<row_t,StyleID_t> > vecRowStyle;
		rh.Style_EnumRows(vecRowStyle);
		for(vector<pair<row_t,StyleID_t> >::const_iterator it=vecRowStyle.begin();it!=vecRowStyle.end();++it){
			const StyleID_t sid=it->second;
			if(sid && it->first>=topRow && it->first<=bottomRow){
				const StyleDesc& sd=pSheet_->Style_GetStyleByID(sid);
				Border bdr=sd.GetBorders()->right;
				if(vec.end()==find(vec.begin(),vec.end(),bdr)){
					vec.push_back(bdr);
					if(vec.size()>1)
						return;
				}
			}
		}
		const StyleDesc& sd=pSheet_->Style_GetTableStyle();
		vec.push_back(sd.GetBorders()->right);
		*/
	}

	LRESULT BorderPropertyPage::OnDrawItem(UINT,WPARAM wID,LPARAM lParam,BOOL& bHandled)
	{
		LPDRAWITEMSTRUCT lpdis = (LPDRAWITEMSTRUCT) lParam;
		if(__IDC_BTN_SCRATCH==wID){
			//scratch_.Draw(lpdis);
			return 0;
		}else if(__IDC_BUTTON12==wID){
			bHandled=FALSE;
			return 0;
		}
		CDCHandle dc(lpdis->hDC);
		DrawPushButton(lpdis);
		//CPen pen(CreatePen(PS_SOLID,0,RGB(0,0,0)));
		//LOGBRUSH lb;
		//lb.lbColor=RGB(0,0,0);
		//lb.lbStyle=BS_SOLID;
		//lb.lbHatch=0;
		//CPen dotPen(ExtCreatePen(PS_GEOMETRIC |PS_DOT|PS_ENDCAP_SQUARE, 0,&lb,1,NULL));


		//HPEN hPen=dc.SelectPen(dotPen);
		//dc.Rectangle(rc);
		//dc.SelectPen(hPen);
		//dc.DrawFocusRect(rc);
		Draw_focus_box<> draw_focus_box;

		switch(wID)
		{
		case __IDC_BUTTON1:
			{
				CRect rc=lpdis->rcItem;
				rc.OffsetRect(-1,0);
				Draw_focus_box<TSetPixcel4Point>()(dc,rc,TRUE,FALSE);	
			}break;
		case __IDC_BUTTON2:
			{
				CRect rc=lpdis->rcItem;
				rc.OffsetRect(-1,0);
				Draw_focus_box<TSetPixcel4Point>()(dc,rc,TRUE,FALSE);	
				rc.OffsetRect(1,1);
				++rc.right;
				++rc.bottom;
				HPEN hPen=dc.SelectPen(CreatePen(PS_SOLID,2,0));
				HBRUSH hbr=dc.SelectBrush((HBRUSH)GetStockObject(NULL_BRUSH));
				dc.Rectangle(rc);
				DeleteObject(dc.SelectPen(hPen));
				dc.SelectBrush(hbr);
			}break;
		case __IDC_BUTTON3:
			{
				CRect rc=lpdis->rcItem;
				rc.OffsetRect(-1,0);
				POINT ptCenter=Draw_focus_box<TSetPixcel4Point>()(dc,rc,FALSE,FALSE);	
				++ptCenter.x;
				++ptCenter.y;

				HPEN hPen=dc.SelectPen(CreatePen(PS_SOLID,2,0));
				dc.MoveTo(ptCenter.x,rc.top);
				dc.LineTo(ptCenter.x,rc.bottom+1);
				dc.MoveTo(rc.left,ptCenter.y);
				dc.LineTo(rc.right+1,ptCenter.y);
				DeleteObject(dc.SelectPen(hPen));
			}break;
		case __IDC_BUTTON4:
			{
				CRect rc=lpdis->rcItem;
				draw_focus_box(dc,rc);	
				dc.MoveTo(rc.left,rc.top);
				dc.LineTo(rc.right,rc.top);
			}break;
		case __IDC_BUTTON5:
			{
				CRect rc=lpdis->rcItem;
				POINT ptCenter=draw_focus_box(dc,rc);	
				dc.MoveTo(rc.left,ptCenter.y);
				dc.LineTo(rc.right,ptCenter.y);
			}break;
		case __IDC_BUTTON6:
			{
				CRect rc=lpdis->rcItem;
				draw_focus_box(dc,rc);	
				dc.MoveTo(rc.left,rc.bottom);
				dc.LineTo(rc.right,rc.bottom);
			}break;
		case __IDC_BUTTON7:
			{
				CRect rc=lpdis->rcItem;
				draw_focus_box(dc,rc,FALSE);	
				dc.MoveTo(rc.left,rc.bottom);
				dc.LineTo(rc.right,rc.top);
			}break;
		case __IDC_BUTTON8:
			{
				CRect rc=lpdis->rcItem;
				draw_focus_box(dc,rc);	
				dc.MoveTo(rc.left,rc.top);
				dc.LineTo(rc.left,rc.bottom);
			}break;
		case __IDC_BUTTON9:
			{
				CRect rc=lpdis->rcItem;
				POINT ptCenter=draw_focus_box(dc,rc);	
				dc.MoveTo(ptCenter.x,rc.top);
				dc.LineTo(ptCenter.x,rc.bottom);
			}break;
		case __IDC_BUTTON10:
			{
				CRect rc=lpdis->rcItem;
				draw_focus_box(dc,rc);	
				dc.MoveTo(rc.right,rc.top);
				dc.LineTo(rc.right,rc.bottom);
			}break;
		case __IDC_BUTTON11:
			{
				CRect rc=lpdis->rcItem;
				draw_focus_box(dc,rc,FALSE);	
				dc.MoveTo(rc.left,rc.top);
				dc.LineTo(rc.right,rc.bottom);
			}break;
		}
		return 0;
	}
	//--------------------------------------------------------------
	void Scratch::CornerMarkSymbol::DrawRow0(CDCHandle dc,RECT rc,int col)
	{
		if(0==col){
			//--rc.bottom;
			//--rc.right;
			dc.MoveTo(rc.right-5,rc.bottom-1);
			dc.LineTo(rc.right,rc.bottom-1);
			dc.MoveTo(rc.right-1,rc.top+5);
			dc.LineTo(rc.right-1,rc.bottom);
		}else if(3==col){
			//++rc.left;
			//--rc.bottom;
			dc.MoveTo(rc.left,rc.bottom-1);
			dc.LineTo(rc.left+5,rc.bottom-1);
			dc.MoveTo(rc.left,rc.top+5);
			dc.LineTo(rc.left,rc.bottom);
		}else if(1==col){
			//--rc.bottom;
			dc.MoveTo(rc.right-5,rc.bottom-1);
			dc.LineTo(rc.right,rc.bottom-1);
			dc.MoveTo(rc.right-1,rc.top+5);
			dc.LineTo(rc.right-1,rc.bottom);
		}else if(2==col){
			//--rc.bottom;
			dc.MoveTo(rc.left,rc.bottom-1);
			dc.LineTo(rc.left+4,rc.bottom-1);
		}
	}
	void Scratch::CornerMarkSymbol::DrawRow1(CDCHandle dc,RECT rc,int col)
	{
		if(0==col){
			dc.MoveTo(rc.right-5,rc.bottom-1);
			dc.LineTo(rc.right,rc.bottom-1);
			dc.MoveTo(rc.right-1,rc.bottom-5);
			dc.LineTo(rc.right-1,rc.bottom);
		}else if(3==col){
			dc.MoveTo(rc.left,rc.bottom-1);
			dc.LineTo(rc.left+5,rc.bottom-1);
			dc.MoveTo(rc.left,rc.bottom-5);
			dc.LineTo(rc.left,rc.bottom);
		}
	}
	void Scratch::CornerMarkSymbol::DrawRow2(CDCHandle dc,RECT rc,int col)
	{
		if(0==col){
			dc.MoveTo(rc.right-1,rc.top);
			dc.LineTo(rc.right-1,rc.top+4);
		}else if(3==col){
			dc.MoveTo(rc.left,rc.top);
			dc.LineTo(rc.left,rc.top+4);
		}
	}
	void Scratch::CornerMarkSymbol::DrawRow3(CDCHandle dc,RECT rc,int col)
	{
		if(0==col){
			dc.MoveTo(rc.right-5,rc.top);
			dc.LineTo(rc.right,rc.top);
			dc.MoveTo(rc.right-1,rc.top);
			dc.LineTo(rc.right-1,rc.top+5);
		}else if(3==col){
			dc.MoveTo(rc.left,rc.top);
			dc.LineTo(rc.left+5,rc.top);
			dc.MoveTo(rc.left,rc.top);
			dc.LineTo(rc.left,rc.top+5);
		}else if(1==col){
			dc.MoveTo(rc.right-5,rc.top);
			dc.LineTo(rc.right,rc.top);
			dc.MoveTo(rc.right-1,rc.top);
			dc.LineTo(rc.right-1,rc.top+5);
		}else if(2==col){
			dc.MoveTo(rc.left,rc.top);
			dc.LineTo(rc.left+4,rc.top);
		}
	}
	
	STDMETHODIMP Scratch::GhostBorderSymbol::Draw(HDC hDC, int row,int col,const DrawCellInfo* pDCI)
	{
		CString text(_T("�ı�"));
		RECT rcText=pDCI->rcCell;
		::DrawText(hDC,text, text.GetLength(),&rcText, DT_CENTER|DT_VCENTER|DT_SINGLELINE);
		const CCellRange crMain(1,1,2,2);
		if(col==crMain.LeftCol() && pScratch_->cellBorder_.left.fDrawGhost){
			RECT rc=rcText;rc.right=rc.left+3;
			DrawGhostBar(hDC,&rc);
		}
		if(col==crMain.RightCol() && pScratch_->cellBorder_.right.fDrawGhost){
			RECT rc=rcText;rc.left=rc.right-3;
			DrawGhostBar(hDC,&rc);
		}
		if(row==crMain.TopRow() && pScratch_->cellBorder_.top.fDrawGhost){
			RECT rc=rcText;rc.bottom=rc.top+3;
			DrawGhostBar(hDC,&rc);
		}
		if(row==crMain.BottomRow() && pScratch_->cellBorder_.bottom.fDrawGhost){
			RECT rc=rcText;rc.top=rc.bottom-3;
			DrawGhostBar(hDC,&rc);
		}
		if(pScratch_->hasInsideVertical_ && pScratch_->cellBorder_.InsideVertical.fDrawGhost){
			RECT rc=rcText;
			if(col==crMain.LeftCol()){
				rc.left=rc.right-2;
			}else if(col==crMain.RightCol()){
				rc.right=rc.left+1;
			}
			DrawGhostBar(hDC,&rc);
		}
		if(pScratch_->hasInsideHorizontal_ && pScratch_->cellBorder_.InsideHorizontal.fDrawGhost){
			RECT rc=rcText;
			if(row==crMain.TopRow()){
				rc.top=rc.bottom-2;
			}else if(row==crMain.BottomRow()){
				rc.bottom=rc.top+1;
			}
			DrawGhostBar(hDC,&rc);
		}
		return S_OK;
	}
	STDMETHODIMP Scratch::CornerMarkSymbol::Draw(HDC hDC, int row,int col,const DrawCellInfo* pDCI)
	{
		if(pDCI->pMerge)
			return S_OK;
		const CCellRange crMain(1,1,2,2);
		//if(crMain.Inside(row,col))
		//	return S_OK;
		CDCHandle dc(hDC);
		HPEN hPenOld=dc.SelectPen(CreatePen(PS_SOLID,0,RGB(0x96,0x96,0x96)));
		const int wi=5;
		//CRect rc=pDCI->lprcCell;
		if(0==row){
			DrawRow0(dc,pDCI->rcCell,col);
		}else if(1==row){
			DrawRow1(dc,pDCI->rcCell,col);
		}else if(2==row){
			DrawRow2(dc,pDCI->rcCell,col);
		}else if(3==row){
			DrawRow3(dc,pDCI->rcCell,col);
		}
		//rc.DeflateRect(1,1);
		//if(col<2){
		//	switch(row)
		//	{
		//	case 0:
		//	case 2:
		//		dc.MoveTo(rc.right-5,rc.bottom-1);
		//		dc.LineTo(rc.right,rc.bottom-1);
		//		break;
		//	case 3:
		//		dc.MoveTo(rc.right-5,rc.top);
		//		dc.LineTo(rc.right,rc.top);
		//		break;
		//	}
		//}
			/*
		if(0==row && 0==col){
			//dc.Rectangle(pDCI->lprcCell);
			dc.MoveTo(ax[i],ay[j]);
			dc.LineTo(ax[i]+5,ay[j]);
		}
		*/
		dc.SelectPen(hPenOld);
		return S_OK;
	}

	//--------------------------------------------------------------
	Scratch::Scratch():hasInsideVertical_(TRUE),hasInsideHorizontal_(TRUE)
	{
		{
			CComObject<CornerMarkSymbol>* pCMSymbol;
			CComObject<CornerMarkSymbol>::CreateInstance(&pCMSymbol);
			CComPtr<ICellSymbol> pSymbol;
			pCMSymbol->QueryInterface(IID_IUnknown,(void**)&pSymbol);
			wb_.RegisterSymbol(static_cast<ECellType>(CellType_Corner),pSymbol);
		}
		{
			CComObject<GhostBorderSymbol>* pGBSymbol;
			CComObject<GhostBorderSymbol>::CreateInstance(&pGBSymbol);
			pGBSymbol->Init(this);
			CComPtr<ICellSymbol> pSymbol;
			pGBSymbol->QueryInterface(IID_IUnknown,(void**)&pSymbol);
			wb_.RegisterSymbol(static_cast<ECellType>(CellType_Ghost),pSymbol);
		}


		wb_.SetShowScrollBars(FALSE,FALSE);
		//cellBorder_.left.put_LineStyle(xlLineStyleNone);	
		//cellBorder_.InsideVertical.put_LineStyle(xlLineStyleNone);	
		//cellBorder_.right.put_LineStyle(xlLineStyleNone);	
		//cellBorder_.top.put_LineStyle(xlLineStyleNone);	
		//cellBorder_.InsideHorizontal.put_LineStyle(xlLineStyleNone);	
		//cellBorder_.bottom.put_LineStyle(xlLineStyleNone);	
	}
	void Scratch::ApplyBorders()
	{
		Worksheet* pSheet=wb_.Worksheet_GetActiveSheet();
		const CCellRange crMain(1,1,2,2);
		StyleDesc style;

		for(int row=crMain.TopRow();row<=crMain.BottomRow();++row){
			for(int col=crMain.LeftCol();col<=crMain.RightCol();++col){
				const CCell cell(row,col);
				const CCellRange* pMerge=((const Worksheet*)pSheet)->GetMergeCells(cell);
				style=pSheet->Style_GetCellStyle(cell);
				Borders* pbdrs=style.GetBorders();
				if(col==crMain.LeftCol()){
					pbdrs->left=cellBorder_.left.get();
					pbdrs->right=hasInsideVertical_?cellBorder_.InsideVertical.get():cellBorder_.right.get();
				}
				if(col==crMain.RightCol()){
					pbdrs->right=cellBorder_.right.get();
				}
				if(row==crMain.TopRow()){
					pbdrs->top=cellBorder_.top.get();
					pbdrs->bottom=hasInsideHorizontal_?cellBorder_.InsideHorizontal.get():cellBorder_.bottom.get();
				}
				if(row==crMain.BottomRow()){
					pbdrs->bottom=cellBorder_.bottom.get();
				}
				/*
				if(pMerge && cell!=pMerge->TopLeft())
					continue;
				if(cell.col==crMain.LeftCol()){
					pbdrs->left=cellBorder_.left.get();
					if(hasInsideVertical_){
						pbdrs->right=cellBorder_.InsideVertical.get();
					}
				}
				if(cell.col==crMain.RightCol() || pMerge && pMerge->RightCol()==crMain.RightCol())
					pbdrs->right=cellBorder_.right.get();
				if(cell.row==crMain.TopRow()){
					pbdrs->top=cellBorder_.top.get();
					if(hasInsideHorizontal_){
						pbdrs->bottom=cellBorder_.InsideHorizontal.get();
					}
				}
				if(cell.row==crMain.BottomRow() || pMerge && pMerge->BottomRow()==crMain.BottomRow())
					pbdrs->bottom=cellBorder_.bottom.get();
				*/
				pSheet->Style_SetCellStyle(cell,style);
				_ASSERT(pSheet->Style_GetCellStyle(cell)==style);
			}
		}
		pSheet->RedrawWindow();
	}
	void Scratch::AfterCreate()
	{
		Worksheet* pSheet=wb_.Worksheet_GetActiveSheet();
		pSheet->put_ShowColHeader(FALSE);
		pSheet->put_ShowRowHeader(FALSE);
		pSheet->put_ShowGrid(FALSE);
		pSheet->put_ShowSelection(FALSE);
		CRect rc;
		pSheet->GetClientRect(&rc);
		pSheet->put_rows(4);
		pSheet->put_cols(4);
		const CCellRange crMain(1,1,2,2);
		//const int leftCol=1;
		//const int topRow=1;
		const int hiR1=10;
		const int height=(rc.Height()-hiR1*2)>>1;
		const int width=(rc.Width()-hiR1*2)>>1;
		for(int i=0;i<4;++i){
			if(0==i || 3==i){
				pSheet->put_RowHeight(i,hiR1);
				pSheet->put_ColWidth(i,hiR1);
			}else{
				pSheet->put_RowHeight(i,height);
				pSheet->put_ColWidth(i,width);
			}
		}
		for(int row=0;row<4;++row){
			for(int col=0;col<4;++col){
				const CCell cell(row,col);
				if(!crMain.Inside(cell)){
					pSheet->SetCellType(cell,(ECellType)CellType_Corner);
				}else{
					pSheet->SetCellType(cell,(ECellType)CellType_Ghost);
				}
			}
		}
		//SetRangeText(pSheet,crMain,_T("�ı�"));
		if(!hasInsideVertical_ && !hasInsideHorizontal_){
			pSheet->Merge(crMain);
			CCellRange cr(crMain.TopRow(),0,crMain.BottomRow(),0);
			pSheet->Merge(cr);
			pSheet->Merge(cr.OffsetCol(3));
			pSheet->Merge(cr.set(0,crMain.LeftCol(),0,crMain.RightCol()));
			pSheet->Merge(cr.OffsetRow(3));
		}else if(!hasInsideVertical_){
			for(int row=0;row<4;++row)
				pSheet->Merge(row,crMain.LeftCol(),row,crMain.RightCol());
		}else if(!hasInsideHorizontal_){
			for(int col=0;col<4;++col)
				pSheet->Merge(crMain.TopRow(),col,crMain.BottomRow(),col);
		}
		//ApplyBorders();
		cellBorder_.SetDirty(FALSE);
		cellBorder_.InsideVertical.fDirty=cellBorder_.InsideHorizontal.fDirty=FALSE;
	}

	/*
	void Scratch::Draw(LPDRAWITEMSTRUCT lpdis)
	{
		CDCHandle dc(lpdis->hDC);
		dc.DrawEdge(&lpdis->rcItem,BDR_SUNKENINNER,BF_LEFT|BF_TOP);
		dc.DrawEdge(&lpdis->rcItem,BDR_SUNKENOUTER,BF_RIGHT|BF_BOTTOM);
		CRect rc=lpdis->rcItem;
		rc.DeflateRect(2,2);
		CBrush br(CreateSolidBrush(RGB(0xff,0xff,0xff)));
		dc.FillRect(&rc,br);
		POINT ptCenter={rc.left+(rc.Width()>>1),rc.top+(rc.Height()>>1)};
		HPEN hPen=dc.SelectPen(CreatePen(PS_SOLID,0,RGB(0x96,0x96,0x96)));
		int ax[]={rc.left+4,ptCenter.x-2,rc.right-8};
		int ay[]={rc.top+9,ptCenter.y,rc.bottom-8};
		int ax1[]={rc.left+9,ptCenter.x,rc.right-8};
		int ay1[]={rc.top+5,ptCenter.y-2,rc.bottom-8};
		for(int i=0;i<sizeof(ax)/sizeof(int);++i)
		{
			for(int j=0;j<sizeof(ay)/sizeof(int);++j){
				if(1==j && !hasInsideHorizontal_) continue;
				if(1==i && !hasInsideVertical_) continue;
				if(!(1==i && 1==j)){
					dc.MoveTo(ax[i],ay[j]);
					dc.LineTo(ax[i]+5,ay[j]);
				}
			}
			for(int j=0;j<sizeof(ay1)/sizeof(int);++j){
				if(1==j && !hasInsideHorizontal_) continue;
				if(1==i && !hasInsideVertical_) continue;
				if(!(1==i && 1==j)){
					dc.MoveTo(ax1[i],ay1[j]);
					dc.LineTo(ax1[i],ay1[j]+5);
				}
			}
		}
		DeleteObject(dc.SelectPen(hPen));
		dc.SetBkMode(TRANSPARENT);
		LPCTSTR lpsz=_T("�ı�");
		int const nCount=lstrlen(lpsz);
		if(hasInsideHorizontal_ && hasInsideVertical_){
			RECT arc[]=
			{
				{ax[0]+9,rc.top+9,ptCenter.x,ptCenter.y},
				{ptCenter.x,rc.top+9,ax[2],ptCenter.y},
				{ax[0]+9,ptCenter.y,ptCenter.x,ay[2]},
				{ptCenter.x,ptCenter.y,ax[2],ay[2]},
			};
			for(int i=0;i<sizeof(arc)/sizeof(arc[0]);++i){
				dc.DrawText(lpsz,nCount,&arc[i],DT_SINGLELINE|DT_CENTER|DT_VCENTER);
			}
		}else if(hasInsideVertical_){
			RECT arc[]=
			{
				{ax[0]+9,rc.top+9,ptCenter.x,ay[2]},
				{ptCenter.x,rc.top+9,ax[2],ay[2]},
			};
			for(int i=0;i<sizeof(arc)/sizeof(arc[0]);++i){
				dc.DrawText(lpsz,nCount,&arc[i],DT_SINGLELINE|DT_CENTER|DT_VCENTER);
			}
		}else if(hasInsideHorizontal_){
			RECT arc[]=
			{
				{ax[0]+9,rc.top+9,ax[2],ptCenter.y},
				{ax[0]+9,ptCenter.y,ax[2],ay[2]},
			};
			for(int i=0;i<sizeof(arc)/sizeof(arc[0]);++i){
				dc.DrawText(lpsz,nCount,&arc[i],DT_SINGLELINE|DT_CENTER|DT_VCENTER);
			}
		}else{
			dc.DrawText(lpsz,nCount,&rc,DT_SINGLELINE|DT_CENTER|DT_VCENTER);
		}


		//draw left border
		dc.MoveTo(ax[0]+5,rc.top+9);
		cellBorder_.left.LineTo(dc,ax[0]+5,rc.bottom-8);
		//DrawLine(cellBorder_.left,dc,ax[0]+5,rc.top+9,ax[0]+5,rc.bottom-8);
		//draw hmiddle border
		if(hasInsideVertical_){
			dc.MoveTo(ptCenter.x,rc.top+9);
			cellBorder_.InsideVertical.LineTo(dc,ptCenter.x,rc.bottom-8);
			//DrawLine(cellBorder_.InsideVertical,dc,ptCenter.x,rc.top+9,ptCenter.x,rc.bottom-8);
		}
		//draw cellBorder_.right border
		dc.MoveTo(ax[2],rc.top+9);
		cellBorder_.right.LineTo(dc,ax[2],rc.bottom-8);
		//DrawLine(cellBorder_.right,dc,ax[2],rc.top+9,ax[2],rc.bottom-8);

		//draw top border
		dc.MoveTo(ax[0]+5,rc.top+9);
		cellBorder_.top.LineTo(dc,ax[2],rc.top+9);
		//DrawLine(cellBorder_.top,dc,ax[0]+5,rc.top+9,ax[2],rc.top+9);
		if(hasInsideHorizontal_){//draw vmiddle border
			dc.MoveTo(ax[0]+5,ptCenter.y);
			cellBorder_.InsideHorizontal.LineTo(dc,ax[2],ptCenter.y);
			//DrawLine(cellBorder_.InsideHorizontal,dc,ax[0]+5,ptCenter.y,ax[2],ptCenter.y);
		}
		//draw bottom border
		dc.MoveTo(ax[0]+5,rc.bottom-8);
		cellBorder_.bottom.LineTo(dc,ax[2],rc.bottom-8);
		//DrawLine(cellBorder_.bottom,dc,ax[0]+5,rc.bottom-8,ax[2],rc.bottom-8);
	}
	*/
}}//namespace mycell::BorderPP

By viewing downloads associated with this article you agree to the Terms of Service and the article's licence.

If a file you wish to view isn't highlighted, and is a text file (not binary), please let us know and we'll add colourisation support for it.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


Written By
Web Developer
China China
My name is Yanxueming,i live in Chengdu China.Graduated from UESTC in 1999.

Comments and Discussions