File indexing completed on 2025-01-05 03:53:17
0001 /* ============================================================ 0002 * 0003 * This file is a part of digiKam project 0004 * https://www.digikam.org 0005 * 0006 * Date : 2019-04-02 0007 * Description : plugin to export image as wallpaper - Windows version. 0008 * 0009 * SPDX-FileCopyrightText: 2019 by Igor Antropov <antropovi at yahoo dot com> 0010 * SPDX-FileCopyrightText: 2019-2024 by Gilles Caulier <caulier dot gilles at gmail dot com> 0011 * 0012 * SPDX-License-Identifier: GPL-2.0-or-later 0013 * 0014 * ============================================================ */ 0015 0016 #include "wallpaperplugin.h" 0017 0018 // Qt includes 0019 0020 #include <QMessageBox> 0021 #include <QProcess> 0022 #include <QDir> 0023 0024 // KDE includes 0025 0026 #include <klocalizedstring.h> 0027 0028 // Local includes 0029 0030 #include "digikam_debug.h" 0031 0032 // Windows includes 0033 0034 #ifdef Q_OS_WIN 0035 # include <windows.h> 0036 # include <wininet.h> 0037 # include <shlobj.h> 0038 #endif 0039 0040 namespace DigikamGenericWallpaperPlugin 0041 { 0042 0043 bool s_checkErrorCode(HRESULT status, const QString& path, const QString& context) 0044 { 0045 if (FAILED(status)) 0046 { 0047 // Code to catch error string from error code with Windows API. 0048 0049 LPWSTR bufPtr = nullptr; 0050 DWORD werr = GetLastError(); 0051 FormatMessageW(FORMAT_MESSAGE_ALLOCATE_BUFFER | 0052 FORMAT_MESSAGE_FROM_SYSTEM | 0053 FORMAT_MESSAGE_IGNORE_INSERTS, 0054 nullptr, 0055 werr, 0056 0, 0057 (LPWSTR)&bufPtr, 0058 0, 0059 nullptr); 0060 0061 // cppcheck-suppress knownConditionTrueFalse 0062 QString errStr = (bufPtr) ? QString::fromUtf16((const ushort*)bufPtr).trimmed() 0063 : i18n("Unknown Error %1", werr); 0064 LocalFree(bufPtr); 0065 0066 QMessageBox::warning(nullptr, 0067 i18nc("@title:window", 0068 "Error While to Set Image as Wallpaper"), 0069 i18n("Cannot change wallpaper image from current desktop with\n" 0070 "%1\n\nContext: %2\n\nError: %3", 0071 path, 0072 context, 0073 errStr)); 0074 0075 return false; 0076 } 0077 0078 return true; 0079 } 0080 0081 bool WallpaperPlugin::setWallpaper(const QString& path, int layout) const 0082 { 0083 // NOTE: IDesktopWallpaper is only defined with Windows >= 8. 0084 // To be compatible with Windows 7, we needs to use IActiveDesktop instead. 0085 0086 CoInitializeEx(0, COINIT_APARTMENTTHREADED); 0087 0088 IActiveDesktop* iADesktop = nullptr; 0089 HRESULT status = CoCreateInstance(CLSID_ActiveDesktop, 0090 nullptr, 0091 CLSCTX_INPROC_SERVER, 0092 IID_IActiveDesktop, 0093 (void**)&iADesktop); 0094 0095 if (!s_checkErrorCode(status, path, i18n("Cannot create desktop context."))) 0096 { 0097 CoUninitialize(); 0098 0099 return false; 0100 } 0101 0102 WALLPAPEROPT wOption; 0103 ZeroMemory(&wOption, sizeof(WALLPAPEROPT)); 0104 wOption.dwSize = sizeof(WALLPAPEROPT); 0105 0106 switch (layout) 0107 { 0108 case Mosaic: 0109 { 0110 wOption.dwStyle = WPSTYLE_TILE; 0111 break; 0112 } 0113 0114 case Centered: 0115 { 0116 wOption.dwStyle = WPSTYLE_CENTER; 0117 break; 0118 } 0119 0120 default: // *Adjusted* 0121 { 0122 wOption.dwStyle = WPSTYLE_STRETCH; 0123 break; 0124 } 0125 } 0126 0127 status = iADesktop->SetWallpaper((PCWSTR)QDir::toNativeSeparators(path).utf16(), 0); 0128 0129 if (!s_checkErrorCode(status, path, i18n("Cannot set wall paper image path."))) 0130 { 0131 iADesktop->Release(); 0132 CoUninitialize(); 0133 0134 return false; 0135 } 0136 0137 status = iADesktop->SetWallpaperOptions(&wOption, 0); 0138 0139 if (!s_checkErrorCode(status, path, i18n("Cannot set wallpaper properties."))) 0140 { 0141 iADesktop->Release(); 0142 CoUninitialize(); 0143 0144 return false; 0145 } 0146 0147 status = iADesktop->ApplyChanges(AD_APPLY_ALL); 0148 0149 if (!s_checkErrorCode(status, path, i18n("Cannot apply changes to desktop wallpaper."))) 0150 { 0151 iADesktop->Release(); 0152 CoUninitialize(); 0153 0154 return false; 0155 } 0156 0157 iADesktop->Release(); 0158 CoUninitialize(); 0159 0160 return true; 0161 } 0162 0163 } // namespace DigikamGenericWallpaperPlugin