什么是GDI?
GDI, Graphics Device Interface
GDI在以下位置已经被微软列为Legacy Graphics,不建议使用来开发应用程序(http://msdn.microsoft.com/zh-CN/library/windows/desktop/hh309470(v=vs.85).aspx)。
但是这里我们需要了解的是GDI的原理,比如为什么能够用它来做出透明的效果。
(事实上这个问题的答案是LayeredWindow是怎么工作的)
GDI就一系列的Windows API函数的集合,负责代表用户程序来进行图像图形的操作。
GDI+:
Windows GDI+ is a class-based API for C/C++ programmers.
Other topic(Windows消息机制:http://msdn.microsoft.com/zh-CN/library/windows/desktop/ff381405(v=vs.85).aspx)
To pass a message to a window, the operating system calls the window procedure registered for that window. (And now you know what the window procedure is for.)
一个窗口程序,需要对外界发生的事件进行一定的响应,比如:
- 用户按下了某个键
- 系统的状态发生了改变,应用程序必须做相应的反馈(笔记本电池电量低)
这是通过消息机制完成的。
向一个窗口发送消息,是通过调用那个窗口注册到Windows操作系统的窗口过程函数(Windows Procedure Function)来完成的。
For each thread that creates a window, the operating system creates a queue for window messages. This queue holds messages for all of the windows that are created on that thread. The queue itself is hidden from your progam. You can't manipulate the queue directly, but you can pull a message from the queue by calling the GetMessage function.
对于每一窗口,它都要接收很多消息,这些消息不能一次性的都立即得到响应,因此需要一种缓存机制,把消息缓存到queue里面,然后在窗口过程函数处理完上一个消息后,可以从队列里再取出下一条消息进行处理。
而实际上,操作系统采用了更加高效的处理办法,并不是为每个窗口过程都维护一个窗口队列,而是为创建了窗口的线程维护一个消息queue,这样做的好处是,如果一个线程创建了多个窗口的话,那么并不需要维护多个消息队列,维护一个就够了。
之所以这么做,还有一个重要的原因,是Windows操作系统为认为创建窗口的这个线程是要为窗口的一生去负责的。因此下面讲到的消息循环函数,也是在这个线程中的。
The DispatchMessage function tells the operating system to call the window procedure of the window that is the target of the message. In other words, the operating system looks up the window handle in its table of windows, finds the function pointer associated with the window, and invokes the function.
这样,消息队列就变成了与线程相关的一个数据结构,可以预见,这是通过类型TLS(线程局部存储)类似的手段来管理的。
在这个线程中,编写消息循环函数,就像是一个泵一样,它负责源源不断地把消息从queue中抽出来,再经过TranslateMessage和DispatchMessage的处理,将消息发送到它所负责维护的相应的窗口过程中去。