Вернулся
 Аватар для HackerVlad
1753 / 649 / 45
Регистрация: 10.09.2021
Сообщений: 2,801

Как программно в Windows XP поменять картинку на рабочем столе, используя файл JPG?

30.07.2023, 20:16. Показов 2475. Ответов 33
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
Всем привет!

Скажите, пожалуйста, как в Windows XP установить картинку на рабочем столе в формате JPG??? Или никак вообще? Неужели только начиная от Windows Vista или даже Windows 7 можно установить именно JPG-картинку???

В семёрке этот код прекрасно работает:

Модуль:
Visual Basic
1
2
3
4
5
6
7
8
9
10
11
12
13
14
' Декларации API...
Private Declare Function SystemParametersInfo Lib "user32" Alias "SystemParametersInfoW" (ByVal uAction As Long, ByVal uParam As Long, ByVal lpvParam As Long, ByVal fuWinIni As Long) As Long
 
' Константы
Private Const SETDESKWALLPAPER = &H14
Private Const UPDATEINIFILE = &H1
 
' Изменение обоев на рабочем столе
Public Function SetWallpaper(ByVal FileName As String) As Boolean
    Dim RetVal As Long
    
    RetVal = SystemParametersInfo(SETDESKWALLPAPER, 0, StrPtr(FileName), UPDATEINIFILE)
    If RetVal = 1 Then SetWallpaper = True
End Function
Форма:
Visual Basic
1
2
3
4
5
Option Explicit
 
Private Sub Command1_Click()
    Print SetWallpaper("C:\WINDOWS\Web\Wallpaper\Nature\img6.jpg")
End Sub
Но в XP почему-то пропускает только BMP-файлы!? Как обойти это ограничение?
1
Лучшие ответы (1)
IT_Exp
Эксперт
34794 / 4073 / 2104
Регистрация: 17.06.2006
Сообщений: 32,602
Блог
30.07.2023, 20:16
Ответы с готовыми решениями:

Как сохранить файл напрямую в базу данных,не используя путь к файлу на рабочем столе?
У меня есть программа CRUD на C # DevExpress, и я храню свои данные в GridView использую MsSql в качестве базы данных. Выбранную строку в...

Как создать файл на рабочем столе так, что бы работало на Linux и на Windows?
Собственно сабж. Я думаю вопрос сводится к тому, каким образом узнать что за ОС у пользователя и как узнать имя его профиля. ...

Как средствами 1С сменить картинку на рабочем столе
Как средствами 1С сменить картинку на рабочем столе

33
Вернулся
 Аватар для HackerVlad
1753 / 649 / 45
Регистрация: 10.09.2021
Сообщений: 2,801
31.07.2023, 19:59  [ТС]
Студворк — интернет-сервис помощи студентам
I can, спасибо большое в семёрке работает со всеми форматами файлов, сейчас в XP ещё проверю будет ли работать...

Добавлено через 10 минут
Да, проверил и в XP тоже работает даже с PNG. Но XP конечно сама их конвертирует в BMP и копирует в определённую папку. А семёрка конвертирует в JPG.

Добавлено через 1 минуту
Цитата Сообщение от I can Посмотреть сообщение
сам не могу проверить - у меня десятка
а почему в десятке не можешь проверить)
0
dive
 Аватар для I can
5005 / 4768 / 852
Регистрация: 13.04.2015
Сообщений: 10,015
31.07.2023, 20:44
Цитата Сообщение от HackerVlad Посмотреть сообщение
а почему в десятке не можешь проверить)
Отмазка такая На самом деле просто лень
0
Вернулся
 Аватар для HackerVlad
1753 / 649 / 45
Регистрация: 10.09.2021
Сообщений: 2,801
31.07.2023, 20:59  [ТС]
Цитата Сообщение от I can Посмотреть сообщение
Отмазка такая На самом деле просто лень
Да всё работает отлично

Добавлено через 12 секунд
I can, спасибо
0
Вернулся
 Аватар для HackerVlad
1753 / 649 / 45
Регистрация: 10.09.2021
Сообщений: 2,801
01.08.2023, 12:44  [ТС]
Единственный минус этой функции ActiveDesktopSetWallpaper это то, что она выполняется слишком долго от 350 до 600 миллисекунд ажно. То есть в среднем приходится ждать аж по пол секунды времени, чтобы картинка поменялась и обратно пришёл отклик в твою программу...

Добавлено через 2 минуты
Я провел некоторые тесты где понял что исполнение SystemParametersInfo выигрывает в производительности это самая быстрая функция для смены обоев, так как ничего не конвертируется в BMP? ничего никуда не перекопируется... Просто сразу устанавливаются обои и всё

Добавлено через 1 минуту
Исполнение функции SystemParametersInfo занимает в среднем 93 миллисекунды времени
0
Вернулся
 Аватар для HackerVlad
1753 / 649 / 45
Регистрация: 10.09.2021
Сообщений: 2,801
01.08.2023, 13:25  [ТС]
Итак, продолжаем эту интересную тему! Я создал для себя модуль в котором расположил две функции. Первая функция, которая сразу меняет картинку, вторая функция которая ещё и конвертирует в BMP сначала. Потом я добавил второй модуль, позаимствовав код с иностранного форума, где какой-то гений придумал код смены картинки через ActiveDesktop.

Итого я решил протестировать три эти функции по времени их выполнения. Тест скорости проводил в EXE в семёрке:
1. SetWallpaper: 63 ml
2. SetWallpaperAndConvertToBMP: 109 ml
3. ActiveDesktopSetWallpaper: 359 ml

Хочу обратить внимание на то, что самая быстрая функция это моя SetWallpaper, которая просто выполняет SystemParametersInfo и всё
Самая медленная функция - ActiveDesktopSetWallpaper она в среднем выполняется вообще пол секунды, очень долго

Код моего модуля с двумя этими функциями:

Visual Basic
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
Option Explicit
'/////////////////////////////////////////////////
'// Модуль для изменения обоев на рабочем столе //
'// Copyright (c) 01.08.2023 by HackerVlad      //
'// e-mail: vladislavpeshkov@yandex.ru          //
'// Версия 2.2                                  //
'/////////////////////////////////////////////////
 
' Декларации API...
Private Declare Function SystemParametersInfo Lib "user32" Alias "SystemParametersInfoW" (ByVal uAction As Long, ByVal uParam As Long, ByVal lpvParam As Long, ByVal fuWinIni As Long) As Long
 
' Константы
Private Const SETDESKWALLPAPER = &H14
Private Const UPDATEINIFILE = &H1
 
' Изменение обоев на рабочем столе
Public Function SetWallpaper(ByVal FileName As String) As Boolean
    Dim RetVal As Long
    
    RetVal = SystemParametersInfo(SETDESKWALLPAPER, 0, StrPtr(FileName), UPDATEINIFILE)
    If RetVal = 1 Then SetWallpaper = True
End Function
 
' Изменение обоев на рабочем столе с конвертацией в BMP
Public Function SetWallpaperAndConvertToBMP(ByVal FileName As String) As Boolean
    Dim RetVal As Long
    Dim WshShell As Object
    Dim pathStr As String
    
    pathStr = Environ("windir")
    If Right$(pathStr, 1) = "\" Then pathStr = Mid$(pathStr, 1, Len(pathStr) - 1)
    pathStr = pathStr & "\wall.bmp"
    
    SavePicture LoadPicture(FileName), pathStr ' Конвертировать в BMP
    RetVal = SystemParametersInfo(SETDESKWALLPAPER, 0, StrPtr(pathStr), UPDATEINIFILE)
    
    If RetVal = 1 Then
        Set WshShell = CreateObject("WScript.Shell")
        WshShell.RegWrite "HKCU\Control Panel\Desktop\Wallpaper", FileName, "REG_SZ"
        SetWallpaperAndConvertToBMP = True
    End If
End Function
Миниатюры
Как программно в Windows XP поменять картинку на рабочем столе, используя файл JPG?  
Вложения
Тип файла: zip ChangeWallpapers.zip (11.7 Кб, 12 просмотров)
1
Вернулся
 Аватар для HackerVlad
1753 / 649 / 45
Регистрация: 10.09.2021
Сообщений: 2,801
01.08.2023, 14:04  [ТС]
Функцией SetWallpaperAndConvertToBMP особо не пользуйтесь, она не поддерживает PNG я её писал только для проверки скорости

Чтобы написать оптимальную новую универсальную функцию лучше всего сначала вызывать SystemParametersInfo и в случае неудачи повторно пробовать вызывать ActiveDesktopSetWallpaper, тогда будет работать само быстро по времени

Добавлено через 1 минуту
Кстати функция ActiveDesktopSetWallpaper в операционной системе Windows XP работает в два раза быстрее по скорости, я заметил

Добавлено через 3 минуты
Но тут важно понимать разницу в алгоритмах, как работает XP и как работает семёрка, при установлении картинки на рабочий стол

XP конвертирует любой графический файл в BMP сохраняет его на диске C: и сразу устанавливает картинку
А семёрка конвертирует любой графический файл в JPG уже, а значит потребуется больше времени на сохранение графического файла ибо его ещё и упаковать надо, а потом уже устанавливает эту картинку. Плюс уходит время на процесс копирования файла ещё на диск C: в дебри системы (я уже писал пути сохранения этих картинок)

Добавлено через 20 минут
Да и функция SetWallpaperAndConvertToBMP не поддерживает юникод и китайщину... А вот функция ActiveDesktopSetWallpaper поддерживает китайщину, это мне понравилось)

Добавлено через 4 минуты
Хотя в том модуле используется CallWindowProcA вместо CallWindowProcW и всё равно поддерживает китайщину... Ну там какой-то гений писал этот код с ассемблерной вставкой даже...
1
Вернулся
 Аватар для HackerVlad
1753 / 649 / 45
Регистрация: 10.09.2021
Сообщений: 2,801
01.08.2023, 21:36  [ТС]
Ура! Я наконец-то написал модуль с универсальной функций смены картинки на рабочем столе:

Visual Basic
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
Option Explicit
'/////////////////////////////////////////////////
'// Модуль для изменения обоев на рабочем столе //
'// Copyright (c) 01.08.2023 by HackerVlad      //
'// e-mail: vladislavpeshkov@yandex.ru          //
'// Версия 3.0                                  //
'/////////////////////////////////////////////////
 
' Декларации API...
Private Declare Function SystemParametersInfoW Lib "user32" (ByVal uAction As Long, ByVal uParam As Long, ByVal lpvParam As Long, ByVal fuWinIni As Long) As Long
Private Declare Function IIDFromString Lib "ole32" (ByVal lpszIID As Long, iid As Any) As Long
Private Declare Function CoCreateInstance Lib "ole32" (rclsid As Any, ByVal pUnkOuter As Long, ByVal dwClsContext As Long, riid As Any, ByVal ppv As Long) As Long
Private Declare Function CallWindowProcA Lib "user32" (ByVal addr As Long, ByVal p1 As Long, ByVal p2 As Long, ByVal p3 As Long, ByVal p4 As Long) As Long
Private Declare Sub RtlMoveMemory Lib "kernel32" (pDst As Any, pSrc As Any, ByVal dlen As Long)
Private Declare Function GetMem4 Lib "msvbvm60" (srcAddr As Any, dstValue As Long) As Long
Private Declare Function GetMem1 Lib "msvbvm60" (srcAddr As Any, dstValue As Long) As Long
 
' Константы
Private Const SETDESKWALLPAPER = &H14
Private Const UPDATEINIFILE = &H1
Private Const CLSCTX_INPROC_SERVER  As Long = 1
Private Const CLSID_ActiveDesktop   As String = "{75048700-EF1F-11D0-9888-006097DEACF9}"
Private Const IID_ActiveDesktop     As String = "{F490EB00-1240-11D1-9888-006097DEACF9}"
 
Private Type GUID
    data1                   As Long
    data2                   As Integer
    data3                   As Integer
    data4(7)                As Byte
End Type
 
Private Type IActiveDesktop
    ' IUnknown
    QueryInterface          As Long
    AddRef                  As Long
    Release                 As Long
    ' IActiveDesktop
    ApplyChanges            As Long
    GetWallpaper            As Long
    SetWallpaper            As Long
    GetWallpaperOptions     As Long
    SetWallpaperOptions     As Long
    GetPattern              As Long
    SetPattern              As Long
    GetDesktopItemOptions   As Long
    SetDesktopItemOptions   As Long
    AddDesktopItem          As Long
    AddDesktopItemWithUI    As Long
    ModifyDesktopItem       As Long
    RemoveDesktopItem       As Long
    GetDesktopItemCount     As Long
    GetDesktopItem          As Long
    GetDesktopItemByID      As Long
    GenerateDesktopItemHtml As Long
    AddUrl                  As Long
    GetDesktopItemBySource  As Long
End Type
 
Private Enum AD_APPLY
    AD_APPLY_SAVE = &H1
    AD_APPLY_HTMLGEN = &H2
    AD_APPLY_REFRESH = &H4
    AD_APPLY_ALL = &H7
    AD_APPLY_FORCE = &H8
    AD_APPLY_BUFFERED_REFRESH = &H10
    AD_APPLY_DYNAMICREFRESH = &H20
End Enum
 
' Универсальная функция изменения обоев на рабочем столе
Public Function SetWallpaperUniversal(ByVal FileName As String) As Boolean
    If SetWallpaper(FileName) = False Then
        If ActiveDesktopSetWallpaper(FileName) = True Then
            SetWallpaperUniversal = True
        End If
    Else
        SetWallpaperUniversal = True
    End If
End Function
 
' Изменение обоев на рабочем столе
Public Function SetWallpaper(ByVal FileName As String) As Boolean
    Dim RetVal As Long
    
    RetVal = SystemParametersInfoW(SETDESKWALLPAPER, 0, StrPtr(FileName), UPDATEINIFILE)
    If RetVal = 1 Then SetWallpaper = True
End Function
 
' Изменение обоев на рабочем столе с помощью интерфейса IActiveDesktop
Public Function ActiveDesktopSetWallpaper(ByVal strFile As String) As Boolean
    Dim vtbl            As IActiveDesktop
    Dim vtblptr         As Long
    Dim classid         As GUID
    Dim iid             As GUID
    Dim obj             As Long
    Dim hRes            As Long
    
    ' CLSID (BSTR) to CLSID (GUID)
    hRes = IIDFromString(StrPtr(CLSID_ActiveDesktop), classid)
    If hRes <> 0 Then
        Exit Function
    End If
    
    ' IID (BSTR) to IID (GUID)
    hRes = IIDFromString(StrPtr(IID_ActiveDesktop), iid)
    If hRes <> 0 Then
        Exit Function
    End If
    
    ' Создать экземпляр IActiveDesktop
    ' (Set IActiveDesktop = New IActiveDesktop)
    hRes = CoCreateInstance(classid, 0, CLSCTX_INPROC_SERVER, iid, VarPtr(obj))
    If hRes <> 0 Then
        Exit Function
    End If
    
    GetMem4 ByVal obj, vtblptr
    RtlMoveMemory vtbl, ByVal vtblptr, Len(vtbl)
    
    ' IActiveDesktop::SetWallpaper
    ' Первым параметром всегда является указатель на объект
    ' Возвращаемое значение всегда должно быть HRESULT (0 = S_OK)
    hRes = CallPointer(vtbl.SetWallpaper, obj, StrPtr(strFile), 0)
    If hRes = 0 Then
        ActiveDesktopSetWallpaper = True
    End If
    
    ' IActiveDesktop::ApplyChanges
    hRes = CallPointer(vtbl.ApplyChanges, obj, AD_APPLY_ALL Or AD_APPLY_FORCE)
    
    ' Освободить память
    ' (Set IActiveDesktop = Nothing)
    CallPointer vtbl.Release, obj
End Function
 
Private Function CallPointer(ByVal fnc As Long, ParamArray params()) As Long
    Dim btASM(&HEC00& - 1)  As Byte
    Dim pASM                As Long
    Dim i                   As Integer
    
    pASM = VarPtr(btASM(0))
    
    AddByte pASM, &H58                  ' POP EAX
    AddByte pASM, &H59                  ' POP ECX
    AddByte pASM, &H59                  ' POP ECX
    AddByte pASM, &H59                  ' POP ECX
    AddByte pASM, &H59                  ' POP ECX
    AddByte pASM, &H50                  ' PUSH EAX
    
    For i = UBound(params) To 0 Step -1
        AddPush pASM, CLng(params(i))   ' PUSH dword
    Next
    
    AddCall pASM, fnc                   ' CALL rel addr
    AddByte pASM, &HC3                  ' RET
    
    CallPointer = CallWindowProcA(VarPtr(btASM(0)), 0, 0, 0, 0)
End Function
 
Private Sub AddPush(pASM As Long, lng As Long)
    AddByte pASM, &H68
    AddLong pASM, lng
End Sub
 
Private Sub AddCall(pASM As Long, addr As Long)
    AddByte pASM, &HE8
    AddLong pASM, addr - pASM - 4
End Sub
 
Private Sub AddLong(pASM As Long, lng As Long)
    GetMem4 lng, ByVal pASM
    pASM = pASM + 4
End Sub
 
Private Sub AddByte(pASM As Long, bt As Byte)
    GetMem1 bt, ByVal pASM
    pASM = pASM + 1
End Sub
Я немного усовершенствовал функцию, оптимизировал слега заменив в некоторых местах CopyMemory на GetMem4 и GetMem1 там где идёт ассемблерная вставка этого гениального кода)
Вложения
Тип файла: zip Изменение обоев на рабочем столе 3.0.zip (4.1 Кб, 10 просмотров)
1
Вернулся
 Аватар для HackerVlad
1753 / 649 / 45
Регистрация: 10.09.2021
Сообщений: 2,801
02.08.2023, 00:09  [ТС]
Я обнаружил, что функция ActiveDesktopSetWallpaper не работает в P-коде есть такой минус... Только, если компилировать EXE в Native коде. Это странно, учитывая, что в среде выполнения VB6 всё работает как надо

Добавлено через 15 минут
Самая новая версия тут: Готовые решения и полезные коды на Visual Basic 6.0
Всё работает как надо. Вроде всё исправил и добавил проверку на существования файла.

Добавлено через 4 минуты
Должно работать для всех версий Windows по идее.
0
Вернулся
 Аватар для HackerVlad
1753 / 649 / 45
Регистрация: 10.09.2021
Сообщений: 2,801
08.07.2024, 21:15  [ТС]
Цитата Сообщение от testuser2 Посмотреть сообщение
Да не очень универсальны способ, у людей может быть и китайская винда, и люди могут нарукоблудить с контекстным меню, тогда метод не сработает.
Возрадуйся! Был найден универсальный способ для смены картинки на рабочем столе, замена твой процедуры ПоменятьОбои:

Visual Basic
1
2
3
4
5
6
7
8
9
10
11
Sub SetWallpaper(FileName)    
    On Error Resume Next
    Set oShA = oShA.Windows.Item.document.Application
    If Not IsObject(oSHA) Then _
    Set oShA = GetObject("new:{C08AFD90-F2A1-11D1-8455-00A0C91F3880}").document.Application
    On Error GoTo 0: Er = Not IsObject(oSHA)
    If Er Then Set oShA = CreateObject("Shell.Application")
    oShA.NameSpace(0).ParseName(FileName).InvokeVerb "setdesktopwallpaper"
    If Er Then WSH.Sleep 4000
    Set oFSO = Nothing: Set oShA = Nothing
End Sub
Но работает только начиная от семёрки конечно же (не проверял может и в Vista, в хрюшке точно не работает)
Теперь с этим новым кодом, уже будет не важно русская винда или английская или вообще китайская какая-нибудь...
Автор этого кода FlasherX. Тема: Смена обоев рабочего стола
1
1407 / 866 / 93
Регистрация: 08.02.2017
Сообщений: 3,697
Записей в блоге: 2
09.07.2024, 05:56
Цитата Сообщение от HackerVlad Посмотреть сообщение
Ура! Я наконец-то написал модуль с универсальной функций смены картинки на рабочем столе:
Реально обоср**ся столько кода чтобы сменить валпейпер? Какие-то неимоверные структуры, pASM-ы, CLSIDы.. Это реально хакерский код

Добавлено через 3 минуты
но мене не нраится, это слишком выпендрежно
0
Вернулся
 Аватар для HackerVlad
1753 / 649 / 45
Регистрация: 10.09.2021
Сообщений: 2,801
09.07.2024, 05:57  [ТС]
testuser2, да, это самый лучший код с помощью ассемблерной вставки
0
7002 / 2886 / 1110
Регистрация: 06.06.2017
Сообщений: 9,813
10.07.2024, 19:13
Цитата Сообщение от HackerVlad Посмотреть сообщение
Автор этого кода FlasherX.
Не кода, а подхода. Тут же отсутствует необходимая строка с объявлением oShA, которая есть в моём. В другой теме писал об этом.
1
Вернулся
 Аватар для HackerVlad
1753 / 649 / 45
Регистрация: 10.09.2021
Сообщений: 2,801
15.07.2024, 08:45  [ТС]
Вот более правильный код:

Visual Basic
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
Public Sub SetWallpaperFlasherX(FileName)
    Dim oShA, Er, oFSO
    
    Set oShA = CreateObject("Shell.Application")
    
    On Error Resume Next
    Set oShA = oShA.Windows.Item.document.Application
    If Not IsObject(oShA) Then _
    Set oShA = GetObject("new:{C08AFD90-F2A1-11D1-8455-00A0C91F3880}").document.Application
    On Error GoTo 0: Er = Not IsObject(oShA)
    If Er Then Set oShA = CreateObject("Shell.Application")
    oShA.NameSpace(0).ParseName(FileName).InvokeVerb "setdesktopwallpaper"
    
    Set oShA = Nothing
End Sub
Добавлено через 32 минуты
Единственное в чём я не разобрался это как включить красивое плавное появление картинки на рабочем столе с fade эффектом? Дело в том, что пока я сам вручную не поменяю картинку на рабочем столе через меню "Персонализация" красивого эффекта смены картинки не будет...

А как только я хотябы один раз поменяю картинку вручную то и потом всегда будет красиво меняться картинка через интерфейс IActiveDesktop

Это странное поведение мною ещё пока не разгадано...

Добавлено через 7 минут
И главное что в MSDN нет такого описания...

Добавлено через 13 минут
Конечно для VB такого кода нигде нет, как обычно, но я выяснил, что нужно сначала включать ActiveDesktop специальным хаком, через функцию EnableActiveDesktop, это код на сях:

C#
1
2
3
4
5
public static void EnableActiveDesktop()
{
    IntPtr result = IntPtr.Zero;
    WinAPI.SendMessageTimeout(WinAPI.FindWindow("Progman", null), 0x52c, IntPtr.Zero, IntPtr.Zero, 0, 500, out result);
}
Перепишем его на VB и думаю может заработает

Добавлено через 9 минут
Итак мы переписали этот код на VB6:

Visual Basic
1
2
3
4
5
6
7
8
Private Declare Function SendMessageTimeout Lib "user32" Alias "SendMessageTimeoutA" (ByVal hwnd As Long, ByVal msg As Long, ByVal wParam As Long, ByVal lParam As Long, ByVal fuFlags As Long, ByVal uTimeout As Long, lpdwResult As Long) As Long
Private Declare Function FindWindow Lib "user32" Alias "FindWindowA" (ByVal lpClassName As String, ByVal lpWindowName As String) As Long
 
Public Sub EnableActiveDesktop()
    Dim result As Long
    
    SendMessageTimeout FindWindow("Progman", vbNullString), &H52C, ByVal 0&, ByVal 0&, ByVal 0&, 500, result
End Sub
Добавлено через 5 минут
И это реально работает!!! Ура!!! Теперь нужно сначала только один раз вызвать EnableActiveDesktop и всё, и потом всякий раз картинка на рабочем столе будет меняться плавно с красивым fade эффектом.
0
Вернулся
 Аватар для HackerVlad
1753 / 649 / 45
Регистрация: 10.09.2021
Сообщений: 2,801
15.07.2024, 10:19  [ТС]
Вот окончательный вариант моего творчества:

Visual Basic
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
Option Explicit
'/////////////////////////////////////////////////
'// Модуль для изменения обоев на рабочем столе //
'// Copyright (c) 15.07.2024 by HackerVlad      //
'// e-mail: vladislavpeshkov@yandex.ru          //
'// Версия 3.5                                  //
'/////////////////////////////////////////////////
 
' Декларации API...
Private Declare Function SystemParametersInfoW Lib "user32" (ByVal uAction As Long, ByVal uParam As Long, ByVal lpvParam As Long, ByVal fuWinIni As Long) As Long
Private Declare Function IIDFromString Lib "ole32" (ByVal lpszIID As Long, iid As Any) As Long
Private Declare Function CoCreateInstance Lib "ole32" (rclsid As Any, ByVal pUnkOuter As Long, ByVal dwClsContext As Long, riid As Any, ByVal ppv As Long) As Long
Private Declare Function CallWindowProcA Lib "user32" (ByVal addr As Long, ByVal p1 As Long, ByVal p2 As Long, ByVal p3 As Long, ByVal p4 As Long) As Long
Private Declare Sub RtlMoveMemory Lib "kernel32" (pDst As Any, pSrc As Any, ByVal dlen As Long)
Private Declare Function GetMem4 Lib "msvbvm60" (srcAddr As Any, dstValue As Long) As Long
Private Declare Function GetMem1 Lib "msvbvm60" (srcAddr As Any, dstValue As Long) As Long
Private Declare Function IsFileAPI Lib "shlwapi" Alias "PathFileExistsW" (ByVal pszPath As Long) As Long
Private Declare Function SendMessageTimeout Lib "user32" Alias "SendMessageTimeoutA" (ByVal hwnd As Long, ByVal msg As Long, ByVal wParam As Long, ByVal lParam As Long, ByVal fuFlags As Long, ByVal uTimeout As Long, lpdwResult As Long) As Long
Private Declare Function FindWindow Lib "user32" Alias "FindWindowA" (ByVal lpClassName As String, ByVal lpWindowName As String) As Long
 
' Константы
Private Const SETDESKWALLPAPER = &H14
Private Const SPI_GETDESKWALLPAPER = 115
Private Const MAX_PATH As Long = 260
Private Const UPDATEINIFILE = &H1
Private Const CLSCTX_INPROC_SERVER  As Long = 1
Private Const CLSID_ActiveDesktop   As String = "{75048700-EF1F-11D0-9888-006097DEACF9}"
Private Const IID_ActiveDesktop     As String = "{F490EB00-1240-11D1-9888-006097DEACF9}"
 
Private Type GUID
    data1                   As Long
    data2                   As Integer
    data3                   As Integer
    data4(7)                As Byte
End Type
 
Private Type IActiveDesktop
    ' IUnknown
    QueryInterface          As Long
    AddRef                  As Long
    Release                 As Long
    ' IActiveDesktop
    ApplyChanges            As Long
    GetWallpaper            As Long
    SetWallpaper            As Long
    GetWallpaperOptions     As Long
    SetWallpaperOptions     As Long
    GetPattern              As Long
    SetPattern              As Long
    GetDesktopItemOptions   As Long
    SetDesktopItemOptions   As Long
    AddDesktopItem          As Long
    AddDesktopItemWithUI    As Long
    ModifyDesktopItem       As Long
    RemoveDesktopItem       As Long
    GetDesktopItemCount     As Long
    GetDesktopItem          As Long
    GetDesktopItemByID      As Long
    GenerateDesktopItemHtml As Long
    AddUrl                  As Long
    GetDesktopItemBySource  As Long
End Type
 
Private Enum AD_APPLY
    AD_APPLY_SAVE = &H1
    AD_APPLY_HTMLGEN = &H2
    AD_APPLY_REFRESH = &H4
    AD_APPLY_ALL = &H7
    AD_APPLY_FORCE = &H8
    AD_APPLY_BUFFERED_REFRESH = &H10
    AD_APPLY_DYNAMICREFRESH = &H20
End Enum
 
' Универсальная функция изменения обоев на рабочем столе
Public Function SetWallpaperUniversal(ByVal FileName As String) As Boolean
    If IsFileAPI(StrPtr(FileName)) = 0 Then ' Файл не существует, с вероятностью 99%
        Exit Function
    End If
    
    If SetWallpaper(FileName) = False Then
        If ActiveDesktopSetWallpaper(FileName) = True Then
            SetWallpaperUniversal = True
        End If
    Else
        SetWallpaperUniversal = True
    End If
End Function
 
' Изменение обоев на рабочем столе
Public Function SetWallpaper(ByVal FileName As String) As Boolean
    Dim RetVal As Long
    
    RetVal = SystemParametersInfoW(SETDESKWALLPAPER, 0, StrPtr(FileName), UPDATEINIFILE)
    If RetVal = 1 Then SetWallpaper = True
End Function
 
' Получение пути и имени файла к обоям на рабочем столе
Public Function GetWallpaper() As String
    Dim RetVal As Long
    Dim str As String
    Dim lNullPos As Long
    
    str = Space$(MAX_PATH)
    
    RetVal = SystemParametersInfoW(SPI_GETDESKWALLPAPER, MAX_PATH, StrPtr(str), 0)
    
    If RetVal Then
        lNullPos = InStr(1, str, vbNullChar)
        If lNullPos Then
            str = Left$(str, lNullPos - 1)
        End If
        GetWallpaper = str
    End If
End Function
 
' Включить ActiveDesktop для того чтобы картинка на рабочем столе появлялась с красивым fade эффектом
Public Sub EnableActiveDesktop()
    Dim result As Long
    
    SendMessageTimeout FindWindow("Progman", vbNullString), &H52C, ByVal 0&, ByVal 0&, ByVal 0&, 500, result
End Sub
 
' Изменение обоев на рабочем столе с помощью интерфейса IActiveDesktop
Public Function ActiveDesktopSetWallpaper(ByVal strFile As String) As Boolean
    Dim vtbl            As IActiveDesktop
    Dim vtblptr         As Long
    Dim classid         As GUID
    Dim iid             As GUID
    Dim obj             As Long
    Dim hRes            As Long
    
    If IsFileAPI(StrPtr(strFile)) = 0 Then ' Файл не существует, с вероятностью 99%
        Exit Function
    End If
    
    ' CLSID (BSTR) to CLSID (GUID)
    hRes = IIDFromString(StrPtr(CLSID_ActiveDesktop), classid)
    If hRes <> 0 Then
        Exit Function
    End If
    
    ' IID (BSTR) to IID (GUID)
    hRes = IIDFromString(StrPtr(IID_ActiveDesktop), iid)
    If hRes <> 0 Then
        Exit Function
    End If
    
    ' Создать экземпляр IActiveDesktop
    ' (Set IActiveDesktop = New IActiveDesktop)
    hRes = CoCreateInstance(classid, 0, CLSCTX_INPROC_SERVER, iid, VarPtr(obj))
    If hRes <> 0 Then
        Exit Function
    End If
    
    GetMem4 ByVal obj, vtblptr
    RtlMoveMemory vtbl, ByVal vtblptr, Len(vtbl)
    
    ' IActiveDesktop::SetWallpaper
    ' Первым параметром всегда является указатель на объект
    ' Возвращаемое значение всегда должно быть HRESULT (0 = S_OK)
    hRes = CallPointer(vtbl.SetWallpaper, obj, StrPtr(strFile), 0)
    If hRes = 0 Then
        ActiveDesktopSetWallpaper = True
    End If
    
    ' IActiveDesktop::ApplyChanges
    hRes = CallPointer(vtbl.ApplyChanges, obj, AD_APPLY_ALL Or AD_APPLY_FORCE Or AD_APPLY_BUFFERED_REFRESH)
    
    ' Освободить память
    ' (Set IActiveDesktop = Nothing)
    CallPointer vtbl.Release, obj
End Function
 
Private Function CallPointer(ByVal fnc As Long, ParamArray params()) As Long
    Dim btASM(&HEC00& - 1)  As Byte
    Dim pASM                As Long
    Dim i                   As Integer
    
    pASM = VarPtr(btASM(0))
    
    AddByte pASM, &H58                  ' POP EAX
    AddByte pASM, &H59                  ' POP ECX
    AddByte pASM, &H59                  ' POP ECX
    AddByte pASM, &H59                  ' POP ECX
    AddByte pASM, &H59                  ' POP ECX
    AddByte pASM, &H50                  ' PUSH EAX
    
    For i = UBound(params) To 0 Step -1
        AddPush pASM, CLng(params(i))   ' PUSH dword
    Next
    
    AddCall pASM, fnc                   ' CALL rel addr
    AddByte pASM, &HC3                  ' RET
    
    CallPointer = CallWindowProcA(VarPtr(btASM(0)), 0, 0, 0, 0)
End Function
 
Private Sub AddPush(pASM As Long, lng As Long)
    AddByte pASM, &H68
    AddLong pASM, lng
End Sub
 
Private Sub AddCall(pASM As Long, addr As Long)
    AddByte pASM, &HE8
    AddLong pASM, addr - pASM - 4
End Sub
 
Private Sub AddLong(pASM As Long, lng As Long)
    GetMem4 lng, ByVal pASM
    pASM = pASM + 4
End Sub
 
Private Sub AddByte(pASM As Long, bt As Byte)
    GetMem1 bt, ByVal pASM
    pASM = pASM + 1
End Sub
Вложения
Тип файла: zip Изменение обоев на рабочем столе 3.5.zip (12.0 Кб, 8 просмотров)
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
BasicMan
Эксперт
29316 / 5623 / 2384
Регистрация: 17.02.2009
Сообщений: 30,364
Блог
15.07.2024, 10:19

Как программно создать иконку на рабочем столе?
Как программным путем создать иконку на рабочем столе?

Как скопировать все *.jpg файлы с рабочего стола в папку на рабочем столе, не зная имени пользователя в пути?
Как скопировать все *.jpg файлы с рабочего стола в папку на рабочем столе, не зная имени пользователя в пути? Читал про...

Как поменять обои на рабочем столе?
есть проблема очень глупая,но которую не могут решить уже несколько человек((на новом буке стоит винда 7,не можем найти где поменять...

Как поменять рисунок на рабочем столе.
Здравствуйте! Помогите, пожалуйста, написать программу, которая меняет рисунок на рабочем столе. Новый рисунок надо, наверное, выбирать...

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


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
34
Ответ Создать тему
Опции темы

Новые блоги и статьи
Термопринтер QR701
Argus19 03.08.2026
Термопринтер QR701 Купил два термопринтера QR701. На сэлф-тесте написано: Language: PC936 (GB18030). Что означает, что принтеры могут печатать только латиницу и китайские иероглифы. Так же. . .
Создание формы заимствованного документа
Maks 03.08.2026
Задача: Необходимо создать собственную форму заимствованного документа. На форме должен быть реквизит "Покупатель", а также табличная часть со следующими реквизитами: - Расчетный счет покупателя. . .
Задача предоставления скидок покупателям
Maks 03.08.2026
Задача: В документе "Продажи" необходимо реализовать функционал предоставления скидок покупателям. Скидка должна автоматически рассчитываться и подставляться в соответствующее поле при выборе. . .
Почему SEO не начинается с ключевых слов: что проверить до написания текстов
Neotwalker 01.08.2026
Когда владельцу сайта предлагают заняться SEO, первым шагом часто становится сбор запросов и написание текстов. Логика кажется понятной: 1. Находим ключевые слова. 2. Добавляем их на. . .
Знание — сила: Доктрина интенциональности знаний, углубление в формулу
Hrethgir 01.08.2026
https:/ / www. cyberforum. ru/ blog_attachment. php?attachmentid=11957&stc=1&d=1785567302 Знаменитый афоризм Фрэнсиса Бэкона «Знание — сила» (Scientia potentia est) в массовой культуре принято понимать. . .
SUNO Ai - Река Без Дна
zorxor 31.07.2026
Автор стихотворения - астрофизик Марина Катыс Ссылка на сгенерированную музыкальную композицию: https:/ / suno. com/ song/ 6f6e5464-b290-4650-be6c-44c85f8d8013 Я говорю, что Время- как вода течет. . .
Из невошедшего на форум (диалог с ИИ-гугла)
zorxor 29.07.2026
А вот, что интересно, сказал мне ИИ-гугла: Этот текст — эмоциональный пост пользователя под ником zorxor на интернет-форуме (вероятно, посвященном мистике, непознанному или альтернативной науке). . . .
Был праздник вчера, а я и не знал.
kumehtar 28.07.2026
27. 07. 2026г. Intel Core 2 Duo исполнилось 20 лет Салют, шампанское, овации! :drink:
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru