Manipulating the positions of desktop icons
Asked Answered
S

2

1

I am currently trying to retrieve the list of icons from my desktop to change their locations and / or hide them as well as display others.

I tried to get the FolderView in the code below but it doesn't even show the number of icons I have on the desktop because count return 0.

HWND hDesktop = GetDesktopWindow();
HWND hDefView = FindWindowEx(hDesktop, NULL, L"SHELLDLL_DefView", NULL);
HWND folderView = FindWindowEx(hShellWnd, NULL, L"SysListView32", NULL);

int count = (int) SendMessage(folderView, LVM_GETITEMCOUNT, 0, 0);
cout << count << endl;

I did tests on the variables and is noticed that hDefView is NULL.
Probably the reason why count return 0.

EDIT : After replace GetDesktopWindow by GetShellWindow the result is always the same, 0

Supersonic answered 22/4, 2018 at 9:2 Comment(6)
Actually you should open Desktop folder and enumerate files there.Spellbinder
Possible duplicate of How do I get the window handle of the desktop?Sportswoman
It isn't a duplicate because this post doesn't help me. @VTT I want to get the icons count for hide icons later.Supersonic
@VTT Icons come from virtual locations and two different filesystem folders.Jasperjaspers
@VTT Things like Computer, Recycle Bin, etc. show as icons but are not present in the folderHipparch
devblogs.microsoft.com/oldnewthing/20211122-00/?p=105948 There is an Old New Thing article on this questionTablecloth
J
5

The shell window hierarchy is not documented nor stable. "ProgMan" is usually the parent of "SHELLDLL_DefView" but if you change to slideshow wallpaper it can also be "WorkerW".

It is much better to inspect/manipulate the desktop with the documented shell COM interfaces: IShellWindows, IShellBrowser, IFolderView and IShellFolder.

Jasperjaspers answered 22/4, 2018 at 9:48 Comment(1)
It would help if you included the important interfaces in this answer.Provincial
G
0

The following C++ code will find a file named "test.txt" on the desktop and move the icon 100 pixels to the right. Code is heavily based on Manipulating the positions of desktop icons by Raymond Chen.

#include <windows.h>
#include <shlobj.h>
#include <atlbase.h>


// Class to help with object destruction
// https://devblogs.microsoft.com/oldnewthing/20040520-00/?p=39243
class CCoInitialize {
    public:
        CCoInitialize() : m_hr(CoInitialize(NULL)) { }
        ~CCoInitialize() { if (SUCCEEDED(m_hr)) CoUninitialize(); }
        operator HRESULT() const { return m_hr; }
        HRESULT m_hr;
};


// Get shell view for the desktop
// https://devblogs.microsoft.com/oldnewthing/20130318-00/?p=4933
void FindDesktopFolderView(REFIID riid, void** ppv)
{
    CComPtr<IShellWindows> spShellWindows;
    spShellWindows.CoCreateInstance(CLSID_ShellWindows);

    CComVariant vtLoc(CSIDL_DESKTOP);
    CComVariant vtEmpty;
    long lhwnd;
    CComPtr<IDispatch> spdisp;
    spShellWindows->FindWindowSW(
        &vtLoc, &vtEmpty,
        SWC_DESKTOP, &lhwnd, SWFO_NEEDDISPATCH, &spdisp);

    CComPtr<IShellBrowser> spBrowser;
    CComQIPtr<IServiceProvider>(spdisp)->
        QueryService(SID_STopLevelBrowser,
            IID_PPV_ARGS(&spBrowser));

    CComPtr<IShellView> spView;
    spBrowser->QueryActiveShellView(&spView);

    spView->QueryInterface(riid, ppv);
}


int main()
{
    CCoInitialize init;
    CComPtr<IFolderView> spView;
    FindDesktopFolderView(IID_PPV_ARGS(&spView));
    CComPtr<IShellFolder> spFolder;
    spView->GetFolder(IID_PPV_ARGS(&spFolder));

    CComPtr<IEnumIDList> spEnum;
    spView->Items(SVGIO_ALLVIEW, IID_PPV_ARGS(&spEnum));

    // Iterate through desktop icons
    for (CComHeapPtr<ITEMID_CHILD> spidl;
        spEnum->Next(1, &spidl, nullptr) == S_OK;
        spidl.Free()) {
        STRRET str;

        // Check icon display name
        spFolder->GetDisplayNameOf(spidl, SHGDN_NORMAL, &str);
        CComHeapPtr<wchar_t> spszName;
        StrRetToStr(&str, spidl, &spszName);
        if (wcscmp(spszName, L"test.txt") == 0)
        {
            // Get icon position
            POINT pt;
            spView->GetItemPosition(spidl, &pt);

            // Move icon 100 pixels right
            pt.x += 100;
            PCITEMID_CHILD apidl[1] = { spidl };
            spView->SelectAndPositionItems(1, apidl, &pt, SVSI_POSITIONITEM);

            break;
        };
    }
    return 0;
}

Gif of icon being moved

Gaither answered 29/4 at 2:10 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.