为了与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...