Пример использования GetModuleHandleEx. интернационализация WTL

Я пытаюсь выполнить интернационализацию в приложении с графическим интерфейсом WTL.. в моем обработчике изменения выбора раскрывающегося списка (который используется для выбора языка, я делаю что-то вроде этого):

int selected = (int)::SendMessage(m_cbLang, CB_GETCURSEL,0,0);
HMODULE hmod;
int retCode = 0;
switch(selected)
{
case 0:
    retCode =::GetModuleHandleEx(GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS | GET_MODULE_HANDLE_EX_FLAG_PIN, NULL, &hmod);
    ATL::_AtlBaseModule.SetResourceInstance(hmod);
    break;
case 1:

    retCode =::GetModuleHandleEx(GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS | GET_MODULE_HANDLE_EX_FLAG_PIN, L"GuiLibOther.dll", &hmod);
    ATL::_AtlBaseModule.SetResourceInstance(hmod);
    break;
}
return S_OK;

Теперь я действительно не знаю, как использовать эту функцию, хотя она здесь , я не знаю, что представляет lpModuleName. «GuiLibOther.dll» — это dll, которая содержит весь интерфейс на другом языке. Все ресурсы переведены на другой язык. Я хочу, чтобы интерфейс сразу же менял язык после выбора другого языка. это правильный путь? Случай 0 возвращает hmod = NULL


person AlexandruC    schedule 21.08.2013    source источник


Ответы (1)


Прежде всего, вы не хотите использовать флаг GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS, если вы не передаете адрес какого-либо элемента в DLL, что в данном случае не так.

Во-вторых, в документации подразумевается, что DLL уже должна быть загружена до того, как вы вызовете GetModuleHandleEx. Если вы не связали его с вашим .exe для автоматической загрузки, вы должны использовать LoadLibrary.

Необходимость использования LoadLibrary предполагает упрощение:

static HMODULE hmodExe = INVALID_HANDLE;
static HMODULE hmodDLL1 = INVALID_HANDLE;
switch(selected)
{
case 0:
    if (hmodExe == INVALID_HANDLE)
        retCode =::GetModuleHandleEx(0, NULL, &hmodExe);
    ATL::_AtlBaseModule.SetResourceInstance(hmodExe);
    break;
case 1:
    if (hmodDLL1 == INVALID_HANDLE)
        hmodDLL1 = LoadLibrary(L"GuiLibOther.dll");
    ATL::_AtlBaseModule.SetResourceInstance(hmodDLL1);
    break;

Это должно позволить вам динамически переключать библиотеки ресурсов без дополнительных накладных расходов.

person Mark Ransom    schedule 21.08.2013
comment
Спасибо, но что, если я хочу, чтобы интерфейс менял язык при выборе раскрывающегося списка, или это не очень практично или часто встречается в реальных приложениях? - person AlexandruC; 22.08.2013
comment
И если я хочу сделать изменения видимыми на существующих окрашенных элементах управления, мне нужно их перерисовать или повторно инициализировать, верно? есть ли способ автоматизировать это? - person AlexandruC; 22.08.2013
comment
@A.K вы должны иметь возможность сделать InvalidateRect в окне верхнего уровня, чтобы все перерисовывалось. - person Mark Ransom; 22.08.2013
comment
И еще у меня есть проблема, вот такой сценарий: у меня графический интерфейс с несколькими окнами и диалогами и я хочу изменить их язык, у меня есть несколько .dll с разными языковыми ресурсами, я делаю то, что вы говорите выше, это работает, если я хочу загрузить строку из таблицы строк другого языка.. НО.. Я хочу, чтобы дочерние элементы управления были заменены вновь выбранными языковыми ресурсами, другими словами, я хочу, чтобы язык мгновенно менялся для каждого элемента графического интерфейса, который содержит статический текст и без мерцания, если это возможно. - person AlexandruC; 10.09.2013
comment
@ AK, это гораздо более глубокая проблема. Изменение ресурсов не помогает, если элементы управления уже активны. Вам нужно либо уничтожить окна и создать их заново, либо изменить текст в каждом отдельно с помощью SetText или чего-то еще. Я не знаю фреймворка, который помог бы. Это может сделать какая-то платформа для создания скинов, но это работает только для простых приложений. - person Mark Ransom; 10.09.2013
comment
Здравствуйте, есть ли у вас какие-либо идеи по поводу этого stackoverflow .com/questions/18810755/ - person AlexandruC; 15.09.2013