merge the formfield patch from ooo-build
[ooovba.git] / vcl / source / window / window.cxx
blobc3f22f9271b5e9f5a4139afd2ca415b4f0e29670
1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: window.cxx,v $
10 * $Revision: 1.285.38.2 $
12 * This file is part of OpenOffice.org.
14 * OpenOffice.org is free software: you can redistribute it and/or modify
15 * it under the terms of the GNU Lesser General Public License version 3
16 * only, as published by the Free Software Foundation.
18 * OpenOffice.org is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU Lesser General Public License version 3 for more details
22 * (a copy is included in the LICENSE file that accompanied this code).
24 * You should have received a copy of the GNU Lesser General Public License
25 * version 3 along with OpenOffice.org. If not, see
26 * <http://www.openoffice.org/license.html>
27 * for a copy of the LGPLv3 License.
29 ************************************************************************/
31 // MARKER(update_precomp.py): autogen include statement, do not remove
32 #include "precompiled_vcl.hxx"
33 #ifndef _SV_SVSYS_HXX
34 #include "svsys.h"
35 #endif
36 #include "vcl/salframe.hxx"
37 #include "vcl/salobj.hxx"
38 #include "vcl/salinst.hxx"
39 #include "vcl/salgtype.hxx"
40 #include "vcl/salgdi.hxx"
41 #include "vcl/salctrlhandle.hxx"
43 #include "vcl/unohelp.hxx"
44 #include "tools/time.hxx"
45 #include "tools/debug.hxx"
46 #ifndef _SV_RC_H
47 #include "tools/rc.h"
48 #endif
49 #include "vcl/svdata.hxx"
50 #include "vcl/windata.hxx"
51 #include "vcl/dbggui.hxx"
52 #include "vcl/outfont.hxx"
53 #include "vcl/outdev.h"
54 #include "vcl/region.h"
55 #include "vcl/event.hxx"
56 #include "vcl/help.hxx"
57 #include "vcl/cursor.hxx"
58 #include "vcl/svapp.hxx"
59 #include "vcl/window.h"
60 #include "vcl/window.hxx"
61 #include "vcl/syswin.hxx"
62 #include "vcl/syschild.hxx"
63 #include "vcl/brdwin.hxx"
64 #include "vcl/helpwin.hxx"
65 #include "vcl/dockwin.hxx"
66 #include "vcl/menu.hxx"
67 #include "vcl/wrkwin.hxx"
68 #include "vcl/wall.hxx"
69 #include "vcl/gradient.hxx"
70 #include "vcl/toolbox.h"
71 #include "vcl/fontcfg.hxx"
72 #include "vcl/sysdata.hxx"
73 #include "vcl/sallayout.hxx"
74 #include "vcl/button.hxx" // Button::GetStandardText
75 #include "vcl/taskpanelist.hxx"
76 #include "com/sun/star/awt/XWindowPeer.hpp"
77 #include "com/sun/star/rendering/XCanvas.hpp"
78 #include "com/sun/star/rendering/XSpriteCanvas.hpp"
79 #include "com/sun/star/awt/XWindow.hpp"
80 #include "comphelper/processfactory.hxx"
81 #include "com/sun/star/datatransfer/dnd/XDragSource.hpp"
82 #include "com/sun/star/datatransfer/dnd/XDropTarget.hpp"
83 #include "com/sun/star/datatransfer/clipboard/XClipboard.hpp"
84 #include "com/sun/star/awt/XTopWindow.hpp"
85 #include "com/sun/star/awt/XDisplayConnection.hpp"
86 #include "com/sun/star/lang/XInitialization.hpp"
87 #include "com/sun/star/lang/XComponent.hpp"
88 #include "com/sun/star/lang/XServiceName.hpp"
89 #include "com/sun/star/accessibility/XAccessible.hpp"
90 #include "com/sun/star/accessibility/AccessibleRole.hpp"
92 #include "vcl/dialog.hxx"
93 #include "vcl/unowrap.hxx"
94 #include "dndlcon.hxx"
95 #include "dndevdis.hxx"
96 #include "vcl/impbmpconv.hxx"
97 #include "unotools/confignode.hxx"
98 #include "vcl/gdimtf.hxx"
100 #include "vcl/pdfextoutdevdata.hxx"
101 #include "vcl/lazydelete.hxx"
103 #include <set>
105 using namespace rtl;
106 using namespace ::com::sun::star::uno;
107 using namespace ::com::sun::star::lang;
108 using namespace ::com::sun::star::datatransfer::clipboard;
109 using namespace ::com::sun::star::datatransfer::dnd;
110 using namespace ::com::sun::star;
111 using namespace com::sun;
113 using ::com::sun::star::awt::XTopWindow;
115 // =======================================================================
117 DBG_NAME( Window )
119 // =======================================================================
121 #define IMPL_PAINT_PAINT ((USHORT)0x0001)
122 #define IMPL_PAINT_PAINTALL ((USHORT)0x0002)
123 #define IMPL_PAINT_PAINTALLCHILDS ((USHORT)0x0004)
124 #define IMPL_PAINT_PAINTCHILDS ((USHORT)0x0008)
125 #define IMPL_PAINT_ERASE ((USHORT)0x0010)
126 #define IMPL_PAINT_CHECKRTL ((USHORT)0x0020)
128 // -----------------------------------------------------------------------
130 typedef Window* PWINDOW;
132 // -----------------------------------------------------------------------
134 struct ImplCalcToTopData
136 ImplCalcToTopData* mpNext;
137 Window* mpWindow;
138 Region* mpInvalidateRegion;
141 struct ImplAccessibleInfos
143 USHORT nAccessibleRole;
144 String* pAccessibleName;
145 String* pAccessibleDescription;
147 ImplAccessibleInfos()
149 nAccessibleRole = 0xFFFF;
150 pAccessibleName = NULL;
151 pAccessibleDescription = NULL;
154 ~ImplAccessibleInfos()
156 delete pAccessibleName;
157 delete pAccessibleDescription;
161 // -----------------------------------------------------------------------
163 WindowImpl::WindowImpl()
167 WindowImpl::~WindowImpl()
172 // -----------------------------------------------------------------------
174 // helper method to allow inline constructor even for pWindow!=NULL case
175 void ImplDelData::AttachToWindow( const Window* pWindow )
177 if( pWindow )
178 const_cast<Window*>(pWindow)->ImplAddDel( this );
181 // -----------------------------------------------------------------------
183 // define dtor for ImplDelData
184 ImplDelData::~ImplDelData()
186 // #112873# auto remove of ImplDelData
187 // due to this code actively calling ImplRemoveDel() is not mandatory anymore
188 if( !mbDel && mpWindow )
190 // the window still exists but we were not removed
191 const_cast<Window*>(mpWindow)->ImplRemoveDel( this );
192 mpWindow = NULL;
196 // -----------------------------------------------------------------------
198 #ifdef DBG_UTIL
199 const char* ImplDbgCheckWindow( const void* pObj )
201 DBG_TESTSOLARMUTEX();
203 const Window* pWindow = (Window*)pObj;
205 if ( (pWindow->GetType() < WINDOW_FIRST) || (pWindow->GetType() > WINDOW_LAST) )
206 return "Window data overwrite";
208 // Fenster-Verkettung ueberpruefen
209 Window* pChild = pWindow->mpWindowImpl->mpFirstChild;
210 while ( pChild )
212 if ( pChild->mpWindowImpl->mpParent != pWindow )
213 return "Child-Window-Parent wrong";
214 pChild = pChild->mpWindowImpl->mpNext;
217 return NULL;
219 #endif
221 // =======================================================================
223 void Window::ImplInitAppFontData( Window* pWindow )
225 ImplSVData* pSVData = ImplGetSVData();
226 long nTextHeight = pWindow->GetTextHeight();
227 long nTextWidth = pWindow->GetTextWidth( XubString( RTL_CONSTASCII_USTRINGPARAM( "aemnnxEM" ) ) );
228 long nSymHeight = nTextHeight*4;
229 // Falls Font zu schmal ist, machen wir die Basis breiter,
230 // damit die Dialoge symetrisch aussehen und nicht zu schmal
231 // werden. Wenn der Dialog die gleiche breite hat, geben wir
232 // noch etwas Spielraum dazu, da etwas mehr Platz besser ist.
233 if ( nSymHeight > nTextWidth )
234 nTextWidth = nSymHeight;
235 else if ( nSymHeight+5 > nTextWidth )
236 nTextWidth = nSymHeight+5;
237 pSVData->maGDIData.mnAppFontX = nTextWidth * 10 / 8;
238 pSVData->maGDIData.mnAppFontY = nTextHeight * 10;
240 // FIXME: this is currently only on aqua, check with other
241 // platforms
242 if( pSVData->maNWFData.mbNoFocusRects )
244 // try to find out wether there is a large correction
245 // of control sizes, if yes, make app font scalings larger
246 // so dialog positioning is not completely off
247 ImplControlValue aControlValue;
248 Region aCtrlRegion( (const Rectangle&)Rectangle( Point(), Size( nTextWidth < 10 ? 10 : nTextWidth, nTextHeight < 10 ? 10 : nTextHeight ) ) );
249 Region aBoundingRgn( aCtrlRegion );
250 Region aContentRgn( aCtrlRegion );
251 if( pWindow->GetNativeControlRegion( CTRL_EDITBOX, PART_ENTIRE_CONTROL, aCtrlRegion,
252 CTRL_STATE_ENABLED, aControlValue, rtl::OUString(),
253 aBoundingRgn, aContentRgn ) )
255 Rectangle aContentRect( aContentRgn.GetBoundRect() );
256 // comment: the magical +6 is for the extra border in bordered
257 // (which is the standard) edit fields
258 if( aContentRect.GetHeight() - nTextHeight > (nTextHeight+4)/4 )
259 pSVData->maGDIData.mnAppFontY = (aContentRect.GetHeight()-4) * 10;
264 pSVData->maGDIData.mnRealAppFontX = pSVData->maGDIData.mnAppFontX;
265 if ( pSVData->maAppData.mnDialogScaleX )
266 pSVData->maGDIData.mnAppFontX += (pSVData->maGDIData.mnAppFontX*pSVData->maAppData.mnDialogScaleX)/100;
269 // -----------------------------------------------------------------------
271 bool Window::ImplCheckUIFont( const Font& rFont )
273 if( ImplGetSVData()->maGDIData.mbNativeFontConfig )
274 return true;
276 String aTestText;
277 aTestText.Append( Button::GetStandardText( BUTTON_OK ) );
278 aTestText.Append( Button::GetStandardText( BUTTON_CANCEL ) );
279 aTestText.Append( Button::GetStandardText( BUTTON_YES ) );
280 aTestText.Append( Button::GetStandardText( BUTTON_NO ) );
281 aTestText.Append( Button::GetStandardText( BUTTON_RETRY ) );
282 aTestText.Append( Button::GetStandardText( BUTTON_HELP ) );
283 aTestText.Append( Button::GetStandardText( BUTTON_CLOSE ) );
284 aTestText.Append( Button::GetStandardText( BUTTON_MORE ) );
285 aTestText.Append( Button::GetStandardText( BUTTON_LESS ) );
286 aTestText.Append( Button::GetStandardText( BUTTON_ABORT ) );
288 return HasGlyphs( rFont, aTestText ) >= aTestText.Len();
291 // -----------------------------------------------------------------------
293 void Window::ImplUpdateGlobalSettings( AllSettings& rSettings, BOOL bCallHdl )
295 // reset high contrast to false, so the system can either update it
296 // or AutoDetectSystemHC can kick in (see below)
297 StyleSettings aTmpSt( rSettings.GetStyleSettings() );
298 aTmpSt.SetHighContrastMode( FALSE );
299 rSettings.SetStyleSettings( aTmpSt );
300 ImplGetFrame()->UpdateSettings( rSettings );
302 // Verify availability of the configured UI font, otherwise choose "Andale Sans UI"
303 String aUserInterfaceFont;
304 bool bUseSystemFont = rSettings.GetStyleSettings().GetUseSystemUIFonts();
306 // check whether system UI font can display a typical UI text
307 if( bUseSystemFont )
308 bUseSystemFont = ImplCheckUIFont( rSettings.GetStyleSettings().GetAppFont() );
310 if ( !bUseSystemFont )
312 ImplInitFontList();
313 String aConfigFont = vcl::DefaultFontConfiguration::get()->getUserInterfaceFont( rSettings.GetUILocale() );
314 xub_StrLen nIndex = 0;
315 while( nIndex != STRING_NOTFOUND )
317 String aName( aConfigFont.GetToken( 0, ';', nIndex ) );
318 if ( aName.Len() && mpWindowImpl->mpFrameData->mpFontList->FindFontFamily( aName ) )
320 aUserInterfaceFont = aConfigFont;
321 break;
325 if ( ! aUserInterfaceFont.Len() )
327 String aFallbackFont (RTL_CONSTASCII_USTRINGPARAM( "Andale Sans UI" ));
328 if ( mpWindowImpl->mpFrameData->mpFontList->FindFontFamily( aFallbackFont ) )
329 aUserInterfaceFont = aFallbackFont;
333 if ( !bUseSystemFont && aUserInterfaceFont.Len() )
335 StyleSettings aStyleSettings = rSettings.GetStyleSettings();
336 Font aFont = aStyleSettings.GetAppFont();
337 aFont.SetName( aUserInterfaceFont );
338 aStyleSettings.SetAppFont( aFont );
339 aFont = aStyleSettings.GetHelpFont();
340 aFont.SetName( aUserInterfaceFont );
341 aStyleSettings.SetHelpFont( aFont );
342 aFont = aStyleSettings.GetTitleFont();
343 aFont.SetName( aUserInterfaceFont );
344 aStyleSettings.SetTitleFont( aFont );
345 aFont = aStyleSettings.GetFloatTitleFont();
346 aFont.SetName( aUserInterfaceFont );
347 aStyleSettings.SetFloatTitleFont( aFont );
348 aFont = aStyleSettings.GetMenuFont();
349 aFont.SetName( aUserInterfaceFont );
350 aStyleSettings.SetMenuFont( aFont );
351 aFont = aStyleSettings.GetToolFont();
352 aFont.SetName( aUserInterfaceFont );
353 aStyleSettings.SetToolFont( aFont );
354 aFont = aStyleSettings.GetLabelFont();
355 aFont.SetName( aUserInterfaceFont );
356 aStyleSettings.SetLabelFont( aFont );
357 aFont = aStyleSettings.GetInfoFont();
358 aFont.SetName( aUserInterfaceFont );
359 aStyleSettings.SetInfoFont( aFont );
360 aFont = aStyleSettings.GetRadioCheckFont();
361 aFont.SetName( aUserInterfaceFont );
362 aStyleSettings.SetRadioCheckFont( aFont );
363 aFont = aStyleSettings.GetPushButtonFont();
364 aFont.SetName( aUserInterfaceFont );
365 aStyleSettings.SetPushButtonFont( aFont );
366 aFont = aStyleSettings.GetFieldFont();
367 aFont.SetName( aUserInterfaceFont );
368 aStyleSettings.SetFieldFont( aFont );
369 aFont = aStyleSettings.GetIconFont();
370 aFont.SetName( aUserInterfaceFont );
371 aStyleSettings.SetIconFont( aFont );
372 aFont = aStyleSettings.GetGroupFont();
373 aFont.SetName( aUserInterfaceFont );
374 aStyleSettings.SetGroupFont( aFont );
375 rSettings.SetStyleSettings( aStyleSettings );
378 StyleSettings aStyleSettings = rSettings.GetStyleSettings();
379 // #97047: Force all fonts except Menu and Help to a fixed height
380 // to avoid UI scaling due to large fonts
381 // - but allow bigger fonts on bigger screens (i16682, i21238)
382 // dialogs were designed to fit 800x600 with an 8pt font, so scale accordingly
383 int maxFontheight = 9; // #107886#: 9 is default for some asian systems, so always allow if requested
384 if( GetDesktopRectPixel().getHeight() > 600 )
385 maxFontheight = (int) ((( 8.0 * (double) GetDesktopRectPixel().getHeight()) / 600.0) + 1.5);
387 Font aFont = aStyleSettings.GetMenuFont();
388 int defFontheight = aFont.GetHeight();
389 if( defFontheight > maxFontheight )
390 defFontheight = maxFontheight;
392 // if the UI is korean, chinese or another locale
393 // where the system font size is kown to be often too small to
394 // generate readable fonts enforce a minimum font size of 9 points
395 bool bBrokenLangFontHeight = false;
396 static const LanguageType eBrokenSystemFontSizeLanguages[] =
397 { LANGUAGE_KOREAN, LANGUAGE_KOREAN_JOHAB,
398 LANGUAGE_CHINESE_HONGKONG, LANGUAGE_CHINESE_MACAU, LANGUAGE_CHINESE_SIMPLIFIED, LANGUAGE_CHINESE_SINGAPORE, LANGUAGE_CHINESE_TRADITIONAL
400 static std::set< LanguageType > aBrokenSystemFontSizeLanguagesSet(
401 eBrokenSystemFontSizeLanguages,
402 eBrokenSystemFontSizeLanguages +
403 (sizeof(eBrokenSystemFontSizeLanguages)/sizeof(eBrokenSystemFontSizeLanguages[0]))
405 LanguageType aLang = Application::GetSettings().GetUILanguage();
406 if( aBrokenSystemFontSizeLanguagesSet.find( aLang ) != aBrokenSystemFontSizeLanguagesSet.end() )
408 defFontheight = Max(9, defFontheight);
409 bBrokenLangFontHeight = true;
412 // i22098, toolfont will be scaled differently to avoid bloated rulers and status bars for big fonts
413 int toolfontheight = defFontheight;
414 if( toolfontheight > 9 )
415 toolfontheight = (defFontheight+8) / 2;
417 aFont = aStyleSettings.GetAppFont();
418 aFont.SetHeight( defFontheight );
419 aStyleSettings.SetAppFont( aFont );
420 aFont = aStyleSettings.GetTitleFont();
421 aFont.SetHeight( defFontheight );
422 aStyleSettings.SetTitleFont( aFont );
423 aFont = aStyleSettings.GetFloatTitleFont();
424 aFont.SetHeight( defFontheight );
425 aStyleSettings.SetFloatTitleFont( aFont );
426 // keep menu and help font size from system unless in broken locale size
427 if( bBrokenLangFontHeight )
429 aFont = aStyleSettings.GetMenuFont();
430 if( aFont.GetHeight() < defFontheight )
432 aFont.SetHeight( defFontheight );
433 aStyleSettings.SetMenuFont( aFont );
435 aFont = aStyleSettings.GetHelpFont();
436 if( aFont.GetHeight() < defFontheight )
438 aFont.SetHeight( defFontheight );
439 aStyleSettings.SetHelpFont( aFont );
443 // use different height for toolfont
444 aFont = aStyleSettings.GetToolFont();
445 aFont.SetHeight( toolfontheight );
446 aStyleSettings.SetToolFont( aFont );
448 aFont = aStyleSettings.GetLabelFont();
449 aFont.SetHeight( defFontheight );
450 aStyleSettings.SetLabelFont( aFont );
451 aFont = aStyleSettings.GetInfoFont();
452 aFont.SetHeight( defFontheight );
453 aStyleSettings.SetInfoFont( aFont );
454 aFont = aStyleSettings.GetRadioCheckFont();
455 aFont.SetHeight( defFontheight );
456 aStyleSettings.SetRadioCheckFont( aFont );
457 aFont = aStyleSettings.GetPushButtonFont();
458 aFont.SetHeight( defFontheight );
459 aStyleSettings.SetPushButtonFont( aFont );
460 aFont = aStyleSettings.GetFieldFont();
461 aFont.SetHeight( defFontheight );
462 aStyleSettings.SetFieldFont( aFont );
463 aFont = aStyleSettings.GetIconFont();
464 aFont.SetHeight( defFontheight );
465 aStyleSettings.SetIconFont( aFont );
466 aFont = aStyleSettings.GetGroupFont();
467 aFont.SetHeight( defFontheight );
468 aStyleSettings.SetGroupFont( aFont );
470 // set workspace gradient to black in dark themes
471 if( aStyleSettings.GetWindowColor().IsDark() )
472 aStyleSettings.SetWorkspaceGradient( Wallpaper( Color( COL_BLACK ) ) );
473 else
475 Gradient aGrad( GRADIENT_LINEAR, DEFAULT_WORKSPACE_GRADIENT_START_COLOR, DEFAULT_WORKSPACE_GRADIENT_END_COLOR );
476 aStyleSettings.SetWorkspaceGradient( Wallpaper( aGrad ) );
479 rSettings.SetStyleSettings( aStyleSettings );
482 // auto detect HC mode; if the system already set it to "yes"
483 // (see above) then accept that
484 if( !rSettings.GetStyleSettings().GetHighContrastMode() )
486 sal_Bool bTmp = sal_False, bAutoHCMode = sal_True;
487 utl::OConfigurationNode aNode = utl::OConfigurationTreeRoot::tryCreateWithServiceFactory(
488 vcl::unohelper::GetMultiServiceFactory(),
489 OUString::createFromAscii( "org.openoffice.Office.Common/Accessibility" ) ); // note: case sensisitive !
490 if ( aNode.isValid() )
492 ::com::sun::star::uno::Any aValue = aNode.getNodeValue( OUString::createFromAscii( "AutoDetectSystemHC" ) );
493 if( aValue >>= bTmp )
494 bAutoHCMode = bTmp;
496 if( bAutoHCMode )
498 if( rSettings.GetStyleSettings().GetFaceColor().IsDark()
499 || rSettings.GetStyleSettings().GetWindowColor().IsDark() )
501 aStyleSettings = rSettings.GetStyleSettings();
502 aStyleSettings.SetHighContrastMode( TRUE );
503 rSettings.SetStyleSettings( aStyleSettings );
508 #ifdef DBG_UTIL
509 // Evt. AppFont auf Fett schalten, damit man feststellen kann,
510 // ob fuer die Texte auf anderen Systemen genuegend Platz
511 // vorhanden ist
512 if ( DbgIsBoldAppFont() )
514 aStyleSettings = rSettings.GetStyleSettings();
515 aFont = aStyleSettings.GetAppFont();
516 aFont.SetWeight( WEIGHT_BOLD );
517 aStyleSettings.SetAppFont( aFont );
518 aFont = aStyleSettings.GetGroupFont();
519 aFont.SetWeight( WEIGHT_BOLD );
520 aStyleSettings.SetGroupFont( aFont );
521 aFont = aStyleSettings.GetLabelFont();
522 aFont.SetWeight( WEIGHT_BOLD );
523 aStyleSettings.SetLabelFont( aFont );
524 aFont = aStyleSettings.GetRadioCheckFont();
525 aFont.SetWeight( WEIGHT_BOLD );
526 aStyleSettings.SetRadioCheckFont( aFont );
527 aFont = aStyleSettings.GetPushButtonFont();
528 aFont.SetWeight( WEIGHT_BOLD );
529 aStyleSettings.SetPushButtonFont( aFont );
530 aFont = aStyleSettings.GetFieldFont();
531 aFont.SetWeight( WEIGHT_BOLD );
532 aStyleSettings.SetFieldFont( aFont );
533 aFont = aStyleSettings.GetIconFont();
534 aFont.SetWeight( WEIGHT_BOLD );
535 aStyleSettings.SetIconFont( aFont );
536 rSettings.SetStyleSettings( aStyleSettings );
538 #endif
540 if ( bCallHdl )
541 GetpApp()->SystemSettingsChanging( rSettings, this );
544 // -----------------------------------------------------------------------
546 MouseEvent ImplTranslateMouseEvent( const MouseEvent& rE, Window* pSource, Window* pDest )
548 Point aPos = pSource->OutputToScreenPixel( rE.GetPosPixel() );
549 aPos = pDest->ScreenToOutputPixel( aPos );
550 return MouseEvent( aPos, rE.GetClicks(), rE.GetMode(), rE.GetButtons(), rE.GetModifier() );
553 // -----------------------------------------------------------------------
555 CommandEvent ImplTranslateCommandEvent( const CommandEvent& rCEvt, Window* pSource, Window* pDest )
557 if ( !rCEvt.IsMouseEvent() )
558 return rCEvt;
560 Point aPos = pSource->OutputToScreenPixel( rCEvt.GetMousePosPixel() );
561 aPos = pDest->ScreenToOutputPixel( aPos );
562 return CommandEvent( aPos, rCEvt.GetCommand(), rCEvt.IsMouseEvent(), rCEvt.GetData() );
565 // =======================================================================
567 void Window::ImplInitWindowData( WindowType nType )
569 mpWindowImpl = new WindowImpl;
571 meOutDevType = OUTDEV_WINDOW;
573 mpWindowImpl->maZoom = Fraction( 1, 1 );
574 mpWindowImpl->maWinRegion = Region( REGION_NULL );
575 mpWindowImpl->maWinClipRegion = Region( REGION_NULL );
576 mpWindowImpl->mpWinData = NULL; // Extra Window Data, that we dont need for all windows
577 mpWindowImpl->mpOverlapData = NULL; // Overlap Data
578 mpWindowImpl->mpFrameData = NULL; // Frame Data
579 mpWindowImpl->mpFrame = NULL; // Pointer to frame window
580 mpWindowImpl->mpSysObj = NULL;
581 mpWindowImpl->mpFrameWindow = NULL; // window to top level parent (same as frame window)
582 mpWindowImpl->mpOverlapWindow = NULL; // first overlap parent
583 mpWindowImpl->mpBorderWindow = NULL; // Border-Window
584 mpWindowImpl->mpClientWindow = NULL; // Client-Window of a FrameWindow
585 mpWindowImpl->mpParent = NULL; // parent (inkl. BorderWindow)
586 mpWindowImpl->mpRealParent = NULL; // real parent (exkl. BorderWindow)
587 mpWindowImpl->mpFirstChild = NULL; // first child window
588 mpWindowImpl->mpLastChild = NULL; // last child window
589 mpWindowImpl->mpFirstOverlap = NULL; // first overlap window (only set in overlap windows)
590 mpWindowImpl->mpLastOverlap = NULL; // last overlap window (only set in overlap windows)
591 mpWindowImpl->mpPrev = NULL; // prev window
592 mpWindowImpl->mpNext = NULL; // next window
593 mpWindowImpl->mpNextOverlap = NULL; // next overlap window of frame
594 mpWindowImpl->mpLastFocusWindow = NULL; // window for focus restore
595 mpWindowImpl->mpDlgCtrlDownWindow = NULL; // window for dialog control
596 mpWindowImpl->mpFirstDel = NULL; // Dtor notification list
597 mpWindowImpl->mpUserData = NULL; // user data
598 mpWindowImpl->mpCursor = NULL; // cursor
599 mpWindowImpl->mpControlFont = NULL; // font propertie
600 mpWindowImpl->mpVCLXWindow = NULL;
601 mpWindowImpl->mpAccessibleInfos = NULL;
602 mpWindowImpl->maControlForeground = Color( COL_TRANSPARENT ); // kein Foreground gesetzt
603 mpWindowImpl->maControlBackground = Color( COL_TRANSPARENT ); // kein Background gesetzt
604 mpWindowImpl->mnLeftBorder = 0; // left border
605 mpWindowImpl->mnTopBorder = 0; // top border
606 mpWindowImpl->mnRightBorder = 0; // right border
607 mpWindowImpl->mnBottomBorder = 0; // bottom border
608 mpWindowImpl->mnX = 0; // X-Position to Parent
609 mpWindowImpl->mnY = 0; // Y-Position to Parent
610 mpWindowImpl->mnAbsScreenX = 0; // absolute X-position on screen, used for RTL window positioning
611 mpWindowImpl->mnHelpId = 0; // help id
612 mpWindowImpl->mnUniqId = 0; // unique id
613 mpWindowImpl->mpChildClipRegion = NULL; // Child-Clip-Region when ClipChildren
614 mpWindowImpl->mpPaintRegion = NULL; // Paint-ClipRegion
615 mpWindowImpl->mnStyle = 0; // style (init in ImplInitWindow)
616 mpWindowImpl->mnPrevStyle = 0; // prevstyle (set in SetStyle)
617 mpWindowImpl->mnExtendedStyle = 0; // extended style (init in ImplInitWindow)
618 mpWindowImpl->mnPrevExtendedStyle = 0; // prevstyle (set in SetExtendedStyle)
619 mpWindowImpl->mnType = nType; // type
620 mpWindowImpl->mnGetFocusFlags = 0; // Flags fuer GetFocus()-Aufruf
621 mpWindowImpl->mnWaitCount = 0; // Wait-Count (>1 == Warte-MousePointer)
622 mpWindowImpl->mnPaintFlags = 0; // Flags for ImplCallPaint
623 mpWindowImpl->mnParentClipMode = 0; // Flags for Parent-ClipChildren-Mode
624 mpWindowImpl->mnActivateMode = 0; // Wird bei System/Overlap-Windows umgesetzt
625 mpWindowImpl->mnDlgCtrlFlags = 0; // DialogControl-Flags
626 mpWindowImpl->mnLockCount = 0; // LockCount
627 mpWindowImpl->meAlwaysInputMode = AlwaysInputNone; // neither AlwaysEnableInput nor AlwaysDisableInput called
628 mpWindowImpl->mbFrame = FALSE; // TRUE: Window is a frame window
629 mpWindowImpl->mbBorderWin = FALSE; // TRUE: Window is a border window
630 mpWindowImpl->mbOverlapWin = FALSE; // TRUE: Window is a overlap window
631 mpWindowImpl->mbSysWin = FALSE; // TRUE: SystemWindow is the base class
632 mpWindowImpl->mbDialog = FALSE; // TRUE: Dialog is the base class
633 mpWindowImpl->mbDockWin = FALSE; // TRUE: DockingWindow is the base class
634 mpWindowImpl->mbFloatWin = FALSE; // TRUE: FloatingWindow is the base class
635 mpWindowImpl->mbPushButton = FALSE; // TRUE: PushButton is the base class
636 mpWindowImpl->mbToolBox = FALSE; // TRUE: ToolBox is the base class
637 mpWindowImpl->mbMenuFloatingWindow= FALSE; // TRUE: MenuFloatingWindow is the base class
638 mpWindowImpl->mbToolbarFloatingWindow= FALSE; // TRUE: ImplPopupFloatWin is the base class, used for subtoolbars
639 mpWindowImpl->mbSplitter = FALSE; // TRUE: Splitter is the base class
640 mpWindowImpl->mbVisible = FALSE; // TRUE: Show( TRUE ) called
641 mpWindowImpl->mbOverlapVisible = FALSE; // TRUE: Hide called for visible window from ImplHideAllOverlapWindow()
642 mpWindowImpl->mbDisabled = FALSE; // TRUE: Enable( FALSE ) called
643 mpWindowImpl->mbInputDisabled = FALSE; // TRUE: EnableInput( FALSE ) called
644 mpWindowImpl->mbDropDisabled = FALSE; // TRUE: Drop is enabled
645 mpWindowImpl->mbNoUpdate = FALSE; // TRUE: SetUpdateMode( FALSE ) called
646 mpWindowImpl->mbNoParentUpdate = FALSE; // TRUE: SetParentUpdateMode( FALSE ) called
647 mpWindowImpl->mbActive = FALSE; // TRUE: Window Active
648 mpWindowImpl->mbParentActive = FALSE; // TRUE: OverlapActive from Parent
649 mpWindowImpl->mbReallyVisible = FALSE; // TRUE: this and all parents to an overlaped window are visible
650 mpWindowImpl->mbReallyShown = FALSE; // TRUE: this and all parents to an overlaped window are shown
651 mpWindowImpl->mbInInitShow = FALSE; // TRUE: we are in InitShow
652 mpWindowImpl->mbChildNotify = FALSE; // TRUE: ChildNotify
653 mpWindowImpl->mbChildPtrOverwrite = FALSE; // TRUE: PointerStyle overwrites Child-Pointer
654 mpWindowImpl->mbNoPtrVisible = FALSE; // TRUE: ShowPointer( FALSE ) called
655 mpWindowImpl->mbMouseMove = FALSE; // TRUE: BaseMouseMove called
656 mpWindowImpl->mbPaintFrame = FALSE; // TRUE: Paint is visible, but not painted
657 mpWindowImpl->mbInPaint = FALSE; // TRUE: Inside PaintHdl
658 mpWindowImpl->mbMouseButtonDown = FALSE; // TRUE: BaseMouseButtonDown called
659 mpWindowImpl->mbMouseButtonUp = FALSE; // TRUE: BaseMouseButtonUp called
660 mpWindowImpl->mbKeyInput = FALSE; // TRUE: BaseKeyInput called
661 mpWindowImpl->mbKeyUp = FALSE; // TRUE: BaseKeyUp called
662 mpWindowImpl->mbCommand = FALSE; // TRUE: BaseCommand called
663 mpWindowImpl->mbDefPos = TRUE; // TRUE: Position is not Set
664 mpWindowImpl->mbDefSize = TRUE; // TRUE: Size is not Set
665 mpWindowImpl->mbCallMove = TRUE; // TRUE: Move must be called by Show
666 mpWindowImpl->mbCallResize = TRUE; // TRUE: Resize must be called by Show
667 mpWindowImpl->mbWaitSystemResize = TRUE; // TRUE: Wait for System-Resize
668 mpWindowImpl->mbInitWinClipRegion = TRUE; // TRUE: Calc Window Clip Region
669 mpWindowImpl->mbInitChildRegion = FALSE; // TRUE: InitChildClipRegion
670 mpWindowImpl->mbWinRegion = FALSE; // TRUE: Window Region
671 mpWindowImpl->mbClipChildren = FALSE; // TRUE: Child-Fenster muessen evt. geclippt werden
672 mpWindowImpl->mbClipSiblings = FALSE; // TRUE: Nebeneinanderliegende Child-Fenster muessen evt. geclippt werden
673 mpWindowImpl->mbChildTransparent = FALSE; // TRUE: Child-Fenster duerfen transparent einschalten (inkl. Parent-CLIPCHILDREN)
674 mpWindowImpl->mbPaintTransparent = FALSE; // TRUE: Paints muessen auf Parent ausgeloest werden
675 mpWindowImpl->mbMouseTransparent = FALSE; // TRUE: Window is transparent for Mouse
676 mpWindowImpl->mbDlgCtrlStart = FALSE; // TRUE: Ab hier eigenes Dialog-Control
677 mpWindowImpl->mbFocusVisible = FALSE; // TRUE: Focus Visible
678 mpWindowImpl->mbUseNativeFocus = FALSE;
679 mpWindowImpl->mbNativeFocusVisible= FALSE; // TRUE: native Focus Visible
680 mpWindowImpl->mbInShowFocus = FALSE; // prevent recursion
681 mpWindowImpl->mbInHideFocus = FALSE; // prevent recursion
682 mpWindowImpl->mbTrackVisible = FALSE; // TRUE: Tracking Visible
683 mpWindowImpl->mbControlForeground = FALSE; // TRUE: Foreground-Property set
684 mpWindowImpl->mbControlBackground = FALSE; // TRUE: Background-Property set
685 mpWindowImpl->mbAlwaysOnTop = FALSE; // TRUE: immer vor allen anderen normalen Fenstern sichtbar
686 mpWindowImpl->mbCompoundControl = FALSE; // TRUE: Zusammengesetztes Control => Listener...
687 mpWindowImpl->mbCompoundControlHasFocus = FALSE; // TRUE: Zusammengesetztes Control hat irgendwo den Focus
688 mpWindowImpl->mbPaintDisabled = FALSE; // TRUE: Paint soll nicht ausgefuehrt werden
689 mpWindowImpl->mbAllResize = FALSE; // TRUE: Auch ResizeEvents mit 0,0 schicken
690 mpWindowImpl->mbInDtor = FALSE; // TRUE: Wir befinden uns im Window-Dtor
691 mpWindowImpl->mbExtTextInput = FALSE; // TRUE: ExtTextInput-Mode is active
692 mpWindowImpl->mbInFocusHdl = FALSE; // TRUE: Innerhalb vom GetFocus-Handler
693 mpWindowImpl->mbCreatedWithToolkit = FALSE;
694 mpWindowImpl->mbSuppressAccessibilityEvents = FALSE; // TRUE: do not send any accessibility events
695 mpWindowImpl->mbDrawSelectionBackground = FALSE; // TRUE: draws transparent window background to indicate (toolbox) selection
696 mpWindowImpl->mbIsInTaskPaneList = FALSE; // TRUE: window was added to the taskpanelist in the topmost system window
697 mpWindowImpl->mnNativeBackground = 0; // initialize later, depends on type
698 mpWindowImpl->mbCallHandlersDuringInputDisabled = FALSE; // TRUE: call event handlers even if input is disabled
699 mpWindowImpl->mbDisableAccessibleLabelForRelation = FALSE; // TRUE: do not set LabelFor relation on accessible objects
700 mpWindowImpl->mbDisableAccessibleLabeledByRelation = FALSE; // TRUE: do not set LabeledBy relation on accessible objects
701 mpWindowImpl->mbFakeFocusSet = FALSE; // TRUE: pretend as if the window has focus.
703 mbEnableRTL = Application::GetSettings().GetLayoutRTL(); // TRUE: this outdev will be mirrored if RTL window layout (UI mirroring) is globally active
706 // -----------------------------------------------------------------------
708 void Window::ImplInit( Window* pParent, WinBits nStyle, const ::com::sun::star::uno::Any& /*aSystemWorkWindowToken*/ )
710 ImplInit( pParent, nStyle, NULL );
713 // -----------------------------------------------------------------------
715 void Window::ImplInit( Window* pParent, WinBits nStyle, SystemParentData* pSystemParentData )
717 DBG_ASSERT( mpWindowImpl->mbFrame || pParent, "Window::Window(): pParent == NULL" );
719 ImplSVData* pSVData = ImplGetSVData();
720 Window* pRealParent = pParent;
722 // 3D-Look vererben
723 if ( !mpWindowImpl->mbOverlapWin && pParent && (pParent->GetStyle() & WB_3DLOOK) )
724 nStyle |= WB_3DLOOK;
726 // create border window if necessary
727 if ( !mpWindowImpl->mbFrame && !mpWindowImpl->mbBorderWin && !mpWindowImpl->mpBorderWindow
728 && (nStyle & (WB_BORDER | WB_SYSTEMCHILDWINDOW) ) )
730 USHORT nBorderTypeStyle = 0;
731 if( (nStyle & WB_SYSTEMCHILDWINDOW) )
733 // handle WB_SYSTEMCHILDWINDOW
734 // these should be analogous to a top level frame; meaning they
735 // should have a border window with style BORDERWINDOW_STYLE_FRAME
736 // which controls their size
737 nBorderTypeStyle |= BORDERWINDOW_STYLE_FRAME;
738 nStyle |= WB_BORDER;
740 ImplBorderWindow* pBorderWin = new ImplBorderWindow( pParent, nStyle & (WB_BORDER | WB_DIALOGCONTROL | WB_NODIALOGCONTROL | WB_NEEDSFOCUS), nBorderTypeStyle );
741 ((Window*)pBorderWin)->mpWindowImpl->mpClientWindow = this;
742 pBorderWin->GetBorder( mpWindowImpl->mnLeftBorder, mpWindowImpl->mnTopBorder, mpWindowImpl->mnRightBorder, mpWindowImpl->mnBottomBorder );
743 mpWindowImpl->mpBorderWindow = pBorderWin;
744 pParent = mpWindowImpl->mpBorderWindow;
746 else if( !mpWindowImpl->mbFrame && ! pParent )
748 mpWindowImpl->mbOverlapWin = TRUE;
749 mpWindowImpl->mbFrame = TRUE;
752 // insert window in list
753 ImplInsertWindow( pParent );
754 mpWindowImpl->mnStyle = nStyle;
756 // Overlap-Window-Daten
757 if ( mpWindowImpl->mbOverlapWin )
759 mpWindowImpl->mpOverlapData = new ImplOverlapData;
760 mpWindowImpl->mpOverlapData->mpSaveBackDev = NULL;
761 mpWindowImpl->mpOverlapData->mpSaveBackRgn = NULL;
762 mpWindowImpl->mpOverlapData->mpNextBackWin = NULL;
763 mpWindowImpl->mpOverlapData->mnSaveBackSize = 0;
764 mpWindowImpl->mpOverlapData->mbSaveBack = FALSE;
765 mpWindowImpl->mpOverlapData->mnTopLevel = 1;
768 if( pParent && ! mpWindowImpl->mbFrame )
769 mbEnableRTL = pParent->mbEnableRTL;
771 // test for frame creation
772 if ( mpWindowImpl->mbFrame )
774 // create frame
775 ULONG nFrameStyle = 0;
777 if ( nStyle & WB_MOVEABLE )
778 nFrameStyle |= SAL_FRAME_STYLE_MOVEABLE;
779 if ( nStyle & WB_SIZEABLE )
780 nFrameStyle |= SAL_FRAME_STYLE_SIZEABLE;
781 if ( nStyle & WB_CLOSEABLE )
782 nFrameStyle |= SAL_FRAME_STYLE_CLOSEABLE;
783 if ( nStyle & WB_APP )
784 nFrameStyle |= SAL_FRAME_STYLE_DEFAULT;
785 // check for undecorated floating window
786 if( // 1. floating windows that are not moveable/sizeable (only closeable allowed)
787 ( !(nFrameStyle & ~SAL_FRAME_STYLE_CLOSEABLE) &&
788 ( mpWindowImpl->mbFloatWin || ((GetType() == WINDOW_BORDERWINDOW) && ((ImplBorderWindow*)this)->mbFloatWindow) || (nStyle & WB_SYSTEMFLOATWIN) ) ) ||
789 // 2. borderwindows of floaters with ownerdraw decoration
790 ( ((GetType() == WINDOW_BORDERWINDOW) && ((ImplBorderWindow*)this)->mbFloatWindow && (nStyle & WB_OWNERDRAWDECORATION) ) ) )
792 nFrameStyle = SAL_FRAME_STYLE_FLOAT;
793 if( nStyle & WB_OWNERDRAWDECORATION )
794 nFrameStyle |= (SAL_FRAME_STYLE_OWNERDRAWDECORATION | SAL_FRAME_STYLE_NOSHADOW);
795 if( nStyle & WB_NEEDSFOCUS )
796 nFrameStyle |= SAL_FRAME_STYLE_FLOAT_FOCUSABLE;
798 else if( mpWindowImpl->mbFloatWin )
799 nFrameStyle |= SAL_FRAME_STYLE_TOOLWINDOW;
801 if( nStyle & WB_TOOLTIPWIN )
802 nFrameStyle |= SAL_FRAME_STYLE_TOOLTIP;
804 if( nStyle & WB_NOSHADOW )
805 nFrameStyle |= SAL_FRAME_STYLE_NOSHADOW;
807 if( nStyle & WB_SYSTEMCHILDWINDOW )
808 nFrameStyle |= SAL_FRAME_STYLE_SYSTEMCHILD;
810 switch (mpWindowImpl->mnType)
812 case WINDOW_DIALOG:
813 case WINDOW_TABDIALOG:
814 case WINDOW_MODALDIALOG:
815 case WINDOW_MODELESSDIALOG:
816 case WINDOW_MESSBOX:
817 case WINDOW_INFOBOX:
818 case WINDOW_WARNINGBOX:
819 case WINDOW_ERRORBOX:
820 case WINDOW_QUERYBOX:
821 nFrameStyle |= SAL_FRAME_STYLE_DIALOG;
822 default:
823 break;
826 SalFrame* pParentFrame = NULL;
827 if ( pParent )
828 pParentFrame = pParent->mpWindowImpl->mpFrame;
829 SalFrame* pFrame;
830 if ( pSystemParentData )
831 pFrame = pSVData->mpDefInst->CreateChildFrame( pSystemParentData, nFrameStyle | SAL_FRAME_STYLE_PLUG );
832 else
833 pFrame = pSVData->mpDefInst->CreateFrame( pParentFrame, nFrameStyle );
834 if ( !pFrame )
836 // do not abort but throw an exception, may be the current thread terminates anyway (plugin-scenario)
837 throw ::com::sun::star::uno::RuntimeException(
838 OUString( RTL_CONSTASCII_USTRINGPARAM( "Could not create system window!" ) ),
839 ::com::sun::star::uno::Reference< ::com::sun::star::uno::XInterface >() );
840 //GetpApp()->Exception( EXC_SYSOBJNOTCREATED );
843 pFrame->SetCallback( this, ImplWindowFrameProc );
845 // set window frame data
846 mpWindowImpl->mpFrameData = new ImplFrameData;
847 mpWindowImpl->mpFrame = pFrame;
848 mpWindowImpl->mpFrameWindow = this;
849 mpWindowImpl->mpOverlapWindow = this;
851 // set frame data
852 mpWindowImpl->mpFrameData->mpNextFrame = pSVData->maWinData.mpFirstFrame;
853 pSVData->maWinData.mpFirstFrame = this;
854 mpWindowImpl->mpFrameData->mpFirstOverlap = NULL;
855 mpWindowImpl->mpFrameData->mpFocusWin = NULL;
856 mpWindowImpl->mpFrameData->mpMouseMoveWin = NULL;
857 mpWindowImpl->mpFrameData->mpMouseDownWin = NULL;
858 mpWindowImpl->mpFrameData->mpFirstBackWin = NULL;
859 mpWindowImpl->mpFrameData->mpFontList = pSVData->maGDIData.mpScreenFontList;
860 mpWindowImpl->mpFrameData->mpFontCache = pSVData->maGDIData.mpScreenFontCache;
861 mpWindowImpl->mpFrameData->mnAllSaveBackSize = 0;
862 mpWindowImpl->mpFrameData->mnFocusId = 0;
863 mpWindowImpl->mpFrameData->mnMouseMoveId = 0;
864 mpWindowImpl->mpFrameData->mnLastMouseX = -1;
865 mpWindowImpl->mpFrameData->mnLastMouseY = -1;
866 mpWindowImpl->mpFrameData->mnBeforeLastMouseX = -1;
867 mpWindowImpl->mpFrameData->mnBeforeLastMouseY = -1;
868 mpWindowImpl->mpFrameData->mnFirstMouseX = -1;
869 mpWindowImpl->mpFrameData->mnFirstMouseY = -1;
870 mpWindowImpl->mpFrameData->mnLastMouseWinX = -1;
871 mpWindowImpl->mpFrameData->mnLastMouseWinY = -1;
872 mpWindowImpl->mpFrameData->mnModalMode = 0;
873 mpWindowImpl->mpFrameData->mnMouseDownTime = 0;
874 mpWindowImpl->mpFrameData->mnClickCount = 0;
875 mpWindowImpl->mpFrameData->mnFirstMouseCode = 0;
876 mpWindowImpl->mpFrameData->mnMouseCode = 0;
877 mpWindowImpl->mpFrameData->mnMouseMode = 0;
878 mpWindowImpl->mpFrameData->meMapUnit = MAP_PIXEL;
879 mpWindowImpl->mpFrameData->mbHasFocus = FALSE;
880 mpWindowImpl->mpFrameData->mbInMouseMove = FALSE;
881 mpWindowImpl->mpFrameData->mbMouseIn = FALSE;
882 mpWindowImpl->mpFrameData->mbStartDragCalled = FALSE;
883 mpWindowImpl->mpFrameData->mbNeedSysWindow = FALSE;
884 mpWindowImpl->mpFrameData->mbMinimized = FALSE;
885 mpWindowImpl->mpFrameData->mbStartFocusState = FALSE;
886 mpWindowImpl->mpFrameData->mbInSysObjFocusHdl = FALSE;
887 mpWindowImpl->mpFrameData->mbInSysObjToTopHdl = FALSE;
888 mpWindowImpl->mpFrameData->mbSysObjFocus = FALSE;
889 mpWindowImpl->mpFrameData->maPaintTimer.SetTimeout( 30 );
890 mpWindowImpl->mpFrameData->maPaintTimer.SetTimeoutHdl( LINK( this, Window, ImplHandlePaintHdl ) );
891 mpWindowImpl->mpFrameData->maResizeTimer.SetTimeout( 50 );
892 mpWindowImpl->mpFrameData->maResizeTimer.SetTimeoutHdl( LINK( this, Window, ImplHandleResizeTimerHdl ) );
893 mpWindowImpl->mpFrameData->mbInternalDragGestureRecognizer = FALSE;
895 if ( pRealParent && IsTopWindow() )
897 ImplWinData* pParentWinData = pRealParent->ImplGetWinData();
898 pParentWinData->maTopWindowChildren.push_back( this );
902 // init data
903 mpWindowImpl->mpRealParent = pRealParent;
905 // #99318: make sure fontcache and list is available before call to SetSettings
906 mpFontList = mpWindowImpl->mpFrameData->mpFontList;
907 mpFontCache = mpWindowImpl->mpFrameData->mpFontCache;
909 if ( mpWindowImpl->mbFrame )
911 if ( pParent )
913 mpWindowImpl->mpFrameData->mnDPIX = pParent->mpWindowImpl->mpFrameData->mnDPIX;
914 mpWindowImpl->mpFrameData->mnDPIY = pParent->mpWindowImpl->mpFrameData->mnDPIY;
916 else
918 if ( ImplGetGraphics() )
920 mpGraphics->GetResolution( mpWindowImpl->mpFrameData->mnDPIX, mpWindowImpl->mpFrameData->mnDPIY );
924 // add ownerdraw decorated frame windows to list in the top-most frame window
925 // so they can be hidden on lose focus
926 if( nStyle & WB_OWNERDRAWDECORATION )
927 ImplGetOwnerDrawList().push_back( this );
929 // delay settings initialization until first "real" frame
930 // this relies on the IntroWindow not needing any system settings
931 if ( !pSVData->maAppData.mbSettingsInit &&
932 ! (nStyle & (WB_INTROWIN|WB_DEFAULTWIN))
935 // side effect: ImplUpdateGlobalSettings does an ImplGetFrame()->UpdateSettings
936 ImplUpdateGlobalSettings( *pSVData->maAppData.mpSettings );
937 OutputDevice::SetSettings( *pSVData->maAppData.mpSettings );
938 pSVData->maAppData.mbSettingsInit = TRUE;
941 // If we create a Window with default size, query this
942 // size directly, because we want resize all Controls to
943 // the correct size before we display the window
944 if ( nStyle & (WB_MOVEABLE | WB_SIZEABLE | WB_APP) )
945 mpWindowImpl->mpFrame->GetClientSize( mnOutWidth, mnOutHeight );
947 else
949 if ( pParent )
951 if ( !ImplIsOverlapWindow() )
953 mpWindowImpl->mbDisabled = pParent->mpWindowImpl->mbDisabled;
954 mpWindowImpl->mbInputDisabled = pParent->mpWindowImpl->mbInputDisabled;
955 mpWindowImpl->meAlwaysInputMode = pParent->mpWindowImpl->meAlwaysInputMode;
958 OutputDevice::SetSettings( pParent->GetSettings() );
963 const StyleSettings& rStyleSettings = maSettings.GetStyleSettings();
964 USHORT nScreenZoom = rStyleSettings.GetScreenZoom();
965 mnDPIX = (mpWindowImpl->mpFrameData->mnDPIX*nScreenZoom)/100;
966 mnDPIY = (mpWindowImpl->mpFrameData->mnDPIY*nScreenZoom)/100;
967 maFont = rStyleSettings.GetAppFont();
968 ImplPointToLogic( maFont );
970 if ( nStyle & WB_3DLOOK )
972 SetTextColor( rStyleSettings.GetButtonTextColor() );
973 SetBackground( Wallpaper( rStyleSettings.GetFaceColor() ) );
975 else
977 SetTextColor( rStyleSettings.GetWindowTextColor() );
978 SetBackground( Wallpaper( rStyleSettings.GetWindowColor() ) );
981 ImplUpdatePos();
983 // calculate app font res (except for the Intro Window or the default window)
984 if ( mpWindowImpl->mbFrame && !pSVData->maGDIData.mnAppFontX && ! (nStyle & (WB_INTROWIN|WB_DEFAULTWIN)) )
985 ImplInitAppFontData( this );
987 if ( GetAccessibleParentWindow() && GetParent() != Application::GetDefDialogParent() )
988 GetAccessibleParentWindow()->ImplCallEventListeners( VCLEVENT_WINDOW_CHILDCREATED, this );
991 // -----------------------------------------------------------------------
993 void Window::ImplSetFrameParent( const Window* pParent )
995 Window* pFrameWindow = ImplGetSVData()->maWinData.mpFirstFrame;
996 while( pFrameWindow )
998 // search all frames that are children of this window
999 // and reparent them
1000 if( ImplIsRealParentPath( pFrameWindow ) )
1002 DBG_ASSERT( mpWindowImpl->mpFrame != pFrameWindow->mpWindowImpl->mpFrame, "SetFrameParent to own" );
1003 DBG_ASSERT( mpWindowImpl->mpFrame, "no frame" );
1004 SalFrame* pParentFrame = pParent ? pParent->mpWindowImpl->mpFrame : NULL;
1005 pFrameWindow->mpWindowImpl->mpFrame->SetParent( pParentFrame );
1007 pFrameWindow = pFrameWindow->mpWindowImpl->mpFrameData->mpNextFrame;
1011 // -----------------------------------------------------------------------
1013 void Window::ImplInsertWindow( Window* pParent )
1015 mpWindowImpl->mpParent = pParent;
1016 mpWindowImpl->mpRealParent = pParent;
1018 if ( pParent && !mpWindowImpl->mbFrame )
1020 // search frame window and set window frame data
1021 Window* pFrameParent = pParent->mpWindowImpl->mpFrameWindow;
1022 mpWindowImpl->mpFrameData = pFrameParent->mpWindowImpl->mpFrameData;
1023 mpWindowImpl->mpFrame = pFrameParent->mpWindowImpl->mpFrame;
1024 mpWindowImpl->mpFrameWindow = pFrameParent;
1025 mpWindowImpl->mbFrame = FALSE;
1027 // search overlap window and insert window in list
1028 if ( ImplIsOverlapWindow() )
1030 Window* pFirstOverlapParent = pParent;
1031 while ( !pFirstOverlapParent->ImplIsOverlapWindow() )
1032 pFirstOverlapParent = pFirstOverlapParent->ImplGetParent();
1033 mpWindowImpl->mpOverlapWindow = pFirstOverlapParent;
1035 mpWindowImpl->mpNextOverlap = mpWindowImpl->mpFrameData->mpFirstOverlap;
1036 mpWindowImpl->mpFrameData->mpFirstOverlap = this;
1038 // Overlap-Windows sind per default die obersten
1039 mpWindowImpl->mpNext = pFirstOverlapParent->mpWindowImpl->mpFirstOverlap;
1040 pFirstOverlapParent->mpWindowImpl->mpFirstOverlap = this;
1041 if ( !pFirstOverlapParent->mpWindowImpl->mpLastOverlap )
1042 pFirstOverlapParent->mpWindowImpl->mpLastOverlap = this;
1043 else
1044 mpWindowImpl->mpNext->mpWindowImpl->mpPrev = this;
1046 else
1048 if ( pParent->ImplIsOverlapWindow() )
1049 mpWindowImpl->mpOverlapWindow = pParent;
1050 else
1051 mpWindowImpl->mpOverlapWindow = pParent->mpWindowImpl->mpOverlapWindow;
1052 mpWindowImpl->mpPrev = pParent->mpWindowImpl->mpLastChild;
1053 pParent->mpWindowImpl->mpLastChild = this;
1054 if ( !pParent->mpWindowImpl->mpFirstChild )
1055 pParent->mpWindowImpl->mpFirstChild = this;
1056 else
1057 mpWindowImpl->mpPrev->mpWindowImpl->mpNext = this;
1062 // -----------------------------------------------------------------------
1064 void Window::ImplRemoveWindow( BOOL bRemoveFrameData )
1066 // Fenster aus den Listen austragen
1067 if ( !mpWindowImpl->mbFrame )
1069 if ( ImplIsOverlapWindow() )
1071 if ( mpWindowImpl->mpFrameData->mpFirstOverlap == this )
1072 mpWindowImpl->mpFrameData->mpFirstOverlap = mpWindowImpl->mpNextOverlap;
1073 else
1075 Window* pTempWin = mpWindowImpl->mpFrameData->mpFirstOverlap;
1076 while ( pTempWin->mpWindowImpl->mpNextOverlap != this )
1077 pTempWin = pTempWin->mpWindowImpl->mpNextOverlap;
1078 pTempWin->mpWindowImpl->mpNextOverlap = mpWindowImpl->mpNextOverlap;
1081 if ( mpWindowImpl->mpPrev )
1082 mpWindowImpl->mpPrev->mpWindowImpl->mpNext = mpWindowImpl->mpNext;
1083 else
1084 mpWindowImpl->mpOverlapWindow->mpWindowImpl->mpFirstOverlap = mpWindowImpl->mpNext;
1085 if ( mpWindowImpl->mpNext )
1086 mpWindowImpl->mpNext->mpWindowImpl->mpPrev = mpWindowImpl->mpPrev;
1087 else
1088 mpWindowImpl->mpOverlapWindow->mpWindowImpl->mpLastOverlap = mpWindowImpl->mpPrev;
1090 else
1092 if ( mpWindowImpl->mpPrev )
1093 mpWindowImpl->mpPrev->mpWindowImpl->mpNext = mpWindowImpl->mpNext;
1094 else
1095 mpWindowImpl->mpParent->mpWindowImpl->mpFirstChild = mpWindowImpl->mpNext;
1096 if ( mpWindowImpl->mpNext )
1097 mpWindowImpl->mpNext->mpWindowImpl->mpPrev = mpWindowImpl->mpPrev;
1098 else
1099 mpWindowImpl->mpParent->mpWindowImpl->mpLastChild = mpWindowImpl->mpPrev;
1102 mpWindowImpl->mpPrev = NULL;
1103 mpWindowImpl->mpNext = NULL;
1106 if ( bRemoveFrameData )
1108 // Graphic freigeben
1109 ImplReleaseGraphics();
1113 // -----------------------------------------------------------------------
1115 void Window::ImplCallResize()
1117 mpWindowImpl->mbCallResize = FALSE;
1119 if( GetBackground().IsGradient() )
1120 Invalidate();
1122 Resize();
1124 // #88419# Most classes don't call the base class in Resize() and Move(),
1125 // => Call ImpleResize/Move instead of Resize/Move directly...
1126 ImplCallEventListeners( VCLEVENT_WINDOW_RESIZE );
1129 // -----------------------------------------------------------------------
1131 void Window::ImplCallMove()
1133 mpWindowImpl->mbCallMove = FALSE;
1135 if( mpWindowImpl->mbFrame )
1137 // update frame position
1138 SalFrame *pParentFrame = NULL;
1139 Window *pParent = ImplGetParent();
1140 while( pParent )
1142 if( pParent->mpWindowImpl->mpFrame != mpWindowImpl->mpFrame )
1144 pParentFrame = pParent->mpWindowImpl->mpFrame;
1145 break;
1147 pParent = pParent->GetParent();
1150 SalFrameGeometry g = mpWindowImpl->mpFrame->GetGeometry();
1151 mpWindowImpl->maPos = Point( g.nX, g.nY );
1152 if( pParentFrame )
1154 g = pParentFrame->GetGeometry();
1155 mpWindowImpl->maPos -= Point( g.nX, g.nY );
1157 // the client window and and all its subclients have the same position as the borderframe
1158 // this is important for floating toolbars where the borderwindow is a floating window
1159 // which has another borderwindow (ie the system floating window)
1160 Window *pClientWin = mpWindowImpl->mpClientWindow;
1161 while( pClientWin )
1163 pClientWin->mpWindowImpl->maPos = mpWindowImpl->maPos;
1164 pClientWin = pClientWin->mpWindowImpl->mpClientWindow;
1168 Move();
1170 ImplCallEventListeners( VCLEVENT_WINDOW_MOVE );
1173 // -----------------------------------------------------------------------
1175 static ULONG ImplAutoHelpID( ResMgr* pResMgr )
1177 if ( !Application::IsAutoHelpIdEnabled() )
1178 return 0;
1180 ULONG nHID = 0;
1182 DBG_ASSERT( pResMgr, "No res mgr for auto help id" );
1183 if( ! pResMgr )
1184 return 0;
1186 nHID = pResMgr->GetAutoHelpId();
1188 return nHID;
1191 // -----------------------------------------------------------------------
1193 WinBits Window::ImplInitRes( const ResId& rResId )
1195 GetRes( rResId );
1197 char* pRes = (char*)GetClassRes();
1198 pRes += 8;
1199 sal_uInt32 nStyle = (sal_uInt32)GetLongRes( (void*)pRes );
1200 rResId.SetWinBits( nStyle );
1201 return nStyle;
1204 // -----------------------------------------------------------------------
1206 void Window::ImplLoadRes( const ResId& rResId )
1208 // newer move this line after IncrementRes
1209 char* pRes = (char*)GetClassRes();
1210 pRes += 12;
1211 sal_uInt32 nHelpId = (sal_uInt32)GetLongRes( (void*)pRes );
1212 if ( !nHelpId )
1213 nHelpId = ImplAutoHelpID( rResId.GetResMgr() );
1214 SetHelpId( nHelpId );
1216 ULONG nObjMask = ReadLongRes();
1218 // ResourceStyle
1219 ULONG nRSStyle = ReadLongRes();
1220 // WinBits
1221 ReadLongRes();
1222 // HelpId
1223 ReadLongRes();
1225 BOOL bPos = FALSE;
1226 BOOL bSize = FALSE;
1227 Point aPos;
1228 Size aSize;
1230 if ( nObjMask & (WINDOW_XYMAPMODE | WINDOW_X | WINDOW_Y) )
1232 // Groessenangabe aus der Resource verwenden
1233 MapUnit ePosMap = MAP_PIXEL;
1235 bPos = TRUE;
1237 if ( nObjMask & WINDOW_XYMAPMODE )
1238 ePosMap = (MapUnit)ReadLongRes();
1239 if ( nObjMask & WINDOW_X )
1240 aPos.X() = ImplLogicUnitToPixelX( ReadLongRes(), ePosMap );
1241 if ( nObjMask & WINDOW_Y )
1242 aPos.Y() = ImplLogicUnitToPixelY( ReadLongRes(), ePosMap );
1245 if ( nObjMask & (WINDOW_WHMAPMODE | WINDOW_WIDTH | WINDOW_HEIGHT) )
1247 // Groessenangabe aus der Resource verwenden
1248 MapUnit eSizeMap = MAP_PIXEL;
1250 bSize = TRUE;
1252 if ( nObjMask & WINDOW_WHMAPMODE )
1253 eSizeMap = (MapUnit)ReadLongRes();
1254 if ( nObjMask & WINDOW_WIDTH )
1255 aSize.Width() = ImplLogicUnitToPixelX( ReadLongRes(), eSizeMap );
1256 if ( nObjMask & WINDOW_HEIGHT )
1257 aSize.Height() = ImplLogicUnitToPixelY( ReadLongRes(), eSizeMap );
1260 // Wegen Optimierung so schlimm aussehend
1261 if ( nRSStyle & RSWND_CLIENTSIZE )
1263 if ( bPos )
1264 SetPosPixel( aPos );
1265 if ( bSize )
1266 SetOutputSizePixel( aSize );
1268 else if ( bPos && bSize )
1269 SetPosSizePixel( aPos, aSize );
1270 else if ( bPos )
1271 SetPosPixel( aPos );
1272 else if ( bSize )
1273 SetSizePixel( aSize );
1275 if ( nRSStyle & RSWND_DISABLED )
1276 Enable( FALSE );
1278 if ( nObjMask & WINDOW_TEXT )
1279 SetText( ReadStringRes() );
1280 if ( nObjMask & WINDOW_HELPTEXT )
1281 SetHelpText( ReadStringRes() );
1282 if ( nObjMask & WINDOW_QUICKTEXT )
1283 SetQuickHelpText( ReadStringRes() );
1284 if ( nObjMask & WINDOW_EXTRALONG )
1285 SetData( (void*)ReadLongRes() );
1286 if ( nObjMask & WINDOW_UNIQUEID )
1287 SetUniqueId( (ULONG)ReadLongRes() );
1289 if ( nObjMask & WINDOW_BORDER_STYLE )
1291 USHORT nBorderStyle = (USHORT)ReadLongRes();
1292 SetBorderStyle( nBorderStyle );
1296 // -----------------------------------------------------------------------
1298 ImplWinData* Window::ImplGetWinData() const
1300 if ( !mpWindowImpl->mpWinData )
1302 static const char* pNoNWF = getenv( "SAL_NO_NWF" );
1304 ((Window*)this)->mpWindowImpl->mpWinData = new ImplWinData;
1305 mpWindowImpl->mpWinData->mpExtOldText = NULL;
1306 mpWindowImpl->mpWinData->mpExtOldAttrAry = NULL;
1307 mpWindowImpl->mpWinData->mpCursorRect = 0;
1308 mpWindowImpl->mpWinData->mnCursorExtWidth = 0;
1309 mpWindowImpl->mpWinData->mpFocusRect = NULL;
1310 mpWindowImpl->mpWinData->mpTrackRect = NULL;
1311 mpWindowImpl->mpWinData->mnTrackFlags = 0;
1312 mpWindowImpl->mpWinData->mnIsTopWindow = (USHORT) ~0; // not initialized yet, 0/1 will indicate TopWindow (see IsTopWindow())
1313 mpWindowImpl->mpWinData->mbMouseOver = FALSE;
1314 mpWindowImpl->mpWinData->mbEnableNativeWidget = (pNoNWF && *pNoNWF) ? FALSE : TRUE; // TRUE: try to draw this control with native theme API
1315 mpWindowImpl->mpWinData->mpSalControlHandle = NULL;
1316 mpWindowImpl->mpWinData->mpSmartHelpId = NULL;
1317 mpWindowImpl->mpWinData->mpSmartUniqueId = NULL;
1320 return mpWindowImpl->mpWinData;
1323 // -----------------------------------------------------------------------
1325 SalGraphics* Window::ImplGetFrameGraphics() const
1327 if ( mpWindowImpl->mpFrameWindow->mpGraphics )
1328 mpWindowImpl->mpFrameWindow->mbInitClipRegion = TRUE;
1329 else
1330 mpWindowImpl->mpFrameWindow->ImplGetGraphics();
1331 mpWindowImpl->mpFrameWindow->mpGraphics->ResetClipRegion();
1332 return mpWindowImpl->mpFrameWindow->mpGraphics;
1335 // -----------------------------------------------------------------------
1337 Window* Window::ImplFindWindow( const Point& rFramePos )
1339 DBG_CHKTHIS( Window, ImplDbgCheckWindow );
1341 Window* pTempWindow;
1342 Window* pFindWindow;
1344 // Zuerst alle ueberlappenden Fenster ueberpruefen
1345 pTempWindow = mpWindowImpl->mpFirstOverlap;
1346 while ( pTempWindow )
1348 pFindWindow = pTempWindow->ImplFindWindow( rFramePos );
1349 if ( pFindWindow )
1350 return pFindWindow;
1351 pTempWindow = pTempWindow->mpWindowImpl->mpNext;
1354 // dann testen wir unser Fenster
1355 if ( !mpWindowImpl->mbVisible )
1356 return NULL;
1358 USHORT nHitTest = ImplHitTest( rFramePos );
1359 if ( nHitTest & WINDOW_HITTEST_INSIDE )
1361 // und danach gehen wir noch alle Child-Fenster durch
1362 pTempWindow = mpWindowImpl->mpFirstChild;
1363 while ( pTempWindow )
1365 pFindWindow = pTempWindow->ImplFindWindow( rFramePos );
1366 if ( pFindWindow )
1367 return pFindWindow;
1368 pTempWindow = pTempWindow->mpWindowImpl->mpNext;
1371 if ( nHitTest & WINDOW_HITTEST_TRANSPARENT )
1372 return NULL;
1373 else
1374 return this;
1377 return NULL;
1380 // -----------------------------------------------------------------------
1382 USHORT Window::ImplHitTest( const Point& rFramePos )
1384 Point aFramePos( rFramePos );
1385 if( ImplIsAntiparallel() )
1387 // - RTL - re-mirror frame pos at this window
1388 ImplReMirror( aFramePos );
1390 Rectangle aRect( Point( mnOutOffX, mnOutOffY ), Size( mnOutWidth, mnOutHeight ) );
1391 if ( !aRect.IsInside( aFramePos ) )
1392 return 0;
1393 if ( mpWindowImpl->mbWinRegion )
1395 Point aTempPos = aFramePos;
1396 aTempPos.X() -= mnOutOffX;
1397 aTempPos.Y() -= mnOutOffY;
1398 if ( !mpWindowImpl->maWinRegion.IsInside( aTempPos ) )
1399 return 0;
1402 USHORT nHitTest = WINDOW_HITTEST_INSIDE;
1403 if ( mpWindowImpl->mbMouseTransparent )
1404 nHitTest |= WINDOW_HITTEST_TRANSPARENT;
1405 return nHitTest;
1408 // -----------------------------------------------------------------------
1410 BOOL Window::ImplIsRealParentPath( const Window* pWindow ) const
1412 pWindow = pWindow->GetParent();
1413 while ( pWindow )
1415 if ( pWindow == this )
1416 return TRUE;
1417 pWindow = pWindow->GetParent();
1420 return FALSE;
1423 // -----------------------------------------------------------------------
1425 BOOL Window::ImplIsChild( const Window* pWindow, BOOL bSystemWindow ) const
1429 if ( !bSystemWindow && pWindow->ImplIsOverlapWindow() )
1430 break;
1432 pWindow = pWindow->ImplGetParent();
1434 if ( pWindow == this )
1435 return TRUE;
1437 while ( pWindow );
1439 return FALSE;
1442 // -----------------------------------------------------------------------
1444 BOOL Window::ImplIsWindowOrChild( const Window* pWindow, BOOL bSystemWindow ) const
1446 if ( this == pWindow )
1447 return TRUE;
1448 return ImplIsChild( pWindow, bSystemWindow );
1451 // -----------------------------------------------------------------------
1453 Window* Window::ImplGetSameParent( const Window* pWindow ) const
1455 if ( mpWindowImpl->mpFrameWindow != pWindow->mpWindowImpl->mpFrameWindow )
1456 return NULL;
1457 else
1459 if ( pWindow->ImplIsChild( this ) )
1460 return (Window*)pWindow;
1461 else
1463 Window* pTestWindow = (Window*)this;
1464 while ( (pTestWindow == pWindow) || pTestWindow->ImplIsChild( pWindow ) )
1465 pTestWindow = pTestWindow->ImplGetParent();
1466 return pTestWindow;
1471 // -----------------------------------------------------------------------
1473 int Window::ImplTestMousePointerSet()
1475 // Wenn Mouse gecaptured ist, dann soll MousePointer umgeschaltet werden
1476 if ( IsMouseCaptured() )
1477 return TRUE;
1479 // Wenn sich Mouse ueber dem Fenster befindet, dann soll MousePointer
1480 // umgeschaltet werden
1481 Rectangle aClientRect( Point( 0, 0 ), GetOutputSizePixel() );
1482 if ( aClientRect.IsInside( GetPointerPosPixel() ) )
1483 return TRUE;
1485 return FALSE;
1488 // -----------------------------------------------------------------------
1490 PointerStyle Window::ImplGetMousePointer() const
1492 PointerStyle ePointerStyle;
1493 BOOL bWait = FALSE;
1495 if ( IsEnabled() && IsInputEnabled() && ! IsInModalMode() )
1496 ePointerStyle = GetPointer().GetStyle();
1497 else
1498 ePointerStyle = POINTER_ARROW;
1500 const Window* pWindow = this;
1503 // Wenn Pointer nicht sichtbar, dann wird suche abgebrochen, da
1504 // dieser Status nicht ueberschrieben werden darf
1505 if ( pWindow->mpWindowImpl->mbNoPtrVisible )
1506 return POINTER_NULL;
1508 if ( !bWait )
1510 if ( pWindow->mpWindowImpl->mnWaitCount )
1512 ePointerStyle = POINTER_WAIT;
1513 bWait = TRUE;
1515 else
1517 if ( pWindow->mpWindowImpl->mbChildPtrOverwrite )
1518 ePointerStyle = pWindow->GetPointer().GetStyle();
1522 if ( pWindow->ImplIsOverlapWindow() )
1523 break;
1525 pWindow = pWindow->ImplGetParent();
1527 while ( pWindow );
1529 return ePointerStyle;
1532 // -----------------------------------------------------------------------
1534 void Window::ImplResetReallyVisible()
1536 BOOL bBecameReallyInvisible = mpWindowImpl->mbReallyVisible;
1538 mbDevOutput = FALSE;
1539 mpWindowImpl->mbReallyVisible = FALSE;
1540 mpWindowImpl->mbReallyShown = FALSE;
1542 // the SHOW/HIDE events serve as indicators to send child creation/destroy events to the access bridge.
1543 // For this, the data member of the event must not be NULL.
1544 // Previously, we did this in Window::Show, but there some events got lost in certain situations.
1545 // #104887# - 2004-08-10 - fs@openoffice.org
1546 if( bBecameReallyInvisible && ImplIsAccessibleCandidate() )
1547 ImplCallEventListeners( VCLEVENT_WINDOW_HIDE, this );
1548 // TODO. It's kind of a hack that we're re-using the VCLEVENT_WINDOW_HIDE. Normally, we should
1549 // introduce another event which explicitly triggers the Accessibility implementations.
1551 Window* pWindow = mpWindowImpl->mpFirstOverlap;
1552 while ( pWindow )
1554 if ( pWindow->mpWindowImpl->mbReallyVisible )
1555 pWindow->ImplResetReallyVisible();
1556 pWindow = pWindow->mpWindowImpl->mpNext;
1559 pWindow = mpWindowImpl->mpFirstChild;
1560 while ( pWindow )
1562 if ( pWindow->mpWindowImpl->mbReallyVisible )
1563 pWindow->ImplResetReallyVisible();
1564 pWindow = pWindow->mpWindowImpl->mpNext;
1568 // -----------------------------------------------------------------------
1570 void Window::ImplSetReallyVisible()
1572 // #i43594# it is possible that INITSHOW was never send, because the visibility state changed between
1573 // ImplCallInitShow() and ImplSetReallyVisible() when called from Show()
1574 // mbReallyShown is a useful indicator
1575 if( !mpWindowImpl->mbReallyShown )
1576 ImplCallInitShow();
1578 BOOL bBecameReallyVisible = !mpWindowImpl->mbReallyVisible;
1580 mbDevOutput = TRUE;
1581 mpWindowImpl->mbReallyVisible = TRUE;
1582 mpWindowImpl->mbReallyShown = TRUE;
1584 // the SHOW/HIDE events serve as indicators to send child creation/destroy events to the access bridge.
1585 // For this, the data member of the event must not be NULL.
1586 // Previously, we did this in Window::Show, but there some events got lost in certain situations. Now
1587 // we're doing it when the visibility really changes
1588 // #104887# - 2004-08-10 - fs@openoffice.org
1589 if( bBecameReallyVisible && ImplIsAccessibleCandidate() )
1590 ImplCallEventListeners( VCLEVENT_WINDOW_SHOW, this );
1591 // TODO. It's kind of a hack that we're re-using the VCLEVENT_WINDOW_SHOW. Normally, we should
1592 // introduce another event which explicitly triggers the Accessibility implementations.
1594 Window* pWindow = mpWindowImpl->mpFirstOverlap;
1595 while ( pWindow )
1597 if ( pWindow->mpWindowImpl->mbVisible )
1598 pWindow->ImplSetReallyVisible();
1599 pWindow = pWindow->mpWindowImpl->mpNext;
1602 pWindow = mpWindowImpl->mpFirstChild;
1603 while ( pWindow )
1605 if ( pWindow->mpWindowImpl->mbVisible )
1606 pWindow->ImplSetReallyVisible();
1607 pWindow = pWindow->mpWindowImpl->mpNext;
1611 // -----------------------------------------------------------------------
1613 void Window::ImplCallInitShow()
1615 mpWindowImpl->mbReallyShown = TRUE;
1616 mpWindowImpl->mbInInitShow = TRUE;
1617 StateChanged( STATE_CHANGE_INITSHOW );
1618 mpWindowImpl->mbInInitShow = FALSE;
1620 Window* pWindow = mpWindowImpl->mpFirstOverlap;
1621 while ( pWindow )
1623 if ( pWindow->mpWindowImpl->mbVisible )
1624 pWindow->ImplCallInitShow();
1625 pWindow = pWindow->mpWindowImpl->mpNext;
1628 pWindow = mpWindowImpl->mpFirstChild;
1629 while ( pWindow )
1631 if ( pWindow->mpWindowImpl->mbVisible )
1632 pWindow->ImplCallInitShow();
1633 pWindow = pWindow->mpWindowImpl->mpNext;
1637 // -----------------------------------------------------------------------
1639 void Window::ImplAddDel( ImplDelData* pDel ) // TODO: make "const" when incompatiblity ok
1641 DBG_ASSERT( !pDel->mpWindow, "Window::ImplAddDel(): cannot add ImplDelData twice !" );
1642 if( !pDel->mpWindow )
1644 pDel->mpWindow = this; // #112873# store ref to this window, so pDel can remove itself
1645 pDel->mpNext = mpWindowImpl->mpFirstDel;
1646 mpWindowImpl->mpFirstDel = pDel;
1650 // -----------------------------------------------------------------------
1652 void Window::ImplRemoveDel( ImplDelData* pDel ) // TODO: make "const" when incompatiblity ok
1654 pDel->mpWindow = NULL; // #112873# pDel is not associated with a Window anymore
1655 if ( mpWindowImpl->mpFirstDel == pDel )
1656 mpWindowImpl->mpFirstDel = pDel->mpNext;
1657 else
1659 ImplDelData* pData = mpWindowImpl->mpFirstDel;
1660 while ( pData->mpNext != pDel )
1661 pData = pData->mpNext;
1662 pData->mpNext = pDel->mpNext;
1666 // -----------------------------------------------------------------------
1668 void Window::ImplInitResolutionSettings()
1670 // AppFont-Aufloesung und DPI-Aufloesung neu berechnen
1671 if ( mpWindowImpl->mbFrame )
1673 const StyleSettings& rStyleSettings = maSettings.GetStyleSettings();
1674 USHORT nScreenZoom = rStyleSettings.GetScreenZoom();
1675 mnDPIX = (mpWindowImpl->mpFrameData->mnDPIX*nScreenZoom)/100;
1676 mnDPIY = (mpWindowImpl->mpFrameData->mnDPIY*nScreenZoom)/100;
1677 SetPointFont( rStyleSettings.GetAppFont() );
1679 else if ( mpWindowImpl->mpParent )
1681 mnDPIX = mpWindowImpl->mpParent->mnDPIX;
1682 mnDPIY = mpWindowImpl->mpParent->mnDPIY;
1685 // Vorberechnete Werte fuer logische Einheiten updaten und auch
1686 // die entsprechenden Tools dazu
1687 if ( IsMapMode() )
1689 MapMode aMapMode = GetMapMode();
1690 SetMapMode();
1691 SetMapMode( aMapMode );
1695 // -----------------------------------------------------------------------
1697 void Window::ImplPointToLogic( Font& rFont ) const
1699 Size aSize = rFont.GetSize();
1700 USHORT nScreenFontZoom = maSettings.GetStyleSettings().GetScreenFontZoom();
1702 if ( aSize.Width() )
1704 aSize.Width() *= mpWindowImpl->mpFrameData->mnDPIX;
1705 aSize.Width() += 72/2;
1706 aSize.Width() /= 72;
1707 aSize.Width() *= nScreenFontZoom;
1708 aSize.Width() /= 100;
1710 aSize.Height() *= mpWindowImpl->mpFrameData->mnDPIY;
1711 aSize.Height() += 72/2;
1712 aSize.Height() /= 72;
1713 aSize.Height() *= nScreenFontZoom;
1714 aSize.Height() /= 100;
1716 if ( IsMapModeEnabled() )
1717 aSize = PixelToLogic( aSize );
1719 rFont.SetSize( aSize );
1722 // -----------------------------------------------------------------------
1724 void Window::ImplLogicToPoint( Font& rFont ) const
1726 Size aSize = rFont.GetSize();
1727 USHORT nScreenFontZoom = maSettings.GetStyleSettings().GetScreenFontZoom();
1729 if ( IsMapModeEnabled() )
1730 aSize = LogicToPixel( aSize );
1732 if ( aSize.Width() )
1734 aSize.Width() *= 100;
1735 aSize.Width() /= nScreenFontZoom;
1736 aSize.Width() *= 72;
1737 aSize.Width() += mpWindowImpl->mpFrameData->mnDPIX/2;
1738 aSize.Width() /= mpWindowImpl->mpFrameData->mnDPIX;
1740 aSize.Height() *= 100;
1741 aSize.Height() /= nScreenFontZoom;
1742 aSize.Height() *= 72;
1743 aSize.Height() += mpWindowImpl->mpFrameData->mnDPIY/2;
1744 aSize.Height() /= mpWindowImpl->mpFrameData->mnDPIY;
1746 rFont.SetSize( aSize );
1749 // -----------------------------------------------------------------------
1751 BOOL Window::ImplSysObjClip( const Region* pOldRegion )
1753 BOOL bUpdate = TRUE;
1755 if ( mpWindowImpl->mpSysObj )
1757 BOOL bVisibleState = mpWindowImpl->mbReallyVisible;
1759 if ( bVisibleState )
1761 Region* pWinChildClipRegion = ImplGetWinChildClipRegion();
1763 if ( !pWinChildClipRegion->IsEmpty() )
1765 if ( pOldRegion )
1767 Region aNewRegion = *pWinChildClipRegion;
1768 pWinChildClipRegion->Intersect( *pOldRegion );
1769 bUpdate = aNewRegion == *pWinChildClipRegion;
1772 if ( mpWindowImpl->mpFrameData->mpFirstBackWin )
1773 ImplInvalidateAllOverlapBackgrounds();
1775 Region aRegion = *pWinChildClipRegion;
1776 Rectangle aWinRect( Point( mnOutOffX, mnOutOffY ), Size( mnOutWidth, mnOutHeight ) );
1777 Region aWinRectRegion( aWinRect );
1778 USHORT nClipFlags = mpWindowImpl->mpSysObj->GetClipRegionType();
1780 if ( aRegion == aWinRectRegion )
1781 mpWindowImpl->mpSysObj->ResetClipRegion();
1782 else
1784 if ( nClipFlags & SAL_OBJECT_CLIP_EXCLUDERECTS )
1786 aWinRectRegion.Exclude( aRegion );
1787 aRegion = aWinRectRegion;
1789 if ( !(nClipFlags & SAL_OBJECT_CLIP_ABSOLUTE) )
1790 aRegion.Move( -mnOutOffX, -mnOutOffY );
1792 // ClipRegion setzen/updaten
1793 long nX;
1794 long nY;
1795 long nWidth;
1796 long nHeight;
1797 ULONG nRectCount;
1798 ImplRegionInfo aInfo;
1799 BOOL bRegionRect;
1801 nRectCount = aRegion.GetRectCount();
1802 mpWindowImpl->mpSysObj->BeginSetClipRegion( nRectCount );
1803 bRegionRect = aRegion.ImplGetFirstRect( aInfo, nX, nY, nWidth, nHeight );
1804 while ( bRegionRect )
1806 mpWindowImpl->mpSysObj->UnionClipRegion( nX, nY, nWidth, nHeight );
1807 bRegionRect = aRegion.ImplGetNextRect( aInfo, nX, nY, nWidth, nHeight );
1809 mpWindowImpl->mpSysObj->EndSetClipRegion();
1812 else
1813 bVisibleState = FALSE;
1816 // Visible-Status updaten
1817 mpWindowImpl->mpSysObj->Show( bVisibleState );
1820 return bUpdate;
1823 // -----------------------------------------------------------------------
1825 void Window::ImplUpdateSysObjChildsClip()
1827 if ( mpWindowImpl->mpSysObj && mpWindowImpl->mbInitWinClipRegion )
1828 ImplSysObjClip( NULL );
1830 Window* pWindow = mpWindowImpl->mpFirstChild;
1831 while ( pWindow )
1833 pWindow->ImplUpdateSysObjChildsClip();
1834 pWindow = pWindow->mpWindowImpl->mpNext;
1838 // -----------------------------------------------------------------------
1840 void Window::ImplUpdateSysObjOverlapsClip()
1842 ImplUpdateSysObjChildsClip();
1844 Window* pWindow = mpWindowImpl->mpFirstOverlap;
1845 while ( pWindow )
1847 pWindow->ImplUpdateSysObjOverlapsClip();
1848 pWindow = pWindow->mpWindowImpl->mpNext;
1852 // -----------------------------------------------------------------------
1854 void Window::ImplUpdateSysObjClip()
1856 if ( !ImplIsOverlapWindow() )
1858 ImplUpdateSysObjChildsClip();
1860 // Schwestern muessen ihre ClipRegion auch neu berechnen
1861 if ( mpWindowImpl->mbClipSiblings )
1863 Window* pWindow = mpWindowImpl->mpNext;
1864 while ( pWindow )
1866 pWindow->ImplUpdateSysObjChildsClip();
1867 pWindow = pWindow->mpWindowImpl->mpNext;
1871 else
1872 mpWindowImpl->mpFrameWindow->ImplUpdateSysObjOverlapsClip();
1875 // -----------------------------------------------------------------------
1877 BOOL Window::ImplSetClipFlagChilds( BOOL bSysObjOnlySmaller )
1879 BOOL bUpdate = TRUE;
1880 if ( mpWindowImpl->mpSysObj )
1882 Region* pOldRegion = NULL;
1883 if ( bSysObjOnlySmaller && !mpWindowImpl->mbInitWinClipRegion )
1884 pOldRegion = new Region( mpWindowImpl->maWinClipRegion );
1886 mbInitClipRegion = TRUE;
1887 mpWindowImpl->mbInitWinClipRegion = TRUE;
1889 Window* pWindow = mpWindowImpl->mpFirstChild;
1890 while ( pWindow )
1892 if ( !pWindow->ImplSetClipFlagChilds( bSysObjOnlySmaller ) )
1893 bUpdate = FALSE;
1894 pWindow = pWindow->mpWindowImpl->mpNext;
1897 if ( !ImplSysObjClip( pOldRegion ) )
1899 mbInitClipRegion = TRUE;
1900 mpWindowImpl->mbInitWinClipRegion = TRUE;
1901 bUpdate = FALSE;
1904 if ( pOldRegion )
1905 delete pOldRegion;
1907 else
1909 mbInitClipRegion = TRUE;
1910 mpWindowImpl->mbInitWinClipRegion = TRUE;
1912 Window* pWindow = mpWindowImpl->mpFirstChild;
1913 while ( pWindow )
1915 if ( !pWindow->ImplSetClipFlagChilds( bSysObjOnlySmaller ) )
1916 bUpdate = FALSE;
1917 pWindow = pWindow->mpWindowImpl->mpNext;
1920 return bUpdate;
1923 // -----------------------------------------------------------------------
1925 BOOL Window::ImplSetClipFlagOverlapWindows( BOOL bSysObjOnlySmaller )
1927 BOOL bUpdate = ImplSetClipFlagChilds( bSysObjOnlySmaller );
1929 Window* pWindow = mpWindowImpl->mpFirstOverlap;
1930 while ( pWindow )
1932 if ( !pWindow->ImplSetClipFlagOverlapWindows( bSysObjOnlySmaller ) )
1933 bUpdate = FALSE;
1934 pWindow = pWindow->mpWindowImpl->mpNext;
1937 return bUpdate;
1940 // -----------------------------------------------------------------------
1942 BOOL Window::ImplSetClipFlag( BOOL bSysObjOnlySmaller )
1944 if ( !ImplIsOverlapWindow() )
1946 BOOL bUpdate = ImplSetClipFlagChilds( bSysObjOnlySmaller );
1948 Window* pParent = ImplGetParent();
1949 if ( pParent &&
1950 ((pParent->GetStyle() & WB_CLIPCHILDREN) || (mpWindowImpl->mnParentClipMode & PARENTCLIPMODE_CLIP)) )
1952 pParent->mbInitClipRegion = TRUE;
1953 pParent->mpWindowImpl->mbInitChildRegion = TRUE;
1956 // Schwestern muessen ihre ClipRegion auch neu berechnen
1957 if ( mpWindowImpl->mbClipSiblings )
1959 Window* pWindow = mpWindowImpl->mpNext;
1960 while ( pWindow )
1962 if ( !pWindow->ImplSetClipFlagChilds( bSysObjOnlySmaller ) )
1963 bUpdate = FALSE;
1964 pWindow = pWindow->mpWindowImpl->mpNext;
1968 return bUpdate;
1970 else
1971 return mpWindowImpl->mpFrameWindow->ImplSetClipFlagOverlapWindows( bSysObjOnlySmaller );
1974 // -----------------------------------------------------------------------
1976 void Window::ImplIntersectWindowClipRegion( Region& rRegion )
1978 if ( mpWindowImpl->mbInitWinClipRegion )
1979 ImplInitWinClipRegion();
1981 rRegion.Intersect( mpWindowImpl->maWinClipRegion );
1984 // -----------------------------------------------------------------------
1986 void Window::ImplIntersectWindowRegion( Region& rRegion )
1988 rRegion.Intersect( Rectangle( Point( mnOutOffX, mnOutOffY ),
1989 Size( mnOutWidth, mnOutHeight ) ) );
1990 if ( mpWindowImpl->mbWinRegion )
1991 rRegion.Intersect( ImplPixelToDevicePixel( mpWindowImpl->maWinRegion ) );
1994 // -----------------------------------------------------------------------
1996 void Window::ImplExcludeWindowRegion( Region& rRegion )
1998 if ( mpWindowImpl->mbWinRegion )
2000 Point aPoint( mnOutOffX, mnOutOffY );
2001 Region aRegion( Rectangle( aPoint,
2002 Size( mnOutWidth, mnOutHeight ) ) );
2003 aRegion.Intersect( ImplPixelToDevicePixel( mpWindowImpl->maWinRegion ) );
2004 rRegion.Exclude( aRegion );
2006 else
2008 Point aPoint( mnOutOffX, mnOutOffY );
2009 rRegion.Exclude( Rectangle( aPoint,
2010 Size( mnOutWidth, mnOutHeight ) ) );
2014 // -----------------------------------------------------------------------
2016 void Window::ImplExcludeOverlapWindows( Region& rRegion )
2018 Window* pWindow = mpWindowImpl->mpFirstOverlap;
2019 while ( pWindow )
2021 if ( pWindow->mpWindowImpl->mbReallyVisible )
2023 pWindow->ImplExcludeWindowRegion( rRegion );
2024 pWindow->ImplExcludeOverlapWindows( rRegion );
2027 pWindow = pWindow->mpWindowImpl->mpNext;
2031 // -----------------------------------------------------------------------
2033 void Window::ImplExcludeOverlapWindows2( Region& rRegion )
2035 if ( mpWindowImpl->mbReallyVisible )
2036 ImplExcludeWindowRegion( rRegion );
2038 ImplExcludeOverlapWindows( rRegion );
2041 // -----------------------------------------------------------------------
2043 void Window::ImplClipBoundaries( Region& rRegion, BOOL bThis, BOOL bOverlaps )
2045 if ( bThis )
2046 ImplIntersectWindowClipRegion( rRegion );
2047 else if ( ImplIsOverlapWindow() )
2049 // Evt. noch am Frame clippen
2050 if ( !mpWindowImpl->mbFrame )
2051 rRegion.Intersect( Rectangle( Point( 0, 0 ), Size( mpWindowImpl->mpFrameWindow->mnOutWidth, mpWindowImpl->mpFrameWindow->mnOutHeight ) ) );
2053 if ( bOverlaps && !rRegion.IsEmpty() )
2055 // Clip Overlap Siblings
2056 Window* pStartOverlapWindow = this;
2057 while ( !pStartOverlapWindow->mpWindowImpl->mbFrame )
2059 Window* pOverlapWindow = pStartOverlapWindow->mpWindowImpl->mpOverlapWindow->mpWindowImpl->mpFirstOverlap;
2060 while ( pOverlapWindow && (pOverlapWindow != pStartOverlapWindow) )
2062 pOverlapWindow->ImplExcludeOverlapWindows2( rRegion );
2063 pOverlapWindow = pOverlapWindow->mpWindowImpl->mpNext;
2065 pStartOverlapWindow = pStartOverlapWindow->mpWindowImpl->mpOverlapWindow;
2068 // Clip Child Overlap Windows
2069 ImplExcludeOverlapWindows( rRegion );
2072 else
2073 ImplGetParent()->ImplIntersectWindowClipRegion( rRegion );
2076 // -----------------------------------------------------------------------
2078 BOOL Window::ImplClipChilds( Region& rRegion )
2080 BOOL bOtherClip = FALSE;
2081 Window* pWindow = mpWindowImpl->mpFirstChild;
2082 while ( pWindow )
2084 if ( pWindow->mpWindowImpl->mbReallyVisible )
2086 // ParentClipMode-Flags auswerten
2087 USHORT nClipMode = pWindow->GetParentClipMode();
2088 if ( !(nClipMode & PARENTCLIPMODE_NOCLIP) &&
2089 ((nClipMode & PARENTCLIPMODE_CLIP) || (GetStyle() & WB_CLIPCHILDREN)) )
2090 pWindow->ImplExcludeWindowRegion( rRegion );
2091 else
2092 bOtherClip = TRUE;
2095 pWindow = pWindow->mpWindowImpl->mpNext;
2098 return bOtherClip;
2101 // -----------------------------------------------------------------------
2103 void Window::ImplClipAllChilds( Region& rRegion )
2105 Window* pWindow = mpWindowImpl->mpFirstChild;
2106 while ( pWindow )
2108 if ( pWindow->mpWindowImpl->mbReallyVisible )
2109 pWindow->ImplExcludeWindowRegion( rRegion );
2110 pWindow = pWindow->mpWindowImpl->mpNext;
2114 // -----------------------------------------------------------------------
2116 void Window::ImplClipSiblings( Region& rRegion )
2118 Window* pWindow = ImplGetParent()->mpWindowImpl->mpFirstChild;
2119 while ( pWindow )
2121 if ( pWindow == this )
2122 break;
2124 if ( pWindow->mpWindowImpl->mbReallyVisible )
2125 pWindow->ImplExcludeWindowRegion( rRegion );
2127 pWindow = pWindow->mpWindowImpl->mpNext;
2131 // -----------------------------------------------------------------------
2133 void Window::ImplInitWinClipRegion()
2135 // Build Window Region
2136 mpWindowImpl->maWinClipRegion = Rectangle( Point( mnOutOffX, mnOutOffY ),
2137 Size( mnOutWidth, mnOutHeight ) );
2138 if ( mpWindowImpl->mbWinRegion )
2139 mpWindowImpl->maWinClipRegion.Intersect( ImplPixelToDevicePixel( mpWindowImpl->maWinRegion ) );
2141 // ClipSiblings
2142 if ( mpWindowImpl->mbClipSiblings && !ImplIsOverlapWindow() )
2143 ImplClipSiblings( mpWindowImpl->maWinClipRegion );
2145 // Clip Parent Boundaries
2146 ImplClipBoundaries( mpWindowImpl->maWinClipRegion, FALSE, TRUE );
2148 // Clip Children
2149 if ( (GetStyle() & WB_CLIPCHILDREN) || mpWindowImpl->mbClipChildren )
2150 mpWindowImpl->mbInitChildRegion = TRUE;
2152 mpWindowImpl->mbInitWinClipRegion = FALSE;
2155 // -----------------------------------------------------------------------
2157 void Window::ImplInitWinChildClipRegion()
2159 if ( !mpWindowImpl->mpFirstChild )
2161 if ( mpWindowImpl->mpChildClipRegion )
2163 delete mpWindowImpl->mpChildClipRegion;
2164 mpWindowImpl->mpChildClipRegion = NULL;
2167 else
2169 if ( !mpWindowImpl->mpChildClipRegion )
2170 mpWindowImpl->mpChildClipRegion = new Region( mpWindowImpl->maWinClipRegion );
2171 else
2172 *mpWindowImpl->mpChildClipRegion = mpWindowImpl->maWinClipRegion;
2174 ImplClipChilds( *mpWindowImpl->mpChildClipRegion );
2177 mpWindowImpl->mbInitChildRegion = FALSE;
2180 // -----------------------------------------------------------------------
2182 Region* Window::ImplGetWinChildClipRegion()
2184 if ( mpWindowImpl->mbInitWinClipRegion )
2185 ImplInitWinClipRegion();
2186 if ( mpWindowImpl->mbInitChildRegion )
2187 ImplInitWinChildClipRegion();
2188 if ( mpWindowImpl->mpChildClipRegion )
2189 return mpWindowImpl->mpChildClipRegion;
2190 else
2191 return &mpWindowImpl->maWinClipRegion;
2194 // -----------------------------------------------------------------------
2196 void Window::ImplIntersectAndUnionOverlapWindows( const Region& rInterRegion, Region& rRegion )
2198 Window* pWindow = mpWindowImpl->mpFirstOverlap;
2199 while ( pWindow )
2201 if ( pWindow->mpWindowImpl->mbReallyVisible )
2203 Region aTempRegion( rInterRegion );
2204 pWindow->ImplIntersectWindowRegion( aTempRegion );
2205 rRegion.Union( aTempRegion );
2206 pWindow->ImplIntersectAndUnionOverlapWindows( rInterRegion, rRegion );
2209 pWindow = pWindow->mpWindowImpl->mpNext;
2213 // -----------------------------------------------------------------------
2215 void Window::ImplIntersectAndUnionOverlapWindows2( const Region& rInterRegion, Region& rRegion )
2217 if ( mpWindowImpl->mbReallyVisible )
2219 Region aTempRegion( rInterRegion );
2220 ImplIntersectWindowRegion( aTempRegion );
2221 rRegion.Union( aTempRegion );
2224 ImplIntersectAndUnionOverlapWindows( rInterRegion, rRegion );
2227 // -----------------------------------------------------------------------
2229 void Window::ImplCalcOverlapRegionOverlaps( const Region& rInterRegion, Region& rRegion )
2231 // Clip Overlap Siblings
2232 Window* pStartOverlapWindow;
2233 if ( !ImplIsOverlapWindow() )
2234 pStartOverlapWindow = mpWindowImpl->mpOverlapWindow;
2235 else
2236 pStartOverlapWindow = this;
2237 while ( !pStartOverlapWindow->mpWindowImpl->mbFrame )
2239 Window* pOverlapWindow = pStartOverlapWindow->mpWindowImpl->mpOverlapWindow->mpWindowImpl->mpFirstOverlap;
2240 while ( pOverlapWindow && (pOverlapWindow != pStartOverlapWindow) )
2242 pOverlapWindow->ImplIntersectAndUnionOverlapWindows2( rInterRegion, rRegion );
2243 pOverlapWindow = pOverlapWindow->mpWindowImpl->mpNext;
2245 pStartOverlapWindow = pStartOverlapWindow->mpWindowImpl->mpOverlapWindow;
2248 // Clip Child Overlap Windows
2249 if ( !ImplIsOverlapWindow() )
2250 mpWindowImpl->mpOverlapWindow->ImplIntersectAndUnionOverlapWindows( rInterRegion, rRegion );
2251 else
2252 ImplIntersectAndUnionOverlapWindows( rInterRegion, rRegion );
2255 // -----------------------------------------------------------------------
2257 void Window::ImplCalcOverlapRegion( const Rectangle& rSourceRect, Region& rRegion,
2258 BOOL bChilds, BOOL bParent, BOOL bSiblings )
2260 Region aRegion( rSourceRect );
2261 if ( mpWindowImpl->mbWinRegion )
2262 rRegion.Intersect( ImplPixelToDevicePixel( mpWindowImpl->maWinRegion ) );
2263 Region aTempRegion;
2264 Window* pWindow;
2266 ImplCalcOverlapRegionOverlaps( aRegion, rRegion );
2268 // Parent-Boundaries
2269 if ( bParent )
2271 pWindow = this;
2272 if ( !ImplIsOverlapWindow() )
2274 pWindow = ImplGetParent();
2277 aTempRegion = aRegion;
2278 pWindow->ImplExcludeWindowRegion( aTempRegion );
2279 rRegion.Union( aTempRegion );
2280 if ( pWindow->ImplIsOverlapWindow() )
2281 break;
2282 pWindow = pWindow->ImplGetParent();
2284 while ( pWindow );
2286 if ( !pWindow->mpWindowImpl->mbFrame )
2288 aTempRegion = aRegion;
2289 aTempRegion.Exclude( Rectangle( Point( 0, 0 ), Size( mpWindowImpl->mpFrameWindow->mnOutWidth, mpWindowImpl->mpFrameWindow->mnOutHeight ) ) );
2290 rRegion.Union( aTempRegion );
2294 // Siblings
2295 if ( bSiblings && !ImplIsOverlapWindow() )
2297 pWindow = mpWindowImpl->mpParent->mpWindowImpl->mpFirstChild;
2300 if ( pWindow->mpWindowImpl->mbReallyVisible && (pWindow != this) )
2302 aTempRegion = aRegion;
2303 pWindow->ImplIntersectWindowRegion( aTempRegion );
2304 rRegion.Union( aTempRegion );
2306 pWindow = pWindow->mpWindowImpl->mpNext;
2308 while ( pWindow );
2311 // Childs
2312 if ( bChilds )
2314 pWindow = mpWindowImpl->mpFirstChild;
2315 while ( pWindow )
2317 if ( pWindow->mpWindowImpl->mbReallyVisible )
2319 aTempRegion = aRegion;
2320 pWindow->ImplIntersectWindowRegion( aTempRegion );
2321 rRegion.Union( aTempRegion );
2323 pWindow = pWindow->mpWindowImpl->mpNext;
2328 // -----------------------------------------------------------------------
2330 void Window::ImplCallPaint( const Region* pRegion, USHORT nPaintFlags )
2332 // call PrePaint. PrePaint may add to the invalidate region as well as
2333 // other parameters used below.
2334 PrePaint();
2336 mpWindowImpl->mbPaintFrame = FALSE;
2338 if ( nPaintFlags & IMPL_PAINT_PAINTALLCHILDS )
2339 mpWindowImpl->mnPaintFlags |= IMPL_PAINT_PAINT | IMPL_PAINT_PAINTALLCHILDS | (nPaintFlags & IMPL_PAINT_PAINTALL);
2340 if ( nPaintFlags & IMPL_PAINT_PAINTCHILDS )
2341 mpWindowImpl->mnPaintFlags |= IMPL_PAINT_PAINTCHILDS;
2342 if ( nPaintFlags & IMPL_PAINT_ERASE )
2343 mpWindowImpl->mnPaintFlags |= IMPL_PAINT_ERASE;
2344 if ( nPaintFlags & IMPL_PAINT_CHECKRTL )
2345 mpWindowImpl->mnPaintFlags |= IMPL_PAINT_CHECKRTL;
2346 if ( !mpWindowImpl->mpFirstChild )
2347 mpWindowImpl->mnPaintFlags &= ~IMPL_PAINT_PAINTALLCHILDS;
2349 if ( mpWindowImpl->mbPaintDisabled )
2351 if ( mpWindowImpl->mnPaintFlags & IMPL_PAINT_PAINTALL )
2352 Invalidate( INVALIDATE_NOCHILDREN | INVALIDATE_NOERASE | INVALIDATE_NOTRANSPARENT | INVALIDATE_NOCLIPCHILDREN );
2353 else if ( pRegion )
2354 Invalidate( *pRegion, INVALIDATE_NOCHILDREN | INVALIDATE_NOERASE | INVALIDATE_NOTRANSPARENT | INVALIDATE_NOCLIPCHILDREN );
2355 return;
2358 nPaintFlags = mpWindowImpl->mnPaintFlags & ~(IMPL_PAINT_PAINT);
2360 Region* pChildRegion = NULL;
2361 Rectangle aSelectionRect;
2362 if ( mpWindowImpl->mnPaintFlags & IMPL_PAINT_PAINT )
2364 Region* pWinChildClipRegion = ImplGetWinChildClipRegion();
2365 if ( mpWindowImpl->mnPaintFlags & IMPL_PAINT_PAINTALL )
2366 mpWindowImpl->maInvalidateRegion = *pWinChildClipRegion;
2367 else
2369 if ( pRegion )
2370 mpWindowImpl->maInvalidateRegion.Union( *pRegion );
2372 if( mpWindowImpl->mpWinData && mpWindowImpl->mbTrackVisible )
2373 /* #98602# need to repaint all children within the
2374 * tracking rectangle, so the following invert
2375 * operation takes places without traces of the previous
2376 * one.
2378 mpWindowImpl->maInvalidateRegion.Union( *mpWindowImpl->mpWinData->mpTrackRect );
2380 if ( mpWindowImpl->mnPaintFlags & IMPL_PAINT_PAINTALLCHILDS )
2381 pChildRegion = new Region( mpWindowImpl->maInvalidateRegion );
2382 mpWindowImpl->maInvalidateRegion.Intersect( *pWinChildClipRegion );
2384 mpWindowImpl->mnPaintFlags = 0;
2385 if ( !mpWindowImpl->maInvalidateRegion.IsEmpty() )
2387 if ( mpWindowImpl->mpCursor )
2388 mpWindowImpl->mpCursor->ImplHide();
2390 mbInitClipRegion = TRUE;
2391 mpWindowImpl->mbInPaint = TRUE;
2393 // Paint-Region zuruecksetzen
2394 Region aPaintRegion( mpWindowImpl->maInvalidateRegion );
2395 Rectangle aPaintRect = aPaintRegion.GetBoundRect();
2397 // - RTL - re-mirror paint rect and region at this window
2398 if( ImplIsAntiparallel() )
2400 ImplReMirror( aPaintRect );
2401 ImplReMirror( aPaintRegion );
2403 aPaintRect = ImplDevicePixelToLogic( aPaintRect);
2404 mpWindowImpl->mpPaintRegion = &aPaintRegion;
2405 mpWindowImpl->maInvalidateRegion.SetEmpty();
2407 if ( (nPaintFlags & IMPL_PAINT_ERASE) && IsBackground() )
2409 if ( IsClipRegion() )
2411 Region aOldRegion = GetClipRegion();
2412 SetClipRegion();
2413 Erase();
2414 SetClipRegion( aOldRegion );
2416 else
2417 Erase();
2420 // #98943# trigger drawing of toolbox selection after all childern are painted
2421 if( mpWindowImpl->mbDrawSelectionBackground )
2422 aSelectionRect = aPaintRect;
2424 Paint( aPaintRect );
2426 if ( mpWindowImpl->mpWinData )
2428 if ( mpWindowImpl->mbFocusVisible )
2429 ImplInvertFocus( *(mpWindowImpl->mpWinData->mpFocusRect) );
2431 mpWindowImpl->mbInPaint = FALSE;
2432 mbInitClipRegion = TRUE;
2433 mpWindowImpl->mpPaintRegion = NULL;
2434 if ( mpWindowImpl->mpCursor )
2435 mpWindowImpl->mpCursor->ImplShow( FALSE );
2438 else
2439 mpWindowImpl->mnPaintFlags = 0;
2441 if ( nPaintFlags & (IMPL_PAINT_PAINTALLCHILDS | IMPL_PAINT_PAINTCHILDS) )
2443 // die Childfenster ausgeben
2444 Window* pTempWindow = mpWindowImpl->mpFirstChild;
2445 while ( pTempWindow )
2447 if ( pTempWindow->mpWindowImpl->mbVisible )
2448 pTempWindow->ImplCallPaint( pChildRegion, nPaintFlags );
2449 pTempWindow = pTempWindow->mpWindowImpl->mpNext;
2453 if ( mpWindowImpl->mpWinData && mpWindowImpl->mbTrackVisible && (mpWindowImpl->mpWinData->mnTrackFlags & SHOWTRACK_WINDOW) )
2454 /* #98602# need to invert the tracking rect AFTER
2455 * the children have painted
2457 InvertTracking( *(mpWindowImpl->mpWinData->mpTrackRect), mpWindowImpl->mpWinData->mnTrackFlags );
2459 // #98943# draw toolbox selection
2460 if( !aSelectionRect.IsEmpty() )
2461 DrawSelectionBackground( aSelectionRect, 3, FALSE, TRUE, FALSE );
2463 if ( pChildRegion )
2464 delete pChildRegion;
2467 // -----------------------------------------------------------------------
2469 void Window::ImplCallOverlapPaint()
2471 // Zuerst geben wir die ueberlappenden Fenster aus
2472 Window* pTempWindow = mpWindowImpl->mpFirstOverlap;
2473 while ( pTempWindow )
2475 if ( pTempWindow->mpWindowImpl->mbReallyVisible )
2476 pTempWindow->ImplCallOverlapPaint();
2477 pTempWindow = pTempWindow->mpWindowImpl->mpNext;
2480 // und dann erst uns selber
2481 if ( mpWindowImpl->mnPaintFlags & (IMPL_PAINT_PAINT | IMPL_PAINT_PAINTCHILDS) )
2483 // - RTL - notify ImplCallPaint to check for re-mirroring (CHECKRTL)
2484 // because we were called from the Sal layer
2485 ImplCallPaint( NULL, mpWindowImpl->mnPaintFlags /*| IMPL_PAINT_CHECKRTL */);
2489 // -----------------------------------------------------------------------
2491 void Window::ImplPostPaint()
2493 if ( !mpWindowImpl->mpFrameData->maPaintTimer.IsActive() )
2494 mpWindowImpl->mpFrameData->maPaintTimer.Start();
2497 // -----------------------------------------------------------------------
2499 IMPL_LINK( Window, ImplHandlePaintHdl, void*, EMPTYARG )
2501 // save paint events until resizing is done
2502 if( mpWindowImpl->mbFrame && mpWindowImpl->mpFrameData->maResizeTimer.IsActive() )
2503 mpWindowImpl->mpFrameData->maPaintTimer.Start();
2504 else if ( mpWindowImpl->mbReallyVisible )
2505 ImplCallOverlapPaint();
2506 return 0;
2509 // -----------------------------------------------------------------------
2511 IMPL_LINK( Window, ImplHandleResizeTimerHdl, void*, EMPTYARG )
2513 if( mpWindowImpl->mbReallyVisible )
2515 ImplCallResize();
2516 if( mpWindowImpl->mpFrameData->maPaintTimer.IsActive() )
2518 mpWindowImpl->mpFrameData->maPaintTimer.Stop();
2519 mpWindowImpl->mpFrameData->maPaintTimer.GetTimeoutHdl().Call( NULL );
2523 return 0;
2526 // -----------------------------------------------------------------------
2528 void Window::ImplInvalidateFrameRegion( const Region* pRegion, USHORT nFlags )
2530 // PAINTCHILDS bei allen Parent-Fenster bis zum ersten OverlapWindow
2531 // setzen
2532 if ( !ImplIsOverlapWindow() )
2534 Window* pTempWindow = this;
2535 USHORT nTranspPaint = IsPaintTransparent() ? IMPL_PAINT_PAINT : 0;
2538 pTempWindow = pTempWindow->ImplGetParent();
2539 if ( pTempWindow->mpWindowImpl->mnPaintFlags & IMPL_PAINT_PAINTCHILDS )
2540 break;
2541 pTempWindow->mpWindowImpl->mnPaintFlags |= IMPL_PAINT_PAINTCHILDS | nTranspPaint;
2542 if( ! pTempWindow->IsPaintTransparent() )
2543 nTranspPaint = 0;
2545 while ( !pTempWindow->ImplIsOverlapWindow() );
2548 // Paint-Flags setzen
2549 mpWindowImpl->mnPaintFlags |= IMPL_PAINT_PAINT;
2550 if ( nFlags & INVALIDATE_CHILDREN )
2551 mpWindowImpl->mnPaintFlags |= IMPL_PAINT_PAINTALLCHILDS;
2552 if ( !(nFlags & INVALIDATE_NOERASE) )
2553 mpWindowImpl->mnPaintFlags |= IMPL_PAINT_ERASE;
2554 if ( !pRegion )
2555 mpWindowImpl->mnPaintFlags |= IMPL_PAINT_PAINTALL;
2557 // Wenn nicht alles neu ausgegeben werden muss, dann die Region
2558 // dazupacken
2559 if ( !(mpWindowImpl->mnPaintFlags & IMPL_PAINT_PAINTALL) )
2560 mpWindowImpl->maInvalidateRegion.Union( *pRegion );
2562 // Handle transparent windows correctly: invalidate must be done on the first opaque parent
2563 if( ((IsPaintTransparent() && !(nFlags & INVALIDATE_NOTRANSPARENT)) || (nFlags & INVALIDATE_TRANSPARENT) )
2564 && ImplGetParent() )
2566 Window *pParent = ImplGetParent();
2567 while( pParent && pParent->IsPaintTransparent() )
2568 pParent = pParent->ImplGetParent();
2569 if( pParent )
2571 Region *pChildRegion;
2572 if ( mpWindowImpl->mnPaintFlags & IMPL_PAINT_PAINTALL )
2573 // invalidate the whole child window region in the parent
2574 pChildRegion = ImplGetWinChildClipRegion();
2575 else
2576 // invalidate the same region in the parent that has to be repainted in the child
2577 pChildRegion = &mpWindowImpl->maInvalidateRegion;
2579 nFlags |= INVALIDATE_CHILDREN; // paint should also be done on all children
2580 nFlags &= ~INVALIDATE_NOERASE; // parent should paint and erase to create proper background
2581 pParent->ImplInvalidateFrameRegion( pChildRegion, nFlags );
2584 ImplPostPaint();
2587 // -----------------------------------------------------------------------
2589 void Window::ImplInvalidateOverlapFrameRegion( const Region& rRegion )
2591 Region aRegion = rRegion;
2593 ImplClipBoundaries( aRegion, TRUE, TRUE );
2594 if ( !aRegion.IsEmpty() )
2595 ImplInvalidateFrameRegion( &aRegion, INVALIDATE_CHILDREN );
2597 // Dann invalidieren wir die ueberlappenden Fenster
2598 Window* pTempWindow = mpWindowImpl->mpFirstOverlap;
2599 while ( pTempWindow )
2601 if ( pTempWindow->IsVisible() )
2602 pTempWindow->ImplInvalidateOverlapFrameRegion( rRegion );
2604 pTempWindow = pTempWindow->mpWindowImpl->mpNext;
2608 // -----------------------------------------------------------------------
2610 void Window::ImplInvalidateParentFrameRegion( Region& rRegion )
2612 if ( mpWindowImpl->mbOverlapWin )
2613 mpWindowImpl->mpFrameWindow->ImplInvalidateOverlapFrameRegion( rRegion );
2614 else
2616 if( ImplGetParent() )
2617 ImplGetParent()->ImplInvalidateFrameRegion( &rRegion, INVALIDATE_CHILDREN );
2621 // -----------------------------------------------------------------------
2623 void Window::ImplInvalidate( const Region* pRegion, USHORT nFlags )
2626 // Hintergrund-Sicherung zuruecksetzen
2627 if ( mpWindowImpl->mpFrameData->mpFirstBackWin )
2628 ImplInvalidateAllOverlapBackgrounds();
2630 // Feststellen, was neu ausgegeben werden muss
2631 BOOL bInvalidateAll = !pRegion;
2633 // Transparent-Invalidate beruecksichtigen
2634 Window* pOpaqueWindow = this;
2635 if ( (mpWindowImpl->mbPaintTransparent && !(nFlags & INVALIDATE_NOTRANSPARENT)) || (nFlags & INVALIDATE_TRANSPARENT) )
2637 Window* pTempWindow = pOpaqueWindow->ImplGetParent();
2638 while ( pTempWindow )
2640 if ( !pTempWindow->IsPaintTransparent() )
2642 pOpaqueWindow = pTempWindow;
2643 nFlags |= INVALIDATE_CHILDREN;
2644 bInvalidateAll = FALSE;
2645 break;
2648 if ( pTempWindow->ImplIsOverlapWindow() )
2649 break;
2651 pTempWindow = pTempWindow->ImplGetParent();
2655 // Region zusammenbauen
2656 USHORT nOrgFlags = nFlags;
2657 if ( !(nFlags & (INVALIDATE_CHILDREN | INVALIDATE_NOCHILDREN)) )
2659 if ( GetStyle() & WB_CLIPCHILDREN )
2660 nFlags |= INVALIDATE_NOCHILDREN;
2661 else
2662 nFlags |= INVALIDATE_CHILDREN;
2664 if ( (nFlags & INVALIDATE_NOCHILDREN) && mpWindowImpl->mpFirstChild )
2665 bInvalidateAll = FALSE;
2666 if ( bInvalidateAll )
2667 ImplInvalidateFrameRegion( NULL, nFlags );
2668 else
2670 Rectangle aRect( Point( mnOutOffX, mnOutOffY ), Size( mnOutWidth, mnOutHeight ) );
2671 Region aRegion( aRect );
2672 if ( pRegion )
2674 // --- RTL --- remirror region before intersecting it
2675 if ( ImplIsAntiparallel() )
2677 Region aRgn( *pRegion );
2678 ImplReMirror( aRgn );
2679 aRegion.Intersect( aRgn );
2681 else
2682 aRegion.Intersect( *pRegion );
2684 ImplClipBoundaries( aRegion, TRUE, TRUE );
2685 if ( nFlags & INVALIDATE_NOCHILDREN )
2687 nFlags &= ~INVALIDATE_CHILDREN;
2688 if ( !(nFlags & INVALIDATE_NOCLIPCHILDREN) )
2690 if ( nOrgFlags & INVALIDATE_NOCHILDREN )
2691 ImplClipAllChilds( aRegion );
2692 else
2694 if ( ImplClipChilds( aRegion ) )
2695 nFlags |= INVALIDATE_CHILDREN;
2699 if ( !aRegion.IsEmpty() )
2700 ImplInvalidateFrameRegion( &aRegion, nFlags ); // transparency is handled here, pOpaqueWindow not required
2703 if ( nFlags & INVALIDATE_UPDATE )
2704 pOpaqueWindow->Update(); // start painting at the opaque parent
2707 // -----------------------------------------------------------------------
2709 void Window::ImplMoveInvalidateRegion( const Rectangle& rRect,
2710 long nHorzScroll, long nVertScroll,
2711 BOOL bChilds )
2713 if ( (mpWindowImpl->mnPaintFlags & (IMPL_PAINT_PAINT | IMPL_PAINT_PAINTALL)) == IMPL_PAINT_PAINT )
2715 Region aTempRegion = mpWindowImpl->maInvalidateRegion;
2716 aTempRegion.Intersect( rRect );
2717 aTempRegion.Move( nHorzScroll, nVertScroll );
2718 mpWindowImpl->maInvalidateRegion.Union( aTempRegion );
2721 if ( bChilds && (mpWindowImpl->mnPaintFlags & IMPL_PAINT_PAINTCHILDS) )
2723 Window* pWindow = mpWindowImpl->mpFirstChild;
2724 while ( pWindow )
2726 pWindow->ImplMoveInvalidateRegion( rRect, nHorzScroll, nVertScroll, TRUE );
2727 pWindow = pWindow->mpWindowImpl->mpNext;
2732 // -----------------------------------------------------------------------
2734 void Window::ImplMoveAllInvalidateRegions( const Rectangle& rRect,
2735 long nHorzScroll, long nVertScroll,
2736 BOOL bChilds )
2738 // Paint-Region auch verschieben, wenn noch Paints anstehen
2739 ImplMoveInvalidateRegion( rRect, nHorzScroll, nVertScroll, bChilds );
2740 // Paint-Region muss bei uns verschoben gesetzt werden, die durch
2741 // die Parents gezeichnet werden
2742 if ( !ImplIsOverlapWindow() )
2744 Region aPaintAllRegion;
2745 Window* pPaintAllWindow = this;
2748 pPaintAllWindow = pPaintAllWindow->ImplGetParent();
2749 if ( pPaintAllWindow->mpWindowImpl->mnPaintFlags & IMPL_PAINT_PAINTALLCHILDS )
2751 if ( pPaintAllWindow->mpWindowImpl->mnPaintFlags & IMPL_PAINT_PAINTALL )
2753 aPaintAllRegion.SetEmpty();
2754 break;
2756 else
2757 aPaintAllRegion.Union( pPaintAllWindow->mpWindowImpl->maInvalidateRegion );
2760 while ( !pPaintAllWindow->ImplIsOverlapWindow() );
2761 if ( !aPaintAllRegion.IsEmpty() )
2763 aPaintAllRegion.Move( nHorzScroll, nVertScroll );
2764 USHORT nPaintFlags = 0;
2765 if ( bChilds )
2766 mpWindowImpl->mnPaintFlags |= INVALIDATE_CHILDREN;
2767 ImplInvalidateFrameRegion( &aPaintAllRegion, nPaintFlags );
2772 // -----------------------------------------------------------------------
2774 void Window::ImplValidateFrameRegion( const Region* pRegion, USHORT nFlags )
2776 if ( !pRegion )
2777 mpWindowImpl->maInvalidateRegion.SetEmpty();
2778 else
2780 // Wenn alle Childfenster neu ausgegeben werden muessen,
2781 // dann invalidieren wir diese vorher
2782 if ( (mpWindowImpl->mnPaintFlags & IMPL_PAINT_PAINTALLCHILDS) && mpWindowImpl->mpFirstChild )
2784 Region aChildRegion = mpWindowImpl->maInvalidateRegion;
2785 if ( mpWindowImpl->mnPaintFlags & IMPL_PAINT_PAINTALL )
2787 Rectangle aRect( Point( mnOutOffX, mnOutOffY ), Size( mnOutWidth, mnOutHeight ) );
2788 aChildRegion = aRect;
2790 Window* pChild = mpWindowImpl->mpFirstChild;
2791 while ( pChild )
2793 pChild->Invalidate( aChildRegion, INVALIDATE_CHILDREN | INVALIDATE_NOTRANSPARENT );
2794 pChild = pChild->mpWindowImpl->mpNext;
2797 if ( mpWindowImpl->mnPaintFlags & IMPL_PAINT_PAINTALL )
2799 Rectangle aRect( Point( mnOutOffX, mnOutOffY ), Size( mnOutWidth, mnOutHeight ) );
2800 mpWindowImpl->maInvalidateRegion = aRect;
2802 mpWindowImpl->maInvalidateRegion.Exclude( *pRegion );
2804 mpWindowImpl->mnPaintFlags &= ~IMPL_PAINT_PAINTALL;
2806 if ( nFlags & VALIDATE_CHILDREN )
2808 Window* pChild = mpWindowImpl->mpFirstChild;
2809 while ( pChild )
2811 pChild->ImplValidateFrameRegion( pRegion, nFlags );
2812 pChild = pChild->mpWindowImpl->mpNext;
2817 // -----------------------------------------------------------------------
2819 void Window::ImplValidate( const Region* pRegion, USHORT nFlags )
2821 // Region zusammenbauen
2822 BOOL bValidateAll = !pRegion;
2823 USHORT nOrgFlags = nFlags;
2824 if ( !(nFlags & (VALIDATE_CHILDREN | VALIDATE_NOCHILDREN)) )
2826 if ( GetStyle() & WB_CLIPCHILDREN )
2827 nFlags |= VALIDATE_NOCHILDREN;
2828 else
2829 nFlags |= VALIDATE_CHILDREN;
2831 if ( (nFlags & VALIDATE_NOCHILDREN) && mpWindowImpl->mpFirstChild )
2832 bValidateAll = FALSE;
2833 if ( bValidateAll )
2834 ImplValidateFrameRegion( NULL, nFlags );
2835 else
2837 Rectangle aRect( Point( mnOutOffX, mnOutOffY ), Size( mnOutWidth, mnOutHeight ) );
2838 Region aRegion( aRect );
2839 if ( pRegion )
2840 aRegion.Intersect( *pRegion );
2841 ImplClipBoundaries( aRegion, TRUE, TRUE );
2842 if ( nFlags & VALIDATE_NOCHILDREN )
2844 nFlags &= ~VALIDATE_CHILDREN;
2845 if ( nOrgFlags & VALIDATE_NOCHILDREN )
2846 ImplClipAllChilds( aRegion );
2847 else
2849 if ( ImplClipChilds( aRegion ) )
2850 nFlags |= VALIDATE_CHILDREN;
2853 if ( !aRegion.IsEmpty() )
2854 ImplValidateFrameRegion( &aRegion, nFlags );
2858 // -----------------------------------------------------------------------
2860 void Window::ImplScroll( const Rectangle& rRect,
2861 long nHorzScroll, long nVertScroll, USHORT nFlags )
2863 if ( !IsDeviceOutputNecessary() )
2864 return;
2866 nHorzScroll = ImplLogicWidthToDevicePixel( nHorzScroll );
2867 nVertScroll = ImplLogicHeightToDevicePixel( nVertScroll );
2869 if ( !nHorzScroll && !nVertScroll )
2870 return;
2872 // Hintergrund-Sicherung zuruecksetzen
2873 if ( mpWindowImpl->mpFrameData->mpFirstBackWin )
2874 ImplInvalidateAllOverlapBackgrounds();
2876 if ( mpWindowImpl->mpCursor )
2877 mpWindowImpl->mpCursor->ImplHide();
2879 USHORT nOrgFlags = nFlags;
2880 if ( !(nFlags & (SCROLL_CHILDREN | SCROLL_NOCHILDREN)) )
2882 if ( GetStyle() & WB_CLIPCHILDREN )
2883 nFlags |= SCROLL_NOCHILDREN;
2884 else
2885 nFlags |= SCROLL_CHILDREN;
2888 Region aInvalidateRegion;
2889 BOOL bScrollChilds = (nFlags & SCROLL_CHILDREN) != 0;
2890 BOOL bErase = (nFlags & SCROLL_NOERASE) == 0;
2892 if ( !mpWindowImpl->mpFirstChild )
2893 bScrollChilds = FALSE;
2895 // --- RTL --- check if this window requires special action
2896 BOOL bReMirror = ( ImplIsAntiparallel() );
2898 Rectangle aRectMirror( rRect );
2899 if( bReMirror )
2901 // --- RTL --- make sure the invalidate region of this window is
2902 // computed in the same coordinate space as the one from the overlap windows
2903 ImplReMirror( aRectMirror );
2906 // Paint-Bereiche anpassen
2907 ImplMoveAllInvalidateRegions( aRectMirror, nHorzScroll, nVertScroll, bScrollChilds );
2909 if ( !(nFlags & SCROLL_NOINVALIDATE) )
2911 ImplCalcOverlapRegion( aRectMirror, aInvalidateRegion, !bScrollChilds, TRUE, FALSE );
2913 // --- RTL ---
2914 // if the scrolling on the device is performed in the opposite direction
2915 // then move the overlaps in that direction to compute the invalidate region
2916 // on the correct side, i.e., revert nHorzScroll
2918 if ( !aInvalidateRegion.IsEmpty() )
2920 aInvalidateRegion.Move( bReMirror ? -nHorzScroll : nHorzScroll, nVertScroll );
2921 bErase = TRUE;
2923 if ( !(nFlags & SCROLL_NOWINDOWINVALIDATE) )
2925 Rectangle aDestRect( aRectMirror );
2926 aDestRect.Move( bReMirror ? -nHorzScroll : nHorzScroll, nVertScroll );
2927 Region aWinInvalidateRegion( aRectMirror );
2928 aWinInvalidateRegion.Exclude( aDestRect );
2930 aInvalidateRegion.Union( aWinInvalidateRegion );
2934 Point aPoint( mnOutOffX, mnOutOffY );
2935 Region aRegion( Rectangle( aPoint, Size( mnOutWidth, mnOutHeight ) ) );
2936 if ( nFlags & SCROLL_CLIP )
2937 aRegion.Intersect( rRect );
2938 if ( mpWindowImpl->mbWinRegion )
2939 aRegion.Intersect( ImplPixelToDevicePixel( mpWindowImpl->maWinRegion ) );
2941 aRegion.Exclude( aInvalidateRegion );
2943 ImplClipBoundaries( aRegion, FALSE, TRUE );
2944 if ( !bScrollChilds )
2946 if ( nOrgFlags & SCROLL_NOCHILDREN )
2947 ImplClipAllChilds( aRegion );
2948 else
2949 ImplClipChilds( aRegion );
2951 if ( mbClipRegion && (nFlags & SCROLL_USECLIPREGION) )
2952 aRegion.Intersect( maRegion );
2953 if ( !aRegion.IsEmpty() )
2955 if ( mpWindowImpl->mpWinData )
2957 if ( mpWindowImpl->mbFocusVisible )
2958 ImplInvertFocus( *(mpWindowImpl->mpWinData->mpFocusRect) );
2959 if ( mpWindowImpl->mbTrackVisible && (mpWindowImpl->mpWinData->mnTrackFlags & SHOWTRACK_WINDOW) )
2960 InvertTracking( *(mpWindowImpl->mpWinData->mpTrackRect), mpWindowImpl->mpWinData->mnTrackFlags );
2963 SalGraphics* pGraphics = ImplGetFrameGraphics();
2964 if ( pGraphics )
2966 if( bReMirror )
2968 // --- RTL --- frame coordinates require re-mirroring
2969 ImplReMirror( aRegion );
2972 ImplSelectClipRegion( aRegion, pGraphics );
2973 pGraphics->CopyArea( rRect.Left()+nHorzScroll, rRect.Top()+nVertScroll,
2974 rRect.Left(), rRect.Top(),
2975 rRect.GetWidth(), rRect.GetHeight(),
2976 SAL_COPYAREA_WINDOWINVALIDATE, this );
2979 if ( mpWindowImpl->mpWinData )
2981 if ( mpWindowImpl->mbFocusVisible )
2982 ImplInvertFocus( *(mpWindowImpl->mpWinData->mpFocusRect) );
2983 if ( mpWindowImpl->mbTrackVisible && (mpWindowImpl->mpWinData->mnTrackFlags & SHOWTRACK_WINDOW) )
2984 InvertTracking( *(mpWindowImpl->mpWinData->mpTrackRect), mpWindowImpl->mpWinData->mnTrackFlags );
2988 if ( !aInvalidateRegion.IsEmpty() )
2990 // --- RTL --- the invalidate region for this windows is already computed in frame coordinates
2991 // so it has to be re-mirrored before calling the Paint-handler
2992 mpWindowImpl->mnPaintFlags |= IMPL_PAINT_CHECKRTL;
2994 USHORT nPaintFlags = INVALIDATE_CHILDREN;
2995 if ( !bErase )
2996 nPaintFlags |= INVALIDATE_NOERASE;
2997 if ( !bScrollChilds )
2999 if ( nOrgFlags & SCROLL_NOCHILDREN )
3000 ImplClipAllChilds( aInvalidateRegion );
3001 else
3002 ImplClipChilds( aInvalidateRegion );
3004 ImplInvalidateFrameRegion( &aInvalidateRegion, nPaintFlags );
3007 if ( bScrollChilds )
3009 Window* pWindow = mpWindowImpl->mpFirstChild;
3010 while ( pWindow )
3012 Point aPos = pWindow->GetPosPixel();
3013 aPos += Point( nHorzScroll, nVertScroll );
3014 pWindow->SetPosPixel( aPos );
3016 pWindow = pWindow->mpWindowImpl->mpNext;
3020 if ( nFlags & SCROLL_UPDATE )
3021 Update();
3023 if ( mpWindowImpl->mpCursor )
3024 mpWindowImpl->mpCursor->ImplShow( FALSE );
3027 // -----------------------------------------------------------------------
3029 void Window::ImplUpdateAll( BOOL bOverlapWindows )
3031 if ( !mpWindowImpl->mbReallyVisible )
3032 return;
3034 BOOL bFlush = FALSE;
3035 if ( mpWindowImpl->mpFrameWindow->mpWindowImpl->mbPaintFrame )
3037 Point aPoint( 0, 0 );
3038 Region aRegion( Rectangle( aPoint, Size( mnOutWidth, mnOutHeight ) ) );
3039 ImplInvalidateOverlapFrameRegion( aRegion );
3040 if ( mpWindowImpl->mbFrame || (mpWindowImpl->mpBorderWindow && mpWindowImpl->mpBorderWindow->mpWindowImpl->mbFrame) )
3041 bFlush = TRUE;
3044 // Ein Update wirkt immer auf das OverlapWindow, damit bei spaeteren
3045 // Paints nicht zuviel gemalt wird, wenn dort ALLCHILDREN usw. gesetzt
3046 // ist
3047 Window* pWindow = ImplGetFirstOverlapWindow();
3048 if ( bOverlapWindows )
3049 pWindow->ImplCallOverlapPaint();
3050 else
3052 if ( pWindow->mpWindowImpl->mnPaintFlags & (IMPL_PAINT_PAINT | IMPL_PAINT_PAINTCHILDS) )
3053 pWindow->ImplCallPaint( NULL, pWindow->mpWindowImpl->mnPaintFlags );
3056 if ( bFlush )
3057 Flush();
3060 // -----------------------------------------------------------------------
3062 void Window::ImplUpdateWindowPtr( Window* pWindow )
3064 if ( mpWindowImpl->mpFrameWindow != pWindow->mpWindowImpl->mpFrameWindow )
3066 // Graphic freigeben
3067 ImplReleaseGraphics();
3070 mpWindowImpl->mpFrameData = pWindow->mpWindowImpl->mpFrameData;
3071 mpWindowImpl->mpFrame = pWindow->mpWindowImpl->mpFrame;
3072 mpWindowImpl->mpFrameWindow = pWindow->mpWindowImpl->mpFrameWindow;
3073 if ( pWindow->ImplIsOverlapWindow() )
3074 mpWindowImpl->mpOverlapWindow = pWindow;
3075 else
3076 mpWindowImpl->mpOverlapWindow = pWindow->mpWindowImpl->mpOverlapWindow;
3078 Window* pChild = mpWindowImpl->mpFirstChild;
3079 while ( pChild )
3081 pChild->ImplUpdateWindowPtr( pWindow );
3082 pChild = pChild->mpWindowImpl->mpNext;
3086 // -----------------------------------------------------------------------
3088 void Window::ImplUpdateWindowPtr()
3090 Window* pChild = mpWindowImpl->mpFirstChild;
3091 while ( pChild )
3093 pChild->ImplUpdateWindowPtr( this );
3094 pChild = pChild->mpWindowImpl->mpNext;
3098 // -----------------------------------------------------------------------
3100 void Window::ImplUpdateOverlapWindowPtr( BOOL bNewFrame )
3102 BOOL bVisible = IsVisible();
3103 Show( FALSE );
3104 ImplRemoveWindow( bNewFrame );
3105 Window* pRealParent = mpWindowImpl->mpRealParent;
3106 ImplInsertWindow( ImplGetParent() );
3107 mpWindowImpl->mpRealParent = pRealParent;
3108 ImplUpdateWindowPtr();
3109 if ( ImplUpdatePos() )
3110 ImplUpdateSysObjPos();
3112 if ( bNewFrame )
3114 Window* pOverlapWindow = mpWindowImpl->mpFirstOverlap;
3115 while ( pOverlapWindow )
3117 Window* pNextOverlapWindow = pOverlapWindow->mpWindowImpl->mpNext;
3118 pOverlapWindow->ImplUpdateOverlapWindowPtr( bNewFrame );
3119 pOverlapWindow = pNextOverlapWindow;
3123 if ( bVisible )
3124 Show( TRUE );
3127 // -----------------------------------------------------------------------
3129 BOOL Window::ImplUpdatePos()
3131 BOOL bSysChild = FALSE;
3133 if ( ImplIsOverlapWindow() )
3135 mnOutOffX = mpWindowImpl->mnX;
3136 mnOutOffY = mpWindowImpl->mnY;
3138 else
3140 Window* pParent = ImplGetParent();
3142 mnOutOffX = mpWindowImpl->mnX + pParent->mnOutOffX;
3143 mnOutOffY = mpWindowImpl->mnY + pParent->mnOutOffY;
3146 Window* pChild = mpWindowImpl->mpFirstChild;
3147 while ( pChild )
3149 if ( pChild->ImplUpdatePos() )
3150 bSysChild = TRUE;
3151 pChild = pChild->mpWindowImpl->mpNext;
3154 if ( mpWindowImpl->mpSysObj )
3155 bSysChild = TRUE;
3157 return bSysChild;
3160 // -----------------------------------------------------------------------
3162 void Window::ImplUpdateSysObjPos()
3164 if ( mpWindowImpl->mpSysObj )
3165 mpWindowImpl->mpSysObj->SetPosSize( mnOutOffX, mnOutOffY, mnOutWidth, mnOutHeight );
3167 Window* pChild = mpWindowImpl->mpFirstChild;
3168 while ( pChild )
3170 pChild->ImplUpdateSysObjPos();
3171 pChild = pChild->mpWindowImpl->mpNext;
3174 // -----------------------------------------------------------------------
3176 void Window::ImplPosSizeWindow( long nX, long nY,
3177 long nWidth, long nHeight, USHORT nFlags )
3179 BOOL bNewPos = FALSE;
3180 BOOL bNewSize = FALSE;
3181 BOOL bNewWidth = FALSE;
3182 BOOL bCopyBits = FALSE;
3183 long nOldOutOffX = mnOutOffX;
3184 long nOldOutOffY = mnOutOffY;
3185 long nOldOutWidth = mnOutWidth;
3186 long nOldOutHeight = mnOutHeight;
3187 Region* pOverlapRegion = NULL;
3188 Region* pOldRegion = NULL;
3190 if ( IsReallyVisible() )
3192 if ( mpWindowImpl->mpFrameData->mpFirstBackWin )
3193 ImplInvalidateAllOverlapBackgrounds();
3195 Rectangle aOldWinRect( Point( nOldOutOffX, nOldOutOffY ),
3196 Size( nOldOutWidth, nOldOutHeight ) );
3197 pOldRegion = new Region( aOldWinRect );
3198 if ( mpWindowImpl->mbWinRegion )
3199 pOldRegion->Intersect( ImplPixelToDevicePixel( mpWindowImpl->maWinRegion ) );
3201 if ( mnOutWidth && mnOutHeight && !mpWindowImpl->mbPaintTransparent &&
3202 !mpWindowImpl->mbInitWinClipRegion && !mpWindowImpl->maWinClipRegion.IsEmpty() &&
3203 !HasPaintEvent() )
3204 bCopyBits = TRUE;
3207 BOOL bnXRecycled = FALSE; // avoid duplicate mirroring in RTL case
3208 if ( nFlags & WINDOW_POSSIZE_WIDTH )
3210 if(!( nFlags & WINDOW_POSSIZE_X ))
3212 nX = mpWindowImpl->mnX;
3213 nFlags |= WINDOW_POSSIZE_X;
3214 bnXRecycled = TRUE; // we're using a mnX which was already mirrored in RTL case
3217 if ( nWidth < 0 )
3218 nWidth = 0;
3219 if ( nWidth != mnOutWidth )
3221 mnOutWidth = nWidth;
3222 bNewSize = TRUE;
3223 bCopyBits = FALSE;
3224 bNewWidth = TRUE;
3227 if ( nFlags & WINDOW_POSSIZE_HEIGHT )
3229 if ( nHeight < 0 )
3230 nHeight = 0;
3231 if ( nHeight != mnOutHeight )
3233 mnOutHeight = nHeight;
3234 bNewSize = TRUE;
3235 bCopyBits = FALSE;
3239 if ( nFlags & WINDOW_POSSIZE_X )
3241 long nOrgX = nX;
3242 // --- RTL --- (compare the screen coordinates)
3243 Point aPtDev( Point( nX+mnOutOffX, 0 ) );
3244 if( ImplHasMirroredGraphics() )
3246 mpGraphics->mirror( aPtDev.X(), this );
3248 // #106948# always mirror our pos if our parent is not mirroring, even
3249 // if we are also not mirroring
3250 // --- RTL --- check if parent is in different coordinates
3251 if( !bnXRecycled && mpWindowImpl->mpParent && !mpWindowImpl->mpParent->mpWindowImpl->mbFrame && mpWindowImpl->mpParent->ImplIsAntiparallel() )
3253 // --- RTL --- (re-mirror at parent window)
3254 nX = mpWindowImpl->mpParent->mnOutWidth - mnOutWidth - nX;
3256 /* #i99166# An LTR window in RTL UI that gets sized only would be
3257 expected to not moved its upper left point
3259 if( bnXRecycled )
3261 if( ImplIsAntiparallel() )
3263 aPtDev.X() = mpWindowImpl->mnAbsScreenX;
3264 nOrgX = mpWindowImpl->maPos.X();
3268 else if( !bnXRecycled && mpWindowImpl->mpParent && !mpWindowImpl->mpParent->mpWindowImpl->mbFrame && mpWindowImpl->mpParent->ImplIsAntiparallel() )
3270 // mirrored window in LTR UI
3272 // --- RTL --- (re-mirror at parent window)
3273 nX = mpWindowImpl->mpParent->mnOutWidth - mnOutWidth - nX;
3277 // check maPos as well, as it could have been changed for client windows (ImplCallMove())
3278 if ( mpWindowImpl->mnAbsScreenX != aPtDev.X() || nX != mpWindowImpl->mnX || nOrgX != mpWindowImpl->maPos.X() )
3280 if ( bCopyBits && !pOverlapRegion )
3282 pOverlapRegion = new Region();
3283 ImplCalcOverlapRegion( Rectangle( Point( mnOutOffX, mnOutOffY ),
3284 Size( mnOutWidth, mnOutHeight ) ),
3285 *pOverlapRegion, FALSE, TRUE, TRUE );
3287 mpWindowImpl->mnX = nX;
3288 mpWindowImpl->maPos.X() = nOrgX;
3289 mpWindowImpl->mnAbsScreenX = aPtDev.X(); // --- RTL --- (store real screen pos)
3290 bNewPos = TRUE;
3293 if ( nFlags & WINDOW_POSSIZE_Y )
3295 // check maPos as well, as it could have been changed for client windows (ImplCallMove())
3296 if ( nY != mpWindowImpl->mnY || nY != mpWindowImpl->maPos.Y() )
3298 if ( bCopyBits && !pOverlapRegion )
3300 pOverlapRegion = new Region();
3301 ImplCalcOverlapRegion( Rectangle( Point( mnOutOffX, mnOutOffY ),
3302 Size( mnOutWidth, mnOutHeight ) ),
3303 *pOverlapRegion, FALSE, TRUE, TRUE );
3305 mpWindowImpl->mnY = nY;
3306 mpWindowImpl->maPos.Y() = nY;
3307 bNewPos = TRUE;
3311 /* if ( nFlags & (WINDOW_POSSIZE_X|WINDOW_POSSIZE_Y) )
3313 POINT aPt;
3314 aPt.x = mpWindowImpl->maPos.X();
3315 aPt.y = mpWindowImpl->maPos.Y();
3316 ClientToScreen( mpWindowImpl->mpFrame->maFrameData.mhWnd , &aPt );
3317 mpWindowImpl->maPos.X() = aPt.x;
3318 mpWindowImpl->maPos.Y() = aPt.y;
3321 if ( bNewPos || bNewSize )
3323 BOOL bUpdateSysObjPos = FALSE;
3324 if ( bNewPos )
3325 bUpdateSysObjPos = ImplUpdatePos();
3327 // the borderwindow always specifies the position for its client window
3328 if ( mpWindowImpl->mpBorderWindow )
3329 mpWindowImpl->maPos = mpWindowImpl->mpBorderWindow->mpWindowImpl->maPos;
3331 if ( mpWindowImpl->mpClientWindow )
3333 mpWindowImpl->mpClientWindow->ImplPosSizeWindow( mpWindowImpl->mpClientWindow->mpWindowImpl->mnLeftBorder,
3334 mpWindowImpl->mpClientWindow->mpWindowImpl->mnTopBorder,
3335 mnOutWidth-mpWindowImpl->mpClientWindow->mpWindowImpl->mnLeftBorder-mpWindowImpl->mpClientWindow->mpWindowImpl->mnRightBorder,
3336 mnOutHeight-mpWindowImpl->mpClientWindow->mpWindowImpl->mnTopBorder-mpWindowImpl->mpClientWindow->mpWindowImpl->mnBottomBorder,
3337 WINDOW_POSSIZE_X | WINDOW_POSSIZE_Y |
3338 WINDOW_POSSIZE_WIDTH | WINDOW_POSSIZE_HEIGHT );
3339 // Wenn wir ein ClientWindow haben, dann hat dieses fuer die
3340 // Applikation auch die Position des FloatingWindows
3341 mpWindowImpl->mpClientWindow->mpWindowImpl->maPos = mpWindowImpl->maPos;
3342 if ( bNewPos )
3344 if ( mpWindowImpl->mpClientWindow->IsVisible() )
3346 mpWindowImpl->mpClientWindow->ImplCallMove();
3348 else
3350 mpWindowImpl->mpClientWindow->mpWindowImpl->mbCallMove = TRUE;
3354 // else
3355 // {
3356 // if ( mpWindowImpl->mpBorderWindow )
3357 // mpWindowImpl->maPos = mpWindowImpl->mpBorderWindow->mpWindowImpl->maPos;
3358 // }
3360 // Move()/Resize() werden erst bei Show() gerufen, damit min. eins vor
3361 // einem Show() kommt
3362 if ( IsVisible() )
3364 if ( bNewPos )
3366 ImplCallMove();
3368 if ( bNewSize )
3370 ImplCallResize();
3373 else
3375 if ( bNewPos )
3376 mpWindowImpl->mbCallMove = TRUE;
3377 if ( bNewSize )
3378 mpWindowImpl->mbCallResize = TRUE;
3381 BOOL bUpdateSysObjClip = FALSE;
3382 if ( IsReallyVisible() )
3384 if ( bNewPos || bNewSize )
3386 // Hintergrund-Sicherung zuruecksetzen
3387 if ( mpWindowImpl->mpOverlapData && mpWindowImpl->mpOverlapData->mpSaveBackDev )
3388 ImplDeleteOverlapBackground();
3389 if ( mpWindowImpl->mpFrameData->mpFirstBackWin )
3390 ImplInvalidateAllOverlapBackgrounds();
3391 // Clip-Flag neu setzen
3392 bUpdateSysObjClip = !ImplSetClipFlag( TRUE );
3395 // Fensterinhalt invalidieren ?
3396 if ( bNewPos || (mnOutWidth > nOldOutWidth) || (mnOutHeight > nOldOutHeight) )
3398 if ( bNewPos )
3400 BOOL bInvalidate = FALSE;
3401 BOOL bParentPaint = TRUE;
3402 if ( !ImplIsOverlapWindow() )
3403 bParentPaint = mpWindowImpl->mpParent->IsPaintEnabled();
3404 if ( bCopyBits && bParentPaint && !HasPaintEvent() )
3406 Point aPoint( mnOutOffX, mnOutOffY );
3407 Region aRegion( Rectangle( aPoint,
3408 Size( mnOutWidth, mnOutHeight ) ) );
3409 if ( mpWindowImpl->mbWinRegion )
3410 aRegion.Intersect( ImplPixelToDevicePixel( mpWindowImpl->maWinRegion ) );
3411 ImplClipBoundaries( aRegion, FALSE, TRUE );
3412 if ( !pOverlapRegion->IsEmpty() )
3414 pOverlapRegion->Move( mnOutOffX-nOldOutOffX, mnOutOffY-nOldOutOffY );
3415 aRegion.Exclude( *pOverlapRegion );
3417 if ( !aRegion.IsEmpty() )
3419 // Paint-Bereiche anpassen
3420 ImplMoveAllInvalidateRegions( Rectangle( Point( nOldOutOffX, nOldOutOffY ),
3421 Size( nOldOutWidth, nOldOutHeight ) ),
3422 mnOutOffX-nOldOutOffX, mnOutOffY-nOldOutOffY,
3423 TRUE );
3424 SalGraphics* pGraphics = ImplGetFrameGraphics();
3425 if ( pGraphics )
3427 const bool bSelectClipRegion = ImplSelectClipRegion( aRegion, pGraphics );
3428 if ( bSelectClipRegion )
3430 pGraphics->CopyArea( mnOutOffX, mnOutOffY,
3431 nOldOutOffX, nOldOutOffY,
3432 nOldOutWidth, nOldOutHeight,
3433 SAL_COPYAREA_WINDOWINVALIDATE, this );
3435 else
3436 bInvalidate = TRUE;
3438 else
3439 bInvalidate = TRUE;
3440 if ( !bInvalidate )
3442 if ( !pOverlapRegion->IsEmpty() )
3443 ImplInvalidateFrameRegion( pOverlapRegion, INVALIDATE_CHILDREN );
3446 else
3447 bInvalidate = TRUE;
3449 else
3450 bInvalidate = TRUE;
3451 if ( bInvalidate )
3452 ImplInvalidateFrameRegion( NULL, INVALIDATE_CHILDREN );
3454 else
3456 Point aPoint( mnOutOffX, mnOutOffY );
3457 Region aRegion( Rectangle( aPoint,
3458 Size( mnOutWidth, mnOutHeight ) ) );
3459 aRegion.Exclude( *pOldRegion );
3460 if ( mpWindowImpl->mbWinRegion )
3461 aRegion.Intersect( ImplPixelToDevicePixel( mpWindowImpl->maWinRegion ) );
3462 ImplClipBoundaries( aRegion, FALSE, TRUE );
3463 if ( !aRegion.IsEmpty() )
3464 ImplInvalidateFrameRegion( &aRegion, INVALIDATE_CHILDREN );
3468 // Parent oder Overlaps invalidieren
3469 if ( bNewPos ||
3470 (mnOutWidth < nOldOutWidth) || (mnOutHeight < nOldOutHeight) )
3472 Region aRegion( *pOldRegion );
3473 if ( !mpWindowImpl->mbPaintTransparent )
3474 ImplExcludeWindowRegion( aRegion );
3475 ImplClipBoundaries( aRegion, FALSE, TRUE );
3476 if ( !aRegion.IsEmpty() && !mpWindowImpl->mpBorderWindow )
3477 ImplInvalidateParentFrameRegion( aRegion );
3481 // System-Objekte anpassen
3482 if ( bUpdateSysObjClip )
3483 ImplUpdateSysObjClip();
3484 if ( bUpdateSysObjPos )
3485 ImplUpdateSysObjPos();
3486 if ( bNewSize && mpWindowImpl->mpSysObj )
3487 mpWindowImpl->mpSysObj->SetPosSize( mnOutOffX, mnOutOffY, mnOutWidth, mnOutHeight );
3490 if ( pOverlapRegion )
3491 delete pOverlapRegion;
3492 if ( pOldRegion )
3493 delete pOldRegion;
3496 // -----------------------------------------------------------------------
3498 void Window::ImplToBottomChild()
3500 if ( !ImplIsOverlapWindow() && !mpWindowImpl->mbReallyVisible && (mpWindowImpl->mpParent->mpWindowImpl->mpLastChild != this) )
3502 // Fenster an das Ende der Liste setzen
3503 if ( mpWindowImpl->mpPrev )
3504 mpWindowImpl->mpPrev->mpWindowImpl->mpNext = mpWindowImpl->mpNext;
3505 else
3506 mpWindowImpl->mpParent->mpWindowImpl->mpFirstChild = mpWindowImpl->mpNext;
3507 mpWindowImpl->mpNext->mpWindowImpl->mpPrev = mpWindowImpl->mpPrev;
3508 mpWindowImpl->mpPrev = mpWindowImpl->mpParent->mpWindowImpl->mpLastChild;
3509 mpWindowImpl->mpParent->mpWindowImpl->mpLastChild = this;
3510 mpWindowImpl->mpPrev->mpWindowImpl->mpNext = this;
3511 mpWindowImpl->mpNext = NULL;
3515 // -----------------------------------------------------------------------
3517 void Window::ImplCalcToTop( ImplCalcToTopData* pPrevData )
3519 DBG_ASSERT( ImplIsOverlapWindow(), "Window::ImplCalcToTop(): Is not a OverlapWindow" );
3521 if ( !mpWindowImpl->mbFrame )
3523 if ( IsReallyVisible() )
3525 // Region berechnen, wo das Fenster mit anderen Fenstern ueberlappt
3526 Point aPoint( mnOutOffX, mnOutOffY );
3527 Region aRegion( Rectangle( aPoint,
3528 Size( mnOutWidth, mnOutHeight ) ) );
3529 Region aInvalidateRegion;
3530 ImplCalcOverlapRegionOverlaps( aRegion, aInvalidateRegion );
3532 if ( !aInvalidateRegion.IsEmpty() )
3534 ImplCalcToTopData* pData = new ImplCalcToTopData;
3535 pPrevData->mpNext = pData;
3536 pData->mpNext = NULL;
3537 pData->mpWindow = this;
3538 pData->mpInvalidateRegion = new Region( aInvalidateRegion );
3544 // -----------------------------------------------------------------------
3546 void Window::ImplCalcChildOverlapToTop( ImplCalcToTopData* pPrevData )
3548 DBG_ASSERT( ImplIsOverlapWindow(), "Window::ImplCalcChildOverlapToTop(): Is not a OverlapWindow" );
3550 ImplCalcToTop( pPrevData );
3551 if ( pPrevData->mpNext )
3552 pPrevData = pPrevData->mpNext;
3554 Window* pOverlap = mpWindowImpl->mpFirstOverlap;
3555 while ( pOverlap )
3557 pOverlap->ImplCalcToTop( pPrevData );
3558 if ( pPrevData->mpNext )
3559 pPrevData = pPrevData->mpNext;
3560 pOverlap = pOverlap->mpWindowImpl->mpNext;
3564 // -----------------------------------------------------------------------
3566 void Window::ImplToTop( USHORT nFlags )
3568 DBG_ASSERT( ImplIsOverlapWindow(), "Window::ImplToTop(): Is not a OverlapWindow" );
3570 if ( mpWindowImpl->mbFrame )
3572 // Wenn in das externe Fenster geklickt wird, ist dieses
3573 // dafuer zustaendig dafuer zu sorgen, das unser Frame
3574 // nach vorne kommt
3575 if ( !mpWindowImpl->mpFrameData->mbHasFocus &&
3576 !mpWindowImpl->mpFrameData->mbSysObjFocus &&
3577 !mpWindowImpl->mpFrameData->mbInSysObjFocusHdl &&
3578 !mpWindowImpl->mpFrameData->mbInSysObjToTopHdl )
3580 // do not bring floating windows on the client to top
3581 if( !ImplGetClientWindow() || !(ImplGetClientWindow()->GetStyle() & WB_SYSTEMFLOATWIN) )
3583 USHORT nSysFlags = 0;
3584 if ( nFlags & TOTOP_RESTOREWHENMIN )
3585 nSysFlags |= SAL_FRAME_TOTOP_RESTOREWHENMIN;
3586 if ( nFlags & TOTOP_FOREGROUNDTASK )
3587 nSysFlags |= SAL_FRAME_TOTOP_FOREGROUNDTASK;
3588 if ( nFlags & TOTOP_GRABFOCUSONLY )
3589 nSysFlags |= SAL_FRAME_TOTOP_GRABFOCUS_ONLY;
3590 mpWindowImpl->mpFrame->ToTop( nSysFlags );
3594 else
3596 if ( mpWindowImpl->mpOverlapWindow->mpWindowImpl->mpFirstOverlap != this )
3598 // Fenster aus der Liste entfernen
3599 mpWindowImpl->mpPrev->mpWindowImpl->mpNext = mpWindowImpl->mpNext;
3600 if ( mpWindowImpl->mpNext )
3601 mpWindowImpl->mpNext->mpWindowImpl->mpPrev = mpWindowImpl->mpPrev;
3602 else
3603 mpWindowImpl->mpOverlapWindow->mpWindowImpl->mpLastOverlap = mpWindowImpl->mpPrev;
3605 // AlwaysOnTop beruecksichtigen
3606 BOOL bOnTop = IsAlwaysOnTopEnabled();
3607 Window* pNextWin = mpWindowImpl->mpOverlapWindow->mpWindowImpl->mpFirstOverlap;
3608 if ( !bOnTop )
3610 while ( pNextWin )
3612 if ( !pNextWin->IsAlwaysOnTopEnabled() )
3613 break;
3614 pNextWin = pNextWin->mpWindowImpl->mpNext;
3618 // TopLevel abpruefen
3619 BYTE nTopLevel = mpWindowImpl->mpOverlapData->mnTopLevel;
3620 while ( pNextWin )
3622 if ( (bOnTop != pNextWin->IsAlwaysOnTopEnabled()) ||
3623 (nTopLevel <= pNextWin->mpWindowImpl->mpOverlapData->mnTopLevel) )
3624 break;
3625 pNextWin = pNextWin->mpWindowImpl->mpNext;
3628 // Fenster in die Liste wieder eintragen
3629 mpWindowImpl->mpNext = pNextWin;
3630 if ( pNextWin )
3632 mpWindowImpl->mpPrev = pNextWin->mpWindowImpl->mpPrev;
3633 pNextWin->mpWindowImpl->mpPrev = this;
3635 else
3637 mpWindowImpl->mpPrev = mpWindowImpl->mpOverlapWindow->mpWindowImpl->mpLastOverlap;
3638 mpWindowImpl->mpOverlapWindow->mpWindowImpl->mpLastOverlap = this;
3640 if ( mpWindowImpl->mpPrev )
3641 mpWindowImpl->mpPrev->mpWindowImpl->mpNext = this;
3642 else
3643 mpWindowImpl->mpOverlapWindow->mpWindowImpl->mpFirstOverlap = this;
3645 // ClipRegion muss von diesem Fenster und allen weiteren
3646 // ueberlappenden Fenstern neu berechnet werden.
3647 if ( IsReallyVisible() )
3649 // Hintergrund-Sicherung zuruecksetzen
3650 if ( mpWindowImpl->mpFrameData->mpFirstBackWin )
3651 ImplInvalidateAllOverlapBackgrounds();
3652 mpWindowImpl->mpOverlapWindow->ImplSetClipFlagOverlapWindows();
3658 // -----------------------------------------------------------------------
3660 void Window::ImplStartToTop( USHORT nFlags )
3662 ImplCalcToTopData aStartData;
3663 ImplCalcToTopData* pCurData;
3664 ImplCalcToTopData* pNextData;
3665 Window* pOverlapWindow;
3666 if ( ImplIsOverlapWindow() )
3667 pOverlapWindow = this;
3668 else
3669 pOverlapWindow = mpWindowImpl->mpOverlapWindow;
3671 // Zuerst die Paint-Bereiche berechnen
3672 Window* pTempOverlapWindow = pOverlapWindow;
3673 aStartData.mpNext = NULL;
3674 pCurData = &aStartData;
3677 pTempOverlapWindow->ImplCalcToTop( pCurData );
3678 if ( pCurData->mpNext )
3679 pCurData = pCurData->mpNext;
3680 pTempOverlapWindow = pTempOverlapWindow->mpWindowImpl->mpOverlapWindow;
3682 while ( !pTempOverlapWindow->mpWindowImpl->mbFrame );
3683 // Dann die Paint-Bereiche der ChildOverlap-Windows berechnen
3684 pTempOverlapWindow = mpWindowImpl->mpFirstOverlap;
3685 while ( pTempOverlapWindow )
3687 pTempOverlapWindow->ImplCalcToTop( pCurData );
3688 if ( pCurData->mpNext )
3689 pCurData = pCurData->mpNext;
3690 pTempOverlapWindow = pTempOverlapWindow->mpWindowImpl->mpNext;
3693 // Dann die Fenster-Verkettung aendern
3694 pTempOverlapWindow = pOverlapWindow;
3697 pTempOverlapWindow->ImplToTop( nFlags );
3698 pTempOverlapWindow = pTempOverlapWindow->mpWindowImpl->mpOverlapWindow;
3700 while ( !pTempOverlapWindow->mpWindowImpl->mbFrame );
3701 // Und zum Schluss invalidieren wir die ungueltigen Bereiche
3702 pCurData = aStartData.mpNext;
3703 while ( pCurData )
3705 pCurData->mpWindow->ImplInvalidateFrameRegion( pCurData->mpInvalidateRegion, INVALIDATE_CHILDREN );
3706 pNextData = pCurData->mpNext;
3707 delete pCurData->mpInvalidateRegion;
3708 delete pCurData;
3709 pCurData = pNextData;
3713 // -----------------------------------------------------------------------
3715 void Window::ImplFocusToTop( USHORT nFlags, BOOL bReallyVisible )
3717 // Soll Focus auch geholt werden?
3718 if ( !(nFlags & TOTOP_NOGRABFOCUS) )
3720 // Erstes Fenster mit GrabFocus-Activate bekommt den Focus
3721 Window* pFocusWindow = this;
3722 while ( !pFocusWindow->ImplIsOverlapWindow() )
3724 // Nur wenn Fenster kein Border-Fenster hat, da wir
3725 // immer das dazugehoerende BorderFenster finden wollen
3726 if ( !pFocusWindow->mpWindowImpl->mpBorderWindow )
3728 if ( pFocusWindow->mpWindowImpl->mnActivateMode & ACTIVATE_MODE_GRABFOCUS )
3729 break;
3731 pFocusWindow = pFocusWindow->ImplGetParent();
3733 if ( (pFocusWindow->mpWindowImpl->mnActivateMode & ACTIVATE_MODE_GRABFOCUS) &&
3734 !pFocusWindow->HasChildPathFocus( TRUE ) )
3735 pFocusWindow->GrabFocus();
3738 if ( bReallyVisible )
3739 ImplGenerateMouseMove();
3742 // -----------------------------------------------------------------------
3744 void Window::ImplShowAllOverlaps()
3746 Window* pOverlapWindow = mpWindowImpl->mpFirstOverlap;
3747 while ( pOverlapWindow )
3749 if ( pOverlapWindow->mpWindowImpl->mbOverlapVisible )
3751 pOverlapWindow->Show( TRUE, SHOW_NOACTIVATE );
3752 pOverlapWindow->mpWindowImpl->mbOverlapVisible = FALSE;
3755 pOverlapWindow = pOverlapWindow->mpWindowImpl->mpNext;
3759 // -----------------------------------------------------------------------
3761 void Window::ImplHideAllOverlaps()
3763 Window* pOverlapWindow = mpWindowImpl->mpFirstOverlap;
3764 while ( pOverlapWindow )
3766 if ( pOverlapWindow->IsVisible() )
3768 pOverlapWindow->mpWindowImpl->mbOverlapVisible = TRUE;
3769 pOverlapWindow->Show( FALSE );
3772 pOverlapWindow = pOverlapWindow->mpWindowImpl->mpNext;
3776 // -----------------------------------------------------------------------
3778 void Window::ImplCallMouseMove( USHORT nMouseCode, BOOL bModChanged )
3780 if ( mpWindowImpl->mpFrameData->mbMouseIn && mpWindowImpl->mpFrameWindow->mpWindowImpl->mbReallyVisible )
3782 ULONG nTime = Time::GetSystemTicks();
3783 long nX = mpWindowImpl->mpFrameData->mnLastMouseX;
3784 long nY = mpWindowImpl->mpFrameData->mnLastMouseY;
3785 USHORT nCode = nMouseCode;
3786 USHORT nMode = mpWindowImpl->mpFrameData->mnMouseMode;
3787 BOOL bLeave;
3788 // Auf MouseLeave testen
3789 if ( ((nX < 0) || (nY < 0) ||
3790 (nX >= mpWindowImpl->mpFrameWindow->mnOutWidth) ||
3791 (nY >= mpWindowImpl->mpFrameWindow->mnOutHeight)) &&
3792 !ImplGetSVData()->maWinData.mpCaptureWin )
3793 bLeave = TRUE;
3794 else
3795 bLeave = FALSE;
3796 nMode |= MOUSE_SYNTHETIC;
3797 if ( bModChanged )
3798 nMode |= MOUSE_MODIFIERCHANGED;
3799 ImplHandleMouseEvent( mpWindowImpl->mpFrameWindow, EVENT_MOUSEMOVE, bLeave, nX, nY, nTime, nCode, nMode );
3803 // -----------------------------------------------------------------------
3805 void Window::ImplGenerateMouseMove()
3807 if ( !mpWindowImpl->mpFrameData->mnMouseMoveId )
3808 Application::PostUserEvent( mpWindowImpl->mpFrameData->mnMouseMoveId, LINK( mpWindowImpl->mpFrameWindow, Window, ImplGenerateMouseMoveHdl ) );
3811 // -----------------------------------------------------------------------
3813 IMPL_LINK( Window, ImplGenerateMouseMoveHdl, void*, EMPTYARG )
3815 mpWindowImpl->mpFrameData->mnMouseMoveId = 0;
3816 Window* pCaptureWin = ImplGetSVData()->maWinData.mpCaptureWin;
3817 if( ! pCaptureWin ||
3818 (pCaptureWin->mpWindowImpl && pCaptureWin->mpWindowImpl->mpFrame == mpWindowImpl->mpFrame)
3821 ImplCallMouseMove( mpWindowImpl->mpFrameData->mnMouseCode );
3823 return 0;
3826 // -----------------------------------------------------------------------
3828 void Window::ImplInvertFocus( const Rectangle& rRect )
3830 InvertTracking( rRect, SHOWTRACK_SMALL | SHOWTRACK_WINDOW );
3833 // -----------------------------------------------------------------------
3835 void Window::ImplCallFocusChangeActivate( Window* pNewOverlapWindow,
3836 Window* pOldOverlapWindow )
3838 ImplSVData* pSVData = ImplGetSVData();
3839 Window* pNewRealWindow;
3840 Window* pOldRealWindow;
3841 Window* pLastRealWindow;
3842 BOOL bCallActivate = TRUE;
3843 BOOL bCallDeactivate = TRUE;
3845 pOldRealWindow = pOldOverlapWindow->ImplGetWindow();
3846 pNewRealWindow = pNewOverlapWindow->ImplGetWindow();
3847 if ( (pOldRealWindow->GetType() != WINDOW_FLOATINGWINDOW) ||
3848 pOldRealWindow->GetActivateMode() )
3850 if ( (pNewRealWindow->GetType() == WINDOW_FLOATINGWINDOW) &&
3851 !pNewRealWindow->GetActivateMode() )
3853 pSVData->maWinData.mpLastDeacWin = pOldOverlapWindow;
3854 bCallDeactivate = FALSE;
3857 else if ( (pNewRealWindow->GetType() != WINDOW_FLOATINGWINDOW) ||
3858 pNewRealWindow->GetActivateMode() )
3860 if ( pSVData->maWinData.mpLastDeacWin )
3862 if ( pSVData->maWinData.mpLastDeacWin == pNewOverlapWindow )
3863 bCallActivate = FALSE;
3864 else
3866 pLastRealWindow = pSVData->maWinData.mpLastDeacWin->ImplGetWindow();
3867 pSVData->maWinData.mpLastDeacWin->mpWindowImpl->mbActive = FALSE;
3868 pSVData->maWinData.mpLastDeacWin->Deactivate();
3869 if ( pLastRealWindow != pSVData->maWinData.mpLastDeacWin )
3871 pLastRealWindow->mpWindowImpl->mbActive = TRUE;
3872 pLastRealWindow->Activate();
3875 pSVData->maWinData.mpLastDeacWin = NULL;
3879 if ( bCallDeactivate )
3881 if( pOldOverlapWindow->mpWindowImpl->mbActive )
3883 pOldOverlapWindow->mpWindowImpl->mbActive = FALSE;
3884 pOldOverlapWindow->Deactivate();
3886 if ( pOldRealWindow != pOldOverlapWindow )
3888 if( pOldRealWindow->mpWindowImpl->mbActive )
3890 pOldRealWindow->mpWindowImpl->mbActive = FALSE;
3891 pOldRealWindow->Deactivate();
3895 if ( bCallActivate && ! pNewOverlapWindow->mpWindowImpl->mbActive )
3897 if( ! pNewOverlapWindow->mpWindowImpl->mbActive )
3899 pNewOverlapWindow->mpWindowImpl->mbActive = TRUE;
3900 pNewOverlapWindow->Activate();
3902 if ( pNewRealWindow != pNewOverlapWindow )
3904 if( ! pNewRealWindow->mpWindowImpl->mbActive )
3906 pNewRealWindow->mpWindowImpl->mbActive = TRUE;
3907 pNewRealWindow->Activate();
3913 static bool IsWindowFocused(const WindowImpl& rWinImpl)
3915 if (rWinImpl.mpSysObj)
3916 return true;
3918 if (rWinImpl.mpFrameData->mbHasFocus)
3919 return true;
3921 if (rWinImpl.mbFakeFocusSet)
3922 return true;
3924 return false;
3927 // -----------------------------------------------------------------------
3928 void Window::ImplGrabFocus( USHORT nFlags )
3930 // #143570# no focus for destructing windows
3931 if( mpWindowImpl->mbInDtor )
3932 return;
3934 // some event listeners do really bad stuff
3935 // => prepare for the worst
3936 ImplDelData aDogTag( this );
3938 // Currently the client window should always get the focus
3939 // Should the border window at some point be focusable
3940 // we need to change all GrabFocus() instances in VCL,
3941 // e.g. in ToTop()
3943 if ( mpWindowImpl->mpClientWindow )
3945 // For a lack of design we need a little hack here to
3946 // ensure that dialogs on close pass the focus back to
3947 // the correct window
3948 if ( mpWindowImpl->mpLastFocusWindow && (mpWindowImpl->mpLastFocusWindow != this) &&
3949 !(mpWindowImpl->mnDlgCtrlFlags & WINDOW_DLGCTRL_WANTFOCUS) &&
3950 mpWindowImpl->mpLastFocusWindow->IsEnabled() &&
3951 mpWindowImpl->mpLastFocusWindow->IsInputEnabled() &&
3952 ! mpWindowImpl->mpLastFocusWindow->IsInModalMode()
3954 mpWindowImpl->mpLastFocusWindow->GrabFocus();
3955 else
3956 mpWindowImpl->mpClientWindow->GrabFocus();
3957 return;
3959 else if ( mpWindowImpl->mbFrame )
3961 // For a lack of design we need a little hack here to
3962 // ensure that dialogs on close pass the focus back to
3963 // the correct window
3964 if ( mpWindowImpl->mpLastFocusWindow && (mpWindowImpl->mpLastFocusWindow != this) &&
3965 !(mpWindowImpl->mnDlgCtrlFlags & WINDOW_DLGCTRL_WANTFOCUS) &&
3966 mpWindowImpl->mpLastFocusWindow->IsEnabled() &&
3967 mpWindowImpl->mpLastFocusWindow->IsInputEnabled() &&
3968 ! mpWindowImpl->mpLastFocusWindow->IsInModalMode()
3971 mpWindowImpl->mpLastFocusWindow->GrabFocus();
3972 return;
3976 // If the Window is disabled, then we don't change the focus
3977 if ( !IsEnabled() || !IsInputEnabled() || IsInModalMode() )
3978 return;
3980 // we only need to set the focus if it is not already set
3981 // note: if some other frame is waiting for an asynchrounous focus event
3982 // we also have to post an asynchronous focus event for this frame
3983 // which is done using ToTop
3984 ImplSVData* pSVData = ImplGetSVData();
3986 BOOL bAsyncFocusWaiting = FALSE;
3987 Window *pFrame = pSVData->maWinData.mpFirstFrame;
3988 while( pFrame )
3990 if( pFrame != mpWindowImpl->mpFrameWindow && pFrame->mpWindowImpl->mpFrameData->mnFocusId )
3992 bAsyncFocusWaiting = TRUE;
3993 break;
3995 pFrame = pFrame->mpWindowImpl->mpFrameData->mpNextFrame;
3998 bool bHasFocus = IsWindowFocused(*mpWindowImpl);
4000 BOOL bMustNotGrabFocus = FALSE;
4001 // #100242#, check parent hierarchy if some floater prohibits grab focus
4003 Window *pParent = this;
4004 while( pParent )
4006 // #102158#, ignore grabfocus only if the floating parent grabs keyboard focus by itself (GrabsFocus())
4007 // otherwise we cannot set the focus in a floating toolbox
4008 if( ( (pParent->mpWindowImpl->mbFloatWin && ((FloatingWindow*)pParent)->GrabsFocus()) || ( pParent->GetStyle() & WB_SYSTEMFLOATWIN ) ) && !( pParent->GetStyle() & WB_MOVEABLE ) )
4010 bMustNotGrabFocus = TRUE;
4011 break;
4013 pParent = pParent->mpWindowImpl->mpParent;
4017 if ( ( pSVData->maWinData.mpFocusWin != this && ! mpWindowImpl->mbInDtor ) || ( bAsyncFocusWaiting && !bHasFocus && !bMustNotGrabFocus ) )
4019 // EndExtTextInput if it is not the same window
4020 if ( pSVData->maWinData.mpExtTextInputWin &&
4021 (pSVData->maWinData.mpExtTextInputWin != this) )
4022 pSVData->maWinData.mpExtTextInputWin->EndExtTextInput( EXTTEXTINPUT_END_COMPLETE );
4024 // Dieses Fenster als letztes FocusWindow merken
4025 Window* pOverlapWindow = ImplGetFirstOverlapWindow();
4026 pOverlapWindow->mpWindowImpl->mpLastFocusWindow = this;
4027 mpWindowImpl->mpFrameData->mpFocusWin = this;
4029 if( !bHasFocus )
4031 // menue windows never get the system focus
4032 // the application will keep the focus
4033 if( bMustNotGrabFocus )
4034 return;
4035 else
4037 // Hier setzen wir schon den Focus um, da ToTop() den Focus
4038 // nicht auf ein anderes Fenster setzen darf
4039 //DBG_WARNING( "Window::GrabFocus() - Frame doesn't have the focus" );
4040 mpWindowImpl->mpFrame->ToTop( SAL_FRAME_TOTOP_GRABFOCUS | SAL_FRAME_TOTOP_GRABFOCUS_ONLY );
4041 return;
4045 Window* pOldFocusWindow = pSVData->maWinData.mpFocusWin;
4046 ImplDelData aOldFocusDel( pOldFocusWindow );
4048 pSVData->maWinData.mpFocusWin = this;
4050 if ( pOldFocusWindow )
4052 // Cursor hiden
4053 if ( pOldFocusWindow->mpWindowImpl->mpCursor )
4054 pOldFocusWindow->mpWindowImpl->mpCursor->ImplHide();
4057 // !!!!! Wegen altem SV-Office Activate/Deavtivate Handling
4058 // !!!!! erstmal so wie frueher
4059 if ( pOldFocusWindow )
4061 // Focus merken
4062 Window* pOldOverlapWindow = pOldFocusWindow->ImplGetFirstOverlapWindow();
4063 Window* pNewOverlapWindow = ImplGetFirstOverlapWindow();
4064 if ( pOldOverlapWindow != pNewOverlapWindow )
4065 ImplCallFocusChangeActivate( pNewOverlapWindow, pOldOverlapWindow );
4067 else
4069 Window* pNewOverlapWindow = ImplGetFirstOverlapWindow();
4070 Window* pNewRealWindow = pNewOverlapWindow->ImplGetWindow();
4071 pNewOverlapWindow->mpWindowImpl->mbActive = TRUE;
4072 pNewOverlapWindow->Activate();
4073 if ( pNewRealWindow != pNewOverlapWindow )
4075 pNewRealWindow->mpWindowImpl->mbActive = TRUE;
4076 pNewRealWindow->Activate();
4080 // call Deactivate and Activate
4081 Window* pDeactivateParent;
4082 Window* pActivateParent;
4083 Window* pParent;
4084 Window* pLastParent;
4085 pDeactivateParent = pOldFocusWindow;
4086 while ( pDeactivateParent )
4088 pParent = pDeactivateParent;
4089 if ( pParent->ImplIsChild( this ) )
4090 break;
4092 if ( pDeactivateParent->ImplIsOverlapWindow() )
4094 if ( !pDeactivateParent->mpWindowImpl->mbParentActive )
4095 break;
4098 pDeactivateParent = pDeactivateParent->ImplGetParent();
4100 if ( pOldFocusWindow )
4102 pActivateParent = this;
4103 while ( pActivateParent )
4105 pParent = pActivateParent;
4106 if ( pParent->ImplIsChild( pOldFocusWindow ) )
4107 break;
4109 if ( pActivateParent->ImplIsOverlapWindow() )
4111 if ( !pActivateParent->mpWindowImpl->mbParentActive )
4112 break;
4115 pActivateParent = pActivateParent->ImplGetParent();
4118 else
4120 if ( ImplIsOverlapWindow() )
4121 pActivateParent = this;
4122 else
4123 pActivateParent = mpWindowImpl->mpOverlapWindow;
4124 while ( pActivateParent )
4126 if ( pActivateParent->ImplIsOverlapWindow() )
4128 if ( !pActivateParent->mpWindowImpl->mbParentActive )
4129 break;
4132 pActivateParent = pActivateParent->ImplGetParent();
4135 if ( pDeactivateParent )
4139 pLastParent = pOldFocusWindow;
4140 if ( pLastParent != pDeactivateParent )
4142 pParent = pLastParent->ImplGetParent();
4143 while ( pParent )
4145 if ( pParent == pDeactivateParent )
4146 break;
4147 pLastParent = pParent;
4148 pParent = pParent->ImplGetParent();
4151 else
4152 pParent = pLastParent;
4154 pParent->mpWindowImpl->mbActive = FALSE;
4155 pParent->Deactivate();
4156 pDeactivateParent = pLastParent;
4158 while ( pDeactivateParent != pOldFocusWindow );
4162 pLastParent = this;
4163 if ( pLastParent != pActivateParent )
4165 pParent = pLastParent->ImplGetParent();
4166 while ( pParent )
4168 if ( pParent == pActivateParent )
4169 break;
4170 pLastParent = pParent;
4171 pParent = pParent->ImplGetParent();
4174 else
4175 pParent = pLastParent;
4177 pParent->mpWindowImpl->mbActive = TRUE;
4178 pParent->Activate();
4179 pActivateParent = pLastParent;
4181 while ( pActivateParent != this );
4183 // call Get- and LoseFocus
4184 if ( pOldFocusWindow && ! aOldFocusDel.IsDelete() )
4186 if ( pOldFocusWindow->IsTracking() &&
4187 (pSVData->maWinData.mnTrackFlags & STARTTRACK_FOCUSCANCEL) )
4188 pOldFocusWindow->EndTracking( ENDTRACK_CANCEL | ENDTRACK_FOCUS );
4189 NotifyEvent aNEvt( EVENT_LOSEFOCUS, pOldFocusWindow );
4190 if ( !ImplCallPreNotify( aNEvt ) )
4191 pOldFocusWindow->LoseFocus();
4192 pOldFocusWindow->ImplCallDeactivateListeners( this );
4195 if ( pSVData->maWinData.mpFocusWin == this )
4197 if ( mpWindowImpl->mpSysObj )
4199 mpWindowImpl->mpFrameData->mpFocusWin = this;
4200 if ( !mpWindowImpl->mpFrameData->mbInSysObjFocusHdl )
4201 mpWindowImpl->mpSysObj->GrabFocus();
4204 if ( pSVData->maWinData.mpFocusWin == this )
4206 if ( mpWindowImpl->mpCursor )
4207 mpWindowImpl->mpCursor->ImplShow();
4208 mpWindowImpl->mbInFocusHdl = TRUE;
4209 mpWindowImpl->mnGetFocusFlags = nFlags;
4210 // if we're changing focus due to closing a popup floating window
4211 // notify the new focus window so it can restore the inner focus
4212 // eg, toolboxes can select their recent active item
4213 if( pOldFocusWindow &&
4214 ! aOldFocusDel.IsDelete() &&
4215 ( pOldFocusWindow->GetDialogControlFlags() & WINDOW_DLGCTRL_FLOATWIN_POPUPMODEEND_CANCEL ) )
4216 mpWindowImpl->mnGetFocusFlags |= GETFOCUS_FLOATWIN_POPUPMODEEND_CANCEL;
4217 NotifyEvent aNEvt( EVENT_GETFOCUS, this );
4218 if ( !ImplCallPreNotify( aNEvt ) && !aDogTag.IsDelete() )
4219 GetFocus();
4220 if( !aDogTag.IsDelete() )
4221 ImplCallActivateListeners( (pOldFocusWindow && ! aOldFocusDel.IsDelete()) ? pOldFocusWindow : NULL );
4222 if( !aDogTag.IsDelete() )
4224 mpWindowImpl->mnGetFocusFlags = 0;
4225 mpWindowImpl->mbInFocusHdl = FALSE;
4230 GetpApp()->FocusChanged();
4231 ImplNewInputContext();
4235 // -----------------------------------------------------------------------
4237 void Window::ImplNewInputContext()
4239 ImplSVData* pSVData = ImplGetSVData();
4240 Window* pFocusWin = pSVData->maWinData.mpFocusWin;
4241 if ( !pFocusWin )
4242 return;
4244 // Is InputContext changed?
4245 const InputContext& rInputContext = pFocusWin->GetInputContext();
4246 if ( rInputContext == pFocusWin->mpWindowImpl->mpFrameData->maOldInputContext )
4247 return;
4249 pFocusWin->mpWindowImpl->mpFrameData->maOldInputContext = rInputContext;
4251 SalInputContext aNewContext;
4252 const Font& rFont = rInputContext.GetFont();
4253 const XubString& rFontName = rFont.GetName();
4254 ImplFontEntry* pFontEntry = NULL;
4255 aNewContext.mpFont = NULL;
4256 if ( rFontName.Len() )
4258 Size aSize = pFocusWin->ImplLogicToDevicePixel( rFont.GetSize() );
4259 if ( !aSize.Height() )
4261 // Nur dann Defaultgroesse setzen, wenn Fonthoehe auch in logischen
4262 // Koordinaaten 0 ist
4263 if ( rFont.GetSize().Height() )
4264 aSize.Height() = 1;
4265 else
4266 aSize.Height() = (12*pFocusWin->mnDPIY)/72;
4268 // TODO: No display device uses ImplDirectFontSubstitution thingy, right? => remove it
4269 ImplDirectFontSubstitution* pFontSubst = NULL;
4270 //if( pFocusWin->mpOutDevData )
4271 // pFontSubst = &pFocusWin->mpOutDevData->maDevFontSubst;
4272 pFontEntry = pFocusWin->mpFontCache->GetFontEntry( pFocusWin->mpFontList,
4273 rFont, aSize, static_cast<float>(aSize.Height()), pFontSubst );
4274 if ( pFontEntry )
4275 aNewContext.mpFont = &pFontEntry->maFontSelData;
4277 aNewContext.meLanguage = rFont.GetLanguage();
4278 aNewContext.mnOptions = rInputContext.GetOptions();
4279 pFocusWin->ImplGetFrame()->SetInputContext( &aNewContext );
4281 if ( pFontEntry )
4282 pFocusWin->mpFontCache->Release( pFontEntry );
4285 // -----------------------------------------------------------------------
4287 Window::Window( WindowType nType )
4289 DBG_CTOR( Window, ImplDbgCheckWindow );
4291 ImplInitWindowData( nType );
4294 // -----------------------------------------------------------------------
4296 Window::Window( Window* pParent, WinBits nStyle )
4298 DBG_CTOR( Window, ImplDbgCheckWindow );
4300 ImplInitWindowData( WINDOW_WINDOW );
4301 ImplInit( pParent, nStyle, NULL );
4304 // -----------------------------------------------------------------------
4306 Window::Window( Window* pParent, const ResId& rResId )
4308 DBG_CTOR( Window, ImplDbgCheckWindow );
4310 ImplInitWindowData( WINDOW_WINDOW );
4311 rResId.SetRT( RSC_WINDOW );
4312 WinBits nStyle = ImplInitRes( rResId );
4313 ImplInit( pParent, nStyle, NULL );
4314 ImplLoadRes( rResId );
4316 if ( !(nStyle & WB_HIDE) )
4317 Show();
4320 // -----------------------------------------------------------------------
4322 Window::~Window()
4324 vcl::LazyDeletor<Window>::Undelete( this );
4326 DBG_DTOR( Window, ImplDbgCheckWindow );
4327 DBG_ASSERT( !mpWindowImpl->mbInDtor, "~Window - already in DTOR!" );
4330 // remove Key and Mouse events issued by Application::PostKey/MouseEvent
4331 Application::RemoveMouseAndKeyEvents( this );
4333 // Dispose of the canvas implementation (which, currently, has an
4334 // own wrapper window as a child to this one.
4335 Reference< rendering::XCanvas > xCanvas( mpWindowImpl->mxCanvas );
4336 if( xCanvas.is() )
4338 uno::Reference < lang::XComponent > xCanvasComponent( xCanvas,
4339 uno::UNO_QUERY );
4340 if( xCanvasComponent.is() )
4341 xCanvasComponent->dispose();
4344 mpWindowImpl->mbInDtor = TRUE;
4346 ImplCallEventListeners( VCLEVENT_OBJECT_DYING );
4348 // do not send child events for frames that were registered as native frames
4349 if( !ImplIsAccessibleNativeFrame() && mpWindowImpl->mbReallyVisible )
4350 if ( ImplIsAccessibleCandidate() && GetAccessibleParentWindow() )
4351 GetAccessibleParentWindow()->ImplCallEventListeners( VCLEVENT_WINDOW_CHILDDESTROYED, this );
4353 // remove associated data structures from dockingmanager
4354 ImplGetDockingManager()->RemoveWindow( this );
4357 // remove ownerdraw decorated windows from list in the top-most frame window
4358 if( (GetStyle() & WB_OWNERDRAWDECORATION) && mpWindowImpl->mbFrame )
4360 ::std::vector< Window* >& rList = ImplGetOwnerDrawList();
4361 ::std::vector< Window* >::iterator p;
4362 p = ::std::find( rList.begin(), rList.end(), this );
4363 if( p != rList.end() )
4364 rList.erase( p );
4367 // shutdown drag and drop
4368 ::com::sun::star::uno::Reference < ::com::sun::star::lang::XComponent > xDnDComponent( mpWindowImpl->mxDNDListenerContainer, ::com::sun::star::uno::UNO_QUERY );
4370 if( xDnDComponent.is() )
4371 xDnDComponent->dispose();
4373 if( mpWindowImpl->mbFrame && mpWindowImpl->mpFrameData )
4377 // deregister drop target listener
4378 if( mpWindowImpl->mpFrameData->mxDropTargetListener.is() )
4380 Reference< XDragGestureRecognizer > xDragGestureRecognizer =
4381 Reference< XDragGestureRecognizer > (mpWindowImpl->mpFrameData->mxDragSource, UNO_QUERY);
4382 if( xDragGestureRecognizer.is() )
4384 xDragGestureRecognizer->removeDragGestureListener(
4385 Reference< XDragGestureListener > (mpWindowImpl->mpFrameData->mxDropTargetListener, UNO_QUERY));
4388 mpWindowImpl->mpFrameData->mxDropTarget->removeDropTargetListener( mpWindowImpl->mpFrameData->mxDropTargetListener );
4389 mpWindowImpl->mpFrameData->mxDropTargetListener.clear();
4392 // shutdown drag and drop for this frame window
4393 Reference< XComponent > xComponent( mpWindowImpl->mpFrameData->mxDropTarget, UNO_QUERY );
4395 // DNDEventDispatcher does not hold a reference of the DropTarget,
4396 // so it's ok if it does not support XComponent
4397 if( xComponent.is() )
4398 xComponent->dispose();
4401 catch ( Exception exc )
4403 // can be safely ignored here.
4407 UnoWrapperBase* pWrapper = Application::GetUnoWrapper( FALSE );
4408 if ( pWrapper )
4409 pWrapper->WindowDestroyed( this );
4411 // MT: Must be called after WindowDestroyed!
4412 // Otherwise, if the accessible is a VCLXWindow, it will try to destroy this window again!
4413 // But accessibility implementations from applications need this dispose.
4414 if ( mpWindowImpl->mxAccessible.is() )
4416 ::com::sun::star::uno::Reference< ::com::sun::star::lang::XComponent> xC( mpWindowImpl->mxAccessible, ::com::sun::star::uno::UNO_QUERY );
4417 if ( xC.is() )
4418 xC->dispose();
4421 ImplSVData* pSVData = ImplGetSVData();
4423 if ( pSVData->maHelpData.mpHelpWin && (pSVData->maHelpData.mpHelpWin->GetParent() == this) )
4424 ImplDestroyHelpWindow( true );
4426 DBG_ASSERT( pSVData->maWinData.mpTrackWin != this,
4427 "Window::~Window(): Window is in TrackingMode" );
4428 DBG_ASSERT( pSVData->maWinData.mpCaptureWin != this,
4429 "Window::~Window(): Window has the mouse captured" );
4430 // #103442# DefModalDialogParent is now determined on-the-fly, so this pointer is unimportant now
4431 //DBG_ASSERT( pSVData->maWinData.mpDefDialogParent != this,
4432 // "Window::~Window(): Window is DefModalDialogParent" );
4434 // Wegen alter kompatibilitaet
4435 if ( pSVData->maWinData.mpTrackWin == this )
4436 EndTracking();
4437 if ( pSVData->maWinData.mpCaptureWin == this )
4438 ReleaseMouse();
4439 if ( pSVData->maWinData.mpDefDialogParent == this )
4440 pSVData->maWinData.mpDefDialogParent = NULL;
4442 #ifdef DBG_UTIL
4443 if ( TRUE ) // always perform these tests in non-pro versions
4445 ByteString aErrorStr;
4446 BOOL bError = FALSE;
4447 Window* pTempWin = mpWindowImpl->mpFrameData->mpFirstOverlap;
4448 while ( pTempWin )
4450 if ( ImplIsRealParentPath( pTempWin ) )
4452 bError = TRUE;
4453 if ( aErrorStr.Len() )
4454 aErrorStr += "; ";
4455 aErrorStr += ByteString( pTempWin->GetText(), RTL_TEXTENCODING_UTF8 );
4457 pTempWin = pTempWin->mpWindowImpl->mpNextOverlap;
4459 if ( bError )
4461 ByteString aTempStr( "Window (" );
4462 aTempStr += ByteString( GetText(), RTL_TEXTENCODING_UTF8 );
4463 aTempStr += ") with living SystemWindow(s) destroyed: ";
4464 aTempStr += aErrorStr;
4465 DBG_ERROR( aTempStr.GetBuffer() );
4466 GetpApp()->Abort( String( aTempStr, RTL_TEXTENCODING_UTF8 ) ); // abort in non-pro version, this must be fixed!
4469 bError = FALSE;
4470 pTempWin = pSVData->maWinData.mpFirstFrame;
4471 while ( pTempWin )
4473 if ( ImplIsRealParentPath( pTempWin ) )
4475 bError = TRUE;
4476 if ( aErrorStr.Len() )
4477 aErrorStr += "; ";
4478 aErrorStr += ByteString( pTempWin->GetText(), RTL_TEXTENCODING_UTF8 );
4480 pTempWin = pTempWin->mpWindowImpl->mpFrameData->mpNextFrame;
4482 if ( bError )
4484 ByteString aTempStr( "Window (" );
4485 aTempStr += ByteString( GetText(), RTL_TEXTENCODING_UTF8 );
4486 aTempStr += ") with living SystemWindow(s) destroyed: ";
4487 aTempStr += aErrorStr;
4488 DBG_ERROR( aTempStr.GetBuffer() );
4489 GetpApp()->Abort( String( aTempStr, RTL_TEXTENCODING_UTF8 ) ); // abort in non-pro version, this must be fixed!
4492 if ( mpWindowImpl->mpFirstChild )
4494 ByteString aTempStr( "Window (" );
4495 aTempStr += ByteString( GetText(), RTL_TEXTENCODING_UTF8 );
4496 aTempStr += ") with living Child(s) destroyed: ";
4497 pTempWin = mpWindowImpl->mpFirstChild;
4498 while ( pTempWin )
4500 aTempStr += ByteString( pTempWin->GetText(), RTL_TEXTENCODING_UTF8 );
4501 pTempWin = pTempWin->mpWindowImpl->mpNext;
4502 if ( pTempWin )
4503 aTempStr += "; ";
4505 DBG_ERROR( aTempStr.GetBuffer() );
4506 GetpApp()->Abort( String( aTempStr, RTL_TEXTENCODING_UTF8 ) ); // abort in non-pro version, this must be fixed!
4509 if ( mpWindowImpl->mpFirstOverlap )
4511 ByteString aTempStr( "Window (" );
4512 aTempStr += ByteString( GetText(), RTL_TEXTENCODING_UTF8 );
4513 aTempStr += ") with living SystemWindow(s) destroyed: ";
4514 pTempWin = mpWindowImpl->mpFirstOverlap;
4515 while ( pTempWin )
4517 aTempStr += ByteString( pTempWin->GetText(), RTL_TEXTENCODING_UTF8 );
4518 pTempWin = pTempWin->mpWindowImpl->mpNext;
4519 if ( pTempWin )
4520 aTempStr += "; ";
4522 DBG_ERROR( aTempStr.GetBuffer() );
4523 GetpApp()->Abort( String( aTempStr, RTL_TEXTENCODING_UTF8 ) ); // abort in non-pro version, this must be fixed!
4526 Window* pMyParent = this;
4527 SystemWindow* pMySysWin = NULL;
4529 while ( pMyParent )
4531 if ( pMyParent->IsSystemWindow() )
4532 pMySysWin = (SystemWindow*)pMyParent;
4533 pMyParent = pMyParent->GetParent();
4535 if ( pMySysWin && pMySysWin->ImplIsInTaskPaneList( this ) )
4537 ByteString aTempStr( "Window (" );
4538 aTempStr += ByteString( GetText(), RTL_TEXTENCODING_UTF8 );
4539 aTempStr += ") still in TaskPanelList!";
4540 DBG_ERROR( aTempStr.GetBuffer() );
4541 GetpApp()->Abort( String( aTempStr, RTL_TEXTENCODING_UTF8 ) ); // abort in non-pro version, this must be fixed!
4544 #endif
4546 if( mpWindowImpl->mbIsInTaskPaneList )
4548 Window* pMyParent = this;
4549 SystemWindow* pMySysWin = NULL;
4551 while ( pMyParent )
4553 if ( pMyParent->IsSystemWindow() )
4554 pMySysWin = (SystemWindow*)pMyParent;
4555 pMyParent = pMyParent->GetParent();
4557 if ( pMySysWin && pMySysWin->ImplIsInTaskPaneList( this ) )
4559 pMySysWin->GetTaskPaneList()->RemoveWindow( this );
4561 else
4563 ByteString aTempStr( "Window (" );
4564 aTempStr += ByteString( GetText(), RTL_TEXTENCODING_UTF8 );
4565 aTempStr += ") not found in TaskPanelList!";
4566 DBG_ERROR( aTempStr.GetBuffer() );
4570 // Fenster hiden, um das entsprechende Paint-Handling auszuloesen
4571 Hide();
4573 // Mitteilen, das Fenster zerstoert wird
4575 NotifyEvent aNEvt( EVENT_DESTROY, this );
4576 Notify( aNEvt );
4579 // EndExtTextInputMode
4580 if ( pSVData->maWinData.mpExtTextInputWin == this )
4582 EndExtTextInput( EXTTEXTINPUT_END_COMPLETE );
4583 if ( pSVData->maWinData.mpExtTextInputWin == this )
4584 pSVData->maWinData.mpExtTextInputWin = NULL;
4587 // check if the focus window is our child
4588 BOOL bHasFocussedChild = FALSE;
4589 if( pSVData->maWinData.mpFocusWin && ImplIsRealParentPath( pSVData->maWinData.mpFocusWin ) )
4591 // #122232#, this must not happen and is an application bug ! but we try some cleanup to hopefully avoid crashes, see below
4592 bHasFocussedChild = TRUE;
4593 #ifdef DBG_UTIL
4594 ByteString aTempStr( "Window (" );
4595 aTempStr += ByteString( GetText(), RTL_TEXTENCODING_UTF8 );
4596 aTempStr += ") with focussed child window destroyed ! THIS WILL LEAD TO CRASHES AND MUST BE FIXED !";
4597 DBG_ERROR( aTempStr.GetBuffer() );
4598 GetpApp()->Abort( String( aTempStr, RTL_TEXTENCODING_UTF8 ) ); // abort in non-pro version, this must be fixed!
4599 #endif
4602 // Wenn wir den Focus haben, dann den Focus auf ein anderes Fenster setzen
4603 Window* pOverlapWindow = ImplGetFirstOverlapWindow();
4604 if ( pSVData->maWinData.mpFocusWin == this
4605 || bHasFocussedChild ) // #122232#, see above, try some cleanup
4607 if ( mpWindowImpl->mbFrame )
4609 pSVData->maWinData.mpFocusWin = NULL;
4610 pOverlapWindow->mpWindowImpl->mpLastFocusWindow = NULL;
4611 GetpApp()->FocusChanged();
4613 else
4615 Window* pParent = GetParent();
4616 Window* pBorderWindow = mpWindowImpl->mpBorderWindow;
4617 // Bei ueberlappenden Fenstern wird der Focus auf den
4618 // Parent vom naechsten FrameWindow gesetzt
4619 if ( pBorderWindow )
4621 if ( pBorderWindow->ImplIsOverlapWindow() )
4622 pParent = pBorderWindow->mpWindowImpl->mpOverlapWindow;
4624 else if ( ImplIsOverlapWindow() )
4625 pParent = mpWindowImpl->mpOverlapWindow;
4627 if ( pParent && pParent->IsEnabled() && pParent->IsInputEnabled() && ! pParent->IsInModalMode() )
4628 pParent->GrabFocus();
4629 else
4630 mpWindowImpl->mpFrameWindow->GrabFocus();
4632 // If the focus was set back to 'this' set it to nothing
4633 if ( pSVData->maWinData.mpFocusWin == this )
4635 pSVData->maWinData.mpFocusWin = NULL;
4636 pOverlapWindow->mpWindowImpl->mpLastFocusWindow = NULL;
4637 GetpApp()->FocusChanged();
4643 if ( pOverlapWindow->mpWindowImpl->mpLastFocusWindow == this )
4644 pOverlapWindow->mpWindowImpl->mpLastFocusWindow = NULL;
4646 // reset hint for DefModalDialogParent
4647 if( pSVData->maWinData.mpActiveApplicationFrame == this )
4648 pSVData->maWinData.mpActiveApplicationFrame = NULL;
4650 // gemerkte Fenster zuruecksetzen
4651 if ( mpWindowImpl->mpFrameData->mpFocusWin == this )
4652 mpWindowImpl->mpFrameData->mpFocusWin = NULL;
4653 if ( mpWindowImpl->mpFrameData->mpMouseMoveWin == this )
4654 mpWindowImpl->mpFrameData->mpMouseMoveWin = NULL;
4655 if ( mpWindowImpl->mpFrameData->mpMouseDownWin == this )
4656 mpWindowImpl->mpFrameData->mpMouseDownWin = NULL;
4658 // Deactivate-Window zuruecksetzen
4659 if ( pSVData->maWinData.mpLastDeacWin == this )
4660 pSVData->maWinData.mpLastDeacWin = NULL;
4662 if ( mpWindowImpl->mbFrame )
4664 if ( mpWindowImpl->mpFrameData->mnFocusId )
4665 Application::RemoveUserEvent( mpWindowImpl->mpFrameData->mnFocusId );
4666 if ( mpWindowImpl->mpFrameData->mnMouseMoveId )
4667 Application::RemoveUserEvent( mpWindowImpl->mpFrameData->mnMouseMoveId );
4670 // Graphic freigeben
4671 ImplReleaseGraphics();
4673 // Evt. anderen Funktion mitteilen, das das Fenster geloescht
4674 // wurde
4675 ImplDelData* pDelData = mpWindowImpl->mpFirstDel;
4676 while ( pDelData )
4678 pDelData->mbDel = TRUE;
4679 pDelData->mpWindow = NULL; // #112873# pDel is not associated with a Window anymore
4680 pDelData = pDelData->mpNext;
4683 // Fenster aus den Listen austragen
4684 ImplRemoveWindow( TRUE );
4686 // de-register as "top window child" at our parent, if necessary
4687 if ( mpWindowImpl->mbFrame )
4689 BOOL bIsTopWindow = mpWindowImpl->mpWinData && ( mpWindowImpl->mpWinData->mnIsTopWindow == 1 );
4690 if ( mpWindowImpl->mpRealParent && bIsTopWindow )
4692 ImplWinData* pParentWinData = mpWindowImpl->mpRealParent->ImplGetWinData();
4694 ::std::list< Window* >::iterator myPos = ::std::find( pParentWinData->maTopWindowChildren.begin(),
4695 pParentWinData->maTopWindowChildren.end(), this );
4696 DBG_ASSERT( myPos != pParentWinData->maTopWindowChildren.end(), "Window::~Window: inconsistency in top window chain!" );
4697 if ( myPos != pParentWinData->maTopWindowChildren.end() )
4698 pParentWinData->maTopWindowChildren.erase( myPos );
4702 // Extra Window Daten loeschen
4703 if ( mpWindowImpl->mpWinData )
4705 if ( mpWindowImpl->mpWinData->mpExtOldText )
4706 delete mpWindowImpl->mpWinData->mpExtOldText;
4707 if ( mpWindowImpl->mpWinData->mpExtOldAttrAry )
4708 delete mpWindowImpl->mpWinData->mpExtOldAttrAry;
4709 if ( mpWindowImpl->mpWinData->mpCursorRect )
4710 delete mpWindowImpl->mpWinData->mpCursorRect;
4711 if ( mpWindowImpl->mpWinData->mpFocusRect )
4712 delete mpWindowImpl->mpWinData->mpFocusRect;
4713 if ( mpWindowImpl->mpWinData->mpTrackRect )
4714 delete mpWindowImpl->mpWinData->mpTrackRect;
4715 // Native widget support
4716 delete mpWindowImpl->mpWinData->mpSalControlHandle;
4717 mpWindowImpl->mpWinData->mpSalControlHandle = NULL;
4719 if ( mpWindowImpl->mpWinData->mpSmartHelpId )
4720 delete mpWindowImpl->mpWinData->mpSmartHelpId;
4721 if ( mpWindowImpl->mpWinData->mpSmartUniqueId )
4722 delete mpWindowImpl->mpWinData->mpSmartUniqueId;
4724 delete mpWindowImpl->mpWinData;
4728 // Overlap-Window-Daten loeschen
4729 if ( mpWindowImpl->mpOverlapData )
4731 delete mpWindowImpl->mpOverlapData;
4734 // Evt. noch BorderWindow oder Frame zerstoeren
4735 if ( mpWindowImpl->mpBorderWindow )
4736 delete mpWindowImpl->mpBorderWindow;
4737 else if ( mpWindowImpl->mbFrame )
4739 if ( pSVData->maWinData.mpFirstFrame == this )
4740 pSVData->maWinData.mpFirstFrame = mpWindowImpl->mpFrameData->mpNextFrame;
4741 else
4743 Window* pSysWin = pSVData->maWinData.mpFirstFrame;
4744 while ( pSysWin->mpWindowImpl->mpFrameData->mpNextFrame != this )
4745 pSysWin = pSysWin->mpWindowImpl->mpFrameData->mpNextFrame;
4746 pSysWin->mpWindowImpl->mpFrameData->mpNextFrame = mpWindowImpl->mpFrameData->mpNextFrame;
4748 mpWindowImpl->mpFrame->SetCallback( NULL, NULL );
4749 pSVData->mpDefInst->DestroyFrame( mpWindowImpl->mpFrame );
4750 delete mpWindowImpl->mpFrameData;
4753 if ( mpWindowImpl->mpChildClipRegion )
4754 delete mpWindowImpl->mpChildClipRegion;
4756 delete mpWindowImpl->mpAccessibleInfos;
4757 delete mpWindowImpl->mpControlFont;
4759 // should be the last statements
4760 delete mpWindowImpl; mpWindowImpl = NULL;
4763 // -----------------------------------------------------------------------
4764 void Window::doLazyDelete()
4766 SystemWindow* pSysWin = dynamic_cast<SystemWindow*>(this);
4767 DockingWindow* pDockWin = dynamic_cast<DockingWindow*>(this);
4768 if( pSysWin || ( pDockWin && pDockWin->IsFloatingMode() ) )
4769 SetParent( ImplGetDefaultWindow() );
4770 vcl::LazyDeletor<Window>::Delete( this );
4773 USHORT Window::GetIndicatorState() const
4775 return mpWindowImpl->mpFrame->GetIndicatorState().mnState;
4778 void Window::SimulateKeyPress( USHORT nKeyCode ) const
4780 mpWindowImpl->mpFrame->SimulateKeyPress(nKeyCode);
4783 // -----------------------------------------------------------------------
4785 void Window::MouseMove( const MouseEvent& rMEvt )
4787 { // Klammerung, da in diesem Handler das Window zerstoert werden darf
4788 DBG_CHKTHIS( Window, ImplDbgCheckWindow );
4791 NotifyEvent aNEvt( EVENT_MOUSEMOVE, this, &rMEvt );
4792 if ( !Notify( aNEvt ) )
4793 mpWindowImpl->mbMouseMove = TRUE;
4796 // -----------------------------------------------------------------------
4798 void Window::MouseButtonDown( const MouseEvent& rMEvt )
4800 { // Klammerung, da in diesem Handler das Window zerstoert werden darf
4801 DBG_CHKTHIS( Window, ImplDbgCheckWindow );
4804 NotifyEvent aNEvt( EVENT_MOUSEBUTTONDOWN, this, &rMEvt );
4805 if ( !Notify( aNEvt ) )
4806 mpWindowImpl->mbMouseButtonDown = TRUE;
4809 // -----------------------------------------------------------------------
4811 void Window::MouseButtonUp( const MouseEvent& rMEvt )
4813 { // Klammerung, da in diesem Handler das Window zerstoert werden darf
4814 DBG_CHKTHIS( Window, ImplDbgCheckWindow );
4817 NotifyEvent aNEvt( EVENT_MOUSEBUTTONUP, this, &rMEvt );
4818 if ( !Notify( aNEvt ) )
4819 mpWindowImpl->mbMouseButtonUp = TRUE;
4822 // -----------------------------------------------------------------------
4824 void Window::KeyInput( const KeyEvent& rKEvt )
4826 { // Klammerung, da in diesem Handler das Window zerstoert werden darf
4827 DBG_CHKTHIS( Window, ImplDbgCheckWindow );
4830 NotifyEvent aNEvt( EVENT_KEYINPUT, this, &rKEvt );
4831 if ( !Notify( aNEvt ) )
4832 mpWindowImpl->mbKeyInput = TRUE;
4835 // -----------------------------------------------------------------------
4837 void Window::KeyUp( const KeyEvent& rKEvt )
4839 { // Klammerung, da in diesem Handler das Window zerstoert werden darf
4840 DBG_CHKTHIS( Window, ImplDbgCheckWindow );
4843 NotifyEvent aNEvt( EVENT_KEYUP, this, &rKEvt );
4844 if ( !Notify( aNEvt ) )
4845 mpWindowImpl->mbKeyUp = TRUE;
4848 // -----------------------------------------------------------------------
4850 void Window::PrePaint()
4854 // -----------------------------------------------------------------------
4856 void Window::Paint( const Rectangle& rRect )
4858 { // Klammerung, da in diesem Handler das Window zerstoert werden darf
4859 DBG_CHKTHIS( Window, ImplDbgCheckWindow );
4862 ImplCallEventListeners( VCLEVENT_WINDOW_PAINT, (void*)&rRect );
4865 // -----------------------------------------------------------------------
4867 void Window::Draw( OutputDevice*, const Point&, const Size&, ULONG )
4869 DBG_CHKTHIS( Window, ImplDbgCheckWindow );
4872 // -----------------------------------------------------------------------
4874 void Window::Move()
4876 DBG_CHKTHIS( Window, ImplDbgCheckWindow );
4879 // -----------------------------------------------------------------------
4881 void Window::Resize()
4883 DBG_CHKTHIS( Window, ImplDbgCheckWindow );
4886 // -----------------------------------------------------------------------
4888 void Window::Activate()
4890 DBG_CHKTHIS( Window, ImplDbgCheckWindow );
4893 // -----------------------------------------------------------------------
4895 void Window::Deactivate()
4897 DBG_CHKTHIS( Window, ImplDbgCheckWindow );
4900 // -----------------------------------------------------------------------
4902 void Window::GetFocus()
4904 { // Klammerung, da in diesem Handler das Window zerstoert werden darf
4905 DBG_CHKTHIS( Window, ImplDbgCheckWindow );
4908 if ( HasFocus() && mpWindowImpl->mpLastFocusWindow && !(mpWindowImpl->mnDlgCtrlFlags & WINDOW_DLGCTRL_WANTFOCUS) )
4910 ImplDelData aDogtag( this );
4911 mpWindowImpl->mpLastFocusWindow->GrabFocus();
4912 if( aDogtag.IsDelete() )
4913 return;
4916 NotifyEvent aNEvt( EVENT_GETFOCUS, this );
4917 Notify( aNEvt );
4920 // -----------------------------------------------------------------------
4922 void Window::LoseFocus()
4924 { // Klammerung, da in diesem Handler das Window zerstoert werden darf
4925 DBG_CHKTHIS( Window, ImplDbgCheckWindow );
4928 NotifyEvent aNEvt( EVENT_LOSEFOCUS, this );
4929 Notify( aNEvt );
4932 // -----------------------------------------------------------------------
4934 void Window::RequestHelp( const HelpEvent& rHEvt )
4936 { // Klammerung, da in diesem Handler das Window zerstoert werden darf
4937 DBG_CHKTHIS( Window, ImplDbgCheckWindow );
4940 // Wenn Balloon-Help angefordert wird, dann den Balloon mit dem
4941 // gesetzten Hilfetext anzeigen
4942 if ( rHEvt.GetMode() & HELPMODE_BALLOON )
4944 const XubString* pStr = &(GetHelpText());
4945 if ( !pStr->Len() )
4946 pStr = &(GetQuickHelpText());
4947 if ( !pStr->Len() && ImplGetParent() && !ImplIsOverlapWindow() )
4948 ImplGetParent()->RequestHelp( rHEvt );
4949 else
4950 Help::ShowBalloon( this, rHEvt.GetMousePosPixel(), *pStr );
4952 else if ( rHEvt.GetMode() & HELPMODE_QUICK )
4954 const XubString* pStr = &(GetQuickHelpText());
4955 if ( !pStr->Len() && ImplGetParent() && !ImplIsOverlapWindow() )
4956 ImplGetParent()->RequestHelp( rHEvt );
4957 else
4959 Point aPos = GetPosPixel();
4960 if ( ImplGetParent() && !ImplIsOverlapWindow() )
4961 aPos = ImplGetParent()->OutputToScreenPixel( aPos );
4962 Rectangle aRect( aPos, GetSizePixel() );
4963 String aHelpText;
4964 if ( pStr->Len() )
4965 aHelpText = GetHelpText();
4966 Help::ShowQuickHelp( this, aRect, *pStr, aHelpText, QUICKHELP_CTRLTEXT );
4969 else
4971 SmartId aSmartId = GetSmartHelpId();
4973 ULONG nNumHelpId = 0;
4974 String aStrHelpId;
4975 if( aSmartId.HasString() )
4976 aStrHelpId = aSmartId.GetStr();
4977 if( aSmartId.HasNumeric() )
4978 nNumHelpId = aSmartId.GetNum();
4980 if ( !nNumHelpId && aStrHelpId.Len() == 0 && ImplGetParent() )
4981 ImplGetParent()->RequestHelp( rHEvt );
4982 else
4984 if ( !nNumHelpId && aStrHelpId.Len() == 0 )
4985 nNumHelpId = OOO_HELP_INDEX;
4987 Help* pHelp = Application::GetHelp();
4988 if ( pHelp )
4990 if( aStrHelpId.Len() > 0 )
4991 pHelp->Start( aStrHelpId, this );
4992 else
4993 pHelp->Start( nNumHelpId, this );
4999 // -----------------------------------------------------------------------
5001 void Window::Command( const CommandEvent& rCEvt )
5003 { // Klammerung, da in diesem Handler das Window zerstoert werden darf
5004 DBG_CHKTHIS( Window, ImplDbgCheckWindow );
5007 ImplCallEventListeners( VCLEVENT_WINDOW_COMMAND, (void*)&rCEvt );
5009 NotifyEvent aNEvt( EVENT_COMMAND, this, &rCEvt );
5010 if ( !Notify( aNEvt ) )
5011 mpWindowImpl->mbCommand = TRUE;
5014 // -----------------------------------------------------------------------
5016 void Window::Tracking( const TrackingEvent& rTEvt )
5018 DBG_CHKTHIS( Window, ImplDbgCheckWindow );
5020 ImplDockingWindowWrapper *pWrapper = ImplGetDockingManager()->GetDockingWindowWrapper( this );
5021 if( pWrapper )
5022 pWrapper->Tracking( rTEvt );
5025 // -----------------------------------------------------------------------
5027 void Window::UserEvent( ULONG, void* )
5029 DBG_CHKTHIS( Window, ImplDbgCheckWindow );
5032 // -----------------------------------------------------------------------
5034 void Window::StateChanged( StateChangedType )
5036 DBG_CHKTHIS( Window, ImplDbgCheckWindow );
5039 // -----------------------------------------------------------------------
5041 void Window::DataChanged( const DataChangedEvent& )
5043 DBG_CHKTHIS( Window, ImplDbgCheckWindow );
5046 // -----------------------------------------------------------------------
5048 void Window::ImplNotifyKeyMouseCommandEventListeners( NotifyEvent& rNEvt )
5050 if( rNEvt.GetType() == EVENT_COMMAND )
5052 const CommandEvent* pCEvt = rNEvt.GetCommandEvent();
5053 if ( pCEvt->GetCommand() != COMMAND_CONTEXTMENU )
5054 // non context menu events are not to be notified up the chain
5055 // so we return immediately
5056 return;
5058 if ( mpWindowImpl->mbCompoundControl || ( rNEvt.GetWindow() == this ) )
5060 if ( rNEvt.GetWindow() == this )
5061 // not interested in: The event listeners are already called in ::Command,
5062 // and calling them here a second time doesn't make sense
5064 else
5066 CommandEvent aCommandEvent = ImplTranslateCommandEvent( *pCEvt, rNEvt.GetWindow(), this );
5067 ImplCallEventListeners( VCLEVENT_WINDOW_COMMAND, &aCommandEvent );
5072 // #82968# notify event listeners for mouse and key events seperately and
5073 // not in PreNotify ( as for focus listeners )
5074 // this allows for procesing those events internally first and pass it to
5075 // the toolkit later
5077 ImplDelData aDelData;
5078 ImplAddDel( &aDelData );
5080 if( rNEvt.GetType() == EVENT_MOUSEMOVE )
5082 if ( mpWindowImpl->mbCompoundControl || ( rNEvt.GetWindow() == this ) )
5084 if ( rNEvt.GetWindow() == this )
5085 ImplCallEventListeners( VCLEVENT_WINDOW_MOUSEMOVE, (void*)rNEvt.GetMouseEvent() );
5086 else
5088 MouseEvent aMouseEvent = ImplTranslateMouseEvent( *rNEvt.GetMouseEvent(), rNEvt.GetWindow(), this );
5089 ImplCallEventListeners( VCLEVENT_WINDOW_MOUSEMOVE, &aMouseEvent );
5093 else if( rNEvt.GetType() == EVENT_MOUSEBUTTONUP )
5095 if ( mpWindowImpl->mbCompoundControl || ( rNEvt.GetWindow() == this ) )
5097 if ( rNEvt.GetWindow() == this )
5098 ImplCallEventListeners( VCLEVENT_WINDOW_MOUSEBUTTONUP, (void*)rNEvt.GetMouseEvent() );
5099 else
5101 MouseEvent aMouseEvent = ImplTranslateMouseEvent( *rNEvt.GetMouseEvent(), rNEvt.GetWindow(), this );
5102 ImplCallEventListeners( VCLEVENT_WINDOW_MOUSEBUTTONUP, &aMouseEvent );
5106 else if( rNEvt.GetType() == EVENT_MOUSEBUTTONDOWN )
5108 if ( mpWindowImpl->mbCompoundControl || ( rNEvt.GetWindow() == this ) )
5110 if ( rNEvt.GetWindow() == this )
5111 ImplCallEventListeners( VCLEVENT_WINDOW_MOUSEBUTTONDOWN, (void*)rNEvt.GetMouseEvent() );
5112 else
5114 MouseEvent aMouseEvent = ImplTranslateMouseEvent( *rNEvt.GetMouseEvent(), rNEvt.GetWindow(), this );
5115 ImplCallEventListeners( VCLEVENT_WINDOW_MOUSEBUTTONDOWN, &aMouseEvent );
5119 else if( rNEvt.GetType() == EVENT_KEYINPUT )
5121 if ( mpWindowImpl->mbCompoundControl || ( rNEvt.GetWindow() == this ) )
5122 ImplCallEventListeners( VCLEVENT_WINDOW_KEYINPUT, (void*)rNEvt.GetKeyEvent() );
5124 else if( rNEvt.GetType() == EVENT_KEYUP )
5126 if ( mpWindowImpl->mbCompoundControl || ( rNEvt.GetWindow() == this ) )
5127 ImplCallEventListeners( VCLEVENT_WINDOW_KEYUP, (void*)rNEvt.GetKeyEvent() );
5130 if ( aDelData.IsDelete() )
5131 return;
5132 ImplRemoveDel( &aDelData );
5134 // #106721# check if we're part of a compound control and notify
5135 Window *pParent = ImplGetParent();
5136 while( pParent )
5138 if( pParent->IsCompoundControl() )
5140 pParent->ImplNotifyKeyMouseCommandEventListeners( rNEvt );
5141 break;
5143 pParent = pParent->ImplGetParent();
5147 // -----------------------------------------------------------------------
5149 long Window::PreNotify( NotifyEvent& rNEvt )
5151 { // Klammerung, da in diesem Handler das Window zerstoert werden darf
5152 DBG_CHKTHIS( Window, ImplDbgCheckWindow );
5155 long bDone = FALSE;
5156 if ( mpWindowImpl->mpParent && !ImplIsOverlapWindow() )
5157 bDone = mpWindowImpl->mpParent->PreNotify( rNEvt );
5159 if ( !bDone )
5161 if( rNEvt.GetType() == EVENT_GETFOCUS )
5163 BOOL bCompoundFocusChanged = FALSE;
5164 if ( mpWindowImpl->mbCompoundControl && !mpWindowImpl->mbCompoundControlHasFocus && HasChildPathFocus() )
5166 mpWindowImpl->mbCompoundControlHasFocus = TRUE;
5167 bCompoundFocusChanged = TRUE;
5170 if ( bCompoundFocusChanged || ( rNEvt.GetWindow() == this ) )
5171 ImplCallEventListeners( VCLEVENT_WINDOW_GETFOCUS );
5173 else if( rNEvt.GetType() == EVENT_LOSEFOCUS )
5175 BOOL bCompoundFocusChanged = FALSE;
5176 if ( mpWindowImpl->mbCompoundControl && mpWindowImpl->mbCompoundControlHasFocus && !HasChildPathFocus() )
5178 mpWindowImpl->mbCompoundControlHasFocus = FALSE ;
5179 bCompoundFocusChanged = TRUE;
5182 if ( bCompoundFocusChanged || ( rNEvt.GetWindow() == this ) )
5183 ImplCallEventListeners( VCLEVENT_WINDOW_LOSEFOCUS );
5186 // #82968# mouse and key events will be notified after processing ( in ImplNotifyKeyMouseCommandEventListeners() )!
5187 // see also ImplHandleMouseEvent(), ImplHandleKey()
5190 else if( rNEvt.GetType() == EVENT_MOUSEMOVE )
5192 if ( mpWindowImpl->mbCompoundControl || ( rNEvt.GetWindow() == this ) )
5194 if ( rNEvt.GetWindow() == this )
5195 ImplCallEventListeners( VCLEVENT_WINDOW_MOUSEMOVE, (void*)rNEvt.GetMouseEvent() );
5196 else
5197 ImplCallEventListeners( VCLEVENT_WINDOW_MOUSEMOVE, &ImplTranslateMouseEvent( *rNEvt.GetMouseEvent(), rNEvt.GetWindow(), this ) );
5200 else if( rNEvt.GetType() == EVENT_MOUSEBUTTONUP )
5202 if ( mpWindowImpl->mbCompoundControl || ( rNEvt.GetWindow() == this ) )
5204 if ( rNEvt.GetWindow() == this )
5205 ImplCallEventListeners( VCLEVENT_WINDOW_MOUSEBUTTONUP, (void*)rNEvt.GetMouseEvent() );
5206 else
5207 ImplCallEventListeners( VCLEVENT_WINDOW_MOUSEBUTTONUP, &ImplTranslateMouseEvent( *rNEvt.GetMouseEvent(), rNEvt.GetWindow(), this ) );
5210 else if( rNEvt.GetType() == EVENT_MOUSEBUTTONDOWN )
5212 if ( mpWindowImpl->mbCompoundControl || ( rNEvt.GetWindow() == this ) )
5214 if ( rNEvt.GetWindow() == this )
5215 ImplCallEventListeners( VCLEVENT_WINDOW_MOUSEBUTTONDOWN, (void*)rNEvt.GetMouseEvent() );
5216 else
5217 ImplCallEventListeners( VCLEVENT_WINDOW_MOUSEBUTTONDOWN, &ImplTranslateMouseEvent( *rNEvt.GetMouseEvent(), rNEvt.GetWindow(), this ) );
5220 else if( rNEvt.GetType() == EVENT_KEYINPUT )
5222 if ( mpWindowImpl->mbCompoundControl || ( rNEvt.GetWindow() == this ) )
5223 ImplCallEventListeners( VCLEVENT_WINDOW_KEYINPUT, (void*)rNEvt.GetKeyEvent() );
5225 else if( rNEvt.GetType() == EVENT_KEYUP )
5227 if ( mpWindowImpl->mbCompoundControl || ( rNEvt.GetWindow() == this ) )
5228 ImplCallEventListeners( VCLEVENT_WINDOW_KEYUP, (void*)rNEvt.GetKeyEvent() );
5233 return bDone;
5236 // -----------------------------------------------------------------------
5238 long Window::Notify( NotifyEvent& rNEvt )
5240 { // Klammerung, da in diesem Handler das Window zerstoert werden darf
5241 DBG_CHKTHIS( Window, ImplDbgCheckWindow );
5244 long nRet = FALSE;
5246 // check for docking window
5247 // but do nothing if window is docked and locked
5248 ImplDockingWindowWrapper *pWrapper = ImplGetDockingManager()->GetDockingWindowWrapper( this );
5249 if( pWrapper && !( !pWrapper->IsFloatingMode() && pWrapper->IsLocked() ) )
5251 if ( rNEvt.GetType() == EVENT_MOUSEBUTTONDOWN )
5253 const MouseEvent* pMEvt = rNEvt.GetMouseEvent();
5254 BOOL bHit = pWrapper->GetDragArea().IsInside( pMEvt->GetPosPixel() );
5255 if ( pMEvt->IsLeft() )
5257 if ( pMEvt->IsMod1() && (pMEvt->GetClicks() == 2) )
5259 // ctrl double click toggles floating mode
5260 pWrapper->SetFloatingMode( !pWrapper->IsFloatingMode() );
5261 return TRUE;
5263 else if ( pMEvt->GetClicks() == 1 && bHit)
5265 // allow start docking during mouse move
5266 pWrapper->ImplEnableStartDocking();
5267 return TRUE;
5271 else if ( rNEvt.GetType() == EVENT_MOUSEMOVE )
5273 const MouseEvent* pMEvt = rNEvt.GetMouseEvent();
5274 BOOL bHit = pWrapper->GetDragArea().IsInside( pMEvt->GetPosPixel() );
5275 if ( pMEvt->IsLeft() )
5277 // check if a single click initiated this sequence ( ImplStartDockingEnabled() )
5278 // check if window is docked and
5279 if( pWrapper->ImplStartDockingEnabled() && !pWrapper->IsFloatingMode() &&
5280 !pWrapper->IsDocking() && bHit )
5282 Point aPos = pMEvt->GetPosPixel();
5283 Window* pWindow = rNEvt.GetWindow();
5284 if ( pWindow != this )
5286 aPos = pWindow->OutputToScreenPixel( aPos );
5287 aPos = ScreenToOutputPixel( aPos );
5289 pWrapper->ImplStartDocking( aPos );
5291 return TRUE;
5294 else if( rNEvt.GetType() == EVENT_KEYINPUT )
5296 const KeyCode& rKey = rNEvt.GetKeyEvent()->GetKeyCode();
5297 if( rKey.GetCode() == KEY_F10 && rKey.GetModifier() &&
5298 rKey.IsShift() && rKey.IsMod1() )
5300 pWrapper->SetFloatingMode( !pWrapper->IsFloatingMode() );
5301 /* At this point the floating toolbar frame does not have the
5302 * input focus since these frames don't get the focus per default
5303 * To enable keyboard handling of this toolbar set the input focus
5304 * to the frame. This needs to be done with ToTop since GrabFocus
5305 * would not notice any change since "this" already has the focus.
5307 if( pWrapper->IsFloatingMode() )
5308 ToTop( TOTOP_GRABFOCUSONLY );
5309 return TRUE;
5314 // Dialog-Steuerung
5315 if ( (GetStyle() & (WB_DIALOGCONTROL | WB_NODIALOGCONTROL)) == WB_DIALOGCONTROL )
5317 // Wenn Parent auch DialogSteuerung aktiviert hat, uebernimmt dieser die Steuerung
5318 if ( (rNEvt.GetType() == EVENT_KEYINPUT) || (rNEvt.GetType() == EVENT_KEYUP) )
5320 if ( ImplIsOverlapWindow() ||
5321 ((ImplGetParent()->GetStyle() & (WB_DIALOGCONTROL | WB_NODIALOGCONTROL)) != WB_DIALOGCONTROL) )
5323 nRet = ImplDlgCtrl( *rNEvt.GetKeyEvent(), rNEvt.GetType() == EVENT_KEYINPUT );
5326 else if ( (rNEvt.GetType() == EVENT_GETFOCUS) || (rNEvt.GetType() == EVENT_LOSEFOCUS) )
5328 ImplDlgCtrlFocusChanged( rNEvt.GetWindow(), rNEvt.GetType() == EVENT_GETFOCUS );
5329 if ( (rNEvt.GetWindow() == this) && (rNEvt.GetType() == EVENT_GETFOCUS) &&
5330 !(GetStyle() & WB_TABSTOP) && !(mpWindowImpl->mnDlgCtrlFlags & WINDOW_DLGCTRL_WANTFOCUS) )
5332 USHORT n = 0;
5333 Window* pFirstChild = ImplGetDlgWindow( n, DLGWINDOW_FIRST );
5334 if ( pFirstChild )
5335 pFirstChild->ImplControlFocus();
5340 if ( !nRet )
5342 if ( mpWindowImpl->mpParent && !ImplIsOverlapWindow() )
5343 nRet = mpWindowImpl->mpParent->Notify( rNEvt );
5346 return nRet;
5349 // -----------------------------------------------------------------------
5351 void Window::ImplCallEventListeners( ULONG nEvent, void* pData )
5353 // The implementation was moved to CallEventListeners(),
5354 // because derived classes in svtools must be able to
5355 // call the event listeners and ImplCallEventListeners()
5356 // is not exported.
5357 // TODO: replace ImplCallEventListeners() by CallEventListeners() in vcl
5359 CallEventListeners( nEvent, pData );
5362 // -----------------------------------------------------------------------
5364 void Window::CallEventListeners( ULONG nEvent, void* pData )
5366 VclWindowEvent aEvent( this, nEvent, pData );
5368 ImplDelData aDelData;
5369 ImplAddDel( &aDelData );
5371 ImplGetSVData()->mpApp->ImplCallEventListeners( &aEvent );
5373 if ( aDelData.IsDelete() )
5374 return;
5376 if ( !mpWindowImpl->maEventListeners.empty() )
5377 mpWindowImpl->maEventListeners.Call( &aEvent );
5379 if ( aDelData.IsDelete() )
5380 return;
5382 ImplRemoveDel( &aDelData );
5384 Window* pWindow = this;
5385 while ( pWindow )
5387 pWindow->ImplAddDel( &aDelData );
5389 if ( !pWindow->mpWindowImpl->maChildEventListeners.empty() )
5390 pWindow->mpWindowImpl->maChildEventListeners.Call( &aEvent );
5392 if ( aDelData.IsDelete() )
5393 return;
5395 pWindow->ImplRemoveDel( &aDelData );
5397 pWindow = pWindow->GetParent();
5401 void Window::FireVclEvent( VclSimpleEvent* pEvent )
5403 ImplGetSVData()->mpApp->ImplCallEventListeners(pEvent);
5406 // -----------------------------------------------------------------------
5408 void Window::AddEventListener( const Link& rEventListener )
5410 mpWindowImpl->maEventListeners.push_back( rEventListener );
5413 // -----------------------------------------------------------------------
5415 void Window::RemoveEventListener( const Link& rEventListener )
5417 mpWindowImpl->maEventListeners.remove( rEventListener );
5420 // -----------------------------------------------------------------------
5422 void Window::AddChildEventListener( const Link& rEventListener )
5424 mpWindowImpl->maChildEventListeners.push_back( rEventListener );
5427 // -----------------------------------------------------------------------
5429 void Window::RemoveChildEventListener( const Link& rEventListener )
5431 mpWindowImpl->maChildEventListeners.remove( rEventListener );
5434 // -----------------------------------------------------------------------
5436 ULONG Window::PostUserEvent( ULONG nEvent, void* pEventData )
5438 ULONG nEventId;
5439 PostUserEvent( nEventId, nEvent, pEventData );
5440 return nEventId;
5443 // -----------------------------------------------------------------------
5445 ULONG Window::PostUserEvent( const Link& rLink, void* pCaller )
5447 ULONG nEventId;
5448 PostUserEvent( nEventId, rLink, pCaller );
5449 return nEventId;
5452 // -----------------------------------------------------------------------
5454 BOOL Window::PostUserEvent( ULONG& rEventId, ULONG nEvent, void* pEventData )
5456 DBG_CHKTHIS( Window, ImplDbgCheckWindow );
5458 ImplSVEvent* pSVEvent = new ImplSVEvent;
5459 pSVEvent->mnEvent = nEvent;
5460 pSVEvent->mpData = pEventData;
5461 pSVEvent->mpLink = NULL;
5462 pSVEvent->mpWindow = this;
5463 pSVEvent->mbCall = TRUE;
5464 ImplAddDel( &(pSVEvent->maDelData) );
5465 rEventId = (ULONG)pSVEvent;
5466 if ( mpWindowImpl->mpFrame->PostEvent( pSVEvent ) )
5467 return TRUE;
5468 else
5470 rEventId = 0;
5471 ImplRemoveDel( &(pSVEvent->maDelData) );
5472 delete pSVEvent;
5473 return FALSE;
5477 // -----------------------------------------------------------------------
5479 BOOL Window::PostUserEvent( ULONG& rEventId, const Link& rLink, void* pCaller )
5481 DBG_CHKTHIS( Window, ImplDbgCheckWindow );
5483 ImplSVEvent* pSVEvent = new ImplSVEvent;
5484 pSVEvent->mnEvent = 0;
5485 pSVEvent->mpData = pCaller;
5486 pSVEvent->mpLink = new Link( rLink );
5487 pSVEvent->mpWindow = this;
5488 pSVEvent->mbCall = TRUE;
5489 ImplAddDel( &(pSVEvent->maDelData) );
5490 rEventId = (ULONG)pSVEvent;
5491 if ( mpWindowImpl->mpFrame->PostEvent( pSVEvent ) )
5492 return TRUE;
5493 else
5495 rEventId = 0;
5496 ImplRemoveDel( &(pSVEvent->maDelData) );
5497 delete pSVEvent;
5498 return FALSE;
5502 // -----------------------------------------------------------------------
5504 void Window::RemoveUserEvent( ULONG nUserEvent )
5506 DBG_CHKTHIS( Window, ImplDbgCheckWindow );
5508 ImplSVEvent* pSVEvent = (ImplSVEvent*)nUserEvent;
5510 DBG_ASSERT( pSVEvent->mpWindow == this,
5511 "Window::RemoveUserEvent(): Event doesn't send to this window or is already removed" );
5512 DBG_ASSERT( pSVEvent->mbCall,
5513 "Window::RemoveUserEvent(): Event is already removed" );
5515 if ( pSVEvent->mpWindow )
5517 pSVEvent->mpWindow->ImplRemoveDel( &(pSVEvent->maDelData) );
5518 pSVEvent->mpWindow = NULL;
5521 pSVEvent->mbCall = FALSE;
5524 // -----------------------------------------------------------------------
5526 IMPL_LINK( Window, ImplAsyncStateChangedHdl, void*, pState )
5528 StateChanged( (StateChangedType)(ULONG)pState );
5529 return 0;
5532 // -----------------------------------------------------------------------
5534 void Window::PostStateChanged( StateChangedType nState )
5536 DBG_CHKTHIS( Window, ImplDbgCheckWindow );
5538 PostUserEvent( LINK( this, Window, ImplAsyncStateChangedHdl ), (void*)(ULONG)nState );
5541 // -----------------------------------------------------------------------
5543 BOOL Window::IsLocked( BOOL bChilds ) const
5545 if ( mpWindowImpl->mnLockCount != 0 )
5546 return TRUE;
5548 if ( bChilds || mpWindowImpl->mbChildNotify )
5550 Window* pChild = mpWindowImpl->mpFirstChild;
5551 while ( pChild )
5553 if ( pChild->IsLocked( TRUE ) )
5554 return TRUE;
5555 pChild = pChild->mpWindowImpl->mpNext;
5559 return FALSE;
5562 // -----------------------------------------------------------------------
5564 void Window::SetStyle( WinBits nStyle )
5566 DBG_CHKTHIS( Window, ImplDbgCheckWindow );
5568 if ( mpWindowImpl->mnStyle != nStyle )
5570 mpWindowImpl->mnPrevStyle = mpWindowImpl->mnStyle;
5571 mpWindowImpl->mnStyle = nStyle;
5572 StateChanged( STATE_CHANGE_STYLE );
5576 // -----------------------------------------------------------------------
5578 void Window::SetExtendedStyle( WinBits nExtendedStyle )
5580 DBG_CHKTHIS( Window, ImplDbgCheckWindow );
5582 if ( mpWindowImpl->mnExtendedStyle != nExtendedStyle )
5584 Window* pWindow = ImplGetBorderWindow();
5585 if( ! pWindow )
5586 pWindow = this;
5587 if( pWindow->mpWindowImpl->mbFrame )
5589 SalExtStyle nExt = 0;
5590 if( (nExtendedStyle & WB_EXT_DOCUMENT) )
5591 nExt |= SAL_FRAME_EXT_STYLE_DOCUMENT;
5592 if( (nExtendedStyle & WB_EXT_DOCMODIFIED) )
5593 nExt |= SAL_FRAME_EXT_STYLE_DOCMODIFIED;
5595 pWindow->ImplGetFrame()->SetExtendedFrameStyle( nExt );
5597 mpWindowImpl->mnPrevExtendedStyle = mpWindowImpl->mnExtendedStyle;
5598 mpWindowImpl->mnExtendedStyle = nExtendedStyle;
5599 StateChanged( STATE_CHANGE_EXTENDEDSTYLE );
5603 // -----------------------------------------------------------------------
5605 SystemWindow* Window::GetSystemWindow() const
5607 DBG_CHKTHIS( Window, ImplDbgCheckWindow );
5609 const Window* pWin = this;
5610 while ( pWin && !pWin->IsSystemWindow() )
5611 pWin = pWin->GetParent();
5612 return (SystemWindow*)pWin;
5615 // -----------------------------------------------------------------------
5617 void Window::SetBorderStyle( USHORT nBorderStyle )
5619 DBG_CHKTHIS( Window, ImplDbgCheckWindow );
5621 if ( mpWindowImpl->mpBorderWindow )
5623 if( nBorderStyle == WINDOW_BORDER_REMOVEBORDER &&
5624 ! mpWindowImpl->mpBorderWindow->mpWindowImpl->mbFrame &&
5625 mpWindowImpl->mpBorderWindow->mpWindowImpl->mpParent
5628 // this is a little awkward: some controls (e.g. svtools ProgressBar)
5629 // cannot avoid getting constructed with WB_BORDER but want to disable
5630 // borders in case of NWF drawing. So they need a method to remove their border window
5631 Window* pBorderWin = mpWindowImpl->mpBorderWindow;
5632 // remove us as border window's client
5633 pBorderWin->mpWindowImpl->mpClientWindow = NULL;
5634 mpWindowImpl->mpBorderWindow = NULL;
5635 mpWindowImpl->mpRealParent = pBorderWin->mpWindowImpl->mpParent;
5636 // reparent us above the border window
5637 SetParent( pBorderWin->mpWindowImpl->mpParent );
5638 // set us to the position and size of our previous border
5639 Point aBorderPos( pBorderWin->GetPosPixel() );
5640 Size aBorderSize( pBorderWin->GetSizePixel() );
5641 SetPosSizePixel( aBorderPos.X(), aBorderPos.Y(), aBorderSize.Width(), aBorderSize.Height() );
5642 // release border window
5643 delete pBorderWin;
5645 // set new style bits
5646 SetStyle( GetStyle() & (~WB_BORDER) );
5648 else
5650 if ( mpWindowImpl->mpBorderWindow->GetType() == WINDOW_BORDERWINDOW )
5651 ((ImplBorderWindow*)mpWindowImpl->mpBorderWindow)->SetBorderStyle( nBorderStyle );
5652 else
5653 mpWindowImpl->mpBorderWindow->SetBorderStyle( nBorderStyle );
5658 // -----------------------------------------------------------------------
5660 USHORT Window::GetBorderStyle() const
5662 DBG_CHKTHIS( Window, ImplDbgCheckWindow );
5664 if ( mpWindowImpl->mpBorderWindow )
5666 if ( mpWindowImpl->mpBorderWindow->GetType() == WINDOW_BORDERWINDOW )
5667 return ((ImplBorderWindow*)mpWindowImpl->mpBorderWindow)->GetBorderStyle();
5668 else
5669 return mpWindowImpl->mpBorderWindow->GetBorderStyle();
5672 return 0;
5675 // -----------------------------------------------------------------------
5677 long Window::CalcTitleWidth() const
5679 DBG_CHKTHIS( Window, ImplDbgCheckWindow );
5681 if ( mpWindowImpl->mpBorderWindow )
5683 if ( mpWindowImpl->mpBorderWindow->GetType() == WINDOW_BORDERWINDOW )
5684 return ((ImplBorderWindow*)mpWindowImpl->mpBorderWindow)->CalcTitleWidth();
5685 else
5686 return mpWindowImpl->mpBorderWindow->CalcTitleWidth();
5688 else if ( mpWindowImpl->mbFrame && (mpWindowImpl->mnStyle & WB_MOVEABLE) )
5690 // Fuer Frame-Fenster raten wir die Breite, da wir den Border fuer
5691 // externe Dialoge nicht kennen
5692 const StyleSettings& rStyleSettings = GetSettings().GetStyleSettings();
5693 Font aFont = GetFont();
5694 ((Window*)this)->SetPointFont( rStyleSettings.GetTitleFont() );
5695 long nTitleWidth = GetTextWidth( GetText() );
5696 ((Window*)this)->SetFont( aFont );
5697 nTitleWidth += rStyleSettings.GetTitleHeight() * 3;
5698 nTitleWidth += rStyleSettings.GetBorderSize() * 2;
5699 nTitleWidth += 10;
5700 return nTitleWidth;
5703 return 0;
5706 // -----------------------------------------------------------------------
5708 void Window::EnableClipSiblings( BOOL bClipSiblings )
5710 DBG_CHKTHIS( Window, ImplDbgCheckWindow );
5712 if ( mpWindowImpl->mpBorderWindow )
5713 mpWindowImpl->mpBorderWindow->EnableClipSiblings( bClipSiblings );
5715 mpWindowImpl->mbClipSiblings = bClipSiblings;
5718 // -----------------------------------------------------------------------
5720 void Window::SetMouseTransparent( BOOL bTransparent )
5722 DBG_CHKTHIS( Window, ImplDbgCheckWindow );
5724 if ( mpWindowImpl->mpBorderWindow )
5725 mpWindowImpl->mpBorderWindow->SetMouseTransparent( bTransparent );
5727 if( mpWindowImpl->mpSysObj )
5728 mpWindowImpl->mpSysObj->SetMouseTransparent( bTransparent );
5730 mpWindowImpl->mbMouseTransparent = bTransparent;
5733 // -----------------------------------------------------------------------
5735 void Window::SetPaintTransparent( BOOL bTransparent )
5737 DBG_CHKTHIS( Window, ImplDbgCheckWindow );
5739 // transparency is not useful for frames as the background would have to be provided by a different frame
5740 if( bTransparent && mpWindowImpl->mbFrame )
5741 return;
5743 if ( mpWindowImpl->mpBorderWindow )
5744 mpWindowImpl->mpBorderWindow->SetPaintTransparent( bTransparent );
5746 mpWindowImpl->mbPaintTransparent = bTransparent;
5749 // -----------------------------------------------------------------------
5751 void Window::SetInputContext( const InputContext& rInputContext )
5753 DBG_CHKTHIS( Window, ImplDbgCheckWindow );
5755 mpWindowImpl->maInputContext = rInputContext;
5756 if ( !mpWindowImpl->mbInFocusHdl && HasFocus() )
5757 ImplNewInputContext();
5760 // -----------------------------------------------------------------------
5762 void Window::EndExtTextInput( USHORT nFlags )
5764 DBG_CHKTHIS( Window, ImplDbgCheckWindow );
5766 if ( mpWindowImpl->mbExtTextInput )
5767 ImplGetFrame()->EndExtTextInput( nFlags );
5770 // -----------------------------------------------------------------------
5772 void Window::SetCursorRect( const Rectangle* pRect, long nExtTextInputWidth )
5774 DBG_CHKTHIS( Window, ImplDbgCheckWindow );
5776 ImplWinData* pWinData = ImplGetWinData();
5777 if ( pWinData->mpCursorRect )
5779 if ( pRect )
5780 *pWinData->mpCursorRect = *pRect;
5781 else
5783 delete pWinData->mpCursorRect;
5784 pWinData->mpCursorRect = NULL;
5787 else
5789 if ( pRect )
5790 pWinData->mpCursorRect = new Rectangle( *pRect );
5793 pWinData->mnCursorExtWidth = nExtTextInputWidth;
5797 // -----------------------------------------------------------------------
5799 const Rectangle* Window::GetCursorRect() const
5801 DBG_CHKTHIS( Window, ImplDbgCheckWindow );
5803 ImplWinData* pWinData = ImplGetWinData();
5804 return pWinData->mpCursorRect;
5807 // -----------------------------------------------------------------------
5809 long Window::GetCursorExtTextInputWidth() const
5811 DBG_CHKTHIS( Window, ImplDbgCheckWindow );
5813 ImplWinData* pWinData = ImplGetWinData();
5814 return pWinData->mnCursorExtWidth;
5817 // -----------------------------------------------------------------------
5818 void Window::SetSettings( const AllSettings& rSettings )
5820 SetSettings( rSettings, FALSE );
5823 void Window::SetSettings( const AllSettings& rSettings, BOOL bChild )
5825 DBG_CHKTHIS( Window, ImplDbgCheckWindow );
5827 if ( mpWindowImpl->mpBorderWindow )
5829 mpWindowImpl->mpBorderWindow->SetSettings( rSettings, FALSE );
5830 if ( (mpWindowImpl->mpBorderWindow->GetType() == WINDOW_BORDERWINDOW) &&
5831 ((ImplBorderWindow*)mpWindowImpl->mpBorderWindow)->mpMenuBarWindow )
5832 ((ImplBorderWindow*)mpWindowImpl->mpBorderWindow)->mpMenuBarWindow->SetSettings( rSettings, TRUE );
5835 AllSettings aOldSettings = maSettings;
5836 OutputDevice::SetSettings( rSettings );
5837 ULONG nChangeFlags = aOldSettings.GetChangeFlags( rSettings );
5839 // AppFont-Aufloesung und DPI-Aufloesung neu berechnen
5840 ImplInitResolutionSettings();
5842 if ( nChangeFlags )
5844 DataChangedEvent aDCEvt( DATACHANGED_SETTINGS, &aOldSettings, nChangeFlags );
5845 DataChanged( aDCEvt );
5848 if ( bChild || mpWindowImpl->mbChildNotify )
5850 Window* pChild = mpWindowImpl->mpFirstChild;
5851 while ( pChild )
5853 pChild->SetSettings( rSettings, bChild );
5854 pChild = pChild->mpWindowImpl->mpNext;
5859 // -----------------------------------------------------------------------
5861 void Window::UpdateSettings( const AllSettings& rSettings, BOOL bChild )
5863 DBG_CHKTHIS( Window, ImplDbgCheckWindow );
5865 if ( mpWindowImpl->mpBorderWindow )
5867 mpWindowImpl->mpBorderWindow->UpdateSettings( rSettings, FALSE );
5868 if ( (mpWindowImpl->mpBorderWindow->GetType() == WINDOW_BORDERWINDOW) &&
5869 ((ImplBorderWindow*)mpWindowImpl->mpBorderWindow)->mpMenuBarWindow )
5870 ((ImplBorderWindow*)mpWindowImpl->mpBorderWindow)->mpMenuBarWindow->UpdateSettings( rSettings, TRUE );
5873 AllSettings aOldSettings = maSettings;
5874 ULONG nChangeFlags = maSettings.Update( maSettings.GetWindowUpdate(), rSettings );
5875 nChangeFlags |= SETTINGS_IN_UPDATE_SETTINGS; // Set this flag so the receiver of the data changed
5876 // event can distinguish between the changing of global
5877 // setting and a local change ( with SetSettings )
5879 // AppFont-Aufloesung und DPI-Aufloesung neu berechnen
5880 ImplInitResolutionSettings();
5882 /* #i73785#
5883 * do not overwrite a WheelBehavior with false
5884 * this looks kind of a hack, but WheelBehavior
5885 * is always a local change, not a system property,
5886 * so we can spare all our users the hassle of reacting on
5887 * this in their respective DataChanged.
5889 MouseSettings aSet( maSettings.GetMouseSettings() );
5890 aSet.SetWheelBehavior( aOldSettings.GetMouseSettings().GetWheelBehavior() );
5891 maSettings.SetMouseSettings( aSet );
5893 if( (nChangeFlags & SETTINGS_STYLE) && IsBackground() )
5895 Wallpaper aWallpaper = GetBackground();
5896 if( !aWallpaper.IsBitmap() && !aWallpaper.IsGradient() )
5898 if ( mpWindowImpl->mnStyle & WB_3DLOOK )
5899 SetBackground( Wallpaper( rSettings.GetStyleSettings().GetFaceColor() ) );
5900 else
5901 SetBackground( Wallpaper( rSettings.GetStyleSettings().GetWindowColor() ) );
5905 if ( nChangeFlags )
5907 DataChangedEvent aDCEvt( DATACHANGED_SETTINGS, &aOldSettings, nChangeFlags );
5908 DataChanged( aDCEvt );
5909 // notify data change handler
5910 ImplCallEventListeners( VCLEVENT_WINDOW_DATACHANGED, &aDCEvt);
5913 if ( bChild || mpWindowImpl->mbChildNotify )
5915 Window* pChild = mpWindowImpl->mpFirstChild;
5916 while ( pChild )
5918 pChild->UpdateSettings( rSettings, bChild );
5919 pChild = pChild->mpWindowImpl->mpNext;
5924 // -----------------------------------------------------------------------
5926 void Window::NotifyAllChilds( DataChangedEvent& rDCEvt )
5928 DBG_CHKTHIS( Window, ImplDbgCheckWindow );
5930 DataChanged( rDCEvt );
5932 Window* pChild = mpWindowImpl->mpFirstChild;
5933 while ( pChild )
5935 pChild->NotifyAllChilds( rDCEvt );
5936 pChild = pChild->mpWindowImpl->mpNext;
5940 // -----------------------------------------------------------------------
5942 void Window::SetPointFont( const Font& rFont )
5944 DBG_CHKTHIS( Window, ImplDbgCheckWindow );
5946 Font aFont = rFont;
5947 ImplPointToLogic( aFont );
5948 SetFont( aFont );
5951 // -----------------------------------------------------------------------
5953 Font Window::GetPointFont() const
5955 DBG_CHKTHIS( Window, ImplDbgCheckWindow );
5957 Font aFont = GetFont();
5958 ImplLogicToPoint( aFont );
5959 return aFont;
5962 // -----------------------------------------------------------------------
5964 // TODO: remove in next incompatible build
5965 void Window::GetFontResolution( sal_Int32& nDPIX, sal_Int32& nDPIY ) const
5967 DBG_CHKTHIS( Window, ImplDbgCheckWindow );
5969 nDPIX = mpWindowImpl->mpFrameData->mnDPIX;
5970 nDPIY = mpWindowImpl->mpFrameData->mnDPIY;
5973 // -----------------------------------------------------------------------
5975 void Window::SetParentClipMode( USHORT nMode )
5977 DBG_CHKTHIS( Window, ImplDbgCheckWindow );
5979 if ( mpWindowImpl->mpBorderWindow )
5980 mpWindowImpl->mpBorderWindow->SetParentClipMode( nMode );
5981 else
5983 if ( !ImplIsOverlapWindow() )
5985 mpWindowImpl->mnParentClipMode = nMode;
5986 if ( nMode & PARENTCLIPMODE_CLIP )
5987 mpWindowImpl->mpParent->mpWindowImpl->mbClipChildren = TRUE;
5992 // -----------------------------------------------------------------------
5994 USHORT Window::GetParentClipMode() const
5996 DBG_CHKTHIS( Window, ImplDbgCheckWindow );
5998 if ( mpWindowImpl->mpBorderWindow )
5999 return mpWindowImpl->mpBorderWindow->GetParentClipMode();
6000 else
6001 return mpWindowImpl->mnParentClipMode;
6004 // -----------------------------------------------------------------------
6006 void Window::SetWindowRegionPixel()
6008 DBG_CHKTHIS( Window, ImplDbgCheckWindow );
6010 if ( mpWindowImpl->mpBorderWindow )
6011 mpWindowImpl->mpBorderWindow->SetWindowRegionPixel();
6012 else if( mpWindowImpl->mbFrame )
6014 mpWindowImpl->maWinRegion = Region( REGION_NULL);
6015 mpWindowImpl->mbWinRegion = FALSE;
6016 mpWindowImpl->mpFrame->ResetClipRegion();
6018 else
6020 if ( mpWindowImpl->mbWinRegion )
6022 mpWindowImpl->maWinRegion = Region( REGION_NULL );
6023 mpWindowImpl->mbWinRegion = FALSE;
6024 ImplSetClipFlag();
6026 if ( IsReallyVisible() )
6028 // Hintergrund-Sicherung zuruecksetzen
6029 if ( mpWindowImpl->mpOverlapData && mpWindowImpl->mpOverlapData->mpSaveBackDev )
6030 ImplDeleteOverlapBackground();
6031 if ( mpWindowImpl->mpFrameData->mpFirstBackWin )
6032 ImplInvalidateAllOverlapBackgrounds();
6033 Rectangle aRect( Point( mnOutOffX, mnOutOffY ), Size( mnOutWidth, mnOutHeight ) );
6034 Region aRegion( aRect );
6035 ImplInvalidateParentFrameRegion( aRegion );
6041 // -----------------------------------------------------------------------
6043 void Window::SetWindowRegionPixel( const Region& rRegion )
6045 DBG_CHKTHIS( Window, ImplDbgCheckWindow );
6047 if ( mpWindowImpl->mpBorderWindow )
6048 mpWindowImpl->mpBorderWindow->SetWindowRegionPixel( rRegion );
6049 else if( mpWindowImpl->mbFrame )
6051 if( rRegion.GetType() != REGION_NULL )
6053 mpWindowImpl->maWinRegion = rRegion;
6054 mpWindowImpl->mbWinRegion = ! rRegion.IsEmpty();
6055 if( mpWindowImpl->mbWinRegion )
6057 // ClipRegion setzen/updaten
6058 long nX;
6059 long nY;
6060 long nWidth;
6061 long nHeight;
6062 ULONG nRectCount;
6063 ImplRegionInfo aInfo;
6064 BOOL bRegionRect;
6066 nRectCount = mpWindowImpl->maWinRegion.GetRectCount();
6067 mpWindowImpl->mpFrame->BeginSetClipRegion( nRectCount );
6068 bRegionRect = mpWindowImpl->maWinRegion.ImplGetFirstRect( aInfo, nX, nY, nWidth, nHeight );
6069 while ( bRegionRect )
6071 mpWindowImpl->mpFrame->UnionClipRegion( nX, nY, nWidth, nHeight );
6072 bRegionRect = mpWindowImpl->maWinRegion.ImplGetNextRect( aInfo, nX, nY, nWidth, nHeight );
6074 mpWindowImpl->mpFrame->EndSetClipRegion();
6076 else
6077 SetWindowRegionPixel();
6079 else
6080 SetWindowRegionPixel();
6082 else
6084 BOOL bInvalidate = FALSE;
6086 if ( rRegion.GetType() == REGION_NULL )
6088 if ( mpWindowImpl->mbWinRegion )
6090 mpWindowImpl->maWinRegion = Region( REGION_NULL );
6091 mpWindowImpl->mbWinRegion = FALSE;
6092 ImplSetClipFlag();
6093 bInvalidate = TRUE;
6096 else
6098 mpWindowImpl->maWinRegion = rRegion;
6099 mpWindowImpl->mbWinRegion = TRUE;
6100 ImplSetClipFlag();
6101 bInvalidate = TRUE;
6104 if ( IsReallyVisible() )
6106 // Hintergrund-Sicherung zuruecksetzen
6107 if ( mpWindowImpl->mpOverlapData && mpWindowImpl->mpOverlapData->mpSaveBackDev )
6108 ImplDeleteOverlapBackground();
6109 if ( mpWindowImpl->mpFrameData->mpFirstBackWin )
6110 ImplInvalidateAllOverlapBackgrounds();
6111 Rectangle aRect( Point( mnOutOffX, mnOutOffY ), Size( mnOutWidth, mnOutHeight ) );
6112 Region aRegion( aRect );
6113 ImplInvalidateParentFrameRegion( aRegion );
6118 // -----------------------------------------------------------------------
6120 const Region& Window::GetWindowRegionPixel() const
6122 DBG_CHKTHIS( Window, ImplDbgCheckWindow );
6124 if ( mpWindowImpl->mpBorderWindow )
6125 return mpWindowImpl->mpBorderWindow->GetWindowRegionPixel();
6126 else
6127 return mpWindowImpl->maWinRegion;
6130 // -----------------------------------------------------------------------
6132 BOOL Window::IsWindowRegionPixel() const
6134 DBG_CHKTHIS( Window, ImplDbgCheckWindow );
6136 if ( mpWindowImpl->mpBorderWindow )
6137 return mpWindowImpl->mpBorderWindow->IsWindowRegionPixel();
6138 else
6139 return mpWindowImpl->mbWinRegion;
6142 // -----------------------------------------------------------------------
6144 Region Window::GetWindowClipRegionPixel( USHORT nFlags ) const
6146 DBG_CHKTHIS( Window, ImplDbgCheckWindow );
6148 Region aWinClipRegion;
6150 if ( nFlags & WINDOW_GETCLIPREGION_NOCHILDREN )
6152 if ( mpWindowImpl->mbInitWinClipRegion )
6153 ((Window*)this)->ImplInitWinClipRegion();
6154 aWinClipRegion = mpWindowImpl->maWinClipRegion;
6156 else
6158 Region* pWinChildClipRegion = ((Window*)this)->ImplGetWinChildClipRegion();
6159 aWinClipRegion = *pWinChildClipRegion;
6160 // --- RTL --- remirror clip region before passing it to somebody
6161 if( ImplIsAntiparallel() )
6162 ImplReMirror( aWinClipRegion );
6165 if ( nFlags & WINDOW_GETCLIPREGION_NULL )
6167 Rectangle aWinRect( Point( mnOutOffX, mnOutOffY ), Size( mnOutWidth, mnOutHeight ) );
6168 Region aWinRegion( aWinRect );
6170 if ( aWinRegion == aWinClipRegion )
6171 aWinClipRegion.SetNull();
6174 aWinClipRegion.Move( -mnOutOffX, -mnOutOffY );
6176 return aWinClipRegion;
6179 // -----------------------------------------------------------------------
6181 Region Window::GetPaintRegion() const
6183 DBG_CHKTHIS( Window, ImplDbgCheckWindow );
6185 if ( mpWindowImpl->mpPaintRegion )
6187 Region aRegion = *mpWindowImpl->mpPaintRegion;
6188 aRegion.Move( -mnOutOffX, -mnOutOffY );
6189 return PixelToLogic( aRegion );
6191 else
6193 Region aPaintRegion( REGION_NULL );
6194 return aPaintRegion;
6198 // -----------------------------------------------------------------------
6200 void Window::ExpandPaintClipRegion( const Region& rRegion )
6202 if( mpWindowImpl->mpPaintRegion )
6204 Region aPixRegion = LogicToPixel( rRegion );
6205 Region aDevPixRegion = ImplPixelToDevicePixel( aPixRegion );
6207 Region aWinChildRegion = *ImplGetWinChildClipRegion();
6208 // --- RTL -- only this region is in frame coordinates, so re-mirror it
6209 if( ImplIsAntiparallel() )
6210 ImplReMirror( aWinChildRegion );
6211 aDevPixRegion.Intersect( aWinChildRegion );
6212 if( ! aDevPixRegion.IsEmpty() )
6214 mpWindowImpl->mpPaintRegion->Union( aDevPixRegion );
6215 mbInitClipRegion = TRUE;
6220 // -----------------------------------------------------------------------
6222 static SystemWindow *ImplGetLastSystemWindow( Window *pWin )
6224 // get the most top-level system window, the one that contains the taskpanelist
6225 SystemWindow *pSysWin = NULL;
6226 if( !pWin )
6227 return pSysWin;
6228 Window *pMyParent = pWin;
6229 while ( pMyParent )
6231 if ( pMyParent->IsSystemWindow() )
6232 pSysWin = (SystemWindow*)pMyParent;
6233 pMyParent = pMyParent->GetParent();
6235 return pSysWin;
6238 void Window::SetParent( Window* pNewParent )
6240 DBG_CHKTHIS( Window, ImplDbgCheckWindow );
6241 DBG_ASSERT( pNewParent, "Window::SetParent(): pParent == NULL" );
6242 DBG_ASSERT( pNewParent != this, "someone tried to reparent a window to itself" );
6244 if( pNewParent == this )
6245 return;
6247 // check if the taskpanelist would change and move the window pointer accordingly
6248 SystemWindow *pSysWin = ImplGetLastSystemWindow(this);
6249 SystemWindow *pNewSysWin = NULL;
6250 BOOL bChangeTaskPaneList = FALSE;
6251 if( pSysWin && pSysWin->ImplIsInTaskPaneList( this ) )
6253 pNewSysWin = ImplGetLastSystemWindow( pNewParent );
6254 if( pNewSysWin && pNewSysWin != pSysWin )
6256 bChangeTaskPaneList = TRUE;
6257 pSysWin->GetTaskPaneList()->RemoveWindow( this );
6260 // remove ownerdraw decorated windows from list in the top-most frame window
6261 if( (GetStyle() & WB_OWNERDRAWDECORATION) && mpWindowImpl->mbFrame )
6263 ::std::vector< Window* >& rList = ImplGetOwnerDrawList();
6264 ::std::vector< Window* >::iterator p;
6265 p = ::std::find( rList.begin(), rList.end(), this );
6266 if( p != rList.end() )
6267 rList.erase( p );
6270 ImplSetFrameParent( pNewParent );
6272 if ( mpWindowImpl->mpBorderWindow )
6274 mpWindowImpl->mpRealParent = pNewParent;
6275 mpWindowImpl->mpBorderWindow->SetParent( pNewParent );
6276 return;
6279 if ( mpWindowImpl->mpParent == pNewParent )
6280 return;
6282 if ( mpWindowImpl->mbFrame )
6283 mpWindowImpl->mpFrame->SetParent( pNewParent->mpWindowImpl->mpFrame );
6285 BOOL bVisible = IsVisible();
6286 Show( FALSE, SHOW_NOFOCUSCHANGE );
6288 // Testen, ob sich das Overlap-Window aendert
6289 Window* pOldOverlapWindow;
6290 Window* pNewOverlapWindow = NULL;
6291 if ( ImplIsOverlapWindow() )
6292 pOldOverlapWindow = NULL;
6293 else
6295 pNewOverlapWindow = pNewParent->ImplGetFirstOverlapWindow();
6296 if ( mpWindowImpl->mpOverlapWindow != pNewOverlapWindow )
6297 pOldOverlapWindow = mpWindowImpl->mpOverlapWindow;
6298 else
6299 pOldOverlapWindow = NULL;
6302 // Fenster in der Hirachie umsetzen
6303 BOOL bFocusOverlapWin = HasChildPathFocus( TRUE );
6304 BOOL bFocusWin = HasChildPathFocus();
6305 BOOL bNewFrame = pNewParent->mpWindowImpl->mpFrameWindow != mpWindowImpl->mpFrameWindow;
6306 if ( bNewFrame )
6308 if ( mpWindowImpl->mpFrameData->mpFocusWin )
6310 if ( IsWindowOrChild( mpWindowImpl->mpFrameData->mpFocusWin ) )
6311 mpWindowImpl->mpFrameData->mpFocusWin = NULL;
6313 if ( mpWindowImpl->mpFrameData->mpMouseMoveWin )
6315 if ( IsWindowOrChild( mpWindowImpl->mpFrameData->mpMouseMoveWin ) )
6316 mpWindowImpl->mpFrameData->mpMouseMoveWin = NULL;
6318 if ( mpWindowImpl->mpFrameData->mpMouseDownWin )
6320 if ( IsWindowOrChild( mpWindowImpl->mpFrameData->mpMouseDownWin ) )
6321 mpWindowImpl->mpFrameData->mpMouseDownWin = NULL;
6324 ImplRemoveWindow( bNewFrame );
6325 ImplInsertWindow( pNewParent );
6326 if ( mpWindowImpl->mnParentClipMode & PARENTCLIPMODE_CLIP )
6327 pNewParent->mpWindowImpl->mbClipChildren = TRUE;
6328 ImplUpdateWindowPtr();
6329 if ( ImplUpdatePos() )
6330 ImplUpdateSysObjPos();
6332 // Wenn sich das Overlap-Window geaendert hat, dann muss getestet werden,
6333 // ob auch OverlapWindow die das Child-Fenster als Parent gehabt haben
6334 // in der Window-Hirachie umgesetzt werden muessen
6335 if ( ImplIsOverlapWindow() )
6337 if ( bNewFrame )
6339 Window* pOverlapWindow = mpWindowImpl->mpFirstOverlap;
6340 while ( pOverlapWindow )
6342 Window* pNextOverlapWindow = pOverlapWindow->mpWindowImpl->mpNext;
6343 pOverlapWindow->ImplUpdateOverlapWindowPtr( bNewFrame );
6344 pOverlapWindow = pNextOverlapWindow;
6348 else if ( pOldOverlapWindow )
6350 // Focus-Save zuruecksetzen
6351 if ( bFocusWin ||
6352 (pOldOverlapWindow->mpWindowImpl->mpLastFocusWindow &&
6353 IsWindowOrChild( pOldOverlapWindow->mpWindowImpl->mpLastFocusWindow )) )
6354 pOldOverlapWindow->mpWindowImpl->mpLastFocusWindow = NULL;
6356 Window* pOverlapWindow = pOldOverlapWindow->mpWindowImpl->mpFirstOverlap;
6357 while ( pOverlapWindow )
6359 Window* pNextOverlapWindow = pOverlapWindow->mpWindowImpl->mpNext;
6360 if ( ImplIsRealParentPath( pOverlapWindow->ImplGetWindow() ) )
6361 pOverlapWindow->ImplUpdateOverlapWindowPtr( bNewFrame );
6362 pOverlapWindow = pNextOverlapWindow;
6365 // Activate-Status beim naechsten Overlap-Window updaten
6366 if ( HasChildPathFocus( TRUE ) )
6367 ImplCallFocusChangeActivate( pNewOverlapWindow, pOldOverlapWindow );
6370 // Activate-Status mit umsetzen
6371 if ( bNewFrame )
6373 if ( (GetType() == WINDOW_BORDERWINDOW) &&
6374 (ImplGetWindow()->GetType() == WINDOW_FLOATINGWINDOW) )
6375 ((ImplBorderWindow*)this)->SetDisplayActive( mpWindowImpl->mpFrameData->mbHasFocus );
6378 // Focus evtl. auf den neuen Frame umsetzen, wenn FocusWindow mit
6379 // SetParent() umgesetzt wird
6380 if ( bFocusOverlapWin )
6382 mpWindowImpl->mpFrameData->mpFocusWin = Application::GetFocusWindow();
6383 if ( !mpWindowImpl->mpFrameData->mbHasFocus )
6385 mpWindowImpl->mpFrame->ToTop( 0 );
6389 // Assure DragSource and DropTarget members are created
6390 if ( bNewFrame )
6392 GetDropTarget();
6395 if( bChangeTaskPaneList )
6396 pNewSysWin->GetTaskPaneList()->AddWindow( this );
6398 if( (GetStyle() & WB_OWNERDRAWDECORATION) && mpWindowImpl->mbFrame )
6399 ImplGetOwnerDrawList().push_back( this );
6401 if ( bVisible )
6402 Show( TRUE, SHOW_NOFOCUSCHANGE | SHOW_NOACTIVATE );
6405 // -----------------------------------------------------------------------
6407 void Window::Show( BOOL bVisible, USHORT nFlags )
6409 DBG_CHKTHIS( Window, ImplDbgCheckWindow );
6411 if ( mpWindowImpl->mbVisible == bVisible )
6412 return;
6414 ImplDelData aDogTag( this );
6416 BOOL bRealVisibilityChanged = FALSE;
6417 mpWindowImpl->mbVisible = (bVisible != 0);
6419 if ( !bVisible )
6421 ImplHideAllOverlaps();
6422 if( aDogTag.IsDelete() )
6423 return;
6425 if ( mpWindowImpl->mpBorderWindow )
6427 BOOL bOldUpdate = mpWindowImpl->mpBorderWindow->mpWindowImpl->mbNoParentUpdate;
6428 if ( mpWindowImpl->mbNoParentUpdate )
6429 mpWindowImpl->mpBorderWindow->mpWindowImpl->mbNoParentUpdate = TRUE;
6430 mpWindowImpl->mpBorderWindow->Show( FALSE, nFlags );
6431 mpWindowImpl->mpBorderWindow->mpWindowImpl->mbNoParentUpdate = bOldUpdate;
6433 else if ( mpWindowImpl->mbFrame )
6435 mpWindowImpl->mbSuppressAccessibilityEvents = TRUE;
6436 mpWindowImpl->mpFrame->Show( FALSE, FALSE );
6439 StateChanged( STATE_CHANGE_VISIBLE );
6441 if ( mpWindowImpl->mbReallyVisible )
6443 Region aInvRegion( REGION_EMPTY );
6444 BOOL bSaveBack = FALSE;
6446 if ( ImplIsOverlapWindow() && !mpWindowImpl->mbFrame )
6448 if ( ImplRestoreOverlapBackground( aInvRegion ) )
6449 bSaveBack = TRUE;
6452 if ( !bSaveBack )
6454 if ( mpWindowImpl->mbInitWinClipRegion )
6455 ImplInitWinClipRegion();
6456 aInvRegion = mpWindowImpl->maWinClipRegion;
6459 if( aDogTag.IsDelete() )
6460 return;
6462 bRealVisibilityChanged = mpWindowImpl->mbReallyVisible;
6463 ImplResetReallyVisible();
6464 ImplSetClipFlag();
6466 if ( ImplIsOverlapWindow() && !mpWindowImpl->mbFrame )
6468 // Focus umsetzen
6469 if ( !(nFlags & SHOW_NOFOCUSCHANGE) && HasChildPathFocus() )
6471 if ( mpWindowImpl->mpOverlapWindow->IsEnabled() &&
6472 mpWindowImpl->mpOverlapWindow->IsInputEnabled() &&
6473 ! mpWindowImpl->mpOverlapWindow->IsInModalMode()
6475 mpWindowImpl->mpOverlapWindow->GrabFocus();
6479 if ( !mpWindowImpl->mbFrame )
6481 if( mpWindowImpl->mpWinData && mpWindowImpl->mpWinData->mbEnableNativeWidget )
6484 * #i48371# native theming: some themes draw outside the control
6485 * area we tell them to (bad thing, but we cannot do much about it ).
6486 * On hiding these controls they get invalidated with their window rectangle
6487 * which leads to the parts outside the control area being left and not
6488 * invalidated. Workaround: invalidate an area on the parent, too
6490 const int workaround_border = 5;
6491 Rectangle aBounds( aInvRegion.GetBoundRect() );
6492 aBounds.Left() -= workaround_border;
6493 aBounds.Top() -= workaround_border;
6494 aBounds.Right() += workaround_border;
6495 aBounds.Bottom() += workaround_border;
6496 aInvRegion = aBounds;
6498 if ( !mpWindowImpl->mbNoParentUpdate && !(nFlags & SHOW_NOPARENTUPDATE) )
6500 if ( !aInvRegion.IsEmpty() )
6501 ImplInvalidateParentFrameRegion( aInvRegion );
6503 ImplGenerateMouseMove();
6507 else
6509 // inherit native widget flag for form controls
6510 // required here, because frames never show up in the child hierarchy - which should be fixed....
6511 // eg, the drop down of a combobox which is a system floating window
6512 if( mpWindowImpl->mbFrame && GetParent() && GetParent()->IsCompoundControl() &&
6513 GetParent()->IsNativeWidgetEnabled() != IsNativeWidgetEnabled() )
6514 EnableNativeWidget( GetParent()->IsNativeWidgetEnabled() );
6516 if ( mpWindowImpl->mbCallMove )
6518 ImplCallMove();
6520 if ( mpWindowImpl->mbCallResize )
6522 ImplCallResize();
6525 StateChanged( STATE_CHANGE_VISIBLE );
6527 Window* pTestParent;
6528 if ( ImplIsOverlapWindow() )
6529 pTestParent = mpWindowImpl->mpOverlapWindow;
6530 else
6531 pTestParent = ImplGetParent();
6532 if ( mpWindowImpl->mbFrame || pTestParent->mpWindowImpl->mbReallyVisible )
6534 // Wenn ein Window gerade sichtbar wird, schicken wir allen
6535 // Child-Fenstern ein StateChanged, damit diese sich
6536 // initialisieren koennen
6537 ImplCallInitShow();
6539 // Wenn es ein SystemWindow ist, dann kommt es auch automatisch
6540 // nach vorne, wenn es gewuenscht ist
6541 if ( ImplIsOverlapWindow() && !(nFlags & SHOW_NOACTIVATE) )
6543 ImplStartToTop( 0 );
6544 ImplFocusToTop( 0, FALSE );
6547 // Hintergrund sichern
6548 if ( mpWindowImpl->mpOverlapData && mpWindowImpl->mpOverlapData->mbSaveBack )
6549 ImplSaveOverlapBackground();
6550 // adjust mpWindowImpl->mbReallyVisible
6551 bRealVisibilityChanged = !mpWindowImpl->mbReallyVisible;
6552 ImplSetReallyVisible();
6554 // Dafuer sorgen, das Clip-Rechtecke neu berechnet werden
6555 ImplSetClipFlag();
6557 if ( !mpWindowImpl->mbFrame )
6559 USHORT nInvalidateFlags = INVALIDATE_CHILDREN;
6560 if( ! IsPaintTransparent() )
6561 nInvalidateFlags |= INVALIDATE_NOTRANSPARENT;
6562 ImplInvalidate( NULL, nInvalidateFlags );
6563 ImplGenerateMouseMove();
6567 if ( mpWindowImpl->mpBorderWindow )
6568 mpWindowImpl->mpBorderWindow->Show( TRUE, nFlags );
6569 else if ( mpWindowImpl->mbFrame )
6571 // #106431#, hide SplashScreen
6572 ImplSVData* pSVData = ImplGetSVData();
6573 if ( !pSVData->mpIntroWindow )
6575 // The right way would be just to call this (not even in the 'if')
6576 GetpApp()->InitFinished();
6578 else if ( !ImplIsWindowOrChild( pSVData->mpIntroWindow ) )
6580 // ... but the VCL splash is broken, and it needs this
6581 // (for ./soffice slot:5500)
6582 pSVData->mpIntroWindow->Hide();
6585 //DBG_ASSERT( !mpWindowImpl->mbSuppressAccessibilityEvents, "Window::Show() - Frame reactivated");
6586 mpWindowImpl->mbSuppressAccessibilityEvents = FALSE;
6588 mpWindowImpl->mbPaintFrame = TRUE;
6589 BOOL bNoActivate = (nFlags & (SHOW_NOACTIVATE|SHOW_NOFOCUSCHANGE)) ? TRUE : FALSE;
6590 mpWindowImpl->mpFrame->Show( TRUE, bNoActivate );
6591 if( aDogTag.IsDelete() )
6592 return;
6594 // Query the correct size of the window, if we are waiting for
6595 // a system resize
6596 if ( mpWindowImpl->mbWaitSystemResize )
6598 long nOutWidth;
6599 long nOutHeight;
6600 mpWindowImpl->mpFrame->GetClientSize( nOutWidth, nOutHeight );
6601 ImplHandleResize( this, nOutWidth, nOutHeight );
6605 if( aDogTag.IsDelete() )
6606 return;
6608 #ifdef DBG_UTIL
6609 if ( IsDialog() || (GetType() == WINDOW_TABPAGE) || (GetType() == WINDOW_DOCKINGWINDOW) )
6611 DBG_DIALOGTEST( this );
6613 #endif
6615 ImplShowAllOverlaps();
6618 if( aDogTag.IsDelete() )
6619 return;
6620 // invalidate all saved backgrounds
6621 if ( mpWindowImpl->mpFrameData->mpFirstBackWin )
6622 ImplInvalidateAllOverlapBackgrounds();
6624 // the SHOW/HIDE events also serve as indicators to send child creation/destroy events to the access bridge
6625 // However, the access bridge only uses this event if the data member is not NULL (it's kind of a hack that
6626 // we re-use the SHOW/HIDE events this way, with this particular semantics).
6627 // Since #104887#, the notifications for the access bridge are done in Impl(Set|Reset)ReallyVisible. Here, we
6628 // now only notify with a NULL data pointer, for all other clients except the access bridge.
6629 if ( !bRealVisibilityChanged )
6630 ImplCallEventListeners( mpWindowImpl->mbVisible ? VCLEVENT_WINDOW_SHOW : VCLEVENT_WINDOW_HIDE, NULL );
6631 if( aDogTag.IsDelete() )
6632 return;
6634 // #107575#, if a floating windows is shown that grabs the focus, we have to notify the toolkit about it
6635 // ImplGrabFocus() is not called in this case
6636 // Because this might lead to problems the task will be shifted to 6.y
6637 // Note: top-level context menues are registered at the access bridge after being shown,
6638 // so this will probably not help here....
6640 if( mpWindowImpl->mbFloatWin && ((FloatingWindow*) this )->GrabsFocus() )
6642 ImplSVData* pSVData = ImplGetSVData();
6643 if( !mpWindowImpl->mbVisible )
6645 ImplCallEventListeners( VCLEVENT_WINDOW_LOSEFOCUS );
6646 if( pSVData->maWinData.mpFocusWin )
6647 pSVData->maWinData.mpFocusWin->ImplCallEventListeners( VCLEVENT_WINDOW_GETFOCUS );
6649 else
6651 if( pSVData->maWinData.mpFocusWin )
6652 pSVData->maWinData.mpFocusWin->ImplCallEventListeners( VCLEVENT_WINDOW_LOSEFOCUS );
6653 ImplCallEventListeners( VCLEVENT_WINDOW_GETFOCUS );
6659 // -----------------------------------------------------------------------
6661 Size Window::GetSizePixel() const
6663 // #i43257# trigger pending resize handler to assure correct window sizes
6664 if( mpWindowImpl->mpFrameData->maResizeTimer.IsActive() )
6666 ImplDelData aDogtag( this );
6667 mpWindowImpl->mpFrameData->maResizeTimer.Stop();
6668 mpWindowImpl->mpFrameData->maResizeTimer.GetTimeoutHdl().Call( NULL );
6669 if( aDogtag.IsDelete() )
6670 return Size(0,0);
6673 return Size( mnOutWidth+mpWindowImpl->mnLeftBorder+mpWindowImpl->mnRightBorder,
6674 mnOutHeight+mpWindowImpl->mnTopBorder+mpWindowImpl->mnBottomBorder );
6677 void Window::GetBorder( sal_Int32& rLeftBorder, sal_Int32& rTopBorder,
6678 sal_Int32& rRightBorder, sal_Int32& rBottomBorder ) const
6680 rLeftBorder = mpWindowImpl->mnLeftBorder;
6681 rTopBorder = mpWindowImpl->mnTopBorder;
6682 rRightBorder = mpWindowImpl->mnRightBorder;
6683 rBottomBorder = mpWindowImpl->mnBottomBorder;
6687 // -----------------------------------------------------------------------
6689 void Window::Enable( bool bEnable, bool bChild )
6691 DBG_CHKTHIS( Window, ImplDbgCheckWindow );
6693 if ( !bEnable )
6695 // Wenn ein Fenster disablte wird, wird automatisch der Tracking-Modus
6696 // beendet oder der Capture geklaut
6697 if ( IsTracking() )
6698 EndTracking( ENDTRACK_CANCEL );
6699 if ( IsMouseCaptured() )
6700 ReleaseMouse();
6701 // Wenn Fenster den Focus hat und in der Dialog-Steuerung enthalten,
6702 // wird versucht, den Focus auf das naechste Control weiterzuschalten
6703 // mpWindowImpl->mbDisabled darf erst nach Aufruf von ImplDlgCtrlNextWindow() gesetzt
6704 // werden. Ansonsten muss ImplDlgCtrlNextWindow() umgestellt werden
6705 if ( HasFocus() )
6706 ImplDlgCtrlNextWindow();
6709 if ( mpWindowImpl->mpBorderWindow )
6711 mpWindowImpl->mpBorderWindow->Enable( bEnable, FALSE );
6712 if ( (mpWindowImpl->mpBorderWindow->GetType() == WINDOW_BORDERWINDOW) &&
6713 ((ImplBorderWindow*)mpWindowImpl->mpBorderWindow)->mpMenuBarWindow )
6714 ((ImplBorderWindow*)mpWindowImpl->mpBorderWindow)->mpMenuBarWindow->Enable( bEnable, TRUE );
6717 // #i56102# restore app focus win in case the
6718 // window was disabled when the frame focus changed
6719 ImplSVData* pSVData = ImplGetSVData();
6720 if( bEnable &&
6721 pSVData->maWinData.mpFocusWin == NULL &&
6722 mpWindowImpl->mpFrameData->mbHasFocus &&
6723 mpWindowImpl->mpFrameData->mpFocusWin == this )
6724 pSVData->maWinData.mpFocusWin = this;
6726 if ( mpWindowImpl->mbDisabled != !bEnable )
6728 mpWindowImpl->mbDisabled = !bEnable;
6729 if ( mpWindowImpl->mpSysObj )
6730 mpWindowImpl->mpSysObj->Enable( bEnable && !mpWindowImpl->mbInputDisabled );
6731 // if ( mpWindowImpl->mbFrame )
6732 // mpWindowImpl->mpFrame->Enable( bEnable && !mpWindowImpl->mbInputDisabled );
6733 StateChanged( STATE_CHANGE_ENABLE );
6735 ImplCallEventListeners( bEnable ? VCLEVENT_WINDOW_ENABLED : VCLEVENT_WINDOW_DISABLED );
6738 if ( bChild || mpWindowImpl->mbChildNotify )
6740 Window* pChild = mpWindowImpl->mpFirstChild;
6741 while ( pChild )
6743 pChild->Enable( bEnable, bChild );
6744 pChild = pChild->mpWindowImpl->mpNext;
6748 if ( IsReallyVisible() )
6749 ImplGenerateMouseMove();
6752 // -----------------------------------------------------------------------
6754 void Window::SetCallHandlersOnInputDisabled( bool bCall )
6756 mpWindowImpl->mbCallHandlersDuringInputDisabled = bCall ? TRUE : FALSE;
6758 Window* pChild = mpWindowImpl->mpFirstChild;
6759 while ( pChild )
6761 pChild->SetCallHandlersOnInputDisabled( bCall );
6762 pChild = pChild->mpWindowImpl->mpNext;
6766 // -----------------------------------------------------------------------
6768 bool Window::IsCallHandlersOnInputDisabled() const
6770 return mpWindowImpl->mbCallHandlersDuringInputDisabled ? true : false;
6773 // -----------------------------------------------------------------------
6775 void Window::EnableInput( BOOL bEnable, BOOL bChild )
6777 DBG_CHKTHIS( Window, ImplDbgCheckWindow );
6779 BOOL bNotify = (bEnable != mpWindowImpl->mbInputDisabled);
6780 if ( mpWindowImpl->mpBorderWindow )
6782 mpWindowImpl->mpBorderWindow->EnableInput( bEnable, FALSE );
6783 if ( (mpWindowImpl->mpBorderWindow->GetType() == WINDOW_BORDERWINDOW) &&
6784 ((ImplBorderWindow*)mpWindowImpl->mpBorderWindow)->mpMenuBarWindow )
6785 ((ImplBorderWindow*)mpWindowImpl->mpBorderWindow)->mpMenuBarWindow->EnableInput( bEnable, TRUE );
6788 if ( (! bEnable && mpWindowImpl->meAlwaysInputMode != AlwaysInputEnabled) ||
6789 ( bEnable && mpWindowImpl->meAlwaysInputMode != AlwaysInputDisabled) )
6791 // Wenn ein Fenster disablte wird, wird automatisch der
6792 // Tracking-Modus beendet oder der Capture geklaut
6793 if ( !bEnable )
6795 if ( IsTracking() )
6796 EndTracking( ENDTRACK_CANCEL );
6797 if ( IsMouseCaptured() )
6798 ReleaseMouse();
6801 if ( mpWindowImpl->mbInputDisabled != !bEnable )
6803 mpWindowImpl->mbInputDisabled = !bEnable;
6804 if ( mpWindowImpl->mpSysObj )
6805 mpWindowImpl->mpSysObj->Enable( !mpWindowImpl->mbDisabled && bEnable );
6806 // if ( mpWindowImpl->mbFrame )
6807 // mpWindowImpl->mpFrame->Enable( !mpWindowImpl->mbDisabled && bEnable );
6811 // #i56102# restore app focus win in case the
6812 // window was disabled when the frame focus changed
6813 ImplSVData* pSVData = ImplGetSVData();
6814 if( bEnable &&
6815 pSVData->maWinData.mpFocusWin == NULL &&
6816 mpWindowImpl->mpFrameData->mbHasFocus &&
6817 mpWindowImpl->mpFrameData->mpFocusWin == this )
6818 pSVData->maWinData.mpFocusWin = this;
6820 if ( bChild || mpWindowImpl->mbChildNotify )
6822 Window* pChild = mpWindowImpl->mpFirstChild;
6823 while ( pChild )
6825 pChild->EnableInput( bEnable, bChild );
6826 pChild = pChild->mpWindowImpl->mpNext;
6830 if ( IsReallyVisible() )
6831 ImplGenerateMouseMove();
6833 // #104827# notify parent
6834 if ( bNotify )
6836 NotifyEvent aNEvt( bEnable ? EVENT_INPUTENABLE : EVENT_INPUTDISABLE, this );
6837 Notify( aNEvt );
6841 // -----------------------------------------------------------------------
6843 void Window::EnableInput( BOOL bEnable, BOOL bChild, BOOL bSysWin,
6844 const Window* pExcludeWindow )
6846 DBG_CHKTHIS( Window, ImplDbgCheckWindow );
6848 EnableInput( bEnable, bChild );
6849 if ( bSysWin )
6851 // pExculeWindow is the first Overlap-Frame --> if this
6852 // shouldn't be the case, than this must be changed in dialog.cxx
6853 if( pExcludeWindow )
6854 pExcludeWindow = pExcludeWindow->ImplGetFirstOverlapWindow();
6855 Window* pSysWin = mpWindowImpl->mpFrameWindow->mpWindowImpl->mpFrameData->mpFirstOverlap;
6856 while ( pSysWin )
6858 // Is Window in the path from this window
6859 if ( ImplGetFirstOverlapWindow()->ImplIsWindowOrChild( pSysWin, TRUE ) )
6861 // Is Window not in the exclude window path or not the
6862 // exclude window, than change the status
6863 if ( !pExcludeWindow || !pExcludeWindow->ImplIsWindowOrChild( pSysWin, TRUE ) )
6864 pSysWin->EnableInput( bEnable, bChild );
6866 pSysWin = pSysWin->mpWindowImpl->mpNextOverlap;
6869 // enable/disable floating system windows as well
6870 Window* pFrameWin = ImplGetSVData()->maWinData.mpFirstFrame;
6871 while ( pFrameWin )
6873 if( pFrameWin->ImplIsFloatingWindow() )
6875 // Is Window in the path from this window
6876 if ( ImplGetFirstOverlapWindow()->ImplIsWindowOrChild( pFrameWin, TRUE ) )
6878 // Is Window not in the exclude window path or not the
6879 // exclude window, than change the status
6880 if ( !pExcludeWindow || !pExcludeWindow->ImplIsWindowOrChild( pFrameWin, TRUE ) )
6881 pFrameWin->EnableInput( bEnable, bChild );
6884 pFrameWin = pFrameWin->mpWindowImpl->mpFrameData->mpNextFrame;
6887 // the same for ownerdraw floating windows
6888 if( mpWindowImpl->mbFrame )
6890 ::std::vector< Window* >& rList = mpWindowImpl->mpFrameData->maOwnerDrawList;
6891 ::std::vector< Window* >::iterator p = rList.begin();
6892 while( p != rList.end() )
6894 // Is Window in the path from this window
6895 if ( ImplGetFirstOverlapWindow()->ImplIsWindowOrChild( (*p), TRUE ) )
6897 // Is Window not in the exclude window path or not the
6898 // exclude window, than change the status
6899 if ( !pExcludeWindow || !pExcludeWindow->ImplIsWindowOrChild( (*p), TRUE ) )
6900 (*p)->EnableInput( bEnable, bChild );
6902 p++;
6908 // -----------------------------------------------------------------------
6910 void Window::AlwaysEnableInput( BOOL bAlways, BOOL bChild )
6912 DBG_CHKTHIS( Window, ImplDbgCheckWindow );
6914 if ( mpWindowImpl->mpBorderWindow )
6915 mpWindowImpl->mpBorderWindow->AlwaysEnableInput( bAlways, FALSE );
6917 if( bAlways && mpWindowImpl->meAlwaysInputMode != AlwaysInputEnabled )
6919 mpWindowImpl->meAlwaysInputMode = AlwaysInputEnabled;
6921 if ( bAlways )
6922 EnableInput( TRUE, FALSE );
6924 else if( ! bAlways && mpWindowImpl->meAlwaysInputMode == AlwaysInputEnabled )
6926 mpWindowImpl->meAlwaysInputMode = AlwaysInputNone;
6929 if ( bChild || mpWindowImpl->mbChildNotify )
6931 Window* pChild = mpWindowImpl->mpFirstChild;
6932 while ( pChild )
6934 pChild->AlwaysEnableInput( bAlways, bChild );
6935 pChild = pChild->mpWindowImpl->mpNext;
6940 // -----------------------------------------------------------------------
6942 void Window::AlwaysDisableInput( BOOL bAlways, BOOL bChild )
6944 DBG_CHKTHIS( Window, ImplDbgCheckWindow );
6946 if ( mpWindowImpl->mpBorderWindow )
6947 mpWindowImpl->mpBorderWindow->AlwaysDisableInput( bAlways, FALSE );
6949 if( bAlways && mpWindowImpl->meAlwaysInputMode != AlwaysInputDisabled )
6951 mpWindowImpl->meAlwaysInputMode = AlwaysInputDisabled;
6953 if ( bAlways )
6954 EnableInput( FALSE, FALSE );
6956 else if( ! bAlways && mpWindowImpl->meAlwaysInputMode == AlwaysInputDisabled )
6958 mpWindowImpl->meAlwaysInputMode = AlwaysInputNone;
6961 if ( bChild || mpWindowImpl->mbChildNotify )
6963 Window* pChild = mpWindowImpl->mpFirstChild;
6964 while ( pChild )
6966 pChild->AlwaysDisableInput( bAlways, bChild );
6967 pChild = pChild->mpWindowImpl->mpNext;
6972 // -----------------------------------------------------------------------
6974 void Window::SetActivateMode( USHORT nMode )
6976 DBG_CHKTHIS( Window, ImplDbgCheckWindow );
6978 if ( mpWindowImpl->mpBorderWindow )
6979 mpWindowImpl->mpBorderWindow->SetActivateMode( nMode );
6981 if ( mpWindowImpl->mnActivateMode != nMode )
6983 mpWindowImpl->mnActivateMode = nMode;
6985 // Evtl. ein Decativate/Activate ausloesen
6986 if ( mpWindowImpl->mnActivateMode )
6988 if ( (mpWindowImpl->mbActive || (GetType() == WINDOW_BORDERWINDOW)) &&
6989 !HasChildPathFocus( TRUE ) )
6991 mpWindowImpl->mbActive = FALSE;
6992 Deactivate();
6995 else
6997 if ( !mpWindowImpl->mbActive || (GetType() == WINDOW_BORDERWINDOW) )
6999 mpWindowImpl->mbActive = TRUE;
7000 Activate();
7006 // -----------------------------------------------------------------------
7008 void Window::ToTop( USHORT nFlags )
7010 DBG_CHKTHIS( Window, ImplDbgCheckWindow );
7012 ImplStartToTop( nFlags );
7013 ImplFocusToTop( nFlags, IsReallyVisible() );
7016 // -----------------------------------------------------------------------
7018 void Window::SetZOrder( Window* pRefWindow, USHORT nFlags )
7020 DBG_CHKTHIS( Window, ImplDbgCheckWindow );
7022 if ( mpWindowImpl->mpBorderWindow )
7024 mpWindowImpl->mpBorderWindow->SetZOrder( pRefWindow, nFlags );
7025 return;
7028 if ( nFlags & WINDOW_ZORDER_FIRST )
7030 if ( ImplIsOverlapWindow() )
7031 pRefWindow = mpWindowImpl->mpOverlapWindow->mpWindowImpl->mpFirstOverlap;
7032 else
7033 pRefWindow = mpWindowImpl->mpParent->mpWindowImpl->mpFirstChild;
7034 nFlags |= WINDOW_ZORDER_BEFOR;
7036 else if ( nFlags & WINDOW_ZORDER_LAST )
7038 if ( ImplIsOverlapWindow() )
7039 pRefWindow = mpWindowImpl->mpOverlapWindow->mpWindowImpl->mpLastOverlap;
7040 else
7041 pRefWindow = mpWindowImpl->mpParent->mpWindowImpl->mpLastChild;
7042 nFlags |= WINDOW_ZORDER_BEHIND;
7045 while ( pRefWindow->mpWindowImpl->mpBorderWindow )
7046 pRefWindow = pRefWindow->mpWindowImpl->mpBorderWindow;
7047 if ( (pRefWindow == this) || mpWindowImpl->mbFrame )
7048 return;
7050 DBG_ASSERT( pRefWindow->mpWindowImpl->mpParent == mpWindowImpl->mpParent, "Window::SetZOrder() - pRefWindow has other parent" );
7051 if ( nFlags & WINDOW_ZORDER_BEFOR )
7053 if ( pRefWindow->mpWindowImpl->mpPrev == this )
7054 return;
7056 if ( ImplIsOverlapWindow() )
7058 if ( mpWindowImpl->mpPrev )
7059 mpWindowImpl->mpPrev->mpWindowImpl->mpNext = mpWindowImpl->mpNext;
7060 else
7061 mpWindowImpl->mpOverlapWindow->mpWindowImpl->mpFirstOverlap = mpWindowImpl->mpNext;
7062 if ( mpWindowImpl->mpNext )
7063 mpWindowImpl->mpNext->mpWindowImpl->mpPrev = mpWindowImpl->mpPrev;
7064 else
7065 mpWindowImpl->mpOverlapWindow->mpWindowImpl->mpLastOverlap = mpWindowImpl->mpPrev;
7066 if ( !pRefWindow->mpWindowImpl->mpPrev )
7067 mpWindowImpl->mpOverlapWindow->mpWindowImpl->mpFirstOverlap = this;
7069 else
7071 if ( mpWindowImpl->mpPrev )
7072 mpWindowImpl->mpPrev->mpWindowImpl->mpNext = mpWindowImpl->mpNext;
7073 else
7074 mpWindowImpl->mpParent->mpWindowImpl->mpFirstChild = mpWindowImpl->mpNext;
7075 if ( mpWindowImpl->mpNext )
7076 mpWindowImpl->mpNext->mpWindowImpl->mpPrev = mpWindowImpl->mpPrev;
7077 else
7078 mpWindowImpl->mpParent->mpWindowImpl->mpLastChild = mpWindowImpl->mpPrev;
7079 if ( !pRefWindow->mpWindowImpl->mpPrev )
7080 mpWindowImpl->mpParent->mpWindowImpl->mpFirstChild = this;
7083 mpWindowImpl->mpPrev = pRefWindow->mpWindowImpl->mpPrev;
7084 mpWindowImpl->mpNext = pRefWindow;
7085 if ( mpWindowImpl->mpPrev )
7086 mpWindowImpl->mpPrev->mpWindowImpl->mpNext = this;
7087 mpWindowImpl->mpNext->mpWindowImpl->mpPrev = this;
7089 else if ( nFlags & WINDOW_ZORDER_BEHIND )
7091 if ( pRefWindow->mpWindowImpl->mpNext == this )
7092 return;
7094 if ( ImplIsOverlapWindow() )
7096 if ( mpWindowImpl->mpPrev )
7097 mpWindowImpl->mpPrev->mpWindowImpl->mpNext = mpWindowImpl->mpNext;
7098 else
7099 mpWindowImpl->mpOverlapWindow->mpWindowImpl->mpFirstOverlap = mpWindowImpl->mpNext;
7100 if ( mpWindowImpl->mpNext )
7101 mpWindowImpl->mpNext->mpWindowImpl->mpPrev = mpWindowImpl->mpPrev;
7102 else
7103 mpWindowImpl->mpOverlapWindow->mpWindowImpl->mpLastOverlap = mpWindowImpl->mpPrev;
7104 if ( !pRefWindow->mpWindowImpl->mpNext )
7105 mpWindowImpl->mpOverlapWindow->mpWindowImpl->mpLastOverlap = this;
7107 else
7109 if ( mpWindowImpl->mpPrev )
7110 mpWindowImpl->mpPrev->mpWindowImpl->mpNext = mpWindowImpl->mpNext;
7111 else
7112 mpWindowImpl->mpParent->mpWindowImpl->mpFirstChild = mpWindowImpl->mpNext;
7113 if ( mpWindowImpl->mpNext )
7114 mpWindowImpl->mpNext->mpWindowImpl->mpPrev = mpWindowImpl->mpPrev;
7115 else
7116 mpWindowImpl->mpParent->mpWindowImpl->mpLastChild = mpWindowImpl->mpPrev;
7117 if ( !pRefWindow->mpWindowImpl->mpNext )
7118 mpWindowImpl->mpParent->mpWindowImpl->mpLastChild = this;
7121 mpWindowImpl->mpPrev = pRefWindow;
7122 mpWindowImpl->mpNext = pRefWindow->mpWindowImpl->mpNext;
7123 if ( mpWindowImpl->mpNext )
7124 mpWindowImpl->mpNext->mpWindowImpl->mpPrev = this;
7125 mpWindowImpl->mpPrev->mpWindowImpl->mpNext = this;
7128 if ( IsReallyVisible() )
7130 // Hintergrund-Sicherung zuruecksetzen
7131 if ( mpWindowImpl->mpFrameData->mpFirstBackWin )
7132 ImplInvalidateAllOverlapBackgrounds();
7134 if ( mpWindowImpl->mbInitWinClipRegion || !mpWindowImpl->maWinClipRegion.IsEmpty() )
7136 BOOL bInitWinClipRegion = mpWindowImpl->mbInitWinClipRegion;
7137 ImplSetClipFlag();
7139 // Wenn ClipRegion noch nicht initalisiert wurde, dann
7140 // gehen wir davon aus, das das Fenster noch nicht
7141 // ausgegeben wurde und loesen somit auch keine
7142 // Invalidates aus. Dies ist eine Optimierung fuer
7143 // HTML-Dokumenten mit vielen Controls. Wenn es mal
7144 // Probleme mit dieser Abfrage gibt, sollte man ein
7145 // Flag einfuehren, ob das Fenster nach Show schon
7146 // einmal ausgegeben wurde.
7147 if ( !bInitWinClipRegion )
7149 // Alle nebeneinanderliegen Fenster invalidieren
7150 // Noch nicht komplett implementiert !!!
7151 Rectangle aWinRect( Point( mnOutOffX, mnOutOffY ), Size( mnOutWidth, mnOutHeight ) );
7152 Window* pWindow = NULL;
7153 if ( ImplIsOverlapWindow() )
7155 if ( mpWindowImpl->mpOverlapWindow )
7156 pWindow = mpWindowImpl->mpOverlapWindow->mpWindowImpl->mpFirstOverlap;
7158 else
7159 pWindow = ImplGetParent()->mpWindowImpl->mpFirstChild;
7160 // Alle Fenster, die vor uns liegen und von uns verdeckt wurden,
7161 // invalidieren
7162 while ( pWindow )
7164 if ( pWindow == this )
7165 break;
7166 Rectangle aCompRect( Point( pWindow->mnOutOffX, pWindow->mnOutOffY ),
7167 Size( pWindow->mnOutWidth, pWindow->mnOutHeight ) );
7168 if ( aWinRect.IsOver( aCompRect ) )
7169 pWindow->Invalidate( INVALIDATE_CHILDREN | INVALIDATE_NOTRANSPARENT );
7170 pWindow = pWindow->mpWindowImpl->mpNext;
7172 // Wenn uns ein Fenster welches im Hinterund liegt verdeckt hat,
7173 // dann muessen wir uns neu ausgeben
7174 while ( pWindow )
7176 if ( pWindow != this )
7178 Rectangle aCompRect( Point( pWindow->mnOutOffX, pWindow->mnOutOffY ),
7179 Size( pWindow->mnOutWidth, pWindow->mnOutHeight ) );
7180 if ( aWinRect.IsOver( aCompRect ) )
7182 Invalidate( INVALIDATE_CHILDREN | INVALIDATE_NOTRANSPARENT );
7183 break;
7186 pWindow = pWindow->mpWindowImpl->mpNext;
7193 // -----------------------------------------------------------------------
7195 void Window::EnableAlwaysOnTop( BOOL bEnable )
7197 DBG_CHKTHIS( Window, ImplDbgCheckWindow );
7199 mpWindowImpl->mbAlwaysOnTop = bEnable;
7201 if ( mpWindowImpl->mpBorderWindow )
7202 mpWindowImpl->mpBorderWindow->EnableAlwaysOnTop( bEnable );
7203 else if ( bEnable && IsReallyVisible() )
7204 ToTop();
7206 if ( mpWindowImpl->mbFrame )
7207 mpWindowImpl->mpFrame->SetAlwaysOnTop( bEnable );
7210 // -----------------------------------------------------------------------
7212 void Window::SetPosSizePixel( long nX, long nY,
7213 long nWidth, long nHeight, USHORT nFlags )
7215 DBG_CHKTHIS( Window, ImplDbgCheckWindow );
7217 BOOL bHasValidSize = !mpWindowImpl->mbDefSize;
7219 if ( nFlags & WINDOW_POSSIZE_POS )
7220 mpWindowImpl->mbDefPos = FALSE;
7221 if ( nFlags & WINDOW_POSSIZE_SIZE )
7222 mpWindowImpl->mbDefSize = FALSE;
7224 // Oberstes BorderWindow ist das Window, welches positioniert werden soll
7225 Window* pWindow = this;
7226 while ( pWindow->mpWindowImpl->mpBorderWindow )
7227 pWindow = pWindow->mpWindowImpl->mpBorderWindow;
7229 if ( pWindow->mpWindowImpl->mbFrame )
7231 // Note: if we're positioning a frame, the coordinates are interpreted
7232 // as being the top-left corner of the window's client area and NOT
7233 // as the position of the border ! (due to limitations of several UNIX window managers)
7234 long nOldWidth = pWindow->mnOutWidth;
7236 if ( !(nFlags & WINDOW_POSSIZE_WIDTH) )
7237 nWidth = pWindow->mnOutWidth;
7238 if ( !(nFlags & WINDOW_POSSIZE_HEIGHT) )
7239 nHeight = pWindow->mnOutHeight;
7242 USHORT nSysFlags=0;
7243 if( nFlags & WINDOW_POSSIZE_WIDTH )
7244 nSysFlags |= SAL_FRAME_POSSIZE_WIDTH;
7245 if( nFlags & WINDOW_POSSIZE_HEIGHT )
7246 nSysFlags |= SAL_FRAME_POSSIZE_HEIGHT;
7247 if( nFlags & WINDOW_POSSIZE_X )
7249 nSysFlags |= SAL_FRAME_POSSIZE_X;
7250 if( pWindow->GetParent() && (pWindow->GetStyle() & WB_SYSTEMCHILDWINDOW) )
7252 Window* pParent = pWindow->GetParent();
7253 nX += pParent->mnOutOffX;
7255 if( GetParent() && GetParent()->ImplIsAntiparallel() )
7257 // --- RTL --- (re-mirror at parent window)
7258 Rectangle aRect( Point ( nX, nY ), Size( nWidth, nHeight ) );
7259 GetParent()->ImplReMirror( aRect );
7260 nX = aRect.nLeft;
7263 if( !(nFlags & WINDOW_POSSIZE_X) && bHasValidSize && pWindow->mpWindowImpl->mpFrame->maGeometry.nWidth )
7265 // --- RTL --- make sure the old right aligned position is not changed
7266 // system windows will always grow to the right
7267 if( pWindow->GetParent() && pWindow->GetParent()->ImplHasMirroredGraphics() )
7269 long myWidth = nOldWidth;
7270 if( !myWidth )
7271 myWidth = mpWindowImpl->mpFrame->GetUnmirroredGeometry().nWidth;
7272 if( !myWidth )
7273 myWidth = nWidth;
7274 nFlags |= WINDOW_POSSIZE_X;
7275 nSysFlags |= SAL_FRAME_POSSIZE_X;
7276 nX = mpWindowImpl->mpFrame->GetUnmirroredGeometry().nX - pWindow->GetParent()->mpWindowImpl->mpFrame->GetUnmirroredGeometry().nX -
7277 mpWindowImpl->mpFrame->GetUnmirroredGeometry().nLeftDecoration;
7278 nX = pWindow->GetParent()->mpWindowImpl->mpFrame->GetUnmirroredGeometry().nX - mpWindowImpl->mpFrame->GetUnmirroredGeometry().nLeftDecoration +
7279 pWindow->GetParent()->mpWindowImpl->mpFrame->GetUnmirroredGeometry().nWidth - myWidth - 1 - mpWindowImpl->mpFrame->GetUnmirroredGeometry().nX;
7280 if(!(nFlags & WINDOW_POSSIZE_Y))
7282 nFlags |= WINDOW_POSSIZE_Y;
7283 nSysFlags |= SAL_FRAME_POSSIZE_Y;
7284 nY = mpWindowImpl->mpFrame->GetUnmirroredGeometry().nY - pWindow->GetParent()->mpWindowImpl->mpFrame->GetUnmirroredGeometry().nY -
7285 mpWindowImpl->mpFrame->GetUnmirroredGeometry().nTopDecoration;
7289 if( nFlags & WINDOW_POSSIZE_Y )
7291 nSysFlags |= SAL_FRAME_POSSIZE_Y;
7292 if( pWindow->GetParent() && (pWindow->GetStyle() & WB_SYSTEMCHILDWINDOW) )
7294 Window* pParent = pWindow->GetParent();
7295 nY += pParent->mnOutOffY;
7299 if( nSysFlags & (SAL_FRAME_POSSIZE_WIDTH|SAL_FRAME_POSSIZE_HEIGHT) )
7301 // check for min/max client size and adjust size accordingly
7302 // otherwise it may happen that the resize event is ignored, i.e. the old size remains
7303 // unchanged but ImplHandleResize() is called with the wrong size
7304 SystemWindow *pSystemWindow = dynamic_cast< SystemWindow* >( pWindow );
7305 if( pSystemWindow )
7307 Size aMinSize = pSystemWindow->GetMinOutputSizePixel();
7308 Size aMaxSize = pSystemWindow->GetMaxOutputSizePixel();
7309 if( nWidth < aMinSize.Width() )
7310 nWidth = aMinSize.Width();
7311 if( nHeight < aMinSize.Height() )
7312 nHeight = aMinSize.Height();
7314 if( nWidth > aMaxSize.Width() )
7315 nWidth = aMaxSize.Width();
7316 if( nHeight > aMaxSize.Height() )
7317 nHeight = aMaxSize.Height();
7321 pWindow->mpWindowImpl->mpFrame->SetPosSize( nX, nY, nWidth, nHeight, nSysFlags );
7323 // Resize should be called directly. If we havn't
7324 // set the correct size, we get a second resize from
7325 // the system with the correct size. This can be happend
7326 // if the size is to small or to large.
7327 ImplHandleResize( pWindow, nWidth, nHeight );
7329 else
7331 pWindow->ImplPosSizeWindow( nX, nY, nWidth, nHeight, nFlags );
7332 if ( IsReallyVisible() )
7333 ImplGenerateMouseMove();
7337 // -----------------------------------------------------------------------
7339 Point Window::GetPosPixel() const
7341 return mpWindowImpl->maPos;
7344 // -----------------------------------------------------------------------
7346 Rectangle Window::GetDesktopRectPixel() const
7348 Rectangle rRect;
7349 mpWindowImpl->mpFrameWindow->mpWindowImpl->mpFrame->GetWorkArea( rRect );
7350 return rRect;
7353 // -----------------------------------------------------------------------
7355 Point Window::OutputToScreenPixel( const Point& rPos ) const
7357 // relative to top level parent
7358 return Point( rPos.X()+mnOutOffX, rPos.Y()+mnOutOffY );
7361 // -----------------------------------------------------------------------
7363 Point Window::ScreenToOutputPixel( const Point& rPos ) const
7365 // relative to top level parent
7366 return Point( rPos.X()-mnOutOffX, rPos.Y()-mnOutOffY );
7369 // -----------------------------------------------------------------------
7371 long Window::ImplGetUnmirroredOutOffX()
7373 // revert mnOutOffX changes that were potentially made in ImplPosSizeWindow
7374 long offx = mnOutOffX;
7375 if( ImplHasMirroredGraphics() )
7377 if( mpWindowImpl->mpParent && !mpWindowImpl->mpParent->mpWindowImpl->mbFrame && mpWindowImpl->mpParent->ImplIsAntiparallel() )
7379 if ( !ImplIsOverlapWindow() )
7380 offx -= mpWindowImpl->mpParent->mnOutOffX;
7382 offx = mpWindowImpl->mpParent->mnOutWidth - mnOutWidth - offx;
7384 if ( !ImplIsOverlapWindow() )
7385 offx += mpWindowImpl->mpParent->mnOutOffX;
7389 return offx;
7392 // normalized screen pixel are independent of mirroring
7393 Point Window::OutputToNormalizedScreenPixel( const Point& rPos ) const
7395 // relative to top level parent
7396 long offx = ((Window*) this)->ImplGetUnmirroredOutOffX();
7397 return Point( rPos.X()+offx, rPos.Y()+mnOutOffY );
7400 Point Window::NormalizedScreenToOutputPixel( const Point& rPos ) const
7402 // relative to top level parent
7403 long offx = ((Window*) this)->ImplGetUnmirroredOutOffX();
7404 return Point( rPos.X()-offx, rPos.Y()-mnOutOffY );
7407 // -----------------------------------------------------------------------
7409 Point Window::OutputToAbsoluteScreenPixel( const Point& rPos ) const
7411 // relative to the screen
7412 Point p = OutputToScreenPixel( rPos );
7413 SalFrameGeometry g = mpWindowImpl->mpFrame->GetGeometry();
7414 p.X() += g.nX;
7415 p.Y() += g.nY;
7416 return p;
7419 // -----------------------------------------------------------------------
7421 Point Window::AbsoluteScreenToOutputPixel( const Point& rPos ) const
7423 // relative to the screen
7424 Point p = ScreenToOutputPixel( rPos );
7425 SalFrameGeometry g = mpWindowImpl->mpFrame->GetGeometry();
7426 p.X() -= g.nX;
7427 p.Y() -= g.nY;
7428 return p;
7431 // -----------------------------------------------------------------------
7433 Rectangle Window::ImplOutputToUnmirroredAbsoluteScreenPixel( const Rectangle &rRect ) const
7435 // this method creates unmirrored screen coordinates to be compared with the desktop
7436 // and is used for positioning of RTL popup windows correctly on the screen
7437 SalFrameGeometry g = mpWindowImpl->mpFrame->GetUnmirroredGeometry();
7439 Point p1 = OutputToScreenPixel( rRect.TopRight() );
7440 p1.X() = g.nX+g.nWidth-p1.X();
7441 p1.Y() += g.nY;
7443 Point p2 = OutputToScreenPixel( rRect.BottomLeft() );
7444 p2.X() = g.nX+g.nWidth-p2.X();
7445 p2.Y() += g.nY;
7447 return Rectangle( p1, p2 );
7451 // -----------------------------------------------------------------------
7453 Rectangle Window::GetWindowExtentsRelative( Window *pRelativeWindow )
7455 // with decoration
7456 return ImplGetWindowExtentsRelative( pRelativeWindow, FALSE );
7459 Rectangle Window::GetClientWindowExtentsRelative( Window *pRelativeWindow )
7461 // without decoration
7462 return ImplGetWindowExtentsRelative( pRelativeWindow, TRUE );
7465 // -----------------------------------------------------------------------
7467 Rectangle Window::ImplGetWindowExtentsRelative( Window *pRelativeWindow, BOOL bClientOnly )
7469 SalFrameGeometry g = mpWindowImpl->mpFrame->GetGeometry();
7470 // make sure we use the extent of our border window,
7471 // otherwise we miss a few pixels
7472 Window *pWin = (!bClientOnly && mpWindowImpl->mpBorderWindow) ? mpWindowImpl->mpBorderWindow : this;
7474 Point aPos( pWin->OutputToScreenPixel( Point(0,0) ) );
7475 aPos.X() += g.nX;
7476 aPos.Y() += g.nY;
7477 Size aSize ( pWin->GetSizePixel() );
7478 // #104088# do not add decoration to the workwindow to be compatible to java accessibility api
7479 if( !bClientOnly && (mpWindowImpl->mbFrame || (mpWindowImpl->mpBorderWindow && mpWindowImpl->mpBorderWindow->mpWindowImpl->mbFrame && GetType() != WINDOW_WORKWINDOW)) )
7481 aPos.X() -= g.nLeftDecoration;
7482 aPos.Y() -= g.nTopDecoration;
7483 aSize.Width() += g.nLeftDecoration + g.nRightDecoration;
7484 aSize.Height() += g.nTopDecoration + g.nBottomDecoration;
7486 if( pRelativeWindow )
7488 // #106399# express coordinates relative to borderwindow
7489 Window *pRelWin = (!bClientOnly && pRelativeWindow->mpWindowImpl->mpBorderWindow) ? pRelativeWindow->mpWindowImpl->mpBorderWindow : pRelativeWindow;
7490 aPos = pRelWin->AbsoluteScreenToOutputPixel( aPos );
7492 return Rectangle( aPos, aSize );
7495 // -----------------------------------------------------------------------
7497 void Window::Scroll( long nHorzScroll, long nVertScroll, USHORT nFlags )
7499 DBG_CHKTHIS( Window, ImplDbgCheckWindow );
7501 ImplScroll( Rectangle( Point( mnOutOffX, mnOutOffY ),
7502 Size( mnOutWidth, mnOutHeight ) ),
7503 nHorzScroll, nVertScroll, nFlags & ~SCROLL_CLIP );
7506 // -----------------------------------------------------------------------
7508 void Window::Scroll( long nHorzScroll, long nVertScroll,
7509 const Rectangle& rRect, USHORT nFlags )
7511 DBG_CHKTHIS( Window, ImplDbgCheckWindow );
7513 Rectangle aRect = ImplLogicToDevicePixel( rRect );
7514 aRect.Intersection( Rectangle( Point( mnOutOffX, mnOutOffY ), Size( mnOutWidth, mnOutHeight ) ) );
7515 if ( !aRect.IsEmpty() )
7516 ImplScroll( aRect, nHorzScroll, nVertScroll, nFlags );
7519 // -----------------------------------------------------------------------
7521 void Window::Invalidate( USHORT nFlags )
7523 DBG_CHKTHIS( Window, ImplDbgCheckWindow );
7525 if ( !IsDeviceOutputNecessary() || !mnOutWidth || !mnOutHeight )
7526 return;
7528 ImplInvalidate( NULL, nFlags );
7531 // -----------------------------------------------------------------------
7533 void Window::Invalidate( const Rectangle& rRect, USHORT nFlags )
7535 DBG_CHKTHIS( Window, ImplDbgCheckWindow );
7537 if ( !IsDeviceOutputNecessary() || !mnOutWidth || !mnOutHeight )
7538 return;
7540 Rectangle aRect = ImplLogicToDevicePixel( rRect );
7541 if ( !aRect.IsEmpty() )
7543 Region aRegion( aRect );
7544 ImplInvalidate( &aRegion, nFlags );
7548 // -----------------------------------------------------------------------
7550 void Window::Invalidate( const Region& rRegion, USHORT nFlags )
7552 DBG_CHKTHIS( Window, ImplDbgCheckWindow );
7554 if ( !IsDeviceOutputNecessary() || !mnOutWidth || !mnOutHeight )
7555 return;
7557 if ( rRegion.IsNull() )
7558 ImplInvalidate( NULL, nFlags );
7559 else
7561 Region aRegion = ImplPixelToDevicePixel( LogicToPixel( rRegion ) );
7562 if ( !aRegion.IsEmpty() )
7563 ImplInvalidate( &aRegion, nFlags );
7567 // -----------------------------------------------------------------------
7569 void Window::Validate( USHORT nFlags )
7571 DBG_CHKTHIS( Window, ImplDbgCheckWindow );
7573 if ( !IsDeviceOutputNecessary() || !mnOutWidth || !mnOutHeight )
7574 return;
7576 ImplValidate( NULL, nFlags );
7579 // -----------------------------------------------------------------------
7581 void Window::Validate( const Rectangle& rRect, USHORT nFlags )
7583 DBG_CHKTHIS( Window, ImplDbgCheckWindow );
7585 if ( !IsDeviceOutputNecessary() || !mnOutWidth || !mnOutHeight )
7586 return;
7588 Rectangle aRect = ImplLogicToDevicePixel( rRect );
7589 if ( !aRect.IsEmpty() )
7591 Region aRegion( aRect );
7592 ImplValidate( &aRegion, nFlags );
7596 // -----------------------------------------------------------------------
7598 void Window::Validate( const Region& rRegion, USHORT nFlags )
7600 DBG_CHKTHIS( Window, ImplDbgCheckWindow );
7602 if ( !IsDeviceOutputNecessary() || !mnOutWidth || !mnOutHeight )
7603 return;
7605 if ( rRegion.IsNull() )
7606 ImplValidate( NULL, nFlags );
7607 else
7609 Region aRegion = ImplPixelToDevicePixel( LogicToPixel( rRegion ) );
7610 if ( !aRegion.IsEmpty() )
7611 ImplValidate( &aRegion, nFlags );
7615 // -----------------------------------------------------------------------
7617 BOOL Window::HasPaintEvent() const
7619 DBG_CHKTHIS( Window, ImplDbgCheckWindow );
7621 if ( !mpWindowImpl->mbReallyVisible )
7622 return FALSE;
7624 if ( mpWindowImpl->mpFrameWindow->mpWindowImpl->mbPaintFrame )
7625 return TRUE;
7627 if ( mpWindowImpl->mnPaintFlags & IMPL_PAINT_PAINT )
7628 return TRUE;
7630 if ( !ImplIsOverlapWindow() )
7632 const Window* pTempWindow = this;
7635 pTempWindow = pTempWindow->ImplGetParent();
7636 if ( pTempWindow->mpWindowImpl->mnPaintFlags & (IMPL_PAINT_PAINTCHILDS | IMPL_PAINT_PAINTALLCHILDS) )
7637 return TRUE;
7639 while ( !pTempWindow->ImplIsOverlapWindow() );
7642 return FALSE;
7645 // -----------------------------------------------------------------------
7647 void Window::Update()
7649 DBG_CHKTHIS( Window, ImplDbgCheckWindow );
7651 if ( mpWindowImpl->mpBorderWindow )
7653 mpWindowImpl->mpBorderWindow->Update();
7654 return;
7657 if ( !mpWindowImpl->mbReallyVisible )
7658 return;
7660 BOOL bFlush = FALSE;
7661 if ( mpWindowImpl->mpFrameWindow->mpWindowImpl->mbPaintFrame )
7663 Point aPoint( 0, 0 );
7664 Region aRegion( Rectangle( aPoint, Size( mnOutWidth, mnOutHeight ) ) );
7665 ImplInvalidateOverlapFrameRegion( aRegion );
7666 if ( mpWindowImpl->mbFrame || (mpWindowImpl->mpBorderWindow && mpWindowImpl->mpBorderWindow->mpWindowImpl->mbFrame) )
7667 bFlush = TRUE;
7670 // Zuerst muessen wir alle Fenster ueberspringen, die Paint-Transparent
7671 // sind
7672 Window* pUpdateWindow = this;
7673 Window* pWindow = pUpdateWindow;
7674 while ( !pWindow->ImplIsOverlapWindow() )
7676 if ( !pWindow->mpWindowImpl->mbPaintTransparent )
7678 pUpdateWindow = pWindow;
7679 break;
7681 pWindow = pWindow->ImplGetParent();
7683 // Ein Update wirkt immer auf das Window, wo PAINTALLCHILDS gesetzt
7684 // ist, damit nicht zuviel gemalt wird
7685 pWindow = pUpdateWindow;
7688 if ( pWindow->mpWindowImpl->mnPaintFlags & IMPL_PAINT_PAINTALLCHILDS )
7689 pUpdateWindow = pWindow;
7690 if ( pWindow->ImplIsOverlapWindow() )
7691 break;
7692 pWindow = pWindow->ImplGetParent();
7694 while ( pWindow );
7696 // Wenn es etwas zu malen gibt, dann ein Paint ausloesen
7697 if ( pUpdateWindow->mpWindowImpl->mnPaintFlags & (IMPL_PAINT_PAINT | IMPL_PAINT_PAINTCHILDS) )
7699 // und fuer alle ueber uns stehende System-Fenster auch ein Update
7700 // ausloesen, damit nicht die ganze Zeit luecken stehen bleiben
7701 Window* pUpdateOverlapWindow = ImplGetFirstOverlapWindow()->mpWindowImpl->mpFirstOverlap;
7702 while ( pUpdateOverlapWindow )
7704 pUpdateOverlapWindow->Update();
7705 pUpdateOverlapWindow = pUpdateOverlapWindow->mpWindowImpl->mpNext;
7708 pUpdateWindow->ImplCallPaint( NULL, pUpdateWindow->mpWindowImpl->mnPaintFlags );
7711 if ( bFlush )
7712 Flush();
7715 // -----------------------------------------------------------------------
7717 void Window::Flush()
7719 DBG_CHKTHIS( Window, ImplDbgCheckWindow );
7721 const Rectangle aWinRect( Point( mnOutOffX, mnOutOffY ), Size( mnOutWidth, mnOutHeight ) );
7722 mpWindowImpl->mpFrame->Flush( aWinRect );
7725 // -----------------------------------------------------------------------
7727 void Window::Sync()
7729 DBG_CHKTHIS( Window, ImplDbgCheckWindow );
7731 mpWindowImpl->mpFrame->Sync();
7734 // -----------------------------------------------------------------------
7736 void Window::SetUpdateMode( BOOL bUpdate )
7738 DBG_CHKTHIS( Window, ImplDbgCheckWindow );
7740 mpWindowImpl->mbNoUpdate = !bUpdate;
7741 StateChanged( STATE_CHANGE_UPDATEMODE );
7744 // -----------------------------------------------------------------------
7746 void Window::GrabFocus()
7748 DBG_CHKTHIS( Window, ImplDbgCheckWindow );
7750 ImplGrabFocus( 0 );
7753 // -----------------------------------------------------------------------
7755 BOOL Window::HasFocus() const
7757 DBG_CHKTHIS( Window, ImplDbgCheckWindow );
7759 // #107575# the first floating window always has the keyboard focus, see also winproc.cxx: ImplGetKeyInputWindow()
7760 // task was shifted to 6.y, so its commented out
7762 Window* pFocusWin = ImplGetSVData()->maWinData.mpFirstFloat;
7763 if( pFocusWin && pFocusWin->mpWindowImpl->mbFloatWin && ((FloatingWindow *)pFocusWin)->GrabsFocus() )
7764 pFocusWin = pFocusWin->GetPreferredKeyInputWindow();
7765 else
7766 pFocusWin = ImplGetSVData()->maWinData.mpFocusWin;
7768 return (this == pFocusWin);
7771 return (this == ImplGetSVData()->maWinData.mpFocusWin);
7774 // -----------------------------------------------------------------------
7776 void Window::GrabFocusToDocument()
7778 Window *pWin = this;
7779 while( pWin )
7781 if( !pWin->GetParent() )
7783 pWin->ImplGetFrameWindow()->GetWindow( WINDOW_CLIENT )->GrabFocus();
7784 return;
7786 pWin = pWin->GetParent();
7790 void Window::SetFakeFocus( bool bFocus )
7792 ImplGetWindowImpl()->mbFakeFocusSet = bFocus;
7795 // -----------------------------------------------------------------------
7797 BOOL Window::HasChildPathFocus( BOOL bSystemWindow ) const
7799 DBG_CHKTHIS( Window, ImplDbgCheckWindow );
7801 // #107575#, the first floating window always has the keyboard focus, see also winproc.cxx: ImplGetKeyInputWindow()
7802 // task was shifted to 6.y, so its commented out
7804 Window* pFocusWin = ImplGetSVData()->maWinData.mpFirstFloat;
7805 if( pFocusWin && pFocusWin->mpWindowImpl->mbFloatWin && ((FloatingWindow *)pFocusWin)->GrabsFocus() )
7806 pFocusWin = pFocusWin->GetPreferredKeyInputWindow();
7807 else
7808 pFocusWin = ImplGetSVData()->maWinData.mpFocusWin;
7810 Window* pFocusWin = ImplGetSVData()->maWinData.mpFocusWin;
7811 if ( pFocusWin )
7812 return ImplIsWindowOrChild( pFocusWin, bSystemWindow );
7813 return FALSE;
7816 // -----------------------------------------------------------------------
7818 void Window::CaptureMouse()
7820 DBG_CHKTHIS( Window, ImplDbgCheckWindow );
7822 ImplSVData* pSVData = ImplGetSVData();
7824 // Tracking evt. beenden
7825 if ( pSVData->maWinData.mpTrackWin != this )
7827 if ( pSVData->maWinData.mpTrackWin )
7828 pSVData->maWinData.mpTrackWin->EndTracking( ENDTRACK_CANCEL );
7831 if ( pSVData->maWinData.mpCaptureWin != this )
7833 pSVData->maWinData.mpCaptureWin = this;
7834 mpWindowImpl->mpFrame->CaptureMouse( TRUE );
7838 // -----------------------------------------------------------------------
7840 void Window::ReleaseMouse()
7842 DBG_CHKTHIS( Window, ImplDbgCheckWindow );
7844 ImplSVData* pSVData = ImplGetSVData();
7846 DBG_ASSERTWARNING( pSVData->maWinData.mpCaptureWin == this,
7847 "Window::ReleaseMouse(): window doesn't have the mouse capture" );
7849 if ( pSVData->maWinData.mpCaptureWin == this )
7851 pSVData->maWinData.mpCaptureWin = NULL;
7852 mpWindowImpl->mpFrame->CaptureMouse( FALSE );
7853 ImplGenerateMouseMove();
7857 // -----------------------------------------------------------------------
7859 BOOL Window::IsMouseCaptured() const
7861 DBG_CHKTHIS( Window, ImplDbgCheckWindow );
7863 return (this == ImplGetSVData()->maWinData.mpCaptureWin);
7866 // -----------------------------------------------------------------------
7868 void Window::SetPointer( const Pointer& rPointer )
7870 DBG_CHKTHIS( Window, ImplDbgCheckWindow );
7872 if ( mpWindowImpl->maPointer == rPointer )
7873 return;
7875 mpWindowImpl->maPointer = rPointer;
7877 // Pointer evt. direkt umsetzen
7878 if ( !mpWindowImpl->mpFrameData->mbInMouseMove && ImplTestMousePointerSet() )
7879 mpWindowImpl->mpFrame->SetPointer( ImplGetMousePointer() );
7882 // -----------------------------------------------------------------------
7884 void Window::EnableChildPointerOverwrite( BOOL bOverwrite )
7886 DBG_CHKTHIS( Window, ImplDbgCheckWindow );
7888 if ( mpWindowImpl->mbChildPtrOverwrite == bOverwrite )
7889 return;
7891 mpWindowImpl->mbChildPtrOverwrite = bOverwrite;
7893 // Pointer evt. direkt umsetzen
7894 if ( !mpWindowImpl->mpFrameData->mbInMouseMove && ImplTestMousePointerSet() )
7895 mpWindowImpl->mpFrame->SetPointer( ImplGetMousePointer() );
7898 // -----------------------------------------------------------------------
7900 void Window::SetPointerPosPixel( const Point& rPos )
7902 DBG_CHKTHIS( Window, ImplDbgCheckWindow );
7904 Point aPos = ImplOutputToFrame( rPos );
7905 if( ImplHasMirroredGraphics() )
7907 if( !IsRTLEnabled() )
7909 // --- RTL --- (re-mirror mouse pos at this window)
7910 ImplReMirror( aPos );
7912 // mirroring is required here, SetPointerPos bypasses SalGraphics
7913 mpGraphics->mirror( aPos.X(), this );
7915 else if( ImplIsAntiparallel() )
7917 ImplReMirror( aPos );
7919 mpWindowImpl->mpFrame->SetPointerPos( aPos.X(), aPos.Y() );
7922 // -----------------------------------------------------------------------
7924 Point Window::GetPointerPosPixel()
7926 DBG_CHKTHIS( Window, ImplDbgCheckWindow );
7928 Point aPos( mpWindowImpl->mpFrameData->mnLastMouseX, mpWindowImpl->mpFrameData->mnLastMouseY );
7929 if( ImplIsAntiparallel() )
7931 // --- RTL --- (re-mirror mouse pos at this window)
7932 ImplReMirror( aPos );
7934 return ImplFrameToOutput( aPos );
7937 // -----------------------------------------------------------------------
7939 Point Window::GetLastPointerPosPixel()
7941 DBG_CHKTHIS( Window, ImplDbgCheckWindow );
7943 Point aPos( mpWindowImpl->mpFrameData->mnBeforeLastMouseX, mpWindowImpl->mpFrameData->mnBeforeLastMouseY );
7944 if( ImplIsAntiparallel() )
7946 // --- RTL --- (re-mirror mouse pos at this window)
7947 ImplReMirror( aPos );
7949 return ImplFrameToOutput( aPos );
7952 // -----------------------------------------------------------------------
7954 void Window::ShowPointer( BOOL bVisible )
7956 DBG_CHKTHIS( Window, ImplDbgCheckWindow );
7958 if ( mpWindowImpl->mbNoPtrVisible != !bVisible )
7960 mpWindowImpl->mbNoPtrVisible = !bVisible;
7962 // Pointer evt. direkt umsetzen
7963 if ( !mpWindowImpl->mpFrameData->mbInMouseMove && ImplTestMousePointerSet() )
7964 mpWindowImpl->mpFrame->SetPointer( ImplGetMousePointer() );
7968 // -----------------------------------------------------------------------
7970 Window::PointerState Window::GetPointerState()
7972 PointerState aState;
7973 aState.mnState = 0;
7975 if (mpWindowImpl->mpFrame)
7977 SalFrame::SalPointerState aSalPointerState;
7979 aSalPointerState = mpWindowImpl->mpFrame->GetPointerState();
7980 if( ImplIsAntiparallel() )
7982 // --- RTL --- (re-mirror mouse pos at this window)
7983 ImplReMirror( aSalPointerState.maPos );
7985 aState.maPos = ImplFrameToOutput( aSalPointerState.maPos );
7986 aState.mnState = aSalPointerState.mnState;
7988 return aState;
7991 // -----------------------------------------------------------------------
7993 BOOL Window::IsMouseOver()
7995 return ImplGetWinData()->mbMouseOver;
7998 // -----------------------------------------------------------------------
8000 void Window::EnterWait()
8002 DBG_CHKTHIS( Window, ImplDbgCheckWindow );
8004 mpWindowImpl->mnWaitCount++;
8006 if ( mpWindowImpl->mnWaitCount == 1 )
8008 // Pointer evt. direkt umsetzen
8009 if ( !mpWindowImpl->mpFrameData->mbInMouseMove && ImplTestMousePointerSet() )
8010 mpWindowImpl->mpFrame->SetPointer( ImplGetMousePointer() );
8014 // -----------------------------------------------------------------------
8016 void Window::LeaveWait()
8018 DBG_CHKTHIS( Window, ImplDbgCheckWindow );
8020 if ( mpWindowImpl->mnWaitCount )
8022 mpWindowImpl->mnWaitCount--;
8024 if ( !mpWindowImpl->mnWaitCount )
8026 // Pointer evt. direkt umsetzen
8027 if ( !mpWindowImpl->mpFrameData->mbInMouseMove && ImplTestMousePointerSet() )
8028 mpWindowImpl->mpFrame->SetPointer( ImplGetMousePointer() );
8033 // -----------------------------------------------------------------------
8035 void Window::SetCursor( Cursor* pCursor )
8037 DBG_CHKTHIS( Window, ImplDbgCheckWindow );
8039 if ( mpWindowImpl->mpCursor != pCursor )
8041 if ( mpWindowImpl->mpCursor )
8042 mpWindowImpl->mpCursor->ImplHide();
8043 mpWindowImpl->mpCursor = pCursor;
8044 if ( pCursor )
8045 pCursor->ImplShow();
8049 // -----------------------------------------------------------------------
8051 void Window::SetText( const XubString& rStr )
8053 DBG_CHKTHIS( Window, ImplDbgCheckWindow );
8055 String oldTitle( mpWindowImpl->maText );
8056 mpWindowImpl->maText = rStr;
8058 if ( mpWindowImpl->mpBorderWindow )
8059 mpWindowImpl->mpBorderWindow->SetText( rStr );
8060 else if ( mpWindowImpl->mbFrame )
8061 mpWindowImpl->mpFrame->SetTitle( rStr );
8063 ImplCallEventListeners( VCLEVENT_WINDOW_FRAMETITLECHANGED, &oldTitle );
8065 // #107247# needed for accessibility
8066 // The VCLEVENT_WINDOW_FRAMETITLECHANGED is (mis)used to notify accessible name changes.
8067 // Therefore a window, which is labeled by this window, must also notify an accessible
8068 // name change.
8069 if ( IsReallyVisible() )
8071 Window* pWindow = GetLabelFor();
8072 if ( pWindow && pWindow != this )
8073 pWindow->ImplCallEventListeners( VCLEVENT_WINDOW_FRAMETITLECHANGED, &oldTitle );
8076 StateChanged( STATE_CHANGE_TEXT );
8079 // -----------------------------------------------------------------------
8081 String Window::GetText() const
8083 DBG_CHKTHIS( Window, ImplDbgCheckWindow );
8085 return mpWindowImpl->maText;
8088 // -----------------------------------------------------------------------
8090 String Window::GetDisplayText() const
8092 DBG_CHKTHIS( Window, ImplDbgCheckWindow );
8094 return GetText();
8097 // -----------------------------------------------------------------------
8099 const Wallpaper& Window::GetDisplayBackground() const
8101 // FIXME: fix issue 52349, need to fix this really in
8102 // all NWF enabled controls
8103 const ToolBox* pTB = dynamic_cast<const ToolBox*>(this);
8104 if( pTB )
8106 if( IsNativeWidgetEnabled() )
8107 return pTB->ImplGetToolBoxPrivateData()->maDisplayBackground;
8110 if( !IsBackground() )
8112 if( mpWindowImpl->mpParent )
8113 return mpWindowImpl->mpParent->GetDisplayBackground();
8116 const Wallpaper& rBack = GetBackground();
8117 if( ! rBack.IsBitmap() &&
8118 ! rBack.IsGradient() &&
8119 rBack.GetColor().GetColor() == COL_TRANSPARENT &&
8120 mpWindowImpl->mpParent )
8121 return mpWindowImpl->mpParent->GetDisplayBackground();
8122 return rBack;
8125 // -----------------------------------------------------------------------
8127 const XubString& Window::GetHelpText() const
8129 DBG_CHKTHIS( Window, ImplDbgCheckWindow );
8131 SmartId aSmartId = GetSmartHelpId();
8133 ULONG nNumHelpId = 0;
8134 String aStrHelpId;
8135 if( aSmartId.HasString() )
8136 aStrHelpId = aSmartId.GetStr();
8137 if( aSmartId.HasNumeric() )
8138 nNumHelpId = aSmartId.GetNum();
8139 bool bStrHelpId = (aStrHelpId.Len() > 0);
8141 if ( !mpWindowImpl->maHelpText.Len() && (nNumHelpId || bStrHelpId) )
8143 if ( !IsDialog() && (mpWindowImpl->mnType != WINDOW_TABPAGE) && (mpWindowImpl->mnType != WINDOW_FLOATINGWINDOW) )
8145 Help* pHelp = Application::GetHelp();
8146 if ( pHelp )
8148 if( bStrHelpId )
8149 ((Window*)this)->mpWindowImpl->maHelpText = pHelp->GetHelpText( aStrHelpId, this );
8150 else
8151 ((Window*)this)->mpWindowImpl->maHelpText = pHelp->GetHelpText( nNumHelpId, this );
8156 return mpWindowImpl->maHelpText;
8159 // -----------------------------------------------------------------------
8161 Window* Window::FindWindow( const Point& rPos ) const
8163 DBG_CHKTHIS( Window, ImplDbgCheckWindow );
8165 Point aPos = OutputToScreenPixel( rPos );
8166 return ((Window*)this)->ImplFindWindow( aPos );
8169 // -----------------------------------------------------------------------
8171 USHORT Window::GetChildCount() const
8173 DBG_CHKTHIS( Window, ImplDbgCheckWindow );
8175 USHORT nChildCount = 0;
8176 Window* pChild = mpWindowImpl->mpFirstChild;
8177 while ( pChild )
8179 nChildCount++;
8180 pChild = pChild->mpWindowImpl->mpNext;
8183 return nChildCount;
8186 // -----------------------------------------------------------------------
8188 Window* Window::GetChild( USHORT nChild ) const
8190 DBG_CHKTHIS( Window, ImplDbgCheckWindow );
8192 USHORT nChildCount = 0;
8193 Window* pChild = mpWindowImpl->mpFirstChild;
8194 while ( pChild )
8196 if ( nChild == nChildCount )
8197 return pChild;
8198 pChild = pChild->mpWindowImpl->mpNext;
8199 nChildCount++;
8202 return NULL;
8205 // -----------------------------------------------------------------------
8207 Window* Window::GetWindow( USHORT nType ) const
8209 DBG_CHKTHIS( Window, ImplDbgCheckWindow );
8211 switch ( nType )
8213 case WINDOW_PARENT:
8214 return mpWindowImpl->mpRealParent;
8216 case WINDOW_FIRSTCHILD:
8217 return mpWindowImpl->mpFirstChild;
8219 case WINDOW_LASTCHILD:
8220 return mpWindowImpl->mpLastChild;
8222 case WINDOW_PREV:
8223 return mpWindowImpl->mpPrev;
8225 case WINDOW_NEXT:
8226 return mpWindowImpl->mpNext;
8228 case WINDOW_FIRSTOVERLAP:
8229 return mpWindowImpl->mpFirstOverlap;
8231 case WINDOW_LASTOVERLAP:
8232 return mpWindowImpl->mpLastOverlap;
8234 case WINDOW_OVERLAP:
8235 if ( ImplIsOverlapWindow() )
8236 return (Window*)this;
8237 else
8238 return mpWindowImpl->mpOverlapWindow;
8240 case WINDOW_PARENTOVERLAP:
8241 if ( ImplIsOverlapWindow() )
8242 return mpWindowImpl->mpOverlapWindow;
8243 else
8244 return mpWindowImpl->mpOverlapWindow->mpWindowImpl->mpOverlapWindow;
8246 case WINDOW_CLIENT:
8247 return ((Window*)this)->ImplGetWindow();
8249 case WINDOW_REALPARENT:
8250 return ImplGetParent();
8252 case WINDOW_FRAME:
8253 return mpWindowImpl->mpFrameWindow;
8255 case WINDOW_BORDER:
8256 if ( mpWindowImpl->mpBorderWindow )
8257 return mpWindowImpl->mpBorderWindow->GetWindow( WINDOW_BORDER );
8258 return (Window*)this;
8260 case WINDOW_FIRSTTOPWINDOWCHILD:
8261 return ImplGetWinData()->maTopWindowChildren.empty() ? NULL : *ImplGetWinData()->maTopWindowChildren.begin();
8263 case WINDOW_LASTTOPWINDOWCHILD:
8264 return ImplGetWinData()->maTopWindowChildren.empty() ? NULL : *ImplGetWinData()->maTopWindowChildren.rbegin();
8266 case WINDOW_PREVTOPWINDOWSIBLING:
8268 if ( !mpWindowImpl->mpRealParent )
8269 return NULL;
8270 const ::std::list< Window* >& rTopWindows( mpWindowImpl->mpRealParent->ImplGetWinData()->maTopWindowChildren );
8271 ::std::list< Window* >::const_iterator myPos =
8272 ::std::find( rTopWindows.begin(), rTopWindows.end(), this );
8273 if ( myPos == rTopWindows.end() )
8274 return NULL;
8275 if ( myPos == rTopWindows.begin() )
8276 return NULL;
8277 return *--myPos;
8280 case WINDOW_NEXTTOPWINDOWSIBLING:
8282 if ( !mpWindowImpl->mpRealParent )
8283 return NULL;
8284 const ::std::list< Window* >& rTopWindows( mpWindowImpl->mpRealParent->ImplGetWinData()->maTopWindowChildren );
8285 ::std::list< Window* >::const_iterator myPos =
8286 ::std::find( rTopWindows.begin(), rTopWindows.end(), this );
8287 if ( ( myPos == rTopWindows.end() ) || ( ++myPos == rTopWindows.end() ) )
8288 return NULL;
8289 return *myPos;
8294 return NULL;
8297 // -----------------------------------------------------------------------
8299 BOOL Window::IsChild( const Window* pWindow, BOOL bSystemWindow ) const
8301 DBG_CHKTHIS( Window, ImplDbgCheckWindow );
8302 DBG_CHKOBJ( pWindow, Window, ImplDbgCheckWindow );
8306 if ( !bSystemWindow && pWindow->ImplIsOverlapWindow() )
8307 break;
8309 pWindow = pWindow->ImplGetParent();
8311 if ( pWindow == this )
8312 return TRUE;
8314 while ( pWindow );
8316 return FALSE;
8319 // -----------------------------------------------------------------------
8321 BOOL Window::IsWindowOrChild( const Window* pWindow, BOOL bSystemWindow ) const
8323 DBG_CHKTHIS( Window, ImplDbgCheckWindow );
8324 DBG_CHKOBJ( pWindow, Window, ImplDbgCheckWindow );
8326 if ( this == pWindow )
8327 return TRUE;
8328 return ImplIsChild( pWindow, bSystemWindow );
8331 // -----------------------------------------------------------------------
8333 const SystemEnvData* Window::GetSystemData() const
8335 DBG_CHKTHIS( Window, ImplDbgCheckWindow );
8337 return mpWindowImpl->mpFrame ? mpWindowImpl->mpFrame->GetSystemData() : NULL;
8340 ::com::sun::star::uno::Any Window::GetSystemDataAny() const
8342 ::com::sun::star::uno::Any aRet;
8343 const SystemEnvData* pSysData = GetSystemData();
8344 if( pSysData )
8346 ::com::sun::star::uno::Sequence< sal_Int8 > aSeq( (sal_Int8*)pSysData, pSysData->nSize );
8347 aRet <<= aSeq;
8349 return aRet;
8352 // -----------------------------------------------------------------------
8354 void Window::SetWindowPeer( ::com::sun::star::uno::Reference< ::com::sun::star::awt::XWindowPeer > xPeer, VCLXWindow* pVCLXWindow )
8356 // be safe against re-entrance: first clear the old ref, then assign the new one
8357 // #133706# / 2006-03-30 / frank.schoenheit@sun.com
8358 mpWindowImpl->mxWindowPeer.clear();
8359 mpWindowImpl->mxWindowPeer = xPeer;
8361 mpWindowImpl->mpVCLXWindow = pVCLXWindow;
8364 // -----------------------------------------------------------------------
8366 ::com::sun::star::uno::Reference< ::com::sun::star::awt::XWindowPeer > Window::GetComponentInterface( BOOL bCreate )
8368 if ( !mpWindowImpl->mxWindowPeer.is() && bCreate )
8370 UnoWrapperBase* pWrapper = Application::GetUnoWrapper();
8371 if ( pWrapper )
8372 mpWindowImpl->mxWindowPeer = pWrapper->GetWindowInterface( this, sal_True );
8374 return mpWindowImpl->mxWindowPeer;
8377 // -----------------------------------------------------------------------
8379 void Window::SetComponentInterface( ::com::sun::star::uno::Reference< ::com::sun::star::awt::XWindowPeer > xIFace )
8381 UnoWrapperBase* pWrapper = Application::GetUnoWrapper();
8382 DBG_ASSERT( pWrapper, "SetComponentInterface: No Wrapper!" );
8383 if ( pWrapper )
8384 pWrapper->SetWindowInterface( this, xIFace );
8387 // -----------------------------------------------------------------------
8389 void Window::ImplCallDeactivateListeners( Window *pNew )
8391 // no deactivation if the the newly activated window is my child
8392 if ( !pNew || !ImplIsChild( pNew ) )
8394 ImplDelData aDogtag( this );
8395 ImplCallEventListeners( VCLEVENT_WINDOW_DEACTIVATE );
8396 if( aDogtag.IsDelete() )
8397 return;
8399 // #100759#, avoid walking the wrong frame's hierarchy
8400 // eg, undocked docking windows (ImplDockFloatWin)
8401 if ( ImplGetParent() && mpWindowImpl->mpFrameWindow == ImplGetParent()->mpWindowImpl->mpFrameWindow )
8402 ImplGetParent()->ImplCallDeactivateListeners( pNew );
8406 // -----------------------------------------------------------------------
8408 void Window::ImplCallActivateListeners( Window *pOld )
8410 // no activation if the the old active window is my child
8411 if ( !pOld || !ImplIsChild( pOld ) )
8413 ImplDelData aDogtag( this );
8414 ImplCallEventListeners( VCLEVENT_WINDOW_ACTIVATE, pOld );
8415 if( aDogtag.IsDelete() )
8416 return;
8418 // #106298# revoke the change for 105369, because this change
8419 // disabled the activate event for the parent,
8420 // if the parent is a compound control
8421 //if( !GetParent() || !GetParent()->IsCompoundControl() )
8423 // #100759#, avoid walking the wrong frame's hierarchy
8424 // eg, undocked docking windows (ImplDockFloatWin)
8425 // #104714#, revert the changes for 100759 because it has a side effect when pOld is a dialog
8426 // additionally the gallery is not dockable anymore, so 100759 canot occur
8427 if ( ImplGetParent() ) /* && mpWindowImpl->mpFrameWindow == ImplGetParent()->mpWindowImpl->mpFrameWindow ) */
8428 ImplGetParent()->ImplCallActivateListeners( pOld );
8429 else if( (mpWindowImpl->mnStyle & WB_INTROWIN) == 0 )
8431 // top level frame reached: store hint for DefModalDialogParent
8432 ImplGetSVData()->maWinData.mpActiveApplicationFrame = mpWindowImpl->mpFrameWindow;
8438 // -----------------------------------------------------------------------
8440 bool Window::ImplStopDnd()
8442 bool bRet = false;
8443 if( mpWindowImpl->mpFrameData && mpWindowImpl->mpFrameData->mxDropTargetListener.is() )
8445 bRet = true;
8446 mpWindowImpl->mpFrameData->mxDropTarget.clear();
8447 mpWindowImpl->mpFrameData->mxDragSource.clear();
8448 mpWindowImpl->mpFrameData->mxDropTargetListener.clear();
8451 return bRet;
8454 // -----------------------------------------------------------------------
8456 void Window::ImplStartDnd()
8458 GetDropTarget();
8461 // -----------------------------------------------------------------------
8463 Reference< XDropTarget > Window::GetDropTarget()
8465 DBG_CHKTHIS( Window, ImplDbgCheckWindow );
8467 if( ! mpWindowImpl->mxDNDListenerContainer.is() )
8469 sal_Int8 nDefaultActions = 0;
8471 if( mpWindowImpl->mpFrameData )
8473 if( ! mpWindowImpl->mpFrameData->mxDropTarget.is() )
8475 // initialization is done in GetDragSource
8476 Reference< XDragSource > xDragSource = GetDragSource();
8479 if( mpWindowImpl->mpFrameData->mxDropTarget.is() )
8481 nDefaultActions = mpWindowImpl->mpFrameData->mxDropTarget->getDefaultActions();
8483 if( ! mpWindowImpl->mpFrameData->mxDropTargetListener.is() )
8485 mpWindowImpl->mpFrameData->mxDropTargetListener = new DNDEventDispatcher( mpWindowImpl->mpFrameWindow );
8489 mpWindowImpl->mpFrameData->mxDropTarget->addDropTargetListener( mpWindowImpl->mpFrameData->mxDropTargetListener );
8491 // register also as drag gesture listener if directly supported by drag source
8492 Reference< XDragGestureRecognizer > xDragGestureRecognizer =
8493 Reference< XDragGestureRecognizer > (mpWindowImpl->mpFrameData->mxDragSource, UNO_QUERY);
8495 if( xDragGestureRecognizer.is() )
8497 xDragGestureRecognizer->addDragGestureListener(
8498 Reference< XDragGestureListener > (mpWindowImpl->mpFrameData->mxDropTargetListener, UNO_QUERY));
8500 else
8501 mpWindowImpl->mpFrameData->mbInternalDragGestureRecognizer = TRUE;
8505 catch( RuntimeException exc )
8507 // release all instances
8508 mpWindowImpl->mpFrameData->mxDropTarget.clear();
8509 mpWindowImpl->mpFrameData->mxDragSource.clear();
8516 mpWindowImpl->mxDNDListenerContainer = static_cast < XDropTarget * > ( new DNDListenerContainer( nDefaultActions ) );
8519 // this object is located in the same process, so there will be no runtime exception
8520 return Reference< XDropTarget > ( mpWindowImpl->mxDNDListenerContainer, UNO_QUERY );
8523 // -----------------------------------------------------------------------
8525 Reference< XDragSource > Window::GetDragSource()
8527 DBG_CHKTHIS( Window, ImplDbgCheckWindow );
8529 if( mpWindowImpl->mpFrameData )
8531 if( ! mpWindowImpl->mpFrameData->mxDragSource.is() )
8535 Reference< XMultiServiceFactory > xFactory = vcl::unohelper::GetMultiServiceFactory();
8536 if ( xFactory.is() )
8538 const SystemEnvData * pEnvData = GetSystemData();
8540 if( pEnvData )
8542 Sequence< Any > aDragSourceAL( 2 ), aDropTargetAL( 2 );
8543 OUString aDragSourceSN, aDropTargetSN;
8544 #if defined WNT
8545 aDragSourceSN = OUString::createFromAscii( "com.sun.star.datatransfer.dnd.OleDragSource" );
8546 aDropTargetSN = OUString::createFromAscii( "com.sun.star.datatransfer.dnd.OleDropTarget" );
8547 aDragSourceAL[ 1 ] = makeAny( (sal_uInt32) pEnvData->hWnd );
8548 aDropTargetAL[ 0 ] = makeAny( (sal_uInt32) pEnvData->hWnd );
8549 #elif defined QUARTZ
8550 /* FIXME: Mac OS X specific dnd interface does not exist! *
8551 * Using Windows based dnd as a temporary solution */
8552 aDragSourceSN = OUString::createFromAscii( "com.sun.star.datatransfer.dnd.OleDragSource" );
8553 aDropTargetSN = OUString::createFromAscii( "com.sun.star.datatransfer.dnd.OleDropTarget" );
8554 aDragSourceAL[ 1 ] = makeAny( static_cast<sal_uInt64>( reinterpret_cast<sal_IntPtr>(pEnvData->pView) ) );
8555 aDropTargetAL[ 0 ] = makeAny( static_cast<sal_uInt64>( reinterpret_cast<sal_IntPtr>(pEnvData->pView) ) );
8556 #elif defined UNX
8557 aDropTargetAL.realloc( 3 );
8558 aDragSourceAL.realloc( 3 );
8559 aDragSourceSN = OUString::createFromAscii( "com.sun.star.datatransfer.dnd.X11DragSource" );
8560 aDropTargetSN = OUString::createFromAscii( "com.sun.star.datatransfer.dnd.X11DropTarget" );
8562 aDragSourceAL[ 0 ] = makeAny( Application::GetDisplayConnection() );
8563 aDragSourceAL[ 2 ] = makeAny( vcl::createBmpConverter() );
8564 aDropTargetAL[ 0 ] = makeAny( Application::GetDisplayConnection() );
8565 aDropTargetAL[ 1 ] = makeAny( (sal_Size)(pEnvData->aShellWindow) );
8566 aDropTargetAL[ 2 ] = makeAny( vcl::createBmpConverter() );
8567 #endif
8568 if( aDragSourceSN.getLength() )
8569 mpWindowImpl->mpFrameData->mxDragSource = Reference< XDragSource > ( xFactory->createInstanceWithArguments( aDragSourceSN, aDragSourceAL ), UNO_QUERY );
8571 if( aDropTargetSN.getLength() )
8572 mpWindowImpl->mpFrameData->mxDropTarget = Reference< XDropTarget > ( xFactory->createInstanceWithArguments( aDropTargetSN, aDropTargetAL ), UNO_QUERY );
8577 // createInstance can throw any exception
8578 catch( Exception exc )
8580 // release all instances
8581 mpWindowImpl->mpFrameData->mxDropTarget.clear();
8582 mpWindowImpl->mpFrameData->mxDragSource.clear();
8586 return mpWindowImpl->mpFrameData->mxDragSource;
8589 return Reference< XDragSource > ();
8592 // -----------------------------------------------------------------------
8594 void Window::GetDragSourceDropTarget(Reference< XDragSource >& xDragSource, Reference< XDropTarget > &xDropTarget )
8595 // only for RVP transmission
8597 if( mpWindowImpl->mpFrameData )
8599 // initialization is done in GetDragSource
8600 xDragSource = GetDragSource();
8601 xDropTarget = mpWindowImpl->mpFrameData->mxDropTarget;
8603 else
8605 xDragSource.clear();
8606 xDropTarget.clear();
8610 // -----------------------------------------------------------------------
8612 Reference< XDragGestureRecognizer > Window::GetDragGestureRecognizer()
8614 return Reference< XDragGestureRecognizer > ( GetDropTarget(), UNO_QUERY );
8617 // -----------------------------------------------------------------------
8619 Reference< XClipboard > Window::GetClipboard()
8621 DBG_CHKTHIS( Window, ImplDbgCheckWindow );
8623 if( mpWindowImpl->mpFrameData )
8625 if( ! mpWindowImpl->mpFrameData->mxClipboard.is() )
8629 Reference< XMultiServiceFactory > xFactory( vcl::unohelper::GetMultiServiceFactory() );
8631 if( xFactory.is() )
8633 mpWindowImpl->mpFrameData->mxClipboard = Reference< XClipboard >( xFactory->createInstance( OUString::createFromAscii( "com.sun.star.datatransfer.clipboard.SystemClipboard" ) ), UNO_QUERY );
8635 #if defined(UNX) && !defined(QUARTZ) // unix clipboard needs to be initialized
8636 if( mpWindowImpl->mpFrameData->mxClipboard.is() )
8638 Reference< XInitialization > xInit = Reference< XInitialization >( mpWindowImpl->mpFrameData->mxClipboard, UNO_QUERY );
8640 if( xInit.is() )
8642 Sequence< Any > aArgumentList( 3 );
8643 aArgumentList[ 0 ] = makeAny( Application::GetDisplayConnection() );
8644 aArgumentList[ 1 ] = makeAny( OUString::createFromAscii( "CLIPBOARD" ) );
8645 aArgumentList[ 2 ] = makeAny( vcl::createBmpConverter() );
8647 xInit->initialize( aArgumentList );
8650 #endif
8654 // createInstance can throw any exception
8655 catch( Exception exc )
8657 // release all instances
8658 mpWindowImpl->mpFrameData->mxClipboard.clear();
8662 return mpWindowImpl->mpFrameData->mxClipboard;
8665 return static_cast < XClipboard * > (0);
8668 // -----------------------------------------------------------------------
8670 Reference< XClipboard > Window::GetPrimarySelection()
8672 DBG_CHKTHIS( Window, ImplDbgCheckWindow );
8674 if( mpWindowImpl->mpFrameData )
8676 if( ! mpWindowImpl->mpFrameData->mxSelection.is() )
8680 Reference< XMultiServiceFactory > xFactory( vcl::unohelper::GetMultiServiceFactory() );
8682 if( xFactory.is() )
8684 #if defined(UNX) && !defined(QUARTZ)
8685 Sequence< Any > aArgumentList( 3 );
8686 aArgumentList[ 0 ] = makeAny( Application::GetDisplayConnection() );
8687 aArgumentList[ 1 ] = makeAny( OUString::createFromAscii( "PRIMARY" ) );
8688 aArgumentList[ 2 ] = makeAny( vcl::createBmpConverter() );
8690 mpWindowImpl->mpFrameData->mxSelection = Reference< XClipboard >( xFactory->createInstanceWithArguments(
8691 OUString::createFromAscii( "com.sun.star.datatransfer.clipboard.SystemClipboard" ), aArgumentList ), UNO_QUERY );
8692 # else
8693 static Reference< XClipboard > s_xSelection;
8695 if ( !s_xSelection.is() )
8696 s_xSelection = Reference< XClipboard >( xFactory->createInstance( OUString::createFromAscii( "com.sun.star.datatransfer.clipboard.GenericClipboard" ) ), UNO_QUERY );
8698 mpWindowImpl->mpFrameData->mxSelection = s_xSelection;
8699 # endif
8703 // createInstance can throw any exception
8704 catch( Exception exc )
8706 // release all instances
8707 mpWindowImpl->mpFrameData->mxSelection.clear();
8711 return mpWindowImpl->mpFrameData->mxSelection;
8714 return static_cast < XClipboard * > (0);
8717 // -----------------------------------------------------------------------
8718 // Accessibility
8719 // -----------------------------------------------------------------------
8721 ::com::sun::star::uno::Reference< ::com::sun::star::accessibility::XAccessible > Window::GetAccessible( BOOL bCreate )
8723 // do not optimize hierarchy for the top level border win (ie, when there is no parent)
8724 /* // do not optimize accessible hierarchy at all to better reflect real VCL hierarchy
8725 if ( GetParent() && ( GetType() == WINDOW_BORDERWINDOW ) && ( GetChildCount() == 1 ) )
8726 //if( !ImplIsAccessibleCandidate() )
8728 Window* pChild = GetAccessibleChildWindow( 0 );
8729 if ( pChild )
8730 return pChild->GetAccessible();
8733 if ( !mpWindowImpl->mxAccessible.is() && bCreate )
8734 mpWindowImpl->mxAccessible = CreateAccessible();
8736 return mpWindowImpl->mxAccessible;
8739 ::com::sun::star::uno::Reference< ::com::sun::star::accessibility::XAccessible > Window::CreateAccessible()
8741 ::com::sun::star::uno::Reference< ::com::sun::star::accessibility::XAccessible > xAcc( GetComponentInterface( TRUE ), ::com::sun::star::uno::UNO_QUERY );
8742 return xAcc;
8745 void Window::SetAccessible( ::com::sun::star::uno::Reference< ::com::sun::star::accessibility::XAccessible > x )
8747 mpWindowImpl->mxAccessible = x;
8750 // skip all border windows that are no top level frames
8751 BOOL Window::ImplIsAccessibleCandidate() const
8753 if( !mpWindowImpl->mbBorderWin )
8754 return TRUE;
8755 else
8756 // #101741 do not check for WB_CLOSEABLE because undecorated floaters (like menues!) are closeable
8757 if( mpWindowImpl->mbFrame && mpWindowImpl->mnStyle & (WB_MOVEABLE | WB_SIZEABLE) )
8758 return TRUE;
8759 else
8760 return FALSE;
8763 BOOL Window::ImplIsAccessibleNativeFrame() const
8765 if( mpWindowImpl->mbFrame )
8766 // #101741 do not check for WB_CLOSEABLE because undecorated floaters (like menues!) are closeable
8767 if( (mpWindowImpl->mnStyle & (WB_MOVEABLE | WB_SIZEABLE)) )
8768 return TRUE;
8769 else
8770 return FALSE;
8771 else
8772 return FALSE;
8775 USHORT Window::ImplGetAccessibleCandidateChildWindowCount( USHORT nFirstWindowType ) const
8777 USHORT nChildren = 0;
8778 Window* pChild = GetWindow( nFirstWindowType );
8779 while ( pChild )
8781 if( pChild->ImplIsAccessibleCandidate() )
8782 nChildren++;
8783 else
8784 nChildren = sal::static_int_cast<USHORT>(nChildren + pChild->ImplGetAccessibleCandidateChildWindowCount( WINDOW_FIRSTCHILD ));
8785 pChild = pChild->mpWindowImpl->mpNext;
8787 return nChildren;
8790 Window* Window::ImplGetAccessibleCandidateChild( USHORT nChild, USHORT& rChildCount, USHORT nFirstWindowType, BOOL bTopLevel ) const
8792 DBG_CHKTHIS( Window, ImplDbgCheckWindow );
8794 if( bTopLevel )
8795 rChildCount = 0;
8797 Window* pChild = GetWindow( nFirstWindowType );
8798 while ( pChild )
8800 Window *pTmpChild = pChild;
8802 if( !pChild->ImplIsAccessibleCandidate() )
8803 pTmpChild = pChild->ImplGetAccessibleCandidateChild( nChild, rChildCount, WINDOW_FIRSTCHILD, FALSE );
8805 if ( nChild == rChildCount )
8806 return pTmpChild;
8807 pChild = pChild->mpWindowImpl->mpNext;
8808 rChildCount++;
8811 return NULL;
8815 Window* Window::GetAccessibleParentWindow() const
8817 Window* pParent = GetParent();
8818 while ( pParent )
8819 if( pParent->ImplIsAccessibleCandidate() )
8820 break;
8821 else
8822 pParent = pParent->GetParent();
8823 return pParent;
8827 Window* Window::GetAccessibleParentWindow() const
8829 if ( ImplIsAccessibleNativeFrame() )
8830 return NULL;
8832 Window* pParent = mpWindowImpl->mpParent;
8833 if( GetType() == WINDOW_MENUBARWINDOW )
8835 // report the menubar as a child of THE workwindow
8836 Window *pWorkWin = GetParent()->mpWindowImpl->mpFirstChild;
8837 while( pWorkWin && (pWorkWin == this) )
8838 pWorkWin = pWorkWin->mpWindowImpl->mpNext;
8839 pParent = pWorkWin;
8841 // If this a floating window which has a native boarder window, this one should be reported as
8842 // accessible parent
8843 else if( GetType() == WINDOW_FLOATINGWINDOW &&
8844 mpWindowImpl->mpBorderWindow && mpWindowImpl->mpBorderWindow->mpWindowImpl->mbFrame)
8846 pParent = mpWindowImpl->mpBorderWindow;
8848 else if( pParent && !pParent->ImplIsAccessibleCandidate() )
8850 pParent = pParent->mpWindowImpl->mpParent;
8852 return pParent;
8856 USHORT Window::GetAccessibleChildWindowCount()
8858 USHORT nChildren = ImplGetAccessibleCandidateChildWindowCount( WINDOW_FIRSTCHILD );
8860 // Search also for SystemWindows.
8861 Window* pOverlap = GetWindow( WINDOW_OVERLAP );
8862 nChildren += pOverlap->ImplGetAccessibleCandidateChildWindowCount( WINDOW_FIRSTOVERLAP );
8864 return nChildren;
8868 USHORT Window::GetAccessibleChildWindowCount()
8870 USHORT nChildren = 0;
8871 Window* pChild = mpWindowImpl->mpFirstChild;
8872 while( pChild )
8874 if( pChild->IsVisible() )
8875 nChildren++;
8876 pChild = pChild->mpWindowImpl->mpNext;
8879 // #107176# ignore overlapwindows
8880 // this only affects non-system floating windows
8881 // which are either not accessible (like the HelpAgent) or should be changed to system windows anyway
8883 if( ImplIsOverlapWindow() )
8885 Window* pOverlap = GetWindow( WINDOW_FIRSTOVERLAP );
8886 while ( pOverlap )
8888 if( pOverlap->IsVisible() )
8889 nChildren++;
8890 pOverlap = pOverlap->GetWindow( WINDOW_NEXT );
8895 // report the menubarwindow as a child of THE workwindow
8896 if( GetType() == WINDOW_BORDERWINDOW )
8898 if( ((ImplBorderWindow *) this)->mpMenuBarWindow &&
8899 ((ImplBorderWindow *) this)->mpMenuBarWindow->IsVisible()
8901 --nChildren;
8903 else if( GetType() == WINDOW_WORKWINDOW )
8905 if( ((WorkWindow *) this)->GetMenuBar() &&
8906 ((WorkWindow *) this)->GetMenuBar()->GetWindow() &&
8907 ((WorkWindow *) this)->GetMenuBar()->GetWindow()->IsVisible()
8909 ++nChildren;
8912 return nChildren;
8916 Window* Window::GetAccessibleChildWindow( USHORT n )
8918 USHORT nChildCount; // will be set in ImplGetAccessibleCandidateChild(...)
8919 Window* pChild = ImplGetAccessibleCandidateChild( n, nChildCount, WINDOW_FIRSTCHILD, TRUE );
8920 if ( !pChild && ( n >= nChildCount ) )
8922 Window* pOverlap = GetWindow( WINDOW_OVERLAP );
8923 pChild = pOverlap->ImplGetAccessibleCandidateChild( n, nChildCount, WINDOW_FIRSTOVERLAP, FALSE );
8926 return pChild;
8930 Window* Window::GetAccessibleChildWindow( USHORT n )
8932 // report the menubarwindow as a the first child of THE workwindow
8933 if( GetType() == WINDOW_WORKWINDOW && ((WorkWindow *) this)->GetMenuBar() )
8935 if( n == 0 )
8937 MenuBar *pMenuBar = ((WorkWindow *) this)->GetMenuBar();
8938 if( pMenuBar->GetWindow() && pMenuBar->GetWindow()->IsVisible() )
8939 return pMenuBar->GetWindow();
8941 else
8942 --n;
8945 // transform n to child number including invisible children
8946 USHORT nChildren = n;
8947 Window* pChild = mpWindowImpl->mpFirstChild;
8948 while( pChild )
8950 if( pChild->IsVisible() )
8952 if( ! nChildren )
8953 break;
8954 nChildren--;
8956 pChild = pChild->mpWindowImpl->mpNext;
8959 if( GetType() == WINDOW_BORDERWINDOW && pChild && pChild->GetType() == WINDOW_MENUBARWINDOW )
8961 do pChild = pChild->mpWindowImpl->mpNext; while( pChild && ! pChild->IsVisible() );
8962 DBG_ASSERT( pChild, "GetAccessibleChildWindow(): wrong index in border window");
8964 if ( !pChild )
8966 // #107176# ignore overlapwindows
8968 if( ImplIsOverlapWindow() )
8970 Window* pOverlap = GetWindow( WINDOW_FIRSTOVERLAP );
8971 while ( !pChild && pOverlap )
8973 if ( !nChildren && pOverlap->IsVisible() )
8975 pChild = pOverlap;
8976 break;
8978 pOverlap = pOverlap->GetWindow( WINDOW_NEXT );
8979 if( pOverlap && pOverlap->IsVisible() )
8980 nChildren--;
8986 if ( pChild && ( pChild->GetType() == WINDOW_BORDERWINDOW ) && ( pChild->GetChildCount() == 1 ) )
8988 pChild = pChild->GetChild( 0 );
8990 return pChild;
8994 void Window::SetAccessibleRole( USHORT nRole )
8996 if ( !mpWindowImpl->mpAccessibleInfos )
8997 mpWindowImpl->mpAccessibleInfos = new ImplAccessibleInfos;
8999 DBG_ASSERT( mpWindowImpl->mpAccessibleInfos->nAccessibleRole == 0xFFFF, "AccessibleRole already set!" );
9000 mpWindowImpl->mpAccessibleInfos->nAccessibleRole = nRole;
9003 USHORT Window::GetAccessibleRole() const
9005 using namespace ::com::sun::star;
9007 USHORT nRole = mpWindowImpl->mpAccessibleInfos ? mpWindowImpl->mpAccessibleInfos->nAccessibleRole : 0xFFFF;
9008 if ( nRole == 0xFFFF )
9010 switch ( GetType() )
9012 case WINDOW_MESSBOX: // MT: Would be nice to have special roles!
9013 case WINDOW_INFOBOX:
9014 case WINDOW_WARNINGBOX:
9015 case WINDOW_ERRORBOX:
9016 case WINDOW_QUERYBOX: nRole = accessibility::AccessibleRole::ALERT; break;
9018 case WINDOW_MODELESSDIALOG:
9019 case WINDOW_MODALDIALOG:
9020 case WINDOW_SYSTEMDIALOG:
9021 case WINDOW_PRINTERSETUPDIALOG:
9022 case WINDOW_PRINTDIALOG:
9023 case WINDOW_TABDIALOG:
9024 case WINDOW_BUTTONDIALOG:
9025 case WINDOW_DIALOG: nRole = accessibility::AccessibleRole::DIALOG; break;
9027 case WINDOW_PUSHBUTTON:
9028 case WINDOW_OKBUTTON:
9029 case WINDOW_CANCELBUTTON:
9030 case WINDOW_HELPBUTTON:
9031 case WINDOW_IMAGEBUTTON:
9032 case WINDOW_MENUBUTTON:
9033 case WINDOW_MOREBUTTON:
9034 case WINDOW_SPINBUTTON:
9035 case WINDOW_BUTTON: nRole = accessibility::AccessibleRole::PUSH_BUTTON; break;
9037 case WINDOW_PATHDIALOG: nRole = accessibility::AccessibleRole::DIRECTORY_PANE; break;
9038 case WINDOW_FILEDIALOG: nRole = accessibility::AccessibleRole::FILE_CHOOSER; break;
9039 case WINDOW_COLORDIALOG: nRole = accessibility::AccessibleRole::COLOR_CHOOSER; break;
9040 case WINDOW_FONTDIALOG: nRole = accessibility::AccessibleRole::FONT_CHOOSER; break;
9042 case WINDOW_IMAGERADIOBUTTON:
9043 case WINDOW_RADIOBUTTON: nRole = accessibility::AccessibleRole::RADIO_BUTTON; break;
9044 case WINDOW_TRISTATEBOX:
9045 case WINDOW_CHECKBOX: nRole = accessibility::AccessibleRole::CHECK_BOX; break;
9047 case WINDOW_MULTILINEEDIT: nRole = accessibility::AccessibleRole::SCROLL_PANE; break;
9049 case WINDOW_PATTERNFIELD:
9050 case WINDOW_NUMERICFIELD:
9051 case WINDOW_METRICFIELD:
9052 case WINDOW_CURRENCYFIELD:
9053 case WINDOW_LONGCURRENCYFIELD:
9054 case WINDOW_EDIT: nRole = ( GetStyle() & WB_PASSWORD ) ? (accessibility::AccessibleRole::PASSWORD_TEXT) : (accessibility::AccessibleRole::TEXT); break;
9056 case WINDOW_PATTERNBOX:
9057 case WINDOW_NUMERICBOX:
9058 case WINDOW_METRICBOX:
9059 case WINDOW_CURRENCYBOX:
9060 case WINDOW_LONGCURRENCYBOX:
9061 case WINDOW_COMBOBOX: nRole = accessibility::AccessibleRole::COMBO_BOX; break;
9063 case WINDOW_LISTBOX:
9064 case WINDOW_MULTILISTBOX: nRole = accessibility::AccessibleRole::LIST; break;
9066 case WINDOW_TREELISTBOX: nRole = accessibility::AccessibleRole::TREE; break;
9068 case WINDOW_FIXEDTEXT: nRole = accessibility::AccessibleRole::LABEL; break;
9069 case WINDOW_FIXEDBORDER:
9070 case WINDOW_FIXEDLINE: nRole = accessibility::AccessibleRole::SEPARATOR; break;
9071 case WINDOW_FIXEDBITMAP:
9072 case WINDOW_FIXEDIMAGE: nRole = accessibility::AccessibleRole::ICON; break;
9073 case WINDOW_GROUPBOX: nRole = accessibility::AccessibleRole::GROUP_BOX; break;
9074 case WINDOW_SCROLLBAR: nRole = accessibility::AccessibleRole::SCROLL_BAR; break;
9076 case WINDOW_SLIDER:
9077 case WINDOW_SPLITTER:
9078 case WINDOW_SPLITWINDOW: nRole = accessibility::AccessibleRole::SPLIT_PANE; break;
9080 case WINDOW_DATEBOX:
9081 case WINDOW_TIMEBOX:
9082 case WINDOW_DATEFIELD:
9083 case WINDOW_TIMEFIELD: nRole = accessibility::AccessibleRole::DATE_EDITOR; break;
9085 case WINDOW_SPINFIELD: nRole = accessibility::AccessibleRole::SPIN_BOX; break;
9087 case WINDOW_TOOLBOX: nRole = accessibility::AccessibleRole::TOOL_BAR; break;
9088 case WINDOW_STATUSBAR: nRole = accessibility::AccessibleRole::STATUS_BAR; break;
9090 case WINDOW_TABPAGE: nRole = accessibility::AccessibleRole::PANEL; break;
9091 case WINDOW_TABCONTROL: nRole = accessibility::AccessibleRole::PAGE_TAB_LIST; break;
9093 case WINDOW_DOCKINGWINDOW:
9094 case WINDOW_SYSWINDOW: nRole = (mpWindowImpl->mbFrame) ? accessibility::AccessibleRole::FRAME :
9095 accessibility::AccessibleRole::PANEL; break;
9097 case WINDOW_FLOATINGWINDOW: nRole = ( mpWindowImpl->mbFrame ||
9098 (mpWindowImpl->mpBorderWindow && mpWindowImpl->mpBorderWindow->mpWindowImpl->mbFrame) ||
9099 (GetStyle() & WB_OWNERDRAWDECORATION) ) ? accessibility::AccessibleRole::FRAME :
9100 accessibility::AccessibleRole::WINDOW; break;
9102 case WINDOW_WORKWINDOW: nRole = accessibility::AccessibleRole::ROOT_PANE; break;
9105 case WINDOW_SCROLLBARBOX: nRole = accessibility::AccessibleRole::FILLER; break;
9107 case WINDOW_HELPTEXTWINDOW: nRole = accessibility::AccessibleRole::TOOL_TIP; break;
9109 case WINDOW_WINDOW:
9110 case WINDOW_CONTROL:
9111 case WINDOW_BORDERWINDOW:
9112 case WINDOW_SYSTEMCHILDWINDOW:
9113 default:
9114 if (ImplIsAccessibleNativeFrame() )
9115 nRole = accessibility::AccessibleRole::FRAME;
9116 else if( IsScrollable() )
9117 nRole = accessibility::AccessibleRole::SCROLL_PANE;
9118 else if( ((Window*)this)->ImplGetWindow()->IsMenuFloatingWindow() )
9119 nRole = accessibility::AccessibleRole::WINDOW; // #106002#, contextmenues are windows (i.e. toplevel)
9120 else
9121 // #104051# WINDOW seems to be a bad default role, use LAYEREDPANE instead
9122 // a WINDOW is interpreted as a top-level window, which is typically not the case
9123 //nRole = accessibility::AccessibleRole::WINDOW;
9124 nRole = accessibility::AccessibleRole::PANEL;
9127 return nRole;
9130 void Window::SetAccessibleName( const String& rName )
9132 if ( !mpWindowImpl->mpAccessibleInfos )
9133 mpWindowImpl->mpAccessibleInfos = new ImplAccessibleInfos;
9135 DBG_ASSERT( !mpWindowImpl->mpAccessibleInfos->pAccessibleName, "AccessibleName already set!" );
9136 delete mpWindowImpl->mpAccessibleInfos->pAccessibleName;
9137 mpWindowImpl->mpAccessibleInfos->pAccessibleName = new String( rName );
9140 String Window::GetAccessibleName() const
9142 String aAccessibleName;
9143 if ( mpWindowImpl->mpAccessibleInfos && mpWindowImpl->mpAccessibleInfos->pAccessibleName )
9145 aAccessibleName = *mpWindowImpl->mpAccessibleInfos->pAccessibleName;
9147 else
9149 switch ( GetType() )
9151 // case WINDOW_IMAGERADIOBUTTON:
9152 // case WINDOW_RADIOBUTTON:
9153 // case WINDOW_TRISTATEBOX:
9154 // case WINDOW_CHECKBOX:
9156 case WINDOW_MULTILINEEDIT:
9157 case WINDOW_PATTERNFIELD:
9158 case WINDOW_NUMERICFIELD:
9159 case WINDOW_METRICFIELD:
9160 case WINDOW_CURRENCYFIELD:
9161 case WINDOW_LONGCURRENCYFIELD:
9162 case WINDOW_EDIT:
9164 case WINDOW_DATEBOX:
9165 case WINDOW_TIMEBOX:
9166 case WINDOW_CURRENCYBOX:
9167 case WINDOW_LONGCURRENCYBOX:
9168 case WINDOW_DATEFIELD:
9169 case WINDOW_TIMEFIELD:
9170 case WINDOW_SPINFIELD:
9172 case WINDOW_COMBOBOX:
9173 case WINDOW_LISTBOX:
9174 case WINDOW_MULTILISTBOX:
9175 case WINDOW_TREELISTBOX:
9178 Window *pLabel = GetLabeledBy();
9179 if ( pLabel && pLabel != this )
9180 aAccessibleName = pLabel->GetText();
9182 break;
9184 case WINDOW_IMAGEBUTTON:
9185 case WINDOW_PUSHBUTTON:
9186 aAccessibleName = GetText();
9187 if ( !aAccessibleName.Len() )
9189 aAccessibleName = GetQuickHelpText();
9190 if ( !aAccessibleName.Len() )
9191 aAccessibleName = GetHelpText();
9193 break;
9195 default:
9196 aAccessibleName = GetText();
9197 break;
9200 aAccessibleName = GetNonMnemonicString( aAccessibleName );
9203 return aAccessibleName;
9206 void Window::SetAccessibleDescription( const String& rDescription )
9208 if ( ! mpWindowImpl->mpAccessibleInfos )
9209 mpWindowImpl->mpAccessibleInfos = new ImplAccessibleInfos;
9211 DBG_ASSERT( !mpWindowImpl->mpAccessibleInfos->pAccessibleDescription, "AccessibleDescription already set!" );
9212 delete mpWindowImpl->mpAccessibleInfos->pAccessibleDescription;
9213 mpWindowImpl->mpAccessibleInfos->pAccessibleDescription = new String( rDescription );
9216 String Window::GetAccessibleDescription() const
9218 String aAccessibleDescription;
9219 if ( mpWindowImpl->mpAccessibleInfos && mpWindowImpl->mpAccessibleInfos->pAccessibleDescription )
9221 aAccessibleDescription = *mpWindowImpl->mpAccessibleInfos->pAccessibleDescription;
9223 else
9225 // Special code for help text windows. ZT asks the border window for the
9226 // description so we have to forward this request to our inner window.
9227 const Window* pWin = ((Window *)this)->ImplGetWindow();
9228 if ( pWin->GetType() == WINDOW_HELPTEXTWINDOW )
9229 aAccessibleDescription = pWin->GetHelpText();
9230 else
9231 aAccessibleDescription = GetHelpText();
9234 return aAccessibleDescription;
9237 BOOL Window::IsAccessibilityEventsSuppressed( BOOL bTraverseParentPath )
9239 if( !bTraverseParentPath )
9240 return mpWindowImpl->mbSuppressAccessibilityEvents;
9241 else
9243 Window *pParent = this;
9244 while ( pParent && pParent->mpWindowImpl)
9246 if( pParent->mpWindowImpl->mbSuppressAccessibilityEvents )
9247 return TRUE;
9248 else
9249 pParent = pParent->mpWindowImpl->mpParent; // do not use GetParent() to find borderwindows that are frames
9251 return FALSE;
9255 void Window::RecordLayoutData( vcl::ControlLayoutData* pLayout, const Rectangle& rRect )
9257 if( ! mpOutDevData )
9258 ImplInitOutDevData();
9259 mpOutDevData->mpRecordLayout = pLayout;
9260 mpOutDevData->maRecordRect = rRect;
9261 Paint( rRect );
9262 mpOutDevData->mpRecordLayout = NULL;
9265 // -----------------------------------------------------------------------
9266 // -----------------------------------------------------------------------
9269 // returns background color used in this control
9270 // false: could not determine color
9271 BOOL Window::ImplGetCurrentBackgroundColor( Color& rCol )
9273 BOOL bRet = TRUE;
9275 switch ( GetType() )
9277 // peform special handling here
9278 case WINDOW_PUSHBUTTON:
9279 case WINDOW_OKBUTTON:
9280 case WINDOW_CANCELBUTTON:
9281 // etc.
9282 default:
9283 if( IsControlBackground() )
9284 rCol = GetControlBackground();
9285 else if( IsBackground() )
9287 Wallpaper aWall = GetBackground();
9288 if( !aWall.IsGradient() && !aWall.IsBitmap() )
9289 rCol = aWall.GetColor();
9290 else
9291 bRet = FALSE;
9293 else
9294 rCol = GetSettings().GetStyleSettings().GetFaceColor();
9295 break;
9297 return bRet;
9300 void Window::DrawSelectionBackground( const Rectangle& rRect, USHORT highlight, BOOL bChecked, BOOL bDrawBorder, BOOL bDrawExtBorderOnly )
9302 DrawSelectionBackground( rRect, highlight, bChecked, bDrawBorder, bDrawExtBorderOnly, 0, NULL, NULL );
9305 void Window::DrawSelectionBackground( const Rectangle& rRect, USHORT highlight, BOOL bChecked, BOOL bDrawBorder, BOOL bDrawExtBorderOnly, Color* pSelectionTextColor )
9307 DrawSelectionBackground( rRect, highlight, bChecked, bDrawBorder, bDrawExtBorderOnly, 0, pSelectionTextColor, NULL );
9310 void Window::DrawSelectionBackground( const Rectangle& rRect,
9311 USHORT highlight,
9312 BOOL bChecked,
9313 BOOL bDrawBorder,
9314 BOOL bDrawExtBorderOnly,
9315 long nCornerRadius,
9316 Color* pSelectionTextColor,
9317 Color* pPaintColor
9320 if( rRect.IsEmpty() )
9321 return;
9323 bool bRoundEdges = nCornerRadius > 0;
9325 const StyleSettings& rStyles = GetSettings().GetStyleSettings();
9328 // colors used for item highlighting
9329 Color aSelectionBorderCol( pPaintColor ? *pPaintColor : rStyles.GetHighlightColor() );
9330 Color aSelectionFillCol( aSelectionBorderCol );
9332 BOOL bDark = rStyles.GetFaceColor().IsDark();
9333 BOOL bBright = ( rStyles.GetFaceColor() == Color( COL_WHITE ) );
9335 int c1 = aSelectionBorderCol.GetLuminance();
9336 int c2 = GetDisplayBackground().GetColor().GetLuminance();
9338 if( !bDark && !bBright && abs( c2-c1 ) < (pPaintColor ? 40 : 75) )
9340 // constrast too low
9341 USHORT h,s,b;
9342 aSelectionFillCol.RGBtoHSB( h, s, b );
9343 if( b > 50 ) b -= 40;
9344 else b += 40;
9345 aSelectionFillCol.SetColor( Color::HSBtoRGB( h, s, b ) );
9346 aSelectionBorderCol = aSelectionFillCol;
9349 if( bRoundEdges )
9351 if( aSelectionBorderCol.IsDark() )
9352 aSelectionBorderCol.IncreaseLuminance( 128 );
9353 else
9354 aSelectionBorderCol.DecreaseLuminance( 128 );
9357 Rectangle aRect( rRect );
9358 if( bDrawExtBorderOnly )
9360 aRect.nLeft -= 1;
9361 aRect.nTop -= 1;
9362 aRect.nRight += 1;
9363 aRect.nBottom += 1;
9365 Color oldFillCol = GetFillColor();
9366 Color oldLineCol = GetLineColor();
9368 if( bDrawBorder )
9369 SetLineColor( bDark ? Color(COL_WHITE) : ( bBright ? Color(COL_BLACK) : aSelectionBorderCol ) );
9370 else
9371 SetLineColor();
9373 USHORT nPercent = 0;
9374 if( !highlight )
9376 if( bDark )
9377 aSelectionFillCol = COL_BLACK;
9378 else
9379 nPercent = bRoundEdges ? 90 : 80; // just checked (light)
9381 else
9383 if( bChecked && highlight == 2 )
9385 if( bDark )
9386 aSelectionFillCol = COL_LIGHTGRAY;
9387 else if ( bBright )
9389 aSelectionFillCol = COL_BLACK;
9390 SetLineColor( COL_BLACK );
9391 nPercent = 0;
9393 else
9394 nPercent = bRoundEdges ? 50 : 20; // selected, pressed or checked ( very dark )
9396 else if( bChecked || highlight == 1 )
9398 if( bDark )
9399 aSelectionFillCol = COL_GRAY;
9400 else if ( bBright )
9402 aSelectionFillCol = COL_BLACK;
9403 SetLineColor( COL_BLACK );
9404 nPercent = 0;
9406 else
9407 nPercent = bRoundEdges ? 70 : 35; // selected, pressed or checked ( very dark )
9409 else
9411 if( bDark )
9412 aSelectionFillCol = COL_LIGHTGRAY;
9413 else if ( bBright )
9415 aSelectionFillCol = COL_BLACK;
9416 SetLineColor( COL_BLACK );
9417 if( highlight == 3 )
9418 nPercent = 80;
9419 else
9420 nPercent = 0;
9422 else
9423 nPercent = bRoundEdges ? 80 : 70; // selected ( dark )
9427 if( bDark && bDrawExtBorderOnly )
9429 SetFillColor();
9430 if( pSelectionTextColor )
9431 *pSelectionTextColor = rStyles.GetHighlightTextColor();
9433 else
9435 SetFillColor( aSelectionFillCol );
9436 if( pSelectionTextColor )
9438 Color aTextColor = IsControlBackground() ? GetControlForeground() : rStyles.GetButtonTextColor();
9439 Color aHLTextColor = rStyles.GetHighlightTextColor();
9440 int nTextDiff = abs(aSelectionFillCol.GetLuminance() - aTextColor.GetLuminance());
9441 int nHLDiff = abs(aSelectionFillCol.GetLuminance() - aHLTextColor.GetLuminance());
9442 *pSelectionTextColor = (nHLDiff >= nTextDiff) ? aHLTextColor : aTextColor;
9447 if( bDark )
9449 DrawRect( aRect );
9451 else
9453 if( bRoundEdges )
9455 Polygon aPoly( aRect, nCornerRadius, nCornerRadius );
9456 PolyPolygon aPolyPoly( aPoly );
9457 DrawTransparent( aPolyPoly, nPercent );
9459 else
9461 Polygon aPoly( aRect );
9462 PolyPolygon aPolyPoly( aPoly );
9463 DrawTransparent( aPolyPoly, nPercent );
9467 SetFillColor( oldFillCol );
9468 SetLineColor( oldLineCol );
9472 void Window::DbgAssertNoEventListeners()
9474 VclWindowEvent aEvent( this, 0, NULL );
9475 DBG_ASSERT( mpWindowImpl->maEventListeners.empty(), "Eventlistener: Who is still listening???" )
9476 if ( !mpWindowImpl->maEventListeners.empty() )
9477 mpWindowImpl->maEventListeners.Call( &aEvent );
9479 DBG_ASSERT( mpWindowImpl->maChildEventListeners.empty(), "ChildEventlistener: Who is still listening???" )
9480 if ( !mpWindowImpl->maChildEventListeners.empty() )
9481 mpWindowImpl->maChildEventListeners.Call( &aEvent );
9485 // controls should return the window that gets the
9486 // focus by default, so keyevents can be sent to that window directly
9487 Window* Window::GetPreferredKeyInputWindow()
9489 return this;
9493 BOOL Window::IsScrollable() const
9495 // check for scrollbars
9496 Window *pChild = mpWindowImpl->mpFirstChild;
9497 while( pChild )
9499 if( pChild->GetType() == WINDOW_SCROLLBAR )
9500 return true;
9501 else
9502 pChild = pChild->mpWindowImpl->mpNext;
9504 return false;
9507 BOOL Window::IsTopWindow() const
9509 if ( mpWindowImpl->mbInDtor )
9510 return FALSE;
9512 // topwindows must be frames or they must have a borderwindow which is a frame
9513 if( !mpWindowImpl->mbFrame && (!mpWindowImpl->mpBorderWindow || (mpWindowImpl->mpBorderWindow && !mpWindowImpl->mpBorderWindow->mpWindowImpl->mbFrame) ) )
9514 return FALSE;
9516 ImplGetWinData();
9517 if( mpWindowImpl->mpWinData->mnIsTopWindow == (USHORT)~0) // still uninitialized
9519 // #113722#, cache result of expensive queryInterface call
9520 Window *pThisWin = (Window*)this;
9521 Reference< XTopWindow > xTopWindow( pThisWin->GetComponentInterface(), UNO_QUERY );
9522 pThisWin->mpWindowImpl->mpWinData->mnIsTopWindow = xTopWindow.is() ? 1 : 0;
9524 return mpWindowImpl->mpWinData->mnIsTopWindow == 1 ? TRUE : FALSE;
9527 void Window::ImplMirrorFramePos( Point &pt ) const
9529 pt.X() = mpWindowImpl->mpFrame->maGeometry.nWidth-1-pt.X();
9532 // frame based modal counter (dialogs are not modal to the whole application anymore)
9533 BOOL Window::IsInModalMode() const
9535 return (mpWindowImpl->mpFrameWindow->mpWindowImpl->mpFrameData->mnModalMode != 0);
9537 void Window::ImplIncModalCount()
9539 Window* pFrameWindow = mpWindowImpl->mpFrameWindow;
9540 Window* pParent = pFrameWindow;
9541 while( pFrameWindow )
9543 pFrameWindow->mpWindowImpl->mpFrameData->mnModalMode++;
9544 while( pParent && pParent->mpWindowImpl->mpFrameWindow == pFrameWindow )
9546 pParent = pParent->GetParent();
9548 pFrameWindow = pParent ? pParent->mpWindowImpl->mpFrameWindow : NULL;
9551 void Window::ImplDecModalCount()
9553 Window* pFrameWindow = mpWindowImpl->mpFrameWindow;
9554 Window* pParent = pFrameWindow;
9555 while( pFrameWindow )
9557 pFrameWindow->mpWindowImpl->mpFrameData->mnModalMode--;
9558 while( pParent && pParent->mpWindowImpl->mpFrameWindow == pFrameWindow )
9560 pParent = pParent->GetParent();
9562 pFrameWindow = pParent ? pParent->mpWindowImpl->mpFrameWindow : NULL;
9565 BOOL Window::ImplIsInTaskPaneList()
9567 return mpWindowImpl->mbIsInTaskPaneList;
9569 void Window::ImplIsInTaskPaneList( BOOL mbIsInTaskList )
9571 mpWindowImpl->mbIsInTaskPaneList = mbIsInTaskList;
9574 void Window::ImplNotifyIconifiedState( BOOL bIconified )
9576 mpWindowImpl->mpFrameWindow->ImplCallEventListeners( bIconified ? VCLEVENT_WINDOW_MINIMIZE : VCLEVENT_WINDOW_NORMALIZE );
9577 // #109206# notify client window as well to have toolkit topwindow listeners notified
9578 if( mpWindowImpl->mpFrameWindow->mpWindowImpl->mpClientWindow && mpWindowImpl->mpFrameWindow != mpWindowImpl->mpFrameWindow->mpWindowImpl->mpClientWindow )
9579 mpWindowImpl->mpFrameWindow->mpWindowImpl->mpClientWindow->ImplCallEventListeners( bIconified ? VCLEVENT_WINDOW_MINIMIZE : VCLEVENT_WINDOW_NORMALIZE );
9582 BOOL Window::HasActiveChildFrame()
9584 BOOL bRet = FALSE;
9585 Window *pFrameWin = ImplGetSVData()->maWinData.mpFirstFrame;
9586 while( pFrameWin )
9588 if( pFrameWin != mpWindowImpl->mpFrameWindow )
9590 BOOL bDecorated = FALSE;
9591 Window *pChildFrame = pFrameWin->ImplGetWindow();
9592 // #i15285# unfortunately WB_MOVEABLE is the same as WB_TABSTOP which can
9593 // be removed for ToolBoxes to influence the keyboard accessibility
9594 // thus WB_MOVEABLE is no indicator for decoration anymore
9595 // but FloatingWindows carry this information in their TitleType...
9596 // TODO: avoid duplicate WinBits !!!
9597 if( pChildFrame && pChildFrame->ImplIsFloatingWindow() )
9598 bDecorated = ((FloatingWindow*) pChildFrame)->GetTitleType() != FLOATWIN_TITLE_NONE;
9599 if( bDecorated || (pFrameWin->mpWindowImpl->mnStyle & (WB_MOVEABLE | WB_SIZEABLE) ) )
9600 if( pChildFrame && pChildFrame->IsVisible() && pChildFrame->IsActive() )
9602 if( ImplIsChild( pChildFrame, TRUE ) )
9604 bRet = TRUE;
9605 break;
9609 pFrameWin = pFrameWin->mpWindowImpl->mpFrameData->mpNextFrame;
9611 return bRet;
9614 LanguageType Window::GetInputLanguage() const
9616 return mpWindowImpl->mpFrame->GetInputLanguage();
9619 void Window::EnableNativeWidget( BOOL bEnable )
9621 static const char* pNoNWF = getenv( "SAL_NO_NWF" );
9622 if( pNoNWF && *pNoNWF )
9623 bEnable = FALSE;
9625 if( bEnable != ImplGetWinData()->mbEnableNativeWidget )
9627 ImplGetWinData()->mbEnableNativeWidget = bEnable;
9629 // send datachanged event to allow for internal changes required for NWF
9630 // like clipmode, transparency, etc.
9631 DataChangedEvent aDCEvt( DATACHANGED_SETTINGS, &maSettings, SETTINGS_STYLE );
9632 DataChanged( aDCEvt );
9634 // sometimes the borderwindow is queried, so keep it in sync
9635 if( mpWindowImpl->mpBorderWindow )
9636 mpWindowImpl->mpBorderWindow->ImplGetWinData()->mbEnableNativeWidget = bEnable;
9639 // push down, useful for compound controls
9640 Window *pChild = mpWindowImpl->mpFirstChild;
9641 while( pChild )
9643 pChild->EnableNativeWidget( bEnable );
9644 pChild = pChild->mpWindowImpl->mpNext;
9648 BOOL Window::IsNativeWidgetEnabled() const
9650 return ImplGetWinData()->mbEnableNativeWidget;
9653 #ifdef WNT // see #140456#
9654 #include <salframe.h>
9655 #endif
9657 Reference< rendering::XCanvas > Window::ImplGetCanvas( const Size& rFullscreenSize,
9658 bool bFullscreen,
9659 bool bSpriteCanvas ) const
9661 // try to retrieve hard reference from weak member
9662 Reference< rendering::XCanvas > xCanvas( mpWindowImpl->mxCanvas );
9664 // canvas still valid? Then we're done.
9665 if( xCanvas.is() )
9666 return xCanvas;
9668 Sequence< Any > aArg(6);
9670 // Feed any with operating system's window handle
9671 // ==============================================
9673 // common: first any is VCL pointer to window (for VCL canvas)
9674 aArg[ 0 ] = makeAny( reinterpret_cast<sal_Int64>(this) );
9676 // TODO(Q1): Make GetSystemData method virtual
9678 // check whether we're a SysChild: have to fetch system data
9679 // directly from SystemChildWindow, because the GetSystemData
9680 // method is unfortunately not virtual
9681 const SystemChildWindow* pSysChild = dynamic_cast< const SystemChildWindow* >( this );
9682 if( pSysChild )
9684 aArg[ 1 ] = pSysChild->GetSystemDataAny();
9685 aArg[ 5 ] = pSysChild->GetSystemGfxDataAny();
9687 else
9689 aArg[ 1 ] = GetSystemDataAny();
9690 aArg[ 5 ] = GetSystemGfxDataAny();
9693 if( bFullscreen )
9694 aArg[ 2 ] = makeAny( ::com::sun::star::awt::Rectangle( 0, 0,
9695 rFullscreenSize.Width(),
9696 rFullscreenSize.Height() ) );
9697 else
9698 aArg[ 2 ] = makeAny( ::com::sun::star::awt::Rectangle( mnOutOffX, mnOutOffY, mnOutWidth, mnOutHeight ) );
9700 aArg[ 3 ] = makeAny( mpWindowImpl->mbAlwaysOnTop ? sal_True : sal_False );
9701 aArg[ 4 ] = makeAny( Reference< awt::XWindow >(
9702 const_cast<Window*>(this)->GetComponentInterface(),
9703 uno::UNO_QUERY ));
9705 Reference< XMultiServiceFactory > xFactory = vcl::unohelper::GetMultiServiceFactory();
9707 // Create canvas instance with window handle
9708 // =========================================
9709 if ( xFactory.is() )
9711 static Reference<lang::XMultiServiceFactory> xCanvasFactory(
9712 xFactory->createInstance(
9713 OUString( RTL_CONSTASCII_USTRINGPARAM(
9714 "com.sun.star."
9715 "rendering.CanvasFactory") ) ), UNO_QUERY );
9716 if(xCanvasFactory.is())
9718 #ifdef WNT
9719 // see #140456# - if we're running on a multiscreen setup,
9720 // request special, multi-screen safe sprite canvas
9721 // implementation (not DX5 canvas, as it cannot cope with
9722 // surfaces spanning multiple displays). Note: canvas
9723 // (without sprite) stays the same)
9724 const sal_uInt32 nDisplay = static_cast< WinSalFrame* >( mpWindowImpl->mpFrame )->mnDisplay;
9725 if( (nDisplay >= Application::GetScreenCount()) )
9727 xCanvas.set( xCanvasFactory->createInstanceWithArguments(
9728 bSpriteCanvas ?
9729 OUString( RTL_CONSTASCII_USTRINGPARAM(
9730 "com.sun.star.rendering.SpriteCanvas.MultiScreen" )) :
9731 OUString( RTL_CONSTASCII_USTRINGPARAM(
9732 "com.sun.star.rendering.Canvas" )),
9733 aArg ),
9734 UNO_QUERY );
9737 else
9739 #endif
9740 xCanvas.set( xCanvasFactory->createInstanceWithArguments(
9741 bSpriteCanvas ?
9742 OUString( RTL_CONSTASCII_USTRINGPARAM(
9743 "com.sun.star.rendering.SpriteCanvas" )) :
9744 OUString( RTL_CONSTASCII_USTRINGPARAM(
9745 "com.sun.star.rendering.Canvas" )),
9746 aArg ),
9747 UNO_QUERY );
9749 #ifdef WNT
9751 #endif
9753 mpWindowImpl->mxCanvas = xCanvas;
9757 // no factory??? Empty reference, then.
9758 return xCanvas;
9761 Reference< rendering::XCanvas > Window::GetCanvas() const
9763 return ImplGetCanvas( Size(), false, false );
9766 Reference< rendering::XSpriteCanvas > Window::GetSpriteCanvas() const
9768 Reference< rendering::XSpriteCanvas > xSpriteCanvas(
9769 ImplGetCanvas( Size(), false, true ), uno::UNO_QUERY );
9770 return xSpriteCanvas;
9773 Reference< ::com::sun::star::rendering::XSpriteCanvas > Window::GetFullscreenSpriteCanvas( const Size& rFullscreenSize ) const
9775 Reference< rendering::XSpriteCanvas > xSpriteCanvas(
9776 ImplGetCanvas( rFullscreenSize, true, true ), uno::UNO_QUERY );
9777 return xSpriteCanvas;
9780 void Window::ImplPaintToDevice( OutputDevice* i_pTargetOutDev, const Point& i_rPos )
9782 BOOL bRVisible = mpWindowImpl->mbReallyVisible;
9783 mpWindowImpl->mbReallyVisible = mpWindowImpl->mbVisible;
9784 BOOL bDevOutput = mbDevOutput;
9785 mbDevOutput = TRUE;
9787 long nOldDPIX = ImplGetDPIX();
9788 long nOldDPIY = ImplGetDPIY();
9789 mnDPIX = i_pTargetOutDev->ImplGetDPIX();
9790 mnDPIY = i_pTargetOutDev->ImplGetDPIY();
9791 BOOL bOutput = IsOutputEnabled();
9792 EnableOutput();
9794 DBG_ASSERT( GetMapMode().GetMapUnit() == MAP_PIXEL, "MapMode must be PIXEL based" );
9796 // preserve graphicsstate
9797 Push();
9798 Region aClipRegion( GetClipRegion() );
9799 SetClipRegion();
9801 GDIMetaFile* pOldMtf = GetConnectMetaFile();
9802 GDIMetaFile aMtf;
9803 SetConnectMetaFile( &aMtf );
9805 // put a push action to metafile
9806 Push();
9807 // copy graphics state to metafile
9808 Font aCopyFont = GetFont();
9809 if( nOldDPIX != mnDPIX || nOldDPIY != mnDPIY )
9811 aCopyFont.SetHeight( aCopyFont.GetHeight() * mnDPIY / nOldDPIY );
9812 aCopyFont.SetWidth( aCopyFont.GetWidth() * mnDPIX / nOldDPIX );
9814 SetFont( aCopyFont );
9815 SetTextColor( GetTextColor() );
9816 if( IsLineColor() )
9817 SetLineColor( GetLineColor() );
9818 else
9819 SetLineColor();
9820 if( IsFillColor() )
9821 SetFillColor( GetFillColor() );
9822 else
9823 SetFillColor();
9824 if( IsTextLineColor() )
9825 SetTextLineColor( GetTextLineColor() );
9826 else
9827 SetTextLineColor();
9828 if( IsOverlineColor() )
9829 SetOverlineColor( GetOverlineColor() );
9830 else
9831 SetOverlineColor();
9832 if( IsTextFillColor() )
9833 SetTextFillColor( GetTextFillColor() );
9834 else
9835 SetTextFillColor();
9836 SetTextAlign( GetTextAlign() );
9837 SetRasterOp( GetRasterOp() );
9838 if( IsRefPoint() )
9839 SetRefPoint( GetRefPoint() );
9840 else
9841 SetRefPoint();
9842 SetLayoutMode( GetLayoutMode() );
9843 SetDigitLanguage( GetDigitLanguage() );
9844 Rectangle aPaintRect( Point( 0, 0 ), GetOutputSizePixel() );
9845 aClipRegion.Intersect( aPaintRect );
9846 SetClipRegion( aClipRegion );
9848 // do the actual paint
9850 // background
9851 if( ! IsPaintTransparent() && IsBackground() && ! (GetParentClipMode() & PARENTCLIPMODE_NOCLIP ) )
9852 Erase();
9853 // foreground
9854 Paint( aPaintRect );
9855 // put a pop action to metafile
9856 Pop();
9858 SetConnectMetaFile( pOldMtf );
9859 EnableOutput( bOutput );
9860 mpWindowImpl->mbReallyVisible = bRVisible;
9862 // paint metafile to VDev
9863 VirtualDevice* pMaskedDevice = new VirtualDevice( *i_pTargetOutDev, 0, 0 );
9864 pMaskedDevice->SetOutputSizePixel( GetOutputSizePixel() );
9865 pMaskedDevice->EnableRTL( IsRTLEnabled() );
9866 aMtf.WindStart();
9867 aMtf.Play( pMaskedDevice );
9868 BitmapEx aBmpEx( pMaskedDevice->GetBitmapEx( Point( 0, 0 ), pMaskedDevice->GetOutputSizePixel() ) );
9869 i_pTargetOutDev->DrawBitmapEx( i_rPos, aBmpEx );
9870 // get rid of virtual device now so they don't pile up during recursive calls
9871 delete pMaskedDevice, pMaskedDevice = NULL;
9874 for( Window* pChild = mpWindowImpl->mpFirstChild; pChild; pChild = pChild->mpWindowImpl->mpNext )
9876 if( pChild->mpWindowImpl->mpFrame == mpWindowImpl->mpFrame && pChild->IsVisible() )
9878 long nDeltaX = pChild->mnOutOffX - mnOutOffX;
9879 if( ImplHasMirroredGraphics() )
9880 nDeltaX = mnOutWidth - nDeltaX - pChild->mnOutWidth;
9881 long nDeltaY = pChild->GetOutOffYPixel() - GetOutOffYPixel();
9882 Point aPos( i_rPos );
9883 Point aDelta( nDeltaX, nDeltaY );
9884 aPos += aDelta;
9885 pChild->ImplPaintToDevice( i_pTargetOutDev, aPos );
9889 // restore graphics state
9890 Pop();
9892 EnableOutput( bOutput );
9893 mpWindowImpl->mbReallyVisible = bRVisible;
9894 mbDevOutput = bDevOutput;
9895 mnDPIX = nOldDPIX;
9896 mnDPIY = nOldDPIY;
9899 void Window::PaintToDevice( OutputDevice* pDev, const Point& rPos, const Size& /*rSize*/ )
9901 // FIXME: scaling: currently this is for pixel copying only
9903 DBG_ASSERT( ! pDev->ImplHasMirroredGraphics(), "PaintToDevice to mirroring graphics" );
9904 DBG_ASSERT( ! pDev->IsRTLEnabled(), "PaintToDevice to mirroring device" );
9907 Point aPos = pDev->LogicToPixel( rPos );
9909 Window* pRealParent = NULL;
9910 if( ! mpWindowImpl->mbVisible )
9912 Window* pTempParent = ImplGetDefaultWindow();
9913 if( pTempParent )
9914 pTempParent->EnableChildTransparentMode();
9915 pRealParent = GetParent();
9916 SetParent( pTempParent );
9917 // trigger correct visibility flags for children
9918 Show();
9919 Hide();
9922 BOOL bVisible = mpWindowImpl->mbVisible;
9923 mpWindowImpl->mbVisible = TRUE;
9925 if( mpWindowImpl->mpBorderWindow )
9926 mpWindowImpl->mpBorderWindow->ImplPaintToDevice( pDev, rPos );
9927 else
9928 ImplPaintToDevice( pDev, rPos );
9930 mpWindowImpl->mbVisible = bVisible;
9932 if( pRealParent )
9933 SetParent( pRealParent );
9936 XubString Window::GetSurroundingText() const
9938 return XubString::EmptyString();
9941 Selection Window::GetSurroundingTextSelection() const
9943 return Selection( 0, 0 );