вторник, 24 февраля 2015 г.

Урок 3. Атрибуты id, idMso и idQ и пространство имён.

На первом уроке мы добавили свою вкладку со своей группой в интерфейс. Как вы, наверное, уже заметили, каждый элемент интерфейса формируется XML-структурой, которая состоит из открывающего и закрывающего тегов, атрибутов, присутствующих внутри открывающего тега, а также значений этих атрибутов, помещённых в кавычки. Имя тега — это имя элемента. Атрибуты — это параметры того или иного элемента.

Одним из важнейших параметров является идентификатор элемента, по которому приложение офиса отличает его от других элементов того же типа, находящихся рядом в том же родительском элементе-контейнере. Другими словами, он присутствует в любом элементе, если подразумевается возможность нахождения нескольких однотипных элементов на одном уровне иерархии. Так, например, элемент tabs не имеет идентификатора, поскольку внутри родительского элемента ribbon может быть только один элемент tabs. Других элементов tabs рядом быть не может. А вот элемент tab обязан иметь идентификатор, поскольку внутри tabs этих элементов может быть много, и их надо как-то различать.

Когда мы вставляем в интерфейс какой-либо элемент, вместе с формирующими элемент тегами в него вставляются некие обязательные атрибуты. При вставке tabs были вставлены только теги, обязательных атрибутов у этого элемента нет. А вот у tab обязательно должен быть идентификатор, поэтому внутри открывающего тега мы видим атрибут id, который как раз и задаёт этот идентификатор. Кроме того, странно было бы видеть вкладку без названия (её тогда даже не будет видно, если она не является текущей), поэтому в тег по умолчанию включён также атрибут label, который, хотя и не является обязательным, но практически всегда используется.

Атрибут id позволяет задать пользовательский идентификатор созданного элемента. Но наряду с элементами, созданными пользователем, существуют и штатные элементы, уже присутствующие в приложении. Это имеющиеся в нём изначально вкладки, группы, кнопки и т.д. Если мы захотим вставить в нашу вкладку уже готовую штатную группу, то вместо id мы пишем idMso (атрибут, задающий штатный идентификатор Microsoft Office) и вставляем в его значение идентификатор того элемента, который хотим видеть. Таким образом, id задаёт идентификатор для созданных пользователем элементов, а idMso — идентификатор уже существующего, штатного элемента офиса.

Проверим это на практике, вставив на нашу вкладку вместо нашей группы другую, уже существующую в Word’е. Для этого откроем в Ribbon XML Editor наш последний документ, установим курсор в любое место атрибута id созданной нами группы и нажмём Ctrl+Пробел. Выберем в появившемся списке атрибут idMso. Атрибут id поменяется на атрибут idMso. Теперь поставим курсор внутрь кавычек перед нашим идентификатором, и снова нажмём Ctrl+Пробел. Откроется список идентификаторов существующих групп. Выберем идентификатор GroupFont. Теперь запустим документ, и если у вас было включено отображение ошибок интерфейса (Файл - Параметры - Дополнительно - Общие - Показывать ошибки интерфейса пользователя надстроек), Word выдаст ошибку по поводу того, что не может изменить label существующей группы. Закрыв окно ошибки, мы увидим, что вместо нашей группы в нашей вкладке появилась существующая в Word’е группа «Шрифт», а наш атрибут label не применился. Так же были бы обруганы и все другие созданные нами элементы, если бы мы попытались вставить их внутрь этой группы. Отметим на будущее, что готовые штатные группы не поддаются модификации.

Помимо id и idMso есть ещё один интересный атрибут для задания идентификаторов — idQ. С помощью него можно выйти за рамки пользовательских и штатных идентификаторов, и сослаться на элемент, находящийся, например, в какой-нибудь сторонней надстройке. Это становится возможным благодаря тому, что idQ позволяет задать в своём значении не только сам идентификатор, но и некий префикс, которому заранее присвоено пространство имён, использующееся в сторонней надстройке. Другими словами, можно сказать, что область видимости idQ не ограничена конкретным пространством имён, как это происходит у id или idMso.

Немного о том, что такое упомянутое мной в выше пространство имён. Пространство имён — это просто часть имени идентификатора, т.е. кусок строки, негласно добавляемый перед строкой каждого идентификатора, находящегося в зоне действия этого пространства имён. Этим достигается уникальность имён всех идентификаторов внутри офисного приложения, даже если элементы одновременно присутствующих надстроек, в которых объявлены разные пространства имён, названы одинаково.

Кроме банального достижения уникальности, пространство имён часто используется для того, чтобы объединить несколько надстроек на одной, созданной для них вкладке. Обычно это делается в случае разделения одной большой надстройки на несколько более мелких. Это особенно удобно, если, например, разные группы в надстройке разрабатывается разными авторами. В этом случае во всех разрабатываемых надстройках объявляется одинаковое пространство имён, а идентификатор общей вкладки указывается атрибутом idQ с указанием префикса этого пространства. С примером использования idQ для объединения надстроек на одной вкладке мы познакомимся позже.

Исходя из вышесказанного вытекает, что idQ можно применять и вместо id и вместо idMso, и это так. Поясню на простейшем примере. Все штатные идентификаторы в 2007-й версии офиса находятся в пространстве имён «http://schemas.microsoft.com/office/2006/01/customui». Если мы посмотрим атрибуты элемента customUI в нашем коде, то найдём среди них атрибут xmlns, которому присвоена вышеупомянутая строка. Если в xmlns не указан префикс, то всем идентификаторам без префикса присваивается именно это пространство имён (т.н. пространство имён по умолчанию). В этом случае, атрибут idQ рассматривает все идентификаторы без префикса как идентификаторы пространства имён «http://schemas.microsoft.com/office/2006/01/customui». То есть, теоретически, мы можем писать idQ вместо idMso без какой-либо дополнительной доработки кода.

Теперь про использование idQ вместо id. Для этого надо объявить какое-то своё, дополнительное пространство имён — добавить второй атрибут xmlns с указанием желаемого префикса (в виде постфикса атрибута xmlns), и присвоить ему любую другую строку, которая и будет определять новое пространство имён, например:

    xmlns:моё="Моё пространство имён"

Теперь все идентификаторы, имеющие префикс «моё:» будут находится в нашем пространстве имён «Моё пространство имён», и вместо id="мояВкладка" можно написать idQ="моё:мояВкладка". В качестве пространств имён можно использовать любую строку с пробелами и другими символами, но на практике чаще всего используют URL (интернет-адрес).

Фактически по этому адресу в Интернете может не быть ничего. Например, в случае со стандартными пространствами имён «http://schemas.microsoft.com/office/2006/01/customui» и «http://schemas.microsoft.com/office/2009/07/customui» при переходе по этим адресам (по крайней мере, на момент написания этого урока) сайт http://schemas.microsoft.com вываливает строку «The resource you are looking for has been removed, had its name changed, or is temporarily unavailable.», т.е. «Ресурс, который вы ищете, был удалён, переименован, или временно недоступен.». Но в других случаях по подобным адресам можно найти странички с описанием соответствующего пространства имён.

На практике с пространствами имён и атрибутами, позволяющими его задавать внутри своих значений (а это не только idQ, а ещё и insertAfterQ и insertBeforeQ), мы познакомимся позже. А пока мы просто попытались понять различия между атрибутами id, idMso и idQ, а также получили первичное представление о пространствах имён.

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

14 комментариев:

  1. При вставке стандартного idMso сам Ворд пишет об ошибке свойства label, после чего переименовывает его в Шрифт. Ошибка возникает и при свойстве label="Шрифт". Само приложение ошибку не показывает при проверке. Пока не справился.

    ОтветитьУдалить
    Ответы
    1. Приведите пожалуйста пример кода, чтобы я мог его проверить.

      Удалить










    2. Код ошибки: 0х80004005
      Не удаётся изменить элементы управления во встроенной группе GroupFont

      Удалить
    3. Этот комментарий был удален автором.

      Удалить
    4. Виден ли код? А то на телефоне не отображается.

      Удалить
    5. Код не виден, но ведь он правильно пишет, элементы встроенной группы изменять нельзя. Можно создать свою группу, и натаскать туда нужные элементы.

      Удалить
    6. Я понимаю, но это не согласуется с вашим утверждением: "а атрибут label вообще игнорирован". Если оставлять любое значение атрибута label, то выйдет ошибка. Чтобы её избежать данный атрибут нужно удалить полностью.

      Удалить
    7. У меня он игнорировался. Возможно, у меня не было принудительно включено отображение ошибок в Word'е. Спасибо за замечание.

      Удалить
    8. Надо удалить Label вообще, т.е. оставить только идентификатор.

      Удалить
  2. Подскажите, пожайлуста, IdMso елемента "Цвет заливки" и к какой группе контролов он относится

    ОтветитьУдалить
    Ответы
    1. Видимо, вы имеете ввиду это:


      Нужные идентификаторы ищите в Word через всплывающие подсказки команд в настройках ленты.

      Удалить
    2. Не пропечаталось, повторю тут:

      Элемент: control
      idMso="TextHighlightColorPicker"

      Удалить
    3. Спасибо за ответ. Но...мне в Excele надо и нет такого idMso. Зато нашел CellFillColorPicker. Брал список с https://www.microsoft.com/en-us/download/details.aspx?id=36798, но трудно понять что есть что.
      За "Смотреть идентификаторы через всплывающие подсказки" отдельное спасибо! теперь все будет на одной вкладке :)

      Удалить
    4. https://www.microsoft.com/en-us/download/details.aspx?id=36798
      Оччень помогло.
      Получилось:
      idMso="MergeCells" — Объединить ячейки;
      idMso="SplitCells" — Разъединить ячейки;
      idMso="AutoSum" — Автосумма;
      idMso="SheetRowsInsert" — Вставить строки на лист;
      idMso="SheetRowsDelete" — Удалить строки с листа.

      Удалить