Отправляет email-рассылки с помощью сервиса Sendsay
  Все выпуски  

Visual C++ - расширенное программирование Ввод-вывод в RichEdit


Информационный Канал Subscribe.Ru

Visual C++ - расширенное программирование

Выпуск      : 18
Подписчиков : 5714
Cайт        : SoftMaker.com.ru
Архив       : Visual C++ - расширенное программирование (архив)
В этом выпуске
От автора

Здравствуйте уважаемые подписчики !

Как всегда, рад приветствовть вас на страницах этой рассылки.
Напоминаю, что, как обычно, вы можете отправить свои пожелания (замечания, предложения, сообщения об ошибках) по поводу рассылки и сайта по этому адресу.
Если вы хотите создать и вести какой либо раздел в этой рассылке - также пишите мне.

И, как всегда, вы можете задать свои вопросы по программированию на сайте в форуме.
Или обсудить их в дискуссионном листе "Программирование. форум !!!".

Многим может быть также интересна рассылка: C/C++ Вопрос-Ответ, содержимое которой формируется из писем читателей. Здесь Вы можете задать вопрос по программированию на C/C++ и ответить на вопросы других подписчиков.

P.S. Должен сообщить, что с этого месяца рассылка уходит в отпуск (ориентировочно - до конца августа). Предложения, пожелания, замечания по- прежнему принимаются, но с ответом возможны задержки. Надеюсь, что материалы рассылки для многих полезны и интересны. И, я надеюсь, в новом сезоне материал рассылки станет еще более интересным и качественным. Пользуясь освободившимся временем, планируется создать новый полноценный сайт - качественный контент-проект, посвященный разработке программного обеспечения (как прикладного ПО, так и web-разработке), составной частью которого будет являться и данная рассылка.

С уважением, Вахтуров Виктор.

Статьи

Ввод-вывод в RichEdit

Введение


В процессе изучения возможностей RichEdit очень многие вопросы лично мне приходилось выуживать по крупицам и в большинстве своем на англоязычных сайтах (www.codeguru.com, www.codeproject.com). В то же время статьи на русском языке мне попадались (www.firststeps.ru). Но и первые, и вторые в основной своей массе были посвящены конкретным аспектам, что не умаляет их ценности, но при этом лишены не только обобщенности, но и полноты (в смысле как рассмотрения конкретных возможностей RichEdit, так и в смысле разницы в версиях компонента). Регулярно отвечая на форумах RSDN на вопросы связанные с использованием RichEdit, и помня о том, как я сам начинал осваивать этот компонент Windows - "изобретал велосипеды", "открывал Америки" и искал сведения о тех или иных аспектах и тонкостях, я решил попробовать написать статью о RichEdit API. Вкупе с моим личным опытом частые вопросы новичков (в программирование Windows API ли вообще, или RichEdit в частности) о применении RichEdit только еще более подталкивали меня к написанию хоть какого-нибудь руководства.

Я надеюсь, эти статьи помогут новичкам сделать первые шаги в использовании RichEdit быстро, "не спотыкаясь" и не тратя время на изобретение уже изобретенных велосипедов. Надеюсь "гуру" также смогут здесь найти что-нибудь интересное и для себя. В перспективе хотелось бы создать если не всеобъемлющее, то хотя бы достаточно разностороннее описание RichEdit на русском языке. Т.к. многие авторы часто сосредотачивают внимание на конкретной версии RichEdit, даже не поясняя возможность или невозможность применения предложенных идей в других версиях компонента или версиях Windows, не говоря уже о прочих нюансах, я попробую описать и различия в версиях RichEdit, и возможности в той или иной степени унифицировать эти различия в Ваших собственных программах.

Как Вы сами понимаете, написание большой статьи требует ощутимого количества времени. К тому же большая статья, как мне кажется, обладает всеми недостатками "тяжелой артиллерии проектирования" - т.е. к тому моменту, когда статья будет закончена, скорее всего выяснится, что многие интересные вопросы не затронуты, другим же более понятным, более известным, более простым наоборот уделено в ущерб первым слишком пристальное внимание. Поэтому я решил написать вместо большой статьи серию небольших статей. Каждая статья будет посвящена тем или иным аспектам использования RichEdit. Полагаю, это значительно более реалистичная цель. А читатели смогут по мере публикации посоветовать каким вопросам уделить большее внимание, и тогда статьи рискуют оказаться в значительно большей степени полезными и интересными обширному кругу читателей. Я буду рассматривать вопросы по мере усложнения, и первоначальный мой план их рассмотрения опирается на частоту "задаваемости" тех или иных вопросов о RichEdit, но конечно этот план может меняться по мере публикации. Эта статья и есть первая, в которой я постараюсь рассмотреть базовую функциональность (без базы, сами понимаете, никуда). Здесь я постараюсь описать возможности ввода-вывода в RichEdit. Тем более, что по моим наблюдениям вопросы именно о вводе-выводе в RichEdit задаются достаточно часто, и в последующих статьях я буду использовать описанные здесь возможности RichEdit.

Итак, что же такое RichEdit? RichEdit это стандартный компонент Windows для редактирования текста. Термин компонент я здесь употребляю скорее как синоним слова "часть", "слагаемое" и не вкладываю в него иного смысла (к примеру компонент ActiveX, хотя и такое бывает, к примеру, в дистрибутиве Visual Basic). Но кроме возможностей стандартного редактора (Edit, тот самый, который в обычном Notepad) RichEdit обладает значительно внушительными возможностями. Среди на мой взгляд самых главных его достоинств следует назвать поддержку форматирования текста, чтения и записи текста в формате RTF (Rich Text Format), отсутствие ограничения размера текста в 64 Кб, и вставки OLE-объектов.

Примечание: у меня нет никакого практического опыта программирования для Windows CE. Но случалось, что пользователи некоторых моих программ сообщали мне, что пытались применять какие-либо из реализованных мною возможностей RichEdit именно под управлением Windows CE. Представьте мое удивление, когда я узнавал о том, что все-таки может быть и не все, но большинство возможностей RichEdit функционировали и под управлением Windows CE, с его "родной" для Windows CE версией RichEdit. Т.е. в общих чертах RichEdit достаточно функционален и в облегченных версиях Windows, а информацию об ограничения можно почерпнуть в MSDN. Я думаю, что программирование под эту версию Windows отдельная песня и заслуживает отдельной статьи. Но если Вы столкнетесь с некоторыми трудностями, или ошибками при работе в Windows CE приведенного здесь кода - свяжитесь со мной по электронной почте.

На данный момент для 32-разрядной Windows существует несколько версий компонента RichEdit, которые доступны на сайте Mircosoft, но ввиду того, что поиск некоторых версий этих библиотек на домашнем сайте не всегда успешен, приведу и некоторые "свои" ссылки:

  • 1.0 (riched32.dll), Win95 и выше, WinNT 4.0 и выше;
  • 2.0 (riched20.dll), Win98 и выше; Win2k и выше;
  • 3.0 (riched20.dll), Win2k и выше;
  • 4.1 (msftedit.dll), WinXP SP1 и выше;

RichEdit это дочернее окно Windows класса "RichEdit". А также "RichEdit20A" и "RichEdit20W" (2-ой версии, ANSI и UNICODE версии соответственно). Написанный выше список показывает в какой Windows какой RichEdit присутствует в стандартной поставке. Но это не означает, что старшие версии RichEdit абсолютно нельзя использовать в младших версиях Windows. Я вполне успешно использовал 3-ую версию RichEdit и в Windows 98. Но для этого приходится предварительно установить соответствующую библиотеку.

Все примеры, я буду писать на MFC 6.0 и в качестве среды и компилятора использовать Microsoft Visual C++ 6.0 (SP5). Я буду стараться использовать ANSI-версии API-функций, так как использование UNICODE-версий в Windows95\98\ME невозможно без специальной поддержки (Unicode Layer), что я думаю не добавит удобства некоторым читателям в использовании примеров, в то время как на unicode-версиях Windows они будут функционировать нормально. Большую часть кода я буду стараться писать так, чтобы было возможно без изменений использовать код в чистых WinAPI-проектах (или к примеру в WTL). Хотя это замечание не относится к использованию строковых классов (MFC::CString, WTL::CString, std::string). Но я думаю, для поклонников чистого WinAPI-программирования модификация "строковой" составляющей не составит особого труда. К тому же большая часть MFC-шных методов класса CRichEditCtrl является простой оберткой над сообщениями окна RichEdit. Хотя это далеко и не всегда так - к примеру славная функция MFC 6.0 CRichEditCtrl::Find скрывает некоторые нюансы (помните, тот анекдот о нюансах...), хотя справедливости надо заметить что Microsoft документировала все эти нюансы в Platform SDK и MSDN. Но сами понимаете, что нюанс хорош для того кто о нем знает, и плох для того у кого не окажется этого знания в нужный момент. В подобных случаях я постараюсь обращать Ваше внимание на подобные различия.

Итак, я думаю многие из Вас, если не встречались с самой ситуацией, то по крайней мере не раз видели вопросы следующего плана: "как прочитать\записать файл в формате RTF", "как прочитать\записать текст из\в RichEdit". С этих вопросов и начнем, благо эта функциональность в дальнейшем нам будет нужна довольно часто.

Для вывода и ввода данных в RichEdit предусмотрены два оконных сообщения EM_SREAMOUT и EM_STREAMIN соответственно.

Вывод в RichEdit. Сообщение EM_STREAMOUT

Сообщение EM_STREAMOUT предназначено для вывода данных из RichEdit и имеет следующую спецификацию.

SendMessage((HWND), //HWND окна получателя - HWND окна RichEdit.
    EM_STREAMIN,    //собственно само сообщение.
    WPARAM wParam,  //флаги указывающие на требуемый формат и
                    //представление данных.
    LPARAM lParam)  //данные - указатель на структуру EDITSTREAM.

Ну с первыми двумя параметрами всё ясно. Это HWND окна получателя, а именно самого RichEdit, и идентификатор сообщения. Интересны последние два.
wParam - содержит флаги форматирования и представления выводимых из RichEdit данных. И может иметь следующие значения:

  • SF_RTF - RichEdit будет выводить данные в формате текста RTF. Т.е. в том самом виде, в котором Вы можете увидеть "начинку" rtf-файла, если откроете его в Notepad или любом стандартном вьювере файлов.
    Или
  • SF_TEXT - RichEdit будет выводить данные в формате простого текста (plain text). В этом случае RichEdit выводит данные в формате простого текста, попросту игнорируя все команды форматирования. То же самое, Вы можете получить оконным сообщением WM_GETTEXT или функцией WinAPI GetWindowText. Обратите внимание, на этот флаг - это как раз тот самый случай, когда можно задействовать RichEdit как стандартный редактор, но лишенный ограничения объема текста в 64 килобайта. Следует заметить, что RichEdit 3.0 поддерживает специальный режим эмуляции Edit (задается сообщением EM_SETEDITSTYLE с флагом SES_EMULATESYSEDIT), и в этом случае ограничение на длину текста будет работать также как и в Edit. Флаги SF_RTF и SF_TEXT взаимоисключаюшие, и не могут использоваться вместе.

    Кроме этого RichEdit поддерживает дополнительные специальные флаги.
  • SF_RTFNOOBJS - вывод RTF-текста без COM-объектов. Все COM-объекты будут заменены на пробелы.
  • SF_TEXTIZED - вывод простого текста с текстовым представлением COM-объектов.
  • SFF_SELECTION - этот флаг указывает на то, что выводить следует только выделенный текст. Если этот флаг не указан, будут выводиться все данные содержащиеся в RichEdit, т.е. полностью весь текст. Если указать этот флаг, при отсутствии выделенного текста, то будет выведена пустая строка. Соответственно, следует предварительно проверять выделение.
  • SFF_PLAINRTF - флаг указывает RichEdit выводить только те слова и команды формата RTF, которые являются общими для всех языков. Все слова и команды которые специфичны для какого-либо языка (русского, китайского) просто игнорируются. Этот флаг можно указывать только в комбинации с флагами SF_RTF и SF_RTFNOOBJS (с SF_TEXT его применение бессмысленно).
  • SF_UNICODE - еще один любопытный флаг. Его можно использовать в сочетании с флагом SF_TEXT и он указывает RichEditу, что следует выводить текст в формате Unicode. Помните, частые вопросы как конвертировать текст в Unicode!?! Извращение, конечно, не спорю, на пишется за не более чем 12.6 секунды (рекорды достигали и 3.8 секунды) и работает как часы. Только представьте себе какое количество программистов протестировало работу с этим флагом!?! А надежности и предсказуемость иногда бывают значительно приоритетнее всего остального :). Обратите внимание, что этот флаг поддерживается только версиями RichEdit 2.0 и выше. Его применение с RichEdit 1.0 (тот который по умолчанию в NT, 95, 98) не работает. Но об этом флаге мы еще поговорим позже. Т.к. для его использования мне сначала придется рассказать, как использовать RichEdit 2.0 в программах написанных на VC 6.0 под управлением Win 9x. Под управлением 2000\XP использование старших версий RichEdit не только проще, но и менее "кодоемко", в силу того что не приходится писать разный код для разных версий RichEdit.
  • SF_USECODEPAGE - выводить текст RTF в заданной кодировке. Кодовая страница задается как старшее слово wParam. Например, для использования кодировки UTF-8 RTF следует настроить wParam как (CP_UTF8 << 16) | SF_USECODEPAGE | SF_RTF. Этот флаг еще более любопытен с точки зрения версии - он поддерживается только RichEdit версии 3.0 и выше.

lParam- указатель на структуру EDITSTREAM. Этот параметр как раз и обеспечивает по сути функционирование вывода. Структура EDITSTREAM имеет следующее определение.

struct EDITSTREAM {
 DWORD  dwCookie; // определяемое приложением значение 
                         // которое передается в функцию
                         // обратного вызова.
                         // Обратите внимание, что его тип DWORD,
                         // а следовательно сюда можно положить
                         //  "через указатель" почти все что
                         // угодно.

 DWORD dwError;   // индицирует ошибки произошедшие
                         // при выводе.
                         // 0 - означает отсутствие ошибок.

        EDITSTREAMCALLBACK pfnCallback // функция обратного
                         // вызова, которую должен указать
                         // программист.
                         // Эта функция и будет выполнять всю 
                         // специфическую часть работы.
    };

Функция обратного вызова EDITSTREAMCALLBACK pfnCallback в структуре EDITSTREAM имеет следующую спецификацию.

DWORD CALLBACK EditStreamCallback(
  DWORD dwCookie, // в этом аргументе будет находиться значение
                  // которое мы указали в EDITSTREAM::dwCookie
  LPBYTE pbBuff,  // буфер с данными которые передает RichEdit
  LONG cb,        // размер буфера в байтах
  LONG *pcb       // указатель на переменную, в которую функция 
                  // должна записать количество байтов 
                  // обработанных из буфера pbBuff
);

В качестве возвращаемого значения мы должны вернуть 0 - индицируя что всё ок, у нас все в порядке. И НеНоль если что-то не так. Причем возвращенное значение (этот самый "НеНоль") и будет возвращен в параметре EDITSTREAM::dwError, т.е. возможно с помощью возвращаемого значения обозначать какие-либо конкретные причины ошибки.

Итак, общая идея проста: функция занимающаяся выводом указывает флаги (форматирование, простой текст или RTF и т.д.), указатель на функцию, проводит всевозможную подготавливающую работу, и посылает сообщение RichEditу. Обратите внимание, что в параметре EDITSTREAM::dwCookie мы можем передать к примеру хендл открытого файла в который нужно осуществлять вывод. RichEdit будет вызывать функцию обратного вызова и передавать нам буфер, который мы должны куда-либо вывести. RichEdit будет вызывать функцию обратного текста пока мы возвращаем 0 (успех) и пока весь интервал текста (выделенного или всего, в зависимости от указанных флагов) не будет обработан.

Код осуществляющий вывод всего текста RTF в файл должен выглядеть примерно следующим образом. В этом примере я использую объект CFile библиотеки MFC, но я полагаю для поклонников WinAPI не составит труда осуществить вывод и средствами чистого WinAPI. Просто вместо указателя на объект CFile Вам потребуется передавать в функцию обратного вызова хендл (HANDLE) открытого файла.

//функция-обертка, осуществляющая вывод в файл
bool OutRichToFile(const HWND hwndRichEdit/*HWND окна RichEdit*/,
     LPCTSTR /*LPCWSTR*/
     lpszFilename /*имя файла в который будет
                    осуществляться вывод*/
{
    CFile file;
    //открываю\создаю файл, полностью заменяю его содержимое
    //если файл существует
    if (!file.Open(lpszFilename,CFile::modeCreate|
                   CFile::modeWrite)) {
        OutputDebugString("Не могу открыть файл для записи");
        return false;
    }
    EDITSTREAM es;
    //указываем нашу функцию обратного вызова
    es.pfnCallback=MyOutFunction;
    //сбрасываем ошибки
    es.dwError=0;
    //в качестве Cookie передаем указатель на наш объект file
    es.dwCookie=(DWORD)&file;
    //посылаем сообщение окну RichEdit, WPARAM==флаги,
    //LPARAM - указатель на EDITSTREAM
    SendMessage(hwndRichEdit,EM_STREAMOUT,
                SF_RTF/*получать текст в формате RTF*/,
                (LPARAM)&es);
    //закрываем файл
    f.Close();

    //true - если не было ошибок, иначе что-то где-то вдруг
    //порою не в порядке.
    return (0==es.dwError);
}

//функция обратного вызова для вывода в файл
DWORD CALLBACK MyOutFunction(
  DWORD dwCookie, // то самое пользовательское значение которое
                  // мы указали в EDITSTREAM::dwCookie
  LPBYTE pbBuff,  // буфер с данными которые передает RichEdit
  LONG cb,        // размер буфера в байтах
  LONG *pcb       // указатель на переменную в которую следует
                  // записать сколько функция MyOutFunction
                  // успешно обработала байтов из буфера pbBuff
)
{
    // в качестве dwCookie получаем указатель который мы
    // установили в EDITSTREAM
    CFile* pFile=reinterpret_cast<CFile*>(dwCookie);
    //записываем полученный буфер в файл, размер переданного нам
    //буфера в переменной cb
    pFile->Write(pbBuff,cb);
    //говорим RichEditу сколько мы обработали байтов
    *pcb=cb;
    //возвращаем ноль (у нас всё ОК)
    return 0;
}

Ввод в RichEdit. Сообщение EM_STREAMIN

Для ввода данных в RichEdit предусмотрено оконнное сообщение EM_STREAMIN. Его использование во многом схоже с сообщением EM_STREAMOUT: также в wParam задаются флаги, и также в lParam передается указатель на структуру EDITSTREAM.

Флаги SF_RTF и SF_TEXT интерпретируется аналогично, но обратите внимание, что за правильное указание флагов отвечает программист. Т.е. если Вы попытаетесь "затолкать" RTF-текст как простой текст с применением флага SF_TEXT, то после этой операции Вы увидите в RichEdit непосредственно код RTF. А если попытаться передать простой текст в RichEdit как RTF-код с флагом SF_RTF, то в окне RichEditа ничего не отобразится.

Несколько иначе ведет себя ввод, если Вы укажете флаг CFF_SELECTION. В его отсутствие все работает ожидаемо и стандартно - т.е. существуюший в RichEdit текст полностью заменяется вводимым. Но если флаг CFF_SELECTION указан, то все зависит от текущего выделения. Если существует выделенный текст, то вводимые данные его заменяют. Если же выделения нет, то вводимый текст вставляется в позицию курсора (каретки). Такое поведение похоже на использование сообщения EM_REPLACESEL. Но, используя EM_STREAMIN с флагами SF_RTF и SFF_SELECTION можно вставлять в RichEdit "куски" форматированного текста. Поведение флагов SFF_PLAINRTF и SFF_UNICODE аналогично поведению при выводе.

Пример ввода текста в формате RTF в RichEdit.

/*Функция-обертка, читающая из файла:*/
bool RichInOutUtil::File2Rich(
     const HWND hwndRichEdit /*HWND RichEdit*/,
     LPCTSTR /*LPCWSTR*/ lpszFilename /*файл для чтения* /)
{
    CFile file;
    /*открываем файл из которого RichEdit будет читать
    RTF-текст*/
    if (!file.Open(strFilename,CFile::modeRead)) {
        OutputDebugString("Не могу открыть\n");
        return false;
    }

    EDITSTREAM es;
    /*в качестве пользовательского значения 
    используем указатель на file*/
    es.dwCookie=(DWORD)& file;
    es.dwError=0;
    /*указываем функцию обратного вызова*/
    es.pfnCallback= MyCallBackFunction;

    /*передаем сообщение RichEditу*/
    SendMessage(hwndRichEdit,EM_STREAMIN, SF_RTF,(LPARAM)&es);
    
    /*закрываем открытый файл*/
    f.Close();

    //не было ли ошибок?
    return (0==es.dwError);
}

/*Функция обратного вызова:*/
DWORD CALLBACK MyCallBackFunction(
  DWORD dwCookie, // определяемое программистом значение,
                  // в этом аргументе находится указатель на
                  // CFile, который мы задали в
                  // EDITSTREAM::dwCookie
  LPBYTE pbBuff,  // буфер который передается RichEditом
                  // для заполнения
  LONG cb,        // размер буфера pbBuff в байтах
  LONG *pcb       // в переменную адресуемую указателем pcb
                  // следует записать количество байтов
                  // записанныхв буфер pbBuff
)
{
    /*в качестве пользовательского значения мы передавали 
    указатель на открытый файл*/
    CFile* pFile=reinterpret_cast<CFile*>(dwCookie);
    /*просто читаем открытый файл в буфер переданный нам
    RichEdit*/
    *pcb=pFile->Read(pbBuff,cb);
    if (*pcb) //если в буфер что-то прочитано
        return 0;
    else
        return 1;
}

Повторю, что за правильное указание формата данных передаваемых в сообщении EM_STREAMIN отвечает программист. Т.е. в примере следует самостоятельно определять какой текст мы загружаем в RichEdit - простой текст или RTF. В примере, я просто указываю флаг SF_RTF, предполагая что считывается файл, содержащий текст RTF. Если в файле окажется простой текст, RichEdit ничего не отобразит. Хотя, в принципе можно "заставить" RichEdit автоматически определять формат файла, но эти возможности удобнее использовать с применением Text Object Model (TOM), о которой будет написано позже.

Это, пожалуй, все о вводе-выводе в RichEdit. Но помимо сообщений EM_STREAMOUT и EM_STREAMIN для ввода и вывода можно использовать стандартные сообщения Windows WM_GETWINDOWTEXT и WM_SETWINDOWTEXT. Эти оконные сообщения возвращают только текст без форматирования, и соответственно при вводе в RichEdit не позволяют вводить текст в формате RTF. Также можно использовать стандартное сообщение EM_REPLACESEL которое в зависимости от выделения, либо заменят выделенный текст, либо вставляет текст в позицию курсора. Но подобные методы обладают значительно меньшей гибкостью и как правило их применение не вызывает затруднений, поэтому подробно я на них останавливаться не буду.

Также для ввода и вывода можно использовать TOM (Text Object Model), специальную технологию предоставляемую Microsoft, которая поддерживается старшими версиями RichEdit (начиная с версии 2.0). Методы, реализованные в TOM, позволяют упростить некоторые "сюжеты", такие как определение формата данных (RTF или простой текст), вставка содержимого документов MS Word, да и многие другие. Хотя стоит отметить, что на данный момент мне, например, пока не удалось добиться устойчивой вставки содержимого документов Word, достаточно часто результат операции был E_NOINTERFACE (интерфейс не поддерживается). Но эта тема несколько выходит за рамки сегодняшней части, тем более что TOM - область достаточно обширная и многофункциональная, и будет рассмотрена позже.

В приведенных в тексте статьи примерах я старался сфокусировать Ваше внимание на общей идее, используя в качестве примера файловый ввод-вывод. Но как я полагаю Вы уже догадались, ввод-вывод может производиться и не только в файлы, но и вообще "к черту на кулички". В примере к статье существуют и примеры функций осуществляющие ввод-вывод в стандартные MFC-строки (MFC::CString). Весь текст примеров снабжен подробными комментариями.

Примечание: если Вы собираетесь использовать CRichEditCtrl в MFC Dialog-based приложениях, не забывайте вызывать AfxInitRichEdit() перед созданием диалога с CRichEditCtrl. Эта функция загружает библиотеку riched32.dll, которая необходима для создания CRichEditCtrl. Если вызов AfxInitRichEdit() не будет произведен до создания диалога, то создание диалога завершается неудачей, т.к. MFC не cможет создать CRichEditCtrl на диалоге без загруженной библиотеки. Кстати, для более "шустрого" и надежного управления памятью при операциях ввода-вывода можно вполне успешно применять как файлы проецируемые в память (Memory Mapped Files), так и некоторые недокументированные классы MFC (CBufferFile, CArchiveFile и т.д.). Но поскольку я старался написать некую скорее "каноническую" форму, то я не буду останавливаться на их применении. Тем более, я полагаю, "WinAPI-шники" не будут в восторге от применения напрочь MFC-специфичных компонентов.

Надеюсь, программисты впервые встречающиеся с данной тематикой нашли в этой статье для себя некоторый путеводитель, возможно и более опытным программистам здесь что-то встретится интересное. Но хочу обратить Ваше внимание, что это пилотная статья, и конечно я с интересом узнал бы от Вас на что в последующих статьях нужно обратить большее внимание, что наиболее интересно, что вызывает те или иные затруднения и дискуссии. Мне интересны Ваши отзывы, и конечно они во многом будут определять и тематику и порядок рассмотрения вопросов в следующих статьях. Если возникли вопросы, то милости прошу в гостевую, или до встречи на RSDN. В конце концов не забывайте и о таком средстве общения как электронная почта, дешево, надежно и сердито. До встречи.

Ссылки

Ресурсы с информацией о RichEdit:
  • www.rsdn.ru: (рус) обширные, содержательные, а главное посещаемые форумы, здесь наверняка Вам смогут помочь, да и сам автор здесь частенько бывает;
  • www.wasm.ru: (рус) если не пугает использование или хотя бы чтение ассемблера обязательно загляните, здесь можно найти очень любопытные примеры по использованию RichEdit;
  • www.firststeps.ru: (рус) здесь не очень много информации, но для новичка будет любопытно;
  • www.codeproject.com: (eng) обязательно загляните, обширный сайт с большим количеством примеров и статей по самым различным аспектам использования RichEdit;
  • www.codeguru.com: (eng) еще один англоязычный сайт с большим количеством статей, примеров по самым разным вопросам;
Ссылки по статье:

Автор статьи: Мазов Егор.     


Подготовка выпуска: Вахтуров Виктор.

Книги по C/C++
Microsoft Visual C++ .NET
Microsoft Visual C++ .NET

Автор: Гюнтер Штайнер

Книга предназначена для программистов, имеющих опыт программирования на процедурных языках, и представляет собой справочник по программному продукту Visual C++ .NET.

Подробно рассматривается интегрированная среда разработки, методика разработки и отладки программ (средства управления проектом, мастера, редакторы ресурсов, инструментарий отладки, утилиты разработки справочной системы). Значительная часть книги посвящена программированию с MFC, причем практическая тематика дополнена основополагающими теоретическими сведениями по программированию в среде Windows. Уделено внимание программированию баз данных, программированию в среде Интернета, использованию рабочих библиотек С и C++.

Страница книги на Озоне
Интерактивная компьютерная графика. Вводный курс на базе OpenGL, 2-е изд.
Интерактивная компьютерная графика. Вводный курс на базе OpenGL, 2-е изд.

Автор: Эдвард Энджел

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

Весь теоретический материал в книге иллюстрируется программами на OpenGL.

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

Страница книги на Озоне
Рассылки и дискуссионные листы компьютерной тематики
Рассылки
C/C++ Вопрос-Ответ

Это - интерактивная рассылка !
Здесь Вы можете задать свой вопрос по программированию на C и C++, а также ответить на вопросы других подписчиков.


Программирование на JavaScript

Все аспекты программирования на JavaScript - нестандартные приемы, ОРИГИНАЛЬНЫЕ скрипты, авторские статьи и наработки. "JavaScript solutions" - в каждом выпуске готовый к применению ИНТЕРЕСНЫЙ скрипт (исходный код с комментариями).

Дискуссионные листы
Программирование. Форум !!!

Самый популярный дискуссионный лист по программированию на subscribe.ru, существующий с момента открытия сервиса дискуссионных листов !

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

Вебстроительство. Форум !!!

В дискуссионном листе ведется обсуждение различных аспектов создания сайтов - написание скриптов, использование, настройка портальных движков, и многое другое. Присоединяйтесь !

Поисковые системы. Форум !!!

Этот дискуссионный лист посвящен обсуждению поиковых систем, методов индексации сайтов поисковиками, способам оптимизации сайта под поисковые системы.

Хостинг. Обзоры и обсуждения платного и бесплатного хостинга.

Вы ищете хостинг (платный, бесплатный) ? Хотите спросить совета в выборе ? Можете обсудить это здесь. Поделитесь советом, если знаете. Или узнайте больше. Все о хостинге.


Всего доброго. До встречи в следующем номере.

Subscribe.Ru
Поддержка подписчиков
Другие рассылки этой тематики
Другие рассылки этого автора
Подписан адрес:
Код этой рассылки: comp.soft.prog.qandacpp
Отписаться
Вспомнить пароль

В избранное