1,简单绘图

  画直线

    a,鼠标按下和抬起       

void CDrawView::OnLButtonDown(UINT nFlags, CPoint point)
{
// TODO: 在此添加消息处理程序代码和/或调用默认值 m_myPoint = point; CView::OnLButtonDown(nFlags, point);
}
void CDrawView::OnLButtonUp(UINT nFlags, CPoint point)
{
// TODO: 在此添加消息处理程序代码和/或调用默认值 CClientDC dc(this);
dc.MoveTo(m_myPoint);
dc.LineTo(point); CView::OnLButtonUp(nFlags, point);
}

    b,CPaintDC 只能在OnPaint 中使用

      CClientDC 在任何地方都可以使用

    c,起点和终点

        MoveTo  移动当前位置

        LineTo  从当前位置到一点画直线,但不包括那个点

    d,选择所属类 -> 右击 -> 添加变量,这种方法会自动帮你初始化变量

    

  连续的线

    鼠标移动事件

// CDrawView 消息处理程序

void CDrawView::OnLButtonDown(UINT nFlags, CPoint point)
{
// TODO: 在此添加消息处理程序代码和/或调用默认值 m_myPoint = point;
m_isPressed = true; CView::OnLButtonDown(nFlags, point);
} void CDrawView::OnLButtonUp(UINT nFlags, CPoint point)
{
// TODO: 在此添加消息处理程序代码和/或调用默认值
#if 0
CClientDC dc(this);
dc.MoveTo(m_myPoint);
dc.LineTo(point);
#endif
m_isPressed = false;
CView::OnLButtonUp(nFlags, point);
} void CDrawView::OnMouseMove(UINT nFlags, CPoint point)
{
// TODO: 在此添加消息处理程序代码和/或调用默认值
if (m_isPressed) {
CClientDC dc(this);
dc.MoveTo(m_myPoint);
dc.LineTo(point); // 终点作为起点
m_myPoint = point;
} CView::OnMouseMove(nFlags, point);
}

void CDrawView::OnDraw(CDC* pDC)
{
CDrawDoc* pDoc = GetDocument();
ASSERT_VALID(pDoc);
if (!pDoc)
return; // TODO: 在此处为本机数据添加绘制代码 // 画圆
/*
参数: x1 指定椭圆外接矩形左上角的X逻辑坐标。
y1 指定椭圆外接矩形左上角的Y逻辑坐标。
x2 指定椭圆外接矩形右下角的X逻辑坐标。
y2 指定椭圆外接矩形右下角的Y逻辑坐标。
*/
pDC->Ellipse(,,,); // 画刷
CBrush brush(RGB(, , ));
pDC->SelectObject(&brush);
pDC->Ellipse(, , , );
}

2,位图的 使用

// CDrawView 绘图

void CDrawView::OnDraw(CDC* pDC)
{
CDrawDoc* pDoc = GetDocument();
ASSERT_VALID(pDoc);
if (!pDoc)
return; // TODO: 在此处为本机数据添加绘制代码 // 画圆
/*
参数: x1 指定椭圆外接矩形左上角的X逻辑坐标。
y1 指定椭圆外接矩形左上角的Y逻辑坐标。
x2 指定椭圆外接矩形右下角的X逻辑坐标。
y2 指定椭圆外接矩形右下角的Y逻辑坐标。
*/
pDC->Ellipse(,,,); // 画刷
CBrush brush(RGB(, , ));
pDC->SelectObject(&brush);
pDC->Ellipse(, , , ); // 定义一个位图对象
CBitmap bitmap;
bitmap.LoadBitmapW(IDB_BITMAP1); CBrush brush2(&bitmap);
pDC->SelectObject(&brush2);
pDC->Ellipse(,,,); }

3,字体

// CDrawView 绘图

void CDrawView::OnDraw(CDC* pDC)
{
CDrawDoc* pDoc = GetDocument();
ASSERT_VALID(pDoc);
if (!pDoc)
return; // TODO: 在此处为本机数据添加绘制代码 // 画圆
/*
参数: x1 指定椭圆外接矩形左上角的X逻辑坐标。
y1 指定椭圆外接矩形左上角的Y逻辑坐标。
x2 指定椭圆外接矩形右下角的X逻辑坐标。
y2 指定椭圆外接矩形右下角的Y逻辑坐标。
*/
pDC->Ellipse(,,,); // 画刷
CBrush brush(RGB(, , ));
pDC->SelectObject(&brush);
pDC->Ellipse(, , , ); // 定义一个位图对象
CBitmap bitmap;
bitmap.LoadBitmapW(IDB_BITMAP1); CBrush brush2(&bitmap);
pDC->SelectObject(&brush2);
pDC->Ellipse(,,,); CFont font;
font.CreatePointFont(, TEXT("楷体"));
pDC->SelectObject(&font);
pDC->TextOutW(,,TEXT("hello world"));
}

4,文本编程

  1,创建插入符CWnd::CreateSolidCaret()

    a,创建CWnd::CreateSolidCaret()

    b,显示CWnd::ShowCaret()

    c,插入符的高度是根据字体的高度来确定

      获取字体信息CDC::GetTextMetrics()

    d,设置插入符的位置CWnd::SetCaretPos()

  2,在字符消息处理函数中写字

    a,写字CDC::TextOutW()

    b,获取字符串的尺寸信息CDC::GetTextExtent()

    c,截取字符串(CString)左边指定长度的字符 str = str.Left(str.GetLength() - 1);

int CEditorView::OnCreate(LPCREATESTRUCT lpCreateStruct)
{
if (CView::OnCreate(lpCreateStruct) == -)
return -; // TODO: 在此添加您专用的创建代码 // 获取字体信息
CClientDC dc(this);
TEXTMETRIC tm;
dc.GetTextMetrics(&tm); // 继承与CWnd
CreateSolidCaret(tm.tmAveCharWidth / ,tm.tmHeight); // 创建插入符 ShowCaret();
return ;
}

写字

// CEditorView 消息处理程序

int CEditorView::OnCreate(LPCREATESTRUCT lpCreateStruct)
{
if (CView::OnCreate(lpCreateStruct) == -)
return -; // TODO: 在此添加您专用的创建代码 // 获取字体信息
CClientDC dc(this);
TEXTMETRIC tm;
dc.GetTextMetrics(&tm); // 继承与CWnd
CreateSolidCaret(tm.tmAveCharWidth / ,tm.tmHeight); // 创建插入符 ShowCaret();
return ;
} void CEditorView::OnLButtonDown(UINT nFlags, CPoint point)
{
// TODO: 在此添加消息处理程序代码和/或调用默认值 SetCaretPos(point);//设置插入符的位置 m_point = point;// 保存点的坐标 m_str.Empty(); // 清空上一次的数据 CView::OnLButtonDown(nFlags, point);
} // 点击键盘,启动调用
void CEditorView::OnChar(UINT nChar, UINT nRepCnt, UINT nFlags)
{
// TODO: 在此添加消息处理程序代码和/或调用默认值 CClientDC dc(this); // 换行和退格
if (nChar == VK_RETURN) {
// 获取字体信息
TEXTMETRIC tm;
dc.GetTextMetrics(&tm); m_point.y = m_point.y + tm.tmHeight;
m_str.Empty();
}
else if (nChar == VK_BACK) {
COLORREF color = dc.GetBkColor();// 获取背景色
COLORREF oldColor = dc.SetTextColor(color);// 设置写字的颜色,返回以前的文本颜色的 RGB 值。 // 白色重写一次文本
dc.TextOutW(m_point.x, m_point.y, m_str);
// 去掉最后一个字符
m_str = m_str.Left(m_str.GetLength() - ); dc.SetTextColor(oldColor);
}
else {
m_str += (TCHAR)nChar;
} CSize size = dc.GetTextExtent(m_str); // 可以获取文本的宽度和长度
// 移动光标
CPoint pos;
pos.x = m_point.x + size.cx;
pos.y = m_point.y;
SetCaretPos(pos); dc.TextOutW(m_point.x, m_point.y, m_str); CView::OnChar(nChar, nRepCnt, nFlags);
}

5,菜单

1,菜单命令响应函数

  a,弹式菜单,ID不可编辑,按下去,弹出一个菜单项

  

  b,非弹式菜单,ID可编辑

  

  c,菜单响应命令消息的路由(顺序)

  

void CMainFrame::OnTestDemo()
{
// TODO: 在此添加命令处理程序代码
MessageBox(TEXT("Frame"));
}
void CTimerApp::OnTestDemo()
{
// TODO: 在此添加命令处理程序代码
AfxMessageBox(TEXT("app"));
}
void CTimerDoc::OnTestDemo()
{
// TODO: 在此添加命令处理程序代码
AfxMessageBox(TEXT("doc"));
}
void CTimerView::OnTestDemo()
{
// TODO: 在此添加命令处理程序代码
MessageBox(TEXT("view"));
}

菜单命令响应路由

视图--文档-框架-应用程序

  d,消息类型

    非标准消息

    命令消息WM_COMMAND:菜单处理函数选中;通告消息,点击按钮,处理函数CCmdTarget, CWnd子类能接收到非标准消息

    标准消息  WM_XXXX ,属性->消息  CWnd子类才能接收到标准消息,CCmdTarget不能接收标准消息

CMainFrame::CMainFrame()
{
// TODO: 在此添加成员初始化代码
m_bAutoMenuEnable = false;
}
int CMainFrame::OnCreate(LPCREATESTRUCT lpCreateStruct)
{
if (CFrameWnd::OnCreate(lpCreateStruct) == -)
return -; if (!m_wndToolBar.CreateEx(this, TBSTYLE_FLAT, WS_CHILD | WS_VISIBLE | CBRS_TOP | CBRS_GRIPPER | CBRS_TOOLTIPS | CBRS_FLYBY | CBRS_SIZE_DYNAMIC) ||
!m_wndToolBar.LoadToolBar(IDR_MAINFRAME))
{
TRACE0("未能创建工具栏\n");
return -; // 未能创建
} if (!m_wndStatusBar.Create(this))
{
TRACE0("未能创建状态栏\n");
return -; // 未能创建
}
m_wndStatusBar.SetIndicators(indicators, sizeof(indicators)/sizeof(UINT)); // TODO: 如果不需要可停靠工具栏,则删除这三行
m_wndToolBar.EnableDocking(CBRS_ALIGN_ANY);
EnableDocking(CBRS_ALIGN_ANY);
DockControlBar(&m_wndToolBar); // 标志
// 获取菜单
//获取主菜单
CMenu *menu = GetMenu();
// 获取子菜单
CMenu *fileMenu = menu->GetSubMenu();
// 标志新建
fileMenu->CheckMenuItem(, MF_BYPOSITION | MF_CHECKED); fileMenu->CheckMenuItem(ID_FILE_OPEN, MF_BYCOMMAND | MF_CHECKED); // 设置默认项 加粗,一个菜单项只有一个默认菜单
// ID FALSE
// 位置 TRUE
fileMenu->SetDefaultItem(ID_FILE_SAVE, FALSE);
fileMenu->SetDefaultItem(, TRUE); // 变灰
// 需要把CFrameWnd::m_bAutoMenuEnable 设置 false
fileMenu->EnableMenuItem(ID_FILE_PRINT, MF_BYCOMMAND | MF_DISABLED); // MF_GRAYED 与 MF_DISABLED等价 return ;
}

菜单更新机制

void CMainFrame::OnUpdateTest1A(CCmdUI *pCmdUI)
{
// TODO: 在此添加命令更新用户界面处理程序代码
if (m_update) {
pCmdUI->Enable(TRUE);
}
else {
pCmdUI->Enable(FALSE);
}
} void CMainFrame::OnTest1B()
{
// TODO: 在此添加命令处理程序代码
m_update = !m_update;
}
CMainFrame::CMainFrame()
{
// TODO: 在此添加成员初始化代码
m_bAutoMenuEnable = false;
}

// CMenuView 消息处理程序

void CMenuView::OnLButtonDown(UINT nFlags, CPoint point)
{
// TODO: 在此添加消息处理程序代码和/或调用默认值 // 获取主菜单
CMenu menu;
menu.LoadMenuW(IDR_MENU1);
// 获取子菜单
CMenu *subMenu = menu.GetSubMenu(); ClientToScreen(&point);
// 子菜单作为快捷菜单,右击菜单
subMenu->TrackPopupMenu(TPM_LEFTALIGN | TPM_LEFTBUTTON, point.x, point.y, this); CView::OnLButtonDown(nFlags, point);
}

点击

6,定时器实现渐变色

字体渐变

  1,定时器的使用

    a,设置定时器:CWnd::SetTimer()

    b,关闭定时器:CWnd::KillTimer()

    c,定时器消息:WM_TIMER

  2,视图类中的OnDraw()中,写字 CDC::TextOutW()

  3,指定区域写字:CDC::DrawText()

  4,让窗口失效,产生WM_PAINT ,间接调用OnDraw()函数:CWnd::Invalidate

// CTimerView 消息处理程序

int CTimerView::OnCreate(LPCREATESTRUCT lpCreateStruct)
{
if (CView::OnCreate(lpCreateStruct) == -)
return -; // TODO: 在此添加您专用的创建代码 // 设置定时器
// 1:定时器ID
// 200:时间间隔,ms
// NULL:使用系统默认的处理函数,每隔...毫秒,触发WM_TIMER
SetTimer(, , NULL); return ;
} void CTimerView::OnTimer(UINT_PTR nIDEvent)
{
// TODO: 在此添加消息处理程序代码和/或调用默认值 if (nIDEvent == ) {
static int i = ;
i++;
CString str;
str.Format(TEXT("%d"), i); if (i >= ) {
KillTimer();
}
MessageBox(str);
} CView::OnTimer(nIDEvent);
}
// CTimerView 消息处理程序

int CTimerView::OnCreate(LPCREATESTRUCT lpCreateStruct)
{
if (CView::OnCreate(lpCreateStruct) == -)
return -; // TODO: 在此添加您专用的创建代码 // 设置定时器
// 1:定时器ID
// 200:时间间隔,ms
// NULL:使用系统默认的处理函数,每隔...毫秒,触发WM_TIMER
SetTimer(, , NULL); return ;
} void CTimerView::OnTimer(UINT_PTR nIDEvent)
{
// TODO: 在此添加消息处理程序代码和/或调用默认值 if (nIDEvent == ) {
static int w = ;
w += ; CString str = TEXT("在此添加消息处理程序代码和/或调用默认值"); CClientDC dc(this);
CSize size = dc.GetTextExtent(str);
// 如果宽度大于字符串的宽度,重新开始
if (w > size.cx) {
w = ;
Invalidate();// 刷新窗口,相当于Qt里面的Update()
}
int x = ;
int y = ; // 黑色写一次
dc.TextOutW(x, y, str); // 设置字体颜色
dc.SetTextColor(RGB(, , )); CRect rect(x, y, x + w, y + size.cy);
dc.DrawText(str, &rect, DT_LEFT); } CView::OnTimer(nIDEvent);
}

字体渐变色

7,动态图标

在资源视图中添加4个icon文件

在框架 .h 文件中添加

private:
HICON icon[];

构造函数中加载资源

// CMainFrame 构造/析构

CMainFrame::CMainFrame()
{
// TODO: 在此添加成员初始化代码 // 加载图片
// 获取应用程序 AfxGetApp()
icon[] = AfxGetApp()->LoadIconW(IDI_ICON1);
icon[] = AfxGetApp()->LoadIconW(IDI_ICON2);
icon[] = AfxGetApp()->LoadIconW(IDI_ICON3);
icon[] = AfxGetApp()->LoadIconW(IDI_ICON4);
}

设置定时器

int CMainFrame::OnCreate(LPCREATESTRUCT lpCreateStruct)
{
if (CFrameWnd::OnCreate(lpCreateStruct) == -)
return -; if (!m_wndToolBar.CreateEx(this, TBSTYLE_FLAT, WS_CHILD | WS_VISIBLE | CBRS_TOP | CBRS_GRIPPER | CBRS_TOOLTIPS | CBRS_FLYBY | CBRS_SIZE_DYNAMIC) ||
!m_wndToolBar.LoadToolBar(IDR_MAINFRAME))
{
TRACE0("未能创建工具栏\n");
return -; // 未能创建
} if (!m_wndStatusBar.Create(this))
{
TRACE0("未能创建状态栏\n");
return -; // 未能创建
}
m_wndStatusBar.SetIndicators(indicators, sizeof(indicators)/sizeof(UINT)); // TODO: 如果不需要可停靠工具栏,则删除这三行
m_wndToolBar.EnableDocking(CBRS_ALIGN_ANY);
EnableDocking(CBRS_ALIGN_ANY);
DockControlBar(&m_wndToolBar); SetTimer(, , NULL); return ;
}

定时器处理函数

void CMainFrame::OnTimer(UINT_PTR nIDEvent)
{
// TODO: 在此添加消息处理程序代码和/或调用默认值 static int i = ; // 修改标题
SetClassLong(m_hWnd, GCL_HICON, (LONG)icon[i]);
i++;
if (i == ) {
i = ;
} CFrameWnd::OnTimer(nIDEvent);
}

https://docs.microsoft.com/en-us/windows/desktop/api/winuser/nf-winuser-setclasslonga

(六)绘图,文本编程,定时器,菜单,图标icon,消息类型的更多相关文章

  1. 测试开发【提测平台】分享14-Vue图标Icon几种用法并利用其一优化菜单

    微信搜索[大奇测试开],关注这个坚持分享测试开发干货的家伙. 回归主线更新,由于本次知识点只有一个,就不给思维导图了,在上系列测试平台开发实践中主要学习了页面直接的转跳方法和远程搜索的如何做,最终实现 ...

  2. visual Studio 2017 扩展开发(二)《菜单图标详解》

    在上一篇我们在菜单栏创建了一个菜单,菜单上显示了一个图标跟文本.那么我们自己创建的菜单如何修改自定义的菜单图标呢.下面娓娓道来..... 首先你要有一个图,创建一个32位的位图.这个位图的像素是16p ...

  3. HTML新特性--canvas绘图-文本

    一.html5新特性--canvas绘图-文本(重点) #常用方法与属性 -ctx.strokeText(str,x,y);   绘制描边文字(空心) str:绘制文本 x,y:字符串左上角位置(以文 ...

  4. Expo大作战(十一)--expo中的预加载和缓存资产(Preloading & Caching Assets),expo中的图标 (Icon)

    简要:本系列文章讲会对expo进行全面的介绍,本人从2017年6月份接触expo以来,对expo的研究断断续续,一路走来将近10个月,废话不多说,接下来你看到内容,讲全部来与官网 我猜去全部机翻+个人 ...

  5. QT 设置菜单图标

    目录 一.添加主窗口菜单 二.添加菜单图标 三.添加资源文件 四.使用资源文件 五.使用代码来添加菜单和图标     正文 一.添加主窗口菜单 1.新建Qt Gui应用,项目名称为myMainWind ...

  6. python---基础知识回顾(六)网络编程2(处理粘包)

    前戏: 之前在python---基础知识回顾(六)网络编程异步模块中提到过粘包现象,而且在使用twisted中提到过一种处理办法,按行接收lineReceived,当收到\r\n换行符时,才去缓冲区中 ...

  7. Ubuntu下增加eclipse菜单图标并配置java path(解决点击图标不能启动eclipse的问题)

    Ubuntu下增加eclipse菜单图标 Ubuntu的菜单图标在/usr/share/applications目录下. 1. 在/usr/share/applications目录下新建eclipse ...

  8. Jetpack Compose学习(3)——图标(Icon) 按钮(Button) 输入框(TextField) 的使用

    原文地址: Jetpack Compose学习(3)--图标(Icon) 按钮(Button) 输入框(TextField) 的使用 | Stars-One的杂货小窝 本篇分别对常用的组件:图标(Ic ...

  9. C#编程总结(六)异步编程

    C#编程总结(六)异步编程 1.什么是异步? 异步操作通常用于执行完成时间可能较长的任务,如打开大文件.连接远程计算机或查询数据库.异步操作在主应用程序线程以外的线程中执行.应用程序调用方法异步执行某 ...

随机推荐

  1. multipart/form-data(二进制流) 两种传输方式

    一.传统表单提交传输方式 <form id= "uploadForm" action= "url" method= "post" en ...

  2. 字典的setdefault()

    setdefault(key, default) 函数 ---有key获取值.没key设置 key:default dict.setdefault(key, default=None) 如果 key ...

  3. Java HttpServletRequest中getAttribute()方法和getParameter()区别

    一.ServletRequest接口 HttpServletRequest接口继承了ServletRequest接口,实现类通常代表一个实际的Http Request. Servlet容器负责创建一个 ...

  4. 怎样理解 display:none 和 visibility:hidden

    1. display: none会使元素节点 "消失" , 就像 死亡后灰飞烟灭了. 它是不占位置的. 2. visibility: hidden会使元素节点 "隐藏&q ...

  5. hdu 1502 大数dp

    对于每一个dp的问题 从其最优解的结构(分哪几种形式或者情况)入手 然后分析状态 这样就比较好找出状态转方程这里数据结构的选择很简单 顺序数组就可以 填充的方式顺序填充就可以 然后这道题目卡了我大数. ...

  6. Spring mvc 参数半丁

    http://blog.csdn.net/eson_15/article/details/51718633 众所周知,springmvc是用来处理页面的一些请求,然后将数据再通过视图返回给用户的,前面 ...

  7. elementUI中的loading

    先安装引入 import ElementUI from 'element-ui' import { Loading } from 'element-ui' 在vue的原型链上定义一个打开loading ...

  8. 如何对Nginx日志文件进行切割保存

    日积月累下,日志文件会越来越大,日志文件太大严重影响服务器效率,须要定时对日志文件进行切割. 切割的方式有按月切割.按天切割.按小时切割,一般都是按天切割. 那么如何进行切割呢? 思路: 创建日志文件 ...

  9. 流媒体服务器搭建 ffmpeg + nginx

    第一部分: mkdir ~/working 切换到~/working目录下 cd ~/working 获取nginx源码: wget http://nginx.org/download/nginx-1 ...

  10. 7.使用EXPLAIN 来分析SQL和表结构_2

    possible_keys    ------   显示可能应用在这张表的索引,一个或多个 查询涉及到的字段上若存在索引,则该索引将被列出,但不一定被实际查询使用 key   ------   实际使 ...