- Timestamp:
- Aug 5, 2009, 3:19:05 AM (16 years ago)
- Location:
- trunk/src/gui/kernel
- Files:
-
- 3 edited
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 // @todo implement 427 return FALSE; 428 } 429 430 PFNWP QtOldFrameProc = 0; 431 432 MRESULT EXPENTRY QtFrameProc(HWND hwnd, ULONG msg, MPARAM mp1, MPARAM mp2) 470 433 { 471 434 // @todo implement -
trunk/src/gui/kernel/qwidget_p.h
r95 r99 67 67 #endif // Q_WS_WIN 68 68 69 #ifdef Q_WS_PM 70 #include "QtCore/qt_os2.h" 71 #endif 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 #if defined(Q_WS_PM) 157 HWND fId; 158 #endif 152 159 QRect normalGeometry; // used by showMin/maximized/FullScreen 153 160 QWindowSurface *windowSurface; … … 460 467 461 468 QInputContext *inputContext() const; 469 470 #if defined(Q_WS_PM) 471 HWND frameWinId() const 472 { return maybeTopData() && maybeTopData()->fId != NULLHANDLE ? 473 maybeTopData()->fId : data.winid; } 474 #endif 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 #include "qdesktopwidget.h" 50 51 51 52 #include "private/qapplication_p.h" … … 53 54 #include <qdebug.h> 54 55 56 #define QT_DEBUGWINCREATEDESTROY 57 55 58 QT_BEGIN_NAMESPACE 59 60 static QWidget *mouseGrb = 0; 61 static QCursor *mouseGrbCur = 0; 62 static QWidget *keyboardGrb = 0; 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 extra->topextra->fId = NULLHANDLE; 253 766 } 254 767 255 768 void QWidgetPrivate::deleteTLSysExtra() 256 769 { 257 // @todo implement770 // Note: extra->topextra->fId is cleaned up in QWidget::destroy() 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.