delphi 虚拟桌面原理及实现


本文整理自网络,侵删。

 一、为什么要使用虚拟桌面。 

场景一、

上班的时候,我们经常会趁老板不注意,去一些工作时间不应该去的网站,或是运行一些不应该运行的程序,比如一些聊天工具,小游戏,股票软件等等。而且,经常会打开一大堆。当老板或其他同事来到你的桌前的时候,你正在手忙脚乱的关着这些程序,而且,还来不及保存想要保存的东西。

场景二、

在你给别人做讲演的时候,需要在电脑桌面上展示很多资料。当然一个桌面经常是远远不够展示的,而且,需要经常的切换画面,由于打开的资料太多,每次还的任务栏里找上一阵。很影响讲演的流畅性。

虚拟桌面程序就是用来解决以上的问题。

场景一、

你可以用虚拟桌面程序同时生成多个桌面。一个桌面打开着你工作的资料,程序等等。一个桌面打开着你的聊天工具及一些你不想别人看到的东西。当然你还可以用一个桌面放一些你想访问的网站啊,股票信息啊等等。剩下的只是简单的按一下快捷键来切换不同的桌面。

场景二、

同场景一,你可以用虚拟桌面程序生成多个桌面,把要讲演的资料提前分配到多个桌面。剩下的只是简单的按一下快捷键来切换不同的桌面。

二、虚拟桌面实现原理

1. 原理概况

每次开机的时候,我就创建多个桌面,然后定时监控快捷键(Ctrl+数字键),如果有快捷键被按下,就切换到数字键对应编号的桌面。

2.什么是桌面?

每一个运行着Window NT 的系统中都有一个Window 工作站对象,这个对象是安全对象的第一层,是所有用户安全对象的继承之源,每一个Window 工作站对象可以拥有一些桌面对象,每一个桌面都拥有一个窗口链。窗口链里存放着显示在所属桌面的各种窗口。Window NT 用了两个桌面窗口对象,一个是用来处理登陆界面、屏蔽、锁住工作站等,一个是我们登陆之后进来操作的窗口了。

Window NT通过"explorer.exe"进程来管理这个桌面对象。这就是为什么我们在任务管理器里杀掉"explorer.exe",我们的桌面就会消失的原因。

3.创建一个桌面。

function CreateANewDesktop(DesktopName: string): Boolean;

var

sin : TStartupInfo;

pin : TProcessInformation;

hDesk : HDESK;

begin

result := false;

hDesk := CreateDesktop(PChar(DesktopName),nil,nil,0,MAXIMUM_ALLOWED,nil);

try

FillChar(sin,SizeOf(sin),0);

sin.cb := SizeOf(sin);

sin.lpDesktop := PChar(DesktopName);

CreateProcess(PChar(WindowDirectory+'explorer.exe'),nil,nil,nil,False,0,nil,nil,sin,pin);

Sleep(2000);

result := true;

finally

CloseDesktop(Desk);

end;

end;

4.查询当前已经存在的桌面。

枚举桌面的API是EnumDesktops.

BOOL EnumDesktops(
HWINSTA hwinsta, // 当前的WindowsStation句柄
DESKTOPENUMPROC lpEnumFunc, // 回调函数,由系统调用。
LPARAM lParam //传递给回调函数的参数指针
);
通常我们定义个一回调函数,定义一个全局TStringList类对象,在回调函数里将枚举到的桌面的名称增加到TStringList里。

var

sttopList : TStringList;

function EnumDesktopProc(Desktop: LPTSTR; Param: LParam): Boolean; stdcall;
begin
if (Desktop<>'Winlogon') and (Desktop<>'Disconnect') then

DesktpList.Add(DeskTop);

result := True;
end;

procedure EnumerateDesktops;
begin
EnumDesktops(GetProcessWindowStation, @EnumDesktopProc, nil);
end;

5.切换桌面。

procedure DesktopSwitch(DesktopName: String);
var hDesk: HDESK;
begin
hDesk:=OpenDesktop(PChar(DesktopName), DF_ALLOWOTHERACCOUNTHOOK, False, MXIMUM_ALLOWED);
Sleep(100);
SwitchDesktop(hDesk);
CloseDesktop(hDesk);
end;

三、结束语

你可以把这个虚拟桌面程序做成一个服务,每次开机就自动加载。这样,你就可以每次都拥有多个桌面了。

附件VirtualDesktop.rar是运行程序,无须安装。

下载地址:http://d.download.csdn.net/down/985557/A00553344

跟踪:

这个是csdn论坛 上的一个昵称为猴子的朋友发的。
但是错误非常多。经过改善后和修正错误后。发表出来!
为论坛做点贡献!

我们先要得到windows安装路径,例如C:/WINDOWS,当然有的可能D盘等等,需要一个函数
function GetWindows Path:String;
var
buf:Array[0..255] of Char;
s: String;
begin
GetWindowsDirectory(@Buf,255);
s:=StrPas(@Buf);
if s[Length(s)] <> '\' then
s:= s + '\';
Result:=s;
end;


同时编写一个函数,进行虚拟桌面的创建,利用的是微软 的API:CreateDesktop
function CreateANewDesktop(DesktopName: string): Boolean;
var
sin:TStartupInfo;
pin:TProcessInformation;
Desk:HDesk;
begin
result := false;
Desk:= CreateDesktop(PChar(DesktopName),nil,nil,0,MAXIMUM_ALLOWED,nil);
try
FillChar(sin,SizeOf(sin),0);
sin.cb := SizeOf(sin);
sin.lpDesktop := PChar(DesktopName);
CreateProcess(PChar(GetWindowsPath+'explorer.exe'),nil,nil,nil,False,0,nil,nil,sin,pin);
Sleep(2000);
result := true;
finally
CloseDesktop(Desk);
end;
end;


我在程序界面添加了一个listbox控件,进行虚拟桌面的存放。
procedure TForm1.Button1Click(Sender: TObject);
begin
CreateANewDesktop('desktop'+inttostr(listbox1.Items.Count+1));//创建一个虚拟桌面,名字是desktop+编号
listbox1.Items.Add('desktop'+inttostr(listbox1.Items.Count+1));
end;


进行虚拟桌面的切换
procedure DesktopSwitch(DesktopName: String);
var
Desk: HDESK;
begin
Desk:=OpenDesktop(PChar(DesktopName),DF_ALLOWOTHERACCOUNTHOOK,False,MAXIMUM_ALLOWED
);
Sleep(100);
SwitchDesktop(Desk);
CloseDesktop(Desk);
end;

这个函数是进行切换虚拟桌面的
,当我们选择listbox里的一个项目时,则切换过去,。。。
procedure TForm1.Button3Click(Sender: TObject);
begin
DesktopSwitch(listbox1.Items.Strings[listbox1.ItemIndex]);//应该都明白吧?切换到选择项目的名字
end;



procedure TForm1.Button2Click(Sender: TObject);
begin
DesktopSwitch('Default'); //default代表默认桌面。呵呵!
end;



接下来是关闭了。。。
procedure TForm1.Button4Click(Sender: TObject);
var
Desk:HDESK;
begin
desk:=OpenDesktop(pchar(listbox1.Items.Strings[listbox1.ItemIndex]),0,false,MAXIMUM_ALLOWED);
closedesktop(desk);
end;


发出来了。希望可以给论坛做点贡献,哈能让葛大看上。弄个新功能 就更好了!!
其实,我也姓葛。呵呵
名字差了一个字哦


本文来自CSDN博客,转载请标明出处:http://blog.csdn.net/suiyunonghen/archive/2009/09/16/4560629.aspx

相关阅读 >>

Delphi 用 directshow 获取本机的视频摄像设备列表

Delphi 读取eset nod32 的用户名与密码

Delphi xe string与tstringbuilder的关系

Delphi编程禁止用户关闭操作系统

Delphi研究之驱动开发篇(五)--使用后备列表

Delphi urldownloadtofile 实现文件下载

Delphi写com+的心得体会

Delphi获取控件界面图像“新招”

Delphi 返回整数的四种情况

Delphi android控制睡眠

更多相关阅读请进入《Delphi》频道 >>



打赏

取消

感谢您的支持,我会继续努力的!

扫码支持
扫码打赏,您说多少就多少

打开支付宝扫一扫,即可进行扫码打赏哦

分享从这里开始,精彩与您同在

评论

管理员已关闭评论功能...