| 1 | /**************************************************************************** | 
|---|
| 2 | ** $Id: qwidget_pm.cpp 8 2005-11-16 19:36:46Z dmik $ | 
|---|
| 3 | ** | 
|---|
| 4 | ** Implementation of QWidget and QWindow classes for OS/2 | 
|---|
| 5 | ** | 
|---|
| 6 | ** Copyright (C) 1992-2000 Trolltech AS.  All rights reserved. | 
|---|
| 7 | ** Copyright (C) 2004 Norman ASA.  Initial OS/2 Port. | 
|---|
| 8 | ** Copyright (C) 2005 netlabs.org.  Further OS/2 Development. | 
|---|
| 9 | ** | 
|---|
| 10 | ** This file is part of the kernel module of the Qt GUI Toolkit. | 
|---|
| 11 | ** | 
|---|
| 12 | ** This file may be distributed under the terms of the Q Public License | 
|---|
| 13 | ** as defined by Trolltech AS of Norway and appearing in the file | 
|---|
| 14 | ** LICENSE.QPL included in the packaging of this file. | 
|---|
| 15 | ** | 
|---|
| 16 | ** This file may be distributed and/or modified under the terms of the | 
|---|
| 17 | ** GNU General Public License version 2 as published by the Free Software | 
|---|
| 18 | ** Foundation and appearing in the file LICENSE.GPL included in the | 
|---|
| 19 | ** packaging of this file. | 
|---|
| 20 | ** | 
|---|
| 21 | ** Licensees holding valid Qt Enterprise Edition or Qt Professional Edition | 
|---|
| 22 | ** licenses may use this file in accordance with the Qt Commercial License | 
|---|
| 23 | ** Agreement provided with the Software. | 
|---|
| 24 | ** | 
|---|
| 25 | ** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE | 
|---|
| 26 | ** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. | 
|---|
| 27 | ** | 
|---|
| 28 | ** See http://www.trolltech.com/pricing.html or email sales@trolltech.com for | 
|---|
| 29 | **   information about Qt Commercial License Agreements. | 
|---|
| 30 | ** See http://www.trolltech.com/qpl/ for QPL licensing information. | 
|---|
| 31 | ** See http://www.trolltech.com/gpl/ for GPL licensing information. | 
|---|
| 32 | ** | 
|---|
| 33 | ** Contact info@trolltech.com if any conditions of this licensing are | 
|---|
| 34 | ** not clear to you. | 
|---|
| 35 | ** | 
|---|
| 36 | **********************************************************************/ | 
|---|
| 37 |  | 
|---|
| 38 | #include "qapplication.h" | 
|---|
| 39 | #include "qapplication_p.h" | 
|---|
| 40 | #include "qpainter.h" | 
|---|
| 41 | #include "qbitmap.h" | 
|---|
| 42 | #include "qwidgetlist.h" | 
|---|
| 43 | #include "qwidgetintdict.h" | 
|---|
| 44 | #include "qobjectlist.h" | 
|---|
| 45 | #include "qaccel.h" | 
|---|
| 46 | #include "qimage.h" | 
|---|
| 47 | #include "qfocusdata.h" | 
|---|
| 48 | #include "qlayout.h" | 
|---|
| 49 | #include "qt_os2.h" | 
|---|
| 50 | #include "qpaintdevicemetrics.h" | 
|---|
| 51 | #include "qcursor.h" | 
|---|
| 52 | #include <private/qapplication_p.h> | 
|---|
| 53 | //@@TODO (dmik): remove | 
|---|
| 54 | //#include <private/qinputcontext_p.h> | 
|---|
| 55 |  | 
|---|
| 56 | //@@TODO (dmik): need this? | 
|---|
| 57 | //#if defined(QT_NON_COMMERCIAL) | 
|---|
| 58 | //#include "qnc_win.h" | 
|---|
| 59 | //#endif | 
|---|
| 60 |  | 
|---|
| 61 | //@@TODO (dmik): remove | 
|---|
| 62 | //#if !defined(WS_EX_TOOLWINDOW) | 
|---|
| 63 | //#define WS_EX_TOOLWINDOW 0x00000080 | 
|---|
| 64 | //#endif | 
|---|
| 65 | // | 
|---|
| 66 | //#if !defined(GWLP_WNDPROC) | 
|---|
| 67 | //#define GWLP_WNDPROC GWL_WNDPROC | 
|---|
| 68 | //#endif | 
|---|
| 69 |  | 
|---|
| 70 | const QString qt_reg_winclass( int );           // defined in qapplication_pm.cpp | 
|---|
| 71 | //@@TODO (dmik): later? | 
|---|
| 72 | //void      qt_olednd_unregister( QWidget* widget, QOleDropTarget *dst ); // dnd_win | 
|---|
| 73 | //QOleDropTarget* qt_olednd_register( QWidget* widget ); | 
|---|
| 74 |  | 
|---|
| 75 |  | 
|---|
| 76 | extern bool qt_nograb(); | 
|---|
| 77 | //@@TODO (dmik): later (qregion_pm.cpp) | 
|---|
| 78 | //extern HRGN qt_win_bitmapToRegion(const QBitmap& bitmap); | 
|---|
| 79 |  | 
|---|
| 80 | // defined in qapplication_pm.cpp | 
|---|
| 81 | extern void qt_sendBlocked( QObject *obj, QWidget *modal, QEvent *e, bool override ); | 
|---|
| 82 |  | 
|---|
| 83 | static QWidget *mouseGrb    = 0; | 
|---|
| 84 | static QCursor *mouseGrbCur = 0; | 
|---|
| 85 | static QWidget *keyboardGrb = 0; | 
|---|
| 86 |  | 
|---|
| 87 | extern "C" MRESULT EXPENTRY QtWndProc( HWND, ULONG, MPARAM, MPARAM ); | 
|---|
| 88 | extern PFNWP QtOldFrameProc; | 
|---|
| 89 | extern "C" MRESULT EXPENTRY QtFrameProc( HWND, ULONG, MPARAM, MPARAM ); | 
|---|
| 90 |  | 
|---|
| 91 | PFNWP QtOldSysMenuProc; | 
|---|
| 92 | extern "C" MRESULT EXPENTRY QtSysMenuProc( HWND hwnd, ULONG msg, MPARAM mp1, MPARAM mp2 ) | 
|---|
| 93 | { | 
|---|
| 94 | if ( msg == WM_MENUEND ) { | 
|---|
| 95 | // the pull-down menu is closed, always dismiss the system menu itself | 
|---|
| 96 | WinPostMsg( hwnd, MM_ENDMENUMODE, MPFROMSHORT(TRUE), 0 ); | 
|---|
| 97 | } | 
|---|
| 98 | return QtOldSysMenuProc( hwnd, msg, mp1, mp2 ); | 
|---|
| 99 | } | 
|---|
| 100 |  | 
|---|
| 101 | static void removeSysMenuAccels( HWND frame ) | 
|---|
| 102 | { | 
|---|
| 103 | HWND sysMenu = WinWindowFromID( frame, FID_SYSMENU ); | 
|---|
| 104 | if ( !sysMenu ) | 
|---|
| 105 | return; | 
|---|
| 106 |  | 
|---|
| 107 | SHORT subId = SHORT1FROMMR( WinSendMsg( sysMenu, MM_ITEMIDFROMPOSITION, 0, 0 ) ); | 
|---|
| 108 | if ( subId != MIT_ERROR ) { | 
|---|
| 109 | MENUITEM item; | 
|---|
| 110 | WinSendMsg( sysMenu, MM_QUERYITEM, MPFROM2SHORT(subId, FALSE), MPFROMP(&item) ); | 
|---|
| 111 | HWND subMenu = item.hwndSubMenu; | 
|---|
| 112 | if ( subMenu ) { | 
|---|
| 113 | USHORT cnt = SHORT1FROMMR( WinSendMsg( subMenu, MM_QUERYITEMCOUNT, 0, 0 ) ); | 
|---|
| 114 | for ( int i = 0; i < cnt; i++ ) { | 
|---|
| 115 | USHORT id = SHORT1FROMMR( | 
|---|
| 116 | WinSendMsg( subMenu, MM_ITEMIDFROMPOSITION, MPFROMSHORT(i), 0 ) ); | 
|---|
| 117 | if ( id == SC_TASKMANAGER || id == SC_CLOSE ) { | 
|---|
| 118 | // accels for these entries always work in Qt, skip them | 
|---|
| 119 | continue; | 
|---|
| 120 | } | 
|---|
| 121 | USHORT len = SHORT1FROMMR( | 
|---|
| 122 | WinSendMsg( subMenu, MM_QUERYITEMTEXTLENGTH, MPFROMSHORT(id), 0 ) ); | 
|---|
| 123 | if ( len++ ) { | 
|---|
| 124 | char *text = new char[len]; | 
|---|
| 125 | WinSendMsg( subMenu, MM_QUERYITEMTEXT, | 
|---|
| 126 | MPFROM2SHORT(id, len), MPFROMP(text) ); | 
|---|
| 127 | char *tab = strrchr( text, '\t' ); | 
|---|
| 128 | if ( tab ) { | 
|---|
| 129 | *tab = 0; | 
|---|
| 130 | WinSendMsg( subMenu, MM_SETITEMTEXT, | 
|---|
| 131 | MPFROMSHORT(id), MPFROMP(text) ); | 
|---|
| 132 | } | 
|---|
| 133 | delete[] text; | 
|---|
| 134 | } | 
|---|
| 135 | } | 
|---|
| 136 | // sublclass the system menu to leave the menu mode completely | 
|---|
| 137 | // when the user presses the ESC key. by default, pressing ESC | 
|---|
| 138 | // while the pull-down menu is showing brings us to the menu bar, | 
|---|
| 139 | // which is confusing in the case of the system menu, because | 
|---|
| 140 | // there is only one item on the menu bar, and we cannot see | 
|---|
| 141 | // that it is active when the frame window has an icon. | 
|---|
| 142 | PFNWP oldProc = WinSubclassWindow( sysMenu, QtSysMenuProc ); | 
|---|
| 143 | // set QtOldSysMenuProc only once: it must be the same for | 
|---|
| 144 | // all FID_SYSMENU windows. | 
|---|
| 145 | if ( !QtOldSysMenuProc ) | 
|---|
| 146 | QtOldSysMenuProc = oldProc; | 
|---|
| 147 | } | 
|---|
| 148 | } | 
|---|
| 149 | } | 
|---|
| 150 |  | 
|---|
| 151 | /***************************************************************************** | 
|---|
| 152 | QWidget member functions | 
|---|
| 153 | *****************************************************************************/ | 
|---|
| 154 |  | 
|---|
| 155 | //#define QT_DEBUGWINCREATEDESTROY | 
|---|
| 156 |  | 
|---|
| 157 | void QWidget::create( WId window, bool initializeWindow, bool destroyOldWindow) | 
|---|
| 158 | { | 
|---|
| 159 | if ( testWState(WState_Created) && window == 0 ) | 
|---|
| 160 | return; | 
|---|
| 161 | setWState( WState_Created );                        // set created flag | 
|---|
| 162 |  | 
|---|
| 163 | if ( !parentWidget() || parentWidget()->isDesktop() ) | 
|---|
| 164 | setWFlags( WType_TopLevel );            // top-level widget | 
|---|
| 165 |  | 
|---|
| 166 | static int sw = -1, sh = -1; | 
|---|
| 167 |  | 
|---|
| 168 | bool topLevel = testWFlags(WType_TopLevel); | 
|---|
| 169 | bool popup = testWFlags(WType_Popup); | 
|---|
| 170 | bool dialog = testWFlags(WType_Dialog); | 
|---|
| 171 | bool desktop  = testWFlags(WType_Desktop); | 
|---|
| 172 | //@@TODO (dmik): guess this is for embedded windows. remove? | 
|---|
| 173 | //    HWND destroyw = 0; | 
|---|
| 174 | WId  id = 0; | 
|---|
| 175 |  | 
|---|
| 176 | if ( !window )                              // always initialize | 
|---|
| 177 | initializeWindow = TRUE; | 
|---|
| 178 |  | 
|---|
| 179 | if ( popup ) { | 
|---|
| 180 | //@@TODO (dmik): ignored for now? | 
|---|
| 181 | setWFlags(WStyle_StaysOnTop); // a popup stays on top | 
|---|
| 182 | } | 
|---|
| 183 |  | 
|---|
| 184 | if ( sw < 0 ) {                             // get the screen size | 
|---|
| 185 | sw = WinQuerySysValue( HWND_DESKTOP, SV_CXSCREEN ); | 
|---|
| 186 | sh = WinQuerySysValue( HWND_DESKTOP, SV_CYSCREEN ); | 
|---|
| 187 | } | 
|---|
| 188 |  | 
|---|
| 189 | //@@TODO (dmik): guess this is for embedded windows. remove? | 
|---|
| 190 | //    if ( window ) { | 
|---|
| 191 | //      // There's no way we can know the background color of the | 
|---|
| 192 | //      // other window because it could be cleared using the WM_ERASEBKND | 
|---|
| 193 | //      // message.  Therefore we assume white. | 
|---|
| 194 | //      bg_col = white; | 
|---|
| 195 | //    } | 
|---|
| 196 |  | 
|---|
| 197 | if ( dialog || popup || desktop ) {         // these are top-level, too | 
|---|
| 198 | topLevel = TRUE; | 
|---|
| 199 | setWFlags( WType_TopLevel ); | 
|---|
| 200 | } | 
|---|
| 201 |  | 
|---|
| 202 | if ( desktop ) {                            // desktop widget | 
|---|
| 203 | popup = FALSE;                          // force this flags off | 
|---|
| 204 | //@@TODO (dmik): use WinGetMaxPosition () to take into account such | 
|---|
| 205 | //  things as XCenter? | 
|---|
| 206 | crect.setRect( 0, 0, sw, sh ); | 
|---|
| 207 | } | 
|---|
| 208 |  | 
|---|
| 209 | PCSZ title = NULL; | 
|---|
| 210 | ULONG style = 0; | 
|---|
| 211 | ULONG fId = 0, fStyle = 0, fcFlags = 0; | 
|---|
| 212 |  | 
|---|
| 213 | //@@TODO (dmik): guess this is for embedded windows. remove? | 
|---|
| 214 | //    if ( window ) { | 
|---|
| 215 | //      style = GetWindowLongA( window, GWL_STYLE ); | 
|---|
| 216 | //#ifndef QT_NO_DEBUG | 
|---|
| 217 | //      if ( !style ) | 
|---|
| 218 | //          qSystemWarning( "QWidget: GetWindowLong failed" ); | 
|---|
| 219 | //#endif | 
|---|
| 220 | //      topLevel = FALSE; // #### needed for some IE plugins?? | 
|---|
| 221 | //    } else if ( popup ) { | 
|---|
| 222 | if ( popup ) { | 
|---|
| 223 | style |= WS_SAVEBITS; | 
|---|
| 224 | } else if ( !topLevel ) { | 
|---|
| 225 | //@@TODO (dmik): why should we set these flags for non-toplevel (child) windows? | 
|---|
| 226 | //      if ( !testWFlags(WStyle_Customize) ) | 
|---|
| 227 | //          setWFlags( WStyle_NormalBorder | WStyle_Title | WStyle_MinMax | WStyle_SysMenu  ); | 
|---|
| 228 | if ( !testWFlags(WStyle_Customize) ) | 
|---|
| 229 | setWFlags( WStyle_Title ); | 
|---|
| 230 | } else if (!desktop ) { | 
|---|
| 231 | if ( !testWFlags(WStyle_Customize) ) { | 
|---|
| 232 | if ( testWFlags(WStyle_Tool) ) { | 
|---|
| 233 | // a special case for WStyle_Tool w/o WStyle_Customize. | 
|---|
| 234 | // it violates the Qt docs but it is used by QPopupMenu | 
|---|
| 235 | // to create torn-off menus. | 
|---|
| 236 | setWFlags( WStyle_Title ); | 
|---|
| 237 | } else { | 
|---|
| 238 | if ( dialog ) | 
|---|
| 239 | setWFlags( WStyle_NormalBorder | WStyle_Title | WStyle_SysMenu ); | 
|---|
| 240 | else | 
|---|
| 241 | setWFlags( WStyle_NormalBorder | WStyle_Title | WStyle_MinMax | WStyle_SysMenu  ); | 
|---|
| 242 | } | 
|---|
| 243 | } | 
|---|
| 244 | } | 
|---|
| 245 | if ( !desktop ) { | 
|---|
| 246 | //@@TODO (dmik): this is temporarily commented out because QSplitter sets | 
|---|
| 247 | //  WPaintUnclipped which causes terrible flicker in QFileDialog's list | 
|---|
| 248 | //  box and list view. this needs to be investigated. Qt/Win32 does also | 
|---|
| 249 | //  comment this out... | 
|---|
| 250 | //      if ( !testWFlags( WPaintUnclipped ) ) | 
|---|
| 251 | style |= WS_CLIPSIBLINGS | WS_CLIPCHILDREN; | 
|---|
| 252 | // for all top-level windows except popups we create a WC_FRAME | 
|---|
| 253 | // as a parent and owner. | 
|---|
| 254 | if ( topLevel && !popup ) { | 
|---|
| 255 | if ( !testWFlags(WStyle_NoBorder) ) { | 
|---|
| 256 | if ( testWFlags(WStyle_NormalBorder) ) { | 
|---|
| 257 | fcFlags |= FCF_SIZEBORDER; | 
|---|
| 258 | } else if ( testWFlags(WStyle_DialogBorder) ) { | 
|---|
| 259 | fcFlags |= FCF_DLGBORDER; | 
|---|
| 260 | } else if ( testWFlags(WStyle_Tool)  ) { | 
|---|
| 261 | fcFlags |= FCF_BORDER; | 
|---|
| 262 | } | 
|---|
| 263 | } | 
|---|
| 264 | if ( testWFlags(WStyle_Title) ) | 
|---|
| 265 | fcFlags |= FCF_TITLEBAR; | 
|---|
| 266 | if ( testWFlags(WStyle_SysMenu) ) | 
|---|
| 267 | fcFlags |= FCF_SYSMENU | FCF_CLOSEBUTTON; | 
|---|
| 268 | if ( testWFlags(WStyle_Minimize) ) | 
|---|
| 269 | fcFlags |= FCF_MINBUTTON; | 
|---|
| 270 | if ( testWFlags(WStyle_Maximize) ) | 
|---|
| 271 | fcFlags |= FCF_MAXBUTTON; | 
|---|
| 272 | fStyle |= FS_NOMOVEWITHOWNER | FS_NOBYTEALIGN; | 
|---|
| 273 | fStyle |= WS_CLIPSIBLINGS | WS_CLIPCHILDREN; | 
|---|
| 274 | } | 
|---|
| 275 | } | 
|---|
| 276 | if ( testWFlags(WStyle_Title) ) { | 
|---|
| 277 | title = topLevel ? qAppName() : name(); | 
|---|
| 278 | } | 
|---|
| 279 |  | 
|---|
| 280 | // The WState_Created flag is checked by translateConfigEvent() in | 
|---|
| 281 | // qapplication_pm.cpp. We switch it off temporarily to avoid move | 
|---|
| 282 | // and resize events during creation | 
|---|
| 283 | clearWState( WState_Created ); | 
|---|
| 284 |  | 
|---|
| 285 | QString className = qt_reg_winclass( getWFlags() ); | 
|---|
| 286 | PCSZ pszClassName = className.latin1(); | 
|---|
| 287 |  | 
|---|
| 288 | //@@TODO (dmik): guess this is for embedded windows. remove? | 
|---|
| 289 | //    if ( window ) {                           // override the old window | 
|---|
| 290 | //      if ( destroyOldWindow ) | 
|---|
| 291 | //          destroyw = winid; | 
|---|
| 292 | //      id = window; | 
|---|
| 293 | //      setWinId( window ); | 
|---|
| 294 | //      LONG res = SetWindowLongA( window, GWL_STYLE, style ); | 
|---|
| 295 | //#ifndef QT_NO_DEBUG | 
|---|
| 296 | //      if ( !res ) | 
|---|
| 297 | //          qSystemWarning( "QWidget: Failed to set window style" ); | 
|---|
| 298 | //#endif | 
|---|
| 299 | //      res = SetWindowLongA( window, GWLP_WNDPROC, (LONG)QtWndProc ); | 
|---|
| 300 | //#ifndef QT_NO_DEBUG | 
|---|
| 301 | //      if ( !res ) | 
|---|
| 302 | //          qSystemWarning( "QWidget: Failed to set window procedure" ); | 
|---|
| 303 | //#endif | 
|---|
| 304 | //    } else if ( desktop ) {                   // desktop widget | 
|---|
| 305 | if ( desktop ) {                            // desktop widget | 
|---|
| 306 | id = WinQueryDesktopWindow( 0, 0 ); | 
|---|
| 307 | QWidget *otherDesktop = find( id );     // is there another desktop? | 
|---|
| 308 | if ( otherDesktop && otherDesktop->testWFlags(WPaintDesktop) ) { | 
|---|
| 309 | otherDesktop->setWinId( 0 );        // remove id from widget mapper | 
|---|
| 310 | setWinId( id );                     // make sure otherDesktop is | 
|---|
| 311 | otherDesktop->setWinId( id );       //   found first | 
|---|
| 312 | } else { | 
|---|
| 313 | setWinId( id ); | 
|---|
| 314 | } | 
|---|
| 315 | } else if ( topLevel ) { | 
|---|
| 316 | // create top-level widget | 
|---|
| 317 | HWND ownerw = 0; | 
|---|
| 318 | if ( !popup ) { | 
|---|
| 319 | QWidget *p = parentWidget(); | 
|---|
| 320 | if ( p && !p->isDesktop() ) | 
|---|
| 321 | ownerw = p->topLevelWidget()->winFId(); | 
|---|
| 322 | } | 
|---|
| 323 |  | 
|---|
| 324 | if ( !popup ) { | 
|---|
| 325 | // create WC_FRAME | 
|---|
| 326 | FRAMECDATA fcData; | 
|---|
| 327 | fcData.cb = sizeof(FRAMECDATA); | 
|---|
| 328 | fcData.flCreateFlags = fcFlags; | 
|---|
| 329 | fcData.hmodResources = NULL; | 
|---|
| 330 | fcData.idResources = 0; | 
|---|
| 331 | #if !defined(QT_NO_DEBUG) && defined(QT_DEBUGWINCREATEDESTROY) | 
|---|
| 332 | qDebug( | 
|---|
| 333 | "|Creating top level window [%s] (frame):\n" | 
|---|
| 334 | "|  owner = %08lX\n" | 
|---|
| 335 | "|  title = '%s'\n" | 
|---|
| 336 | "|  style = %08lX\n" | 
|---|
| 337 | "|  fcFlags = %08lX", | 
|---|
| 338 | name(), ownerw, title, fStyle, fcFlags | 
|---|
| 339 | ); | 
|---|
| 340 | #endif | 
|---|
| 341 | fId = WinCreateWindow( | 
|---|
| 342 | HWND_DESKTOP, WC_FRAME, title, fStyle, 0, 0, 0, 0, | 
|---|
| 343 | ownerw, HWND_TOP, 0, &fcData, NULL | 
|---|
| 344 | ); | 
|---|
| 345 | #ifndef QT_NO_DEBUG | 
|---|
| 346 | #ifdef QT_DEBUGWINCREATEDESTROY | 
|---|
| 347 | qDebug( "|  hwnd = %08lX", fId ); | 
|---|
| 348 | #endif | 
|---|
| 349 | if ( fId == 0 ) | 
|---|
| 350 | qSystemWarning( "QWidget: Failed to create frame window" ); | 
|---|
| 351 | #endif | 
|---|
| 352 | PFNWP oldProc = WinSubclassWindow( fId, QtFrameProc ); | 
|---|
| 353 | // set QtOldFrameProc only once: it must be the same for | 
|---|
| 354 | // all WC_FRAME windows. | 
|---|
| 355 | if ( !QtOldFrameProc ) | 
|---|
| 356 | QtOldFrameProc = oldProc; | 
|---|
| 357 |  | 
|---|
| 358 | removeSysMenuAccels( fId ); | 
|---|
| 359 |  | 
|---|
| 360 | // create client | 
|---|
| 361 | #if !defined(QT_NO_DEBUG) && defined(QT_DEBUGWINCREATEDESTROY) | 
|---|
| 362 | qDebug( | 
|---|
| 363 | "|Creating top level window [%s] (client):\n" | 
|---|
| 364 | "|  owner & parent = %08lX\n" | 
|---|
| 365 | "|  class = '%s'\n" | 
|---|
| 366 | "|  title = '%s'\n" | 
|---|
| 367 | "|  style = %08lX", | 
|---|
| 368 | name(), fId, pszClassName, title, style | 
|---|
| 369 | ); | 
|---|
| 370 | #endif | 
|---|
| 371 | id = WinCreateWindow( | 
|---|
| 372 | fId, pszClassName, title, style, 0, 0, 0, 0, | 
|---|
| 373 | fId, HWND_BOTTOM, FID_CLIENT, NULL, NULL | 
|---|
| 374 | ); | 
|---|
| 375 | } else { | 
|---|
| 376 | #if !defined(QT_NO_DEBUG) && defined(QT_DEBUGWINCREATEDESTROY) | 
|---|
| 377 | qDebug( | 
|---|
| 378 | "|Creating top level window [%s]:\n" | 
|---|
| 379 | "|  owner = %08lX\n" | 
|---|
| 380 | "|  class = '%s'\n" | 
|---|
| 381 | "|  title = '%s'\n" | 
|---|
| 382 | "|  style = %08lX", | 
|---|
| 383 | name(), ownerw, pszClassName, title, style | 
|---|
| 384 | ); | 
|---|
| 385 | #endif | 
|---|
| 386 | id = WinCreateWindow( | 
|---|
| 387 | HWND_DESKTOP, pszClassName, title, style, 0, 0, 0, 0, | 
|---|
| 388 | ownerw, HWND_TOP, 0, NULL, NULL | 
|---|
| 389 | ); | 
|---|
| 390 | } | 
|---|
| 391 | #ifndef QT_NO_DEBUG | 
|---|
| 392 | #ifdef QT_DEBUGWINCREATEDESTROY | 
|---|
| 393 | qDebug( "|  hwnd = %08lX", id ); | 
|---|
| 394 | #endif | 
|---|
| 395 | if ( id == 0 ) | 
|---|
| 396 | qSystemWarning( "QWidget: Failed to create window" ); | 
|---|
| 397 | #endif | 
|---|
| 398 | setWinId( id ); | 
|---|
| 399 | //@@TODO (dmik): remove? | 
|---|
| 400 | //      if ( testWFlags( WStyle_StaysOnTop) ) | 
|---|
| 401 | //          SetWindowPos( id, HWND_TOPMOST, 0, 0, 100, 100, SWP_NOACTIVATE ); | 
|---|
| 402 |  | 
|---|
| 403 | // When the FS_SHELLPOSITION flag is specified during WC_FRAME window | 
|---|
| 404 | // creation its size and position remains zero until it is shown | 
|---|
| 405 | // for the first time. So, we don't use FS_SHELLPOSITION but emulate | 
|---|
| 406 | // its functionality here. | 
|---|
| 407 | SWP swp; | 
|---|
| 408 | WinQueryTaskSizePos( 0, 0, &swp ); | 
|---|
| 409 | WinSetWindowPos( fId, 0, swp.x, swp.y, swp.cx, swp.cy, SWP_SIZE | SWP_MOVE ); | 
|---|
| 410 | } else { | 
|---|
| 411 | // create child widget | 
|---|
| 412 | HWND parentw = parentWidget()->winId(); | 
|---|
| 413 | #if !defined(QT_NO_DEBUG) && defined(QT_DEBUGWINCREATEDESTROY) | 
|---|
| 414 | qDebug( | 
|---|
| 415 | "|Creating child window [%s]:\n" | 
|---|
| 416 | "|  owner & parent = %08lX\n" | 
|---|
| 417 | "|  class = '%s'\n" | 
|---|
| 418 | "|  title = '%s'\n" | 
|---|
| 419 | "|  style = %08lX", | 
|---|
| 420 | name(), parentw, pszClassName, title, style | 
|---|
| 421 | ); | 
|---|
| 422 | #endif | 
|---|
| 423 | id = WinCreateWindow( | 
|---|
| 424 | parentw, pszClassName, title, style, | 
|---|
| 425 | 0, parentWidget()->crect.height() - 30, 100, 30, | 
|---|
| 426 | parentw, HWND_TOP, 0, NULL, NULL | 
|---|
| 427 | ); | 
|---|
| 428 | #ifndef QT_NO_DEBUG | 
|---|
| 429 | #ifdef QT_DEBUGWINCREATEDESTROY | 
|---|
| 430 | qDebug( "|  hwnd = %08lX", id ); | 
|---|
| 431 | #endif | 
|---|
| 432 | if ( id == 0 ) | 
|---|
| 433 | qSystemWarning( "QWidget: Failed to create window" ); | 
|---|
| 434 | #endif | 
|---|
| 435 | setWinId( id ); | 
|---|
| 436 | } | 
|---|
| 437 |  | 
|---|
| 438 | if ( desktop ) { | 
|---|
| 439 | setWState( WState_Visible ); | 
|---|
| 440 | } else { | 
|---|
| 441 | //@@TODO (dmik): remove. probably this is done for embedded windows? | 
|---|
| 442 | //      RECT  fr, cr; | 
|---|
| 443 | //      GetWindowRect( id, &fr );               // update rects | 
|---|
| 444 | //      GetClientRect( id, &cr ); | 
|---|
| 445 | //      if ( cr.top == cr.bottom && cr.left == cr.right ) { | 
|---|
| 446 | //          if ( initializeWindow ) { | 
|---|
| 447 | //              int x, y, w, h; | 
|---|
| 448 | //              if ( topLevel ) { | 
|---|
| 449 | //                  x = sw/4; | 
|---|
| 450 | //                  y = 3*sh/10; | 
|---|
| 451 | //                  w = sw/2; | 
|---|
| 452 | //                  h = 4*sh/10; | 
|---|
| 453 | //              } else { | 
|---|
| 454 | //                  x = y = 0; | 
|---|
| 455 | //                  w = 100; | 
|---|
| 456 | //                  h = 30; | 
|---|
| 457 | //              } | 
|---|
| 458 | // | 
|---|
| 459 | //              MoveWindow( winId(), x, y, w, h, TRUE ); | 
|---|
| 460 | //          } | 
|---|
| 461 | //          GetWindowRect( id, &fr );           // update rects | 
|---|
| 462 | //          GetClientRect( id, &cr ); | 
|---|
| 463 | //      } | 
|---|
| 464 | SWP cswp; | 
|---|
| 465 | WinQueryWindowPos( id, &cswp ); | 
|---|
| 466 | if ( topLevel ) { | 
|---|
| 467 | QTLWExtra *top = topData(); | 
|---|
| 468 | if ( fId ) { | 
|---|
| 469 | SWP fswp; | 
|---|
| 470 | WinQueryWindowPos( fId, &fswp ); | 
|---|
| 471 | // flip y coordinates | 
|---|
| 472 | fswp.y = sh - (fswp.y + fswp.cy); | 
|---|
| 473 | cswp.y = fswp.cy - (cswp.y + cswp.cy); | 
|---|
| 474 | crect.setRect( | 
|---|
| 475 | fswp.x + cswp.x, fswp.y + cswp.y, | 
|---|
| 476 | cswp.cx, cswp.cy | 
|---|
| 477 | ); | 
|---|
| 478 |  | 
|---|
| 479 | top->fleft = cswp.x; | 
|---|
| 480 | top->ftop = cswp.y; | 
|---|
| 481 | top->fright = fswp.cx - cswp.x - cswp.cx; | 
|---|
| 482 | top->fbottom = fswp.cy - cswp.y - cswp.cy; | 
|---|
| 483 | top->fId = fId; | 
|---|
| 484 | } else { | 
|---|
| 485 | // flip y coordinate | 
|---|
| 486 | cswp.y = sh - (cswp.y + cswp.cy); | 
|---|
| 487 | crect.setRect( cswp.x, cswp.y, cswp.cx, cswp.cy ); | 
|---|
| 488 | } | 
|---|
| 489 | fstrut_dirty = FALSE; | 
|---|
| 490 | } else { | 
|---|
| 491 | int cy = parentWidget()->crect.height(); | 
|---|
| 492 | // flip y coordinate | 
|---|
| 493 | cswp.y = cy - (cswp.y + cswp.cy); | 
|---|
| 494 | crect.setRect( cswp.x, cswp.y, cswp.cx, cswp.cy ); | 
|---|
| 495 | // in case extra data already exists (eg. reparent()).  Set it. | 
|---|
| 496 | //@@TODO (dmik): what's this? ~~~^ | 
|---|
| 497 | } | 
|---|
| 498 | } | 
|---|
| 499 |  | 
|---|
| 500 | setWState( WState_Created );                // accept move/resize events | 
|---|
| 501 | hps = 0;                                    // no presentation space | 
|---|
| 502 |  | 
|---|
| 503 | //@@TODO (dmik): guess this is for embedded windows. remove? | 
|---|
| 504 | //    if ( window ) {                           // got window from outside | 
|---|
| 505 | //      if ( IsWindowVisible(window) ) | 
|---|
| 506 | //          setWState( WState_Visible ); | 
|---|
| 507 | //      else | 
|---|
| 508 | //          clearWState( WState_Visible ); | 
|---|
| 509 | //    } | 
|---|
| 510 |  | 
|---|
| 511 | //@@TODO (dmik): need? | 
|---|
| 512 | //#if defined(QT_NON_COMMERCIAL) | 
|---|
| 513 | //    QT_NC_WIDGET_CREATE | 
|---|
| 514 | //#endif | 
|---|
| 515 |  | 
|---|
| 516 | //@@TODO (dmik): guess this is for embedded windows. remove? | 
|---|
| 517 | //    if ( destroyw ) { | 
|---|
| 518 | //      WinDestroyWindow( destroyw ); | 
|---|
| 519 | //    } | 
|---|
| 520 |  | 
|---|
| 521 | setFontSys(); | 
|---|
| 522 | //@@TODO (dmik): remove? | 
|---|
| 523 | //    QInputContext::enable( this, im_enabled & !((bool)testWState(WState_Disabled)) ); | 
|---|
| 524 | } | 
|---|
| 525 |  | 
|---|
| 526 |  | 
|---|
| 527 | void QWidget::destroy( bool destroyWindow, bool destroySubWindows ) | 
|---|
| 528 | { | 
|---|
| 529 | deactivateWidgetCleanup(); | 
|---|
| 530 | if ( testWState(WState_Created) ) { | 
|---|
| 531 | clearWState( WState_Created ); | 
|---|
| 532 | if ( children() ) { | 
|---|
| 533 | QObjectListIt it(*children()); | 
|---|
| 534 | register QObject *obj; | 
|---|
| 535 | while ( (obj=it.current()) ) {      // destroy all widget children | 
|---|
| 536 | ++it; | 
|---|
| 537 | if ( obj->isWidgetType() ) | 
|---|
| 538 | ((QWidget*)obj)->destroy(destroySubWindows, | 
|---|
| 539 | destroySubWindows); | 
|---|
| 540 | } | 
|---|
| 541 | } | 
|---|
| 542 | if ( mouseGrb == this ) | 
|---|
| 543 | releaseMouse(); | 
|---|
| 544 | if ( keyboardGrb == this ) | 
|---|
| 545 | releaseKeyboard(); | 
|---|
| 546 | if ( testWFlags(WShowModal) )           // just be sure we leave modal | 
|---|
| 547 | qt_leave_modal( this ); | 
|---|
| 548 | else if ( testWFlags(WType_Popup) ) | 
|---|
| 549 | qApp->closePopup( this ); | 
|---|
| 550 | if ( destroyWindow && !testWFlags(WType_Desktop) ) { | 
|---|
| 551 | HWND id = winId(); | 
|---|
| 552 | if ( isTopLevel() && !testWFlags(WType_Popup) ) { | 
|---|
| 553 | // extra data including extra->topextra has been already | 
|---|
| 554 | // deleted at this point by deleteExtra() and therefore | 
|---|
| 555 | // calling winFId() useless -- it will always return the | 
|---|
| 556 | // client window handle. Use WinQueryWindow() instead. | 
|---|
| 557 | id = WinQueryWindow( id, QW_PARENT ); | 
|---|
| 558 | } | 
|---|
| 559 | #if !defined(QT_NO_DEBUG) && defined(QT_DEBUGWINCREATEDESTROY) | 
|---|
| 560 | qDebug( | 
|---|
| 561 | "|Destroying window:\n" | 
|---|
| 562 | "|  hwnd = %08lX", | 
|---|
| 563 | id | 
|---|
| 564 | ); | 
|---|
| 565 | #endif | 
|---|
| 566 | WinDestroyWindow( id ); | 
|---|
| 567 | } | 
|---|
| 568 | setWinId( 0 ); | 
|---|
| 569 | } | 
|---|
| 570 | } | 
|---|
| 571 |  | 
|---|
| 572 | void QWidget::reparentSys( QWidget *parent, WFlags f, const QPoint &p, | 
|---|
| 573 | bool showIt ) | 
|---|
| 574 | { | 
|---|
| 575 | QWidget* oldtlw = topLevelWidget(); | 
|---|
| 576 | WId old_winfid = winFId(); | 
|---|
| 577 |  | 
|---|
| 578 | // hide and reparent our own window away. Otherwise we might get | 
|---|
| 579 | // destroyed when emitting the child remove event below. See QWorkspace. | 
|---|
| 580 | // this is also necessary for modal windows to leave the modal state | 
|---|
| 581 | // correctly. | 
|---|
| 582 | if ( isVisible() ) { | 
|---|
| 583 | hide(); | 
|---|
| 584 | WinSetParent( old_winfid, HWND_OBJECT, FALSE ); | 
|---|
| 585 | WinSetOwner( old_winfid, 0 ); | 
|---|
| 586 | } | 
|---|
| 587 |  | 
|---|
| 588 | // unblock the widget if blocked | 
|---|
| 589 | QWidget *blockedBy = 0; | 
|---|
| 590 | if ( isTopLevel() ) | 
|---|
| 591 | blockedBy = (QWidget*) WinQueryWindowULong( winId(), QWL_QTMODAL ); | 
|---|
| 592 | if ( !blockedBy && parentWidget() ) | 
|---|
| 593 | blockedBy = (QWidget*) WinQueryWindowULong( | 
|---|
| 594 | parentWidget()->topLevelWidget()->winId(), QWL_QTMODAL ); | 
|---|
| 595 | if ( blockedBy ) { | 
|---|
| 596 | QEvent e( QEvent::WindowUnblocked ); | 
|---|
| 597 | qt_sendBlocked( this, blockedBy, &e, FALSE ); | 
|---|
| 598 | } | 
|---|
| 599 |  | 
|---|
| 600 | bool accept_drops = acceptDrops(); | 
|---|
| 601 | if ( accept_drops ) | 
|---|
| 602 | setAcceptDrops( FALSE ); // ole dnd unregister (we will register again below) | 
|---|
| 603 | if ( testWFlags(WType_Desktop) ) | 
|---|
| 604 | old_winfid = 0; | 
|---|
| 605 | setWinId( 0 ); | 
|---|
| 606 | if ( isTopLevel() ) { | 
|---|
| 607 | QTLWExtra *top = topData(); | 
|---|
| 608 | if ( top->swEntry ) { | 
|---|
| 609 | WinRemoveSwitchEntry( top->swEntry ); | 
|---|
| 610 | top->swEntry = 0; | 
|---|
| 611 | } | 
|---|
| 612 | top->fId = 0; | 
|---|
| 613 | } | 
|---|
| 614 |  | 
|---|
| 615 | if ( parent != parentObj ) { | 
|---|
| 616 | if ( parentObj )                                // remove from parent | 
|---|
| 617 | parentObj->removeChild( this ); | 
|---|
| 618 | if ( parent )                                   // insert into new parent | 
|---|
| 619 | parent->insertChild( this ); | 
|---|
| 620 | } | 
|---|
| 621 |  | 
|---|
| 622 | bool enable     = isEnabled();              // remember status | 
|---|
| 623 | FocusPolicy fp  = focusPolicy(); | 
|---|
| 624 | QSize s         = size(); | 
|---|
| 625 | QString capt    = caption(); | 
|---|
| 626 | widget_flags    = f; | 
|---|
| 627 | clearWState( WState_Created | WState_Visible | WState_ForceHide ); | 
|---|
| 628 | create(); | 
|---|
| 629 | if ( isTopLevel() || (!parent || parent->isVisible() ) ) | 
|---|
| 630 | setWState( WState_ForceHide );  // new widgets do not show up in already visible parents | 
|---|
| 631 | const QObjectList *chlist = children(); | 
|---|
| 632 | if ( chlist ) {                             // reparent children | 
|---|
| 633 | SWP swp; | 
|---|
| 634 | QObjectListIt it( *chlist ); | 
|---|
| 635 | QObject *obj; | 
|---|
| 636 | while ( (obj=it.current()) ) { | 
|---|
| 637 | if ( obj->isWidgetType() ) { | 
|---|
| 638 | QWidget *w = (QWidget *)obj; | 
|---|
| 639 | if ( w->isPopup() ) | 
|---|
| 640 | ; | 
|---|
| 641 | else if ( w->isTopLevel() ) { | 
|---|
| 642 | w->reparent( this, w->getWFlags(), w->pos(), !w->isHidden() ); | 
|---|
| 643 | } else { | 
|---|
| 644 | WinSetParent( w->winId(), winId(), FALSE ); | 
|---|
| 645 | WinSetOwner( w->winId(), winId() ); | 
|---|
| 646 | // bring PM coords into accordance with Qt coords, | 
|---|
| 647 | // otherwise setGeometry() below will wrongly position | 
|---|
| 648 | // children if this widget manages their layout. | 
|---|
| 649 | int hd = height() - s.height(); | 
|---|
| 650 | WinQueryWindowPos( w->winId(), &swp ); | 
|---|
| 651 | swp.y += hd; | 
|---|
| 652 | WinSetWindowPos( w->winId(), 0, swp.x, swp.y, 0, 0, SWP_MOVE ); | 
|---|
| 653 | } | 
|---|
| 654 | } | 
|---|
| 655 | ++it; | 
|---|
| 656 | } | 
|---|
| 657 | } | 
|---|
| 658 |  | 
|---|
| 659 | // block the widget if it should be blocked | 
|---|
| 660 | blockedBy = 0; | 
|---|
| 661 | if ( parentWidget() ) | 
|---|
| 662 | blockedBy = (QWidget*) WinQueryWindowULong( | 
|---|
| 663 | parentWidget()->topLevelWidget()->winId(), QWL_QTMODAL ); | 
|---|
| 664 | if ( blockedBy ) { | 
|---|
| 665 | if ( isTopLevel() && testWFlags( WGroupLeader ) ) | 
|---|
| 666 | blockedBy = 0; | 
|---|
| 667 | } else { | 
|---|
| 668 | QWidget *topModal = qApp->activeModalWidget(); | 
|---|
| 669 | if ( | 
|---|
| 670 | topModal && this != topModal && parentWidget() != topModal && | 
|---|
| 671 | isTopLevel() && !testWFlags( WGroupLeader ) | 
|---|
| 672 | ) | 
|---|
| 673 | blockedBy = topModal; | 
|---|
| 674 | } | 
|---|
| 675 | if ( blockedBy ) { | 
|---|
| 676 | QEvent e( QEvent::WindowBlocked ); | 
|---|
| 677 | qt_sendBlocked( this, blockedBy, &e, FALSE ); | 
|---|
| 678 | } | 
|---|
| 679 |  | 
|---|
| 680 | setGeometry( p.x(), p.y(), s.width(), s.height() ); | 
|---|
| 681 | setEnabled( enable ); | 
|---|
| 682 | setFocusPolicy( fp ); | 
|---|
| 683 | if ( !capt.isNull() ) { | 
|---|
| 684 | extra->topextra->caption = QString::null; | 
|---|
| 685 | setCaption( capt ); | 
|---|
| 686 | } | 
|---|
| 687 | if ( showIt ) | 
|---|
| 688 | show(); | 
|---|
| 689 | if ( old_winfid ) | 
|---|
| 690 | WinDestroyWindow( old_winfid ); | 
|---|
| 691 |  | 
|---|
| 692 | reparentFocusWidgets( oldtlw );             // fix focus chains | 
|---|
| 693 |  | 
|---|
| 694 | if ( accept_drops ) | 
|---|
| 695 | setAcceptDrops( TRUE ); | 
|---|
| 696 |  | 
|---|
| 697 | //@@TODO (dmik): remove? | 
|---|
| 698 | //#ifdef Q_OS_TEMP | 
|---|
| 699 | //    // Show borderless toplevel windows in tasklist & NavBar | 
|---|
| 700 | //    if ( !parent ) { | 
|---|
| 701 | //      QString txt = caption().isEmpty()?qAppName():caption(); | 
|---|
| 702 | //      SetWindowText( winId(), (TCHAR*)txt.ucs2() ); | 
|---|
| 703 | //    } | 
|---|
| 704 | //#endif | 
|---|
| 705 | } | 
|---|
| 706 |  | 
|---|
| 707 | QPoint QWidget::mapToGlobal( const QPoint &pos ) const | 
|---|
| 708 | { | 
|---|
| 709 | if ( !isVisible() || isMinimized() ) | 
|---|
| 710 | return mapTo( topLevelWidget(), pos ) + topLevelWidget()->pos() + | 
|---|
| 711 | (topLevelWidget()->geometry().topLeft() - topLevelWidget()->frameGeometry().topLeft()); | 
|---|
| 712 | POINTL ptl; | 
|---|
| 713 | ptl.x = pos.x(); | 
|---|
| 714 | // flip y (local) coordinate | 
|---|
| 715 | ptl.y = height() - (pos.y() + 1); | 
|---|
| 716 | WinMapWindowPoints( winId(), HWND_DESKTOP, &ptl, 1 ); | 
|---|
| 717 | // flip y (global) coordinate | 
|---|
| 718 | ptl.y = QApplication::desktop()->height() - (ptl.y + 1); | 
|---|
| 719 | return QPoint( ptl.x, ptl.y ); | 
|---|
| 720 | } | 
|---|
| 721 |  | 
|---|
| 722 | QPoint QWidget::mapFromGlobal( const QPoint &pos ) const | 
|---|
| 723 | { | 
|---|
| 724 | if ( !isVisible() || isMinimized() ) | 
|---|
| 725 | return mapFrom( topLevelWidget(), pos - topLevelWidget()->pos() ); | 
|---|
| 726 | POINTL ptl; | 
|---|
| 727 | ptl.x = pos.x(); | 
|---|
| 728 | // flip y (global) coordinate | 
|---|
| 729 | ptl.y = QApplication::desktop()->height() - (pos.y() + 1); | 
|---|
| 730 | WinMapWindowPoints( HWND_DESKTOP, winId(), &ptl, 1 ); | 
|---|
| 731 | // flip y (local) coordinate | 
|---|
| 732 | ptl.y = height() - (ptl.y + 1); | 
|---|
| 733 | return QPoint( ptl.x, ptl.y ); | 
|---|
| 734 | } | 
|---|
| 735 |  | 
|---|
| 736 | void QWidget::setFontSys( QFont *f ) | 
|---|
| 737 | { | 
|---|
| 738 | //@@TODO (dmik): should this do something on OS/2? | 
|---|
| 739 | //@@TODO (dmik): remove? | 
|---|
| 740 | //    QInputContext::setFont( this, (f ? *f : font()) ); | 
|---|
| 741 | } | 
|---|
| 742 |  | 
|---|
| 743 | void QWidget::setMicroFocusHint(int x, int y, int width, int height, bool text, QFont *f) | 
|---|
| 744 | { | 
|---|
| 745 | //@@TODO (dmik): do we need to create a caret (cursor) in OS/2 also? | 
|---|
| 746 | //  currently, try to do so (which can be useful for 3rd-party apps | 
|---|
| 747 | //  that are interested in the current cursor position, i.e. where the user | 
|---|
| 748 | //  input is now taking place. | 
|---|
| 749 | // flip y coordinate | 
|---|
| 750 | int fy = crect.height() - (y + height); | 
|---|
| 751 | WinCreateCursor( winId(), x, fy, width, height, CURSOR_SOLID, NULL ); | 
|---|
| 752 |  | 
|---|
| 753 | //@@TODO (dmik): remove? | 
|---|
| 754 | //    if ( text ) | 
|---|
| 755 | //      QInputContext::setFocusHint( x, y, width, height, this ); | 
|---|
| 756 | setFontSys( f ); | 
|---|
| 757 |  | 
|---|
| 758 | if ( QRect( x, y, width, height ) != microFocusHint() ) | 
|---|
| 759 | extraData()->micro_focus_hint.setRect( x, y, width, height ); | 
|---|
| 760 | } | 
|---|
| 761 |  | 
|---|
| 762 | void QWidget::resetInputContext() | 
|---|
| 763 | { | 
|---|
| 764 | //@@TODO (dmik): remove? | 
|---|
| 765 | //    QInputContext::accept(); | 
|---|
| 766 | } | 
|---|
| 767 |  | 
|---|
| 768 | void QWidget::setBackgroundColorDirect( const QColor &color ) | 
|---|
| 769 | { | 
|---|
| 770 | bg_col = color; | 
|---|
| 771 | if ( extra && extra->bg_pix ) {             // kill the background pixmap | 
|---|
| 772 | delete extra->bg_pix; | 
|---|
| 773 | extra->bg_pix = 0; | 
|---|
| 774 | } | 
|---|
| 775 | } | 
|---|
| 776 |  | 
|---|
| 777 |  | 
|---|
| 778 | static int allow_null_pixmaps = 0; | 
|---|
| 779 |  | 
|---|
| 780 |  | 
|---|
| 781 | void QWidget::setBackgroundPixmapDirect( const QPixmap &pixmap ) | 
|---|
| 782 | { | 
|---|
| 783 | QPixmap old; | 
|---|
| 784 | if ( extra && extra->bg_pix ) | 
|---|
| 785 | old = *extra->bg_pix; | 
|---|
| 786 | if ( !allow_null_pixmaps && pixmap.isNull() ) { | 
|---|
| 787 | if ( extra && extra->bg_pix ) { | 
|---|
| 788 | delete extra->bg_pix; | 
|---|
| 789 | extra->bg_pix = 0; | 
|---|
| 790 | } | 
|---|
| 791 | } else { | 
|---|
| 792 | if ( extra && extra->bg_pix ) | 
|---|
| 793 | delete extra->bg_pix; | 
|---|
| 794 | else | 
|---|
| 795 | createExtra(); | 
|---|
| 796 | extra->bg_pix = new QPixmap( pixmap ); | 
|---|
| 797 | } | 
|---|
| 798 | } | 
|---|
| 799 |  | 
|---|
| 800 |  | 
|---|
| 801 | void QWidget::setBackgroundEmpty() | 
|---|
| 802 | { | 
|---|
| 803 | allow_null_pixmaps++; | 
|---|
| 804 | setErasePixmap(QPixmap()); | 
|---|
| 805 | allow_null_pixmaps--; | 
|---|
| 806 | } | 
|---|
| 807 |  | 
|---|
| 808 | extern void qt_set_cursor( QWidget *, const QCursor & ); // qapplication_pm.cpp | 
|---|
| 809 |  | 
|---|
| 810 | void QWidget::setCursor( const QCursor &cursor ) | 
|---|
| 811 | { | 
|---|
| 812 | if ( cursor.handle() != arrowCursor.handle() | 
|---|
| 813 | || (extra && extra->curs) ) { | 
|---|
| 814 | createExtra(); | 
|---|
| 815 | delete extra->curs; | 
|---|
| 816 | extra->curs = new QCursor(cursor); | 
|---|
| 817 | } | 
|---|
| 818 | setWState( WState_OwnCursor ); | 
|---|
| 819 | qt_set_cursor( this, QWidget::cursor() ); | 
|---|
| 820 | } | 
|---|
| 821 |  | 
|---|
| 822 | void QWidget::unsetCursor() | 
|---|
| 823 | { | 
|---|
| 824 | if ( extra ) { | 
|---|
| 825 | delete extra->curs; | 
|---|
| 826 | extra->curs = 0; | 
|---|
| 827 | } | 
|---|
| 828 | if ( !isTopLevel() ) | 
|---|
| 829 | clearWState( WState_OwnCursor ); | 
|---|
| 830 | qt_set_cursor( this, cursor() ); | 
|---|
| 831 | } | 
|---|
| 832 |  | 
|---|
| 833 | void QWidget::setCaption( const QString &caption ) | 
|---|
| 834 | { | 
|---|
| 835 | if ( QWidget::caption() == caption ) | 
|---|
| 836 | return; // for less flicker | 
|---|
| 837 | topData()->caption = caption; | 
|---|
| 838 |  | 
|---|
| 839 | //@@TODO (dmik): need? | 
|---|
| 840 | //#if defined(QT_NON_COMMERCIAL) | 
|---|
| 841 | //    QT_NC_CAPTION | 
|---|
| 842 | //#else | 
|---|
| 843 | //    QString cap = caption; | 
|---|
| 844 | //#endif | 
|---|
| 845 |  | 
|---|
| 846 | QCString cap = caption.local8Bit(); | 
|---|
| 847 | WinSetWindowText( winFId(), cap ); | 
|---|
| 848 |  | 
|---|
| 849 | HSWITCH swEntry = topData()->swEntry; | 
|---|
| 850 | if ( swEntry ) { | 
|---|
| 851 | SWCNTRL swc; | 
|---|
| 852 | WinQuerySwitchEntry( swEntry, &swc ); | 
|---|
| 853 | strncpy( swc.szSwtitle, cap, sizeof(swc.szSwtitle)-1 ); | 
|---|
| 854 | swc.szSwtitle [sizeof(swc.szSwtitle)-1] = 0; | 
|---|
| 855 | WinChangeSwitchEntry( swEntry, &swc ); | 
|---|
| 856 | } | 
|---|
| 857 |  | 
|---|
| 858 | QEvent e( QEvent::CaptionChange ); | 
|---|
| 859 | QApplication::sendEvent( this, &e ); | 
|---|
| 860 | } | 
|---|
| 861 |  | 
|---|
| 862 | //@@TODO (dmik): later | 
|---|
| 863 | ///* | 
|---|
| 864 | //  Create an icon mask the way Windows wants it using CreateBitmap. | 
|---|
| 865 | //*/ | 
|---|
| 866 | // | 
|---|
| 867 | //HBITMAP qt_createIconMask( const QBitmap &bitmap ) | 
|---|
| 868 | //{ | 
|---|
| 869 | //    QImage bm = bitmap.convertToImage(); | 
|---|
| 870 | //    int w = bm.width(); | 
|---|
| 871 | //    int h = bm.height(); | 
|---|
| 872 | //    int bpl = ((w+15)/16)*2;                  // bpl, 16 bit alignment | 
|---|
| 873 | //    uchar *bits = new uchar[bpl*h]; | 
|---|
| 874 | //    bm.invertPixels(); | 
|---|
| 875 | //    for ( int y=0; y<h; y++ ) | 
|---|
| 876 | //      memcpy( bits+y*bpl, bm.scanLine(y), bpl ); | 
|---|
| 877 | //    HBITMAP hbm = CreateBitmap( w, h, 1, 1, bits ); | 
|---|
| 878 | //    delete [] bits; | 
|---|
| 879 | //    return hbm; | 
|---|
| 880 | //} | 
|---|
| 881 |  | 
|---|
| 882 | void QWidget::setIcon( const QPixmap &pixmap ) | 
|---|
| 883 | { | 
|---|
| 884 | qWarning( "QWidget::setIcon() is not yet implemented on OS/2" ); | 
|---|
| 885 | //@@TODO (dmik): later | 
|---|
| 886 | //    QTLWExtra* x = topData(); | 
|---|
| 887 | //    delete x->icon; | 
|---|
| 888 | //    x->icon = 0; | 
|---|
| 889 | //    if ( x->winIcon ) { | 
|---|
| 890 | //      DestroyIcon( x->winIcon ); | 
|---|
| 891 | //      x->winIcon = 0; | 
|---|
| 892 | //    } | 
|---|
| 893 | //    if ( !pixmap.isNull() ) {                 // valid icon | 
|---|
| 894 | //      QPixmap pm( pixmap.size(), pixmap.depth(), QPixmap::NormalOptim ); | 
|---|
| 895 | //      QBitmap mask( pixmap.size(), FALSE, QPixmap::NormalOptim ); | 
|---|
| 896 | //      if ( pixmap.mask() ) { | 
|---|
| 897 | //          pm.fill( black );                   // make masked area black | 
|---|
| 898 | //          bitBlt( &mask, 0, 0, pixmap.mask() ); | 
|---|
| 899 | //      } else { | 
|---|
| 900 | //          mask.fill( color1 ); | 
|---|
| 901 | //      } | 
|---|
| 902 | //      bitBlt( &pm, 0, 0, &pixmap ); | 
|---|
| 903 | //      HBITMAP im = qt_createIconMask(mask); | 
|---|
| 904 | //      ICONINFO ii; | 
|---|
| 905 | //      ii.fIcon    = TRUE; | 
|---|
| 906 | //      ii.hbmMask  = im; | 
|---|
| 907 | //      ii.hbmColor = pm.hbm(); | 
|---|
| 908 | //      ii.xHotspot = 0; | 
|---|
| 909 | //      ii.yHotspot = 0; | 
|---|
| 910 | //      x->icon = new QPixmap( pixmap ); | 
|---|
| 911 | //      x->winIcon = CreateIconIndirect( &ii ); | 
|---|
| 912 | //      DeleteObject( im ); | 
|---|
| 913 | //    } | 
|---|
| 914 | //    SendMessageA( winId(), WM_SETICON, 0, /* ICON_SMALL */ | 
|---|
| 915 | //                (long)x->winIcon ); | 
|---|
| 916 | //    SendMessageA( winId(), WM_SETICON, 1, /* ICON_BIG */ | 
|---|
| 917 | //                (long)x->winIcon ); | 
|---|
| 918 | // | 
|---|
| 919 | //    QEvent e( QEvent::IconChange ); | 
|---|
| 920 | //    QApplication::sendEvent( this, &e ); | 
|---|
| 921 | } | 
|---|
| 922 |  | 
|---|
| 923 |  | 
|---|
| 924 | void QWidget::setIconText( const QString &iconText ) | 
|---|
| 925 | { | 
|---|
| 926 | topData()->iconText = iconText; | 
|---|
| 927 | } | 
|---|
| 928 |  | 
|---|
| 929 | QCursor *qt_grab_cursor() | 
|---|
| 930 | { | 
|---|
| 931 | return mouseGrbCur; | 
|---|
| 932 | } | 
|---|
| 933 |  | 
|---|
| 934 | void QWidget::grabMouse() | 
|---|
| 935 | { | 
|---|
| 936 | if ( !qt_nograb() ) { | 
|---|
| 937 | if ( mouseGrb ) | 
|---|
| 938 | mouseGrb->releaseMouse(); | 
|---|
| 939 | WinSetCapture( HWND_DESKTOP, winFId() ); | 
|---|
| 940 | mouseGrb = this; | 
|---|
| 941 | } | 
|---|
| 942 | } | 
|---|
| 943 |  | 
|---|
| 944 | void QWidget::grabMouse( const QCursor &cursor ) | 
|---|
| 945 | { | 
|---|
| 946 | if ( !qt_nograb() ) { | 
|---|
| 947 | if ( mouseGrb ) | 
|---|
| 948 | mouseGrb->releaseMouse(); | 
|---|
| 949 | WinSetCapture( HWND_DESKTOP, winFId() ); | 
|---|
| 950 | mouseGrbCur = new QCursor( cursor ); | 
|---|
| 951 | WinSetPointer( HWND_DESKTOP, mouseGrbCur->handle() ); | 
|---|
| 952 | mouseGrb = this; | 
|---|
| 953 | } | 
|---|
| 954 | } | 
|---|
| 955 |  | 
|---|
| 956 | void QWidget::releaseMouse() | 
|---|
| 957 | { | 
|---|
| 958 | if ( !qt_nograb() && mouseGrb == this ) { | 
|---|
| 959 | WinSetCapture( HWND_DESKTOP, 0 ); | 
|---|
| 960 | if ( mouseGrbCur ) { | 
|---|
| 961 | delete mouseGrbCur; | 
|---|
| 962 | mouseGrbCur = 0; | 
|---|
| 963 | } | 
|---|
| 964 | mouseGrb = 0; | 
|---|
| 965 | } | 
|---|
| 966 | } | 
|---|
| 967 |  | 
|---|
| 968 | void QWidget::grabKeyboard() | 
|---|
| 969 | { | 
|---|
| 970 | if ( !qt_nograb() ) { | 
|---|
| 971 | if ( keyboardGrb ) | 
|---|
| 972 | keyboardGrb->releaseKeyboard(); | 
|---|
| 973 | keyboardGrb = this; | 
|---|
| 974 | } | 
|---|
| 975 | } | 
|---|
| 976 |  | 
|---|
| 977 | void QWidget::releaseKeyboard() | 
|---|
| 978 | { | 
|---|
| 979 | if ( !qt_nograb() && keyboardGrb == this ) | 
|---|
| 980 | keyboardGrb = 0; | 
|---|
| 981 | } | 
|---|
| 982 |  | 
|---|
| 983 |  | 
|---|
| 984 | QWidget *QWidget::mouseGrabber() | 
|---|
| 985 | { | 
|---|
| 986 | return mouseGrb; | 
|---|
| 987 | } | 
|---|
| 988 |  | 
|---|
| 989 | QWidget *QWidget::keyboardGrabber() | 
|---|
| 990 | { | 
|---|
| 991 | return keyboardGrb; | 
|---|
| 992 | } | 
|---|
| 993 |  | 
|---|
| 994 | void QWidget::setActiveWindow() | 
|---|
| 995 | { | 
|---|
| 996 | WinSetActiveWindow( HWND_DESKTOP, topLevelWidget()->winFId() ); | 
|---|
| 997 | } | 
|---|
| 998 |  | 
|---|
| 999 | void QWidget::update() | 
|---|
| 1000 | { | 
|---|
| 1001 | update( 0, 0, -1, -1 ); | 
|---|
| 1002 | } | 
|---|
| 1003 |  | 
|---|
| 1004 | void QWidget::update( int x, int y, int w, int h ) | 
|---|
| 1005 | { | 
|---|
| 1006 | if ( w && h && | 
|---|
| 1007 | (widget_state & (WState_Visible|WState_BlockUpdates)) == WState_Visible ) { | 
|---|
| 1008 | if ( w < 0 ) | 
|---|
| 1009 | w = crect.width() - x; | 
|---|
| 1010 | if ( h < 0 ) | 
|---|
| 1011 | h = crect.height() - y; | 
|---|
| 1012 |  | 
|---|
| 1013 | // flip y coordinate | 
|---|
| 1014 | y = crect.height() - (y + h); | 
|---|
| 1015 | RECTL rcl = { x, y, x + w, y + h }; | 
|---|
| 1016 |  | 
|---|
| 1017 | // WinInvalidateRect() has such a "feature" that children are not | 
|---|
| 1018 | // actually extracted from the window's update region when it has | 
|---|
| 1019 | // the WS_CLIPCHILDREN flag, meaning that every child will anyway | 
|---|
| 1020 | // receive a WM_PAINT message if its visible region intersects with | 
|---|
| 1021 | // the update region of its parent, with its update region set to | 
|---|
| 1022 | // that intersection. This in turn means that if we invalidate the | 
|---|
| 1023 | // window completely, all its visible children wil completely repaint | 
|---|
| 1024 | // themselves, what is not we want. The solution is to manually | 
|---|
| 1025 | // substract children from the region we want to be updated. | 
|---|
| 1026 | ULONG wstyle = WinQueryWindowULong( winId(), QWL_STYLE ); | 
|---|
| 1027 | if ( (wstyle & WS_CLIPCHILDREN) && children() ) { | 
|---|
| 1028 | HPS lhps = hps; | 
|---|
| 1029 | if ( !lhps ) lhps = qt_display_ps(); | 
|---|
| 1030 | HRGN hrgn = GpiCreateRegion( lhps, 1, &rcl ); | 
|---|
| 1031 | HRGN whrgn = GpiCreateRegion( lhps, 0, NULL ); | 
|---|
| 1032 | int hgt = crect.height(); | 
|---|
| 1033 |  | 
|---|
| 1034 | QObjectListIt it(*children()); | 
|---|
| 1035 | register QObject *object; | 
|---|
| 1036 | QWidget *w; | 
|---|
| 1037 | while ( it ) { | 
|---|
| 1038 | object = it.current(); | 
|---|
| 1039 | ++it; | 
|---|
| 1040 | if ( object->isWidgetType() ) { | 
|---|
| 1041 | w = (QWidget*)object; | 
|---|
| 1042 | if ( !w->isTopLevel() && w->isShown() ) { | 
|---|
| 1043 | //@@TODO (dmik): later: substract the region of the child window | 
|---|
| 1044 | // (WinQueryClipRegion()) instead of the window rectangle. | 
|---|
| 1045 | const QRect &r = w->crect; | 
|---|
| 1046 | rcl.xLeft = r.left(); | 
|---|
| 1047 | rcl.yBottom = hgt - (r.bottom() + 1); | 
|---|
| 1048 | rcl.xRight = r.right() + 1; | 
|---|
| 1049 | rcl.yTop = hgt - r.top(); | 
|---|
| 1050 | GpiSetRegion( lhps, whrgn, 1, &rcl ); | 
|---|
| 1051 | GpiCombineRegion( lhps, hrgn, hrgn, whrgn, CRGN_DIFF ); | 
|---|
| 1052 | } | 
|---|
| 1053 | } | 
|---|
| 1054 | } | 
|---|
| 1055 | GpiDestroyRegion( lhps, whrgn ); | 
|---|
| 1056 | WinInvalidateRegion( winId(), hrgn, FALSE ); | 
|---|
| 1057 | GpiDestroyRegion( lhps, hrgn ); | 
|---|
| 1058 | } else { | 
|---|
| 1059 | WinInvalidateRect( winId(), &rcl, FALSE ); | 
|---|
| 1060 | } | 
|---|
| 1061 | } | 
|---|
| 1062 | } | 
|---|
| 1063 |  | 
|---|
| 1064 | void QWidget::repaint( int x, int y, int w, int h, bool erase ) | 
|---|
| 1065 | { | 
|---|
| 1066 | if ( (widget_state & (WState_Visible|WState_BlockUpdates)) == WState_Visible ) { | 
|---|
| 1067 | #if defined (DEBUG_REPAINTRESIZE) | 
|---|
| 1068 | qDebug( "repaint(): [%s/%s/%08X] %d,%d; %d,%d erase: %d resizeNoErase: %d", | 
|---|
| 1069 | name(), className(), widget_flags, x, y, w, h, erase, | 
|---|
| 1070 | (testWFlags( WResizeNoErase ) != 0) ); | 
|---|
| 1071 | #endif | 
|---|
| 1072 | if ( w < 0 ) | 
|---|
| 1073 | w = crect.width()  - x; | 
|---|
| 1074 | if ( h < 0 ) | 
|---|
| 1075 | h = crect.height() - y; | 
|---|
| 1076 | QRect r( x, y, w, h ); | 
|---|
| 1077 | if ( r.isEmpty() ) | 
|---|
| 1078 | return; // nothing to do | 
|---|
| 1079 |  | 
|---|
| 1080 | // flip y coordinate | 
|---|
| 1081 | int fy = crect.height() - (y + h); | 
|---|
| 1082 | RECTL rcl = { x, fy, x + w, fy + h }; | 
|---|
| 1083 | WinValidateRect( winId(), &rcl, FALSE ); | 
|---|
| 1084 |  | 
|---|
| 1085 | QRegion *pcrgn = 0; | 
|---|
| 1086 | if ( r != rect() ) { | 
|---|
| 1087 | pcrgn = new QRegion( r ); | 
|---|
| 1088 | WinSetWindowULong( winId(), QWL_QTCLIPRGN, (ULONG) pcrgn ); | 
|---|
| 1089 | } | 
|---|
| 1090 |  | 
|---|
| 1091 | QPaintEvent e( r, erase ); | 
|---|
| 1092 | if ( erase ) | 
|---|
| 1093 | this->erase( x, y, w, h ); | 
|---|
| 1094 | QApplication::sendEvent( this, &e ); | 
|---|
| 1095 |  | 
|---|
| 1096 | if ( pcrgn ) { | 
|---|
| 1097 | WinSetWindowULong( winId(), QWL_QTCLIPRGN, 0 ); | 
|---|
| 1098 | delete pcrgn; | 
|---|
| 1099 | } | 
|---|
| 1100 | } | 
|---|
| 1101 | } | 
|---|
| 1102 |  | 
|---|
| 1103 | void QWidget::repaint( const QRegion& reg, bool erase ) | 
|---|
| 1104 | { | 
|---|
| 1105 | if ( (widget_state & (WState_Visible|WState_BlockUpdates)) == WState_Visible ) { | 
|---|
| 1106 | #if defined (DEBUG_REPAINTRESIZE) | 
|---|
| 1107 | qDebug( "repaint(): [%s/%s/%08X] <region> erase: %d resizeNoErase: %d", | 
|---|
| 1108 | name(), className(), widget_flags, | 
|---|
| 1109 | (testWFlags( WResizeNoErase ) != 0) ); | 
|---|
| 1110 | #endif | 
|---|
| 1111 | // convert region y coordinates from Qt to GPI (see qregion_pm.cpp) | 
|---|
| 1112 | POINTL ptl = { 0, height() }; | 
|---|
| 1113 | GpiOffsetRegion( qt_display_ps(), reg.handle(), &ptl ); | 
|---|
| 1114 | WinValidateRegion( winId(), reg.handle(), FALSE ); | 
|---|
| 1115 | // convert region y coordinates back from GPI to Qt | 
|---|
| 1116 | ptl.y = -ptl.y; | 
|---|
| 1117 | GpiOffsetRegion( qt_display_ps(), reg.handle(), &ptl ); | 
|---|
| 1118 |  | 
|---|
| 1119 | QRegion *pcrgn = new QRegion( reg ); | 
|---|
| 1120 | WinSetWindowULong( winId(), QWL_QTCLIPRGN, (ULONG) pcrgn ); | 
|---|
| 1121 |  | 
|---|
| 1122 | QPaintEvent e( reg, erase ); | 
|---|
| 1123 | if ( erase ) | 
|---|
| 1124 | this->erase( reg ); | 
|---|
| 1125 | QApplication::sendEvent( this, &e ); | 
|---|
| 1126 |  | 
|---|
| 1127 | WinSetWindowULong( winId(), QWL_QTCLIPRGN, 0 ); | 
|---|
| 1128 | delete pcrgn; | 
|---|
| 1129 | } | 
|---|
| 1130 | } | 
|---|
| 1131 |  | 
|---|
| 1132 | void QWidget::setWindowState(uint newstate) | 
|---|
| 1133 | { | 
|---|
| 1134 | uint oldstate = windowState(); | 
|---|
| 1135 |  | 
|---|
| 1136 | //@@TODO (dmik): should we deactivate the widget when no WindowActive | 
|---|
| 1137 | //  is specified? Guess no, because such behavior can be seen in Win32 | 
|---|
| 1138 | //  (the only exception is when WindowMinimized is set w/o WindowActive). | 
|---|
| 1139 | //  As well as nothing is done in Win32 when only WindowActive is | 
|---|
| 1140 | //  specified. | 
|---|
| 1141 | ULONG fl = (newstate & WindowActive) ? | 
|---|
| 1142 | SWP_ACTIVATE : | 
|---|
| 1143 | // mimic Win32 behavior | 
|---|
| 1144 | (newstate & WindowMinimized) ? SWP_DEACTIVATE : | 
|---|
| 1145 | // mimic Win32 behavior | 
|---|
| 1146 | ((oldstate & WindowMinimized) && | 
|---|
| 1147 | (newstate & WindowMaximized)) ? SWP_ACTIVATE : | 
|---|
| 1148 | 0; | 
|---|
| 1149 |  | 
|---|
| 1150 | if (isTopLevel()) { | 
|---|
| 1151 | WId id = winFId(); | 
|---|
| 1152 | QTLWExtra *top = topData(); | 
|---|
| 1153 |  | 
|---|
| 1154 | if ((oldstate & WindowMaximized) != (newstate & WindowMaximized)) { | 
|---|
| 1155 | if (isVisible() && !(newstate & WindowMinimized)) { | 
|---|
| 1156 | ULONG f = (newstate & WindowMaximized) ? SWP_MAXIMIZE : SWP_RESTORE; | 
|---|
| 1157 | WinSetWindowPos( id, 0, 0, 0, 0, 0, fl | f ); | 
|---|
| 1158 | QRect r = topData()->normalGeometry; | 
|---|
| 1159 | if (!(newstate & WindowMaximized) && r.width() >= 0) { | 
|---|
| 1160 | if (pos() != r.topLeft() || size() !=r.size()) { | 
|---|
| 1161 | top->normalGeometry = QRect( 0, 0, -1, -1 ); | 
|---|
| 1162 | r.addCoords( top->fleft, top->ftop, top->fleft, top->ftop); | 
|---|
| 1163 | setGeometry( r ); | 
|---|
| 1164 | } | 
|---|
| 1165 | } | 
|---|
| 1166 | } | 
|---|
| 1167 | } | 
|---|
| 1168 |  | 
|---|
| 1169 | if ((oldstate & WindowFullScreen) != (newstate & WindowFullScreen)) { | 
|---|
| 1170 | if (newstate & WindowFullScreen) { | 
|---|
| 1171 | if ( top->normalGeometry.width() < 0 && !(oldstate & WindowMaximized) ) | 
|---|
| 1172 | top->normalGeometry = QRect( pos(), size() ); | 
|---|
| 1173 | QRect r = QApplication::desktop()->screenGeometry(this); | 
|---|
| 1174 | r.addCoords( -top->fleft, -top->fbottom, top->fright, top->ftop ); | 
|---|
| 1175 | WinSetWindowPos( | 
|---|
| 1176 | id, 0, r.x(), r.y(), r.width(), r.height(), | 
|---|
| 1177 | fl | SWP_SIZE | SWP_MOVE | 
|---|
| 1178 | ); | 
|---|
| 1179 | //@@TODO (dmik): we do not need to call updateFrameStrut() because the frame | 
|---|
| 1180 | //  is not changed, but who will update our crect?.. | 
|---|
| 1181 | //              updateFrameStrut(); | 
|---|
| 1182 | } else { | 
|---|
| 1183 | ULONG f = fl; | 
|---|
| 1184 | // the widget is still maximized | 
|---|
| 1185 | if ( newstate & WindowMaximized ) { | 
|---|
| 1186 | if (isVisible()) | 
|---|
| 1187 | f |= SWP_MAXIMIZE; | 
|---|
| 1188 | } | 
|---|
| 1189 | if ( f ) WinSetWindowPos( id, 0, 0, 0, 0, 0, f ); | 
|---|
| 1190 | if ( !(newstate & WindowMaximized) ) { | 
|---|
| 1191 | QRect r = top->normalGeometry; | 
|---|
| 1192 | top->normalGeometry = QRect( 0, 0, -1, -1 ); | 
|---|
| 1193 | r.addCoords( top->fleft, top->ftop, top->fleft, top->ftop); | 
|---|
| 1194 | setGeometry( r ); | 
|---|
| 1195 | } | 
|---|
| 1196 | //@@TODO (dmik): we do not need to call updateFrameStrut() because the frame | 
|---|
| 1197 | //  is not changed, but who will update our crect?.. | 
|---|
| 1198 | //              else { | 
|---|
| 1199 | //                    updateFrameStrut(); | 
|---|
| 1200 | //                } | 
|---|
| 1201 | } | 
|---|
| 1202 | } | 
|---|
| 1203 |  | 
|---|
| 1204 | if ((oldstate & WindowMinimized) != (newstate & WindowMinimized)) { | 
|---|
| 1205 | if (isVisible()) { | 
|---|
| 1206 | ULONG f = | 
|---|
| 1207 | (newstate & WindowMinimized) ? SWP_MINIMIZE : | 
|---|
| 1208 | (newstate & WindowMaximized) ? SWP_MAXIMIZE : SWP_RESTORE; | 
|---|
| 1209 | WinSetWindowPos( id, 0, 0, 0, 0, 0, fl | f ); | 
|---|
| 1210 | } | 
|---|
| 1211 | } | 
|---|
| 1212 | } | 
|---|
| 1213 |  | 
|---|
| 1214 | widget_state &= ~(WState_Minimized | WState_Maximized | WState_FullScreen); | 
|---|
| 1215 | if (newstate & WindowMinimized) | 
|---|
| 1216 | widget_state |= WState_Minimized; | 
|---|
| 1217 | if (newstate & WindowMaximized) | 
|---|
| 1218 | widget_state |= WState_Maximized; | 
|---|
| 1219 | if (newstate & WindowFullScreen) | 
|---|
| 1220 | widget_state |= WState_FullScreen; | 
|---|
| 1221 |  | 
|---|
| 1222 | QEvent e(QEvent::WindowStateChange); | 
|---|
| 1223 | QApplication::sendEvent(this, &e); | 
|---|
| 1224 | } | 
|---|
| 1225 |  | 
|---|
| 1226 |  | 
|---|
| 1227 | /* | 
|---|
| 1228 | \internal | 
|---|
| 1229 | Platform-specific part of QWidget::hide(). | 
|---|
| 1230 | */ | 
|---|
| 1231 |  | 
|---|
| 1232 | void QWidget::hideWindow() | 
|---|
| 1233 | { | 
|---|
| 1234 | deactivateWidgetCleanup(); | 
|---|
| 1235 | HWND id = winFId(); | 
|---|
| 1236 | WinShowWindow( id, FALSE ); | 
|---|
| 1237 | if ( isTopLevel() ) | 
|---|
| 1238 | WinSetWindowPos( id, 0, 0, 0, 0, 0, SWP_DEACTIVATE ); | 
|---|
| 1239 |  | 
|---|
| 1240 | HSWITCH swEntry = topData()->swEntry; | 
|---|
| 1241 | if ( swEntry ) { | 
|---|
| 1242 | SWCNTRL swc; | 
|---|
| 1243 | WinQuerySwitchEntry( swEntry, &swc ); | 
|---|
| 1244 | swc.uchVisibility = SWL_INVISIBLE; | 
|---|
| 1245 | WinChangeSwitchEntry( swEntry, &swc ); | 
|---|
| 1246 | } | 
|---|
| 1247 | } | 
|---|
| 1248 |  | 
|---|
| 1249 |  | 
|---|
| 1250 | /* | 
|---|
| 1251 | \internal | 
|---|
| 1252 | Platform-specific part of QWidget::show(). | 
|---|
| 1253 | */ | 
|---|
| 1254 |  | 
|---|
| 1255 | void QWidget::showWindow() | 
|---|
| 1256 | { | 
|---|
| 1257 | //@@TODO (dmik): need? | 
|---|
| 1258 | //#if defined(QT_NON_COMMERCIAL) | 
|---|
| 1259 | //    QT_NC_SHOW_WINDOW | 
|---|
| 1260 | //#endif | 
|---|
| 1261 | WinShowWindow( winFId(), TRUE ); | 
|---|
| 1262 | ULONG fl = 0; | 
|---|
| 1263 | if ( isTopLevel() ) { | 
|---|
| 1264 | // we do this check here bevause setWindowState() does not actually | 
|---|
| 1265 | // change the window state when the window is not visible, assuming | 
|---|
| 1266 | // it will be done here. | 
|---|
| 1267 | if (testWState(WState_Minimized)) | 
|---|
| 1268 | fl |= SWP_MINIMIZE; | 
|---|
| 1269 | else if (testWState(WState_Maximized)) | 
|---|
| 1270 | fl |= SWP_MAXIMIZE; | 
|---|
| 1271 |  | 
|---|
| 1272 | if ( | 
|---|
| 1273 | !testWFlags(WType_Popup | WStyle_Tool) && | 
|---|
| 1274 | (!testWFlags(WType_Dialog) || !parentWidget()) | 
|---|
| 1275 | ) { | 
|---|
| 1276 | HSWITCH &swEntry = topData()->swEntry; | 
|---|
| 1277 | if ( !swEntry ) { | 
|---|
| 1278 | // lazily create a new window list entry | 
|---|
| 1279 | HWND id = winFId(); // frame handle, if any | 
|---|
| 1280 | PID pid; | 
|---|
| 1281 | WinQueryWindowProcess( id, &pid, NULL ); | 
|---|
| 1282 | SWCNTRL swc; | 
|---|
| 1283 | memset( &swc, 0, sizeof(SWCNTRL) ); | 
|---|
| 1284 | swc.hwnd = id; | 
|---|
| 1285 | swc.idProcess = pid; | 
|---|
| 1286 | swc.uchVisibility = SWL_VISIBLE; | 
|---|
| 1287 | swc.fbJump = SWL_JUMPABLE; | 
|---|
| 1288 | WinQueryWindowText( id, sizeof(swc.szSwtitle), swc.szSwtitle ); | 
|---|
| 1289 | swEntry = WinAddSwitchEntry( &swc ); | 
|---|
| 1290 | } else { | 
|---|
| 1291 | SWCNTRL swc; | 
|---|
| 1292 | WinQuerySwitchEntry( swEntry, &swc ); | 
|---|
| 1293 | swc.uchVisibility = SWL_VISIBLE; | 
|---|
| 1294 | WinChangeSwitchEntry( swEntry, &swc ); | 
|---|
| 1295 | } | 
|---|
| 1296 | } | 
|---|
| 1297 | } | 
|---|
| 1298 | if (!testWFlags(WStyle_Tool) && !isPopup()) | 
|---|
| 1299 | fl |= SWP_ACTIVATE; | 
|---|
| 1300 | if ( fl ) | 
|---|
| 1301 | WinSetWindowPos( winFId(), 0, 0, 0, 0, 0, fl ); | 
|---|
| 1302 |  | 
|---|
| 1303 | //@@TODO (dmik): remove? in OS/2 WinShowWindow() does not influence | 
|---|
| 1304 | //  any other state flags of the window (such as maximized/minimized, active), | 
|---|
| 1305 | //  so, the window is always shown at its current state (i.e. if its state was | 
|---|
| 1306 | //  not changed while it was hidden it will be restored to that state upon | 
|---|
| 1307 | //  unhiding; if the state was changed, it will be restored to that new state). | 
|---|
| 1308 | //    int sm = SW_SHOWNORMAL; | 
|---|
| 1309 | //    if ( isTopLevel() ) { | 
|---|
| 1310 | //      if (testWState(WState_Minimized)) | 
|---|
| 1311 | //          sm = SW_SHOWMINIMIZED; | 
|---|
| 1312 | //      else if (testWState(WState_Maximized)) | 
|---|
| 1313 | //          sm = SW_SHOWMAXIMIZED; | 
|---|
| 1314 | //    } | 
|---|
| 1315 | //    if (testWFlags(WStyle_Tool) || isPopup()) | 
|---|
| 1316 | //      sm = SW_SHOWNOACTIVATE; | 
|---|
| 1317 | // | 
|---|
| 1318 | //    ShowWindow( winId(), sm ); | 
|---|
| 1319 | //    UpdateWindow( winId() ); | 
|---|
| 1320 | } | 
|---|
| 1321 |  | 
|---|
| 1322 | void QWidget::raise() | 
|---|
| 1323 | { | 
|---|
| 1324 | QWidget *p = parentWidget(); | 
|---|
| 1325 | if ( p && p->childObjects && p->childObjects->findRef(this) >= 0 ) | 
|---|
| 1326 | p->childObjects->append( p->childObjects->take() ); | 
|---|
| 1327 | //@@TODO (dmik): remove? SWP_ZORDER doesn't cause activation in OS/2... | 
|---|
| 1328 | //    uint f = ( isPopup() || testWFlags(WStyle_Tool) ) ? SWP_NOACTIVATE : 0; | 
|---|
| 1329 | WinSetWindowPos( winFId(), HWND_TOP, 0, 0, 0, 0, SWP_ZORDER ); | 
|---|
| 1330 | } | 
|---|
| 1331 |  | 
|---|
| 1332 | void QWidget::lower() | 
|---|
| 1333 | { | 
|---|
| 1334 | QWidget *p = parentWidget(); | 
|---|
| 1335 | if ( p && p->childObjects && p->childObjects->findRef(this) >= 0 ) | 
|---|
| 1336 | p->childObjects->insert( 0, p->childObjects->take() ); | 
|---|
| 1337 | //@@TODO (dmik): remove? SWP_ZORDER doesn't cause activation in OS/2... | 
|---|
| 1338 | //    uint f = ( isPopup() || testWFlags(WStyle_Tool) ) ? SWP_NOACTIVATE : 0; | 
|---|
| 1339 | WinSetWindowPos( winFId(), HWND_BOTTOM, 0, 0, 0, 0, SWP_ZORDER ); | 
|---|
| 1340 | } | 
|---|
| 1341 |  | 
|---|
| 1342 | void QWidget::stackUnder( QWidget* w ) | 
|---|
| 1343 | { | 
|---|
| 1344 | QWidget *p = parentWidget(); | 
|---|
| 1345 | if ( !w || isTopLevel() || p != w->parentWidget() || this == w ) | 
|---|
| 1346 | return; | 
|---|
| 1347 | if ( p && p->childObjects && p->childObjects->findRef(w) >= 0 && p->childObjects->findRef(this) >= 0 ) { | 
|---|
| 1348 | p->childObjects->take(); | 
|---|
| 1349 | p->childObjects->insert( p->childObjects->findRef(w), this ); | 
|---|
| 1350 | } | 
|---|
| 1351 | WinSetWindowPos( winId(), w->winId(), 0, 0, 0, 0, SWP_ZORDER ); | 
|---|
| 1352 | } | 
|---|
| 1353 |  | 
|---|
| 1354 | // | 
|---|
| 1355 | // The internal qPMRequestConfig, defined in qeventloop_pm.cpp, stores move, | 
|---|
| 1356 | // resize and setGeometry requests for a widget that is already | 
|---|
| 1357 | // processing a config event. The purpose is to avoid recursion. | 
|---|
| 1358 | // | 
|---|
| 1359 | void qPMRequestConfig( WId, int, int, int, int, int ); | 
|---|
| 1360 |  | 
|---|
| 1361 | void QWidget::internalSetGeometry( int x, int y, int w, int h, bool isMove ) | 
|---|
| 1362 | { | 
|---|
| 1363 | if ( extra ) {                              // any size restrictions? | 
|---|
| 1364 | w = QMIN(w,extra->maxw); | 
|---|
| 1365 | h = QMIN(h,extra->maxh); | 
|---|
| 1366 | w = QMAX(w,extra->minw); | 
|---|
| 1367 | h = QMAX(h,extra->minh); | 
|---|
| 1368 | } | 
|---|
| 1369 | if ( w < 1 )                                // invalid size | 
|---|
| 1370 | w = 1; | 
|---|
| 1371 | if ( h < 1 ) | 
|---|
| 1372 | h = 1; | 
|---|
| 1373 | QSize  oldSize( size() ); | 
|---|
| 1374 | QPoint oldPos( pos() ); | 
|---|
| 1375 | if ( !isTopLevel() ) | 
|---|
| 1376 | isMove = (crect.topLeft() != QPoint( x, y )); | 
|---|
| 1377 | if ( isMove == FALSE && oldSize.width()==w && oldSize.height()==h ) | 
|---|
| 1378 | return; | 
|---|
| 1379 | clearWState(WState_Maximized); | 
|---|
| 1380 | clearWState(WState_FullScreen); | 
|---|
| 1381 | if (isTopLevel()) | 
|---|
| 1382 | topData()->normalGeometry = QRect(0, 0, -1, -1); | 
|---|
| 1383 | if ( testWState(WState_ConfigPending) ) {   // processing config event | 
|---|
| 1384 | qPMRequestConfig( winId(), isMove ? 2 : 1, x, y, w, h ); | 
|---|
| 1385 | } else { | 
|---|
| 1386 | setWState( WState_ConfigPending ); | 
|---|
| 1387 | if ( isTopLevel() ) { | 
|---|
| 1388 | //@@TODO (dmik): remove, no need to check for extra... | 
|---|
| 1389 | //          QRect fr( frameGeometry() ); | 
|---|
| 1390 | //          if ( extra ) { | 
|---|
| 1391 | //              fr.setLeft( fr.left() + x - crect.left() ); | 
|---|
| 1392 | //              fr.setTop( fr.top() + y - crect.top() ); | 
|---|
| 1393 | //              fr.setRight( fr.right() + ( x + w - 1 ) - crect.right() ); | 
|---|
| 1394 | //              fr.setBottom( fr.bottom() + ( y + h - 1 ) - crect.bottom() ); | 
|---|
| 1395 | //          } | 
|---|
| 1396 | //          MoveWindow( winId(), fr.x(), fr.y(), fr.width(), fr.height(), TRUE ); | 
|---|
| 1397 | //          crect.setRect( x, y, w, h ); | 
|---|
| 1398 |  | 
|---|
| 1399 | //@@TODO (dmik): optimize: use extra->topextra directly (after updating fstrut | 
|---|
| 1400 | //  if necessary) instead of calling frameGeometry() | 
|---|
| 1401 | QRect fr( frameGeometry() ); | 
|---|
| 1402 | int fx = fr.left() + x - crect.left(); | 
|---|
| 1403 | int fy = fr.top() + y - crect.top(); | 
|---|
| 1404 | int fw = fr.width() + w - crect.width(); | 
|---|
| 1405 | int fh = fr.height() + h - crect.height(); | 
|---|
| 1406 | // flip y coordinate | 
|---|
| 1407 | fy = QApplication::desktop()->height() - (fy + fh); | 
|---|
| 1408 | crect.setRect( x, y, w, h ); | 
|---|
| 1409 | WinSetWindowPos( winFId(), 0, fx, fy, fw, fh, SWP_MOVE | SWP_SIZE ); | 
|---|
| 1410 | } else { | 
|---|
| 1411 | // flip y coordinate | 
|---|
| 1412 | int fy = parentWidget()->height() - (y + h); | 
|---|
| 1413 | crect.setRect( x, y, w, h ); | 
|---|
| 1414 | WinSetWindowPos( winId(), 0, x, fy, w, h, SWP_MOVE | SWP_SIZE ); | 
|---|
| 1415 | } | 
|---|
| 1416 | clearWState( WState_ConfigPending ); | 
|---|
| 1417 | } | 
|---|
| 1418 |  | 
|---|
| 1419 | bool isResize = w != oldSize.width() || h != oldSize.height(); | 
|---|
| 1420 | if ( isVisible() ) { | 
|---|
| 1421 | if ( isMove && pos() != oldPos ) { | 
|---|
| 1422 | QMoveEvent e( pos(), oldPos ); | 
|---|
| 1423 | QApplication::sendEvent( this, &e ); | 
|---|
| 1424 | } | 
|---|
| 1425 | if ( isResize ) { | 
|---|
| 1426 | QResizeEvent e( size(), oldSize ); | 
|---|
| 1427 | QApplication::sendEvent( this, &e ); | 
|---|
| 1428 | if ( !testWFlags( WStaticContents ) ) | 
|---|
| 1429 | repaint( !testWFlags(WResizeNoErase) ); | 
|---|
| 1430 | } | 
|---|
| 1431 | } else { | 
|---|
| 1432 | if ( isMove && pos() != oldPos ) | 
|---|
| 1433 | QApplication::postEvent( this, | 
|---|
| 1434 | new QMoveEvent( pos(), oldPos ) ); | 
|---|
| 1435 | if ( isResize ) | 
|---|
| 1436 | QApplication::postEvent( this, | 
|---|
| 1437 | new QResizeEvent( size(), oldSize ) ); | 
|---|
| 1438 | } | 
|---|
| 1439 | } | 
|---|
| 1440 |  | 
|---|
| 1441 | void QWidget::setMinimumSize( int minw, int minh ) | 
|---|
| 1442 | { | 
|---|
| 1443 | #if defined(QT_CHECK_RANGE) | 
|---|
| 1444 | if ( minw < 0 || minh < 0 ) | 
|---|
| 1445 | qWarning("QWidget::setMinimumSize: The smallest allowed size is (0,0)"); | 
|---|
| 1446 | #endif | 
|---|
| 1447 | createExtra(); | 
|---|
| 1448 | if ( extra->minw == minw && extra->minh == minh ) | 
|---|
| 1449 | return; | 
|---|
| 1450 | extra->minw = minw; | 
|---|
| 1451 | extra->minh = minh; | 
|---|
| 1452 | if ( minw > width() || minh > height() ) { | 
|---|
| 1453 | bool resized = testWState( WState_Resized ); | 
|---|
| 1454 | resize( QMAX(minw,width()), QMAX(minh,height()) ); | 
|---|
| 1455 | if ( !resized ) | 
|---|
| 1456 | clearWState( WState_Resized ); //not a user resize | 
|---|
| 1457 | } | 
|---|
| 1458 | updateGeometry(); | 
|---|
| 1459 | } | 
|---|
| 1460 |  | 
|---|
| 1461 | void QWidget::setMaximumSize( int maxw, int maxh ) | 
|---|
| 1462 | { | 
|---|
| 1463 | #if defined(QT_CHECK_RANGE) | 
|---|
| 1464 | if ( maxw > QWIDGETSIZE_MAX || maxh > QWIDGETSIZE_MAX ) { | 
|---|
| 1465 | qWarning("QWidget::setMaximumSize: The largest allowed size is (%d,%d)", | 
|---|
| 1466 | QWIDGETSIZE_MAX, QWIDGETSIZE_MAX ); | 
|---|
| 1467 | maxw = QMIN( maxw, QWIDGETSIZE_MAX ); | 
|---|
| 1468 | maxh = QMIN( maxh, QWIDGETSIZE_MAX ); | 
|---|
| 1469 | } | 
|---|
| 1470 | if ( maxw < 0 || maxh < 0 ) { | 
|---|
| 1471 | qWarning("QWidget::setMaximumSize: (%s/%s) Negative sizes (%d,%d) " | 
|---|
| 1472 | "are not possible", | 
|---|
| 1473 | name( "unnamed" ), className(), maxw, maxh ); | 
|---|
| 1474 | maxw = QMAX( maxw, 0 ); | 
|---|
| 1475 | maxh = QMAX( maxh, 0 ); | 
|---|
| 1476 | } | 
|---|
| 1477 | #endif | 
|---|
| 1478 | createExtra(); | 
|---|
| 1479 | if ( extra->maxw == maxw && extra->maxh == maxh ) | 
|---|
| 1480 | return; | 
|---|
| 1481 | extra->maxw = maxw; | 
|---|
| 1482 | extra->maxh = maxh; | 
|---|
| 1483 | if ( maxw < width() || maxh < height() ) { | 
|---|
| 1484 | bool resized = testWState( WState_Resized ); | 
|---|
| 1485 | resize( QMIN(maxw,width()), QMIN(maxh,height()) ); | 
|---|
| 1486 | if ( !resized ) | 
|---|
| 1487 | clearWState( WState_Resized ); //not a user resize | 
|---|
| 1488 | } | 
|---|
| 1489 | updateGeometry(); | 
|---|
| 1490 | } | 
|---|
| 1491 |  | 
|---|
| 1492 | void QWidget::setSizeIncrement( int w, int h ) | 
|---|
| 1493 | { | 
|---|
| 1494 | createTLExtra(); | 
|---|
| 1495 | extra->topextra->incw = w; | 
|---|
| 1496 | extra->topextra->inch = h; | 
|---|
| 1497 | } | 
|---|
| 1498 |  | 
|---|
| 1499 | void QWidget::setBaseSize( int w, int h ) | 
|---|
| 1500 | { | 
|---|
| 1501 | createTLExtra(); | 
|---|
| 1502 | extra->topextra->basew = w; | 
|---|
| 1503 | extra->topextra->baseh = h; | 
|---|
| 1504 | } | 
|---|
| 1505 |  | 
|---|
| 1506 | extern void qt_erase_background( HPS, int, int, int, int, | 
|---|
| 1507 | const QColor &, const QPixmap *, int, int, int ); | 
|---|
| 1508 |  | 
|---|
| 1509 | void QWidget::erase( int x, int y, int w, int h ) | 
|---|
| 1510 | { | 
|---|
| 1511 | // SIMILAR TO region ERASE BELOW | 
|---|
| 1512 |  | 
|---|
| 1513 | if ( backgroundMode()==NoBackground ) | 
|---|
| 1514 | return; | 
|---|
| 1515 | if ( w < 0 ) | 
|---|
| 1516 | w = crect.width() - x; | 
|---|
| 1517 | if ( h < 0 ) | 
|---|
| 1518 | h = crect.height() - y; | 
|---|
| 1519 |  | 
|---|
| 1520 | HPS lhps; | 
|---|
| 1521 | bool tmphps; | 
|---|
| 1522 |  | 
|---|
| 1523 | if( QPainter::redirect( this ) ) { | 
|---|
| 1524 | tmphps = FALSE; | 
|---|
| 1525 | lhps = QPainter::redirect( this )->handle(); | 
|---|
| 1526 | Q_ASSERT( lhps ); | 
|---|
| 1527 | } else if ( !hps ) { | 
|---|
| 1528 | tmphps = TRUE; | 
|---|
| 1529 | lhps = WinGetPS( winId() ); | 
|---|
| 1530 | } else { | 
|---|
| 1531 | tmphps = FALSE; | 
|---|
| 1532 | lhps = hps; | 
|---|
| 1533 | } | 
|---|
| 1534 |  | 
|---|
| 1535 | QPoint offset = backgroundOffset(); | 
|---|
| 1536 | int ox = offset.x(); | 
|---|
| 1537 | int oy = offset.y(); | 
|---|
| 1538 |  | 
|---|
| 1539 | qt_erase_background( | 
|---|
| 1540 | lhps, x, y, w, h, bg_col, backgroundPixmap(), | 
|---|
| 1541 | ox, oy, crect.height() | 
|---|
| 1542 | ); | 
|---|
| 1543 |  | 
|---|
| 1544 | if ( tmphps ) { | 
|---|
| 1545 | WinReleasePS( lhps ); | 
|---|
| 1546 | hps = 0; | 
|---|
| 1547 | } | 
|---|
| 1548 | } | 
|---|
| 1549 |  | 
|---|
| 1550 | void QWidget::erase( const QRegion& rgn ) | 
|---|
| 1551 | { | 
|---|
| 1552 | // SIMILAR TO rect ERASE ABOVE | 
|---|
| 1553 |  | 
|---|
| 1554 | if ( backgroundMode()==NoBackground ) | 
|---|
| 1555 | return; | 
|---|
| 1556 |  | 
|---|
| 1557 | HPS lhps; | 
|---|
| 1558 | bool tmphps; | 
|---|
| 1559 |  | 
|---|
| 1560 | if( QPainter::redirect( this ) ) { | 
|---|
| 1561 | tmphps = FALSE; | 
|---|
| 1562 | lhps = QPainter::redirect( this )->handle(); | 
|---|
| 1563 | Q_ASSERT( lhps ); | 
|---|
| 1564 | } else if ( !hps ) { | 
|---|
| 1565 | tmphps = TRUE; | 
|---|
| 1566 | lhps = WinGetPS( winId() ); | 
|---|
| 1567 | } else { | 
|---|
| 1568 | tmphps = FALSE; | 
|---|
| 1569 | lhps = hps; | 
|---|
| 1570 | } | 
|---|
| 1571 |  | 
|---|
| 1572 | // convert region y coordinates from Qt to GPI (see qregion_pm.cpp) | 
|---|
| 1573 | POINTL ptl = { 0, height() }; | 
|---|
| 1574 | GpiOffsetRegion( lhps, rgn.handle(), &ptl ); | 
|---|
| 1575 |  | 
|---|
| 1576 | HRGN oldRegion = GpiQueryClipRegion( lhps ); | 
|---|
| 1577 | HRGN newRegion = 0; | 
|---|
| 1578 | if ( oldRegion ) { | 
|---|
| 1579 | GpiSetClipRegion( lhps, 0, NULL ); | 
|---|
| 1580 | newRegion = GpiCreateRegion( lhps, 0, NULL ); | 
|---|
| 1581 | GpiCombineRegion( lhps, newRegion, oldRegion, rgn.handle(), CRGN_AND ); | 
|---|
| 1582 | } else { | 
|---|
| 1583 | newRegion = rgn.handle(); | 
|---|
| 1584 | } | 
|---|
| 1585 | GpiSetClipRegion( lhps, newRegion, &oldRegion ); | 
|---|
| 1586 |  | 
|---|
| 1587 | QPoint offset = backgroundOffset(); | 
|---|
| 1588 | int ox = offset.x(); | 
|---|
| 1589 | int oy = offset.y(); | 
|---|
| 1590 |  | 
|---|
| 1591 | qt_erase_background( | 
|---|
| 1592 | lhps, 0, 0, crect.width(), crect.height(), | 
|---|
| 1593 | bg_col, backgroundPixmap(), ox, oy, crect.height() | 
|---|
| 1594 | ); | 
|---|
| 1595 |  | 
|---|
| 1596 | GpiSetClipRegion( lhps, oldRegion, NULL ); | 
|---|
| 1597 |  | 
|---|
| 1598 | // convert region y coordinates back from GPI to Qt | 
|---|
| 1599 | ptl.y = -ptl.y; | 
|---|
| 1600 | GpiOffsetRegion( lhps, rgn.handle(), &ptl ); | 
|---|
| 1601 |  | 
|---|
| 1602 | if ( oldRegion ) | 
|---|
| 1603 | GpiDestroyRegion( lhps, newRegion ); | 
|---|
| 1604 | if ( tmphps ) { | 
|---|
| 1605 | WinReleasePS( lhps ); | 
|---|
| 1606 | hps = 0; | 
|---|
| 1607 | } | 
|---|
| 1608 | } | 
|---|
| 1609 |  | 
|---|
| 1610 |  | 
|---|
| 1611 | // helper function to extract regions of all windows that overlap the given | 
|---|
| 1612 | // hwnd subject to their z-order (excluding children of hwnd) from the given | 
|---|
| 1613 | // hrgn. hps is the presentation space of hrgn. | 
|---|
| 1614 | void qt_WinExcludeOverlappingWindows( HWND hwnd, HPS hps, HRGN hrgn ) | 
|---|
| 1615 | { | 
|---|
| 1616 | HRGN vr = GpiCreateRegion( hps, 0, NULL ); | 
|---|
| 1617 | RECTL r; | 
|---|
| 1618 |  | 
|---|
| 1619 | // enumerate all windows that are on top of this hwnd | 
|---|
| 1620 | HWND id = hwnd, deskId = QApplication::desktop()->winId(); | 
|---|
| 1621 | do { | 
|---|
| 1622 | HWND i = id; | 
|---|
| 1623 | while( (i = WinQueryWindow( i, QW_PREV )) ) { | 
|---|
| 1624 | if ( WinIsWindowShowing( i ) ) { | 
|---|
| 1625 | //@@TODO (dmik): probably we should use WinQueryClipRegion() here to | 
|---|
| 1626 | //  handle non-rectangular windows properly | 
|---|
| 1627 | WinQueryWindowRect( i, &r ); | 
|---|
| 1628 | WinMapWindowPoints( i, hwnd, (PPOINTL) &r, 2 ); | 
|---|
| 1629 | GpiSetRegion( hps, vr, 1, &r ); | 
|---|
| 1630 | GpiCombineRegion( hps, hrgn, hrgn, vr, CRGN_DIFF ); | 
|---|
| 1631 | } | 
|---|
| 1632 | } | 
|---|
| 1633 | id = WinQueryWindow( id, QW_PARENT ); | 
|---|
| 1634 | } while( id != deskId ); | 
|---|
| 1635 |  | 
|---|
| 1636 | GpiDestroyRegion( hps, vr ); | 
|---|
| 1637 | } | 
|---|
| 1638 |  | 
|---|
| 1639 | // helper function to scroll window contents. WinScrollWindow() is a bit | 
|---|
| 1640 | // buggy and corrupts update regions sometimes (which leaves some outdated | 
|---|
| 1641 | // areas unpainted after scrolling), so we reimplement its functionality in | 
|---|
| 1642 | // this function. dy and clip->yBottom/yTop should be GPI coordinates, not Qt. | 
|---|
| 1643 | // all clip coordinates are inclusive. | 
|---|
| 1644 | void qt_WinScrollWindowWell( HWND hwnd, LONG dx, LONG dy, const PRECTL clip = NULL ) | 
|---|
| 1645 | { | 
|---|
| 1646 | WinLockVisRegions( HWND_DESKTOP, TRUE ); | 
|---|
| 1647 |  | 
|---|
| 1648 | HPS lhps = WinGetClipPS( | 
|---|
| 1649 | hwnd, HWND_TOP, | 
|---|
| 1650 | PSF_LOCKWINDOWUPDATE | PSF_CLIPSIBLINGS | 
|---|
| 1651 | ); | 
|---|
| 1652 | if ( clip ) | 
|---|
| 1653 | GpiIntersectClipRectangle( lhps, clip ); | 
|---|
| 1654 |  | 
|---|
| 1655 | // remember the update region and validate it. it will be shifted and | 
|---|
| 1656 | // invalidated again later | 
|---|
| 1657 | HRGN update = GpiCreateRegion( lhps, 0, NULL ); | 
|---|
| 1658 | WinQueryUpdateRegion( hwnd, update ); | 
|---|
| 1659 | WinValidateRegion( hwnd, update, TRUE ); | 
|---|
| 1660 |  | 
|---|
| 1661 | POINTL ptls[4]; | 
|---|
| 1662 | RECTL &sr = *(PRECTL) &ptls[2]; | 
|---|
| 1663 | RECTL &tr = *(PRECTL) &ptls[0]; | 
|---|
| 1664 |  | 
|---|
| 1665 | // get the source rect for scrolling | 
|---|
| 1666 | GpiQueryClipBox( lhps, &sr ); | 
|---|
| 1667 | sr.xRight++; sr.yTop++; // inclusive -> exclusive | 
|---|
| 1668 |  | 
|---|
| 1669 | // get the visible region ignoring areas covered by children | 
|---|
| 1670 | HRGN visible = GpiCreateRegion( lhps, 1, &sr ); | 
|---|
| 1671 | qt_WinExcludeOverlappingWindows( hwnd, lhps, visible ); | 
|---|
| 1672 |  | 
|---|
| 1673 | // scroll visible region rectangles separately to avoid the flicker | 
|---|
| 1674 | // that could be produced by scrolling parts of overlapping windows | 
|---|
| 1675 | RGNRECT ctl; | 
|---|
| 1676 | ctl.ircStart = 1; | 
|---|
| 1677 | ctl.crc = 0; | 
|---|
| 1678 | ctl.crcReturned = 0; | 
|---|
| 1679 | if ( dx >= 0 ) { | 
|---|
| 1680 | if ( dy >= 0 ) ctl.ulDirection = RECTDIR_RTLF_TOPBOT; | 
|---|
| 1681 | else ctl.ulDirection = RECTDIR_RTLF_BOTTOP; | 
|---|
| 1682 | } else { | 
|---|
| 1683 | if ( dy >= 0 ) ctl.ulDirection = RECTDIR_LFRT_TOPBOT; | 
|---|
| 1684 | else ctl.ulDirection = RECTDIR_LFRT_BOTTOP; | 
|---|
| 1685 | } | 
|---|
| 1686 | GpiQueryRegionRects( lhps, visible, NULL, &ctl, NULL ); | 
|---|
| 1687 | ctl.crc = ctl.crcReturned; | 
|---|
| 1688 | int rclcnt = ctl.crcReturned; | 
|---|
| 1689 | PRECTL rcls = new RECTL[rclcnt]; | 
|---|
| 1690 | GpiQueryRegionRects( lhps, visible, NULL, &ctl, rcls ); | 
|---|
| 1691 | PRECTL r = rcls; | 
|---|
| 1692 | for ( int i = 0; i < rclcnt; i++, r++ ) { | 
|---|
| 1693 | // source rect | 
|---|
| 1694 | sr = *r; | 
|---|
| 1695 | // target rect | 
|---|
| 1696 | tr.xLeft = sr.xLeft + dx; | 
|---|
| 1697 | tr.xRight = sr.xRight + dx; | 
|---|
| 1698 | tr.yBottom = sr.yBottom + dy; | 
|---|
| 1699 | tr.yTop = sr.yTop + dy; | 
|---|
| 1700 | GpiBitBlt( lhps, lhps, 3, ptls, ROP_SRCCOPY, BBO_IGNORE ); | 
|---|
| 1701 | } | 
|---|
| 1702 | delete [] rcls; | 
|---|
| 1703 |  | 
|---|
| 1704 | // make the scrolled version of the visible region | 
|---|
| 1705 | HRGN scrolled = GpiCreateRegion( lhps, 0, NULL ); | 
|---|
| 1706 | GpiCombineRegion( lhps, scrolled, visible, 0, CRGN_COPY ); | 
|---|
| 1707 | // invalidate the initial update region | 
|---|
| 1708 | GpiCombineRegion( lhps, scrolled, scrolled, update, CRGN_DIFF ); | 
|---|
| 1709 | // shift the region | 
|---|
| 1710 | POINTL dp = { dx, dy }; | 
|---|
| 1711 | GpiOffsetRegion( lhps, scrolled, &dp ); | 
|---|
| 1712 | // substract scrolled from visible to get invalid areas | 
|---|
| 1713 | GpiCombineRegion( lhps, scrolled, visible, scrolled, CRGN_DIFF ); | 
|---|
| 1714 |  | 
|---|
| 1715 | WinInvalidateRegion( hwnd, scrolled, TRUE ); | 
|---|
| 1716 |  | 
|---|
| 1717 | GpiDestroyRegion( lhps, scrolled ); | 
|---|
| 1718 | GpiDestroyRegion( lhps, visible ); | 
|---|
| 1719 | GpiDestroyRegion( lhps, update ); | 
|---|
| 1720 |  | 
|---|
| 1721 | WinReleasePS( lhps ); | 
|---|
| 1722 |  | 
|---|
| 1723 | WinLockVisRegions( HWND_DESKTOP, FALSE ); | 
|---|
| 1724 |  | 
|---|
| 1725 | WinUpdateWindow( hwnd ); | 
|---|
| 1726 | } | 
|---|
| 1727 |  | 
|---|
| 1728 | void QWidget::scroll( int dx, int dy ) | 
|---|
| 1729 | { | 
|---|
| 1730 | if ( testWState( WState_BlockUpdates ) && !children() ) | 
|---|
| 1731 | return; | 
|---|
| 1732 |  | 
|---|
| 1733 | // move non-toplevel children | 
|---|
| 1734 | if ( children() ) { | 
|---|
| 1735 | QObjectListIt it(*children()); | 
|---|
| 1736 | register QObject *obj; | 
|---|
| 1737 | int h = crect.height(); | 
|---|
| 1738 | while ( (obj=it.current()) ) { | 
|---|
| 1739 | ++it; | 
|---|
| 1740 | if ( obj->isWidgetType() ) { | 
|---|
| 1741 | QWidget *w = (QWidget*)obj; | 
|---|
| 1742 | if ( !w->isTopLevel() ) { | 
|---|
| 1743 | WinSetWindowPos( | 
|---|
| 1744 | w->winId(), 0, | 
|---|
| 1745 | w->crect.left() + dx, | 
|---|
| 1746 | // flip y coordinate | 
|---|
| 1747 | h - (w->crect.bottom() + dy + 1), | 
|---|
| 1748 | 0, 0, | 
|---|
| 1749 | SWP_MOVE | SWP_NOADJUST | SWP_NOREDRAW | 
|---|
| 1750 | ); | 
|---|
| 1751 | // WinSetWindowPos() doesn't send WM_MOVE to windows w/o | 
|---|
| 1752 | // CS_MOVENOTIFY, but having this style for non-toplevel | 
|---|
| 1753 | // widgets is unwanted, so we send them WM_MOVE manually | 
|---|
| 1754 | // to let their geometry to be properly updated by | 
|---|
| 1755 | // QETWidget::translateConfigEvent(). | 
|---|
| 1756 | WinSendMsg( w->winId(), WM_MOVE, 0, 0 ); | 
|---|
| 1757 | } | 
|---|
| 1758 | } | 
|---|
| 1759 | } | 
|---|
| 1760 | } | 
|---|
| 1761 |  | 
|---|
| 1762 | qt_WinScrollWindowWell( winId(), dx, -dy, NULL ); | 
|---|
| 1763 | } | 
|---|
| 1764 |  | 
|---|
| 1765 | void QWidget::scroll( int dx, int dy, const QRect& r ) | 
|---|
| 1766 | { | 
|---|
| 1767 | if ( testWState( WState_BlockUpdates ) ) | 
|---|
| 1768 | return; | 
|---|
| 1769 |  | 
|---|
| 1770 | int h = crect.height(); | 
|---|
| 1771 | // flip y coordinate (all coordinates are inclusive) | 
|---|
| 1772 | RECTL rcl = { r.left(), h - (r.bottom() + 1), r.right(), h - (r.top() + 1) }; | 
|---|
| 1773 | qt_WinScrollWindowWell( winId(), dx, -dy, &rcl ); | 
|---|
| 1774 | } | 
|---|
| 1775 |  | 
|---|
| 1776 | void QWidget::drawText( int x, int y, const QString &str ) | 
|---|
| 1777 | { | 
|---|
| 1778 | if ( testWState(WState_Visible) ) { | 
|---|
| 1779 | QPainter paint; | 
|---|
| 1780 | paint.begin( this ); | 
|---|
| 1781 | paint.drawText( x, y, str ); | 
|---|
| 1782 | paint.end(); | 
|---|
| 1783 | } | 
|---|
| 1784 | } | 
|---|
| 1785 |  | 
|---|
| 1786 |  | 
|---|
| 1787 | int QWidget::metric( int m ) const | 
|---|
| 1788 | { | 
|---|
| 1789 | LONG val; | 
|---|
| 1790 | if ( m == QPaintDeviceMetrics::PdmWidth ) { | 
|---|
| 1791 | val = crect.width(); | 
|---|
| 1792 | } else if ( m == QPaintDeviceMetrics::PdmHeight ) { | 
|---|
| 1793 | val = crect.height(); | 
|---|
| 1794 | } else { | 
|---|
| 1795 | HDC hdc = GpiQueryDevice( qt_display_ps() ); | 
|---|
| 1796 | switch ( m ) { | 
|---|
| 1797 | case QPaintDeviceMetrics::PdmDpiX: | 
|---|
| 1798 | case QPaintDeviceMetrics::PdmPhysicalDpiX: | 
|---|
| 1799 | DevQueryCaps( hdc, CAPS_HORIZONTAL_FONT_RES, 1, &val ); | 
|---|
| 1800 | break; | 
|---|
| 1801 | case QPaintDeviceMetrics::PdmDpiY: | 
|---|
| 1802 | case QPaintDeviceMetrics::PdmPhysicalDpiY: | 
|---|
| 1803 | DevQueryCaps( hdc, CAPS_VERTICAL_FONT_RES, 1, &val ); | 
|---|
| 1804 | break; | 
|---|
| 1805 | case QPaintDeviceMetrics::PdmWidthMM: | 
|---|
| 1806 | DevQueryCaps( hdc, CAPS_HORIZONTAL_RESOLUTION, 1, &val ); | 
|---|
| 1807 | val = width() * 1000 / val; | 
|---|
| 1808 | break; | 
|---|
| 1809 | case QPaintDeviceMetrics::PdmHeightMM: | 
|---|
| 1810 | DevQueryCaps( hdc, CAPS_VERTICAL_RESOLUTION, 1, &val ); | 
|---|
| 1811 | val = width() * 1000 / val; | 
|---|
| 1812 | break; | 
|---|
| 1813 | case QPaintDeviceMetrics::PdmNumColors: | 
|---|
| 1814 | DevQueryCaps( hdc, CAPS_COLORS, 1, &val ); | 
|---|
| 1815 | break; | 
|---|
| 1816 | case QPaintDeviceMetrics::PdmDepth: | 
|---|
| 1817 | LONG colorInfo [2]; | 
|---|
| 1818 | DevQueryCaps( hdc, CAPS_COLOR_PLANES, 2, colorInfo ); | 
|---|
| 1819 | val = colorInfo [0] * colorInfo [1]; | 
|---|
| 1820 | break; | 
|---|
| 1821 | default: | 
|---|
| 1822 | val = 0; | 
|---|
| 1823 | #if defined(QT_CHECK_RANGE) | 
|---|
| 1824 | qWarning( "QWidget::metric: Invalid metric command" ); | 
|---|
| 1825 | #endif | 
|---|
| 1826 | } | 
|---|
| 1827 | } | 
|---|
| 1828 | return val; | 
|---|
| 1829 | } | 
|---|
| 1830 |  | 
|---|
| 1831 | void QWidget::createSysExtra() | 
|---|
| 1832 | { | 
|---|
| 1833 | //@@TODO (dmik): later | 
|---|
| 1834 | //    extra->dropTarget = 0; | 
|---|
| 1835 | } | 
|---|
| 1836 |  | 
|---|
| 1837 | void QWidget::deleteSysExtra() | 
|---|
| 1838 | { | 
|---|
| 1839 | setAcceptDrops( FALSE ); | 
|---|
| 1840 | } | 
|---|
| 1841 |  | 
|---|
| 1842 | void QWidget::createTLSysExtra() | 
|---|
| 1843 | { | 
|---|
| 1844 | //@@TODO (dmik): remove? | 
|---|
| 1845 | //    extra->topextra->winIcon = 0; | 
|---|
| 1846 | extra->topextra->fId = 0; | 
|---|
| 1847 | extra->topextra->swEntry = 0; | 
|---|
| 1848 | } | 
|---|
| 1849 |  | 
|---|
| 1850 | void QWidget::deleteTLSysExtra() | 
|---|
| 1851 | { | 
|---|
| 1852 | if ( extra->topextra->swEntry ) { | 
|---|
| 1853 | WinRemoveSwitchEntry( extra->topextra->swEntry ); | 
|---|
| 1854 | } | 
|---|
| 1855 | // frame window (extra->topextra->fId) is destroyed in | 
|---|
| 1856 | // destroy() if it exists | 
|---|
| 1857 | //@@TODO (dmik): remove? | 
|---|
| 1858 | //    if ( extra->topextra->winIcon ) | 
|---|
| 1859 | //      DestroyIcon( extra->topextra->winIcon ); | 
|---|
| 1860 | } | 
|---|
| 1861 |  | 
|---|
| 1862 | bool QWidget::acceptDrops() const | 
|---|
| 1863 | { | 
|---|
| 1864 | return 0; | 
|---|
| 1865 | //@@TODO (dmik): later | 
|---|
| 1866 | //    return ( extra && extra->dropTarget ); | 
|---|
| 1867 | } | 
|---|
| 1868 |  | 
|---|
| 1869 | void QWidget::setAcceptDrops( bool on ) | 
|---|
| 1870 | { | 
|---|
| 1871 | //@@TODO (dmik): later | 
|---|
| 1872 | //    // Enablement is defined by extra->dropTarget != 0. | 
|---|
| 1873 | // | 
|---|
| 1874 | //    if ( on ) { | 
|---|
| 1875 | //      // Turn on. | 
|---|
| 1876 | //      createExtra(); | 
|---|
| 1877 | //      QWExtra *extra = extraData(); | 
|---|
| 1878 | //      if ( !extra->dropTarget ) | 
|---|
| 1879 | //          extra->dropTarget = qt_olednd_register( this ); | 
|---|
| 1880 | //    } else { | 
|---|
| 1881 | //      // Turn off. | 
|---|
| 1882 | //      QWExtra *extra = extraData(); | 
|---|
| 1883 | //      if ( extra && extra->dropTarget ) { | 
|---|
| 1884 | //          qt_olednd_unregister(this, extra->dropTarget); | 
|---|
| 1885 | //          extra->dropTarget = 0; | 
|---|
| 1886 | //      } | 
|---|
| 1887 | //    } | 
|---|
| 1888 | } | 
|---|
| 1889 |  | 
|---|
| 1890 | void QWidget::setMask( const QRegion ®ion ) | 
|---|
| 1891 | { | 
|---|
| 1892 | qWarning( "QWidget::setMask() is not yet implemented on OS/2" ); | 
|---|
| 1893 | //@@TODO (dmik): later (don't forget to offset region, see qregion_pm.cpp) | 
|---|
| 1894 | //    // Since SetWindowRegion takes ownership, and we need to translate, | 
|---|
| 1895 | //    // we take a copy. | 
|---|
| 1896 | //    HRGN wr = CreateRectRgn(0,0,1,1); | 
|---|
| 1897 | //    CombineRgn(wr, region.handle(), 0, RGN_COPY); | 
|---|
| 1898 | // | 
|---|
| 1899 | //    int fleft = 0, ftop = 0; | 
|---|
| 1900 | //    if (isTopLevel()) { | 
|---|
| 1901 | //      ftop = topData()->ftop; | 
|---|
| 1902 | //      fleft = topData()->fleft; | 
|---|
| 1903 | //    } | 
|---|
| 1904 | //    OffsetRgn(wr, fleft, ftop ); | 
|---|
| 1905 | //    SetWindowRgn( winId(), wr, TRUE ); | 
|---|
| 1906 | } | 
|---|
| 1907 |  | 
|---|
| 1908 | void QWidget::setMask( const QBitmap &bitmap ) | 
|---|
| 1909 | { | 
|---|
| 1910 | qWarning( "QWidget::setMask() is not yet implemented on OS/2" ); | 
|---|
| 1911 | //@@TODO (dmik): later | 
|---|
| 1912 | //    HRGN wr = qt_win_bitmapToRegion(bitmap); | 
|---|
| 1913 | // | 
|---|
| 1914 | //    int fleft = 0, ftop = 0; | 
|---|
| 1915 | //    if (isTopLevel()) { | 
|---|
| 1916 | //      ftop = topData()->ftop; | 
|---|
| 1917 | //      fleft = topData()->fleft; | 
|---|
| 1918 | //    } | 
|---|
| 1919 | //    OffsetRgn(wr, fleft, ftop ); | 
|---|
| 1920 | //    SetWindowRgn( winId(), wr, TRUE ); | 
|---|
| 1921 | } | 
|---|
| 1922 |  | 
|---|
| 1923 | void QWidget::clearMask() | 
|---|
| 1924 | { | 
|---|
| 1925 | qWarning( "QWidget::clearMask() is not yet implemented on OS/2" ); | 
|---|
| 1926 | //@@TODO (dmik): later | 
|---|
| 1927 | //    SetWindowRgn( winId(), 0, TRUE ); | 
|---|
| 1928 | } | 
|---|
| 1929 |  | 
|---|
| 1930 | void QWidget::setName( const char *name ) | 
|---|
| 1931 | { | 
|---|
| 1932 | QObject::setName( name ); | 
|---|
| 1933 | } | 
|---|
| 1934 |  | 
|---|
| 1935 | void QWidget::updateFrameStrut() const | 
|---|
| 1936 | { | 
|---|
| 1937 | QWidget *that = (QWidget *) this; | 
|---|
| 1938 |  | 
|---|
| 1939 | if ( !isVisible() || isDesktop() ) { | 
|---|
| 1940 | that->fstrut_dirty = isVisible(); | 
|---|
| 1941 | return; | 
|---|
| 1942 | } | 
|---|
| 1943 |  | 
|---|
| 1944 | QTLWExtra *top = that->topData(); | 
|---|
| 1945 | if ( top->fId ) { | 
|---|
| 1946 | // this widget has WC_FRAME | 
|---|
| 1947 | SWP cswp; | 
|---|
| 1948 | WinQueryWindowPos( winId(), &cswp ); | 
|---|
| 1949 | SWP fswp; | 
|---|
| 1950 | WinQueryWindowPos( top->fId, &fswp ); | 
|---|
| 1951 | // flip y coordinates | 
|---|
| 1952 | fswp.y = QApplication::desktop()->height() - (fswp.y + fswp.cy); | 
|---|
| 1953 | cswp.y = fswp.cy - (cswp.y + cswp.cy); | 
|---|
| 1954 | that->crect.setRect( | 
|---|
| 1955 | fswp.x + cswp.x, fswp.y + cswp.y, | 
|---|
| 1956 | cswp.cx, cswp.cy | 
|---|
| 1957 | ); | 
|---|
| 1958 |  | 
|---|
| 1959 | top->fleft = cswp.x; | 
|---|
| 1960 | top->ftop = cswp.y; | 
|---|
| 1961 | top->fright = fswp.cx - cswp.x - cswp.cx; | 
|---|
| 1962 | top->fbottom = fswp.cy - cswp.y - cswp.cy; | 
|---|
| 1963 | } | 
|---|
| 1964 | that->fstrut_dirty = FALSE; | 
|---|
| 1965 | } | 
|---|
| 1966 |  | 
|---|
| 1967 | void QWidget::setMouseTracking( bool enable ) | 
|---|
| 1968 | { | 
|---|
| 1969 | if ( enable ) | 
|---|
| 1970 | setWState( WState_MouseTracking ); | 
|---|
| 1971 | else | 
|---|
| 1972 | clearWState( WState_MouseTracking ); | 
|---|
| 1973 | } | 
|---|
| 1974 |  | 
|---|
| 1975 | void QWidget::setWindowOpacity(double) | 
|---|
| 1976 | { | 
|---|
| 1977 | } | 
|---|
| 1978 |  | 
|---|
| 1979 | double QWidget::windowOpacity() const | 
|---|
| 1980 | { | 
|---|
| 1981 | return 1.0; | 
|---|
| 1982 | } | 
|---|
| 1983 |  | 
|---|
| 1984 | /* | 
|---|
| 1985 | \internal | 
|---|
| 1986 | Returns the frame wihdow handle if this widget is a top-level widget and | 
|---|
| 1987 | has the standard WC_FRAME as its parent/owner (where it is FID_CLIENT). | 
|---|
| 1988 | If the widget does not have the standard frame or it is not top-level, this | 
|---|
| 1989 | function simply retuns the winId() value. | 
|---|
| 1990 | */ | 
|---|
| 1991 | WId QWidget::winFId() | 
|---|
| 1992 | { | 
|---|
| 1993 | HWND fId = 0; | 
|---|
| 1994 | if ( isTopLevel() ) | 
|---|
| 1995 | fId = topData()->fId; | 
|---|
| 1996 | if ( !fId ) | 
|---|
| 1997 | fId = winId(); | 
|---|
| 1998 | return fId; | 
|---|
| 1999 | } | 
|---|
| 2000 |  | 
|---|