MFC MDI CMFCPropertyGridProperty 添加 Array 用于下拉列表合并 MP4 标签数据

问题描述

我需要一些关于如何在解析 MP4 标签数据的读取信息后从数据数组添加下拉列表的指导。我使用的机制是 100% 可操作的,这是一个生物特征添加。我正在使用的 MP4 标签是使用 ID3V1 标准的流派。有191个选择。我的应用程序的继承方式有 2 列,属性/值和多行。所有这些都有效。流派标签是随意设置的,因此您基本上可以输入任何内容并存储它。我想删除它并使用下拉列表从数组中选择 191 个元素。加载过程的一部分是它将拉入 MP4 文件中的任何内容。所以,我希望用户能够保持原样(最有可能被标记支持 ID3V2 的东西),或者从下拉列表中填充的 191 个元素中进行选择。

对象看起来像这样的信息。h:

protected:
    CMFCPropertyGridCtrl m_wndProperties;

information.cpp 如下所示:

void CinformationView::OnInitialUpdate()
{
    // create property grid
    VERIFY(m_wndProperties.Create(WS_CHILD|WS_VISIBLE|WS_TABSTOP| WS_BORDER,CRect(0,0),this,0));

    // get document
    CMovieDoc *lpkDoc = GetDocument();
    ASSERT_VALID_PTR(lpkDoc);

    // add properties //information ORDER Loading <<<<< List shortened Stack overflow question
    m_wndProperties.AddProperty(lpkDoc->m_pkArtist);
    m_wndProperties.AddProperty(lpkDoc->m_pkTempo);
    m_wndProperties.AddProperty(lpkDoc->m_pkGenre);

    CView::OnInitialUpdate();
}

它从 mp4.cpp 中提取数据的方式:

// Genre
m_pkGenre = new CMFCPropertyGridProperty(_T("Genre"),COleVariant(AfxStringFromUtf8(lptTags->genre),VT_BSTR));

mp4.h 中的指针:

CMFCPropertyGridProperty *m_pkArtist;
CMFCPropertyGridProperty *m_pkTempo;
CMFCPropertyGridProperty *m_pkGenre;

现在我知道可以完成第二列(值)中的下拉,因为其他标签具有可以选择的简单 TRUE/FALSE,所以这告诉我应该可以创建我正在寻找的下拉列表去做。 TRUE/FALSE 的示例如下所示:

// Compilation
m_pkCompilation = new CMFCPropertyGridProperty(_T("Compilation"),COleVariant((!VALID_PTR(lptTags->compilation)) ? (short)0 : (short)*lptTags->compilation,VT_BOOL));

我在 C 语言中为微控制器之类的东西做过数组,但不完全确定它在 C++ 中是否相同。我认为它应该是这样的:

// Initialize Genre Array
const char *genre[4] = { "Rock","Rap","Soul","House" };

问题是:

  1. 我如何创建一个数组(或者我上面的例子看起来是否正确?)来容纳固定的字符串,如“Rock”、“Rap”、“Soul”等?
  2. 如何修改 VALUE 行以显示包含已解析流派标签的下拉菜单,然后在打开时显示 191 个流派标签,可以从中选择一个(并最终保存已经工作的标签)。
  3. 实际代码,而不是对 docs.microsoft.com 的引用,当我尝试更改我假设的 AddProperties 时,由于使用了 lpkDoc 指针,我尝试的几件事崩溃了。

解决方法

  1. 如果没有充分的理由,您不应该使用普通的旧 C 样式数组。请改用 std::vector。您甚至不需要指明 [size]char * 也是如此。改用 CStringstd::string

    const std::vector<CString> = { L"Rock",L"Rap",L"Soul",L"House" };
    

不要让你的生活变得比需要的更艰难。

2.

for (size_t i= 0; i < genre.size(); i++)
{
     auto gnr= genre[i];
     lpkDoc->m_pkGenre->AddOption(gnr);
}

甚至更好

for (auto it : genre)
{
     lpkDoc->m_pkGenre->AddOption(it);
}

重要说明:您的 doc 对象中不应包含有关属性的代码。您将业务逻辑与用户交互逻辑混合在一起。您将来的代码将成为维护的噩梦。

  1. 我没有在任何地方看到您的 lpkDoc->m_pk 变量初始化,而且我敢打赌这些指针指向无人区。