MFC_基本知识
1.创建窗口的四大步骤(这是必须掌握的) 整体框架
- 设计窗口类
- 注册窗口类
- 创建窗口
- 显示窗口
#include "windows.h"//包含头文件 LoadCursor,TextOut 等函数 #include "stdio.h"//包含 sprintf,printf 等函数 LRESULT CALLBACK MyProc(...);//声明回调函数 int WINAPI WinMain() { WNDCLASS wndcls;//设计窗口类 wndcls.hcursor=LoadCursor();//初始化 .... RegisterClass(&wndcls);//注册窗口类 hwnd=CreateWindow(...);//创建窗口 ShowWindow(..);//显示窗口 UpdateWindow(..); MSG msg;//定义消息结构体 while(GetMessage(...))//消息循环 { ... } return 0; } LRESULT CALLBACK MyProc(...)//实现回调函数 { switch(uMsg) { case WM_CHAR: break; ... } }
2.基本概念
变量的生命周期:可以认为出了包含它的大括号,这个变量的生命周期结束。所以全局变量的声明位于所有大括号之外。但是用 new 声明的变量和用 static 声明的变量除外
野指针:将指针指向的变量的内存释放后,此指针即变成野指针!如何避免野指针?答:将此指针指向 NULL 即可。p=NULL;
#include <xxx.h>与#include "xxx.h"的区别:<>不查找运行时目录,""查找运行时目录!
3.如何防止类的重复定义?
用#inndef Point_H_H
#define Point_H_H
class Point{};
#endif 来防止
4.强制类型转换注意事项
强制类型转换。 如果 CFish 从 CAnimal 派生而来。 则可以将鱼的对象转换为 CAnimal 的对
象,而反之则不行。从现实中理解也是正常的,鱼可以是动物,而动物却不是鱼。再如 int
可以强制转换成 char 型。而反之则出错
5.在 main 或 WinMain 之前,全局变量已经被分配内存并初始化了。
6 MFC 大致流程
CTestApp theApp;//构造全局对象 WinMain() { AfxWinMain();//调用下面的函数 } AfxWinMain() { pThread->Initinstance();//初始化工作和注册窗口类,窗口显示和更新 pThread->Run();//消息循环 } 而在 BOOL CTestApp::InitInstance()中的代码 CSingleDocTemplate* pDocTemplate; pDocTemplate = new CSingleDocTemplate( IDR_MAINFRAME, RUNTIME_CLASS(CTestDoc), RUNTIME_CLASS(CMainFrame), // main SDI frame window RUNTIME_CLASS(CTestView)); AddDocTemplate(pDocTemplate); 完成了将这三个类关联起来的工作
7.消息响应
消息响应会在 3 处修改代码,1 处是在头文件中,
1 2 //{{AFX_MSG(CDrawView) 3 afx_msg void OnLButtonDown(UINT nFlags, CPoint point); 4 afx_msg void OnLButtonUp(UINT nFlags, CPoint point); 5 afx_msg void OnMouseMove(UINT nFlags, CPoint point); 6 //}}AFX_MSG 7 DECLARE_MESSAGE_MAP() 8 另一处是 cpp 文件的 begin MessageMap 和 End MessageMap 之间, 9 BEGIN_MESSAGE_MAP(CDrawView, CView) 10 //{{AFX_MSG_MAP(CDrawView) 11 ON_WM_LBUTTONDOWN() 12 ON_WM_LBUTTONUP() 13 ON_WM_MOUSEMOVE() 14 //}}AFX_MSG_MAP 15 // Standard printing commands 16 ON_COMMAND(ID_FILE_PRINT, CView::OnFilePrint) 17 ON_COMMAND(ID_FILE_PRINT_DIRECT, CView::OnFilePrint) 18 ON_COMMAND(ID_FILE_PRINT_PREVIEW, CView::OnFilePrintPreview) 19 END_MESSAGE_MAP() 20 最后是要有函数实现的代码。 21 void CDrawView::OnLButtonDown(UINT nFlags, CPoint point) 22 { 23 // TOD Add your message handler code here and/or call default 24 m_ptOrigin=m_ptOld=point; 25 m_bDraw=TRUE; 26 CView::OnLButtonDown(nFlags, point); 27 }
8.画线
2 1)API 函数方法画线用 HDC
3 2)用 CDC 类成员函数画线。此时别忘记 ReleaseDC
4 3)用 CClientDC
5 4)用 CWindowDC,用它甚至可以整个屏幕区域画线。
1 画线:定义一个成员变量保存 mouseDown 的点 m_Point 2 1)API 函数方法画线用 HDC 3 2)用 CDC 类成员函数画线。此时别忘记 ReleaseDC 4 3)用 CClientDC 5 4)用 CWindowDC,用它甚至可以整个屏幕区域画线。 6 下面是上面 4 种方法的代码 7 /*HDC hdc; 8 hdc=::GetDC(m_hWnd); 9 MoveToEx(hdc,m_ptOrigin.x,m_ptOrigin.y,NULL); 10 LineTo(hdc,point.x,point.y); 11 ::ReleaseDC(m_hWnd,hdc);必须成对使用。*/ 12 /*CDC *pDC=GetDC(); 13 pDC->MoveTo(m_ptOrigin); 14 pDC->LineTo(point); 15 ReleaseDC(pDC);必须成对使用。*/ 16 //CClientDC dc(this); 17 /*CClientDC dc(GetParent()); 18 dc.MoveTo(m_ptOrigin); 19 dc.LineTo(point);此处不需要 ReleaseDC,因为 CClientDC 会自动释放 DC*/ 20 //CWindowDC dc(this); 21 //CWindowDC dc(GetParent()); 22 /*CWindowDC dc(GetDesktopWindow());//此时可以在整个屏幕上画线。 23 dc.MoveTo(m_ptOrigin); 24 dc.LineTo(point);*/ 25 /*CPen pen(PS_DOT,1,RGB(0,255,0)); 26 CClientDC dc(this); 27 CPen *pOldPen=dc.SelectObject(&pen); 28 dc.MoveTo(m_ptOrigin); 29 dc.LineTo(point); 30 dc.SelectObject(pOldPen);*/