将参数编程到对象数组

Program arguments to an array of objects

本文关键字:对象 数组 编程 参数      更新时间:2023-10-16

我是一名 Java 程序员,需要一种方法在资源管理器中显示多个文件,所以我找到了一个允许这样做的函数SHOpenFolderAndSelectItems(资源管理器 CLI 只允许选择单个文件(。

我已经从这里和那里编写了示例代码,它成功地适用于硬编码路径,但现在我希望程序接受包含文件夹的路径作为第一个参数,并选择文件作为其余所有参数。

这是一个硬编码的。

#include "stdafx.h"
#include <Objbase.h>
#include <Shlobj.h>
#include "RevealMultiple.h"

int _tmain(int argc, _TCHAR* argv[])
{
        //Directory to open
    ITEMIDLIST *dir = ILCreateFromPath(_T("C:\"));
    //Items in directory to select
    ITEMIDLIST *item1 = ILCreateFromPath(_T("C:\Program Files\"));
    ITEMIDLIST *item2 = ILCreateFromPath(_T("C:\Windows\"));
    const ITEMIDLIST* selection[] = { item1, item2 };
    UINT count = sizeof(selection) / sizeof(ITEMIDLIST);
    CoInitialize(NULL);
    //Perform selection
    HRESULT res = SHOpenFolderAndSelectItems(dir, count, selection, 0);
    //Free resources
    ILFree(dir);
    ILFree(item1);
    ILFree(item2);
    CoUninitialize();
    return res;
}

这是代码,可以了解我想要实现的目标。

 #include "stdafx.h"
#include <Objbase.h>
#include <Shlobj.h>
#include "RevealMultiple.h"
#include <list>

int _tmain(int argc, _TCHAR* argv[])
{
    //Directory to open
    ITEMIDLIST *dir = ILCreateFromPath(argv[0]);
    const ITEMIDLIST* files = new ITEMIDLIST[argc - 1];
    //Items in directory to select
    std::list<ITEMIDLIST*> filesList;
    for (int i = 1; i < argc; i++)
    {
        filesList.push_back(ILCreateFromPath(argv[i]));
    }
    CoInitialize(NULL);
    //Perform selection
    HRESULT res = SHOpenFolderAndSelectItems(dir, filesList.size, filesList._Get_data(), 0);
    //Free resources
    ILFree(dir);
    for (auto file : filesList)
    {
        ILFree(file);
    }
    CoUninitialize();
    return res;
}

但是很明显,我遇到了一个错误:

revealmultiple.cpp(25): error C3867: 'std::list<ITEMIDLIST *,std::allocator<_Ty>>::size': non-standard syntax; use '&' to create a pointer to member
1>        with
1>        [
1>            _Ty=ITEMIDLIST *
1>        ]

如何正确地将字符串参数数组转换为ITEMIDLIST*数组,以便我可以将其传递给 SHOpenFolderAndSelectItems?

感谢您的任何帮助。

首先要注意的是,argv[0] 是用于调用程序的命令,常规参数从 argv[1] 开始。

话虽如此,像下面这样的事情应该可以完成您所追求的:

ITEMIDLIST *dir = ILCreateFromPath(_T(argv[0]);
ITEMIDLIST ** ppItems = new ITEMIDLIST *[argc-2];
for(int ndx = 2; argc > ndx; ++ndx)
  ppItems[ndx] = ILCreateFromPath(_T(argv[ndx]);

std::list 这样的容器不能保证数据存储为连续的内存块,不适合使用像 SHOpenFolderAndSelectItems 这样的 API 需要指向数组的指针。

标准容器的唯一有效选择是std::vectorstd::array、普通旧数组或任何手动分配的连续内存块。

使用std::vector代码将更改为:

std::vector<ITEMIDLIST*> filesList;
HRESULT res = SHOpenFolderAndSelectItems(dir, filesList.size(), filesList.data(), 0);

请注意,size()是一个函数,而不是您在原始代码中处理它的数据成员。这就是您收到编译器错误的原因。此外,对于std::vector,无需使用专有成员函数来获取指向数据的指针,std::vector::data()已明确定义。