我想创建一个允许用户在不同的Windows 10桌面上拥有不同图标的应用程序。我可以使用Window Station and Desktop functions和Virtual Desktop Shell Interface来处理虚拟桌面的切换。所以现在我知道如何检测桌面已经切换,我需要尽快更改桌面用户文件夹的位置。
我知道在用户界面中有两种方法:
A)通过用户文件夹'特性
%HomePath%/Desktop
B)通过注册表
Desktop
中的HKCU\Software\Microsoft\Windows\CurrentVersion\Explorer\User Shell Folders
更改为新地址
如果对于重新编写部分,B选项对于程序设计解决方案是理想的选择。正如你当然可以理解的那样,这是一个破坏者。
答案 0 :(得分:0)
下面的VB.Net代码将保存Windows注册表中所有打开的桌面文件夹位置和大小,并根据需要进行恢复。从命令行或批处理文件运行。要保存文件夹属性,请添加“设置”(无引号)参数,以便还原,无参数。
Option Explicit On
Imports System.Text
Public Class FixFolders
Structure RECT
Dim Left As Integer
Dim Top As Integer
Dim Right As Integer
Dim Bottom As Integer
End Structure
Structure POINTAPI
Dim x As Integer
Dim y As Integer
End Structure
Structure WINDOWPLACEMENT
Dim length As Integer
Dim flags As Integer
Dim showCmd As Integer
Dim ptMinPosition As POINTAPI
Dim ptMaxPosition As POINTAPI
Dim rcNormalPosition As RECT
End Structure
Private Structure TDeskTopWindow
Dim lhwnd As Integer
Dim WinTitle As String
Dim WinRect As RECT
End Structure
Private Declare Function GetWindowRect Lib "user32" Alias "GetWindowRect" (ByVal hwnd As Integer, ByRef lpRect As RECT) As Integer
Declare Function MoveWindow Lib "user32" (ByVal hwnd As Int32, ByVal x As Int32, ByVal y As Int32, ByVal nWidth As Int32, ByVal nHeight As Int32, ByVal bRepaint As Int32) As Int32
Declare Function GetDesktopWindow Lib "user32" () As Int32
Declare Function GetClassName Lib "user32" Alias "GetClassNameA" (ByVal hwnd As Int32, ByVal lpClassName As String, ByVal nMaxCount As Int32) As Int32
Private Delegate Function EnumChildWindowsCallback(ByVal hWnd As IntPtr, ByVal lParam As IntPtr) As Boolean
Private Declare Function EnumChildWindows Lib "user32" (ByVal hWnd As IntPtr, ByVal lpEnumFunc As EnumChildWindowsCallback, ByVal lParam As IntPtr) As Boolean
Private Delegate Function EnumWindowsProcDelegate(ByVal hWnd As IntPtr, ByVal lParam As IntPtr) As Boolean
Private Declare Function EnumWindows Lib "user32" (ByVal lpEnumFunc As EnumWindowsProcDelegate, ByVal lParam As IntPtr) As Boolean
Private Declare Auto Function GetWindowText Lib "user32" (ByVal hWnd As IntPtr, ByVal lpString As StringBuilder, ByVal nMaxCount As Integer) As Integer
Private Declare Function SetFocusAPI Lib "user32" Alias "SetFocus" (ByVal hwnd As Int32) As Int32
Private Declare Function SetWindowPlacement Lib "user32" (ByVal hwnd As Integer, ByRef lpwndpl As WINDOWPLACEMENT) As Integer
Private Declare Function SetForegroundWindow Lib "user32" (ByVal hwbd As Int32) As Int32
'Private Declare Function FlashWindow Lib "User32" (ByVal hWnd As Int32, ByVal Invert As Int32) As Int32
Private Declare Function SetActiveWindow Lib "User32" (ByVal hWnd As Int32) As Int32
Private Shared lpwndplNew As WINDOWPLACEMENT
Private Const SW_SHOWMINIMIZED As Short = 2
Private Const SW_SHOWMAXIMIZED As Short = 3
Private Const SW_SHOWNORMAL As Short = 1
Private Shared Mode As String
Private WindowArray() As String
Private Shared DeskTopWindows() As TDeskTopWindow, DTWinIndex As Integer
Public Shared Sub Main()
Dim left, Right, Top, Bottom As Integer
Dim DTWinIndex As Integer
Dim RetVal1, RetVal2, RetVal3, TimeOut As Integer
Mode = Command()
GetDeskTopFolderWindows()
For DTWinIndex = 0 To DeskTopWindows.GetUpperBound(0)
Select Case Mode
Case ""
With DeskTopWindows(DTWinIndex)
'If it' s not there, put it in
If GetSetting("FixFolders", .WinTitle, "Left") = "" Then
SaveSetting("FixFolders", .WinTitle, "Left", .WinRect.Left.ToString)
SaveSetting("FixFolders", .WinTitle, "Right", .WinRect.Right.ToString)
SaveSetting("FixFolders", .WinTitle, "Top", .WinRect.Top.ToString)
SaveSetting("FixFolders", .WinTitle, "Bottom", .WinRect.Bottom.ToString)
End If
left = Val(GetSetting("FixFolders", .WinTitle, "Left"))
Right = Val(GetSetting("FixFolders", .WinTitle, "Right"))
Top = Val(GetSetting("FixFolders", .WinTitle, "Top"))
Bottom = Val(GetSetting("FixFolders", .WinTitle, "Bottom"))
While .WinRect.Bottom <> Bottom Or .WinRect.Left <> left Or .WinRect.Right <> Right Or .WinRect.Top <> Top
'RetVal1 = SetForegroundWindow(lhWnd)
RetVal2 = SetWindowPlacement(.lhwnd, lpwndplNew) 'This 'restores' the window if minimized
RetVal3 = MoveWindow(.lhwnd, left, Top, Right - left, Bottom - Top, True)
' Log.WriteLine(Now.TimeOfDay.ToString.Substring(0, 8) & " Set " & .WinTitle)
RetVal1 = GetWindowRect(.lhwnd, .WinRect) ' get current size
TimeOut += 1
If TimeOut > 1 And TimeOut < 10 Then Threading.Thread.Sleep(1000)
End While
End With
Case "Set"
With DeskTopWindows(DTWinIndex)
SaveSetting("FixFolders", .WinTitle, "Left", .WinRect.Left.ToString)
SaveSetting("FixFolders", .WinTitle, "Right", .WinRect.Right.ToString)
SaveSetting("FixFolders", .WinTitle, "Top", .WinRect.Top.ToString)
SaveSetting("FixFolders", .WinTitle, "Bottom", .WinRect.Bottom.ToString)
End With
End Select
Next
End Sub
Private Shared Sub GetDeskTopFolderWindows()
Dim lhwnd As Integer, lParam As IntPtr
DTWinIndex = -1
lhwnd = GetDesktopWindow() ' Find the Desktop's Child Windows
EnumChildWindows(lhwnd, AddressOf EnumChildProc, lParam)
End Sub
Shared Function EnumChildProc(ByVal lhWnd As IntPtr, ByVal lParam As IntPtr) As Boolean
Dim RetVal1 As Int32
Dim WinClassBuf As String
Dim WinTitleBuf As New StringBuilder(256)
Dim WinClass As String
Dim WinRect As RECT
WinClassBuf = New String(Chr(0), 256)
WinTitleBuf.Append(Chr(0), 256)
RetVal1 = GetClassName(lhWnd, WinClassBuf, WinClassBuf.Length)
WinClass = WinClassBuf.ToString
WinClass = StripNulls(WinClassBuf) ' remove extra Nulls & spaces
If WinClass = "CabinetWClass" Or WinClass = "ExploreWClass" Then ' TextBox Window
DTWinIndex += 1
ReDim Preserve DeskTopWindows(DTWinIndex)
DeskTopWindows(DTWinIndex).lhwnd = lhWnd
GetWindowText(lhWnd, WinTitleBuf, WinTitleBuf.Capacity)
DeskTopWindows(DTWinIndex).WinTitle = WinTitleBuf.ToString
RetVal1 = GetWindowRect(lhWnd, WinRect) ' get current size
DeskTopWindows(DTWinIndex).WinRect = WinRect
End If
EnumChildProc = True
End Function
Public Shared Function StripNulls(ByVal OriginalStr As String) As String
' This removes the extra Nulls so String comparisons will work
If (InStr(OriginalStr, Chr(0)) > 0) Then
'OriginalStr = Left(OriginalStr, InStr(OriginalStr, Chr(0)) - 1)
OriginalStr = OriginalStr.Substring(0, OriginalStr.IndexOf(Chr(0)))
End If
StripNulls = OriginalStr
End Function
End Class