Для просмотра серверов 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.
Воспользуйтесь 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.
Все остальные параметры приложения можно оставить по умолчанию и нажать на кнопку 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 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, наследованный от базового класса 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 расположено в файле 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 и используйте его.
Все методы класса 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 в проект, он станет доступен в панели инструментов разработки диалоговых панелей. Выберите в окне 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
Чтобы нам было удобно работать с органами управления диалоговой панели 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 имеет пользовательский интерфейс на основе диалоговой панели. Мы не будем рассматривать основные принципы устройства этого приложения. Соответствующую информацию вы можете получить из 24 тома серии “Библиотека системного программиста”. Больше внимания мы уделим прикладной части приложения, имеющей отношение к управлению навигатором Microsoft Web Browser Control.
Метод InitInstance главного класса приложения выполняет инициализацию и, собственно, отображает на экране главную диалоговую панель приложения, которая управляется классом CLookDlg.
В целом, метод InitInstance практически ни чем не отличается от аналогичных методов других приложений с пользовательским интерфейсом на основе диалоговой панели. Исключение составляет только вызов глобальной функции AfxEnableControlContainer:
AfxEnableControlContainer();
Эта функция вызывается сразу после того как метод InitInstance получает управление и позволяет работать приложению как контейнеру для органов управления ActiveX. Другими словами функция AfxEnableControlContainer позволяет вам использовать в приложении органы управления ActiveX (OLE).
Основную работу по управлению диалоговой панелью приложения выполняет класс 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);
При разработке приложения мы привязали к некоторым органам управления диалоговой панели приложения соответствующие элементы данных и ввели их в состав класса 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, присутствуют во всех приложениях, имеющих пользовательский интерфейс на основе диалоговой панели. Макрокоманды 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 |
Параметры отсутствуют |
Когда вы отображаете диалоговую панель на экране, вызывая методы DoModal, функции диалоговой панели передается сообщение WM_INITDIALOG. В ответ на сообщение WM_INITDIALOG вызывается метод OnInitDialog, объявленный как виртуальный метод класса CDialog. Таблица сообщений класса CDialogDlg не содержит макрокоманд для обработки сообщения WM_INITDIALOG. Метод OnInitDialog вызывается непосредственно MFC.
Для нашего приложения MFC AppWizard уже переопределил метод OnInitDialog. В нем вызывается метод SetIcon, определенный в базовом классе CWnd, который выбирает пиктограммы для приложения. Метод OnInitDialog возвращает значение TRUE. Это означает, что фокус ввода будет установлен на первый орган управления диалоговой панели.
Методы OnPaint и OnQueryDragIcon создаются во время создания проекта с помощью MFC AppWizard и используются для отображении пиктограммы приложения в случае его минимизации. Данные методы одинаковы для всех приложений, созданных MFC AppWizard и имеющих пользовательский интерфейс на основе диалоговой панели. Поэтому сейчас мы не станем рассматривать их более подробно. Вы можете найти описание этих методов в первой книге, посвященной Microsoft Visual C++ и библиотеке MFC из серии “Библиотека системного программиста” (том 24).
Метод 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 соединяется с сервером, загружает с него указанную страницу и отображает ее в окне навигатора диалоговой панели приложения.
Когда пользователь нажимает на кнопку Refresh, вызывается метод OnButtonRefresh класса CLookDlg. Этот метод обновляет текущую страницу, отображаемую в данный момент навигатором. Для этого используется метод Refresh:
m_explorer.Refresh();
Пользователь может прервать загрузку страницы WWW, если нажмет кнопку Stop. В этом случае вызывается метод OnButtonStop останавливающий загрузку при помощи метода Stop:
m_explorer.Stop();
Просмотрев несколько страниц WWW, пользователь может вернуться к уже просмотренным страницам, если нажмет кнопку Back. В этом случае вызывается метод OnButtonBack класса CLookDlg, который возвращает навигатор к просмотру предыдущих страниц:
m_explorer.GoBack();
Если вы перешли к уже просмотренным страницам, нажав кнопку Back, вы можете вернуться обратно, если нажмете кнопку Next. В ответ на это вызывается метод OnButtonNext класса CLookDlg, который дает соответствующую команду навигатору:
m_explorer.GoForward();
Когда навигатор приступает к загрузке очередного объекта с сервера, будь то сама страница HTML, рисунок, анимация или что либо еще, вызывается метод OnDownloadBeginExplorer.
В этом случае мы инициализируем линейный индикатор, который будет показывать ход загрузки данного объекта:
m_Progress.SetRange(0, 100); m_Progress.SetStep(0); m_Progress.SetPos(0);
По окончании загрузки очередного объекта, навигатор вызывает метод OnDownloadCompleteExplorer. В нем мы сбрасываем линейный индикатор в начальное положение:
m_Progress.SetPos(0);
В ходе загрузки объектов с сервера, навигатор вызывает метод 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 вызывается навигатором, когда он загружает заголовок страницы WWW. Текст заголовка передается через параметр Text данного метода:
void CLookDlg::OnTitleChangeExplorer(LPCTSTR Text) { . . . }
Мы отображаем заголовок в поле редактирования IDC_TITLE_BAR диалоговой панели приложения. Для этого вызываем метод SetDlgItemText класса CWnd и передаем ему идентификатор поля редактирования и текст заголовка:
SetDlgItemText(IDC_TITLE_BAR, Text);
Метод OnStatusTextChangeExplorer вызывается навигатором, когда он переходит к выполнению новой операции или когда со страницы WWW загружен текст для строки состояния.
Текст, для отображения в строке состояния передается через единственный параметр метода - Text:
void CLookDlg::OnStatusTextChangeExplorer(LPCTSTR Text) { . . . }
Мы выводим этот текст в поле редактирования IDC_STATUS_TEXT, вызывая метод SetDlgItemText класса CWnd:
SetDlgItemText(IDC_STATUS_TEXT, Text);
После запуска приложения навигатор не задействован. Чтобы он начал работать, пользователь должен выбрать из списка адрес сервера, а затем нажать кнопку Navigate. Когда пользователь нажимает эту кнопку, вызывается метод OnNavigate класса CLookDlg.
В нем мы сначала определяем адрес, выбранный из списка. Для этого мы вызываем метод UpdateData с параметром TRUE. Он копирует строку выбранную из списка IDC_COMBO_ADDRESS в строку m_address:
UpdateData(TRUE);
Этот адрес передается навигатору, он соединяется с указанным сервером и отображает соответствующую страницу в своем окне:
m_explorer.Navigate( m_address, NULL, NULL, NULL, NULL );
После того, как навигатор завершит загрузку страницы 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 мы указываем, что нам надо привязать к органу управления объект соответствующего класса, через который мы затем сможем иметь над ним полный контроль.
Рис. 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 в свое приложение и позволить пользователю просматривать только определенные ресурсы сети.