суббота, 14 марта 2009 г.

Как таблицы в текст пихались

В ОС Windows в RichEdit-контроле - который отвечает за форматированный текст RTF - поддержка таблиц реализована… да никак она, собственно, и не реализована. И девелоперском кругу бытует мнение, “что великий чешский писатель Карел Чапек был карелом”… тьфу ты… что поделать с таким “отсутствием” таблиц ничего нельзя. Однако на самом деле, чем старше версия RichEdit, тем больше возможностей работы с таблицами. Правда, иногда до них не так-то просто добраться, но все же они есть. Ты видишь суслика? Нет… Но суслик есть!” © – как именно добраться – разговор отдельный.

А за прошедшие зимние месяцы распространился было слушок, что новейшая версия RichEdit 6.0 (RE) не только умеет создавать и показывать таблицы – экая невидаль, это давным-давно “взятая высота”! Но и изменять размеры ячеек. Ну, а такой функционал меняет дело. Одно дело генерировать таблицы да любоваться на них, совсем другое предоставить пользователю возможность и самому порезвиться. А раз есть разница для пользователя, то скорее всего должна быть разница и для нашего кармана.

Оказывается эта версия RE есть в составе Microsoft Office 2007 (и не только). Не долго размышляя, скачал 2007-ой офис, поставил, с тоской посмотрел на него… и незамедлительно выпил © снёс.

Офис то снесен, но вот файлы системные от него остались. А вот именно они-то мне и нужны. Иду в папку %COMMON_FILES%\Microsoft Shared\OFFICE12 и с любопытством копаюсь в ее содержимом. Все привычно, серая скука и до боли знакомые файлы. Но посредь папки гордо красуется файл RichEd20.DLL, который вообще говоря, есть почти в любой даже Win98\2K, не то что в XP. Ага, думаю, очередная заглушка для совместимости… Но нафига же новейшему офису совместимость с древним RE 2.x-3.x – уж эти “заглушечные” DLL есть вообще практически в любой XP. Да и офис немаленький, на кой ему таскать заглушки, если он сам ими и вовсе не пользуется…

В общем, есть над чем призадуматься. Сигаретку, еще кофейчинского (ну какой девелопер без кофейчиского!?!) и начинаем, неспеша, эдакой “археологической метелкой” сметать пыль с нижних пластов “офисных” недр – ковыряться в подробностях.

Смотрите, экая штука! А размер-то RichEd20.DLL – аж почти цельный метр мегабайт – многова-а-ато - это уже вообще на заглушку никак не тянет.  И… о-п-п-па, смотрим в детали и вот оно: описание – “Microsoft RichEdit 6.0”, да и номер версии файла аж 12.xxx. Вообще в RichEd20.DLL содержится реализация RichEdit версии 3.0. Но размер самой DLL в версии 3.0 значительно меньше – что-то около 400 килобайт. И уж точно major-номер версии ну никак не 12 (имеется ввиду версия файла, если RichEdit 6.0 это версия продукта вообще, то версия файла несколько иное. Вы можете всё это увидеть в свойствах файла).

Ну, точно судя по всему это и есть новая версия. Долго сказки блоги сказываются, да быстро код пишется. Фтоппку все эти дот.нет`ы. Стартую старинную подружку 6-ую студию, генерю визардом простейшее MFC-приложение на основе СRichEditView и начинаю колдовать над “визардовым” кодом.

Элементарно, Ватсон! Ручками загружаем в адресное простраство необходимую DLL. На этапе создания вида CRichEditView подменяем имя класса окна… Компилируемся, с предыханием запускаем… И у-у-упс! Все сработало!  Рихтеровским Spy`ем проверяем класс окна. Отлично! Это RichEdit60W – приложение создало именно то, что просили. Затаив дыхание, открываем любой rtf-файл c таблицей… Подтаскиваем мыша к границе таблицы… Курсор меняется на стрелку! Нажали левую кнопку и перетаскиваем границы ячеек. Вуаля!

Получили приложение с поддержкой таблиц в тексте ака в не самой старой Висте. Но созданное аж в древнем Visual C++ 6, причем безо всяких там VS2008, WPF, SilverLight и иже с ними. Не так страшен черт, как его малюют, если только чуть-чуть спуститься с заоблачных высот абстракций к старому доброму WinAPI. Ну не люблю я, хоть режьте меня, все эти похотливые до вычислительных ресурсов модные новинки: постоянно пытающиеся подкачать очередной Дот.Нет в десяток метров, требущие пары гигов памяти, очередных service pack`ов…  А если можно несколькими простыми штрихами создать приложение, весящее первые сотни килобайт,  то зачем, пожалуйста скажите мне, за-а-ачем платить больше?

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

  1. В Delphi есть компонент TRxRichEdit из библиотеки RX. Я сменил в исходнике RxRichEd.pas
    RICHEDIT_CLASS = 'RichEdit60A';

    Скопировал MSPTLS.DLL, RICHED20.DLL в каталог, где exe-шник.


    О чудо - и картинки показывает и таблицы со всеми прибабахами.

    ОтветитьУдалить
  2. По идее лучше использовать RichEdit60W. Вообще-то уже вышел и RichEdit 7.0, только допроситься у MS где его взять как-то так и не удалось.

    ОтветитьУдалить
  3. Кстати сейчас нарвался на то, что если оффис не был установлен, то RICHED20.DLL не грузится с ошибкой.

    GetLastError()=0x36B1
    Приложение не было запущено, поскольку оно некорректно настроено. Повторная установка приложения может решить данную проблему.


    А кто нибудь знает как зашаманить что бы RICHED20.DLL грузится бы без оффиса ?

    ОтветитьУдалить
  4. Если не беспокоиться о лицензионной чистоте распространения этих файлов из состава офиса, то достаточно оба DLL файла просто расположить рядом с exe-шником. Причем именно оба: т.к. RichEdit20.DLL будет ругаться при загрузке на отсутствие MSPTLS.DLL, хотя и все равно грузится.

    Если же распространять нельзя, тогда можно вытаскивать эти файлы из папки офиса - известно где они лежат, нужно только проверять номера версий файлов. Т.к. в RichEdit20.DLL может быть и RichEdit 2.0 и RichEdit 3.0, но в той DLL номера версий младше.

    Если нужные файлы есть - отлично, их и юзаем. Если нет, то ищем предыдущие версии RichEdit. RichEdit 4.1 тоже достойная штука по возможностям, но она есть в составе XP SP3, соответственно с ней уже вроде как не должно быть никаких траблов с лицензионностью.

    Собственно, Aml Pages именно так и делает: сначала ищет новейшие версии RichEdit, если их нет, ищет более младшие, если и их нет, то еще более младшие. Только нужно помнить в младших версиях и другие имена классов окон (RichEditXXA).

    ОтветитьУдалить
  5. Взял richedit20.dll из оффиса 2003.
    Поставил класс RICHEDIT_CLASS = 'RichEdit50A';

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

    Пока вопрос о лицензионности не рассматривал. Если удастся "уговорить" richedit20.dll из XP+SP3, то и вопрос отпадёт.

    ОтветитьУдалить
  6. На самом деле юзается библиотека MsFtEdit.DLL, это RichEdit 4.1 из XP SP3, ну и имя класса окна RichEdit50W/A (лучше сразу ставить W). Таблицы отображает эта версия нормально, но вот изменять размеры ячеек она действительно не умеет.

    ОтветитьУдалить
  7. 1 Во первых - спасибо автору блога за консультацию!

    2 TRxRichEdit работает с RICHED20.DLL(5.50.99.2010), взятого из "C:\Program Files\Common Files\Microsoft Shared\OFFICE11\"

    RICHEDIT_CLASS = 'RICHEDIT50W';


    3 C MsFtEdit.DLL(5.41.15.1515, XP+SP3) этот TRxRichEdit не заработал. Разбираться не буду почему.

    ОтветитьУдалить