2013-02-25 116 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