2

マウスを 1 回または 2 回クリックするだけでデスクトップの背景を変更する小さなプログラムを作成しています。

画像ファイルを右クリックして、デスクトップの背景として設定できることを知っています..

そして、まさにそこから問題が始まります。Set As Desktop Background または New Desktop Background というエントリを持つ dll に適切なエントリが見つかりません。

レジストリでそれらを作成する方法は知っていますが、このためにレジストリを編集したくありません。むしろ、Tiny Program で正しく設定して、2 回クリックするだけでコンピュータ上のすべての画像ファイルを制御できるようにしたいのです。それらをデスクトップの背景として表示します。これは、任意のフォルダーから、または接続されているドライブからでも、個人用設定メニューに戻る必要はありません。

上記のコンテキスト メニューの文字列のエントリがどこにあるか知っている人がいれば、とても感謝しています。

これは個人的な使用のためのものであり、販売または譲渡するものではありません..

ありがとうクリス

PS 私の下手な英語を許してください。私は英語を話さないヨーロッパの国から来ました。

4

1 に答える 1

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

于 2013-08-05T21:28:09.800 に答える