Exemplo n.º 1
0
void CaImMenu::MeasureItem (LPMEASUREITEMSTRUCT lpMeasureItemStruct) {
	MENUITEMINFO iInfo;
	GetMenuItemInfo (lpMeasureItemStruct->CtlID, &iInfo);
	CaImMenuItem* pItem = (CaImMenuItem*)lpMeasureItemStruct->itemData;

	CFont fntDef;
	LOGFONT lfDef;
	CClientDC dc (0);
	CFont* pFont = (CFont *)dc.SelectStockObject (ANSI_VAR_FONT);
	if (pItem->CheckStyle (AMIS_DEFAULT)) {
		CFont* pFnt = dc.GetCurrentFont ();
		pFnt->GetLogFont (&lfDef);
		lfDef.lfWeight = FW_BOLD;
		fntDef.CreateFontIndirect (&lfDef);
		dc.SelectObject (&fntDef);
	}

	if (pItem->CheckStyle (AMIS_BAR))
		lpMeasureItemStruct->itemHeight = 4;
	else
		lpMeasureItemStruct->itemHeight = m_dwHeight;
	lpMeasureItemStruct->itemWidth = 25 + 8 + 8 + 2 + dc.GetTextExtent (pItem->GetText ()).cx;

	dc.SelectObject (pFont);
	if (pItem->CheckStyle (AMIS_DEFAULT))
		fntDef.DeleteObject ();
}
Exemplo n.º 2
0
// determine size of a given cell based on actual font settings 
CSize CMiniCalendarCtrl::ComputeSize()
{
	const int iXDaysSpaceFromBorder = 15;
	const int iHeaderSpaceForBorder = 15;
	const int iHeaderYSpaceForBorder = 3;
	const int iDaysXSpacing = 5;
	const int iDaysYSpacing = 2;

	CSize szReturn(0, 0);
	int iWidthByDays = 0;
	int iWidthByDaysOfWeekIndividual = 0;
	int iWidthByHeader = 0;
	int iHeaderHeight = 0;
	int iDaysHeight = 0;
	int iX;

	// allocate a DC to use when testing sizes, etc
	CClientDC* pDC = NULL;
	if (::IsWindow(GetSafeHwnd())) 
		pDC = new CClientDC(this);
	else
		pDC = new CClientDC(AfxGetMainWnd());
	ASSERT(pDC);

	if (!pDC)
		throw (new CMemoryException());

	// get current font and save for later restoration
	CFont* pOldFont = pDC->GetCurrentFont();

	// first, use days to determine width
	// NOTE: typically, most fonts use the same pixel sizes for all numbers,
	// but this is not mandatory and many "fancy" fonts change this.  To deal
	// with this, I am calculating the width of all possible dates the control will display
	pDC->SelectObject(m_pFont);
	for (iX = 1; iX <= 31; iX++)
	{
		CString strTemp = "00";
		strTemp += CCalendarUtils::LongToString(iX);
		strTemp = strTemp.Right(2);

		CSize szTemp = pDC->GetTextExtent(strTemp);
		if (szTemp.cx > iWidthByDays)
			iWidthByDays = szTemp.cx;
		if (szTemp.cy > iDaysHeight)
			iDaysHeight = szTemp.cy;
	}

	// make sure we also try it with the special days font
	pDC->SelectObject(m_pFontBold);
	for (iX = 1; iX <= 31; iX++)
	{
		CString strTemp = "00";
		strTemp += CCalendarUtils::LongToString(iX);
		strTemp = strTemp.Right(2);

		CSize szTemp = pDC->GetTextExtent(strTemp);
		if (szTemp.cx > iWidthByDays)
			iWidthByDays = szTemp.cx;
		if (szTemp.cy > iDaysHeight)
			iDaysHeight = szTemp.cy;
	}

	// finish computation
	m_iDaysHeight = iDaysHeight;
	m_iIndividualDayWidth = iWidthByDays;

	iWidthByDays = (iWidthByDays * 7) + (iDaysXSpacing*6) + (iXDaysSpaceFromBorder*2);	
	iDaysHeight = (iDaysHeight * 6) + (iDaysYSpacing*6);

	// next use days of week to determine width and height. here again, we test each variant 
	pDC->SelectObject(m_pFont);

	int iWidthByDaysOfWeek = pDC->GetTextExtent("S").cx;
	if (pDC->GetTextExtent("M").cx > iWidthByDaysOfWeek)
		iWidthByDaysOfWeek = pDC->GetTextExtent("M").cx;
	if (pDC->GetTextExtent("T").cx > iWidthByDaysOfWeek)
		iWidthByDaysOfWeek = pDC->GetTextExtent("T").cx;
	if (pDC->GetTextExtent("W").cx > iWidthByDaysOfWeek)
		iWidthByDaysOfWeek = pDC->GetTextExtent("W").cx;
	if (pDC->GetTextExtent("F").cx > iWidthByDaysOfWeek)
		iWidthByDaysOfWeek = pDC->GetTextExtent("F").cx;

	int iDaysOfWeekHeight = pDC->GetTextExtent("S").cy;
	if (pDC->GetTextExtent("M").cy > iDaysOfWeekHeight)
		iDaysOfWeekHeight = pDC->GetTextExtent("M").cy;
	if (pDC->GetTextExtent("T").cy > iDaysOfWeekHeight)
		iDaysOfWeekHeight = pDC->GetTextExtent("T").cy;
	if (pDC->GetTextExtent("W").cy > iDaysOfWeekHeight)
		iDaysOfWeekHeight = pDC->GetTextExtent("W").cy;
	if (pDC->GetTextExtent("F").cy > iDaysOfWeekHeight)
		iDaysOfWeekHeight = pDC->GetTextExtent("F").cy;

	// finish computation
	iWidthByDaysOfWeekIndividual = iWidthByDaysOfWeek;
	iWidthByDaysOfWeek = (iWidthByDaysOfWeek * 7) + (iDaysXSpacing*6) + (iXDaysSpaceFromBorder*2);

	if (iWidthByDaysOfWeekIndividual > m_iIndividualDayWidth)
		m_iIndividualDayWidth = iWidthByDaysOfWeekIndividual;

	m_iDaysOfWeekHeight = iDaysOfWeekHeight;

	// next compute width and height of header (month name and year)
	// again, because of font variations we will use a 20 year window and
	// attempt the calculation with every month name
	pDC->SelectObject(m_pFontBold);
	for (int iYear = m_iCurrentYear-10; iYear <= m_iCurrentYear+10; iYear++)
	{
		for (int iMonth = 1; iMonth <= 12; iMonth++)
		{
			CString strTest = GetMonthName(iMonth);
			strTest += " ";
			strTest += CCalendarUtils::LongToString(iYear);

			if (pDC->GetTextExtent(strTest).cx > iWidthByHeader)
				iWidthByHeader = pDC->GetTextExtent(strTest).cx;
			if (pDC->GetTextExtent(strTest).cy > iHeaderHeight)
				iHeaderHeight = pDC->GetTextExtent(strTest).cy;
		}
	}

	// finish computation
	iWidthByHeader += (iHeaderSpaceForBorder*2);
	iHeaderHeight += (iHeaderYSpaceForBorder*2);
	m_iHeaderHeight = iHeaderHeight;

	// cleanup DC
	pDC->SelectObject(pOldFont);

	// destroy DC
	delete pDC;

	// NOW, adjust return size if needed
	// start with widths (these are easy at this point)
	int iTotalWidth = iWidthByHeader;
	if (iWidthByDaysOfWeek > iTotalWidth)
		iTotalWidth = iWidthByDaysOfWeek;
	if (iWidthByDays > iTotalWidth)
		iTotalWidth = iWidthByDays;
	if (iTotalWidth > szReturn.cx)
		szReturn.cx = iTotalWidth;

	// adjust heights
	int iTotalHeight = iHeaderHeight + iDaysOfWeekHeight + iDaysHeight + 12;
	if (iTotalHeight > szReturn.cy)
		szReturn.cy = iTotalHeight;

	m_szMonthSize = szReturn;
	m_bSizeComputed = TRUE;

	return szReturn;
}