строка в ресурсе

Предыдущая тема Следующая тема Перейти вниз

строка в ресурсе

Сообщение  Eric-S в Пт Сен 04, 2009 5:13 pm

Привет!

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

Соответственно, как это сделать, и как потом взять эту строчку?

Eric-S

Сообщения : 738
Дата регистрации : 2008-08-06
Возраст : 34
Откуда : Россия, Санкт-Петербург

Посмотреть профиль http://eric50.narod.ru

Вернуться к началу Перейти вниз

Re: строка в ресурсе

Сообщение  tux в Пт Сен 04, 2009 5:35 pm

глянь на файлы *.po, специально для локализации (если правильно помню), я сильно в ето не выникал, но ето спец для лолизации сделано
avatar
tux

Сообщения : 365
Дата регистрации : 2008-04-06
Возраст : 29
Откуда : Сибирь

Посмотреть профиль http://tux.nsk.ru/

Вернуться к началу Перейти вниз

Re: строка в ресурсе

Сообщение  Eric-S в Пт Сен 04, 2009 5:43 pm

Да, GetText я знаю. Забавная вещь.
Но меня интересуют именно стандартные виндовые ресурсы.

Как я уже понял, строку из ресурсов надо читать функцией LoadString()

Вот чувак конкретно пишет,

http://blogs.gotdotnet.ru/personal/imwhistler/PermaLink.aspx?guid=d394bf20-6d26-4da6-acdb-0f5810f99aac


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

И я согласен с этим утверждением.

А gettext и его разработчики не согласны.

Eric-S

Сообщения : 738
Дата регистрации : 2008-08-06
Возраст : 34
Откуда : Россия, Санкт-Петербург

Посмотреть профиль http://eric50.narod.ru

Вернуться к началу Перейти вниз

Re: строка в ресурсе

Сообщение  Eric-S в Пт Сен 04, 2009 5:59 pm

Загрузка строковых ресурсов 
-----------------------------------------------------------------
Принципиальная причина выделения строк приложения в качестве ресурсов состоит в облегчении процесса настройки приложения на конкретное применение или возможности перевода приложения на иностранный язык. Если строки определены в исходном коде, то для их изменения или перевода нужно иметь доступ к исходному коду.
Если же они определены как ресурсы, то хранятся в таблице строк выполняемого файла приложения. Вы можете использовать редактор строк для перевода строк в таблице, без изменения и даже доступа к исходному коду.
Каждый выполняемый файл может иметь только одну таблицу строк.
 
Для загрузки строки из таблицы в буфер сегмента данных вашего приложения используется функция LoadString. Синтаксис
LoadString следующий:
 
LoadString(HInstance, StringID, @TextItem,SizeOf(TextItem));
 
* Параметр StringID - это номер идентификатора строки (например, 601) в таблице строк. Это число можно заменить
константой.
 
* Параметр @TextItem - это указатель на массив символов (PChar), который принимает строку.
 
* Параметр SizeOf(TextItem) - это максимальное число символов, передаваемых в @TextItem. Максимальный размер ресурса
строки 255 символов, поэтому передача буфера из 256 символов гарантирует полную передачу строки.
 
LoadString возвращает число скопированных в буфер символов, или ноль, если ресурс не существует.
 
Вы можете использовать ресурс строки для вывода текста в блоке сообщения. Например, вы можете вывести сообщение об ошибке.
В данном примере вы определяете строку 'Program unavailable' в таблице строк и определяете константу ids_NoProgrm в качестве
идентификатора строки. Для использования этого ресурса строки в блоке сообщения об ошибке, вы можете написать следующую процедуру:
 
procedure TestDialog.RunErrorBox(ErrorNumber:
Integer); virtual;
var
TextItem: array[0255] of Char;
begin
LoadString(HInstance, ids_NoPrgrm, @TextItem, 20);
MessageBox(HWindow, @TextItem, 'Error', mb_OK or
mb_IconExclamation);
end;
 
Данный пример загружает отдельную строку в блок сообщения об ошибке. Для загрузки списка строк в блок списка вызывается
LoadString для загрузки каждой строки, затем вызывается AddString для добавления ее в блок списка.

Eric-S

Сообщения : 738
Дата регистрации : 2008-08-06
Возраст : 34
Откуда : Россия, Санкт-Петербург

Посмотреть профиль http://eric50.narod.ru

Вернуться к началу Перейти вниз

Re: строка в ресурсе

Сообщение  Eric-S в Пт Сен 04, 2009 6:06 pm

Функция LoadString

Описание:

function LoadString(Instance: THandle; ID: Word; Buffer: PChar; BufferMax: Integer): Integer;

Загружает поименованный ресурс строки и копирует ее в Buffer, присоединяя в конец пустой символ.

Параметры:

Instance: Экземпляр модуля, исполнимый файл которого содержит строку.

ID: Целочисленный идентификатор строки.

Buffer: Принимающий буфер.

BufferMax: Размер буфера.


Возвращаемое значение:
Фактическое число скопированных байт; 0 - если не существует.
функция находится в файле user32.dll

Eric-S

Сообщения : 738
Дата регистрации : 2008-08-06
Возраст : 34
Откуда : Россия, Санкт-Петербург

Посмотреть профиль http://eric50.narod.ru

Вернуться к началу Перейти вниз

Re: строка в ресурсе

Сообщение  Eric-S в Пт Сен 04, 2009 6:09 pm

Ресурсы в виде таблиц строк (Stringtable) являются очень полезным подспорьем, когда ваше приложение должно хранить большое количество строк для их вывода
во время выполнения приложения. Вы должны побороть искушение непосредственной вставки строк в вашу программу, поскольку использование таблиц строк имеет
два неоспоримых преимущества: 1) Строки, хранимые в ресурсах, не занимают память до тех пор, пока они не будут загружены вашим приложением. 2) Stringtables
легко редактировать, создавая таким образом локализованные (переведенные) версии вашего приложения.

Таблицы строк компилируются в ".res"-файл, который включается в exe-файл приложения во время сборки. Даже после того, как вы распространите ваше приложение,
таблицы строк, содержащиеся в вашем приложении могут редактироваться редактором ресурсов. Моим любимым редактором ресурсов является Borland Resource Workshop,
поставляемый в комплекте с Delphi. Он позволяет в режиме WYSIWYG редактировать как 16-, так и 32-битные ресурсы, как автономные, так и имплантированные
в exe или dll-файлы.

Eric-S

Сообщения : 738
Дата регистрации : 2008-08-06
Возраст : 34
Откуда : Россия, Санкт-Петербург

Посмотреть профиль http://eric50.narod.ru

Вернуться к началу Перейти вниз

Re: строка в ресурсе

Сообщение  Eric-S в Пт Сен 04, 2009 6:14 pm

Вот содержание .rc-файла для нашего примера. Файл содержит слова "Yes" и "No" на английском, испанском и шведских языках:

STRINGTABLE
{
1, "&Yes"
2, "&No"
17, "&Si"
18, "&No"
33, "&Ja"
34, "&Nej"
}
Файл начинается с ключевого слова stringtable, обозначая, что следом располагается таблица строк. Сами строки находятся внутри скобок, таким образом таблица
должна быть обрамлена двумя скобками - открывающей и закрывающей. Каждая строка должна содержать идентификатор, сопровождаемый строкой, заключенной в кавычки.
Строка может содержать вплоть до 255 символов. Если вам нужно вставить нестандартный символ, напишите его восьмиричный код и предварите его обратной косой
чертой. Единственное исключение - когда вам нужно вставить саму обратную черту - в этом случае понадобиться использование двух таких символов. Вот два
примера:

1, "A two\012line string"
 
2, "c:\\Borland\\Delphi"
Используемый номер индекса абсолютно не важен для компилятора. Вы должны иметь в виду, что таблицы строк располагаются в памяти в 16 битных сегментах (Win 3.xx).

Eric-S

Сообщения : 738
Дата регистрации : 2008-08-06
Возраст : 34
Откуда : Россия, Санкт-Петербург

Посмотреть профиль http://eric50.narod.ru

Вернуться к началу Перейти вниз

Re: строка в ресурсе

Сообщение  Eric-S в Пт Сен 04, 2009 6:16 pm

Ндя... Всё же яндекс это сила.

А примеры выдраны из нескольких статей по делфи. Линков не даю, потому что сам делфи это отстой!

Пойду мучать тесты!

oftop:
Electrik, почему ты не здесь? Звякни на город или скайп.

Eric-S

Сообщения : 738
Дата регистрации : 2008-08-06
Возраст : 34
Откуда : Россия, Санкт-Петербург

Посмотреть профиль http://eric50.narod.ru

Вернуться к началу Перейти вниз

Re: строка в ресурсе

Сообщение  electrik в Пт Сен 04, 2009 7:08 pm

файл test.bi

Код:

#define myString 1001
#define helloString 1002

файл test.rc

Код:

#include "test.bi"

STRINGTABLE
{
myString "this is my string"
helloString "hello world"
}

файл test.bas

Код:

#include "windows.bi"
#include "test.bi"

dim progHandle as HMODULE
dim StrTable(1001 to 1002) as Zstring * 64
progHandle = GetModuleHandle(NULL)
for i as integer = 1001 to 1002
LoadString(progHandle, i, @strTable(i), 64)
next

messagebox(0,strTable(helloString),strTable(MyString),0)

компилировать:
fbc -s gui test.rc test.bas


Последний раз редактировалось: electrik (Пт Сен 04, 2009 7:20 pm), всего редактировалось 1 раз(а)

electrik

Сообщения : 391
Дата регистрации : 2008-09-02
Возраст : 37
Откуда : галактика Млечный путь, система Солнечная, планета Земля, страна россия, город Санкт Петербург

Посмотреть профиль

Вернуться к началу Перейти вниз

Re: строка в ресурсе

Сообщение  Eric-S в Пт Сен 04, 2009 7:19 pm

О! А вот и Электрик подал голос.
Я уже в принципе сам нечто аналогичное сделал, только правда прямо в программе.

Ну что же, вот пользуйтесь.
Это кажеться гораздо правильнее .

Eric-S

Сообщения : 738
Дата регистрации : 2008-08-06
Возраст : 34
Откуда : Россия, Санкт-Петербург

Посмотреть профиль http://eric50.narod.ru

Вернуться к началу Перейти вниз

Re: строка в ресурсе

Сообщение  Eric-S в Пт Сен 04, 2009 7:37 pm

Я немного по другому сделал. Примерно так:

Код:

// получение строки
function get_res_string( buf as wstring ptr, id as integer ) as wstring ptr
LoadString( _
GetModuleHandle(NULL), _
id, buf, 256 )
function = buf
end function


// тестовая функция
sub foot()

// создаём буфер для строки
dim ws as wstring ptr
ws = new wstring[256]

// выведем сообщение
MessageBox( NULL, _
get_res_string( ws, myString  ), _
get_res_string( ws, helloString ), _
MB_ICONINFORMATION )

// освобождаем буфер
delete[] ws
end sub
т.е. для разных ситуаций разные варианты удобнее.
Как сделал Электрик... Дык ведь ещё нужно разом выделить память под весь массив.
И тем более сделать его глобальным.
У меня же, будут тормоза не во время загрузки, а во время исполнения, где их будет очень трудно заметить. Кроме того память не будет столь щедро расходоваться.

Но вариант Электрика, приколен тем, что строки второй раз уже не читаються из ресурсов.

Кстати, возможно вы обратили внимание, на то что у меня wstring, а у Электрика zstring?

Строки, в ресурсах программы, храняться в юникоде, т.е. wstring.

соответственно функция
LoadStringW берёт оригинальную строку.
А функция
LoadStringA перекодирует её в ansi, на что конечно же тоже тратиться время.

Eric-S

Сообщения : 738
Дата регистрации : 2008-08-06
Возраст : 34
Откуда : Россия, Санкт-Петербург

Посмотреть профиль http://eric50.narod.ru

Вернуться к началу Перейти вниз

Re: строка в ресурсе

Сообщение  Eric-S в Сб Сен 05, 2009 5:27 am

Ндяс... Моя функция всё же требует некоторой доработки... Нужен ещё один параметр, который будет возвращать длину строки.
В прочем фиг с ним, когда приспичит, тогда и вкручу.

А вот мне стало интересно. Если я создаю текстовой файл ресурса в системной кодировке, например windows-1251, то компилируеться он в юнинкод или как?
Вроде бы юникод, но меня смущает именно перекодировка при компиляции.

А не может ли ресурс оказаться в аски? И конвертиться в юникод, при необходимости?

Eric-S

Сообщения : 738
Дата регистрации : 2008-08-06
Возраст : 34
Откуда : Россия, Санкт-Петербург

Посмотреть профиль http://eric50.narod.ru

Вернуться к началу Перейти вниз

Re: строка в ресурсе

Сообщение  Спонсируемый контент


Спонсируемый контент


Вернуться к началу Перейти вниз

Предыдущая тема Следующая тема Вернуться к началу


 
Права доступа к этому форуму:
Вы не можете отвечать на сообщения