一、系统维持一个全局惟一的消息队列。web
二、各个建立了window的线程,每一个都有且只有一个消息队列,甭管它建立了多少窗口。有多少建立了window的线程,就有多少消息队列。相应就有多少消息循环。编程
三、鼠标、键盘等硬件靠各自驱动程序将用户的输入搞成message发到系统消息队列。系统有消息循环,将其Dispatch到正确的线程消息队列。GUI线程里也有消息循环,将其最终Dispatch到正确的WNDPROC处理。ide
四、只要用户有按键行为,必然触发且只触发虚拟按键消息,如WM_KEYDOWN/WM_KEYUP/WM_SYSKEYDOWN/WM_SYSKEYUP。不会产生WM_CHAR消息,WM_CHAR消息永远不会由敲击键盘行为产生。(不带alt的按键称为nonsystem key)函数
五、消息循环中,通常TranslateMessage与DispatchMessage成一对,就是解决上面的问题,即TranslateMessage的惟一做用就是将WM_KEYDOWN/UP等虚拟按键消息作个解析,好比检测到你按的是A键,就产生一个WM_CHAR消息并放到消息队列里,但正被解析的虚拟按键消息自己不发生任何变化,会继续被传给DispatchMessage去分发,显然,这个新生的WM_CHAR消息只能在之后的新的消息循环里才能获得处理。即只要碰到WM_CHAR消息,它必定是由TranslateMessage函数产生的。固然应用程序主动制造的除外。并且,若是被解析的消息不是虚拟按键消息,那TranslateMessage啥也不干。spa
六、搞清window之间的两对关系:Parent与Child,Owner与Owned。父子关系中的关注点仅仅要知道:对child进行绘制时,所用的坐标的参考系是其Parent的客户区的左上角,child画在其Parent客户区以外的部分不可见,仅此无它。Owner就是拥有者,被它拥有的东西自称Be Owned。Be Owned的东西永远遮在其Owner之上,当其Owner最小化时,它自身会被隐藏。当其Owner被销毁时,它自身也会被销毁,即Owner是关系到其生死存亡的东西。通常Parent与Owner是同一个window,但理论上是能够不一样的。但你本身应搞清这两种关系的区别。线程
七、鉴于上面这两种关系的重要性,CreateWindow系列函数,都须要指定将被建立的window的Parent。若是一个window没有Parent,或者其Parent是系统桌面Desktop(桌面是一个window,只是它没标题栏而已),那么这个window称为top-level窗口。orm
八、CreateWindow与CreateWindowEx的惟一区别是,后者多一个风格参数。CreateWindow里用的窗口风格叫Window Style,以WS_开头;CreateWindowEx里多出来的风格叫Extended Window Style,以WS_EX_开头。CreateWindow内部实现是CreateWindowEx(0, ...)队列
九、Subclassing在win32 sdk编程里全称是Window Procedure Subclassing.别扯什么子类化,我彻底不懂子类化在汉语里是啥意思,也别扯什么派生,这个和派生没半毛钱关系。Subclassing只能在同一个进程里进行,是指更换窗口类或具体窗口的WNDPROC,仅此而已,没有其余。进程
十、Superclassing。同上,全称是Window Procedure Superclassing.也别跟我扯什么超类化,在个人汉语里彻底听不懂。Superclassing的实质是填一张WNDCLASS单子,经过RegisterClass提交给系统注册一下。看到没,这实际上就是构造一个全新的窗口类而已嘛。只是,这张单子的大部份内容,咱们是从一张已有的WNDCLASS单子中拷贝过来的,手段是GetClassInfo函数。很显然,既然咱们是提交一张新的WNDCLASS单子给系统,咱们天然得将单子上的hInstance项、lpszClassName项改为咱们本身的。实际上GetClassInfo返回的单子中没有填写hInstance和lpszClassName这两项,也没有hMenu那一项。这里咱们天然就得考虑一下menu的问题了,menu有什么问题呢?事件
若是原先的窗口类没有menu,咱们天然不需考虑menu了;若是原先的窗口类有menu,那么在它的窗口类里极有可能有对menu各item项的响应 ,即响应WM_COMMAND消息,case语句比对menu item的id,做出相应处理;若是咱们新的窗口过程也处理WM_COMMAND,并且处理完后不交给原先的窗口过程,那咱们天然不用担忧新的窗口类的MENU的问题;但除了这种状况呢?咱们必须保证当有WM_COMMAND消息传递给原先的窗口过程时,能正确运做,那咱们就必须将原先窗口类所用的menu资源克隆出一份,其各identifiers保持和原先一致,而后将新的menu资源填到咱们的新窗口类单子里。固然,若是新老窗口类在同一个应用程序工程里,共享一份已有的menu资源的话,menu问题也不成为问题,新窗口类只需将那个menu资源填到单子里就能够了,无需拷贝一份menu资源,并且也应该这样干。
很明显,由于咱们如今提交了一张新的WNDCLASS单子,因此固然可使用单子里的cbClsExtra和cbWndExtra这俩玩意儿,这俩玩意儿的意思参考WNDCLASS的MSDN文档。可是要注意了,原先的窗口过程里可能有依赖于这俩玩意的代码,因此为保证原先的窗口过程能正常运做,咱们在使用这俩玩意儿时应作到,咱们须要多大的额外空间,则给cbClsExtra和cbWndExtra赋值时应指定各自原来的大小加上如今须要的大小,在新的窗口过程里使用时也要注意咱们新的额外内存是在原先大小的额外内存结尾处开始的。
十一、子控件,也叫子窗口,是窗口。子控件在工做时,可能有时会通知或知会一下它的Parent,通知的方式只有一种,给Parent发消息。发的消息只有两种:WM_COMMAND、WM_NOTIFY。notify比command能够携带的信息量大。好比BUTTON控件被用户单击时,会给其Parent发一条WM_COMMAND消息,消息的lParent参数是这个控件的窗口句柄,消息的wParent高半部分整数值是BN_CLICKED,低半部分整数值是这个控件的id。父窗口想知道本身哪个子控件被点了的话,只须要在本身的窗口过程里响应WM_COMMAND消息,并依据wParam和lParam这两个消息参数作出正确的判断。全部的父子窗口之间的交互都是经过这种简单的方式,是否是简单得不能再简单了。不一样的控件依据不一样的事件给其Parent发的是WM_COMMAND仍是WM_NOTIFY,消息参数如何解释等等这些东西,都在MSDN的控件本身那一页上能够直接查询到。
十二、自绘。我不知道“自绘”这个词是哪一个傻B发明的,反正它让我长久以来一直没搞懂啥叫“自绘”。“自绘”英文是Owner-Draw。看到没,是Owner在Draw,Owner是啥,Owner是控件的拥有者,不是控件自身,所谓的Owner-Draw就是控件窗口须要绘制显示在屏幕上时,会给其Owner发一条WM_DRAWITEM消息,通知其Owner,让它负责把控件本身给画出来。这尼玛是自绘吗???是本身绘制本身吗???明明是让别人画本身!
看了大半夜的MSDN文档,目前就总结出这些东西吧,接着看。