Электронная библиотека книг Александра Фролова и Григория Фролова.
Shop2You.ru Создайте свой интернет-магазин
Библиотека
Братьев
Фроловых

Разработка приложений для Internet

© Александр Фролов, Григорий Фролов
Том 31, М.: Диалог-МИФИ, 1997, 286 стр.

[Назад] [Содеожание] [Дальше]

Приложение Look

Воспользуйтесь MFC AppWizard и создайте приложение Look, пользовательский интерфейс которого основан на диалоговой панели. Для этого выберите из меню File строку New. На экране появится диалоговая панель New. Выберите из списка в этой панели строку Project Workspace и нажмите на кнопку OK. Теперь на экране откроется диалоговая панель New Project Workspace. В ней вы должны выбрать тип проекта и его название. Чтобы воспользоваться средствами автоматизированной разработки приложений выберите из списка типов проектов Type строку MFC AppWizard (exe). В поле Name введите имя проекта Look. Нажмите кнопку Create.

Начнет работать MFC AppWizard. Вам будет предложено заполнить несколько диалоговых панелей MFC AppWizard, в которых определяются свойства создаваемого приложения. В первой такой панели, которая называется MFC AppWizard - Step 1, выберите тип пользовательского интерфейса для приложения. Переключатель What type of application would you like to create переведите в положение Dialog based. Нажмите кнопку Next. На экране появится следующая диалоговая панель MFC AppWizard - Step 2 of 4. В группе What OLE support would you like to include этой панели вы должны включить переключатель OLE controls.

¨     Если вы работаете в Microsoft Visual C++ версии 5.0, вы должны иметь в виду, что в диалоговой панели MFC AppWizard - Step 2 of 4 изменились названия некоторых полей и переключателей. Это связано с тем, что технология OLE стала именоваться как ActiveX. Так группа What OLE support would you like to include стала называться What ActiveX support would you like to include

Все остальные параметры приложения можно оставить по умолчанию и нажать на кнопку Finish. На экране появится панель New Project Information, содержащая список свойств создаваемого приложения. Нажмите кнопку OK и MFC AppWizard создаст для вас проект Look.

Теперь надо добавить к проекту орган управления Microsoft Web Browser Control, с помощью которого приложение Look будет обмениваться данными с Internet.

Выберите из меню Insert строку Component. На экране появится диалоговая панель Component Gallery. Откройте страницу OLE Controls этой панели (рис. 4.2). На странице OLE Controls представлены органы управления OCX, которые вы можете использовать в ваших приложениях.

Рис. 4.2. Диалоговая панель Component Gallery

Среди органов управления, представленных на странице OLE Controls в диалоговой панели Component Gallery, выберите орган управления Microsoft Web Browser Control. Для большинства органов управления, представленных в панели Component Gallery, можно получить их описание. Для этого достаточно нажать кнопку ?. К сожалению, при выборе пиктограммы Microsoft Web Browser Control, кнопка ? остается заблокированной.

Когда вы устанавливаете Internet Explorer, орган управления ActiveX подключается к операционной системе. Microsoft Visual C++ обнаруживает установленные органы ActiveX и позволяет использовать их в своих приложениях. Фактически программный код органа управления ActiveX расположен в файле Shdocvw.dll, который вы можете обнаружить в системном каталоге Windows.

¨     Если вы используете Microsoft Visual C++ более ранней версии, чем 5.0, вы можете получить информацию об органе управления Microsoft Web Browser Control можно на WWW-сервере компании Microsoft, по адресу http://www.microsoft.com в документе Web Browsing Objects for C/C++ Developers. Начиная с версии 5.0 соответствующее описание включено в документацию Microsoft Visual C++.

Орган управления Microsoft Web Browser Control предоставляет возможность просмотра WWW страниц.

Для добавления к проекту органа управления Microsoft Web Browser Control нажмите кнопку Insert, после того как вы выберите соответствующую пиктограмму. На экране появится диалоговая панель Confirm Classes (рис. 4.3).

Список классов, которые будут созданы для работы с органом управления Microsoft Web Browser Control содержит название только одного класса - CWebBrowser. Обратите внимание на то, что переключатель отображаемый перед названием класса CWebBrowser должен быть включен.

В поле Class name отображается имя выбранного класса. Вы можете изменить его по своему усмотрению. Имя базового класса для класса CWebBrowser отображается в поле Base class. Данное поле выполняет исключительно информационные функции, так как изменить имя базового класса в панели Confirm Classes невозможно. В качестве базового класса для CWebBrowser выступает класс CWnd.

Имена включаемого файла и файла реализации, в которых будут помещены определение класса CWebBrowser и его методов, отображаются в полях Headr file и Implementation file. По умолчанию используются имена файлов WebBrowser.h и WebBrowser.cpp. В случае необходимости вы можете указать для этих файлов другие имена.

Рис. 4.3. Диалоговая панель Confirm Classes

Когда все поля диалоговой панели Confirm Classes заполнены, нажмите кнопку OK. Для нашего приложения мы оставили имя класса органа управления Microsoft Web Browser Control, а также имена включаемого файла и файла реализации без изменения.

После того, как вы добавите в проект орган управления Microsoft Web Browser, просмотрите список входящих в него файлов. Для этого откройте окно Project Workspace и перейдите на страницу FileView (рис. 4.4).

Рис. 4.4. Исходные файлы приложения Look

В проект будет добавлен класс CWebBrowser, представленный файлами WebBrowser.h и WebBrowser.cpp. Полный список классов приложения Look можно посмотреть в окне Project Workspace на странице ClassView (рис. 4.5). Мы не стали раскрывать на рисунке содержимое классов, так как класс CWebBrowser включает в себя слишком много методов.

Рис. 4.5. Классы приложения Look

В состав проекта Look входят всего три класса, коротко описанные в следующей таблице.

Класс

Описание

CLookApp

Главный класс приложения Look

CLookDlg

Класс, управляющий диалоговой панелью приложения

CWebBrowser

Класс органа управления Microsoft Web Browser Control

Класс CLookApp

Главный класс приложения CLookApp, наследованный от базового класса CWinApp, определен во включаемом файле Look.h. Исходный текст этого файла представлен в листинге 4.1. Фактически в классе CLookApp определен только конструктор класса и переопределен метод InitInstance базового класса CWinApp.

Листинг 4.1. Файл Look.h


#ifndef __AFXWIN_H__
   #error include 'stdafx.h' before including this file for PCH
#endif

#include "resource.h"   

//////////////////////////////////////////////////////////////
// Определение класса CLookApp
//

class CLookApp : public CWinApp
{
public:
   CLookApp();

// Overrides
   //{{AFX_VIRTUAL(CLookApp)
   public:
   virtual BOOL InitInstance();
   //}}AFX_VIRTUAL

// Implementation

   //{{AFX_MSG(CLookApp)
   //}}AFX_MSG
   DECLARE_MESSAGE_MAP()
};

//////////////////////////////////////////////////////////////

Реализация класса CLookApp содержится в файле Look.cpp (листинг 4.2). В нем определены конструктор класса CLookApp, метод InitInstance и таблица сообщений класса CLookApp. Кроме того, в файле Look.cpp объявлен глобальный объект theApp главного класса приложения CLookApp.

Листинг 4.2. Файл Look.cpp


#include "stdafx.h"
#include "Look.h"
#include "LookDlg.h"

#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif

//////////////////////////////////////////////////////////////
// Таблица сообщений класса CLookApp

BEGIN_MESSAGE_MAP(CLookApp, CWinApp)
   //{{AFX_MSG_MAP(CLookApp)
      //    DO NOT EDIT 
   //}}AFX_MSG
   ON_COMMAND(ID_HELP, CWinApp::OnHelp)
END_MESSAGE_MAP()

//////////////////////////////////////////////////////////////
// Конструктор класса CLookApp 

CLookApp::CLookApp()
{
   // TODO: add construction code here,
   // Place all significant initialization in InitInstance
}

//////////////////////////////////////////////////////////////
// Объект глаавного класса приложения

CLookApp theApp;

//////////////////////////////////////////////////////////////
// Метод InitInstance класса CLookApp. 
// Выполняет инициализацию приложения

BOOL CLookApp::InitInstance()
{
   // Разрешаем использование органов управления ActiveX
   AfxEnableControlContainer();

   // Выполняем стандартную инициализацию
#ifdef _AFXDLL
   Enable3dControls(); 
#else
   Enable3dControlsStatic();   
#endif

   // Отображаем на экране диалоговую панель приложения
   CLookDlg dlg;
   m_pMainWnd = &dlg;
   int nResponse = dlg.DoModal();
   if (nResponse == IDOK)
   {
      // TODO: Нажата клавиша OK
   }
   else if (nResponse == IDCANCEL)
   {
      // TODO: Нажата клавиша Cancel
   }

   return FALSE;
}

Класс CWebBrowser

Определение класса CWebBrowser расположено в файле webbrowser.h, исходный текст которого представлен в листинге 4.1. Методы GetClsid и Create определены непосредственно в самом классе CWebBrowser. Остальные методы класса CWebBrowser определены в файле webbrowser.cpp, содержащимся в листинге 4.3. Мы оставили комментарии на английском языке, которые были добавлены во время вставки Microsoft Web Browser Control в проект.

Листинг 4.3. Файл webbrowser.h


#ifndef __WEBBROWSER_H__
#define __WEBBROWSER_H__

// Machine generated IDispatch wrapper class(es) created by 
// Microsoft Visual C++

// NOTE: Do not modify the contents of this file.  If this 
// class is regenerated by Microsoft Visual C++, your 
// modifications will be overwritten. 

//////////////////////////////////////////////////////////////
// CWebBrowser wrapper class

class CWebBrowser : public CWnd
{
protected:
   DECLARE_DYNCREATE(CWebBrowser)
public:
   CLSID const& GetClsid()
   {
      static CLSID const clsid
         = { 0xeab22ac3, 0x30c1, 0x11cf, 
             { 0xa7, 0xeb, 0x0, 0x0, 0xc0, 0x5b, 0xae, 0xb }
           };
      return clsid;
   }

   virtual BOOL Create(
      LPCTSTR lpszClassName,
      LPCTSTR lpszWindowName, DWORD dwStyle,
      const RECT& rect,
      CWnd* pParentWnd, UINT nID,
      CCreateContext* pContext = NULL)
   { 
      return CreateControl(
         GetClsid(), 
         lpszWindowName, 
         dwStyle, 
         rect, 
         pParentWnd, 
         nID); 
   }

   BOOL Create(LPCTSTR lpszWindowName, DWORD dwStyle,
      const RECT& rect, CWnd* pParentWnd, UINT nID,
      CFile* pPersist = NULL, BOOL bStorage = FALSE,
      BSTR bstrLicKey = NULL)
   { 
      return CreateControl(
         GetClsid(), 
         lpszWindowName, 
         dwStyle, 
         rect, 
         pParentWnd, 
         nID,
         pPersist, 
         bStorage, 
         bstrLicKey); 
   }

// Operations
public:
   // method 'QueryInterface' not emitted because of invalid 
   // return type or parameter type
   unsigned long AddRef();
   unsigned long Release();
   // method 'GetTypeInfoCount' not emitted because of invalid 
   // return type or parameter type
   // method 'GetTypeInfo' not emitted because of invalid 
   // return type or parameter type
   // method 'GetIDsOfNames' not emitted because of invalid 
   // return type or parameter type
   // method 'Invoke' not emitted because of invalid return 
   // type or parameter type
   void GoBack(); 
   void GoForward();
   void GoHome();
   void GoSearch();
   void Navigate(
      LPCTSTR URL, VARIANT* Flags, VARIANT* TargetFrameName, 
      VARIANT* PostData, VARIANT* Headers);
   void Refresh();
   void Refresh2(VARIANT* Level);
   void Stop();
   LPDISPATCH GetApplication();
   LPDISPATCH GetParent();
   LPDISPATCH GetContainer();
   LPDISPATCH GetDocument();
   BOOL GetTopLevelContainer();
   CString GetType();
   long GetLeft();
   void SetLeft(long nNewValue);
   long GetTop();
   void SetTop(long nNewValue);
   long GetWidth();
   void SetWidth(long nNewValue);
   long GetHeight();
   void SetHeight(long nNewValue);
   CString GetLocationName();
   CString GetLocationURL();
   BOOL GetBusy();
};

#endif // __WEBBROWSER_H__

Не рекомендуется вносить изменения в исходные тексты класса CWebBrowser и тексты его методов, расположенные в файлах webbrowser.h и webbrowser.cpp. Эти файлы могут быть созданы Microsoft Visual C++ заново, если вы повторно вставите орган управления Microsoft Web Browser в проект. В этом случае все изменения, внесенные вами в файлы webbrowser.h и webbrowser.cpp будут уничтожены.

Если у вас все же возникнет необходимость модифицировать класс CWebBrowser, создайте новый класс, порожденный от класса CWebBrowser и используйте его.

¨     Когда вы добавляете в проект орган управления Microsoft Web Browser Control, в файле определения класса отмечается, что ряд методов (QueryInterface, AddRef, Release, GetTypeInfoCount, GetTypeInfo, GetIDsOfNames, Invoke) не подключены, так как они имеют неправильный тип возвращаемого значения или неправильный тип параметров. В случае если вы пользуетесь Microsoft Visual C++ версии 5.0 эти сообщения не появляются, но перечисленные методы также не будут доступны

Все методы класса CWebBrowser, за исключением метода GetClsid и двух модификаций метода Create, определены в файле webbrowser.cpp. Исходный текст этого файла представлен в листинге 4.4. Методы GetClsid и Create определены непосредственно в описании класса CWebBrowser (листинг 4.3).

Листинг 4.4. Файл webbrowser.cpp


// Machine generated IDispatch wrapper class(es) created by 
// Microsoft Visual C++

// NOTE: Do not modify the contents of this file.  If this 
// class is regenerated by Microsoft Visual C++, your 
// modifications will be overwritten.

#include "stdafx.h"
#include "webbrowser.h"

//////////////////////////////////////////////////////////////
// CWebBrowser

IMPLEMENT_DYNCREATE(CWebBrowser, CWnd)

//////////////////////////////////////////////////////////////
// CWebBrowser properties

//////////////////////////////////////////////////////////////
// CWebBrowser operations

unsigned long CWebBrowser::AddRef()
{
   unsigned long result;
   InvokeHelper(0x60000001, DISPATCH_METHOD, VT_I4,
      (void*)&result, NULL);
   return result;
}

unsigned long CWebBrowser::Release()
{
   unsigned long result;
   InvokeHelper(0x60000002, DISPATCH_METHOD, VT_I4, 
      (void*)&result, NULL);
   return result;
}

void CWebBrowser::GoBack()
{
   InvokeHelper(0x64, DISPATCH_METHOD, VT_EMPTY, NULL, NULL);
}

void CWebBrowser::GoForward()
{
   InvokeHelper(0x65, DISPATCH_METHOD, VT_EMPTY, NULL, NULL);
}

void CWebBrowser::GoHome()
{
   InvokeHelper(0x66, DISPATCH_METHOD, VT_EMPTY, NULL, NULL);
}

void CWebBrowser::GoSearch()
{
   InvokeHelper(0x67, DISPATCH_METHOD, VT_EMPTY, NULL, NULL);
}

void CWebBrowser::Navigate(
   LPCTSTR URL, 
   VARIANT* Flags, 
   VARIANT* TargetFrameName, 
   VARIANT* PostData, 
   VARIANT* Headers)
{
   static BYTE parms[] =
      VTS_BSTR VTS_PVARIANT VTS_PVARIANT 
      VTS_PVARIANT VTS_PVARIANT;
   InvokeHelper(0x68, DISPATCH_METHOD, VT_EMPTY, NULL, parms,
       URL, Flags, TargetFrameName, PostData, Headers);
}

void CWebBrowser::Refresh()
{
   InvokeHelper(DISPID_REFRESH, DISPATCH_METHOD, VT_EMPTY, 
      NULL, NULL);
}

void CWebBrowser::Refresh2(VARIANT* Level)
{
   static BYTE parms[] = VTS_PVARIANT;
   InvokeHelper(0x69, DISPATCH_METHOD, VT_EMPTY, NULL, parms,
      Level);
}

void CWebBrowser::Stop()
{
   InvokeHelper(0x6a, DISPATCH_METHOD, VT_EMPTY, NULL, NULL);
}

LPDISPATCH CWebBrowser::GetApplication()
{
   LPDISPATCH result;
   InvokeHelper(0xc8, DISPATCH_PROPERTYGET, VT_DISPATCH, 
      (void*)&result, NULL);
   return result;
}

LPDISPATCH CWebBrowser::GetParent()
{
   LPDISPATCH result;
   InvokeHelper(0xc9, DISPATCH_PROPERTYGET, VT_DISPATCH, 
      (void*)&result, NULL);
   return result;
}

LPDISPATCH CWebBrowser::GetContainer()
{
   LPDISPATCH result;
   InvokeHelper(0xca, DISPATCH_PROPERTYGET, VT_DISPATCH, 
      (void*)&result, NULL);
   return result;
}

LPDISPATCH CWebBrowser::GetDocument()
{
   LPDISPATCH result;
   InvokeHelper(0xcb, DISPATCH_PROPERTYGET, VT_DISPATCH, 
      (void*)&result, NULL);
   return result;
}

BOOL CWebBrowser::GetTopLevelContainer()
{
   BOOL result;
   InvokeHelper(0xcc, DISPATCH_PROPERTYGET, VT_BOOL, 
      (void*)&result, NULL);
   return result;
}

CString CWebBrowser::GetType()
{
   CString result;
   InvokeHelper(0xcd, DISPATCH_PROPERTYGET, VT_BSTR, 
      (void*)&result, NULL);
   return result;
}

long CWebBrowser::GetLeft()
{
   long result;
   InvokeHelper(0xce, DISPATCH_PROPERTYGET, VT_I4, 
      (void*)&result, NULL);
   return result;
}

void CWebBrowser::SetLeft(long nNewValue)
{
   static BYTE parms[] = VTS_I4;
   InvokeHelper(0xce, DISPATCH_PROPERTYPUT, VT_EMPTY, NULL, 
      parms, nNewValue);
}

long CWebBrowser::GetTop()
{
   long result;
   InvokeHelper(0xcf, DISPATCH_PROPERTYGET, VT_I4, 
      (void*)&result, NULL);
   return result;
}

void CWebBrowser::SetTop(long nNewValue)
{
   static BYTE parms[] = VTS_I4;
   InvokeHelper(0xcf, DISPATCH_PROPERTYPUT, VT_EMPTY, NULL, 
      parms, nNewValue);
}

long CWebBrowser::GetWidth()
{
   long result;
   InvokeHelper(0xd0, DISPATCH_PROPERTYGET, VT_I4, 
      (void*)&result, NULL);
   return result;
}

void CWebBrowser::SetWidth(long nNewValue)
{
   static BYTE parms[] = VTS_I4;
   InvokeHelper(0xd0, DISPATCH_PROPERTYPUT, VT_EMPTY, NULL, 
   parms, nNewValue);
}

long CWebBrowser::GetHeight()
{
   long result;
   InvokeHelper(0xd1, DISPATCH_PROPERTYGET, VT_I4, 
      (void*)&result, NULL);
   return result;
}

void CWebBrowser::SetHeight(long nNewValue)
{
   static BYTE parms[] = VTS_I4;
   InvokeHelper(0xd1, DISPATCH_PROPERTYPUT, VT_EMPTY, NULL, 
   parms, nNewValue);
}

CString CWebBrowser::GetLocationName()
{
   CString result;
   InvokeHelper(0xd2, DISPATCH_PROPERTYGET, VT_BSTR, 
      (void*)&result, NULL);
   return result;
}

CString CWebBrowser::GetLocationURL()
{
   CString result;
   InvokeHelper(0xd3, DISPATCH_PROPERTYGET, VT_BSTR, 
      (void*)&result, NULL);
   return result;
}

BOOL CWebBrowser::GetBusy()
{
   BOOL result;
   InvokeHelper(0xd4, DISPATCH_PROPERTYGET, VT_BOOL, 
      (void*)&result, NULL);
   return result;
}

Все методы, определенные в файле webbrowser.cpp, вызывают вспомогательный метод InvokeHelper класса CWnd, передавая ему различные параметры. В зависимости от своих параметров, метод InvokeHelper, в свою очередь, вызывает те или иные методы органа управления ActiveX. В нашем случае в качестве этого органа управления выступает Microsoft Web Browser Control.

Подробное описание Microsoft Web Browser Control, включая описание управляющего класса, смотрите на странице http://www.microsoft.com сервера WWW компании Microsoft. В следующей таблице мы дадим краткое описание основных методов класса CWebBrowser:

Метод

Описание

GetBusy

Позволяет узнать, выполняет ли орган управления Microsoft Web Browser Control в данный момент времени загрузку данных из Internet

GetHeight

Определяет вертикальный размер окна (frame window), содержащего орган управления Web Browser

GetLeft

Определяет расстояние между внутренней левой стороной органа управления Web Browser и левой стороной его контейнера (содержащего его окна)

GetLocationName

Определяет имя ресурса Internet, который отображается органом управления Microsoft Web Browser Control

GetLocationURL

Определяет URL имя ресурса Internet, который отображается органом управления Microsoft Web Browser Control

GetTop

Определяет расстояние между внутренней верхней стороной органа управления Web Browser и верхней стороной его контейнера

GetWidth

Определяет горизонтальный размер окна (frame window), содержащего орган управления Web Browser

GoBack

Вернуться к просмотру предыдущей страницы WWW

GoForward

Перейти к просмотру следующей страницы WWW. Этот метод можно использовать, если вы вернулись к просмотру предыдущей страницы WWW с помощью метода GoBack

GoHome

Перейти к просмотру домашней страницы WWW. Адрес домашней страницы Microsoft Internet Explorer можно изменить через панель управления Control Panel, запустив приложение Internet. Приложение Internet отображает на экране диалоговую панель Internet Properties. В ней надо выбрать страницу Navigation, а затем выбрать из списка Page строку Start Page (начальная или домашняя страница) и ввести ее адрес в поле Address

GoSearch

Перейти к просмотру поисковой страницы WWW. Адрес поисковой страницы Microsoft Internet Explorer можно изменить через панель управления Control Panel, запустив приложение Internet

Navigate

Перейти к просмотру страницы WWW с заданным адресом. Именно этот метод мы будем использовать в приложении Look чтобы перейти к просмотру определенной страницы WWW

Refresh, Refresh2

Обновить информацию текущей страницы WWW

SetHeight

Устанавливает вертикальный размер окна (frame window), содержащего орган управления Web Browser

SetLeft

Устанавливает расстояние между внутренней левой стороной органа управления Web Browser и левой стороной его контейнера

SetTop

Устанавливает расстояние между внутренней верхней стороной органа управления Web Browser и верхней стороной его контейнера

SetWidth

Устанавливает горизонтальный размер окна (frame window), содержащего орган управления Web Browser

Stop

Остановить загрузку страницы WWW

Класс CWebBrowser, представляющий орган управления Microsoft Web Browser Control, также содержит целый ряд методов, которые вызываются в различных ситуациях. В следующей таблице мы привели список этих методов и дали им краткие описания.

Метод

Описание

BeforeNavigate

Вызывается когда навигатор переходит к просмотру другого URL

CommandStateChange

Выполнение определенных команд разрешено или запрещено

DownloadBegin

Началась загрузка ресурса

DownloadComplete

Загрузка ресурса завершается, останавливается или прерывается

FrameBeforeNavigate

Навигатор приступает к загрузке нового ресурса с другим адресом URL. Происходит, если на данной странице WWW присутствуют фреймы

FrameNavigateComplete

Вызывается после того, как навигатор загрузит новый ресурс.

FrameNewWindow

Создано новое окно. Происходит, если на данной странице WWW присутствуют фреймы

NavigateComplete

Навигатор успешно загрузил новый ресурс

NewWindow

Новое окно должно быть создано для отображения ресурсса

ProgressChange

Изменилось состояние процесса загрузки

Quit

Приложение Internet Explorer готово завершиться

StatusTextChange

Изменяется текст в панели состояния

TitleChange

Заголовок документа в окне навигатора получен или изменен

WindowActivate

Окно навигатора получило упраавление

WindowMove

Окно навигатора переместилось

WindowResize

Изменен размер окна навигатора

Орган управления Microsoft Web Browser

После того, как вы вставите орган управления Microsoft Web Browser в проект, он станет доступен в панели инструментов разработки диалоговых панелей. Выберите в окне Project Workspace страницу ResourceView (рис. 4.6). Как видите, приложение имеет три типа ресурсов - диалоговую панель IDD_LOOK_DIALOG, пиктограмму IDR_MAINFRAME и ресурс с описанием версии приложения VS_VERSION_INFO. Это стандартный набор ресурсов приложения с диалоговым интерфейсом, созданного при помощи MFC AppWizard.

Рис. 4.6. Ресурсы приложения Look

Загрузите в редактор ресурсов диалоговую панель IDD_LOOK_DIALOG приложения Look. Если панель инструментов Controls не появилась на экране, откройте ее. Для этого выберите из меню View главного окна Microsoft Visual C++ строку Toolbars. На экране появится диалоговая панель Toolbars (рис. 4.7). Найдите в списке Toolbars переключатель Controls и включите его. Затем нажмите кнопку Close.

Если в списке Toolbars вы не смогли обнаружить переключатель Controls, проверьте, загружена ли диалоговая панель в окно редактирования. Панели управления Microsoft Visual C++ являются контекстно-зависимыми. При работе с различными объектами доступны разные панели управления.

Рис. 4.7. Диалоговая панель Toolbars

Измените диалоговую панель приложения Look в соответствии с листингом 4.х. На рисунке 4.8 мы представили вид диалоговой панели IDD_LOOK_DIALOG в редакторе ресурсов.

Рис. 4.8. Диалоговая панель Look

В верхней части диалоговой панели IDD_LOOK_DIALOG поместите поле редактирования IDC_TITLE_BAR. В нем будет отображаться заголовок просматриваемой страницы WWW. Слева от поля редактирования поместите текстовую строку Title.

Непосредственно под полем IDC_TITLE_BAR разместите список IDC_COMBO_ADDRESS для выбора адреса URL. В списке Address введите адреса URL серверов WWW, которые можно посетить нашим навигатором. Мы использовали следующие адреса серверов:


\http://www.glasnet.ru/~frolov
http://www.dials.ccas.ru/frolov
http://www.microsoft.com/
http://www.dials.ccas.ru/

Первые два адреса из представленного списка, указывают на сервер WWW авторов этой книги. Третий адрес принадлежит компании Microsoft, а последний, четвертый адрес, - фирме АО “ДиалогНаука”.

Вы можете ввести в этом списке адреса других, известных вам серверов, которые вы желаете посетить с помощью навигатора Look. Конечно, жестко “зашивать” адреса серверов WWW в приложении плохо, но нашей задачей является не создание законченного приложения, а изучение органа управления Microsoft Web Browser.

В дальнейшем вы можете расширить приложение Look и хранить адреса серверов в базе данных, организовав к ней доступ через драйвер ODBC или интерфейс DAO. Пример работы с базами данных через драйвера ODBC с помощью классов MFC мы приводили в 28 томе серии “Библиотека системного программиста”.

Слева от списка IDC_COMBO_ADDRESS расположите текстовую строку Address. А справа разместите четыре кнопки Navigate, Refresh, Stop и Exit. Присвойте им соответственно идентификаторы IDC_NAVIGATE, IDC_BUTTON_REFRESH, IDC_BUTTON_STOP и IDOK.

Обратите внимание на органы управления, представленные в панели инструментов Controls. В ней появилась новая пиктограмма (рис. 4.9), которая и представляет Microsoft Web Browser Control. Если в диалоговой панели Toolbars установлен переключатель Show ToolTips, который включает режим кратких подсказок, и вы поместите на указатель мыши на пиктограмму , то через некоторое время появится название этого органа управления - Microsoft Web Browser.

Рис. 4.9. Панель инструментов Controls

Таким образом, вы можете разместить окно Microsoft Web Browser Control в обычной диалоговой панели точно также, как вы размещаете на ней текстовую строку, кнопку или переключатель. Поместите орган управления Microsoft Web Browser Control в центре диалоговой панели IDD_LOOK_DIALOG и присвойте ему идентификатор IDC_EXPLORER.

Как вы увидите позже, когда навигатор “Microsoft Web Browser Control” не отображает никакой информации, он имеет серый цвет и полностью сливается с самой диалоговой панелью. Чтобы выделить окно навигатора, создайте вокруг него группу с текстом World Wide Web. Эта группа будет отображаться как тонкая рамка с текстом в левом верхнем углу.

Непосредственно под навигатором IDC_EXPLORER разместите поле редактирования IDC_STATUS_TEXT, дополнительно обозначив его текстовой строкой Status и линейный индикатор IDC_PROGRESS с текстовой строкой Progress.

Поля редактирования IDC_TITLE_BAR и IDC_STATUS_TEXT будут использоваться только для отображения текста, поэтому вы можете указать для них в панели свойств атрибут Read-Only.

Файл ресурсов приложения Look представлен в листинге 4.5. В нем вы найдете шаблон диалоговой панели IDD_LOOK_DIALOG, команды для включения в ресурсы пиктограмм, информационный ресурс VS_VERSION_INFO и другие вспомогательные команды.

Листинг 4.5. Файл Look.rc


//Microsoft Developer Studio generated resource script.
//
#include "resource.h"

#define APSTUDIO_READONLY_SYMBOLS
//////////////////////////////////////////////////////////////
//
// Generated from the TEXTINCLUDE 2 resource.
//
#include "afxres.h"

//////////////////////////////////////////////////////////////
#undef APSTUDIO_READONLY_SYMBOLS

//////////////////////////////////////////////////////////////
// Русские ресурсы

#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_RUS)
   #ifdef _WIN32
      LANGUAGE LANG_RUSSIAN, SUBLANG_DEFAULT
      #pragma code_page(1251)
   #endif //_WIN32
#ifdef APSTUDIO_INVOKED

//////////////////////////////////////////////////////////////
//
// TEXTINCLUDE
//

1 TEXTINCLUDE DISCARDABLE 
BEGIN
    "resource.h\0"
END

2 TEXTINCLUDE DISCARDABLE 
BEGIN
    "#include ""afxres.h""\r\n"
    "\0"
END

3 TEXTINCLUDE DISCARDABLE 
BEGIN
    "#define _AFX_NO_SPLITTER_RESOURCES\r\n"
    "#define _AFX_NO_OLE_RESOURCES\r\n"
    "#define _AFX_NO_TRACKER_RESOURCES\r\n"
    "#define _AFX_NO_PROPERTY_RESOURCES\r\n"
    "\r\n"
    "#if !defined(AFX_RESOURCE_DLL) || 
        defined(AFX_TARG_ENU)\r\n"
    "#ifdef _WIN32\r\n"
    "LANGUAGE 9, 1\r\n"
    "#pragma code_page(1252)\r\n"
    "#endif\r\n"
    "#include ""res\\Look.rc2\r\n"
    "#include ""afxres.rc\r\n"
    "#endif\0"
END

#endif    // APSTUDIO_INVOKED

//////////////////////////////////////////////////////////////
//
// Пиктограмма приложения
//

IDR_MAINFRAME         ICON    DISCARDABLE     "res\\Look.ico"

//////////////////////////////////////////////////////////////
//
// Диалоговая панель IDD_LOOK_DIALOG
//

IDD_LOOK_DIALOG DIALOGEX 0, 0, 444, 253
STYLE DS_MODALFRAME | WS_POPUP | WS_VISIBLE | WS_CAPTION
EXSTYLE WS_EX_APPWINDOW
CAPTION "Look"
FONT 8, "MS Sans Serif"
BEGIN
    CONTROL         "",IDC_EXPLORER,
                    "{EAB22AC3-30C1-11CF-A7EB-0000C05BAE0B}",
                    WS_TABSTOP,10,44,425,180
    COMBOBOX        IDC_COMBO_ADDRESS, 
                    47,20,185,50,CBS_DROPDOWN | CBS_SORT | 
                    WS_VSCROLL | WS_GROUP | WS_TABSTOP
    PUSHBUTTON      "Refresh",IDC_BUTTON_REFRESH,285,20,40,15
    PUSHBUTTON      "Stop",IDC_BUTTON_STOP,330,20,40,15
    GROUPBOX        "World Wide Web",IDC_STATIC,5,34,435,195
    LTEXT           "Address:",IDC_STATIC,8,22,28,8
    CONTROL         "Progress1",IDC_PROGRESS, 
                    "msctls_progress32",WS_BORDER,
                    327,236,112,12
    EDITTEXT        IDC_STATUS_TEXT,47,236,224,12,
                    ES_AUTOHSCROLL | ES_READONLY
    EDITTEXT        IDC_TITLE_BAR,47,3,392,13,
                    ES_AUTOHSCROLL | ES_READONLY
    LTEXT           "Title:",IDC_STATIC,8,6,16,8
    LTEXT           "Status:",IDC_STATIC,5,238,23,8
    LTEXT           "Progress:",IDC_STATIC,293,238,30,8
    PUSHBUTTON      "Navigate",IDC_NAVIGATE,240,20,40,15
    PUSHBUTTON      "Exit",IDOK,393,21,44,14
END


#ifndef _MAC
//////////////////////////////////////////////////////////////
//
// Информация о приложении
//

VS_VERSION_INFO VERSIONINFO
 FILEVERSION 1,0,0,1
 PRODUCTVERSION 1,0,0,1
 FILEFLAGSMASK 0x3fL
#ifdef _DEBUG
 FILEFLAGS 0x1L
#else
 FILEFLAGS 0x0L
#endif
 FILEOS 0x4L
 FILETYPE 0x1L
 FILESUBTYPE 0x0L
BEGIN
    BLOCK "StringFileInfo"
    BEGIN
        BLOCK "040904B0"
        BEGIN
            VALUE "CompanyName", "\0"
            VALUE "FileDescription", "LOOK MFC Application\0"
            VALUE "FileVersion", "1, 0, 0, 1\0"
            VALUE "InternalName", "LOOK\0"
            VALUE "LegalCopyright", "Copyright © 1997\0"
            VALUE "LegalTrademarks", "\0"
            VALUE "OriginalFilename", "LOOK.EXE\0"
            VALUE "ProductName", "LOOK Application\0"
            VALUE "ProductVersion", "1, 0, 0, 1\0"
        END
    END
    BLOCK "VarFileInfo"
    BEGIN
        VALUE "Translation", 0x409, 1200
    END
END

#endif    // !_MAC

//////////////////////////////////////////////////////////////
//
// DESIGNINFO
//

#ifdef APSTUDIO_INVOKED
GUIDELINES DESIGNINFO DISCARDABLE 
BEGIN
    IDD_LOOK_DIALOG, DIALOG
    BEGIN
        LEFTMARGIN, 7
        RIGHTMARGIN, 437
        TOPMARGIN, 7
        BOTTOMMARGIN, 246
    END
END
#endif    // APSTUDIO_INVOKED

//////////////////////////////////////////////////////////////
//
// Данные для иинициализации диалоговой панели IDD_LOOK_DIALOG
//

IDD_LOOK_DIALOG DLGINIT
BEGIN
   IDC_EXPLORER, 0x376, 128, 0
       0x0000, 0x0000, 0x002c, 0x0000, 0x027e, 0x0000, 0x0125, 
       0x0000, 0x0001, 0x0000, 0x8201, 0x0000, 0x0000, 0x0000, 
       0x0000, 0x0000, 0xffff, 0xffff, 0x0000, 0x0000, 0x002c, 
       0x0000, 0x0000, 0x0000, 0x004c, 0x0000, 0x1401, 0x0002, 
       0x0000, 0x0000, 0x00c0, 0x0000, 0x0000, 0x4600, 0x0000, 
       0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
       0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
       0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0001, 0x0000, 
       0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x6248, 
       0x004b, 
   IDC_COMBO_ADDRESS, 0x403, 30, 0
       0x7468, 0x7074, 0x2f3a, 0x772f, 0x7777, 0x672e, 0x616c,
       0x6e73, 0x7465, 0x722e, 0x2f75, 0x667e, 0x6f72, 0x6f6c, 
       0x0076, 
   IDC_COMBO_ADDRESS, 0x403, 32, 0
       0x7468, 0x7074, 0x2f3a, 0x772f, 0x7777, 0x642e, 0x6169, 
       0x736c, 0x632e, 0x6163, 0x2e73, 0x7572, 0x662f, 0x6f72, 
       0x6f6c, 0x0076, 
   IDC_COMBO_ADDRESS, 0x403, 26, 0
       0x7468, 0x7074, 0x2f3a, 0x772f, 0x7777, 0x642e, 0x6169, 
       0x736c, 0x632e, 0x6163, 0x2e73, 0x7572, 0x002f, 
   IDC_COMBO_ADDRESS, 0x403, 26, 0
       0x7468, 0x7074, 0x2f3a, 0x772f, 0x7777, 0x6d2e, 0x6369, 
       0x6f72, 0x6f73, 0x7466, 0x632e, 0x6d6f, 0x002f, 
   IDC_COMBO_ADDRESS, 0x403, 20, 0
       0x7468, 0x7074, 0x2f3a, 0x772f, 0x7777, 0x6d2e, 0x7063, 
       0x632e, 0x6d6f, 0x002f, 0
END

#endif    
//////////////////////////////////////////////////////////////

#ifndef APSTUDIO_INVOKED
   ///////////////////////////////////////////////////////////
   //
   // Generated from the TEXTINCLUDE 3 resource.
   //
   #define _AFX_NO_SPLITTER_RESOURCES
   #define _AFX_NO_OLE_RESOURCES
   #define _AFX_NO_TRACKER_RESOURCES
   #define _AFX_NO_PROPERTY_RESOURCES

   #if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU)
      #ifdef _WIN32
         LANGUAGE 9, 1
         #pragma code_page(1252)
      #endif
      #include "res\Look.rc2" 
      #include "afxres.rc"
   #endif
   ///////////////////////////////////////////////////////////
#endif    // not APSTUDIO_INVOKED

Идентификаторы ресурсов приложения Look определены в файле resource.h. Этот файл создается автоматически редактором ресурсов Microsoft Visual C++. Мы привели исходный текст файла resource.h в листинге 4.6.

Листинг 4.6. Файл resource.h


//{{NO_DEPENDENCIES}}
// Microsoft Developer Studio generated include file.
// Used by Look.rc
//
#define IDD_LOOK_DIALOG                 102
#define IDR_MAINFRAME                   128
#define IDC_EXPLORER                    1000
#define IDC_BUTTON_BACK                 1002
#define IDC_BUTTON_NEXT                 1003
#define IDC_PROGRESS                    1003
#define IDC_BUTTON_REFRESH              1004
#define IDC_BUTTON_STOP                 1005
#define IDC_STATUS_TEXT                 1006
#define IDC_TITLE_BAR                   1007
#define IDC_NAVIGATE                    1008
#define IDC_COMBO_ADDRESS               1012

// Next default values for new objects
// 
#ifdef APSTUDIO_INVOKED
   #ifndef APSTUDIO_READONLY_SYMBOLS
      #define _APS_NEXT_RESOURCE_VALUE        131
      #define _APS_NEXT_COMMAND_VALUE         32771
      #define _APS_NEXT_CONTROL_VALUE         1010
      #define _APS_NEXT_SYMED_VALUE           101
   #endif
#endif

Класс CLookDlg и органы управления панели IDD_LOOK_DIALOG

Чтобы нам было удобно работать с органами управления диалоговой панели IDD_LOOK_DIALOG, запустите MFC ClassWizard и привяжите к ним переменные, добавив их к классу CLookDlg. К полям редактирования IDC_COMBO_ADDRESS, IDC_TITLE_BAR и IDC_STATUS_TEXT привяжите строки m_address, m_TitleBar и m_StatusText. Эти переменные будут использоваться нами, чтобы узнать адрес сервера, выбранный из списка IDC_COMBO_ADDRESS и вывести в полях IDC_TITLE_BAR и IDC_STATUS_TEXT заголовок страницы и строку состояния.

К линейному индикатору IDC_PROGRESS привяжите объект m_progress. Обратите внимание, что это управляющий объект класса CProgressCtrl и чтобы изменять его состояние мы будем пользоваться методами этого класса.

И, наконец, самое главное. К навигатору IDC_EXPLORER вы должны привязать управляющий объект m_explorer. Для него надо выбрать класс CWebBrowser. Напомним, что этот класс был добавлен в наш проект, когда мы вставили в него орган управления Microsoft Web Browser Control. Этот класс содержит большое количество методов, позволяющих управлять навигатором - переходить к просмотру заданных страниц, обновлять отображаемую информацию и т. д.

Рис. 4.10. Диалоговая панель IDD_LOOK_DIALOG и MFC ClassWizard

Внешний вид диалоговой панели MFC ClassWizard после того как мы добавили ко всем органам управления панели IDD_LOOK_DIALOG управляющие объекты (кроме кнопок) представлен на рисунке 4.10.

Добавление программного кода

После того как вы подготовили главную диалоговую панель приложения Look и привязали к органам управления этой панели соответствующие переменные, надо добавить к классу CLookDlg ряд методов, которые будут обрабатывать сообщения от диалоговой панели. Вы должны добавить методы, обрабатывающие сообщения от кнопок Navigate (IDC_NAVIGATE), Stop (IDC_BUTTON_STOP), Refresh (IDC_BUTTON_REFRESH), Exit (IDOK), от списка с адресами серверов Internet (IDC_COMBO_ADDRESS) и от объекта навигатора (IDC_EXPLORER).

Чтобы добавить все эти методы мы рекомендуем вам воспользоваться средствами MFC ClassWizard. Для этого надо запустить MFC ClassWizard, в диалоговой панели MFC ClassWizard выбрать страницу Message Map. Затем из списка Class name выберите имя класса CLookDlg. К этому классу мы будем добавлять все наши методы.

Из списка Object IDs выбирайте идентификаторы кнопок, списка и навигатора, сообщения от которых надо обрабатывать. При этом в списке Messages будет отображаться список сообщений, которые этот орган управления вырабатывает и методов которые вызываются при определенных условиях. Чтобы добавить новый метод, выберите из списка Messages идентификатор сообщения или название метода которые надо обработать или переопределить и нажмите кнопку Add Function. Вам будет предложено определить название метода. Вы можете оставить его по умолчанию или изменить по своему усмотрению.

Так, вы должны добавить к классу CLookDlg методы для обработки командных сообщений BN_CLICKED от кнопок Navigate (IDC_NAVIGATE), Stop (IDC_BUTTON_STOP), Refresh (IDC_BUTTON_REFRESH). Примите предложение MFC ClassWizard и назовите соответствующие методы именами OnButtonNavigate, OnButtonStop и OnButtonRefresh.

Для списка IDC_COMBO_ADDRESS вы должны назначить обработчик сообщения с кодом идентификации CBN_SELCHANGE. Это сообщение передается диалоговой панели, когда пользователь выбирает из списка новый элемент. Назовите этот метод OnSelchangeComboAddress.

Рис. 4.11. Орган управления Microsoft Web Browser и MFC ClassWizard

Теперь вам надо переназначить ряд методов, которые вызываются навигатором IDC_EXPLORER. Выберите из списка Object IDs идентификатор IDC_EXPLORER. В списке Messages появятся названия методов, которые вы можете переназначить (рис. 4.11). Обратите внимание, когда вы выбираете строки из списка Messages, то ниже списка Member function в поле Description отображается краткое описание данного метода.

Вы должны переопределить следующие методы - DownloadBegin, DownloadComplete, ProgressChange, BeforeNavigate, FrameBeforeNavigate, TitleChange, Quit, StatusTextChange и NavigateComplete. Для каждого из них MFC ClassWizard предложит собственное название. Согласитесь со всеми предложенными названиями. В следующей таблице мы привели соответствие названий событий в списке Messages и названий методов, которые их обрабатывают:

Строка Messages

Метод-обработчик

DownloadBegin

OnDownloadBeginExplorer

DownloadComplete

OnDownloadCompleteExplorer

ProgressChange

OnProgressChangeExplorer

TitleChange

OnTitleChangeExplorer

StatusTextChange

OnStatusTextChangeExplorer

NavigateComplete

OnNavigateCompleteExplorer

Шаблоны новых методов будут добавлены к файлу LookDlg.cpp, содержащему определения всех методов класса CLookDlg. Вы должны внести в них изменения в соответствии с листингом 4.8.

Определение класса CLookDlg содержится во включаемом файле LookDlg.h. Мы привели исходный текст файла LookDlg.h в листинге 4.7.

Листинг 4.7. Файл LookDlg.h


//////////////////////////////////////////////////////////////
// CLookDlg dialog
//{{AFX_INCLUDES()
#include "webbrowser.h"
//}}AFX_INCLUDES

class CLookDlg : public CDialog
{
// Construction
public:
   CLookDlg(CWnd* pParent = NULL);   // standard constructor

// Dialog Data
   //{{AFX_DATA(CLookDlg)
   enum { IDD = IDD_LOOK_DIALOG };
   CProgressCtrl   m_Progress;
   CWebBrowser   m_explorer;
   CString   m_address;
   CString   m_StatusText;
   CString   m_TitleBar;
   //}}AFX_DATA

   // ClassWizard generated virtual function overrides
   //{{AFX_VIRTUAL(CLookDlg)
   protected:
   virtual void DoDataExchange(CDataExchange* pDX);  
   //}}AFX_VIRTUAL

// Implementation
protected:
   HICON m_hIcon;

   // Generated message map functions
   //{{AFX_MSG(CLookDlg)
   virtual BOOL OnInitDialog();
   afx_msg void OnPaint();
   afx_msg HCURSOR OnQueryDragIcon();
   afx_msg void OnSelchangeComboAddress();
   afx_msg void OnButtonRefresh();
   afx_msg void OnButtonStop();
   afx_msg void OnButtonBack();
   afx_msg void OnButtonNext();
   afx_msg void OnDownloadBeginExplorer();
   afx_msg void OnDownloadCompleteExplorer();
   afx_msg void OnProgressChangeExplorer(long Progress, 
                   long ProgressMax);
   afx_msg void OnTitleChangeExplorer(LPCTSTR Text);
   afx_msg void OnStatusTextChangeExplorer(LPCTSTR Text);
   afx_msg void OnNavigate();
   afx_msg void OnNavigateCompleteExplorer(LPCTSTR URL);
   DECLARE_EVENTSINK_MAP()
   //}}AFX_MSG
   DECLARE_MESSAGE_MAP()
};

Вы должны самостоятельно доработать все новые методы, только что добавленные MFC ClassWizard к классу CLookDlg, в соответствии с листингом 3.3.

Определение методов класса CLookDlg и таблица сообщений этого класса содержатся в файле LookDlg.cpp. Кроме того файл LookDlg.cpp содержит конструкцию, которая ранее не встречалась в наших приложениях.

Исходный текст файла LookDlg.cpp приведен нами в листинге 4.8.

Листинг 4.8. Файл LookDlg.cpp


#include "stdafx.h"
#include "Look.h"
#include "LookDlg.h"

#ifdef _DEBUG
   #define new DEBUG_NEW
   #undef THIS_FILE
   static char THIS_FILE[] = __FILE__;
#endif

//////////////////////////////////////////////////////////////
// Конструктор класса CLookDlg 
CLookDlg::CLookDlg(CWnd* pParent /*=NULL*/)
   : CDialog(CLookDlg::IDD, pParent)
{
   //{{AFX_DATA_INIT(CLookDlg)
   m_address = _T("");
   m_StatusText = _T("");
   m_TitleBar = _T("");
   //}}AFX_DATA_INIT

   m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME);
}

//////////////////////////////////////////////////////////////
// Метод DoDataExchange класса CLookDlg.
// Организует взаимодействие между органами управления 
// диалоговой панели и привязанными к ним элементами класса 
void CLookDlg::DoDataExchange(CDataExchange* pDX)
{
   CDialog::DoDataExchange(pDX);
   //{{AFX_DATA_MAP(CLookDlg)
   DDX_Control(pDX, IDC_PROGRESS, m_Progress);
   DDX_Control(pDX, IDC_EXPLORER, m_explorer);
   DDX_CBString(pDX, IDC_COMBO_ADDRESS, m_address);
   DDX_Text(pDX, IDC_STATUS_TEXT, m_StatusText);
   DDX_Text(pDX, IDC_TITLE_BAR, m_TitleBar);
   //}}AFX_DATA_MAP
}

//////////////////////////////////////////////////////////////
// Таблица сообщений класса CLookDlg
BEGIN_MESSAGE_MAP(CLookDlg, CDialog)
   //{{AFX_MSG_MAP(CLookDlg)
   ON_WM_PAINT()
   ON_WM_QUERYDRAGICON()
   ON_CBN_SELCHANGE(IDC_COMBO_ADDRESS, 
      OnSelchangeComboAddress)
   ON_BN_CLICKED(IDC_BUTTON_REFRESH, OnButtonRefresh)
   ON_BN_CLICKED(IDC_BUTTON_STOP, OnButtonStop)
   ON_BN_CLICKED(IDC_BUTTON_BACK, OnButtonBack)
   ON_BN_CLICKED(IDC_BUTTON_NEXT, OnButtonNext)
   ON_BN_CLICKED(IDC_NAVIGATE, OnNavigate)
   //}}AFX_MSG_MAP
END_MESSAGE_MAP()

//////////////////////////////////////////////////////////////
// Метод OnInitDialog класса CLookDlg 
BOOL CLookDlg::OnInitDialog()
{
   CDialog::OnInitDialog();

   SetIcon(m_hIcon, TRUE);        
   SetIcon(m_hIcon, FALSE);      
   
   return TRUE;
}

//////////////////////////////////////////////////////////////
// Метод OnPaint класса CLookDlg 
void CLookDlg::OnPaint() 
{
   if (IsIconic())
   {
      CPaintDC dc(this); // device context for painting

      SendMessage(WM_ICONERASEBKGND, 
         (WPARAM) dc.GetSafeHdc(), 0);

      int cxIcon = GetSystemMetrics(SM_CXICON);
      int cyIcon = GetSystemMetrics(SM_CYICON);
      CRect rect;
      GetClientRect(&rect);
      int x = (rect.Width() - cxIcon + 1) / 2;
      int y = (rect.Height() - cyIcon + 1) / 2;

      dc.DrawIcon(x, y, m_hIcon);
   }
   else
   {
      CDialog::OnPaint();
   }
}

//////////////////////////////////////////////////////////////
// Метод OnQueryDragIcon класса CLookDlg 
HCURSOR CLookDlg::OnQueryDragIcon()
{
   return (HCURSOR) m_hIcon;
}

//////////////////////////////////////////////////////////////
// Метод OnSelchangeComboAddress класса CLookDlg.
// Вызывается при выборе нового адреса из списка
void CLookDlg::OnSelchangeComboAddress() 
{
   // Определяем адрес, выбранный из списка
   UpdateData(TRUE);
   // Переходим к просмотру соответствующего ресурса
   m_explorer.Navigate(
      m_address,   // Адрес URL для просмотра
      NULL,        // Дополнительные флаги
      NULL,        // Имя (frame name) ресурса
      NULL,        // Данные для запроса POST 
      NULL         // Заголовок запроса HTTP 
   );
}

//////////////////////////////////////////////////////////////
// Метод OnButtonRefresh класса CLookDlg. Обновить
// текущую страницу WWW, которая отображается навигатором 
void CLookDlg::OnButtonRefresh() 
{
   m_explorer.Refresh();
}

//////////////////////////////////////////////////////////////
// Метод OnButtonStop класса CLookDlg. 
// Прервать загрузку страницы WWW 
void CLookDlg::OnButtonStop() 
{
   m_explorer.Stop();   
}

//////////////////////////////////////////////////////////////
// Метод OnButtonBack класса CLookDlg. 
// Вернуться к просмотру предыдущей страницы
void CLookDlg::OnButtonBack() 
{
   m_explorer.GoBack();      
}

//////////////////////////////////////////////////////////////
// Метод OnButtonStop класса CLookDlg. 
// Передти к просмотру следующей страницы
void CLookDlg::OnButtonNext() 
{
   m_explorer.GoForward();      
}

//////////////////////////////////////////////////////////////
// Таблица сообщений класса CLookDlg. 
// 
BEGIN_EVENTSINK_MAP(CLookDlg, CDialog)
    //{{AFX_EVENTSINK_MAP(CLookDlg)
   ON_EVENT(CLookDlg, IDC_EXPLORER, 106 /* DownloadBegin */, 
      OnDownloadBeginExplorer, VTS_NONE)
   ON_EVENT(CLookDlg,IDC_EXPLORER, 104 /* DownloadComplete */, 
      OnDownloadCompleteExplorer, VTS_NONE)
   ON_EVENT(CLookDlg, IDC_EXPLORER, 108 /* ProgressChange */, 
      OnProgressChangeExplorer, VTS_I4 VTS_I4)
   ON_EVENT(CLookDlg, IDC_EXPLORER, 100 /* BeforeNavigate */, 
      OnBeforeNavigateExplorer, VTS_BSTR VTS_I4 VTS_BSTR 
      VTS_PVARIANT VTS_BSTR VTS_PBOOL)
   ON_EVENT(CLookDlg,IDC_EXPLORER,200 /*FrameBeforeNavigate*/, 
      OnFrameBeforeNavigateExplorer, VTS_BSTR VTS_I4 VTS_BSTR 
      VTS_PVARIANT VTS_BSTR VTS_PBOOL)
   ON_EVENT(CLookDlg, IDC_EXPLORER, 113 /* TitleChange */, 
      OnTitleChangeExplorer, VTS_BSTR)
   ON_EVENT(CLookDlg, IDC_EXPLORER, 103 /* Quit */, 
      OnQuitExplorer, VTS_PBOOL)
   ON_EVENT(CLookDlg,IDC_EXPLORER, 102 /* StatusTextChange */, 
      OnStatusTextChangeExplorer, VTS_BSTR)
   ON_EVENT(CLookDlg, IDC_EXPLORER, 101 /*NavigateComplete */,
      OnNavigateCompleteExplorer, VTS_BSTR)
   //}}AFX_EVENTSINK_MAP
END_EVENTSINK_MAP()

//////////////////////////////////////////////////////////////
// Метод OnDownloadBeginExplorer класса CLookDlg. 
// Начало загрузки файла
void CLookDlg::OnDownloadBeginExplorer() 
{
   // Инициализируем линейный индикатор
   m_Progress.SetRange(0, 100);
   m_Progress.SetStep(0);
   m_Progress.SetPos(0);
}

//////////////////////////////////////////////////////////////
// Метод OnDownloadCompleteExplorer класса CLookDlg. 
// Загрузка завершена, сбрасываем линейный индикатор
void CLookDlg::OnDownloadCompleteExplorer() 
{
   // TODO: Add your control notification handler code here
   m_Progress.SetPos(0);
}

//////////////////////////////////////////////////////////////
// Метод OnProgressChangeExplorer класса CLookDlg. 
// Идет загрузка, обновляем положение линейного индикатора
void CLookDlg::OnProgressChangeExplorer(long Progress, long ProgressMax) 
{
   // На всякий случай проверяем параметры метода 
   if(Progress <= 0 | ProgressMax <= 0)
      return;

   // Изменяем положение линейного индикатора
   m_Progress.SetPos( (int) (Progress * 100) / ProgressMax);
}

//////////////////////////////////////////////////////////////
// Метод OnTitleChangeExplorer класса CLookDlg. 
// Получен текст для заголовка окна навигатора
void CLookDlg::OnTitleChangeExplorer(LPCTSTR Text) 
{
   // Отображаем заголовок в поле редактирования IDC_TITLE_BAR
   SetDlgItemText(IDC_TITLE_BAR, Text);
}

//////////////////////////////////////////////////////////////
// Метод OnTitleChangeExplorer класса CLookDlg. 
// Получен текст для панели состояния окна навигатора
void CLookDlg::OnStatusTextChangeExplorer(LPCTSTR Text) 
{
   // Отображаем текст в поле редактирования IDC_STATUS_TEXT
   SetDlgItemText(IDC_STATUS_TEXT, Text);
}

//////////////////////////////////////////////////////////////
// Метод OnNavigate класса CLookDlg. 
// Передти к просмотру заданного адреса URL
void CLookDlg::OnNavigate() 
{
   // Определяем адрес URL, выбранный пользователем 
   UpdateData(TRUE);

   // Переходим к просмотру ресурса по заданному адресу 
   m_explorer.Navigate(
      m_address,   // Адрес URL
      NULL,   
      NULL,   
      NULL,   
      NULL   
   );
}

//////////////////////////////////////////////////////////////
// Метод OnNavigateCompleteExplorer класса CLookDlg. 
// Загрузка всех ресурсов страницы завершена
void CLookDlg::OnNavigateCompleteExplorer(LPCTSTR URL) 
{
   // Обновляем адрес URL ресурса, показанного навигатором
   m_address =  URL;
   UpdateData(FALSE);
}

Как работает приложение Look

Приложение Look имеет пользовательский интерфейс на основе диалоговой панели. Мы не будем рассматривать основные принципы устройства этого приложения. Соответствующую информацию вы можете получить из 24 тома серии “Библиотека системного программиста”. Больше внимания мы уделим прикладной части приложения, имеющей отношение к управлению навигатором Microsoft Web Browser Control.

Главный класс приложения

Метод InitInstance главного класса приложения выполняет инициализацию и, собственно, отображает на экране главную диалоговую панель приложения, которая управляется классом CLookDlg.

В целом, метод InitInstance практически ни чем не отличается от аналогичных методов других приложений с пользовательским интерфейсом на основе диалоговой панели. Исключение составляет только вызов глобальной функции AfxEnableControlContainer:


AfxEnableControlContainer();

Эта функция вызывается сразу после того как метод InitInstance получает управление и позволяет работать приложению как контейнеру для органов управления ActiveX. Другими словами функция AfxEnableControlContainer позволяет вам использовать в приложении органы управления ActiveX (OLE).

Класс CLookDlg

Основную работу по управлению диалоговой панелью приложения выполняет класс CLookDlg. Именно в него мы добавляли элементы, представляющие органы управления и методы, обрабатывающие сообщения от диалоговой панели.

Конструктор класса CLookDlg

Конструктор класса CLookDlg вызывается при создании объекта данного класса методом InitInstance главного класса приложения. Он вызывает конструктор базового класса CDialog. При этом ему указывается идентификатор диалоговой панели IDD, который определен в классе CLookDlg следующим образом:


enum { IDD = IDD_LOOK_DIALOG };

Конструктор базового класса загружает шаблон диалоговой панели IDD_LOOK_DIALOG и подготавливает все к отображению ее на экране.

Затем выполняется инициализация строк m_address, m_StatusText и m_TitleBar и загружается пиктограмма приложения:


// Инициализируем строки
//{{AFX_DATA_INIT
m_address = _T("");
m_StatusText = _T("");
m_TitleBar = _T("");
//}}AFX_DATA_INIT
// Загружаем пиктограмму приложения
m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME);
Метод DoDataExchange

При разработке приложения мы привязали к некоторым органам управления диалоговой панели приложения соответствующие элементы данных и ввели их в состав класса CLookDlg. Чтобы обеспечить связь между этими органами управления и элементами данных класса, MFC ClassWizard добавил в блоке AFX_DATA_MAP метода DoDataExchange ряд методов DDX_ XE:


DDX_Control(pDX, IDC_PROGRESS, m_Progress);
DDX_Control(pDX, IDC_EXPLORER, m_explorer);
DDX_Text(pDX, IDC_STATUS_TEXT, m_StatusText);
DDX_Text(pDX, IDC_TITLE_BAR, m_TitleBar);
DDX_CBString(pDX, IDC_COMBO_ADDRESS, m_address);

Линейный индикатор IDC_PROGRESS и навигатор IDC_EXPLORER связываются с элементами данных m_Progress и m_explorer при помощи методов DDX_Control. Таким образом, мы можем полностью управлять линейным индикатором и навигатором вызывая методы соответствующих классов.

Поля редактирования IDC_STATUS_TEXT и IDC_TITLE_BAR связываются со строками m_StatusText и m_TitleBar методами DDX_Text. Чтобы выполнить обмен данными между этими строками и полями редактирования мы будем обращаться к методу UpdateData.

И, наконец, последний метод в блоке DDX_CBString связывает список IDC_COMBO_ADDRESS со строкой m_address. Для того, чтобы узнать текущее состояние списка мы также будем обращаться к методу UpdateData.

Таблицы сообщений класса CLookDlg

Первые две макрокоманды, таблицы сообщений класса CLookDlg, присутствуют во всех приложениях, имеющих пользовательский интерфейс на основе диалоговой панели. Макрокоманды ON_WM_PAINT и ON_WM_QUERYDRAGICON выполняют обработку сообщений WM_PAINT и WM_QUERYDRAGICON, вызывая для этого методы OnSysCommand, OnPaint и OnQueryDragIcon.

Следующая макрокоманда ON_CBN_SELCHANGE обрабатывает сообщение от списка IDC_COMBO_ADDRESS, которое передается когда пользователь выбирает из него строку.

Последующие пять макрокоманд ON_BN_CLICKED вызывают обработчики сообщений от кнопок IDC_BUTTON_REFRESH, IDC_BUTTON_STOP, IDC_BUTTON_BACK, IDC_BUTTON_NEXT и IDC_NAVIGATE, когда пользователь нажимает на них:


BEGIN_MESSAGE_MAP(CLookDlg, CDialog)
   //{{AFX_MSG_MAP(CLookDlg)
   ON_WM_PAINT()
   ON_WM_QUERYDRAGICON()
   ON_CBN_SELCHANGE(IDC_COMBO_ADDRESS, 
      OnSelchangeComboAddress)
   ON_BN_CLICKED(IDC_BUTTON_REFRESH, OnButtonRefresh)
   ON_BN_CLICKED(IDC_BUTTON_STOP, OnButtonStop)
   ON_BN_CLICKED(IDC_BUTTON_BACK, OnButtonBack)
   ON_BN_CLICKED(IDC_BUTTON_NEXT, OnButtonNext)
   ON_BN_CLICKED(IDC_NAVIGATE, OnNavigate)
   //}}AFX_MSG_MAP
END_MESSAGE_MAP()

Таблица сообщений класса CLookDlg, выделенная в блоке BEGIN_MESSAGE_MAP, не содержит в себе ничего необычного, за исключением того, что в ней отсутствуют обработчики сообщений навигатора. Несмотря на то что мы использовали MFC ClassWizard для переопределения ряда методов навигатора, это не нашло никакого отражения в таблице сообщений.

Однако не спешите думать, что в наше приложение закрались какая-то ошибка. Просмотрите файл LookDlg.cpp до конца. Вы обнаружите еще одну таблицу сообщений, обозначенную макрокомандами BEGIN_EVENTSINK_MAP XE "BEGIN_EVENTSINK_MAP" . Эта таблица также относится к классу CLookDlg, наследованному от базового класса CDialog, как это указано в заголовке таблицы:


BEGIN_EVENTSINK_MAP(CLookDlg, CDialog)
    //{{AFX_EVENTSINK_MAP(CLookDlg)
   ON_EVENT(CLookDlg, IDC_EXPLORER, 106 /* DownloadBegin */, 
      OnDownloadBeginExplorer, VTS_NONE)
   ON_EVENT(CLookDlg,IDC_EXPLORER, 104 /* DownloadComplete */, 
      OnDownloadCompleteExplorer, VTS_NONE)
   ON_EVENT(CLookDlg, IDC_EXPLORER, 108 /* ProgressChange */, 
      OnProgressChangeExplorer, VTS_I4 VTS_I4)
   ON_EVENT(CLookDlg, IDC_EXPLORER, 100 /* BeforeNavigate */, 
      OnBeforeNavigateExplorer, VTS_BSTR VTS_I4 VTS_BSTR 
      VTS_PVARIANT VTS_BSTR VTS_PBOOL)
   ON_EVENT(CLookDlg,IDC_EXPLORER,200 /*FrameBeforeNavigate*/, 
      OnFrameBeforeNavigateExplorer, VTS_BSTR VTS_I4 VTS_BSTR 
      VTS_PVARIANT VTS_BSTR VTS_PBOOL)
   ON_EVENT(CLookDlg, IDC_EXPLORER, 113 /* TitleChange */, 
      OnTitleChangeExplorer, VTS_BSTR)
   ON_EVENT(CLookDlg, IDC_EXPLORER, 103 /* Quit */, 
      OnQuitExplorer, VTS_PBOOL)
   ON_EVENT(CLookDlg,IDC_EXPLORER, 102 /* StatusTextChange */, 
      OnStatusTextChangeExplorer, VTS_BSTR)
   ON_EVENT(CLookDlg, IDC_EXPLORER, 101 /*NavigateComplete */,
      OnNavigateCompleteExplorer, VTS_BSTR)
   //}}AFX_EVENTSINK_MAP
END_EVENTSINK_MAP()

Все макрокоманды ON_EVENT в этой таблице сообщений обрабатывают сообщения от навигатора IDC_EXPLORER. Макрокоманда ON_EVENT имеет пять параметров.

Первый параметр определяет имя класса которому принадлежит таблица сообщений. В данном случае все сообщения органа управления обрабатываются классом CLookDlg, которому и принадлежит таблица сообщений AFX_EVENTSINK_MAP.

Второй параметр определяет идентификатор органа управления сообщения от которого обрабатываются. В главной диалоговой панели нашего приложения есть только один орган управления ActiveX, сообщения которого обрабатываются - это навигатор IDC_EXPLORER.

Третий параметр содержит идентификатор метода, который перехватывается данной макрокомандой. Данный идентификатор представляет собой целое число, однозначно определяющее сообщение органа управления. MFC ClassWizard вставляет после этого идентификатора комментарий с именем соответствующего метода.

Имя метода, который определен в нашем приложении и вызывается для обработки данного сообщения, указывается в четвертом параметре макрокоманды. По умолчанию эти имена присваиваются MFC ClassWizard на основе имени сообщения.

И, наконец, последний пятый параметр макрокоманды определяет типы параметров метода обработчика. В качестве этого параметра может фигурировать один или несколько идентификаторов VTS_, разделенных символами пробела.

Описание идентификаторов VTS_ вы можете найти в документации Microsoft Visual C++. Сейчас мы опишем только те идентификаторы, которые фигурируют в таблице сообщений приложения:

Идентификатор

Тип параметра

VTS_I4

long

VTS_BSTR

const char*

VTS_PVARIANT

VARIANT*

VTS_PBOOL

BOOL FAR*

VTS_NONE

Параметры отсутствуют

Метод OnInitDialog

Когда вы отображаете диалоговую панель на экране, вызывая методы DoModal, функции диалоговой панели передается сообщение WM_INITDIALOG. В ответ на сообщение WM_INITDIALOG вызывается метод OnInitDialog, объявленный как виртуальный метод класса CDialog. Таблица сообщений класса CDialogDlg не содержит макрокоманд для обработки сообщения WM_INITDIALOG. Метод OnInitDialog вызывается непосредственно MFC.

Для нашего приложения MFC AppWizard уже переопределил метод OnInitDialog. В нем вызывается метод SetIcon, определенный в базовом классе CWnd, который выбирает пиктограммы для приложения. Метод OnInitDialog возвращает значение TRUE. Это означает, что фокус ввода будет установлен на первый орган управления диалоговой панели.

Методы OnPaint и OnQueryDragIcon

Методы OnPaint и OnQueryDragIcon создаются во время создания проекта с помощью MFC AppWizard и используются для отображении пиктограммы приложения в случае его минимизации. Данные методы одинаковы для всех приложений, созданных MFC AppWizard и имеющих пользовательский интерфейс на основе диалоговой панели. Поэтому сейчас мы не станем рассматривать их более подробно. Вы можете найти описание этих методов в первой книге, посвященной Microsoft Visual C++ и библиотеке MFC из серии “Библиотека системного программиста” (том 24).

Метод OnSelchangeComboAddress

Метод OnSelchangeComboAddress вызывается когда пользователь выбирает из списка IDC_COMBO_ADDRESS адрес нового сервера. В нем мы сразу вызываем метод UpdateData с параметром TRUE чтобы записать выбранный адрес в строку m_address:


UpdateData(TRUE);

Затем нам остается только вызвать метод Navigate для навигатора IDC_EXPLORER, представленного элементом данных m_explorer. Мы указали только первый параметр этого метода, который определяет адрес для просмотра:


m_explorer.Navigate(
      m_address,   // Адрес URL для просмотра
      NULL, NULL, NULL, NULL
);

Метод Navigate соединяется с сервером, загружает с него указанную страницу и отображает ее в окне навигатора диалоговой панели приложения.

Метод OnButtonRefresh

Когда пользователь нажимает на кнопку Refresh, вызывается метод OnButtonRefresh класса CLookDlg. Этот метод обновляет текущую страницу, отображаемую в данный момент навигатором. Для этого используется метод Refresh:


m_explorer.Refresh();
Метод OnButtonStop

Пользователь может прервать загрузку страницы WWW, если нажмет кнопку Stop. В этом случае вызывается метод OnButtonStop останавливающий загрузку при помощи метода Stop:


m_explorer.Stop(); 
Метод OnButtonBack

Просмотрев несколько страниц WWW, пользователь может вернуться к уже просмотренным страницам, если нажмет кнопку Back. В этом случае вызывается метод OnButtonBack класса CLookDlg, который возвращает навигатор к просмотру предыдущих страниц:


m_explorer.GoBack(); 
Метод OnButtonNext

Если вы перешли к уже просмотренным страницам, нажав кнопку Back, вы можете вернуться обратно, если нажмете кнопку Next. В ответ на это вызывается метод OnButtonNext класса CLookDlg, который дает соответствующую команду навигатору:


m_explorer.GoForward(); 
Метод OnDownloadBeginExplorer

Когда навигатор приступает к загрузке очередного объекта с сервера, будь то сама страница HTML, рисунок, анимация или что либо еще, вызывается метод OnDownloadBeginExplorer.

В этом случае мы инициализируем линейный индикатор, который будет показывать ход загрузки данного объекта:


m_Progress.SetRange(0, 100);
m_Progress.SetStep(0);
m_Progress.SetPos(0);
Метод OnDownloadCompleteExplorer

По окончании загрузки очередного объекта, навигатор вызывает метод OnDownloadCompleteExplorer. В нем мы сбрасываем линейный индикатор в начальное положение:


m_Progress.SetPos(0);
Метод OnProgressChangeExplorer

В ходе загрузки объектов с сервера, навигатор вызывает метод OnProgressChangeExplorer. В качестве параметров этому методу передается текущее состояние загрузки Progress и максимальное ProgressMax:


void CLookDlg::OnProgressChangeExplorer(long Progress, long ProgressMax) 
{
   . . .
}

Мы проверяем значение параметров Progress и ProgressMax:


if(Progress <= 0 | ProgressMax <= 0)
   return;

Если они больше нуля, изменяем значение линейного индикатора. При этом мы принимаем, что индикатор может отображать значения до ProgressMax:


m_Progress.SetPos( (int) (Progress * 100) / ProgressMax);
Метод OnTitleChangeExplorer

Метод OnTitleChangeExplorer вызывается навигатором, когда он загружает заголовок страницы WWW. Текст заголовка передается через параметр Text данного метода:


void CLookDlg::OnTitleChangeExplorer(LPCTSTR Text) 
{
   . . . 
}

Мы отображаем заголовок в поле редактирования IDC_TITLE_BAR диалоговой панели приложения. Для этого вызываем метод SetDlgItemText класса CWnd и передаем ему идентификатор поля редактирования и текст заголовка:


SetDlgItemText(IDC_TITLE_BAR, Text);
Метод OnStatusTextChangeExplorer

Метод OnStatusTextChangeExplorer вызывается навигатором, когда он переходит к выполнению новой операции или когда со страницы WWW загружен текст для строки состояния.

Текст, для отображения в строке состояния передается через единственный параметр метода - Text:


void CLookDlg::OnStatusTextChangeExplorer(LPCTSTR Text) 
{
   . . . 
}

Мы выводим этот текст в поле редактирования IDC_STATUS_TEXT, вызывая метод SetDlgItemText класса CWnd:


SetDlgItemText(IDC_STATUS_TEXT, Text);
Метод OnNavigate

После запуска приложения навигатор не задействован. Чтобы он начал работать, пользователь должен выбрать из списка адрес сервера, а затем нажать кнопку Navigate. Когда пользователь нажимает эту кнопку, вызывается метод OnNavigate класса CLookDlg.

В нем мы сначала определяем адрес, выбранный из списка. Для этого мы вызываем метод UpdateData с параметром TRUE. Он копирует строку выбранную из списка IDC_COMBO_ADDRESS в строку m_address:


UpdateData(TRUE);

Этот адрес передается навигатору, он соединяется с указанным сервером и отображает соответствующую страницу в своем окне:


m_explorer.Navigate(
      m_address,   
      NULL, NULL, NULL, NULL
);
Метод OnNavigateCompleteExplorer

После того, как навигатор завершит загрузку страницы WWW он вызывает метод OnNavigateCompleteExplorer и передает ему точный адрес этой страницы:


void CLookDlg::OnNavigateCompleteExplorer(LPCTSTR URL) 
{
}

Мы записываем этот адрес в строку m_address и отображаем его в диалоговой панели, для чего вызываем метод UpdateData с параметром FALSE:


m_address =  URL;
UpdateData(FALSE);

Вспомогательные файлы

Кроме уже описанных нами файлов в проект Look входят еще два исходных файла, содержащих программный код. Это файлы stdafx.cpp и включаемый файл stdafx.h. Исходный текст файла stdafx.cpp содержится в листинге 4.9. Как видите, он состоит из единственной директивы #include, включающей файл stdafx.h (листинг 4.10).

Листинг 4.9. Файл stdafx.cpp


// Включаем файл stdafx.h, определенный в нашем приложении
#include "stdafx.h"

Файл stdafx.h задействует часто используемые включаемые системные файлы - afxwin.h, afxext.h, afxcmn.h и afxdisp.h. Эти файлы не изменяются, поэтому Microsoft Visual C++ компилирует их только один раз. За счет этого значительно сокращается время, затрачиваемое на повторное построение проекта.

Листинг 4.10. Файл stdafx.h


// Исключает редко используемые определения при обработке 
// файлов заголовков
#define VC_EXTRALEAN 
 
// Основные компоненты библиотеки MFC 
#include <afxwin.h> 

// Расширения MFC
#include <afxext.h> 

// Будут использоваться органы управления ActiveX
#include <afxdisp.h> 

#ifndef _AFX_NO_AFXCMN_SUPPORT
   // Используется для органов управления Windows
   #include <afxcmn.h>   // Common Controls
#endif // _AFX_NO_AFXCMN_SUPPORT

Методы класса CLookDlg и таблица сообщений этого класса определяются в файле LookDlg.cpp. Мы привели полный исходный текст файла LookDlg.cpp в листинге 4.4.

Запустите приложение

Если компьютер настроен для работы с Internet, но в настоящий момент соединение не установлено, подключитесь к Internet. Запустите приложение Look (рис. 4.12). Сразу после того, как на экране появится панель приложения Look, вы можете перейти к просмотру серверов WWW и FTP. Для этого выберите адрес сервера из списка Address или введите его вручную. Нажмите кнопку Navigate. Через некоторое время в окне просмотра появится выбранная вами страница. В зависимости от множества причин, таких как скорость соединения вашего компьютера с сервером поставщика услуг Internet, загруженности его сервера и сервера, с которым вы соединяетесь, возможны значительные задержки при загрузке страниц из сети.

Когда страничка WWW или FTP появится в окне приложения, вы можете перейти к просмотру других страниц, используя приложение Look как действующую модель Internet Explorer в натуральную величину.

Рис. 4.12. Приложение Look

Кнопки “Вперед” и “Назад”

В нашем варианте навигатора отсутствуют кнопки, позволяющие вернуться к просмотру страниц WWW, которые вы уже посетили во время текущего сеанса связи. Это крайне неудобно, так как затрудняет обход дерева гипертекстовых ссылок серверов WWW.

Добавить возможность возврата к предыдущим страницам WWW очень просто. Орган управления Microsoft Web Browser Control сам запоминает путь ваших хождений по паутине Internet. В состав класса CWebBrowser входят методы GoBack и GoForward, которые позволяют просматривать уже посещенные вами страницы.

Методы GoBack и GoForward имеют простой прототип - у них отсутствуют параметры и они не возвращают никакого значения. Интересно, что в документации на Microsoft Web Browser Control, которую мы получили через сеть Internet, указывается, что эти методы возвращают значение типа HRESULT, определяющее результат выполнения метода:


void CWebBrowser::GoBack()
void CWebBrowser::GoForward()

С помощью редактора ресурсов добавьте к диалоговой панели IDD_LOOK_DIALOG приложения Look, две кнопки. Первую назовите Back (назад) и присвойте ей идентификатор IDC_BACK, а вторую - Forward (вперед) и воспользуйтесь идентификатором IDC_FORWARD.

После того как кнопки заняли свое место в диалоговой панели, запустите MFC ClassWizard и добавьте к классу CLookDlg два метода для обработки командных сообщений от кнопок Back и Forward. Согласитесь с предложением MFC ClassWizard и оставьте для них названия OnBack и OnForward.

Затем непосредственно из MFC ClassWizard перейдите к просмотру и редактированию методов OnBack и OnForward, выбрав одно из названий этих методов из списка и нажав кнопку Edit code. Добавьте к OnBack и OnForward вызовы, соответственно, методов GoBack и GoForward класса CWebBrowser.

Постройте проект и запустите приложение. Посетите несколько страниц WWW и попробуйте вернуться к уже просмотренным страницам, воспользовавшись кнопками Back и Forward. Вы обнаружите, что кнопки работают правильно, но когда вы выходите за границу уже просмотренного материала, на экране появляется ужасная диалоговая панель, показанная на рисунке 4.13.

Рис. 4.13. Предупреждающая диалоговая панель

Класс CWebBrowser имеет средства для управления кнопками просмотра Back и Forward. Для этого предназначен виртуальный метод CommandStateChange, который вызывается самим органом управления. Чтобы переназначить метод CommandStateChange надо воспользоваться средствами MFC ClassWizard (рис. 3.4):


void CBrowserDlg::OnCommandStateChangeExplorer(long Command, BOOL Enable)
{
}

В качестве значения параметра Command, методу CommandStateChange передается отдна из следующих констант - CSC_UPDATECOMMANDS, CSC_NAVIGATEFORWARD или CSC_NAVIGATEBACK. Эти константы определяются следующим образом:


typedef enum CommandStateChangeConstants {
    CSC_UPDATECOMMANDS = 0xFFFFFFFF,
    CSC_NAVIGATEFORWARD = 0x00000001,
    CSC_NAVIGATEBACK = 0x00000002
} CommandStateChangeConstants;

Второй параметр Enable определяет, новое состояние кнопки - заблокирована или доступна. Когда требуется изменить состояние кнопки Back, вызывается метод OnCommandStateChangeExplorer. В качестве первого параметра ему передается значение CSC_NAVIGATEBACK. Когда надо изменить состояние кнопки Forward, в первом параметре передается значение CSC_NAVIGATEFORWARD.

Чтобы управлять состоянием кнопок IDC_BACK и IDC_FORWARD нужно сначала привязать к ним две переменные. Для этого следует воспользоваться средствами MFC ClassWizard.

Откройте в редакторе ресурсов диалоговую панель приложения и выберите в ней кнопку Forward или Back. Запустите MFC ClassWizard. Выберите в панели MFC ClassWizard страницу Member Variables. В списке идентификаторов органов управления диалоговой панели Control IDs укажите идентификатор IDC_BACK, принадлежащий кнопке Back и нажмите кнопку Add Variables. На экране появится диалоговая панель Add Member Variables (рис. 4.14). Введите в поле Member Variables name имя переменной, которая будет связана с кнопкой. Мы предлагаем использовать имя m_Back.

Рис. 4.14. Диалоговая панель Add Member Variables

Обратите внимание, что из списка категории органа управления Category должна быть выбрана строка Control, а из списка типа переменной Variables type - строка CButton. Таким образом мы привяжем к кнопке переменную m_Back класса CButton.

Выбирая из списка Category строку Control мы указываем, что нам надо привязать к органу управления объект соответствующего класса, через который мы затем сможем иметь над ним полный контроль.

¨     Как мы говорили в предыдущих томах серии БСП, посвященных библиотеке MFC, к одному органу управления с помощью MFC ClassWizard можно привязать несколько переменных. Однако это верно только если указывается категория Value. Если вы используете категорию Control, то к одному органу управления можно привязать только одну переменную. Попытка привязать еще одну переменную вызывает сообщение об ошибке (рис. 4.15)

Рис. 4.15. Предупреждение

Повторите описанную процедуру и привяжите к кнопке IDC_FORWARD переменную m_Forward класса CButton.

Когда вы привяжите к кнопкам переменные, MFC ClassWizard внесет изменения в исходные тексты приложения. Во-первых в класс CLookDlg, управляющий диалоговой панелью будет включены два новых элемента данных, представляющих кнопки:


class CLookDlg : public CDialog
{
public:
   CLookDlg(CWnd* pParent = NULL);   

// Dialog Data
   //{{AFX_DATA(CLookDlg)
   enum { IDD = IDD_LOOK_DIALOG };
   CButton   m_Forward;           // Кнопка Forward
   CButton   m_Back;              // Кнопка Back
   CWebBrowser   m_explorer;
   CString   m_address;
   //}}AFX_DATA
   ...

Во-вторых, будут добавлены новые записи в таблице обмена данными, расположенной в методе DoDataExchange класса CLookDlg. Новые записи являются вызовами методов DDX_Control XE "DDX_Control" , которые выполняют обмен данными между органом управления и привязанной к нему переменной:


void CLookDlg::DoDataExchange(CDataExchange* pDX)
{
   CDialog::DoDataExchange(pDX);
   //{{AFX_DATA_MAP(CLookDlg)
   DDX_Control(pDX, IDC_FORWARD, m_Forward); // Кнопка Forward
   DDX_Control(pDX, IDC_BACK, m_Back);       // Кнопка Back
   DDX_Control(pDX, IDC_EXPLORER, m_explorer);
   DDX_CBString(pDX, IDC_COMBO_ADDRESS, m_address);
   //}}AFX_DATA_MAP
}

Блокировка кнопок

Теперь нам надо добавить программный код, выполняющий блокировку кнопок. Для этого мы будем использовать метод EnableWindow базового класса CWnd (Класс CButton наследуется от базового класса CWnd).


BOOL EnableWindow(BOOL bEnable = TRUE);

Этот метод имеет единственный необязательный параметр, который задает новое состояние кнопки. Если параметр bEnable не указан или равен TRUE, тогда кнопка становится доступна, а если FALSE - кнопка блокируется.

Значение второго параметра метода OnCommandStateChangeExplorer, принадлежащего классу CBrowserDlg, можно непосредственно передавать параметру bEnable метода EnableWindow данной кнопки.

Переопределите метод OnCommandStateChangeExplorer класса CBrowserDlg, опять же используя для этого средства MFC ClassWizard. Загрузите полученный шаблон метода OnCommandStateChangeExplorer в редактор и дополните его в соответствии со следующим листингом:


void CBrowserDlg::OnCommandStateChangeExplorer(
   long Command,
   BOOL Enable
)
{
   switch(Command)
   {
   case CSC_NAVIGATEFORWARD:
      // Меняем состояние кнопки Forward
      m_Forward.EnableWindow(Enable);
      break;

   case CSC_NAVIGATEBACK:
      // Меняем состояние кнопки Back
      m_Back.EnableWindow(Enable);
      break;
   }
}

В представленном выше программном коде мы не проверяем значение параметра Command на равенство значению CSC_UPDATECOMMANDS. Метод OnCommandStateChangeExplorer вызывается с этим значением, если изменилось состояние кнопок панели управления.

Постройте полученное приложение и запустите его на выполнение. Теперь вы заметите, что кнопки Back и Forward будут автоматически блокироваться по мере необходимости и предупреждающее сообщение, представленное на рисунке 3.3 больше не появится.

После прочтения главы об органе управления Microsoft Web Browser Control у вас может появиться вполне резонный вопрос - а зачем вообще нужно создавать свою программу просмотра, если можно просто использовать готовое приложение Internet Explorer без всякого дополнительного программирования.

Безусловно, создавать свой Internet Explorer не имеет особого смысла. Эта задача успешно решена Microsoft. Однако, если вы разрабатываете приложения для компьютерной сети в рамках своего предприятия, преимущества налицо. Вы, например, можете легко интегрировать средства WWW в свое приложение и позволить пользователю просматривать только определенные ресурсы сети.

[Назад] [Содеожание] [Дальше]