Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
УМК ПП1 (C++ БД).doc
Скачиваний:
4
Добавлен:
01.03.2025
Размер:
5 Мб
Скачать
☆

9.2. Вызов других приложений

Взаимодействие приложения с внешними программами может происходить различными способами. Это может быть:

• непосредственный вызов внешней программы из вашего приложения;

• вызов внешней программы, связанной с некоторым документом;

• обмен с приложениями сообщениями Windows;

• технология OLE – внедрения и связывания документов, подготовленных внешними программами, в ваше приложение;

• динамический обмен данными между приложениями – DDE.

В данном пособии рассматриваются только два первых способа. Например, ваша задача может заключаться в создании с помощью C++Builder пользовательского интерфейса к какой-нибудь ранее разработанной программе, которая представлена только своим выполняемым модулем. Тогда естественным способом решения этой задачи является запуск загрузочного модуля программы из вашего приложения. Другой пример использования внешней программы – желание предоставить пользователю, работающему с вашей программой, какие-то дополнительные возможности. Например, вам может захотеться дать пользователю возможность вызвать из вашего приложения программу архивации для того, чтобы предоставить пользователю эту услугу, но не обременять его дополнительными знаниями о создании архивных файлов.

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

Вызов внешней программы функцией execlp

Функция execlp позволяет выполнить из своего приложения любое указанное приложение, передав ему управление. Вызванная программа замещает в памяти вызвавшее ее приложение. Таким образом, родительское приложение завершается и начинается новое.

Функция execlp определена в файле process.h (не забывайте включать его в приложение соответствующей директивой #include) следующим образом:

int execlp(char *path, char *param1, *param2, …*paramn, NULL)

Функция execlp возвращает 0 при успешной загрузке нового приложения, а при ошибке возвращает -1.

Рассмотрим примеры использования функции execlp. Оператор

if (execlp(“NotePad.exe”, “ReadMe.txt”,NULL))

ShowMessage(“Текстовый редактор не запущен”);

завершает выполнение вашего приложения и передает управление программе с NotePad.exe. Этот файл должен быть расположен в рабочем каталоге или в одном из каталогов, указанных в переменной окружения PATH. Иначе функция execlp вернет -1 и будет выдано сообщение функцией ShowMessage. Аналогичное сообщение будет выдано если, например, для загрузки FI.exe не хватает оперативной памяти. Оператор

execlp(“nc”, “nc”,NULL)

передает управление программе Norton Commander, если только путь к этой программе указан в переменной окружения PATH.

Оператор

execlp(“Excel”,”Excel”,”Tabl1.xls”)

запускает офисную программу Excel и передает в него файл Tabl.xls.

Мы рассмотрели только одну функцию execlp из целого семейства, включающего 8 подобных функций. Подробную информацию о них вы найдете в [1].

Рассмотренные функции могут найти достаточно ограниченное применение, поскольку они обеспечивают безвозвратную передачу управления из вызвавшего приложения в новое.

Вызов внешней программы функцией spawnlp

Функция spawnlp подобна рассмотренной выше функции execlp, но обладает более широкими возможностями. В частности, после выполнения внешнего приложения она возвращает управление исходному процессу.

Она и используемые в ней константы описаны в файлах process.h и stdio.h. Объявление функции:

int spawnlp(int mode, char *path, char *arg0, arg1, ..., argn, NULL);

Функция spawnlp отличается от execlp наличием параметра mode, задающего режим выполнения приложения, запускаемого на выполнение. Этот параметр может, в частности, принимать следующие значения:

P_WAIT

Переводит родительский процесс в состояние ожидания, которое продолжается до тех пор, пока не закончится дочерний процесс

P_NOWAIT

Родительский процесс продолжает выполняться одновременно с дочерним

P_NOWAITO .

Аналогичен P_NOWAIT, но вызванный процесс выполняется в фоновом режиме, так что он не имеет доступа к клавиатуре

P_DETACH

Идентичен функции ececlp

Хорошим примером использования этой процедуры может служить вызов архиватора c целью удаления файла MyText.txt из собственного архива:

if (spawnlp(P_WAIT, ”arj”, ”arj”,”e MyArchive.arj MyText.txt”,NULL))

Showmessage(“Архиватор arj не запускается”)

else

{ Memo1->Clear;

Memo1->Lines->LoadFromFile(“MyText.txt”);

DeleteFile(“MyText.txt”);

}

В этом примере запускается архиватор arj, извлекающий из архива MyArcive.arj файл MyText.txt. Приложение ждет, пока программа arj закончит работу, затем загружает разархивированный файл в окно редактирования Memol и удаляет этот файл с диска.

Операции, подобные рассмотренным выше, невозможно было бы выполнить функцией execlp, поскольку она не обеспечивает возвращение в исходное приложение. Нельзя было бы выполнить эти операции и функцией spawnlp при режиме, отличном от P_WAIT, поскольку в этом случае оператор загрузки файла в окно редактирования выполнялся бы раньше, чем успевал распаковываться архив.

Функция spawnlp принадлежит к целому семейству, включающему 8 подобных функций, ознакомиться с остальными вариантами можно по справочному файлу системы Builder.

Вызов внешней программы функцией WinExec

Функция WinExec, в отличие от описанных в предыдущих разделах, позволяет управлять формой представления окна запускаемого приложения. Эта функция может работать в любых версиях Windows и выполнять любые файлы: приложения Windows. Функция WinExec опре­деляется следующим образом:

int WinExec(const char *CmdLine, unsigned int CmdShow);

Параметр CmdLine является указателем на строку с нулевым символом в конце, содержащую имя выполняемого файла и, если необходимо, параметры командной строки. Если имя файла указано без пути, то Windows будет искать выполняемый файл в каталогах в следующей последовательности:

1. Каталог, из которого загружено приложение.

2. Текущий каталог.

3. Системный каталог Windows, возвращаемый функцией GetSystemDirectory.

4. Каталог Windows, возвращаемый функцией GetWindowsDirectory.

5. Список каталогов из переменной окружения PATH.

Параметр CmdShow определяет форму представления окна запускаемого приложения Windows. Чаще всего используется значение SW_RESTORE (восстановить), при котором окно запускаемого приложения активизируется и отображается на экране. При успешном выполнении запуска приложения функция WinExec возвращает значение, большее 31. При неудаче могут возвращаться следующие значения:

Возвращаемое значение

Описание

0

Не хватает памяти

ERROR_BAD_FORMAT

Неправильный формат выполняемого exe-файла

ERROR_FILE_NOTFOUND

Файл не найден

ERROR_PATH_NOTFOUND

Каталог не найден

Достоинством функции WinExec является ее совместимость с ранними версиями Windows.

Например, оператор

WinExec(“NotePad.exe”,SW_RESTORE);

запускает программу NotePad (блокнот).

В заключение приведем пример процедуры, обеспечивающей выполнение любой выбранной пользователем программы. Откройте новый проект и разместите на форме компонент OpenDialog, задав в нем фильтр

программы

*.exe;*.com

все файлы

*.*

Разместите на форме кнопку Button (назовите её bЕхес), при щелчке на которой пользователь может выбрать в окне «Открыть файл» программу и выполнить ее. Обработчик события OnClick этой кнопки может иметь вид:

int n;

if (OpenDialog1->Execute())

{ n=WinExec(OpenDialog->FileName.c_str(),SW_REStORE)

switch (n)

{case 0:

ShowMesage(“Не хватает памяти”);

break;

case ERROR_BAD_FORMAT:

ShowMesage(“Неправильный формат выполняемого exe-файла”);

break;

case ERROR_PATH_NOTFOUND:

ShowMesage(“Каталог не найден”);

break;

case ERROR_FILE_NOTFOUND:

ShowMesage(“Файл не найден”);

}//конец оператора case и switch

}//конец оператора if

Вызов внешней программы и открытие документа функцией ShellExecute

Процедура ShellExecute обладает более широкими возможностями по сравнению с функцией WinExec. Она может не только выполнять заданное приложение, но и открывать документ и печатать его. Под термином «открыть файл документа» понимается выполнение связанного с ним приложения и загрузка в него этого документа. Например, обычно с документами, имеющими расширение .doc, связан Word. В этом случае открыть файл, например, с именем file.doc означает запустить Word и передать ему в качестве параметра имя файла file.doc. Кроме описанных возможностей функция ShellExecute позволяет открыть указанную папку. Это означает, что будет запущена программа «Проводник» с открытой указанной папкой.

Для использования функции ShellExecute в модуль надо добавить директиву препроцессора

#include “ShellAPI.h”

подключающую модуль ShellAPI, в котором описана функция. Автоматически Builder эту директиву не добавляет.

Процедура ShellExecute определена следующим образом:

viod ShellExecute(HWND, const char *Operation, const char *FileName,

const char *Parameters, const char *Directory, unsigned int ShowCmd);

Параметр HWND является дескриптором родительского окна, в котором отображаются сообщения запускаемого приложения. Обычно в качестве него можно просто указать Handle (дескриптор).

Параметр Operation указывает на строку с нулевым символом в конце, которая определяет выполняемую операцию. Эта строка может содержать текст «open» (открыть) или «print» (напечатать). Если параметр Operation равен NULL, то по умолчанию выполняется операция «open».

Параметр FileName указывает на строку с нулевым символом в конце, которая определяет имя открываемого файла или имя открываемой папки.

Параметр Parameters указывает на строку с нулевым символом в конце, которая определяет передаваемые в приложение параметры, если FileName определяет выполняемый файл. Если FileName указывает на строку, определяющую открываемый документ или папку, то этот параметр задается равным NULL.

Параметр Directory указывает на строку с нулевым символом в конце, которая определяет каталог по умолчанию.

Параметр ShowCmd определяет режим открытия указанного файла. Этот параметр может иметь множество различных значений. Обычно, как и для функции WinExec, используется значение SW_RESTORE, при котором окно запускаемого приложения активизируется и отображается на экране.

Приведем примеры использования функции ShellExecute.

Пусть вы хотите открыть файл документа с именем file.doc, т.е. запустить WinWord (обычно именно он связан с файлами .doc), загрузив в него указанный файл. Тогда вы можете написать:

ShellExecute(Handle, NULL, “file.doc”, NULL, NULL,SW_RESTORE);

Если вы хотите не открыть, а напечатать документ, записываются аналогичные операторы, но изме­няется значение параметра Operation:

ShellExecute(Handle, “print”, “file.doc”, NULL, NULL,SW_RESTORE);

Выполнение этого оператора будет протекать следующим образом. Запустится Winword, связанный с файлами .doc, в него загрузится файл file.doc, затем из Winword запустится печать с атрибутами по умолчанию, после чего файл file.doc выгрузится из Winword.

Функция ShellExecute не возвращает никакого значения. Если при вызове функции произошла ошибка, то ее можно узнать, вызвав функцию GetLastError:

Эта функция возвращает нуль, если ShellExecute выполнена нормально. В противном случае возвращаются коды ошибок.

Вопросы для самопроверки

  1. Типы звуковых файлов.

  2. Воспроизведение звука отдельного щелчка.

  3. Воспроизведение мелодии с помощью API- функции PlaySound.

  4. Воспроизведение мелодии с помощью компонента MediaPlayer.

  5. Приведите интерфейс элементарного медиаплеера и поясните роль необходимых для его организации компонентов.

  6. В чем заключается понятие API Windows? Каким образом в общем виде строится вызов API-функций?

  7. Каким образом визуальные приемы программирования в среде C++Builder связаны с API Windows?

  8. Каким образом из приложения может быть запущен другой процесс (другая программа)? Какие действия при этом совершает компьютер?

  9. Приведите наиболее распространённые команды API для вызова других приложений.