一、简单绘图
a)画直线
b)画笔CPen的使用
c)画刷CBrush的使用
d)写字,CFont的使用
1、画直线
a)鼠标按下和抬起
b)创建画家对象 CClientDC
//创建画家对象,指定绘画设备
CClientDC dc(this);//画在当前对话框
c)起点和终点
MoveTo LineTo
d)选中所属类->右击->添加变量
2、画笔、画刷的使用
a)定义画家
b)定义画笔(画刷)CPen,CBursh
c)把画笔交给画家 CDC::SelectObject
实例解析:
1、新建一个基于单文档的项目
2、在所属类中添加变量(视图类添加)
/*在DrawView.h中添加变量*/
private:
CPoint m_myPoint; //鼠标当前的坐标
bool m_isPress; //鼠标按下与抬起的标识
3、添加消息处理程序
4、添加事件程序实现的代码
/*在DrawView.cpp中实现*/
//鼠标左键按下
void CMy04_DrawView::OnLButtonDown(UINT nFlags, CPoint point)
{
// TODO: 在此添加消息处理程序代码和/或调用默认值
m_myPoint = point;//保存点击点的坐标
m_isPress = true; //标志 鼠标左键按下
CView::OnLButtonDown(nFlags, point);
}
//鼠标抬起
void CMy04_DrawView::OnLButtonUp(UINT nFlags, CPoint point)
{
// TODO: 在此添加消息处理程序代码和/或调用默认值
//创建画家对象,指定绘画设备
CClientDC dc(this);//画在当前对话框
dc.MoveTo(m_myPoint);//起点
dc.LineTo(point);//终点
m_isPress = false;
CView::OnLButtonUp(nFlags, point);
}
画笔和画刷的代码:
void CMy04_DrawView::OnDraw(CDC* pDC)
{
CMy04_DrawDoc* pDoc = GetDocument();
ASSERT_VALID(pDoc);
if (!pDoc)
return;
// TODO: 在此处为本机数据添加绘制代码
/*
a)定义画家
b)定义画笔(画刷)CPen,CBursh
c)把画笔交给画家 CDC::SelectObject
*/
//PS_DASH:虚线 只有当画笔宽度为1或更小(以设备单位计算)时才有效。
//10:线宽
//RGB(255, 0, 0):红色
CPen pen(PS_SOLID, 1, RGB(255, 0, 0));
//返回当前的状态
CPen *oldPen = pDC->SelectObject(&pen);
pDC->MoveTo(10, 10);
pDC->LineTo(120, 10);
//恢复原来的状态
pDC->SelectObject(&oldPen);
//画圆型
pDC->Ellipse(20, 20, 120, 120);
//画刷
CBrush brush(RGB(255, 0, 0));
pDC->SelectObject(&brush);
pDC->Ellipse(20, 20, 120, 120);
//定义一个位图对象
CBitmap bitmap;
bitmap.LoadBitmapW(IDB_BITMAP1);//加载位图
CBrush brush2(&bitmap);
pDC->SelectObject(&brush2);
pDC->Ellipse(120, 20, 600, 600);
//写字
CFont font;
pDC->SelectObject(&font);
pDC->TextOutW(100, 100, TEXT("Hello,World!"));
}
二、文本编辑器
1)创建插入符CWnd::CreateSolidCaret()
a)创建CWnd::CreateSolidCaret()
b)获取字符串的尺寸信息CDC::GetTextExtent()
c)截取字符串(CString)左边指定长度的字符 str = str.Left(str.GetLength()-1);
// CMy05_EditorView 消息处理程序
//窗口创建后自动启用
int CMy05_EditorView::OnCreate(LPCREATESTRUCT lpCreateStruct)
{
if (CView::OnCreate(lpCreateStruct) == -1)
return -1;
// TODO: 在此添加您专用的创建代码
//获取字体信息
CClientDC dc(this);
TEXTMETRIC tm;//字体信息结构体
dc.GetTextMetrics(&tm);
//继承于CWnd
CreateSolidCaret(tm.tmAveCharWidth, tm.tmHeight);//创建插入符
ShowCaret();//显示
return 0;
}
//鼠标左键按下
void CMy05_EditorView::OnLButtonDown(UINT nFlags, CPoint point)
{
// TODO: 在此添加消息处理程序代码和/或调用默认值
SetCaretPos(point);//移动插入符
//保存点击点坐标
m_point = point;//m_point是坐标变量,在视图类中已添加
//清空
str = TEXT(""); //str字符串变量
str.Empty();
//MessageBox(TEXT("m_point"));
CView::OnLButtonDown(nFlags, point);
}
//点击键盘,启动调用
void CMy05_EditorView::OnChar(UINT nChar, UINT nRepCnt, UINT nFlags)
{
// TODO: 在此添加消息处理程序代码和/或调用默认值
CClientDC dc(this);//创建画家对象
//str += (TCHAR)nChar;
CSize size = dc.GetTextExtent(str);//获取字符串长度
if (nChar == VK_RETURN)//换行 清空
{
str.Empty();
TEXTMETRIC tm;//字体信息结构体
dc.GetTextMetrics(&tm);
m_point.y = m_point.y + tm.tmHeight;
}
else if (nChar == VK_BACK)//退格
{
//获取背景图
COLORREF color = dc.GetBkColor();
//设置写字的颜色
COLORREF oldColor = dc.SetTextColor(color);
//白色重写一次
dc.TextOutW(m_point.x, m_point.y, str);
//去掉最后一个字符
str = str.Left(str.GetLength() - 1);
//恢复原来颜色
dc.SetTextColor(oldColor);
}
else
{
str.Empty();
str += (TCHAR)nChar;
//CSize size = dc.GetTextExtent(str);//获取字符串长度
}
int x = m_point.x = m_point.x + size.cx;
int y = m_point.y;
SetCaretPos(CPoint(x, y));//移动插入符
dc.TextOutW(m_point.x, m_point.y, str);
CView::OnChar(nChar, nRepCnt, nFlags);
}
三、字体渐变
1)定时器的使用
a)设置定时器:CWnd::SetTimer() 在视图类中的OnCreate中设置定时器
b)关闭定时器:CWnd::KillTimer()
c)定时器消息:WM_TIMER
2)视图类中的OnDraw()中,写字 CDC::TextOutW()
3)指定区域写字:CDC::DrawText()
4)让窗口失效,产生WM_PAINT,间接调用OnDraw()函数:CWnd::Invalidate
代码示例:
// CMy06_TimeoutView 消息处理程序
int CMy06_TimeoutView::OnCreate(LPCREATESTRUCT lpCreateStruct)
{
if (CView::OnCreate(lpCreateStruct) == -1)
return -1;
// TODO: 在此添加您专用的创建代码
//设置定时器
//参数说明: 1:定时器id 1000:时间间隔,毫秒 NULL : 系统默认的处理函数,每个100毫秒,触发WM_TIMER
SetTimer(1, 100, NULL);
return 0;
}
//在WM_TIME中添加OnTimer()
void CMy06_TimeoutView::OnTimer(UINT_PTR nIDEvent)
{
// TODO: 在此添加消息处理程序代码和/或调用默认值
#if 0
if (nIDEvent == 1)
{
static int i = 0;
i++;
CString str;
str.Format(TEXT("%d"), i);
if (i == 5)
{
KillTimer(1);
}
MessageBox(str);
}
static int i = 0;
i++;
CString str;
str.Format(TEXT("%d"), i);
if (i == 5)
{
KillTimer(1);
}
MessageBox(str);
#endif
CView::OnTimer(nIDEvent);
static int w = 0;
w += 5;
CString str = TEXT("塑造自己的过程很疼,但是你可以得到一个更好的自己!");
//获取字符串的长度(宽度)
CClientDC dc(this);//画家对象
CSize size = dc.GetTextExtent(str);
//如果宽度大于字符串的宽度,重新开始
if (w > size.cx)
{
w = 0;
Invalidate();//Qt 中Update()
}
int x = 30;
int y = 30;
CRect rect(x, y, x + w, y + size.cy);
//黑色写一次
dc.TextOutW(x, y, str);
//设置字体颜色
dc.SetTextColor(RGB(255, 0, 0));
dc.DrawText(str, &rect, DT_LEFT);
CView::OnTimer(nIDEvent);
}
四、菜单的相关操作
1)菜单的命令响应函数
a)弹式菜单,ID不可以编辑,按下去,弹出一个 菜单项
b)非弹式菜单,ID可以编辑
c)菜单响应命令消息的路由(顺序)
d)消息类型
非标准消息
WM_COMMAND,命令消息、通告消息,CCmdTarget、CWnd子类能接受到非标准消息
标准消息 WM_XXXX CWnd子类才能收到标准消息
命令消息 WM_COMMAND:菜单处理函数选中
标准消息:属性->消息类型
通告消息:点击按钮,处理函数
CWnd可以接收任何消息
CCmdTarget:不能接收标准消息
2)菜单相关静态操作
在框架类MainFrame中进行相应操作,在OnCreate()中实现
A)获取菜单栏:CWnd::GetMenu
B)获取子菜单:CMenu::GetSubMenu
a)标志菜单:CMenu::CheckMenuItem
MF_BYPOSITION:通过位置
MF_BYCOMMAND:通过ID
b)设置默认菜单:CMenu::SetDefaultItem
注意:一个菜单项只能设置一个默认项
c)禁用菜单:CMenu::EnableMenuItem
注意:需要把CFrameWnd::m_bAutoMenuEnable 成员变量设置为 FALSE
d)分隔线
C)移除菜单 CWnd::SetMenu
SetMenu(NULL)
D)装载菜单
a)创建菜单 CMenu::LoadMenu
b)设置菜单 CWnd::SetMenu
c)从CMenu 对象中分离出Windows菜单 CMenu::Detach
E)菜单更新机制
F)快捷菜单,弹出菜单(一定要新建菜单,不能使用框架类的主菜单)
由于鼠标点击区域是视图区域,所以需要在视图类类中处理
a)处理鼠标右击事件WM_RBUTTONDOWN
b)获取所需的子菜单
c)弹出菜单项 CMenu::TrackPopupMenu
d)客户区坐标转到屏幕坐标:CWnd::CClientToScreen
3)菜单相关动态操作
a)创建空菜单 CMenu::CreateMenu
b)追加弹式菜单 CMenu::AppendMenu(MF_POPUP)
每个菜单都有一个菜单句柄:CMenu::m_hMenu
重画菜单条:CWnd::DrawMenuBar
c)追加普通菜单 CMenu::AppendMenu(MF_STRING)
d)插入菜单:CMenu::InsertMenu
e)删除菜单:CMenu::DeleteMenu
五、动态图标
1)定时器:CWnd::SetTimer
a)定时器信号:WM_TIMER
b)设置定时器应该在OnCreate()
2)加载自定义图标(WinAPI):LoadIcon()
a)将资源ID转换为字符串 MAKEINSERSOURCE()
b)获取应用程序实例:
AfxGetInstanceHandle()
AfxGetApp()->m_hInstance
3)设置图标(WinAPI)SetClassLong()
窗口句柄:CWnd::m_hWnd