研究Win32 GUI中SetActiveWindow与SetFocus和窗口消息

为了与Win32 GUI的函数功能兼容,得先知道Windows是怎么处理这些信息的,才能模仿。

这次研究对象是SetActiveWindow与SetFocus和窗口消息WM_SETFOCUS,WM_ACTIVATE之间的关系

------------------------------------

SetFocus

功能:设置新的焦点窗口,只有焦点窗口才能获取键盘输入消息

1.这个函数会检查输入的窗口,如果是最小化的窗口,或者禁用的窗口,则不会改变焦点.

2.如果要设置的焦点窗口是子窗口,且其父窗口不是激活状态,还会调用SetActiveWindow将其父窗口激活.

3.检查激活窗口是否成功,如果没有成功,则取消设置新焦点.

4.向窗口发送WM_SETFOCUS消息,向前一个焦点窗口发送WM_KILLFOCUS消息

-----------------------------------

SetActiveWindow

功能:设置激活窗口,只有激活窗口,才能拥有焦点窗口

1.检查传入的窗口,如果是子窗口,则取消操作

2.向当前激活窗口发送WM_NCACTIVE消息,如果当前激活窗口返回FALSE,则表示它不同意其它窗口被激活,所以取消操作.

3.如果第2步没有问题,则向当前激活窗口发送WM_ACTIVE消息,告之被取消激活.

4.将传入的窗口标记为激活窗口,并将窗口的Z序置顶,

5.向新激活窗口发送WM_NCACTIVE和WM_ACTIVE消息,告之被成功激活.


---------------------------------

WM_NCACTIVE

这个消息通知窗口,非客户区被激活或取消激活.

当WPARAM参数为FALSE时,表示窗口要被取消激活,此时如果返回FALSE,则会阻止被取消激活,返回TRUE则表示允许被激活。

DefWindowProc 处理方式:做一些内部标记,如果lParam为-1的话,还要重绘标题栏和菜单栏!


WM_SETFOCUS 

这个消息是通知窗口,即将获得或失去焦点;

DefWindowProc好像并没有处理这个消息。


WM_ACTIVATE 

 这个消息是通知窗口,即将被激活或取消激活;

DefWindowProc 处理方式是:如果这个窗口马上要被激活了,则将这个窗口设置为焦点窗口


---------------------------------

这里很诡异的是,如果对一个未激活的主窗口调用SetFocus,它会激活这个窗口,

而激活这个窗口会发送WM_ACTIVE消息,而默认处理WM_ACTIVE消息的方式又是对这个窗口调用SetFocus...


你可能感兴趣的:(学习笔记)