2013-02-25 89 views
2

我正在写一个小程序更改桌面背景有一个或两个鼠标点击..Windows 8的设置为桌面背景

我知道,我可以右键点击任何图像文件,并将其设置为桌面背景。

确切地说,问题出现在哪里。我无法找到正确的条目在任何DLL将有条目设置为桌面背景甚至新的桌面背景。

我知道如何在注册表中创建这些注册表,但我不想为此编辑注册表,而是希望将它设置在我的Tiny程序中,因此只需两次点击即可控制所有图像我的电脑上的文件将其显示为桌面背景。并从任何文件夹或任何连接的驱动器,而不必返回到个性化菜单。

如果你们中的任何一个人都知道我在哪里可以找到上述上下文菜单字符串的条目,那么我会非常感激。

这仅仅是为个人使用,既不出售或放弃..

谢谢克里斯

附:请原谅我英语不好,我来自一个非英语国家的欧洲人。

回答

0

如果你看一下,例如,HKEY_CLASSES_ROOT \ SystemFileAssociations.jpg \壳牌\ setdesktopwallpaper \命令

你会发现,它有DelegateExecute成员集。这意味着Windows将尝试在指定的DLL中使用IExecuteCommand接口。阅读MSDN上的内容,并尝试模拟浏览器,我想出了这个,这是有效的。

我不知道为什么睡眠()是需要的,但如果有人可以详细说明,我很乐意。

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