Click here to Skip to main content
15,881,172 members
Articles / Desktop Programming / MFC
Tip/Trick

Select Font

Rate me:
Please Sign up or sign in to vote.
5.00/5 (2 votes)
28 Jan 2019CPOL2 min read 5K   144   1  
Selected Font name, Point Size and Weight are displayed

Image 1

Introduction

This is a program to view system fonts of different names, sizes and weights.

Background

This program will allow the user to see what different fonts and sizes will look like on different background colors.

To view large fonts, the user can select maximize button. Right click the center of the screen and select the background color for the "Static Control". Click Select Font and pick a font to display.

Using the Code

Some items that need to be preset in "OnInitDialog".

C++
BOOL CFontSelectDlg::OnInitDialog()
{
	CDialogEx::OnInitDialog();
    ...
    ...
    ...
	// TODO: Add extra initialization here
	bContinue = FALSE;
	m_hbrush = CreateSolidBrush(RGB(220, 220, 220));
	rgbColor = RGB(0, 0, 0);
	m_rgbColor = (RGB(220, 220, 220));
	SetTimer(1, 500, NULL);

The code for the "Select Font Button".

"rgbCurrent" is set to black and is passed when you call "ChooseFont" MFC library common Dialog.

If the call to the Dialog is successful, it returns TRUE and you can get the returned values.

C++
void CFontSelectDlg::OnBnClickedSelectFont()
{
	// TODO: Add your control notification handler code here
	BOOL bRet;
	CHOOSEFONT cf;
	static LOGFONT lf;        // logical font structure
	static COLORREF rgbCurrent;  // current text color
	rgbCurrent = RGB(0, 0, 0);
	rgbColor = rgbCurrent;
	int nPointSize;
	// Initialize CHOOSEFONT
	ZeroMemory(&cf, sizeof(cf));
	cf.lStructSize = sizeof (cf);
	cf.hwndOwner = NULL;
	cf.lpLogFont = &lf;
    // default color
	cf.rgbColors = rgbCurrent;
    // show screen fonts only and allow selection of colors, underline and strikeout.
	cf.Flags = CF_SCREENFONTS | CF_EFFECTS;
	bRet = ChooseFont(&cf);

	if(bRet)
	{
		rgbColor = cf.rgbColors;
		m_font.CreateFontIndirect(&lf);
		m_static1.SetFont(&m_font, TRUE);
		nPointSize = cf.iPointSize;
		CString szDisplay;
		CString szFont;
		CString szPointSize;
		CString szWeight;
        // "\r\n" tells the output to go to the next line.
		szFont.Format(_T("\r\n%s\r\n"), lf.lfFaceName);
		szPointSize.Format(_T("Point Size: %ld\r\n"), nPointSize);
		szWeight.Format(_T("Weight: %ld\r\n"), lf.lfWeight);
		szDisplay = szFont;
		szDisplay += szPointSize;
		szDisplay += szWeight;
		m_static1.SetWindowTextA(szDisplay);
	}
}

The code for "OnCtrlColor". This function sets the text and background color when the program displays the string in the output window.

C++
HBRUSH CFontSelectDlg::OnCtlColor(CDC* pDC, CWnd* pWnd, UINT nCtlColor)
{
	HBRUSH hbr = CDialogEx::OnCtlColor(pDC, pWnd, nCtlColor);
	HBRUSH hbrush;                  // brush handle
	hbrush = m_hbrush;
	// TODO:  Change any attributes of the DC here
	if(nCtlColor == CTLCOLOR_STATIC)
	{
		pDC->SetTextColor(rgbColor);
		pDC->SetBkColor(m_rgbColor);
		hbrush = m_hbrush;
	}

	// TODO:  Return a different brush if the default is not desired
	return hbrush;
}

The code for "OnSize". This code changes the size of the main window to display a larger font.

C++
void CFontSelectDlg::OnSize(UINT nType, int cx, int cy)
{
	CDialogEx::OnSize(nType, cx, cy);

	// TODO: Add your message handler code here
	theApp.ProcessIdleMsg();
	CWnd *pWnd;
	HWND hDlg;
	RECT rc;
	RECT rcItem;
	int buttonWidth;
	int buttonHeight;
	int buttonWidth2;
	int buttonHeight2;
	GetClientRect(&rc);
	pWnd = GetDlgItem(IDCANCEL);
	hDlg = pWnd->GetSafeHwnd();
	::GetWindowRect(hDlg, &rcItem);
	buttonWidth = rcItem.right - rcItem.left;
	buttonHeight = rcItem.bottom - rcItem.top;
	::MoveWindow(hDlg, (rc.right - buttonWidth - 32), 
          (rc.bottom - buttonHeight - 8), buttonWidth, buttonHeight, TRUE);
	pWnd = GetDlgItem(IDOK);
	hDlg = pWnd->GetSafeHwnd();
	::GetWindowRect(hDlg, &rcItem);
	buttonWidth2 = rcItem.right - rcItem.left;
	buttonHeight2 = rcItem.bottom - rcItem.top;
	::MoveWindow(hDlg, ((rc.right - (buttonWidth + 32)) - 
       (buttonWidth2 + 8)), (rc.bottom - buttonHeight2 - 8), buttonWidth2, buttonHeight2, TRUE);
	pWnd = GetDlgItem(IDC_SELECT_FONT);
	hDlg = pWnd->GetSafeHwnd();
	::GetWindowRect(hDlg, &rcItem);
	buttonWidth = rcItem.right - rcItem.left;
	buttonHeight = rcItem.bottom - rcItem.top;
	::MoveWindow(hDlg, ((rc.right - buttonWidth - 32) / 2), 
           (rc.bottom - buttonHeight - 8), buttonWidth, buttonHeight, TRUE);
	pWnd = GetDlgItem(IDC_STATIC_FONT);
	hDlg = pWnd->GetSafeHwnd();
	::MoveWindow(hDlg, (rc.left + 32), (rc.top + 32), (rc.right - rc.left) - 64, 
             (rc.bottom - rc.top) - 96, TRUE);
    // Get saved font, force redraw of static window
   	m_static1.SetFont(&m_font, TRUE);
	Invalidate();
}

The code for "OnEraseBkgnd". This code changes the portion of the main window that is not used to display the selected font.

C++
BOOL CFontSelectDlg::OnEraseBkgnd(CDC* pDC)
{
	// TODO: Add your message handler code here and/or call default
	CRect rc;
	GetClientRect(&rc);
	pDC->FillSolidRect(rc, GetSysColor(COLOR_ACTIVECAPTION));

	return TRUE;
}

The code to pick the background color uses the "Right Mouse Button".

The right mouse button is used to select the background color of the selected font.

The right mouse is also used by the main program to display a context menu, therefore I check to see if the cursor is inside my display window frame.

If it is, set the bContinue flag to TRUE to allow selection of the background color.

C++
void CFontSelectDlg::OnRButtonDown(UINT nFlags, CPoint point)
{
	// TODO: Add your message handler code here and/or call default
	CRect rc;
	CWnd *pWnd;
	HWND hWnd;
	CPoint pt;
	GetCursorPos(&pt);
	pWnd = GetDlgItem(IDC_STATIC_FONT);
	hWnd = pWnd->GetSafeHwnd();
	::GetWindowRect(hWnd, &rc);
	if(((pt.x > rc.left) && (pt.x < rc.right)) &&
		((pt.y > rc.top) && (pt.y < rc.bottom)))
		bContinue = TRUE;
	else
		bContinue = FALSE;
	CDialogEx::OnRButtonDown(nFlags, point);
}

void CFontSelectDlg::OnRButtonUp(UINT nFlags, CPoint point)
{
	// TODO: Add your message handler code here and/or call default
	if(bContinue)
	{
		CHOOSECOLOR cc;                 // common dialog box structure 
		static COLORREF acrCustClr[16]; // array of custom colors 
		HWND hwnd = NULL;                      // owner window
		HBRUSH hbrush;                  // brush handle
		static DWORD rgbCurrent;        // initial color selection

		// Initialize CHOOSECOLOR 
		ZeroMemory(&cc, sizeof(cc));
		cc.lStructSize = sizeof(cc);
		cc.hwndOwner = hwnd;
		cc.lpCustColors = (LPDWORD) acrCustClr;
		cc.rgbResult = rgbCurrent;
		cc.Flags = CC_FULLOPEN | CC_RGBINIT;
 
		if (ChooseColor(&cc)==TRUE) 
		{
			hbrush = CreateSolidBrush(cc.rgbResult);
			m_hbrush = hbrush;
			rgbCurrent = cc.rgbResult;
			m_rgbColor = cc.rgbResult;
			m_static1.SetWindowTextA(_T("\r\nOk,\r\nSelect\r\nFont."));
		}
	}
	CDialogEx::OnRButtonUp(nFlags, point);
}

And the last thing to do, display the string using "OnTimer".

C++
void CFontSelectDlg::OnTimer(UINT_PTR nIDEvent)
{
	// TODO: Add your message handler code here and/or call default
	KillTimer(1);
	m_static1.SetWindowTextA(_T("\r\n\r\nRight click to set Background Color."));

	CDialogEx::OnTimer(nIDEvent);
}

Points of Interest

To display a string in a "Static Control", you can't have the code in "OnInitDialog" because the window has not been created yet. I used a 500 millisecond timer to display the text.

History

  • January 24th, 2019: V 1.0

License

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


Written By
United States United States
This member has not yet provided a Biography. Assume it's interesting and varied, and probably something to do with programming.

Comments and Discussions

 
-- There are no messages in this forum --