线程和消息队列的详解 【图】

RIT+SHIQ构成了系统的硬件输入模型的核心

  系统为每个线程维护一个消息队列,还维护一个全局的消息队列,称为系统硬件输入队列(SHIQ:SystemHanrwareInputQueue),用于存储系统中硬件出发的消息。(如鼠标、键盘等引发的消息)在系统初始化的时候会建立一个特殊的线程------原始输入线程(RIT:RawInputThread).

  系统为线程建立消息队列,实际上就是分配一个THREADINFO结构的数据,使其与线程关联。

  在THREADINFO结构中包含有登记消息队列的指针虚拟输入队列指针发送队列指针、应答消息队列指针、退出代码、唤醒标记和局部输入状态变量等信息。

线程和消息队列的详解 【图】_第1张图片

线程和消息队列的详解 【图】

 

 

 

 

    *   虚拟输入队列指针(Virtualized-input):接收接盘的等虚拟输入信息队列                                (就是一个指针数组)
    *   登记消息队列指针(Posted-Message):使用PostMessage函数发送的消息,将存放于此                      (就是一个指针数组)
    *   发送消息队列指针(Send-Message):SendMessage函数发送的消息存放位置                                (就是一个指针数组)
    *   应答消息队列指针(Reply-Message):使用SendMessage函数发送信息后,返回的信息存放于此
    *   nExitCode:确定线程退出状态,是一个int型,不同数值说明线程处于不同状态
    *   唤醒标志:判断是否处于唤醒状态
    *   局部输入状态变量:不详

PostMessage(HWND hWnd,UINT Msg,WPARAM wParam,LPARAM lParam):(SendMessage和PostMessage的原理差不多,只是SendMessage会等待窗口过程处理完了以后才返回)

在调用该函数时,系统首先确定是哪个线程创建了hWnd参数标识的窗口,然后系统分配一块内存区域,将消息信息(该函数的实参)存储在这块区域中,并将该区域的首地址添加到线程的登记消息队列中。

 

整体流程:(以鼠标消息为例WM_MOUSEMOVE)

1.用户移动鼠标产生事件,系统通过设备驱动程序将消息(系统先将鼠标事件封装成消息,即MSG结构体)放入SHIQ(就是把一个指向MSG结构体的32位地址放入虚拟输入队列指针中),此时RIT会唤醒,RIT通过当前鼠标光标之下的窗口,获取创建窗口的线程ID(通过GetWindowThreadProcessId函数实现),然后将鼠标消息放入到线程的虚拟输入队列中(就是把一个指向MSG结构体的32位地址放入虚拟输入队列指针中)

2.应用程序从虚拟输入队列指针中取消息,并将其回传给操作系统

3.由操作系统调用窗口过程(通过hWnd找到所属的窗口类,在窗口类中找到窗口过程的地址)

你可能感兴趣的:(存储,存储系统)