孙鑫VC视频教程笔记
孙鑫视频VC++深入详解学习笔记

VC++深入详解学习笔记Lesson1: Windows程序运行原理及程序编写流程窗口产生过程,句柄原理,消息队列,回调函数,窗口关闭与应用程序退出的工作关系,使用VC++的若干小技巧,stdcall与Lessonecl调用规范的比较,初学者常犯错误及注意事项。
1.Windows API与Win32 SDK操作系统提供了各种方便开发Windows应用程序的编程接口,所的函数都在Window s。
h头文件中声明。
Win32 SDK(Software Development Kit): 即Windows 32位平台下的软件开发包,包括API函数,帮助文档,微软提供的一些辅助开发工具。
2.窗口与句柄窗口是是屏幕上一块矩形区域,是Windows应用程序与用户进行交互的接口。
窗口分为客户区和非客户区。
在Windows应用程序中,窗口是通过窗口句柄(HWND)来标识的,要对某个窗口进行操作,首先就要得到这个窗口的句柄。
其它各种资源(窗口,图标,光标等),系统在创建这些资源时会为它们分配内在,并返回标识这些资源的标识号,即句柄。
-->光标句柄(HCURSOR),图标句柄(HICON)。
3.消息与消息队列Windows程序设计是一种基于消息的事件驱动方式的程序设计模式。
消息:在Windows中由结构体MSG来表示,typedef struct tagMSG{HWND hwnd;//消息所属的窗口句柄UINT message;//消息本身标识符,由一数值表示,系统对消息定//义为WM_XXX宏(WM为Windows Message缩写)WPARAM wParam; //随消息的不同附加信息也不同LPARAM lParam; //消息的附加参数DWORD time; //消息投递的时间POINT pt; //鼠标当前位置}消息队列:每当一个Windows应用程序创建后,系统都会为该程序创建一个消息队列,这个消息队列用来存放该程序一的窗口的消息,消息产生后被投递到消息队列中,应用程序通过一个消息循环不断的消息队列中取出消息进行响应。
孙鑫笔记7

4,创建属性表单
利用Classwizard插入一个新的类,基类选为CPropertySheet
5,给属性表单添加三个public变量
CProp1 m_prop1;
CProp2 m_prop2;
CProp3 m_prop3;
6,在属性表单的两个构造函数增加表单
AddPage(&m_prop1);
AddPage(&m_prop2);
AddPage(&m_prop3);
7,在View类添加一个菜单项,添加响应函数,添加下列语句
CPropSheet propSheet("维新属性表单程序");
((CPropertySheet*)GetParent())->SetWizardButtons(PSWIZB_NEXT);
在CProp4::OnSetActive中添加
((CPropertySheet*)GetParent())->SetWizardButtons(PSWIZB_BACK | PSWIZB_FINISH);
解决办法:删除类信息文件XXX.clw;再次调用classwizard,重新产生一个xxx.clw即可
2,属性页资源的增加
在Resource View里Dialog处点击右键InsertèDialogèIDD_PROPPAGE_LARGE(English(U.S.))
注意看属性页资源的属性:类型-Child,Border-Thin,System menu不复选,More style中复选了Disabled
也可以通过修改普通对话框,而成为属性页。
3,创建类
给属性页对话框添加类的时候,基类选为CPropertyPage,而不是CDialog
孙鑫VC学习笔记第8课

a.Indicator[]数组中有状态栏的信息
如果要增加,可以在String Table中加入一个IDS_Timer,然后将其加入到[]中。
b.在时间栏显示时间,代码略,比较简单
6.进度栏
a.增加成员变量,CProgressCtrl m_progress
b.OnCreate中 m_progress.Create(WS_CHILD | WS_VISIBLE,// | PBS_VERTICAL,
第二种ShowControlBar(&m_newToolBar,!m_newToolBar.IsWindowVisible(),FALSE);
e.将菜单增加复选标记。在OnUpdateUI中加入代码
pCmdUI->SetCheck(m_newToolBar.IsWindowVisible());
然后将其初始化
c.然后在定时器中实现
3.工具栏的编程
a.加入分隔符的方法,向右拖动即可;
b.删除按纽的方法,拖出即可。
4.创建一个新的工具栏的方法
a.插入一个工具栏,画出其图形。
b.在头文件中,定义CToolBar m_newToolBar
c.在MainFrm.cpp的OnCreate()中调用
cs.lpszClass=AfxRegisterWndClass(CS_HREDRAW | CS_VREDRAW);
OnCreate()中
SetClassLong(m_hWnd,GCL_HBRBACKGROUND,(LONG)GetStockObject(BLACK_BRUSH));
m_progress.Create(WS_CHILD | WS_VISIBLE | PBS_SMOOTH,
孙鑫老师的VC视频笔记

申明本人什么功劳都没有,以上所有都是参考“虎非龙“所写的视频笔记。
望大家不要误会VC视频教程笔记目录第1课Windows程序运行原理及程序编写流程 (3)第2课类的编写与应用 (5)第3课讲述MFC AppWizard的原理与MFC程序框架的剖析 (6)第4课第4课MFC消息映射机制的剖析讲述如何运用ClassWizard (8)第五课文本编程 (11)第6课菜单编程 (15)第7课对话框用户界面程序的编写 (21)第8课逃跑按钮的巧妙实现 (23)第9课如何修改MFC AppWizard向导生成的框架程序的外观和大小 (24)第10课图形的绘制,如何使用自定义画笔 (27)第11课如何让CDC上输出的文字、图形具有保持功能 (29)第12课文件操作 (31)第13课使用CArchive类对文件进行操作 (33)第14课网络编程 (35)第15课多线程与网络编程 (40)第16课事件内核对象、关键代码段(临界区)的讲解 (44)第17课进程间通信 (47)第18课ActiveX编程 (55)第19课DLL编程 (57)第20课钩子与数据库编程 (60)第1课Windows程序运行原理及程序编写流程1.MFC生成的C++源文件中都有StdAfx.h,此文件包含了常用的AFX函数的声明,其中有afxwin.h,此文件包含了CRECT,CPoint,CWnd等许多类及其方法的声明。
2.Project->Setting->Debug可以加入命令行参数。
3.在SDK中要加入"windows.h"和stdio.h。
因为LoadCursor,MessageBox等函数的声明在这个文件中。
4.创建一个完整的窗口的四个步骤SDK,1设计窗口类,2注册窗口类,3创建窗口,4显示窗口5.函数名可以代表函数代码的首地址,即可作为函数指针。
6.要查看VC数据类型,可以在MSDN中输入“BOOL”然后选择“DATA TYPE”。
孙鑫笔记1

//__stdcall 标准调用预定,是PASCAL 调用约定,象DELPHI使用的就是标准调用约定
#define WINAPIV __cdecl
// __cdecl 是C 语言形式的调用约定。
主要区别:函数参数传递顺序 和 对堆栈的清除上。
孙鑫VC++视频学习笔记之1: Windows程序内部运行机制2007年04月26日 星期四 下午 10:19这一章比较零散,笔记也很零散
一、windows是事件驱动方式的程序设计
windows程序设计是种事件驱动方式的程序设计,主要基于消息的。当用户需要完成某种功能时,需要调用OS某种支持,然后OS将用户的需要包装成消息,并投入到消息队列中,最后应用程序从消息队列中取走消息并进行响应。
UINT uMsg, // message identifier
WPARAM wParam, // first message parameter
LPARAM lParam // second message parameter
);
说明:两种函数调用约定(__stdcall 和 __cdecl):
2, 注册窗口类。如:RegisterClass(&wndcls)。
3, 创建窗口。如:CreateWindow(),CreateWindowEX();
4, 显示及更新窗口。如:ShowWindow(),UpdateWindow();
其他值得注意的地方
1, 消息结构
问题:除了那些可变参数的函数调用外,其余的一般都是__stdcall约定。但 C/C++编译默然的是__cdecl约定。所以如果在VC等环境中调用__stdcall约定的函数,必须要在函数声明的时加上 __stdcall 修饰符,以便对这个函数的调用是使用__stdcall约定(如使用DELPHI编写的DLL时候)。
孙鑫笔记3

2)消息映射方式:MFC在后台维护了一个句柄和C++对象指针对照表,当收到一个消息后,通过消息结构里资源句柄(查对照表)就可找到与它对应的一个C++对象指针,然后把这个指针传给基类,基类利用这个指针调用WindowProc()函数对消息进行处理,WindowProc()函数中调用OnWndMsg()函数,真正的消息路由及处理是由OnWndMsg()函数完成的。由于WindowProc()和OnWndMsg()都是虚函数,而且是用派生类对象指针调用的,由多态性知最总终调用子类的。在OnWndMsg()函数处理的时候,根据消息种类去查找消息映射,判断所发的消息有没有响应函数,具体方式是到相关的头文件和源文件中寻找消息响应函数声明(从注释宏//{{AFX_MSG(CDrawView)...//}}AFX_MSG之间寻找),消息映射(从宏BEGIN_MESSAGE_MAP(...)....END_MESSAGE_MAP()之间寻找),最终找到对应的消息处理函数。当然,如果子类中没有对消息进行处理,则消息交由基类处理。
回到原文件,我们将看到三处进行了修改:
1, 在头文件(View.h)中声明消息响应函数原型。
//{{AFX_MSG(CDrawView) //注释宏
afx_msg void OnLButtonDown(UINT nFlags, CPoint point);
//}}AFX_MSG //注释宏
//}}AFX_MSG_MAP
在宏BEGIN_MESSAGE_MAP()与END_MESSAGE_MAP()之间进行消息映射。
宏ON_WM_LBUTTONDOWN()把消息WM_LBUTTONDOWN与它的响应函数OnLButtonDown()相关联。这样一旦有消息的产生,就会自动调用相关联的消息响应函数去处理。
孙鑫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了。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
VC视频教程笔记!第一课1.MFC生成的C++源文件中都有StdAfx.h,此文件包含了常用的AFX函数的声明,其中有afxwin.h,此文件包含了CRECT,CPoint,CWnd等许多类及其方法的声明。
2.Project->Setting->Debug可以加入命令行参数。
3.在SDK中要加入"windows.h"和stdio.h。
因为LoadCursor,MessageBox等函数的声明在这个文件中。
4.创建一个完整的窗口的四个步骤SDK,1设计窗口类,2注册窗口类,3创建窗口,4显示窗口5.函数名可以代表函数代码的首地址,即可作为函数指针。
6.要查看VC数据类型,可以在MSDN中输入“BOOL”然后选择“DATA TYPE”。
7.atof将字符串转化为float,atoi将字符串转化为int型。
8.所有从CWnd类派生的类都有m_hWnd句柄。
9.变量的生命周期:可以认为出了包含它的大括号,这个变量的生命周期结束。
所以全局变量的声明位于所有大括号之外。
但是用new声明的变量和用static声明的变量除外。
10.SDK示范程序,见下面。
11.sprintf格式化字符,其头文件为stdio.h,在MFC中格式化字符用CString.Format12.GetDC()与ReleaseDC()要成对使用,否则会内存泄漏。
同样,BeginPaint()与EndPaint()。
13.GetStockObject()得到画笔、画刷、字体、调色板的句柄,使用时必须用类型转换。
14.什么时候用NULL,什么时候用0.答,对指针赋值时用NULL,对变量赋值时用0.15.什么是野指针?答:将指针指向的变量的内存释放后,此指针即变成野指针!如何避免野指针?答:将此指针指向NULL即可。
p=NULL;16.SDK代码流程:#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课1.定义结构体和类时别忘记在最后加入";"号!例如Class Point{int x;int y;};2.#include <xxx.h>与#include "xxx.h"的区别:<>不查找运行时目录(从系统目录进行查找),""查找运行时目录(从当前目录进行查找)!3.类的定义中,如果未指明成员类型,则缺省为private.而结构体中则缺省为public.4.引用:引用经常用在函数的传参上。
另外数值交换函数也经常用引用。
例change(int &x,int &y){int temp;temp=x;x=y;y=x}调用时即可以用 int a=3;int b=4;change(a,b);一般不用指针来作为参数进行数值交换。
因为会引起歧义。
5.通常将类的定义放.h文件,而将其实现放在cpp文件中,别忘记了在cpp文件中#include "xxx.h"6.如何防止类的重复定义?用#ifndef Point_H_H#define Point_H_Hclass Point{};#endif来防止7.源文件cpp文件单独编译成obj文件。
最后由链接器将与将要使用到的C++标准库类链接成exe文件,头文件不参加编译。
所以在cpp文件中别忘记了加入#include "xxx.h"8.函数的覆盖,在子类中重写父类的函数,此时采用早期绑定的方法。
如果加入了virtual,则将采用迟绑定的技术,在运行时根据对象的类型确定调用哪一个函数。
此迟绑定技术是MFC的类的继承的精髓。
(多态性)9.强制类型转换。
如果CFish从CAnimal派生而来。
则可以将鱼的对象转换为CAnimal的对象,而反之则不行。
从现实中理解也是正常的,鱼可以是动物,而动物却不是鱼。
再如int可以强制转换成char型。
而反之则出错。
第3课1.在main或WinMain之前,全局变量已经被分配内存并初始化了。
2.在MFC中在WinMain之前有个theApp全局变量先被构造并被初始化,而由于子类构造函数执行前,其父类的构造函数先被执行,所以CTestApp的父类CWinAPP的构造函数先执行。
产生了theApp对象后,在Wi nMain()中的指针*pThread和*pApp就有了内容。
3.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 windowRUNTIME_CLASS(CTestView));AddDocTemplate(pDocTemplate);完成了将这三个类关联起来的工作。
4.如何在单文档文件中显示一个CButton的对象?在CMainFrame::OnCreate()中定义一个CButton的对象btn;然后调用btn.Create("维新",WS_DISABLED |WS_CHILD | WS_VISIBLE | BS_AUTO3STATE,CRect(0,0,300,100),/*GetParent(),*/this,123);注意点:(1).此处btn不能是局部变量,否则它的生命周期太短,将不能显示。
(2).在create函数的第二个参数中加入WS_VISIBLE 参数才行。
否则必须调用ShowWindow也可以在view的OnCreate消息响应函数中加入(3).CButton类的定义头文件在afxwin.h中,而stdafx.h包含了afxwin.h,所以可以直接使用。
因为MFC中的每一个类中都有#include "stdafx.h"的声明。
5.CWnd封装了窗口句柄m_hWnd。
第4课1.在单文档中view挡在MainFrame的前面。
此时如果编写针对MainFrame的mouseClick事件,将不会有反应。
2.消息响应会在3处修改代码,1处是在头文件中,//{{AFX_MSG(CDrawView)afx_msg void OnLButtonDown(UINT nFlags, CPoint point);afx_msg void OnLButtonUp(UINT nFlags, CPoint point);afx_msg void OnMouseMove(UINT nFlags, CPoint point);//}}AFX_MSGDECLARE_MESSAGE_MAP()另一处是cpp文件的begin MessageMap和End MessageMap之间,BEGIN_MESSAGE_MAP(CDrawView, CView)//{{AFX_MSG_MAP(CDrawView)ON_WM_LBUTTONDOWN()ON_WM_LBUTTONUP()ON_WM_MOUSEMOVE()//}}AFX_MSG_MAP// Standard printing commandsON_COMMAND(ID_FILE_PRINT, CView::OnFilePrint)ON_COMMAND(ID_FILE_PRINT_DIRECT, CView::OnFilePrint)ON_COMMAND(ID_FILE_PRINT_PREVIEW, CView::OnFilePrintPreview)END_MESSAGE_MAP()最后是要有函数实现的代码。
void CDrawView::OnLButtonDown(UINT nFlags, CPoint point){// TOD Add your message handler code here and/or call defaultm_ptOrigin=m_ptOld=point;m_bDraw=TRUE;CView::OnLButtonDown(nFlags, point);}3.画线:定义一个成员变量保存mouseDown的点m_Point1)API函数方法画线用HDC2)用CDC类成员函数画线。
此时别忘记ReleaseDC3)用CClientDC4)用CWindowDC,用它甚至可以整个屏幕区域画线。
下面是上面4种方法的代码/*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);必须成对使用。
*/CDC *pDC=GetDC();pDC->MoveTo(m_ptOrigin);pDC->LineTo(point);ReleaseDC(pDC);必须成对使用。
*/CClientDC dc(this);/*CClientDC dc(GetParent());dc.MoveTo(m_ptOrigin);dc.LineTo(point);此处不需要ReleaseDC,因为CClientDC会自动释放DC*///CWindowDC dc(this);//CWindowDC dc(GetParent());/*CWindowDC dc(GetDesktopWindow());//此时可以在整个屏幕上画线。