Changeset 99 for trunk/src/gui
- Timestamp:
- Aug 5, 2009, 3:19:05 AM (16 years ago)
- Location:
- trunk/src/gui/kernel
- Files:
-
- 3 edited
-
qapplication_pm.cpp (modified) (4 diffs)
-
qwidget_p.h (modified) (3 diffs)
-
qwidget_pm.cpp (modified) (5 diffs)
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/gui/kernel/qapplication_pm.cpp
r98 r99 91 91 static void releaseAutoCapture(); 92 92 93 static void unregWinClasses();94 95 93 extern QCursor *qt_grab_cursor(); 96 94 97 extern "C"MRESULT EXPENTRY QtWndProc(HWND, ULONG, MPARAM, MPARAM);95 MRESULT EXPENTRY QtWndProc(HWND, ULONG, MPARAM, MPARAM); 98 96 99 97 class QETWidget : public QWidget // event translator widget … … 189 187 void qt_cleanup() 190 188 { 191 unregWinClasses();192 189 QPixmapCache::clear(); 193 190 … … 224 221 return false; 225 222 #endif 226 }227 228 typedef QSet<QString> WinClassNameHash;229 Q_GLOBAL_STATIC(WinClassNameHash, winclassNames)230 231 // register window class232 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 list253 return cname;254 255 // QT_EXTRAWINDATASIZE is defined in qwindowdefs_pm.h256 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 done265 // automatically upon process termination.266 winclassNames()->clear();267 223 } 268 224 … … 466 422 // QtWndProc() receives all messages from the main event loop 467 423 468 extern "C"469 424 MRESULT EXPENTRY QtWndProc(HWND hwnd, ULONG msg, MPARAM mp1, MPARAM mp2) 425 426 427 428 429 430 431 432 470 433 { 471 434 // @todo implement -
trunk/src/gui/kernel/qwidget_p.h
r95 r99 67 67 #endif // Q_WS_WIN 68 68 69 70 71 72 69 73 #ifdef Q_WS_X11 70 74 #include "QtGui/qx11info_x11.h" … … 150 154 HICON winIconSmall; // internal small Windows icon 151 155 #endif 156 157 158 152 159 QRect normalGeometry; // used by showMin/maximized/FullScreen 153 160 QWindowSurface *windowSurface; … … 460 467 461 468 QInputContext *inputContext() const; 469 470 471 472 473 474 462 475 463 476 #if defined(Q_WS_QWS) -
trunk/src/gui/kernel/qwidget_pm.cpp
r95 r99 48 48 49 49 #include "qapplication.h" 50 50 51 51 52 #include "private/qapplication_p.h" … … 53 54 #include <qdebug.h> 54 55 56 57 55 58 QT_BEGIN_NAMESPACE 59 60 61 62 56 63 57 64 // defined in qapplication_pm.cpp 58 65 extern bool qt_nograb(); 59 extern const QString qt_reg_winclass(QWidget *w); 60 extern "C" MRESULT EXPENTRY QtWndProc(HWND, ULONG, MPARAM, MPARAM); 66 extern MRESULT EXPENTRY QtWndProc(HWND, ULONG, MPARAM, MPARAM); 67 extern PFNWP QtOldFrameProc; 68 extern MRESULT EXPENTRY QtFrameProc(HWND, ULONG, MPARAM, MPARAM); 69 70 typedef QSet<QString> WinClassNameHash; 71 Q_GLOBAL_STATIC(WinClassNameHash, winclassNames) 72 73 // register window class 74 static 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 */ 115 static 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 127 static PFNWP QtOldSysMenuProc; 128 static 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 137 static 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 } 61 186 62 187 /***************************************************************************** … … 66 191 void QWidgetPrivate::create_sys(WId window, bool initializeWindow, bool destroyOldWindow) 67 192 { 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 323 QWidgetPrivate *ppp; 324 ppp->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 } 69 541 } 70 542 71 543 void QWidget::destroy(bool destroyWindow, bool destroySubWindows) 72 544 { 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 } 74 587 } 75 588 … … 250 763 void QWidgetPrivate::createTLSysExtra() 251 764 { 252 // @todo implement765 253 766 } 254 767 255 768 void QWidgetPrivate::deleteTLSysExtra() 256 769 { 257 // @todo implement770 // 258 771 } 259 772 … … 270 783 void QWidgetPrivate::updateFrameStrut() 271 784 { 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; 273 816 } 274 817
Note:
See TracChangeset
for help on using the changeset viewer.
