Получение и изменение обоев рабочего стола на Ассемблере
Тема обоев рабочего стола Windows уже поднималась тут несколько раз, но это были, в основном, какие-то готовые программные решения. Настало время заглянуть "под капот" системы и посмотреть, как оно устроено. А лучшего инструмента, чем Ассемблер, для этих целей сложно придумать.Начнем с получения информации об установленных обоях рабочего стола. Тут ничего сложного, достаточно вызвать функцию SystemParametersInfo с параметром SPI_GETDESKWALLPAPER.
Code (Assembler) : Убрать нумерацию
- SPI_GETDESKWALLPAPER = 0x0073
- invoke SystemParametersInfo,SPI_GETDESKWALLPAPER,\
- MAX_PATH,szPath,0
- ; szPath -> строка пути к файлу обоев
Теперь переходим к смене обоев рабочего стола. В интернетах для этих целей обычно рекомендуют использовать упомянутую выше функцию SystemParametersInfo с параметром SPI_SETDESKWALLPAPER. Код получается минимальный, все очень просто реализуется, выглядит на первый взгляд стильно, модно, молодежно.
Code (Assembler) : Убрать нумерацию
- ; Путь к файлу с новыми обоями рабочего стола
- szPath db 'c:\windows\wallpaper.bmp',0
- SPI_SETDESKWALLPAPER = 20
- SPIF_SENDWININICHANGE = 2
- SPIF_UPDATEINIFILE = 1
- invoke SystemParametersInfo,SPI_SETDESKWALLPAPER,\
- 0,szPath,SPIF_UPDATEINIFILE+SPIF_SENDWININICHANGE
Давайте сделаем все по-правильному, то есть с использованием технологии COM и системного интерфейса IActiveDesktop. FASM про все это колдунство вообще не в курсе, так что начинаем как обычно, то есть с описания структур, интерфейсов и GUID'ов.
Code (Assembler) : Убрать нумерацию
- ; GUID {75048700-EF1F-11D0-9888-006097DEACF9}
- CLSID_ActiveDesktop dd 075048700h
- dw 0EF1Fh
- dw 011D0h
- db 098h, 088h, 000h, 060h, 097h, 0DEh, 0ACh, 0F9h
- ; GUID {F490EB00-1240-11D1-9888-006097DEACF9}
- IID_IActiveDesktop dd 0F490EB00h
- dw 01240h
- dw 011D1h
- db 098h, 088h, 000h, 060h, 097h, 0DEh, 0ACh, 0F9h
- ; IID_IActiveDesktop Interface
- struct IActiveDesktop
- ; IUnknown
- QueryInterface dd ? ; 000h
- AddRef dd ? ; 004h
- Release dd ? ; 008h
- ; IActiveDesktop
- ApplyChanges dd ? ; 00Ch
- GetWallpaper dd ? ; 010h
- SetWallpaper dd ? ; 014h
- GetWallpaperOptions dd ? ; 018h
- SetWallpaperOptions dd ? ; 01Ch
- GetPattern dd ? ; 020h
- SetPattern dd ? ; 024h
- GetDesktopItemOptions dd ? ; 028h
- SetDesktopItemOptions dd ? ; 02Ch
- AddDesktopItem dd ? ; 030h
- AddDesktopItemWithUI dd ? ; 034h
- ModifyDesktopItem dd ? ; 038h
- RemoveDesktopItem dd ? ; 03Ch
- GetDesktopItemCount dd ? ; 040h
- GetDesktopItem dd ? ; 044h
- GetDesktopItemByID dd ? ; 048h
- GenerateDesktopItemHtml dd ? ; 04Ch
- AddUrl dd ? ; 050h
- GetDesktopItemBySource dd ? ; 054h
- ends
- ; Настройки отображения обоев
- struct WALLPAPEROPT
- dwSize dd ?
- dwStyle dd ?
- ends
- CLSCTX_INPROC_SERVER = 1
- S_OK = 0
- WPSTYLE_CENTER = 0
- WPSTYLE_TILE = 1
- WPSTYLE_STRETCH = 2
- WPSTYLE_KEEPASPECT = 3
- WPSTYLE_CROPTOFIT = 4
- WPSTYLE_SPAN = 5
- AD_APPLY_SAVE = 1
- AD_APPLY_HTMLGEN = 2
- AD_APPLY_REFRESH = 4
- AD_APPLY_FORCE = 8
- AD_APPLY_BUFFERED_REFRESH = 0x00000010
- AD_APPLY_DYNAMICREFRESH = 0x00000020
- AD_APPLY_ALL = AD_APPLY_SAVE+AD_APPLY_HTMLGEN+AD_APPLY_REFRESH
Code (Assembler) : Убрать нумерацию
- invoke CoInitialize,0
- ; Создать объект
- invoke CoCreateInstance,CLSID_ActiveDesktop,NULL,\
- CLSCTX_INPROC_SERVER,\
- IID_IActiveDesktop,pIActDesk
- cmp eax,S_OK
- jne loc_exit
- ; Получить путь к файлу обоев
- mov eax, [pIActDesk]
- mov eax, [eax]
- stdcall dword [eax+IActiveDesktop.GetWallpaper],\
- [pIActDesk],szPath,MAX_PATH,0
- ; Получить параметры отображения
- mov [wpOpt.dwSize],sizeof.WALLPAPEROPT
- mov eax, [pIActDesk]
- mov eax, [eax]
- stdcall dword [eax+IActiveDesktop.GetWallpaperOptions],\
- [pIActDesk],wpOpt,0
- ; Прибраться за собой
- mov eax, [pIActDesk]
- mov eax, [eax]
- stdcall dword [eax+IActiveDesktop.Release],[pIActDesk]
- ; szPath -> строка пути к файлу обоев
- ; wpOpt.dwStyle -> стиль отображения обоев
- loc_exit:
- ; Удалить объект
- invoke CoUninitialize
Code (Assembler) : Убрать нумерацию
- invoke CoInitialize,0
- ; Создать объект
- invoke CoCreateInstance,CLSID_ActiveDesktop,NULL,\
- CLSCTX_INPROC_SERVER,\
- IID_IActiveDesktop,pIActDesk
- cmp eax,S_OK
- jne loc_exit
- ; Установить новые обои рабочего стола
- mov eax, [pIActDesk]
- mov eax, [eax]
- stdcall dword [eax+IActiveDesktop.SetWallpaper],\
- [pIActDesk],szPath,0
- ; Установить параметры отображения
- mov [wpOpt.dwSize],sizeof.WALLPAPEROPT
- mov [wpOpt.dwStyle],WPSTYLE_CENTER
- mov eax, [pIActDesk]
- mov eax, [eax]
- stdcall dword [eax+IActiveDesktop.SetWallpaperOptions],\
- [pIActDesk],wpOpt,0
- ; Применить изменения
- mov eax, [pIActDesk]
- mov eax, [eax]
- stdcall dword [eax+IActiveDesktop.ApplyChanges],[pIActDesk],\
- AD_APPLY_ALL
- ; Прибраться за собой
- mov eax, [pIActDesk]
- mov eax, [eax]
- stdcall dword [eax+IActiveDesktop.Release],[pIActDesk]
- loc_exit:
- ; Удалить объект
- invoke CoUninitialize
Просмотров: 671 | Комментариев: 2
Внимание! Статья опубликована больше года назад, информация могла устареть!
Комментарии
Отзывы посетителей сайта о статье
ManHunter
(19.01.2023 в 14:58):
Да я никуда не тороплюсь. Работает и ладно.
Grey
(19.01.2023 в 14:53):
На 32 битах до пенсии не просидишь). Консерватизм думаю связан с неудобством восприятия таких длинных чисел. Да и разработчики компиляторов и дебагеров, если не на 64 то 128 битах задумаются о замене hex-представления на более высокие порядки.
Добавить комментарий
Заполните форму для добавления комментария