Программирование на Visual C++. Архив рассылки
Шрифт:
В MFC существует специальный класс, под названием CCmdTarget. Наследуя свои классы от cCmdtarget, вы можете обеспечить для них необходимую функциональность в dispatch виде – как раз как ее понимают скрипты. При созднании нового класса в ClassWizard (View>ClassWizard>Add Class>New), наследуемого от cСmdtarget, просто щелкните на кнопке Automation или Creatable by ID, чтобы обеспечить возможность создания экземпляра объекта по его ProgID. Замечу, что для программ, реализующих внутреннюю автоматизацию, это не нужно. Для приложений, реализующих внешнуюю и смешанную автоматизацию, это необходимо для "корневых" объектов.
После создания такого объекта, ClassWizard создает интерфейс ITestAutomatedClass (это dispatch интерфейс, т.е. наследуется от IDispatch), который реализуется моим CTestAutomatedClass. Теперь к этому интерфейсу я могу добавить методы или свойства, которые автоматически будут реализованы в CTestAutomatedClass. Я добавил свойство Age.
COM-объекты, коим и является наш CTestAutomatedClass, можно создавать только динамически. Это связано с тем, что объект может использоваться несколькими приложениями одновременно, а значит, удаление объекта из
Создаваемые через ProgID COM-объекты, обычно являются Proxy-компонентами. Реально они не содержат никакой функциональности, но имеют доступ к приложению и его внутренним, не доступным извне, функциям. Хотя можно организовать все таким образом, чтобы всегда создавался только один COM-объект, а все остальные вызовы на создание возвращали указатели на него.
Метод интерфейса CCmdTarget GetIDispatch, позволяет получить указатель на реализованный интерфейс IDispatch. В параметрах можно указать, нужно ли увеличивать счетчик ссылок или нет.
В следующей статье, посвященной использованию функциональности WebBrowser Control, я обращусь к практическому применению dispatch-объектов программы в скриптах. А в дальнейшем, мы поговорим о внедрении процессора скриптов в собственные приложения.
Q. Как сделать так, чтобы программа сама себя могла стереть, т.е. свой *.exe файл?
A1 Удалить программу в тот момент, когда она запущена, не представляется возможным (во всяком случае такая возможность мне не знакома), остается удаление после завершения ее выполнения. Идея следующая: при выходе из программы создать BAT-файл, который ждет до тех пор, пока файл можно будет удалить (программа завершит работу), удаляет файл программы и себя, и запустить его:
Преимущества:
– файл удаляется сразу в тот момент, когда это становится возможно
Недостатки:
– если запустить два экземпляра приложения, то после завершения работы первого мы получаем цикл активного ожидания до тех пор пока не завершится второй экземпляр (это незаметно в W95/98, но в NT в окне Task Manager можно заметить полную загрузку процессора). Также пользователь все это время будет удивляться наличию невесть откуда взявшегося файла sefdel.bat.
Майкрософт же предлагает свой способ решения проблемы, причем его реализация отличается для WinNT и Win95/98. Удаление (переименование, замещение, и т.д.) файла происходит во время следующей перезагрузки системы.
Win95/98: В процессе перезагрузки системы запускается утилита wininit.exe, которая осуществляет заданные действия над файлами, указанные в секции [rename] файла wininit.ini. При этом т.к. wininit.exe запускается еще до того как запущена система поддержки длинных имен файлов, все имена должны быть указаны в формате DOS (8.3).
Последовательность действий для удаления или переименования файла:
1. Проверить наличие файла WININIT.INI в директории Windows
2. Если WININIT.INI существует, открываем его и добавляем новые строки в секцию [rename]. Если файла нет, создаем его и секцию [rename] в нем. 3.Добавляем строки следующего формата в секцию [rename]:
Оба пути DestinationFileName и SourceFileName не должны содержать длинных имен. Приемник и источник должны находится на одном диске. Для удаления файла вместо DestinationFileName использовать NUL.
WinNT:
Здесь все сделано по-человечески. Для удаления файла следует использовать функцию MoveFileEx:
где szSrcFile – имя файла или директории
Преимущества:
– "Лицензированный" метод Майкрософт
Недостатки:
– Чрезмерно утяжеленная процедура редактирования wininit.ini, проблемы при работе с длинными именами Win95/98,
– Удаление происходит только в момент перезагрузки.
A2 Программа не может удалить свой exe-файл, пока она работает. Это фундаментальное правило при работе под Windows. Поэтому всё, что остаётся – это поручить удаление другому процессу перед тем как завершить свой.
Самый простой вариант – создать на лету и запустить bat-файл, который дождётся завершения нашего процесса, а затем удалит его exe-файл. Более сложные варианты подразумевают создание в чужом процессе (например, в Task Manager) рабочего потока, который опять же дождётся завершения нашего процесса и убьёт файл.
Вот пример функции, которая создаёт bat-файл и запускает его, чтобы убить наш exe-файл. Лучше всего вызывать её непосредственно перед завершением нашего процесса.
Замечу, что это только пример, который можно улучшать в различных направлениях. Можно, скажем, получать имя bat-файла через GetTempFileName, чтобы гарантировать его уникальность. Или понизить приоритет создаваемого из bat-файла процесса до минимума, чтобы он кушал поменьше ресурсов в процессе циклической проверки существования exe-файла.
Q. Есть у меня файлы с расширением .pdb (Microsoft C/C++ program database 2.00) (их MS VC++ делает, в папке Debug проекта создаются), можно ли с их помощью восстановить исходники программы (размер у них такой, что туда не только прога влезет, но и комментарии к ней в HTML (FrontPage Style) формате :)
Пока все. До скорого!
Программирование на Visual C++
Выпуск №33 от 18 февраля 2001 г.
Приветствую!
Сегодня хочу предложить вашему вниманию заключительную часть статьи про ODBC нашего постоянного автора Александра Шаргина, которая, если вы помните, открывает цикл статей о технологиях доступа к данным.
СТАТЬЯ
Доступ к БД с использованием ODBC
Часть 2
Автор: Александр Шаргин
В предыдущей части статьи мы с вами рассмотрели основы использования ODBC для доступа к базам данных. Но в процессе знакомства с этой технологией у каждого естественным образом возникает целый ряд вопросов. Ответам на самые распространённые из них и будет посвящена вторая часть статьи.
При переносе программы, использующей ODBC, на другой компьютер возникает целый ряд проблем. Во-первых, на нём может не оказаться нужных компонентов ODBC, а значит, их необходимо распространять вместе с программой. Во-вторых, на другом компьютере придётся заново регистрировать источник данных, причём желательно, чтобы пользователь об этом не знал. В этом разделе я расскажу, как всё это делается.
Сразу замечу, что некоторые приложения изначально разрабатываются для работы с произвольными БД. К таким приложениям относятся пакеты статистической обработки данных или электронные таблицы, способные импортировать данные из выбранной пользователем БД. Другой характерный пример – среда Visual C++. Если вы разрабатываете подобное приложение, можете смело пропустить этот раздел. Установка компонентов, необходимых для работы с конкретной базой данных – не ваша забота. Любому приложения, использующему ODBC, необходимы основные компоненты ODBC (core components) и ODBC-драйвер. К основным компонентам относятся менеджер драйверов (ODBC32.DLL), библиотека инсталлятора (ODBCCP32.DLL), библиотека курсоров (ODBCCR32.DLL) и администратор источников данных (ODBCAD32.EXE), а также несколько вспомогательных файлов. Драйвер состоит из двух DLL: библиотеки драйвера (driver DLL) и библиотеки настройки (setup DLL). Библиотека драйвера экспортирует все необходимые функции ODBC API, а библиотека настройки – функции ConfigDriver и ConfigDSN, используемые для конфигурирования самого драйвера и связанных с ним источников данных. Иногда обе библиотеки объединяют в одной DLL. Основные компоненты сейчас установлены практически на каждом компьютере, поэтому об их инсталляции я рассказывать не буду. Тем, кого интересует этот вопрос, советую обратиться к описанию функции SQLInstallDriverManager. Драйвер для каждой конкретной СУБД обычно распространяется со своей программой инсталляции. В этом случае вам нужно просто включить её в комплект поставки. Но предположим, что такая программа недоступна. Тогда можно воспользоваться функцией SQLInstallDriverEx, входящей в библиотеку инсталляции. Эта функция вызывается дважды: первый раз, чтобы определить целевую папку для драйвера, а второй раз, чтобы добавить необходимые записи в реестр. Копирование осуществляет вызывающая программа. Предположим, что драйвер "My Driver" состоит из файлов MYDRV.DLL и MYSETUP.DLL. Установку этого драйвера выполнит следующий код.