[CMD] Выделение иконки на десктопе

Dragokas

Angry & Scary Developer
Команда форума
Супер-Модератор
Разработчик
Клуб переводчиков
Сообщения
6,782
Реакции
6,243
В уже открытой папке или ещё нет?

Код:
explorer /select,"путь"
 

fils

Пользователь
Сообщения
23
Реакции
3
В уже открытой папке или ещё нет?

Код:
explorer /select,"путь"
Этот скрипт откроет и выделит файл/папку в папке "Desktop",
а мне надо чтобы выделело иконку на рабочем поле монитора.
 
Последнее редактирование:

Dragokas

Angry & Scary Developer
Команда форума
Супер-Модератор
Разработчик
Клуб переводчиков
Сообщения
6,782
Реакции
6,243
Для уже открытой папки, если знакомы с программированием на интерфейсах и Shell, то вот так можно:

C++:
IWebBrowserApp *m_pSite;
if (SUCCEEDED(pdisp->QueryInterface(IID_IWebBrowserApp, (void**)&m_pSite)))
{
    IServiceProvider * pServiceProvider;
    if (SUCCEEDED(m_pSite->QueryInterface(IID_IServiceProvider, (LPVOID*)&pServiceProvider)))
    {
        IShellBrowser * pShellBrowser;
        if (SUCCEEDED(pServiceProvider->QueryService(SID_SShellBrowser, IID_IShellBrowser, (LPVOID*)&pShellBrowser)))
        {
            // получаем интерфейс активного окна explorer
            IShellView * pShellView;
            if (SUCCEEDED(pShellBrowser->QueryActiveShellView(&pShellView)))
            {
                IFolderView * pFolderView;
                if (SUCCEEDED(pShellView->QueryInterface(IID_IFolderView, (LPVOID*)&pFolderView)))
                {
                    int nCount = 0;
                    if (SUCCEEDED(pFolderView->ItemCount(SVGIO_ALLVIEW, &nCount)))
                    {
                        // select each entry
                        for (int i = 0; i < nCount; i++)
                        {
                            LPITEMIDLIST pidl;
                            pFolderView->Item(i, &pidl);
                            // здесь можно получить имя объекта, например через IShellFolder::GetDisplayNameOf
                        
                            // выделить объект
                            pFolderView->SelectItem(i, SVSI_SELECT);
                        }
                    }
                }
                pShellView->Release();
            }
            pShellBrowser->Release();
        }
        pServiceProvider->Release();
    }
    m_pSite->Release();
}

Или более быстро наверное так: IPersistFolder2::GetCurFolder, затем IShellView::SelectItem

Из скриптовых ЯП ничего из этого не доступно.
 
Последнее редактирование:

Dragokas

Angry & Scary Developer
Команда форума
Супер-Модератор
Разработчик
Клуб переводчиков
Сообщения
6,782
Реакции
6,243
Вообще-то скриптовым языкам доступен объект Shell.Application и в частности Shell.Windows, но там в FolderItem нет нужного метода SelectItem.

На счёт варианта на С++, вот здесь есть более подробное объяснение кода от Реймонда Чена.

Сейчас вот поэкспериментировал, если открыта папка и там уже выделены какие-то объекты, то чтобы убрать выделение со всех них, а также прямоугольник фокуса, после чего выделить нужный объект, требуется выполнить последовательность таких действий:

Код:
pFolderView->SelectItem(i, SVSI_DESELECTOTHERS);
pFolderView->SelectItem(i, SVSI_FOCUSED);
pFolderView->SelectItem(i, SVSI_SELECT);

Здесь вот кстати, еще вариант на VB6: Раз, Два.
Для кода "Раз", пример с перечислением элементов в папке и выделения нужного на VB6:

VB.NET / VBA:
Dim k As Long
Dim nCount As Long
Dim shItem As IShellItem2

'получаем кол-во элементов
Call spfv.ItemCount(SVGIO_ALLVIEW, nCount)

For k = 0 To nCount - 1

    spfv.GetItem k, IID_IShellItem, shItem

    'получаем полный путь к файлу
    shItem.GetDisplayName SIGDN_DESKTOPABSOLUTEPARSING, lpPath
    sPath = LPWSTRtoStr(lpPath)
    
    Debug.Print sPath

    If sPath = "xxxxx" Then ' проверяем что нашли нужный нам путь
        
        'выделяем его, сняв выделение с остальных
        Call spfv.SelectItem(k, SVSI_DESELECTOTHERS)
        Call spfv.SelectItem(k, SVSI_FOCUSED)
        Call spfv.SelectItem(k, SVSI_SELECT)
        
        Exit For
    End If
Next
 

Сергій

Разработчик
Сообщения
670
Реакции
332
Он имеет ввиду иконки на рабочем столе, там где стоит фоновая картинка, когда все окна свернутые.
Иконка проорамно выделится, если по ней сделать клик (нужно знать ее координаты), или сделать клик по первой иконке (Мой компьютер) и кдавишей Таб дойти до нужной (нужно знать ее номер).
Хотя... если сделать переименование иконки (ярлыка), то она получает фокус
(не утверждаю, а предполагаю, так как проверить не могу - у меня нет иконок на раб.столе - просто синий єкран).
 

Dragokas

Angry & Scary Developer
Команда форума
Супер-Модератор
Разработчик
Клуб переводчиков
Сообщения
6,782
Реакции
6,243
На рабочем столе множество иконок:
1) иконки ярлыков и других файлов в области открытой виртуальной папки "Рабочий стол"
2) иконки закрепленных ярлыков на панели задач
3) иконки запущенных приложений на панели задач
4) иконки запущенных приложений в панели уведомления
5) иконки файлов в отдельно открытой папке
Ждём от TC скриншот, что именно он имел в виду.
 
Последнее редактирование:

fils

Пользователь
Сообщения
23
Реакции
3
нету такого понятия.

Вы имеете в виду уже открытую папку?
На рабочем столе выделена иконка 1.txt.
Я бы хотел сделать это выделение программно зная только имя файла (в данном случае 1.txt ).
 

Вложения

  • Рабочий стол.jpg
    Рабочий стол.jpg
    30.5 KB · Просмотры: 3
Последнее редактирование:

fils

Пользователь
Сообщения
23
Реакции
3
Он имеет ввиду иконки на рабочем столе, там где стоит фоновая картинка, когда все окна свернутые.
Иконка проорамно выделится, если по ней сделать клик (нужно знать ее координаты), или сделать клик по первой иконке (Мой компьютер) и кдавишей Таб дойти до нужной (нужно знать ее номер).
Хотя... если сделать переименование иконки (ярлыка), то она получает фокус
(не утверждаю, а предполагаю, так как проверить не могу - у меня нет иконок на раб.столе - просто синий єкран).
Вы всё поняли абсолютно правильно.
Я подумаю над Вашей идеей "сделать клик (программно) по первой иконке (Мой компьютер) и клавишей Таб дойти до нужной (программно)".
Спасибо за подсказку!
 

Dragokas

Angry & Scary Developer
Команда форума
Супер-Модератор
Разработчик
Клуб переводчиков
Сообщения
6,782
Реакции
6,243
@fils,

C++:
#define UNICODE
#define _UNICODE
#include <windows.h>
#include <shlobj.h>
#include <exdisp.h>
#include <shlwapi.h>
#include <atlbase.h>
#include <atlalloc.h>
#include <stdio.h>

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 __cdecl wmain(int argc, wchar_t** argv)
{
    LPVOID lpRes = NULL;
    CoInitialize(lpRes);
    CComPtr<IFolderView> spView;
    FindDesktopFolderView(IID_PPV_ARGS(&spView));
    CComPtr<IShellFolder> spFolder;
    spView->GetFolder(IID_PPV_ARGS(&spFolder));
    int nCount = 0;
    spView->ItemCount(SVGIO_ALLVIEW, &nCount);
    
    for (int i = 0; i < nCount; i++)
    {
        CComHeapPtr<ITEMID_CHILD> spidl;
        spView->Item(i, &spidl);

        STRRET str;
        spFolder->GetDisplayNameOf(spidl, SHGDN_NORMAL, &str);
        CComHeapPtr<wchar_t> spszName;
        StrRetToStr(&str, spidl, &spszName);

        wprintf(L"Name: %ls\n", static_cast<LPWSTR>(spszName));

        if (_wcsicmp(spszName, L"Reverse") == 0) // название файла на рабочем столе
        {
            spView->SelectItem(i, SVSI_DESELECTOTHERS | SVSI_FOCUSED | SVSI_SELECT);
        }
    }
    
    return 0;
}

Часть кода взята из статей Raymond Chen:
 

fils

Пользователь
Сообщения
23
Реакции
3
Он имеет ввиду иконки на рабочем столе, там где стоит фоновая картинка, когда все окна свернутые.
Иконка проорамно выделится, если по ней сделать клик (нужно знать ее координаты), или сделать клик по первой иконке (Мой компьютер) и кдавишей Таб дойти до нужной (нужно знать ее номер).
Хотя... если сделать переименование иконки (ярлыка), то она получает фокус
(не утверждаю, а предполагаю, так как проверить не могу - у меня нет иконок на раб.столе - просто синий єкран).
Попробывал Вашу вторую догатку с переименованием иконки, и вроде всё получилось.
Т.е батник работает как поисковая система. Вводишь имя с расширением файла или имя папки
и он на рабочем столе выделяет её иконку.
Спасибо за помощь.
 

fils

Пользователь
Сообщения
23
Реакции
3
Всем большое спасибо!
Вопрос решён.
Прилагаю скрипт батника, может быть кому-нибудь будет интересно.
CMD/BATCH:
@echo off >nul
Chcp 1251 >nul

set /p i= ВВЕДИ ИМЯ файла/папки -
for %%a in ("%i%") do set x=%%~xa

cmdow @ /min
ren "%i%" ъ%x%
nircmd wait 500
nircmd win activate class progman
nircmd wait 500
nircmd sendkeypress ctrl+1 shift+221
nircmd wait 500
ren ъ%x% "%i%"
exit
 
Последнее редактирование:

fils

Пользователь
Сообщения
23
Реакции
3
@fils,

C++:
#define UNICODE
#define _UNICODE
#include <windows.h>
#include <shlobj.h>
#include <exdisp.h>
#include <shlwapi.h>
#include <atlbase.h>
#include <atlalloc.h>
#include <stdio.h>

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 __cdecl wmain(int argc, wchar_t** argv)
{
    LPVOID lpRes = NULL;
    CoInitialize(lpRes);
    CComPtr<IFolderView> spView;
    FindDesktopFolderView(IID_PPV_ARGS(&spView));
    CComPtr<IShellFolder> spFolder;
    spView->GetFolder(IID_PPV_ARGS(&spFolder));
    int nCount = 0;
    spView->ItemCount(SVGIO_ALLVIEW, &nCount);
   
    for (int i = 0; i < nCount; i++)
    {
        CComHeapPtr<ITEMID_CHILD> spidl;
        spView->Item(i, &spidl);

        STRRET str;
        spFolder->GetDisplayNameOf(spidl, SHGDN_NORMAL, &str);
        CComHeapPtr<wchar_t> spszName;
        StrRetToStr(&str, spidl, &spszName);

        wprintf(L"Name: %ls\n", static_cast<LPWSTR>(spszName));

        if (_wcsicmp(spszName, L"Reverse") == 0) // название файла на рабочем столе
        {
            spView->SelectItem(i, SVSI_DESELECTOTHERS | SVSI_FOCUSED | SVSI_SELECT);
        }
    }
   
    return 0;
}

Часть кода взята из статей Raymond Chen:
Где это можно скомпилировать on-line?
Или ещё что-нибудь посоветуете для разового применения.
 

Dragokas

Angry & Scary Developer
Команда форума
Супер-Модератор
Разработчик
Клуб переводчиков
Сообщения
6,782
Реакции
6,243
Где это можно скомпилировать on-line?
не в курсе, но могу скомпилировать вам, сделав название файла как первый аргумент запуска программы

Или ещё что-нибудь посоветуете для разового применения.
не понимаю вопроса
 

Dragokas

Angry & Scary Developer
Команда форума
Супер-Модератор
Разработчик
Клуб переводчиков
Сообщения
6,782
Реакции
6,243
И в чём прикол?
В Win10 можно поставить такой же компилятор, как и на Линукс (mingw), если лень заморачиваться со скачиванием огромного дистрибутива MS Visual Studio.
Вот только не факт, что в нём найдутся все нужные хидеры. Приведённый выше код требует ATL.
 
Последнее редактирование:

Сергій

Разработчик
Сообщения
670
Реакции
332
Попробывал Вашу вторую догатку с переименованием иконки, и вроде всё получилось.
Т.е батник работает как поисковая система. Вводишь имя с расширением файла или имя папки
и он на рабочем столе выделяет её иконку.
Спасибо за помощь.
Там учтите, что иконки - иногда ярлыки (папок) с расширением lnk или даже url
 

Dragokas

Angry & Scary Developer
Команда форума
Супер-Модератор
Разработчик
Клуб переводчиков
Сообщения
6,782
Реакции
6,243
Хоть что угодно.
Если брать из числа Visual Studio, то наиболее легковесная версия 2013, где более-менее есть поддержка основных фич и код выше должен собраться.
 
Сверху Снизу