Win32/MFC的基本概念

时间:2023-03-08 17:04:45

一、MFC的基本概念

单文档、多文档和对话框框架的区别

MFC中的类继承图的基本框架

CView类与CDocument的关系

Onpaint()和Ondraw()的关系

hdc-cdc区别联系

RUNTIME_CLASS是什么

DECLARE_DYNAMIC 和 IMPLEMENT_DYNAMIC

DECLARE_DYNCREATE 和 IMPLEMENT_DYNCREATE

DECLARE_SERIAL 和 IMPLEMENT_SERIAL

RUNTIME_CLASS宏的定义是这样的:

#define RUNTIME_CLASS(class_name)

((CRuntimeClass*)(&class_name::class##class_name))

其中##的意思是把##两边的符号都进行宏扩展(如果它们是宏的话),然后把扩展

后的内容连接在一起,中间不加空格。例如:RUNTIME_CLASS(CView)将被扩展成

:(CRuntimeClass*)(&CView::classCView)

但这个classCView是什么意思?原来,classCView是由DECLARE_DYNAMIC(CView)

引入的一个public属性的CRuntimeClass类型的静态成员变量:

static const AFX_DATA CRuntimeClass classCView;

原来RUNTIME_CLASS的作用就是引用由DECLARE_DYNAMIC宏引入的静态成员变量。

二、Win32的基本问题:

1.SDK创建窗口的过程

2.Getmessage函数与Peekmessage函数的区别:

(1)GetMessage的主要功能是从消息队列中“取出”消息,消息被取出以后,就从消息队列中将其删除;而PeekMessage的主要功能是“窥视”消息,如果有消息,就返回true,否则返回false。也可以使用PeekMessage从消息队列中取出消息,这要用到它的一个参数(UINT wRemoveMsg),如果设置为PM_REMOVE,消息则被取出并从消息队列中删除;如果设置为PM_NOREMOVE,消息就不会从消息队列中取出。
(2)GetMessage每次都会等待消息,直到取到消息才返回;而PeekMessage只是查询消息队列,没有消息就立即返回,从返回值判断是否取到了消息。

SendMessage()和PostMessage()的区别

3. 发送WM_QUIT消息使程序终止的内部过程:

WM_CLOSE:

在系统菜单里选择了“关闭”或者点击了窗口右上角的“X”按钮,你的窗口过程就会收到WM_CLOSE。DefWindowProc对 WM_CLOSE的处理是调DestroyWindow。 当然,你可以不让DefWindowProc处理,而是自己处理,例如询问用户是否保存更改等。如果用户选择“取消”,你忽略此消息,那么程序照常运行;如果用户确认要退出,你就调用DestroyWindow。

WM_DESTROY:

接下来,DestroyWindow完成窗口的清理工作,最后向窗口过程发送WM_DESTROY。对于 WM_DESTROY,DefWindowProc不会处理。也就是说,你如果不处理这个消息,虽然你的窗口已经销毁,但进程并不会结束。一般处理 WM_DESTROY时都是释放资源(例如申请的内存等),然后调用PostQuitMessage。

WM_QUIT:

PostQuitMessage会发送WM_QUIT给消息队列。注意,WM_QUIT永远不会到达窗口过程,因为GetMessage得到WM_QUIT后就会返回FALSE,从而结束消息循环,最后进程结束,程序退出。

4.TranslateMessage及 DispatchMessage的作用

MFC的消息处理机制:

winsows消息队列把得到的消息发送到线程消息队列, 线程消息队列每次取出一条消息发送到指定窗口,不断循环直到程序退出.

这个循环就是靠消息

while(GetMessage())

{

TranslateMessage();

DispatchMessage();

}    
实现的。

GetMessage()只是从线程消息中取出一条消息,而DispatchMessage 则把取出的消息发送到目的窗口。

TranslateMessage是翻译需要翻译的消息   DispatchMessage()则会把翻译好的消息发送到系统的消息处理函数中,而这个函数又会把这个消息传递到注册窗体时用户指定的消息处理函数中。

5. 有模式对话框与无模式对话框的区别,创建步骤。收到的创建消息是什么

使用上的区别:模式对话框创建后,程序的其他窗口便不能进行操作,必须将该窗口关闭后,其他窗口才能进行操作。而非模式对话框则无需这样,它不强制要求用户立即反应,而是与其他窗口同时接受用户操作。

创建上的差别:在MFC或是WTL中,模式对话框一般是使用DoModal,而非模式对话框的创建则是使用Create。

在消息响应方面,模式对话框和非模式对话框之间又有着很大的区别。模式对话框工作的时候,它有内部的消息泵机制,控件之间的交互不用我们人为的去控制,系统会帮助我们去处理。非模式对话框则像普通窗口一样,则由WinMain中书写的消息循环驱动。但由于是对话框,它对一些消息有特殊的处理。因此,在消息循环中,需要先对对话框提供截获消息的机会。

销毁的差别:模式对话框的销毁是使用EndDialog,而非模式对话框的销毁是使用DestroyWindow.。所以我们在销毁对话框的时候,也要对其进行区别。

非模式对话框,用户关闭对话框时,对话框消息处理函数将收到WM_CLOSE消息,接到后调用DestroyWindow以销毁非模式对话框。

模式对话框,则一般响应IDOK和IDCANCEL。在PPC上,我们对于OK键和X键的处理要注意这点。

6. 试比较_beginthreadex、_beginthread 和 CreateThread的区别。关闭线程和关闭进程的函数分别是什么?试比较_endthreadex、_endthread 和 ExitThread的区别。

1:_beginthreadex与CreateThread的区域

在 Win32
API 中,创建线程的基本函数是
CreateThread,而
_beginthread(ex) 是C++
运行库的函数。为什么要有两个呢?因为C++ 运行库里面有一些函数使用了全局量,如果使用
CreateThread 的情况下使用这些C++
运行库的函数,就会出现不安全的问题。而
_beginthreadex 为这些全局变量做了处理,使得每个线程都有一份独立的“全局”量。

所以,如果你的编程只调用 Win32
API/SDK ,就放心用
CreateThread;如果要用到C++
运行时间库,那么就要使用
_beginthreadex ,并且需要在编译环境中选择
Use MultiThread Lib/DLL。_beginthreadex内部调用了CreateThread。

2:_beginthread()和_beginthreadex()的区别

beginthread()和_beginthreadex()的线程执行函数的定义是不一样的。

对于_beginthread()创建的线程,其线程函数定义为:

void ThreadPro(void * pArguments );

对于_beginthreadex()创建的线程,其线程函数定义为:

unsigned __stdcallThreadFunc( void* pArguments )

(1)两者创建线程函数方式不同,_beginthreadex()的线程函数必须使用__stdcall调用方式,而且必须返回一个unsigned型的退出码。

(2)_beginthreadex()在创建线程失败时返回0,而_beginthread()在创建线程失败时返回-1,这一点在检测返回结果时必须注意。

(3)如果是调用_beginthread()创建线程,并相应地调用_endthread()结束线程时,系统将自动关闭线程句柄。而调用_beginthreadex()创建线程,并相应地调用_endthreadex()结束线程时,系统不能自动关闭线程句柄。

(4)由于_beginthread()创建线程参数比较简单,不能控制线程的初始启动状态,且不返回创建的线程句柄,也不能调用

WaitForSingleObject()/WaitForMultipleObjects()函数。所以一般不常用,而_beginthreadex()与CreatThread()函数比较相似。能方便控制线程。

7.线程同步的四种方式的机制

1、临界区:通过对多线程的串行化来访问公共资源或一段代码,速度快,适合控制数据访问。在任意时刻只允许一个线程对共享资源进行访问,如果有多个线程试图访问公共资源,那么在有一个线程进入后,其他试图访问公共资源的线程将被挂起,并一直等到进入临界区的线程离开,临界区在被释放后,其他线程才可以抢占。
2、互斥量:采用互斥对象机制。 只有拥有互斥对象的线程才有访问公共资源的权限,因为互斥对象只有一个,所以能保证公共资源不会同时被多个线程访问。互斥不仅能实现同一应用程序的公共资源安全共享,还能实现不同应用程序的公共资源安全共享
3、信号量:它允许多个线程在同一时刻访问同一资源,但是需要限制在同一时刻访问此资源的最大线程数目
4、事 件: 通过通知操作的方式来保持线程的同步,还可以方便实现对多个线程的优先级比较的操作

8.简述Winsock的六种主要IO处理模式

有阻塞,select,异步选择,事件选择,重叠模型,完成端口模型。

9.TCP和UDP的区别。建立基于TCP的网络编程客户端和服务器的基本过程是什么

笔记本上有。