Главная
Новости
Программы
Проекты
Статьи
Ссылки
Контакты
Гостевая
Выпуск №1. Список классов WTL, описание классов CSimpleArray и CSimpleMap

Приветствую вас, уважаемые читатели!

Вот наконец и свершилось - вышел в свет первый номер этой рассылки. Для начала попробую разобраться зачем я за это все взялся и кому это может быть нужно, кроме меня ?

Итак, зачем?

Как язык программирования мне более всего нравится С++, а как среда разработки - MS Visual C++ 6.0 (далее просто "VC"). VC - очень мощный и гибкий инструмент. В нем можно разрабатывать программы любого уровня сложности - от самых простеньких, до серьезных, больших приложений. Все это понятно. Что же предлагает для разработки программ VC? Конечно есть "голый" Windows API, еще есть MFC, есть еще библиотека ATL, которая в общем-то предназначена для написания Active-X контролов. Чем же пользоваться мне? Раньше, как мне кажется фактически было два варианта:

  1. MFC. Все описано, документировано, есть масса сторонних библиотек, расширяющих функциональность. В Сети навалом и даже больше информации по ней. И все-таки. Если мне, например требуется написать небольшую программу, то зачем стрелять пушкой по воробьям, тянуть за собой рантайм и тому подобное? К тому же, про нестыковки и ошибки MFC слагаются легенды. Так что - это не мой путь :)
  2. Windows API. Тоже все документировано, все описано, информации в Сети полным полно. Плюсы, как мне кажетсся такие: никаких сторонних прослоек, то есть если есть ошибка, то она либо в моем коде (что скорее), либо в функции WinAPI (про котороую скорее всего давно знают и описали), а не где-то в недрах какой-то там библиотеки. Потом, размер программ, написанных с помощью WinAPI, кардинально меньше, чем такой же программы, написанной на MFC. Для меня лишь оставалось небольшим неудобством то, что все построено на одних С-функциях, обработка и маршрутизация сообщений выглядели не так, как хотелось бы.

Но появилась библиотека WTL, которая в сущности является расширением ATL и служит для работы с GUI. WTL появилась достаточно давно и я не обращал на нее ососбого внимания. А зря! Ведь это то, что мне было нужно: библотека в виде тонкой прослойки, в которой есть масса необходимых вещей и почти ничего лишнего. К тому же WTL, как мне кажется, довольно красиво разработана и в ней учтены многие недоработки проектирования MFC. Программы, написанные на WTL, компактны, быстры и не тянут за собой никаких рантаймов. На настоящий момент доступна версия 7.0, взять ее можно здесь (434 Кб).

Теперь я приблизился к вопросу, который прозвучал в начале. WTL официально не документирована и поставляется в исходных текстах. Для освоения этой библиотеки приходиться искать информацию в Сети и разбираться с ее внутренним устройством. Так как я не могу причислить себя к гуру в программировании, то и решил создать эту рассылку, в которой публиковал бы разичные сведения на тему ATL/WTL и Windows API, которые посчитал бы интересными. А читатели, то есть вы, могли бы подсказать мне где я не прав или предложить интересную тему для обсуждения.

Что планируется здесь публиковать

  • Занимательные факты по поводу ATL, WTL, WinAPI, MS VC.
  • Решение каких-то проблем
  • Код, который делает что-то полезное
  • Интересные вопросы и ответы на них
  • Может еще что-то в том же духе

Содержательная часть

Классы WTL

Хорошо, хватит общих слов, постараюсь сообщить что-нибудь полезное. Для начала, для тех кто не знает, есть прекрасный проект , который называется RSDN . На этом сайте можно найти массу полезной информации по Visual C++, Delphi, Windows API, различным алгоритмам и еще много чему. Среди прочих, на сайте есть несколько статей про библиотеку WTL. Эти статьи , на мой взгляд, несут массу полезной информации и практически незаменимы для тех, кто решил разобраться с основами программирования с использованием WTL. Да и для тех, кто уже использует эту библиотеку, но не так давно, думаю что почитать тоже будет интересно. Вот ссылки на три статьи:

Прочитав эти статьи в свое время, я решил сделать для себя полный список классов WTL с указанием файлов, в которых определен каждый класс. Вот эта несложная табличка (имена классов упорядочены по алфавиту):

Название класса В каком файле определен
Название класса
В каком файле определен
_U_MENUorID atlapp.h
_U_RECT atlapp.h
_U_STRINGorID atlapp.h
CAnimateCtrl atlctrls.h
CAppModule atlapp.h
CAxPropertyPage atldlgs.h
CAxPropertyPageImpl atldlgs.h
CBitmap atlgdi.h
CBitmapButton atlctrlx.h
CBitmapButtonImpl atlctrlx.h
CBitmapHandle atlgdi.h
CBrush atlgdi.h
CBrushHandle atlgdi.h
CButton atlctrls.h
CCheckListViewCtrl atlctrlx.h
CCheckListViewCtrlImpl atlctrlx.h
CCheckListViewCtrlImplTraits atlctrlx.h
CClientDC atlgdi.h
CColorDialog atldlgs.h
CColorDialogImpl atldlgs.h
CComboBox atlctrls.h
CComboBoxEx atlctrls.h
CCommandBarCtrl atlctrlw.h
CCommandBarCtrlBase atlctrlw.h
CCommandBarCtrlImpl atlctrlw.h
CCommonDialogImplBase atldlgs.h
CCustomDraw atlctrls.h
CDateTimePickerCtrl atlctrls.h
CDC atlgdi.h
CDCHandle atlgdi.h
CDevMode atlprint.h
CDevModeHandle atlprint.h
CDialogResize atlframe.h
CDragListBox atlctrls.h
CDragListNotifyImpl atlctrls.h
CEdit atlctrls.h
CEditCommands atlctrls.h
CEnhMetaFile atlgdi.h
CEnhMetaFileDC atlgdi.h
CEnhMetaFileHandle atlgdi.h
CEnhMetaFileInfo atlgdi.h
CFileDialog atldlgs.h
CFileDialogImpl atldlgs.h
CFindFile atlmisc.h
CFindReplaceDialog atldlgs.h
CFindReplaceDialogImpl atldlgs.h
CFlatScrollBar atlctrls.h
CFlatScrollBarImpl atlctrls.h
CFolderDialog atldlgs.h
CFolderDialogImpl atldlgs.h
CFont atlgdi.h
CFontDialog atldlgs.h
CFontDialogImpl atldlgs.h
CFontHandle atlgdi.h
CFrameWindowImpl atlframe.h
CFrameWindowImplBase atlframe.h
CFrameWndClassInfo atlframe.h
CFSBWindowT atlscrl.h
CHeaderCtrl atlctrls.h
CHotKeyCtrl atlctrls.h
CHyperLink atlctrlx.h
CHyperLinkImpl atlctrlx.h
CIdleHandler atlapp.h
CImageList atlctrls.h
CIPAddressCtrl atlctrls.h
CLinkCtrl atlctrls.h
CListBox atlctrls.h
CListViewCtrl atlctrls.h
CMapScrollImpl atlscrl.h
CMapScrollWindowImpl atlscrl.h
CMDIChildWindowImpl atlframe.h
CMDICommandBarCtrl atlctrlw.h
CMDICommandBarCtrlImpl atlctrlw.h
CMDIFrameWindowImpl atlframe.h
CMDIWindow atlframe.h
CMenu atluser.h
CMenuHandle atluser.h
CMenuItemInfo atluser.h
CMessageFilter atlapp.h
CMessageLoop atlapp.h
CMonthCalendarCtrl atlctrls.h
CMultiPaneStatusBarCtrl atlctrlx.h
CMultiPaneStatusBarCtrlImpl atlctrlx.h
COwnerDraw atlframe.h
CPagerCtrl atlctrls.h
CPageSetupDialog atldlgs.h
CPageSetupDialogImpl atldlgs.h
CPaintDC atlgdi.h
CPalette atlgdi.h
CPaletteHandle atlgdi.h
CPaneContainer atlctrlx.h
CPaneContainerImpl atlctrlx.h
CPen atlgdi.h
CPenHandle atlgdi.h
CPoint atlmisc.h
CPrintDialog atldlgs.h
CPrintDialogEx atldlgs.h
CPrintDialogExImpl atldlgs.h
CPrintDialogImpl atldlgs.h
CPrinter atlprint.h
CPrinterDC atlprint.h
CPrinterHandle atlprint.h
CPrinterInfo atlprint.h
CPrintPreview atlprint.h
CPrintPreviewWindow atlprint.h
CPrintPreviewWindowImpl atlprint.h
CProgressBarCtrl atlctrls.h
CPropertyPage atldlgs.h
CPropertyPageImpl atldlgs.h
CPropertyPageWindow atldlgs.h
CPropertySheet atldlgs.h
CPropertySheetImpl atldlgs.h
CPropertySheetWindow atldlgs.h
CReBarCtrl atlctrls.h
CRecentDocumentList atlmisc.h
CRecentDocumentListBase atlmisc.h
CRect atlmisc.h
CRgn atlgdi.h
CRgnHandle atlgdi.h
CRichEditCommands atlctrls.h
CRichEditCtrl atlctrls.h
CRichEditFontDialog atldlgs.h
CRichEditFontDialogImpl atldlgs.h
CScrollBar atlctrls.h
CScrollImpl atlscrl.h
CScrollWindowImpl atlscrl.h
CServerAppModule atlapp.h
CSimpleArray atlbase.h
CSimpleStack atlctrlw.h
CSimpleValArray atlbase.h
CSize atlmisc.h
CSplitterImpl atlsplit.h
CSplitterWindowImpl atlsplit.h
CSplitterWindowT atlsplit.h
CStatic atlctrls.h
CStatusBarCtrl atlctrls.h
CString atlmisc.h
CStringData atlmisc.h
CTabCtrl atlctrls.h
CTheme atltheme.h
CThemeImpl atltheme.h
CToolBarCtrl atlctrls.h
CToolInfo atlctrls.h
CToolTipCtrl atlctrls.h
CTrackBarCtrl atlctrls.h
CTreeItem atlctrls.h
CTreeViewCtrl atlctrls.h
CTreeViewCtrlEx atlctrls.h
CUpdateUI atlframe.h
CUpdateUIBase atlframe.h
CUpDownCtrl atlctrls.h
CWaitCursor atlctrlx.h
CWinDataExchange atlddx.h
CWindowDC atlgdi.h

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

Далее я решил набросать иерархию классов в WTL. Ее можно взять отсюда (.rtf файл, запакованный в ZIP, 20 Кб) . Как видно из этой схемы, многие классы в WTL не имеют общего предка или вообще существуют "сами по себе".

Два простых класса контейнера

В библиотеке ATL, в файле atlbase.h определены, кроме всего прочего, два интересных класса:

  • CSimpleArray . Этот класс предсталяет из себя динамический массив, который использует только С++ и функции CRT для управления памятью.
  • CSimpleMap . Тоже незатейливый класс, позволяющий создавать списки вида "ключ,значение" (карта) . Как написано в комментарии к этому классу:"предназначен для небольшого количества простых типов или указателей".

Оба класса реализованы как шаблоны, оба очень простые и не зависят от других классов. Как мне кажется, эти классы можно использовать и для своих целей, особенно когда нет желания писать похожие свои собственные и нельзя воспльзоваться подобными классами из стандартной библиотеки STL. В каждом классе есть функции, которые могут найти требуемый элемент простым перебором, используя как критерий результат операции "==" между искомым элементом и элементами в контейнере. Это значит, что если если используется пользовательский тип, то он должен перегружать оператор "==", для того чтобы его можно было найти. Если функции поиска элемента не вызываются, то можно использовать простую структуру,например. Рассмотрю более подробно эти два класса.

CSimpleArray

Объявить экземпляр класса можно, например, так:

CSimpleArray<TSimple> simle_array;

Вместо TSimple можно использовать свой тип или встроенный, например int или double . Теперь опишу методы класса CSimpleArray :

Синтаксис метода
Описание
CSimpleArray()
Конструктор по умолчанию. Тело конструктора вообще ничего не делает, только через список инициализации конструктора задаются начальные значения переменным класса.
~CSimpleArray()
Деструктор. Вызвается при уничтожении массива. Вызывает функцию RemoveAll() (см.ниже).
int GetSize() const
Возвращает число элементов в массиве
BOOL Add(T& t)
Добавляет один элемент в массив. Добавляемый элемент должен быть уже создан. В принципе, в этой и в других подобных функциях, было бы естественнее передавать ссылку на константу, как мне кажется.
BOOL Remove(T& t)
Сначала находит позицию элемента в массиве, а потом удаляет его из этой позиции.
BOOL RemoveAt(int nIndex)
Удаляет элемент массива из указанной позиции. Метод также вызывает деструктор удаляемого элемента.
void RemoveAll()
Удаляет все элементы и освобождает занимаемую память. При удалении вызываются деструкторы удаляемых элементов.
T& operator[] (int nIndex) const
Возвращает ссылку на элемент, заднный номером. Проверка границ диапазона происходит только в отладочной версии.
T* GetData() const
Возвращает указатель на область памяти, отведенной под массив.
Служебные методы
void SetAtIndex(int nIndex, T& t)
Записывает в указанную позицию передаваемый элемент. Проверка границ диапазона происходит только в отладочной версии.
int Find(T& t) const
Возвращает позицию элемента в массиве или -1, если такого элемента не найдено.

CSimpleMap

Пример объявления экземпляра класса:

CSimpleMap<int, TSimple> simple_map;

Вместо int и TSimple можно использовать свои собственные типы или встроенные.

Методы класса CSimpleMap :

Синтаксис метода
Описание
CSimpleMap()
Конструктор по умолчанию. Тело конструктора вообще ничего не делает, только через список инициализации конструктора задаются начальные значения переменным класса.
~CSimpleMap()
Деструктор. Вызвается при уничтожении карты. Вызывает функцию RemoveAll() (см.ниже).
int GetSize() const
Возвращает количество элементов в карте.
BOOL Add(TKey key, TVal val)
Добавляет новую пару "ключ,значение".
BOOL Remove(TKey key)
Находит соответствующий ключ (если есть) и удаляет пару "ключ, значение" из карты. Для удаляемых элементов вызываются деструкторы.
void RemoveAll()
Удаляет все элементы и освобождает память. Для всех удаляемых элементов вызываются деструкторы.
BOOL SetAt(TKey key, TVal val)
Записывает значение, соответствующее ключу, при условии что такой ключ есть.
TVal Lookup(TKey key) const
Выполняет поиск значения по ключу.
TKey ReverseLookup(TVal val) const
Выполняет поиск ключа по значению.
TKey& GetKeyAt(int nIndex) const
Возвращает ссылку на ключ по его позиции. Границы диапазона проверяются только в отладочной версии.
TVal& GetValueAt(int nIndex) const
Возвращает ссылку на значение по его позиции. Границы диапазона проверяются только в отладочной версии.
Служебные методы
void SetAtIndex(int nIndex, TKey& key, TVal& val)
Записывает в указанную позицию ключ и значение.
int FindKey(TKey& key) const
Выполняет поиск ключа и возвращает его позицию или -1, если не найдено
int FindVal(TVal& val) const
Выполняет поиск значения и возвращает его позицию или -1, если не найдено.

В обоих классах, как я уже говорил, поиск выполняется простым перебором. К тому же при удалении элемента "лишняя" память не освобождается. Вся отведенная память освобождается только при удалении массива. Несмотря на все это, я считаю что эти два класса вполне можно использовать для небольших наборов данных.

Вот, пока все. Все вопросы, пожелания, критику можете направлять мне по адресу: softonic@narod.ru

Используются технологии uCoz