0

I'm trying to get the elements in the desktop (icon shortcuts) using winapi, but for some reason I'm getting nothing. Am I doing it wrong? (I'm very new to this)

BOOL CALLBACK EnumChildWindows(HWND hwnd,LPARAM lParam) {
    char str[256];
    GetWindowTextA(hwnd, str, 200);
    OutputDebugStringA(str);
    return true;
}

Inside wWinMain:

HWND hDesktop = GetDesktopWindow();
EnumChildWindows(hDesktop, 0);
Remy Lebeau
  • 555,201
  • 31
  • 458
  • 770
Omi Kor
  • 25
  • 4
  • 1
    Check out [`SHGetDesktopFolder`](https://learn.microsoft.com/en-us/windows/win32/api/shlobj_core/nf-shlobj_core-shgetdesktopfolder) and [`IShellFolder::EnumObjects`](https://learn.microsoft.com/en-us/windows/win32/api/shobjidl_core/nf-shobjidl_core-ishellfolder-enumobjects). – dxiv Jan 07 '21 at 06:53
  • Consider using [Qt](https://qt.io/) – Basile Starynkevitch Jan 07 '21 at 06:55
  • @dxiv Can you tell me how to use it? or where I can find example about it? – Omi Kor Jan 07 '21 at 07:11
  • @OmiKor [Introduction to the Shell Namespace](https://learn.microsoft.com/en-us/windows/win32/shell/namespace-intro) and [Getting Information About the Contents of a Folder](https://learn.microsoft.com/en-us/windows/win32/shell/folder-info) would be good starting points. – dxiv Jan 07 '21 at 07:21

1 Answers1

1

You used the EnumChildWindows function by mistake:

BOOL CALLBACK EnumChildProc(HWND hwnd, LPARAM lParam) {
    char str[256]{};
    GetWindowTextA(hwnd, str, 200);
    OutputDebugStringA(str);
    return true;
}
int main(int argc, const char* argv[])
{
    HWND hDesktop = GetDesktopWindow();
    EnumChildWindows(hDesktop, EnumChildProc, 0);
    return 0;
}

You need to set a callback function and call it with EnumChildWindows.

Of course, this cannot get the name of the "desktop shortcut", what you get is the name of all child windows.

If you want to get the name and location of the desktop shortcut, you need to use COM related, here is an example:

#include <windows.h>
#include <stdio.h>
#include <conio.h>
#include <ShlObj.h>
#include <atlbase.h>

int main(int argc, char** argv)
{
    CComPtr<IShellWindows> spShellWindows;
    CComPtr<IShellBrowser> spBrowser;
    CComPtr<IDispatch> spDispatch;
    CComPtr<IShellView> spShellView;
    CComPtr<IFolderView>  spView;
    CComPtr<IShellFolder> spFolder;
    CComPtr<IEnumIDList>  spEnum;
    CComHeapPtr<ITEMID_CHILD> spidl;
    CComVariant vtLoc(CLSID_ShellWindows);
    CComVariant vtEmpty;
    STRRET str;

    int count = 0;
    HRESULT hr;
    long lhWnd;

    // INITIALIZE COM
    CoInitialize(NULL);

    // GET ShellWindows INTERFACE
    hr = spShellWindows.CoCreateInstance(CLSID_ShellWindows);

    // FIND WINDOW
    hr = spShellWindows->FindWindowSW(
        &vtLoc, &vtEmpty, SWC_DESKTOP, &lhWnd, SWFO_NEEDDISPATCH, &spDispatch);

    // GET DISPATCH INTERFACE
    CComQIPtr<IServiceProvider>(spDispatch)->
        QueryService(SID_STopLevelBrowser, IID_PPV_ARGS(&spBrowser));

    spBrowser->QueryActiveShellView(&spShellView);
    spShellView->QueryInterface(IID_PPV_ARGS(&spView));

    hr = spView->GetFolder(IID_PPV_ARGS(&spFolder));

    // GET ENUMERATOR
    spView->Items(SVGIO_ALLVIEW, IID_PPV_ARGS(&spEnum));    // get enumerator

    // ENUMERATE ALL DESKTOP ITEMS
    for (; spEnum->Next(1, &spidl, nullptr) == S_OK; spidl.Free()) {
        // GET/PRINT ICON NAME AND POSITION
        char* name;
        POINT pt;
        spFolder->GetDisplayNameOf(spidl, SHGDN_NORMAL, &str);
        StrRetToStrA(&str, spidl, &name);
        spView->GetItemPosition(spidl, &pt);
        printf("%5d %5d \"%s\"\n", pt.x, pt.y, name);
    }
    CoUninitialize();           // release COM
    exit(0);
}
Zeus
  • 3,703
  • 3
  • 7
  • 20
  • Wow! Thank you very much! – Omi Kor Jan 07 '21 at 07:20
  • 1
    It's much easier to ask for IShellItemArray instead of IEnumIDList so you don't have to use old STRRET structs (you should use Unicode version BTW, not Ansi). IShellItem (Vista+) should be used wherever possible. https://stackoverflow.com/a/62622272/403671 – Simon Mourier Jan 07 '21 at 08:19
  • Where can I find more information about using com objects like this example? The MSDN documentation don't have much information about actually using it... – Omi Kor Jan 08 '21 at 11:08