什么是桌面?
每一个运行着 Window NT 的系统中都有一个 Window 工作站对象,这个对象是安全对象的第一层,是所有用户安全对象的继承之源,每一个 Window 工作站对象可以拥有一些桌面对象,每一个桌面都拥有一个窗口链。窗口链里存放着显示在所属桌面的各种窗口。Window NT 用了两个桌面窗口对象,一个是用来处理登陆界面、屏蔽、锁住工作站等,一个是我们登陆之后进来操作的窗口了。 Window NT 通过”explorer.exe”进程来管理这个桌面对象。这就是为什么我们在任务管理器里杀掉”explorer.exe”,我们的桌面就会消失的原因。
什么是虚拟桌面?
虚拟桌面是一种可以在电脑原来桌面基础上再创造一个新的桌面出来,在新的桌面上可以进行日常的操作。
虚拟桌面的用途?
(1) 本人觉得这门技术最重要的用途就是可以把任何有UI界面的软件变成一个后台软件(即看不到任何界面,包括启动界面) ,可常用于调用其他软件进行工作,并隐藏其界面。
(2) 可以时工作时是一个桌面,娱乐时是一个桌面(大家可以去下载网站上搜索一下这类软件的用途,上面的功能描述非常有意思)
虚拟桌面的实现方法
在windows中,要创建一下新的桌面可用到API:CreateDesktop(),函数声明如下
HDESK CreateDesktop(
LPCTSTR lpszDesktop, // 新桌面的名称
LPCTSTR lpszDevice, // 为NULL
LPDEVMODE pDevmode, // 为 NULL
DWORD dwFlags, // 指定应用程序在桌面的兼容方式
ACCESS_MASK dwDesiredAccess, // 指定新桌面的权限
LPSECURITY_ATTRIBUTES lpsa //指定句柄是否能被继承
);
返回值是新创建的桌面的句柄。
那么新建了一个桌面后,怎么在这个新的桌面上运行程序呢?先不要着急,我们先来回顾一下创建进程的函数 CreateProcess(),在这个函数的参数中 StartupInfo 中有 lpDesktop这么一个属性,如果这个属性为 NULL 则在当前的桌面创建线程,如果指定了桌面的名称,则进程将会在指定的桌面上启动,所以想在创建的新桌面里初始化一些程序,只要把lpDesktop 参数指定为新桌面的名称即可。
另外也有一个简单的方法可把新的线程挂在新创建的桌面下,就是使用 API 函数SetThreadDesktop(),声明如下:
BOOL SetThreadDesktop(
HDESK hDesktop // 指向指定的桌面句柄
);
但使用这个函数要注意一 点,根据 MSDN 的说法:
The SetThreadDesktop function will fail if the calling thread has any windows or hooks on its current desktop (unless the hDesktop parameter is a handle to the current desktop)
意思就是除非要指定的桌面句柄是当前的桌面,不然的话这个函数的调用会失败如果当前线程拥有任何的窗口(即UI界面).
怎么实现不同桌面之间的切换呢?
要在不同的桌面之间切换,可用API函数SwitchDesktop,声明如下:
BOOL SwitchDesktop(
HDESK hDesktop // 桌面的句柄
);
另外也可通过点击“切换”按钮实现桌面的切换。
但又引申出一个新的问题,必须要知道各个桌面的句柄,获取桌面的句柄可通过API函数GetThreadDesktop,函数的声明如下:
HDESK GetThreadDesktop(
DWORD dwThreadId //线程的ID);
返回值就是指定线程所在的桌面了。
而且我们必须要认清的是创建新桌面的线程启动是在旧的桌面上,所以可以用下面的语句轻松获得当前桌面的句柄:
GetThreadDesktop(GetCurrentThreadId());
返回值就是旧的桌面句柄。
怎么关闭新创建的桌面?
这个问题其实也不用我们担心,微软已经替我们想好了^-^ , 用 CloseDesktop 函数可轻松实现这个功能,函数声明如下:
BOOL CloseDesktop(
HDESK hDesktop // 指定要关闭的桌面的句柄
);
注意:当切换到另一个桌面时,另里个桌面没有你这个切换桌面的程序,需要在切换之前,关掉这个程序,在切换到另一个桌面时,在打开一个同样的程序。