// SelectView.cpp : implementation of the CaplSelectView class
//

#include "stdafx.h"
#include "apl_gui.h"
#include "aplPrintDcDlg.h"
//#include "SelectView.h"
//#include "resource.h"

//#include <Wingdi.h>

#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif

#ifndef IDC_HAND
#define IDC_HAND MAKEINTRESOURCE(32649)
#endif

#define BTN_COLOR_HILIGHT	25	


COLORREF aplColor_GetHilightColor(COLORREF color, int pearcent)
{
	if(pearcent>100 || pearcent<-1000) return 0;
	
	int r_val, g_val, b_val;
	r_val = GetRValue(color);
	g_val = GetGValue(color);
	b_val = GetBValue(color);
	
	r_val = (int)(r_val+(255-r_val)*pearcent/100);
	g_val = (int)(g_val+(255-g_val)*pearcent/100);
	b_val = (int)(b_val+(255-b_val)*pearcent/100);
	
	return RGB(r_val, g_val, b_val);
}

COLORREF  aplColor_MixColor(COLORREF color1, COLORREF color2, int mixfactor)
{
	int r1 = GetRValue(color1);
	int g1 = GetGValue(color1);
	int b1 = GetBValue(color1);

	int r2 = GetRValue(color2);
	int g2 = GetGValue(color2);
	int b2 = GetBValue(color2);

	int r3=(int)(r1+(r2-r1)*mixfactor/100);
	int g3=(int)(g1+(g2-g1)*mixfactor/100);
	int b3=(int)(b1+(b2-b1)*mixfactor/100);

	return RGB(r3, g3, b3);
}

COLORREF  aplColor_InvertColor(COLORREF color)
{
	int r1 = GetRValue(color);
	int g1 = GetGValue(color);
	int b1 = GetBValue(color);

	int r2 = 255-r1;
	int g2 = 255-g1;
	int b2 = 255-b1;


	return RGB(r2, g2, b2);
}

CaplSelectView::CaplSelectViewGroup::CaplSelectViewGroup()
{
	m_cy = 25;
	m_ico = -1;
	m_text.Empty();

	m_pData	= NULL;

	m_bDrawHeader = true;
	m_bClosed = false;

	m_drawrect = CRect(0,0,0,0);
	m_elemrect = CRect(0,0,0,0);
	m_data=0;
}

CaplSelectView::CaplSelectViewGroup::CaplSelectViewGroup(LPCTSTR txt, int ico,long data)
{
	m_pData	= NULL;
	
	m_bDrawHeader = true;
	m_bClosed = false;
	
	m_drawrect = CRect(0,0,0,0);
	m_elemrect = CRect(0,0,0,0);

	m_text=txt;
	m_ico=ico;
	m_cy=0;
	m_data=data;
}

CaplSelectView::CaplSelectViewGroup::~CaplSelectViewGroup()
{
	Clear();
}

void CaplSelectView::CaplSelectViewGroup::Clear()
{
	int i;
	for(i=0;i<m_elements.GetSize();i++)
		delete m_elements[i];
	
	m_elements.RemoveAll();
	m_text.Empty();
	m_ico = -1;
}

CaplSelectView* CaplSelectView::CreateSelectView( CWnd *parent ,LPRECT rect, int id, UINT WndStyle)
{
	CString wndclass = ::AfxRegisterWndClass(CS_DBLCLKS,
        ::LoadCursor(NULL, IDC_ARROW),
        ::GetSysColorBrush(COLOR_BTNFACE), 0);


	CaplSelectView *selectView=(CaplSelectView*)RUNTIME_CLASS(CaplSelectView)->CreateObject();

	ASSERT(selectView);

	if(selectView==0) return 0;

	if(selectView->CScrollView::Create(wndclass, _T("SelView"), WndStyle, *rect, parent, id, NULL))
		return selectView;

	delete selectView;
	return 0;

}



/////////////////////////////////////////////////////////////////////////////
// CaplSelectView

IMPLEMENT_DYNCREATE(CaplSelectView, CScrollView)

BEGIN_MESSAGE_MAP(CaplSelectView, CScrollView)
	//{{AFX_MSG_MAP(CaplSelectView)
	ON_WM_ERASEBKGND()
	ON_WM_LBUTTONDOWN()
	ON_WM_LBUTTONUP()
	ON_WM_MOUSEMOVE()
	ON_WM_SETCURSOR()
	ON_WM_MOUSEACTIVATE()
	ON_WM_SIZE()
	ON_WM_ERASEBKGND()
	ON_WM_LBUTTONDBLCLK()
	//}}AFX_MSG_MAP
END_MESSAGE_MAP()

/////////////////////////////////////////////////////////////////////////////
// CaplSelectView construction/destruction

void CaplSelectView::UpdateGDI()
{
	if(m_brush_group_bk.m_hObject!=0) m_brush_group_bk.DeleteObject();
	m_brush_group_bk.CreateSolidBrush(m_color_group_bk);
	
	if(m_brush_group_head.m_hObject!=0) m_brush_group_head.DeleteObject();
	m_brush_group_head.CreateSolidBrush(m_color_group_head);

	if(m_brush_group_sel_head.m_hObject!=0) m_brush_group_sel_head.DeleteObject();
	m_brush_group_sel_head.CreateSolidBrush(m_color_group_head_sel);
	
	if(m_brush_element_sel.m_hObject!=0) m_brush_element_sel.DeleteObject();
	m_brush_element_sel.CreateSolidBrush(m_color_element_sel);
	
	if(m_brush_element_hl.m_hObject!=0) m_brush_element_hl.DeleteObject();
	m_brush_element_hl.CreateSolidBrush(m_color_element_hl);
}

CaplSelectView::CaplSelectView()
{
	// TODO: add construction code here
	m_NonGroupItemsGroup.m_bDrawHeader = false;
	m_bAutoFitWidth = false;

	m_bTextBottom=false;
	m_bElementAsButton=false;

	m_iMargin=3;

	m_sel_element=0;
	m_prev_sel_element=0;
	m_last_hl_element=0;
	
	m_SelectedGroup= NULL;
	m_HighLightGroup= NULL;

	m_roundpoint_element.x=3; m_roundpoint_element.y=3;
	m_roundpoint_group.x=5; m_roundpoint_group.y=5;

	SetColorSchema(0);

	m_DefCursor=0;
	m_HLCursor=0;

	CWinApp *app=AfxGetApp(); // При вызове из ActiveX возвращает 0
	if(0!=app)
	{
		m_DefCursor=app->LoadStandardCursor(IDC_ARROW);
		m_HLCursor=app->LoadStandardCursor(IDC_HAND);
	}

	m_curCursor=m_DefCursor;

	m_fontGroup.CreateFont(
	   16,                        // nHeight
	   0,                         // nWidth
	   0,                         // nEscapement
	   0,                         // nOrientation
	   FW_BOLD,                   // nWeight
	   FALSE,                     // bItalic
	   FALSE,                     // bUnderline
	   0,                         // cStrikeOut
	   DEFAULT_CHARSET,              // nCharSet
	   OUT_DEFAULT_PRECIS,        // nOutPrecision
	   CLIP_DEFAULT_PRECIS,       // nClipPrecision
	   DEFAULT_QUALITY,           // nQuality
	   DEFAULT_PITCH | FF_SWISS,  // nPitchAndFamily
	   _T("Tahoma")	// lpszFacename
	   );  
	
	m_fontElement.CreateFont(
	   14,                        // nHeight
	   0,                         // nWidth
	   0,                         // nEscapement
	   0,                         // nOrientation
	   FW_NORMAL,                   // nWeight
	   FALSE,                     // bItalic
	   FALSE,                     // bUnderline
	   0,                         // cStrikeOut
	   DEFAULT_CHARSET,              // nCharSet
	   OUT_DEFAULT_PRECIS,        // nOutPrecision
	   CLIP_DEFAULT_PRECIS,       // nClipPrecision
	   DEFAULT_QUALITY,           // nQuality
	   DEFAULT_PITCH | FF_SWISS,  // nPitchAndFamily
	   _T("Tahoma")	// lpszFacename
	   );  


	m_fontElementSel.CreateFont(
	   14,                        // nHeight
	   0,                         // nWidth
	   0,                         // nEscapement
	   0,                         // nOrientation
	   FW_NORMAL /*FW_BOLD*/,                   // nWeight
	   FALSE,                     // bItalic
	   FALSE,                     // bUnderline
	   0,                         // cStrikeOut
	   DEFAULT_CHARSET,              // nCharSet
	   OUT_DEFAULT_PRECIS,        // nOutPrecision
	   CLIP_DEFAULT_PRECIS,       // nClipPrecision
	   DEFAULT_QUALITY,           // nQuality
	   DEFAULT_PITCH | FF_SWISS,  // nPitchAndFamily
	   _T("Tahoma")	// lpszFacename
	   );  


	m_fontElementHL.CreateFont(
	   14,                        // nHeight
	   0,                         // nWidth
	   0,                         // nEscapement
	   0,                         // nOrientation
	   FW_NORMAL,                   // nWeight
	   FALSE,                     // bItalic
	   TRUE,                     // bUnderline
	   0,                         // cStrikeOut
	   DEFAULT_CHARSET,              // nCharSet
	   OUT_DEFAULT_PRECIS,        // nOutPrecision
	   CLIP_DEFAULT_PRECIS,       // nClipPrecision
	   DEFAULT_QUALITY,           // nQuality
	   DEFAULT_PITCH | FF_SWISS,  // nPitchAndFamily
	   _T("Tahoma")	// lpszFacename
	   );  
}

CaplSelectView::~CaplSelectView()
{
	Clear();
}

void CaplSelectView::SetWindowsDefaultSchema()
{
	m_color_bk = ::GetSysColor(COLOR_BTNFACE);
	m_color_group_bk = ::GetSysColor(COLOR_BTNFACE);
	m_color_group_head = ::GetSysColor(COLOR_BTNSHADOW);

	m_color_element_hl = ::GetSysColor(COLOR_BTNFACE);
	m_color_element_sel = ::GetSysColor(COLOR_BTNHILIGHT);
	m_color_txt_element_sel = ::GetSysColor(COLOR_MENUTEXT);

	m_color_element_tl = ::GetSysColor(COLOR_3DHILIGHT);
	m_color_element_br = ::GetSysColor(COLOR_3DSHADOW);
	
	m_fontElement.DeleteObject();
	m_fontElement.CreateStockObject(ANSI_VAR_FONT);
	m_fontElementSel.DeleteObject();
	m_fontElementSel.CreateStockObject(ANSI_VAR_FONT);
	m_fontElementHL.DeleteObject();
	m_fontElementHL.CreateStockObject(ANSI_VAR_FONT);

	LOGFONT lf;
	memset(&lf, 0, sizeof(LOGFONT));

	m_fontElementHL.GetLogFont(&lf);
	lf.lfUnderline = 1;
	m_fontElementHL.DeleteObject();
	m_fontElementHL.CreateFontIndirect(&lf);
}

BOOL CaplSelectView::PreCreateWindow(CREATESTRUCT& cs)
{
	// TODO: Modify the Window class or styles here by modifying
	//  the CREATESTRUCT cs

	return CScrollView::PreCreateWindow(cs);
}

/////////////////////////////////////////////////////////////////////////////
// CaplSelectView drawing

void CaplSelectView::OnDraw(CDC* pDC)
{
	//CSelectDoc* pDoc = GetDocument();
	//ASSERT_VALID(pDoc);
	// TODO: add draw code for native data here
	
	// Определяем выделенную группу
	int i,j,iy=0;
	CaplSelectViewGroup *selGroup=0;
	for (i=0;i<m_groups.GetSize();i++)
	{
		CaplSelectViewGroup *grp=m_groups[i];
		for(j=0;j<grp->m_elements.GetSize();j++)
		{
			CaplSelectViewElement *elem= grp->m_elements[j];
			if(elem==m_sel_element)
			{
				selGroup=grp;
				i=m_groups.GetSize();
				break;
			}
		}
	}
	
	CDC MemDC;
	CDC *pDrawDC = pDC;
	CBitmap bm;


	CPen group_pen;
	CPen* pOldPen;
	CBrush *pOldBrush;
	CBitmap *pOldBm = NULL;

	group_pen.CreatePen(PS_SOLID, 1, m_color_group_ramka);
	
	CPen state_pen(PS_SOLID,2,m_color_txt_group_head);

	// Очистка фона
	CRect rect;
	CSize size;
	CBrush brush_bk(m_color_bk);
	int i1, i2;

	GetClientRect(&rect);

	GetScrollRange(SB_HORZ, &i1, &i2);
	size.cx = i2+i1+1;
	GetScrollRange(SB_VERT, &i1, &i2);
	size.cy = i2+i1+1;
	size.cx = size.cx>rect.Width()?size.cx:rect.Width();
	size.cy = size.cy>rect.Height()?size.cy:rect.Height();
	rect.right = rect.left+size.cx;
	rect.bottom = rect.top+size.cy;

	if(MemDC.CreateCompatibleDC(pDC))
	{
		MemDC.SetMapMode(pDC->GetMapMode());
		if(bm.CreateCompatibleBitmap(pDC, size.cx, size.cy))
		{
			pOldBm = MemDC.SelectObject(&bm);
			pDrawDC = &MemDC;
		}
	}

	if(m_bElementAsButton)
	{
		pOldPen= pDrawDC->SelectObject(&group_pen);
		pOldBrush= pDrawDC->SelectObject(&m_brush_group_bk);
		
// 		pDrawDC->FillSolidRect(rect, RGB(240,240,240));
		pDrawDC->FillRect(&rect, &brush_bk);

		CFont *pOldFont=pDrawDC->SelectObject(&m_fontGroup);
		CaplSelectViewGroup* group;

		COLORREF	color_bk_hl;

		color_bk_hl=aplColor_GetHilightColor(m_color_bk, BTN_COLOR_HILIGHT);

		CBrush *fon_brush= &brush_bk;
		CBrush fon_brush_hilight(color_bk_hl);
		COLORREF txt_color= m_color_txt_element;
		COLORREF txt_bk_color= m_color_bk;
		CFont *txt_font= &m_fontElement;
		CPen pen(PS_SOLID, 0, txt_bk_color);
		
		CRect tDRect;
		CPoint point;
		UINT allign;

		int oldBkMode = pDrawDC->SetBkMode(TRANSPARENT);
		pDrawDC->SetTextColor(txt_color);
		pDrawDC->SetBkColor(txt_bk_color);	
		pDrawDC->SelectObject(txt_font);

		for(int i= 0; i<m_groups.GetSize(); i++)
		{
			group= m_groups[i];
			if(group==0) continue;

			if(group==m_SelectedGroup)
			{
				txt_font= &m_fontElementSel;
				fon_brush= &m_brush_element_sel;
				txt_bk_color= m_color_element_sel;
				txt_color= m_color_txt_element_sel;
			}
			else if(group==m_HighLightGroup)
			{
				txt_font= &m_fontElementHL;
				fon_brush= &brush_bk;
				txt_color= m_color_txt_element;
				txt_bk_color= m_color_bk;
			}
			else
			{	
				fon_brush= &brush_bk;
				txt_color= m_color_txt_element;
				txt_bk_color= m_color_bk;
				txt_font= &m_fontElement;
			}
			
			pen.FromHandle(CPen(PS_SOLID, 0, txt_bk_color));
			pDrawDC->SelectObject(&pen);
			pDrawDC->SelectObject(fon_brush);

			rect= group->m_drawrect;
			
			if(group==m_SelectedGroup)
			{
				pDrawDC->FillRect(&rect, fon_brush);
				pDrawDC->Draw3dRect(&rect, m_color_element_br , m_color_element_tl);
			}
			else if(group==m_HighLightGroup)
			{
				pDrawDC->FillRect(&rect, &fon_brush_hilight);
				pDrawDC->Draw3dRect(&rect, m_color_element_tl, m_color_element_br);
			}
			else
				pDrawDC->FillRect(&rect, fon_brush);


			if(group->m_ico>=0 && m_il_group.m_hImageList!=0)
			{
				point= group->m_ico_point;			
				if(group==m_SelectedGroup) point.Offset(2, 2);

				m_il_group.Draw(pDrawDC, group->m_ico, point, ILD_TRANSPARENT);
			}		

			rect= group->m_textrect;
			if(group==m_SelectedGroup) rect.OffsetRect(2, 2);

			allign= DT_LEFT;
			if(m_bTextBottom) allign= DT_CENTER;

			pDrawDC->DrawText(group->m_text, rect, allign|DT_WORDBREAK|DT_END_ELLIPSIS);		
		}

		pDrawDC->SetBkMode(oldBkMode);

		pDrawDC->SelectObject(pOldFont);
		pDrawDC->SelectObject(pOldBrush);
		pDrawDC->SelectObject(pOldPen);
	}
	else
	{
		// задний план
		pOldPen = pDrawDC->SelectObject(&group_pen);
		pOldBrush=pDrawDC->SelectObject(&m_brush_group_bk);
		pDrawDC->FillRect(&rect,&brush_bk);

		//pDrawDC->SetBkMode(TRANSPARENT);
		pDrawDC->SetBkMode(OPAQUE);

		CFont *pOldFont=pDrawDC->SelectObject(&m_fontGroup);

		for (i=0;i<m_groups.GetSize();i++)
		{
			CaplSelectViewGroup *grp=m_groups[i];

			iy+=3;

			if(selGroup==grp) pDrawDC->SelectObject(m_brush_group_sel_head);
			else pDrawDC->SelectObject(m_brush_group_head);

			
			pDrawDC->RoundRect(&(grp->m_drawrect),m_roundpoint_group);

			CRect rect0=grp->m_drawrect;
			rect0.bottom=rect0.top+grp->m_cy;
			//rect0.DeflateRect(grp->m_cy,3,5,3);
			rect0.DeflateRect(7,4,5,4);

			if(grp->m_ico>=0 && m_il_group!=0)
			{
				int ico_cx, ico_cy;
				::ImageList_GetIconSize(m_il_group.m_hImageList, &ico_cx, &ico_cy);

				POINT ico_point={grp->m_drawrect.left+7,grp->m_drawrect.top+((grp->m_cy-ico_cy)/2)};
				m_il_group.Draw(pDrawDC,grp->m_ico,ico_point,ILD_TRANSPARENT);

				rect0.left+=(ico_cx+5);
			}

			pDrawDC->SetTextColor(m_color_txt_group_head);
			pDrawDC->SelectObject(&m_fontGroup);
			
			if(selGroup==grp) pDrawDC->SetBkColor(m_color_group_head_sel);
			else pDrawDC->SetBkColor(m_color_group_head);
			
			

			rect0.right-=20;
			pDrawDC->DrawText(grp->m_text,rect0,DT_LEFT|DT_VCENTER|DT_WORDBREAK|DT_END_ELLIPSIS);

			// Рисуем состояние
			CPen *oldpen=pDrawDC->SelectObject(&state_pen);

			POINT state_points[3];
			
			state_points[0].x=rect0.right+3;
			state_points[1].x=state_points[0].x+5;
			state_points[2].x=state_points[1].x+5;

			if(grp->m_bClosed)
			{
				state_points[0].y=rect0.top+((grp->m_cy-10)/2);
				state_points[1].y=state_points[0].y+5;
			}
			else
			{
				state_points[0].y=rect0.top+((grp->m_cy-10)/2)+6;
				state_points[1].y=state_points[0].y-5;
			}
			state_points[2].y=state_points[0].y;

			pDrawDC->Polyline(state_points,3);

			state_points[0].y-=5;
			state_points[1].y-=5;
			state_points[2].y-=5;
			pDrawDC->Polyline(state_points,3);

			pDrawDC->SelectObject(oldpen);



			if((grp->m_elements.GetSize()>0)  && !grp->m_bClosed)
			{

				pDrawDC->SelectObject(m_brush_group_bk);
				pDrawDC->RoundRect(grp->m_elemrect,m_roundpoint_group);
		
				for(j=0;j<grp->m_elements.GetSize();j++)
				{
					CaplSelectViewElement *elem= grp->m_elements[j];

					DrawElement(elem,pDrawDC);
				}
			}
		}
		if(m_NonGroupItemsGroup.m_elements.GetSize()>0)
		{
			for(j=0;j<m_NonGroupItemsGroup.m_elements.GetSize();j++)
			{
				DrawElement(m_NonGroupItemsGroup.m_elements[j], pDrawDC);
			}
		}

		pDrawDC->SelectObject(pOldFont);
		pDrawDC->SelectObject(pOldBrush);
		pDrawDC->SelectObject(pOldPen);
	}

	if(MemDC.GetSafeHdc())
	{
		::BitBlt(pDC->m_hDC, 0, 0, size.cx, size.cy, MemDC.m_hDC, 0, 0, SRCCOPY);

		MemDC.SelectObject(pOldBm);
		MemDC.DeleteDC();
	}
}
/*//*************************************************************************************
bool CaplSelectView::DrawElementAsButton(CaplSelectViewElement *elem, CDC *pDC,bool bHighLigt,int dx, int dy)
{
	if(elem==0) return false;
	if(pDC==0) return false;



	return true;
}*/

//*************************************************************************************
bool CaplSelectView::DrawElement(CaplSelectViewElement *elem, CDC *pDC,bool bHighLigt,int dx, int dy)
{
//	if(m_bElementAsButton) return DrawElementAsButton(elem,pDC,bHighLigt, dx,  dy);

	if(elem==0) return false;
	if(pDC==0) return false;

	CBrush *fon_brush=&m_brush_group_bk;
	COLORREF txt_color=m_color_txt_element;
	COLORREF txt_bk_color=m_color_group_bk;
	COLORREF pen_color = txt_bk_color;
	CFont *txt_font=&m_fontElement;


	if(bHighLigt)
	{
		txt_font=&m_fontElementHL;
		fon_brush=&m_brush_element_hl;
		txt_bk_color=m_color_element_hl;
	}
	if(elem==m_sel_element)
	{
		txt_color=m_color_txt_element_sel;
		txt_bk_color=m_color_element_sel;
		txt_font=&m_fontElementSel;
		fon_brush=&m_brush_element_sel;
		pen_color=m_color_element_sel_ramka;
	}
	if(elem->m_bEnable==false)
	{
		//txt_color=RGB(192,192,192);
		txt_color=GetSysColor(COLOR_GRAYTEXT);

	}

	CPen pen(PS_SOLID,0,pen_color);
	CPen *pOldPen=pDC->SelectObject(&pen);


	CBrush *pOldBrush=pDC->SelectObject(fon_brush);

	CRect realRect=elem->m_drawrect;
	realRect.OffsetRect(-dx,-dy);

	if(m_bElementAsButton)
	{
		pDC->FillRect(&realRect,fon_brush);
		if(bHighLigt)
		{
			pDC->Draw3dRect(&realRect, m_color_element_tl, m_color_element_br);
		}
		else  if(elem==m_sel_element)
		{ 
			pDC->Draw3dRect(&realRect, m_color_element_br, m_color_element_tl);
		}
		pDC->SelectObject(fon_brush);

	}
	else
	{
		pDC->RoundRect(realRect,m_roundpoint_element);
	}

	if(elem->m_ico>=0 && m_il_elements!=0)
	{
		POINT ico_point=elem->m_ico_point;
		ico_point.x-=dx;
		ico_point.y-=dy;
		m_il_elements.Draw(pDC,elem->m_ico,ico_point,ILD_TRANSPARENT);
	}

	UINT allign=DT_LEFT;
	if(m_bTextBottom) allign=DT_CENTER;

	CRect txtrect=elem->m_textrect;
	txtrect.OffsetRect(-dx,-dy);

	pDC->SetBkMode(OPAQUE);
	pDC->SetTextColor(txt_color);
	pDC->SetBkColor(txt_bk_color);	
	CFont *pOldFont=pDC->SelectObject(txt_font);
	pDC->DrawText(elem->m_text,txtrect,allign|DT_WORDBREAK|DT_END_ELLIPSIS);

	pDC->SelectObject(pOldPen);
	pDC->SelectObject(pOldFont);
	pDC->SelectObject(pOldBrush);

	return true;
}


void CaplSelectView::Clear()
{
	int i;
	for (i=0;i<m_groups.GetSize();i++) delete m_groups[i];
	m_groups.RemoveAll();
	m_NonGroupItemsGroup.Clear();
}

int CaplSelectView::AddGroup(LPCTSTR txt,int ico,long data)
{
	CaplSelectViewGroup *grp=new CaplSelectViewGroup(txt,ico,data);

	return m_groups.Add(grp);
}

void CaplSelectView::SetGroupData(int iPos,void* pData)
{
	CaplSelectViewGroup* grp=NULL;
	if(iPos>=m_groups.GetSize())
		return;
	grp=m_groups[iPos];
	grp->m_pData=pData;
}

void CaplSelectView::GetGroupData(int iPos,void*& pData)
{
	CaplSelectViewGroup* grp=NULL;

	pData=NULL;

	if(iPos>=m_groups.GetSize())
		return;
	grp=m_groups[iPos];
	pData=grp->m_pData;
}

void CaplSelectView::CloseGroup(int group, bool bClose)
{
	CaplSelectViewGroup* grp=NULL;

	if(group>=m_groups.GetSize())
		return;
	grp=m_groups[group];
	grp->m_bClosed=bClose;
}


int CaplSelectView::AddElement(int group, LPCTSTR txt, int ico, long data)
{
	//CaplSelectViewGroup *grp=new CaplSelectViewGroup(txt);
	if(group==-1)
	{
		CaplSelectViewElement *elm=new CaplSelectViewElement(txt,ico,data);
		m_NonGroupItemsGroup.m_elements.Add(elm);
		return (int)elm;
	}
	else if(group>=m_groups.GetSize()) 
		return 0;

	CaplSelectViewElement *elm=new CaplSelectViewElement(txt,ico,data);
	m_groups[group]->m_elements.Add(elm);
	return (int)elm;
}

void CaplSelectView::GetSelected(int &nGrp, int &nEl)
{
	for(int i=0; i<m_groups.GetSize(); i++)
	{
		for(int j=0; j<m_groups[i]->m_elements.GetSize(); j++)
		{
			if(m_groups[i]->m_elements[j] == m_sel_element)
			{
				nGrp = i;
				nEl = j;
				return;
			}
		}
	}
}

void CaplSelectView::SetElementData(int iGroup,int iElement,void* pData)
{
	CaplSelectViewGroup*	grp		=NULL;
	CaplSelectViewElement*	elem	=NULL;

	if(iGroup>=m_groups.GetSize())
		return;
	grp=m_groups[iGroup];
	if(iElement>=grp->m_elements.GetSize())
		return;
	elem=grp->m_elements[iElement];
	elem->m_data=(long)pData;
}

void CaplSelectView::GetElementData(int iGroup,int iElement,void*& pData)
{
	pData=0;
	if(iGroup<0) return;
	if(iElement<0) return;
	if(iGroup>=m_groups.GetSize())		return;

	CaplSelectViewGroup *grp= m_groups[iGroup];
	CaplSelectViewElement *elem	=NULL;
	if(iElement>=grp->m_elements.GetSize()) 	return;
	elem=grp->m_elements[iElement];
	pData=(void*)elem->m_data;
}


bool CaplSelectView::EnableElement(int element, bool bEnable)
{
	if(element==0) return false;

	CaplSelectViewElement *elm=(CaplSelectViewElement*)element;
	elm->m_bEnable=bEnable;
	return true;
}

void CaplSelectView::RecalcSize()
{
	if(m_bElementAsButton){RecalcSize4ButttonStyle(); return;}

	RECT clientrect;
	SetScrollSizes(MM_TEXT, CSize(1, 1));
	GetClientRect(&clientrect);
	//int cx=clientrect.right-clientrect.left;

	RECT wndrect;
	GetWindowRect(&wndrect);
	int cx=wndrect.right-wndrect.left-2-2*(GetSystemMetrics(SM_CXBORDER));
	if(cx<1) cx=1;
	else if(cx>500) cx=500;

	CDC *dc=GetDC();
	CFont *pOldFont=dc->SelectObject(&m_fontGroup);

	int cy;
	CalcViewSize(dc, cx, cy);

	if(cy > clientrect.bottom-clientrect.top)
	{
		cx-=GetSystemMetrics(SM_CXVSCROLL);
		if(cx<1) cx=1;
		CalcViewSize(dc, cx, cy);
	}
	SetScrollSizes(MM_TEXT, CSize(cx-1,cy));

	dc->SelectObject(pOldFont);
	ReleaseDC(dc);
}

void CaplSelectView::CalcViewSize(CDC *dc, int cx, int &cy)
{
	cy=0;
	if(cx==0) return;

	int i,j,iy=0;
	RECT tmp_rect;

	int ico_group_cx=0, ico_group_cy=0,ico_element_cx=0,ico_element_cy=0;
	if(m_il_group!=0) ::ImageList_GetIconSize(m_il_group.m_hImageList, &ico_group_cx, &ico_group_cy);
	if(m_il_elements!=0) ::ImageList_GetIconSize(m_il_elements.m_hImageList, &ico_element_cx, &ico_element_cy);

	CaplSelectViewGroup *grp;
	for (i=-1;i<m_groups.GetSize();i++)
	{
		if(i<0 && m_NonGroupItemsGroup.m_elements.GetSize()==0) continue;
		
		grp = (i<0) ? &m_NonGroupItemsGroup : m_groups[i];
		grp->m_drawrect.left=(grp->m_bDrawHeader?m_iMargin:0);
		grp->m_drawrect.right=cx-(grp->m_bDrawHeader?m_iMargin:0);
		grp->m_drawrect.top=cy+(grp->m_bDrawHeader?m_iMargin:0);
		grp->m_drawrect.bottom = cy+(grp->m_bDrawHeader?m_iMargin:0);
		if(grp->m_bDrawHeader)
		{
			if(grp->m_cy<ico_group_cy+m_iMargin) grp->m_cy=ico_group_cy+m_iMargin;
			
			tmp_rect.left=grp->m_drawrect.left+m_iMargin;
			tmp_rect.right=grp->m_drawrect.right-10-ico_group_cx;
			tmp_rect.top=0;
			tmp_rect.bottom=10;
			
			dc->SelectObject(&m_fontGroup);
			dc->DrawText(grp->m_text,&tmp_rect,DT_CALCRECT|DT_LEFT|DT_WORDBREAK|DT_NOCLIP);
			
			if(grp->m_cy<(tmp_rect.bottom+8)) grp->m_cy=tmp_rect.bottom+8;
			
			grp->m_drawrect.bottom=grp->m_drawrect.top+grp->m_cy;
			
			iy=grp->m_drawrect.bottom;
		}
		else
		{
			grp->m_elemrect = grp->m_drawrect;
		}

		if(grp->m_elements.GetSize()>0 && grp->m_bClosed==false )
		{
			dc->SelectObject(&m_fontElement);
			
			for (j=0;j<grp->m_elements.GetSize();j++)
			{
				CaplSelectViewElement *elem= grp->m_elements[j];

				if(grp->m_bClosed)
				{
					elem->m_drawrect.left=elem->m_drawrect.right=-1;
					elem->m_drawrect.top=elem->m_drawrect.bottom=-1;
					
					continue;
				}

				iy+=4;

				elem->m_drawrect.left=grp->m_drawrect.left+(grp->m_bDrawHeader?6:0);
				elem->m_drawrect.right=grp->m_drawrect.right-(grp->m_bDrawHeader?6:0);

				elem->m_drawrect.top=iy;

				// Вычисление высоты текста
				int txt_y;
				
				if(m_bTextBottom)// текст снизу 
				{
					elem->m_ico_point.x=elem->m_drawrect.left+((elem->m_drawrect.right-elem->m_drawrect.left-ico_element_cx)/2);
					elem->m_ico_point.y=elem->m_drawrect.top+5;

					tmp_rect.left=elem->m_drawrect.left+5;
					tmp_rect.right=elem->m_drawrect.right-5;
					
					tmp_rect.top=elem->m_drawrect.top+3;
					if(elem->m_ico>=0)	tmp_rect.top+=ico_element_cy+3;

					tmp_rect.bottom=tmp_rect.top+100;
					dc->DrawText(elem->m_text,&tmp_rect,DT_CALCRECT|DT_CENTER|DT_WORDBREAK);
					tmp_rect.left=elem->m_drawrect.left+5;
					tmp_rect.right=elem->m_drawrect.right-5;


					elem->m_textrect=tmp_rect;
					elem->m_drawrect.bottom=elem->m_textrect.bottom+4;

				}
				else // текст слева 
				{
					tmp_rect.left=elem->m_drawrect.left+5;
					if(elem->m_ico>=0)	tmp_rect.left+=ico_element_cx+10;
					tmp_rect.right=elem->m_drawrect.right-5;
					tmp_rect.top=0;	
					tmp_rect.bottom=200;

					dc->DrawText(elem->m_text,&tmp_rect,DT_CALCRECT|DT_LEFT|DT_WORDBREAK);
					txt_y=tmp_rect.bottom-tmp_rect.top;
					cy=txt_y;

					tmp_rect.right=elem->m_drawrect.right-5;
					
					if(elem->m_ico>=0)
					{
						if(cy<ico_element_cy+7) cy=ico_element_cy+7;
					}
					//cy+=4;
					if(cy<20) cy=20; // Меньше 20 как-то не хорошо

					if(m_bElementAsButton) 	cy+=4;
					else	cy+=2;
					
					elem->m_ico_point.x=elem->m_drawrect.left+7;
					elem->m_ico_point.y=elem->m_drawrect.top+((cy-ico_element_cy)/2);

					elem->m_textrect=tmp_rect;
					elem->m_textrect.top=elem->m_drawrect.top+((cy-txt_y)/2);
					elem->m_textrect.bottom=elem->m_textrect.top+txt_y;
					
					elem->m_drawrect.bottom=elem->m_drawrect.top+cy;
				}
				iy=elem->m_drawrect.bottom;
			}

			if(!grp->m_bClosed)iy+=(4+3);

			grp->m_drawrect.bottom=iy;
		}

		grp->m_elemrect=grp->m_drawrect;
		grp->m_elemrect.left+=3;
		grp->m_elemrect.right-=3;
		grp->m_elemrect.bottom-=3;
		grp->m_elemrect.top+=grp->m_cy;

		cy=grp->m_drawrect.bottom+2;
	}

	//cx+=10;
	cy+=m_iMargin;

	//CSize sizeTotal;
	//sizeTotal.cx = cx;
	//sizeTotal.cy = cy;
}

void CaplSelectView::CalcRectSize(CRect& drawrect, CRect& textrect, CPoint& ico_point, CDC* pDC, CFont* pFont, CString& text, int& ico_cx, int& ico_cy, int &ico)
{
	CRect tmp_rect;
	int txt_y, cy;
	
	if(m_bTextBottom)// текст снизу 
	{
		ico_point.x=drawrect.left+((drawrect.right-drawrect.left-ico_cx)/2);
		ico_point.y=drawrect.top+5;

		tmp_rect.left= drawrect.left+5;
		tmp_rect.right= drawrect.right-5;
		
		tmp_rect.top=drawrect.top+5;
//		if(ico>=0)	
			tmp_rect.top+=ico_cy+5;

		tmp_rect.bottom=tmp_rect.top+100;
		pDC->DrawText(text,&tmp_rect,DT_CALCRECT|DT_CENTER|DT_WORDBREAK);
		tmp_rect.left=drawrect.left+5;
		tmp_rect.right=drawrect.right-5;

//		if(tmp_rect.bottom<iy) tmp_rect.bottom= iy;
		
		textrect=tmp_rect;
		drawrect.bottom=textrect.bottom+5;

	}
	else // текст слева 
	{
		tmp_rect.left= drawrect.left+5;
		if(ico>=0)	
			tmp_rect.left+=ico_cx+10;
		tmp_rect.right= drawrect.right-5;
		tmp_rect.top=0;	
		tmp_rect.bottom=200;

		pDC->DrawText(text,&tmp_rect,DT_CALCRECT|DT_LEFT|DT_WORDBREAK);
		txt_y=tmp_rect.bottom-tmp_rect.top;
		cy= txt_y;

		tmp_rect.right= drawrect.right-5;
		
		if(ico>=0)
		{
			if(cy<ico_cy+7) cy=ico_cy+7;
		}
		cy+=5;
		if(cy<20) cy=20; // Меньше 20 как-то не хорошо
		
		ico_point.x= drawrect.left+7;
		ico_point.y= drawrect.top+((cy-ico_cy)/2);

		
		textrect= tmp_rect;
		textrect.top= drawrect.top+((cy-txt_y)/2);
		textrect.bottom= textrect.top+txt_y;
		
		drawrect.bottom= drawrect.top+cy;
	}	
}

void CaplSelectView::RecalcSize4ButttonStyle()
{
	static bool bDoubleRecalc = false;

	int i,j,cx=0,cy=0,iy=0;

	RECT wndrect;
	if(!bDoubleRecalc)
		SetScrollSizes(MM_TEXT, CSize(1, 1));
	GetClientRect(&wndrect);
	cx = wndrect.right-wndrect.left;

	if(cx>145) cx= 145;

	CDC *dc=GetDC();
	CFont *pOldFont=dc->SelectObject(&m_fontGroup);

	int ico_group_cx=0, ico_group_cy=0,ico_element_cx=0,ico_element_cy=0;
	if(m_il_group!=0) ::ImageList_GetIconSize(m_il_group.m_hImageList, &ico_group_cx, &ico_group_cy);
	if(m_il_elements!=0) ::ImageList_GetIconSize(m_il_elements.m_hImageList, &ico_element_cx, &ico_element_cy);

	CaplSelectViewGroup *grp= NULL;
	
	for (i=0; i<m_groups.GetSize(); i++)
	{
		grp = m_groups[i];
		
		grp->m_drawrect.left	= (grp->m_bDrawHeader?m_iMargin:0);
		grp->m_drawrect.right	= cx-(grp->m_bDrawHeader?m_iMargin:0);
		grp->m_drawrect.top		= cy+(grp->m_bDrawHeader?m_iMargin:0);
		grp->m_drawrect.bottom	= cy+(grp->m_bDrawHeader?m_iMargin:0);
		
		dc->SelectObject(&m_fontElement);
		
		CalcRectSize(grp->m_drawrect, grp->m_textrect, grp->m_ico_point, dc, &m_fontElement, grp->m_text, 
			 ico_group_cx, ico_group_cy, grp->m_ico);
				
		iy= grp->m_drawrect.bottom;

		if(grp->m_elements.GetSize()>0)
		{
			dc->SelectObject(&m_fontElement);
			
			for (j=0;j<grp->m_elements.GetSize();j++)
			{
				CaplSelectViewElement *elem= grp->m_elements[j];
				elem->m_drawrect.left= grp->m_drawrect.right+j*(grp->m_drawrect.right-grp->m_drawrect.left);
				elem->m_drawrect.right= grp->m_drawrect.right+(j+1)*(grp->m_drawrect.right-grp->m_drawrect.left);

				elem->m_drawrect.top=grp->m_drawrect.top;

				CalcRectSize(elem->m_drawrect, elem->m_textrect, elem->m_ico_point, dc, &m_fontElement, elem->m_text, 
					 ico_element_cx, ico_element_cy, elem->m_ico);

				if(iy<elem->m_drawrect.bottom)
				{
					// отрисовываем группу по самому большому элементу
					iy = elem->m_drawrect.bottom;
					elem->m_textrect.top	-= (iy-elem->m_drawrect.bottom)/2;
					elem->m_textrect.bottom	+= (iy-elem->m_drawrect.bottom)/2;
					elem->m_ico_point.y		-= (iy-elem->m_drawrect.bottom)/2;
				}
			}

			for(j=0;j<grp->m_elements.GetSize();j++)
			{
				CaplSelectViewElement *elem= grp->m_elements[j];
				if(elem->m_drawrect.bottom<iy)
				{
					// выровнять текст и иконки по центру
					if(!m_bTextBottom)
					{
						elem->m_textrect.top	-= (iy-elem->m_drawrect.bottom)/2;
						elem->m_textrect.bottom	+= (iy-elem->m_drawrect.bottom)/2;
						elem->m_ico_point.y		-= (iy-elem->m_drawrect.bottom)/2;
					}
					
					grp->m_elements[j]->m_drawrect.bottom= iy;
					continue;
				}
			}

			grp->m_cy+= iy-grp->m_drawrect.bottom;
			grp->m_drawrect.bottom= iy;
		}

		grp->m_elemrect=grp->m_drawrect;
		cy=grp->m_drawrect.bottom+1;
	}

	//cx+=10;
	cy+=m_iMargin;

	CSize sizeTotal;
	sizeTotal.cx = cx;
	sizeTotal.cy = cy;

	dc->SelectObject(pOldFont);
	ReleaseDC(dc);

	SetScrollSizes(MM_TEXT, sizeTotal);

	if(cy>wndrect.bottom-wndrect.top && !bDoubleRecalc)
	{
		bDoubleRecalc = true;
		RecalcSize4ButttonStyle();
	}
	bDoubleRecalc = false;
}

void CaplSelectView::OnInitialUpdate()
{
	CScrollView::OnInitialUpdate();

	UpdateGDI();

}

/////////////////////////////////////////////////////////////////////////////
// CaplSelectView diagnostics

#ifdef _DEBUG
void CaplSelectView::AssertValid() const
{
	CScrollView::AssertValid();
}

void CaplSelectView::Dump(CDumpContext& dc) const
{
	CScrollView::Dump(dc);
}
/*
CSelectDoc* CaplSelectView::GetDocument() // non-debug version is inline
{
	ASSERT(m_pDocument->IsKindOf(RUNTIME_CLASS(CSelectDoc)));
	return (CSelectDoc*)m_pDocument;
}*/
#endif //_DEBUG

/////////////////////////////////////////////////////////////////////////////
// CaplSelectView message handlers
//*******************************************************************
bool CaplSelectView::SetGroupImageList(CImageList *imagelist)
{
	if(m_il_group.m_hImageList!=0) m_il_group.DeleteImageList();
	if(imagelist!=0) m_il_group.Create(imagelist);
	return true;
}

bool CaplSelectView::SetElementImageList(CImageList *imagelist)
{
	if(m_il_elements.m_hImageList!=0) m_il_elements.DeleteImageList();
	if(imagelist!=0) m_il_elements.Create(imagelist);
	return true;
}


bool CaplSelectView::SetGroupFont(CFont *font)
{
	if (font==0) return false;

	if (m_fontGroup.m_hObject) m_fontGroup.DeleteObject();

	LOGFONT LogFont;
	font->GetLogFont(&LogFont);
	m_fontGroup.CreateFontIndirect(&LogFont);

	return true;
}

bool CaplSelectView::SetElementFont(CFont *font, CFont *font_sel, CFont *font_highlight )
{
	LOGFONT LogFont;

	if (font!=0)
	{
		if (m_fontElement.m_hObject) m_fontElement.DeleteObject();
		font->GetLogFont(&LogFont);
		m_fontElement.CreateFontIndirect(&LogFont);
	}

	if (font_sel!=0)
	{
		if (m_fontElementSel.m_hObject) m_fontElementSel.DeleteObject();
		font_sel->GetLogFont(&LogFont);
		m_fontElementSel.CreateFontIndirect(&LogFont);
	}

	if (font_highlight!=0)
	{
		if (m_fontElementHL.m_hObject) m_fontElementHL.DeleteObject();
		font_highlight->GetLogFont(&LogFont);
		m_fontElementHL.CreateFontIndirect(&LogFont);
	}

	return true;
}

//*******************************************************************
BOOL CaplSelectView::OnEraseBkgnd(CDC* pDC) 
{
	return TRUE;
	// TODO: Add your message handler code here and/or call default
	RECT rect;
	GetClientRect(&rect);

	/*rect.left+=5;
	rect.right-=5;

	rect.top+=5;
	rect.bottom-=5;*/

	//pDC->FillSolidRect(&rect,RGB(244,247,249));
	//pDC->FillSolidRect(&rect,m_color_bk);


	CBrush brush_bk(m_color_bk);

	//CBrush *pOldBrush=pDC->SelectObject(&brush_bk);	

	pDC->FillRect(&rect,&brush_bk);
	//pDC->SelectObject(pOldBrush);

	/*TRIVERTEX vertex[2] =
	{
	   {rect.left, rect.top,     0x7a00, 0xa100, 0xe600, 0xff00},
	   {rect.right, rect.bottom, 0x6300, 0x7700, 0xd600, 0x0000}
	};
	GRADIENT_RECT rc = {0, 1};
	//pDC->GradientFill( vertex, 2,  &rc,  1, GRADIENT_FILL_RECT_H);
	::GradientFill(pDC->m_hDC, vertex, 2,  &rc,  1, GRADIENT_FILL_RECT_V);
    */

	return TRUE;
	//return CScrollView::OnEraseBkgnd(pDC);
}
//****************************************************************

void CaplSelectView::OnLButtonDblClk(UINT nFlags, CPoint point) 
{
	// TODO: Add your message handler code here and/or call default
	
	CScrollView::OnLButtonDblClk(nFlags, point);

	if(m_bElementAsButton) return;
	
	CaplSelectViewGroup* group= Point2Group(point);
	if(group==0) return;

	if(point.y<(group->m_drawrect.top+group->m_cy))
	{
		if(point.x<group->m_drawrect.right-30)
		{
			group->m_bClosed=!group->m_bClosed;
			RecalcSize();
			Invalidate();
		}
	}

}

//****************************************************************
void CaplSelectView::OnLButtonUp(UINT nFlags, CPoint point) 
{
	if(m_bElementAsButton)
	{
			
	}
	else
	{
		
	}
}

void CaplSelectView::OnLButtonDown(UINT nFlags, CPoint point) 
{
	CScrollView::OnLButtonDown(nFlags, point);
	ReleaseCapture();

	if(m_bElementAsButton)
	{
		CaplSelectViewGroup* group= Point2Group(point);

		while(group)
		{
			CaplSelectElemWnd elemWnd;
			elemWnd.m_group= group;
			elemWnd.m_viewWnd= this;
			
			long iRes= elemWnd.ShowElements();

			if(iRes!=SVW_CANCEL)
			{
//				CString str;
//				str.Format("%i", iRes);
//				AfxMessageBox(str);
				
				CWnd *wnd_par=GetParent();
				if(wnd_par!=0)
				{
					if(wnd_par->IsKindOf(RUNTIME_CLASS(CDialog)))
					{
						wnd_par->SendMessage(WM_COMMAND, iRes, 0);
						return;
					}

				}
				if(!SendMessage(WM_COMMAND, iRes, 0) && AfxGetMainWnd()!=0)
					AfxGetMainWnd()->SendMessage(WM_COMMAND, iRes, 0);
				
				if(group && group!=m_SelectedGroup)
				{
					m_SelectedGroup= group;
		//			Invalidate();
				}
			}
			
			group= Point2Group(elemWnd.GetLastPoint());
			if(group)
			{
				m_SelectedGroup= group;
			}

			m_HighLightGroup= NULL;			
			Invalidate();
		}
	}
	else
	{
		// Проверяем клик на заголовке
		CaplSelectViewGroup* group= Point2Group(point);
		if(group!=0)
		{
			if(point.y<(group->m_drawrect.top+group->m_cy))
			{
				if(point.x>group->m_drawrect.right-30)
				{
					group->m_bClosed=!group->m_bClosed;
					RecalcSize();
					Invalidate();
					return;
				}
			}
		}
		// В заголовок не попали
		CaplSelectViewElement *elem=Point2Element(point);
		if(elem!=0)
		{
			//AfxMessageBox(elem->m_text);
			m_prev_sel_element=m_sel_element;
			m_sel_element=elem;
			Invalidate();

			CWnd *wnd_par=GetParent();
			if(wnd_par!=0)
			{
				if(wnd_par->IsKindOf(RUNTIME_CLASS(CDialog)))
				{
					wnd_par->SendMessage(WM_COMMAND,m_sel_element->m_data,0);
					return;
				}

			}
			//CWnd *wnd=AfxGetMainWnd();
			if(!SendMessage(WM_COMMAND,m_sel_element->m_data,0) && AfxGetMainWnd()!=0)
				AfxGetMainWnd()->SendMessage(WM_COMMAND,m_sel_element->m_data,0);
			//GetParent()->SendMessage(WM_USER, m_sel_element->m_data, 0);
			
		}
	}


}
//****************************************************************
CaplSelectView::CaplSelectViewElement *CaplSelectView::Point2Element(CPoint point)
{
	int i,j;

	CPoint RealPoint=point;
	CPoint pnt_scroll=GetScrollPosition( );
	
	RealPoint+=pnt_scroll;
	CaplSelectViewGroup *grp;
	for (i=-1;i<m_groups.GetSize();i++)
	{
		grp = i<0? &m_NonGroupItemsGroup : m_groups[i];
		
		if(grp->m_bClosed) continue;
		if(FALSE==grp->m_drawrect.PtInRect(RealPoint)) continue;
	
		for (j=0;j<grp->m_elements.GetSize();j++)
		{
			CaplSelectViewElement *elem= grp->m_elements[j];
			if(FALSE==elem->m_drawrect.PtInRect(RealPoint)) continue;

			if(elem->m_bEnable==false) return 0;
			return elem;
		}
	}

	return 0;

}

CaplSelectView::CaplSelectViewGroup* CaplSelectView::Point2Group(CPoint& point)
{
	CPoint RealPoint=point;
	CPoint pnt_scroll=GetScrollPosition( );
	
	RealPoint+=pnt_scroll;
	
	for(int i= 0; i<m_groups.GetSize(); i++)
	{
		if(m_groups[i]->m_drawrect.PtInRect(RealPoint))
		{
			return m_groups[i];
		}
	}

	return NULL;
}
//****************************************************************
void CaplSelectView::OnMouseMove(UINT nFlags, CPoint point) 
{
	CScrollView::OnMouseMove(nFlags, point);

	CRect client_rect;
	GetClientRect(&client_rect);
	if(client_rect.PtInRect(point))
		SetCapture();
	else
		ReleaseCapture();

	if(m_bElementAsButton)
	{
		CaplSelectViewGroup* group= Point2Group(point);

		if(group!=m_HighLightGroup)
		{
			m_HighLightGroup= group;
			Invalidate();
		}	
	}	
	else
	{
		CaplSelectViewElement *elem=Point2Element(point);

		if(m_last_hl_element==elem) return;

		CPoint pnt_scroll=GetScrollPosition( );

		m_curCursor=m_DefCursor;

		CDC *pDC=GetDC();
		
		DrawElement(m_last_hl_element,pDC,FALSE,pnt_scroll.x,pnt_scroll.y);	
		if(elem!=0)
		{
			if(elem->m_bEnable==true)
			{
				DrawElement(elem,pDC,TRUE,pnt_scroll.x,pnt_scroll.y);
				m_curCursor=m_HLCursor;
				SetCursor(m_curCursor);
			}
		}
		m_last_hl_element=elem;
		SetCursor(m_curCursor);
		
		ReleaseDC(pDC);
	}
}
//****************************************************************

BOOL CaplSelectView::OnSetCursor(CWnd* pWnd, UINT nHitTest, UINT message) 
{
	// TODO: Add your message handler code here and/or call default

	SetCursor(m_curCursor);
	return true;
	//return CScrollView::OnSetCursor(pWnd, nHitTest, message);
}

int CaplSelectView::OnMouseActivate(CWnd* pDesktopWnd, UINT nHitTest, UINT message) 
{
	// TODO: Add your message handler code here and/or call default
	return MA_ACTIVATE;
	//return CScrollView::OnMouseActivate(pDesktopWnd, nHitTest, message);
}

bool CaplSelectView::SelectElement(CaplSelectView::CaplSelectViewElement* element)
{
	m_prev_sel_element=m_sel_element;
	m_sel_element = element;
	Invalidate();
	return true;
}

bool CaplSelectView::SelectPrevElement()
{
	return SelectElement(m_prev_sel_element);
}

bool CaplSelectView::SelectGroup(CaplSelectView::CaplSelectViewGroup* group)
{
	m_SelectedGroup= group;
	Invalidate();
	return true;
}

bool CaplSelectView::SelectGroup(long element_data)
{
	int i, j;
	bool bRes = false;
	CaplSelectViewGroup *pGroup;
	m_SelectedGroup = NULL;

	for(i=-1; i<m_groups.GetSize(); i++)
	{
		pGroup = i<0 ? &m_NonGroupItemsGroup : m_groups[i];
		if(pGroup==NULL) continue;

		for(j=0; j<pGroup->m_elements.GetSize(); j++)
		{
			if(pGroup->m_elements[j]->m_data==element_data)
			{
				m_SelectedGroup= pGroup;
				bRes = true;
				break;
			}
		}
	}
	Invalidate();
	return bRes;
}

bool CaplSelectView::SelectElement(long element_data)
{
	int i, j;
	bool bRes = false;
	CaplSelectViewGroup *pGroup;
	m_sel_element = NULL;
	for(i=-1; i<m_groups.GetSize(); i++)
	{
		pGroup = i<0 ? &m_NonGroupItemsGroup : m_groups[i];
		if(pGroup==NULL) continue;

		for(j=0; j<pGroup->m_elements.GetSize(); j++)
		{
			if(pGroup->m_elements[j]->m_data==element_data)
			{
				m_prev_sel_element=m_sel_element;
				m_sel_element = pGroup->m_elements[j];
				bRes = true;
				break;
			}
		}
	}
	Invalidate();
	return bRes;
}

bool CaplSelectView::Unselect()
{
	m_sel_element = NULL;
	Invalidate();
	return true;
}

void CaplSelectView::OnSize(UINT nType, int cx, int cy) 
{
	//CScrollView::OnSize(nType, cx, cy);

	if(m_bAutoFitWidth)
	{
		RecalcSize();
		//CScrollView::OnSize(nType, cx, cy);
		Invalidate();
	}
	else
	{
		CScrollView::OnSize(nType, cx, cy);
	}
}


bool CaplSelectView::SetColorSchema(int schema)
{
	switch(schema)
	{
	case 0:

		m_color_bk=GetSysColor(COLOR_SCROLLBAR);
		m_color_group_bk=GetSysColor(COLOR_WINDOW);
		//m_color_group_bk=GetSysColor(COLOR_3DLIGHT);
		//m_color_group_bk=aplColor_GetHilightColor(m_color_bk,75);
		m_color_group_head=GetSysColor(COLOR_INACTIVECAPTION);
		m_color_group_ramka=GetSysColor(COLOR_ACTIVEBORDER);
		m_color_group_head_sel=GetSysColor(COLOR_HIGHLIGHT/*COLOR_ACTIVECAPTION*/);
		
		m_color_group_head=aplColor_MixColor(m_color_group_head_sel,m_color_group_head,75);
		
		m_color_element_sel_ramka=GetSysColor(COLOR_HIGHLIGHT);
		m_color_element_sel=aplColor_GetHilightColor(m_color_element_sel_ramka,80);

		//m_color_element_sel=aplColor_InvertColor(aplColor_GetHilightColor(m_color_group_head_sel,85));
		//m_color_element_sel=aplColor_MixColor(m_color_element_sel,RGB(255,255,255),75);

		m_color_element_hl=GetSysColor(COLOR_INFOBK);
		m_color_txt_group_head=GetSysColor(COLOR_CAPTIONTEXT);
		m_color_txt_element=GetSysColor(COLOR_MENUTEXT);
		m_color_txt_element_sel=m_color_txt_element;
		
		m_color_element_tl = GetSysColor(COLOR_3DHILIGHT);//RGB(255,255,255);
		m_color_element_br = GetSysColor(COLOR_3DSHADOW);//RGB(64,64,64);

		m_color_group_ramka=m_color_txt_group_head;

		break;

	case 1:

		m_color_bk=GetSysColor(COLOR_SCROLLBAR);
		m_color_group_bk=RGB(255,255,255);
		m_color_group_head=RGB(0,101,200);//RGB(128,128,128);
		m_color_group_ramka=RGB(255,255,255);//=RGB(0,0,0);
		m_color_group_head_sel=RGB(0,72,143);
		
		//m_color_group_head=aplColor_MixColor(m_color_group_head_sel,m_color_group_head,75);
		
		m_color_element_sel_ramka=m_color_group_head_sel;//RGB(128,192,255);
		m_color_element_sel=RGB(193,222,251);

		//m_color_element_sel=aplColor_InvertColor(aplColor_GetHilightColor(m_color_group_head_sel,85));
		//m_color_element_sel=aplColor_MixColor(m_color_element_sel,RGB(255,255,255),75);

		m_color_element_hl=GetSysColor(COLOR_INFOBK);
		m_color_txt_group_head=RGB(255,255,255);
		m_color_txt_element=RGB(0,0,0);
		m_color_txt_element_sel=RGB(0,0,0);
		
		m_color_element_tl = GetSysColor(COLOR_3DHILIGHT);//RGB(255,255,255);
		m_color_element_br = GetSysColor(COLOR_3DSHADOW);//RGB(64,64,64);

		//m_color_group_ramka=m_color_txt_group_head;

		break;

	case 2:

		m_color_bk=GetSysColor(COLOR_SCROLLBAR);			// Общий фон
		m_color_group_bk=RGB(234,241,247);      // Фон элементов вгруппе
		m_color_group_head=RGB(111,150,207/*107,149,207*/);      // Цвет заголовка группы
		
		m_color_element_sel=RGB(0,51,204);		// Цвет фона выделенного элемента

		m_color_element_hl=RGB(51,102,255);    // Цвет фона подсвеченного элемента

		m_color_element_tl=RGB(255,255,255);    // Цвет левой и верхней границы подсвеченного элемента
		m_color_element_br=RGB(128,128,128);    // Цвет правой и нижней границы подсвеченного элемента

		m_color_txt_group_head=RGB(255,255,255);// Цвет текста в заголовке группы
		m_color_txt_element=RGB(0,0,0);			// Цвет текста невыделенного элемента
		m_color_txt_element_sel=RGB(255,255,255);//Цвет текста выделенного элемента

		//POINT m_roundpoint_element;		// скругление углов для элемента
		//POINT m_roundpoint_group;       // скругление углов для группы   


		break;

	case 3:

		m_color_bk=RGB(128,128,128);			// Общий фон
		m_color_group_bk=RGB(192,192,192);      // Фон элементов вгруппе
		m_color_group_head=RGB(40,61,108);    // Цвет заголовка группы
		m_color_element_sel=RGB(255,255,255);   // Цвет фона выделенного элемента
		m_color_element_hl=RGB(125,142,182);    // Цвет фона подсвеченного элемента

		m_color_element_tl=RGB(255,255,255);    // Цвет левой и верхней границы подсвеченного элемента
		m_color_element_br=RGB(128,128,128);    // Цвет правой и нижней границы подсвеченного элемента

		m_color_txt_group_head=RGB(255,255,255);    // Цвет текста в заголовке группы
		m_color_txt_element=RGB(0,0,0);		// Цвет текста невыделенного элемента
		m_color_txt_element_sel=RGB(0,0,0);	// Цвет текста выделенного элемента

		break;

	case 4:

		m_color_bk=RGB(234,235,219);				// Общий фон
		m_color_group_bk=RGB(244,196,179);      	// Фон элементов вгруппе
		m_color_group_head=RGB(75,186,202);		// Цвет заголовка группы

		m_color_element_sel=RGB(224,229,97);   		// Цвет фона выделенного элемента
		m_color_element_hl=RGB(125,142,182);    	// Цвет фона подсвеченного элемента

		m_color_element_tl=RGB(255,255,255);    	// Цвет левой и верхней границы подсвеченного элемента
		m_color_element_br=RGB(128,128,128);    	// Цвет правой и нижней границы подсвеченного элемента

		m_color_txt_group_head=RGB(255,255,255);	// Цвет текста в заголовке группы
		m_color_txt_element=RGB(0,0,0);				// Цвет текста невыделенного элемента
		m_color_txt_element_sel=RGB(0,0,0);			// Цвет текста выделенного элемента

		break;

	default:
		return false;
	}

	UpdateGDI();
	return true;

}

/************************************************************************/
/* CaplSelectElemWnd                                                    */
/************************************************************************/

IMPLEMENT_DYNCREATE(CaplSelectElemWnd, CWnd)

CaplSelectElemWnd::CaplSelectElemWnd()
{
	m_viewWnd= NULL;

	m_SelectedElement= NULL;
	m_HighLightElement= NULL;

	m_Flag= SVW_NONE;

	m_group= NULL;

	m_ix= 0;
	m_iy= 0;
	m_icx= 10;
	m_icy= 10;

	m_LLPoint= CPoint(-1,-1);

	m_nSelectResult= SVW_CANCEL;
}

CaplSelectElemWnd::~CaplSelectElemWnd()
{
}

BEGIN_MESSAGE_MAP(CaplSelectElemWnd, CWnd)
	//{{AFX_MSG_MAP(CaplSelectElemWnd)
	ON_WM_PAINT()
	ON_WM_ERASEBKGND()
	ON_WM_LBUTTONDOWN()
	ON_WM_LBUTTONUP()
	ON_WM_MOUSEMOVE()
 	ON_WM_MOUSEACTIVATE()
	ON_WM_KILLFOCUS()
	ON_WM_KEYDOWN()
	ON_WM_MDIACTIVATE()
	//}}AFX_MSG_MAP
END_MESSAGE_MAP()

/////////////////////////////////////////////////////////////////////////////
// CaplSelectElemWnd message handlers

void CaplSelectElemWnd::OnPaint() 
{
	CPaintDC dc(this); // device context for painting	
	if(!m_group) return;

	// фон 
	CRect clRect;
	GetClientRect(clRect);
	dc.Draw3dRect(clRect, m_viewWnd->m_color_element_tl, m_viewWnd->m_color_element_br);

	// сами элементы
	CPen *pOldPen;
	CBrush *pOldBrush;
	CFont *pOldFont;

	CBrush brush_bk(m_viewWnd->m_color_bk);
	
	COLORREF txt_color=m_viewWnd->m_color_txt_element;
	COLORREF txt_bk_color=m_viewWnd->m_color_bk;
	COLORREF color;
	CBrush *fon_brush=&brush_bk;
	color=aplColor_GetHilightColor(m_viewWnd->m_color_bk, BTN_COLOR_HILIGHT);
	CBrush fon_brush_light(color);
	CFont *txt_font=&m_viewWnd->m_fontElement;
	
	CRect rect, tDRect;
	CPoint point;
	UINT allign;
	
	CaplSelectView::CaplSelectViewElement* elem= NULL;

	CPen pen(PS_SOLID, 0, txt_bk_color);

	pOldPen= dc.SelectObject(&pen);
	pOldFont= dc.SelectObject(txt_font);
	pOldBrush= dc.SelectObject(fon_brush);

	int oldBkMode = dc.SetBkMode(TRANSPARENT);
	
	dc.SetTextColor(txt_color);
	dc.SetBkColor(txt_bk_color);	
	dc.SelectObject(txt_font);

	for(int i= 0; i<m_group->m_elements.GetSize(); i++)
	{
		elem= m_group->m_elements[i];
		if(elem==0) continue;
	
		rect= elem->m_drawrect;
 		rect.OffsetRect(-m_group->m_drawrect.right+1, -m_group->m_drawrect.top+1);

		if(elem==m_SelectedElement)
		{
			txt_font= &m_viewWnd->m_fontElementSel;
			fon_brush= &m_viewWnd->m_brush_element_sel;
			txt_bk_color= m_viewWnd->m_color_element_sel;
			txt_color= m_viewWnd->m_color_txt_element_sel;
		}
		else if(elem==m_HighLightElement)
		{
			txt_font= &m_viewWnd->m_fontElementHL;
		}
		else
		{			
			fon_brush=&brush_bk;
			txt_color=m_viewWnd->m_color_txt_element;
			txt_bk_color=m_viewWnd->m_color_bk;
			txt_font=&m_viewWnd->m_fontElement;
		}
		
		pen.FromHandle(CPen(PS_SOLID, 0, txt_bk_color));
		dc.SelectObject(&pen);
		dc.SelectObject(fon_brush);
		
		tDRect= rect;

		if(elem==m_SelectedElement)
		{
			dc.FillRect(&rect, fon_brush);
			dc.Draw3dRect(&tDRect, m_viewWnd->m_color_element_br, m_viewWnd->m_color_element_tl);
		}
		else if(elem==m_HighLightElement)
		{
			dc.FillRect(&rect, &fon_brush_light);
			dc.Draw3dRect(&tDRect, m_viewWnd->m_color_element_tl, m_viewWnd->m_color_element_br);
		}
		else
			dc.FillRect(&rect, fon_brush);

		if(elem->m_ico>=0 && m_viewWnd->m_il_elements.m_hImageList!=0)
		{
			point= elem->m_ico_point;
			point.Offset(-m_group->m_drawrect.right+1, -m_group->m_drawrect.top+1);
			
			if(elem==m_SelectedElement)	point.Offset(2, 2);

			m_viewWnd->m_il_elements.Draw(&dc, elem->m_ico, point, ILD_TRANSPARENT);
		}		

		rect= elem->m_textrect;
		rect.OffsetRect(-m_group->m_drawrect.right+1, -m_group->m_drawrect.top+1);
		if(elem==m_SelectedElement)	rect.OffsetRect(2, 2);

		allign=DT_LEFT;
		if(m_viewWnd->m_bTextBottom) allign=DT_CENTER;

		dc.DrawText(elem->m_text, rect,allign|DT_WORDBREAK|DT_END_ELLIPSIS);
	}

	dc.SetBkMode(oldBkMode);

	dc.SelectObject(pOldPen);
	dc.SelectObject(pOldFont);
	dc.SelectObject(pOldBrush);
}

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

CaplSelectView::CaplSelectViewElement* CaplSelectElemWnd::GetElementByPoint(CPoint &point)
{
	if(m_group==NULL) return NULL;

	if(m_group->m_elements.GetSize()>0)
	{
		point.x+=m_group->m_elements[0]->m_drawrect.left;
		point.y+=m_group->m_elements[0]->m_drawrect.top;

		for(int i= 0; i<m_group->m_elements.GetSize(); i++)
		{
			if(m_group->m_elements[i]->m_drawrect.PtInRect(point))
			{
				return m_group->m_elements[i];
			}
		}
	}

	return NULL;	
}

int CaplSelectElemWnd::OnMouseActivate(CWnd* pDesktopWnd, UINT nHitTest, UINT message) 
{	
	return CWnd::OnMouseActivate(pDesktopWnd, nHitTest, message);
}

void CaplSelectElemWnd::OnMouseMove(UINT nFlags, CPoint point) 
{	
//	CWnd::OnMouseMove(nFlags, point);
	
	CaplSelectView::CaplSelectViewElement* element= GetElementByPoint(point);

	if(element!=m_HighLightElement)
	{
		m_HighLightElement= element;
		if(!element) m_SelectedElement= NULL;
		else if(m_Flag & SVW_MM_BEGIN) 
			m_SelectedElement= element;
		Invalidate();
	}
}

void CaplSelectElemWnd::OnLButtonDown(UINT nFlags, CPoint point) 
{	
//	CWnd::OnLButtonDown(nFlags, point);

	CaplSelectView::CaplSelectViewElement* element  = GetElementByPoint(point);

	if(!element)// просто закрываем и все
	{
		m_nSelectResult = SVW_CANCEL;
		m_Flag = SVW_STOPLOOP; 
		
		// если тыкнули мимо - могли попасть в другую группу
		// по точке можно обработать этот случай
		m_LLPoint = point;
		m_LLPoint.Offset(m_group->m_drawrect.right, m_group->m_drawrect.top);
		
		return;		
	}
	
	if(element!=m_SelectedElement)
	{
		m_SelectedElement= element;
		if(m_SelectedElement) m_Flag|=SVW_MM_BEGIN; //при движении курсора элемент будет выделяться
		Invalidate();
	}
}

void CaplSelectElemWnd::OnLButtonUp(UINT nFlags, CPoint point) 
{	
//	CWnd::OnLButtonUp(nFlags, point);
	
	CaplSelectView::CaplSelectViewElement* element= GetElementByPoint(point);

	if(element)
	{
		//результат
		if(m_Flag & SVW_MM_BEGIN)// на всякий случай
		{
			m_nSelectResult= element->m_data;
			m_Flag = SVW_STOPLOOP; 
			return;
		}
	}
	else
	{
		if(m_Flag & SVW_MM_BEGIN)
			m_Flag &= ~SVW_MM_BEGIN;
	}
}

BOOL CaplSelectElemWnd::Continue()
{
	return m_Flag & SVW_CONTINUELOOP;
}

long CaplSelectElemWnd::ShowElements()
{
	if(m_group && m_group->m_elements.GetSize()==1)
		return m_group->m_elements[0]->m_data;

	SetSizes();
	
	CRect rect(m_ix, m_iy, m_ix+m_icx, m_iy+m_icy);
	m_viewWnd->ClientToScreen(rect);
	CPoint point= m_viewWnd->GetScrollPosition();
	m_ix+=point.x;
	m_iy+=point.y;	

	HWND hWnd = NULL;

	CWinApp *app=AfxGetApp(); // При вызове из ActiveX возвращает 0
	if(0!=app)
	{
	 	if((hWnd = ::CreateWindowEx(WS_EX_TOPMOST|WS_EX_TOOLWINDOW, AfxRegisterWndClass(CS_OWNDC|CS_DBLCLKS|CS_IME), NULL, WS_POPUP, rect.left, rect.top, rect.Width(), rect.Height(), NULL, NULL, app->m_hInstance, 0))==NULL) return 0;
		SubclassWindow(hWnd);
	}

	SetWindowPos(&CWnd::wndTopMost, 0, 0, 0, 0, SWP_NOMOVE|SWP_NOSIZE);

	m_Flag |= SVW_CONTINUELOOP;

	BOOL bBreak= FALSE;
	
#if _MFC_VER <0x0700
	// VS 6.0
	MSG* pMsg = &AfxGetThread()->m_msgCur;
#else
	// VS NET
	_AFX_THREAD_STATE* pState = AfxGetThreadState();
	ASSERT(pState!=0);
	MSG* pMsg = &(pState->m_msgCur);
#endif

	ShowWindow(SW_SHOWNORMAL);
	UpdateWindow();

	SetCapture();
	SetFocus();

	for (;;)
	{
		if(bBreak) break;
		ShowWindow(SW_SHOW);
		do
		{
			if (!AfxGetThread()->PumpMessage())
			{
				AfxPostQuitMessage(0);
				return -1;
			}

			if (!Continue())
			{
				bBreak= TRUE; break;
			}
			
		} while (::PeekMessage(pMsg, NULL, NULL, NULL, PM_NOREMOVE));
	}

	ReleaseCapture();
	
	ShowWindow(SW_HIDE);

	UnsubclassWindow();

	::DestroyWindow(hWnd);

	return m_nSelectResult;
}

void CaplSelectElemWnd::SetSizes()
{
	if(!m_group) return;

	// отрисовывем в размерах группы
	m_ix= m_group->m_drawrect.right-m_viewWnd->GetScrollPos(SB_HORZ);/*+::GetSystemMetrics(SM_CXSIZEFRAME)*/
	m_iy= m_group->m_drawrect.top-1-m_viewWnd->GetScrollPos(SB_VERT); /*-::GetSystemMetrics(SM_CYSIZEFRAME)*/
	m_icy= (m_group->m_drawrect.bottom-m_group->m_drawrect.top)+2;
	m_icx= 0;

	for(int i= 0; i<m_group->m_elements.GetSize(); i++)
	{
		m_icx+=m_group->m_elements[i]->m_drawrect.Width();
	}
	
 	m_icx+=2; // делаем размер больше чем размер кнопок
}

CPoint & CaplSelectElemWnd::GetLastPoint()
{
	return m_LLPoint;
}

void CaplSelectElemWnd::OnKillFocus(CWnd* pNewWnd) 
{
	m_Flag &=~SVW_CONTINUELOOP;
}

void CaplSelectElemWnd::OnKeyDown(UINT nChar, UINT nRepCnt, UINT nFlags) 
{
	if(nChar==VK_ESCAPE) 
		m_Flag &=~SVW_CONTINUELOOP;
}

BOOL aplUniversalStretchBlt(CDC &DstDC,int x, int y, int nWidth, int nHeight, CDC* pSrcDC,
							int xSrc, int ySrc, int nSrcWidth, int nSrcHeight, DWORD dwRop)
{
	BOOL b=DstDC.StretchBlt(x,y,nWidth,nHeight,pSrcDC,xSrc,ySrc,nSrcWidth,nSrcHeight,dwRop);
	if(b) return TRUE;
	CDC tmpdc;
	tmpdc.CreateCompatibleDC(&DstDC);
	CBitmap bmp;
	bmp.CreateCompatibleBitmap(&DstDC,nWidth,nHeight);
	tmpdc.SelectObject(&bmp);
	tmpdc.FillSolidRect(0,0,nWidth,nHeight,RGB(0,255,0));
	BOOL b1,b2=FALSE;
	b1=tmpdc.StretchBlt(0,0,nWidth,nHeight,pSrcDC,xSrc,ySrc,nSrcWidth,nSrcHeight,dwRop);
	if(b1) b2=DstDC.BitBlt(x,y,nWidth,nHeight,&tmpdc,0,0,SRCCOPY);
	return b2&&b1;
}



bool aplPrintDC(CDC &dc,LPCTSTR header)
{
	CBitmap *bmp=dc.GetCurrentBitmap();
	if(0==bmp) {AfxMessageBox(APL_T("В DC отсутствует bitmap!")); return false;}
	BITMAP bm;
	bmp->GetBitmap(&bm);
	int bmp_width=bm.bmWidth;
	int bmp_high=bm.bmHeight;

	if(0==bmp_width || 0==bmp_high) {AfxMessageBox(APL_T("Нечего печатать (нулевой размер bitmap)"));return false;}

	CPrintDialog dlg(TRUE);
	if(IDOK!=dlg.DoModal()) return false;

	HDC hdc=dlg.CreatePrinterDC();
	if(0==hdc){AfxMessageBox(APL_T("Ошибка при создании контекста принтера!"));return false;}
	CDC PrintDC;
	PrintDC.Attach(hdc);

	//Расчет количества страниц по вертикали.
	int a_HorRes = PrintDC.GetDeviceCaps(HORZRES);
	int a_VertRes = PrintDC.GetDeviceCaps(VERTRES);
	//int a_VertRes = PrintDC.GetDeviceCaps(VERTRES);

	int printer_page_x = PrintDC.GetDeviceCaps(PHYSICALWIDTH);
	int printer_page_y = PrintDC.GetDeviceCaps(PHYSICALHEIGHT);
	int printer_offset_x = PrintDC.GetDeviceCaps(PHYSICALOFFSETX);
	int printer_offset_y = PrintDC.GetDeviceCaps(PHYSICALOFFSETY);

	SIZE Scale; Scale.cx=100; Scale.cy=100;
	PrintDC.HIMETRICtoDP(&Scale);

	if(0==a_HorRes || 0==a_VertRes) {AfxMessageBox(APL_T("Некорректный DC принтера")); return false;}

	CaplPrintDcDlg PrintOptDlg;
	PrintOptDlg.m_bmp_cx=bmp_width;
	PrintOptDlg.m_bmp_cy=bmp_high;
	PrintOptDlg.m_page_cx=printer_page_x/Scale.cx;
	PrintOptDlg.m_page_cy=(printer_page_y/Scale.cy)-10; // 10 - для заголовка
	PrintOptDlg.m_min_offset_x=1+printer_offset_x/Scale.cx;
	PrintOptDlg.m_min_offset_y=1+printer_offset_y/Scale.cy;

	PrintOptDlg.m_ViewDC=&dc;


	if(PrintOptDlg.DoModal()!=IDOK) {PrintDC.Detach(); return false;}


	printer_offset_x=PrintOptDlg.m_field_x*Scale.cx;
	printer_offset_y=PrintOptDlg.m_field_y*Scale.cy;

	int header_high=10*Scale.cy;
	int printer_cx=printer_page_x-(printer_offset_x*2);
	int printer_cy=(printer_page_y-(printer_offset_y*2))-header_high;

	ASSERT(printer_cx<a_HorRes);

	int hPages=PrintOptDlg.m_pages_x;
	int dx=bmp_width/hPages;
	int dy = printer_cy*dx/printer_cx;
	int vPages=1+bmp_high/dy;


	CFont font;
	font.CreatePointFont(100,_T("Arial Cyr"),&PrintDC);
	CFont *oldfont=PrintDC.SelectObject(&font);

	CString txt,buf;

	PrintDC.StartDoc(APL_T("Диаграмма Ганта"));
	for(int i=0; i<vPages; i++)
	{
		for(int j=0; j<hPages;j++)
		{
			PrintDC.StartPage();
			int x=j*dx;
			int y=i*dy;
			int out_v=printer_cy;
			int dy1=bmp_high-y;
			if(dy1>dy) dy1=dy;
			else out_v=printer_cy*dy1/dy;
			buf.Format(_T(" (%i,%i)"),i+1,j+1);
			txt=header; txt+=buf;
			PrintDC.TextOut(printer_offset_x,printer_offset_y,txt);
			//BOOL b=PrintDC.StretchBlt(printer_offset_x,printer_offset_y,printer_cx,out_v,&dc,x,y,dx,dy1,SRCCOPY);
			BOOL b=aplUniversalStretchBlt(PrintDC,printer_offset_x,printer_offset_y+header_high,printer_cx,out_v,&dc,x,y,dx,dy1,SRCCOPY);
			PrintDC.EndPage();
			if(!b)
			{
				AfxMessageBox(APL_T("Ошибка при выводе изображения"));
				j=hPages; i=vPages;
			}
		}
	}
	PrintDC.EndDoc();
	PrintDC.SelectObject(oldfont);
	PrintDC.Detach();
	return true;
}

void aplShowDcInfo(CDC *dc)
{	
	if(0==dc) return;

	CString b0,b1;
	CPoint p0;
	CSize sz;
	CSize sz_LPtoHIMETRIC;  sz_LPtoHIMETRIC.cx =100;sz_LPtoHIMETRIC.cy =100; dc->LPtoHIMETRIC(&sz_LPtoHIMETRIC);
	CSize sz_HIMETRICtoLP;  sz_HIMETRICtoLP.cx =100;sz_HIMETRICtoLP.cy =100; dc->HIMETRICtoLP(&sz_HIMETRICtoLP);

	CSize sz_LPtoDP;  sz_LPtoDP.cx =100;sz_LPtoDP.cy =100; dc->LPtoDP(&sz_LPtoDP);
	CSize sz_DPtoLP;  sz_DPtoLP.cx =100;sz_DPtoLP.cy =100; dc->DPtoLP(&sz_DPtoLP);

	b1.Format(_T("\n sz_LPtoDP = %i  %i"),sz_LPtoDP.cx, sz_LPtoDP.cy); b0+=b1;
	b1.Format(_T("\n sz_DPtoLP = %i  %i"),sz_DPtoLP.cx, sz_DPtoLP.cy); b0+=b1;
	b1.Format(_T("\n sz_LPtoHIMETRIC = %i  %i"),sz_LPtoHIMETRIC.cx, sz_LPtoHIMETRIC.cy); b0+=b1;
	b1.Format(_T("\n sz_HIMETRICtoLP = %i  %i"),sz_HIMETRICtoLP.cx, sz_HIMETRICtoLP.cy); b0+=b1;
	b0+=_T("\n");

	p0=dc->GetViewportOrg();
	b1.Format(_T("\n GetViewportOrg = %i  %i"),p0.x,p0.y); b0+=b1;

	p0=dc->GetWindowOrg();
	b1.Format(_T("\n GetWindowOrg = %i  %i"),p0.x,p0.y); b0+=b1;

	sz=dc->GetWindowExt();
	b1.Format(_T("\n GetWindowExt = %i  %i"),sz.cx,sz.cy); b0+=b1;

	sz= dc->GetViewportExt( );
	b1.Format(_T("\n GetViewportExt = %i  %i"),sz.cx,sz.cy); b0+=b1;

	b0+=_T("\n");
	b1.Format(_T("\n TEXTCAPS = %i"),dc->GetDeviceCaps(TEXTCAPS)); b0+=b1;
	b1.Format(_T("\n TECHNOLOGY = %i"),dc->GetDeviceCaps(TECHNOLOGY)); b0+=b1;
	b1.Format(_T("\n HORZRES = %i"),dc->GetDeviceCaps(HORZRES)); b0+=b1;
	b1.Format(_T("\n VERTRES = %i"),dc->GetDeviceCaps(VERTRES)); b0+=b1;
	b1.Format(_T("\n HORZSIZE = %i"),dc->GetDeviceCaps(HORZSIZE)); b0+=b1;
	b1.Format(_T("\n VERTSIZE = %i"),dc->GetDeviceCaps(VERTSIZE)); b0+=b1;
	b1.Format(_T("\n LOGPIXELSX = %i"),dc->GetDeviceCaps(LOGPIXELSX)); b0+=b1;
	b1.Format(_T("\n LOGPIXELSY = %i"),dc->GetDeviceCaps(LOGPIXELSY)); b0+=b1;
	b1.Format(_T("\n ASPECTX = %i"),dc->GetDeviceCaps(ASPECTX)); b0+=b1;
	b1.Format(_T("\n ASPECTY = %i"),dc->GetDeviceCaps(ASPECTY)); b0+=b1;
	b1.Format(_T("\n PHYSICALWIDTH = %i"),dc->GetDeviceCaps(PHYSICALWIDTH)); b0+=b1;
	b1.Format(_T("\n PHYSICALHEIGHT = %i"),dc->GetDeviceCaps(PHYSICALHEIGHT)); b0+=b1;
	b1.Format(_T("\n PHYSICALOFFSETX = %i"),dc->GetDeviceCaps(PHYSICALOFFSETX)); b0+=b1;
	b1.Format(_T("\n PHYSICALOFFSETY = %i"),dc->GetDeviceCaps(PHYSICALOFFSETY)); b0+=b1;
	b1.Format(_T("\n SCALINGFACTORX = %i"),dc->GetDeviceCaps(SCALINGFACTORX)); b0+=b1;
	b1.Format(_T("\n SCALINGFACTORY = %i"),dc->GetDeviceCaps(SCALINGFACTORY)); b0+=b1;

	AfxMessageBox(b0);
}