MFC基础知识3

1.简单绘图应用
    1.1 画一条直线
        1.1.1 鼠标按下和抬起
        1.1.2 创建画家对象CClientDc;例如 CClientDc dc(this);dc.xxxx
        1.1.3 起点:CDC::MoveTo 和终点:CDC::LineTo
        1.1.4 选中所属类->右击->添加变量

                

                


    1.2 画刷、画笔的使用
        1.2.1 定义画家
        1.2.2 定义画刷(画笔)CBrush,CPen
        1.2.3 把画笔交给画家,用CDC::SelectObject
        1.2.4 画刷:单色,样式,位图
    1.3 写字,CFont的使用
    1.4 位图加载

// CMy02DrawView 绘图

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

	//1.2.1 定义画家
	//	1.2.2 定义画刷(画笔)CBrush,CPen
	//	1.2.3 把画笔交给画家,用CDC::SelectObject

	//ps_dash:虚线  1:线宽
	CPen pen(PS_DASH, 1, RGB(255, 0, 0));
	//pDC->SelectObject(&pen);

	//返回设置前状态
	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, 120, 240, 240);

	//字体使用
	CFont font;
	//500:字体宽度,0.1倍
	// TEXT("楷体"):字体风格
	font.CreatePointFont(500, TEXT("楷体"));
	//使用字体,字体交给画家
	pDC->SelectObject(&font);
	pDC->TextOutW(100, 100, TEXT("hello 12"));
	// TODO: 在此处为本机数据添加绘制代码
}



// CMy02DrawView 消息处理程序


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

	CView::OnLButtonDown(nFlags, point);
}

// 鼠标抬起
void CMy02DrawView::OnLButtonUp(UINT nFlags, CPoint point)
{
	// TODO: 在此添加消息处理程序代码和/或调用默认值
#if 0
//创建画家 指定绘图设备
	CClientDC dc(this);
	dc.MoveTo(m_myPoint);
	dc.LineTo(point);
#endif
	m_isPress = false;

	CView::OnLButtonUp(nFlags, point);
}


void CMy02DrawView::OnMouseMove(UINT nFlags, CPoint point)
{
	// TODO: 在此添加消息处理程序代码和/或调用默认值
	if (m_isPress == true)
	{
		//创建画家 指定绘图设备
		CClientDC dc(this);
		dc.MoveTo(m_myPoint);
		dc.LineTo(point);

		//终点作为起点
		m_myPoint = point;
	}
	CView::OnMouseMove(nFlags, point);
}


2.文本编辑器
    2.1 创建插入符CWnd::CreateSolidCaret ()-----视图创建好之后才创建插入符,放在OnCreate()中
        2.1.1 创建CWnd::CreateSolidCaret ()
        2.1.2 显示CWnd::ShowCaret ()
        2.1.3 插入符的高度是根据字体的高度来确定
            获取字体信息CDC::GetTextMetrics ()
        2.1.4 设置插入符位置Cwnd::SetCaretPos ()----没有用对象调,是继承CWnd的,直接用

//窗口创建后自动调用
int CMy03EditorView::OnCreate(LPCREATESTRUCT lpCreateStruct)
{
	if (CView::OnCreate(lpCreateStruct) == -1)
		return -1;

	// TODO:  在此添加您专用的创建代码

	//获取字体信息
	CClientDC dc(this);
	TEXTMETRIC tm;//字体信息结构体
	dc.GetTextMetrics(&tm);

	//继承于CWnd
	CreateSolidCaret(tm.tmAveCharWidth/8,tm.tmHeight);//创建插入符
	ShowCaret();//显示
	return 0;
}


    2.2 在字符消息处理函数中写字
        2.2.1 写字CDC::TextOutW ()
        2.2.2 获取字符串的尺寸信息CDC::GetTextExtent ()
        2.2.3 截取字符串(CString)左边指定长度的字符str = str. Left (str .GetIength() - 1) ;


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

	SetCaretPos(point);//移动插入符
	//保存点击坐标
	m_point = point;
	
	m_str = TEXT("");//将之前的所敲入的字符清空
	m_str.Empty();
		
	CView::OnLButtonDown(nFlags, point);
}

//点击键盘,启动调用
void CMy03EditorView::OnChar(UINT nChar, UINT nRepCnt, UINT nFlags)
{
	// TODO: 在此添加消息处理程序代码和/或调用默认值

	CClientDC dc(this);

	if (nChar==VK_RETURN)//按下换行
	{
		m_str.Empty();

		//获取字体信息
		CClientDC dc(this);
		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, m_str);

		//去掉最后一个字符
		m_str = m_str.Left(m_str.GetLength() - 1);
		//恢复原来颜色

		dc.SetTextColor(oldColor);

	}
	else {
		m_str += (TCHAR)nChar;
	}

	CSize size = dc.GetOutputTextExtent(m_str);//获取敲入的字符串长度
	int x = m_point.x + size.cx;
	int y = m_point.y;


	SetCaretPos(CPoint(x, y));

	dc.TextOutW(m_point.x, m_point.y, m_str);
	CView::OnChar(nChar, nRepCnt, nFlags);
}


3.字体渐变
    3.1 定时器的使用(重点)
        3.1.1 设置定时器: CWnd::SetTimer ()
        3.1.2 关闭定时器: CWnd::KillTimer ()
        3.1.3 定时器消息: WM_ TIMER
    3.2 视图类中的OnDraw()中,写字CDC::TextOutw ()
    3.3 指定区域写字:CDC::DrawText ()
    3.4 让窗口失效,产生WM_ PAINT,间接调用OnDraw()函数: CWnd::Invalida

int CMy04TimeoutView::OnCreate(LPCREATESTRUCT lpCreateStruct)
{
	if (CView::OnCreate(lpCreateStruct) == -1)
		return -1;

	// TODO:  在此添加您专用的创建代码

	//设置定时器;  1:定时器ID   500:时间间隔,单位毫秒  NULL: 使用系统默认处理函数,每隔500毫秒触发该信号
	SetTimer(1,220,NULL);

	return 0;
}


void CMy04TimeoutView::OnTimer(UINT_PTR nIDEvent)
{
	// TODO: 在此添加消息处理程序代码和/或调用默认值
	if (nIDEvent == 1)
	{
		static int w = 0;
		w += 5;
		CString str = TEXT("塑造自己的过程很痛,但是你可以得到一个更好的自己");
		//获取字符串的长度(宽度)
		CClientDC dc(this);
		CSize size = dc.GetTextExtent(str);
		//如果宽度大于字符串宽度,重新开始
		if (w > size.cx)
		{
			w = 0;
			//重新刷新窗口
			Invalidate();
		}
		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);
}


4.菜单的相关操作
    4.1 菜单的命令响应函数
        4.1.1 弹式菜单,ID不可编辑,按下去,弹出一一个菜单项
        4.1.2 非弹式菜单,ID可编辑
        4.1.3 菜单响应命令消息的路由(顺序)    
        4.1.4 消息类型:    
                非标准消息
                WM_ COMMAND,命令消息、通告消息,CCmdTarget、 CWnd子类子类能接收到非标准消息    
                WM XXXX ,标准消息,CWnd子类才能接收到标准消息
                命令消息WM_COMMAND: 菜单处理函数选中
                标准消息:在属性->消息中 设定
                通告消息:点击按钮,运行处理函数
                CWnd可以接收任何消息,CCmdTarget不能接收标准消息

    4.2 菜单相关静态操作
        4.2.1 在框架类中进行相应操作,在OnCreate()中实现    
        4.2.2 获取菜单栏: CWnd::GetMenu()///如果要在View中使用应该先创建菜单项,通过菜单ID加载菜单
        4.2.3 获取菜单栏中的子菜单:CMenu::GetSubMenu
            4.2.3.1 标志菜单: CMenu::CheckMenuItem
                      ME_ BYPOSITION:通过位置
                      ME RVCOMMAND:通过ID
            4.2.3.2 设置默认菜单: CMenu::SetDe faultItem,
                    注意:一个菜单项只能设置一一个默认菜单
            4.2.3.3 禁用菜单: CMenu::EnableMenultem
                    注意:需要把CFrameWnd: :m bAutoMenuEnable成员变量设置为FALSE
            4.2.3.4 分隔线也算一个
        4.2.4 移除菜单CWnd::SetMenu
                SetMenu (NULL) ;
        4.2.5 装载菜单
            4.2.5.1 创建菜单CMenu::LoadMenu
            4.2.5.2 设置菜单CWnd::SetMenu
            4.2.5.3 从CMenu对象中分离windows菜单CMenu::Detach
        4.2.6 菜单命令更新机制(要掌握)
        4.2.7 快捷菜单,弹出菜单(一定要新建菜单,不能使用框架类的主菜单)
            由于鼠标点击的区域是在视图区域,所以需要在视图类中处理
            4.2.7.1 处理鼠标右击事件WM RBUTTONDOWN
            4.2.7.2 获取所需的子菜单
            4.2.7.3 弹出菜单项CMenu::TrackPopupMenu
            4.2.7.4 客户区坐标转屏幕坐标: CWnd::ClientToScreen

int CMainFrame::OnCreate(LPCREATESTRUCT lpCreateStruct)
{
	if (CFrameWnd::OnCreate(lpCreateStruct) == -1)
		return -1;

	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 -1;      // 未能创建
	}

	if (!m_wndStatusBar.Create(this))
	{
		TRACE0("未能创建状态栏\n");
		return -1;      // 未能创建
	}
	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(0);

	//标志“新建”,第一个参数由MF_BYPOSITION 决定
	fileMenu->CheckMenuItem(0, MF_BYPOSITION | MF_CHECKED);

	//标志“新建”,第一个参数由MF_BYCOMMAND决定
	fileMenu->CheckMenuItem(ID_FILE_OPEN, MF_BYCOMMAND | MF_CHECKED);

	//设置默认项, 加粗,一个菜单只有一个默认菜单
			//flase:用的是ID
				//true:用的是位置
	fileMenu->SetDefaultItem(ID_FILE_SAVE, false);
	/*fileMenu->SetDefaultItem(2, true);*/

	//变灰操作
	//需要把CFrameWnd::m_bAutoMenuEnable 设置 false
	fileMenu->EnableMenuItem(5, MF_BYPOSITION | MF_DISABLED|MF_GRAYED);

	//移除菜单项
	SetMenu(NULL);

	//加载菜单

	CMenu menu2;
	
	//加载菜单
	menu2.LoadMenuW(IDR_MENU1);
	
	SetMenu(&menu2);

	//分离 ,
	menu2.Detach();  

	return 0;
}



// CMy05View 消息处理程序

//视图鼠标左键按下
void CMy05View::OnLButtonDown(UINT nFlags, CPoint point)
{
	// TODO: 在此添加消息处理程序代码和/或调用默认值
	//获取主菜单

	//CMenu *menu = GetMenu();

	//创建菜单项
	CMenu menu;
	menu.LoadMenuW(IDR_MENU1);

	//获取子菜单

	CMenu *subMenu = menu.GetSubMenu(0);


	ClientToScreen(&point);
	//子菜单作为左击菜单--快捷菜单
	subMenu->TrackPopupMenu(TPM_LEFTALIGN | TPM_LEFTBUTTON,
		point.x, point.y, this);

	CView::OnLButtonDown(nFlags, point);
}

    4.3 菜单相关动态操作
        4.3.1 创建空菜单CMenu::CreateMenu
        4.3.2 追加弹式菜单CMenu::AppendMenu(MF_ POPUP, )
            每个菜单都有-一个菜单句柄: CMenu::m_hMenu
            重画菜单条: CWnd::DrawMenuBar
        4.3.3 追加普通菜单 CMenu::AppendMenu (MF_ STRING, )
        4.3.4 插入菜单 CMenu::InsertMenu
        4.3.5 删除菜单 CMenu::DeleteMenu
5.动态图标
    5.1 定时器: CWnd::SetTimer
        5.1.1 定时器信号: WM TIMER
        5.1.2 设置定时器应该放在OnCreate()
    5.2 加载自定义图标(WinAPI) : LoadIcon ()///或者用
        5.2.1 将资源ID转换为字符串 MAKEINTRESOURCE ()
        5.2.2 获取应用程序实例:
                    AfxGetInstanceHandle ()
                    AfxGetApp()->m_hInstance
    5.3 设置图标(WinAPI) SetClassLong ()
             窗口句柄: CWnd::m_hWnd



// CMainFrame 消息处理程序


void CMainFrame::OnTimer(UINT_PTR nIDEvent)
{
	// TODO: 在此添加消息处理程序代码和/或调用默认值

	static int i = 0;

	//修改窗口左上角图标
	SetClassLong(m_hWnd, GCLP_HICON, (LONG)icon[i]);
	i++;
	if (i == 2)
	{
		i = 0;
	}

	CFrameWnd::OnTimer(nIDEvent);
}

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值