Сохранение и загрузка фигур Visio в поток

Эта статься раскрывает данное сообщение в microsoft.public.visio.developers newsgroup (которая, кстати, уже померла), и предоставляет информацию о том, как можно сохранять фигуры Visio во внешнем источнике данных, и загружать их обратно. Обратите внимание, что это не имеет ничего общего с данными фигур. О том как использовать данные фигур, можно прочитать в руководстве по Visio, или в блоге Visio. Здесь же рассматривается именно загрузка и сохранение самих фигур. В общем, я думаю, данная статься может быть полезна, если только если вы разрабатываете что-нибудь достаточно хардконое под Visio =)

Итак, для того, чтобы сохранить фигуру во внешнем источнике можно:

— Запросить у нее интерфейс IDataObject. Все объекты типа Shape его поддерживают.
— Используя данный интерфейс, получить блок данных формата «Visio 11.0 Shapes» (см. код). Для Visio 2013 есть еще новый формат, с этим пока не разбирался, не знаю.

Данный блок данных может быть сохранен где пожелаете (база данных/память/файл/что угодно). Код примера просто сохраняет его в строковую переменную в base64. Теперь, чтобы положить фигуру обратно на диаграмму, можно использовать метод «Drop» у объекта Document/Page. Оказывается, данные функции вполне счастливы, если в качестве параметра им подсовывать IDataObject, и не требую обязательно Shape или Master в качестве параметра. Итак, чтобы положить сохраненную фигуру обратно нужно:

— Создать объект, реализующей интерфейс IDataObject.
— Когда Visio запросит данные, отдать их из этого объекта.
— Передать его  функцию «Drop»  (например в Page.Drop)

Для .NET, это все можно сделать с используя класс “DataObject” из .NET Framework, который сделает всю грязную работу. Основная идея:

string _clipFormat;
string _shapeData;

void SaveShape(IVShape shape)
{
  DataObject dataObj = new DataObject(shape);
  foreach (string clipFormat in dataObj.GetFormats(false))
  {
    if (clipFormat.Contains("Visio 11.0 Shapes"))
    {
      MemoryStream stream = (MemoryStream)dataObj.GetData(clipFormat);
      _clipFormat = clipFormat;
      _shapeData = Convert.ToBase64String(stream.ToArray());
    }
  }
}

void DropSavedShape(IVPage page)
{
  MemoryStream stream = new MemoryStream(Convert.FromBase64String(_shapeData));
  DataObject obj = new DataObject(_clipFormat, stream);
  page.Drop(obj, 0, 0);
}

Для С++ придется написать немного больше (см. исходники ниже).

Shape persistence source code (c++) (14.4 KiB)

Shape persistence source code (c#) (9.1 KiB)

Добавить комментарий