Как известно, ссылки для запуска приложений сохраняются в соответствующих директориях в виде ярлыков (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 она будет отсутствовать в списке предлагаемых библиотек. В этом случае нужно зарегистрировать ее.