孙鑫MFC视频 笔记
孙鑫VC++讲座笔记
孙鑫VC++讲座笔记-(1)Windows程序内部运行机制1,windows程序设计是种事件驱动方式的程序设计,主要基于消息的。
当用户需要完成某种功能时,需要调用OS某种支持,然后OS将用户的需要包装成消息,并投入到消息队列中,最后应用程序从消息队列中取走消息并进行响应。
2,消息结构:typedef struct tagMSG { // msgHWND hwnd; //接收消息的窗口句柄。
和哪个窗口相关联。
UINT message; //消息标识。
消息本身是什么。
WPARAM wParam; //消息的附加信息。
具体取决于消息本身。
LPARAM lParam;DWORD time; //消息投递时间。
POINT pt; //消息投递时,光标在屏幕上的位置。
} MSG;3,消息队列:每个应用程序OS都为它建立一个消息队列,消息队列是个先进先出的缓冲区,其中每个元素都是一个消息,OS将生成的每个消息按先后顺序放进消息队列中,应用程序总是取走当前消息队列中的第一条消息,应用程序取走消息后便知道用户的操作和程序的状态,然后对其处理即消息响应,消息响应通过编码实现。
4,使用VC编程除了良好的C基础外还需要掌握两方面:一,消息本身。
不同消息所代表的用户操作和应用程序的状态。
二,对于某个特定的消息来说,要让OS执行某个特定的功能去响应消息。
5,Window程序入口:int WINAPI WinMain(HINSTANCE hInstance, // 当前事例句柄。
HINSTANCE hPrevInstance, // 先前事例句柄。
LPSTR lpCmdLine, // 命令行指针int nCmdShow // (窗口)显示的状态);说明:WinMain函数是Windows程序入口点函数,由OS调用,当OS启动应用程序的时候,winmain函数的参数由OS传递的。
6,创建一个完整的窗口需要经过下面四个操作步骤:一,设计一个窗口类;如:WNDCLASS wndcls;二,注册窗口类;如:RegisterClass(&wndcls);三,创建窗口;如:CreateWindow(),CreateWindowEX();四,显示及更新窗口。
孙鑫VC++
第六讲菜单的结构Getmenu Cmenu::checkmenuitem索引号玉菜单项的ID去访问缺省菜单项(粗体显示)的创建Cmenu::SetDefaultItem 长的分隔栏算1
缺省菜单项一个菜单中只能有一个选项
图形标记菜单的创建Cmenu::SetMenuItemBitMap 位图把底色变掉跟变小函数GetSystemMetrics获取系统信息下面有图形标记的长度跟宽度SetMenu移走菜单,设置为空menu。
Loadmenu(ID号)
图标与菜单项关联只需要设置成相同的ID号
右键弹出菜单功能:工程-增加到工程-组件与控件
DrawMenuBar重画菜单
第七讲对话框
插入对话框insert-resource-dialog 或者点击键dialog的ID:dialog1
CDialog是类,在屏幕上显示,有模态(应用程序执行前必须被关闭掉)跟非模态的(显示对话框时可以转而运用其他)
模态的创建:有函数DoModle,enddialog关闭对话框静态文本框的处理
对话框完成加减的功能
第八讲基于对话框的应用程序。
孙鑫VC学习笔记第9课
OnCreate()中
SetClassLong(m_hWnd,GCL_HBRBACKGROUND,(LONG)GetStockObject(BLACK_BRUSH));
SetClassLong(m_hWnd,GCL_HCURSOR,(LONG)LoadCursor(NULL,IDC_HELP));
2.创建一个不断变化的图标。用定时器和SetClassLong完成
a.准备三个图标文件,放在RES文件夹,Insert->Resource-三个图标,
b.在CMainFrame中增加图标句柄数组,m_hIcons[3]
m_progress.Create(WS_CHILD | WS_VISIBLE | PBS_SMOOTH,
rect,&m_wndStatusBar,123);
m_progress.SetPos(50);
}
最后在OnCreate中调用 PostMessage(UM_PROGRESS);//不能用SendMessage()
然后将其初始化
c.然后在定时器中实现
3.工具栏的编程
a.加入分隔符的方法,向右拖动即可;
b.删除按纽的方法,拖出即可。
4.创建一个新的工具栏的方法
a.插入一个工具栏,画出其图形。
b.在头文件中,定义CToolBar m_newToolBar
c.在MainFrm.cpp的OnCreate()中调用
GetParent()->GetDescendantWindow(AFX_IDW_STATUS_BAR)->SetWindowText(str);
MFC VC WIN7画线延迟(画线不显示)
WIN7使用LineT o()画线延迟(不立即显示)参照孙鑫的<<VC++ 教学>>第四课视频在使用Visual Stidio使用MoveTo()和LineTo()进行画线时,发现画出来的线条不会立即显示.环境:Windows7旗舰版,VS2012实际上是WIN7 + 透明主题+ 屏幕无变化 不显示程序的功能是:鼠标左键按下不放,将移动到另一个位置后放开左键, 然后在这两个位置间画出一条直线.具体如下:工程名是Draw1. 利用MFC建立一个基本的单文档应用程序2. 在CDrawView类中加入私有变量CPoint m_ptOrign 用来保存鼠标左键按下时光标的位置3. 使用类向导加入对鼠标左键按下消息WM_LBUTTONDOWN 的处理函数, 在里面保存左键按下时光标的位置:void CDraw2View::OnLButtonDown(UINT nFlags, CPoint point){// TODO: 在此添加消息处理程序代码和/或调用默认值m_ptOrign = point;CView::OnLButtonDown(nFlags, point);}4. 使用类向导加入对鼠标左键按下消息WM_LBUTTONUP 的处理函数, 在里面画线:void CDraw2View::OnLButtonUp(UINT nFlags, CPoint point){// TODO: 在此添加消息处理程序代码和/或调用默认值CDC *pDC = GetDC();pDC ->MoveTo( m_ptOrign );pDC ->LineTo( point );ReleaseDC( pDC );/*HDC hdc=::GetDC(m_hWnd);MoveToEx(hdc,m_point.x,m_point.y,NULL);LineTo(hdc,point.x,point.y);::ReleaseDC(m_hWnd,hdc);*//*CClientDC dc(this);dc.MoveTo(m_point);dc.LineTo(point);*/CView::OnLButtonUp(nFlags, point);}孙老师视频里, 一画就显示一根直线, 还可以画好几根,自己的程序画完后直线显示不出来,除非画完线后再点一下鼠标左键或者鼠标指到菜单栏或者工具栏的选项才可以显示.解决方法:1.把Windows的主题改为Windows经典2.画完线后加一个输出pDC->TextOut( 0,0, _T(" "));。
孙鑫VC++讲座笔记-(6)菜单编程_
1,弹出菜单(Pop-up)是不能用来作命令响应的。
1,弹出菜单(Pop-up)是不能用来作命令响应的。
2,MFC中菜单项消息如果利用ClassWizard来对菜单项消息分别在上述四个类中进行响应,则菜单消息传递顺序:View类--Doc类--CMainFrame类--App类。
菜单消息一旦在其中一个类中响应则不再在其它类中查找响应函数。
具体:当点击一个菜单项的时候,最先接受到菜单项消息的是CMainFrame框架类,CMainFra me框架类将会把菜单项消息交给它的子窗口View类,由View类首先进行处理;如果View 类检测到没对该菜单项消息做响应,则View类把菜单项消息交由文档类Doc类进行处理;如果Doc类检测到Doc类中也没对该菜单项消息做响应,则Doc类又把该菜单项消息交还给View类,由View类再交还给CMainFrame类处理。
如果CMainFrame类查看到CMainFrame 类中也没对该消息做响应,则最终交给App类进行处理。
3,消息的分类:标准消息,命令消息,通告消息。
[标准消息]:除WM_COMMAND之外,所有以WM_开头的消息。
[命令消息]:来自菜单、加速键或工具栏按钮的消息。
这类消息都以WM_COMMAND呈现。
在MFC中,通过菜单项的标识(ID)来区分不同的命令消息;在SDK中,通过消息的w Param参数识别。
[通告消息]:由控件产生的消息,例如,按钮的单击,列表框的选择等均产生此类消息,为的是向其父窗口(通常是对话框)通知事件的发生。
这类消息也是以WM_COMMAND形式呈现。
说明:1)从CWnd派生的类,都可以接收到[标准消息]。
2)从CCmdTarget派生的类,都可以接收到[命令消息]和[通告消息]。
4,一个菜单拦可以有若干个子菜单,一个子菜单又可以有若干个菜单项等。
对菜单栏的子菜单由左至右建立从0开始的索引。
对特定子菜单的菜单项由上至下建立了从0开始的索引。
孙鑫VC学习笔记
孙鑫孙鑫VC++视频笔记列表(全)简介第一课Windows程序内部运行机制第二课MFC程序框架的剖析第三课MFC消息映射机制和DC的获取第四课简单字处理软件第五课菜单编程第六课对话框编程1第七课对话框编程2第八课MFC中各类指针的获取第九课应用程序外观修改第十课图形绘制与通用对话框第十一课图形保存和重绘第十二课文件操作第十三课文档和串行化第十四课网络编程第十五课多线程和简单聊天室制作第十六课线程同步与异步套接字编程第十七课进程间通信第十八课 ActiveX 控件第十九课动态链接库第二十课 Hook钩子函数第0章简介Lesson1:Windows程序运行原理及程序编写流程,窗口产生过程,句柄原理,消息队列,回调函数,窗口关闭与应用程序退出的工作关系,使用VC++的若干小技巧,stdcall与cdecl 调用规范的比较,初学者常犯错误及注意事项。
Lesson2:C++经典语法与应用,类的编写与应用,构造与析构函数,函数的重载,类的继承,函数覆盖,基类与派生类的构造函数、析构函数先后调用顺序,如何在派生类构造函数中向基类的构造函数传递参数,this成员变量,类型转换的内幕,虚拟函数与多态性,引用和指针变量的区别与共同处。
VC工程的编译原理与过程,将工程中不同的类拆分到不同的文件中,每一个类由一个.h和.cpp文件共同完成,头文件重复定义问题的解决,培养了学员良好的编程习惯,也为以后分析MFC AppWizard生成的工程奠定了良好基础。
Lesson3:讲述MFC AppWizard的原理与MFC程序框架的剖析。
AppWizard是一个源代码生成工具,是计算机辅助程序设计工具,WinMain在MFC程序中是如何从源程序中被隐藏的,theApp全局变量是如何被分配的,MFC框架中的几个类的作用与相互关系,MFC框架窗口是如何产生和销毁的,对窗口类的PreCreateWidow和OnCreate两个函数的着重分析,Windows窗口与C++中的CWnd类的关系。
孙鑫VC教学视频学习笔记1-8
2:路径层(Path)的概念!
3: 我试图写一个 MyNotePad 的小应用程序,已完成的任务有:设置自定义的图标,窗口背景,光标.在窗口 显示插入符,并让插入符随鼠标的点击而显示在相应的位置,用 TextOut 完成串的输入,显示,并保存于一个 CString 对象中,可是我发现显示文本的背景色(默认是白色)与自定义的窗口背景色不一致,我先是用如下 的代码: hdc.SetBkColor(hdc.GetBkColor)); 来设置文本背景色,可是背景色仍然是默认的白色,我不停地想是不是 SetBkcolor()不可以用,但当时真是 笨,明明用 GetBkColor()取到的就是文本的背景色,你再设置回去,那不就相当于什么都没做嘛!当时脑子 中充斥的想法是以为 GetBkColor()取到的是窗口的背景色呢!呵呵,笨!另外,hdc.SetTextColor ()可以设 置文本的颜色.但还有一个问题:下面是我处理退格键的代码: void CMyNotePadView::OnChar(UINT nChar, UINT nRepCnt, UINT nFlags) { // TODO: Add your message handler code here and/or call default if(0x0d==nChar) { // m_ptOrigin } else if(0x08==nChar) { CClientDC hdc(this); hdc.SetBkColor(RGB(208,221,238)); hdc.SetTextColor(RGB(208,221,238)); hdc.TextOut(m_ptOrigin.x,m_ptOrigin.y,m_strLine); m_strLine=m_strLine.Left(m_strLine.GetLength()-1); } else { m_strLine+=nChar; } ::InvalidateRect(m_hWnd,NULL,FALSE); CView::OnChar(nChar, nRepCnt, nFlags); } 为了应付窗口切换时的重绘,我把输出工作放在了 OnDraw()函数中了,别的都是正常的,可当退格的时候
孙鑫VC视频笔记_掌握CDC的文字处理程序的编写
1 首先在view类捕获WM_CHAR消息.
2 为了保存字符,我们去定义一个CString的对象,专门用来存储我们输入的字符。在view类增加一个成员变量,类型CString,名称m_strLine,权限public。
3 在view的构造函数,初始化CString的对象,把它赋一个空,先给它清空,m_strLine="";
//要获取一个字体的高度,要用到GetTextMetrics,所以首先的定义一个DC
CClientDC dc(this);//首先的定义一个DC
TEXTMETRIC tm;//定义TEXTMETRIC结构体,GetTextMetrics这个函数要用到
dc.GetTextMetrics(&tm);//获取字体的高度
根据当前设备描述表(DC)字体的来自小,来改变插入符。 要实现以上功能,首先要获取当前DC字体(文本)的信息,要获取文本的信息,可以用GetTextMetrics。
BOOL GetTextMetrics( LPTEXTMETRIC lpMetrics ) const;
Points to the TEXTMETRIC structure that receives the metrics
那么就要在响应WM_PAINT的时候,将我们的文字再次输出。
在view中,就给我们提供了OnDraw函数,利用这个函数。可以解决以上的问题。也就是说想要我们,输出的文字,图型,在view类中,始终都被看到的话,就可以在OnDraw这个函数中处理。
另外,在函数被调用的时候,应用程序框架类,构造了一个CDC的指针pDC传进来[OnDraw(CDC* pDC)],可以方便我们不用构造DC了。
孙鑫老师笔记18课
Lesson18 Active控件容器和服务器程序容器应用程序时可以嵌入或链接对象的应用程序。
Word就是容器应用程序。
服务器应用程序是创建对象并且当对象被双击时,可以被启动的应用程序。
Excel 就是服务器应用程序。
ActiveX控件不能独立运行,它必须被嵌入容器应用程序中,和容器应用程序一起运行。
Dispatch maps调度映射,主要是MFC提供让外部应用程序可以访问控件的属性和方法Event maps事件映射,控件向包含它的容器发送事件通知接口是外部程序和控件进行通信的协议,可以把接口看作是函数的集合,外部程序通过借口提供的方法,去访问控件的属性和方法。
接口中所定义的所有函数都是纯虚函数regsvr32 ...注册控件 regsvr32 /u....卸载控件STDAPI DllRegisterServer(void)将控件信息写入注册表中STDAPI DllUnregisterServer(void)卸载注册信息。
制作一个时间控件,在void CClockCtrl::OnDraw(CDC* pdc, const CRect& rcBounds,const CRect& rcInvalid)中添加以下代码:CBrush brush(TranslateColor(GetBackColor()));pdc->FillRect(rcBounds,&brush);pdc->SetBkMode(TRANSPARENT);pdc->SetTextColor(TranslateColor(GetForeColor()));//为控件设置属性,必须在MFC ClassWizared中为控件添加属性,上面几 //行代码才有用CTime time=CTime::GetCurrentTime();CString str=time.Format("%H : %M : %S");pdc->TextOut(0,0,str);这样就能做出一个静态的时间控件,如果我们想使控件实时显示时间,需要添加两个消息响应函数 WM_CREATE,WM_TIMER.代码:int CClockCtrl::OnCreate(LPCREATESTRUCT lpCreateStruct){if (COleControl::OnCreate(lpCreateStruct) == -1)return -1;// TODO: 在此添加您专用的创建代码SetTimer(1,1000,NULL);return 0;}void CClockCtrl::OnTimer(UINT nIDEvent){// TODO: 在此添加消息处理程序代码和/或调用默认值Invalidate(); //立即引起窗口重绘//也可以使用InvalidateControl(); //强制窗口重绘,效果相同COleControl::OnTimer(nIDEvent);}要修改控件的背景色前景色和字体颜色在OnDraw中添加CBrush brush(TranslateColor(GetBackColor()));pdc->FillRect(rcBounds,&brush);pdc->SetBkMode(TRANSPARENT);pdc->SetTextColor(TranslateColor(GetForeColor()));ActiveX控件的四种属性Stock:为每个控件提供的标准属性,如字体或颜色。
孙鑫VC学习笔记第14课
addrSrv.sin_addr.S_un.S_addr=inet_addr("127.0.0.1");
addrSrv.sin_family=AF_INET;
addrSrv.sin_port=htons(6000); sendto(sockClient,"Hello",strlen("Hello")+1,0,
char recvBuf[100];
recv(sockConn,recvBuf,100,0);
printf("%s\n",recvBuf);
closesocket(sockConn);//关闭套接字。等待另一个用户请求
}
}客户端代码如下:
#include <Winsock2.h>
addrSrv.sin_addr.S_un.S_addr=htonl(INADDR_ANY);//转换Unsigned short为网络字节序的格式
addrSrv.sin_family=AF_INET;
addrSrv.sin_port=htons(6000); bind(sockSrv,(SOCKADDR*)&addrSrv,sizeof(SOCKADDR));
char sendBuf[100];
sprintf(sendBuf,"Welcome %s to ",
inet_ntoa(addrClient.sin_addr));
//用返回的套接字和客户端进行通信(send/recv)。
send(sockConn,sendBuf,strlen(sendBuf)+1,0);
MFC(继续画图,孙鑫C第十讲笔记整理)
MFC(继续画图,孙鑫C第十讲笔记整理)1.画图:a.创建四个菜单,为其添加消息响应;b.在View中添加m_DrawType,保存绘画类型;c.增加成员变量,m_PtOrigin,当按下鼠标左键时,保存此点;d.在OnLButtonUp中画点,线,矩形,椭圆,别忘记设置成透明画刷2.为其添加一个设置对话框(线型和线宽)a.创建对话框,为其创建一个新类关联它;b.为其中的线宽关联成员变量;c.在View中增加一个菜单,响应新的对话框;d.添加线型选项设置,将其Group属性选中,并为单选按纽关联成员变量。
在view中增加一个线型变量m_nLineStyle3.添加一个颜色对话框a.实例化一个CColorDialogb.调用DoModal方法4.添加字体对话框,将选择的字体在View中显示出来。
a.实例化一个对象;b.为View添加一个字体成员变量,得到用户选择的字体。
c.调用Invadate()发出重绘消息;d.再次注意一个对象只能创建一次,故要再次创建,必须将原告的删除!5.为设置对话框增加示例功能。
a.当控件内容改变时,发出En_change消息。
而Radio按纽则为Clicked。
需先UpdateData()。
另外还需要ScreenToClient(&rect)6.改变对话框的背景色和控件颜色。
每个控件被绘制时都发出WM_CTlColor消息,7.如何改变OK按纽的字体和背景?OK按纽a.创建一个新类,CT estBtn,基类为CButtonb.在类中增加虚函数,DrawItem,添加代码。
c.将OK按纽关联成员变量。
类型为CT estBtn,注意将OK按纽的OwnerDraw特性选中。
Cancel按纽用新类来改变。
a.加入新文件。
b.为Cancel关联一个成员变量,类型为CSXBtn;c.调用CSXBtn的方法。
Cancel2按纽a.方法同上。
8.在窗口中贴图,4个步骤1、创建位图CBitmap bitmap;bitmap.LoadBitmap(IDB_BITMAP1);2、创建兼容DCCDC dcCompatible;dcCompatible.CreateCompatibleDC(pDC);3、将位图选到兼容DC中dcCompatible.SelectObject(&bitmap);4、将兼容DC中的位图贴到当前DC中。
MFC笔记——VC++深入详解(第3版)孙鑫
MFC笔记——VC++深⼊详解(第3版)孙鑫1、Windows下的程序都是基于消息的,窗⼝在创建时都会产⽣⼀个WM_CREATE消息。
其他类可以响应这个消息,添加WM_CREATE消息的处理函数。
类视图——某个类处⿏标右键,属性——消息(找到WM_CREATE)。
或者使⽤“类向导”。
2、⽂档/视类结构,视类窗⼝始终覆盖在框架类窗⼝之上,⿏标所有操作都只能由视类窗⼝捕获。
如,CMainFrame中⿏标单击事件⽆反应,⽽在CDrawView中就有反应。
3、消息映射机制消息映射表,由头⽂件的DECLARE_MESSAGE_MAP()、源⽂件的BEGIN_MESSAGE_MAP与END_MESSAGE_MAP构建⽽成。
BEGIN_MESSAGE_MAP与END_MESSAGE_MAP之间,有消息映射宏,⼀旦有消息产⽣,程序就调⽤对应的消息响应函数来处理。
消息响应函数4、画线,推荐⽅式三/* ⽅式⼀:SDK// ⾸先获得窗⼝的设备描述表HDC hdc;hdc = ::GetDC(m_hWnd); //当前窗⼝的设备描述表//移动到线条的起点MoveToEx(hdc, m_ptOrigin.x, m_ptOrigin.y, NULL);//画线LineTo(hdc, point.x, point.y);//释放设备描述表::ReleaseDC(m_hWnd, hdc);*//* ⽅式⼆:MFC的CDC类,封装了所有与绘图相关的操作CDC* pDC = GetDC();pDC->MoveTo(m_ptOrigin);pDC->LineTo(point);ReleaseDC(pDC);*/⽅式三:MFC的CClientDC类,CDC的进⼀步封装,省去GetDC与ReleaseDCCClientDC dc(this); //客户区范围//CClientDC dc(GetParent()); //客户区+⼯具栏区dc.MoveTo(m_ptOrigin);dc.LineTo(point);/* ⽅式四:MFC的CWindowDC类,也是派⽣⾃CDC,可画的范围更⼤CWindowDC dc(this); //客户区范围//CWindowDC dc(GetParent()); //客户区+⼯具栏区//CWindowDC dc(GetDesktopWindow()); //所有窗⼝dc.MoveTo(m_ptOrigin);dc.LineTo(point);*/5、画笔CPen pen(PS_SOLID, 1, RGB(255, 0, 0)); //PS_DASH、PS_DOT宽度≤1,虚线才有效CClientDC dc(this);CPen* pOldPen = dc.SelectObject(&pen); //选择画笔dc.MoveTo(m_ptOrigin);dc.LineTo(point);//推荐写上以下两⾏,不然可能造成GDI对象的增加,程序崩溃dc.SelectObject(pOldPen); //重置画笔pen.DeleteObject(); //释放画笔6、画刷,⼀般⽤于填充CBrush brush(RGB(255, 0, 0));//创建⼀个红⾊画刷CClientDC dc(this); //创建并获得设备描述表dc.FillRect(CRect(m_ptOrigin, point), &brush);//利⽤红⾊画刷填充⿏标拖曳过程中形成的矩形区域brush.DeleteObject();画刷画矩形,dc中有默认⽩⾊画刷。
孙鑫C 详解阅读笔记
目录Windows程序运行原理: (2)C++的简单概括 (3)Windows程序运行原理:Api:操作系统把它所能够完成的功能以函数的形式提供给应用程序使用,应用程序对这些函数的调用就叫做系统调用,这些函数的集合就是Windows操作系统提供给应用程序编程的接口(Application Programming Interface),简称Windows API。
消息和消息队列:操作系统将每个事件都包装成一个称为消息的结构体MSG来传递给应用程序,参看MSDN。
MSG结构定义如下:typedef struct tagMSG{HWND hwnd;UINT message;WPARAM wParam;LPARAM lParam;DWORD time;POINT pt;}MSG;⏹句柄(HANDLE),资源的标识。
⏹操作系统要管理和操作这些资源,都是通过句柄来找到对应的资源。
按资源的类型,又可将句柄细分成图标句柄(HICON),光标句柄(HCURSOR),窗口句柄(HWND),应用程序实例句柄(HINSTANCE)等等各种类型的句柄。
操作系统给每一个窗口指定的一个唯一的标识号即窗口句柄。
WinMain函数:⏹Windows程序的入口函数int WINAPI WinMain(HINSTANCE hInstance,//handle to current instanceHINSTANCE hPrevInstance,//handle to previous instanceLPSTR lpCmdLine,//command lineint nCmdShow//show state);窗口的创建:创建一个完整的窗口需要经过下面四个操作步骤:⏹设计一个窗口类;⏹注册窗口类;⏹创建窗口;⏹显示及更新窗口。
附录:回掉函数:回调函数的原理是这样的,当应用程序收到给某一窗口的消息时(还记得前面讲过的消息通常与窗口相关的吗?),就应该调用某一函数来处理这条消息。
孙鑫VC 讲座笔记-(3)MFC程序框架的剖析
(f) #define AfxDeferRegisterClass(fClass) AfxEndDeferRegisterClass(fClass) define AFX_WNDFRAMEORVIEW_REG 0x00008 const TCHAR _afxWndFrameOrView[] = AFX_WNDFRAMEORVIEW;//WINCORE.CPP 文件 中,定义为全局数组。 //#define AFX_W NDFRAMEORVIEW AFX_WNDCLASS("FrameOrView") 10,创建窗口: Create()函数路径: MFC|SRC|WINFRM.CPP: CFrameWnd::Create(……){ …… CreateEx(……);//从父类继 承来的,调用 CWnd::CreateEx(). …… } CWnd::CreateEx()函数路径:MFC|SRC|WI NCORE.CPP BOOL CWnd::CreateEx(……){ …… if (!PreCreateWindow(cs))//虚函数 ,如果子类有调用子类的。 { PostNcDestroy(); return FALSE; } …… HWND hWnd = ::CreateWindowEx(cs.dwExStyle, cs.lpszClass, cs.lp szName, cs.style, cs.x, cs.y, cs.cx, cs.cy, cs.hwndParent, cs.hMenu, cs.hI nstance, cs.lpCreateParams); …… } 说明:CreateWindowEx()函数与 CREATESTR UCT 结构体参数的对应关系,使我们在创建窗 口 之 前 通 过 可 PreCreateWindow (cs) 修 改 cs 结 构 体 成 员 来 修 改 所 要 的 窗 口 外 观 。 PreCreateWin dow(cs))//是虚函数,如果子类有调用子类的。 HWND CreateWindowEx( DWORD dwEx Style, LPCTSTR lpClassName, LPCTSTR lpWindowName, DWORD dwStyle, int x, in t y, int nWidth, int nHeight, HWND hWndParent, HMENU hMenu, HINSTANCE hIns tance, LPVOID lpParam ); typedef struct tagCREATESTRUCT { // cs LPVOID lpC reateParams; HINSTANCE hInstance; HMENU hMenu; HWND hwndParent; int cy; in t cx; int y; int x; LONG style; LPCTSTR lpszName; LPCTSTR lpszClass; DWORD dwExStyle; } CREATESTRUCT; 11,显示和更新窗口: CTEApp 类,TEApp.cpp 中 m _pMainWnd->ShowWindow(SW_SHOW);//显示窗口,m_pMainWnd 指向框架窗口的指针 m _pMainWnd->UpdateWindow();//更新窗口 说明: class CTEApp : public CWinApp{……} class CWinApp : public CWi nThread{……} class CWinThread : public CCmdTarget { …… public: CWnd* m_ pMainWnd; …… …… } 12,消息循环: int AFXAPI AfxWinMain() { …… // Per form specific initializations if (!pThread->InitInstance()){……} //完成窗 口初始化工作,完成窗口的注册,完成窗口的创建,显示和更新。 nReturnCode = p Thread->Run(); //继承基类 Run()方法,调用 CWinThread::Run()来完成消息循环 …… } //////////////////////////////////////////////////////////////// CW inThread::Run()方法路径:MFC|SRC|THRDCORE.CPP int CWinThread::Run() { …… // phase2: pump messages while available do//消息循环 { // pump message, but quit on WM_QUIT if (!PumpMessage())//取消息并处理 return ExitInstance( ); …… } while (::PeekMessage(&m_msgCur, NULL, NULL, NULL, PM_NOREMOVE)); …… } 说明: BOOL PeekMessage(,,,,)函数说明 The PeekMessage function che cks a thread message queue for a message and places the message (if any) i n the specified structure. If a message is available, the return value is nonzero. If no messages are available, the return value is zero. ///////// //////////////////////////////////////////////////// BOOL CWinThread::PumpMessage() { …… if (!::GetMessage(&m_msgCur, NU LL, NULL, NULL))//取消息 {……} …… // process this message if (m_msgCur. message != WM_KICKIDLE && !PreTranslateMessage(&m_msgCur)) { ::TranslateMe ssage(&m_msgCur);//进行消息(如键盘消息)转换 ::DispatchMessage(&m_msgCur) ;//分派消息到窗口的回调函数处理(实际上分派的消息经 过消息映射,交由消息响 应函数进行处理。 ) } return TRUE; } 13,文档与视结构: 可以认为 View 类窗 口是 CMainFram 类窗口的子窗口。 DOCument 类是文档类。 DOC-VIEW 结构将数据本 身与它的显示分离开。 文档类:数据的存储,加载 视类:数据的显示,修改 14,文 档类,视类,框架类的有机结合: 在 CTEApp 类 CTEApp::InitInstance()函数中通 过文档模板将文档类,视类,框架类的有机组 织一起。 …… CSingleDocTemplate* pDocTemplate; pDocTemplate = new CSingleDocTemplate( IDR_MAINFRAME, RUNTI ME_CLASS(CTEDoc), RUNTIME_CLASS(CMainFrame), // main SDI frame window RUNT IME_CLASS(CTEView)); AddDocTemplate(pDocTemplate);//增加到模板 …… 15.视图 类是框架窗口的子类,获得 CWnd 类的父窗口的函数 CWnd* GetParent( ) const; 视
孙鑫笔记9
HICON m_hI3=LoadIcon(AfxGetApp()->m_hInstance,MAKEINTRESOURCE(IDI_ICON3));
4,为适时更新设置定时器。在CMainFrame::OnTimer()中复制下面代码如下:
CTime t=CTime::GetCurrentTIme();
CString str=t.Format("%H:%M:%S");
//调整显示宽度
CClinetDC dc(this);
把OnCreate()中的PostMessage()删除使之失效.
首先添加OnPaint()消息函数
窗口改变重绘会发送WM_PAINT消息,所以只要在OnPaint函数中处理即可.以下代码添加到OnPaint()中
CRect r;
m_wndStatusBar.GetItemRect(2,&r);
if(!m_progress.m_hWnd)m_progress.Create(WS_CHILD | WS_VISIBLE,r,&m_wndStatusBar,123);//创建时大小和父窗口都改变
else m_progress.MoveWindow(r);//或者SetWindowPos()函数
5,进度栏放入状态栏窗格
CRect r;
m_wndStatusBar.GetItemRect(2,&r);
//创建时大小和父窗口都改变
m_progress.Create(WS_CHILD | WS_VISIBLE |PBS_SMOOTH,r,&m_wndStatusBar,123);
VC++深入详解(孙鑫)学习笔记
wnd.lpfnWndProc = WinProc;//消息响应函数
wnd.lpszClassName = "gaojun";//窗口类的名子,在注册时会使用到
wnd.lpszMenuName = NULL;//默认为NULL没有标题栏
LPARAM lParam // second message parameter
);
//(1) WinMain函数,程序入口点函数
int WINAPI WinMain(
4. 创建一个完整的Win32程序,该程序实现创建一个窗口,其中主要步骤为
A. WinMain函数的定义
B. 创建一个窗口 创建一个完整的窗口的四个步骤SDK,1设计窗口类,2注册窗口类,3创建窗口,4显示窗口
C. 进行消息循环
wnd.style = CS_HREDRAW | CS_VREDRAW;//定义为水平和垂直重画
//二.注册窗口类
RegisterClass(&wnd);
//三.根据定制的窗口类创建窗口
HWND hwnd;//保存创建窗口后的生成窗口句柄用于显示
if (-1 == bSet)
{
return -1;
}
else{
TranslateMessage(&msg);
//如果是多文档程序,则最后一个参数lParam必须指向一个CLIENTCREATESTRUCT结构体
hwnd = CreateWindow("gaojun", "WIN32应用程序", WS_OVERLAPPEDWINDOW,
CW_USEDEFAULT, CW_USEDEFAULT, 800, 600, NULL, NULL, hInstance, NULL);
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
/*CDC *pDC=GetDC();
pDC->MoveTo(m_ptOrigin);
pDC->LineTo(point);
ReleaseDC(pDC);必须成对使用。*/
//CClientDC dc(this);
/*CClientDC dc(GetParent());
3)用CClientDC
4)用CWindowDC,用它甚至可以整个屏幕区域画线。
下面是上面4种方法的代码
/*HDC hdc;
hdc=::GetDC(m_hWnd);
MoveToEx(hdc,m_ptOrigin.x,m_ptOrigin.y,NULL);
LineTo(hdc,point.x,point.y);
12.GetDC()与ReleaseDC()要成对使用,否则会内存泄漏。同样,BeginPaint()与EndPaint()。
13.GetStockObject()得到画笔、画刷、字体、调色板的句柄,使用时必须用类型转换。
14.什么时候用NULL,什么时候用0.答,对指针赋值时用NULL,对变量赋值时用0.
}
而在BOOL CTestApp::InitInstance()中的代码
CSingleDocTemplate* pDocTemplate;
pDocTemplate = new CSingleDocTemplate(
IDR_MAINFRAME,
RUNTIME_CLASS(CTestDoc),
dc.MoveTo(m_ptOrigin);
dc.LineTo(point);此处不需要ReleaseDC,因为CClientDC会自动释放DC*/
//CWindowDC dc(this);
//CWindowDC dc(GetParent());
/*CWindowDC dc(GetDesktopWindow());//此时可以在整个屏幕上画线。
5.通常将类的定义放.h文件,而将其实现放在cpp文件中,别忘记了在cpp文件中#include "xxx.h"
6.如何防止类的重复定义?
用#inndef Point_H_H
#define Point_H_H
class Point{};
#endif来防止
7.源文件cpp文件单独编译成obj文件。最后由链接器将与将要使用到的C++标准库类链接成exe文件,头文件不参加编译。所以在cpp文件中别忘记了加入#include "xxx.h"
8.函数的覆盖,在子类中重写父类的函数,此时采用早期绑定的方法。如果加入了virtual,则将采用迟绑定的技术,在运行时根据对象的类型确定调用哪一个函数。此迟绑定技术是MFC的类的继承的精髓。
9.强制类型转换。如果CFish从CAnimal派生而来。则可以将鱼的对象转换为CAnimal的对象,而反之则不行。从现实中理解也是正常的,鱼可以是动物,而动物却不是鱼。再如int可以强制转换成char型。而反之则出错。
hwnd=CreateWindow(...);//创建窗口
ShowWindow(..);//显示窗口
UpdateWindow(..);
MSG msg;//定义消息结构体
while(GetMessage(...))//消息循环
{
...
}
return 0;
}
LRESULT CALLBACK MyProc(...)//实现回调函数
m_ptOrigin=m_ptOld=point;
m_bDraw=TRUE;
CView::OnLButtonDown(nFlags, point);
}
3.画线:定义一个成员变量保存mouseDown的点m_Point
1)API函数方法画线用HDC
2)用CDC类成员函数画线。此时别忘记ReleaseDC
第3课
1.在main或WinMain之前,全局变量已经被分配内存并初始化了。
2.在MFC中在WinMain之前有个theApp全局变量先被构造并被初始化,而由于子类构造函数执行前,其父类的构造函数先被执行,所以CTestApp的父类CWinAPP的构造函数先执行。产生了theApp对象后,在WinMain()中的指针*pThread和*pApp就有了内容。
8.所有从CWnd类派生的类都有m_hWnd句柄。
9.变量的生命周期:可以认为出了包含它的大括号,这个变量的生命周期结束。所以全局变量的声明位于所有大括号之外。但是用new声明的变量和用static声明的变量除外。
10.SDK示范程序,见下面。
11.sprintf格式化字符,其头文件为stdio.h,在MFC中格式化字符用CString.Format
注意点:
(1).此处btn不能是局部变量,否则它的生命周期太短,将不能显示。
(2).在create函数的第二个参数中加入WS_VISIBLE 参数才行。否则必须调用ShowWindow
也可以在view的OnCreate消息响应函数中加入
(3).CButton类的定义头文件
dc.MoveTo(m_ptOrigin);
dc.LineTo(point);*/
/*CPen pen(PS_DOT,1,RGB(0,255,0));
CClientDC dc(this);
CPen *pOldPen=dc.SelectObject(&pen);
dc.MoveTo(m_ptOrigin);
第4课
1.在单文档中view挡在MainFrame的前面。此时如果编写针对MainFrame的mouseClick事件,将不会有反应。
2.消息响应会在3处修改代码,1处是在头文件中,
//{{AFX_MSG(CDrawView)
afx_msg void OnLButtonDown(UINT nFlags, CPoint point);
BEGIN_MESSAGE_MAP(CDrawView, CView)
//{{AFX_MSG_MAP(CDrawView)
ON_WM_LBUTTONDOWN()
ON_WM_LBUTTONUP()
ON_WM_MOUSEMOVE()
//}}AFX_MSG_MAP
// Standard printing commands
{
switch(uMsg)
{
case WM_CHAR:
break;
...
}
}
第2课
1.定义结构体和类时别忘记在最后加入";"号!例如Class Point{int x;int y;};
2.#include <xxx.h>与#include "xxx.h"的区别:<>不查找运行时目录,""查找运行时目录!
在CMainFrame::OnCreate()中定义一个CButton的对象btn;然后调用btn.Create("维新",WS_DISABLED |WS_CHILD | WS_VISIBLE | BS_AUTO3STATE,
CRect(0,0,300,100),/*GetParent(),*/this,123);
afx_msg void OnLButtonUp(UINT nFlags, CPoint point);
afx_msg void OnMouseMove(UINT nFlags, CPoint point);
//}}AFX_MSG
DECLARE_MESSAGE_MAP()
另一处是cpp文件的begin MessageMap和End MessageMap之间,
15.什么是野指针?答:将指针指向的变量的内存释放后,此指针即变成野指针!如何避免野指针?答:将此指针指向NULL即可。p=NULL;
16.SDK代码流程:
#include "windows.h"//包含头文件LoadCursor,TextOut等函数
#include "stdio.h"//包含sprintf,printf等函数
ON_COMMAND(ID_FILE_PRINT, CView::OnFilePrint)
ON_COMMAND(ID_FILE_PRINT_DIRECT, CView::OnFilePrint)
ON_COMMAND(ID_FILE_PRINT_PREVIEW, CView::OnFilePrintPreview)
RUNTIME_CLASS(CMainFrame), // main SDI frame window
RUNTIME_CLASS(CTestView));
AddDocTemplate(pDocTemplate);
完成了将这三个类关联起来的工作。
4.如何在单文档文件中显示一个CButton的对象?
dc.FillRect(CRect(m_ptOrigin,point),&brush);
//CBRUSH::FromHandle是静态成员函数,所以可以用下面的方法调用。
CBrush *pBrush=CBrush::FromHandle((HBRUSH)GetStockObject(NULL_BRUSH));
3.MFC大致流程:
CTestApp theApp;//构造全局对象
WinMain()
{
AfxWinMain();//调用下面的函数