MFC面试常见问题1

1CView类的子类都有什么。

视图类(CView)的三个子类

CScrollView类提供视图的滚动显示;CEditView类支持在视图中的文本编辑操作;CHtmlView类支持在视图中显示和操作html文件。

2、静态链接库与动态链接库的区别:

1)静态链接库与动态链接库 都是共享代码的方式 。静态链接库把最后的指令 都包含 在最终生成的EXE文件中了;动态链接库不必被包含在最终EXE文件中,EXE文件 执行时可以“动态”地引用和卸载 这个与EXE独立的DLL文件。

2) 静态链接库中 不能再包含其他的动态链接库或者静态库 ,而在动态链接库中还可以再包含其他的动态或静态链接库。

3PostMessageSendMessage的区别

 1PostMessage只把消息放入队列,不管其他程序是否处理都返回,然后继续执行,这是个异步消息投放函数。而SendMessage必须等待其他程序处理消息完了之后才返回,继续执行,这是个同步消息投放函数。而且,PostMessage的返回值表示PostMessage函数执行是否正确;而SendMessage的返回值表示其他程序处理消息后的返回值。这点大家应该都明白。

2, 如果在同一个线程内,PostMessage发送消息时,消息要先放入线程的消息队列,然后通过消息循环Dispatch到目标窗口。SendMessage发送消息时,系统直接调用目标窗口的消息处理程序,并将结果返回。SendMessage在同一线程中发送消息并不入线程消息队列。 如果在不同线程内。最好用PostThreadMessage代替PostMessage,他工作的很好。SendMessage发送消息到目标窗口所属的线程的消息队列,然后发送消息的线程等待(事实上,他应该还在做一些监测工作,比如监视QS_SENDMESSAGE标志),直到目标窗口处理完并且结果返回,发送消息的线程才继续运行。这是SendMessage的一般情况,事实上,处理过程要复杂的多。比如,当发送消息的线程监测到有别的窗口SendMessage一个消息到来时,他直接调用窗口处理过程(重入),并将处理结果返回(这个过程不需要消息循环中GetMessage等的支持)

3, 如果发送的消息码在WM_USER之下(非自定义消息)且消息参数中带有指针,那么PostMessage,SendNotifyMessage,SendMessageCallback这些异步消息发送函数将会调用失败。 最好不要用PostMessage发送带有指针参数的消息。

4CViewCdocument的关系

CView有一个成员变量CDocument* m_pDocument,指向相关的Documente.

Documentview交谈过程:

    1 使用者在Viewl做动作(View扮演使用者接口的第一线)

    2 Viewl调用GetDocument,取得Document指针,更改资料内容。

    3 Viewl调用DocumentUpdateAllViews

    4 View2View3OnUpdate一一被调用起来,这是更新画面的时机。

CView::OnUpdate被调用,代表着View被告知:“嘿,Document的内容己经改变了,请你准备修改你的显示画面”。如果你想节省力气,利用Invalidate(TRUE)把窗口整个设为重绘区(无效区)并产生WM_PAINT,再让CView::OnDraw去伤脑筋算了。但是全部重绘的效率低落,程序看起来很笨拙。

5MFC中有哪6类核心机制

       1MFC程序的初始化。

       2、运行时类型识别(RTTI)。

每一个从CObject类派生出的类都维护了一个CRuntimeClass类型变量,然后所有类的CRuntimeClass类型变量构建了一个链表。每一个支持运行时类型识别的类都要定义一个CRuntimeClass静态成员。因为静态成员为所有类对象共享,所以它可以作为类的类型识别依据。同时CRuntimeClass还记录了基类的类型,它的成员函数有类名,对象大小,还有指向基类的CRuntimeClass结构指针,因此还可以用于判断某个子类是否是某个基类。

3、动态创建。

就是在程序运行时创建指定类的对象

具体实现(原理):先定义默认不带参数的构造函数,因为我们是用CreateObject()动态创建,然后在类的头文件和cpp中加入声明宏和实现宏,这个宏会完成构造出CRuntimeClass对象加入到动态创建类的链表当中,使用时通过RUNTIME_CLASS就可以得到类的运行时类信息,然后再调用CreateObject完成创建。

       4、永久保存。

       5、消息映射。

消息处理函数WindowProc收到消息后, 调用OnWndMsg进行消息路由, 它会到相应的子类头文件中查找消息声明宏DECLARE_MESSAGE_MAP()下是否有相应的消息响应函数原型声明;再到子类的cpp中查看是否有相应的消息映射宏.如果有就找到了消息响应函数,完成了消息映射。

       6、消息传递。

6win32程序的消息响应机制是如何实现的

Win32程序中,当有消息产生时,操作系统会把这条消息放到应用程序的消息队列中,应用程序通过GetMessage函数从这个队列中取出消息,并通过DispatchMessage 函数把消息交给操作系统,然后调用应用程序的窗口过程函数WndProc进行处理

7MFC中的消息响应机制是如何实现的

消息响应在程序中有三处相关信息,函数原型,函数实现和消息映射宏。首先在每个能处理消息的类中定义一个消息映射表.在这个表中,消息与对应的处理函数指针是成对出现的.当有消息传送过来时,先找到这个消息的窗口类,然后调用窗口函数WindowProc里的OnWndMsg进行消息路由,也就是上面所说的消息映射表,程序会搜索这个消息映射表中是否有这个消息,如果有的话就调用对应的消息处理函数,没找到的话就交给基类进行处理。

8WM_COMMAND命令消息处理顺序

它的处理优先级依次是CView大于CDocument,大于CFrameWnd,最后是由  CWinApp处理。

执行过程

1 WM_COMMAND发送到程序的顶层窗口FrameWnd

2 FrameWnd获取当前活动视图,将命令派发给View

3 View中进行消息处理,处理后返回,若没有处理然后派发给CDocument.     

4 CDocument进行消息处理, 处理后返回,若没有处理返回到FrameWnd, FrameWnd自己进行消息处理,处理后返回,若没有处理     

5 派发给CWinApp进行消息处理

9.MFC序列化的概念

序列化就是将数据以二进制流的方式写入到文件或者从文件中读取数据的过程。

序列化对象 - 将对象的类信息和成员变量写入到文件的过程。

反序列化对象 - 从文件中读取类的信息创建对象,然后读取成员变量的值赋给对象。

作用:

为了让数据的保存与显示分开,如果直接用普通文件操作也可以,但这样不能照顾到整个MFC,因为文件的话只有字节流,没有数据结构,而序列化的思想是把一个运行期的对象保存到永久性设备中,以便任何时候都可以恢复这个对象的状态,它的实现运用到了MFC的动态创建和运行时类信息的机制。

9PeekMessageGetMessage的主要区别:

两个函数都是从消息队列中拿消息, GetMessage相当于一个线程同步行为的函数,如果消息队列中没有消息的话,函数会一直等待,然后取出消息后,消息就从消息队列中删除了,而PeekMessage是不管消息队列中是否有消息,函数都会立即返回,它要根据它设置的一个参数决定消息是否从消息队列中取出。一个是取消息一个是查消息。

10MFC的消息分类

1)窗口消息:WM_CREATEWM_PAINT通过直接调用窗口处理函数

2WM_COMMAND命令消息:先发送到主窗口,再逐层向子窗口派发

3)通知消息

 (4)自注册消息

猜你喜欢

转载自www.cnblogs.com/jlyg/p/10399044.html