![](https://img-blog.csdnimg.cn/20201014180756930.png?x-oss-process=image/resize,m_fixed,h_64,w_64)
VC++孙
将VC++深入详解这本书进行学习、简化、整理。
身影王座
人生在世,谦字当头;学海无涯,愿得一慧眼,以小观世界。
展开
-
第十八章、ActiveX控件
第十八章、ActiveX控件ActiveX控件可以看作是一个极小的服务器应用程序,他不能独立运行,必须嵌入到某个容器程序中,与该容器一起运行。18.1ActiveX控件在本章中我们用VB作为ActiveX控件的测试容器。首先新建一个VB应用程序,加载一个ActiveX控件:Project\Components,弹出如下组件对话框,如图这个对话框列出了本机可用的ActiveX控件,选择Microsoft Winsock Control6.0这一控件,该控件对应的文件是MSWINSOCK.OCX,OCX是原创 2020-07-05 09:35:42 · 1154 阅读 · 0 评论 -
17.3命名管道
17.3命名管道17.3.1基础知识//匿名管道只能在本地机器的父子进程之间通信,而命名管道不仅可以在本地机器上实现两个进程间的通信,还可以跨网络实现两个进程间的通信。//将命名管道作为网络编程方案时,它实际上建立了客户机/服务器通信体系,并在其中可靠地传输数据。命名管道服务器和客户机的区别在于:服务器是唯一一个有权创建命名管道的进程,也只有它才能接收管道客户机的连接请求,而客户机只能同一个现成的命名管道服务器建立连接。//命名管道提供了两种基本通信模式:字节模式和消息模式。如果程序中像创建一个命名原创 2020-07-03 09:16:17 · 305 阅读 · 0 评论 -
17.2匿名管道
17.2匿名管道17.2.1基础知识//匿名管道是一个未命名的、单向管道,通常用在一个父进程和一个子进程之间传输数据。匿名管道只能实现本地机器上两个进程间的通信,而不能实现跨网络的通信。为创建匿名管道,需要调用CreatePipe函数:BOOL CreatePipe( PHANDLE hReadPipe, // 返回管道读取的句柄 PHANDLE hWritePipe, // 接收管道写入的句柄 LPSECURITY_ATTRIBU原创 2020-06-29 08:19:47 · 547 阅读 · 0 评论 -
第十七章、进程间的通信
第十七章、进程间的通信//每个进程拥有的4GB空间是私有的,一个进程不能访问另一个进程地址空间中的数据,这里介绍4种进程间的通信方式:剪贴板、匿名管道、命名管道、邮槽。17.1剪贴板//先建立一个对话框应用程序,命名为Clipboard,然后添加如图所示的控件。实现的基本功能就是向左边编辑框输入数据,单击发送按钮,将数据发送到剪切板上;单击接收按钮,从剪切板上面取出数据,并在右边的编辑框中显示出来。17.1.1数据发送//数据放到剪贴板之前,首先得打开剪切板,利用CWnd类的OpenClipbo原创 2020-06-28 17:11:25 · 246 阅读 · 0 评论 -
16.5基于消息的异步套接字
16.5基于消息的异步套接字//在很多情况下,阻塞方式会影响应用程序的性能,所以有时需要采用非阻塞方式实现网络应用程序,有很多机制可以实现这种方式。采用异步套接字能够有效提高应用程序的性能。16.5.1相关函数的说明//WSAAsyncSelect函数int WSAAsyncSelect ( SOCKET s, //套接字描述符 HWND hWnd, //接收消息的窗口句柄 unsigned int wMsg, //窗口收到的消息 long l原创 2020-06-24 15:46:31 · 219 阅读 · 0 评论 -
16.2关键代码段
16.2关键代码段关键代码段,也成为临界区,工作在用户方式下。它是指一个小代码段,在代码能够执行之前,它必须独占对某些资源的访问权。16.2.1相关的API函数在进入关键代码段之前,首先得初始化这样一个关键代码段,这个用InitializeCriticalSection函数实现。VOID InitializeCriticalSection( LPCRITICAL_SECTION lpCriticalSection // address of critical原创 2020-06-23 09:26:41 · 176 阅读 · 0 评论 -
# 第十六章、线程同步与异步套接字编程 ##
16.1事件对象事件对象也属于内核对象,主要包括三个成员:使用计数;指定是自动重置事件还是人工重置事件的布尔值;指定是已通知状态还是未通知状态的布尔值。16.1.1创建事件对象//CreateEvent函数创建一个匿名或者命名的事件对象:HANDLE CreateEvent( LPSECURITY_ATTRIBUTES lpEventAttributes, // 若为NULL,指定默认的安全性 BOOL bManualReset, // TRUE原创 2020-06-22 10:28:55 · 162 阅读 · 0 评论 -
15.3.2多线程程序容易出现的问题
//如果线程2执行完上述操作之后,正好轮到线程1开始执行,而这时线程1上次是执行到if语句块之后才暂停的,而这时tickets变量的值已经为0了,也就是线程1卖了号码为0的票。//为了避免上述情况的发生,要求在多个线程之间进行一个同步处理,保证一个线程访问共享资源时候,其他线程不能访问该资源。15.3.3利用互斥对象实现线程同步//互斥对象属于内核对象,他能确保线程对单个资源的互斥访问权;互斥对象包含一个使用数量,一个线程ID与一个计数器,其中ID用于标识系统中的那个线程当前拥有互斥对象,计数器表示该原创 2020-06-19 09:49:29 · 279 阅读 · 0 评论 -
第十五章、多线程
15.1线程创建函数创建线程可以利用系统提供的API函数:CreateThread函数来完成。HANDLE CreateThread( LPSECURITY_ATTRIBUTES lpThreadAttributes, DWORD dwStackSize, // 初始化线程大小,若为0时使用默认大小 LPTHREAD_START_ROUTINE lpStartAddress, //新线程起始地址 LPVOID lpParameter, // 给新创建的线程传原创 2020-06-18 10:02:18 · 146 阅读 · 0 评论 -
14.3基于TCP的网络应用程序的编写
14.3.1服务器端程序先建立一个Win32 Console Application程序,取名为TCPSrv。在应用向导中选择An empty project。然后在该工程下添加一个C++源文件。#include<Winsock2.h>#include<stdio.h>void main(){ //加载套接字库 WORD wVersionRequested; WSADATA wsaData; int err; wVersionRequ原创 2020-06-14 15:59:05 · 534 阅读 · 0 评论 -
第十四章、网络编程
14.1Windows Sockets的实现Windows Sockets是Microsoft Windows的网络程序设计,以动态链接库的形式提供给我们使用。14.1.1套接字的类型流式套接字(SOCK_STREAM):流式套接字实际上是基于TCP协议实现的。数据报套接字(SOCK_DGRAM):数据包套接字实际上是基于UDP协议实现的。原始套接字(SOCK_RAW)14.1.2基于TCP(面向连接)的Socket编程基于TCP的Socket编程的服务器端程序流程:1、创建套接字(socket原创 2020-06-13 11:29:54 · 190 阅读 · 0 评论 -
13.4可串行化类
13.4.1实现类对串行化的支持如果要用CArchive类保存对象的话,那么这个对象的类必须支持串行化。一个可串行化的类通常有一个Serialize成员函数。要想使一个类可串行化,要经历以下5个步骤:1、从CObject派生类2、重写Serialize成员函数3、使用DECLARE_SERIAL宏:DECLARE_SERIAL( class_name )参数就是想要成为可串行化类的类名。4、定义不带参数的构造函数5、为类在实现文件中使用IMPLEMENT_SERIAL宏:IMPLEMENT_原创 2020-06-12 17:28:24 · 395 阅读 · 0 评论 -
第十三章、文档与串行化
13.1使用CArchive类对文件进行读/写操作我们可以利用CArchive类将对象数据永久地保存到磁盘文件上,再次重启后仍然可以读取对象数据。让对象数据持久性的过程就称为串行化。CArchive对象可以认为就是一种二进制流。首先在创建CArchive对象之前必须先建一个CFile类或其派生类对象;当构造一个CArchive对象后,就可以将它与CFile类或者其派生类对象相关联。应该注意,一个文件(CFile对象)只能与一个活动的存档对象相关联。CArchive类重载了<<和>>原创 2020-06-08 09:15:09 · 245 阅读 · 0 评论 -
12.6Win.ini文件的访问
12.6.1Win.ini文件的结构现在大部分软件将信息写入注册表中,然后在软件启动时,从注册表中读取这些初始化信息。但是早期的一些程序都是将这些初始化信息写入Win.ini文件中,该文件位于系统安装根目录下的Wi目录下。12.6.2Win.ini文件的写入在程序中,如果想要向Win.ini文件写入一些初始化信息,可以使用WriteProfileString函数来实现。该函数的作用是将一个字符串复制到Win.ini文件指定段中。BOOL WriteProfileString( LPCTSTR l原创 2020-06-07 08:49:26 · 984 阅读 · 0 评论 -
12.3C++对文件操作的支持
在C++中,向文件写入数据可以用ofstream类来实现ofstream( const char* szName, int nMode = ios::out, int nProt = filebuf::openprot );第一个参数是要打开的文件名;第二个参数指定文件打开的模式;第三个参数指定文件保护规格。下面利用ofsream类实现文件的写入操作:void CFileView::OnFileWrite() { // TODO: Add your command handler code he原创 2020-06-06 08:20:22 · 227 阅读 · 0 评论 -
第十二章、文件和注册表操作
12.1const char*和char *constconst char*:不能修改其指向的内存中的内容,但可以修改其所指向的内存地址。char *const:能修改其指向的内存中的内容,但不可以修改其所指向的内存地址。12.2C语言对文件操作的支持新建一个单文档类型的MFC程序,取名为File。然后添加一个子菜单,名称为:文件操作。然后为其添加两个菜单项,并分别添加视类的命令响应函数:ID:IDM_FILE_WRITE 菜单名称:写入文件 响应函数:OnFileWriteID:IDM_FI原创 2020-06-05 08:50:00 · 143 阅读 · 0 评论 -
11.3窗口滚动功能的实现
11.3.1CScrollView类在创建向导的第六步可以把视类的基类选择为CScrollView,这样,视图窗口就有了滚动功能。如图。在这里也可以手工将视图的基类由CView改为CStrollView:先将视类头文件中将CView修改为CScrollView。Edit->Replace->Find what输入CView,Repalce with输入CStrollView->选中Match whole word only,单击Repalce All。就可以将视类源文件中的也修改原创 2020-06-02 09:15:56 · 790 阅读 · 0 评论 -
第十一章、图形的保存和重绘
11.1坐标空间和转换11.1.1坐标空间和转换Win32应用程序编程接口(API)使用四种坐标空间:世界坐标系空间、页面空间、设备空间和物理设备空间。前两种称为逻辑空间,最后一种通常指应用程序窗口的客户区。11.1.2转换如果应用程序调用了SetWorldTransform函数,那么映射就从世界坐标系空间开始;否则,映射在页面空间进行。转换是把对象从一个坐标空间复制到另一个坐标空间时改变或者转变这一对象的大小、方位和形态。在实际绘图时,世界坐标系空间中的一个区域要先被映射到页面空间,然后再由原创 2020-06-01 13:23:41 · 381 阅读 · 0 评论 -
10.5示例对话框
在对话框中设置一个示例区,当用户选择不同线型时,在示例区能看到。首先在对话框中设置一个组框,Caption为组框,因为要对组框进行操作,将其ID设置为IDC_SAMPLE。当用户对编辑框上面的文本进行改变时,会向对话框发送一个EN_CHANGE通知消息;同样地,当用户单击单选按钮时,该按钮会向对话框发送BN_CLICKED消息。对CSettingDlg类添加编辑框控件EN_CHANGE消息响应函数,三个单选按钮的BN_CLICKED消息响应函数。在四个添加的消息响应函数中调用Invalidate函数原创 2020-05-31 09:00:25 · 247 阅读 · 1 评论 -
10.3颜色对话框
MFC为我们提供了一个类:CColorDialog类,可以很方便创建一个颜色对话框。CColorDialog类构造函数:CColorDialog( COLORREF clrInit = 0, DWORD dwFlags = 0, CWnd* pParentWnd = NULL );第一个参数指定默认颜色选择,默认是黑色。第二个参数来设置对话框的功能和它的外观。第三个参数指向父窗口或者拥有者窗口指针。在绘图子菜单下添加颜色菜单项,ID设置为IDM_COLOR,在视类中为该菜单项添加命令消息响应函数原创 2020-05-29 08:00:36 · 502 阅读 · 1 评论 -
第十章、绘图控制
10.1简单绘图建立一个单文档应用程序,取名为Graphic,此程序将实现点、直线、矩形和椭圆的绘图功能。首先添加一个子菜单,菜单名为绘图,再添加四个菜单项,来控制不同图形的绘制。然后为四个菜单项添加视类命令消息响应函数。当用户单击某个菜单项时,应该将用户的选择保存起来,因此添加一个视类的成员变量:m_nDrawType,私有类型,并在视类的构造函数中将其初始化为0。在四个菜单项命令消息响应函数中将m_nDrawType设置为不同值:void CGraphicView::OnDot() { /原创 2020-05-28 08:54:00 · 405 阅读 · 1 评论 -
9.5状态栏编程
应用程序最下方就是状态栏。状态栏分为两个部分:左边最长的那部分称为提示行;第二个部分就是最右边的三个窗格,主要用来显示CapsLock,NumLock,ScrollLock键的状态,称为状态栏指示器。状态栏对象是在框架类中定义的:CStatusBar m_wndStatusBar;CStatusBar类就是与状态栏相关的MFC类。框架类的OnCreate函数中:if (!m_wndStatusBar.Create(this) || !m_wndStatusBar.SetIndicators(原创 2020-05-24 08:48:29 · 553 阅读 · 0 评论 -
9.3模拟动画图标
利用定时器和SetWindowLong函数就可以实现该功能。9.3.1加载图标资源首先将三个图标资源放到res目录下。接着Insert\Resource->Import->找到res目录,选中上述三个图标资源导入。这样资源视图Icon中就有了三幅新图标:IDI_ICON1,IDI_ICON2,IDI_ICON3。如图。然后,在框架类中,定义一个图标句柄数组的成员变量,框架类上鼠标右键进行添加。如图。接下来就在框架类的OnCreate函数中利用LoadIcon函数来加载这三个图标,同原创 2020-05-23 09:01:21 · 236 阅读 · 0 评论 -
第九章、定制应用程序外观
9.1修改应用程序窗口的外观对于MFC AppWizard生成的应用程序,我们可以在应用程序窗口创建之前修改,也可以在该窗口创建之后进行。9.1.1在窗口创建之前修改新建一个单文档应用程序,取名Style,如果想在应用程序创建之前修改它的外观和大小,就应该在框架类的PreCreateWindow成员函数中进行。BOOL CMainFrame::PreCreateWindow(CREATESTRUCT& cs){ if( !CFrameWnd::PreCreateWindow(cs) )原创 2020-05-22 10:41:17 · 251 阅读 · 0 评论 -
8.2.3向导的创建
创建一个向导类型的对话框,应该遵循创建一个属性表单的步骤来实现,但是在调用属性表单对象之前的DoModal函数之前,应该先调用SetWizardMode函数。propSheet.SetWizardMode();运行程序,如图。但是第一页不应该有上一步的按钮,最后一页不应该有下一步按钮,而应该是完成的按钮。CPropertySheet类提供了一个SetWizardButtons成员函数...原创 2020-04-27 09:07:52 · 373 阅读 · 1 评论 -
8.2属性表单和向导的创建
属性表单就是例如ClassWizard属性表页一样,一个属性表单由一个或者多个属性页组成。提供了对信息分类和组织管理功能。向导就是,你刚开始建立一个工程时,会有一个接一个属性页引导你做出相应的选择。现在新建一个MFC AppWizard(exe)工程,看下向导提供的功能,工程名Prop。1、弹出第一个对话框:选择Single document,同时取消Document/View···选项,将...原创 2020-04-26 08:47:48 · 505 阅读 · 0 评论 -
第八章、对话框(二)
8.1逃跑按钮的实现首先建立一个基于对话框的应用程序的MFC工程,然后发现ClassView中有CAboutDlg,CTestApp,CTestDlg三个类。CTestDlg它是从CDialog类派生出来的一个类,该应用程序的窗口就是一个对话框界面。如图。逃跑按钮:在Test程序的对话框主界面上增加一个按钮,当单击这个按钮时,这个按钮就会移动到另一个位置。1、首先删除该对话框上面的所有控...原创 2020-04-25 08:03:58 · 140 阅读 · 1 评论 -
7.5对话框伸缩功能实现
实现的功能:在Mybole程序的测试对话框中添加一个按钮,将其Caption改为“收缩<<”;单击这个按钮后,测试对话框将会切除一部分,按钮的文本改为“扩展>>”;再次单击这个按钮,对话框将会还原,文本也会再次变化。首先给IDC_BUTTON1按钮添加一个BN_CLICKED消息响应函数,可以通过ClassWizard,也可以通过在这个按钮上双击鼠标左键。然后在该消息响...原创 2020-04-20 08:50:08 · 386 阅读 · 0 评论 -
7.4.3编辑框控件
实现:前两个编辑框输入一个数字,单击Add按钮,求和结果显示在第三个编辑框中。首先把Add按钮下面的消息响应函数的代码去掉。第一种方式:利用GetWindowText和SetWindowText函数。void CTestDlg::OnBtnAdd() { // TODO: Add your control notification handler code here int num1,...原创 2020-04-19 08:17:05 · 300 阅读 · 0 评论 -
7.3动态创建按钮
单击对话框中某个按钮,就动态创建一个新按钮。首先将程序代码恢复到创建模态对话框那个时候的代码。非模态对话框实现起来比较困难。为该对话框添加一个按钮:鼠标双击ResourceView->IDD_DIALOG,打开资源编辑窗口。用鼠标单击控制面板上面的按钮控件,在对话框适当位置上拖出一个适当大小的按钮;用鼠标右键单击该按钮,选择属性对话框,将按钮的ID改为IDC_BTN_ADD,Capt...原创 2020-04-18 08:51:31 · 556 阅读 · 0 评论 -
第七章、对话框(一)
7.1对话框基本知识对话框就是一个窗口,可以接收消息、移动、关闭以及在它的客户区绘图。7.1.1控件所有的控件也是一个个窗口。控件通常作为对话框的子窗口而创建的,也出现在视类窗口、工具栏和状态条中。以后会陆陆续续介绍相应的控件。7.1.2对话框的种类对话框有两种类型:模态对话框和非模态对话框。模态对话框:模态对话框显示的时候,程序会暂停执行。直到关闭这个对话框后,才能继续执行程序。...原创 2020-04-17 08:36:36 · 505 阅读 · 0 评论 -
6.5电话本示例程序
6.5.1动态添加子菜单的实现在程序窗口中输入人名和电话号码,按下回车键,就在帮助菜单之后生成一个子菜单,将人名作为该菜单的菜单项来显示,单击这个菜单项,就会在程序窗口中出现相应的人名和电话号码。将之前的代码都注释起来。窗口中显示键盘输入的文字:需要视类捕获WM_CHAR消息,然后添加相应的消息处理函数。为视类添加一个成员变量:m_nIndex,提示当前第几次按下回车键,int型私有成员变...原创 2020-04-16 07:51:17 · 306 阅读 · 0 评论 -
6.4动态菜单操作
一种是针对弹出菜单操作,一种是针对菜单项的动态操作。6.4.1添加菜单项目重新建立一个单文档工程,进行添加菜单项目,之前在资源编辑器中添加完成的,现在通过代码进行动态添加菜单项目。CMenu类提供了一个成员函数:AppendMenu函数,把一个新菜单项目添加到指定菜单项目的末尾。BOOL AppendMenu( UINT nFlags, UINT nIDNewItem = 0, LPCTS...原创 2020-04-15 08:34:46 · 454 阅读 · 2 评论 -
6.3基本菜单操作(下)
6.3.4禁用菜单项利用CMenu类的成员函数:EnableMenuItem来完成,能够使用、禁用和变灰显示菜单项。UINT EnableMenuItem( UINT nIDEnableItem, UINT nEnable );第一个参数由第二个参数决定。第二个参数;MF_BYCOMMAND:指定第一个参数是菜单项标识ID。MF_BYPOSITION:指定第一个参数是菜单项的位置索引。...原创 2020-04-14 08:32:46 · 512 阅读 · 2 评论 -
6.3基本菜单操作
对于菜单来说,要访问某个菜单项,可以通过该菜单的标识ID,也可以通过位置索引。对于子菜单来说,只能通过索引号进行访问,因为子菜单没有标识号。6.3.1标记菜单菜单栏->查看子菜单下面两个菜单项,前面都有一个对号。这种类型的菜单称为标记菜单。为文件子菜单下面新建菜单项添加一个标记:因为主菜单位于框架窗口,所以在框架窗口创建完成后再去访问菜单对象。在框架类OnCreate函数中添加代码...原创 2020-04-13 08:08:23 · 439 阅读 · 0 评论 -
第六章、菜单
6.1菜单命令响应函数新建一个单文档工程,命名为Menu。Resource View->Menu->IDR_MAINFRAME,双击打开下面的如图菜单资源。整个栏就是菜单,里面的每一个按钮就是菜单项。在帮助菜单项后面添加一个自定义菜单项:鼠标右键单击虚线框->Properties,出现下图菜单项属性对话框,将菜单项名称->Test,即Caption编辑框->...原创 2020-04-12 08:00:56 · 204 阅读 · 0 评论 -
5.4字符输入
打字时,一个字符一个字符输入。当输入一个新的字符时,实际上是重新输入了一个字符串,因为每个字符的宽度不定。因为人眼有视觉残留效应,所以感觉是一个字符一个字符地输入。因此实现该功能:首先给CTestView类添加WM_CHAR消息响应函数OnChar。接着给CTestView类添加CString类型的成员变量:m_strLine,用来存储输入的字符串,同时在CTestView类构造函数中初始化为...原创 2020-04-11 08:58:56 · 389 阅读 · 0 评论 -
5.2窗口重绘
窗口大小发生变化,就会发生窗口重绘,窗口中的文字和图形就会擦除掉。要想内容始终显示在窗口中,就要在视类WM_PAINT消息的消息响应函数OnDraw函数中显示。5.2.1OnDraw函数void CTextView::OnDraw(CDC* pDC){ CTextDoc* pDoc = GetDocument(); ASSERT_VALID(pDoc); // TODO: add dr...原创 2020-04-10 09:13:54 · 416 阅读 · 0 评论 -
第五章、文本编程
5.1插入符文本编辑窗口中有一条闪烁的竖线,称为插入符。5.1.1创建文本插入符要用到CWnd类CreateSolidCaret()。void CreateSolidCaret( int nWidth, int nHeight );第一个参数表示插入符的宽度,第二个参数表示插入符的高度。为0表示系统定义的值。由于窗口客户区的鼠标和键盘的操作都在视类窗口上进行,因此在视类窗口上插入文本插...原创 2020-04-09 09:10:07 · 461 阅读 · 0 评论 -
4.3使用画刷绘图
4.3.1简单画刷MFC中提供了一个CBrush类,可以用来创建画刷对象。void CTestView::OnLButtonUp(UINT nFlags, CPoint point) { // TODO: Add your message handler code here and/or call default CBrush brush(RGB(255,0,0)); CClientD...原创 2020-04-08 09:13:23 · 200 阅读 · 0 评论