Как известно, ссылки для запуска приложений сохраняются в соответствующих директориях в виде ярлыков (Shortcuts) - файлов с расширением *.lnk. Это двоичные файлы, имеющие достаточно сложную структуру. Для их создания в Windows 3.x использовался динамический обмен данными - DDE (Dynamic Data Exchange) с приложением Program Manager, которое всегда запущено при работе Windows 3.1/З.11. Для создания такого файла в Windows 95 можно также использовать динамический обмен данными с Program Manager, но для этого его нужно обязательно предварительно запустить (например, набрав Progman после команды Run главного меню); в противном случае команды DDE не станут выполняться. Кроме того, компанией Microsoft было объявлено о недопустимости использования DDE при создании новых приложений; поддержка динамического обмена данными сохраняется только с целью обеспечения работоспособности ранее созданных приложений.
Конечно, можно создать ярлык непосредственно с помощью записи двоичных данных, однако для этой цели необходимо знать формат такого файла. Вместо этого можно воспользоваться тем, что программный интерфейс Microsoft Shell API полностью базируется на СОМ-технологии.
Приведем простейший пример, в котором используется этот факт. Создадим обычное консольное приложение, создающее ярлык на это же самое приложение на Рабочем столе Windows:
#include <shlobj.h> #include <string.h> HRESULT CreateLink (LPCSTR lpszPathObj, LPCSTR lpszPathLink, LPCSTR lpszDesc) { HRESULT hres; IShellLink *psl; // Получить указатель на интерфейс IShellLink hres = CoCreateInstance (CLSID_ShellLink, NULL, CLSCTX_INPROC_SERVER, IID_IShellLink, (LPVOID *) &psl); if (SUCCEEDED (hres)) { IPersistFile *ppf; // Установить путь к ярлыку и добавить описание psl->SetPath (lpszPathObj); psl->SetDescription (lpszDesc); // Преобразовать IShellLink в IPersistFile для сохранения ярлыка hres = psl->QueryInterface (IID_IPersistFile, (LPVOID *) &ppf); if (SUCCEEDED (hres)) { WCHAR wsz[MAX_PATH]; // Преобразовать строку в Unicode MultiByteToWideChar (CP_ACP, 0, lpszPathLink, -1, wsz, MAX_PATH); // Сохранить ярлык вызовом IPersistFile::Save. hres = ppf->Save (wsz, TRUE); ppf->Release (); } psl->Release (); } return hres; } int main (int argc, char *argv[]) { LPITEMIDLIST P; char szLink[512] = ""; // Инициализация библиотеки COM CoInitialize (NULL); // Получить путь к Рабочему столу if (SHGetSpecialFolderLocation (NULL, CSIDL_DESKTOP, &P) == NOERROR) { // Преобразовать путь к строке SHGetPathFromIDList (P, szLink); strcat (szLink, "\\Program.lnk"); // Создать ярлык CreateLink (argv[0], szLink, "Link"); } // Закрытие библиотеки COM CoUninitialize (); return 0; }
При выполнении этого кода сначала инициализируется библиотека СОМ и определяется путь к Рабочему столу. Создается COM-объект, который поддерживает несколько стандартных СОМ-интерфейсов, в частности IShellLink и IPersistFile. В интерфейсе IShellLink следует определить ряд параметров - путь и имя исполняемого файла, а также описание. Можно также определить некоторые необязательные параметры, например выбрать другую пиктограмму для ярлыка или указать, в каком состоянии должно быть при запуске главное окно приложения - в минимизированном, максимизированном или нормальном.
Интерфейс IPersistFile служит для запоминания или считывания файла *.lnk. В качестве параметра он использует один из стандартных каталогов Windows - Desktop, Program Files и др.
Обратите внимание на то, что никогда не следует указывать имена этих каталогов в явном виде - в различных языковых версиях Windows они могут быть различными! Например, каталогу Main Menu/Program Files английской версии Windows соответствует каталог "Главное меню/Программы" в соответствующей русской версии Windows. Следует также помнить, что имена, присваиваемые по умолчанию при установке Windows всем специальным каталогам, могут быть впоследствии изменены.
По этой причине необходимо использовать метод SHGetSpecialFolderLocation и вслед за ним SHGetPathFromIDList для получения физического адреса специальных каталогов. Эти методы вместе со списком констант, определяющих тип специальных каталогов, приведены в файле shlobj.h.
Microsoft Internet Explorer является СОМ-сервером, поэтому его можно использовать в своих приложениях. Поскольку начиная с версии Windows 95 OSR/2 он стал частью операционной системы, при его использовании в данной операционной системе нет необходимости добавлять в дистрибутив какие-либо модули.
Для использования Internet Explorer в приложении необходимо выбрать элемент управления TCppWebBrowser со страницы Internet. После этого элемент управления можно поместить на форму и сделать его размер достаточно большим.
Полученный элемент управления полностью идентичен по возможностям приложению Microsoft Internet Explorer: он показывает гипертекст, графику, имеет виртуальную Java-машину, что позволяет применять скрипты и апплеты; он также поддерживает работу других элементов управления v ActiveX, использующих его как контейнер. Главные его методы - Navigate, Forward, GoBack, Search, Stop и другие - соответствуют командам, доступным в приложении Microsoft Internet Explorer. Из полезных нотификационных сообщений следует отметить OnStatusTextChange, которое вызывается при необходимости поместить текст в строку состояния, и OnProgressChange, которое можно использовать для индикации состояния какого-либо процесса (например, загрузки содержимого). На форму нанесены кнопки: "Navigate", "Stop", "Previous", "Next", "Refresh", "Search" и Ëxplore", а также элементы: ComboBox, ProgressBar и StatusBar. Код для тестирования элемента управления ActiveX TCppWebBrowser приведен ниже:
// кнопка Navigate void __fastcall TForm1::Button1Click(TObject *Sender) { OleVariant Flags, TargetFrameName, PostData, Headers; BSTR AD; AnsiString S; int N; S = ComboBox1->Text; N = ComboBox1->Items->IndexOf (S); if (N < 0) { if (ComboBox1->Items->Count == 0) { ComboBox1->Items->Add (S); } else { ComboBox1->Items->Insert (0, S); } } else { ComboBox1->Items->Exchange (0, N); } ComboBox1->Text = S; AD = WideString(S); CppWebBrowser1->Navigate (AD, Flags, TargetFrameName, PostData, Headers); } // кнопка Stop void __fastcall TForm1::Button2Click(TObject *Sender) { CppWebBrowser1->Stop (); } // кнопка Previous void __fastcall TForm1::Button3Click(TObject *Sender) { CppWebBrowser1->GoBack (); } // кнопка Next void __fastcall TForm1::Button4Click(TObject *Sender) { CppWebBrowser1->GoForward (); } // кнопка Refresh void __fastcall TForm1::Button5Click(TObject *Sender) { CppWebBrowser1->Refresh (); } void __fastcall TForm1::CppWebBrowser1StatusTextChange(TObject *Sender, BSTR URL) { StatusBar1->SimpleText = Text; } void __fastcall TForm1::CppWebBrowser1ProgressChange(TObject *Sender, long Progress, long ProgressMax) { ProgressBar1->Position = 100 * Progress / (ProgressMax + 1); }
При запуске данного приложения получаем полноценный Web-браузер.
Из других полезных свойств следует отметить свойство Documents, которое объявлено как IDispatch. При использовании этого свойства можно получить информацию о последней полученной HTML-странице (ее текстовое содержание, какие команды встречались в гипертексте и т. д.) Вся эта информация не показывается пользователю Internet Explorer, но может быть полезной для программиста. Например, вместо того чтобы создавать свой интерпретатор гипертекста, можно просто воспользоваться данными возможностями.
Свойство Documents в том виде, как оно определено, практически бесполезно, так как неизвестны команды для интерфейса IDispatch. Но имеется вспомогательная библиотека, которая детально расшифровывает методы и свойства объектов, входящих в коллекцию Documents. Для извлечения информации о гипертексте необходимо иметь Microsoft Internet Explorer версии 4.0 или старше.
Для начала к проекту необходимо добавить библиотеку типов Internet Explorer Scripting Object Model, которая определена в модуле MSHTML.DLL. Следует иметь в виду, что эта библиотека может быть не зарегистрирована как сервер и при выборе пункта меню C++Builder Project/Import Type Library она будет отсутствовать в списке предлагаемых библиотек. В этом случае нужно зарегистрировать ее.