C++/MFC 面试题(五、MFC)

本文深入探讨MFC编程的多个方面,包括MFC类的继承关系、视图类的子类特性、静态库与动态库的区别、绘图机制、消息机制等核心概念。此外,还介绍了线程同步机制、进程间通信方法、自定义消息处理等内容。

1. 谈一谈MFC类的继承关系
在这里插入图片描述
在这里插入图片描述
2. 谈一谈CView的子类

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

3. 谈一谈静态库与动态库的区别

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

4. 谈谈OnPaint和OnDraw的关系

一般Windows会发送两个消息WM_PAINT(通知客户区 有变化)和WM_NCPAINT(通知非客户区有变化)。非客户区的重画系统自己搞定了,而客户区的重画需要我们自己来完成。这就需要OnDraw()或 OnPaint()来重画窗口。
而OnPaint()是CWnd的类成员,同时负责响应WM_PAINT消息。OnDraw()是CVIEW的成员函数,并且没有响应消息的功能。
当视图变得无效时(包括大小的改变,移动,被遮盖等等),Windows 将 WM_PAINT 消息发送给它。该视图的 OnPaint 处理函数通过创建 CPaintDC 类的DC对象来响应该消息并调用视图的 OnDraw 成员函数。通常我们不必编写重写的 OnPaint 处理成员函数。

5. 谈一谈SendMessage和PostMessage的区别

1, 异步与同步
PostMessage只把消息放入队列,不管其他程序是否处理都返回,然后继续执行,这是个异步消息投放函数。
SendMessage必须等待其他程序处理消息完了之后才返回,继续执行,这是个同步消息投放函数。
2,返回值
PostMessage的返回值表示PostMessage函数执行是否正确
SendMessage的返回值表示其他程序处理消息后的返回值。这点大家应该都明白。
3,内部逻辑
同一个线程内:
PostMessage发送消息时,消息要先放入线程的消息队列,然后通过消息循环Dispatch到目标窗口。SendMessage发送消息时,系统直接调用目标窗口的消息处理程序,并将结果返回。
SendMessage在同一线程中发送消息并不入线程消息队列。
不同线程内:
最好用PostThreadMessage代替PostMessage,他工作的很好。
SendMessage发送消息到目标窗口所属的线程的消息队列,然后发送消息的线程等待(事实上,他应该还在做一些监测工作,比如监视QS_SENDMESSAGE标志),直到目标窗口处理完并且结果返回,发送消息的线程才继续运行。
4, 特殊情况
如果发送的消息码在WM_USER之下(非自定义消息)且消息参数中带有指针,那么PostMessage,SendNotifyMessage,SendMessageCallback这些异步消息发送函数将会调用失败。 最好不要用PostMessage发送带有指针参数的消息。

6. 简述COM技术

COM(Component Object Model,组件对象模型),是由微软推出的一套接口规范,通过设定不同组件之间需要遵守的标准与协议,主要用来跨语言、跨进程之间的模块通信。所谓COM(Component Object Model,组件对象模型)是一种说明如何建立可动态互变组件的规范,此规范提供了为保证能够互操作,客户和组件应遵循的一些二进制和网络标准。通过这种标准将可以在任意两个组件之间进行通信而不用考虑其所处的操作环境是否相同、使用的开发语言是否一致以及是否运行于同一台计算机。

7. C/C++/MFC 分别是怎么读写文件的

C:

FILE *pFile=fopen("1.txt","w");
fwrite("http://www.sunxin.org",1,strlen("http://www.sunxin.org"),pFile");
fseek(pFile,0,SEEK_SET);
fwrite("ftp:",1,strlen("ftp:"),pFile);
fwrite("http://www.sunxin.org",1,strlen("http://www.sunxin.org"),pFile");
fclose(pFile);*/
fflush(pFile);

C++

#include "fstream.h"
ofstream ofs("4.txt");
ofs.write("http://www.sunxin.org",strlen("http://www.sunxin.org"));
ofs.close();

MFC

CFileDialog fileDlg(FALSE);
fileDlg.m_ofn.lpstrTitle="我的文件保存对话框";
fileDlg.m_ofn.lpstrFilter="Text Files(*.txt)\0*.txt\0All Files(*.*)\0*.*\0\0";
fileDlg.m_ofn.lpstrDefExt="txt";
if(IDOK==fileDlg.DoModal())
{
  CFile file(fileDlg.GetFileName(),CFile::modeCreate | CFile::modeWrite);
  file.Write("http://www.sunxin.org",strlen("http://www.sunxin.org"));
  file.Close();
}

8. 谈一谈MFC的消息机制

消息映射机制:MFC使用消息映射机制来处理消息,拥有一个消息与消息处理函数一一对应的消息映射表。当窗口发送数据的时候,会先去消息映射表里找到对应的消息处理函数,然后由消息处理函数进行相应的处理。
消息循环机制:应用程序如何不断为窗口传递消息?在一个循环内不断检测消息,并将消息发送到对于的窗口。

9. 消息类型与实现

类型:
Windows消息 WM开头
控件通知 窗口和控件发往主窗口的消息
命令消息 WM_COMMAND
实现:
MFC中的消息映射机制是在OnWndMsg()这个函数中实现的,而在这个函数里又会去查找相应的消息映射的宏。
MFC通过宏将指定的消息映射到派生类的成员函数中。

10. 线程间通信

线程间通信:由于多线程共享地址空间和数据空间,所以多个线程间的通信是一个线程的数据可以直接提供给其他线程使用,而不必通过操作系统(也就是内核的调度)。

11. 进程间通信

进程间的通信则不同,它的数据空间的独立性决定了它的通信相对比较复杂,需要通过操作系统。以前进程间的通信只能是单机版的,现在操作系统都继承了基于套接字(socket)的进程间的通信机制。这样进程间的通信就不局限于单台计算机了,实现了网络通信。

进程的通信机制主要有:管道、有名管道、消息队列、信号量、共享空间、信号、套接字。

1)管道(Pipe):管道可用于具有亲缘关系进程间的通信,允许一个进程和另一个与它有共同祖先的进程之间进行通信。
2)命名管道(named pipe):命名管道克服了管道没有名字的限制,因此,除具有管道所具有的功能外,它还允许无亲缘关系进程间的通信。命名管道在文件系统中有对应的文件名。命名管道通过命令mkfifo或系统调用mkfifo来创建。
3)信号(Signal):信号是比较复杂的通信方式,用于通知接受进程有某种事件发生,除了用于进程间通信外,进程还可以发送信号给进程本身;Linux除了支持Unix早期信号语义函数sigal外,还支持语义符合Posix.1标准的信号函数sigaction(实际上,该函数是基于BSD的,BSD为了实现可靠信号机制,又能够统一对外接口,用sigaction函数重新实现了signal函数)。
4)消息(Message)队列:消息队列是消息的链接表,包括Posix消息队列system V消息队列。有足够权限的进程可以向队列中添加消息,被赋予读权限的进程则可以读走队列中的消息。消息队列克服了信号承载信息量少,管道只能承载无格式字节流以及缓冲区大小受限等缺
5)共享内存:使得多个进程可以访问同一块内存空间,是最快的可用IPC形式。是针对其他通信机制运行效率较低而设计的。往往与其它通信机制,如信号量结合使用,来达到进程间的同步及互斥。
6)信号量(semaphore):主要作为进程间以及同一进程不同线程之间的同步手段。
7)套接字(Socket):更为一般的进程间通信机制,可用于不同机器之间的进程间通信。起初是由Unix系统的BSD分支开发出来的,但现在一般可以移植到其它类Unix系统上:Linux和System V的变种都支持套接字。

12. 线程同步与互斥

当线程并发执行时,由于资源共享和线程协作,使用线程之间会存在以下两种制约关系。

 (1)间接相互制约/互斥。一个系统中的多个线程必然要共享某种系统资源,如共享CPU,共享I/O设备,所谓间接相互制约即源于这种资源共享,打印机就是最好的例子,线程A在使用打印机时,其它线程都要等待。

 (2)直接相互制约/同步。这种制约主要是因为线程之间的合作,如有线程A将计算结果提供给线程B作进一步处理,那么线程B在线程A将数据送达之前都将处于阻塞状态。

线程A和线程B互斥访问某个资源则它们之间就会产个顺序问题——要么线程A等待线程B操作完毕,要么线程B等待线程操作完毕,这其实就是线程的同步了。
因此同步包括互斥,互斥其实是一种特殊的同步。

13. 线程同步的方式

事件:
事件(Event)是WIN32提供的最灵活的线程间同步方式,事件可以处于激发状态(signaled or true)或未激发状态(unsignal or false)。
信号量:
信号量是维护0到指定最大值之间的同步对象。信号量状态在其计数大于0时是有信号的,而其计数是0时是无信号的。信号量对象在控制上可以支持有限数量共享资源的访问。
互斥量:
采用互斥对象机制。 只有拥有互斥对象的线程才有访问公共资源的权限,因为互斥对象只有一个,所以能保证公共资源不会同时被多个线程访问。互斥不仅能实现同一应用程序的公共资源安全共享,还能实现不同应用程序的公共资源安全共享。
临界区:
临界区(Critical Section)是一段独占对某些共享资源访问的代码,在任意时刻只允许一个线程对共享资源进行访问。如果有多个线程试图同时访问临界区,那么在有一个线程进入后其他所有试图访问此临界区的线程将被挂起,并一直持续到进入临界区的线程离开。临界区在被释放后,其他线程可以继续抢占,并以此达到用原子方式操作共享资源的目的。

14. 线程与进程的区别

线程和进程的区别在于,子进程和父进程有不同的代码和数据空间,而多个线程则共享数据空间,每个线程有自己的执行堆栈和程序计数器为其执行上下文。多线程主要是为了节约CPU时间,发挥利用,根据具体情况而定。线程的运行中需要使用计算机的内存资源和CPU。

15. MFC线程和普通线程的区别

分为界面线程和工作者线程,主要区别是消息循环
Win32 CreateThread
MFC界面线程 AfxBeginThread
Qt线程 继承Qthread类,然后重写run()方法;
C++11线程 Thread t(funThread);t.join()或者t.detach()来启动线程。

16. MFC包涵哪几类程序

单文档SDI,多文档MDI,对话框dialog

17. 在哪个类的什么函数中进行MFC程序初始化?相当于main功能的函数。

pApp->InitInstance();

18. 如何自定义消息

1、自定义消息号:#define WM_CCTRY_MSG (WM_USER+100)
2、在头文件中添加消息响应函数的声明:afx_msg LRESULT OnCcTryMsg(WPARAM wParam, LPARAM lParam);
3、在CPP文件中添加消息响应函数的实现:
LRESULTCXXXDlg::OnCcTryMsg(WPARAM wParam, LPARAM lParam) {
//相关代码;
}
4、在 BEGIN_MESSAGE_MAP 与 END_MESSAGE_MAP 之间加入消息的映射代码:ON_MESSAGE(WM_CCTRY_MSG, &CDlgTestDlg::OnCcTryMsg)
5、消息的发送:

19. MFC绘图有哪几类DC?各自的类名,及区别。
CObject
public |------CDC
public|------|------CClientDC
public|------|------CPaintDC
public|------|------CWindowDC
public|------|------CMetaFileDC

20. MFC有哪几类绘图对象?各自的类名。

CBrush - 刷子定义了一种位图形式的像素,用它可以对区域内部填充颜色。
CFont - 字体是一种具有某种风格和尺寸的所有字符的集合。
CPalette - 调色板是一种颜色映射接口。
CPen - 笔是一种画线和有形边框的工具,可以指定画线的宽度,以及画虚线,实线等。
CRgn -区域是一种范围,可以用它来填充、裁剪以及鼠标点中测试。

21. MFC的对话框的种类,各自怎么使用?及相关函数。

Windows中有两种对话框,模态对话框和非模态对话框.
模态对话框 (Modal Dialog Boxes)工作时使其父类窗口无效,直到对话框结束,也就是说,该对话框打开后,程序等待用户输入并关闭对话框后才执行其它任务。

CMyDialog dlg ;
dlg.DoModal();

非模态对话框 ( Modeless Dialog Boxes) 与模态对话框相反,对话框打开期间,允许用户切换到程序其它部分,不一定要关闭对话框。

CMyDialog dlg;
dlg.Create();

22. MFC常用的通用控件有哪些?举出类名。

在这里插入图片描述
23. MFC的动态库有哪几种类型?扩展库一般用来做什么?
DLL分类:
1。Non-MFC DLL(非MFC动态库):不采用MFC类库结构,其导出函数为标准的C接口,能被非MFC或MFC编写的应用程序所调用;
2。MFC Regular DLL(MFC规则DLL):非MFC动态库MFC规则DLL 包含一个继承自CWinApp的类,但其无消息循环;
3。MFC Extension DLL(MFC扩展DLL):采用MFC的动态链接版本创建,它 只能被用MFC类库所编写的应用程序所调用。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值