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

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

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

4. Ваш собственный Internet Explorer

  • Приложение Look
  • Для просмотра серверов Internet используются специальные программы - навигаторы. Сегодня вы можете встретить много различных навигаторов, однако наиболее часто используются Microsoft Internet Explorer и Netscape Navigator.

    Навигаторы представляют собой весьма сложные программы. Достаточно сказать, что они должны уметь работать с протоколами передачи данных TCP/IP, протоколом передачи гипертекста HTTP, протоком передачи файлов FTP. Навигатор также должен уметь правильно отображать принятые данные на экране. Он должен понимать данные в формате HTML, уметь отображать на экране графические файлы, использовать органы управления ActiveX, исполнять аплеты на языке Java и т. д. (рис. 4.1).

    Рис. 4.1. Microsoft Internet Explorer

    Основу навигатора Microsoft Internet Explorer составляют несколько библиотек dll, в которых определены объекты ActiveX. Именно они несут на себе основную нагрузку - взаимодействуют с серверами, отображают страницы WWW на экране и т. д. Окно навигатора вместе с меню панелями управления и состояния - не более чем простая оболочка и не несет на себе никакой функциональной нагрузки.

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

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

    Приложение 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 в свое приложение и позволить пользователю просматривать только определенные ресурсы сети.

     

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