mfc—改变控件的颜色、背景、字体以及画图

  本周学习了孙鑫老师的第十课,本节课主要讲的是:画图以及改变控件的颜色、背景、字体、大小。

mfc—改变控件的颜色、背景、字体以及画图_第1张图片

  通过上面四个选项,设置我们画图的形状。下面三个选项,设置我们线条的大小、颜色和字体。

首先是选择颜色的窗口:

mfc—改变控件的颜色、背景、字体以及画图_第2张图片

窗口mfc已经为我们写好了,我们只需要调用一下,在单文档的view类里面添加相应点击颜色菜单的函数:

void CGraphicView::OnColor()
{
	// TODO: 在此添加命令处理程序代码
	CColorDialog dlg;
	dlg.m_cc.Flags |= CC_RGBINIT;//设置颜色对话框的初始颜色由用户指定
	dlg.m_cc.rgbResult = m_clr;//初始颜色
	if (IDOK == dlg.DoModal())
	{
		m_clr = dlg.m_cc.rgbResult;//保存用户选定的颜色
	}
}


/*
CColorDialog 中有一个类型为CHOOSECOLOR的成员变量m_cc,我们可以通过改变他的值来设置颜色。
*/

typedef struct {
    DWORD lStructSize;
    HWND hwndOwner;
    HWND hInstance;
    COLORREF rgbResult;
    COLORREF *lpCustColors;
    DWORD Flags;
    LPARAM lCustData;
    LPCCHOOKPROC lpfnHook;
    LPCTSTR lpTemplateName;
} CHOOSECOLOR, *LPCHOOSECOLOR;


rgbResult
/*
如果Flags设置了CC_RGBINIT标志,则rgbResult是创建对话框时最初选择的颜色。 
如果指定的颜色值不在可用颜色中,系统将选择最接近的纯色。 
如果rgbResult为零或未设置CC_RGBINIT,则最初选择的颜色为黑色。 
如果用户单击“确定”按钮,则rgbResult指定用户的颜色选择。 
要创建COLORREF颜色值,请使用RGB宏。
*/

其次是字体类型和字体大小的选择:

mfc—改变控件的颜色、背景、字体以及画图_第3张图片mfc—改变控件的颜色、背景、字体以及画图_第4张图片

这个窗口也由mfc给我写好了,我们只需要调用CFontDialog

void CGraphicView::OnFont()
{
	// TODO: 在此添加命令处理程序代码
	CFontDialog dlg;
	if (IDOK == dlg.DoModal())
	{
		if (m_font.m_hObject)
		{
			m_font.DeleteObject();//如果已经创建,需要先切断该对象与之前的资源的连接
		}
		m_font.CreateFontIndirect(dlg.m_cf.lpLogFont);//创建用户选中的字体
		m_strFontName = dlg.m_cf.lpLogFont->lfFaceName;//保存用户选择字体的名称
		Invalidate();//重绘窗口
	}
	
}

/*
msdn 中关于成员变量m_font的描述是:构造CFontDialog对象后,可以使用m_cf结构初始化对话框中控件的值或状态。 m_cf结构的类型为CHOOSEFONT。
*/

typedef struct {
    DWORD lStructSize;
    HWND hwndOwner;
    HDC hDC;
    LPLOGFONT lpLogFont;
    INT iPointSize;
    DWORD Flags;
    COLORREF rgbColors;
    LPARAM lCustData;
    LPCFHOOKPROC lpfnHook;
    LPCTSTR lpTemplateName;
    HINSTANCE hInstance;
    LPTSTR lpszStyle;
    WORD nFontType;
    INT nSizeMin;
    INT nSizeMax;
} CHOOSEFONT, *LPCHOOSEFONT;

lpLogFont
/*
如果在Flags成员中设置CF_INITTOLOGFONTSTRUCT标志并初始化LOGFONT成员,
则ChooseFont函数会使用最接近的字体初始化对话框。 
如果用户单击“确定”按钮,则ChooseFont将根据用户的选择设置LOGFONT结构的成员。
*/

发送重绘消息后,在ondraw函数中相应

void CGraphicView::OnDraw(CDC* pDC)
{
	CGraphicDoc* pDoc = GetDocument();
	ASSERT_VALID(pDoc);
	if (!pDoc)
		return;

	// TODO: 在此处为本机数据添加绘制代码
	CFont* pOldFont = pDC->SelectObject(&m_font);//将用户选择的字体添加到设备描述表中,并返回之前的字体
	pDC->TextOut(0,0,m_strFontName);//打印字体名称
	pDC->SelectObject(pOldFont);//
}

第三个是设置对话框,设置线型、线宽,另外还有一个示例,可以实时展示用户的选择样式。

mfc—改变控件的颜色、背景、字体以及画图_第5张图片

当我们在编辑框里面输入内容时,编辑框会发送一个EN_CHANGE消息,我们需要相应这个消息就可以实时示例中改变线宽。线型的话,需要相应BN_CLICKED消息。

void CSettingDlg::OnEnChangeLineWidth()
{
	Invalidate();
}

void CSettingDlg::OnBnClickedRadio1()
{
	// TODO: 在此添加控件通知处理程序代码
	Invalidate();
}

void CSettingDlg::OnBnClickedRadio2()
{
	// TODO: 在此添加控件通知处理程序代码
	Invalidate();
}

void CSettingDlg::OnBnClickedRadio3()
{
	// TODO: 在此添加控件通知处理程序代码
	Invalidate();
}

Invalidate()会向系统发送WM_PAINT消息,我们只需要相应该消息即可。

void CSettingDlg::OnPaint()
{
	CPaintDC dc(this); // device context for painting
	// TODO: 在此处添加消息处理程序代码
	UpdateData(TRUE);//将控件的数据更新到与之关联的空间变量
	CPen pen(m_nLineStyle, m_nLineWidth, m_clr);
	dc.SelectObject(&pen);
	CRect rect;
	GetDlgItem(IDC_SIMPLE)->GetWindowRect(&rect);//得到示例的画图区域
	ScreenToClient(&rect);

	dc.MoveTo(rect.left+20, rect.top + rect.Height() / 2);
	dc.LineTo(rect.right-20, rect.top + rect.Height() / 2);
	// 不为绘图消息调用 CDialog::OnPaint()
}

最后画图的话,只需要在view类中实现鼠标点下和松开的方法:

void CGraphicView::OnLButtonDown(UINT nFlags, CPoint point)
{
	// TODO: 在此添加消息处理程序代码和/或调用默认值
	m_ptOrigin = point;//保存鼠标点下时的坐标

	CView::OnLButtonDown(nFlags, point);
}

void CGraphicView::OnLButtonUp(UINT nFlags, CPoint point)
{
	// TODO: 在此添加消息处理程序代码和/或调用默认值

	CClientDC dc(this);
	CPen pen(m_nLineStyle, m_nLineWidth > 0 ? m_nLineWidth : 1, m_clr);
	dc.SelectObject(&pen);
	CBrush* pBrush = CBrush::FromHandle((HBRUSH)GetStockObject(NULL_BRUSH));//获得透明的画刷
	dc.SelectObject(pBrush);
	switch(m_nDrawType)
	{
	case 1:
		dc.SetPixel(point, m_clr);
		break;
	case 2:
		dc.MoveTo(m_ptOrigin);
		dc.LineTo(point);
		break;
	case 3:
		dc.Rectangle(CRect(m_ptOrigin, point));
		break;
	case 4:
		dc.Ellipse(CRect(m_ptOrigin, point));
		break;
	}
	CView::OnLButtonUp(nFlags, point);
}

除此之外,孙老师还着重讲了关于改变控件颜色的方法。

首先我们需要相应WM_CTLCOLOR消息,添加函数OnCtlColor

HBRUSH CSettingDlg::OnCtlColor(CDC* pDC, CWnd* pWnd, UINT nCtlColor)
{//每一个控件都会调用一次,pdc,pwnd指向了每一个子控件
	HBRUSH hbr = CDialog::OnCtlColor(pDC, pWnd, nCtlColor);

	// TODO:  在此更改 DC 的任何属性
	if (IDC_LINE_STYLE == pWnd->GetDlgCtrlID())
	{
		pDC->SetTextColor(RGB(255,0,0));//设置文本颜色
		pDC->SetBkMode(TRANSPARENT);//设置背景为透明
		return m_brush;
	}

	if (IDC_LINE_WIDTH == pWnd->GetDlgCtrlID())
	{
		pDC->SetTextColor(RGB(255,0,0));//设置文本颜色
		pDC->SetBkColor(RGB(0,0,255));//设置背景颜色
		return m_brush;
	}

	if (IDC_TEXT == pWnd->GetDlgCtrlID())
	{
		pDC->SelectObject(&m_font);//设置文本的字体
	}
	// TODO:  如果默认的不是所需画笔,则返回另一个画笔
	return hbr;
}

要想改变button的颜色和样式,需要从CButton派生一个类,重写CButton::DrawItem方法。

void CTestBtn::DrawItem(LPDRAWITEMSTRUCT lpDrawItemStruct)
{
	// TODO:  添加您的代码以绘制指定项
	UINT uStyle = DFCS_BUTTONPUSH;

	// This code only works with buttons.
	ASSERT(lpDrawItemStruct->CtlType == ODT_BUTTON);

	// If drawing selected, add the pushed style to DrawFrameControl.
	if (lpDrawItemStruct->itemState & ODS_SELECTED)
		uStyle |= DFCS_PUSHED;

	// Draw the button frame.
	::DrawFrameControl(lpDrawItemStruct->hDC, &lpDrawItemStruct->rcItem, 
		DFC_BUTTON, uStyle);

	// Get the button's text.
	CString strText;
	GetWindowText(strText);

	// Draw the button text using the text color red.
	COLORREF crOldColor = ::SetTextColor(lpDrawItemStruct->hDC, RGB(255,0,0));
	::DrawText(lpDrawItemStruct->hDC, strText, strText.GetLength(), 
		&lpDrawItemStruct->rcItem, DT_SINGLELINE|DT_VCENTER|DT_CENTER);
	::SetTextColor(lpDrawItemStruct->hDC, crOldColor);

}

 

你可能感兴趣的:(mfc)