"Программирование на Visual C++. Архив рассылки" - читать интересную книгу автора (Jenter Алекс)
Программирование на Visual C++ Выпуск №10 от 18/07/2000
Здравствуйте!
Прошу прощения за небольшую задержку этого выпуска.
Между прочим, со дня создания рассылки уже прошел целый месяц. За это время на нее подписалось более 5000 человек, причем чуть меньше 4000 из них – на HTML версию.
WEBзор
Недавно мне пришло письмо от одного человека с предложением рассказать в рассылке об их сайте, часть которого посвящена как раз программированию на Visual C++. Тогда у меня появилась идея сделать эту рубрику, где я мог бы рассказывать об интересных ресурсах по теме рассылки, которые можно обнаружить на просторах интернета. Я уже, правда, рассказывал про CodeGuru – но это не было вынесено в отдельную рубрику… да и те, кто не очень дружит с английским, могли задаться вопросом, а нет ли в Сети чего-нибудь интересного по VC на русском языке?
Прежде всего, стоит отметить широкий диапазон тем, охватываемых этим сайтом – это MFC, WinAPI, OpenGL, ActiveX, а также VBA, SQL, HTML, CGI, Perl, форматы файлов, алгоритмы и многое другое.
Содержание оформлено в виде "шагов" – отсюда, в частности, и название – маленьких порций информации, которые легко читать и усваивать. Обычно каждый шаг ставит и выполняет определенную задачу, так что легко можно найти решение какой-то конкретной проблемы.
Все описанное мной далее относится к разделу "Visual C++".
Есть материал как для начинающих, так и для более продвинутых программистов. Раздел, посвященный MFC, содержит более 200 "шагов". Темы шагов в большинстве своем подобраны интересные и нужные, а для новичков, не имеющих возможности свободно читать MSDN, вообще незаменимые.
Из недостатков хочу отметить некоторую сухость и краткость изложения (хотя последняя, конечно, сестра таланта), иногда все выливается в "нажми туда-то, напиши то-то". Также мне не совсем по вкусу местами чересчур неофициальный и немного непоследовательный стиль автора, но это кому как, наверное.
ОЧЕНЬ СИЛЬНО портит впечатление обилие опечаток и орфографических ошибок (не говоря уже о пунктуационных) … во многих из "шагов" я мог насчитать не меньше двух. Обидно! В крайнем случае – вроде спел-чекеры уже не редкость…
Не знаю, как сейчас, но раньше, помню, сайт не позволял себя скачивать целиком программами типа Teleport Pro. Мне это казалось совершенно неоправданным и ненужным ограничением – в конце концов, у нас ведь не Америка, где неограниченный доступ стоит 15-20 долларов в месяц. В гостевой книге 90% записей были посвящены этому вопиющему безобразию… Авторам сайта, наверно, это надоело, и они гостевую книгу убрали совсем… ;)
Хотя выполнять свое предназначение сайту все это, конечно, не мешает. Да и критиковать легко…
Зайдите, посмотрите, – скорее всего, найдете что-нибудь интересное и для себя.
ВОПРОС-ОТВЕТ
Q. Как получить доступ к ресурсам DLL в самой DLL? Задача сводилась к следующему – нужно было сделать диалоговое окно в функции, которая находилась в DLL
declspec(dllexport)
int MyDllFunction() {
CDialog dlg;
int ret = dlg.DoModal();
return ret;
}
DLL имела ресурс Dialog для этого диалогового окна, но работать напрочь отказывалась – этот ресурс не обнаруживался и окно не создавалось. DLL собиралась как со статически линкуемой библиотекой MFC, так и с динамически линкуемой библиотекой MFC.
Igor Sorokin
A1. В вопросе приводился пример функции, с помощью которого предполагалось вызвать диалог. В MSDN я нашёл статью TN058, рассказывающую о том, как реализовано управление модулями в MFC.
Для того, чтобы получить доступ к любому объекту MFC из экспортируемой функции, необходимо в самом начале функции поставить AFX_MANAGE_STATE(AfxGetStaticModuleState()) ;
Таким образом, будут корректно реализована связь дескрипторов (HANDLE) с объектами MFC и , в частности, ресурсы, хранимые в DLL будут корректно задействованы:
declspec(dllexport)
int MyDllFunction() {
AFX_MANAGE_STATE(AfxGetStaticModuleState());
CDialog dlg(IDD_TESTDLG);
return dlg.DoModal();
}
Алексей Селезнев
A2. Вообще говоря, доступ к ресурсам DLL из самой DLL получать не надо – он и так дан. Но пример, указанный в вопросе, по-моему, чуть-чуть не правильный, и работать никогда не будет, потому как "CDialog dlg" не проинициализирован как следует. Пусть в DLL-проекте создан ресурс-диалог, с идентификатором (например) IDD_RTNDIALOG. Для того, показать этот ресурс-диалог (в модальном режиме), надо выполнить:
CDialog dlg(IDD_RTNDIALOG);
dlg.DoModal();
Здесь конструктору объекта dlg передаём ID ресурса – нашего диалога. Можно еще указать родительское окно. Чтобы показывать этот диалог немодально, следует использовать Create/[ShowWindow/WS_VISIBLE].
Однако, если мы хотим, чтобы диалог содержал всякие контролы, помимо OK и Cancel, то нужно на основе ресурса-диалога создать класс-наследник CDialog'a. (в MFC – например с даблкликнув на форму шаблона). Пусть мы создали класс с именем CRtnDlg. Он и будет реализовывать всякие обработчики контролов.
Показать модально проще простого:
CRtnDlg dlg;
dlg.DoModal();
Немодально – use ShowWindow(…);
Кстати, в описании CRtnDlg.h нужно не забыть вставить #include "resource.h" – а то компилятор тоже ресурса не увидит :)))
Кстати, на счет примера – Игоря я обидеть не хотел, может он его так, для пояснения сути написал.
3. Вопрос:
Недавно я писал курсовую – рисует всякие дифуры. А каждое конкретное диф.ур-ие реализуется в отдельной DLL'ке (по типу plugins). А т.к. мои DLL с дифурами имели единый интерфейс(не COM), для них я сделал шаблон. А потом случилось страшное – DLL-проекты, созданные по шаблону, не компилировались, с дурацкими ошибками. Короче, через сутки я выяснил, что почему-то в проекте, созданном по шаблону, директива компилятора _AFXEXT заменяется на _USRDLL (в результате мой DLL плавно превращается из MFC extension в Regular DLL). Шаблон создавал по существующему проекту. Ни в исходном проекте, ни в шаблоне ничего в опциях не путал. Приходилось потом вручную каждый раз изменять директивы. А в чем же дело? Может знает кто?
4. Алекс, и ещё – на счет ответов на вопрос в №8. Я там между прочим указывал, что объект CFont нужно сделать членом класса окна, т.к. передаётся указатель.
Pavel Vasev
Насчет пункта 4 Павел совершенно прав, я просто не обратил внимания на это его замечание (тогда я не знал, что это имеет ключевое значение, а потом не вспомнил). Он, кажется, единственный, кто на это указал.
Благодарю также авторов всех остальных ответов на этот вопрос. Их прислали: Ivan Nevraev, Alexander N. Dovzhikov, Alex Hin.
В ПОИСКАХ ИСТИНЫ
Q. Не подскажете как в tray выводить текст, как например сделаны часы в Windows?
Dmitriy
Как выводить в tray иконку, надеюсь, все знают ;)
Shell_NotifyIcon() есть, а вот Shell_NotifyText(), к сожалению, не существует… ;)
У меня просьба (в связи с небольшими неполадками) – прошу тех, кто не получил от меня ответа в течение недели или больше, послать письмо еще раз.