Значения параметров в файлах ресурсов представляются в виде строк. Перед использованием в программе, их надо преобразовать к требуемому типу. Так, например, значение атрибута XtNwidth задается строкой "100", но должно быть превращено в целое число. Для этого Xt и программы регистрируют специальные процедуры, преобразующие значения из одной формы представления в другую (т.е. из одного типа в другой). Их называют "конвертеры" (converter) (также мы будем употреблять термины "процедура-конвертор" и "преобразователь").
Механизм использования "конвертеров" следующий. Когда программа получает ресурс с помощью XtGetApplicationResources( ) или создает widget, обращаясь к XtCreateWidget( ) или аналогичной процедуре, Xt достает значение ресурса из базы данных. Это значение представлено в виде строки. Xt знает тип атрибута (обозначим его T) и ищет зарегистрированный "конвертер" "строка T". Если таковой есть, то он вызывается и значение ресурса переводится в требуемую форму. Если же "конвертера" нет, параметр получает значение по умолчанию.
Мы описали работу "преобразователя" "строка произвольный тип". Однако можно создать и зарегистрировать "конвертер" "произвольный тип произвольный тип" и использовать его для своих нужд.
Ниже, в таблице, приведены преобразования типов данных, поддерживаемые самой Xt.
Откуда | Куда | Описание |
XtRString | XtRAcceleratorTable | преобразует строку, задающую "таблицу" акселераторов во внутреннюю форму Xt |
XtRString | XtRAtom | преобразует строку, содержащую имя "свойства", в соответствующий атом |
XtRString | XtRBoolean | конвертирует строки "True", "False", "yes", "no", "on", "off" в соответствующее логическое значение |
XtRString | XtRBool | аналогично предыдущему |
XtRString | XtRCursor | преобразует стандартное название курсора для X WINDOW в соответствующий идентификатор |
XtRString | XtRDimension | конвертирует ширину и высоту к типу Dimension |
XtRString | XtRDisplay | преобразует имя дисплея и возвращает указатель на структуру типа Display |
XtRString | XtRFile | преобразует имя файла и возвращает его дескриптор |
XtRString | XtRFloat | конвертирует строку, задающую число, в формат float |
XtRString | XtRFont | преобразует имя шрифта и возвращает его идентификатор |
XtRString | XtRFontStruct | преобразует имя шрифта и возвращает указатель на структуру типа XFontStruct |
XtRString | XtRInitialState | конвертирует строки "Normal" или "Iconic" в символы NormalState или IconicState соответственно |
XtRString | XtRInt | конвертирует строку, содержащую число, в формат int |
XtRString | XtRPixel | преобразует строку содержащую имя цвета (например, black или #FF0000), в значение пиксела |
XtRString | XtRPosition | преобразует значения x и y координат к типу Position |
XtRString | XtRShort | конвертирует строку, содержащую число, в форму short |
XtRString | XtRTranslationTable | преобразует строку, задающую "таблицу трансляции", во внутреннюю форму Xt |
XtRString | XtRUnsignedChar | конвертирует строку, содержащую число, в форму unsigned char |
XtRString | XtRVisual | преобразует строку, задающую тип палитры, и возвращает указатель на структуру типа Visual |
XtRPixel | XtRColor | конвертирует значение пиксела в указатель на структуру типа XColor |
XtRInt | XtRBool | конвертирует целое в логическое |
XtRInt | XtRColor | конвертирует целое в XColor |
XtRInt | XtRDimension | конвертирует целое в Dimension |
XtRInt | XtRFloat | конвертирует целое в плавающее |
XtRInt | XtRFont | конвертирует целое в Font |
XtRInt | XtRPixel | конвертирует целое в значение пиксела |
XtRInt | XtRPixmap | конвертирует целое в Pixmap |
XtRInt | XtRPosition | конвертирует целое в Position |
XtRInt | XtRShort | конвертирует целое в short |
XtRInt | XtRUnsignedChar | конвертирует целое в беззнаковое целое |
Процедура-конвертор должна иметь следующий прототип:
void ConverterProc (XrmValue *prArgs, Cardinal *nArgs, XrmValue *prFromVal, XrmValue *prToVal); |
Здесь аргументы prArgs, prFromVal, prToVal - это указатели на структуры типа XrmValue (см. приложение 1) .
Процедура-конвертор должна преобразовывать данные из структуры prFromVal и результат помещать в структуру prToVal. Любые дополнительные данные, требующиеся при конвертации, передаются через аргументы prArgs и nArgs.
До того, как менеджер ресурсов сможет использовать указанную процедуру-конвертор, последняя должна быть зарегистрирована. Для этого можно использовать одну из функций XtAddConverter( ), XtAppAddConverter( ) или XtSetTypeConverter( ). В коде программы "конвертор" должен быть зарегистрирован после инициализации Xt, но до обращения к XtGetApplicationResources( ).
Процедура XtAddConverter( ) имеет следующий прототип:
void XtAddConverter (String prFromType, String psToType, XtConverter pConverter, XtConvertArgList prConvArgs, Cardinal nNumArgs); |
Первый и второй аргументы процедуры - это строки, задающие соответственно типы, из которого и в который надо преобразовывать. Это должны быть стандартные имена типов данных, определенные в файле "StringDefs.h", или имена, определенные в файле-заголовке программы. Третий аргумент задает непосредственно саму процедуру-конвертор. Четвертый и пятый аргументы задают дополнительные данные, которые передаются "конвертору" и используются им. При этом prConvArgs - указатель на массив структур типа XtConvertArgRec, определяемых следующим образом:
typedef struct { XtAdddressMode address_mode; XtPointer address_id; } XtConvertArgRec, *XtConvertArgList; |
Здесь address_mode определяет, как следует интерпретировать поле address_id. Возможные значения для поля address_mode даются перечисляемым типом XtAdddressMode:
typedef enum { XtAddress, /*адрес */ XtBaseOffset, /* смещение */ XtImmediate, /* константа */ XtResourceString, /* строчное имя ресурса */ XtResourceQuark, /* внутренняя форма задания ресурса */ XtWidgetBaseOffset, /* смещение от "родителя" */ XtProcedureArg, /* вызов процедуры */ } XtAddressMode; |
Здесь
XtAddress | указывает, что параметр address_id интерпретируется как адрес данных; |
XtBaseOffset | address_id интерпретируется как смещение относительно базового адреса widget; |
XtImmediate | address_id - константа; |
XtResourceString | address_id интерпретируется как имя ресурса, которое будет преобразовано в смещение относительно базового адреса widget; |
XtResourceQuark | address_id интерпретируется как имя ресурса, которое будет преобразовано во внутреннюю форму XtResourceString; |
XtWidgetBaseOffset | аналогично XtBaseOffset, за исключением того, что смещение рассматривается относительно "родителя", если последний не принадлежит подклассу класса Core; |
XtProcedureArg | address_id интерпретируется как указатель на процедуру типа XtConvertArgProc, которая будет вызываться при завершении конвертации (см. определение данного типа в приложении 2 данного издания). |
Процедура XtAppAddConverter( ) аналогична описанной выше процедуре, за исключением того, что добавлен еще один аргумент - контекст приложения. Процедура XtSetTypeConverter( ) также аналогична описанной процедуре, давая при этом дополнительные возможности по более эффективному конвертированию значений ресурсов (более детальную информацию по указанным процедурам можно найти в [9]).
Ниже приведен пример процедуры-конвертора, позволяющий преобразовывать строку в длинное целое.
Void CnvStringToLong (XrmValue *prArgs, Cardinal *pnNrgs, XrmValue *prFromVal, XrmValue *prToVal) { static long nResult; /* result variable */ if (*pnArgs! = 0) XtWarning ("String to Long conversion needs no extra arguments!"); if (sscanf ( (char *) prFromVal->addr, "%ld", &nResult) = = 1) { prToVal->size = sizeof (long); prToVal->addr = (XtPointer) &nResult; } else XtStringConversionWarning ( (char *) prFromVal->addr, XtRLong); } |
Данная процедура-конвертор использует функцию XtWarning( ) для печати предупреждающего сообщения, если число аргументов args больше нуля, для конвертирования строковой переменной в переменную типа long используется процедура sscanf( ). Результат работы данной процедуры сохраняется в структуре prToVal. Процедура XtStringConversionWarning( ) предназначена для выдачи предупреждающего сообщения при неуспешном завершении sscanf( ). Процедура имеет два аргумента типа String; первый - строка, задающая данные конвертируемого типа, второй - название типа данных, к которому не смогли быть преобразованы данные, определенные первым аргументом.
В заключении отметим следующее: в данном издании не освещаются некоторые аспекты работы с ресурсами, в частности, установка значений по умолчанию, описание подресурсов и методов работы с ними, и некоторые другие. Информацию по указанным вопросам можно найти, например, в [9,10] или в аналогичных изданиях.