-
Notifications
You must be signed in to change notification settings - Fork 12
Expand file tree
/
Copy pathJumpListHelper.bas
More file actions
476 lines (288 loc) · 11.6 KB
/
JumpListHelper.bas
File metadata and controls
476 lines (288 loc) · 11.6 KB
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
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
Attribute VB_Name = "JumpListHelper"
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
Public Type ShellLink
szPath As String
szArguments As String
End Type
Public Function GetMRUListForKey(ByRef srcMRURoot As WinRegistryKey) 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
Debug.Print srcMRURoot.Path
If srcMRURoot Is Nothing Then Exit Function
s_mruList = srcMRURoot.GetValueAsString("MRUList")
If srcMRURoot.GetLastError = 0 Then
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.GetValueAsString(CStr(thisMRU))
lnkFileName = thisMRUValue
Debug.Print lnkFileName
If FileExists(lnkFileName) Then
ReDim Preserve MRUList(MRUArrayIndex)
MRUList(MRUArrayIndex) = lnkFileName
MRUArrayIndex = MRUArrayIndex + 1
End If
End If
Wend
Else
s_mruList = srcMRURoot.GetValueAsString("MRUListEx")
While LenB(s_mruList) > 0
thisMRU = MidB(s_mruList, 1, 4)
s_mruList = MidB(s_mruList, LenB(thisMRU) + 1)
thisMRU = GetDWord(thisMRU)
If thisMRU > -1 Then
Debug.Print thisMRU
thisMRUValue = srcMRURoot.GetValueAsString(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
While (Mid(thisMRUValue, endFileNamePos, 1) <> Chr(0)) And endFileNamePos < Len(thisMRUValue)
endFileNamePos = endFileNamePos + 1
Wend
If endFileNamePos > 1 Then
thisLnkName = Mid(thisMRUValue, 1, endFileNamePos - 1)
If Len(thisLnkName) > 3 Then
If Not (Right(thisLnkName, 4) = ".lnk") And InStr(thisLnkName, ".") > 0 Then
'lnkFileName = Left(lnkFileName, InStrRev(lnkFileName, ".") - 1) & ".lnk"
thisLnkName = thisLnkName & ".lnk"
End If
End If
Debug.Print thisLnkName
lnkFileName = GetShortcut(Environ("userprofile") & "\Recent\" & thisLnkName).szPath
If FileExists(lnkFileName) Then
ReDim Preserve MRUList(MRUArrayIndex)
MRUList(MRUArrayIndex) = lnkFileName
MRUArrayIndex = MRUArrayIndex + 1
End If
End If
End If
Wend
End If
GetMRUListForKey = MRUList
End Function
Function SetOpenSaveDocs()
Dim thisType As New WinRegistryKey
thisType.RootKeyType = HKEY_CURRENT_USER
EXPLORER_OPENSAVEDOCS = EXPLORER_OPENSAVEDOCS_XP
thisType.Path = EXPLORER_OPENSAVEDOCS
If thisType.GetLastError <> 0 Then
EXPLORER_OPENSAVEDOCS = EXPLORER_OPENSAVEDOCS_VISTA
End If
End Function
Public Function GetShortcut(lnkSrcFile As String) As ShellLink
On Error GoTo Handler
Dim objShell
Dim objFolder
Dim sFileName As String
Dim sParentFolder As String
Dim returnData As ShellLink
sFileName = StrEnd(lnkSrcFile, "\")
sParentFolder = Left(lnkSrcFile, Len(lnkSrcFile) - Len(sFileName) - 1)
Set objShell = CreateObject("Shell.Application")
Set objFolder = objShell.NameSpace(sParentFolder & "\")
If (Not objFolder Is Nothing) Then
Dim objFolderItem
Set objFolderItem = objFolder.ParseName(sFileName)
If (Not objFolderItem Is Nothing) Then
Dim objShellLink
Set objShellLink = objFolderItem.GetLink
If (Not objShellLink Is Nothing) Then
returnData.szArguments = objShellLink.Arguments
returnData.szPath = objShellLink.Path
GetShortcut = returnData
End If
Set objShellLink = Nothing
End If
Set objFolderItem = Nothing
End If
Set objFolder = Nothing
Set objShell = Nothing
Exit Function
Handler:
End Function
Public Function isLnkTargetValid(sPath As String) As Boolean
On Error GoTo AssumeYes
Dim objShell
Dim objFolder
Dim sFileName As String
Dim sParentFolder As String
sFileName = StrEnd(sPath, "\")
sParentFolder = Left(sPath, Len(sPath) - Len(sFileName) - 1)
If Not (Right(sFileName, 4) = ".lnk") And InStr(sFileName, ".") > 0 Then
sFileName = Left(sFileName, InStrRev(sFileName, ".") - 1) & ".lnk"
End If
Set objShell = CreateObject("Shell.Application")
Set objFolder = objShell.NameSpace(sParentFolder & "\")
If (Not objFolder Is Nothing) Then
Dim objFolderItem
Set objFolderItem = objFolder.ParseName(sFileName)
If (Not objFolderItem Is Nothing) Then
Dim objShellLink
Set objShellLink = objFolderItem.GetLink
If (Not objShellLink Is Nothing) Then
isLnkTargetValid = FileExists(objShellLink.Path)
End If
Set objShellLink = Nothing
End If
Set objFolderItem = Nothing
End If
Set objFolder = Nothing
Set objShell = Nothing
Exit Function
AssumeYes:
isLnkTargetValid = True
End Function
Public Function BuildMenuWithoutJumpList() As clsMenu
Dim srcMenu As New clsMenu
srcMenu.AddItem 1, "Minimize"
srcMenu.AddItem 2, "Restore"
srcMenu.AddSeperater
srcMenu.AddItem 5, "Pin"
srcMenu.AddItem 4, "Close All Windows"
Set BuildMenuWithoutJumpList = srcMenu
End Function
Public Function BuildMenuWithJumpList(srcCompletePaths)
Dim thisItem As String
Dim srcMenu As New clsMenu
Dim jumpListIndex As Long
Dim jumpListMax As Long
If IsArrayInitialized(srcCompletePaths) Then
jumpListMax = sizeOf(srcCompletePaths)
If jumpListMax > JUMPLIST_CAP Then
jumpListMax = JUMPLIST_CAP
End If
For jumpListIndex = 0 To jumpListMax
srcMenu.AddItem 7 + jumpListIndex, StrEnd(CStr(srcCompletePaths(jumpListIndex)), "\")
Next
srcMenu.AddSeperater
End If
srcMenu.AddItem 1, "Minimize"
srcMenu.AddItem 2, "Restore"
srcMenu.AddSeperater
srcMenu.AddItem 5, "Pin"
srcMenu.AddItem 4, "Close All Windows"
Set BuildMenuWithJumpList = srcMenu
End Function
Public Function GetImageJumpList(ByVal srcImagePath As String) As JumpList
Dim r_recentDocs As New WinRegistryKey
Dim r_openSaveDocs As New WinRegistryKey
Dim thisType As WinRegistryKey
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
r_openSaveDocs.RootKeyType = HKEY_CURRENT_USER
r_openSaveDocs.Path = EXPLORER_OPENSAVEDOCS
r_recentDocs.RootKeyType = HKEY_CURRENT_USER
r_recentDocs.Path = EXPLORER_RECENTDOCS
thisJumpList.ImageName = srcImagePath
srcImagePath = UCase(srcImagePath)
If isset(r_recentDocs.SubKeys) Then
For Each thisType In r_recentDocs.SubKeys
thisImagePath = UCase(StrEnd(Trim(GetEXEPathFromQuote(GetAbsolutePath(GetTypeHandlerPath(thisType.Name)))), "\"))
If thisImagePath = srcImagePath Then
thisJumpList.AddMRURegKey thisType
setJumpList = True
End If
Next
End If
If isset(r_openSaveDocs.SubKeys) Then
For Each thisType In r_openSaveDocs.SubKeys
thisImagePath = UCase(StrEnd(Trim(GetEXEPathFromQuote(GetAbsolutePath(GetTypeHandlerPath("." & thisType.Name)))), "\"))
If thisImagePath = srcImagePath Then
thisJumpList.AddMRURegKey thisType
setJumpList = True
End If
Next
End If
End Function
Private Function GetTypeHandlerPath(srcType As String)
Dim thisKey As New WinRegistryKey
Dim typeFullName As String
Dim primaryCommand As String
thisKey.RootKeyType = HKEY_CLASSES_ROOT
thisKey.Path = srcType
typeFullName = thisKey.GetValueAsString()
thisKey.Path = typeFullName & "\shell"
primaryCommand = thisKey.GetValueAsString()
If primaryCommand = "" Then primaryCommand = "open"
thisKey.Path = typeFullName & "\shell\" & primaryCommand & "\command"
GetTypeHandlerPath = thisKey.GetValueAsString
'Debug.Print srcType & "::" & GetTypeHandlerPath
End Function
Public Function GetEXEPathFromQuote(ByVal srcPath As String)
On Error GoTo Handler
Dim a As Long
Dim b As Long
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