我正在编写一个小程序,只需点击一下鼠标即可更改桌面背景。
我知道我可以右键单击任何图像文件并将其设置为桌面背景..
确切地说问题就在哪里开始。我无法在任何具有条目设置为桌面背景或甚至新桌面背景的dll中找到正确的条目。
我知道如何在注册表中创建那些,但我不想为此编辑注册表,而是我想在我的Tiny Program中设置它,所以只需两次点击我就可以控制所有图像文件在我的电脑上将它们显示为桌面背景。这来自任何文件夹,甚至来自任何连接的驱动器,无需返回个性化菜单。
如果你们中的任何人都知道我在哪里可以找到上述上下文菜单字符串的条目,那么我将非常感激。
这仅供个人使用,不得出售或赠送......
谢谢Chris
P.S。请原谅我英语不好,我来自非英语国家。
答案 0 :(得分:0)
如果你看一下,例如,HKEY_CLASSES_ROOT \ SystemFileAssociations.jpg \ Shell \ setdesktopwallpaper \ Command
您会注意到它已设置DelegateExecute成员。这意味着Windows将尝试在指定的DLL中使用IExecuteCommand接口。阅读MSDN上的内容并尝试模拟资源管理器,我想出了这个,它有效。
我不确定为什么需要Sleep(),如果有人能详细说明,我很乐意。
void SetWallpaper(LPCWSTR path)
{
const GUID CLSID_SetWallpaper = { 0xFF609CC7, 0xD34D, 0x4049, { 0xA1, 0xAA, 0x22, 0x93, 0x51, 0x7F, 0xFC, 0xC6 } };
HRESULT hr;
IExecuteCommand *executeCommand = nullptr;
IObjectWithSelection *objectWithSelection = nullptr;
IShellItemArray *shellItemArray = nullptr;
IShellFolder *rootFolder = nullptr;
LPITEMIDLIST idlist = nullptr;
// Initalize COM, probably shouldn't be done in this function
hr = CoInitialize(nullptr);
if (SUCCEEDED(hr))
{
// Get the IExecuteCommand interface of the DLL
hr = CoCreateInstance(CLSID_SetWallpaper, nullptr, CLSCTX_INPROC_SERVER, IID_IExecuteCommand, reinterpret_cast<LPVOID*>(&executeCommand));
// Get the IObjectWithSelection interface
if (SUCCEEDED(hr))
{
hr = executeCommand->QueryInterface(IID_IObjectWithSelection, reinterpret_cast<LPVOID*>(&objectWithSelection));
}
//
if (SUCCEEDED(hr))
{
hr = SHGetDesktopFolder(&rootFolder);
}
if (SUCCEEDED(hr))
{
hr = rootFolder->ParseDisplayName(nullptr, nullptr, (LPWSTR)path, nullptr, &idlist, NULL);
}
if (SUCCEEDED(hr))
{
hr = SHCreateShellItemArrayFromIDLists(1, (LPCITEMIDLIST*)&idlist, &shellItemArray);
}
if (SUCCEEDED(hr))
{
hr = objectWithSelection->SetSelection(shellItemArray);
}
if (SUCCEEDED(hr))
{
hr = executeCommand->Execute();
}
// There is probably some event, or something to wait for here, but we
// need to wait and relinquish control of the CPU, or the wallpaper won't
// change.
Sleep(2000);
// Release interfaces and memory
if (idlist)
{
CoTaskMemFree(idlist);
}
if (executeCommand)
{
executeCommand->Release();
}
if (objectWithSelection)
{
objectWithSelection->Release();
}
if (shellItemArray)
{
shellItemArray->Release();
}
if (rootFolder)
{
rootFolder->Release();
}
CoUninitialize();
}
}
编辑:在对此进行更多研究之后,为了我自己,我意识到stobject.dll实际上只是使用了IDesktopWallpaper接口;这是CLSID_DesktopWallpaper的一部分
http://msdn.microsoft.com/en-us/library/windows/desktop/hh706946(v=vs.85).aspx