Форум программистов, компьютерный форум, киберфорум
Visual Basic
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
 
Рейтинг 4.56/9: Рейтинг темы: голосов - 9, средняя оценка - 4.56
Вернулся
 Аватар для HackerVlad
1748 / 644 / 45
Регистрация: 10.09.2021
Сообщений: 2,786

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

30.07.2023, 20:16. Показов 2383. Ответов 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
1748 / 644 / 45
Регистрация: 10.09.2021
Сообщений: 2,786
31.07.2023, 19:59  [ТС]
Студворк — интернет-сервис помощи студентам
I can, спасибо большое в семёрке работает со всеми форматами файлов, сейчас в XP ещё проверю будет ли работать...

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

Добавлено через 1 минуту
Цитата Сообщение от I can Посмотреть сообщение
сам не могу проверить - у меня десятка
а почему в десятке не можешь проверить)
0
dive
 Аватар для I can
4976 / 4689 / 848
Регистрация: 13.04.2015
Сообщений: 9,902
31.07.2023, 20:44
Цитата Сообщение от HackerVlad Посмотреть сообщение
а почему в десятке не можешь проверить)
Отмазка такая На самом деле просто лень
0
Вернулся
 Аватар для HackerVlad
1748 / 644 / 45
Регистрация: 10.09.2021
Сообщений: 2,786
31.07.2023, 20:59  [ТС]
Цитата Сообщение от I can Посмотреть сообщение
Отмазка такая На самом деле просто лень
Да всё работает отлично

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

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

Добавлено через 1 минуту
Исполнение функции SystemParametersInfo занимает в среднем 93 миллисекунды времени
0
Вернулся
 Аватар для HackerVlad
1748 / 644 / 45
Регистрация: 10.09.2021
Сообщений: 2,786
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
1748 / 644 / 45
Регистрация: 10.09.2021
Сообщений: 2,786
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
1748 / 644 / 45
Регистрация: 10.09.2021
Сообщений: 2,786
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
1748 / 644 / 45
Регистрация: 10.09.2021
Сообщений: 2,786
02.08.2023, 00:09  [ТС]
Я обнаружил, что функция ActiveDesktopSetWallpaper не работает в P-коде есть такой минус... Только, если компилировать EXE в Native коде. Это странно, учитывая, что в среде выполнения VB6 всё работает как надо

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

Добавлено через 4 минуты
Должно работать для всех версий Windows по идее.
0
Вернулся
 Аватар для HackerVlad
1748 / 644 / 45
Регистрация: 10.09.2021
Сообщений: 2,786
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
1400 / 858 / 92
Регистрация: 08.02.2017
Сообщений: 3,642
Записей в блоге: 2
09.07.2024, 05:56
Цитата Сообщение от HackerVlad Посмотреть сообщение
Ура! Я наконец-то написал модуль с универсальной функций смены картинки на рабочем столе:
Реально обоср**ся столько кода чтобы сменить валпейпер? Какие-то неимоверные структуры, pASM-ы, CLSIDы.. Это реально хакерский код

Добавлено через 3 минуты
но мене не нраится, это слишком выпендрежно
0
Вернулся
 Аватар для HackerVlad
1748 / 644 / 45
Регистрация: 10.09.2021
Сообщений: 2,786
09.07.2024, 05:57  [ТС]
testuser2, да, это самый лучший код с помощью ассемблерной вставки
0
6999 / 2884 / 1109
Регистрация: 06.06.2017
Сообщений: 9,802
10.07.2024, 19:13
Цитата Сообщение от HackerVlad Посмотреть сообщение
Автор этого кода FlasherX.
Не кода, а подхода. Тут же отсутствует необходимая строка с объявлением oShA, которая есть в моём. В другой теме писал об этом.
1
Вернулся
 Аватар для HackerVlad
1748 / 644 / 45
Регистрация: 10.09.2021
Сообщений: 2,786
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
1748 / 644 / 45
Регистрация: 10.09.2021
Сообщений: 2,786
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
Ответ Создать тему
Новые блоги и статьи
[golang] Алгоритм «Хак Госпера»
alhaos 17.05.2026
Алгоритм «Хак Госпера» Хак Госпера (Gosper's Hack) — алгоритм нахождения следующего по величине числа с тем же количеством установленных бит. Придуман Биллом Госпером в 1970-х, опубликован в. . .
Рисование бинарного древа до 6-го колена на js, svg.
russiannick 17.05.2026
<svg width="335" height="240" viewBox="0 0 335 240" fill="#e5e1bb"> <style> <!]> </ style> <g id="bush"> </ g> </ svg> function fn(){ let rost;/ / высота древа let xx=165,yy=210,w=256;
FSharp: interface of module
DevAlt 16.05.2026
Интерфейс модуля F# позволяет управлять доступностью членов, содержащихся в реализации модуля. По-умолчанию все члены модуля доступны: module Foo let x = 10 let boo () = printfn "boo" . . .
Хитросплетение родственных связей пантеона греческих богов.
russiannick 14.05.2026
Однооконник, позволяющий узреть и изучить отдельных героев древней Греции. <!DOCTYPE html> <html lang="ru"> <head> <meta charset="UTF-8"> <meta http-equiv="X-UA-Compatible". . .
[golang] Угол между стрелками часов
alhaos 12.05.2026
По заданным значениям часа и минуты необходимо определить значение меньшего угла между стрелками аналогового циферблата часов. import "math" func angleClock(hour int, minutes int) float64 { . . .
Debian 13: Установка Lazarus QT5
ВитГо 09.05.2026
Эта инструкция моя компиляция инструкций volvo https:/ / www. cyberforum. ru/ blogs/ 203668/ 10753. html и его же старой инструкции по установке Lazarus с gtk2. . .
Нейросеть на алгоритме "эстафета хвоста" как перспектива.
Hrethgir 06.05.2026
На десерт, когда запущу сервер. Статья тут https:/ / habr. com/ ru/ articles/ 1030914/ . Автор я сам, нейросеть только помогает в вопросах которые мне не известны - не знаю людей которые знали-бы. . .
Асинхронный приём данных из COM-порта
Argus19 01.05.2026
Асинхронный приём данных из COM-порта Купил на aliexpress термопринтер QR701. Он оказался странным. Поключил к Arduino Nano. Был очень удивлён. Наотрез отказывается печатать русские буквы. Чтобы. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru