孙鑫VC教程学习笔记1

来源:互联网 发布:刘诗雯禁赛知乎 编辑:程序博客网 时间:2024/04/28 12:09

 

2008-1-2      孙鑫VC教程学习笔记     NO1
1.GetStockObject()得到画笔、画刷、字体、调色板的句柄,使用时必须用类型转换。
2.什么是野指针?答:将指针指向的变量的内存释放后,此指针即变成野指针!如何避免野指针?答:将此指针指向NULL即可。p=NULL;
3.创建一个完整的窗口的四个步骤SDK,1设计窗口类,2注册窗口类,3创建窗口,4显示窗口。5 消息循环
4.在处理消息的回调函数中,我们一定要实现WM_PAINT和WM_DSTROY消息。前一个消息用来绘制窗口,后一个消息在我们关闭窗口时,调用PostQuitMessage这个函数。The PostQuitMessage function posts a WM_QUIT message to the thread's message queue and returns immediately; the function simply indicates to the system that the thread is requesting to quit at some time in the future. When the thread retrieves the WM_QUIT message from its message queue, it should exit its message loop and return control to the system.
5.消息在windows中是有消息结构体
typedef struct tagMSG {
 HWND   hwnd;   //指定消息所属窗口的句柄
 UINT   message;//消息标示符,eg:WM_QUIT这样的宏
 WPARAM wParam; //指定消息的附加信息
 LPARAM lParam; //指定消息的附加信息。具体见不同的消息说明
 DWORD time;   //指定消息产生时间
 POINT pt;     //指定消息产生时鼠标的当前位置
} MSG, *PMSG;
 
消息队列:当每一个windows应用程序开始执行时,系统会为它创建一个存放消息的队列。Windows将产生的消息依次放到消息队列中,应用程序通过消息循环不断地从消息队列中取出消息并响应它。
进队消息和不进队消息:进队消息有系统放入到应用程序的消息队列中,然后由应用程序取出并发送。不进队消息在系统调用窗口过程时直接发送给窗口。例如:UpdateWindow就是通过直接将WM_PAINT消息发送给窗口过程函数来刷新指定窗口的客户区。WM_PAINT消息就不进入此应用程序的消息队列
 
6、WinMain函数
int WINAPI WinMain(
 HINSTANCE hInstance,      // handle to current instance
 HINSTANCE hPrevInstance, // handle to previous instance
 LPSTR lpCmdLine,          // command line
 int nCmdShow              // show state
)
它是应用程序的人口(实际上是由插入到可执行文件中的启动代码调用)。参数解析如下:
hInstance:标示应用程序当前运行的实例句柄。
hPrevInstance:标示应用程序当前实例的前一个实例句柄。
lpCmdLine:是一个以空结尾的字符串,表示传递给应用程序的命令行参数。
nCmdShow:指示应用程序显示属性,最大/小化等。一般我们不用管它,它是由程序的调用者来指定。
 
7、句柄:句柄是系统返回的标示内存中资源(如:cursor、Icon、Brush等)的唯一表示符
 
8、BOOL GetMessage(
 LPMSG lpMsg,         // 消息信息
 HWND hWnd,           // 指定接受属于那一个窗口的信息,一般设置为NULL,// 用于接受属于调用线程的所有窗口的信息
 UINT wMsgFilterMin, // 指定获取消息的最小值(我们消息宏都是整数值)
 UINT wMsgFilterMax   // 指定获取消息的最大值。如果两个都为0,则接受// 所有消息
);
函数接收到WM_QUIT消息返回0,其余的消息返回非0.错误返回-1.由这点我们知道为什么一定要在销毁窗口时传递WM_QUIT消息,当接收WM_QUIT消息时,GetMessage返回0,退出消息死循环,不然windows应用程序就要通过while死循环来保证应用程序的运行
 
9、TranslateMessage函数就是将虚拟键消息转换为字符消息,字符消息被投递到调用线程的消息队列中,当下一次调用GetMessage或PeekMessage时被取出。当我们敲击键盘时,会产生WM_KEYDOWN和WM_KEYUP消息,这两个消息的(wParm、lParam)包含虚拟键代码和扫描码信息等,而我们程序要得到的是我们敲击的键的ASCLL码,TranslateMessage可一将WM_KEYDOWN和WM_KEYUP消息转换成一条WM_CHAR消息(该消息的wParam参数包含字符键的ASCLL码信息),并将转换后的新消息投递到调用线程的消息队列中。注意在这个过程中TranslateMessage并没有修改原来的消息,它指示产生新的消息并投放到调用线程的消息队列中
 
10、DispatchMessage将消息回传给窗口过程函数来处理。
    PeekMessage的前4个参数和GetMessage一样,最后的UINT wRemoveMsg指定消息回去的方式
PM_NOREMOVE
Messages are not removed from the queue after processing by PeekMessage.
PM_REMOVE
Messages are removed from the queue after processing by PeekMessage
SendMessage是发送不进队消息,直接将消息发送给窗口,并调用窗口的窗口处理函数进行处理,在处理完毕后返回。
PostMessage是发送进队消息,将消息发送给相关进程的消息队列后立即返回。
PostThreadMessage用与想线程发送消息。
 
11、WM_PAINT消息详解
WM_PAINT消息由系统产生,当一个窗口创建、窗口大小改变(摘抄:Update Region标识了一个窗口上无效、需要被重画的部分。系统使用它来来产生WM_PAINT消息。它使应用程序能够高效地更新窗口内容,因为一方面应用程序可以根据Update Region来决定哪些重画操作是必要的,哪些是不必要的,从而执行最少的重画操作;另一方面,即使重画整个窗口,也只对Update Region区产生效果,其他部分自动处于clip region之外。)应用程序只是强迫接受这个消息,并在窗口处理函数中进行响应
当应用程序消息队列为空时,系统会发送WM_PAINT消息,应用程序要调用BeginPaint来处理(BeginPaint 和WM_PAINT消息紧密相关,并且BeginPaint只能在WM_PAINT处理函数中使用)。试一试在WM_PAINT处理函数中不写BeginPaint会怎样?程序会像进入了一个死循环一样达到惊人的CPU占用率,你会发现程序总在处理一个接 一个的WM_PAINT消息。这是因为在通常情况下,当应用收到WM_PAINT消息时,窗口的Update Region都是非空的(如果为空就不需要发送WM_PAINT消息了),BeginPaint的一个作用就是把该Update Region置为空,这样如果不调用BeginPaint,窗口的Update Region就一直不为空,如前所述,系统就会一直发送WM_PAINT消息
 
12LOWORD()和HIWORD()宏
     分别得到一个32为的字的低位(low-order word)和高位(high-order word)