狂自私

导航

C++ 使用指定目录的图片设置壁纸,并输出图片名称

写这个是因为目录中的壁纸图片太多了,有些我不喜欢,有些我喜欢,但是我也不想专门去一张一张的筛选,就写了这么个小东西,我看到不喜欢的壁纸了,就看看当前是哪张壁纸,找到后删除掉。

也试过其他办法,比如找到Windows的壁纸目录,但是壁纸文件到了那边之后就被修改名字了,我压根不知道这张壁纸在原来的目录的哪个位置。

 

#include <locale>
#include <Windows.h>    //设置壁纸
#include <iostream>
#include <string>
#include <io.h>            //获取目录下的文件列表
#include <random>

enum class WallpaperStyle
{
    Tile = 0,       //平铺
    Center = 1,     //居中
    Stretch = 2,    //拉伸
    Fit = 3,        //适应
    Fill = 4        //填充
};

HRESULT SetDesktopEallpaper(wchar_t* pszFile, WallpaperStyle style) {
    HRESULT hr = S_OK;

    //以可读写的方式打开HKCU\Control Panel\Desktop注册表项
    HKEY hkey = NULL;
    hr = HRESULT_FROM_WIN32(RegOpenKeyEx(HKEY_CURRENT_USER, L"Control Panel\\Desktop", 0, KEY_READ | KEY_WRITE, &hkey));
    if (SUCCEEDED(hr)) {
        PWSTR pszWallpaperStyle{}, pszTileWallpaper{};
        WCHAR WallpaperStyle[][3] = { L"0" ,L"1",L"2", L"6",L"10" };
        //std::wstring WallpaperStyle[]{ L"0" ,L"1",L"2", L"6",L"10" };
        switch (style)
        {
        case WallpaperStyle::Tile:
            pszWallpaperStyle = WallpaperStyle[0];
            pszTileWallpaper = WallpaperStyle[1];
            break;
        case WallpaperStyle::Center:
            pszWallpaperStyle = WallpaperStyle[0];
            pszTileWallpaper = WallpaperStyle[0];
            break;
        case WallpaperStyle::Stretch:
            pszWallpaperStyle = WallpaperStyle[2];
            pszTileWallpaper = WallpaperStyle[0];
            break;
        case WallpaperStyle::Fit:
            pszWallpaperStyle = WallpaperStyle[3];
            pszTileWallpaper = WallpaperStyle[0];
            break;
        case WallpaperStyle::Fill:
            pszWallpaperStyle = WallpaperStyle[4];
            pszTileWallpaper = WallpaperStyle[0];
            break;
        default:
            pszWallpaperStyle = WallpaperStyle[4];
            pszTileWallpaper = WallpaperStyle[0];
            break;
        }
        //设置pszWallpaperStyle和pszTileWallpaper到注册表项中
        DWORD cdData = lstrlen(pszWallpaperStyle) * sizeof(*pszWallpaperStyle);
        hr = HRESULT_FROM_WIN32(RegSetValueEx(hkey, L"WallpaperStyle", 0, REG_SZ, reinterpret_cast<const BYTE*>(pszWallpaperStyle), cdData));
        if (SUCCEEDED(hr)) {
            cdData = lstrlen(pszTileWallpaper) * sizeof(*pszTileWallpaper);
            hr = HRESULT_FROM_WIN32(RegSetValueEx(hkey, L"pszTileWallpaper", 0, REG_SZ, reinterpret_cast<const BYTE*>(pszTileWallpaper), cdData));
        }
        RegCloseKey(hkey);
    }
    else {
        std::cout << "打开注册表失败,错误码:" << GetLastError() << std::endl;

        return hr;
    }
    //通过调用Windows 32api 函数SystemParametersInfo  设置桌面壁纸
    //SPI_SETDESKWALLPAPER使得壁纸改变保存并持续可见;
    if (SUCCEEDED(hr)) {
        if (!SystemParametersInfo(SPI_SETDESKWALLPAPER, 0, static_cast<PVOID>(pszFile), SPIF_UPDATEINIFILE | SPIF_SENDWININICHANGE)) {
            //实际上,根据微软自己的文档说明,当SystemParametersInfo函数的第一个参数指定为SPI_SETDESKWALLPAPER时,函数总会返回True;
            //若是文件不存在,权限不够等情况,会使得桌面纯黑色,这样的情况也不会使得函数返回false;
            hr = HRESULT_FROM_WIN32(GetLastError());
        }
    }
    return hr;
}

//获取指定目录下的文件数量
unsigned int getFileNumber(std::wstring& path) {
    WIN32_FIND_DATAW stFD{};    //存放文件信息的结构体
    HANDLE h_handle{};
    std::wstring temp = path + L"\\*.jpg";    //查找jpg文件;
    unsigned int num{ 1 };


    h_handle = FindFirstFileW(temp.c_str(), &stFD);
    if (INVALID_HANDLE_VALUE == h_handle) {
        //查找失败
        std::cout << "查找失败,错误代码:" << GetLastError() << std::endl;
        return    EXIT_FAILURE;
    }
    while (FindNextFileW(h_handle, &stFD)) {
        //继续查找下一个符合条件的文件
        //因为后缀的原因,找到的文件不可能是个目录,所以没有写处理目录的情况的代码
        num++;
    }
    return num;
}
//获取指定目录下的文件名,使用new分配内存
std::wstring* getFileNames(std::wstring& path, unsigned int num) {
    if (num == 0) {
        return nullptr;
    }
    std::wstring* ret = new std::wstring[num]{};
    WIN32_FIND_DATAW stFD{};    //存放文件信息的结构体
    HANDLE h_handle{};
    std::wstring temp = path + L"\\*.jpg";    //查找jpg文件;
    unsigned int index{};

    h_handle = FindFirstFileW(temp.c_str(), &stFD);
    if (INVALID_HANDLE_VALUE == h_handle) {
        //查找失败
        std::cout << "查找失败,错误代码:" << GetLastError() << std::endl;
        delete[]ret;
        return nullptr;
    }
    else {
        ret[index] = stFD.cFileName;
        index += 2;         //强迫症犯了,后面的ret[index-1] = stFD.cFileName;,下标必须-1,不然就有警告说可能会越界~
    }
    while (FindNextFileW(h_handle, &stFD)) {
        //继续查找下一个符合条件的文件
        //因为后缀的原因,找到的文件不可能是个目录,所以没有写处理目录的情况的代码
        ret[index-1] = stFD.cFileName;
        index++;
    }
    return ret;
}
//检查文件是否存在
bool FindFirstFileExists(std::wstring& path)
{
    WIN32_FIND_DATAW stFD{};    //存放文件信息的结构体

    HANDLE hFind = FindFirstFile(path.c_str(), &stFD);
    if (INVALID_HANDLE_VALUE == hFind) {
        //查找失败,文件不存在
        //std::cout << "文件查找失败,错误代码:" << GetLastError() << std::endl;
        return    false;
    }
    else {
        return true;
    }
}
int main(void) {
    std::locale::global(std::locale(""));

    std::wstring* pathList{};
    std::wstring path = LR"(C:\Users\gyj\Pictures\美女)";
    unsigned int fileNum{};
    WallpaperStyle style{ WallpaperStyle::Fill };
    PWSTR filePath{};
    std::wstring picPath = path + L"\\";
    std::random_device rd;                        // 非确定性生成器
    std::mt19937 gen(rd());                        // 将随机数种子传递过去
    while (true)
    {
        fileNum = getFileNumber(path);
        std::wcout << L"文件数量:" << fileNum << std::endl;
        pathList = getFileNames(path, fileNum);

        if (pathList != nullptr) 
        {
            for (unsigned int i{}; i < fileNum; i++) {
                std::uniform_int_distribution<> dist(0, fileNum - 1);    //设置随机数范围
                unsigned int index = dist(gen); //生成随机数

                picPath += pathList[index];
                if (FindFirstFileExists(picPath)) {
                    Sleep(30*1000);        //30秒换一次壁纸
                    filePath = new WCHAR[picPath.size() + 1]{};
                    memcpy(filePath, picPath.c_str(), sizeof(wchar_t) * picPath.size());
                    unsigned long ret = SetDesktopEallpaper(filePath, style);
                    //std::wcout << L"filePath:" << filePath << L'\n';
                    std::wcout << pathList[index] << std::endl;
                    std::wcout << L"第:" << i << L"张。" << std::endl;
                    delete[] filePath;
                }
                else {
                    std::wcout << L"不存在:" << picPath << std::endl;
                }
                picPath = path + L"\\";
            }
        }
        else {
            std::wcout << L"pathList=nullptr\n" << L"path=" << path << L"\nfileNum:" << fileNum << std::endl;
        }
        delete[]pathList;
    }    

    return EXIT_SUCCESS;
}

 

posted on 2022-04-13 22:25  狂自私  阅读(203)  评论(0编辑  收藏  举报