[rkward-cvs] SF.net SVN: rkward:[2518] trunk/rkward/rkward

tfry at users.sourceforge.net tfry at users.sourceforge.net
Fri Jun 5 20:42:07 UTC 2009


Revision: 2518
          http://rkward.svn.sourceforge.net/rkward/?rev=2518&view=rev
Author:   tfry
Date:     2009-06-05 20:42:07 +0000 (Fri, 05 Jun 2009)

Log Message:
-----------
Geometry handling of windows devices works, now. Other things don't, yet.

Modified Paths:
--------------
    trunk/rkward/rkward/qwinhost/README.txt
    trunk/rkward/rkward/qwinhost/qwinhost.cpp
    trunk/rkward/rkward/qwinhost/qwinhost.h
    trunk/rkward/rkward/rbackend/rembedinternal.cpp
    trunk/rkward/rkward/rkwardapplication.cpp
    trunk/rkward/rkward/windows/rkwindowcatcher.cpp

Added Paths:
-----------
    trunk/rkward/rkward/qwinhost/qwinhost.cpp.orig
    trunk/rkward/rkward/qwinhost/qwinhost.h.orig

Modified: trunk/rkward/rkward/qwinhost/README.txt
===================================================================
--- trunk/rkward/rkward/qwinhost/README.txt	2009-06-04 19:58:09 UTC (rev 2517)
+++ trunk/rkward/rkward/qwinhost/README.txt	2009-06-05 20:42:07 UTC (rev 2518)
@@ -1,5 +1,6 @@
-This directory contains the files qwinhost.cpp and qwinhost.h which are part
-of the "Qt/MFC Migration Framework" version 2.8 from Qt solutions.
+The files qwinhost.cpp and qwinhost.h in this directory are derivatives
+of the files of the same names in the "Qt/MFC Migration Framework"
+version 2.8 from Qt solutions.
 http://www.qtsoftware.com/products/appdev/add-on-products/catalog/4/Windows/qtwinmigrate/
 
 These files are
@@ -8,10 +9,18 @@
 
 The applicable licences are contained in this directory in full form.
 
-The files qwinhost.cpp and qwinhost.h are unmodified copies from the
-"Qt/MFC Migration Framework" version 2.8. Nethertheless, since these files are
-usually part of a larger package, this copy must be regarded as a
-modified work. The original copyright holder(s) Nokia Corporation and/or its
+The files qwinhost.cpp.orig and qwinhost.h.orig are unmodified copies from the
+"Qt/MFC Migration Framework" version 2.8. The files qwinhost.cpp and qwinhost.h
+are modified for the needs of this project.
+
+The original copyright holder(s) Nokia Corporation and/or its
 subsidiary(-ies) are not to be held responsible for any malfunctioning. 
 
 These files are used on windows, only.
+
+Changes with respect to the qwinhost.cpp.orig and qwinhost.h.orig:
+
+2009-06-05:
+- Support for auto-destruction of client
+- Notification when client is destroyed
+- Notification when client window title changes
\ No newline at end of file

Modified: trunk/rkward/rkward/qwinhost/qwinhost.cpp
===================================================================
--- trunk/rkward/rkward/qwinhost/qwinhost.cpp	2009-06-04 19:58:09 UTC (rev 2517)
+++ trunk/rkward/rkward/qwinhost/qwinhost.cpp	2009-06-05 20:42:07 UTC (rev 2518)
@@ -53,8 +53,10 @@
 #include "qwinhost.h"
 
 #include <QtCore/QEvent>
-#include <qt_windows.h>
 
+//static
+QMap<HWND, QWinHost*> QWinHost::winhosts;
+
 /*!
     \class QWinHost qwinhost.h
     \brief The QWinHost class provides an API to use native Win32
@@ -87,7 +89,7 @@
     QWidget::setParent or move the QWinHost into a different layout.
 */
 QWinHost::QWinHost(QWidget *parent, Qt::WFlags f)
-: QWidget(parent, f), wndproc(0),own_hwnd(false), hwnd(0)
+: QWidget(parent, f), wndproc(0),auto_destruct(false), hwnd(0)
 {
     setAttribute(Qt::WA_NoBackground);
     setAttribute(Qt::WA_NoSystemBackground);
@@ -116,10 +118,23 @@
 #endif
     }
 
-    if (hwnd && own_hwnd)
+    if (hwnd) {
+	winhosts.remove(hwnd);
+    }
+
+    if (hwnd && isAutoDestruct()) {
+	setAutoDestruct(false);
+	SendMessage(hwnd, WM_CLOSE, 0, 0);
 	DestroyWindow(hwnd);
+qDebug ("destruct");
+    }
 }
 
+// static
+QWinHost *QWinHost::findHost (HWND client) {
+	return (winhosts.value(client));
+}
+
 /*!
     Reimplement this virtual function to create and return the native
     Win32 window. \a parent is the handle to this widget, and \a
@@ -143,46 +158,21 @@
     return 0;
 }
 
-/*!
-    Ensures that the window provided a child of this widget, unless
-    it is a WS_OVERLAPPED window.
-*/
-void QWinHost::fixParent()
-{
-    if (!hwnd)
-        return;
-    if (!::IsWindow(hwnd)) {
-        hwnd = 0;
-        return;
-    }
-    if (::GetParent(hwnd) == winId())
-        return;
-    long style = GetWindowLong(hwnd, GWL_STYLE);
-    if (style & WS_OVERLAPPED)
-        return;
-    ::SetParent(hwnd, winId());
-}
 
 /*!
     Sets the native Win32 window to \a window. If \a window is not a child 
     window of this widget, then it is reparented to become one. If \a window 
     is not a child window (i.e. WS_OVERLAPPED is set), then this function does nothing.
 
-    The lifetime of the window handle will be managed by Windows, QWinHost does not
-    call DestroyWindow. To verify that the handle is destroyed when expected, handle
-    WM_DESTROY in the window procedure.
-
-    \sa window(), createWindow()
+    \sa window(), createWindow(), setAutoDestruct()
 */
 void QWinHost::setWindow(HWND window)
 {
-    if (hwnd && own_hwnd)
+    if (hwnd && isAutoDestruct())
 	DestroyWindow(hwnd);
 
     hwnd = window;
     fixParent();
-
-    own_hwnd = false;
 }
 
 /*!
@@ -196,44 +186,83 @@
     return hwnd;
 }
 
+/*!
+    \see setAutoDestruct()
+*/
+bool QWinHost::isAutoDestruct() const
+{
+    return auto_destruct;
+}
+
+/*!
+    \a destruct if this is false (the default), the lifetime of the window handle
+    will be managed by Windows, QWinHost does not
+    call DestroyWindow. To verify that the handle is destroyed when expected, handle
+    WM_DESTROY in the window procedure. If \a destruct is true, the client window
+    will be destroyed, when this window is destroyed.
+
+    For windows created by createWindow(), this is set to true, else the default is false.
+
+    \sa isAutoDestruct()
+ */
+void QWinHost::setAutoDestruct(bool destruct)
+{
+    auto_destruct = destruct;
+}
+
 void *getWindowProc(QWinHost *host)
 {
     return host ? host->wndproc : 0;
 }
 
+bool QWinHost::handleWindowCallback (HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) {
+qDebug ("%p, %x, %x, %x", hwnd, msg, wParam, lParam);
+	switch(msg) {
+		case WM_LBUTTONDOWN:
+			if (::GetFocus() != hwnd && (focusPolicy() & Qt::ClickFocus)) {
+#warning TODO: async handling!
+				setFocus(Qt::MouseFocusReason);
+			}
+			break;
+
+		case WM_SYSKEYDOWN:
+		case WM_SYSKEYUP:
+			QT_WA({
+				SendMessage(winId(), msg, wParam, lParam);
+			}, {
+				SendMessageA(winId(), msg, wParam, lParam);
+			})
+			break;
+
+		case WM_KEYDOWN:
+			if (wParam == VK_TAB) {
+			QT_WA({
+				SendMessage(winId(), msg, wParam, lParam);
+			}, {
+				SendMessageA(winId(), msg, wParam, lParam);
+			})
+			}
+			break;
+		case WM_SETTEXT:
+			clientTitleChanged((char *) lParam);
+			break;
+		case WM_DESTROY:
+qDebug ("client destruct");
+			clientDestroyed();
+			break;
+		default:
+			break;
+	}
+}
+
+
 LRESULT CALLBACK WinHostProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
 {
-    QWinHost *widget = qobject_cast<QWinHost*>(QWidget::find(::GetParent(hwnd)));
+    QWinHost *widget = QWinHost::findHost(hwnd);
     WNDPROC oldproc = (WNDPROC)getWindowProc(widget);
     if (widget) {
-	switch(msg) {
-	case WM_LBUTTONDOWN:
-	    if (::GetFocus() != hwnd && (widget->focusPolicy() & Qt::ClickFocus)) {
-		widget->setFocus(Qt::MouseFocusReason);
-	    }
-	    break;
-
-	case WM_SYSKEYDOWN:
-	case WM_SYSKEYUP:
-	    QT_WA({
-		SendMessage(widget->winId(), msg, wParam, lParam);
-	    }, {
-		SendMessageA(widget->winId(), msg, wParam, lParam);
-	    })
-	    break;
-
-	case WM_KEYDOWN:
-	    if (wParam == VK_TAB) {
-		QT_WA({
-		    SendMessage(widget->winId(), msg, wParam, lParam);
-		}, {
-		    SendMessageA(widget->winId(), msg, wParam, lParam);
-		})
-	    }
-	    break;
-
-	default:
-	    break;
+	if (!widget->handleWindowCallback (hwnd, msg, wParam, lParam)) {
+		return 0;
 	}
     }
 
@@ -249,18 +278,26 @@
 }
 
 /*!
-    \reimp
+    Ensures that the window provided a child of this widget, unless
+    it is a WS_OVERLAPPED window.
 */
-bool QWinHost::event(QEvent *e)
+void QWinHost::fixParent()
 {
-    switch(e->type()) {
-    case QEvent::Polish:
-        if (!hwnd) {
-            hwnd = createWindow(winId(), qWinAppInst());
-            fixParent();
-            own_hwnd = hwnd != 0;
-        }
-        if (hwnd && !wndproc && GetParent(hwnd) == winId()) {
+    if (!hwnd)
+        return;
+    if (!::IsWindow(hwnd)) {
+        hwnd = 0;
+        return;
+    }
+    if (::GetParent(hwnd) == winId())
+        return;
+    long style = GetWindowLong(hwnd, GWL_STYLE);
+    if (style & WS_OVERLAPPED)
+        return;
+    ::SetParent(hwnd, winId());
+
+    winhosts.insert(hwnd, this);
+
 #if defined(GWLP_WNDPROC)
             QT_WA({
                 wndproc = (void*)GetWindowLongPtr(hwnd, GWLP_WNDPROC);
@@ -279,14 +316,21 @@
             })
 #endif
 
-            LONG style;
-            QT_WA({
-                style = GetWindowLong(hwnd, GWL_STYLE);
-            }, {
-                style = GetWindowLongA(hwnd, GWL_STYLE);
-            })
             if (style & WS_TABSTOP)
                 setFocusPolicy(Qt::FocusPolicy(focusPolicy() | Qt::StrongFocus));
+}
+
+/*!
+    \reimp
+*/
+bool QWinHost::event(QEvent *e)
+{
+    switch(e->type()) {
+    case QEvent::Polish:
+        if (!hwnd) {
+            hwnd = createWindow(winId(), qWinAppInst());
+            fixParent();
+            setAutoDestruct(hwnd != 0);
         }
         break;
     case QEvent::WindowBlocked:

Copied: trunk/rkward/rkward/qwinhost/qwinhost.cpp.orig (from rev 2516, trunk/rkward/rkward/qwinhost/qwinhost.cpp)
===================================================================
--- trunk/rkward/rkward/qwinhost/qwinhost.cpp.orig	                        (rev 0)
+++ trunk/rkward/rkward/qwinhost/qwinhost.cpp.orig	2009-06-05 20:42:07 UTC (rev 2518)
@@ -0,0 +1,355 @@
+/****************************************************************************
+**
+** This file is part of a Qt Solutions component.
+** 
+** Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** 
+** Contact:  Qt Software Information (qt-info at nokia.com)
+** 
+** Commercial Usage  
+** Licensees holding valid Qt Commercial licenses may use this file in
+** accordance with the Qt Solutions Commercial License Agreement provided
+** with the Software or, alternatively, in accordance with the terms
+** contained in a written agreement between you and Nokia.
+** 
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file.  Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+** 
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+** 
+** GNU General Public License Usage 
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file.  Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+** 
+** Please note Third Party Software included with Qt Solutions may impose
+** additional restrictions and it is the user's responsibility to ensure
+** that they have met the licensing requirements of the GPL, LGPL, or Qt
+** Solutions Commercial license and the relevant license of the Third
+** Party Software they are using.
+** 
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales at nokia.com.
+** 
+****************************************************************************/
+
+// Implementation of the QWinHost classes
+
+#ifdef QT3_SUPPORT
+#undef QT3_SUPPORT
+#endif
+
+#include "qwinhost.h"
+
+#include <QtCore/QEvent>
+#include <qt_windows.h>
+
+/*!
+    \class QWinHost qwinhost.h
+    \brief The QWinHost class provides an API to use native Win32
+    windows in Qt applications.
+
+    QWinHost exists to provide a QWidget that can act as a parent for
+    any native Win32 control. Since QWinHost is a proper QWidget, it
+    can be used as a toplevel widget (e.g. 0 parent) or as a child of
+    any other QWidget.
+
+    QWinHost integrates the native control into the Qt user interface,
+    e.g. handles focus switches and laying out.
+
+    Applications moving to Qt may have custom Win32 controls that will
+    take time to rewrite with Qt. Such applications can use these
+    custom controls as children of QWinHost widgets. This allows the
+    application's user interface to be replaced gradually.
+
+    When the QWinHost is destroyed, and the Win32 window hasn't been
+    set with setWindow(), the window will also be destroyed.
+*/
+
+/*!
+    Creates an instance of QWinHost. \a parent and \a f are
+    passed on to the QWidget constructor. The widget has by default
+    no background.
+
+    \warning You cannot change the parent widget of the QWinHost instance 
+    after the native window has been created, i.e. do not call 
+    QWidget::setParent or move the QWinHost into a different layout.
+*/
+QWinHost::QWinHost(QWidget *parent, Qt::WFlags f)
+: QWidget(parent, f), wndproc(0),own_hwnd(false), hwnd(0)
+{
+    setAttribute(Qt::WA_NoBackground);
+    setAttribute(Qt::WA_NoSystemBackground);
+}
+
+/*!
+    Destroys the QWinHost object. If the hosted Win32 window has not
+    been set explicitly using setWindow() the window will be
+    destroyed.
+*/
+QWinHost::~QWinHost()
+{
+    if (wndproc) {
+#if defined(GWLP_WNDPROC)
+	QT_WA({
+	    SetWindowLongPtr(hwnd, GWLP_WNDPROC, (LONG_PTR)wndproc);
+	},{
+	    SetWindowLongPtrA(hwnd, GWLP_WNDPROC, (LONG_PTR)wndproc);
+	})
+#else
+	QT_WA({
+	    SetWindowLong(hwnd, GWL_WNDPROC, (LONG)wndproc);
+	},{
+	    SetWindowLongA(hwnd, GWL_WNDPROC, (LONG)wndproc);
+	})
+#endif
+    }
+
+    if (hwnd && own_hwnd)
+	DestroyWindow(hwnd);
+}
+
+/*!
+    Reimplement this virtual function to create and return the native
+    Win32 window. \a parent is the handle to this widget, and \a
+    instance is the handle to the application instance. The returned HWND
+    must be a child of the \a parent HWND.
+
+    The default implementation returns null. The window returned by a
+    reimplementation of this function is owned by this QWinHost
+    instance and will be destroyed in the destructor.
+
+    This function is called by the implementation of polish() if no
+    window has been set explicitly using setWindow(). Call polish() to
+    force this function to be called.
+
+    \sa setWindow()
+*/
+HWND QWinHost::createWindow(HWND parent, HINSTANCE instance)
+{
+    Q_UNUSED(parent);
+    Q_UNUSED(instance);
+    return 0;
+}
+
+/*!
+    Ensures that the window provided a child of this widget, unless
+    it is a WS_OVERLAPPED window.
+*/
+void QWinHost::fixParent()
+{
+    if (!hwnd)
+        return;
+    if (!::IsWindow(hwnd)) {
+        hwnd = 0;
+        return;
+    }
+    if (::GetParent(hwnd) == winId())
+        return;
+    long style = GetWindowLong(hwnd, GWL_STYLE);
+    if (style & WS_OVERLAPPED)
+        return;
+    ::SetParent(hwnd, winId());
+}
+
+/*!
+    Sets the native Win32 window to \a window. If \a window is not a child 
+    window of this widget, then it is reparented to become one. If \a window 
+    is not a child window (i.e. WS_OVERLAPPED is set), then this function does nothing.
+
+    The lifetime of the window handle will be managed by Windows, QWinHost does not
+    call DestroyWindow. To verify that the handle is destroyed when expected, handle
+    WM_DESTROY in the window procedure.
+
+    \sa window(), createWindow()
+*/
+void QWinHost::setWindow(HWND window)
+{
+    if (hwnd && own_hwnd)
+	DestroyWindow(hwnd);
+
+    hwnd = window;
+    fixParent();
+
+    own_hwnd = false;
+}
+
+/*!
+    Returns the handle to the native Win32 window, or null if no
+    window has been set or created yet.
+
+    \sa setWindow(), createWindow()
+*/
+HWND QWinHost::window() const
+{
+    return hwnd;
+}
+
+void *getWindowProc(QWinHost *host)
+{
+    return host ? host->wndproc : 0;
+}
+
+LRESULT CALLBACK WinHostProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
+{
+    QWinHost *widget = qobject_cast<QWinHost*>(QWidget::find(::GetParent(hwnd)));
+    WNDPROC oldproc = (WNDPROC)getWindowProc(widget);
+    if (widget) {
+	switch(msg) {
+	case WM_LBUTTONDOWN:
+	    if (::GetFocus() != hwnd && (widget->focusPolicy() & Qt::ClickFocus)) {
+		widget->setFocus(Qt::MouseFocusReason);
+	    }
+	    break;
+
+	case WM_SYSKEYDOWN:
+	case WM_SYSKEYUP:
+	    QT_WA({
+		SendMessage(widget->winId(), msg, wParam, lParam);
+	    }, {
+		SendMessageA(widget->winId(), msg, wParam, lParam);
+	    })
+	    break;
+
+	case WM_KEYDOWN:
+	    if (wParam == VK_TAB) {
+		QT_WA({
+		    SendMessage(widget->winId(), msg, wParam, lParam);
+		}, {
+		    SendMessageA(widget->winId(), msg, wParam, lParam);
+		})
+	    }
+	    break;
+
+	default:
+	    break;
+	}
+    }
+
+    QT_WA({
+	if (oldproc)
+	    return CallWindowProc(oldproc, hwnd, msg, wParam, lParam);
+	return DefWindowProc(hwnd,msg,wParam,lParam);
+    }, {
+	if (oldproc)
+	    return CallWindowProcA(oldproc, hwnd, msg, wParam, lParam);
+	return DefWindowProcA(hwnd,msg,wParam,lParam);
+    })
+}
+
+/*!
+    \reimp
+*/
+bool QWinHost::event(QEvent *e)
+{
+    switch(e->type()) {
+    case QEvent::Polish:
+        if (!hwnd) {
+            hwnd = createWindow(winId(), qWinAppInst());
+            fixParent();
+            own_hwnd = hwnd != 0;
+        }
+        if (hwnd && !wndproc && GetParent(hwnd) == winId()) {
+#if defined(GWLP_WNDPROC)
+            QT_WA({
+                wndproc = (void*)GetWindowLongPtr(hwnd, GWLP_WNDPROC);
+                SetWindowLongPtr(hwnd, GWLP_WNDPROC, (LONG_PTR)WinHostProc);
+            }, {
+                wndproc = (void*)GetWindowLongPtrA(hwnd, GWLP_WNDPROC);
+                SetWindowLongPtrA(hwnd, GWLP_WNDPROC, (LONG_PTR)WinHostProc);
+            })
+#else
+                QT_WA({
+                wndproc = (void*)GetWindowLong(hwnd, GWL_WNDPROC);
+                SetWindowLong(hwnd, GWL_WNDPROC, (LONG)WinHostProc);
+            }, {
+                wndproc = (void*)GetWindowLongA(hwnd, GWL_WNDPROC);
+                SetWindowLongA(hwnd, GWL_WNDPROC, (LONG)WinHostProc);
+            })
+#endif
+
+            LONG style;
+            QT_WA({
+                style = GetWindowLong(hwnd, GWL_STYLE);
+            }, {
+                style = GetWindowLongA(hwnd, GWL_STYLE);
+            })
+            if (style & WS_TABSTOP)
+                setFocusPolicy(Qt::FocusPolicy(focusPolicy() | Qt::StrongFocus));
+        }
+        break;
+    case QEvent::WindowBlocked:
+        if (hwnd)
+            EnableWindow(hwnd, false);
+        break;
+    case QEvent::WindowUnblocked:
+        if (hwnd)
+            EnableWindow(hwnd, true);
+        break;
+    }
+    return QWidget::event(e);
+}
+
+/*!
+    \reimp
+*/
+void QWinHost::showEvent(QShowEvent *e)
+{
+    QWidget::showEvent(e);
+
+    if (hwnd)
+	SetWindowPos(hwnd, HWND_TOP, 0, 0, width(), height(), SWP_SHOWWINDOW);
+}
+
+/*!
+    \reimp
+*/
+void QWinHost::focusInEvent(QFocusEvent *e)
+{
+    QWidget::focusInEvent(e);
+
+    if (hwnd)
+	::SetFocus(hwnd);
+}
+
+/*!
+    \reimp
+*/
+void QWinHost::resizeEvent(QResizeEvent *e)
+{
+    QWidget::resizeEvent(e);
+
+    if (hwnd)
+	SetWindowPos(hwnd, HWND_TOP, 0, 0, width(), height(), 0);
+}
+
+/*!
+    \reimp
+*/
+bool QWinHost::winEvent(MSG *msg, long *result)
+{
+    switch (msg->message)
+    {
+    case WM_SETFOCUS:
+        if (hwnd) {
+            ::SetFocus(hwnd);
+            return true;
+        }
+    default:
+        break;
+    }
+
+    return QWidget::winEvent(msg, result);
+}
+

Modified: trunk/rkward/rkward/qwinhost/qwinhost.h
===================================================================
--- trunk/rkward/rkward/qwinhost/qwinhost.h	2009-06-04 19:58:09 UTC (rev 2517)
+++ trunk/rkward/rkward/qwinhost/qwinhost.h	2009-06-05 20:42:07 UTC (rev 2518)
@@ -51,6 +51,8 @@
 #define QWINHOST_H
 
 #include <QtGui/QWidget>
+#include <QtCore/QMap>
+#include <qt_windows.h>
 
 #if defined(Q_WS_WIN)
 #  if !defined(QT_QTWINMIGRATE_EXPORT) && !defined(QT_QTWINMIGRATE_IMPORT)
@@ -78,6 +80,15 @@
     void setWindow(HWND);
     HWND window() const;
 
+    bool isAutoDestruct() const;
+    void setAutoDestruct(bool);
+
+    static QWinHost *findHost(HWND);
+
+    virtual bool handleWindowCallback (HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam);
+signals:
+    void clientDestroyed();
+    void clientTitleChanged(const QString& new_title);
 protected:
     virtual HWND createWindow(HWND parent, HINSTANCE instance);
 
@@ -93,8 +104,10 @@
     friend void* getWindowProc(QWinHost*);
 
     void *wndproc;
-    bool own_hwnd;
+    bool auto_destruct;
     HWND hwnd;
+
+    static QMap<HWND, QWinHost*> winhosts;
 };
 
 #endif // QWINHOST_H

Copied: trunk/rkward/rkward/qwinhost/qwinhost.h.orig (from rev 2516, trunk/rkward/rkward/qwinhost/qwinhost.h)
===================================================================
--- trunk/rkward/rkward/qwinhost/qwinhost.h.orig	                        (rev 0)
+++ trunk/rkward/rkward/qwinhost/qwinhost.h.orig	2009-06-05 20:42:07 UTC (rev 2518)
@@ -0,0 +1,100 @@
+/****************************************************************************
+**
+** This file is part of a Qt Solutions component.
+** 
+** Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** 
+** Contact:  Qt Software Information (qt-info at nokia.com)
+** 
+** Commercial Usage  
+** Licensees holding valid Qt Commercial licenses may use this file in
+** accordance with the Qt Solutions Commercial License Agreement provided
+** with the Software or, alternatively, in accordance with the terms
+** contained in a written agreement between you and Nokia.
+** 
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file.  Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+** 
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+** 
+** GNU General Public License Usage 
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file.  Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+** 
+** Please note Third Party Software included with Qt Solutions may impose
+** additional restrictions and it is the user's responsibility to ensure
+** that they have met the licensing requirements of the GPL, LGPL, or Qt
+** Solutions Commercial license and the relevant license of the Third
+** Party Software they are using.
+** 
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales at nokia.com.
+** 
+****************************************************************************/
+
+
+// Declaration of the QWinHost classes
+
+#ifndef QWINHOST_H
+#define QWINHOST_H
+
+#include <QtGui/QWidget>
+
+#if defined(Q_WS_WIN)
+#  if !defined(QT_QTWINMIGRATE_EXPORT) && !defined(QT_QTWINMIGRATE_IMPORT)
+#    define QT_QTWINMIGRATE_EXPORT
+#  elif defined(QT_QTWINMIGRATE_IMPORT)
+#    if defined(QT_QTWINMIGRATE_EXPORT)
+#      undef QT_QTWINMIGRATE_EXPORT
+#    endif
+#    define QT_QTWINMIGRATE_EXPORT __declspec(dllimport)
+#  elif defined(QT_QTWINMIGRATE_EXPORT)
+#    undef QT_QTWINMIGRATE_EXPORT
+#    define QT_QTWINMIGRATE_EXPORT __declspec(dllexport)
+#  endif
+#else
+#  define QT_QTWINMIGRATE_EXPORT
+#endif
+
+class QT_QTWINMIGRATE_EXPORT QWinHost : public QWidget
+{
+    Q_OBJECT
+public:
+    QWinHost(QWidget *parent = 0, Qt::WFlags f = 0);
+    ~QWinHost();
+
+    void setWindow(HWND);
+    HWND window() const;
+
+protected:
+    virtual HWND createWindow(HWND parent, HINSTANCE instance);
+
+    bool event(QEvent *e);
+    void showEvent(QShowEvent *);
+    void focusInEvent(QFocusEvent*);
+    void resizeEvent(QResizeEvent*);
+
+    bool winEvent(MSG *msg, long *result);
+
+private:
+    void fixParent();
+    friend void* getWindowProc(QWinHost*);
+
+    void *wndproc;
+    bool own_hwnd;
+    HWND hwnd;
+};
+
+#endif // QWINHOST_H

Modified: trunk/rkward/rkward/rbackend/rembedinternal.cpp
===================================================================
--- trunk/rkward/rkward/rbackend/rembedinternal.cpp	2009-06-04 19:58:09 UTC (rev 2517)
+++ trunk/rkward/rkward/rbackend/rembedinternal.cpp	2009-06-05 20:42:07 UTC (rev 2518)
@@ -455,22 +455,7 @@
 	if (!r_running) return;		// already shut down
 	r_running = false;
 
-// Code-recipe below essentially copied from http://stat.ethz.ch/R-manual/R-devel/doc/manual/R-exts.html#Linking-GUIs-and-other-front_ends-to-R
-// modified quite a bit for our needs.
-
-	if (!suicidal) {
-		R_dot_Last ();
-	}
-
-	R_RunExitFinalizers();
-
-	R_CleanTempDir ();
-
-	/* close all the graphics devices */
-	if (!suicidal) Rf_KillAllDevices ();
-#ifndef Q_WS_WIN
-	fpu_setup ((Rboolean) FALSE);
-#endif
+	Rf_endEmbeddedR (suicidal);
 }
 
 #if 0

Modified: trunk/rkward/rkward/rkwardapplication.cpp
===================================================================
--- trunk/rkward/rkward/rkwardapplication.cpp	2009-06-04 19:58:09 UTC (rev 2517)
+++ trunk/rkward/rkward/rkwardapplication.cpp	2009-06-05 20:42:07 UTC (rev 2518)
@@ -52,24 +52,6 @@
 		toplevel_windows.clear ();
 		EnumWindows (EnumWindowsCallback, 0);
 	};
-
-// TODO: this is a test, only
-	BOOL CALLBACK ChildWindowCallback (HWND hwnd, LPARAM) {
-		WINDOWINFO info;
-		info.cbSize = sizeof (WINDOWINFO);
-		GetWindowInfo (hwnd, &info);
-qDebug ("%p: rect: %d, %d, %d, %d, client: %d, %d, %d, %d, style: %d, exstyle: %d, status: %d, borders: %d %d", hwnd,
-		info.rcWindow.left, info.rcWindow.top, info.rcWindow.right, info.rcWindow.bottom,
-		info.rcClient.left, info.rcClient.top, info.rcClient.right, info.rcClient.bottom,
-		info.dwStyle, info.dwExStyle, info.dwWindowStatus, info.cxWindowBorders, info.cyWindowBorders);
-
-		return true;
-	}
-
-	void showWindowChildren (HWND hwnd) {
-		ChildWindowCallback (hwnd, 0);
-		EnumChildWindows (hwnd, ChildWindowCallback, 0);
-	}
 }
 #endif	//Q_WS_WIN
 
@@ -136,10 +118,7 @@
 
 	if (candidate_windows.size ()) {
 		RK_ASSERT (candidate_windows.size () < 2);
-		for (int i = 0; i < candidate_windows.size (); ++i) {
-			qDebug ("candidate: %d", i);
-			RKWardApplicationPrivate::showWindowChildren (candidate_windows[i]);
-		}
+#warning TODO: the above assert fails. More windows get created. Sieve out the invisible ones, first?
 		return candidate_windows[0];
 	}	// else
 	return 0;

Modified: trunk/rkward/rkward/windows/rkwindowcatcher.cpp
===================================================================
--- trunk/rkward/rkward/windows/rkwindowcatcher.cpp	2009-06-04 19:58:09 UTC (rev 2517)
+++ trunk/rkward/rkward/windows/rkwindowcatcher.cpp	2009-06-05 20:42:07 UTC (rev 2518)
@@ -69,6 +69,7 @@
 #include <qlabel.h>
 #ifdef Q_WS_WIN
 #	include "../qwinhost/qwinhost.h"
+#	include <windows.h>
 #else
 #	include <QX11EmbedContainer>
 #endif
@@ -108,17 +109,30 @@
 	layout->addWidget (scroll_widget);
 
 	xembed_container = new KVBox (box_widget);	// QX11EmbedContainer can not be reparented (between the box_widget, and the scroll_widget) directly. Therefore we place it into a container, and reparent that instead
-	dynamic_size = true;
-	dynamic_size_action->setChecked (true);
 
 #ifdef Q_WS_WIN
-#	warning TODO: set geometry
+	// unfortunately, trying to get KWindowInfo as below hangs on windows (KDElibs 4.2.3)
+	WINDOWINFO wininfo;
+	wininfo.cbSize = sizeof (WINDOWINFO);
+	GetWindowInfo (embedded, &wininfo);
+
+	// clip off the window frame and menubar
+	xembed_container->setContentsMargins (wininfo.rcWindow.left - wininfo.rcClient.left, wininfo.rcWindow.top - wininfo.rcClient.top,
+				wininfo.rcClient.right - wininfo.rcWindow.right, wininfo.rcClient.bottom - wininfo.rcWindow.bottom);
+	// set a fixed size until the window is shown
+	xembed_container->setFixedSize (wininfo.rcClient.right - wininfo.rcClient.left, wininfo.rcClient.bottom - wininfo.rcClient.top);
+	move (wininfo.rcClient.left, wininfo.rcClient.top);
 #else
-	KWindowInfo wininfo = KWindowSystem::windowInfo (embedded, NET::WMName | NET::WMFrameExtents);
+	KWindowInfo wininfo = KWindowSystem::windowInfo (embedded, NET::WMName | NET::WMGeometry);
 	RK_ASSERT (wininfo.valid ());
-	setGeometry (wininfo.frameGeometry ());
+
+	// set a fixed size until the window is shown
+	xembed_container->setFixedSize (wininfo.geometry ().width (), wininfo.geometry ().height ());
+	move (wininfo.geometry ().topLeft());
 	setCaption (wininfo.name ());
 #endif
+	dynamic_size = false;
+	dynamic_size_action->setChecked (false);
 
 	// somehow in Qt 4.4.3, when the RKCaughtWindow is reparented the first time, the QX11EmbedContainer may kill its client. Hence we delay the actual embedding until after the window was shown.
 	// In some previous version of Qt, this was not an issue, but I did not track the versions.
@@ -131,15 +145,22 @@
 	RK_TRACE (MISC);
 
 #ifdef Q_WS_WIN
+#	warning TODO: set name
 	capture = new QWinHost (xembed_container);
 	capture->setWindow (embedded);
-#	warning TODO: deletion
+	capture->setAutoDestruct (true);
+	connect (capture, SIGNAL (clientDestroyed()), this, SLOT (deleteLater()), Qt::QueuedConnection);
+	connect (capture, SIGNAL (clientTitleChanged(const QString&)), this, SLOT (setWindowTitle(const QString&)), Qt::QueuedConnection);
 #else
 	capture = new QX11EmbedContainer (xembed_container);
+
 	capture->embedClient (embedded);
 
 	connect (capture, SIGNAL (clientClosed ()), this, SLOT (deleteLater ()));
 #endif
+	// make xembed_container resizable, again, now that it actually has a content
+	dynamic_size_action->setChecked (true);
+	fixedSizeToggled ();
 }
 
 RKCaughtX11Window::~RKCaughtX11Window () {


This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.




More information about the rkward-tracker mailing list