Changeset 99 for trunk/src/gui


Ignore:
Timestamp:
Aug 5, 2009, 3:19:05 AM (16 years ago)
Author:
Dmitry A. Kuminov
Message:

gui: Implemented widget creation/destruction functions.

Location:
trunk/src/gui/kernel
Files:
3 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/gui/kernel/qapplication_pm.cpp

    r98 r99  
    9191static void releaseAutoCapture();
    9292
    93 static void unregWinClasses();
    94 
    9593extern QCursor *qt_grab_cursor();
    9694
    97 extern "C" MRESULT EXPENTRY QtWndProc(HWND, ULONG, MPARAM, MPARAM);
     95MRESULT EXPENTRY QtWndProc(HWND, ULONG, MPARAM, MPARAM);
    9896
    9997class QETWidget : public QWidget                // event translator widget
     
    189187void qt_cleanup()
    190188{
    191     unregWinClasses();
    192189    QPixmapCache::clear();
    193190
     
    224221    return false;
    225222#endif
    226 }
    227 
    228 typedef QSet<QString> WinClassNameHash;
    229 Q_GLOBAL_STATIC(WinClassNameHash, winclassNames)
    230 
    231 // register window class
    232 const QString qt_reg_winclass(QWidget *w)
    233 {
    234     int flags = w->windowFlags();
    235     int type = flags & Qt::WindowType_Mask;
    236 
    237     QString cname;
    238     ULONG style = 0;
    239 
    240     if (type == Qt::Window) {
    241         // this class is for frame window clients when WC_FRAME is used.
    242         cname = QLatin1String("QWindow");
    243         style |= CS_MOVENOTIFY;
    244     } else if (type == Qt::Popup || type == Qt::Tool || type == Qt::ToolTip) {
    245         cname = QLatin1String("QPopup");
    246         // @todo do we really want SAVEBITS here?
    247         style |= CS_SAVEBITS;
    248     } else {
    249         cname = QLatin1String("QWidget");
    250     }
    251 
    252     if (winclassNames()->contains(cname)) // already registered in our list
    253         return cname;
    254 
    255     // QT_EXTRAWINDATASIZE is defined in qwindowdefs_pm.h
    256     WinRegisterClass(0, cname.toLatin1(), QtWndProc, style, QT_EXTRAWINDATASIZE);
    257 
    258     winclassNames()->insert(cname);
    259     return cname;
    260 }
    261 
    262 static void unregWinClasses()
    263 {
    264     // there is no need to unregister private window classes -- it is done
    265     // automatically upon process termination.
    266     winclassNames()->clear();
    267223}
    268224
     
    466422// QtWndProc() receives all messages from the main event loop
    467423
    468 extern "C"
    469424MRESULT EXPENTRY QtWndProc(HWND hwnd, ULONG msg, MPARAM mp1, MPARAM mp2)
     425
     426
     427
     428
     429
     430
     431
     432
    470433{
    471434    // @todo implement
  • trunk/src/gui/kernel/qwidget_p.h

    r95 r99  
    6767#endif // Q_WS_WIN
    6868
     69
     70
     71
     72
    6973#ifdef Q_WS_X11
    7074#include "QtGui/qx11info_x11.h"
     
    150154    HICON winIconSmall; // internal small Windows icon
    151155#endif
     156
     157
     158
    152159    QRect normalGeometry; // used by showMin/maximized/FullScreen
    153160    QWindowSurface *windowSurface;
     
    460467
    461468    QInputContext *inputContext() const;
     469
     470
     471
     472
     473
     474
    462475
    463476#if defined(Q_WS_QWS)
  • trunk/src/gui/kernel/qwidget_pm.cpp

    r95 r99  
    4848
    4949#include "qapplication.h"
     50
    5051
    5152#include "private/qapplication_p.h"
     
    5354#include <qdebug.h>
    5455
     56
     57
    5558QT_BEGIN_NAMESPACE
     59
     60
     61
     62
    5663
    5764// defined in qapplication_pm.cpp
    5865extern bool qt_nograb();
    59 extern const QString qt_reg_winclass(QWidget *w);
    60 extern "C" MRESULT EXPENTRY QtWndProc(HWND, ULONG, MPARAM, MPARAM);
     66extern MRESULT EXPENTRY QtWndProc(HWND, ULONG, MPARAM, MPARAM);
     67extern PFNWP QtOldFrameProc;
     68extern MRESULT EXPENTRY QtFrameProc(HWND, ULONG, MPARAM, MPARAM);
     69
     70typedef QSet<QString> WinClassNameHash;
     71Q_GLOBAL_STATIC(WinClassNameHash, winclassNames)
     72
     73// register window class
     74static const QString qt_reg_winclass(QWidget *w)
     75{
     76    int flags = w->windowFlags();
     77    int type = flags & Qt::WindowType_Mask;
     78
     79    QString cname;
     80    ULONG style = 0;
     81
     82    if (type == Qt::Popup || type == Qt::ToolTip) {
     83        cname = QLatin1String("QPopup");
     84        style |= CS_SAVEBITS;
     85    } else if (w->isWindow()) {
     86        // this class is for top level widgets which are client HWNDs of a
     87        // WC_FRAME parent HWND internally maintaned for them
     88        cname = QLatin1String("QWindow");
     89        style |= CS_MOVENOTIFY;
     90    } else {
     91        cname = QLatin1String("QWidget");
     92    }
     93
     94    if (winclassNames()->contains(cname)) // already registered in our list
     95        return cname;
     96
     97    // QT_EXTRAWINDATASIZE is defined in qwindowdefs_pm.h
     98    WinRegisterClass(0, cname.toLatin1(), QtWndProc, style, QT_EXTRAWINDATASIZE);
     99
     100    winclassNames()->insert(cname);
     101    return cname;
     102
     103    // Note: there is no need to unregister private window classes registered by
     104    // this function -- it is done automatically upon process termination.
     105}
     106
     107/*!
     108 * \internal
     109 * For some unknown reason, PM sends WM_SAVEAPPLICATION to every window
     110 * being destroyed, which makes it indistinguishable from WM_SAVEAPPLICATION
     111 * sent to top level windows during system shutdown. We use our own version of
     112 * WinDestroyWindow() and a special flag (qt_about_to_destroy_wnd) to
     113 * distinguish it in qapplication_pm.cpp.
     114 */
     115static BOOL qt_WinDestroyWindow(HWND hwnd)
     116{
     117#if !defined (QT_NO_SESSIONMANAGER)
     118    qt_about_to_destroy_wnd = true;
     119#endif
     120    BOOL rc = WinDestroyWindow(hwnd);
     121#if !defined (QT_NO_SESSIONMANAGER)
     122    qt_about_to_destroy_wnd = false;
     123#endif
     124    return rc;
     125}
     126
     127static PFNWP QtOldSysMenuProc;
     128static MRESULT EXPENTRY QtSysMenuProc(HWND hwnd, ULONG msg, MPARAM mp1, MPARAM mp2)
     129{
     130    if (msg == WM_MENUEND) {
     131        // the pull-down menu is closed, always dismiss the system menu itself
     132        WinPostMsg(hwnd, MM_ENDMENUMODE, MPFROMSHORT(TRUE), 0);
     133    }
     134    return QtOldSysMenuProc(hwnd, msg, mp1, mp2);
     135}
     136
     137static void removeSysMenuAccels(HWND frame)
     138{
     139    HWND sysMenu = WinWindowFromID(frame, FID_SYSMENU);
     140    if (!sysMenu)
     141        return;
     142
     143    SHORT subId = SHORT1FROMMR(WinSendMsg(sysMenu, MM_ITEMIDFROMPOSITION, 0, 0));
     144    if (subId != MIT_ERROR) {
     145        MENUITEM item;
     146        WinSendMsg(sysMenu, MM_QUERYITEM, MPFROM2SHORT(subId, FALSE), MPFROMP(&item));
     147        HWND subMenu = item.hwndSubMenu;
     148        if (subMenu) {
     149            USHORT cnt = SHORT1FROMMR(WinSendMsg(subMenu, MM_QUERYITEMCOUNT, 0, 0));
     150            for (int i = 0; i < cnt; i++) {
     151                USHORT id = SHORT1FROMMR(
     152                    WinSendMsg(subMenu, MM_ITEMIDFROMPOSITION, MPFROMSHORT(i), 0));
     153                if (id == SC_TASKMANAGER || id == SC_CLOSE) {
     154                    // accels for these entries always work in Qt, skip them
     155                    continue;
     156                }
     157                USHORT len = SHORT1FROMMR(
     158                    WinSendMsg(subMenu, MM_QUERYITEMTEXTLENGTH, MPFROMSHORT(id), 0));
     159                if (len++) {
     160                    char *text = new char[len];
     161                    WinSendMsg(subMenu, MM_QUERYITEMTEXT,
     162                        MPFROM2SHORT(id, len), MPFROMP(text));
     163                    char *tab = strrchr(text, '\t');
     164                    if (tab) {
     165                        *tab = 0;
     166                        WinSendMsg(subMenu, MM_SETITEMTEXT,
     167                            MPFROMSHORT(id), MPFROMP(text));
     168                    }
     169                    delete[] text;
     170                }
     171            }
     172            // sublclass the system menu to leave the menu mode completely
     173            // when the user presses the ESC key. by default, pressing ESC
     174            // while the pull-down menu is showing brings us to the menu bar,
     175            // which is confusing in the case of the system menu, because
     176            // there is only one item on the menu bar, and we cannot see
     177            // that it is active when the frame window has an icon.
     178            PFNWP oldProc = WinSubclassWindow(sysMenu, QtSysMenuProc);
     179            // set QtOldSysMenuProc only once: it must be the same for
     180            // all FID_SYSMENU windows.
     181            if (!QtOldSysMenuProc)
     182                QtOldSysMenuProc = oldProc;
     183        }
     184    }
     185}
    61186
    62187/*****************************************************************************
     
    66191void QWidgetPrivate::create_sys(WId window, bool initializeWindow, bool destroyOldWindow)
    67192{
    68     // @todo implement
     193    // @todo when window is not zero, it represents an existing (external)
     194    // window handle we should create a QWidget "wrapper" for to incorporate it
     195    // to the Qt widget hierarchy. This functionality isn't really necessary on
     196    // OS/2 at the moment, so it is not currently supported (and the window
     197    // argument is simply ignored). Note that destroyOldWindow only makes
     198    //  sense when window is != 0 so it is also ignored.
     199
     200    Q_ASSERT(window == 0);
     201    Q_UNUSED(destroyOldWindow);
     202
     203    Q_Q(QWidget);
     204    static int sw = -1, sh = -1;
     205
     206    Qt::WindowType type = q->windowType();
     207    Qt::WindowFlags flags = data.window_flags;
     208
     209    bool topLevel = q->isWindow();
     210    bool popup = (type == Qt::Popup);
     211    bool dialog = (type == Qt::Dialog
     212                   || type == Qt::Sheet
     213                   || (flags & Qt::MSWindowsFixedSizeDialogHint));
     214    bool desktop = (type == Qt::Desktop);
     215    bool tool = (type == Qt::Tool || type == Qt::Drawer);
     216
     217    WId id;
     218
     219    QByteArray className = qt_reg_winclass(q).toLatin1();
     220
     221    // @todo WindowStaysOnTopHint is ignored for now (does nothing)
     222    if (popup)
     223        flags |= Qt::WindowStaysOnTopHint; // a popup stays on top
     224
     225    if (sw < 0) { // get the screen size
     226        sw = WinQuerySysValue(HWND_DESKTOP, SV_CXSCREEN);
     227        sh = WinQuerySysValue(HWND_DESKTOP, SV_CYSCREEN);
     228    }
     229
     230    if (desktop && !q->testAttribute(Qt::WA_DontShowOnScreen)) { // desktop widget
     231        popup = false; // force this flags off
     232        // @todo use WinGetMaxPositionto take into account such things as XCenter?
     233        data.crect.setRect(0, 0, sw, sh);
     234    }
     235
     236    QByteArray title;
     237    ULONG style = 0;
     238    ULONG fId = 0, fStyle = 0, fcFlags = 0;
     239
     240    if (!desktop) {
     241        // @todo testing for Qt::WA_PaintUnclipped is commented out because it
     242        // is said that it causes some problems on Win32 and we also saw the
     243        // problems with this line enabled in Qt3 on OS/2 in QT_PM_NO_WIDGETMASK
     244        // mode (terrible flicker in QFileDialog because QSplitter used there
     245        // sets WA_PaintUnclipped). This however doesn't make a big difference
     246        // now since we don't support QT_PM_NO_WIDGETMASK anymore (read below
     247        // about clipping) and is left here just to show where WA_PaintUnclipped
     248        // was originally intended to be used.
     249#if 0
     250        if (!testAttribute(Qt::WA_PaintUnclipped))
     251#endif
     252        {
     253            // We don't use WS_CLIPSIBLINGS and WS_CLIPCHILDREN because when these
     254            // styles are set and the child (sibling) window has a non-NULL clip region,
     255            // PM still continues to exclude the entire child's rectangle from the
     256            // parent window's update region, ignoring its clip region. As a result,
     257            // areas outside the clip region are left unpainted. Instead, we correct
     258            // the update region of the window ourselves, on every WM_PAINT event.
     259            // Note: for top-level widgets, we specify WS_CLIPSIBLINGS anyway to let
     260            // the system do correct clipping for us (qt_WinProcessWindowObstacles()
     261            // relies on this). It's ok because top-level widgets cannot be non-
     262            // rectangular and therefore don't require our magic clipping procedure.
     263            if (topLevel)
     264                style |= WS_CLIPSIBLINGS;
     265        }
     266
     267        // for all top-level windows except popups we create a WC_FRAME
     268        // as a parent and owner.
     269        if (topLevel && !popup) {
     270            if ((type == Qt::Window || dialog || tool)) {
     271                if (!(flags & Qt::FramelessWindowHint)) {
     272                    if (flags & Qt::MSWindowsFixedSizeDialogHint) {
     273                        fcFlags |= FCF_DLGBORDER;
     274                    } else if (tool) {
     275                        fcFlags |= FCF_BORDER;
     276                    } else {
     277                        fcFlags |= FCF_SIZEBORDER;
     278                    }
     279                }
     280                if (flags & Qt::WindowTitleHint)
     281                    fcFlags |= FCF_TITLEBAR;
     282                if (flags & Qt::WindowSystemMenuHint)
     283                    fcFlags |= FCF_SYSMENU | FCF_CLOSEBUTTON;
     284                if (flags & Qt::WindowMinimizeButtonHint)
     285                    fcFlags |= FCF_MINBUTTON;
     286                if (flags & Qt::WindowMaximizeButtonHint)
     287                    fcFlags |= FCF_MAXBUTTON;
     288            } else {
     289                fcFlags |= FCF_BORDER;
     290            }
     291
     292            fStyle |= FS_NOMOVEWITHOWNER | FS_NOBYTEALIGN;
     293            fStyle |= WS_CLIPSIBLINGS | WS_CLIPCHILDREN;
     294        }
     295    }
     296
     297    if (flags & Qt::WindowTitleHint) {
     298        title = topLevel ? qAppName().toLocal8Bit() : q->objectName().toLocal8Bit();
     299    }
     300
     301    // The Qt::WA_WState_Created flag is checked by translateConfigEvent() in
     302    // qapplication_pm.cpp. We switch it off temporarily to avoid move
     303    // and resize events during creation
     304    q->setAttribute(Qt::WA_WState_Created, false);
     305
     306    if (desktop) { // desktop widget
     307        id = WinQueryDesktopWindow(0, 0);
     308        // @todo commented out on Win32 too
     309//      QWidget *otherDesktop = QWidget::find(id); // is there another desktop?
     310//      if (otherDesktop && otherDesktop->testWFlags(Qt::WPaintDesktop)) {
     311//          otherDesktop->d_func()->setWinId(0); // remove id from widget mapper
     312//          setWinId(id); // make sure otherDesktop is found first
     313//          otherDesktop->d_func()->setWinId(id);
     314//      } else {
     315            setWinId(id);
     316//      }
     317    } else if (topLevel) {
     318        // create top-level widget
     319        if (!popup) {
     320            HWND ownerw = NULLHANDLE;
     321            QWidget *parent = q->parentWidget();
     322
     323QWidgetPrivate *ppp;
     324ppp->frameWinId();
     325            if (parent && !(parent->windowType() == Qt::Desktop))
     326                ownerw = parent->window()->d_func()->frameWinId();
     327            // create WC_FRAME
     328            FRAMECDATA fcData;
     329            fcData.cb = sizeof(FRAMECDATA);
     330            fcData.flCreateFlags = fcFlags;
     331            fcData.hmodResources = NULL;
     332            fcData.idResources = 0;
     333            // check whether a default icon is present in .EXE and use it if so
     334            ULONG sz = 0;
     335            if (DosQueryResourceSize(NULL, RT_POINTER, 1, &sz) == 0) {
     336                fcData.flCreateFlags |= FCF_ICON;
     337                fcData.idResources = 1;
     338            }
     339#if defined(QT_DEBUGWINCREATEDESTROY)
     340            qDebug("|Creating top level window (frame) [%s/%s]:\n"
     341                   "|  owner = %08lX\n"
     342                   "|  title = '%s'\n"
     343                   "|  style = %08lX\n"
     344                   "|  fcFlags = %08lX",
     345                   q->objectName().toLocal8Bit().constData(),
     346                   q->metaObject()->className(),
     347                   ownerw, title.constData(), fStyle, fcFlags);
     348#endif
     349            fId = WinCreateWindow(HWND_DESKTOP, WC_FRAME, title, fStyle,
     350                                  0, 0, 0, 0, ownerw, HWND_TOP, 0,
     351                                  &fcData, NULL);
     352#if defined(QT_DEBUGWINCREATEDESTROY)
     353            qDebug("|  hwnd = %08lX", fId);
     354#endif
     355            if (fId == NULLHANDLE)
     356                qWarning("QWidget::create(): WinCreateWindow(WC_FRAME) "
     357                         "failed with 0x%08lX", WinGetLastError(0));
     358
     359            PFNWP oldProc = WinSubclassWindow(fId, QtFrameProc);
     360            // remember QtOldFrameProc only once: it's the same for
     361            // all WC_FRAME windows.
     362            if (!QtOldFrameProc)
     363                QtOldFrameProc = oldProc;
     364
     365            removeSysMenuAccels(fId);
     366
     367            // create client window
     368#if defined(QT_DEBUGWINCREATEDESTROY)
     369            qDebug("|Creating top level window (client) [%s/%s]:\n"
     370                   "|  owner & parent = %08lX\n"
     371                   "|  class = '%s'\n"
     372                   "|  title = '%s'\n"
     373                   "|  style = %08lX",
     374                   q->objectName().toLocal8Bit().constData(),
     375                   q->metaObject()->className(),
     376                   fId, className.constData(), title.constData(), style);
     377#endif
     378            // note that we place the client on top (HWND_TOP) to exclude other
     379            // frame controls from being analyzed in qt_WinProcessWindowObstacles
     380            id = WinCreateWindow(fId, className, title, style, 0, 0, 0, 0,
     381                                 fId, HWND_TOP, FID_CLIENT, NULL, NULL);
     382        } else {
     383#if defined(QT_DEBUGWINCREATEDESTROY)
     384            qDebug("|Creating top level window (popup) [%s/%s]:\n"
     385                   "|  class = '%s'\n"
     386                   "|  title = '%s'\n"
     387                   "|  style = %08lX",
     388                   q->objectName().toLocal8Bit().constData(),
     389                   q->metaObject()->className(),
     390                   className.constData(), title.constData(), style);
     391#endif
     392            id = WinCreateWindow(HWND_DESKTOP, className, title, style,
     393                                 0, 0, 0, 0, NULLHANDLE, HWND_TOP, 0, NULL, NULL);
     394        }
     395#if defined(QT_DEBUGWINCREATEDESTROY)
     396        qDebug("|  hwnd = %08lX", id);
     397#endif
     398        if (id == NULLHANDLE)
     399            qWarning("QWidget::create(): WinCreateWindow "
     400                     "failed with 0x%08lX", WinGetLastError(0));
     401        setWinId(id);
     402
     403        // it isn't mentioned in PMREF that PM is obliged to initialize window
     404        // data with zeroes (although seems to), so do it ourselves
     405        for (LONG i = 0; i <= (LONG) (QT_EXTRAWINDATASIZE - 4); i += 4)
     406            WinSetWindowULong(id, i, 0);
     407
     408        SWP swp;
     409        // Get the default window position and size. Note that when the
     410        // FS_SHELLPOSITION flag is specified during WC_FRAME window
     411        // creation its size and position remains zero until it is shown
     412        // for the first time. So, we don't use FS_SHELLPOSITION but emulate
     413        // its functionality here.
     414        WinQueryTaskSizePos(0, 0, &swp);
     415
     416        //update position & initial size of POPUP window
     417        const bool wasMoved = q->testAttribute(Qt::WA_Moved);
     418        const bool wasResized = q->testAttribute(Qt::WA_Resized);
     419        const bool isVisibleOnScreen = !q->testAttribute(Qt::WA_DontShowOnScreen);
     420        if (popup && initializeWindow && isVisibleOnScreen) {
     421            if (!q->testAttribute(Qt::WA_Resized)) {
     422                swp.cx = sw / 2;
     423                swp.cy = 4 * sh / 10;
     424            }
     425            if (!wasMoved) {
     426                swp.x = sw / 2 - swp.cx / 2;
     427                swp.y = sh / 2 - swp.cy / 2;
     428            }
     429        }
     430
     431        ULONG fl = SWP_SIZE | SWP_MOVE;
     432        HWND insertBehind = NULLHANDLE;
     433        if ((flags & Qt::WindowStaysOnTopHint) || (type == Qt::ToolTip)) {
     434            insertBehind = HWND_TOP;
     435            fl |= SWP_ZORDER;
     436            if (flags & Qt::WindowStaysOnBottomHint)
     437                qWarning() << "QWidget: Incompatible window flags: the window "
     438                              "can't be on top and on bottom at the same time";
     439        } else if (flags & Qt::WindowStaysOnBottomHint) {
     440            insertBehind = HWND_BOTTOM;
     441            fl |= SWP_ZORDER;
     442        }
     443        WinSetWindowPos(popup ? id : fId, insertBehind,
     444                        swp.x, swp.y, swp.cx, swp.cy, fl);
     445
     446        if (!popup) {
     447            QTLWExtra *top = topData();
     448            top->fId = fId;
     449            WinQueryWindowPos(fId, &swp);
     450            SWP cswp;
     451            WinQueryWindowPos(id, &cswp);
     452            // flip y coordinates
     453            swp.y = sh - (swp.y + swp.cy);
     454            cswp.y = swp.cy - (cswp.y + cswp.cy);
     455            // store frame dimensions
     456            QRect &fs = top->frameStrut;
     457            fs.setCoords(cswp.x, cswp.y, swp.cx - cswp.x - cswp.cx,
     458                                         swp.cy - cswp.y - cswp.cy);
     459            data.fstrut_dirty = false;
     460            if (wasMoved || wasResized) {
     461                // resize & move if necessary (we couldn't do it earlier
     462                // because we didn't know the frame dimensions yet)
     463                if (wasMoved) {
     464                    swp.x = data.crect.left() - fs.left();
     465                    swp.y = data.crect.top() - fs.top();
     466                }
     467                if (wasResized) {
     468                    swp.cx = data.crect.width() + fs.left() + fs.right();
     469                    swp.cy = data.crect.height() + fs.top() + fs.bottom();
     470                }
     471                // flip y coordinate
     472                swp.y = sh - (swp.y + swp.cy);
     473                WinSetWindowPos(fId, NULLHANDLE, swp.x, swp.y, swp.cx, swp.cy,
     474                                SWP_SIZE | SWP_MOVE);
     475            }
     476        }
     477
     478        if (!popup || (initializeWindow && isVisibleOnScreen)) {
     479            // fetch the actual geometry
     480            WinQueryWindowPos(popup ? id : fId, &swp);
     481            // flip y coordinate
     482            swp.y = sh - (swp.y + swp.cy);
     483            if (popup) {
     484                data.crect.setRect(swp.x, swp.y, swp.cx, swp.cy);
     485            } else {
     486                const QRect &fs = topData()->frameStrut;
     487                data.crect.setRect(swp.x + fs.left(), swp.y + fs.top(),
     488                                   swp.cx - fs.left() - fs.right(),
     489                                   swp.cy - fs.top() - fs.bottom());
     490            }
     491        }
     492    } else if (q->testAttribute(Qt::WA_NativeWindow) || paintOnScreen()) {
     493        // create child widget
     494        Q_ASSERT(q->parentWidget());
     495        HWND parentw = q->parentWidget()->effectiveWinId();
     496
     497#if defined(QT_DEBUGWINCREATEDESTROY)
     498        qDebug("|Creating child window [%s/%s]:\n"
     499               "|  owner & parent = %08lX\n"
     500               "|  class = '%s'\n"
     501               "|  title = '%s'\n"
     502               "|  style = %08lX",
     503               q->objectName().toLocal8Bit().constData(),
     504               q->metaObject()->className(),
     505               parentw, className.constData(), title.constData(), style);
     506#endif
     507        id = WinCreateWindow(parentw, className, title, style,
     508                             data.crect.left(),
     509                             // flip y coordinate
     510                             q->parentWidget()->height() - data.crect.bottom() - 1,
     511                             data.crect.width(), data.crect.height(),
     512                             parentw, HWND_TOP, 0, NULL, NULL);
     513#if defined(QT_DEBUGWINCREATEDESTROY)
     514        qDebug("|  hwnd = %08lX", id);
     515#endif
     516        if (id == NULLHANDLE)
     517            qWarning("QWidget::create(): WinCreateWindow "
     518                     "failed with 0x%08lX", WinGetLastError(0));
     519        setWinId(id);
     520    }
     521
     522    if (desktop) {
     523        q->setAttribute(Qt::WA_WState_Visible);
     524    }
     525
     526    q->setAttribute(Qt::WA_WState_Created); // accept move/resize events
     527
     528    hd = 0; // no presentation space
     529
     530    if (extra && !extra->mask.isEmpty())
     531        setMask_sys(extra->mask);
     532
     533    if (topLevel && (data.crect.width() == 0 || data.crect.height() == 0)) {
     534        q->setAttribute(Qt::WA_OutsideWSRange, true);
     535    }
     536
     537    if (!topLevel && q->testAttribute(Qt::WA_NativeWindow) && q->testAttribute(Qt::WA_Mapped)) {
     538        Q_ASSERT(q->internalWinId() != NULLHANDLE);
     539        WinShowWindow(q->internalWinId(), TRUE);
     540    }
    69541}
    70542
    71543void QWidget::destroy(bool destroyWindow, bool destroySubWindows)
    72544{
    73     // @todo implement
     545    Q_D(QWidget);
     546    if (!isWindow() && parentWidget())
     547        parentWidget()->d_func()->invalidateBuffer(geometry());
     548    d->deactivateWidgetCleanup();
     549    if (testAttribute(Qt::WA_WState_Created)) {
     550        setAttribute(Qt::WA_WState_Created, false);
     551        for(int i = 0; i < d->children.size(); ++i) { // destroy all widget children
     552            register QObject *obj = d->children.at(i);
     553            if (obj->isWidgetType())
     554                ((QWidget*)obj)->destroy(destroySubWindows,
     555                                         destroySubWindows);
     556        }
     557        if (mouseGrb == this)
     558            releaseMouse();
     559        if (keyboardGrb == this)
     560            releaseKeyboard();
     561        if (testAttribute(Qt::WA_ShowModal)) // just be sure we leave modal
     562            QApplicationPrivate::leaveModal(this);
     563        else if ((windowType() == Qt::Popup))
     564            qApp->d_func()->closePopup(this);
     565        if (destroyWindow && !(windowType() == Qt::Desktop) &&
     566            internalWinId() != NULLHANDLE) {
     567            HWND id = internalWinId();
     568            if (isWindow() && !(windowType() == Qt::Popup)) {
     569                // extra data including extra->topextra has been already
     570                // deleted at this point by deleteExtra() and therefore
     571                // calling frameWinId() is useless -- it will return the
     572                // client window handle. Use WinQueryWindow() instead.
     573                id = WinQueryWindow(id, QW_PARENT);
     574                Q_ASSERT(id != NULLHANDLE);
     575            }
     576#if defined(QT_DEBUGWINCREATEDESTROY)
     577            qDebug("|Destroying window [%s/%s]:\n"
     578                   "|  hwnd = %08lX",
     579                   objectName().toLocal8Bit().constData(),
     580                   metaObject()->className(), id);
     581#endif
     582
     583            qt_WinDestroyWindow(id);
     584        }
     585        d->setWinId(0);
     586    }
    74587}
    75588
     
    250763void QWidgetPrivate::createTLSysExtra()
    251764{
    252     // @todo implement
     765   
    253766}
    254767
    255768void QWidgetPrivate::deleteTLSysExtra()
    256769{
    257     // @todo implement
     770    //
    258771}
    259772
     
    270783void QWidgetPrivate::updateFrameStrut()
    271784{
    272     // @todo implement
     785    Q_Q(QWidget);
     786
     787    if (!q->testAttribute(Qt::WA_WState_Created))
     788        return;
     789
     790    if (q->internalWinId() == NULLHANDLE) {
     791        data.fstrut_dirty = false;
     792        return;
     793    }
     794
     795    QTLWExtra *top = maybeTopData();
     796    if (!top || top->fId == NULLHANDLE) {
     797        data.fstrut_dirty = false;
     798        return;
     799    }
     800
     801    // this widget has WC_FRAME
     802    SWP swp;
     803    WinQueryWindowPos(top->fId, &swp);
     804    SWP cswp;
     805    WinQueryWindowPos(data.winid, &cswp);
     806    // flip y coordinates
     807    swp.y = QApplication::desktop()->height() - (swp.y + swp.cy);
     808    cswp.y = swp.cy - (cswp.y + cswp.cy);
     809    QRect &fs = top->frameStrut;
     810    fs.setCoords(cswp.x, cswp.y, swp.cx - cswp.x - cswp.cx,
     811                                 swp.cy - cswp.y - cswp.cy);
     812    // @todo need this??
     813    //data.crect.setRect(swp.x + cswp.x, swp.y + cswp.y, cswp.cx, cswp.cy);
     814
     815    data.fstrut_dirty = false;
    273816}
    274817
Note: See TracChangeset for help on using the changeset viewer.