您的位置:首页 > 其它

孙鑫vc学习笔记_第10课

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

绘图

1. 添加菜单项 点线矩形和椭圆 并添加命令响应
2. 在命令相应中保存其选择 m_nDrawType
3. Buttondown 和 buttonup
4. 用CPoint M_ptOrigin 保存原点
5. 作图
void CGraphicView::OnLButtonUp(UINT nFlags, CPoint point)
{
// TODO: Add your message handler code here and/or call default
CClientDC dc(this);
//创建画笔,1,线类型,2,宽度,3,颜色RGB()
CPen pen(m_nLineStyle,m_nLineWidth,m_clr);
//选入设备描述表中
dc.SelectObject(&pen);
//创建画刷,NULL_BRUSH为透明画刷,
//CBrush::FromHandle静态方法转换一个画刷的句柄返回一个CBrush的指针
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));
//画矩形,Rectangle要求的是指针,但CRect是一个对象
//但CRect重载LPCRect操作,进行类型转换
//会用系统画刷去填充矩形
//边框由系统画笔进行描绘
break;
case 4:
dc.Ellipse(CRect(m_ptOrigin,point));
//椭圆
break;
}
CView::OnLButtonUp(nFlags, point);
}

6.00:16 设置对话框指定画笔类型,线宽

#线宽编辑框 UINT m_nLineWidth

#线形设置单选按钮 int m_nLineStyle
实线 虚线 点线(0,1,2)都没选则为-1
第一个单选按钮设置为group
不需要对其进行对应的关联,因为PS_SOLID就是1
画笔类型定义为:
/* Pen Styles */
#define PS_SOLID 0
#define PS_DASH 1 /* ------- */
#define PS_DOT 2 /* ....... */
#define PS_DASHDOT 3 /* _._._._ */
#define PS_DASHDOTDOT 4 /* _.._.._ */
#define PS_NULL 5
…………………………………………….

#保存用户设置:
//void CGraphicView::OnSetting()
CSettingDlg dlg;
//保存上次设置的值
dlg.m_nLineWidth=m_nLineWidth;
dlg.m_nLineStyle=m_nLineStyle;
dlg.m_clr=m_clr;
if(IDOK==dlg.DoModal()) //用户按ok
{
m_nLineWidth=dlg.m_nLineWidth;
m_nLineStyle=dlg.m_nLineStyle;
}

00:37

7. 颜色对话框(CColorDialog)派生自CDialog

CColorDialog(
COLORREF clrInit = 0,
//缺省为黑色
DWORD dwFlags = 0,
//定制颜色对话框的功能和外观
//参考CHOOSECOLOR structure
CWnd* pParentWnd = NULL
//指向其所有者窗口或其父窗口
);
代码
COLORREF m_clr;//颜色的类型
void CGraphicView::OnColor()
{
// TODO: Add your command handler code here
CColorDialog dlg;
//CColorDialog::m_cc其成员变量就是CHOOSECOLOR结构体类型
//CHOOSECOLOR其中rgbResult变量就保存了用户的颜色选择
dlg.m_cc.Flags|=CC_RGBINIT | CC_FULLOPEN;
//使用“|=”保存其Flags以前的设置
// CC_RGBINIT被设置以后才能对其初始颜色选择进行设置
dlg.m_cc.rgbResult=m_clr;
if(IDOK==dlg.DoModal())
{
m_clr=dlg.m_cc.rgbResult;
}
}

00:51

8. 字体对话框

CFontDialog 派生自 CDialog
CFontDialog(
LPLOGFONT lplfInitial = NULL,
//A pointer to a LOGFONT data structure that allows you to set some of the font's //characteristics.
DWORD dwFlags = CF_EFFECTS | CF_SCREENFONTS,
CDC* pdcPrinter = NULL,
CWnd* pParentWnd = NULL
);
保存用户选择 并把字体名字用所选字体显示在view中
//其类成员CHOOSEFONT m_cf
//CHOOSEFONT LPLOGFONT lpLogFont
//LPLOGFONT中的TCHAR lfFaceName[LF_FACESIZE];
//它是一个空终止的字符串指示了字体的名字
用lpLogFont对一个CFont对象进行初始化
MSDN的例子:
// The code fragment creates a font based on the information
// we got from CFontDialog::m_cf variable.

CFontDialog dlg;
if (dlg.DoModal() == IDOK)
{
// Create the font using the selected font from CFontDialog.
LOGFONT lf;
memcpy(&lf, dlg.m_cf.lpLogFont, sizeof(LOGFONT));

CFont font;
VERIFY(font.CreateFontIndirect(&lf));

// Do something with the font just created...
CClientDC dc(this);
CFont* def_font = dc.SelectObject(&font);
dc.TextOut(5, 5, "Hello", 5);
dc.SelectObject(def_font);

// Done with the font. Delete the font object.
font.DeleteObject();
}
代码:
void CGraphicView::OnFont()
{
// TODO: Add your command handler code here
CFontDialog dlg;
if(IDOK==dlg.DoModal())
{
//判断是否已经与一个字体相关联了?用句柄来判断
//若是则释放资源windows GDI object
//继承自CGdiObject(m_hObject)
if(m_font.m_hObject)
m_font.DeleteObject();
m_font.CreateFontIndirect(dlg.m_cf.lpLogFont);
//保存字体的名字
m_strFontName=dlg.m_cf.lpLogFont->lfFaceName;
Invalidate();
//OnDraw
//CFont *pOldFont=pDC->SelectObject(&m_font);
//pDC->TextOut(0,0,m_strFontName);
//pDC->SelectObject(pOldFont);
}
}

01:06

9. 设置对话框的示例功能

改变线宽,和线形时能够在对话框中显示线条的变化
#设置一个组框
#改变其ID号为IDC_SAMPLE
#捕获用户对编辑框,单选按钮的改变
编辑框 EN_CHANG消息
单选按钮 BN_CLICKED
void CSettingDlg::OnRadio1()
{
Invalidate();
//点击单选引起重绘
}
……..
增加WM_PAINT消息进行绘图
CPaintDC dc(this);
UpdateData();
//m_clr由view类传递
CPen pen(m_nLineStyle,m_nLineWidth,m_clr);
dc.SelectObject(&pen);

CRect rect;
//获取组框窗口矩形区域大小
GetDlgItem(IDC_SAMPLE)->GetWindowRect(&rect);
// GetWindowRect接受的是屏幕坐标
//而划线的时候使用的是客户区的坐标
//所以需要将屏幕坐标转换为客户区的坐标
ScreenToClient(&rect);

dc.MoveTo(rect.left+20,rect.top+rect.Height()/2);
dc.LineTo(rect.right-20,rect.top+rect.Height()/2);
//由于整数除法的误差
//所以为了高度一致不能使用rect.bottom - rect.Height()/2

01:22

10. 改变对话框和对话框控件的背景色和文字颜色

WM_CTLCOLOR
CWnd::OnCtlColor
afx_msg HBRUSH OnCtlColor(

CDC* pDC,//指向显示上下文(子窗口)的指针

CWnd* pWnd,//请求颜色的控件的指针

UINT nCtlColor //指示是哪一类的控件

);
每一个控件创建时都要调用OnCtlColor函数,都要为其准备pDC。

控件将要绘制的时候发送一个消息给其父窗口(通常是对话框),来准备pDC用正确的控件来绘制窗口
改变文本的颜色调用SetTextColor成员函数

#捕获其消息响应
#判断当前绘制的是那一个控件
m_brush.CreateSolidBrush(RGB(0,0,255));//设置画刷

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

// pWnd->GetDlgCtrlID()获取一个窗口(不是顶层窗口)的ID
if(pWnd->GetDlgCtrlID()==IDC_LINE_STYLE)
{
//改变文字颜色
pDC->SetTextColor(RGB(255,0,0));
//把文字背景色设为透明
pDC->SetBkMode(TRANSPARENT);
//CBrush重载了HBRUSH的操作符
return m_brush;
}
if(pWnd->GetDlgCtrlID()==IDC_LINE_WIDTH)
{
pDC->SetTextColor(RGB(255,0,0));
//要改变一个单行编辑框的背景色,需要调用SetBkColor
//pDC->SetBkMode(TRANSPARENT);
pDC->SetBkColor(RGB(0,0,255));
return m_brush;
}
//改变字体
//m_font.CreatePointFont(200,"华文行楷");
if(pWnd->GetDlgCtrlID()==IDC_TEXT)
{
pDC->SelectObject(&m_font);
}
/*if(pWnd->GetDlgCtrlID()==IDOK)
{
pDC->SetTextColor(RGB(255,0,0));
return m_brush;
}*/
// TODO: Return a different brush if the default is not desired
//返回的画刷句柄去绘制对话框和子控件
return hbr;
//返回背景色
//return m_brush;
}
01:40
#改变按钮颜色,需要自己编写一个button类覆盖DrawItem函数
CButton::DrawItem
MSDN例子:
// NOTE: CMyButton is a class derived from CButton. The CMyButton
// object was created as follows:
//
// CMyButton myButton;
// myButton.Create(_T("My button"),
// WS_CHILD|WS_VISIBLE|BS_PUSHBUTTON|BS_OWNERDRAW,
// CRect(10,10,100,30), pParentWnd, 1);
//

// This example implements the DrawItem method for a CButton-derived
// class that draws the button's text using the color red.
void CMyButton::DrawItem(LPDRAWITEMSTRUCT lpDrawItemStruct)
{
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.
//改变了文本的颜色,hDC表示了Button控件相关的DC
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);
}
#建立自己的button类
#设置按钮为 Owner Draw
#关联按钮的成员变量
#添加代码

01:51
#使用button
Sxbtn类
Buttonst类
手动改基类
Buttonst类:不需要设置Owner Draw 它自己会设置
m_btnST.SetActiveBgColor(RGB(0,0,255));//活动时的背景色
m_btnST.SetActiveFgColor(RGB(255,0,0));//活动时的前景色,文字颜色

m_btnST.SetInactiveBgColor(RGB(255,0,255));//不活动时。。。
m_btnST.SetInactiveFgColor(RGB(255,255,0));

01:58

11.在窗口中显示位图

1、创建位图
CBitmap bitmap;
bitmap.LoadBitmap(IDB_BITMAP1);
2、创建兼容DC
CDC dcCompatible;
dcCompatible.CreateCompatibleDC(pDC);
//创建一个内存设备上下文和通过参数所指定的pDC(目的dc)相兼容,一个内存上下文是一个内存块表示了一个显示的表面,在拷贝图像到实际的兼容设备的设备表面之前,它可以被用来在内存中准备这些图像。
//兼容dc创建时它的表面大小为1个象素的大小。要在兼容dc上调用GDI的输出函数完成一些图形的绘制,你必须要有一幅图像创建并选入dc当中之后才能调用输出函数
3.将位图选入兼容dc中去
4、将兼容DC中的位图贴到当前DC中。
pDC->BitBlt(rect.left,rect.top,rect.Width(),
rect.Height(),&dcCompatible,0,0,SRCCOPY);
//Bitblt拷贝一个位图从源设备上下文到当前设备上下文1:1

#准备一幅位图
#资源中导入位图

#窗口绘制过程

×先擦除窗口背景
WM_ERASEBKGND
×然后重绘窗口
BOOL CGraphicView::OnEraseBkgnd(CDC* pDC)
{
CBitmap bitmap;
bitmap.LoadBitmap(IDB_BITMAP1);
// GetBitmap来获取BITMAP结构体来获取位图信息
BITMAP bmp;
bitmap.GetBitmap(&bmp);

CDC dcCompatible;
dcCompatible.CreateCompatibleDC(pDC);

dcCompatible.SelectObject(&bitmap);

CRect rect;
GetClientRect(&rect);//得到客户端区域的大小
// SRCCOPY从源位图到目的矩形区域
// pDC->BitBlt(0,0,rect.Width(),rect.Height(),&dcCompatible,0,0,SRCCOPY);
//bitblt是1比1拷贝而StretchBlt可以拉伸和压缩图片来适合矩形大小
//需要bmp.bmWidth,bmp.bmHeight位图的高度和宽度
pDC->StretchBlt(0,0,rect.Width(),rect.Height(),&dcCompatible,
0,0,bmp.bmWidth,bmp.bmHeight,SRCCOPY);
//擦除了背景则返回非零值
return TRUE;
//去掉基类的函数不然就擦除了背景
// return CView::OnEraseBkgnd(pDC);
}
//若放在OnDraw函数中时会发生闪烁,因为要先擦除再重绘

作业

CDialogBar-CControlBar-CWnd
在其上放一些控件,改变一下其编辑框的颜色,改变DialogBar的背景色,在列表框中显示位图
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: