Reputation:
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
Upvotes: 1
Views: 962
Reputation: 26752
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;
}
Upvotes: 0
Reputation: 101606
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
.
Upvotes: 5