C ++ win32 загрузка строк из ресурса - PullRequest
7 голосов
/ 20 мая 2011

Хорошо, поэтому недавно я принял решение поместить каждую строку в моем приложении в STRINGTABLE, чтобы я мог легко переводить на разные языки. Я знаю, как использовать API LoadString (), но это связано с тем, что у меня есть разные переменные для каждой строки, которую я хочу загрузить, и если мое приложение имеет 100 строк, это много переменных. Это лучший способ сделать это? Или я должен создать глобальную переменную, которая используется в качестве буфера для загрузки строк по мере необходимости? Кроме того, поскольку невозможно узнать, насколько велика моя строка, я должен просто создать достаточно большой буфер для хранения любой строки, которую я мог бы иметь, или есть лучший способ сделать это?

Кроме того, загрузка строк по мере необходимости плохо влияет на производительность? Есть ли способ, которым я могу их предварительно загрузить?

RE: Хорошо, я попытался создать буфер размером 256 байт и загрузить в него строки по мере необходимости, хотя я столкнулся с небольшой проблемой ...

Вот мой код, который отображает сообщение об ошибке, ошибка «Ошибка выделения памяти!»

LoadString(g_hInst, IDS_ERROR_MEMORY, szBuffer, sizeof(szBuffer)/sizeof(TCHAR));
MessageBox(NULL, szBuffer, TEXT("Error"), MB_OK | MB_ICONERROR);
ExitProcess(1);

И у меня есть буфер в качестве глобальной переменной: TCHAR szBuffer[256];

Это работает, но я хотел бы также сохранить текст «Ошибка» в таблице строк и загрузить, чтобы, когда я хочу отобразить ошибку, проблема заключалась в том, что мне потребовалось бы две глобальные переменные для загрузки строк, и В некоторых местах мне нужно загружать даже больше, чем за один раз.

Есть ли лучшее решение, чем наличие нескольких глобальных переменных?

1 Ответ

7 голосов
/ 20 мая 2011

Вы можете предварительно загрузить их, если хотите.Вам просто нужно создать массив строковых указателей и загрузить каждую строку в этот массив.Или вы можете использовать хэш-карту или что-то подобное.

Плохо для производительности?Это зависит.Если вы отображаете эти строки в виде подсказок в пользовательском интерфейсе, я не вижу, как загрузка каждой строки по мере необходимости будет проблемой производительности.В любом случае, операционная система будет выполнять интеллектуальное кэширование, поэтому не похоже, что вы будете нажимать на диск для каждой строки, которую вам нужно отобразить.С другой стороны, если вы собираетесь работать с этими строками в тесном цикле, то, вероятно, лучше предварительно загрузить их в память, чтобы вам не приходилось постоянно вызывать LoadString.

Что касается буферов, я всегда выделял буфер размером до самой большой строки, которую я ожидал иметь в своем файле ресурсов.Учитывая, что строки пользовательского интерфейса обычно очень малы, 256-байтовый буфер был более чем достаточным.Что-нибудь большее, чем это, я бы либо предварительно загрузил в память при запуске, чтобы я мог сохранить это, либо я написал отдельный метод, который будет выделять строку во время загрузки, а не хранить буфер вокруг.

Дополнительная информация:

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

char * LoadStringFromResource(uint id)
{
    // szBuffer is a globally pre-defined buffer of some maximum length
    LoadString(ghInst, id, szBuffer, bufferSize);
    // yes, I know that strdup has problems. But you get the idea.
    return strdup(szBuffer);
}

Ваш код становится:

char* errMem = LoadStringFromResource(IDS_ERROR_MEMORY);
char* errText = LoadStringFromResource(IDS_ERROR_TEXT);
MessageBox(NULL, errMem, errText, MB_OK | MB_ICONERROR);
free(errMem);
free(errText);

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

...