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

Здравствуйте, уважаемые читатели!

Можно сказать, что я закончил написание моей первой программы, в которой используется только WTL и Win API. Программа называется CDOpen и предназначена для быстрого открытия/закрытия лотка CD-привода. Мне самому давно была нужна такая программа, так как системный блок на моем рабочем месте установлен не очень удобно и тянуться к кнопке открытия на приводе не удобно (к тому же были случаи, когда вместо кнопки открытия я нажимал кнопку питания, а это не смешно). Несмотря на то, что программа получилась на вид довольно простой, в ходе ее создания пришлось столкнуться с решением некоторых проблем, которые не лежат на поверхности. Почитать описание и возможности CDOpen, а также скачать можете здесь.

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

Первые впечатления

Многое из того, что предлагает WTL я в своей программе не использовал. ПОКА. Но все равно кое-какие мысли на тему WTL у меня появились. Попробую организовать их по пунктам:

  1. Не все то, что я знал про MFC нужно забыть. Многие классы в WTL, такие как CMenu или СBrush, практически один-а-один повторяют интерфейс классов MFC. С одной стороны это не очень хорошо, так как можно было переписать такие классы так, чтобы ими удобнее пользоваться. С другой стороны это большой плюс, так как тем, кто использовал MFC такие классы будут привычны, а те, кто не использовал MFC смогут посмотреть описание таких классов в MSDN. Сразу оговорюсь, что я не проверял соответствие классов WTL классам MFC, это сходство было замечено мной лишь на некоторых, но я сделал предположение, что такое сходство в большей или меньшей степени будет повторяться и для других схожих классов. Впоследствии, может быть, я более внимательно займусь этим вопросом.
  2. Исходники должны лежать по правую руку. Практически во всех статьях по WTL пишут, что исходники библиотеки должны стать верным спутником разработчика, который ее использует. Со своей стороны могу согласиться на 101% с этим утверждением. При любой неясности, в исходных текстах WTL можно найти ответ практически наверняка. Задачу навигации по WTL облегчает VC - команда "Go definition of _____" контекстного меню, она мнгновенно перебрасывает в один из исходных файлов WTL на место определения интересующего макроса, функции, класса и т.д.
  3. Организация классов целиком в h-файлах не самая удачная мысль. Во-первых, интерфейс класса захламляется реализацией и без Class Wizard-а уже сразу не разберешься что и где лежит. Во-вторых, "традиционное" разделение на интерфейс и реализацию, как мне кажется, наиболее естественно. Но в таком случае методы класса перестают быть inline-методами. Делайте со мной что хотите, но я все равно не пойму, зачем в обычной программе делать все методы inline?

Что же получается в итоге? Могу сказать, что WTL пока меня не разочаровала. Могу сказать, что даже наоборот - постепенно WTL мне стала нравиться больше. WTL практически не навязывает мне как разработчику никаких правил и не обременяет толстой прослойкой, наподобии VCL. Минус WTL - это небольшая ее распространненость и небольшое число разных расширений, например классов для работы с сетью и т.д. в отличии от MFC, под которую понаписано столько всего, что кажется количество всяких сторонних библиотек и классов приближается к бесконечности.

Макросы WTL

Один из читателей предложил мне составить список макросов WTL, я пробежался по заголовочным файлам и набросал вот эту табличку:

Название макроса
Файл, где определен
BEGIN_DDX_MAP(thisClass) atlddx.h
BEGIN_MSG_MAP_EX(theClass) atlcrack.h
BEGIN_UPDATE_UI_MAP(thisClass) atlframe.h
CHAIN_CLIENT_COMMANDS() atlframe.h
CHAIN_COMMANDS(theChainClass) atlframe.h
CHAIN_COMMANDS_ALT(theChainClass, msgMapID) atlframe.h
CHAIN_COMMANDS_ALT_MEMBER(theChainMember, msgMapID) atlframe.h
CHAIN_COMMANDS_MEMBER(theChainMember) atlframe.h
CHAIN_MDI_CHILD_COMMANDS() atlframe.h
COMMAND_CODE_HANDLER_EX(code, func) atlcrack.h
COMMAND_HANDLER_EX(id, code, func) atlcrack.h
COMMAND_ID_HANDLER_EX(id, func) atlcrack.h
COMMAND_RANGE_CODE_HANDLER_EX(idFirst, idLast, code, func) atlcrack.h
COMMAND_RANGE_HANDLER_EX(idFirst, idLast, func) atlcrack.h
DDX_CHECK(nID, var) atlddx.h
DDX_CONTROL(nID, obj) atlddx.h
DDX_FLOAT(nID, var) atlddx.h
DDX_FLOAT_RANGE(nID, var, min, max) atlddx.h
DDX_INT(nID, var) atlddx.h
DDX_INT_RANGE(nID, var, min, max) atlddx.h
DDX_RADIO(nID, var) atlddx.h
DDX_TEXT(nID, var) atlddx.h
DDX_TEXT_LEN(nID, var, len) atlddx.h
DDX_UINT(nID, var) atlddx.h
DDX_UINT_RANGE(nID, var, min, max) atlddx.h
DECLARE_FRAME_WND_CLASS(WndClassName, uCommonResourceID) atlframe.h
DECLARE_FRAME_WND_CLASS_EX(WndClassName, uCommonResourceID, style, bkgnd) atlframe.h
DECLARE_FRAME_WND_SUPERCLASS(WndClassName, OrigWndClassName, uCommonResourceID) atlframe.h
END_DDX_MAP() atlddx.h
FORWARD_NOTIFICATIONS() atlapp.h
HandleToLong( h ) atlapp.h
HandleToUlong( h ) atlapp.h
IntToPtr( i ) atlapp.h
LongToHandle( h) atlapp.h
LongToPtr( l ) atlapp.h
MESSAGE_HANDLER_EX(msg, func) atlcrack.h
MESSAGE_RANGE_HANDLER_EX(msgFirst, msgLast, func) atlcrack.h
NOTIFY_CODE_HANDLER_EX(cd, func) atlcrack.h
NOTIFY_HANDLER_EX(id, cd, func) atlcrack.h
NOTIFY_ID_HANDLER_EX(id, func) atlcrack.h
NOTIFY_RANGE_CODE_HANDLER_EX(idFirst, idLast, cd, func) atlcrack.h
NOTIFY_RANGE_HANDLER_EX(idFirst, idLast, func) atlcrack.h
PtrToInt( p ) atlapp.h
PtrToLong( p ) atlapp.h
PtrToShort( p ) atlapp.h
PtrToUint( p ) atlapp.h
PtrToUlong( p ) atlapp.h
PtrToUshort( p ) atlapp.h
REFLECTED_COMMAND_CODE_HANDLER atlapp.h
REFLECTED_COMMAND_CODE_HANDLER_EX(code, func) atlcrack.h
REFLECTED_COMMAND_HANDLER atlapp.h
REFLECTED_COMMAND_HANDLER_EX(id, code, func) atlcrack.h
REFLECTED_COMMAND_ID_HANDLER atlapp.h
REFLECTED_COMMAND_ID_HANDLER_EX(id, func) atlcrack.h
REFLECTED_COMMAND_RANGE_CODE_HANDLER atlapp.h
REFLECTED_COMMAND_RANGE_CODE_HANDLER_EX(idFirst, idLast, code, func) atlcrack.h
REFLECTED_COMMAND_RANGE_HANDLER atlapp.h
REFLECTED_COMMAND_RANGE_HANDLER_EX(idFirst, idLast, func) atlcrack.h
REFLECTED_NOTIFY_CODE_HANDLER atlapp.h
REFLECTED_NOTIFY_CODE_HANDLER_EX(cd, func) atlcrack.h
REFLECTED_NOTIFY_HANDLER atlapp.h
REFLECTED_NOTIFY_HANDLER_EX(id, cd, func) atlcrack.h
REFLECTED_NOTIFY_ID_HANDLER atlapp.h
REFLECTED_NOTIFY_ID_HANDLER_EX(id, func) atlcrack.h
REFLECTED_NOTIFY_RANGE_CODE_HANDLER atlapp.h
REFLECTED_NOTIFY_RANGE_CODE_HANDLER_EX(idFirst, idLast, cd, func) atlcrack.h
REFLECTED_NOTIFY_RANGE_HANDLER atlapp.h
REFLECTED_NOTIFY_RANGE_HANDLER_EX(idFirst, idLast, func) atlcrack.h
UIntToPtr( ui ) atlapp.h
ULongToPtr( ul ) atlapp.h

В файле atlcrack.h кроме перечисленных макросов определено очень много макросов, имеющих префиск MSG_WM и несколько MSG_OCM. Почитать про них можно на сайте RSDN, в статье Использование WTL. Часть 1.

На сегодня вроде все.

Всего наилучшего.

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