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

Как получить список ярлыков на рабочем столе
Если вы интересуетесь компьютерами и любите порядок в своем электронном хозяйстве, то наверняка встречали программы для сохранения и восстановления позиций ярлыков на рабочем столе. Судя по многочисленным отзывам пользователей на различных софтовых порталах и форумах, такие программы действительно востребованы. Давайте посмотрим, каким образом можно получить список и позиции ярлыков рабочего стола.
Начинаем с определения структур и констант, которые нам понадобятся для дальнейшей работы, но про которые FASM ничего не знает.
Code (Assembler) : Убрать нумерацию
- struct DECIMAL
- wReserved dw ?
- union
- struct
- scale db ?
- sign db ?
- ends
- signscale dw ?
- ends
- Hi32 dd ?
- union
- struct
- Lo32 dd ?
- Mid32 dd ?
- ends
- Lo64 dq ?
- ends
- ends
- struct VARIANT
- union
- struct
- vt dw ?
- wReserved rw 3
- union
- llVal dq ?
- lVal dd ?
- iVal dw ?
- bVal db ?
- ends
- ends
- decVal DECIMAL
- ends
- ends
- struct STRRET
- uType dd ?
- union
- pOleStr dd ?
- uOffset dd ?
- cStr rb 260
- ends
- ends
- CLSCTX_INPROC_SERVER = 0x01
- CLSCTX_INPROC_HANDLER = 0x02
- CLSCTX_LOCAL_SERVER = 0x04
- CLSCTX_REMOTE_SERVER = 0x10
- CLSCTX_SERVER = CLSCTX_INPROC_SERVER + CLSCTX_LOCAL_SERVER\
- + CLSCTX_REMOTE_SERVER
- CLSCTX_ALL = CLSCTX_INPROC_HANDLER + CLSCTX_SERVER
- S_OK = 0
- SWC_DESKTOP = 8
- SWFO_NEEDDISPATCH = 1
- CSIDL_DESKTOP = 0x0000
- SVGIO_ALLVIEW = 2
- SHGDN_NORMAL = 0
- VT_EMPTY = 0
- VT_NULL = 1
- VT_I2 = 2
- VT_I4 = 3
- VT_R4 = 4
- VT_R8 = 5
- VT_CY = 6
- VT_DATE = 7
- VT_BSTR = 8
- VT_DISPATCH = 9
- VT_ERROR = 10
- VT_BOOL = 11
- VT_VARIANT = 12
- VT_UNKNOWN = 13
- VT_DECIMAL = 14
- VT_I1 = 16
- VT_UI1 = 17
- VT_UI2 = 18
- VT_UI4 = 19
- VT_I8 = 20
- VT_UI8 = 21
- VT_INT = 22
- VT_UINT = 23
- VT_VOID = 24
- VT_HRESULT = 25
- VT_PTR = 26
- VT_SAFEARRAY = 27
- VT_CARRAY = 28
- VT_USERDEFINED = 29
- VT_LPSTR = 30
- VT_LPWSTR = 31
- VT_RECORD = 36
- VT_INT_PTR = 37
- VT_UINT_PTR = 38
- VT_FILETIME = 64
- VT_BLOB = 65
- VT_STREAM = 66
- VT_STORAGE = 67
- VT_STREAMED_OBJECT = 68
- VT_STORED_OBJECT = 69
- VT_BLOB_OBJECT = 70
- VT_CF = 71
- VT_CLSID = 72
- VT_VERSIONED_STREAM = 73
- VT_BSTR_BLOB = 0x0FFF
- VT_VECTOR = 0x1000
- VT_ARRAY = 0x2000
- VT_BYREF = 0x4000
- VT_RESERVED = 0x8000
- VT_ILLEGAL = 0xFFFF
- VT_ILLEGALMASKED = 0x0FFF
- VT_TYPEMASK = 0x0FFF
Code (Assembler) : Убрать нумерацию
- ; GUID {9BA05972-F6A8-11CF-A442-00A0C90A8F39}
- CLSID_ShellWindows dd 09BA05972h
- dw 0F6A8h
- dw 011CFh
- db 0A4h, 042h, 000h, 0A0h, 0C9h, 00Ah, 08Fh, 039h
- ; GUID {85CB6900-4D95-11CF-960C-0080C7F4EE85}
- IID_IShellWindows dd 085CB6900h
- dw 04D95h
- dw 011CFh
- db 096h, 00Ch, 000h, 080h, 0C7h, 0F4h, 0EEh, 085h
- ; GUID {4C96BE40-915C-11CF-99D3-00AA004AE837}
- CLSID_STopLevelBrowser dd 04C96BE40h
- dw 0915Ch
- dw 011CFh
- db 099h, 0D3h, 000h, 0AAh, 000h, 04Ah, 0E8h, 037h
- ; GUID {000214E2-0000-0000-C000-000000000046}
- IID_IShellBrowser dd 0000214E2h
- dw 00000h
- dw 00000h
- db 0C0h, 000h, 000h, 000h, 000h, 000h, 000h, 046h
- ; GUID {CDE725B0-CCC9-4519-917E-325D72FAB4CE}
- IID_IFolderView dd 0CDE725B0h
- dw 0CCC9h
- dw 04519h
- db 091h, 07Eh, 032h, 05Dh, 072h, 0FAh, 0B4h, 0CEh
- ; GUID {000214E6-0000-0000-C000-000000000046}
- IID_IShellFolder dd 0000214E6h
- dw 00000h
- dw 00000h
- db 0C0h, 000h, 000h, 000h, 000h, 000h, 000h, 046h
- ; GUID {000214F2-0000-0000-C000-000000000046}
- IID_IEnumIDList dd 0000214F2h
- dw 00000h
- dw 00000h
- db 0C0h, 000h, 000h, 000h, 000h, 000h, 000h, 046h
- ; IID_IShellWindows Interface
- struct IShellWindows
- QueryInterface dd ?
- AddRef dd ?
- Release dd ?
- GetTypeInfoCount dd ?
- GetTypeInfo dd ?
- GetIDsOfNames dd ?
- _Invoke dd ?
- ; Properties
- get_Count dd ?
- ; IShellWindows
- Item dd ?
- _NewEnum dd ?
- Register dd ?
- RegisterPending dd ?
- Revoke dd ?
- OnNavigate dd ?
- OnActivated dd ?
- FindWindowSW dd ?
- OnCreated dd ?
- ProcessAttachDetach dd ?
- ends
- ; IID_IShellBrowser Interface
- struct IShellBrowser
- QueryInterface dd ?
- AddRef dd ?
- Release dd ?
- GetWindow dd ?
- ContextSensitiveHelp dd ?
- InsertMenusSB dd ?
- SetMenuSB dd ?
- RemoveMenusSB dd ?
- SetStatusTextSB dd ?
- EnableModelessSB dd ?
- TranslateAcceleratorSB dd ?
- BrowseObject dd ?
- GetViewStateStream dd ?
- GetControlWindow dd ?
- SendControlMsg dd ?
- QueryActiveShellView dd ?
- OnViewWindowActive dd ?
- SetToolbarItems dd ?
- ends
- ; IID_IShellFolder Interface
- struct IShellFolder
- QueryInterface dd ?
- AddRef dd ?
- Release dd ?
- ParseDisplayName dd ?
- EnumObjects dd ?
- BindToObject dd ?
- BindToStorage dd ?
- CompareIDs dd ?
- CreateViewObject dd ?
- GetAttributesOf dd ?
- GetUIObjectOf dd ?
- GetDisplayNameOf dd ?
- SetNameOf dd ?
- ends
- ; IID_IFolderView Interface
- struct IFolderView
- QueryInterface dd ?
- AddRef dd ?
- Release dd ?
- GetCurrentViewMode dd ?
- SetCurrentViewMode dd ?
- GetFolder dd ?
- Item dd ?
- ItemCount dd ?
- Items dd ?
- GetSelectionMarkedItem dd ?
- GetFocusedItem dd ?
- GetItemPosition dd ?
- GetSpacing dd ?
- GetDefaultSpacing dd ?
- GetAutoArrange dd ?
- SelectItem dd ?
- SelectAndPositionItems dd ?
- ends
- ; IID_IEnumIDList Interface
- struct IEnumIDList
- QueryInterface dd ?
- AddRef dd ?
- Release dd ?
- Next dd ?
- Skip dd ?
- Reset dd ?
- Clone dd ?
- ends
- struct IUnknown
- QueryInterface dd ?
- AddRef dd ?
- Release dd ?
- ends
Code (Assembler) : Убрать нумерацию
- ; Инициализировать COM-объект
- invoke CoInitialize,NULL
- ; Создать объект
- invoke CoCreateInstance,CLSID_ShellWindows,NULL,\
- CLSCTX_ALL,IID_IShellWindows,pISwDisp
- cmp eax,S_OK
- jne loc_exit
- ; Найти окно рабочего стола и получить интерфейс
- ; для работы с ним
- mov [varLoc.vt],VT_I4
- mov [varLoc.lVal],CSIDL_DESKTOP
- mov [varLocRoot.vt],VT_EMPTY
- mov eax,[pISwDisp]
- mov eax,[eax]
- stdcall dword [eax+IShellWindows.FindWindowSW],[pISwDisp],varLoc,\
- varLocRoot,SWC_DESKTOP,hwnd,SWFO_NEEDDISPATCH,spdisp
- invoke IUnknown_QueryService,[spdisp],CLSID_STopLevelBrowser,\
- IID_IShellBrowser,spBrowser
- mov eax,[spBrowser]
- mov eax,[eax]
- stdcall dword [eax+IShellBrowser.QueryActiveShellView],\
- [spBrowser],spshView
- mov eax,[spshView]
- mov eax,[eax]
- stdcall dword [eax+IShellFolder.QueryInterface],[spshView],\
- IID_IFolderView,spView
- mov eax,[spView]
- mov eax,[eax]
- stdcall dword [eax+IFolderView.GetFolder],[spView],\
- IID_IShellFolder,spFolder
- ; Получить список объектов
- mov eax,[spView]
- mov eax,[eax]
- stdcall dword [eax+IFolderView.Items],[spView],SVGIO_ALLVIEW,\
- IID_IEnumIDList,spEnum
- loc_loop:
- ; Получить следующий объект рабочего стола
- mov eax,[spEnum]
- mov eax,[eax]
- stdcall dword [eax+IEnumIDList.Next],[spEnum],1,spidl,0
- or eax,eax
- jne loc_done
- ; Получить название иконки
- mov eax,[spFolder]
- mov eax,[eax]
- stdcall dword [eax+IShellFolder.GetDisplayNameOf],[spFolder],\
- [spidl],SHGDN_NORMAL,strRet
- ; Преобразовать его в привычный вид
- invoke StrRetToStr,strRet,[spidl],spszName
- ; Получить координаты иконки
- mov eax,[spView]
- mov eax,[eax]
- stdcall dword [eax+IFolderView.GetItemPosition],[spView],\
- [spidl],pt
- ; [spszName] --> указатель на строку названия ярлыка
- ; pt --> координаты ярлыка относительно левого верхнего угла
- ...
- ...
- jmp loc_loop
- loc_done:
- ; Прибраться за собой
- mov eax,[spEnum]
- mov eax,[eax]
- stdcall dword [eax+IUnknown.Release],[spEnum]
- mov eax,[spFolder]
- mov eax,[eax]
- stdcall dword [eax+IUnknown.Release],[spFolder]
- mov eax,[spView]
- mov eax,[eax]
- stdcall dword [eax+IUnknown.Release],[spView]
- mov eax,[spshView]
- mov eax,[eax]
- stdcall dword [eax+IUnknown.Release],[spshView]
- mov eax,[spBrowser]
- mov eax,[eax]
- stdcall dword [eax+IUnknown.Release],[spBrowser]
- mov eax,[spdisp]
- mov eax,[eax]
- stdcall dword [eax+IUnknown.Release],[spdisp]
- mov eax,[pISwDisp]
- mov eax,[eax]
- stdcall dword [eax+IUnknown.Release],[pISwDisp]
- ; Удалить объект
- invoke CoUninitialize
Code (Assembler) : Убрать нумерацию
- SVSI_POSITIONITEM = 0x80
- ; Установить новые координаты иконки
- mov eax,[spView]
- mov eax,[eax]
- stdcall dword [eax+IFolderView.SelectAndPositionItems],[spView],\
- 1,spidl,pt,SVSI_POSITIONITEM
В приложении пример программы с исходным текстом, которая выводит список ярлыков рабочего стола с их координатами.
Просмотров: 1814 | Комментариев: 11

Внимание! Статья опубликована больше года назад, информация могла устареть!
Комментарии
Отзывы посетителей сайта о статье
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
Повторюсь все идеи я взял в ваших уроках.
По этому я и задал вопрос:
Узнать хендл определённой иконки рабочего стола,
и запретить именно ей только, перетаскиваться по рабочему столу.
То есть воплотить тот же смысл, только сделать это по другому.
можно немного промахнутся и соответственно иконки немного перестроятся.
Для большинства иконок рабочего стола это не так уж и принципиально.
Но есть определённые иконки, которые многие бы предпочли, чтобы они не сдвигались
Например - "Мой компьютер" , "Корзина" , "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 их координаты.
подключится к процессу 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г..) аналогичные примеры..
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), не каждый откроет, если не будет пролистывать блог вниз.
Ещё и публикации появляются задним числом (дата статьи: 25.07; по факту отобразилась только 04.08), не каждый откроет, если не будет пролистывать блог вниз.

ManHunter
(04.08.2020 в 23:12):
Похоже, что популяризация Ассемблера проходит мимо. Может оно и не надо совсем? Завести инстаграмм, постить фотки пюрешки с сосисками...

Добавить комментарий
Заполните форму для добавления комментария
