Blog. Just Blog

Как получить список ярлыков на рабочем столе

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

Если вы интересуетесь компьютерами и любите порядок в своем электронном хозяйстве, то наверняка встречали программы для сохранения и восстановления позиций ярлыков на рабочем столе. Судя по многочисленным отзывам пользователей на различных софтовых порталах и форумах, такие программы действительно востребованы. Давайте посмотрим, каким образом можно получить список и позиции ярлыков рабочего стола.

Начинаем с определения структур и констант, которые нам понадобятся для дальнейшей работы, но про которые FASM ничего не знает.
  1. struct DECIMAL
  2.     wReserved dw ?
  3.     union
  4.         struct
  5.             scale db ?
  6.             sign db ?
  7.         ends
  8.         signscale dw ?
  9.     ends
  10.     Hi32 dd ?
  11.     union
  12.         struct
  13.             Lo32 dd ?
  14.             Mid32 dd ?
  15.         ends
  16.         Lo64 dq ?
  17.     ends
  18. ends
  19.  
  20. struct VARIANT
  21.     union
  22.         struct
  23.             vt dw ?
  24.             wReserved rw 3
  25.             union
  26.                 llVal dq ?
  27.                 lVal  dd ?
  28.                 iVal  dw ?
  29.                 bVal  db ?
  30.             ends
  31.         ends
  32.         decVal DECIMAL
  33.     ends
  34. ends
  35.  
  36. struct STRRET
  37.     uType dd ?
  38.     union
  39.         pOleStr dd ?
  40.         uOffset dd ?
  41.         cStr    rb 260
  42.     ends
  43. ends
  44.  
  45. CLSCTX_INPROC_SERVER  = 0x01
  46. CLSCTX_INPROC_HANDLER = 0x02
  47. CLSCTX_LOCAL_SERVER   = 0x04
  48. CLSCTX_REMOTE_SERVER  = 0x10
  49.  
  50. CLSCTX_SERVER = CLSCTX_INPROC_SERVER + CLSCTX_LOCAL_SERVER\
  51.                 + CLSCTX_REMOTE_SERVER
  52. CLSCTX_ALL    = CLSCTX_INPROC_HANDLER + CLSCTX_SERVER
  53. S_OK          = 0
  54.  
  55. SWC_DESKTOP     = 8
  56. SWFO_NEEDDISPATCH = 1
  57. CSIDL_DESKTOP   = 0x0000
  58. SVGIO_ALLVIEW   = 2
  59. SHGDN_NORMAL    = 0
  60.  
  61. VT_EMPTY            = 0
  62. VT_NULL             = 1
  63. VT_I2               = 2
  64. VT_I4               = 3
  65. VT_R4               = 4
  66. VT_R8               = 5
  67. VT_CY               = 6
  68. VT_DATE             = 7
  69. VT_BSTR             = 8
  70. VT_DISPATCH         = 9
  71. VT_ERROR            = 10
  72. VT_BOOL             = 11
  73. VT_VARIANT          = 12
  74. VT_UNKNOWN          = 13
  75. VT_DECIMAL          = 14
  76. VT_I1               = 16
  77. VT_UI1              = 17
  78. VT_UI2              = 18
  79. VT_UI4              = 19
  80. VT_I8               = 20
  81. VT_UI8              = 21
  82. VT_INT              = 22
  83. VT_UINT             = 23
  84. VT_VOID             = 24
  85. VT_HRESULT          = 25
  86. VT_PTR              = 26
  87. VT_SAFEARRAY        = 27
  88. VT_CARRAY           = 28
  89. VT_USERDEFINED      = 29
  90. VT_LPSTR            = 30
  91. VT_LPWSTR           = 31
  92. VT_RECORD           = 36
  93. VT_INT_PTR          = 37
  94. VT_UINT_PTR         = 38
  95. VT_FILETIME         = 64
  96. VT_BLOB             = 65
  97. VT_STREAM           = 66
  98. VT_STORAGE          = 67
  99. VT_STREAMED_OBJECT  = 68
  100. VT_STORED_OBJECT    = 69
  101. VT_BLOB_OBJECT      = 70
  102. VT_CF               = 71
  103. VT_CLSID            = 72
  104. VT_VERSIONED_STREAM = 73
  105. VT_BSTR_BLOB        = 0x0FFF
  106. VT_VECTOR           = 0x1000
  107. VT_ARRAY            = 0x2000
  108. VT_BYREF            = 0x4000
  109. VT_RESERVED         = 0x8000
  110. VT_ILLEGAL          = 0xFFFF
  111. VT_ILLEGALMASKED    = 0x0FFF
  112. VT_TYPEMASK         = 0x0FFF
Теперь GUID для работы с COM-объектами и интерфейсы этих объектов. Я реально задолбался собирать это все по интернету, хорошо, что этим приходится заниматься только один раз, потом можно будет использовать готовые решения.
  1. ; GUID {9BA05972-F6A8-11CF-A442-00A0C90A8F39}
  2. CLSID_ShellWindows      dd 09BA05972h
  3.                         dw 0F6A8h
  4.                         dw 011CFh
  5.                         db 0A4h, 042h, 000h, 0A0h, 0C9h, 00Ah, 08Fh, 039h
  6.  
  7. ; GUID {85CB6900-4D95-11CF-960C-0080C7F4EE85}
  8. IID_IShellWindows       dd 085CB6900h
  9.                         dw 04D95h
  10.                         dw 011CFh
  11.                         db 096h, 00Ch, 000h, 080h, 0C7h, 0F4h, 0EEh, 085h
  12.  
  13. ; GUID {4C96BE40-915C-11CF-99D3-00AA004AE837}
  14. CLSID_STopLevelBrowser  dd 04C96BE40h
  15.                         dw 0915Ch
  16.                         dw 011CFh
  17.                         db 099h, 0D3h, 000h, 0AAh, 000h, 04Ah, 0E8h, 037h
  18.  
  19. ; GUID {000214E2-0000-0000-C000-000000000046}
  20. IID_IShellBrowser       dd 0000214E2h
  21.                         dw 00000h
  22.                         dw 00000h
  23.                         db 0C0h, 000h, 000h, 000h, 000h, 000h, 000h, 046h
  24.  
  25. ; GUID {CDE725B0-CCC9-4519-917E-325D72FAB4CE}
  26. IID_IFolderView         dd 0CDE725B0h
  27.                         dw 0CCC9h
  28.                         dw 04519h
  29.                         db 091h, 07Eh, 032h, 05Dh, 072h, 0FAh, 0B4h, 0CEh
  30.  
  31. ; GUID {000214E6-0000-0000-C000-000000000046}
  32. IID_IShellFolder        dd 0000214E6h
  33.                         dw 00000h
  34.                         dw 00000h
  35.                         db 0C0h, 000h, 000h, 000h, 000h, 000h, 000h, 046h
  36.  
  37. ; GUID {000214F2-0000-0000-C000-000000000046}
  38. IID_IEnumIDList         dd 0000214F2h
  39.                         dw 00000h
  40.                         dw 00000h
  41.                         db 0C0h, 000h, 000h, 000h, 000h, 000h, 000h, 046h
  42.  
  43. ; IID_IShellWindows Interface
  44. struct IShellWindows
  45.     QueryInterface      dd ?
  46.     AddRef              dd ?
  47.     Release             dd ?
  48.  
  49.     GetTypeInfoCount    dd ?
  50.     GetTypeInfo         dd ?
  51.     GetIDsOfNames       dd ?
  52.     _Invoke             dd ?
  53.  
  54.     ; Properties
  55.     get_Count           dd ?
  56.  
  57.     ; IShellWindows
  58.     Item                dd ?
  59.     _NewEnum            dd ?
  60.     Register            dd ?
  61.     RegisterPending     dd ?
  62.     Revoke              dd ?
  63.     OnNavigate          dd ?
  64.     OnActivated         dd ?
  65.     FindWindowSW        dd ?
  66.     OnCreated           dd ?
  67.     ProcessAttachDetach dd ?
  68. ends
  69.  
  70. ; IID_IShellBrowser Interface
  71. struct IShellBrowser
  72.     QueryInterface      dd ?
  73.     AddRef              dd ?
  74.     Release             dd ?
  75.  
  76.     GetWindow           dd ?
  77.     ContextSensitiveHelp dd ?
  78.     InsertMenusSB       dd ?
  79.     SetMenuSB           dd ?
  80.     RemoveMenusSB       dd ?
  81.     SetStatusTextSB     dd ?
  82.     EnableModelessSB    dd ?
  83.     TranslateAcceleratorSB dd ?
  84.     BrowseObject        dd ?
  85.     GetViewStateStream  dd ?
  86.     GetControlWindow    dd ?
  87.     SendControlMsg      dd ?
  88.     QueryActiveShellView dd ?
  89.     OnViewWindowActive  dd ?
  90.     SetToolbarItems     dd ?
  91. ends
  92.  
  93. ; IID_IShellFolder Interface
  94. struct IShellFolder
  95.     QueryInterface      dd ?
  96.     AddRef              dd ?
  97.     Release             dd ?
  98.  
  99.     ParseDisplayName    dd ?
  100.     EnumObjects         dd ?
  101.     BindToObject        dd ?
  102.     BindToStorage       dd ?
  103.     CompareIDs          dd ?
  104.     CreateViewObject    dd ?
  105.     GetAttributesOf     dd ?
  106.     GetUIObjectOf       dd ?
  107.     GetDisplayNameOf    dd ?
  108.     SetNameOf           dd ?
  109. ends
  110.  
  111. ; IID_IFolderView Interface
  112. struct IFolderView
  113.     QueryInterface      dd ?
  114.     AddRef              dd ?
  115.     Release             dd ?
  116.  
  117.     GetCurrentViewMode  dd ?
  118.     SetCurrentViewMode  dd ?
  119.     GetFolder           dd ?
  120.     Item                dd ?
  121.     ItemCount           dd ?
  122.     Items               dd ?
  123.     GetSelectionMarkedItem dd ?
  124.     GetFocusedItem      dd ?
  125.     GetItemPosition     dd ?
  126.     GetSpacing          dd ?
  127.     GetDefaultSpacing   dd ?
  128.     GetAutoArrange      dd ?
  129.     SelectItem          dd ?
  130.     SelectAndPositionItems dd ?
  131. ends
  132.  
  133. ; IID_IEnumIDList Interface
  134. struct IEnumIDList
  135.     QueryInterface      dd ?
  136.     AddRef              dd ?
  137.     Release             dd ?
  138.  
  139.     Next                dd ?
  140.     Skip                dd ?
  141.     Reset               dd ?
  142.     Clone               dd ?
  143. ends
  144.  
  145. struct IUnknown
  146.     QueryInterface      dd ?
  147.     AddRef              dd ?
  148.     Release             dd ?
  149. ends
Список с ярлыками запрятан достаточно глубоко в структуре окна рабочего стола, поэтому и доступ к нему приходится получать, поочередно обращаясь к объектам все более низкого уровня. Больше всего это напоминает разборку игрушки-матрешки. Добравшись до списка, перебираем поочередно его элементы и получаем интересующие нас свойства, то есть координаты и название каждого ярлыка на рабочем столе.
  1.         ; Инициализировать COM-объект
  2.         invoke  CoInitialize,NULL
  3.         ; Создать объект
  4.         invoke  CoCreateInstance,CLSID_ShellWindows,NULL,\
  5.                 CLSCTX_ALL,IID_IShellWindows,pISwDisp
  6.         cmp     eax,S_OK
  7.         jne     loc_exit
  8.  
  9.         ; Найти окно рабочего стола и получить интерфейс
  10.         ; для работы с ним
  11.         mov     [varLoc.vt],VT_I4
  12.         mov     [varLoc.lVal],CSIDL_DESKTOP
  13.         mov     [varLocRoot.vt],VT_EMPTY
  14.         mov     eax,[pISwDisp]
  15.         mov     eax,[eax]
  16.         stdcall dword [eax+IShellWindows.FindWindowSW],[pISwDisp],varLoc,\
  17.                 varLocRoot,SWC_DESKTOP,hwnd,SWFO_NEEDDISPATCH,spdisp
  18.  
  19.         invoke  IUnknown_QueryService,[spdisp],CLSID_STopLevelBrowser,\
  20.                 IID_IShellBrowser,spBrowser
  21.  
  22.         mov     eax,[spBrowser]
  23.         mov     eax,[eax]
  24.         stdcall dword [eax+IShellBrowser.QueryActiveShellView],\
  25.                 [spBrowser],spshView
  26.  
  27.         mov     eax,[spshView]
  28.         mov     eax,[eax]
  29.         stdcall dword [eax+IShellFolder.QueryInterface],[spshView],\
  30.                 IID_IFolderView,spView
  31.  
  32.         mov     eax,[spView]
  33.         mov     eax,[eax]
  34.         stdcall dword [eax+IFolderView.GetFolder],[spView],\
  35.                 IID_IShellFolder,spFolder
  36.  
  37.         ; Получить список объектов
  38.         mov     eax,[spView]
  39.         mov     eax,[eax]
  40.         stdcall dword [eax+IFolderView.Items],[spView],SVGIO_ALLVIEW,\
  41.                 IID_IEnumIDList,spEnum
  42.  
  43. loc_loop:
  44.         ; Получить следующий объект рабочего стола
  45.         mov     eax,[spEnum]
  46.         mov     eax,[eax]
  47.         stdcall dword [eax+IEnumIDList.Next],[spEnum],1,spidl,0
  48.         or      eax,eax
  49.         jne     loc_done
  50.  
  51.         ; Получить название иконки
  52.         mov     eax,[spFolder]
  53.         mov     eax,[eax]
  54.         stdcall dword [eax+IShellFolder.GetDisplayNameOf],[spFolder],\
  55.                 [spidl],SHGDN_NORMAL,strRet
  56.         ; Преобразовать его в привычный вид
  57.         invoke  StrRetToStr,strRet,[spidl],spszName
  58.  
  59.         ; Получить координаты иконки
  60.         mov     eax,[spView]
  61.         mov     eax,[eax]
  62.         stdcall dword [eax+IFolderView.GetItemPosition],[spView],\
  63.                 [spidl],pt
  64.         ; [spszName] --> указатель на строку названия ярлыка
  65.         ; pt --> координаты ярлыка относительно левого верхнего угла
  66.         ...
  67.         ...
  68.         jmp     loc_loop
  69. loc_done:
  70.         ; Прибраться за собой
  71.         mov     eax,[spEnum]
  72.         mov     eax,[eax]
  73.         stdcall dword [eax+IUnknown.Release],[spEnum]
  74.  
  75.         mov     eax,[spFolder]
  76.         mov     eax,[eax]
  77.         stdcall dword [eax+IUnknown.Release],[spFolder]
  78.  
  79.         mov     eax,[spView]
  80.         mov     eax,[eax]
  81.         stdcall dword [eax+IUnknown.Release],[spView]
  82.  
  83.         mov     eax,[spshView]
  84.         mov     eax,[eax]
  85.         stdcall dword [eax+IUnknown.Release],[spshView]
  86.  
  87.         mov     eax,[spBrowser]
  88.         mov     eax,[eax]
  89.         stdcall dword [eax+IUnknown.Release],[spBrowser]
  90.  
  91.         mov     eax,[spdisp]
  92.         mov     eax,[eax]
  93.         stdcall dword [eax+IUnknown.Release],[spdisp]
  94.  
  95.         mov     eax,[pISwDisp]
  96.         mov     eax,[eax]
  97.         stdcall dword [eax+IUnknown.Release],[pISwDisp]
  98.  
  99.         ; Удалить объект
  100.         invoke  CoUninitialize
Естественно, список методов IFolderView не ограничивается только координатами ярлыков, с их помощью можно получить настройки отображения интересующей вас папки, а также управлять положением и выделением элементов. Например, сохранив где-нибудь в сухом прохладном месте положение ярлыков на рабочем столе, в дальнейшем можно будет их восстановить на привычные места, как это делают упомянутые в начале статьи утилиты. Делается это примерно так:
  1.         SVSI_POSITIONITEM = 0x80
  2.  
  3.         ; Установить новые координаты иконки
  4.         mov     eax,[spView]
  5.         mov     eax,[eax]
  6.         stdcall dword [eax+IFolderView.SelectAndPositionItems],[spView],\
  7.                 1,spidl,pt,SVSI_POSITIONITEM
Добираемся до списка ярлыков, как показано в приведенном выше коде, но вместо получения координат меняем их на нужные (сохраненные). Не забудьте только отключить в настройках рабочего стола галочки "Упорядочить значки автоматически" и "Выровнять значки по сетке".

В приложении пример программы с исходным текстом, которая выводит список ярлыков рабочего стола с их координатами.

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

Get.Desktop.Icons.Demo.zip (5,284 bytes)


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

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

Комментарии

Отзывы посетителей сайта о статье
ManHunter (15.05.2024 в 17:59):
Говорю же - херней заниматься. В иконках на рабочем столе вообще нет необходимости, как и в самом рабочем столе. Открыт на весь размер браузер, открыт редактор кода, открыт тотал коммандер. Этого хватает. Если требуется чесать ногой за ухом, то это вообще не моя забота. И, судя по странным хотелкам, любая другая подобная идея на любую другую тему - это тоже не моя забота.
assch (15.05.2024 в 15:37):
Иногда (подчеркну не всегда) при перетаскивании иконок рабочего стола,
можно немного промахнутся и соответственно иконки немного перестроятся.
Для большинства иконок рабочего стола это не так уж и принципиально.
Но есть определённые иконки, которые многие бы предпочли, чтобы они не сдвигались
Например - "Мой компьютер" , "Корзина" , "Chrome"
Можно конечно включить - Упорядочить значки автоматически.
Но тогда исчезает возможность размещения иконок по своему выбору.
Я например сделал так:
При запуске (ПК) моя програмка отображается в трее рабочего стола,
которую я естественно могу отключить.
Кстати делал я её на основе ваших примеров,
за что вам большое спасибо.
Функциональность програмки:
Над первыми тремя иконками в правом верхнем углу экрана.
Я повесил прозрачное окно, в этом окне также разместил три прозрачных
дочерних окна, естественно по определённым координатам и с определёнными стилями.
Саму идею со стилями я также узнал в ваших примерах.
Ну и соответственно прописал определённые действия в процедурах.
Мышкой эти условно видимые иконки ни как не захватить,
и соответственно сдвигаться они не будут.
Но если в зоне иконки будет - WM_LBUTTONUP
тут же окну добавиться стиль - WS_EX_TRANSPARENT
програмнно имитируется - MOUSEEVENTF_LEFTDOWN or MOUSEEVENTF_LEFTUP
и тут же обратно снимаеться стиль - WS_EX_TRANSPARENT
Точно такая же обработка и правой кнопки.
Для окна под иконкой "Корзина" добавлен еще обработчик - WM_DROPFILES
Повторюсь все идеи я взял в ваших уроках.
По этому я и задал вопрос:
Узнать хендл определённой иконки рабочего стола,
и запретить именно ей только, перетаскиваться по рабочему столу.
То есть воплотить тот же смысл, только сделать это по другому.
ManHunter (15.05.2024 в 14:10):
Херней заниматься
assch (15.05.2024 в 13:02):
Отличный пример.
А можно например узнать хендл определённой иконки рабочего стола,
и запретить именно ей только, перетаскиваться по рабочему столу.
То есть при захвате мышкой, она бы не реагировала бы на перетаскивание
ManHunter (09.08.2020 в 11:25):
Проактивка антивирусов может не одобрить такого поведения.
wet (09.08.2020 в 09:24):
Можно попроще сделать. Найти pid проводника GetWindowThreadProcessId,
подключится к процессу OpenProcess, скопировать структуру LV_ITEM WriteProcessMemory в выделенную для этого память VirtualAllocEx.
А дальше SendMessage к Desktop Handle:
LVM_GETITEMCOUNT общее кол-во иконок
LVM_GETITEMTEXT  их имена
LVM_GETITEMPOSITION их координаты.
Василий (06.08.2020 в 12:46):
ManHunter, такого годного контента ещё поискать... очень хорошие статьи, не вздумай бросать)))
Евгений (05.08.2020 в 13:08):
"Может оно и не надо совсем?" - несогласен, нужно посмотреть на кнопочку "сказать спасибо!".
0101 (05.08.2020 в 10:30):
похоже). Как им бабки зарабатывать? В интсте/ютубе за просмотры и лайки капает денежка! И мозги не напрягаются. Кайми вот в бизнес подался.. Имхо:
1. давно уже надо/пора выдрать файлы костант и структур (из других ЯП), чтобы вообще о них не думать и подключать инкудом.
2. без макросов select/case, прямого сравнения (>=<) и присвоения данных/строк (без постоянного дёрганья eax), объявления строк и переменных "по месту" - совсем скучно. Форки asm'а это давно могут.
3. меня раздражают скобки вместо @/&/*, инвоки, отсутствие процедур - код нечитаем с этими @f/ret.
4. секция ресурсов не наглядна. Почему бы не нарисовать диалоговое окно в ResEd и затем прилинковать? Знаю, есть прога, которые из *.rc переводят в формат ресурсов fasm.. Ты их используешь или из головы сразу пишешь такие большие ресурсы?
5.FASMW в качестве IDE не подходит - нет подсветки и автокомплита. Надо или RadAsm/EasyCode продвигать или к npp автокомплит прикручивать (подходит от RadAsm с небольшими правками) или твой Sublime расшаривать..
6. нужны исходники - литература, откуда всё (идеи статей) взялось, даже на английском. Кому-то проще в си-коде разбираться, кому-то (мне) хотелось бы не просто на код посмотреть, но и теорию почитать. Например: в теме "Создание и обработка улучшенного MessageBox" хотелось бы почитать теорию по хукам или о том, что у MsgBox есть (независимое) текстовое поле со своим хендлом..  Статьи (мне) не достаточно для понимания, приходится гуглить (копаться в chm-форуме RDSN за 2007г..) аналогичные примеры..
A1eksandr1 (05.08.2020 в 04:21):
Ну некоторые всё же почитывают. А комментировать/дискутировать - это уже совсем другая история)
Ещё и публикации появляются задним числом (дата статьи: 25.07; по факту отобразилась только 04.08), не каждый откроет, если не будет пролистывать блог вниз.
ManHunter (04.08.2020 в 23:12):
Похоже, что популяризация Ассемблера проходит мимо. Может оно и не надо совсем? Завести инстаграмм, постить фотки пюрешки с сосисками...

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

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

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