среда, 16 июля 2008 г.

Переезд

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

Вообщем встречайте новый адрес блога про программирование с wxWidgets

среда, 9 июля 2008 г.

Достало восстанавления лайота в AUI

Как же меня достал механизм восстанавления лайота в AUI, который не может отследить ситуацию что реальный лайот  у нас поменялся (добавился новый элемент), и все косячит:(

понедельник, 16 июня 2008 г.

wxMenu с иконками и обход выделенных атемов в wxListCtrl

Пара маленьких функий, может кому пригодится.

Был удивлен что у wxMenu::Append нету для добавления меню с картинками. Пришлось писать самому

 

wxMenuItem * MainFrame::AppendMenuItemWithImage(wxMenu* parentMenu,

int id, const wxString& text, const wxString& helpString, const wxBitmap& checked, const wxBitmap& unchecked, wxItemKind kind, wxMenu* subMenu)

{

       wxMenuItem* menuItem =

      new wxMenuItem(parentMenu, id, text, helpString, kind, subMenu);

       menuItem->SetBitmaps(checked, unchecked);

       parentMenu->Append(menuItem);

       return menuItem;

}

Использование:

wxMenu* itemMenu = new wxMenu;

AppendMenuItemWithImage(itemMenu, ID_HIDE, _("&Hide In Tray\tEsc"), _T(""), wxBitmap(hide_xpm));

AppendMenuItemWithImage(itemMenu, wxID_EXIT, _("E&xit\tAlt-x"), _T(""), wxBitmap(exit_xpm));

menuBar->Append(itemMenu, _("&File"));

 

И еще один маленький хелпер для удобной работы  с выделенными айтемами в wxListCtrl:

vector<

long> MainFrame::GetListCtrlItems(const wxListCtrl * lcont, int state /*= wxLIST_STATE_DONTCARE*/, int geometry /*= wxLIST_NEXT_ALL*/, long item/*=-1*/)

{

   vector<

long> items;

   items.resize(lcont->GetSelectedItemCount());

// надеюсь так быстрее чем push_back

    long ind=0;

  do

  {

     item= lcont->GetNextItem(item, geometry, state);

     if (item!=-1) items[ind++]=item; //items.push_back(item);

  }

while( item != -1 );

return items;

}

Использование:

vector<

long> items=GetListCtrlItems(m_listFormat, wxLIST_STATE_SELECTED);

BOOST_FOREACH(

long item, items)

{

   str+=m_listFormat->GetItemText(item)+wxT(

"\n");

   …

}

Иногда удобнее работать с вектором, хотя это я просто сейчас с STL знакомлюсь, вот и выпендриваюсь:)

пятница, 30 мая 2008 г.

А счастье казалось так возможно с EVT_CHAR_HOOK

Так я думал когда увидел в wx-mail-list упоминание EVT_CHAR_HOOK. В доке про этот эвент ничего нет, но порывшись в гугле и поэкспеременитровал - я понял что его обработчик получает все нажатия клавиш для окна перед тем как они будут обработанны дочерними контролами. И возрадовался. Дело в том что я люблю так хоткее делать, под мфц это было PreTranslateMessage, под wxWidgets найденный вариант был - вся работа в обработчике EVT_KEY_DOWN и connect для (почти) каждого контрола на форме

m_Note->Connect(wxID_ANY, wxEVT_KEY_DOWN, wxKeyEventHandler(MainFrame::OnKeyDown), (wxObject*)NULL, this);

А поскольку коннкетить каждый контрол для сложного окна не самое приятно времепрепровождение, то я легко возбудился увидив  EVT_CHAR_HOOK. И действительно коннекты уже не нужно, обработчик вызывается автоматом. Проблемы вылезли через пару дней:(. Первое по esc приложение "прячется" в трей - в новом варианте, если при открытом меню нажать еск, приложение спрячется а меню останется висеть:) Те хоткеи обработка которых зависила от выбранного в данный момент окна - то же в пролете.

Вообщем не получилось, хотя возможно стоит использовать EVT_CHAR_HOOK для ряда глобальных хоткеев (хотя с этим и меню справляется), а EVT_KEY_DOWN  оставить для более специфических вещей.

вторник, 20 мая 2008 г.

Update для функции ReplaceForbiddenCharsInFileName

Обнаружил что Винда не любит точки в конце папок, поэтому доработал функциию ReplaceForbiddenCharsInFileName, теперь будет так

/********************** 22/03/08 19:41 *************************

deleteDotsAtEnd - удалять ли точки в конце, винда неразрешает такие имена, хотя и дает их создать програмно:)

******************************************************************/

/*static*/

wxString & BegUtils::ReplaceForbiddenCharsInFileName(wxString & name, const wxString ch/*=wxT("_")*/, bool deleteDotsAtEnd/*=true*/)

{

  wxString forbidden = wxFileName::GetForbiddenChars();

  int size=forbidden.Length();

  for (int i=0; i<size; ++i)

     name.Replace( wxString(forbidden[i]), ch,

true);

  if (deleteDotsAtEnd)

  {

     int count=0, len=name.Len()-1;

     while( name.GetChar(len-count)==_T('.')) count++;

    if (count) name=name.Left(name.Length()-count);

  }

  return name;

}

(пока я пишу только под винду)

суббота, 12 апреля 2008 г.

wxWidgets: Немного о хорошем

Что-то последнее время были преимущественно негативные топики. Но не все так плохо, просто готовил программу к релизу, осваивал кучу новых тем, разумеется много чего не получалось вот и расстраивался:)

А вообще:

  1. Сайзеры это прикольно, конечно незнаю как они поведут себя при портировании под другие ОС. Пока пишу только под винду - вполне нравится.
  2. DialogBlocks is good resource editor for wxWidgets applications. Так все-таки не плох. Конечно надо разобратся, привыкнуть - но в принципе использовать можно. Особенно полезно поигратся на первых порах что бы понять идеологию сайзеров, изучить свойства и поиметь представления как вообще делать интерфейс.  Правда мне не особенно нравится код который он генерит да и гибкости немного не хватает что бы делать главные окна приложений... Но для отдельных простых диалогов - типа опций, вспомогательных окон - достаточно быстро можно нарисовать интерфейс. Хорошая вешь. Кстати незарегистрированная копия - вполне пойдет для ознакомления с иделогией построения интерфейса. Воообщем зачет:)
  3. Проблему с отсутвием контрола для ввода горячей клавиши в wxWidgets. Я вроде решил, вставил родной виндовый Hot Key Control, попытавшись обернуть его в wxWidgets. Так как документации по этой теме я не нашел - код там наверное кривой до ужаса:) Но если испытания покажут что работает, можно будет его почистить и выложить.
  4. Размер программы. Для меня это  имело большое значения, программы у меня маленькие, вспомогательные утилиты которые висят в трее. Сейчас размер получился 1.9М что почти в 4 раза больше версии с MFC, но судя по всему на скорости работы это не сказалось.
  5. Ну и главное я все таки выпустил программу, уже несколько дней вроде полет нормальный:) Так что можете удобно хранить свои быстрые заметки :)

Вообщем к эксплуатации пригодно.

вторник, 8 апреля 2008 г.

Отрелизился:)

Наконец более-менее дописал, хотя с иконками конечно еще плохо, но если кому интересно - бету, а фактически релиз, можно посмотреть тут.

Завершение программы при выходе из системы или EVT_QUERY_END_SESSION нам не всегда друг

Полюбуйтесь на это  - http://sourceforge.net/tracker/index.php?func=detail&aid=1428691&group_id=9863&atid=109863 . Багу больше 2x(!) лет, тянется еще с прошлого стабильного релиза. До сих пор не пофиксен. Status: Open.  А ведь есть специальные события даже  EVT_QUERY_END_SESSION и EVT_END_SESSION

Потратил полдня включая\выключая комп что бы найти приемлимый порядок команд для того что бы заставить его корректно выходить при выключении компа и сохранять настройки. И вчера уже собираясь выложить первую бету народу, обнаружил что под win2K не работает все равно. Мало того что не работает, так еще и подвисает при выходе. Сейчас опять буду е****я что бы работало везде.

понедельник, 7 апреля 2008 г.

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

Изолью душу:) Решил добавить сабж, думал все просто: копи\пайст с книжки, разобраться, подправить под себя, потестить - на час работы, максимум два. Растянулось на целый день:)

Скопировал, разобрался, подправил, тестю - все ок. Обрадовался, собрал себе релиз для внутреннего пользования -  и тут засада. В релизе, при запуске второй копии, падает сервер. Дебаг, понятное дело затруднен... В итоге нашел падает на строчке.

return m_connection;

В wxConnectionBase *stServer::OnAcceptConnection(const wxString& topic). Вернее конечно не на ней, а после нее в дебрях библиотеки. Начал ковырятся, дошел до того что поведение программы, в смысле место падения, меняется в зависимости от того где определен конструктор в заголовочном файле или в cpp :).  В итоге решил вообще отказатся от использования соединений для общения, просто если приходит от клиента попытка установить соединение, ему отказывать и серверу появлятся на экране. Так работало.

Но тут осенило, что трабла в то что, где-то что-то портило память - поэтому такое, более чем странное поведение программы. Решил рыть до конца. В итоге заметил, что в декларациях классов скопированных с книжки, после определения функций в пределах h файла ';' то есть, то нет. Насколько я знаю это не критично, можно ставить можно нет. Решил поставить везде ';' и чудо свершилось... с надеждой в душе, убрал их назад в небытие, но не помогло - программа все равно не падала. Вот и как это объяснить?

пятница, 4 апреля 2008 г.

Сколько весит wxHtmlWindow

Добавление к программе wxmsw28u_html.lib для поддержки wxHtmlWindow и about- диалога основанного на хтмл утяжеляет екзешник на 170 кб, для меня это 10%.

понедельник, 31 марта 2008 г.

C размаху головой об стену бьюсь

Начал делать опции, диалог набросал - вполне нормально получилось. А дальше траблы:

  1. Контрола для ввода горячей клавиши в wxWidgets нету. Из сторонних решений есть keybinder, но как я понять это достаточно мощный комбаин предназначенный немного для другого. Но попробую поковырять. Откровенно говоря подозреваю что такой контрол и ручками можно написать достаточно просто или вообще виндовый заюзать (хотя не уверен что это можно).
  2. Чекбоксы не поддерживают мультилайн. Хреново. \r\n не работает, хотя это было бы тоже не выход а костыли. Почему то у wxStaticText есть Wrap, а чекбокса нету.

 

Да если вас заинтересовал первый пункт, то наверное будет интересно узнать, что возможности сделать system wide hotkey под linux'om тоже нету. Разработчики библиотеки говорят - что линукс не дает такого апи. Хотя ходят слухи, что какие обходные пути есть. Дожевем до линукса посмотрим.

четверг, 27 марта 2008 г.

GetForbiddenChars() -> ReplaceForbiddenCharsInFileName()

Оказалось, что если в диалог открытия файла в качестве дефолтного имени передать имя содержащее запрещенные символы - он вываливается с ошибкой так и не открывшись. Проверил под MFC, тоже не фонтан,  просто молча не открывается. Так что надо запрещенные символы убирать. Удивился, что это не делает сама библиотека, перед тем как сунуть имя в системный диалог. Полез искать функцию которая могла бы это сделать. Удивился еще больше - похоже такой функции нет(или я не нашел).

wxFileName::GetForbiddenChars() есть, а обработать имя нечем. Написал свою.

/*static*/

wxString & BegUtils::ReplaceForbiddenCharsInFileName(wxString & name, const wxString ch/*=wxT("_")*/)

{

    wxString forbidden = wxFileName::GetForbiddenChars();

    int size=forbidden.Length();

    for (int i=0; i<size; ++i)

          name.Replace( wxString(forbidden[i]), ch,

true);

   return name;

}

 

P.S. Кстати если в диалоге выбора папки - выбрать что-нибудь типа Мой Компьюте или Сетевое Окружение и нажать ОК, то диалог ввернет wxID_CANCEL. Он то вроде и правильно, нельзя же в эти папки писать - но пользователь может и не понять. Под MFC возращает id_ok и кривой путь, в результате получается запись в корень с:

суббота, 22 марта 2008 г.

Антиспамеры зло

Чего-то там правят в списках рассылки wx'совских, перенесли на новый сервер, поставили SpamAssassin.  Теперь все мои письма Blocked by SpamAssassin. Обращения на форум шадонета не помогло, письмо лично тому чуваку который анонсировал изменения в майл листах тоже без ответа. Так что теперь чукча не писатель, чукча читатель.

четверг, 6 марта 2008 г.

Грузим текстовый файл

Задача: есть wxTextCtrl, пользователь должен уметь загружать в него свои текстовые файлы для просмотра и редактирования, своего рода notepad. Файлы у пользователя могут быть в ANSI, utf-8 и в одном из двух юникодов.

Есть wxTextCtrl::LoadFile() - думаю зашибись, повезло. Тестирую, юникод\утф-8 грузит, ANSI грузит только если там одни английские символы, если есть русские обламывается. Нахожу? что проблема в дебрях библиотеки, в попытке грузить файл как wxFFile::ReadAll(wxString * str, wxMBConv& conv = wxConvUTF8)

Спрашиваю в wx-dev@, вот ответ

TN> Is this a bug? If no, is there a any way to load ANSI files in unicode
TN> build?

Yes, use wxCSConv(wxFONTENCODING_CP1251) instead of default wxConvAuto
which only handles UTF-x encodings in 2.8 (in the trunk it falls back to
the system default encoding if the input doesn't seem to be in UTF-8, but
not in 2.8).

Баг это или нет, я так и не понял. Но понял что wxTextCtrl::LoadFile() использовать нельзя, так как кодировку там задать нет возможности. Пришлось использовать напрямую wxFFile, с шаманством. Вот функция для загрузки файла

bool BegUtils::ReadFileToString(const wxString & FileName, wxString & Data)

{

wxFFile file(FileName);

if (!file.IsOpened() ) return false;

// пытаемся читать файл подразумевая что он юникодный

if (!file.ReadAll(&Data)) return false;

if (Data.IsEmpty() && file.Length()>0)

{ // Если строка пустая и длина у файла есть - то он наверняка был анси, читаем как анси

file.Seek(0);

if (!file.ReadAll(&Data, *wxConvCurrent)) return false;

}

return true;

}


Вроде как работает, правда будут проблемы при загрузки пустых юникодных файлов - на экране будет мусор (BOM), можно конечно проверять загруженную строку на равенство одному из них, но я забил.

Подозреваю что это довольно кривой метод, поэтому если кто знает как решить задачу "правильно", с удовольствием послушаю.

понедельник, 3 марта 2008 г.

Легким движением руки брюки превращаются... (опять поиск и замена wxTextCtrl)

Я уже давал ссылку на мою статью про написание Find & Replace для wxWidgets-приложений. Тот код я начинал писать для wxTextCtrl'a со стилем wxTE_RICH, а закончил и окончательно тестировал на wxRichTextCtrl'e. Сейчас я отказался от использования wxRichTextCtrl (только если вдруг его допишут до юзабельного состояния), и вернулся на самый что не на есть простой виндовый эдит, тот который в нотепаде. Пришлось править код поиска и замены.  Если вам нужен код для поиска и замены в *обычном* wxTextCtrl (без  wxTE_RICH), то правьте код из статьи вместе со мной. Пока я нашел вот что.

1. Выкидываем или убираем под дефайн следующую строчку

#ifdef

WeUseWXRichTextCtrl

//If we have not selection, wxTextCtrl return StartFromBack=StartFromForward=Current_Insertion_Point, but wxRichTextCtrl return -2,-2

if (StartFromBack<0) StartFromBack=StartFromForward=m_Note->GetInsertionPoint();

#endif

2. Дальше оказывается что ищет криво, причина находится в документации. Перед тем как считать startPos и endPos, добавляем следующий код (изврат конечно, но что делать, кому сейчас легко?):

#ifdef WeUseWXTextCtrl

#ifdef

__WIN32__

// проблемма с wxTextCtrl - The multiline text controls always store the text as a sequence of lines separated by \n characters, i.e. in the Unix text format even on non-Unix platforms. This allows the user code to ignore the differences between the platforms but at a price: the indices in the control such as those returned by GetInsertionPoint or GetSelection can not be used as indices into the string returned by GetValue as they're going to be slightly off for platforms using \r\n as separator (as Windows does), for example.

m_foundPos+=(string.Left(m_foundPos)).Replace(wxT(

"\n"), wxT("\n")); // Returns the number of replacements made.

#endif

#endif

3. В OnReplace убираем или выносим под ифдеф 1 строчку.

if (SelText==FindText)

{

#ifdef

WeUseWXRichTextCtrl

m_Note->DeleteSelection(); // this line is needed only for wxRichTextCtrl and needed not for wxTextCtrl

#endif

m_Note->WriteText(m_findData.GetReplaceString());

}

В итоге брюки превращаются...

Теперь вроде все ок, но если что еще найду - напишу.

суббота, 1 марта 2008 г.

Русский форум по wxWidgets

The wxWidgets forum has opened 3 sub forums for our international wx
friends. In the past it had appeared to us that non-native speakers
can't express their problems with wxWidgets very well which can
increase frustration unnecissarily. So we decided to open a Chinese,
Russian and French sub forum to begin with, and if needed, will open
some more for other languages. If English is not your first language
and you're still strugging a bit to explain exactly what your problems
are, go take a look at http://wxforum.shadonet.com/



Вообщем теперь есть русский подфорум по wxWidgets на шадонете - общайтесь. Ура.

среда, 27 февраля 2008 г.

Побуждающая сила мысли

В начале января я уже писал про кучу багов в wxRichtTextCtrl и невозможности, на мой взгяд, использовать его в реальных приложениях. Потом я отвлекся на другие проекты, сейчас вернулся опять к переписыванию программы для быстрых заметок на wx. Полез в трекер смотреть как там мои баги поживают. Глухо, за полтора месяца из 7 тикетов ни один не отвечен. Хотя посмторел репозиторий кода - за это время более 10 правок только в одном из файлов реализующих wxRichTextCtrl. Короче решил плюнуть на ихний ричедит и довольствоваться простым виндовым эдитом.

Буквально через полдня приходят ответы на все мои тикеты:) Пару простых судя по ответам исправили, про более сложный загадочно написали  (пометив тикет как fixed\closed)

This should be fixed in 2.8 branch (forthcoming 2.8.8) and SVN trunk.

Несколько других - не прошли. Вердикт - если исправили, редактор стал немного более юзабельным. Но по прежнему для моих задач - эмуляция простого редактора без ртф возможностей или с ограниченными ртф возможностями, например только форматирование текста без картинок - неподходит. Причем как я понял это принципиальная позиция Julian Smart'a. Буду пока виндовый эдит использовать.

суббота, 16 февраля 2008 г.

wxWidgets vs QT статистика навевает на размышления

Просматриваю форум по с++ на RSDN. Замечаю что вопрос про QT намного больше чем по wxWidgets. Интересно... решил проверить поиском по форуму RSDN

По запросу 'wxwidgets' найдено документов: 693
По запросу 'wxwindows' найдено документов: 299

В сумме меньше тысячи. А вот QT

По запросу 'qt' найдено документов: 4349

В 4.5 раза больше. С чего бы это? И это при бесплатности wxWidgets и более чем платности QT. Ясно что кто-то опен соурс пишет, кто-то на работе на купленной работает, а кто-то и ворованной пользуется - но в 4.5 раза больше... не нравится мне это.

воскресенье, 3 февраля 2008 г.

wxSQLite GUI Browser

Сегодня нашел более чем приятный SQLite Browser. Даже более чем просто броузер полноценный manadgment tool. Фрии с исходниками (GPL) написанный на wxWidgets. Теперь даже и не знаю писать ли свой:)

Рекомендую: http://cfred.free.fr/wxsqliteplus.php.

суббота, 2 февраля 2008 г.

Find and Replace для текстового редактора

На блог http://wxwidgets.info добавлена моя статья Find & Replace для wxWidgets-приложений.  Полный код для встраивания функциональности поиска и замены для текстового редактора. Пользуйтесь и не уподобляйтесь MS которая выпустила Windows Live Writer без функции Replace (!) (только вчера узнал когда понадобилось).

вторник, 15 января 2008 г.

Как reference counting чуть было не заставил поверить меня в мистику

Вчера вечером была написанна функция. Сегодня утром DialogBloks похерил мне весь файл, файл был восстановлен с архива, функция востановленна с аськи\почты. Но одно но - она не работала!, не работал не первый, ни второй вариант, всего было написанно три, третий работал но я проверил его только в конце. Функция простая как две копейки, берем строку, получаем ее внутренний буфер и отдаем винапи для изменения.

Обьявление функции:

void BegUtils::StrMakeLowerUniversal(wxString & data)

Первый

CharLower( data.GetWriteBuf(data.Length()) );

data.UngetWriteBuf();

и второй нерабочий вариант тела

wxStringBuffer buf(data, data.length()+1);

CharLower(buf);

Вчера работало - сегодня нет, классика :)

 

Оказалось все дело в контексте вызова - вот так работает

wxString data=_("NTnt НТнт öffnen вікно привет Donnée rápido test");

BegUtils::StrMakeLowerUniversal(data);

wxMessageBox(data);

А вот так уже нет

wxString data1=_("NTnt НТнт öffnen вікно привет Donnée rápido test");

wxString data(data1);

BegUtils::StrMakeLowerUniversal(data);

wxMessageBox(data);

Все оказалось прозаично, оптимизация строк, reference counting и разделямый внутренний буфер. Подробности обьяснять не буду - сам толком не понимаю, а ляпнуть что-нибудь и выглядеть дураком не хочется:) Зато дам вариант функции который работает и который я юзаю.

 

void

BegUtils::StrMakeLowerUniversal(wxString & data)

{

  #ifdef __WIN32__

      int len=data.length()+1;

      wxChar * buf = new wxChar[len];

      wxStrcpy(buf, data.c_str());

      CharLower(buf);

      data=buf;

      delete [] buf;

#else

      data.MakeLower();

#endif

}

 

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

понедельник, 14 января 2008 г.

Юмористы

Авторы не лишены чуства юмора, из доков

    wxString theAnswer;
    GetMeaningOfLifeAsString(wxStringBuffer(theAnswer, 1024));
    if ( theAnswer != "42" )
    {
        wxLogError("Something is very wrong!");
    }

хотя было бы наверное лучше если бы они wxCharBuffer в документации описали.

воскресенье, 13 января 2008 г.

Почти герой:)

Такое впечетление что wxRichTreeCtrl тестили спустя рукава, сегодня открыл 6 тикетов относительно него, и только один из них это предложениее имхо явной функциональности, остальныне -  баги. Выходной прошел не зря, теперь можно и в сауну:)

суббота, 12 января 2008 г.

wxRichTextCtrl не фонтан

Как я и боялся wxRichTextCtrl не всегда адекватен. За час тестов я нашел кучу "странного поведения", и раза 4 он херил мне стиль всего документа. В результате несложных манипуляций- то весь текст стает жирным, то центрированным, самый тяжелый случай - при ресайзе окна весь текст превратился в сплошной список, каждый пункт которого начинался с '1' и всеб было bold & italik. Ну и как я могу дать подобное юзерам? Ответил Julian Smart'y на его предложение юзать wxRichTextCtrl, описанием багов и методикой воспроизведения одной из ситуаций, посмотрим что ответит - как никак он автор.

Уточню, речь шла о использовании wxRichTextCtrl  как РТФ редактора. Мысль о том, что можно попробывать эмулировать им простой эдит с расширенной функциональностью все еще не покидает меня - буду пробывать.

четверг, 10 января 2008 г.

Мягкая часть тела с Edit'ами

Просто какая-то отвратительная ситуация с эдитами в мире, причем не  в wxWidgets а в целом. Не могу подобрать идеальный Edit Control для своей задачи, хотя требования у меня довольно простые, без особых наворотов.

Чего хочется:

  1. Функциональность обычного простого эдита (notepad)
  2. _Обязательно_ множественное undo\redo.
  3. _Желательно_ подсветка и клик на ссылках.
  4. Корректная работа с точки зрения пользователя.
  5. Хотелось бы иметь возможность в будущем (опционально) перейти на RTF если стукнет в голову.

Собственно если говорить про MSW и wxWidgets, есть 4 варианта:

  1. Обычный edit control (CEdit, wxTextCtrl, Notepad) - (2) обязательное условие не выполняется.
  2. RTF контрол (CRichTextCtrl, wxTextCtrl+wxTE_RICH, WordPad) - все пункты кроме (4) выполняются. На скорость работы и совместимость версией под линукс можно забить пока, но (4) условие не выполняется. Для пользователя контрол должен выглядеть простым (не ртф) - соответвенно вставять и копировать _только_ plain text, этого добиться не получается.
  3. wxWidgets версию RTF контрола wxRichTextCtrl (generic, ground-up implementation of a text control capable of showing multiple styles and images.) - Как-то она вообще не внушает доверия в плане работы, к тому же пункт (5) вызывает определенные проблемы.
  4. Scintilla - там что-то непонятное с RTF, с одной стороны он умеет с ним работать - сохранять файлы как RTF, копировать в буфер - но полноценной работы я не нашел.

Наверное забью я в итоге на пользователей (и на себя самого, потому что от отсутствия ундо я сам страдаю) и возьму для начала обычный edit.