Использование Windows API в Qt


Оглавление

Программа, окно которой показано на рисунке, демонстрирует возможность использования для графического вывода в ОС Windows функций GDI (Graphical Device Interface, интерфейс графического устройства). При нажатии правой кнопки мыши в области окна приложения производится вызов окна сообщения посредством Windows API.

{рисунок}


class WinAPI : public QWidget {
protected:
    virtual bool winEvent(MSG* pmsg, long* result)
    {
        QString str1 = "Windows Version = " 
                       + QString::number(QSysInfo::WindowsVersion);
        QString str2 = "Windows Message";

        switch(pmsg->message) {
        case WM_RBUTTONDOWN:
            ::MessageBox(winId(), 
                         (const WCHAR*)str1.utf16(), 
                         (const WCHAR*)str2.utf16(),
                         MB_OK | MB_ICONEXCLAMATION
                        );
            break;
        default:
            ;
        }
        return QWidget::winEvent(pmsg, result);
    }

    virtual void paintEvent(QPaintEvent*)
    {
        QPainter painter(this);

        HDC        hdc    = painter.paintEngine()->getDC();
        HBRUSH     hBrush = ::CreateSolidBrush(RGB(255, 0, 255));
        HPEN       hPen   = ::CreatePen(PS_SOLID, 2, RGB(0, 0, 128));
        QString    str    = "GDI Drawing";
        TEXTMETRIC tm;     

        ::GetTextMetrics(hdc, &tm);
        ::SelectObject(hdc, hBrush);
        ::SelectObject(hdc, hPen);
        ::Ellipse(hdc, 0, 0, width(), height());
        ::TextOut(hdc, 
                  width() / 2 - (tm.tmAveCharWidth * str.length()) / 2, 
                  (height() - tm.tmHeight) / 2, 
                  (const WCHAR*)str.utf16(), 
                  str.length()
                 );
        ::DeleteObject(hBrush);
        ::DeleteObject(hPen);
        painter.paintEngine()->releaseDC(hdc);
    }

public:
    WinAPI(QWidget* pwgt = 0) : QWidget(pwgt) 
    {
    }
};

Выше приведен специальный метод обработки событий для ОС Windows — winEvent(). Если не требуется дальнейшей обработки события с помощью Qt, то из этого метода нужно вернуть значение true. Реализация этого метода, по своей сути, очень похожа на реализацию оконной функции ОС Windows. В нашем случае производится отслеживание события нажатия правой кнопки мыши и, в случае нажатия, вызывается функция MessageBox() из Windows API, отображающая окно сообщения. Первым параметром в эту функцию, в качестве родительского окна, передается значение, возвращаемое методом winId(). Метод поддерживается для всех платформ и, в случае ОС Windows, возвращает идентификационный номер окна, соответствующий типу hwnd (указатель на окно).

В методе события перерисовки paintEvent() производится отображение надписи и эллипса при помощи функций GDI. Обратите внимание на вызов метода getDC() объекта класса QPaintEngine. Он возвращает значение типа hdc (указатель на Device Context, контекст устройства), которое нужно для функций GDI, чтобы они могли проводить рисование. По окончании рисования мы вызываем из объекта QPaintEngine метод releaseDC(), в который передаем наш дескриптор контекста GDI (переменная hdc) для его закрытия.

Так же, как и в случае ОС Windows, в UNIX Qt предоставляет возможность доступа к событиям на низком уровне. Класс QWidget содержит метод x11Event(), который необходим для получения событий оконной системы X Window. Чтобы получать события, этот метод нужно просто перезаписать.

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

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

Читать далее: Проведение тестов