Qt Application using Win32 Windows
This examples shows how to use the QWinHost class to use a native Win32 window inside a Qt based user interface.
class HostWindow : public QWinHost { Q_OBJECT public: HostWindow(QWidget *parent = 0, Qt::WFlags f = 0) : QWinHost(parent, f) { setFocusPolicy(Qt::StrongFocus); } HWND createWindow(HWND parent, HINSTANCE instance) { static ATOM windowClass = 0; if (!windowClass) { WNDCLASSEX wcex; wcex.cbSize = sizeof(WNDCLASSEX); wcex.style = CS_HREDRAW | CS_VREDRAW; wcex.lpfnWndProc = (WNDPROC)WndProc; wcex.cbClsExtra = 0; wcex.cbWndExtra = 0; wcex.hInstance = instance; wcex.hIcon = NULL; wcex.hCursor = LoadCursor(NULL, IDC_ARROW); wcex.hbrBackground = (HBRUSH)(COLOR_WINDOW+1); wcex.lpszMenuName = NULL; wcex.lpszClassName = L"qtest"; wcex.hIconSm = NULL; windowClass = RegisterClassEx(&wcex); } HWND hwnd = CreateWindow((TCHAR*)windowClass, 0, WS_CHILD|WS_CLIPSIBLINGS|WS_TABSTOP, CW_USEDEFAULT, 0, CW_USEDEFAULT, 0, parent, NULL, instance, NULL); return hwnd; }
The HostWindow class is a subclass of QWinHost and reimplements the virtual function QWinHost::createWindow() to register a Win32 window class using the RegisterClassEx API, and to create a window using the CreateWindow API. Note that the UNICODE version of all Win32 APIs is used.
signals: void message(const QString &msg, int timeout); public slots: void returnPressed() { QMessageBox::information(topLevelWidget(), "Message from Qt", "Return pressed in QLineEdit!"); }
The class implements a signal message to report status changes.
protected: static LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) { QWidget *widget = QWidget::find(GetParent(hWnd)); HostWindow *window = qobject_cast<HostWindow*>(widget);
The static WndProc function implements the message handling of the Win32 window. Since the method is static we have to use QWidget::find() to get the QWidget object for the window handle. Since we want to use the signal of the HostWindow class, which is the parent window of the native Win32 window, we have to cast the QWidget pointer to HostWindow, which is safe when using qobject_cast().
if (window) switch (message) { case WM_SETFOCUS: window->message("SetFocus for Win32 window!", 1000); break; case WM_KILLFOCUS: window->message("KillFocus for Win32 window!", 1000); break; case WM_MOUSEMOVE: window->message("Moving the mouse, aren't we?", 200); break; case WM_KEYDOWN: if (wParam != VK_TAB) window->message("Key Pressed!", 500); break; default: return DefWindowProc(hWnd, message, wParam, lParam); } return 0; } };
The message is then handled in the switch statement. Unhandled messages are passed on to the default window procedure.
#include "main.moc" int main(int argc, char **argv) { QApplication a(argc, argv); QMainWindow mw; mw.menuBar()->addMenu("&File")->addAction("&Exit", &a, SLOT(quit())); QWidget central(&mw); QLineEdit edit(¢ral); HostWindow host(¢ral); QObject::connect(&host, SIGNAL(message(const QString&,int)), mw.statusBar(), SLOT(showMessage(const QString&,int))); QObject::connect(&edit, SIGNAL(returnPressed()), &host, SLOT(returnPressed())); QVBoxLayout vbox(¢ral); vbox.addWidget(&edit); vbox.addWidget(&host); mw.setCentralWidget(¢ral); mw.show(); return a.exec(); }
The main function creates a standard Qt user interface using QMainWindow. The main window's central widget contains a QLineEdit as well as the HostWindow. Messages sent by the HostWindow object are displayed in the main window's default statusbar.
- ۹۸/۰۸/۲۹