孙鑫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++讲座笔记-(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学习笔记第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”。
孙鑫老师VC++教学视频学习另一篇笔记
孙鑫老师VC++教学视频学习另一篇笔记<< 一:掌握C++>>1:struct 或者 class的定义完成后面一定不要忘记分号!2: 可以这么写:cout<class test{public:test(){cout<<"aaa"<using namespace std;class test{public:test(){cout<<"aaa"<>1:_tWinMain实际上是一个宏,其等于WinMain!2:_tWinMain()的定义位于文件appmodul.cpp中,而CWinapp的定义位于appcore.cpp中,AfxWinMain()在winmain.cpp当中.而负责注册窗口类的函数AfxEndDeferRegisterClass()位于wincore.cpp当中.至于窗口类的定义,在MFC 中,微软为我们定义了好几个默认的窗口类.3:所谓CWnd对象,只是在CWnd类中封装了创建窗口的过程然后保存了生成的窗口句柄而已,然后通过构造一个它的对象来启动那些过程,并不是说CWnd对象与窗口有什么固定的关系.又因为CMainFrame与CView都是从CWnd派生而来的,所以CMainFrame 与CView对象之于窗口的关系也差不多.也就是说,一个窗口关闭了,并不代表那个对象一定也销毁了.还可以从那个对象出发,再调用一遍其中的函数生成窗口,但是若是对象都销毁了,则窗口一定不会存在!CMainFrame对应窗口的标题栏及菜单栏为非客户区,工具栏及以下为客户区.而CView对象对应窗口的客户区为工具栏以下区域.4:具体追踪过程见TrackMfc 工程!5:为了修改程序的背景色,我在View类的PreCreateWindow()中新定义了一个窗口类如下:WNDCLASS wndcls;wndcls.cbClsExtra=0;wndcls.cbWndExtra=0;wndcls.hbrBackground=(HBRUSH)::CreateSolidBrush(RGB(2 08,221,238));wndcls.hCursor=::LoadCursor(NULL, IDC_ARROW);wndcls.hIcon=LoadIcon(::AfxGetInstanceHandle(),MAKEINT RESOURCE(IDI_MY ICON));wndcls.hInstance=AfxGetInstanceHandle();wndcls.lpfnWndProc=(WNDPROC)::DefWindowProc;wndcls.lpszClassName="wndcls";wndcls.lpszMenuName=NULL;wndcls.style=CS_HREDRAW | CS_VREDRAW;cs.lpszClass="wndcls";却发现一启动程序就弹出一个消息框说"建立空文档失败!".几番查找,才发现还要将自定义的窗口类进行注册才可以,在最后一句前面加上一句::RegisterClass(&wndcls);问题就解决了,背景色也变了,可是窗口图标还是没有变成我自画的IDI_MYICON,怎么回事呢?原来改变图标要在MainFrame类的PreCreateWindow()中进行,可是只改变个图标定义一个窗口类太过麻烦了,可以用下面的方法:cs.lpszClass=AfxRegisterWndClass(NULL,NULL,NULL,AfxGetApp()->LoadIcon (IDI_MYICON));使用了一个AfxRegisterWndClass()的函数.当然在View类中做一个大大的窗口类也是相当麻烦的,所以也可以使用AfxRegisterWndClass()函数!只用一句:cs.lpszClass=AfxRegisterWndClass(CS_HREDRAW |CS_VREDRAW,::LoadCursor(NULL,IDC_CROSS,(HBRUSH)::CreateSolidBrush(RGB(208,221,238)), 0);即可!做完上面这些,我通过import重新载入了一个ICON,在ResourceView窗口中直接删除了原本自己画的IDI_MYICON,然后将新载入的ICON改ID 为IDI_MYICON,然后重新编译,却得不到想要的效果,然后我在Build菜单下点击了Rebuild All,编译完成后新图标才显示出来,具体原因估计跟预编译有关!6:还有就是即使如上所示改变了窗口左上角的那个图标,可应用程序自身的图标却还是那个MFC标准图标,这时,你只需将你想要的图标放到工程的res文件夹下,交将之改名为标准MFC图标的名称,再做个Rebuild All就可以将之更改!之于上面的窗口类定义中菜单怎么可以定义为NULL,是因为由MFC产生的代码,菜单的创建是在App类的InitInstance()中在构造单文档模板的时候将菜单的资源标识传递过来,并进行相关的创建工作的!所以上面传递NULL并不会影响菜单的创建的. (相关更多知识见第八课的笔记)<< 三: GDI编程 >>1:如果你想画一个虚线线条,也就是说线形为PS_DASH,那么线宽必须是1才行.具有同样要求的还有PS_DOT...2:如何创建一个透明画刷CBrush *pBrush=CBrush::FromHandle((HBRUSH)GetStockObject(NU LL_BRUSH));这就可以了,然后选入DC使用即可!3:关于画点,我们一般用SetPixel()函数,可是你会发现不管你把画笔的线宽设为几,画出来的点都是一个像素大小,但通常我们希望我们指定4的大小时可以画一个比原先大小大相应程度的点,这时,我想到的办法就是画点部分用画圆函数来实现,只要把填充画刷设置合理即可.不知还有没别的办法.<< 四:文本编程 >>1:创建普通插入符用CreateSolidCaret(),而创建位图插入符用CreateCaret()函数.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 defaultif(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()函数中了,别的都是正常的,可当退格的时候后面的那个残留的插入符没有消失,仍然保留着,我找了半天找不到原因,最后才发现原来调用::InvalidateRect()来启动OnDraw()时,第三个参数如果传FALSE,会导致原来无效区域的背景不刷新,然后我将之换成TRUE就OK了!4:至于类似卡拉OK字幕的平滑变色效果,可以用DrawT ext()来实现.<< 五:菜单编程 >>1:消息的分类及路由形态:(1)标准消息:除WM_COMMAND之外,所有以WM_开关的消息都是标准消息.(2)命令消息:来自菜单,加速键或工具栏按钮的消息.这类消息都是以WM_COMMAND呈现.在MFC 中,通过菜单项的标识ID来区分不同的命令消息,在SDK中,则是以wParam参数识别.(3)通告消息:由控件产生的消息,例如,按钮的单击,列表框的选择等均产生此类消息,为的是向其父窗口(通常是对话框)通知事件的发生.这类消息也是以WM_COMMAND形式呈现.关于消息的接收:只要是从CWnd派生的类,都既可以接收标准消息,又可以接收命令消息以及通告消息.而其它从CCmdTarget派生的类,就只能接收命令消息与通告消息,而不能接收到标准消息.另外,从视频教材的第一个菜单响应例子的实验证明,一个WM_COMMAND消息,是首先被CMainFrame类接收到,但它先交由它的子窗口View类处理,如果View类没有相应的处理函数,就由View 类将此消息交由Doc类处理,如果Doc类也没有相应的处理函数,那么Doc类会将消息返还给View类,而View类再将消息返还给MainFrame类,这时才检查MainFrame类中有没有相应的消息处理函数,如果仍然没有的话,它就将消息上还给了App类处理(如果在这里仍没有处理函数,则回到CCmdTarget类,然后由FrameWork会将消息传递给::DefWindowProc()函数,注意这儿绕过了CWinThread,因为CWinThread并不参与消息路由!)并且一个消息一旦在某个类中被响应过,则不再接着传递!(关于这个看<<深入浅出MFC>>第9章的图9-4会很清楚!)而对于一个标准WM_消息,则由CMyView类先处理,如果没有处理函数,则上溯到CView,如果仍没有处理函数,则上溯到CWnd类,如果仍没有处理函数,则上溯到CCmdTarget了.这就是消息的路由过程!2:如何在菜单项上加上对号标记:在MainFrame类的OnCreate()中最后加入GetMenu()->GetSubMenu(3)->CheckMenuItem(0,MF_BYPO SITION | MF_CHECKED);另外,在响应刷新消息的函数中由MFC传入的那个CCmdUI*指针也可以用于此!3:如何在菜单项中设置默认菜单项:同样在MainFrame类的OnCreate()的最后加入GetMenu()->GetSubMenu(3)->SetDefaultItem(0,TRUE);即可.要注意,一个子菜单中只可以有一个默认(缺省)菜单项.以最后一个设置为默认的菜单项为准.4:如何设计图形标记菜单:同样在MainFrame类的OnCreate()的最后加入GetMenu()->GetSubMenu(3)->SetMenuItemBitmap(,,,);要注意,一个菜单的图形标记只能是13*13大小的位图,这个数据可以通过GetSystemMetrics(SH_CXMENUCHECK);或者GetSystemMetrics(SH_CYMENUCHECK);来获取!5:如何Enable或者Disable一个菜单项同样在MainFrame类的OnCreate()的最后加入GetMenu()->GetSubMenu(3)->EnableMenuItem(,);要注意,菜单项的Enable或者Disable功能的正常完成需要在MainFrame类的构造函数中将一个叫m_bAutoMenuEnable的成员变量设置为FALSE.但是如果做了m_bAutoMenuEnable=FALSE;后,会导致CMainFrame so no ON_UPDATE_COMMAND_UI or ON_COMMAND handlers are needed!6:如何让一个菜单显示或不显示:要让菜单不显示,在MainFrame类的OnCreate()的最后加入SetMenu(NULL);即可!要让菜单显示,可以先构造一个CMenu对象,再利用该对象的LoadMenu(ID of menu)函数将之加载,然后再用SetMenu(该menu 对象的指针)即可!要注意,你的CMenu对象必须是一个定义在CMainFrame类中的成员变量,不能是一个在OnCreate()函数中临时定义的一个变量,因为该函数结束时其中的成员变量要发生析构,那么你的菜单就要出问题.或者你也可以定义临时函数内的局部变量,然后在SetMenu()完了后用一个menu.Detach()成员函数将菜单与菜单对象的关系切断,这样也是可以的.7:MFC之于菜单项的命令更新机制:菜单项状态的维护是依赖于CN_UPDATE_COMMAND_UI消息,谁捕获CN_UPDATE_COMMAND_UI消息,MFC就在其中创建一个CCmdUI对象.我们可以通过手工或者利用ClassWizard在消息映射中添加ON_UPDATE_COMMAND_UI宏来捕获CN_UPDATE_COMMAND_UI消息.在后台所做的工作是:操作系统发出WM_INITMENUPOPUP消息,然后由MFC 的基类如CFrameWnd接管.它创建一个CCmdUI对象,并与第一个菜单项相关联,调用对象的一个成员函数DoUpdate().这个函数发出CN_UPDATE_COMMAND_UI消息,这条消息带有指向CCmdUI对象的指针.同一个CCmdUI对象就设置为与第二个菜单项相关联,这样顺序进行,直到完成所有菜单项.更新命令UI处理程序仅应用于弹出式菜单项上的项目,不能应用于永久显示的顶级菜单项目.用我自己的话来讲就是:命令更新机制就是当无论何时要显示菜单项时,系统都会对CMainFrame类发出一个包含每个菜单项的UPDATE_COMMAND_UI消息,如果你在CMainFrame类中针对某个菜单项做了相应的消息处理函数,那么你可以在这个函数中检测程序中的某些条件,做出让某个菜单项显示或不显示或者变灰的决定!8:如何制作右键弹出菜单:方法一:在VC中,点菜单上的Project/Add To Project/Components and Controls...,在弹出的对话框中打开Visual C++ Components文件夹,再找到Pop-up Menu,选择Insert按钮,在随后的确认框中点确定,然后在随后的 Add pop-up menu to:下拉列表框中选择View类,资源ID可以不改,按OK,然后重新编译工程就可以看到结果了.方法二:其实在方法一中,MFC在后台所做的就是在View类中加入了一个函数:OnContextMenu()函数如下:void CMyNotePadView::OnContextMenu(CWnd*, CPoint point){// CG: This block was added by the Pop-up Menu component {if (point.x == -1 && point.y == -1){ //keystroke invocationCRect rect;GetClientRect(rect);ClientToScreen(rect);point = rect.TopLeft();point.Offset(5, 5);}CMenu menu;VERIFY(menu.LoadMenu(CG_IDR_POPUP_MY_NOTE_PAD_VI EW));CMenu* pPopup = menu.GetSubMenu(0);ASSERT(pPopup != NULL);CWnd* pWndPopupOwner = this;while (pWndPopupOwner->GetStyle() & WS_CHILD)pWndPopupOwner = pWndPopupOwner->GetParent();pPopup->TrackPopupMenu(TPM_LEFTALIGN | TPM_RIGHTBUTTON, point.x, point.y, pWndPopupOwner);}}这就使得我们也可以模仿以上行为做出自己的弹出菜单,首先在View类中添加对右键的响应函数,在其中也写如下代码:CMenu menu;menu.LoadMenu(IDR_MENU1);//这个ID所对应的菜单你要事先做好CMenu* pPopup=menu.GetSubMenu(0);pPopup->TrackPopupMenu(PM_LEFTALIGN | TPM_RIGHTBUTTON, point.x, point.y, this);就可以了.但是现在的菜单显示的位置很离谱,原来显示弹出菜单用得是屏幕坐标,而你在View类中捕获的位置坐标是窗口坐标,这时就得用这个函数:ClientToScreen(point);在TrackPopupMenu()之前做个转换!这样就正常了.9:右键弹出菜单项的响应:在响应右键弹出菜单时,你可以在View类中响应,也可以在MainFrame类中响应,这主要取决于你在做pPopup->TrackPopupMenu()时的第四个参数,也就是该弹出菜单的父窗口.如果如上是this,则只能在View 类中响应,如果用GetParent()设其为MainFrame类,则既可以View类中响应,又可以在MainFrame类中响应.并且如果View类跟MainFrame类皆有响应函数,则优先响应View类,其实也就是说MainFrame中的响应函数将被忽略.所以为了方便,弹出菜单的父类就尽可能设为MainFrame类!10:如何在菜单栏上动态增加,插入或删除一个子菜单因为以前菜单栏上的子菜单都是在菜单编辑器中事先做好的,而现在要求在程序运行期间按需添加一个子菜单到指定位置.可以用如下代码段实现:CMenu menu;menu.CreatePopupMenu();GetMenu()->AppendMenu(MF_POPUP,(UINT)menu.m_hMe nu,"动态菜单");menu.Detach();如上的代码会将新子菜单放在所有已有子菜单项的后面,如果要想在指定的位置插入子菜单,则应该用InsertMenu()而不是AppendMenu(),示例如下:CMenu menu;menu.CreatePopupMenu();GetMenu()->AppendMenu(MF_POPUP,(UINT)menu.m_hMe nu,"动态菜单");menu.Detach();menu.CreatePopupMenu();GetMenu()->InsertMenu(2,MF_BYPOSITION | MF_POPUP,(UINT)menu.m_hMenu,"插入菜单");menu.Detach();要在新加入的子菜单下面显示菜单项的示例代码如下:CMenu menu;menu.CreatePopupMenu();GetMenu()->AppendMenu(MF_POPUP,(UINT)menu.m_hMe nu,"动态菜单");menu.Detach();menu.CreatePopupMenu();GetMenu()->InsertMenu(2,MF_BYPOSITION | MF_POPUP,(UINT)menu.m_hMenu,"插入菜单");menu.AppendMenu(MF_STRING,111,"How");menu.AppendMenu(MF_STRING,112,"I");menu.AppendMenu(MF_STRING,113,"Feel?");menu.Detach();要在已有子菜单中添加菜单项同样可以用AppendMenu()或者InsertMenu()它们的区别自然是前者在最后放置,后者由你指定位置.示例代码如下:GetMenu()->GetSubMenu(0)->AppendMenu(MF_STRING,1 14,"动态");GetMenu()->GetSubMenu(0)->InsertMenu(ID_FILE_OPEN,M F_BYCOMMAND |MF_STRING,115,"安岳");以上函数中若使用MF_SEPARATOR参数可以插入分割符!要删除一个子菜单或者菜单项可以使用DeleteMenu()函数.如果调用它的是菜单栏,则删除的是子菜单,如果调用它的是子菜单,则删除的是菜单项.至于这种动态菜单项的命令响应则不能再借助于ClassWizard啦,跟手动添加对其它消息的响应一样,需要三个步骤:一:添加响应函数声明在CMainFrame的构造函数中,紧随系统原有的afx_msg int OnCreate();之类的语句之后写上:afx_msg void OnHow();但注意不要写在括住系统自己的响应函数的//{{AFx_MSG...及//}}AFX_MSG之内了.二:添加消息映射在MainFram.cpp中找到以(CMainFrame,CFrameWnd)为参数的BEGIN_MESSAGE_MAP,END_MESSAGE_MAP宏对,在其中添加: ON_COMMAND(IDM_HOW,OnHow)注意这一句是宏语句,不要在其后面加分号.(也注意不要写在//{{AFx_MSG...及//}}AFX_MSG之内了.)因为这个宏中需要ID,所以自己还要手动的在Resource.h中加入:#Define IDM_HOW 111 一句.(111是AppendMenu()时指定的ID).三:完成消息响应函数在MainFrame.cpp文件后面写如下代码段:void CMainFrame::OnHow(){MessageBox("Hey man,what are you doing!");}即完成了此命令消息响应.11:在本课的最后,为了实现一个在CMainFrame中截获WM_COMMAND消息,而不让它下流到View 类中去的方法:通过重载CWnd::OnCommand()函数!还介绍了一个非常典型的头文件包含编译错误的解决方法,LOWORD()宏的使用!以及如何在CMainFrame类的成员函数中调用CView类中的成员变量的问题-GetActiveView()的使用!<< 六:对话框编程 >>1:分清模态,非模态,系统模态对话框!2:在View类的cpp中响应菜单消息,利用已有的对话框类来产生对话框别忘了在该cpp中包含相应定义对话框类的头文件.3:制作非模态对话框要使用成员变量或者堆上分配的对象,不能在函数内定义一个局部变量来用.示例代码如下:dlg.Create(IDD_MYDIALOG,this);dlg.ShowWindow(SW_SHOW);4:注意一个模态对话框当点击其中的OK按钮时这个对话框是被Destroy了的,而对于一个非模态对话框而言,它只是隐藏了,而并未被Destroy,所以如果你定义了一个非模态对话框,并使用了原有的OK按钮,你一定要重载其基类CDialog 的OnOK()函数,在其中自己调用DestroyWindow().详见MSDN中CDialog::OnOK()函数的讲解页!5:静态文本控件的消息响应要注意一两点:一:要为静态文本控件指定具体的ID,而不能是默认的IDC_STATIC;二: 要在静态文本控件的属性页中的Styles页中将Notify前面的勾打上,才能实现消息响应.下面是一段静态文本控件的操作代码:(设置静态文本的内容);DWORD elapsedTime;elapsedTime=GetTickCount()/1000; //get secondsUINT hours=elapsedTime/3600;UINT minutes=elapsedTime%3600/60;UINT seconds=elapsedTime%3600%60;char times[100];sprintf(times,"系统已运行%d小时%d分钟%d秒!",hours,minutes,seconds); GetDlgItem(IDC_TIME)->SetWindowT ext(times);是在对话框类的成员函数中所做的.6:获取控件文本的几种方法:一:GetDlgItem()->GetWindowText();二:GetDlgItemText();三:GetDlgItemInt();这个函数取到控件文本并将之转换成int返回给调用者.这对如使用EDIT控件获取整数非常方便,并且它可以有效处理有符号数.这个函数的调用稍有复杂,查阅MSDN!四:将控件与成员变量相关联,比如要从EDIT控件获取整数,可以直接将EDIT控件与int类型的变量相关联,它会直接获取整数,并自动做相关的输入数据的类型检测,当然也可以关联CEdit型变量,再间接获取数据,用这种方法时要注意UpdateData()函数的适时调用!如果是CEdit 控件,可以用CEdit中的GetWindowT ext()函数获取其内容!五:通过发送WM_GETTEXT或者WM_SETTEXT消息的方式获取: 分为三种情况:(1)使用合全局的::SendMessage(),如下:::SendMessage(GetDlgItem(IDC_EDIT1)->m_hWnd,WM_GET TEXT,10,(LPARAM)ch1 );//ch1是一个字符数组或者是:::SendMessage(m_edit1.m_hWnd,WM_GETTEXT,10,(LPARAM )ch1); //这是已关联控件变量的情况下(2)使用CWnd的SendMessage(),如下:GetDlgItem(IDC_EDIT1)->SendMessage(WM_GETTEXT,10,(L PARAM)ch1);或者是:m_edit1.SendMessage(WM_GETTEXT,10,(LPARAM)ch1);(3):使用CWnd::SendDlgItemMessage()函数,它实际上相当于先用GetDlgItem()得到控件句柄,再SendMessage(),是一种组合的方便方式!如:SendDlgItemMessage(IDC_EDIT1,WM_GETTEXT,10,(LPARAM)ch1 );在讲这个的时候,还讲到了可以获得一个控件中选中的内容的消息-EM_GETSEL以及可以设置哪些内容被选中的EM_SETSEL消息.使用方法见MSDN.如: SendDlgItemMessage(IDC_EDIT1,EM_SETSEL,1,3);m_edit1.SetFocus();//这句的意义是因为如果该控件不是当前的FOCUS所在,那么即使显示了选中也会不可见.7:实现对话框收缩与扩展功能的代码示例:void CTestDlg::OnButton1(){// TODO: Add your control notification handler code here CString str;GetDlgItemText(IDC_BUTTON1,str);static CRect rectLardge;static CRect rectSmall;if(rectLardge.IsRectNull()){CRect rectSeparator;GetWindowRect(&rectLardge);GetDlgItem(IDC_SEPARATOR)->GetWindowRect(&rectSepar ator);rectSmall.top=rectLardge.top;rectSmall.left=rectLardge.left;rectSmall.right=rectLardge.right;rectSmall.bottom=rectSeparator.bottom;}if(str=="收缩<<"){SetDlgItemT ext(IDC_BUTTON1,"扩展>>");SetWindowPos(NULL,0,0,rectSmall.Width(),rectSmall.Height( ),SWP_NOMOVE | SWP_NOZORDER);}else{SetDlgItemT ext(IDC_BUTTON1,"收缩<<");SetWindowPos(NULL,0,0,rectLardge.Width(),rectLardge.Heig ht(),SWP_NOMOVE | SWP_NOZORDER);}}8:这节课最后讲了如何实现回车时让输入焦点在各个控件之间遍历的方法,其中涉及到了默认键消息响应函数的操作,以及如何用SetWindowLong()来改变一个控件的窗口响应函数的方法.<< 七:对话框编程之二 >>1:要改变对话框内控件上的文本字体,要在对话框的属性对话框中设置,而不是在单个对话框的属性中设置!2:逃跑按钮的制作放置两个外观一样的按钮,初始化为隐藏其中的一个,在对话框类中响应MouseMove消息,一旦检测到鼠标位于某个当前正在显示的按钮上时,就隐藏之,将另一个按钮显示出来.这样给用户的感觉就是只有一个按钮,在躲藏你的鼠标! 而录像中的做法是新建一个继承自CButton的类,然后将两个按钮分别与该新类的一个对象所关联,然后由这个类实现对MouseMove的响应,并在每个对象中放置一个指向本类的公有成员指针变量,指向另一个对象,这样,在响应函数中很方便地实现了ShowWindow(SW_HIDE),以及ShowWindow(SW_SHOW)操作.至于那两个对象中指向对方的指针的初始化可以放在控件所在对话框类的构造函数中,也可以该对话框类中加入一个对WM_INITDIALOG的消息的响应函数,将初始化放置于其中!3:往对话框或其它地方插入组合框(combo box)资源时,初始放置时一定要将它拖大一些,要不然放置好以后其高度无法修改,而且下拉出的列表框部分无法显示出来,只能重新加入一个!4:关于属性表单对话框的制作,一:要插入属性页,并做好控件布局;二:要为每个属性页关联相应的继承自CPropertyPage类的自定义类.三:要在类视图中点根工程图标右键,加入一个类型为MFC Class的新类,其基类为CPropertySheet.四:在该类中分别加入每个属性页类的一个对象.(注意头文件的包含)五:在该类的两个构造函数中都通过AddPage()函数加载每个属性页对象.六:在某个菜单项的响应函数中定义一个该类的对象(其参数为属性表单的标题),然后调用该类的成员函数:DoModal()创建一个模态的表单,或者Create()创建一个非模态的表单.(注意头文件的包含);5:关于向导对话框的制作:向导对话框实际是属性表单的一种变体,只要在属性表单的DoModal()调用生成属性表单之前加上一句:propsheet.SetWizardMode();生成的就是向导对话框而不是表单了.如何去掉默认生成向导对话框第一页中的上一步按钮:在该页的类中增加一个虚函数OnSetActive(),在其中加入如下语句:((CPropertySheet*)GetParent())->SetWizardButtons(PSWIZB _NEXT);即可.如何去掉默认生成向导对话框最后一页的下一步按钮,并且加上结束按钮: 同上理: 在相应的类中增加虚函数OnSetActive(),加入如下语句:((CPropertySheet*)GetParent())->SetWizardButtons(PSWIZB _BACK | PSWIZB_FINISH);注意:如果你在第一页中将上一步按钮去掉了,则后面每一页的上一步按钮都没有了(我觉得这样不太合理)所以你要用同样的方法设置每一个属性页,在其中设置合适的按钮!6:本次课程中提到了用C语言函数memset初始化数组的一种方法很好,如: memset(m_bLike,0,sizeof(m_bLike));<<八:界面修改,工具栏,状态栏,启动画面的制作>>1:如何修改单文档应用程序的窗口标题,查阅MSDC文章:Changing the styles of a window created by MFC.要在MainFrame的PrecreatWindow()中加入如下代码:cs.style&=~FWS_ADDTOTITLE;cs.lpszName="This is a test!";可以先不要上一句试一试!另一种方法是:cs.style=WS_OVERLAPPEDWINDOW;再进行修改,也可以不修改,那么是去掉默认文档标题,而只显示原程序标题!另一类方法是在窗口创建后再修改,因为在OnCreate中,开始的这些代码: if (CFrameWnd::OnCreate(lpCreateStruct) == -1) return -1;if (!m_wndT oolBar.CreateEx(this, TBSTYLE_FLAT, WS_CHILD | WS_VISIBLE | CBRS_TOP| CBRS_GRIPPER | CBRS_TOOLTIPS | CBRS_FLYBY | CBRS_SIZE_DYNAMIC)|| !m_wndT oolBar.LoadToolBar(IDR_MAINFRAME)){TRACE0("Failed to create toolbar\n");return -1; // fail to create}if (!m_wndStatusBar.Create(this) ||!m_wndStatusBar.SetIndicators(indicators,sizeof(indicators)/sizeof(UINT))){TRACE0("Failed to create status bar\n");return -1; // fail to create}// TODO: Delete these three lines if you don't want the toolbar to// be dockablem_wndT oolBar.EnableDocking(CBRS_ALIGN_ANY);EnableDocking(CBRS_ALIGN_ANY);DockControlBar(&m_wndT oolBar);完成了窗口创建,工具栏,状态栏的创建等工作,可以在后面利用一个系统全局函数SetWindowLong()函数进行修改:加入代码为:SetWindowLong(m_hWnd,GWL_STYLE,WS_OVERLAPPEDWIN DOW);与此相对,还有一个GetWindowLong()函数可供使用!如下面代码去掉了窗口上的最大化按钮:SetWindowLong(m_hWnd,GWL_STYLE,GetWindowLong(m_ hWnd,GWL_STYLE) &~MAXIMIZEBOX);当然SetWindowLont()还可以做别的修改.与SetWindowLong()相类似的另一个系统全局函数为SetClassLong();2:如何完成一个动画图标其实就是准备好几个图标,在定时器消息响应中更改图标即可完成.第一步是准备好几个(如三个)图标.第二步是在MainFrame类中做三个图标类的相关对象的成员变量,或者是一个大小为3的HICON数组.第三步是在MainFrame类的OnCreate()函数中LoadIcon()进行对三个图标的加载.其中用到的实例句柄的获取有三种方法: 一:用全局函数AfxGetInstanceHandle()获取,二:先在MainFrame文件中用extern声明一下全局对象theApp,然后使用theApp.hInstance;三:使用全局函数AfxGetApp()获取全局对象theApp对象的指针,然后用AfxGetApp()->hInstance;第二个参数是一个字符指针,可我们只有图标的资源ID,所以要进行必要的转换:用MAKEINTRESOURCE宏!第四步是设置定时器,也在OnCreate()函数中定义:SetTimer(1,1000,NULL);第五步是在MainFrame中添加WM_TIMER消息响应,在其中加入代码:static int index=0;SetClassLong(m_hWnd,GCL_HICON,(LONG)m_hIcons[index] );index=++index%3;3:在工具栏上新加一个按钮,要让它与前一个按钮之间有一个分隔符,只需要将它轻轻向一旁拖动一点点再放开即可,而要删除工具栏上的一个按钮,你只是选中它再按DEL键是完不成的,它只是将按钮上的图案删除,所以删除一个按钮要将它拖动到工具栏之外,再松手!4:如何创建一个工具栏在MSDN 的关于CT oolBar的讲解页有详细说明!一:在CMainFrame中加入一个CT oolBar类对象的成员变量,二:插入工具栏资源,三:在CMainFrame的OnCreate()中加入:if (!m_MyToolBar.CreateEx(this, TBSTYLE_FLAT, WS_CHILD | WS_VISIBLE | CBRS_TOP| CBRS_GRIPPER | CBRS_TOOLTIPS | CBRS_FLYBY |CBRS_SIZE_DYNAMIC)|| !m_MyToolBar.LoadToolBar(IDR_MYTOOLBAR)){TRACE0("Failed to create toolbar\n");return -1; // fail to create}m_MyToolBar.EnableDocking(CBRS_ALIGN_ANY);DockControlBar(&m_MyToolBar);各个函数调用及参数传递查看MSDN!5:如何让一个工具栏隐藏或显示:if(m_MyT oolBar.IsWindowVisible()){m_MyToolBar.ShowWindow(SW_HIDE);}else{m_MyToolBar.ShowWindow(SW_SHOW);}但这样做的结果是工具栏虽说隐藏了,但是工具条还在,所以还要在后面加上一句:ReCalcLayout();这样做还是有问题,如果工具栏没有停靠在边上而是一个单独的小窗口,那么只做上面的工作只使得工具栏上的按钮不见了,而那个小窗口还在,所以,还要调用一个函数:DockControlBar(&m_MyToolBar);经过上面这句,小窗口也如愿消失了,但问题还有一点,就是当用户将工具栏放置为一个小窗口时,再点击菜单,要让这个工具栏显示出来,当然我们应该将工具栏仍按用户先前的小窗口样式显示出来比较好,可是这次工具栏又自动停靠在客户区顶部了?这个功能如何实现呢?孙老师只是提示可以查MSDN中CToolBar的成员函数解决这个问题,并没细讲,所以我看了MSDN,发现有两个函数:CToolBar::IsFloating()利用这个函数可以判断一个工具栏是否处于浮动状态,另一个是CFrameWnd::FloatControlBar()这个函数可以让一个控制栏处于浮动状态,然后我在CMainFrame中加入了一个BOOL型的成员变量,在每次判断工具栏是否可见时用来记录工具栏是否处于浮动状态,然后在重新生成工具栏时根据它的置决定是否将工具栏设为浮动状态,但是第二个函数好像不太好使,所以我又换用了SetWindowPos()成员函数,可是也不能将它放置为一个独立的小窗口.显示和隐藏工具栏的第二种方法:用一个函数:CFrameWnd::ShowControlBar(),因为这个函数的固有特性,上面是if...else...判断就可以简化为一句代码:ShowControlBar(&m_MyToolBar,!m_MyToolBar.IsWindowVis ible(),FALSE); 并且我惊讶的发现,用这个函数时,上面提到的浮动工具栏让它在恢复的时候仍回复为浮动的问题自动解决了!哈哈,好.6:状态栏相关编程因为MFC自动生成的系统已经包含了一个状态栏,所以我们暂时仅限于已有状态栏的修改,而不是另外生成一个状态栏.状态栏最左边的那一长条,就是经常显示一些提示字符串的那部分叫做提示行,而右侧那三个小窗口是用来指示CapsLock,ScrollLock,NumLock开关的状态,称为状态指示器.状态栏跟工具栏一样,也是在CMainFrame类中定义并在OnCreate()中创建的. 下面的代码在状态指示器的最左边放置了两个小窗口,并在第一个小窗口中放置了一个时钟:同样的CMainFrame的OnCreate()中,CTime tm=CTime::GetCurrentTime();CString strTime=tm.Format("%H:%M:%S");CClientDC dc(this);CSize sz=dc.GetTextExtent(strTime);m_wndStatusBar.SetPaneInfo(1,IDS_TIMER,SBPS_NORMAL,s z.cx);//调整窗口大小。
孙鑫老师Visual-C++第一章
(2) ResourceView(资源视图)
显示项目中所包含的资源文件。展开文件夹可显示 所有的资源类型。
(3) (文件视图)
显示所创建的工程。展开文件夹可以查看工程中所 包含的文件。窗格显示了工程文件和项目工作区中 所包含的文件的逻辑关系。一个工作区可以包含多 个工程,其中活动工程以黑体显示。活动配置决定 了编译活动工程时的编译选项。
活动工程是使用Build或Rebuild All时要编译的那一 个工程。可以用Build菜单上的Set Active Configuration选择不同的活动配置; 也可以在 Project菜单上用Set Active Project选择不同的活动工 程。使用可以查看文件、管理文件(包括增加、删除、 移动、重命名、拷贝文件等)。要增加一个文件到过 程中,可以选择Project→Add to Project→Files菜单, 弹出文件对话框,选择相应文件即可; 要从工程中
图1.2 开始菜单中的Visual Studio 6.0和MSDN
Visual Studio 6.0是1998年下半年发布的,由于其中 还存在着很多Bugs,以及一些其他原因,截止到 1999年5月底,微软已经专门为Visual Studio 6.0推出 了三次Service Pack(软件更新包),其中SP1解决 了与老版本Visual Studio工具存在着的二进制兼容性 问题,SP2又更换了Java虚拟机,新近发布的SP3则 再次修订了大量的Bugs,因此建议在安装完Visual C++ 6.0后,再找一份SP2或SP3来打个补丁,SP2可 在某些报纸的配套光盘上找到,SP3则暂时需要到微 软的MSDN站点上去下载。
Visual C++6.0 实用教程
[课程]孙鑫VC6.0视频教程目录
孙鑫VC++6.0视频教程目录孙鑫VC++6.0视频教程目录CD1:Windows程序运行原理及程序编写流程,窗口产生过程,句柄原理,消息队列,回调函数,窗口关闭与应用程序退出的工作关系,使用VC++的若干小技巧,stdcall与cdecl调用规范的比较,初学者常犯错误及注意事项。
CD2:C++经典语法与应用,类的编写与应用,构造与析构函数,函数的重载,类的继承,函数覆盖,基类与派生类的构造函数、析构函数先后调用顺序,如何在派生类构造函数中向基类的构造函数传递参数,this成员变量,类型转换的内幕,虚拟函数与多态性,引用和指针的变量的区别与共同处。
VC工程的编译原理与过程,将工程中不同的类拆分到不同的原文件中,每一个类由一个.h和.cpp文件共同完成,头文件重复定义问题的解决,培养了学员良好的编程习惯,也为以后分析MFC Appwizard生成的工程奠定了良好基础。
CD3:讲述MFC AppWizard的原理与MFC程序框架的剖析。
AppWizard 是一个源代码生成工具,是计算机辅助程序设计工具,WinMain在MFC 程序中是如何从源程序中被隐藏的,theApp全局变量是如何被分配的,MFC框架中的几个类的作用与相互关系,MFC框架窗口是如何产生和销毁的,对窗口类的PreCreateWidow和OnCreate两个函数的着重分析,Windows窗口与C++中的CWnd类的关系。
CD4:MFC消息映射机制的剖析,讲述如何运用ClassWizard,,理解发送给窗口的消息是如何被MFC框架通过窗口句柄映射表和消息映射表来用窗口类的函数进行响应的。
掌握设备描述表及其封装类CDC 的使用,CDC是如何与具体的设备发生关联的,融合具体的画图程序进行分析。
如何设置封闭图形的填充刷子(位图画刷与透明画刷的使用)。
CD5:掌握CDC的文字处理程序的编写,如何产生自定义字体和自定义插入符,熟悉对CString类的使用。
孙鑫笔记2
4, PreCreateWindow()是个虚函数,如果子类有则调用子类的。
5, CreateWindowEx()函数参数与CREATESTRUCT结构体成员完全一致,CreateWindowEx()函数与CREATESTRUCT结构体参数的对应关系,使我们在创建窗口之前通过可PreCreateWindow(cs)修改cs结构体成员来修改所要的窗口外观。
对于MFC程序,MainFrame,View,ToolBar,Controlbar等都是窗口,所以下面的窗口注册与创建、显示等要反复调用多次,一次对应一个窗口
(1) 注册窗口类
AfxEndDeferRegisterClass
(2) 创建窗口
CMainFrame::PreCreateWindow()//反复调用一次是给我们修改窗口属性的机会
一、C语言程序执行步骤
在C语言中,大约的步骤如下:
1, 全局变量内存分配 要是初始化)
打开一个MFC APPWizard(exe)工程,跟踪其执行步骤,可以发现,是以下顺序:
1) CXXApp中的全局变量定义
1) 设计一个窗口类
2) 注册窗口类
3) 创建窗口
4) 显示及更新窗口
5) 消息循环
补充2:其他需要注意的几点
1, 每一个MFC程序,有且只有一个从WinApp类派生的类(应用程序类),也只有一个从应用程序类所事例化的对象,表示应用程序本身。在WIN32程序当中,表示应用程序是通过WINMAIN入口函数来表示的(通过一个应用程序的一个事例号这一个标识来表示的)。在基于MFC应用程序中,是通过产生一个应用程序对象,用它来唯一的表示了应用程序。
6,注意两个函数。
孙鑫C++教程 完整版
从变量的类型区分变量的用途
int x,y; x=30; y=30; //x和y既可以用来表示坐标点,也可以用来表示宽度和 高度,还可以用来表示身高和体重。 typedef int WIDTH typedef int HEIGHT WIDTH x; HEIGHT y; //好处:我们从变量的类型上就可以知道x和y是用来表 示宽度和高度。
2.掌握C++
C++的标准输入输出流
C++中提供了一套输入输出流类的对象,它们是cin 、cout和cerr,对 应c语言中的三个文件指针stdin、stdout、stderr,分别指向终端输入、 终端输出和标准出错输出(也从终端输出)。cin与>>一起完成输入 操作,cout、cerr与<<一起完成输出与标准错误输出。利用cin和cout 比C语言中的scanf和printf要方便得多,cin和cout可以自动判别输入输 出数据类型而自动调整输入输出格式,不必像scanf和printf那样一个 个由用户指定。使用cin,cout不仅方便,而且减少了出错的可能性。 对于输出来说,我们像以上方式调用就可以了,对于输入来说,我 们以如下方式调用即可: int i; cin>>i; 注意箭头的方向。在输出中我们还使用endl(end of line),表示换 行,注意最后一个是字符‘l’,而不是数字1,endl相当于C语言的 '\n',表示输出一个换行。
C++的特性
构造函数
1、构造函数最重要的作用是创建对象本身 。 2、C++规定,每个类必须有一个构造函数, 没有构造函数,就不能创建任何对象。
C++的特性
孙鑫VC学习笔记第5课
//DEL {
//DEL m_nWidth=0;
//DEL dc.SetTextColor(RGB(0,255,0));
//DEL dc.TextOut(0,200,str);
//DEL }
b.取出动态创建的菜单的数据的方法。
1)创建一个弹出菜单,弹出菜单下面有4个子菜单。将子菜单的ID号连续。
2)在resource.h中添加#define IDM_PHONE1 123....
3)添加其消息响应函数。注意注释中的文字
BEGIN_MESSAGE_MAP(CMenu2View, CView)
CRgn rn;
rn.CreateRectRgn(0,50,sz.cx,sz.cy);
pDC->SelectClipRgn(&rn,RGN_DIFF);
路径层有什么作用?可以保护我们先前的文本或者图像不被后来画的覆盖。
4.在View上输入文字的步骤。
CMenu *pPopup=menu.GetSubMenu(0);
ClientToScreen(&point);
pPopup->TrackPopupMenu(TPM_LEFTALIGN | TPM_RIGHTBUTTON, point.x, point.y,
GetParent());
dc.TextOut(m_ptOrigin.x,m_ptOrigin.y,m_strLine);
m_strLine=m_strLine.Left(m_strLine.GetLength()-1);
孙鑫VC++教程之第03节 指针与数组
我们看到a, &a , &a[0]输出的结果都是一致的, 他们都是数组的首地址,这里a体现的是指针 的特性,&a则体现了结构的特性。但是对于p 来讲就不一样了,因为指针p在开始的时候开 辟了一块自己的内存空间,经过p=a后,p里面 放的是数组a的首地址,所以p和&p[0]结果都 是数组a的首地址,但是&p则是指针p本身的内 存地址。 那么一维数组究竟是什么含义呢?
第三节、数组与指针
目标: 1. 一维数组与指针 2.数组越界 3.指针和堆的内存分配 4.丢失指针
一、一维数组与指针
1、什么是数组? 数组是一组数据存储单元,每个单元保存相同数据类 型,每个存储单元成为数组的一个元素。 2、什么是指针? 指针是一个变量,它保存了一个变量的地址。 首先我们看一下下面的例子: char a[10], *p; p=a;
三、指针和堆的内存分配
前面谈到无论什么类型的指针,win32下都是占4个字节 的内存空间。那么对于指针的类型,有什么作用呢? 答:指针的类型代表着指针内存空间中存储的变量的类 型,同时也是指针运算时的步长。 例如:char a[] = “hello”; char *p = a; p++; //p++时,对于char型,p向前迈进1个字节。 Int a[] = {1,2,3,4,5,6}; Int* p = a; P++; //p++时,对于int型,p向前迈进4个字节。
下面是从堆中申请数组 1、申请数组空间: 指针变量名=new 类型名[下标表达式]; 注意:“下标表达式”不是常量表达式,即它的值不必在编译 时确定,可以在运行时确定。这就是堆的一个非常显著的特点, 有的时候程序员本身都不知道要申请能够多少内存的时候,堆 就变的格外有用。 2、释放数组空间: delete [ ]指向该数组的指针变量名; 注意:方括号非常重要的,如果delete语句中少了方括号,因 编译器认为该指针是指向数组第一个元素的,会产生回收不彻 底的问题(只回收了第一个元素所占空间),我们通常叫它 “内存泄露”,加了方括号后就转化为指向数组的指针,回收 整个数组。delete [ ]的方括号中不需要填数组元素数,系统自 知。即使写了,编译器也忽略。<<Think in c++>>上说过以前 的delete []方括号中是必须添加个数的,后来由于很容易出错, 所以后来的版本就改进了这个缺陷。
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中有默认⽩⾊画刷。
孙鑫VC学习笔记第3课
而在BOOL CTestApp::InitInstance()中的代码
CSingleDocTemplate* pDocTemplate;
pDocTemplate = new CSingleDocTemplate(
IDR_MAINFRAME,
RUNTIME_CLASS(CTestDoc),
在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"的声明。�
第3课
1.在main或WinMain之前,全局变量已经被分配内存并初始化了。
2.在MFC中在WinMain之前有个theApp全局变量先被构造并被初始化,而由于子类构造函数执行前,其父类的构造函数先被执行,所以CTestApp的父类CWinAPP的构造函数先执行。产生了theApp对象后,在WinMain()中的指针*pThread和*pApp就有了内容。
孙鑫VC教程之Windows编程基础
Windows基础-消息-消息循环
在应程序中有一个消息循环,它的代码如下: while(GetMessage(&msg, NULL, 0, 0)) { TranslateMessage(&msg); DispatchMessage(&msg); } 只要从应用程序消息队列中接受到的消息不是WM_QUIT,消息循环就继续 从消息队列中接收消息。当收到WM_QUIT消息后,GetMessage将返回 false,这样应用程序将终止运行。但只要循环继续下去,它就调用Win32 API的GetMessage函数获取下一消息;如果队列中没有消息,GetMessage 就会等待消息的到来。 当GetMessage返回一个消息后,采用TranslateMessage函数来看一下是否 由键盘输入,若由键盘输入则将原始的键盘消息转化为WM_CHAR消息。 TranslateMessage也可以用来处理键盘命令如Ctrl+X组合键等, TranslateMessage对非键盘消息则不进行任何处理。 最后,DispatchMessage消息确定应用程序哪一个窗口将获得消息,并把它 发送给该窗口。
设备描述表--句柄 Windows用句柄来标识和管理对象。句柄 是Windows系统给的,且是唯一的,并可通过 Windows访问。例如,调用GetDC函数可返回 设备描述表(即DC)句柄。设备描述表句柄类 型是HDC。Windows提供了许多句柄类型,如 窗口、画刷、字体等对象都有一个相关的句柄 类型:HWND、HBRUSH和HFONT,下表显示 了不同对象的句柄类型。
Windows基础-消息-谁来调用
在所编写的消息处理函数中,可调用Win32 API, 消息处理函数由Windows负责调用。大多数时间,程 序代码等待被调用。 对Windows几百个消息,如果程序员不编写消息 处理函数,则Windows提供一个缺省的DefWindowsProc 函数。 Windows如何知道是那一个函数被调用呢?在由 C编写的Windows程序中,在程序开始【WinMain函数 中】设置WinProc的名字,然后采用这个名字编写函数。 在WinProc函数中,使用C/C++switch语句,根据不同 的消息,调用相应的消息处理函数。当有一个窗口消 息时,Windows调用该处理函数。在MFC中,可以不 用编写窗口程序,只要编写消息处理函数,MFC通过 消息映射来为消息查找相关的消息处理函数。
孙鑫VC++从入门到精通开发详解视频教程FLASH版
第85集 第十课 A-1
第86集 第十课 A-2
第87集 第十课 B
第88集 第十课 C
第89集 第十课 D
第90集 第十课 E
第91集 第十课 F
第92集 第十课 G
第93集 第十课 H
第94集 第十课 I
第26集 第三课 G
第27集 第三课 H
第28集 第三课 I
第四课 MFC消息映射机制的剖析 讲述如何运用ClassWizard
第29集 第四课 A-1
第30集 第四课 A-2
第31集 第四课 B
第32集 第四课 C
第33集 第四课 D
第50集 第六课 G
第51集 第六课 H
第52集 第六课 I
第53集 第六课 J
第54集 第六课 K
第七课 对话框用户界面程序的编写
Hale Waihona Puke 第55集 第七课 A-1
第56集 第七课 A-2
第57集 第七课 B
第58集 第七课 C
第一课 Windows程序运行原理及程序编写流程
第1集 第一课 A-1
第2集 第一课 A-2
第3集 第一课 B
第4集 第一课 C
第5集 第一课 D
第6集 第一课 E
第7集 第一课 F
第8集 第一课 G
第9集 第一课 H
第42集 第五课 G
第六课 菜单的工作原理及编写应用
第43集 第六课 A-1
第44集 第六课 A-2
第45集 第六课 B
第46集 第六课 C
第47集 第六课 D
第48集 第六课 E
孙鑫vc课程笔记
作者tag:windows/.net孙鑫vc++讲座笔记 CSDN 推荐孙鑫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传递的。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
视频特色内容介绍何被分配的,MFC框架中的几个类的作用与相互关系,MFC框架窗口是如何产生和销毁的,对窗口类的PreCreateWidow和OnCreate两个函数的着重分析,Windows窗口与C++中的CWnd类的关系。
Lesson4:MFC消息映射机制的剖析,讲述如何运用ClassWizard,,理解发送给窗口的消息是如何被MFC框架通过窗口句柄映射表和消息映射表来用窗口类的函数进行响应的。
掌握设备描述表及其封装类CDC的使用,CDC是如何与具体的设备发生关联的,融合具体的画图程序进行分析。
如何设置封闭图形的填充刷子(位图画刷与透明画刷的使用)。
Lesson5:掌握CDC的文字处理程序的编写,如何产生自定义字体和自定义插入符,熟悉对CString类的使用。
通过对卡拉OK程序的编写,讲解定时器的使用和DrawText函数的巧妙运用。
讲解如何使用CDC 的裁减功能。
Lesson6:菜单的工作原理及编写应用,菜单命令消息在MFC框架程序的几个类中的传递顺序和处理过程。
标记菜单、缺省菜单的实现原理、图形菜单的实现及常犯错误的分析,GetSystemMetrics的应用,快捷弹出菜单的实现方式及其命令响应函数有效范围(与弹出菜单时所指定的父窗口有密切的关系,最底层的子窗口具有最优先的处理机会)。
动态菜单的编写,如何让程序在运行时产生新的菜单项及如何手工为这些新产生的菜单命令安排处理函数,如何在顶层窗口中截获对菜单命令的处理,更进一步掌握CString 类的应用。
Lesson7:对话框用户界面程序的编写,如何向对话框控件关联数据成员及其实现机理,如何利用对话框类的成员函数向控件发送消息和获取对话框控件的类指针,如何直接利用对话框控件类操纵对话框控件(发送消息和直接调用成员函数)。
如何在程序运行时产生和销毁控件。
对话框控件的几种操作方式的优劣比较分析。
如何实现对话框的部分收缩和展开。
如何让对话框上的文本框在程序启动后立即获得焦点,如何利用SetWindowLong改变窗口的回调函数,通过改变文本框的默认回车处理方式进行演示。
实现多个输入文本框间通过回车逐一向下传递焦点的另一种巧妙方法(用缺省按钮来处理)。
Lesson8:逃跑按钮的巧妙实现。
如何制作属性页对话框和向导对话框,融合讲解组合框(如何调整组合框的大小)、列表框、单选按钮、复选按钮等常用对话框控件的多种使用方法。
如何限制用户在不满足设定的条件时切换到其他属性页和向导页。
Lesson9:如何修改MFC AppWizard向导生成的框架程序的外观和大小,修改图标、光标、背景的三种方法。
如何增加和删除工具栏按钮,如何给应用程序增加工具栏,如何显示和隐藏工具栏。
定制状态栏,在状态栏中添加时钟显示,CTime类及其用法。
在状态栏中添加进度条(主窗口产生后立即产生进度条的巧妙思想,不能在OnCreate函数中直接处理,要用到自定义消息的方法)。
鼠标坐标显示,在CView中获取状态栏对象的几种方式。
如何为应用程序添加启动画面。
Lesson10:图形的绘制,如何使用自定义画笔(颜色,线宽,线型)。
如何为程序中添加选项菜单和选项设置对话框,如何使用标准颜色对话框,如何使用字体对话框,在选项对话框中实现预览功能。
实现选项对话框和窗口类中的数据交换。
如何改变对话框和控件的背景色,如何改变控件的文本颜色,对按钮控件的特殊处理。
如何在窗口中显示一幅位图。
Lesson11:如何让CDC上输出的文字、图形具有保持功能,集合类CPtrArray的使用,CPaintDC与CClientDC的区别与应用,OnPaint与OnDraw在CView中的关系及实现内幕,滚动窗口的实现,坐标空间,映射方式,设备坐标与逻辑坐标的转换。
元文件设备描述表的使用,如何利用兼容DC实现图形的保存和再现。
Lesson12:const char *与char * const的区别。
C语言对文件读写的支持,FILE指针;文本文件和二进制文件的区别。
用文本方式读写文件和以二进制方式读写文件的注意事项。
C++对文件读写的支持,ofstream和ifstream的用法。
Win32 SDK对文件读写的支持,CreateFile函数、WriteFile函数、ReadFile 函数的使用;MFC对文件读写的支持,CFile类和CFileDialog的使用,文件过滤器的设置。
win.ini文件和注册表的读写方式及相关知识点。
Lesson13:使用CArchive类对文件进行操作。
MFC框架程序提供的文件新建与打开功能内部的实现机制。
如何利用CDocument类的串行化存储功能保存与加载数据。
如何实现类对串行化的支持,CObArray的串行化实现内幕。
删除文档数据时常犯的错误。
MFC框架程序的文档类和视类的关系,以及如何获得相互的指针引用。
Lesson14:网络的相关知识,网络程序的编写,Socket是连接应用程序与网络驱动程序的桥梁,Socket 在应用程序中创建,通过bind与驱动程序建立关系。
此后,应用程序送给Socket的数据,由Socket交给驱动程序向网络上发送出去。
计算机从网络上收到与该Socket绑定的IP+Port相关的数据后,由驱动程序交给Socket,应用程序便可从该Socket中提取接收到的数据。
网络应用程序就是这样通过socket进行数据的发送与接收的。
TCP与UDP的工作原理与编写过程,如何在程序中链接库文件。
一个字符界面的聊天程序。
Lesson15:多线程程序的编写,多线程应用中容易出现的问题。
互斥对象的讲解,如何使用互斥对象来实现多线程的同步。
如何利用命名互斥对象保证应用程序只有一个实例运行。
应用多线程编写网络聊天室程序。
Lesson16:事件内核对象、关键代码段(临界区)的讲解,以及在多线程同步中的应用。
在Windows下编写基于消息的网络应用程序,掌握阻塞与非阻塞网络程序的编写,理解在Windows平台下,采用异步选择机制可以提高网络应用程序的性能。
Lesson17:详细讲解进程间通讯的四种方式:剪贴板、匿名管道、命名管道和邮槽。
并比较分析这几种进程间通信的优点和缺点。
Lesson18:ActiveX控件的应用与工作原理。
ActiveX控件的编写,如何为控件安排属性,方法,事件,属性页,持久性存储,控件如何通知容器自身属性的改变。
如何注册控件与取消控件注册。
在VB和VC中访问ActiveX控件。
Lesson19:动态链接库程序的编写。
静态库与动态库的区别,以及调用程序在链接静态库和动态库时的区别。
如何利用工具查看动态链接库输出的函数,Depends工具的使用,C++编译器名字改编技术对动态链接库输出函数的影响,extern "C"的用法,利用模块定义文件来解决C++名字改编的问题。
用typedef定义指向函数的指针类型,如何获得动态连接库里的函数的指针。
Lesson20:Hook编程。
如何安装钩子过程,如何编写全局钩子,动态连接库里的全局变量数据共享问题视频特色定义问题的解决,培养了学员良好的编程习惯,也为以后分析MFC AppWizard生成的工程奠定了良好基础。
Lesson3:讲述MFC AppWizard的原理与MFC程序框架的剖析。
AppWizard是一个源代码生成工具,是计算机辅助程序设计工具,WinMain在MFC程序中是如何从源程序中被隐藏的,theApp全局变量是如何被分配的,MFC框架中的几个类的作用与相互关系,MFC框架窗口是如何产生和销毁的,对窗口类的PreCreateWidow和OnCreate两个函数的着重分析,Windows窗口与C++中的CWnd类的关系。
Lesson4:MFC消息映射机制的剖析,讲述如何运用ClassWizard,,理解发送给窗口的消息是如何被MFC框架通过窗口句柄映射表和消息映射表来用窗口类的函数进行响应的。
掌握设备描述表及其封装类CDC的使用,CDC是如何与具体的设备发生关联的,融合具体的画图程序进行分析。
如何设置封闭图形的填充刷子(位图画刷与透明画刷的使用)。
Lesson5:掌握CDC的文字处理程序的编写,如何产生自定义字体和自定义插入符,熟悉对CString类的使用。
通过对卡拉OK程序的编写,讲解定时器的使用和DrawText函数的巧妙运用。
讲解如何使用CDC 的裁减功能。
Lesson6:菜单的工作原理及编写应用,菜单命令消息在MFC框架程序的几个类中的传递顺序和处理过程。
标记菜单、缺省菜单的实现原理、图形菜单的实现及常犯错误的分析,GetSystemMetrics的应用,快捷弹出菜单的实现方式及其命令响应函数有效范围(与弹出菜单时所指定的父窗口有密切的关系,最底层的子窗口具有最优先的处理机会)。
动态菜单的编写,如何让程序在运行时产生新的菜单项及如何手工为这些新产生的菜单命令安排处理函数,如何在顶层窗口中截获对菜单命令的处理,更进一步掌握CString 类的应用。
Lesson7:对话框用户界面程序的编写,如何向对话框控件关联数据成员及其实现机理,如何利用对话框类的成员函数向控件发送消息和获取对话框控件的类指针,如何直接利用对话框控件类操纵对话框控件(发送消息和直接调用成员函数)。
如何在程序运行时产生和销毁控件。
对话框控件的几种操作方式的优劣比较分析。
如何实现对话框的部分收缩和展开。
如何让对话框上的文本框在程序启动后立即获得焦点,如何利用SetWindowLong改变窗口的回调函数,通过改变文本框的默认回车处理方式进行演示。
实现多个输入文本框间通过回车逐一向下传递焦点的另一种巧妙方法(用缺省按钮来处理)。
Lesson8:逃跑按钮的巧妙实现。
如何制作属性页对话框和向导对话框,融合讲解组合框(如何调整组合框的大小)、列表框、单选按钮、复选按钮等常用对话框控件的多种使用方法。
如何限制用户在不满足设定的条件时切换到其他属性页和向导页。
Lesson9:如何修改MFC AppWizard向导生成的框架程序的外观和大小,修改图标、光标、背景的三种方法。
如何增加和删除工具栏按钮,如何给应用程序增加工具栏,如何显示和隐藏工具栏。
定制状态栏,在状态栏中添加时钟显示,CTime类及其用法。
在状态栏中添加进度条(主窗口产生后立即产生进度条的巧妙思想,不能在OnCreate函数中直接处理,要用到自定义消息的方法)。
鼠标坐标显示,在CView中获取状态栏对象的几种方式。
如何为应用程序添加启动画面。
Lesson10:图形的绘制,如何使用自定义画笔(颜色,线宽,线型)。
如何为程序中添加选项菜单和选项设置对话框,如何使用标准颜色对话框,如何使用字体对话框,在选项对话框中实现预览功能。
实现选项对话框和窗口类中的数据交换。