拟桌面
突然翻到以前的一个小软件,这个软件的作用是创建一个虚拟桌面,并切换到他,这还是在Win7时代时候的了,貌似那时候很多人用这种类似的软件在上班时玩游戏,但是在Win10中加入了虚拟桌面,这类软件不知道怎么样了。
Win10中可以点击任务视图按钮,在最上面就可以创建,(虚拟桌面在Linux操作系统是一个标配,但是在Windows操作系统一直没有此功能,直到Win10才加入这项功能)。笔记本的话四个手指左右滑动触摸板就可以切换,或者Win + Ctrl + → |←切换。
创建一个虚拟桌面需要CreateDesktop函数,创建出来还需要切换过去,则要使用SwitchDesktop,如果要在虚拟桌面中运行程序,则可以使用CreateProcess,另外创建的新桌面是光秃秃的,并没有桌面图标、桌面壁纸,所以我们要注册一个快捷键,切换过去的时候还要可以切换回来,由于学艺不精,只会点VB,VB注册全局快捷键需要改变默认的窗口过程,然后去判断消息标识是不是WM_HOTKEY,在做相应的判断。
CreateDesktop函数参数
HDESK CreateDesktopA(
LPCSTR lpszDesktop,
LPCSTR lpszDevice,
DEVMODEA *pDevmode,
DWORD dwFlags,
ACCESS_MASK dwDesiredAccess,
LPSECURITY_ATTRIBUTES lpsa
);
lpszDesktops:要创建的桌面的名称。桌面名称不区分大小写,并且不能包含反斜杠字符。
lpszDevice:保留;必须为NULL。
pDevmode:保留;必须为NULL。
dwFlags:此参数可以为零或DF_ALLOWOTHERACCOUNTHOOK,DF_ALLOWOTHERACCOUNTHOOK意思是使在桌面上其他帐户中运行的进程能够在此进程中设置挂钩。
dwDesiredAccess:桌面的权限。
lpsa:指向SECURITY_ATTRIBUTES结构的指针,该结构确定返回的句柄是否可以由子进程继承。如果lpsa为NULL,则不能继承该句柄。
实例
这部分是创建新的桌面,并将默认的窗口过程改成myWindowProc。
其中的GetThreadDesktop用来检索分配给指定线程的桌面的句柄,还有RegisterHotKey注册一个快捷键,当快捷键按下时,窗口过程中会收到WM_HOTKEY消息。
Private Sub Form_Load()
g_hDesktopThreadOld = GetThreadDesktop(App.ThreadID)
RegisterHotKey Me.hWnd, 1, MOD_CONTROL, Asc("Q")
RegisterHotKey Me.hWnd, 2, MOD_CONTROL, Asc("W")
g_hDesktopNameNew = "MyNewDesktop"
g_hDesktopNew = CreateDesktop(g_hDesktopNameNew, vbNullString, ByVal 0&, 0, GENERIC_ALL, ByVal 0&)
SetThreadDesktop g_hDesktopNew
lpOldWinProc = SetWindowLong(Me.hWnd, GWL_WNDPROC, AddressOf myWindowProc)
End Sub
模块中。
这部分主要的逻辑就是判断热键,如果是Ctrl+W,则通过SwitchDesktop 切换到新的桌面,另外通过CreateProcess在新的桌面中打开一个资源管理器(CreateProcess参数中的STARTUPINFOA结构体lpDesktop属性指定新的桌面名称即可),如果是Ctrl+Q则切换到原来桌面。
SwitchDesktop只有一个参数,桌面的句柄,这个句柄由CreateDesktop和 OpenDesktop函数返回。
Public Declare Function GetThreadDesktop Lib "user32" (ByVal dwThread As Long) As Long
Public Declare Function CreateDesktop Lib "user32" Alias "CreateDesktopA" (ByVal lpszDesktop As String, ByVal lpszDevice As String, pDevmode As Long, ByVal dwFlags As Long, ByVal dwDesiredAccess As Long, lpsa As Long) As Long
Public Declare Function SwitchDesktop Lib "user32" (ByVal hDesktop As Long) As Long
Public Declare Function SetThreadDesktop Lib "user32" (ByVal hDesktop As Long) As Long
Public Declare Function CloseDesktop Lib "user32" (ByVal hDesktop As Long) As Long
Public Declare Function OpenDesktop Lib "user32" Alias "OpenDesktopA" (ByVal lpszDesktop As String, ByVal dwFlags As Long, ByVal fInherit As Boolean, ByVal dwDesiredAccess As Long) As Long
Public Declare Function RegisterHotKey Lib "user32" (ByVal hWnd As Long, ByVal id As Long, ByVal fsModifiers As Long, ByVal vk As Long) As Long
Public Declare Function SetWindowLong Lib "user32" Alias "SetWindowLongA" (ByVal hWnd As Long, ByVal nIndex As Long, ByVal dwNewLong As Long) As Long
Public Declare Function CreateProcess Lib "kernel32" Alias "CreateProcessA" (ByVal lpApplicationName As String, ByVal lpCommandLine As String, lpProcessAttributes As Long, lpThreadAttributes As Long, ByVal bInheritHandles As Long, ByVal dwCreationFlags As Long, lpEnvironment As Any, ByVal lpCurrentDriectory As String, lpStartupInfo As STARTUPINFO, lpProcessInformation As PROCESS_INFORMATION) As Long
Public Declare Function CallWindowProc Lib "user32" Alias "CallWindowProcA" (ByVal lpPrevWndFunc As Long, ByVal hWnd As Long, ByVal Msg As Long, ByVal wParam As Long, ByVal lParam As Long) As Long
Public Const CCHDEVICENAME = 32
Public Const CCHFORMNAME = 32
Public Const MOD_CONTROL = &H2
Public Const WM_HOTKEY = &H312
Public Const GWL_WNDPROC = -4
Public Type STARTUPINFO
cb As Long
lpReserved As String
lpDesktop As String
lpTitle As String
dwX As Long
dwY As Long
dwXSize As Long
dwYSize As Long
dwXCountChars As Long
dwYCountChars As Long
dwFillAttribute As Long
dwFlags As Long
wShowWindow As Integer
cbReserved2 As Integer
lpReserved2 As Long
hStdInput As Long
hStdOutput As Long
hStdError As Long
End Type
Public Type PROCESS_INFORMATION
hProcess As Long
hThread As Long
dwProcessId As Long
dwThreadId As Long
End Type
Public Type DEVMODE
dmDeviceName As String * CCHDEVICENAME
dmSpecVersion As Integer
dmDriverVersion As Integer
dmSize As Integer
dmDriverExtra As Integer
dmFields As Long
dmOrientation As Integer
dmPaperSize As Integer
dmPaperLength As Integer
dmPaperWidth As Integer
dmScale As Integer
dmCopies As Integer
dmDefaultSource As Integer
dmPrintQuality As Integer
dmColor As Integer
dmDuplex As Integer
dmYResolution As Integer
dmTTOption As Integer
dmCollate As Integer
dmFormName As String * CCHFORMNAME
dmUnusedPadding As Integer
dmBitsPerPel As Long
dmPelsWidth As Long
dmPelsHeight As Long
dmDisplayFlags As Long
dmDisplayFrequency As Long
End Type
Public Type SECURITY_ATTRIBUTES
nLength As Long
lpSecurityDescriptor As Long
bInheritHandle As Long
End Type
Public Const GENERIC_ALL = &H10000000
Public Const DESKTOP_SWITCHDESKTOP = &H100
Public Const DESKTOP_CREATEMENU = &H4&
Public Const DESKTOP_CREATEWINDOW = &H2&
Public Const DESKTOP_ENUMERATE = &H40&
Public Const DESKTOP_HOOKCONTROL = &H8&
Public Const DESKTOP_JOURNALPLAYBACK = &H20&
Public Const DESKTOP_JOURNALRECORD = &H10&
Public Const DESKTOP_READOBJECTS = &H1&
Public Const DESKTOP_WRITEOBJECTS = &H80&
Public Const DESKTOP_ALL = 511
Public Const MAXIMUM_ALLOWED = &H2000000
Public lpOldWinProc As Long
Public g_hDesktopThreadOld As Long
Public g_hDesktopNew As Long, g_hDesktopNameNew As String
Function myWindowProc(ByVal hWnd As Long, ByVal uMsg As Long, ByVal wParam As Long, ByVal lParam As Long) As Long
If uMsg = WM_HOTKEY Then
If wParam = 2 And g_hDesktopNew <> 0 Then
SwitchDesktop g_hDesktopNew
startExplorer ("explorer.exe")
End If
If wParam = 1 Then
SwitchDesktop g_hDesktopThreadOld
End If
End If
myWindowProc = CallWindowProc(lpOldWinProc, hWnd, uMsg, wParam, lParam)
End Function
Public Sub startExplorer(str As String)
Dim sui As STARTUPINFO, pi As PROCESS_INFORMATION
sui.cb = Len(sui)
sui.lpDesktop = g_hDesktopNameNew
CreateProcess vbNullString, str, ByVal 0&, ByVal 0&, 1, &H4000000 Or &H800, ByVal 0&, vbNullString, sui, pi
End Sub
是不是有点意思呢?