Предыдущая Оглавление

Применение COM-объектов, входящих в состав Windows

Создание ярлыков

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

Использование Internet Explorer в приложениях

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

Предыдущая Оглавление