|  | Home · Overviews · Examples

# Web Browser Example (ActiveQt)

The Web Browser example uses the Microsoft Web Browser ActiveX control to implement a fully functional Web Browser application. The user interface has been developed using the Qt Designer integration of the QAxWidget class.

The code demonstrates how the Qt application can communicate with the embedded ActiveX controls using signals, slots and the dynamicCall() function.
The following code example is written in c++.

    class MainWindow : public QMainWindow, public Ui::MainWindow
    {
        Q_OBJECT
    public:
        MainWindow();

    public slots:
        void on_WebBrowser_TitleChange(const QString &title);
        void on_WebBrowser_ProgressChange(int a, int b);
        void on_WebBrowser_CommandStateChange(int cmd, bool on);
        void on_WebBrowser_BeforeNavigate();
        void on_WebBrowser_NavigateComplete(QString);

        void on_actionGo_triggered();
        void on_actionNewWindow_triggered();
        void on_actionAbout_triggered();
        void on_actionAboutQt_triggered();
        void on_actionFileClose_triggered();

    private:
        QProgressBar *pb;
    };

The `MainWindow` class declares a `QMainWindow` based user interface, using the `Ui::MainWindow` class generated by Qt Designer. A number of slots are implemented to handle events from the various user interface elements, including the `WebBrowser` object, which is a QAxWidget hosting the Microsoft Web Browser control.
The following code example is written in c++.

    MainWindow::MainWindow()
    {
        setupUi(this);

        connect(addressEdit, SIGNAL(returnPressed()), actionGo, SLOT(trigger()));
        connect(actionBack, SIGNAL(triggered()), WebBrowser, SLOT(GoBack()));
        connect(actionForward, SIGNAL(triggered()), WebBrowser, SLOT(GoForward()));
        connect(actionStop, SIGNAL(triggered()), WebBrowser, SLOT(Stop()));
        connect(actionRefresh, SIGNAL(triggered()), WebBrowser, SLOT(Refresh()));
        connect(actionHome, SIGNAL(triggered()), WebBrowser, SLOT(GoHome()));
        connect(actionSearch, SIGNAL(triggered()), WebBrowser, SLOT(GoSearch()));

        pb = new QProgressBar(statusBar());
        pb->setTextVisible(false);
        pb->hide();
        statusBar()->addPermanentWidget(pb);

        WebBrowser->dynamicCall("GoHome()");
    }

The constructor initializes the user interface, installs a progress bar on the status bar, and uses QAxBase::dynamicCall() to invoke the `GoHome()` method of Internet Explorer to navigate to the user's home page.
The following code example is written in c++.

    void MainWindow::on_WebBrowser_TitleChange(const QString &title)
    {
        setWindowTitle("Qt WebBrowser - " + title);
    }

    void MainWindow::on_WebBrowser_ProgressChange(int a, int b)
    {
        if (a <= 0 || b <= 0) {
    	pb->hide();
    	return;
        }
        pb->show();
        pb->setRange(0, b);
        pb->setValue(a);
    }

    void MainWindow::on_WebBrowser_CommandStateChange(int cmd, bool on)
    {
        switch (cmd) {
        case 1:
    	actionForward->setEnabled(on);
    	break;
        case 2:
    	actionBack->setEnabled(on);
    	break;
        }
    }

    void MainWindow::on_WebBrowser_BeforeNavigate()
    {
        actionStop->setEnabled(true);
    }

    void MainWindow::on_WebBrowser_NavigateComplete(QString)
    {
        actionStop->setEnabled(false);
    }

Different slots handle the signals emitted by the WebBrowser object.

Connections that don't require any coding, i.e. connecting the `back` action to the `GoBack()` slot, have already been made in Qt Designer.
The following code example is written in c++.

    void MainWindow::on_actionGo_triggered()
    {
        WebBrowser->dynamicCall("Navigate(const QString&)", addressEdit->text());
    }

    void MainWindow::on_actionNewWindow_triggered()
    {
        MainWindow *window = new MainWindow;
        window->show();
        if (addressEdit->text().isEmpty())
    	return;
        window->addressEdit->setText(addressEdit->text());
        window->actionStop->setEnabled(true);
        window->on_actionGo_triggered();
    }

    void MainWindow::on_actionAbout_triggered()
    {
        QMessageBox::about(this, tr("About WebBrowser"),
    		tr("This Example has been created using the ActiveQt integration into Qt Designer.\n"
    		   "It demonstrates the use of QAxWidget to embed the Internet Explorer ActiveX\n"
    		   "control into a Qt application."));
    }

    void MainWindow::on_actionAboutQt_triggered()
    {
        QMessageBox::aboutQt(this, tr("About Qt"));
    }

    void MainWindow::on_actionFileClose_triggered()
    {
        close();
    }

    #include "main.moc"
    static QAbstractEventDispatcher::EventFilter previous_filter = 0;
    HWND gParentWnd = 0;

    bool keyFilterProc(void *m)
    {
        // This filter is required to correct a problem specific to Internet explorer activeX control.
        // The IE activeX translates and processes the backspace & arrow keys in the TranslateAccelerator()
        // function itself. When it receives the corresponding WM_KEYDOWN messages, they are processed once again.
        MSG *msg = (MSG*)m;
        if (msg && gParentWnd && msg->message == WM_KEYDOWN && (msg->wParam == VK_BACK
            || (msg->wParam >= VK_LEFT && msg->wParam <= VK_DOWN))) {
                if (msg->hwnd == gParentWnd || IsChild(gParentWnd, msg->hwnd)) {
                    if (previous_filter)
                        previous_filter(m);
                    return true;
                }
        }
        if (previous_filter)
            return previous_filter(m);
        return false;
    }

    int main(int argc, char ** argv)
    {
        QApplication a(argc, argv);
        MainWindow w;
    #if defined(Q_OS_WINCE)
        w.showMaximized();
    #else
        w.show();
    #endif
        gParentWnd = w.WebBrowser->winId();
        previous_filter = QAbstractEventDispatcher::instance()->setEventFilter(keyFilterProc);
        return a.exec();
    }

The rest of the implementation is not related to ActiveQt - the actions are handled by different slots, and the entry point function starts the application using standard Qt APIs.

To build the example you must first build the QAxContainer library. Then run your make tool in `examples/activeqt/webbrowser` and run the resulting `webbrowser.exe`.