Blog. Just Blog

Добавление элементов и задач в Jump List приложения

Версия для печати Добавить в Избранное Отправить на E-Mail | Категория: Образ мышления: Assembler | Автор: ManHunter
Добавление элементов и задач в Jump List приложения
Добавление элементов и задач в Jump List приложения

Функция "Jump List" - список быстрого перехода - впервые появилась в Windows 7. Она создана для облегчения поиска нужных опций и ускорения выполнения наиболее частых операций для выбранного приложения. Списки быстрого перехода появляются при нажатии правой кнопкой мыши на значке приложения в панели задач. Большинство функций для работы с панелью задач я уже давным-давно разобрал, а про Jump List совсем забыл. Срочно исправляю ситуацию.

Как и в случае с другими функциями панели задач, тут тоже используются COM-объекты. А для работы с ними придется, как обычно, предварительно описать огромную пачку структур, GUID'ов, интерфейсов и констант.
  1. struct PROPVARIANT
  2.     vt        dw ?
  3.     wReserved rw 3
  4.     struct
  5.         lVal  dd ?
  6.     ends
  7.     decVal    dd ?
  8. ends
  9.  
  10. struct PROPKEY
  11.      fmtid rb 16
  12.      pid   dd ?
  13. ends
  14.  
  15. ; IID_ICustomDestinationList Interface
  16. struct ICustomDestinationList
  17.     ; IUnknown
  18.     QueryInterface         dd ?   ; 000h
  19.     AddRef                 dd ?   ; 004h
  20.     Release                dd ?   ; 008h
  21.     ; ICustomDestinationList
  22.     SetAppID               dd ?   ; 00Ch
  23.     BeginList              dd ?   ; 010h
  24.     AppendCategory         dd ?   ; 014h
  25.     AppendKnownCategory    dd ?   ; 018h
  26.     AddUserTasks           dd ?   ; 01Ch
  27.     CommitList             dd ?   ; 020h
  28.     GetRemovedDestinations dd ?   ; 024h
  29.     DeleteList             dd ?   ; 028h
  30.     AbortList              dd ?   ; 02Ch
  31. ends
  32.  
  33. ; IID_IObjectCollection Interface
  34. struct IObjectCollection
  35.     ; IUnknown
  36.     QueryInterface dd ?   ; 000h
  37.     AddRef         dd ?   ; 004h
  38.     Release        dd ?   ; 008h
  39.     ; IObjectCollection
  40.     GetCount       dd ?   ; 00Ch
  41.     GetAt          dd ?   ; 010h
  42.     AddObject      dd ?   ; 014h
  43.     AddFromArray   dd ?   ; 018h
  44.     RemoveObjectAt dd ?   ; 01Ch
  45.     Clear          dd ?   ; 020h
  46. ends
  47.  
  48. ; IID_IShellLinkW Interface
  49. struct IShellLinkW
  50.     ; IUnknown
  51.     QueryInterface      dd ?   ; 000h
  52.     AddRef              dd ?   ; 004h
  53.     Release             dd ?   ; 008h
  54.     ; IShellLinkW
  55.     GetPath             dd ?   ; 00Ch
  56.     GetIDList           dd ?   ; 010h
  57.     SetIDList           dd ?   ; 014h
  58.     GetDescription      dd ?   ; 018h
  59.     SetDescription      dd ?   ; 01Ch
  60.     GetWorkingDirectory dd ?   ; 020h
  61.     SetWorkingDirectory dd ?   ; 024h
  62.     GetArguments        dd ?   ; 028h
  63.     SetArguments        dd ?   ; 02Ch
  64.     GetHotkey           dd ?   ; 030h
  65.     SetHotkey           dd ?   ; 034h
  66.     GetShowCmd          dd ?   ; 038h
  67.     SetShowCmd          dd ?   ; 03Ch
  68.     GetIconLocation     dd ?   ; 040h
  69.     SetIconLocation     dd ?   ; 044h
  70.     SetRelativePath     dd ?   ; 048h
  71.     Resolve             dd ?   ; 04Ch
  72.     SetPath             dd ?   ; 050h
  73. ends
  74.  
  75. ; IID_IPropertyStore Interface
  76. struct IPropertyStore
  77.     ; IUnknown
  78.     QueryInterface dd ?   ; 000h
  79.     AddRef         dd ?   ; 004h
  80.     Release        dd ?   ; 008h
  81.     ; IPropertyStore
  82.     GetCount       dd ?   ; 00Ch
  83.     GetAt          dd ?   ; 010h
  84.     GetValue       dd ?   ; 014h
  85.     SetValue       dd ?   ; 018h
  86.     Commit         dd ?   ; 01Ch
  87. ends
  88.  
  89. ; GUID {77F10CF0-3DB5-4966-B520-B7C54FD35ED6}
  90. CLSID_DestinationList \
  91.     dd 077F10CF0h
  92.     dw 03DB5h
  93.     dw 04966h
  94.     db 0B5h, 020h, 0B7h, 0C5h, 04Fh, 0D3h, 05Eh, 0D6h
  95.  
  96. ; GUID {6332DEBF-87B5-4670-90C0-5E57B408A49E}
  97. IID_ICustomDestinationList \
  98.     dd 06332DEBFh
  99.     dw 087B5h
  100.     dw 04670h
  101.     db 090h, 0C0h, 05Eh, 057h, 0B4h, 008h, 0A4h, 09Eh
  102.  
  103. ; GUID {92CA9DCD-5622-4BBA-A805-5E9F541BD8C9}
  104. IID_IObjectArray \
  105.     dd 092CA9DCDh
  106.     dw 05622h
  107.     dw 04BBAh
  108.     db 0A8h, 005h, 05Eh, 09Fh, 054h, 01Bh, 0D8h, 0C9h
  109.  
  110. ; GUID {2D3468C1-36A7-43B6-AC24-D3F02FD9607A}
  111. CLSID_EnumerableObjectCollection \
  112.     dd 02D3468C1h
  113.     dw 036A7h
  114.     dw 043B6h
  115.     db 0ACh, 024h, 0D3h, 0F0h, 02Fh, 0D9h, 060h, 07Ah
  116.  
  117. ; GUID {5632B1A4-E38A-400A-928A-D4CD63230295}
  118. IID_IObjectCollection \
  119.     dd 05632B1A4h
  120.     dw 0E38Ah
  121.     dw 0400Ah
  122.     db 092h, 08Ah, 0D4h, 0CDh, 063h, 023h, 002h, 095h
  123.  
  124. ; GUID {00021401-0000-0000-C000-000000000046}
  125. CLSID_ShellLink \
  126.     dd 000021401h
  127.     dw 00000h
  128.     dw 00000h
  129.     db 0C0h, 000h, 000h, 000h, 000h, 000h, 000h, 046h
  130.  
  131. ; GUID {000214F9-0000-0000-C000-000000000046}
  132. IID_IShellLinkW \
  133.     dd 0000214F9h
  134.     dw 00000h
  135.     dw 00000h
  136.     db 0C0h, 000h, 000h, 000h, 000h, 000h, 000h, 046h
  137.  
  138. ; GUID {886D8EEB-8CF2-4446-8D02-CDBA1DBDCF99}
  139. IID_IPropertyStore \
  140.     dd 0886D8EEBh
  141.     dw 08CF2h
  142.     dw 04446h
  143.     db 08Dh, 002h, 0CDh, 0BAh, 01Dh, 0BDh, 0CFh, 099h
  144.  
  145. ; GUID {9F4C2855-9F79-4B39-A8D0-E1D42DE1D5F3}
  146. PKEY_AppUserModel_IsDestListSeparator \
  147.     dd 09F4C2855h
  148.     dw 09F79h
  149.     dw 04B39h
  150.     db 0A8h, 0D0h, 0E1h, 0D4h, 02Dh, 0E1h, 0D5h, 0F3h
  151. PKEY_AppUserModel_IsDestListSeparator_pid = 6
  152.  
  153. ; GUID {F29F85E0-4FF9-1068-AB91-08002B27B3D9}
  154. PKEY_Title \
  155.     dd 0F29F85E0h
  156.     dw 04FF9h
  157.     dw 01068h
  158.     db 0ABh, 091h, 008h, 000h, 02Bh, 027h, 0B3h, 0D9h
  159. PKEY_Title_pid = 2
  160.  
  161. CLSCTX_INPROC_SERVER = 1
  162. S_OK                 = 0
  163.  
  164. VT_I4     = 3
  165. VT_LPWSTR = 31
Доступ к списку быстрого перехода осуществляется через интерфейс ICustomDestinationList, но сперва надо вызвать функцию SetCurrentProcessExplicitAppUserModelID, чтобы назначить нашему приложению уникальный идентификатор, по которому в дальнейшем с приложением можно будет связать Jump List.

Дальше уже знакомая вам работа с объектами. Создаем объект списка, создаем нужное количество категорий, внутри них создаем объекты-ссылки с описанием действий, которые должны выполняться. Затем собираем это все вместе и применяем к приложению. Категории могут быть пользовательские с произвольным названием, одна стандартная категория с задачами и пара системных категорий с автоматическим заполнением, в которых будут отображаться элементы "Частые" или "Последние". В виде кода это выглядит примерно так:
  1.         ; Установить идентификатор пользовательской модели приложения
  2.         invoke  SetCurrentProcessExplicitAppUserModelID,szAppID
  3.  
  4.         ; Создать объект
  5.         invoke  CoCreateInstance,CLSID_DestinationList,NULL,\
  6.                 CLSCTX_INPROC_SERVER,\
  7.                 IID_ICustomDestinationList,pDestList
  8.  
  9.         ; Связать с нашим приложением через идентификатор
  10.         mov     eax, [pDestList]
  11.         mov     eax, [eax]
  12.         stdcall dword [eax+ICustomDestinationList.SetAppID],[pDestList],\
  13.                 szAppID
  14.  
  15.         ; Создать новый Jump List
  16.         mov     eax, [pDestList]
  17.         mov     eax, [eax]
  18.         stdcall dword [eax+ICustomDestinationList.BeginList],[pDestList],\
  19.                 dMaxSlots,IID_IObjectArray,pItems
  20.  
  21.         ; Создать коллекцию
  22.         invoke  CoCreateInstance,CLSID_EnumerableObjectCollection,NULL,\
  23.                 CLSCTX_INPROC_SERVER,\
  24.                 IID_IObjectCollection,pObjColl
  25.  
  26.         ; Имя файла нашего приложения для извлечения иконок
  27.         invoke  GetModuleFileName,NULL,szExePath,MAX_PATH
  28.  
  29.         ; Добавить задачи в коллекцию задач
  30.         stdcall AddTask,[pObjColl],szApp1,szDesc1,szTitle1,1
  31.         stdcall AddTask,[pObjColl],szApp2,szDesc2,szTitle2,2
  32.         stdcall AddSeparator,[pObjColl]
  33.         stdcall AddTask,[pObjColl],szApp3,szDesc3,szTitle3,3
  34.  
  35.         ; Добавить коллекцию задач в Jump List
  36.         mov     eax, [pDestList]
  37.         mov     eax, [eax]
  38.         stdcall dword [eax+ICustomDestinationList.AddUserTasks],[pDestList],\
  39.                 [pObjColl]
  40.  
  41.         ; Создать пользовательскую категорию
  42.         invoke  CoCreateInstance,CLSID_EnumerableObjectCollection,NULL,\
  43.                 CLSCTX_INPROC_SERVER,\
  44.                 IID_IObjectCollection,pCategory
  45.  
  46.         ; Добавить задачи в пользовательскую категорию
  47.         stdcall AddTask,[pCategory],szApp4,szDesc4,szTitle4,4
  48.         stdcall AddTask,[pCategory],szApp5,szDesc5,szTitle5,0
  49.  
  50.         ; Добавить пользовательскую категорию в Jump List
  51.         mov     eax, [pDestList]
  52.         mov     eax, [eax]
  53.         stdcall dword [eax+ICustomDestinationList.AppendCategory],[pDestList],\
  54.                 szCategory,[pCategory]
  55.  
  56.         ; Применить изменения
  57.         mov     eax, [pDestList]
  58.         mov     eax, [eax]
  59.         stdcall dword [eax+ICustomDestinationList.CommitList],[pDestList]
Чтобы немного сократить количество писанины, я вынес код для создания ссылок и разделителей в отдельные функции. Для еще большего упрощения я установил, что иконки будут браться из нашего же приложения. В реальном проекте это может быть не так, поэтому при необходимости подкорректируйте код вызова. Также здесь не учитывается возможность устанавливать параметры командной строки для добавляемых задач.
  1. ;-------------------------------------------------
  2. ; Добавить ссылку в категорию
  3. ;-------------------------------------------------
  4. proc AddTask dObj:DWORD,szApp:DWORD,szDesc:DWORD,szTitle:DWORD,dIcon:DWORD
  5.         pusha
  6.  
  7.         ; Создать ссылку
  8.         invoke  CoCreateInstance,CLSID_ShellLink,NULL,\
  9.                 CLSCTX_INPROC_SERVER,\
  10.                 IID_IShellLinkW,pLink
  11.  
  12.         ; Путь к запускаемому приложению
  13.         mov     eax, [pLink]
  14.         mov     eax, [eax]
  15.         stdcall dword [eax+IShellLinkW.SetPath],[pLink],\
  16.                 [szApp]
  17.  
  18.         ; Ссылка на файл с иконкой и ее номер в ресурсах
  19.         mov     eax, [pLink]
  20.         mov     eax, [eax]
  21.         stdcall dword [eax+IShellLinkW.SetIconLocation],[pLink],\
  22.                 szExePath,[dIcon]
  23.  
  24.         ; Текст всплывающей подсказки
  25.         mov     eax, [pLink]
  26.         mov     eax, [eax]
  27.         stdcall dword [eax+IShellLinkW.SetDescription],[pLink],\
  28.                 [szDesc]
  29.  
  30.         ; Заполнить название
  31.         mov     eax,[pLink]
  32.         mov     eax,[eax]
  33.         stdcall dword [eax+IShellLinkW.QueryInterface],[pLink],\
  34.                 IID_IPropertyStore,pPropStore
  35.  
  36.         mov     [pv.vt],VT_LPWSTR
  37.         mov     eax,[szTitle]
  38.         mov     [pv.lVal],eax
  39.  
  40.         mov     edi,prop.fmtid
  41.         mov     esi,PKEY_Title
  42.         movsd
  43.         movsd
  44.         movsd
  45.         movsd
  46.         mov     [prop.pid],PKEY_Title_pid
  47.  
  48.         ; Установить значение
  49.         mov     eax,[pPropStore]
  50.         mov     eax,[eax]
  51.         stdcall dword [eax+IPropertyStore.SetValue],[pPropStore],\
  52.                 prop,pv
  53.  
  54.         mov     eax,[pPropStore]
  55.         mov     eax,[eax]
  56.         stdcall dword [eax+IPropertyStore.Commit],[pPropStore]
  57.  
  58.         ; Добавить ссылку в коллекцию
  59.         mov     eax, [dObj]
  60.         mov     eax, [eax]
  61.         stdcall dword [eax+IObjectCollection.AddObject],[dObj],\
  62.                 [pLink]
  63.  
  64.         popa
  65.         ret
  66. endp
Следующая функция просто добавляет разделитель в указанную категорию. При использовании разделителей есть следующие особенности: разделитель не может находиться на первом или последнем месте в списке элементов категории, несколько последовательных разделителей будут схлопнуты в один.
  1. ;-------------------------------------------------
  2. ; Добавить разделитель
  3. ;-------------------------------------------------
  4. proc AddSeparator dObj:DWORD
  5.         pusha
  6.  
  7.         ; Создать ссылку
  8.         invoke  CoCreateInstance,CLSID_ShellLink,NULL,\
  9.                 CLSCTX_INPROC_SERVER,\
  10.                 IID_IShellLinkW,pLink
  11.  
  12.         mov     eax,[pLink]
  13.         mov     eax,[eax]
  14.         stdcall dword [eax+IShellLinkW.QueryInterface],[pLink],\
  15.                 IID_IPropertyStore,pPropStore
  16.  
  17.         mov     [pv.vt],VT_BOOL
  18.         mov     [pv.lVal],VT_TRUE
  19.  
  20.         mov     edi,prop.fmtid
  21.         mov     esi,PKEY_AppUserModel_IsDestListSeparator
  22.         movsd
  23.         movsd
  24.         movsd
  25.         movsd
  26.         mov     [prop.pid],PKEY_AppUserModel_IsDestListSeparator_pid
  27.  
  28.         mov     eax,[pPropStore]
  29.         mov     eax,[eax]
  30.         stdcall dword [eax+IPropertyStore.SetValue],[pPropStore],\
  31.                 prop,pv
  32.  
  33.         mov     eax,[pPropStore]
  34.         mov     eax,[eax]
  35.         stdcall dword [eax+IPropertyStore.Commit],[pPropStore]
  36.  
  37.         ; Добавить ссылку в коллекцию
  38.         mov     eax, [dObj]
  39.         mov     eax, [eax]
  40.         stdcall dword [eax+IObjectCollection.AddObject],[dObj],\
  41.                 [pLink]
  42.  
  43.         popa
  44.         ret
  45. endp
Ну и не забываем освобождать созданные объекты при выходе из приложения или в случае, когда они становятся ненужными.
  1.         ; Прибраться за собой
  2.         mov     eax, [pDestList]
  3.         mov     eax, [eax]
  4.         stdcall dword [eax+ICustomDestinationList.Release],[pDestList]
В приложении пример программы с исходным текстом, которая добавляет Jump List к своему ярлыку в панели задач.

Пример программы с исходным текстом (FASM)Пример программы с исходным текстом (FASM)

Jump.List.Demo.zip (11,713 bytes)


Поделиться ссылкой ВКонтакте
Просмотров: 646 | Комментариев: 0

Внимание! Статья опубликована больше года назад, информация могла устареть!

Комментарии

Отзывы посетителей сайта о статье
Комментариeв нет

Добавить комментарий

Заполните форму для добавления комментария
Имя*:
Текст комментария (не более 2000 символов)*:

*Все поля обязательны для заполнения.
Комментарии, содержащие рекламу, ненормативную лексику, оскорбления и т.п., а также флуд и сообщения не по теме, будут удаляться. Нарушителям может быть заблокирован доступ к сайту.
Наверх
Powered by PCL's Speckled Band Engine 0.2 RC3
© ManHunter / PCL, 2008-2024
При использовании материалов ссылка на сайт обязательна
Время генерации: 0.07 сек. / MySQL: 2 (0.0046 сек.) / Память: 4.5 Mb
Наверх