source: trunk/src/kernel/qwidget_pm.cpp@ 60

Last change on this file since 60 was 57, checked in by dmik, 20 years ago

Implemented QWidget::setIcon().

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