1 句柄句柄是用来标志被应用程序建立或使用的对象的唯一整数。Windows要使用各种各样的句柄来标志窗口、菜单、输出设备和文件等。可以把句柄理解为与指针类似。用户必须通过某种方式来创建句柄,并要保证在使用完后销毁,以免造成资源的浪费。2存储器内存,随机存储器,它的一个重要特性就是,任何位置或字节都能以固定的时间进行访问。只读存储器,ROM的内容是计算机组装时做好的,不能改写。这个存储器有时称为ROM BIOS(Basic Input/Output Subroutines),所存信息是标明计算机的类型和开机后启动计算机的指令。3 WM_LBUTTONDOWN是当鼠标在客户区左键单击时触发的的消息,WM_NCLBUTTONDOWN是鼠标在非客户区左键单击时触发的消息(Non-Client),系统将他们分别发送给:视图窗口和主窗口。4 应用程序启动后,会调用OnCreate() 函数,然后会自动调用OnInitialUpdate()函数,OnCreate()函数只能被调用一次,即在程序启动之时,而OnInitialUpdate()可以被调用多次,即程序启动时,或用户从菜单中选择New或Open时等。5 当文档数据发生改变时,有必要通知所有的视图,以便他们能够对数据进行更新。这时就需要调用到CDocument类的UpdateAllView()函数。如果在文档派生类的成员函数中调用UpdateAllView(),他的一个参数应该为NULL,如果在视图类的成员函数中调用UpdateAllView(),该参数应该设置为当前视图:GetDocument()->UpdateAllView(this)当调用UpdateAllView()后,应用程序框架会相应调用所有视图的OnUpdate(),也可以直接在派生类中调用该函数。可以利用OnUpdate()函数使视图的某部分无效,触发视图的OnDraw()函数,重绘窗口。6 通常用CDocument类的成员函数GetFirstViewPosition()获得第一个视图的POSITION,而用GetNextView(POSITION ps)返回下一个视图,函数返回后ps指向该视图的下一个视图。7文档被关闭时,会自动调用DeleteContents()函数8 单文档应用程序的运行过程:应用程序启动theApp 实例创建,并建立模板窗口被创建文档类被创建视图类被创建视图窗口被创建视图类的OnCreate被调用视图类的OnInitialUpdate被调用视图类对象被初始化视图窗口被显示用户编辑数据视图类的函数对文档类的对象进行更新用户退出应用程序视图类被删除文档类被删除窗口类被删除退出theApp实例9 事件是由菜单或工具栏产生的,消息一般是由框架调用的10 VC中,如果想连接动态链接库的.lib文件,可以在“工程->设置->Link-.>L对象/库模块”设置对应的VC.NET中,“Solution Explorer->右击工程名->属性->Linker->Input->Additional Dependencies”中设置另一种方法:将.lib文件拷贝到调用链接库的程序的文件夹中,并通过“Solution Explorer->右击工程名->Add->Add Existing Item….”将该.lib文件加入到工程中,链接库的头文件同样可以用该方法加入到工程中。11 Windows API发展到的最新版本是Win32 API。在它的核心中,依靠三个主要组件提供Windows的大部分函数,这三个组件分别是USER32.DLL, GDI32.DLL, KERNEL32.DLL,其中USER32.DLL负责窗口管理,包括消息、菜单、光标、通信、计时器和其他一些控制显示窗口的函数;GDI32.DLL(Graphic Device Interface图形设备接口)负责管理用户界面和图形绘制,包括Windows元文件、位图、设备描述表和字体;12 KERNEL.DLL处理一些底层功能、任务和资源管理器,它是Windows的核心。句柄是一个标识符,用来标识各种对象。从数据类型上来看,它是一个16位无符号整数。应用程序几乎总是通过调用Windows函数来获得句柄,然后其他的Windows函数就可以使用句柄,以引用相应的对象。HBITMAP 保存DIB图象信息的内存域的句柄HBRUSH 用于填满设备范围的刷子的句柄HCTL 子窗口控件的句柄HCURSOR 鼠标光标的句柄HDC 设备环境描述表的句柄HDLG 对话框句柄HFONT 字体句柄HICON 图标句柄HINSTANCE 应用程序实例句柄HMEM 内存块句柄HMENU 菜单句柄HMODUL 模式的句柄,常用来从可执行文件中获取资源数据HPALETTE 颜色调色板句柄HPEN 画笔句柄HRGN 在窗口上剪切一块区域的句柄HTASK 独立于已执行的任务的句柄HWND 窗口句柄我们也可以采用一个通用句柄,即HANDLE,如:HINSTANCE hInstance;可以改写为 HANDLE hInstance;13 “Solution Explorer->右击工程名->属性->Linker->System”,System选项设置中,有一个subsystem,链接器会根据选定的/subsystem参数自动选择程序入口函数,如果指定了subsystem:windows,则寻找WinsMain或者wWinMain函数,若二者都没有被找到,则显示错误信息“unresolved external symbol”,如果指定subsystem:console,则寻找Main或者wMain函数;如果省掉/subsystem项,链接器则会自动替我们选择合适的参数。14 实际上,main函数或者WinMain函数只是程序员编写程序的入口点,通常,编译程序时将在可执行文件中插入一些启动代码,由这些启动代码来调用main函数或者WinMain函数。15 WinMain的形式int WINAPI WinMain(HINSTANCE hInstance,HINSTANCE hPrevInstance,LPSTR lpszCmdLine,int nCmdShow)其中:hInstance是程序当前实例句柄,该数字用于唯一标识这个程序,如果同时运行几个程序的副本,则每个实例均有不同的hInstance值;hPrevInstance是应用程序前一个实例的句柄。如果当前只运行程序的一个实例,则hPrevInstance为0或者NULL。由于Win32是一个32位系统,每个进程都有独立的4G地址空间,从0到2G属于进程的私有地址空间,是不可见的,所以,在Win32系统中,hPrevInstance总是为NULL;szCmdLine是一个字符串,内容是命令行参数。iCmdShow是一个int数值,表明程序窗口如何在Windows中显示。其取值为0到11,分别表示最大化、最小化或者隐藏等显示属性。在WINUSER.H中定义了对应的常量,如SW_HIDE被定义为0,SW_NORMAL被定义为1等。16 TranslateMessage函数的作用是把虚拟键消息转换到字符消息,以满足键盘输入的需要。DispatchMessage函数是把当前的消息发送到对应的窗口过程中去。17 窗口过程函数定义如下LRESULT CALLBACK WindowProc(HWND hWnd,UINT uMsg,WPARAM wParam,LPARAM lParam)其中,第一个参数是接受消息的窗口句柄,它与CreateWindow返回值相同,如果程序基于同一个窗口类创建了多个窗口,hWnd用来区分各个窗口。18 调用ShowWindow函数将产生WM_PAINT消息进入消息队列;CS_VREDRAW和CS_HREDRAW表示窗口的尺寸大小发生变化时,窗口将无效。UpdateWindow函数直接发送WM_PAINT消息给窗口过程函数,而不是先发送到消息队列,注意区别。19 消息分为“进队的”和“不进队的”两种。进队的消息是由Windows放入程序的消息队列中,等待被取出和发送;不进队的消息是在Windows调用窗口过程时直接送给窗口。进队消息一般来自用户的输入,比如敲击键盘、移动鼠标、单击鼠标按钮等。定时器消息(WM_TIMER)、刷新客户区消息(WM_PAINT)以及程序退出消息(WM_QUIT)也都是进队消息。不进队消息一般都是由窗口过程函数处理进队消息时产生的消息。20 消息循环中调用DispatchMessage把消息发送给窗口过程函数处理,知道窗口过程函数处理完这个消息后DispatchMessage函数才返回。21 在Visual Studio.NET安装目录下,Vc7/atlmfc/include子目录中,有个名字叫afx.h的文件,在这个文件中定义了类CObject;在Visual Studio.NET安装目录下,在Vc7/atlmfc/src/mfc子目录下,有个名字叫objcore.cpp的文件,其中定义了类CObject的函数。22 CRuntimeClass是一个结构,其定义可以在afx.h文件中找到(见21),其中,m_lpszClassName保存类的名称,m_nObjectSize保存类的实例数据所占用内存的大小;m_pBaseClass是指向当前类的基类的指针,类型也是CRuntimeClass。因此,CRuntimeClass就形成了一个继承链表。DECLARE_DYNAMIC宏负责添加一个CRuntimeClass类型的指针,IMPLEMENT_DYNAMIC宏负责建立基类和继承类之间的指针链表。如果想在自己的类中添加“确定运行时类信息”功能,需一下几个步骤:(1) 从CObject派生类(2) 在类声明中使用DECLARE_DYNAMIC宏,如class CPerson: public CObject{DECLARE_DYNAMIC(CPerson)…………………………}(3) 在类的实现文件中使用IMPLEMENT_DYNAMIC宏,如:IMPLEMENT_DYNAMIC(CPerson, CObject)注意位置应放在最开始,紧靠包含的头文件,放在其下。SERIALIZE与此类似。23 RUNTIME_CLASS是一个宏,返回该类对应的一个CRuntimeClass类型的指针,该变量的名字是在类的名字前添加“class”字段,该宏的定义如下:#define _RUNTIME_CLASS(class_name) /((CRuntimeClass*)(&class_name::class##class_name))24 自己创建的任何GDI对象最后都应该被删除,这个删除是一个自动过程,但是只有从设备上下文中分离出来的对象才会被自动删除,因此,我们的工作就是把曾经选入的GDI对象分离出来。分离的方式就是利用SelectObject函数,该函数在把指定的GDI对象选进设备上下文的同时,还返回了前一次被选中的对象,也就是前一次的被赶了出来。因此,一个简单的办法就是,在选择自己的GDI对象的同时,将原来的GDI对象暂时保存起来,等自己的GDI对象使用完之后,再将原来的对象恢复即可,这样,自己的GDI对象就被自动删除了。25 GetTextMetrics()返回当前使用字体的尺寸描述。26 在VC.NET中,在单文档模式下,当新定义一个菜单项,并设定其ID后,在进行消息响应时,如果不采取右键单击菜单项,选择Add Eventhandler方式的话,而是在右下边选择Event按钮,然后进行映射的话,一般找不到对应的新添加的菜单的ID,而是一个整数,此时,可以回到菜单项属性,重新选择新添加菜单的ID,单击右面的向下按钮,随便选择其中一个已有菜单ID,然后再将此ID改回希望的ID,这时再进行映射,就会出现该希望的ID了。想在哪个类中进行消息映射,只需在该类的属性中选择Event按钮,找到对应菜单ID,然后进行消息映射即可。27 WM_CHAR消息的产生:WM_KEYDOWN->WM_CHAR—>WM_KEYUP注意,当产生WM_KEYDOWN和WM_CHAR消息后,先执行OnChar(),后执行OnKeyDown()。28 SendMessage函数发送消息后,一直等到发送的消息被窗口过程函数处理后才返回,而PostMessage函数则是把消息送到Windows的消息队列后立即返回。29 能够产生WM_CHAR消息的主要是数字键和字符键,另外包括Esc键、Tab键、Back Space键和空格键。而左右上下方向键、Home、End只产生WM_KEYDOWN消息,而并不触发WM_CHAR消息。30 OnPaint调用OnDraw31 有些情况下,比如开发的某个程序响应了鼠标左键单击和弹起消息,当用户在按住鼠标左键的过程中把鼠标移动到该程序的主窗口之外释放左键,这样程序将响应不到鼠标左键弹起消息,造成难以预料的后果。为了解决这种情况,SetCapture用来指定响应鼠标消息的窗口。32 GetBuffer用于获得指向CString对象内字符的指针。返回的指针可以直接操作修改其内容,但调用GetBuffer之后,在使用该CString对象的其他成员之前,必须先调用ReleaseBuffer。33 程序寻找命令消息处理函数的顺序:SDI程序:视图->文档->SDI主框架窗口->应用程序MDI程序:视图->文档->MDI子框架窗口->MDI主框架窗口->应用程序34 不同的WM_COMMAND消息可以映射到相同的响应函数,WM_COMMAND消息的wParam和lParam参数的含义:wParam:高位:当消息来自控件时表示消息通知码;如果来自加速键,高位值为1,如果来自菜单,高位值为0低位:表示菜单项。空间或者加速建的IDlParam:如果消息来自控件,lParam是控件的句柄,否则为NULL35 GetCurrentMessage()用来获得当前消息,返回的消息指针可以用来获得wParam 和lParam36 当定义了自己的类,并且在该类中重写了必要的函数,如何在对话框中使用自定义类的对象呢?当然可以使用派生类的Create函数,但是这样必须由程序员自己维护控件的大小和位置,反复调整,非常麻烦。CWnd::SubClassDlgItem函数可以把对话框中已有的控件与某个窗口对象动态连接起来,由该窗口对象接管控件的消息处理。比如,自定义类的对象为m_color,其基类为CListBox,对话框中已有一个CListBox控件,其ID为IDC_LISTBOX1,此时,可以m_color.SubClassDlgItem(IDC_LISTBOX1,this)这样,对该控件的操作都将由自定义类来处理。注意,m_color只是一个成员变量,并不与对话框中的某个控件相联系,子类化的实质是DoDataExchange函数。也可用SubClassWindow函数在ClassWizard中给该控件关联一个自定义类的对象也可以。37 要想获得对话框中某控件的客户坐标,可以先用GetWindowRect获得其屏幕坐标,然后用ScreenToClient转换为客户坐标,而不能直接使用GetClientRect,GetClientRect只能用来获得对话框窗口客户区左上角的的客户坐标,即(0,0),无论其指针是对话框窗口指针还是其中的控件指针,其用途是可以与ClientToScreen一起使用用来获得对话框窗口的屏幕坐标。38 单击微调按钮一类的控件的左右上下按钮会产生WM_HSCROLL和WM_VSCROLL消息。39 DAO是针对开发Microsoft Jet 引擎的数据库而生成的数据库访问对象,因此对于 Microsoft Jet(.mdb)数据库,适合用DAO类访问。ODBC支持大多数的数据源,尤其是对客户/服务器结构的程序,采用ODBC可以减少许多麻烦。40 用VC.NET编写对数据库操作的程序时,当根据向导选好数据源和其他所有设置并单击Finish时,会弹出一个对话框,对话框的目的是告诉用户在想到帮助生成的代码中,可能包含着明文密码,或者其他的重要信息,请在想到中酌情修改,并且需要把代码中的下面这一行出错提示信息注释掉:#error Security Issue: The connection string may contain a password可以通过下面的方法找到该语句:编译程序->出现错误->双击错误->注释掉该语句。初始时向导会生成一个派生于RecordSet的类,其中有和数据源各字段相关的成员变量,但对于CString字段,相关的成员变量是CStringW类型的,这是错误的,需要手动改成CString类型。41 数据库基本框架:CMyView里面有一个CMyRecordset对象指针m_pSet,CMyDoc里有一个CMyRecordset对象m_DocSet,m_pSet需要在CMyView::OnInitialUpdate()里初始化为指向CMyDoc的成员变量m_DocSet类对象,具体方法为:CMyView::OnInitialUpdate(){m_pSet=&GetDocument()àm_DocSet;………………..}42 CDatabase类说明了一个同数据源的连接,在使用某一个数据库对象时,首先需要创建一个CDatabase对象,然后使用其成员函数Open()或者OpenEx()建立与数据源的连接.建立连接以后,向使用数据源的CRecordSet对象的构造函数传递一个该CDatabase对象的指针,CRecordSet对象就可以对该数据源进行操作了.CRecordset类的构造函数为:CRecordset(CDatabase* pDatabase=NULL)参数pDatabase指向一个CDatabase对象,用来获取数据源.如果pDatabase为NULL,则会在CRecordset对象的成员函数Open()中自动创建一个CDatabase对象.如果CDatabase对象还未与数据源连接,那么会在Open()函数中建立连接.43 当利用CRecordset类的成员函数GetFieldValue获取字段值时,该函数的第二个参数是CDBVarint类型,CDBVarint是一个联合(union),调用该函数后,根据得到的CDBVarint对象的数据成员的类型判断其内容.44 DAO可以通过ODBC驱动程序访问ODBC数据源.但DAO是基于Microsoft Jet 引擎的,通过该引擎, DAO可以直接访问Acess、dBASE、Paradox、Excel和Lotus WK等数据库。CDaoDatabase类可以直接与这些数据库进行连接,而不必在ODBC管理器中注册DSN。例如,下面的代码可以打开一个FoxPro数据库:CDaoDatabase daoDb;daoDb.Open(“”,FALSE,FALSE, “FoxPro 2.5;DATABASE=D://foxpro//xy”);若DaoDatabase的Open函数用来打开一个ODBC数据源,则需要响应的ODBC驱动程序,并需要在ODBC管理器中注册DSN。建立连接的字符串形式为“ODBC;DSN=MyDataSource”。显然,用DAO访问像FoxPro这样的数据库时,直接打开比把它当作ODBC数据源打开要省了许多麻烦。45 ODBC封装类只支持DML(Data Manipulation Language 数据操作语言),而不支持DDL(Data Definition Language 数据定义语言),而DAO类同时支持DDL和DML,所以ODBC只能完成数据的操作,不能涉及数据库的结构。而DAO可以使程序员创建数据库以及修改数据库的结构。46 CDaoFieldInfo结构保存了DAO字段的信息,其成员变量m_strName表示字段的名称。CDaoTableDefoInfo结构保存了DAO数据库表的信息。47 可以用CreatePatternBrush创建位图画刷。48 利用ADO对象开发数据库的步骤(1) 使用ADO之前必须在程序中用直接引入符号#import引入ADO库文件,以使编译器能正确编译。可以把#import语句放在stdafx.h文件中:#import “c/program files/common files/system/ado/msado15.dll”no_namespace rename(“EOF”, “adoEOF”)这条语句声明在工程中使用ADO,但不实用ADO名字控件,而把常数EOF重命名为adoEOF,避免名称的冲突。(2) 初始化COM库由于ADO库是一组COM动态库,在调用ADO之前需要初始化COM库,提供COM库环境。可以在应用程序类的InitInstance成员函数中初始化COM库。BOOL CADOApp::InitInstance(){if(!AfxOleInit()){AfxMessageBox(“初始化OLE出错”);return FALSE;}………..}(3) 使用_ConnectionPtr指针_ConnectionPtr是一个连接指针,其作用类似于ODBC和DAO里面的CDatabase和CDaoDatabase。使用_ConnectionPtr的方法是:首先创建一个_ConnectionPtr指针对象,然后指向并打开一个ODBC或OLE DB数据源。下面的代码直接连接SQL Server中的一个数据库,名称为NewsDB。_ConnectionPtr m_pConnection;m_pConnection.CreateInstance(__uuidof(Connection));m_pConncetion->Open(“Provider=SQLOLEDB;SERVER=server;DATABASE=samp;UID=admin;PWD=adminsqloledb;DataSource=;InitialCatalog=NewDb;UserId=’sa’;Password=’sa’;”,””,””,-1);创建指针对象实例的方法还有另外一种,即:m_pConnection.CreateInstance(“ADODB.Connection”);(4) 使用_RecordsetPtr指针_RecordsetPtr m_pRecordset;m_pRecordset.CreateInstance(__uuidof(Recordset));m_pRecordset->Open(“SELECT * FROM studentinfo”, m_pConnection, adOpenDynamic, adLockOptimistic, adCmdText);下面可以获取数据:_variant_t varValue;while(!m_pRecordset->adoEOF){varValue=m_pRecordset->GetCollect(“姓名”);if(varValue.vt!=VT_NULL)AfxMessageBox((char*)_bstr_t(varValue));m_pRecordset->MoveNext();}(5) 使用_CommandPtr指针_CommandPtr指针返回一个Recordset对象,并且提供了更多的记录集控制功能。_CommandPtr m_pCommand;_RecordsetPtr m_pSet;m_pCommand.CreateInstance(__uuidof(Command));m_pommand->ActiveConnetion=MyDb;m_pCommand->CommandText=”select * from some_table”;m_pCommand->CommandType=adCmdText;m_pCommand->Parameters->Refresh();m_pSet=m_pCommand->Execute(NULL,NULL,adCmdUnknown);_variant_t varValue=m_pSet->GetCollect(“姓名”);CString str=(char*)_bstr_t(varValue)49可以使用_ConnectionPtr建立连接,然后将该连接作为参数传递给_RecordsetPtr的Open成员函数,也可以不建立_ConnectionPtr连接,而是将连接语句赋值给_RecordsetPtr指针的connection成员变量。可以使用_RecordsetPtr指针的Open成员函数获得一个记录集,也可以使用_CommandPtr指针的Execute成员函数返回值来获得记录集。50 _ConnectionPtr通常用来创建一个数据连接或执行一条不返回任何结果的SQL语句,通常和CDatabase一样,使用它创建一个数据连接,然后使用其他对象执行数据记录集的操作。_RecordsetPtr是一个记录集对象指针。它不一定要使用一个已经创建的数据连接,可以使用一个连接字符串代替连接指针付给_RecordsetPtr的connection成员变量,让它自己建立数据连接。如果要使用多个记录集,最好是使用已经创建了数据连接的全局_CoonnectionPtr指针,然后使用_RecordsetPtr执行存储过程和SQL语句。_CommandPtr指针返回一个记录集。它提供了一种简单的方法来执行返回记录集的存储过程和SQL语句。在使用_CommandPtr指针时,可以利用全局的_ConnectionPtr指针,也可以在_CommandPtr指针内直接使用连接字符串。如果需要频繁的访问数据库,并要返回很多记录集,建议使用全局_ConnectionPtr指针创建一个数据连接,然后使用_CommandPtr指针执行存储过程和SQL语句。51 通用数据源的OLE DB连接字符串数据源OLE DB连接字符串Microsoft AcdessProvider=Microsoft.Jet.OLEDB.4.0;Source=.mdb文件的物理路径Microsoft SQL ServerProvider=SQLOLEDB.1;Source=服务器上的数据库路径OracleProvider=MSDAORA.1;Source=服务器上的数据库路径Microsoft Indexing ServiceProvider=MSIDXS.1;Source=文件路径52 根据句柄,可以用FromHandle函数来获取对应的指针。53 通用语言运行时(Common Language Runtime)为多种语言提供了一种统一的运行环境。54 基于通用语言运行时开发的代码称为受控代码(托管代码),它的运行步骤如下:首先使用一种通用语言运行时支持的语言编写源代码,然后使用针对通用语言运行时的编译器生成独立于及其的微软中间语言(Microsoft Intermediate Language),同时产生运行所需的源数据,在代码运行时再使用及时编译器(Just In Time Compiler)生成相应的机器代码来执行。55 一条消息包括6方面内容(1)目标窗口的窗口句柄hwnd(2)消息类型标识符message(3)参数1 wParam(4)参数2 lParam(5)消息送到消息队列中的时间time(6)消息发送是鼠标光标的屏幕坐标pt56 当想在状态栏中创建CProgressCtrl控件时,不能在OnCreate()函数里设定其大小,因为在OnCreate()被调用时,窗口的状态栏位置和大小还未确 定,而状态栏里的窗格的大小会随着窗口大小的改变而改变,所以解决办法 是:在OnCreate()里创建CProgressCtrl控件,而在OnPaint()或者OnSize里面使用MoveWindow(或者SetWindowPos)来改变CProgressCtrl控件的位置和大小,该位置可以通过CStatusBar的成员函数GetItemRect()来获得。同样,不能在OnCreate()函数里获得准确的状态栏的大小和位置。57 标签式对话框的创建步骤(1)分别为各个页创建对话框模板,去掉缺省的OK和Cancel按钮,每页的模板最好具有相同的尺寸,如果尺寸不统一,则框架将根据最大的页来确定标签对话框的大小。在创建模板时,需要在模板属性对话框中指定下列属性。(2)指定标题(Caption)的内容。标题的内容将显示在该页对应的标签中。(3)选择TitleBar、Child、ThinBorder和Disable属性。(4)根据各个页的模板,为每页创建CPropertyPage类的派生类。(5)为每页加入与控件对应的成员变量(6)创建CPropertySheet对象,调用CPropertySheet类的成员函数AddPage添加页。58 注册ActiveX控件的方法:运行->regsvr32 控件存储地址取消ActiveX控件的注册可以运行->regsvr32 /u 控件存储地址59 互斥对象属于内核对象,每一个互斥对象包含一个使用数量,一个线程ID和一个计数器。计数器记录当前线程请求互斥对象的次数,每请求一次加1,每释放一次减1。只有计数器值为0时,互斥量才会变成有信号状态。当一个线程请求到互斥对象后,该线程ID将被赋予此ID,当调用ReleaseMutex时,函数会首先判断当前ID和互斥对象的线程ID是否相同,只有相同才能正确释放互斥对象。也就是说谁拥有互斥对象,谁才能释放互斥对象。即使互斥对象处于无信号状态,在当前拥有该互斥对象的线程内WaitForSingleObject仍然可以获得该互斥对象。此时计数器将加1。线程终止时系统会自动释放该线程拥有而没有释放的互斥对象。60 ActiveX控件的属性在ClassWizard的Automation属性页里添加。ActiveX控件的四种属性:(1)Stock:为每个控件提供的标准属性,如字体或颜色(2)Ambient:围绕控件的环境属性――已被置入容器的属性这些属性不能被更改,但控件可以使用它们调整自己的属性。比如控件是处于设计状态还是运行状态(由COleControl::AmbientUserMode()来获得)(3)Extended:这些是由容器处理的属性,一般包括大小和在屏幕上的位置(4)Custom:由控件开发者提供的属性61 VC自带的ActiveX控件的属性页全局标识符CLSID_CFontPropPage 字体CLSID_CColorPropPage 颜色CLSID_CPicturePropPage 图象62 要想使ActiveX控件自定义的事件生效,必须在某个条件下调用FireEventName函数来触发事件,从而向容器程序发送事件通知。对于Stock系统事件,则根据用户对控件的操作来发送相应的消息,比如Click。63 进行网络编程时,套接字库的初始化可以在CWinApp::InitialInstance()函数里进行,可以调用AfxSocketInit()完成初始化,注意,该函数需要包含头文件Afxsock.h,可以将该头文件放到stdafx.h预编译头文件里。64 基于TCP(面向连接)的socket编程服务器端程序(1) 创建套接字(socket)(2) 将套接字绑定到一个本地地址和端口上(bind)(3) 将套接字设为监听模式,准备接收客户请求(listen)(4) 等待客户请求,当请求到来时,接收连接请求,返回一个新的对应于此次连接的套接字(accept)(5) 用返回的套接字和客户端进行通信(send/recv)(6) 返回,等待另一客户请求(7) 关闭套接字客户端程序(1) 创建套接字(socket)(2) 向服务器发出连接请求(connect)(3) 和服务器进行通信(send/recv)(4) 关闭套接字65 基于UDP(面向无连接)的socket编程服务器端(接收端)程序(1) 创建套接字(socket)(2) 将套接字绑定到一个本地地址和端口上(bind)(3) 等待接收收据(recvfrom)(4) 关闭套接字客户端(发送端)程序(1) 创建套接字(2) 向服务器发送数据(3) 关闭套接字66 要获得位图资源的句柄,可以先创建一个CBitmap对象bp,然后bp.LoadBitmap(IDB_BITMAP),然后可以bp.GetSafeHandle();或者可以用::LoadBitmap(AfxGetInstanceHandle(),MAKEINTRESOURCE(IDB_BITMAP1))67 通过普通的CButton创建位图按钮,可以先构造CBitmap对象,然后调用CButton::SetBitmap(HBITMAP),注意,该CBitmap对象必须为成员函数,而不能为局部变量。68 在编写可收缩和扩展对话框程序时,不能在OnInitialDialog()函数里获取对话框的CRect,因为在OnInitialDialog()函数运行时,程序的对话框的框架还没有被创建,只是进行了初始化。69 若在非模式对话框中完成了OK按钮,则必须重载OnOk()函数,并从中调用DestroyWindow()。千万不要调用基类中的该成员函数,因为基类中的该函数将调用EndDialog(),它将导致对话框不可见但并不销毁它。OnCancel()同样只是调用EndDialog()。70 CDialog的Create函数用来创建非模式对话框窗口,而不是创建对话框对象。DestroyWindow用来销毁该窗口。Create函数在显示了对话框后就立即返回,而DoModal在对话框被关闭后才返回。Create函数不会启动新的消息循环,对话框与应用程序公用一个消息循环,这样对话框就不会垄断用户的输入。不能在未关闭窗口的情况下而删除窗口对象,由于Create返回后,不能确定对话框是否已经关闭,这样就无法确定对话框对象的生存期,因此只好在堆中构建对话框对象,而不能以局部变量的形式来构建。用new构建非模态对话框对象,在对话框关闭后,必须用delete删除该对象,屏幕上一个窗口被删除后,框架会调用CWnd::PostNcDestroy,可以重载该虚函数来完成删除窗口对象的工作。71 要想倒出一个类,可以在class和类名之间加入_declspec(dllexport),如果只想导出类中的成员变量而不是整个类,可以在成员函数的声明前加上_declspec(dllexport),此时,仍然可以构造该类的对象,但只能访问被导出的成员函数。为了防止名字改编,可以在_declspec(dllexport)前面加上extern “C”,但extern “C”不能导出类的成员函数,而只能导出全局函数。可以在函数返回类型和名称之间加入_stdcall来完善调用?加入_stdcall仍会造成名字改编,为了消除名字改编,可以用.def文件来导出函数。72 扩展的动态链接库与一般的动态链接库的区别是扩展的动态链接库可以导出MFC类73 GetCurrentThreadID()获取当前线程ID74 GetModuleHandle(LPCTSTR lpModuleName)用来获得指定模块句柄75 在动态链接库里可以通过柚霉蚕斫诶创唇梢员凰薪坦蚕淼谋淞?o:p>#pragma data_seg(“MySec”) //节的名称最长8位变量 //变量必须被初始化#pragma data_seg() 然后设置该变量为共享方法1:#pragma comment(“linker”,”/section:MySec,RWS”)方法2:在.def文件中SEGMENTMySec READ WRITE SHARED //大小写都可以,但不能为缩写76 添加.avi资源的方法:添加资源import定位到要添加的avi资源文件打开资源类型设为AVI77 从一个bmp文件装入位图的方法:CBitmap bitmap;HBITMAP hBitmap=(HBITMAP)::LoadImage(NULL , // handle of the instance that contains the image"Wzd2.bmp", // name or identifier of imageIMAGE_BITMAP, // type of image,can also be IMAGE_CURSOR or //IMAGE_ICON0 , 0 , // desired width and heightLR_LOADFROMFILE) ; // load from filebitmap.Attach(hbitmap) ; // attach this bitmap object to our //bitmap class 78 CImageList的成员函数Add必须在Create创建之后才能使用,不能直接使用。如果想使用从外部导入的BITMAP资源,可以直接将BITMAP资源ID作为参数传递给CImageList::Create()函数,如果想使用从外部导入的ICON资源,可以先随便导入或创建一个BITMAP资源,调用Create函数,然后使用CImageList()::Add(HICON)添加ICON资源,通过CTreeCtrl::InsertItem()函数中的一个设定图象的指数index的参数来选定想要的ICON。79 在用ADO访问SQL数据库时,需要注意:(1)当使用Microsoft ADO Data Control,version 6.0控件来获得连接字符串时,如果使用Windows NT集成安全设置,注意如果服务器名采用域的形式时,连接字符串中域/服务器名中的‘/’要写为‘//’,如:pConn->ConnectionString="Provider=SQLOLEDB.1;Integrated Security=SSPI;Persist Security Info=False;User ID=sa;Initial Catalog=Northwind;Data Source=DUSTFLY//NEWSERVER3";服务器名也可以采用别名的形式,如:pConn->ConnectionString="Provider=SQLOLEDB.1;Persist Security Info=False;User ID=sa;Password=charonhoo;Initial Catalog=Northwind;Data Source=newServer3";两者是等效的。(2)当使用Microsoft ADO Data Control,version 6.0控件来获得连接字符串时,如果使用指定的用户名和密码,则生成的连接字符串是没有Password字段的,需要手工添加,如:系统生成的字符串为:pConn->ConnectionString="Provider=SQLOLEDB.1;Persist Security Info=False;User ID=sa;Initial Catalog=Northwind;Data Source=DUSTFLY//NEWSERVER3";需要手工添加Password字段,修改后如:pConn->ConnectionString="Provider=SQLOLEDB.1;Persist Security Info=False;User ID=sa;Password=charonhoo;Initial Catalog=Northwind;Data Source=DUSTFLY//NEWSERVER3";80 可以用MoveWindow函数来移动窗口,也可以利用Windows API函数SetWindowPos来移动窗口。该函数的优点在于可以强迫窗口重新读入它的风格及其他信息。只要用SetWindowLong函数改变了窗口的任何参数,就应该调用SetWindowPos来激活更改,即使实际并未移动窗口。81 要想找一个窗口和其中控件在位置上的相对关系,可以分别对窗口和控件GetWindowRect求其差,最好不要用ClientToScreen,否则会出现差错。82 客户坐标是相对于它的调用对象而言的,比如对窗口调用者而言,窗口左上角坐标永远是(0,0),而对窗口中的按钮控件调用GetClientRect的话,其左上角也是(0,0),而不是其相对于窗口的坐标。83 Windows维护了一个系统消息队列以及每个线程自己的消息队列。比如控制键盘的程序,从设备得到信息然后放入系统消息队列中,Windows每次从系统队列中取出一个消息,决定哪个窗口应该接收它,然后将它放入创建该窗口的线程的消息队列中。Windows一般将消息放入线程消息队列的尾部,于是线程按照先入先出的顺序得到消息,一个例外是WM_PAINT消息。Windows等到线程的消息队列为空之后,才将WM_PAINT消息放入队列中。多个WM_PAINT消息被合并为一个后,才放入消息队列当中。处理WM_PAINT需要消耗大量的CPU时间,而这种方法可以尽量减少重新画出窗口客户区域的时间。这就是排队消息。但是,一些消息由于太重要而不能等待。典型的,它们是影响窗口的事件通告消息。对于它们,Windows跳过系统队列,直接将消息发送到线程消息队列的首部,这就是非排队消息。84 一般来说,预处理命令单独占一行,如果写成多行,要加续行符“/”,加载前一行的末尾。

VC 基础知识(转载)相关推荐

  1. 中文字符集与字符编码的基础知识[转载]

    中文字符集与字符编码的基础知识 字符是各种文字和符号的总称,包括各国家文字.标点符号.图形符号.数字等.字符集是多个字符的集合,字符集种类较多,每个字符集包含的字符个数不同,常见字符集名称:ASCII ...

  2. jeee的基础知识(转载)

    Servlet: 1)servlet : servlet是一个特殊的java程序,需要在web服务器上运行,并接收和响应客户端的请求,遵循http协议. 2)Servlet;作用: 主要用于控制层. ...

  3. 计算机检索基础知识,[转载]四 计算机文献检索基础知识(原理、结构和功能)...

    1.计算机检索原理 计算机一方面接受用户的检索提问,一方面从数据库中读取文献记录,然后把两者进行比较,即检索提问标识与文献记录标识进行匹配运算,如果比较的结果一致,那么这篇文献就会作为命中文献在检索结 ...

  4. HtmlCSS 基础知识

    Html 基础知识Html 基础知识Html 基础知识Html 基础知识Html 基础知识Html 基础知识Html 基础知识Html 基础知识Html 基础知识Html 基础知识Html 基础知识H ...

  5. [转载] ANTLR——编译原理基础知识

    来源:ANTLR中文网站:http://www.antlr.org.cn 编译是将计算机高级语言如C++.Java.C#编写的源程序翻译成可以在计算机上执行的机器语言的翻译过程.编译过程中分:词法分析 ...

  6. VC++6.0及MFC基础知识

    VC++6.0及MFC基础知识 这是早期的学习笔记,今天翻出来,觉得还有点价值,就转发到这里. Visual C++ 6.0的主界面 VC++6.0的MFC Windows 的三大模块就是以DLL( ...

  7. 新手上路:ADAMS 基础知识讲解(图文并茂)【转载仿真论坛】

    引用 Baker 的 新手上路:ADAMS 基础知识讲解(图文并茂)[转载仿真论坛] 经过不知道多少个日夜,终于出来一个雏形了,内容主要是版内的帖子总结,这个为1.0版本,由于时间的问题,内容还不全, ...

  8. 新手上路:ADAMS 基础知识讲解(图文并茂)【转载仿真论坛】(四)

    引用 Baker 的 新手上路:ADAMS 基础知识讲解(图文并茂)[转载仿真论坛](四) 14.如何在ADAMS下由数据生成样条曲线? 在tools->command navigator... ...

  9. 新手上路:ADAMS 基础知识讲解(图文并茂)【转载仿真论坛】(五)

    引用 Baker 的 新手上路:ADAMS 基础知识讲解(图文并茂)[转载仿真论坛](五) 五.常用函数介绍篇 (一).adams函数总体介绍 1.ADAMS/View? 是MDI公司出品的动力学仿真 ...

最新文章

  1. mysql5.7.20安装红黑_Window环境安装MySQLServer5.7.21
  2. 上海巴斯德所在新型冠状病毒早期进化机制方面取得进展
  3. 头号任务:CIO面临的十大挑战预测
  4. Rhythmk 一步一步学 JAVA(11)Ibatis 环境配置
  5. 电路交换网络中,每条电路独占其经过的物理链路。
  6. 一致性哈希算法在分布式缓存中的应用
  7. matlab过滤,matlab过滤问题
  8. 事物传递机制、应用、加载时机
  9. 二、先在SD卡上启动U-boot,再烧写新的U-boot进Nandflash
  10. Redis高级项目实战,java配置jdk环境时
  11. 1-5docker私有镜像仓库
  12. GLSurfaceView源码分析以及简单使用
  13. 自定义jQuery 跨域请求 callback 函数名
  14. WampServer下使用PHP
  15. Python之常用函数小结
  16. 创建指南针View的例子
  17. 在.NET开发中的单元测试工具之(2)——xUnit.Net
  18. 如何从JFrog Artifactory下载资源到本地
  19. 采购订单模板_金蝶KIS商贸版(采购模块)常见问题汇总
  20. 2022-2027(新版)全球与中国鱼藤酮行业发展动态及前景展望报告

热门文章

  1. vs2013无法启动IIS Expres Web服务器
  2. python符号运算卷积_Python使用scipy模块实现一维卷积运算示例
  3. web浏览器与IE的关系,如何设置web浏览器工作在IE9模式下?
  4. 系统移植1------U-Boot
  5. 清洁单反相机镜头的方法与步骤解析
  6. php 生成ppt,php phppowerpoint
  7. WADL(REST) 基础
  8. linux移植过程注意事项,linux移植过程的错误记录
  9. 【Excel神技】之 打印标题行设置
  10. Java开发中token 的使用