#include "stdafx.h"
#include "apl_gui.h"
#include "resource.h"
#include <afxpriv.h>

// aplMenu2.cpp : implementation file
//

COLORREF CaplUIColors::m_color_bk_no_sel=GetSysColor(COLOR_3DFACE);
COLORREF CaplUIColors::m_color_gradient=GetSysColor(COLOR_3DFACE);
COLORREF CaplUIColors::m_color_bk_popup=aplColor_MixColor(m_color_bk_no_sel,GetSysColor(COLOR_WINDOW),85);

COLORREF CaplUIColors::m_color_bk_sel=aplColor_GetHilightColor(GetSysColor(COLOR_HIGHLIGHT),90);
COLORREF CaplUIColors::m_color_bk_hotlite=aplColor_GetHilightColor(GetSysColor(COLOR_HIGHLIGHT),80);
COLORREF CaplUIColors::m_color_ramka_sel=GetSysColor(COLOR_HIGHLIGHT);
COLORREF CaplUIColors::m_color_text=GetSysColor(COLOR_MENUTEXT);
COLORREF CaplUIColors::m_color_text_sel=GetSysColor(COLOR_MENUTEXT);
COLORREF CaplUIColors::m_color_text_disabled=GetSysColor(COLOR_GRAYTEXT);

int CaplUIColors::GetCurScheme(){return m_cur_scheme;};


int CaplUIColors::m_cur_scheme=3;   

bool CaplUIColors::bUseGrarient=true;  // Использовать ли градиенты 
bool CaplUIColors::bUseBitmap=false;   
CBitmap CaplUIColors::fon_tb;		  // Фон для заливки toolbar
CBitmap CaplUIColors::fon_menu_popup; // Фон для заливки левой части popup меню


void CaplUIColors::SetScheme(int scheme) // 0 - нет темы;  1 - xp; 2 - голубая;
{
	CaplSetResourceHandle setres(module_inst);

	fon_tb.DeleteObject();
	fon_menu_popup.DeleteObject();

	switch(scheme)
	{
	case 0: //Win2000
		m_color_bk_no_sel=GetSysColor(COLOR_MENU);
		m_color_bk_popup=m_color_bk_no_sel;
		m_color_bk_sel=GetSysColor(COLOR_HIGHLIGHT);
		m_color_bk_hotlite=GetSysColor(COLOR_HIGHLIGHT);
		m_color_ramka_sel=m_color_bk_sel;
		m_color_text=GetSysColor(COLOR_MENUTEXT);
		m_color_text_sel=GetSysColor(COLOR_HIGHLIGHTTEXT);
		m_color_text_disabled=GetSysColor(COLOR_GRAYTEXT);
		fon_tb.LoadBitmap(IDB_TB_0);
		break;

	case 1: //WinXP
		m_color_bk_no_sel=RGB(226,226,226);//GetSysColor(COLOR_3DFACE);
		m_color_bk_popup=aplColor_MixColor(m_color_bk_no_sel,GetSysColor(COLOR_WINDOW),85);
		m_color_bk_sel=aplColor_GetHilightColor(GetSysColor(COLOR_HIGHLIGHT),90);
		m_color_bk_hotlite=aplColor_GetHilightColor(GetSysColor(COLOR_HIGHLIGHT),80);
		m_color_ramka_sel=GetSysColor(COLOR_HIGHLIGHT);
		m_color_text=GetSysColor(COLOR_MENUTEXT);
		m_color_text_sel=GetSysColor(COLOR_MENUTEXT);
		m_color_text_disabled=GetSysColor(COLOR_GRAYTEXT);

		fon_tb.LoadBitmap(IDB_TB_1);
		fon_menu_popup.LoadBitmap(IDB_PMENU_1);
		break;

	case 2:
		m_color_bk_no_sel=RGB(198,223,255);//RGB(165,195,246);
		m_color_bk_popup=RGB(246,246,246);
		m_color_bk_sel=RGB(216,231,252);
		m_color_bk_hotlite=RGB(255,238,194);
		m_color_ramka_sel=RGB(0,0,128);
		m_color_text=RGB(0,0,0);
		m_color_text_sel=RGB(0,0,0);
		m_color_text_disabled=GetSysColor(COLOR_GRAYTEXT);

		fon_tb.LoadBitmap(IDB_TB_2);
		fon_menu_popup.LoadBitmap(IDB_PMENU_2);
		break;
	case 3:
		m_color_bk_no_sel=aplColor_GetHilightColor(GetSysColor(COLOR_3DFACE),50);
		m_color_gradient=GetSysColor(COLOR_3DFACE);
		m_color_bk_popup=aplColor_MixColor(m_color_bk_no_sel,GetSysColor(COLOR_WINDOW),85);
		m_color_bk_sel=aplColor_GetHilightColor(GetSysColor(COLOR_HIGHLIGHT),90);
		m_color_bk_hotlite=aplColor_GetHilightColor(GetSysColor(COLOR_HIGHLIGHT),80);
		m_color_ramka_sel=GetSysColor(COLOR_HIGHLIGHT);
		m_color_text=GetSysColor(COLOR_MENUTEXT);
		m_color_text_sel=GetSysColor(COLOR_MENUTEXT);
		m_color_text_disabled=GetSysColor(COLOR_GRAYTEXT);

		fon_tb.LoadBitmap(IDB_TB_1);
		fon_menu_popup.LoadBitmap(IDB_PMENU_1);

		break;
	}
	CaplMenu::ResetColors();
}
const TCHAR KeyName[] = _T("Software\\CALS Centre \"Applied Logistic\"");
const TCHAR Val1Name[] = _T("CaplUIColors_mode");
const TCHAR Val2Name[] = _T("CaplUIColors_usegradient");

void CaplUIColors::SaveScheme()
{
	HKEY key;
	if(ERROR_SUCCESS==RegCreateKey(HKEY_CURRENT_USER,KeyName,&key))
	{
		RegSetValueEx(key,Val1Name,0,REG_DWORD,(BYTE *)(&m_cur_scheme),sizeof(DWORD));
		int i=0; if(bUseGrarient) i=1;
		RegSetValueEx(key,Val2Name,0,REG_DWORD,(BYTE *)(&i),sizeof(DWORD));
		RegCloseKey(key);
	}
}

void CaplUIColors::LoadScheme()
{
	HKEY key;
	if(ERROR_SUCCESS==RegOpenKeyEx(HKEY_CURRENT_USER,KeyName,0, KEY_QUERY_VALUE,&key))
	{
		DWORD val=0,type=REG_DWORD,size=sizeof(DWORD);
		if(ERROR_SUCCESS==RegQueryValueEx (key,Val1Name,0,&type,(BYTE *)(&val),&size))
		{
			m_cur_scheme=val;
		}

		if(ERROR_SUCCESS==RegQueryValueEx (key,Val2Name,0,&type,(BYTE *)(&val),&size))
		{
			if(0==val) bUseGrarient=false; else bUseGrarient=true;
		}
		RegCloseKey(key);
	}
}













//******************************************************************
// CaplMenu

CBrush CaplMenu::m_brush_bk;
CBrush CaplMenu::m_brush_bk_popup;
CFont CaplMenu::m_fontMenu;
HMENU CaplMenu::m_last_menu=0;

CSize CaplMenu::m_icon_size=CSize(16,16);

CImageList CaplMenu::m_il;
CImageList CaplMenu::m_il_grayed;
CMap <int,int,int,int> CaplMenu::m_icons_map(64);

/*CaplMenu::CaplMenu()
{
	//m_sub_wnd.menu=this;
}

CaplMenu::~CaplMenu()
{
}*/


// CaplMenu member functions

void  CaplMenu::ResetColors(CWnd *wnd)
{
	if(0!=m_brush_bk.m_hObject) m_brush_bk.DeleteObject();
	m_brush_bk.CreateSolidBrush(CaplUIColors::m_color_bk_no_sel);
	/*if(0!=m_brush_bk_popup.m_hObject)m_brush_bk_popup.DeleteObject();
	if(0!=CaplUIColors::fon_menu_popup.m_hObject)
	{
		CBitmap bmp;
		aplCreateResizedBitmap(bmp,&CaplUIColors::fon_menu_popup,m_icon_size.cx+7,1);
		m_brush_bk_popup.CreatePatternBrush(&bmp);
	}*/
	SetMenuBk(AfxGetMainWnd());
}

void CaplMenu::SetMenuBk(CWnd *mainwnd)
{
	if(0==mainwnd) mainwnd=AfxGetMainWnd();
	if(0==mainwnd) return;
	CMenu *menu=mainwnd->GetMenu();
	if(0==menu) return;
	if(!IsMenu(menu->m_hMenu))return;

	MENUINFO mi;
	mi.cbSize=sizeof(MENUINFO); 
	mi.fMask=MIM_BACKGROUND;
	mi.hbrBack=HBRUSH(m_brush_bk);
	menu->SetMenuInfo(&mi);	

	mainwnd->DrawMenuBar();
}

bool CaplMenu::Install(CWnd *wnd)
{
	if (wnd==0) 
		return false;

	ResetColors(wnd);

	if(0==m_fontMenu.m_hObject)
	{
		LOGFONT m_lf;
		ZeroMemory ((PVOID) &m_lf,sizeof (LOGFONT));
		NONCLIENTMETRICS nm;
		nm.cbSize = sizeof (NONCLIENTMETRICS);
		if(SystemParametersInfo (SPI_GETNONCLIENTMETRICS,nm.cbSize,&nm,0))
		{
			DWORD err= GetLastError();
			m_lf =  nm.lfMenuFont;
			m_fontMenu.DeleteObject();
			m_fontMenu.CreateFontIndirect (&m_lf);
		}
		else 
			m_fontMenu.CreateFont(-11,0,0,0,FW_NORMAL,0,0,0,0,0,0,0,0,_T("Tahoma"));
	}

	CMenu *menu=wnd->GetMenu();
	if(0!=menu)
	{
		if(IsMenu(menu->m_hMenu)) 
			UpdateMenu(menu);
	}
	SubclassWindow(wnd->m_hWnd);

	wnd->DrawMenuBar();
	return true;
}


void CaplMenu::UpdateMenu(CMenu *menu)
{
	if(0==menu) return;

	MENUITEMINFO mii;
	mii.cbSize=sizeof(MENUITEMINFO); 
	mii.fMask=MIIM_FTYPE|MIIM_ID;

	UINT i;
	for(i=0;i<menu->GetMenuItemCount();i++)
	{
		menu->GetMenuItemInfo(i,&mii,TRUE);

		if(mii.fType&MFT_RIGHTJUSTIFY)break;  // Так приходит системное меню для MDI
		
		mii.fType|=MFT_OWNERDRAW;
		menu->SetMenuItemInfo(i,&mii,TRUE);
	}

	// переводим пункты меню
	aplTranslateMenu(menu);

	return;
}

void CaplMenu::AddIcon(int cmd, HICON icon, bool b_NoWarningIfExist)
{
	if(0==icon) return;

	int pos=-1;
	if(0==m_il.m_hImageList)
	{
		m_il.Create(m_icon_size.cx,m_icon_size.cy,ILC_COLORDDB|ILC_MASK,0,64);
		m_il_grayed.Create(m_icon_size.cx,m_icon_size.cy,ILC_COLORDDB|ILC_MASK,0,64);
	}

	// Проверяем размер иконки

	bool bNeedDestroy=false;

	ICONINFO iconinfo = { 0 };
	if(!GetIconInfo(icon, &iconinfo)) return;
	BITMAP bm = {0};
	GetObject(iconinfo.hbmColor, sizeof(bm), &bm);

	if(0==bm.bmWidth || 0==bm.bmHeight) return;

	if(bm.bmWidth!=m_icon_size.cx || bm.bmHeight!=m_icon_size.cy)
	{
		if( ( (10*bm.bmWidth)/bm.bmHeight) != ((10*m_icon_size.cx)/m_icon_size.cy)) // Только если не те пропорции
		{
			HICON icon2=aplResizeIcon(icon, m_icon_size.cx, m_icon_size.cy);
			if(0!=icon2)
			{
				icon=icon2;
				bNeedDestroy=true;
			}
		}
	}

	// Добавляем в списочек

	HICON gicon=aplIconCopyAsSpecificBlend(icon,75,true);

	if(m_icons_map.Lookup(cmd,pos))
	{
		if(!b_NoWarningIfExist)
		{
			#ifdef  _DEBUG
			CString buf; buf.Format( APL_T("Повторная загрузка иконки в CaplMenu\n\nid=%i"),cmd);
			AfxMessageBox(buf);
			#endif
		}
		m_il.Replace(pos,icon);
		m_il_grayed.Replace(pos,gicon);
	}
	else
	{
		pos=m_il.Add(icon);
		m_il_grayed.Add(gicon);
		m_icons_map.SetAt(cmd,pos);
	}
	
	DestroyIcon(gicon);
	if(bNeedDestroy) DestroyIcon(icon);
}

void CaplMenu::RemoveIcon(int cmd)
{
	int pos = -1;
	if (m_icons_map.Lookup(cmd, pos))
	{
		int iBegin = pos;
		int iEnd = m_il.GetImageCount();

		CMap <int,int,int,int> tmpMap;

		POSITION mapIt = m_icons_map.GetStartPosition();
		while (mapIt != NULL)
		{
			int nKey = 0;
			int iCurValue = 0;

			m_icons_map.GetNextAssoc( mapIt, nKey, iCurValue );

			if (iCurValue > iBegin && iCurValue <= iEnd)
			{
				tmpMap.SetAt(nKey, iCurValue - 1);
			}
			else
			{
				tmpMap.SetAt(nKey, iCurValue);
			}
		}

		m_icons_map.RemoveAll();
		
		mapIt = tmpMap.GetStartPosition();
		while (mapIt != NULL)
		{
			int nKey = 0;
			int iCurValue = 0;

			tmpMap.GetNextAssoc( mapIt, nKey, iCurValue );

			m_icons_map.SetAt(nKey, iCurValue);
		}

		m_icons_map.RemoveKey(cmd);

		if (m_il.GetSafeHandle())
		{
			m_il.Remove(pos);
		}

		if (m_il_grayed.GetSafeHandle())
		{
			m_il_grayed.Remove(pos);
		}
	}
}

void CaplMenu::LoadToolBar(UINT tb_id, UINT bmp_id)
{
	CToolBar tb;
	CWnd *wnd=AfxGetMainWnd();
	if(0==wnd) wnd=CWnd::GetDesktopWindow();
	tb.Create(wnd);
	tb.LoadToolBar(tb_id);

	CBitmap bmp;
	CImageList  til,*il=0;


	if(0!=bmp_id)
	{
		if(bmp.LoadBitmap(bmp_id))
		{
			CToolBarCtrl &tbc=tb.GetToolBarCtrl();
			CImageList *tbil=tbc.GetImageList( );
			if(tbil)
			{
				IMAGEINFO ii;
				tbil->GetImageInfo(0,&ii);
				int cx=ii.rcImage.right-ii.rcImage.left;
				int cy=ii.rcImage.bottom-ii.rcImage.top;

				til.Create(cx,cy,ILC_COLOR24|ILC_MASK,0,100);
				til.Add(&bmp,RGB(192,192,192));
				il=&til;
			}
		}
	}
	LoadToolBar(tb,il);
}

void CaplMenu::LoadToolBar(CToolBar &tb, CImageList *il)
{
	CToolBarCtrl &tbc=tb.GetToolBarCtrl();
	CImageList *tbil=tbc.GetImageList( );
	if(0==tbil) return;

	int i,img;
	UINT id,style;
	for(i=0;i<tbc.GetButtonCount();i++)
	{
		tb.GetButtonInfo(i,id,style,img);
		if(id!=0)
		{
			HICON ico;
			if(il==0) ico=tbil->ExtractIcon(img);
			else ico=il->ExtractIcon(img);
			AddIcon(id,ico);
		}
	}
}
 void CaplMenu::DrawPopupMenuBk(CDC &dc, RECT &r1, RECT &r2)
{
	if(CaplUIColors::bUseGrarient)
	{
		if(0!=CaplUIColors::fon_menu_popup.m_hObject && CaplUIColors::bUseBitmap)
		{
			CDC memdc; memdc.CreateCompatibleDC(&dc);
			CBitmap *oldBitmap=memdc.SelectObject(&CaplUIColors::fon_menu_popup);
			BITMAP bmp;
			CaplUIColors::fon_menu_popup.GetBitmap(&bmp);
			dc.SetStretchBltMode(HALFTONE);
			dc.StretchBlt(r1.left,r1.top,r1.right-r1.left,r1.bottom-r1.top,&memdc,0,0, bmp.bmWidth, bmp.bmHeight,SRCCOPY);
			memdc.SelectObject(oldBitmap);
		}
		else
		{
			aplDrawGradient(&dc,&r1,CaplUIColors::m_color_bk_popup,CaplUIColors::m_color_gradient,1);

		}
	}
	else dc.FillSolidRect(&r1,CaplUIColors::m_color_bk_no_sel);

	dc.FillSolidRect(&r2,CaplUIColors::m_color_bk_popup);

	CPen pen(PS_SOLID,0,aplColor_MixColor(CaplUIColors::m_color_gradient,RGB(0,0,0),20));
	CPen *oldpen=dc.SelectObject(&pen);
	dc.MoveTo(r1.right,r1.top);
	dc.LineTo(r1.right,r1.bottom);
	dc.SelectObject(&oldpen);
}


void CaplMenu::DrawItem(CWnd *wnd, int nIDCtl, LPDRAWITEMSTRUCT lpDrawItemStruct)
{
	if(wnd==0) return;
	if(lpDrawItemStruct->CtlType!=ODT_MENU) return;
	RECT r=lpDrawItemStruct->rcItem;

	CMenu menu;
	menu.Attach((HMENU)lpDrawItemStruct->hwndItem);
	//CMenu *menu=wnd->GetMenu();	
	
	//Определяем текст и другие параметры пункта меню
	CString text; 
	TCHAR buf[256];
	UINT i=0,cmd=0;
	MENUITEMINFO mii;
	mii.cbSize=sizeof(MENUITEMINFO); 
	mii.fMask=MIIM_STRING|MIIM_FTYPE|MIIM_ID|MIIM_STATE/*|MIIM_DATA|MIIM_BITMAP|MIIM_CHECKMARKS*/;	
	mii.dwTypeData=buf;
	mii.cch=256;
	mii.dwItemData=0;
	if(!menu.GetMenuItemInfo(lpDrawItemStruct->itemID,&mii,FALSE))return ;
	text=(TCHAR*)mii.dwTypeData;
	UINT fType=mii.fType;
	UINT fState=mii.fState;
	cmd=mii.wID;

	menu.Detach();
	bool bPopup=true;
	CMenu *wndmenu=wnd->GetMenu();
	if(wndmenu!=0)
	{
		if((HMENU)(lpDrawItemStruct->hwndItem)==wndmenu->m_hMenu) 	bPopup=false;
	}

	//if(text=="") text=="aaaaaa";

	CDC dc;
	dc.Attach(lpDrawItemStruct->hDC);
	COLORREF textcolor=CaplUIColors::m_color_text;

	// Рисуем фон
	RECT r1=r,r2=r;
	r1.right=r1.left+m_icon_size.cx+7;
	r2.left=r1.right;

	//if(bPopup) TRACE("\nFILL %i, %i  %s\n",r1.left,r1.right,LPCSTR(text));

	if(fType&MFT_SEPARATOR)
	{
		if(bPopup)
		{
			DrawPopupMenuBk(dc,r1,r2);
			//dc.Draw3dRect(r2.left+1,(r2.bottom+r2.top)/2,r2.right-r2.left-2,2,GetSysColor(COLOR_3DSHADOW)),GetSysColor(COLOR_3DHILIGHT));
			RECT r3; r3.left=r2.left+2; r3.right=r2.right-2; r3.top=(r2.bottom+r2.top)/2-1;  r3.bottom=r3.top+2;
			dc.DrawEdge(&r3,EDGE_ETCHED,BF_TOP);
		}
		else
		{
			int k1=ODS_DISABLED;
			int k2=ODS_GRAYED;
			if(!(lpDrawItemStruct->itemState&ODS_NOACCEL))
			{
				dc.FillSolidRect(&r,CaplUIColors::m_color_bk_no_sel);
				//dc.Draw3dRect((r.right+r.left)/2,r.top+1,2,r.bottom-r.top-2,GetSysColor(COLOR_3DSHADOW),GetSysColor(COLOR_3DHILIGHT));
				RECT r3; r3.left=(r.right+r.left)/2; r3.right=r3.left+2; r3.top=r.top+2;  r3.bottom=r.bottom-2;
				dc.DrawEdge(&r3,EDGE_ETCHED,BF_LEFT);
			}
		}
	}
	else
	{
		// скидываем выделенность для задизейбленных
		if(lpDrawItemStruct->itemState&ODS_DISABLED || lpDrawItemStruct->itemState&ODS_GRAYED)
		{
			lpDrawItemStruct->itemState&=0xffffffff^(ODS_HOTLIGHT|ODS_SELECTED);
		}
		
		if(lpDrawItemStruct->itemState&ODS_HOTLIGHT) // Подсвечен
		{
			textcolor=CaplUIColors::m_color_text_sel;
			if(bPopup)
			{
				//	dc.FillSolidRect(&r,CaplUIColors::m_color_bk_hotlite);
				//	dc.Draw3dRect(&r, CaplUIColors::m_color_ramka_sel,CaplUIColors::m_color_ramka_sel);
			}
			else 
			{
				if(CaplUIColors::m_color_ramka_sel==CaplUIColors::m_color_bk_hotlite)//обычное меню
				{
					dc.Draw3dRect(&r,GetSysColor(COLOR_3DHILIGHT), GetSysColor(COLOR_3DSHADOW));
					textcolor=CaplUIColors::m_color_text;
				}
				else
				{
					RECT r3=r; r3.top++;
					dc.FillSolidRect(&r3,CaplUIColors::m_color_bk_hotlite);
					dc.Draw3dRect(&r3, CaplUIColors::m_color_ramka_sel,CaplUIColors::m_color_ramka_sel);
					//COLORREF c1=aplColor_MixColor(CaplUIColors::m_color_ramka_sel,GetSysColor(COLOR_3DHILIGHT),50);
					//COLORREF c2=aplColor_MixColor(CaplUIColors::m_color_ramka_sel,GetSysColor(COLOR_3DSHADOW),50);
					//c1=RGB(255,255,255);
					//c2=RGB(0,0,0);
					//dc.Draw3dRect(&r, c1,c2);
					//dc.Draw3dRect(&r,GetSysColor(COLOR_3DHILIGHT), GetSysColor(COLOR_3DSHADOW));
				}
			}
		}
		else if(lpDrawItemStruct->itemState&ODS_SELECTED) // выделено
		{
			textcolor=CaplUIColors::m_color_text_sel;
			if(bPopup)
			{
				dc.FillSolidRect(&r,CaplUIColors::m_color_bk_hotlite);
				dc.Draw3dRect(&r, CaplUIColors::m_color_ramka_sel,CaplUIColors::m_color_ramka_sel);
			}
			else 
			{
				if(CaplUIColors::m_color_ramka_sel==CaplUIColors::m_color_bk_hotlite)//обычное меню
				{
					dc.Draw3dRect(&r, GetSysColor(COLOR_3DSHADOW),GetSysColor(COLOR_3DHILIGHT));
					textcolor=CaplUIColors::m_color_text;
				}
				else
				{
					dc.FillSolidRect(&r,CaplUIColors::m_color_bk_sel);
					//dc.Draw3dRect(&r, CaplUIColors::m_color_ramka_sel,CaplUIColors::m_color_ramka_sel);
					CPen m_penBack;
					m_penBack.CreatePen (PS_SOLID,0,CaplUIColors::m_color_ramka_sel);
					CPen *pOldPen = dc.SelectObject (&m_penBack);
					dc.MoveTo(r.left,r.bottom-1);
					dc.LineTo(r.left,r.top+1);
					dc.LineTo(r.right-1,r.top+1);
					dc.LineTo(r.right-1,r.bottom-1);
					dc.SelectObject(&m_penBack);
				}
			}
		}
		else //обычный фон
		{
			if(bPopup)
			{
				DrawPopupMenuBk(dc,r1,r2);
			}
			else
			{
				dc.FillSolidRect(&r,CaplUIColors::m_color_bk_no_sel);
			}
		}


		// рисуем галочку
		if ( (lpDrawItemStruct->itemState & ODS_CHECKED || mii.fState & MFS_CHECKED) )
		{
			if ( bPopup )
			{
				RECT r3;
				r3.left=(r1.right+r1.left-m_icon_size.cx)/2;
				r3.top=(r1.top+r1.bottom-m_icon_size.cy)/2;
				r3.right=r3.left+m_icon_size.cx;
				r3.bottom=r3.top+m_icon_size.cy;
				if(!(CaplUIColors::m_color_ramka_sel==CaplUIColors::m_color_bk_hotlite))//обычное меню
				{
					COLORREF c1=aplColor_MixColor(CaplUIColors::m_color_bk_hotlite,RGB(255,255,255),25);
					//COLORREF c2=aplColor_MixColor(CaplUIColors::m_color_bk_hotlite,textcolor,50);;
					COLORREF c2=CaplUIColors::m_color_ramka_sel;
					dc.FillSolidRect(&r3,c1);
					dc.Draw3dRect(&r3,c2,c2);
				}

				CPen m_penBack;
				m_penBack.CreatePen (PS_SOLID,0,textcolor);
				CPen *pOldPen = dc.SelectObject (&m_penBack);

				int dp=6;
				int x=(r3.left+r3.right-6)/2;
				int y=(r3.top+r3.bottom-2)/2;

				dc.MoveTo(x,y+2);
				dc.LineTo(x,y+5-dp);

				dc.MoveTo(x+1,y+3);
				dc.LineTo(x+1,y+6-dp);

				dc.MoveTo(x+2,y+4);
				dc.LineTo(x+2,y+7-dp);

				dc.MoveTo(x+3,y+3);
				dc.LineTo(x+3,y+6-dp);

				dc.MoveTo(x+4,y+2);
				dc.LineTo(x+4,y+5-dp);

				dc.MoveTo(x+5,y+1);
				dc.LineTo(x+5,y+4-dp);

				dc.MoveTo(x+6,y);
				dc.LineTo(x+6,y+3-dp);

				dc.SelectObject (pOldPen);
				m_penBack.DeleteObject();
			}
		}
		else
		{
			// рисуем иконку
			int pos = -1;
			if (m_icons_map.Lookup(cmd, pos))
			{
				POINT p;
				p.x=r.left+3;
				p.y=r.top+((r.bottom-r.top-m_icon_size.cy)/2);
				if(lpDrawItemStruct->itemState&ODS_DISABLED || lpDrawItemStruct->itemState&ODS_GRAYED)
					m_il_grayed.Draw(&dc,pos,p,ILD_TRANSPARENT|ILD_NORMAL);
				else m_il.Draw(&dc,pos,p,ILD_TRANSPARENT|ILD_NORMAL);
			}
		}

		// Рисуем текст
		if (lpDrawItemStruct->itemState&ODS_DISABLED || lpDrawItemStruct->itemState&ODS_GRAYED)
		{
			textcolor=CaplUIColors::m_color_text_disabled;
		}
		
		//COLORREF olb_bk_color=dc.SetBkColor(bkcolor);
		COLORREF old_text_color=dc.SetTextColor(textcolor);

		int f_Text_prefix=DT_HIDEPREFIX;
		if(lpDrawItemStruct->itemState<2) f_Text_prefix=0; // надо подчеркивание

		RECT r_text;
		if(bPopup)
		{
			r_text=r2;
			r_text.left+=7;
			r_text.right-=7;
		}
		else
		{
			r_text=r;
			r_text.left+=5;
		}
		CFont *oldFont=dc.SelectObject(&m_fontMenu);
		int oldbkmode=dc.SetBkMode(TRANSPARENT );

		int postab=text.Find(_T('\t'));
		if(postab<0) dc.DrawText(text,&r_text,DT_VCENTER|DT_SINGLELINE|f_Text_prefix);
		else
		{
			CString text1=text.Left(postab-i);
			dc.DrawText(text1,&r_text,DT_VCENTER|DT_SINGLELINE|f_Text_prefix|DT_LEFT);
			text1=LPCTSTR(text)+1+postab;
			dc.DrawText(text1,&r_text,DT_VCENTER|DT_SINGLELINE|f_Text_prefix|DT_RIGHT);
		}
		dc.SetBkMode(oldbkmode );
		dc.SelectObject(oldFont);
		//dc.SetBkColor(olb_bk_color);
		dc.SetTextColor(old_text_color);
	}

	//dc.FillSolidRect(&r,RGB(255,0,0));
	dc.Detach();
}


void CaplMenu::MeasureItem(CWnd *wnd, int nIDCtl, LPMEASUREITEMSTRUCT lpMeasureItemStruct)
{
	if(wnd==0) return;
	if(lpMeasureItemStruct->CtlType!=ODT_MENU) return;

	//Определяем текст
	MENUITEMINFO mii;
	mii.cbSize=sizeof(MENUITEMINFO); 
	mii.fMask=MIIM_STRING|MIIM_FTYPE;	

	UINT ftype=0;
	
	CString text; 
	TCHAR buf[256];   
	ZeroMemory(buf,256);
	bool b_found=0;
	bool b_popup=false;

	if(m_last_menu)
	{
		if(IsMenu(m_last_menu))
		{
			CMenu menu1;
			menu1.Attach(m_last_menu);
			mii.dwTypeData=buf;
			mii.cch=256;
			if(menu1.GetMenuItemInfo(lpMeasureItemStruct->itemID,&mii,FALSE))
			{
				ftype=mii.fType;
				((TCHAR*)(mii.dwTypeData))[mii.cch]=_T('\0');
				text=buf;
				b_found=true;
				b_popup=true;
			}
			menu1.Detach();
		}
	}
	
	if(!b_found)
	{
		mii.dwTypeData=buf;
		mii.cch=256;
		CMenu *menu=wnd->GetMenu();
		if (menu)
		{
			if(menu->GetMenuItemInfo(lpMeasureItemStruct->itemID,&mii,FALSE))
			{
				text=buf;
				ftype=mii.fType;
			}
		}
	}

	lpMeasureItemStruct->itemHeight=25;
	if(ftype&MFT_SEPARATOR)
	{
		lpMeasureItemStruct->itemWidth=6;
		lpMeasureItemStruct->itemHeight=6;
		return;
	}

	lpMeasureItemStruct->itemHeight=m_icon_size.cy+6;

	if(text==_T("")) /*text="aaaaaaaaaaaaaaaaaaaaaaaaaaaaa\n";//-*/lpMeasureItemStruct->itemWidth=0;
	else
	{
		//TRACE("\n!!!! MEASUREITEM %i  %s\n",lpMeasureItemStruct->itemID, LPCSTR(text));
		/*int font_heigh=GetSystemMetrics(SM_CYMENU);
		if(font_heigh<0) font_heigh=12;
		font_heigh-=4;*/

		CDC *dc=wnd->GetDC();
		CFont *oldFont=dc->SelectObject(&m_fontMenu);
		RECT r;  r.left=0; r.right=1000; r.top=0;  r.bottom=1000;
		dc->DrawText(text,&r,DT_VCENTER|DT_SINGLELINE|DT_CALCRECT);
		lpMeasureItemStruct->itemWidth=r.right;
		dc->SelectObject(oldFont);

		if(0<text.Find(_T('\t')))lpMeasureItemStruct->itemWidth+=10;
	}

	if(b_popup)
	{
		lpMeasureItemStruct->itemWidth+=m_icon_size.cx+20;
	}

}


LRESULT CALLBACK CaplMenu::MyWndProc(HWND hWnd, UINT nMsg, WPARAM wParam, LPARAM lParam)
{
	// special message which identifies the window as using AfxWndProc
	if (nMsg == WM_QUERYAFXWNDPROC)
		return 1;

	// all other messages route through message map
	CWnd* pWnd = CWnd::FromHandlePermanent(hWnd);

	ASSERT(pWnd != NULL);
	ASSERT(pWnd->m_hWnd == hWnd);

	//LRESULT lRetDef = AfxCallWndProc(pWnd, hWnd, nMsg, wParam, lParam);
	LRESULT lRetDef=0;

	if(nMsg== WM_DRAWITEM )
	{
		lRetDef = AfxCallWndProc(pWnd, hWnd, nMsg, wParam, lParam);
		LPDRAWITEMSTRUCT lpDrawItemStruct=( LPDRAWITEMSTRUCT)(lParam);
		if (lpDrawItemStruct->CtlType == ODT_MENU)
		{
			BOOL setflag = TRUE;
			CaplMenu::DrawItem(pWnd, 0, lpDrawItemStruct);
			lRetDef = 0;
			return lRetDef;
		}
		//else lRetDef = AfxCallWndProc(pWnd, hWnd, nMsg, wParam, lParam);
	}
	else if(nMsg== WM_MEASUREITEM)
	{
		LPMEASUREITEMSTRUCT lpMeasureItemStruct = ( LPMEASUREITEMSTRUCT)(lParam);
		if (lpMeasureItemStruct->CtlType == ODT_MENU)
		{
			CaplMenu::MeasureItem(pWnd,0,lpMeasureItemStruct);
			lRetDef = 0;
		}
		else lRetDef = AfxCallWndProc(pWnd, hWnd, nMsg, wParam, lParam);
	}
	else if(nMsg== WM_INITMENUPOPUP)
	{
		lRetDef = AfxCallWndProc(pWnd, hWnd, nMsg, wParam, lParam);
		HMENU pSysMenu = ::GetSystemMenu(hWnd, FALSE);
		if(pSysMenu!=(HMENU)wParam)
		{
			CMenu* pPopupMenu = CMenu::FromHandle((HMENU)wParam);
			CaplMenu::UpdateMenu(pPopupMenu);
			CaplMenu::m_last_menu=(HMENU)wParam;
			lRetDef=0;
		}
		//else lRetDef = AfxCallWndProc(pWnd, hWnd, nMsg, wParam, lParam);
	}
	else if(nMsg== WM_MENUCHAR)
	{
		lRetDef = AfxCallWndProc(pWnd, hWnd, nMsg, wParam, lParam);
		
		/*LRESULT lresult;
		if(m_menu.IsMenu(pMenu))
		lresult=CaplMenu::FindKeyboardShortcut(nChar, nFlags, pMenu);
		else
		lresult=CFrameWnd::OnMenuChar(nChar, nFlags, pMenu);
		return(lresult);*/
		
		/*
		UINT nChar=(UINT)LOWORD(wParam);
		UINT nFlags=(UINT)HIWORD(wParam);
		CMenu* pMenu=(CMenu*)CMenu::FromHandle((HMENU)lParam);
		return CaplMenu::FindKeyboardShortcut(nChar, nFlags, pMenu);
		*/

		//lRetDef = AfxCallWndProc(pWnd, hWnd, nMsg, wParam, lParam);

		/*return CaplMenu::FindKeyboardShortcut(
			(UINT)LOWORD(wParam),
			(UINT)HIWORD(wParam),
			(CMenu*)CMenu::FromHandle((HMENU)lParam));*/
	}
	else lRetDef = AfxCallWndProc(pWnd, hWnd, nMsg, wParam, lParam);

	return lRetDef;
}

BOOL CaplMenu::SubclassWindow(HWND hWnd)
{
	if(0==hWnd) return FALSE;

	CWnd* pWnd=NULL;
	CWnd* pNewWnd=NULL;

	WNDPROC OldWndProc=NULL;

	pWnd=CWnd::FromHandlePermanent(hWnd);
	if(NULL==pWnd)
	{
		pNewWnd=new CWnd;
		ASSERT(pNewWnd);
		VERIFY(pNewWnd->SubclassWindow(hWnd));

		pWnd=CWnd::FromHandlePermanent(hWnd);
		ASSERT(pWnd);
	}

	OldWndProc=(WNDPROC)::GetWindowLong(hWnd,GWL_WNDPROC);
	if(OldWndProc==MyWndProc) return TRUE;

	OldWndProc=(WNDPROC)::SetWindowLong(hWnd,GWL_WNDPROC,(DWORD)MyWndProc);

	ASSERT(OldWndProc==AfxGetAfxWndProc());
	ASSERT(OldWndProc!=MyWndProc);

	return TRUE;
}
