Friday, May 28, 2010

Регулярные выражения и ATL

Если вы пользуетесь регулярными выражениями, то в ATL Server есть для этого средство:
atlrx.h - CAtlRegExp, CAtlREMatchContext. ATL Server сейчас уже не поставляют со студией.

Регулярные выражения уже есть и в STL TR1, но раньше их там не было, и поэтому приходилось использовать либо ATL либо сторонние либы.

Рендеринг и GDI

GDI сейчас под Windows самый древний API и тем не менее его используют даже для рендеринга сложной графики. Недавно я делал графический эффект волны на GDI, и мне нужен был быстрый способ изменять растр. Быстроту я измерял через AQTime, ну и визуально. Идеологически для этого берут сам растр и копируют в память, далее по этой памяти "шарятся" применяя некий алгоритм, и потом возвращают обратно эту память на контекст. Это обычно происходит по таймеру. Если брать простой случай - контекст - это экран, а источник - bmp, то есть несколько способов работы с памятью растра:
1. Самый неэффективный по скорости способ (если операций много): GetPixel/SetPixel; О причине их медленной работы можно прочитать в книге Фень Юань "Программирование графики для Windows" глава 7.
2. GetBitmapBits, SetBitmapBits; Во-первых эти функции уже устаревшие (только для совместимости остались), и работают только с DDB. Во-вторых, для рендеринга через эти функции вам понадобится уже как минимум 2 копирования растра - для взятия буфера на изменения и его установку назад.
3. Альтернатива предыдущим - GetDIBits, SetDIBits. Они копируют растр между форматами DIB и DDB. Для рендеринга на экран это неоправданно сложно, т.к. конвертация нам не нужна, плюс сложность работы с DIB. Опять же - как минимум 2 копирования растра + возможны расходы на конвертацию. Так же учтите, что для DIB нет поддержки GDI в рисовании. DIB растр хранится в памяти на уровне приложения (размер картинки ограничивается только виртуальным адресным пространством приложения) и вы имеете прямой доступ к представлению. В DDB вы не имеете прямого доступа к представлению зато можете рисовать через GDI, растры хранится в системной памяти и поэтому для них еще есть и ограничения по размеру (48MB - примерно 3500х3500 при 32bit цвете).
4. Ввиду выше описанных способов были придуманы DIB-секции. Это DIB-растр в который можно писать как через GDI так и напрямую в буфер. Отсюда выгода - при работе с буфером не нужно копирование вообще.

Также хочу дать еще несколько советов по рисованию/рендерингу в GDI.
1. Используйте концепцию двойной (или более) буферизации перед выводом на экран (CreateCompatibleDC, в WTL есть CMemDC, и т.п.).
2. Рисуйте только один раз - не рисуйте в одном и том же пикселе дважды.
3. Не используйте WM_ERASEBKGND.
4. Используйте GetUpdateRgn, GetUpdateRect или BeginPaint/EndPaint - если перерисовать нужно только малую часть.
5. Стили CS_VREDRAW и СS_HREDRAW означают что содержимое окна будет полностью перерисовываться при изменении его размеров по вертикали или по горизонтали соответственно.
6. Стиль WS_CLIPCHILDREN - чтобы не было при рисовании своего содержимого, затирания дочерних окон своим изображением, а затем поверх него рисования самих дочерних окон.
7. Используйте ExcludeClipRect/SelectClipRgn - для предотвращения повторного рисования.
8. В рендерере используйте таблицы синусов/косинусов, вместо функций - макросы, все локальные переменные выносите выше, используйте многопоточность для сложных алгоритмов.
9. Используйте списки сохранения промежуточных сжатий изображений при ресайзе - для ускорения следующих ресайзов относительно них. Также полезен пассивный предресайзинг.
10. Выделяйте на стеке обработчика WM_PAINT/WM_TIMER поменьше памяти, в идеале вообще не выделять или использовать повторно.

Пока всё. Надеюсь все написал что хотел.

Thursday, May 27, 2010

Указатели, константы...

char * const p; // константный указатель на char
char const * p; // указатель на const char
const char * p; // указатель на const char
const * char p; // ошибка

const char * const p; // константный указатель на константный объект (const char)
char const * const p; // тоже самое

Мониторинг COM

Мониторинг COM - это весьма не простая задача, и поэтому для этого почти нет никаких средств. Не так давно я нашел великолепный открытый API-монитор который также мониторит COM. Называется он WinAPIOverride32:
http://jacquelin.potier.free.fr/winapioverride32/

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

Также есть еще мелкие проекты по монитору COM-а:
-ComTrace (Blunck Software)
-COMRaider (IDefense Labs)

В общем в след. раз я подробней расскажу про WinAPIOverride32.

Wednesday, May 26, 2010

Литература по СОМ

Для изучения я бы рекомендовал такую последовательность:
-Andrew Troelsen - "Developer's Workshop to COM and ATL 3.0"
-Christopher Tavares - "ATL Internals: Working with ATL 8 (2nd Edition)"
-Don Box - "Essential COM"
-Kraig Brockschmidt - "Inside OLE, 2nd Edition"

Все эти книги (кроме последней) есть на русском языке. Также все они есть у меня в электронном виде, если кому нужно - могу выслать.
Привет,
этот блог будет посвящен моим изысканиям в технологии СОМ и не только;
Пока всё.