Стоит Windows 8 Pro, Visual Studio 2010 Express Edition . |
Встраивание возможностей броузера в приложение
Настройка приложения на открытие локальных HTML-документов
Тот стандартный каркас приложения, который сгенерировал для нас мастер в самом начале, не рассчитан на открытие документов в формате HTML. Заложенные изначально базовые возможности открытия документа реализуются посылкой сообщения ON_FILE_OPEN в ответ на щелчок Пользователя по кнопке Open панели инструментов (значок ) или выполнения одноименной команды меню. Это сообщение перехватывается в классе CWebBrowseApp (карта сообщений файла WebBrowse.cpp ) и обрабатывается функцией базового класса CWinApp::OnFileOpen()
Карта сообщений для класса CWebBrowseApp в файле WebBrowse.cpp // CWebBrowseApp BEGIN_MESSAGE_MAP(CWebBrowseApp, CWinApp) ON_COMMAND(ID_APP_ABOUT, OnAppAbout) // Standard file based document commands ON_COMMAND(ID_FILE_NEW, CWinApp::OnFileNew) ON_COMMAND(ID_FILE_OPEN, CWinApp::OnFileOpen) // Standard print setup command ON_COMMAND(ID_FILE_PRINT_SETUP, CWinApp::OnFilePrintSetup) END_MESSAGE_MAP()
Для того, чтобы реализовать задуманное, прежде всего нужно убрать выделенный код из карты сообщений класса CWebBrowseApp. Перехватывать это сообщение мы будем во фреймовом окне, в классе которого у нас есть доступ к полю редактирования адреса. В классе фреймового окна мы построим обработчик сообщения ON_FILE_OPEN, в котором создадим и настроим диалог FileOpen, из которого извлечем информацию об имени выбранного Пользователем открываемого файла. После этого имя файла можно передать в поле ввода адреса панели управления и сгенерировать сообщение IDOK, обработчик которого у нас уже создан. Итак, приступим.
-
Закомментируйте код маршрутизации сообщения ON_FILE_OPEN в карте сообщений класса CWebBrowseApp, как показано ниже
Комментируем код базового сообщения ON_FILE_OPEN для класса CWebBrowseApp в файле WebBrowse.cpp // CWebBrowseApp BEGIN_MESSAGE_MAP(CWebBrowseApp, CWinApp) ON_COMMAND(ID_APP_ABOUT, OnAppAbout) // Standard file based document commands ON_COMMAND(ID_FILE_NEW, CWinApp::OnFileNew) // ON_COMMAND(ID_FILE_OPEN, CWinApp::OnFileOpen) // Standard print setup command ON_COMMAND(ID_FILE_PRINT_SETUP, CWinApp::OnFilePrintSetup) END_MESSAGE_MAP()
- Постройте приложение и убедитесь, что кнопка и команда меню Open стали недоступными ( Disabled )
- В панели Class View выделите класс CMainFrame и сразу после этого в панели Properties установите режим Events
- Найдите сообщение ON_FILE_OPEN и создайте для него обработчик
- Постройте приложение и убедитесь, что команда и кнопка Open стали доступными, но естественно ничего не делают, так как обработчик пока пустой
-
Внесите в обработчик код, который и решит всю задачу
Код нового обработчика сообщения ON_FILE_OPEN void CMainFrame::OnFileOpen() { // TODO: Add your command handler code here // Создать диалог File Open static char szFilter[] = "HTM Files (*.htm)|*.htm|HTML Files (*.html)|*.html|All Files (*.*)|*.*||"; CFileDialog openFile(TRUE, ".htm", "", OFN_HIDEREADONLY | OFN_OVERWRITEPROMPT, szFilter); CString name; if(openFile.DoModal() == IDOK) name = openFile.GetPathName();// Полное имя с путем else return; // Сменить значение поля адреса (m_wndDlgBar.GetDlgItem(IDC_EADDRESS))->SetWindowText(name); OnNewAddress();// Вызвать нашу функцию }
- Постройте приложение и убедитесь, что все работает как задумали. Отметьте также, что полнофункционально работает и контекстное меню, генерируемое базовым классом CHtmlView
Подчистка лишних интерфейсов и оформление About
Теперь осталось совсем немного - убрать лишние интерфейсы, которые из добрых побуждений создал для нас мастер при генерации SDI -приложения. Он же не мог предположить, что мы станем "извращаться" с его заготовкой и приспосабливать ее под самопальный броузер.
-
Вызовите на редактирование панель инструментов и удалите лишние кнопки
Кнопки удаляйте перетаскиванием мышью за пределы панели. Сепараторы между кнопками вводятся более широкими отступами по ширине панели.
Ресурс панели инструментов после редактирования должен выглядеть так
-
Вызовите на редактирование ресурс меню, и приведите категорию File в соответствие с действительной функциональностью приложения
Теперь, когда мы удалили инструменты New и Save, в классе документа CWebBrowseDoc стали ненужными переопределения функций OnNewDocument() и Serialize(). Теперь уже никто их не сможет вызвать. Все ниточки-веревочки для их вызова мы обрезали. Они конечно никому не мешают и код не портят, но место все-таки занимают, да и могут смутить бедного сопровождающего программиста. Поэтому удалим их объявления в файле WebBrowseDoc.h и реализацию в файле WebBrowseDoc.cpp.
-
Откройте файл WebBrowseDoc.h и удалите (или закомментируйте) в объявлении класса CWebBrowseDoc следующий код
Удаление объявлений функций в классе CWebBrowseDoc class CWebBrowseDoc : public CDocument { ........................................ // Overrides public: // virtual BOOL OnNewDocument(); // virtual void Serialize(CArchive& ar); ........................................ };
-
Откройте файл WebBrowseDoc.cpp и удалите (или закомментируйте) в реализации класса CWebBrowseDoc код функций OnNewDocument() и Serialize(CArchive& ar)
Удаление лишнего кода в реализации класса CWebBrowseDoc // WebBrowseDoc.cpp : implementation of the CWebBrowseDoc class // #include "stdafx.h" #include "WebBrowse.h" #include "WebBrowseDoc.h" #ifdef _DEBUG #define new DEBUG_NEW #endif // CWebBrowseDoc IMPLEMENT_DYNCREATE(CWebBrowseDoc, CDocument) BEGIN_MESSAGE_MAP(CWebBrowseDoc, CDocument) END_MESSAGE_MAP() // CWebBrowseDoc construction/destruction CWebBrowseDoc::CWebBrowseDoc() { // TODO: add one-time construction code here } CWebBrowseDoc::~CWebBrowseDoc() { } /* BOOL CWebBrowseDoc::OnNewDocument() { if (!CDocument::OnNewDocument()) return FALSE; // TODO: add reinitialization code here // (SDI documents will reuse this document) return TRUE; } // CWebBrowseDoc serialization void CWebBrowseDoc::Serialize(CArchive& ar) { if (ar.IsStoring()) { // TODO: add storing code here } else { // TODO: add loading code here } } */ // CWebBrowseDoc diagnostics #ifdef _DEBUG void CWebBrowseDoc::AssertValid() const { CDocument::AssertValid(); } void CWebBrowseDoc::Dump(CDumpContext& dc) const { CDocument::Dump(dc); } #endif //_DEBUG // CWebBrowseDoc commands
-
Откройте файл WebBrowse.cpp и удалите в карте сообщений маршрутизатор сообщения ID_FILE_NEW. Все равно теперь никто в приложении это сообщение не пошлет - мы все стерилизовали
Корректировка карты приема сообщений класса CWebBrowseApp BEGIN_MESSAGE_MAP(CWebBrowseApp, CWinApp) ON_COMMAND(ID_APP_ABOUT, OnAppAbout) // Standard file based document commands // ON_COMMAND(ID_FILE_NEW, CWinApp::OnFileNew) // ON_COMMAND(ID_FILE_OPEN, CWinApp::OnFileOpen) // Standard print setup command ON_COMMAND(ID_FILE_PRINT_SETUP, CWinApp::OnFilePrintSetup) END_MESSAGE_MAP()
- Добавьте в категорию View меню нашего приложения пункт Browse Bar и виберите значение ID из ракрывающегося списка как показано на рисунке
- Оформите About и смените иконку приложения
- Запустите и испытайте приложение - работает как настоящий Броузер (почти)