虚拟桌面原理及实现
blog: http://blog.csdn.net/A00553344/archive/2009/02/02/3858216.aspx文章作者:不赖猴 2009-02-02一、为什么要使用虚拟桌面。场景一、上班的时候,我们经常会趁老板不注意,去一些工作时间不应该去的网站,或是运行一些不应该运行的程序,比如一些聊天工具,小游戏,股票软件等等。而且,经常会打开一大堆。当老板或其他同事来到你的桌前的时候,你正在手忙脚乱的关着这些程序,而且,还来不及保存想要保存的东西。场景二、在你给别人做讲演的时候,需要在电脑桌面上展示很多资料。当然一个桌面经常是远远不够展示的,而且,需要经常的切换画面,由于打开的资料太多,每次还的任务栏里找上一阵。很影响讲演的流畅性。虚拟桌面程序就是用来解决以上的问题。场景一、你可以用虚拟桌面程序同时生成多个桌面。一个桌面打开着你工作的资料,程序等等。一个桌面打开着你的聊天工具及一些你不想别人看到的东西。当然你还可以用一个桌面放一些你想访问的网站啊,股票信息啊等等。剩下的只是简单的按一下快捷键来切换不同的桌面。场景二、同场景一,你可以用虚拟桌面程序生成多个桌面,把要讲演的资料提前分配到多个桌面。剩下的只是简单的按一下快捷键来切换不同的桌面。二、虚拟桌面实现原理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;三、结束语你可以把这个虚拟桌面程序做成一个服务,每次开机就自动加载。这样,你就可以每次都拥有多个桌面了。附件release.rar是运行程序,无须安装。
http://d.download.csdn.net/down/985557/A00553344
blog: http://blog.csdn.net/A00553344/archive/2009/02/02/3858216.aspx文章作者:不赖猴 2009-02-02一、为什么要使用虚拟桌面。场景一、上班的时候,我们经常会趁老板不注意,去一些工作时间不应该去的网站,或是运行一些不应该运行的程序,比如一些聊天工具,小游戏,股票软件等等。而且,经常会打开一大堆。当老板或其他同事来到你的桌前的时候,你正在手忙脚乱的关着这些程序,而且,还来不及保存想要保存的东西。场景二、在你给别人做讲演的时候,需要在电脑桌面上展示很多资料。当然一个桌面经常是远远不够展示的,而且,需要经常的切换画面,由于打开的资料太多,每次还的任务栏里找上一阵。很影响讲演的流畅性。虚拟桌面程序就是用来解决以上的问题。场景一、你可以用虚拟桌面程序同时生成多个桌面。一个桌面打开着你工作的资料,程序等等。一个桌面打开着你的聊天工具及一些你不想别人看到的东西。当然你还可以用一个桌面放一些你想访问的网站啊,股票信息啊等等。剩下的只是简单的按一下快捷键来切换不同的桌面。场景二、同场景一,你可以用虚拟桌面程序生成多个桌面,把要讲演的资料提前分配到多个桌面。剩下的只是简单的按一下快捷键来切换不同的桌面。二、虚拟桌面实现原理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;三、结束语你可以把这个虚拟桌面程序做成一个服务,每次开机就自动加载。这样,你就可以每次都拥有多个桌面了。附件release.rar是运行程序,无须安装。
http://d.download.csdn.net/down/985557/A00553344
解决方案 »
- 关于勾子回调函数中参数的问题
- 请问大家一般用Delphi开发网络服务器用TServerSocket还是TIdTCPServer还是...?
- 一个程序出错,请高手帮帮忙!!急!
- Delphi中存储过程参数怎么处理
- 请问如何在DELPHI中实现有选择的从SQL SEVER 中提取一些数据到本地的ACCESS数据库中
- 如何用delphi制作一个独立的www服务器?
- 在WIN2000,XP中,自定义纸张的报表打印不对,请大家帮忙解决,在线等待!
- 在线高分求救!!谁能提供Delphi的反编译软件??
- 怎样在调用API函数打开画图软件的同时将图片将某张图片加载到画图里直接编辑,而不用再次打开文件.
- Blob has been modified 是怎么回事
- 仿做一个,咋就那么难呢....
- exception class EInouterror with message 'I/O erro 103'这样的错误是什么原因啊?
本公司是一家大型的信息专业网站,公司09年为了开拓全国业务需要,现急需招聘具备良好的团队合作精神,责任感强,善于沟通,能够承受压力的程序员3-5名,职位要求如下:(一)Delphi程序员
1、三年以上Delphi开发经验,精通Delphi+SQL Server编程, 熟悉SQ LServer数据库;
2、从事过行业管理信息系统开发全过程,具有一定的软件工程思想;
3、有电子商务、国际货运代理、仓储、物流EDICRM软件开发经验优。
(二)C#程序员
1.二年以上C#软件研发工作经验;
2.有软件体系结构设计经验,有很强的C#编码技能;
3.精通XML、MSDTC、COM+/COM、Web Services和.net framework;
4.熟练掌握Oracle、SQL Server等大型数据库系统,熟悉数据库设计、调优及SQL存储过程的编写。
(三)网站设计程序员
1. 美术、计算机二年以上工作经验;
2. 熟悉SQL数据,精通ASP.NET编程进行后台的开发,有一定的编辑经验,能够独立完成项目方案的设计;
3. 精通网页设计和平面设计的相关软件,如Dreamweaver、Photoshop、Flash、Coredraw等 ;
4.文字功底好,有丰富的想象策划能力,能独立完成大型网站的建设需求/策划方案。 工作地点:河南 工作方式:全职 福利待遇:面议(不会低于你的期望值)联系方式:冯先生 13603728111
因为你是在当前桌面建的,只要你不切换,是不会到其他桌面去的.而且当前的桌面的名字叫'Default',你还可以通过SwitchToDesktop('Default')返回到原始桌面.
;新建桌面之间切换,按CTRL + 3关闭程序;你可以在不同的桌面做不同的事情。 ;
;本代码根据网络上流传的C++代码改编(作者无从考证),非我独创。 ;
;你可以任意修改,使用此代码。此代码由http://www.aogosoft.com/提供下载 ;
;Author: xiep ;
;Email : [email protected] ;
;Wwb : http://hi.baidu.com/xiep_ ; .386
.model flat,stdcall
option casemap:none
include windows.inc
include kernel32.inc
include user32.inc
includelib kernel32.lib
includelib user32.lib .data
hInstance dd 0
hWinMain dd 0
hNewDesktop dd 0
hCurrentDesktop dd 0
szNewDesktop db "NewDeskTop",0
szExplorer db "explorer",0
szClassName db "MyClass",0
CTRL1 EQU 0 ;0 - 0BFFFh
CTRL2 EQU 1
CTRL3 EQU 2 .code
StartExplore proc
LOCAL @stStartInfo :STARTUPINFO
LOCAL @stProcessInfo :PROCESS_INFORMATION mov @stStartInfo.cb, SIZEOF STARTUPINFO
mov @stStartInfo.lpDesktop, offset szNewDesktop
invoke CreateProcess,NULL, addr szExplorer, NULL, NULL, \
TRUE, NULL, NULL, NULL, addr @stStartInfo, addr @stProcessInfo
ret
StartExplore endpSetDesktop proc
invoke GetCurrentThreadId
invoke GetThreadDesktop, eax
mov hCurrentDesktop, eax
mov hNewDesktop, 0
invoke OpenDesktop, addr szNewDesktop, 0, FALSE, 0 ;检查桌面是否已经存在
.if !eax
invoke CloseDesktop, eax ;存在则先关闭
.endif
invoke CreateDesktop, addr szNewDesktop, NULL, NULL, 0, MAXIMUM_ALLOWED, NULL
mov hNewDesktop, eax
.if eax
invoke SetThreadDesktop, hNewDesktop
invoke SwitchDesktop, hNewDesktop
invoke StartExplore
.endif
ret
SetDesktop endp _ProcWinMain proc hWnd, uMsg, wParam, lParam
mov eax, uMsg
.if eax == WM_CLOSE
invoke SwitchDesktop, hCurrentDesktop
invoke CloseDesktop, hNewDesktop
invoke UnregisterHotKey, hWnd, CTRL1
invoke UnregisterHotKey, hWnd, CTRL2
invoke UnregisterHotKey, hWnd, CTRL3
invoke DestroyWindow, hWinMain
invoke PostQuitMessage, NULL
.elseif eax == WM_CREATE
invoke SetWindowPos, hWnd, HWND_TOPMOST, \
0, 0, 0, 0, SWP_NOMOVE or SWP_NOSIZE ;窗口置顶
invoke RegisterHotKey, hWnd, CTRL1, MOD_CONTROL, 31h ;CTRL + 1
invoke RegisterHotKey, hWnd, CTRL2, MOD_CONTROL, 32h ;CTRL + 2
invoke RegisterHotKey, hWnd, CTRL3, MOD_CONTROL, 33h ;CTRL + 3
invoke SetDesktop
.elseif eax == WM_HOTKEY
.if wParam == CTRL1
invoke SwitchDesktop, hCurrentDesktop
.elseif wParam == CTRL2
invoke SwitchDesktop, hNewDesktop
.elseif wParam == CTRL3
invoke SwitchDesktop, hCurrentDesktop
invoke PostQuitMessage, NULL
.endif
.else
invoke DefWindowProc, hWnd, uMsg, wParam, lParam
ret
.endif
xor eax, eax
ret
_ProcWinMain endp _WinMain proc
local @stWndClass:WNDCLASSEX
local @stMsg:MSG
invoke GetModuleHandle, NULL
mov hInstance, eax
invoke RtlZeroMemory, addr @stWndClass, sizeof @stWndClass
invoke LoadCursor, 0, IDC_ARROW
mov @stWndClass.hCursor, eax
mov eax, hInstance
mov @stWndClass.hInstance, eax
mov @stWndClass.cbSize, sizeof WNDCLASSEX
mov @stWndClass.lpfnWndProc, offset _ProcWinMain
mov @stWndClass.hbrBackground, COLOR_WINDOW + 1
mov @stWndClass.lpszClassName, offset szClassName
invoke RegisterClassEx, addr @stWndClass
invoke CreateWindowEx, WS_EX_TOOLWINDOW, addr szClassName,\
NULL, WS_POPUP or WS_SYSMENU, 0, 0, 0, 0,\
NULL, NULL, hInstance, NULL ;创建无标题栏的窗口,这样就不会在任务栏显示了
mov hWinMain, eax
invoke ShowWindow, hWinMain, SW_SHOWNORMAL
invoke UpdateWindow, hWinMain
.while TRUE
invoke GetMessage, addr @stMsg, NULL, 0, 0
.break .if eax == 0
invoke TranslateMessage, addr @stMsg
invoke DispatchMessage, addr @stMsg
.endw
ret
_WinMain endpstart:
call _WinMain
invoke ExitProcess, NULL
end start
sc delete 服务名
[/code]
CreateDesktop
SwitchDesktop
CloseDesktop
EnumDesktops
这么几个API函数,串联一下,加个全局热键就搞定了。
这并不困难,实际上虚拟桌面最大的难题是如何将一个窗口或者进程从一个桌面切换到另一个,
以及如何原原本本的讲桌面关闭楼主能把自己的东西共享出来,精神可嘉,但希望可以看到更深层次的研究!
也不是什么难题,几行代码的事,只不过是不能在GUI线程中处理罢了.关闭桌面,只要将这个桌面里所有的东西关闭完,再去关闭句柄就是了