Можно ли упростить заполнение этого списка std :: list? - PullRequest
1 голос
/ 10 июня 2019

Могу ли я упростить заполнение моего std::list кода:

void CMeetingScheduleAssistantApp::InitBrowserRegistryLookupList(RegistryPathList& rListRegPaths)
{
    S_REGISTRY_PATH  sRegPath;

    // Reset the list
    rListRegPaths.clear();

    // These will be "native" 32bit or native 64bit browsers (i.e. the Operating System bitness)
    sRegPath.hRootKey = HKEY_LOCAL_MACHINE;
    sRegPath.strKeyPath = _T("SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\App Paths\\firefox.exe");
    sRegPath.strBrowser = _T("Firefox");
    rListRegPaths.push_back(sRegPath);

    sRegPath.hRootKey = HKEY_LOCAL_MACHINE;
    sRegPath.strKeyPath = _T("SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\App Paths\\IEXPLORE.EXE");
    sRegPath.strBrowser = _T("Internet Explorer");
    rListRegPaths.push_back(sRegPath);

    sRegPath.hRootKey = HKEY_LOCAL_MACHINE;
    sRegPath.strKeyPath = _T("SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\App Paths\\chrome.exe");
    sRegPath.strBrowser = _T("Google Chrome");
    rListRegPaths.push_back(sRegPath);

    sRegPath.hRootKey = HKEY_CURRENT_USER;
    sRegPath.strKeyPath = _T("SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\App Paths\\opera.exe");
    sRegPath.strBrowser = _T("Opera Internet Browser");
    rListRegPaths.push_back(sRegPath);

    // These will be 32 bit browsers (on a 64 bit Operating System)
    if (IsOS(OS_WOW6432))
    {
        sRegPath.hRootKey = HKEY_LOCAL_MACHINE;
        sRegPath.strKeyPath = _T("SOFTWARE\\Wow6432Node\\Microsoft\\Windows\\CurrentVersion\\App Paths\\firefox.exe");
        sRegPath.strBrowser = _T("Firefox");
        rListRegPaths.push_back(sRegPath);

        sRegPath.hRootKey = HKEY_LOCAL_MACHINE;
        sRegPath.strKeyPath = _T("SOFTWARE\\Wow6432Node\\Microsoft\\Windows\\CurrentVersion\\App Paths\\IEXPLORE.EXE");
        sRegPath.strBrowser = _T("Internet Explorer");
        rListRegPaths.push_back(sRegPath);

        sRegPath.hRootKey = HKEY_LOCAL_MACHINE;
        sRegPath.strKeyPath = _T("SOFTWARE\\Wow6432Node\\Microsoft\\Windows\\CurrentVersion\\App Paths\\chrome.exe");
        sRegPath.strBrowser = _T("Google Chrome");
        rListRegPaths.push_back(sRegPath);
    }
}

Обновление

Определение RegPathlist:

typedef struct tagRegistryPath
{
    HKEY hRootKey;
    CString strBrowser;
    CString strKeyPath;

} S_REGISTRY_PATH;
using RegistryPathList = list<S_REGISTRY_PATH>;

Ответы [ 5 ]

2 голосов
/ 10 июня 2019

Да, вы можете упростить это.Лучше всего было бы предоставить файл конфигурации с этими данными.

Если вы не хотите использовать файл, просто используйте список инициализации (см. Версию 5 std :: list :: insert ):

void CMeetingScheduleAssistantApp::InitBrowserRegistryLookupList(RegistryPathList& rListRegPaths)
{
    rListRegPaths.insert(rListRegPaths.end(),
         {
             {
                 HKEY_LOCAL_MACHINE,
                 _T("SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\App Paths\\firefox.exe"),
                 _T("Firefox")
             },
             {
                 HKEY_LOCAL_MACHINE,
                 _T("SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\App Paths\\IEXPLORE.EXE"),
                 _T("Internet Explorer")
             },
             {
                 ....
             }
             ....
        });
}

2 голосов
/ 10 июня 2019

Вы можете использовать конструктор списка инициализаторов и push_back:

struct RegistryPath {
    HKEY hRootKey;
    TCHAR const* strBrowser;
    TCHAR const* strKeyPath;
};

int main() {
    std::list<RegistryPath> sRegPath = {
        {HKEY_LOCAL_MACHINE, _T("SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\App Paths\\firefox.exe"), _T("Firefox")},
        {HKEY_LOCAL_MACHINE, _T("SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\App Paths\\IEXPLORE.EXE"), _T("Internet Explorer")}
        // ...
    };
    if(IsOS(OS_WOW6432)) {
        sRegPath.push_back({HKEY_LOCAL_MACHINE, _T("SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\App Paths\\firefox.exe"), _T("Firefox")});
        // ...
    }
}

Обратите внимание, что я заменил CString на TCHAR const*, чтобы избежать выделения памяти и копирования строк.

2 голосов
/ 10 июня 2019

Вероятно, вы захотите emplace_back ваших элементов, что может ускорить и "упростить" (субъективный термин) ваш код.Пример:

rListRegPaths.emplace_back(
      HKEY_LOCAL_MACHINE, 
      _T("SOFTWARE\\Wow6432Node\\Microsoft\\Windows\\CurrentVersion\\App Paths\\firefox.exe"),
      _T("Firefox"));
1 голос
/ 10 июня 2019

Вы можете создавать массивы в разных браузерах, например:

S_REGISTRY_PATH native[] = { 
    {HKEY_LOCAL_MACHINE, _T("SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\App Paths\\firefox.exe"), _T("Firefox")},
    //...
}

S_REGISTRY_PATH wow64[] = {
   {HKEY_LOCAL_MACHINE, _T("SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\App Paths\\firefox.exe"), _T("Firefox")},
    //...
}

Это может быть даже отдельный файл, даже автоматически сгенерированный, который вы просто включили бы в файл, реализующий метод. Тогда внутри метода все, что вам нужно сделать, это:

void CMeetingScheduleAssistantApp::InitBrowserRegistryLookupList(RegistryPathList& rListRegPaths)
{
    rListRegPaths.clear();

    for (auto && it : native) {
        rListRegPaths.push_back(*it);
    }

    if (IsOS(OS_WOW6432)) {
         for (auto && it : wow64) {
             rListRegPaths.push_back(*it);
         }
    }
}

Это отделяет то, что в основном представляет собой просто данные, от самого кода, что значительно облегчает чтение, изменение и общее управление.

1 голос
/ 10 июня 2019

Вы можете сделать его короче, построив аргументы.

typedef struct tagRegistryPath
{
    HKEY hRootKey;
    CString strBrowser;
    CString strKeyPath;

} S_REGISTRY_PATH;

rListRegPaths.push_back(S_REGISTRY_PATH {
    HKEY_LOCAL_MACHINE,
    _T("SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\App Paths\\firefox.exe"),
    _T("Firefox")
});
...