forked from lee-soft/ViStart
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathJumpListHelper.bas
299 lines (222 loc) · 8.95 KB
/
JumpListHelper.bas
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
Attribute VB_Name = "MRUHelper"
Option Explicit
Private Const EXPLORER_RECENTDOCS As String = "Software\Microsoft\Windows\CurrentVersion\Explorer\RecentDocs"
Private Const EXPLORER_OPENSAVEDOCS_XP As String = "Software\Microsoft\Windows\CurrentVersion\Explorer\ComDlg32\OpenSaveMRU"
Private Const EXPLORER_OPENSAVEDOCS_VISTA As String = "Software\Microsoft\Windows\CurrentVersion\Explorer\ComDlg32\OpenSavePidlMRU"
Private EXPLORER_OPENSAVEDOCS As String
Private m_logger As SeverityLogger
Private Property Get Logger() As SeverityLogger
If m_logger Is Nothing Then
Set m_logger = LogManager.GetLogger("MRUHelper")
End If
Set Logger = m_logger
End Property
Function SetOpenSaveDocs()
EXPLORER_OPENSAVEDOCS = EXPLORER_OPENSAVEDOCS_XP
If Registry.CurrentUser.OpenSubKey(EXPLORER_OPENSAVEDOCS) Is Nothing Then
EXPLORER_OPENSAVEDOCS = EXPLORER_OPENSAVEDOCS_VISTA
End If
End Function
Public Function GetMRUListForKey(ByRef srcMRURoot As RegistryKey) As String()
On Error Resume Next
Dim s_mruList As String
Dim thisMRU
Dim thisMRUValue As String
Dim thisLnkName As String
Dim endFileNamePos As Long
Dim MRUList() As String
Dim lnkFileName As String
Dim MRUArrayIndex As Long
If srcMRURoot Is Nothing Then Exit Function
s_mruList = srcMRURoot.GetValue("MRUList")
While LenB(s_mruList) > 0
thisMRU = MidB$(s_mruList, 1, 2)
s_mruList = MidB$(s_mruList, LenB(thisMRU) + 1)
If LenB(thisMRU) = 2 Then
thisMRUValue = srcMRURoot.GetValue(CStr(thisMRU))
lnkFileName = thisMRUValue
If FileExists(lnkFileName) Then
ReDim Preserve MRUList(MRUArrayIndex)
MRUList(MRUArrayIndex) = lnkFileName
MRUArrayIndex = MRUArrayIndex + 1
End If
End If
Wend
s_mruList = srcMRURoot.GetValue("MRUListEx")
While LenB(s_mruList) > 0
thisMRU = MidB$(s_mruList, 1, 4)
s_mruList = MidB$(s_mruList, 5)
thisMRU = GetDWord(CStr(thisMRU))
If thisMRU > -1 Then
thisMRUValue = srcMRURoot.GetValue(CStr(thisMRU))
endFileNamePos = 1
'Chr$(0) is actually a double byte ZERO ChrB(0) is a single byte
'Remember strings are double-byte in VB6
endFileNamePos = InStrB(thisMRUValue, Chr$(0))
If endFileNamePos > 1 Then
thisLnkName = MidB$(thisMRUValue, 1, endFileNamePos)
If Len(thisLnkName) > 3 Then
If Not (Right$(thisLnkName, 4) = ".lnk") And InStr(thisLnkName, ".") > 0 Then
If FileExists(Environ$("userprofile") & "\Recent\" & Left$(thisLnkName, InStrRev(thisLnkName, ".") - 1) & ".lnk") Then
thisLnkName = Left$(thisLnkName, InStrRev(thisLnkName, ".") - 1) & ".lnk"
Else
thisLnkName = thisLnkName & ".lnk"
End If
End If
End If
lnkFileName = ResolveLink(Environ$("userprofile") & "\Recent\" & thisLnkName)
If FileExists(lnkFileName) Then
ReDim Preserve MRUList(MRUArrayIndex)
MRUList(MRUArrayIndex) = lnkFileName
MRUArrayIndex = MRUArrayIndex + 1
End If
End If
End If
Wend
Err.Clear
GetMRUListForKey = MRUList
Handler:
Logger.Error Err.Description, "GetMRUListForKey"
Err.Clear
End Function
Public Function GetImageJumpList(ByVal srcImagePath As String) As JumpList
'On Error GoTo Handler
Dim r_recentDocs As RegistryKey
Dim r_openSaveDocs As RegistryKey
Dim thisTypeNameColItem As Variant
Dim thisTypeName As String
Dim thisImagePath As String
Dim setJumpList As Boolean
Dim thisJumpList As New JumpList
Set GetImageJumpList = thisJumpList
srcImagePath = UCase$(StrEnd(srcImagePath, "\"))
If Len(srcImagePath) = 0 Then Exit Function
Set r_openSaveDocs = Registry.CurrentUser.OpenSubKey(EXPLORER_OPENSAVEDOCS)
Set r_recentDocs = Registry.CurrentUser.OpenSubKey(EXPLORER_RECENTDOCS)
thisJumpList.ImageName = srcImagePath
srcImagePath = UCase$(srcImagePath)
For Each thisTypeNameColItem In r_recentDocs.GetSubKeyNames
thisTypeName = CStr(thisTypeNameColItem)
If ExistInStringArray(GetTypeHandlersImageName(thisTypeName), srcImagePath) Then
thisJumpList.AddMRURegKey r_recentDocs.OpenSubKey(thisTypeName)
setJumpList = True
End If
Next
For Each thisTypeNameColItem In r_openSaveDocs.GetSubKeyNames
thisTypeName = CStr(thisTypeNameColItem)
If ExistInStringArray(GetTypeHandlersImageName(thisTypeName), srcImagePath) Then
thisJumpList.AddMRURegKey r_openSaveDocs.OpenSubKey(thisTypeName)
setJumpList = True
End If
Next
Exit Function
Handler:
Logger.Error Err.Description, "GetImageJumpList", srcImagePath
End Function
Public Function GetTypeHandlersImageName(srcType As String) As String()
On Error GoTo Handler
Dim thisKey As RegistryKey
Dim primaryCommand As String
Dim theChars() As Byte
Dim theCharIndex As Long
Dim returnHandlers() As String
GetTypeHandlersImageName = returnHandlers
If Left$(srcType, 1) <> "." Then srcType = "." & srcType
Set thisKey = Registry.CurrentUser.OpenSubKey("Software\Microsoft\Windows\CurrentVersion\Explorer\FileExts\" & srcType & "\OpenWithList")
If thisKey Is Nothing Then
Logger.Error "Unable to open registry key", "GetTypeHandlersImageName", srcType
Exit Function
End If
theChars = StrConv(thisKey.GetValue("MRUList"), vbFromUnicode)
For theCharIndex = LBound(theChars) To UBound(theChars)
ReDim Preserve returnHandlers(theCharIndex)
returnHandlers(theCharIndex) = thisKey.GetValue(Chr$(theChars(theCharIndex)))
Next
GetTypeHandlersImageName = returnHandlers
Exit Function
Handler:
Logger.Error Err.Description, "GetTypeHandlersImageName", srcType
End Function
Public Function GetTypeHandlerPath(ByVal srcType As String) As String
Dim thisKey As RegistryKey
Dim typeFullName As String
Dim primaryCommand As String
On Error GoTo HandleInvalidSubKey
Set thisKey = Registry.ClassesRoot.OpenSubKey(srcType)
typeFullName = thisKey.GetValue("")
Set thisKey = Registry.ClassesRoot.OpenSubKey(typeFullName & "\shell")
primaryCommand = thisKey.GetValue("")
If primaryCommand = "" Then primaryCommand = "open"
Set thisKey = Registry.ClassesRoot.OpenSubKey(typeFullName & "\shell\" & primaryCommand & "\command")
GetTypeHandlerPath = thisKey.GetValue("")
Exit Function
HandleInvalidSubKey:
Logger.Error Err.Description, "GetTypeHandlerPath", srcType
End Function
Public Function GetEXEPathFromQuote(ByVal srcPath As String)
On Error GoTo Handler
Dim A As Long
Dim b As Long
Dim spliceA As String
Dim spliceB As String
Dim ret As String
A = InStr(srcPath, """") + 1
b = InStr(A, srcPath, """")
If (A <> 2) Then
If (A > 1) Then
'would fetch path in this situation: C:\blabla\notepad.exe "%1"
GetEXEPathFromQuote = Trim$(Mid$(srcPath, 1, A - 2))
Exit Function
Else
'would fetch path in this situation: C:\blabla\notepad.exe %1
A = InStr(srcPath, "%") - 1
If A > 0 Then
GetEXEPathFromQuote = Left$(srcPath, A)
Else
GetEXEPathFromQuote = srcPath
End If
Exit Function
End If
End If
If (A > 1 And b > 0 And _
b > A) Then
GetEXEPathFromQuote = Mid$(srcPath, A, (b - A))
Exit Function
Else
A = InStr(srcPath, "%") - 1
If (A > 0) Then
GetEXEPathFromQuote = Mid$(srcPath, 1, A)
Exit Function
End If
End If
Exit Function
Handler:
GetEXEPathFromQuote = srcPath
End Function
'Replaces all enviromental variables with their absolute equivalents
'It doesn't require that a path be valid either
Public Function GetAbsolutePath(ByVal srcPath As String)
Dim A As Long
Dim b As Long
Dim varName As String
Dim spliceA As String
Dim spliceB As String
Dim ret As String
A = InStr(srcPath, "%") + 1
b = InStr(A, srcPath, "%")
If (A > 1 And b > 0 And _
b > A) Then
varName = Mid$(srcPath, A, (b - A))
spliceA = Mid$(srcPath, 1, A - 2)
spliceB = Mid$(srcPath, b + 1)
ret = spliceA & Environ$(varName) & spliceB
Else
GetAbsolutePath = srcPath
Exit Function
End If
If InStr(ret, "%") > 0 Then
GetAbsolutePath = GetAbsolutePath(ret)
Else
GetAbsolutePath = ret
End If
End Function