//////////////////////////////////////////////////////////////////////
//
// Разработчик: Алексей Фёдоров aka АЛьФ, mailto: alf@dorex.ru
//
//////////////////////////////////////////////////////////////////////
//
// FormExMenu.cpp: implementation of the CFormExMenu class.
//
//////////////////////////////////////////////////////////////////////

#include "stdafx.h"
#include "addin.h"
#include "FormExMenu.h"

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

extern CBkEndUI * pBkEndUI;
extern HINSTANCE hDllInstance;
static LONG hMeasureItemWndProc = 0;
static HFONT hFontG = NULL;

LRESULT CALLBACK MeasureItemWndProc(HWND hWnd, UINT nMessage, WPARAM wParam, LPARAM lParam)
{
	if(nMessage == WM_MEASUREITEM)
	{
		CWnd* pParent = CWnd::FromHandle(hWnd);
		CClientDC dc(pParent);
		HFONT hFont = (HFONT)::SelectObject(dc.GetSafeHdc(), hFontG);

		if (hFont != 0) {
			LPMEASUREITEMSTRUCT lpMeasureItemStruct = (LPMEASUREITEMSTRUCT) lParam;


			lpMeasureItemStruct->itemWidth	= 25 + dc.GetTextExtent((LPCSTR)lpMeasureItemStruct->itemData).cx;

			lpMeasureItemStruct->itemHeight = dc.GetTextExtent((LPCSTR)lpMeasureItemStruct->itemData).cy;
			lpMeasureItemStruct->itemHeight += 6;

			if (lpMeasureItemStruct->itemHeight < 3)
				lpMeasureItemStruct->itemHeight = 3;

			// Делаем поправку на сепаратор
			if(lpMeasureItemStruct->itemID == 0)
				lpMeasureItemStruct->itemHeight = 6 + 1;

			::SelectObject(dc.GetSafeHdc(), hFont);
		}
	}
	
	return ((WNDPROC)hMeasureItemWndProc)(hWnd, nMessage, wParam, lParam);
}

//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////
IMPLEMENT_DYNCREATE(CFormExMenu,CMenu);

CFormExMenu::CFormExMenu(HFONT hFont):CMenu()
{
	m_hFont = hFont;
	m_pParent = NULL;
}

CFormExMenu::CFormExMenu():CMenu()
{
	// Загружаем значёк checked
	m_hFont = NULL;
	m_pParent = NULL;
}

CFormExMenu::~CFormExMenu()
{
	while(m_pSubMenu.GetSize())
	{
		CFormExMenu* pSubMenu = (CFormExMenu*)m_pSubMenu.GetAt(0);
		delete pSubMenu;
		m_pSubMenu.RemoveAt(0);
	}
	if((m_pParent != NULL) && (hMeasureItemWndProc != 0))
	{
		::SetWindowLong(m_pParent->GetSafeHwnd(),GWL_WNDPROC,hMeasureItemWndProc);
		hMeasureItemWndProc = NULL;
	}
}

void CFormExMenu::Init()
{
	
	if(m_pParent)
	{
		if(hMeasureItemWndProc == 0) hMeasureItemWndProc = ::GetWindowLong(m_pParent->GetSafeHwnd(),GWL_WNDPROC);
		::SetWindowLong(m_pParent->GetSafeHwnd(),GWL_WNDPROC,(LONG)MeasureItemWndProc);
		hFontG = m_hFont;
	}
}


BOOL CFormExMenu::AppendMenu(UINT nFlags, CFormExMenu* pSubMenu /*= NULL*/, LPCTSTR lpszNewItem /*= NULL*/)
{
	HMENU hMenu = NULL;
	if(pSubMenu)
	{
		m_pSubMenu.Add(pSubMenu);
		hMenu = pSubMenu->GetSafeHmenu();
	}
	return /*CMenu::*/::AppendMenu(m_hMenu, nFlags, (UINT)hMenu, lpszNewItem);
}

void CFormExMenu::DrawItem(LPDRAWITEMSTRUCT lpDrawItemStruct)
{
	CString str = (LPCSTR)lpDrawItemStruct->itemData;

    CRect RFull(lpDrawItemStruct->rcItem); // Ограничивающий пункт прямоугольник
	// Зона значка
	CRect RIcon(RFull.left,RFull.top,RFull.left+20,RFull.top+20);
	// зона текста
	CRect RText(RIcon.right,RFull.top,RFull.right,RFull.bottom);

	// получаем контекст, на котором будем рисовать
	CDC* pDC = CDC::FromHandle(lpDrawItemStruct->hDC);
	CFont* pOldFont = NULL;
	if(m_hFont)
	{
		CFont* pFont = CFont::FromHandle(m_hFont);
		pOldFont = pDC->SelectObject(pFont);
	}

	pDC->FillSolidRect(&RFull, pDC->GetBkColor()); // фон

	if(lpDrawItemStruct->itemID == 0) // если этот пункт - это Separator
	{
		CPen pen;
		pen.CreatePen(PS_SOLID, 1, GetSysColor(COLOR_GRAYTEXT));
		CPen* pOldPen = pDC->SelectObject(&pen);

		// рисуем сепаратор
		pDC->MoveTo(RFull.left+5,  RFull.top+(RFull.bottom-RFull.top)/2);
		pDC->LineTo(RFull.right, RFull.top+(RFull.bottom-RFull.top)/2);

		pDC->SelectObject(pOldPen);
		DeleteObject(pen);
	}

	else if ((lpDrawItemStruct->itemState & ODS_SELECTED) &&
			 (lpDrawItemStruct->itemAction & (ODA_SELECT | ODA_DRAWENTIRE)) )
	{
		// Если пункт выделен - то рисуем выделение
		if (!(lpDrawItemStruct->itemState & ODS_GRAYED)) // проверка доступен ли пункт
		{
			pDC->FillSolidRect(&RFull, COLORREF(RGB(182, 189, 210))); // фон
			CBrush* br = new CBrush;
			br->CreateSolidBrush(COLORREF(RGB(10, 36, 106)));
			pDC->FrameRect(&RFull, br); // рамка
			delete br;
		};
	};

	if(lpDrawItemStruct->itemState & ODS_CHECKED) // если пункт в состоянии checked
	{
		HBITMAP		hBmp;
		CBitmap*	pBmp;
		BITMAP		bmp;
		CSize		szBmp;
		CPoint		ptBmp;
		ZeroMemory(&bmp, sizeof(BITMAP));
		
		// Загружаем значёк checked
		hBmp = ::LoadBitmap(NULL, MAKEINTRESOURCE(32760));
		pBmp = CBitmap::FromHandle(hBmp);
		pBmp->GetBitmap(&bmp);
		szBmp = pBmp->GetBitmapDimension();
		//szBmp = CSize(bmp.bmWidth, bmp.bmHeight);
		ptBmp = CPoint(RIcon.left+1, 
						RIcon.top+1);
		// рисуем состояние
		pDC->DrawState(ptBmp, szBmp, hBmp, DSS_NORMAL|DSS_UNION);
		DeleteObject(hBmp);
	};

	// Устанавливаем цвет фона и границу надписи
	//pDC->SetBkColor(TextColor);
	RText.left += 5;
	RText.top += 3;
	RText.bottom -= 3;

	// если пункт недоступен - устанавливаем соответствующий цвет текста
	if (lpDrawItemStruct->itemState & ODS_GRAYED)
		pDC->SetTextColor(GetSysColor(COLOR_GRAYTEXT));
	// Рисуем текст пункта
		pDC->DrawText(str, &RText, DT_EXPANDTABS|DT_LEFT|DT_VCENTER|
					  DT_EDITCONTROL );
	if(pOldFont)
	{
		pOldFont = pDC->SelectObject(pOldFont);
	}
}

void CFormExMenu::MeasureItem(LPMEASUREITEMSTRUCT lpMeasureItemStruct)
{
	if(m_pParent)
	{
		CClientDC dc(m_pParent);
		HFONT hFont = (HFONT)::SelectObject(dc.GetSafeHdc(), m_hFont);

		if (hFont != 0) {

			lpMeasureItemStruct->itemWidth	= 25 + dc.GetTextExtent((LPCSTR)lpMeasureItemStruct->itemData).cx;

			lpMeasureItemStruct->itemHeight = dc.GetTextExtent((LPCSTR)lpMeasureItemStruct->itemData).cy;
			lpMeasureItemStruct->itemHeight += 6;

			if (lpMeasureItemStruct->itemHeight < 3)
				lpMeasureItemStruct->itemHeight = 3;

			// Делаем поправку на сепаратор
			if(lpMeasureItemStruct->itemID == 0)
				lpMeasureItemStruct->itemHeight = 6 + 1;

			::SelectObject(dc.GetSafeHdc(), hFont);
		}
	}
}
