在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(, ) 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 还待继续测试, 不过鬼线程的问题到是找到答案了
在XE5中 VCL空窗体的3个线程的更多相关文章
- Delphi XE5中的新增内容
Delphi XE5中的新增内容 Delphi XE5是所有Delphi开发人员的必须备升级,并且是来自Embarcadero的获奖的.多设备应用开发解决方案的最新版本.使用Delphi XE5的新特 ...
- winform打开子窗体后,在子窗体中刷新父窗体,或者关闭子窗体刷新父窗体
winform打开子窗体后,在子窗体中刷新父窗体,或者关闭子窗体刷新父窗体,搜集了几个方法,列举如下: 一 . 所有权法 父窗体,名称为“fuForm”,在父窗体中有个公共刷新方法,也就是窗体数据初始 ...
- Unity 3D Intantiate过程中Transform 空物体和本体之间的关系
想当年刚学Unity的时候,这个问题困扰了我好几天,因此来分享一下当初解决问题的思路. 我们通过Unity构建场景的过程中,经常发现一个现象,就是物体在拖进场景中后,我们会发现物体是反的,通过改变物体 ...
- C#中如何排除/过滤/清空/删除掉字符串数组中的空字符串
C#中要如何才能删除一个字符串数组中的空字符串呢?随着微软对C#不断发展和更新,C#中对于数组操作的方式也变得越来越多样化.以往要实现过滤数组中的空字符串,都是需要实行循环的方式来排除和过滤.C#3. ...
- ubuntu 工作区中拖动一个窗体到另一个工作区就卡住回不到桌面了
ubuntu 工作区中拖动一个窗体到另一个工作区就卡住回不到桌面了 解决方法: 按 alt + 回车 键直接就返回去了
- 转:C/C++中,空数组、空类、类中空数组的解析及其作用
转自:http://blog.sina.com.cn/s/blog_93b45b0f01015s95.html 我们经常会遇到这些问题: (1)C++中定义一个空类,他们它的大小(sizeof) 为多 ...
- INNO SETUP卸载程序中加入自定义窗体
原文:INNO SETUP卸载程序中加入自定义窗体 [Setup] AppName=My Program AppVerName=My Program v.1.2 DefaultDirName={pf} ...
- Unity Editor 检查工程Prefab(预设)中的空组件
在我们做项目的过程中 经常会有预设中出现空的脚本 例如: 导致的原因是因为 脚本的丢失 现在我们来做一个检查工程中有空脚本的预设工具 老规矩直接上代码 放到工程就能用 using UnityEngin ...
- C#中制作MDI窗体
在VB中做 MDI窗体很简单.在C#里就没有这个轻松了,不过还是很方便的. 首先在C#里添加一个窗体,命名为MdiMain,将其IsMdiContainer设定成true,这样MDI主窗体就建立了.然 ...
随机推荐
- 图文详解YUV420, yuv格式2
YUV格式有两大类:planar和packed. 对于planar的YUV格式,先连续存储所有像素点的Y,紧接着存储所有像素点的U,随后是所有像素点的V. 对于packed的YUV格式,每个像素点的Y ...
- HTML-meta
设置meta: 默认下移动设备浏览器会像PC浏览器一样显示页面,这种时候需要进行设备宽度设置:一般情况下设置为: <meta name='viewport' content='width=dev ...
- PDA移动POS开单扫描打票收银系统-带来零售批发 新的技术 新的手段!!
手持POS终端高清彩屏,清晰.美观.大方,适用于仓库.超市.服装.食品.批发零售.手机电脑等企业管理.可与管理软件灵活对接.1:员工记不住价格,产品名称,只要有PDA扫描,价格,库存,直接开销售单,打 ...
- 水题 ZOJ 3875 Lunch Time
题目传送门 /* 水题:找排序找中间的价格,若有两个,选价格大的: 写的是有点搓:) */ #include <cstdio> #include <iostream> #inc ...
- DFS POJ 2362 Square
题目传送门 /* DFS:问能否用小棍子组成一个正方形 剪枝有3:长的不灵活,先考虑:若根本构不成正方形,直接no:若第一根比边长长,no 这题是POJ_1011的精简版:) */ #include ...
- 模拟 2013年山东省赛 J Contest Print Server
题目传送门 /* 题意:每支队伍需求打印机打印n张纸,当打印纸数累计到s时,打印机崩溃,打印出当前打印的纸数,s更新为(s*x+y)%mod 累计数清空为0,重新累计 模拟简单题:关键看懂题意 注意: ...
- BZOJ3847 : ZCC loves march
注意到集结操作相当于合并一些点 于是我们可以使用并查集 对于每一行.每一列维护一个链表,储存里面的点 查询x时,在并查集中找到x的祖先u,此时x的坐标就是u的坐标 然后扫描u所在行列的链表,依次删除每 ...
- Java读数据是的编码问题。
今天使用Java的I/O读写数据的时候,出现了中文乱码问题,在老师的帮助下找到了问题的根源: 在window中新建文件时,如果你新建的是文本文件或者是一个windows无法识别的文件,他默认使用的编码 ...
- C#中DataTable使用技巧
在项目中经常用到DataTable,如果DataTable使用得当,不仅能使程序简洁实用,而且能够提高性能,达到事半功倍的效果,现对DataTable的使用技巧进行一下总结. 一.DataTable简 ...
- HDU 4612 Warm up(Tarjan)
果断对Tarjan不熟啊,Tarjan后缩点,求树上的最长路,注意重边的处理,借鉴宝哥的做法,开标记数组,标记自己的反向边. #pragma comment(linker, "/STACK: ...