在XE5中 VCL空窗体的3个线程

中午看到技术群里有人讨论, XE5一个空窗体程序就包含了3个线程, 赶忙打开XE5开了个空窗体一看, 果然如此

再打开D7和2010看了一下, 都是一个线程

这时看到有人说一个是输入法, 一个是GDI+, 没细想, 觉得这种说法还比较靠谱, 于是就继续吃饭了, 吃完了睡觉(猪一样的生活啊)

下午睡醒了, 突然又想起了中午看到呢那些, 发觉有些不对, 空窗体启动的时候输入法是关闭的, 哪来的线程, 所以仔细跟踪了一下, 发现和输入法以及GDI+都没关系, 吧相关的单元删除以后线程依旧

于是猜测应该是XE5在程序启动的时候做了什么

于是根据VCL的启动顺序, 从Controls单元的Initialization部分开始跟踪, 发现在TApplication创建以后, 线程出现了, 继续内部跟踪

VCL.Controls -> Initialization -> InitControls -> TApplication.Create(nil) -> CreateHandle

最终跟踪到下面这句:

    if TOSVersion.Check(5, 1) then
      WTSRegisterSessionNotification(LHandle, NOTIFY_FOR_THIS_SESSION);

在执行完WTSRegisterSessionNotification以后, 2个莫名其妙的线程就出现了

发现这个函数是wtsapi32.dll里的一个函数, 于是查MSDN得到如下解释:

If this function is called before the dependent services of Remote Desktop Services have started, an RPC_S_INVALID_BINDING error code may be returned. When the Global\TermSrvReadyEvent global event is set, all dependent services have started and this function can be successfully called.

Session change notifications are sent in the form of a WM_WTSSESSION_CHANGE message. These notifications are sent only to the windows that have registered for them using this function.

When a window no longer requires these notifications, it must call WTSUnRegisterSessionNotification before being destroyed. For every call to this function, there must be a corresponding call to WTSUnRegisterSessionNotification.

If the window handle passed in this function is already registered, the value of the dwFlags parameter is ignored.

To receive session change notifications from a service, use the HandlerEx function.

从字面的意思上看, 这个函数的做用应该是注册一个服务, 用于在用户session切换的时会给程序发一个通知

至于那个WM_WTSSESSION_CHANGE 还待继续测试, 不过鬼线程的问题到是找到答案了

原文地址:https://www.cnblogs.com/lzl_17948876/p/3487378.html