vc小总结

来源:互联网 发布:龟山汉墓未解之谜 知乎 编辑:程序博客网 时间:2024/05/02 01:59

句柄

句柄是用来标志被应用程序建立或使用的对象的唯一整数。Windows要使用各种各样的句柄来标志窗口、菜单、输出设备和文件等。可以把句柄理解为与指针类似。用户必须通过某种方式来创建句柄,并要保证在使用完后销毁,以免造成资源的浪费。

2存储器

内存,随机存储器,它的一个重要特性就是,任何位置或字节都能以固定的时间进行访问。

只读存储器,ROM的内容是计算机组装时做好的,不能改写。这个存储器有时称为ROM BIOS(Basic Input/Output Subroutines),所存信息是标明计算机的类型和开机后启动计算机的指令。

3 WM_LBUTTONDOWN是当鼠标在客户区左键单击时触发的的消息,WM_NCLBUTTONDOWN是鼠标在非客户区左键单击时触发的消息(NonClient),系统将他们分别发送给:视图窗口和主窗口。

应用程序启动后,会调用OnCreate() 函数,然后会自动调用OnInitialUpdate()函数,OnCreate()函数只能被调用一次,即在程序启动之时,而OnInitialUpdate()可以被调用多次,即程序启动时,或用户从菜单中选择NewOpen时等。

当文档数据发生改变时,有必要通知所有的视图,以便他们能够对数据进行更新。这时就需要调用到CDocument类的UpdateAllView()函数。如果在文档派生类的成员函数中调用UpdateAllView(),他的一个参数应该为NULL,如果在视图类的成员函数中调用UpdateAllView(),该参数应该设置为当前视图:

GetDocument()->UpdateAllView(this)

当调用UpdateAllView()后,应用程序框架会相应调用所有视图的OnUpdate(),也可以直接在派生类中调用该函数。可以利用OnUpdate()函数使视图的某部分无效,触发视图的OnDraw()函数,重绘窗口。

通常用CDocument类的成员函数GetFirstViewPosition()获得第一个视图的POSITION,而用GetNextView(POSITION ps)返回下一个视图,函数返回后ps指向该视图的下一个视图。

7文档被关闭时,会自动调用DeleteContents()函数

单文档应用程序的运行过程:

应用程序启动

theApp 实例创建,并建立模板

窗口被创建

文档类被创建

视图类被创建

视图窗口被创建

视图类的OnCreate被调用

视图类的OnInitialUpdate被调用

视图类对象被初始化

视图窗口被显示

用户编辑数据

视图类的函数对文档类的对象进行更新

用户退出应用程序

视图类被删除

文档类被删除

窗口类被删除

退出theApp实例

事件是由菜单或工具栏产生的,消息一般是由框架调用的

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.DLLGraphic 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参数自动选择程序入口函数,如果指定了subsystemwindows,则寻找WinsMain或者wWinMain函数,若二者都没有被找到,则显示错误信息“unresolved external symbol”,如果指定subsystemconsole,则寻找Main或者wMain函数;如果省掉/subsystem项,链接器则会自动替我们选择合适的参数。

14 实际上,main函数或者WinMain函数只是程序员编写程序的入口点,通常,编译程序时将在可执行文件中插入一些启动代码,由这些启动代码来调用main函数或者WinMain函数。

15 WinMain的形式

int WINAPI WinMain(HINSTANCE hInstance,

HINSTANCE hPrevInstance,

LPSTR lpszCmdLine,

int nCmdShow)

其中:

hInstance是程序当前实例句柄,该数字用于唯一标识这个程序,如果同时运行几个程序的副本,则每个实例均有不同的hInstance值;

hPrevInstance是应用程序前一个实例的句柄。如果当前只运行程序的一个实例,则hPrevInstance0或者NULL。由于Win32是一个32位系统,每个进程都有独立的4G地址空间,从02G属于进程的私有地址空间,是不可见的,所以,在Win32系统中,hPrevInstance总是为NULL

szCmdLine是一个字符串,内容是命令行参数。

iCmdShow是一个int数值,表明程序窗口如何在Windows中显示。其取值为011,分别表示最大化、最小化或者隐藏等显示属性。在WINUSER.H中定义了对应的常量,如SW_HIDE被定义为0SW_NORMAL被定义为1等。

16 TranslateMessage函数的作用是把虚拟键消息转换到字符消息,以满足键盘输入的需要。DispatchMessage函数是把当前的消息发送到对应的窗口过程中去。

17 窗口过程函数定义如下

LRESULT CALLBACK WindowProc(

HWND hWnd,

UINT uMsg,

WPARAM wParam,

LPARAM lParam)

其中,第一个参数是接受消息的窗口句柄,它与CreateWindow返回值相同,如果程序基于同一个窗口类创建了多个窗口,hWnd用来区分各个窗口。

18 调用ShowWindow函数将产生WM_PAINT消息进入消息队列;CS_VREDRAWCS_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_KEYDOWNWM_CHAR消息后,先执行OnChar(),后执行OnKeyDown()

28 SendMessage函数发送消息后,一直等到发送的消息被窗口过程函数处理后才返回,而PostMessage函数则是把消息送到Windows的消息队列后立即返回。

29 能够产生WM_CHAR消息的主要是数字键和字符键,另外包括Esc键、Tab键、Back Space键和空格键。而左右上下方向键、HomeEnd只产生WM_KEYDOWN消息,而并不触发WM_CHAR消息。

30 OnPaint调用OnDraw

31 有些情况下,比如开发的某个程序响应了鼠标左键单击和弹起消息,当用户在按住鼠标左键的过程中把鼠标移动到该程序的主窗口之外释放左键,这样程序将响应不到鼠标左键弹起消息,造成难以预料的后果。为了解决这种情况,SetCapture用来指定响应鼠标消息的窗口。

32 GetBuffer用于获得指向CString对象内字符的指针。返回的指针可以直接操作修改其内容,但调用GetBuffer之后,在使用该CString对象的其他成员之前,必须先调用ReleaseBuffer

33 程序寻找命令消息处理函数的顺序:

SDI程序:

视图->文档->SDI主框架窗口->应用程序

MDI程序:

视图->文档->MDI子框架窗口->MDI主框架窗口->应用程序

34 不同的WM_COMMAND消息可以映射到相同的响应函数,WM_COMMAND消息的wParamlParam参数的含义:

wParam

高位:当消息来自控件时表示消息通知码;如果来自加速键,高位值为1,如果来自菜单,高位值为0

低位:表示菜单项。空间或者加速建的ID

lParam

如果消息来自控件,lParam是控件的句柄,否则为NULL

35 GetCurrentMessage()用来获得当前消息,返回的消息指针可以用来获得wParam lParam

36 当定义了自己的类,并且在该类中重写了必要的函数,如何在对话框中使用自定义类的对象呢?当然可以使用派生类的Create函数,但是这样必须由程序员自己维护控件的大小和位置,反复调整,非常麻烦。CWnd::SubClassDlgItem函数可以把对话框中已有的控件与某个窗口对象动态连接起来,由该窗口对象接管控件的消息处理。比如,自定义类的对象为m_color,其基类为CListBox,对话框中已有一个CListBox控件,其IDIDC_LISTBOX1,此时,可以

m_color.SubClassDlgItem(IDC_LISTBOX1,this)

这样,对该控件的操作都将由自定义类来处理。注意,m_color只是一个成员变量,并不与对话框中的某个控件相联系,子类化的实质是DoDataExchange函数。也可用SubClassWindow函数

ClassWizard中给该控件关联一个自定义类的对象也可以。

37 要想获得对话框中某控件的客户坐标,可以先用GetWindowRect获得其屏幕坐标,然后用ScreenToClient转换为客户坐标,而不能直接使用GetClientRectGetClientRect只能用来获得对话框窗口客户区左上角的的客户坐标,即(00),无论其指针是对话框窗口指针还是其中的控件指针,其用途是可以与ClientToScreen一起使用用来获得对话框窗口的屏幕坐标。

38 单击微调按钮一类的控件的左右上下按钮会产生WM_HSCROLLWM_VSCROLL消息。

 

原创粉丝点击