孙鑫视频教程第十课——图形的绘制、颜色对话框、字体对话框、改变控件的字体及颜色、在对话框中显示位图

       图形的绘制,如何使用自定义画笔(颜色,线宽,线形)。如何为程序中添加选项菜单和选项设置对话框,如何使用标准颜色对话框,如何使用字体对话框,在选项对话框中实现预览功能。实现选项对话框和窗口类中的数据交换。如何改变对话框和控件的背景色,如何改变控件的文本颜色,对按钮控件的特殊处理。如何在窗口中显示一幅位图。

1.图形的绘制:通过菜单项的选择来绘制用户所需要的图形(点,直线,矩形,椭圆):

a.首先需要一个变量来保存用户的选择和坐标的位置:在view类中添加一个变量m_nDrawType和m_ptOrigin;

b.为各个菜单项添加消息响应函数;

void CID102View::OnDot()
{
	// TODO: 在此添加命令处理程序代码
	m_nDrawType = 1;//当用户选择为点的时候,这个值就为1!
}

void CID102View::OnLine()
{
	// TODO: 在此添加命令处理程序代码
	m_nDrawType = 2;//当用户选择为直线的时候,这个值就为2!
}

void CID102View::OnRectangle()
{
	// TODO: 在此添加命令处理程序代码
	m_nDrawType = 3;//当用户选择为矩形的时候,这个值就为3!
}

void CID102View::OnEllipse()
{
	// TODO: 在此添加命令处理程序代码
	m_nDrawType = 4;//当用户选择为椭圆的时候,这个值就为4!
}


void CID102View::OnLButtonDown(UINT nFlags, CPoint point)
{
	// TODO: 在此添加消息处理程序代码和/或调用默认值
    m_ptOrigin = point;
	CView::OnLButtonDown(nFlags, point);
}

c. 通过对鼠标的消息捕获来实现画图的功能:

void CID102View::OnLButtonDown(UINT nFlags, CPoint point)
{
	// TODO: 在此添加消息处理程序代码和/或调用默认值
    m_ptOrigin = point;
	CView::OnLButtonDown(nFlags, point);
}

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

	CClientDC dc(this);
	CPen pen(PS_SOLID, 1, RGB(255, 0, 0));//创建一个红色的画笔
	dc.SelectObject(&pen);//将画笔选入设备描述表中
	CBrush *pBrush = CBrush::FromHandle((HBRUSH)GetStockObject(NULL_BRUSH));//创建一个透明的画刷
	dc.SelectObject(pBrush);//将画刷选入设备描述表中
	switch(m_nDrawType)
	{
	case 1://完成画点功能
		dc.SetPixel(point, RGB(255, 0, 0));
		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;
	default:
		break;
	}
	CView::OnLButtonUp(nFlags, point);
}

2.设置对话框的创建:

a.首先需要插入一个对话框资源;然后再为对话框资源添加一个新类;

b.通过菜单项的按钮来调出对话框,然后在对话框上面设置值,需要给控件添加一个变量m_nLineWidth,而在view类中也需要设置一个变量来保存其所选择的值m_nlinewidth;

c.通过添加菜单项的消息响应函数来完成:

void CID102View::OnSetting()
{
	// TODO: 在此添加命令处理程序代码
	CSettingDlg dlg;//声明一个对话框的对象
	dlg.m_nLineWidth = m_nLineWidth;//将之前设置的值传递回给对话框上面的变量!
	if (IDOK == dlg.DoModal())//调出对话框
	{
		m_nLineWidth = dlg.m_nLineWidth;//将对话框上的选择值保存下来
	}
}

其他控件的处理与上面的处理方式差不多,所以就不在啰嗦!

3.颜色对话框的创建:主要是通过一个ccolordialog类来创建,菜单项上面的颜色按钮来作消息函数的响应!记得需要在view类中设置变量来保存颜色值的选择!

void CID102View::OnColor()
{
	// TODO: 在此添加命令处理程序代码
	CColorDialog dlg;//创建一个颜色对话框的对象
	dlg.m_cc.Flags |= CC_RGBINIT | CC_FULLOPEN;//这个地方的方法需要注意!
	dlg.m_cc.rgbResult = m_clr;
	if (IDOK == dlg.DoModal())//产生一个颜色对话框!
	{
		m_clr = dlg.m_cc.rgbResult;//对用户颜色选择的保存!
	}
}


4.字体对话框的创建:先由菜单项调出一个字体对话框,再由你选择的字体显示在view类上!与颜色对话框的创建相似!

void CID102View::OnFont()
{
	// TODO: 在此添加命令处理程序代码
	CFontDialog dlg;//字体对话框的一个类声明
	if (IDOK == dlg.DoModal())//创建一个字体对话框
	{
		if (m_font.m_hObject)//判断是否已经选择有字体
			m_font.DeleteObject();//切断与对象的联系
		m_font.CreateFontIndirectW(dlg.m_cf.lpLogFont);//对字体对象的初始化
		m_strFontName = dlg.m_cf.lpLogFont->lfFaceName;//对所选字体的保存!
		Invalidate();//使窗口无效!
	}
}


 

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

	// TODO: 在此处为本机数据添加绘制代码
	CFont *pOldFont = pDC->SelectObject(&m_font);
	pDC->TextOutW(0, 0, m_strFontName);
	pDC->SelectObject(pOldFont);
}


包括了两次处理选择字体出现的错误处理:m_font.deleteobject();

5.示例对话框的创建:主要是在dlg类中的onpain()函数中完成:

void CSettingDlg::OnPaint()
{
	CPaintDC dc(this); // device context for painting
	// TODO: 在此处添加消息处理程序代码
	UpdateData();//由控件的值反映到变量上,必须调用!
    CPen pen(m_nLineStyle, m_nLineWidth, m_clr);//创建一个画笔
	dc.SelectObject(&pen);

	CRect rect;
	GetDlgItem(IDC_SAMPLE)->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()

}


6.修改对话框及其控件的背景色:主要在对话框的类中来完成,在对话框类中添加一个函数onctlcolor(),在函数中完成代码:

HBRUSH CSettingDlg::OnCtlColor(CDC* pDC, CWnd* pWnd, UINT nCtlColor)
{
	HBRUSH hbr = CDialog::OnCtlColor(pDC, pWnd, nCtlColor);

	// TODO:  在此更改 DC 的任何属性
	//改变对话框的背景颜色!
	if (pWnd->GetDlgCtrlID() == IDC_LINE)//判断其ID号是否符合
	{
		pDC->SetTextColor(RGB(255, 0, 0));//改变控件上的文本颜色!
		pDC->SetBkMode(TRANSPARENT);//改变背景模式,设置为透明!
		return m_brush;
	}
	//改变控件上的字体颜色
	if (pWnd->GetDlgCtrlID() == IDC_LINE_WIDTH)
	{
		pDC->SetTextColor(RGB(255, 0, 0));//改变控件上的文本颜色!
		pDC->SetBkMode(TRANSPARENT);//改变背景模式,设置为透明!
		pDC->SetBkColor(RGB(0, 0, 255));//设置背景色为蓝色!
		return m_brush;
	}
	//改变控件上的字体
	if (pWnd->GetDlgCtrlID() == IDC_TEXT)
	{
		pDC->SelectObject(&m_font);
	}

	// TODO:  如果默认的不是所需画笔,则返回另一个画笔
	return hbr;
	//return m_brush;//返回由自己创建的画刷!使整个对话框的背景色发生改变!
}

而修改对话框上的按钮的文本颜色和其背景色就比较麻烦,需要添加一个cbutton类,然后再为其按钮创建一个与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);

}

7.如何在窗口中显示位图:可以在view类中添加函数wm_erasebkgnd()函数中根据四步来完成,也可以在对话框的ondraw函数中完成,因为在view类中的效果好,所以下面就写成在view类中完成的代码:

BOOL CID102View::OnEraseBkgnd(CDC* pDC)
{
	// TODO: 在此添加消息处理程序代码和/或调用默认值
    //创建位图
	CBitmap bitmap;
	bitmap.LoadBitmapW(IDB_BITMAP1);
	BITMAP bmp;
	bitmap.GetBitmap(&bmp);//得到位图的结构体
    //创建一个兼容dc
	CDC dcCompatible;
	dcCompatible.CreateCompatibleDC(pDC);
	//将位图选到兼容DC中
	dcCompatible.SelectObject(&bitmap);
    //将兼容dc中的位图贴到当前dc中
    CRect rect;
	GetClientRect(&rect);
	//pDC->BitBlt(0, 0, rect.Width(), rect.Height(), &dcCompatible, 0, 0, SRCCOPY);
	pDC->StretchBlt(0, 0, rect.Width(), rect.Height(), &dcCompatible, 0, 0, bmp.bmWidth, bmp.bmHeight, SRCCOPY);
	return TRUE;
	//return CView::OnEraseBkgnd(&bitmap);
}



 





 

你可能感兴趣的:(MFC)