Итак, особенности реализации:
Глобальное описание функций каркаса. Задача встраивания каркаса в приложение не стоит по определению, кроме того, у нас нет необходимости в двух копиях функциональности, заложенной в каркас, поэтому, я считаю, что ничто не мешает нам описать большую часть переменных и функций в глобальном пространстве имен. Кроме, того, это позволяет легко реализовать следующую особенность каркаса. Итак
Направленность на выполнение любой задачи действиями (функции с префиксом ueAction). Это позволяет в экземплярах классов ставить в соответствие действию (например, щелчку мышкой на экземпляре класса Button, здесь он не приводится, можно поставить в соответствие глобальный Action, который осуществляет корректное завершение работы программы) события. Причем событие не фиксируется жестко в классе. Кроме того, если в реализацию добавить компилятор Си (а такие реализации я видел), то можно легко расширять возможности приложения без перекомпиляции.
Реализованы подобия различных сцен (с возможностью смены с автоматической выгрузкой предыдущей сцены). В каркасе они пустые, то есть мы просто переводим движок в главный цикл, но уже в следующей статье я опишу и, естественно, реализую главное меню приложения.
Осуществляется отслеживание ошибок. Причем, сделана не только стандартная проверка возвращаемого значения, но и проверка глобального флага (схожая с GetLastError() из Win32 API). Это позволяет возвращать ошибки из функций, реализующих события. Кроме того, проверяется, выставлен ли флаг (m_dwError) во всех критических местах приложения. То есть любая ошибка ведет к корректному завершению программы с выдающимся после завершения работы приложения сообщением.
А также, я посчитал необходимым добавить в каркас следующие функции:
Рисование Курсора (CCursor). Это позволило сделать каркас законченным приложением. Все равно практически всегда требуется рисовать собственный курсор. Возможно реализация, которая предлагается спорна и требует доработки, но у меня она работает без ошибок как в оконном режиме, так и в полноэкранном режиме, кроме того, особенностью (но не недостатком) этого класса можно считать только то, что инициализация курсора происходит изнутри класса, то есть не определяется необходимая функциональность для смены загруженного курсора на лету. Но это, в общем, не сложная задача, а здесь я ее не реализовал только потому, что не посчитал нужным. Реализована анимация курсора и реализована смена стадий курсора, в заголовочном файле описан пример добавления новых стадий (кстати, как вам мой английский :)), а в функции Create() — создания анимационных цепочек.
Распаковка ресурсов из файла ресурсов (ResourceManager). Я прекрасно понимаю, что реализация, которая есть в этом классе, неидеальна, но это лучше, чем отдельно лежащие ресурсы, пусть даже записанные не в общедоступном формате. А при необходимости реализацию можно дописать или переделать — было бы желание. Используется CFolder класс, основанный на реализации одной из олимпиадных задачек (задача про хакера Билла у которого накрылся жесткий диск). Он создает и удаляет дерево каталогов по названию файла, начиная с определенного пути (названия файлов должны быть относительными). Описание использования класса есть в main.cpp и мне кажется достаточно логичным.