Программирование на Visual C++. Архив рассылки - Алекс Jenter
Шрифт:
Интервал:
Закладка:
Статья про WTL в 14-ом выпуске не осталась незамеченной. Некоторые заитересовались этой темой, некоторые захотели высказать свое мнение. Вот одно из таких писем:
Добрый день (вечер, ночь, утро) Алекс и подписчики "Программирование на Visual C++" (в случае, если мое письмо опубликуют в рассылке).
После прочтения выпуска No.14 у меня появилась пара мыслей по поводу будущего MFC и WTL. Точнее, мысли эти у меня есть давно (месяца два-три), возможно, вы об этом тоже знаете. То, что MFC умирает – это факт. С самого начала она была мертворожденной. Постоянные баги, внутренняя сложность, обилие недокументированных внутренних структур и функций – все это не делает библиотеку хорошей. Я уже не говорю о ее монстрообразности. Да, с ней удобно работать. Но стоят ли проблемы удобства? Можно говорить очень долго о достоинствах и недостатках MFC, но факт остается фактом: будущего у нее нет.
Что касается WTL, то здесь тоже все непросто. Точнее, если верить одному из мэнэджеров Майкрософт (к сожалению, не помню кто), то все очень просто: у WTL будущего тоже нет. В одном из выступлений он заметил, что WTL не будет поддерживаться Майкрософт. Правда, не исключено, что WTL получит свое развитие.
Ну и последнее. Я думаю, все слышали о проекте Майкрософт .NET. Я занимаюсь им в свободное время и могу сказать одно: это действительно отличная вещь. Пока еще сырая, нет даже беты, но уже в следующем обновлении MSDN (октябрь) должна появиться Visual Studio 7 Beta (или Visual Studio.Net). Не хочу рассказывать о .NET, не для маленького письма тема, к тому же, я не настолько хороший лектор, как Jeffrey Richter и Don Box. Поэтому всем, кто интересуется, могу посоветовать пару ссылок: http://www.msdn.microsoft.com/net/, http://www.andymcm.com/ и замечательный список рассылки DOTNET на http://discuss.develop.com.
Alex Ivanoff ВОПРОС-ОТВЕТQ1 В Visual C++ 6.0 создаётся ImageList с помощью ImageList_LoadImage. Потом две загруженные картинки рисуются в окошке – сначала одна, потом поверх неё другая (используется маска) – функция ImageList_Draw. Проблема в том, что рисуется только в 16 стандартных цветах. Картинка 24-битная. Пробовал и с 256 и 16-цветными, с использованием палитры – эффект тот же. Если не сложно, подскажи, как её нарисовать в 16M цвете (использую только API, без MFC)?
ДронA. Насколько я понимаю, в функцию ImageList_LoadImage следует передать флаг LR_CREATEDIBSECTION, чтобы избежать преобразований цветов в изображении.
Например:
…
HIMAGELIST hImageList;
…
hImageList = ImageList_LoadImage(hInstance, MAKEINTRESOURCE(IDB_BITMAP1), 100, 0, CLR_NONE, IMAGE_BITMAP, LR_CREATEDIBSECTION);
…
Alexander SharginТакой же ответ на этот вопрос прислал David Potashinsky. Большое спасибо всем, кто откликнулся.
У меня выдалось немного свободного времени, поэтому следующий вопрос я не стал помещать в рубрику "В поисках истины", а ответил на него сам:
Q2 Меня попросили сделать страничку свойств (CPropertySheet), которая является главным окном приложения, минимизируемой. Означенная просьба неожиданно оказалась не столь простой как кажется на первый взгляд. Добавить собственно значок минимизации – нет проблем: в CPropertySheet::OnInitDialog добавляем ModifyStyle(0, WS_MINIMIZEBOX). Одно плохо – не работает он.
ОлегA. Сначала скажу, что эта идея – property sheet в качестве главного окна приложения – довольно неудачная. Сейчас объясню, почему. С точки зрения Windows Ваше приложение является не окном в полном смысле слова, а диалогом, причем таким диалогом, кнопка которого на панель задач не выводится. Т.о. при минимизации произойдет вовсе не то, что Вы ожидали – он минимизируется а-ля windows 3.1 (или как дочернее окно MDI) – в левый нижний угол.
Можно конечно ухитриться и сделать так, чтобы показывалась кнопка на таскбаре (см. предыдущий выпуск), но приемлемый, на мой взгляд, выход в данной ситуации – минимизировать в системный трей.
Теперь – что надо сделать, чтобы кнопка минимизации заработала:
При нажатии на эту кнопку для такого окна генерации события WM_SYSCOMMAND не происходит, и обрабатывать его нет смысла. Поэтому в класс-наследник CPropertySheet нужно добавить обработчик события WM_NCLBUTTONDOWN (non-client left button down, это событие происходит, когда нажимается левая кнопка мыши в неклиентской области окна, а значок минимизации как раз и находится в этой области):
void CMinSheet::OnNcLButtonDown(UINT nHitTest, CPoint point) {
// TODO: Add your message handler code here and/or call default
CPropertySheet::OnNcLButtonDown(nHitTest, point);
if (nHitTest == HTMINBUTTON) {
IsIconic()? ShowWindow(SW_RESTORE): ShowWindow(SW_MINIMIZE);
}
}
Заметьте, что в свернутом состоянии кнопка минимизации (minimize) становится кнопкой восстановления (restore).
Повторю, в этом случае минимизироваться диалог будет в левый нижний угол. Лучше всего вместо минимизации его прятать [ ShowWindow(SW_HIDE); ] и выводить иконку в трее (как это делать см. выпуск рассылки №11).
Если кто-то из вас, уважаемые подписчики, не согласен в чем-то с этим ответом, или есть какие-нибудь дополнения – обязательно напишите.
Подробно про класс CPropertySheet вы сможете прочитать в следующем выпуске.
В ПОИСКАХ ИСТИНЫQ. Возникла вот такая задачка. Имеется некоторое разбиение SDI на несколько view при помощи сплиттеров (A). Как его изменить не убивая окна (на B или C)?
+--+----+ +--+----+ +--+----+
| | | | | | + + +
+--+----+ +--+ | + +----+
| | | | | + + +
A +-------+ B +--+----+ C +--+----+
Nikita ZeeminДо встречи!
©Алекс Jenter mailto:[email protected] Красноярск, 2000.Программирование на Visual C++
Выпуск №17 от 29 сентября 2000 г.
Всем привет!
До меня дошли сведения, что предыдущий, 16-тый, выпуск дошел почему-то не до всех подписчиков. То ли из-за глюков на ГорКоте, то ли из-за гиперактивности магнитных бурь … ;)
Повторно высылать я его, пожалуй, не стану, лучше дам вам на него прямую ссылку. Тем, кто его еще не видел, рекомендую прочитать,так как данный выпуск связан с предыдущим.
MFCИтак, наконец-то мы добрались до темы создания окон свойств, которые в MFC реализуются с помощью, как вы уже догадались, класса CPropertySheet.
Работа с окнами свойств : использование класса CPropertySheetКак известно, практически во всех более-менее серъезных программах есть диалоговые окна настройки параметров, или опций, приложения. Такие окна получили название окон свойств. Чтобы увидеть одно из таких окон, достаточно выбрать Tools|Options в Visual C++ IDE.
Задача создания окон свойств стоит практически перед каждым разработчиком, именно поэтому в MFC решение этой проблемы в некоторой степени автоматизировано с помощью класса CPropertySheet. В результате его применения вы получаете готовое диалоговое окно с набором закладок и некоторым количеством стандартных кнопок – OK, Cancel, и т.д. Закладки здесь – это объекты типа CPropertyPage. Этот класс, кажется, уже фигурировал в одном из выпусков. Никогда не путайте CPropertySheet и CPropertyPage: помните, что первый (CPropertySheet) СОДЕРЖИТ вторые (CPropertyPage) так же, как книга содержит страницы.
Так, с этим разобрались, идем дальше. Как пользоваться классом CPropertySheet? Очень несложно, вы в этом сами сейчас убедитесь.
Для каждой закладки нужно создать диалоговый ресурс (не обязательно со стилем child), куда вы помещаете все содержимое соответствующей страницы (также, как и при работе с CTabCtrl). Например, IDD_PROPPAGE1 и IDD_PROPPAGE2ROPPAGE2. Можно сразу заполнить поле Caption в диалогах, чтобы потом заголовки закладок сформировались автоматически.
В проект добавляется класс-наследник от CPropertySheet, пускай он называется CMyPropSheet.
Для того, чтобы можно было работать с контролами на закладках, добавляется отдельный класс для каждой страницы-закладки (наследованный от CPropertyPage). Например, для двух закладок это будут классы CPropPage1 и CPropPage2 (эти классы добавьте дабл-кликнув на поверхности соответствующего диалога и выбрав "Create a new class", затем в поле "Base class" выберите CPropertyPage в качестве класса-родителя). В эти классы нужно поместить члены, связанные с контролами, расположенными на странице. Например, если у нас на первой странице (IDD_PROPPAGE1) есть Edit Box, добавляем в класс CPropPage1 переменную m_strEdit класса CString, доступ – public. Пусть на второй странице у нас Check Box, значит в класс CPropPage2 записываем член m_isChecked типа BOOL, и т.д. Использование типа доступа public к этим полям в данном случае оправданно, т.к. избавляет в дальнейшем от многих хлопот. И не забывайте, эти члены класса должны быть связаны с соответствующими контролами на закладке.
Теперь в файл mypropsheet.h (где объявлен класс CMyPropSheet) пишем:
#include "proppage1.h" // делаем классы страниц видимыми
#include "proppage2.h"
…
class CMyPropSheet: public CPropertySheet {
…