update dev300-m58
[ooovba.git] / vcl / source / window / winproc.cxx
blob2870687b91e38fa75f1adf555c59fea02f6a1ac0
1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: winproc.cxx,v $
10 * $Revision: 1.127 $
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"
34 #ifndef _SV_SVSYS_HXX
35 #include <svsys.h>
36 #endif
37 #include <vcl/salwtype.hxx>
38 #include <vcl/salframe.hxx>
39 #include <tools/debug.hxx>
40 #ifndef _INTN_HXX
41 //#include <tools/intn.hxx>
42 #endif
43 #include <vcl/i18nhelp.hxx>
44 #include <vcl/unohelp.hxx>
45 #include <unotools/localedatawrapper.hxx>
46 #include <vcl/svdata.hxx>
47 #include <vcl/dbggui.hxx>
48 #include <vcl/windata.hxx>
49 #include <vcl/timer.hxx>
50 #include <vcl/event.hxx>
51 #include <vcl/sound.hxx>
52 #include <vcl/settings.hxx>
53 #include <vcl/svapp.hxx>
54 #include <vcl/cursor.hxx>
55 #include <vcl/accmgr.hxx>
56 #include <vcl/print.h>
57 #include <vcl/window.h>
58 #include <vcl/wrkwin.hxx>
59 #include <vcl/floatwin.hxx>
60 #include <vcl/dialog.hxx>
61 #include <vcl/help.hxx>
62 #include <vcl/helpwin.hxx>
63 #include <vcl/brdwin.hxx>
64 #include <vcl/dockwin.hxx>
65 #include <vcl/salgdi.hxx>
66 #include <vcl/menu.hxx>
68 #include <dndlcon.hxx>
69 #include <com/sun/star/datatransfer/dnd/XDragSource.hpp>
70 #include <com/sun/star/awt/MouseEvent.hpp>
72 #if OSL_DEBUG_LEVEL > 1
73 char dbgbuffer[1024];
74 #ifndef WNT
75 #include <stdio.h>
76 #define MyOutputDebugString(s) (fprintf(stderr, s ))
77 #else
78 extern void MyOutputDebugString( char *s);
79 #endif
80 #endif
83 // =======================================================================
85 #define IMPL_MIN_NEEDSYSWIN 49
87 // =======================================================================
89 long ImplCallPreNotify( NotifyEvent& rEvt )
91 long nRet = Application::CallEventHooks( rEvt );
92 if ( !nRet )
93 nRet = rEvt.GetWindow()->PreNotify( rEvt );
94 return nRet;
97 // =======================================================================
99 long ImplCallEvent( NotifyEvent& rEvt )
101 long nRet = ImplCallPreNotify( rEvt );
102 if ( !nRet )
104 Window* pWindow = rEvt.GetWindow();
105 switch ( rEvt.GetType() )
107 case EVENT_MOUSEBUTTONDOWN:
108 pWindow->MouseButtonDown( *rEvt.GetMouseEvent() );
109 break;
110 case EVENT_MOUSEBUTTONUP:
111 pWindow->MouseButtonUp( *rEvt.GetMouseEvent() );
112 break;
113 case EVENT_MOUSEMOVE:
114 pWindow->MouseMove( *rEvt.GetMouseEvent() );
115 break;
116 case EVENT_KEYINPUT:
117 pWindow->KeyInput( *rEvt.GetKeyEvent() );
118 break;
119 case EVENT_KEYUP:
120 pWindow->KeyUp( *rEvt.GetKeyEvent() );
121 break;
122 case EVENT_GETFOCUS:
123 pWindow->GetFocus();
124 break;
125 case EVENT_LOSEFOCUS:
126 pWindow->LoseFocus();
127 break;
128 case EVENT_COMMAND:
129 pWindow->Command( *rEvt.GetCommandEvent() );
130 break;
134 return nRet;
137 // =======================================================================
139 static BOOL ImplHandleMouseFloatMode( Window* pChild, const Point& rMousePos,
140 USHORT nCode, USHORT nSVEvent,
141 BOOL bMouseLeave )
143 ImplSVData* pSVData = ImplGetSVData();
145 if ( pSVData->maWinData.mpFirstFloat && !pSVData->maWinData.mpCaptureWin &&
146 !pSVData->maWinData.mpFirstFloat->ImplIsFloatPopupModeWindow( pChild ) )
149 * #93895# since floats are system windows, coordinates have
150 * to be converted to float relative for the hittest
152 USHORT nHitTest = IMPL_FLOATWIN_HITTEST_OUTSIDE;
153 FloatingWindow* pFloat = pSVData->maWinData.mpFirstFloat->ImplFloatHitTest( pChild, rMousePos, nHitTest );
154 FloatingWindow* pLastLevelFloat;
155 ULONG nPopupFlags;
156 if ( nSVEvent == EVENT_MOUSEMOVE )
158 if ( bMouseLeave )
159 return TRUE;
161 if ( !pFloat || (nHitTest & IMPL_FLOATWIN_HITTEST_RECT) )
163 if ( pSVData->maHelpData.mpHelpWin && !pSVData->maHelpData.mbKeyboardHelp )
164 ImplDestroyHelpWindow( true );
165 pChild->ImplGetFrame()->SetPointer( POINTER_ARROW );
166 return TRUE;
169 else
171 if ( nCode & MOUSE_LEFT )
173 if ( nSVEvent == EVENT_MOUSEBUTTONDOWN )
175 if ( !pFloat )
177 pLastLevelFloat = pSVData->maWinData.mpFirstFloat->ImplFindLastLevelFloat();
178 nPopupFlags = pLastLevelFloat->GetPopupModeFlags();
179 pLastLevelFloat->EndPopupMode( FLOATWIN_POPUPMODEEND_CANCEL | FLOATWIN_POPUPMODEEND_CLOSEALL );
180 // Erstmal ausgebaut als Hack fuer Bug 53378
181 // if ( nPopupFlags & FLOATWIN_POPUPMODE_PATHMOUSECANCELCLICK )
182 // return FALSE;
183 // else
184 return TRUE;
186 else if ( nHitTest & IMPL_FLOATWIN_HITTEST_RECT )
188 if ( !(pFloat->GetPopupModeFlags() & FLOATWIN_POPUPMODE_NOMOUSERECTCLOSE) )
189 pFloat->ImplSetMouseDown();
190 return TRUE;
193 else
195 if ( pFloat )
197 if ( nHitTest & IMPL_FLOATWIN_HITTEST_RECT )
199 if ( pFloat->ImplIsMouseDown() )
200 pFloat->EndPopupMode( FLOATWIN_POPUPMODEEND_CANCEL );
201 return TRUE;
204 else
206 pLastLevelFloat = pSVData->maWinData.mpFirstFloat->ImplFindLastLevelFloat();
207 nPopupFlags = pLastLevelFloat->GetPopupModeFlags();
208 if ( !(nPopupFlags & FLOATWIN_POPUPMODE_NOMOUSEUPCLOSE) )
210 pLastLevelFloat->EndPopupMode( FLOATWIN_POPUPMODEEND_CANCEL | FLOATWIN_POPUPMODEEND_CLOSEALL );
211 return TRUE;
216 else
218 if ( !pFloat )
220 pLastLevelFloat = pSVData->maWinData.mpFirstFloat->ImplFindLastLevelFloat();
221 nPopupFlags = pLastLevelFloat->GetPopupModeFlags();
222 if ( nPopupFlags & FLOATWIN_POPUPMODE_ALLMOUSEBUTTONCLOSE )
224 if ( (nPopupFlags & FLOATWIN_POPUPMODE_NOMOUSEUPCLOSE) &&
225 (nSVEvent == EVENT_MOUSEBUTTONUP) )
226 return TRUE;
227 pLastLevelFloat->EndPopupMode( FLOATWIN_POPUPMODEEND_CANCEL | FLOATWIN_POPUPMODEEND_CLOSEALL );
228 if ( nPopupFlags & FLOATWIN_POPUPMODE_PATHMOUSECANCELCLICK )
229 return FALSE;
230 else
231 return TRUE;
233 else
234 return TRUE;
240 return FALSE;
243 // -----------------------------------------------------------------------
245 static void ImplHandleMouseHelpRequest( Window* pChild, const Point& rMousePos )
247 ImplSVData* pSVData = ImplGetSVData();
248 if ( !pSVData->maHelpData.mpHelpWin ||
249 !( pSVData->maHelpData.mpHelpWin->IsWindowOrChild( pChild ) ||
250 pChild->IsWindowOrChild( pSVData->maHelpData.mpHelpWin ) ) )
252 USHORT nHelpMode = 0;
253 if ( pSVData->maHelpData.mbQuickHelp )
254 nHelpMode = HELPMODE_QUICK;
255 if ( pSVData->maHelpData.mbBalloonHelp )
256 nHelpMode |= HELPMODE_BALLOON;
257 if ( nHelpMode )
259 if ( pChild->IsInputEnabled() && ! pChild->IsInModalMode() )
261 HelpEvent aHelpEvent( rMousePos, nHelpMode );
262 pSVData->maHelpData.mbRequestingHelp = TRUE;
263 pChild->RequestHelp( aHelpEvent );
264 pSVData->maHelpData.mbRequestingHelp = FALSE;
266 // #104172# do not kill keyboard activated tooltips
267 else if ( pSVData->maHelpData.mpHelpWin && !pSVData->maHelpData.mbKeyboardHelp)
269 ImplDestroyHelpWindow( true );
275 // -----------------------------------------------------------------------
277 static void ImplSetMousePointer( Window* pChild )
279 ImplSVData* pSVData = ImplGetSVData();
280 if ( pSVData->maHelpData.mbExtHelpMode )
281 pChild->ImplGetFrame()->SetPointer( POINTER_HELP );
282 else
283 pChild->ImplGetFrame()->SetPointer( pChild->ImplGetMousePointer() );
286 // -----------------------------------------------------------------------
288 static BOOL ImplCallCommand( Window* pChild, USHORT nEvt, void* pData = NULL,
289 BOOL bMouse = FALSE, Point* pPos = NULL )
291 Point aPos;
292 if ( pPos )
293 aPos = *pPos;
294 else
296 if( bMouse )
297 aPos = pChild->GetPointerPosPixel();
298 else
300 // simulate mouseposition at center of window
301 Size aSize = pChild->GetOutputSize();
302 aPos = Point( aSize.getWidth()/2, aSize.getHeight()/2 );
306 CommandEvent aCEvt( aPos, nEvt, bMouse, pData );
307 NotifyEvent aNCmdEvt( EVENT_COMMAND, pChild, &aCEvt );
308 ImplDelData aDelData( pChild );
309 BOOL bPreNotify = (ImplCallPreNotify( aNCmdEvt ) != 0);
310 if ( aDelData.IsDelete() )
311 return FALSE;
312 if ( !bPreNotify )
314 pChild->ImplGetWindowImpl()->mbCommand = FALSE;
315 pChild->Command( aCEvt );
317 if( aDelData.IsDelete() )
318 return FALSE;
319 pChild->ImplNotifyKeyMouseCommandEventListeners( aNCmdEvt );
320 if ( aDelData.IsDelete() )
321 return FALSE;
322 if ( pChild->ImplGetWindowImpl()->mbCommand )
323 return TRUE;
326 return FALSE;
329 // -----------------------------------------------------------------------
331 /* #i34277# delayed context menu activation;
332 * necessary if there already was a popup menu running.
335 struct ContextMenuEvent
337 Window* pWindow;
338 ImplDelData aDelData;
339 Point aChildPos;
342 static long ContextMenuEventLink( void* pCEvent, void* )
344 ContextMenuEvent* pEv = (ContextMenuEvent*)pCEvent;
346 if( ! pEv->aDelData.IsDelete() )
348 pEv->pWindow->ImplRemoveDel( &pEv->aDelData );
349 ImplCallCommand( pEv->pWindow, COMMAND_CONTEXTMENU, NULL, TRUE, &pEv->aChildPos );
351 delete pEv;
353 return 0;
356 long ImplHandleMouseEvent( Window* pWindow, USHORT nSVEvent, BOOL bMouseLeave,
357 long nX, long nY, ULONG nMsgTime,
358 USHORT nCode, USHORT nMode )
360 ImplSVData* pSVData = ImplGetSVData();
361 Point aMousePos( nX, nY );
362 Window* pChild;
363 long nRet;
364 USHORT nClicks;
365 ImplFrameData* pWinFrameData = pWindow->ImplGetFrameData();
366 USHORT nOldCode = pWinFrameData->mnMouseCode;
368 // we need a mousemove event, befor we get a mousebuttondown or a
369 // mousebuttonup event
370 if ( (nSVEvent == EVENT_MOUSEBUTTONDOWN) ||
371 (nSVEvent == EVENT_MOUSEBUTTONUP) )
373 if ( (nSVEvent == EVENT_MOUSEBUTTONUP) && pSVData->maHelpData.mbExtHelpMode )
374 Help::EndExtHelp();
375 if ( pSVData->maHelpData.mpHelpWin )
377 if( pWindow->ImplGetWindow() == pSVData->maHelpData.mpHelpWin )
379 ImplDestroyHelpWindow( false );
380 return 1; // pWindow is dead now - avoid crash!
382 else
383 ImplDestroyHelpWindow( true );
386 if ( (pWinFrameData->mnLastMouseX != nX) ||
387 (pWinFrameData->mnLastMouseY != nY) )
389 ImplHandleMouseEvent( pWindow, EVENT_MOUSEMOVE, FALSE, nX, nY, nMsgTime, nCode, nMode );
393 // update frame data
394 pWinFrameData->mnBeforeLastMouseX = pWinFrameData->mnLastMouseX;
395 pWinFrameData->mnBeforeLastMouseY = pWinFrameData->mnLastMouseY;
396 pWinFrameData->mnLastMouseX = nX;
397 pWinFrameData->mnLastMouseY = nY;
398 pWinFrameData->mnMouseCode = nCode;
399 pWinFrameData->mnMouseMode = nMode & ~(MOUSE_SYNTHETIC | MOUSE_MODIFIERCHANGED);
400 if ( bMouseLeave )
402 pWinFrameData->mbMouseIn = FALSE;
403 if ( pSVData->maHelpData.mpHelpWin && !pSVData->maHelpData.mbKeyboardHelp )
405 ImplDelData aDelData( pWindow );
407 ImplDestroyHelpWindow( true );
409 if ( aDelData.IsDelete() )
410 return 1; // pWindow is dead now - avoid crash! (#122045#)
413 else
414 pWinFrameData->mbMouseIn = TRUE;
416 DBG_ASSERT( !pSVData->maWinData.mpTrackWin ||
417 (pSVData->maWinData.mpTrackWin == pSVData->maWinData.mpCaptureWin),
418 "ImplHandleMouseEvent: TrackWin != CaptureWin" );
420 // AutoScrollMode
421 if ( pSVData->maWinData.mpAutoScrollWin && (nSVEvent == EVENT_MOUSEBUTTONDOWN) )
423 pSVData->maWinData.mpAutoScrollWin->EndAutoScroll();
424 return 1;
427 // find mouse window
428 if ( pSVData->maWinData.mpCaptureWin )
430 pChild = pSVData->maWinData.mpCaptureWin;
432 DBG_ASSERT( pWindow == pChild->ImplGetFrameWindow(),
433 "ImplHandleMouseEvent: mouse event is not sent to capture window" );
435 // java client cannot capture mouse correctly
436 if ( pWindow != pChild->ImplGetFrameWindow() )
437 return 0;
439 if ( bMouseLeave )
440 return 0;
442 else
444 if ( bMouseLeave )
445 pChild = NULL;
446 else
447 pChild = pWindow->ImplFindWindow( aMousePos );
450 // test this because mouse events are buffered in the remote version
451 // and size may not be in sync
452 if ( !pChild && !bMouseLeave )
453 return 0;
455 // Ein paar Test ausfuehren und Message abfangen oder Status umsetzen
456 if ( pChild )
458 if( pChild->ImplIsAntiparallel() )
460 // - RTL - re-mirror frame pos at pChild
461 pChild->ImplReMirror( aMousePos );
463 // no mouse messages to system object windows ?
464 // !!!KA: Is it OK to comment this out? !!!
465 // if ( pChild->ImplGetWindowImpl()->mpSysObj )
466 // return 0;
468 // no mouse messages to disabled windows
469 // #106845# if the window was disabed during capturing we have to pass the mouse events to release capturing
470 if ( pSVData->maWinData.mpCaptureWin != pChild && (!pChild->IsEnabled() || !pChild->IsInputEnabled() || pChild->IsInModalMode() ) )
472 ImplHandleMouseFloatMode( pChild, aMousePos, nCode, nSVEvent, bMouseLeave );
473 if ( nSVEvent == EVENT_MOUSEMOVE )
475 ImplHandleMouseHelpRequest( pChild, aMousePos );
476 if( pWinFrameData->mpMouseMoveWin != pChild )
477 nMode |= MOUSE_ENTERWINDOW;
480 // Call the hook also, if Window is disabled
481 Point aChildPos = pChild->ImplFrameToOutput( aMousePos );
482 MouseEvent aMEvt( aChildPos, pWinFrameData->mnClickCount, nMode, nCode, nCode );
483 NotifyEvent aNEvt( nSVEvent, pChild, &aMEvt );
484 Application::CallEventHooks( aNEvt );
486 if( pChild->IsCallHandlersOnInputDisabled() )
488 pWinFrameData->mpMouseMoveWin = pChild;
489 pChild->ImplNotifyKeyMouseCommandEventListeners( aNEvt );
492 if ( nSVEvent == EVENT_MOUSEBUTTONDOWN )
494 Sound::Beep( SOUND_DISABLE, pChild );
495 return 1;
497 else
499 // Set normal MousePointer for disabled windows
500 if ( nSVEvent == EVENT_MOUSEMOVE )
501 ImplSetMousePointer( pChild );
503 return 0;
507 // End ExtTextInput-Mode, if the user click in the same TopLevel Window
508 if ( pSVData->maWinData.mpExtTextInputWin &&
509 ((nSVEvent == EVENT_MOUSEBUTTONDOWN) ||
510 (nSVEvent == EVENT_MOUSEBUTTONUP)) )
511 pSVData->maWinData.mpExtTextInputWin->EndExtTextInput( EXTTEXTINPUT_END_COMPLETE );
514 // determine mouse event data
515 if ( nSVEvent == EVENT_MOUSEMOVE )
517 // Testen, ob MouseMove an das gleiche Fenster geht und sich der
518 // Status nicht geaendert hat
519 if ( pChild )
521 Point aChildMousePos = pChild->ImplFrameToOutput( aMousePos );
522 if ( !bMouseLeave &&
523 (pChild == pWinFrameData->mpMouseMoveWin) &&
524 (aChildMousePos.X() == pWinFrameData->mnLastMouseWinX) &&
525 (aChildMousePos.Y() == pWinFrameData->mnLastMouseWinY) &&
526 (nOldCode == pWinFrameData->mnMouseCode) )
528 // Mouse-Pointer neu setzen, da er sich geaendet haben
529 // koennte, da ein Modus umgesetzt wurde
530 ImplSetMousePointer( pChild );
531 return 0;
534 pWinFrameData->mnLastMouseWinX = aChildMousePos.X();
535 pWinFrameData->mnLastMouseWinY = aChildMousePos.Y();
538 // mouse click
539 nClicks = pWinFrameData->mnClickCount;
541 // Gegebenenfalls den Start-Drag-Handler rufen.
542 // Achtung: Muss vor Move gerufen werden, da sonst bei schnellen
543 // Mausbewegungen die Applikationen in den Selektionszustand gehen.
544 Window* pMouseDownWin = pWinFrameData->mpMouseDownWin;
545 if ( pMouseDownWin )
547 // Testen, ob StartDrag-Modus uebereinstimmt. Wir vergleichen nur
548 // den Status der Maustasten, damit man mit Mod1 z.B. sofort
549 // in den Kopiermodus gehen kann.
550 const MouseSettings& rMSettings = pMouseDownWin->GetSettings().GetMouseSettings();
551 if ( (nCode & (MOUSE_LEFT | MOUSE_RIGHT | MOUSE_MIDDLE)) ==
552 (rMSettings.GetStartDragCode() & (MOUSE_LEFT | MOUSE_RIGHT | MOUSE_MIDDLE)) )
554 if ( !pMouseDownWin->ImplGetFrameData()->mbStartDragCalled )
556 long nDragW = rMSettings.GetStartDragWidth();
557 long nDragH = rMSettings.GetStartDragWidth();
558 //long nMouseX = nX;
559 //long nMouseY = nY;
560 long nMouseX = aMousePos.X(); // #106074# use the possibly re-mirrored coordinates (RTL) ! nX,nY are unmodified !
561 long nMouseY = aMousePos.Y();
562 if ( !(((nMouseX-nDragW) <= pMouseDownWin->ImplGetFrameData()->mnFirstMouseX) &&
563 ((nMouseX+nDragW) >= pMouseDownWin->ImplGetFrameData()->mnFirstMouseX)) ||
564 !(((nMouseY-nDragH) <= pMouseDownWin->ImplGetFrameData()->mnFirstMouseY) &&
565 ((nMouseY+nDragH) >= pMouseDownWin->ImplGetFrameData()->mnFirstMouseY)) )
567 pMouseDownWin->ImplGetFrameData()->mbStartDragCalled = TRUE;
569 // Check if drag source provides it's own recognizer
570 if( pMouseDownWin->ImplGetFrameData()->mbInternalDragGestureRecognizer )
572 // query DropTarget from child window
573 ::com::sun::star::uno::Reference< ::com::sun::star::datatransfer::dnd::XDragGestureRecognizer > xDragGestureRecognizer =
574 ::com::sun::star::uno::Reference< ::com::sun::star::datatransfer::dnd::XDragGestureRecognizer > ( pMouseDownWin->ImplGetWindowImpl()->mxDNDListenerContainer,
575 ::com::sun::star::uno::UNO_QUERY );
577 if( xDragGestureRecognizer.is() )
579 // retrieve mouse position relative to mouse down window
580 Point relLoc = pMouseDownWin->ImplFrameToOutput( Point(
581 pMouseDownWin->ImplGetFrameData()->mnFirstMouseX,
582 pMouseDownWin->ImplGetFrameData()->mnFirstMouseY ) );
584 // create a uno mouse event out of the available data
585 ::com::sun::star::awt::MouseEvent aMouseEvent(
586 static_cast < ::com::sun::star::uno::XInterface * > ( 0 ),
587 #ifdef MACOSX
588 nCode & (KEY_SHIFT | KEY_MOD1 | KEY_MOD2 | KEY_MOD3),
589 #else
590 nCode & (KEY_SHIFT | KEY_MOD1 | KEY_MOD2),
591 #endif
592 nCode & (MOUSE_LEFT | MOUSE_RIGHT | MOUSE_MIDDLE),
593 nMouseX,
594 nMouseY,
595 nClicks,
596 sal_False );
598 ULONG nCount = Application::ReleaseSolarMutex();
600 // FIXME: where do I get Action from ?
601 ::com::sun::star::uno::Reference< ::com::sun::star::datatransfer::dnd::XDragSource > xDragSource = pMouseDownWin->GetDragSource();
603 if( xDragSource.is() )
605 static_cast < DNDListenerContainer * > ( xDragGestureRecognizer.get() )->fireDragGestureEvent( 0,
606 relLoc.X(), relLoc.Y(), xDragSource, ::com::sun::star::uno::makeAny( aMouseEvent ) );
609 Application::AcquireSolarMutex( nCount );
615 else
616 pMouseDownWin->ImplGetFrameData()->mbStartDragCalled = TRUE;
619 // test for mouseleave and mouseenter
620 Window* pMouseMoveWin = pWinFrameData->mpMouseMoveWin;
621 if ( pChild != pMouseMoveWin )
623 if ( pMouseMoveWin )
625 Point aLeaveMousePos = pMouseMoveWin->ImplFrameToOutput( aMousePos );
626 MouseEvent aMLeaveEvt( aLeaveMousePos, nClicks, nMode | MOUSE_LEAVEWINDOW, nCode, nCode );
627 NotifyEvent aNLeaveEvt( EVENT_MOUSEMOVE, pMouseMoveWin, &aMLeaveEvt );
628 ImplDelData aDelData;
629 ImplDelData aDelData2;
630 pWinFrameData->mbInMouseMove = TRUE;
631 pMouseMoveWin->ImplGetWinData()->mbMouseOver = FALSE;
632 pMouseMoveWin->ImplAddDel( &aDelData );
633 // Durch MouseLeave kann auch dieses Fenster zerstoert
634 // werden
635 if ( pChild )
636 pChild->ImplAddDel( &aDelData2 );
637 if ( !ImplCallPreNotify( aNLeaveEvt ) )
639 pMouseMoveWin->MouseMove( aMLeaveEvt );
640 // #82968#
641 if( !aDelData.IsDelete() )
642 aNLeaveEvt.GetWindow()->ImplNotifyKeyMouseCommandEventListeners( aNLeaveEvt );
645 pWinFrameData->mpMouseMoveWin = NULL;
646 pWinFrameData->mbInMouseMove = FALSE;
648 if ( pChild )
650 if ( aDelData2.IsDelete() )
651 pChild = NULL;
652 else
653 pChild->ImplRemoveDel( &aDelData2 );
655 if ( aDelData.IsDelete() )
656 return 1;
657 pMouseMoveWin->ImplRemoveDel( &aDelData );
660 nMode |= MOUSE_ENTERWINDOW;
662 pWinFrameData->mpMouseMoveWin = pChild;
663 if( pChild )
664 pChild->ImplGetWinData()->mbMouseOver = TRUE;
666 // MouseLeave
667 if ( !pChild )
668 return 0;
670 else
672 // mouse click
673 if ( nSVEvent == EVENT_MOUSEBUTTONDOWN )
675 const MouseSettings& rMSettings = pChild->GetSettings().GetMouseSettings();
676 ULONG nDblClkTime = rMSettings.GetDoubleClickTime();
677 long nDblClkW = rMSettings.GetDoubleClickWidth();
678 long nDblClkH = rMSettings.GetDoubleClickHeight();
679 //long nMouseX = nX;
680 //long nMouseY = nY;
681 long nMouseX = aMousePos.X(); // #106074# use the possibly re-mirrored coordinates (RTL) ! nX,nY are unmodified !
682 long nMouseY = aMousePos.Y();
684 if ( (pChild == pChild->ImplGetFrameData()->mpMouseDownWin) &&
685 (nCode == pChild->ImplGetFrameData()->mnFirstMouseCode) &&
686 ((nMsgTime-pChild->ImplGetFrameData()->mnMouseDownTime) < nDblClkTime) &&
687 ((nMouseX-nDblClkW) <= pChild->ImplGetFrameData()->mnFirstMouseX) &&
688 ((nMouseX+nDblClkW) >= pChild->ImplGetFrameData()->mnFirstMouseX) &&
689 ((nMouseY-nDblClkH) <= pChild->ImplGetFrameData()->mnFirstMouseY) &&
690 ((nMouseY+nDblClkH) >= pChild->ImplGetFrameData()->mnFirstMouseY) )
692 pChild->ImplGetFrameData()->mnClickCount++;
693 pChild->ImplGetFrameData()->mbStartDragCalled = TRUE;
695 else
697 pChild->ImplGetFrameData()->mpMouseDownWin = pChild;
698 pChild->ImplGetFrameData()->mnClickCount = 1;
699 pChild->ImplGetFrameData()->mnFirstMouseX = nMouseX;
700 pChild->ImplGetFrameData()->mnFirstMouseY = nMouseY;
701 pChild->ImplGetFrameData()->mnFirstMouseCode = nCode;
702 pChild->ImplGetFrameData()->mbStartDragCalled = !((nCode & (MOUSE_LEFT | MOUSE_RIGHT | MOUSE_MIDDLE)) ==
703 (rMSettings.GetStartDragCode() & (MOUSE_LEFT | MOUSE_RIGHT | MOUSE_MIDDLE)));
705 pChild->ImplGetFrameData()->mnMouseDownTime = nMsgTime;
707 nClicks = pChild->ImplGetFrameData()->mnClickCount;
709 pSVData->maAppData.mnLastInputTime = Time::GetSystemTicks();
712 DBG_ASSERT( pChild, "ImplHandleMouseEvent: pChild == NULL" );
714 // create mouse event
715 Point aChildPos = pChild->ImplFrameToOutput( aMousePos );
716 MouseEvent aMEvt( aChildPos, nClicks, nMode, nCode, nCode );
718 // tracking window gets the mouse events
719 if ( pSVData->maWinData.mpTrackWin )
720 pChild = pSVData->maWinData.mpTrackWin;
722 // handle FloatingMode
723 if ( !pSVData->maWinData.mpTrackWin && pSVData->maWinData.mpFirstFloat )
725 ImplDelData aDelData;
726 pChild->ImplAddDel( &aDelData );
727 if ( ImplHandleMouseFloatMode( pChild, aMousePos, nCode, nSVEvent, bMouseLeave ) )
729 if ( !aDelData.IsDelete() )
731 pChild->ImplRemoveDel( &aDelData );
732 pChild->ImplGetFrameData()->mbStartDragCalled = TRUE;
734 return 1;
736 else
737 pChild->ImplRemoveDel( &aDelData );
740 // call handler
741 BOOL bDrag = FALSE;
742 BOOL bCallHelpRequest = TRUE;
743 DBG_ASSERT( pChild, "ImplHandleMouseEvent: pChild is NULL" );
745 ImplDelData aDelData;
746 NotifyEvent aNEvt( nSVEvent, pChild, &aMEvt );
747 pChild->ImplAddDel( &aDelData );
748 if ( nSVEvent == EVENT_MOUSEMOVE )
749 pChild->ImplGetFrameData()->mbInMouseMove = TRUE;
751 // bring window into foreground on mouseclick
752 if ( nSVEvent == EVENT_MOUSEBUTTONDOWN )
754 if( !pSVData->maWinData.mpFirstFloat && // totop for floating windows in popup would change the focus and would close them immediately
755 !(pChild->ImplGetFrameWindow()->GetStyle() & WB_OWNERDRAWDECORATION) ) // ownerdrawdecorated windows must never grab focus
756 pChild->ToTop();
757 if ( aDelData.IsDelete() )
758 return 1;
761 if ( ImplCallPreNotify( aNEvt ) || aDelData.IsDelete() )
762 nRet = 1;
763 else
765 nRet = 0;
766 if ( nSVEvent == EVENT_MOUSEMOVE )
768 if ( pSVData->maWinData.mpTrackWin )
770 TrackingEvent aTEvt( aMEvt );
771 pChild->Tracking( aTEvt );
772 if ( !aDelData.IsDelete() )
774 // When ScrollRepeat, we restart the timer
775 if ( pSVData->maWinData.mpTrackTimer &&
776 (pSVData->maWinData.mnTrackFlags & STARTTRACK_SCROLLREPEAT) )
777 pSVData->maWinData.mpTrackTimer->Start();
779 bCallHelpRequest = FALSE;
780 nRet = 1;
782 else
784 // Auto-ToTop
785 if ( !pSVData->maWinData.mpCaptureWin &&
786 (pChild->GetSettings().GetMouseSettings().GetOptions() & MOUSE_OPTION_AUTOFOCUS) )
787 pChild->ToTop( TOTOP_NOGRABFOCUS );
789 if( aDelData.IsDelete() )
790 bCallHelpRequest = FALSE;
791 else
793 // if the MouseMove handler changes the help window's visibility
794 // the HelpRequest handler should not be called anymore
795 Window* pOldHelpTextWin = pSVData->maHelpData.mpHelpWin;
796 pChild->ImplGetWindowImpl()->mbMouseMove = FALSE;
797 pChild->MouseMove( aMEvt );
798 if ( pOldHelpTextWin != pSVData->maHelpData.mpHelpWin )
799 bCallHelpRequest = FALSE;
803 else if ( nSVEvent == EVENT_MOUSEBUTTONDOWN )
805 if ( pSVData->maWinData.mpTrackWin &&
806 !(pSVData->maWinData.mnTrackFlags & STARTTRACK_MOUSEBUTTONDOWN) )
807 nRet = 1;
808 else
810 pChild->ImplGetWindowImpl()->mbMouseButtonDown = FALSE;
811 pChild->MouseButtonDown( aMEvt );
814 else
816 if ( pSVData->maWinData.mpTrackWin )
818 pChild->EndTracking();
819 nRet = 1;
821 else
823 pChild->ImplGetWindowImpl()->mbMouseButtonUp = FALSE;
824 pChild->MouseButtonUp( aMEvt );
828 // #82968#
829 if ( !aDelData.IsDelete() )
830 aNEvt.GetWindow()->ImplNotifyKeyMouseCommandEventListeners( aNEvt );
833 if ( aDelData.IsDelete() )
834 return 1;
837 if ( nSVEvent == EVENT_MOUSEMOVE )
838 pChild->ImplGetWindowImpl()->mpFrameData->mbInMouseMove = FALSE;
840 if ( nSVEvent == EVENT_MOUSEMOVE )
842 if ( bCallHelpRequest && !pSVData->maHelpData.mbKeyboardHelp )
843 ImplHandleMouseHelpRequest( pChild, pChild->OutputToScreenPixel( aMEvt.GetPosPixel() ) );
844 nRet = 1;
846 else if ( !nRet )
848 if ( nSVEvent == EVENT_MOUSEBUTTONDOWN )
850 if ( !pChild->ImplGetWindowImpl()->mbMouseButtonDown )
851 nRet = 1;
853 else
855 if ( !pChild->ImplGetWindowImpl()->mbMouseButtonUp )
856 nRet = 1;
860 pChild->ImplRemoveDel( &aDelData );
862 if ( nSVEvent == EVENT_MOUSEMOVE )
864 // set new mouse pointer
865 if ( !bMouseLeave )
866 ImplSetMousePointer( pChild );
868 else if ( (nSVEvent == EVENT_MOUSEBUTTONDOWN) || (nSVEvent == EVENT_MOUSEBUTTONUP) )
870 if ( !bDrag )
872 // Command-Events
873 if ( /*(nRet == 0) &&*/ (nClicks == 1) && (nSVEvent == EVENT_MOUSEBUTTONDOWN) &&
874 (nCode == MOUSE_MIDDLE) )
876 USHORT nMiddleAction = pChild->GetSettings().GetMouseSettings().GetMiddleButtonAction();
877 if ( nMiddleAction == MOUSE_MIDDLE_AUTOSCROLL )
878 nRet = !ImplCallCommand( pChild, COMMAND_STARTAUTOSCROLL, NULL, TRUE, &aChildPos );
879 else if ( nMiddleAction == MOUSE_MIDDLE_PASTESELECTION )
880 nRet = !ImplCallCommand( pChild, COMMAND_PASTESELECTION, NULL, TRUE, &aChildPos );
882 else
884 // ContextMenu
885 const MouseSettings& rMSettings = pChild->GetSettings().GetMouseSettings();
886 if ( (nCode == rMSettings.GetContextMenuCode()) &&
887 (nClicks == rMSettings.GetContextMenuClicks()) )
889 BOOL bContextMenu;
890 if ( rMSettings.GetContextMenuDown() )
891 bContextMenu = (nSVEvent == EVENT_MOUSEBUTTONDOWN);
892 else
893 bContextMenu = (nSVEvent == EVENT_MOUSEBUTTONUP);
894 if ( bContextMenu )
896 if( pSVData->maAppData.mpActivePopupMenu )
898 /* #i34277# there already is a context menu open
899 * that was probably just closed with EndPopupMode.
900 * We need to give the eventual corresponding
901 * PopupMenu::Execute a chance to end properly.
902 * Therefore delay context menu command and
903 * issue only after popping one frame of the
904 * Yield stack.
906 ContextMenuEvent* pEv = new ContextMenuEvent;
907 pEv->pWindow = pChild;
908 pEv->aChildPos = aChildPos;
909 pChild->ImplAddDel( &pEv->aDelData );
910 Application::PostUserEvent( Link( pEv, ContextMenuEventLink ) );
912 else
913 nRet = ! ImplCallCommand( pChild, COMMAND_CONTEXTMENU, NULL, TRUE, &aChildPos );
920 return nRet;
923 // -----------------------------------------------------------------------
925 static Window* ImplGetKeyInputWindow( Window* pWindow )
927 ImplSVData* pSVData = ImplGetSVData();
929 // determine last input time
930 pSVData->maAppData.mnLastInputTime = Time::GetSystemTicks();
932 // #127104# workaround for destroyed windows
933 if( pWindow->ImplGetWindowImpl() == NULL )
934 return 0;
936 // find window - is every time the window which has currently the
937 // focus or the last time the focus.
938 // the first floating window always has the focus
939 Window* pChild = pSVData->maWinData.mpFirstFloat;
940 if( !pChild || ( pChild->ImplGetWindowImpl()->mbFloatWin && !((FloatingWindow *)pChild)->GrabsFocus() ) )
941 pChild = pWindow->ImplGetWindowImpl()->mpFrameData->mpFocusWin;
942 else
944 // allow floaters to forward keyinput to some member
945 pChild = pChild->GetPreferredKeyInputWindow();
948 // no child - than no input
949 if ( !pChild )
950 return 0;
952 // We call also KeyInput if we haven't the focus, because on Unix
953 // system this is often the case when a Lookup Choise Window has
954 // the focus - because this windows send the KeyInput directly to
955 // the window without resetting the focus
956 DBG_ASSERTWARNING( pChild == pSVData->maWinData.mpFocusWin,
957 "ImplHandleKey: Keyboard-Input is sent to a frame without focus" );
959 // no keyinput to disabled windows
960 if ( !pChild->IsEnabled() || !pChild->IsInputEnabled() || pChild->IsInModalMode() )
961 return 0;
963 return pChild;
966 // -----------------------------------------------------------------------
968 static long ImplHandleKey( Window* pWindow, USHORT nSVEvent,
969 USHORT nKeyCode, USHORT nCharCode, USHORT nRepeat, BOOL bForward )
971 ImplSVData* pSVData = ImplGetSVData();
972 KeyCode aKeyCode( nKeyCode, nKeyCode );
973 USHORT nEvCode = aKeyCode.GetCode();
975 // allow application key listeners to remove the key event
976 // but make sure we're not forwarding external KeyEvents, (ie where bForward is FALSE)
977 // becasue those are coming back from the listener itself and MUST be processed
978 KeyEvent aKeyEvent( (xub_Unicode)nCharCode, aKeyCode, nRepeat );
979 if( bForward )
981 USHORT nVCLEvent;
982 switch( nSVEvent )
984 case EVENT_KEYINPUT:
985 nVCLEvent = VCLEVENT_WINDOW_KEYINPUT;
986 break;
987 case EVENT_KEYUP:
988 nVCLEvent = VCLEVENT_WINDOW_KEYUP;
989 break;
990 default:
991 nVCLEvent = 0;
992 break;
994 if( nVCLEvent && pSVData->mpApp->HandleKey( nVCLEvent, pWindow, &aKeyEvent ) )
995 return 1;
998 // #i1820# use locale specific decimal separator
999 if( nEvCode == KEY_DECIMAL )
1001 if( Application::GetSettings().GetMiscSettings().GetEnableLocalizedDecimalSep() )
1003 String aSep( pWindow->GetSettings().GetLocaleDataWrapper().getNumDecimalSep() );
1004 nCharCode = (USHORT) aSep.GetChar(0);
1008 BOOL bCtrlF6 = (aKeyCode.GetCode() == KEY_F6) && aKeyCode.IsMod1();
1010 // determine last input time
1011 pSVData->maAppData.mnLastInputTime = Time::GetSystemTicks();
1013 // handle tracking window
1014 if ( nSVEvent == EVENT_KEYINPUT )
1016 #ifdef DBG_UTIL
1017 // #105224# use Ctrl-Alt-Shift-D, Ctrl-Shift-D must be useable by app
1018 if ( aKeyCode.IsShift() && aKeyCode.IsMod1() && (aKeyCode.IsMod2() || aKeyCode.IsMod3()) && (aKeyCode.GetCode() == KEY_D) )
1020 DBGGUI_START();
1021 return 1;
1023 #endif
1025 if ( pSVData->maHelpData.mbExtHelpMode )
1027 Help::EndExtHelp();
1028 if ( nEvCode == KEY_ESCAPE )
1029 return 1;
1031 if ( pSVData->maHelpData.mpHelpWin )
1032 ImplDestroyHelpWindow( false );
1034 // AutoScrollMode
1035 if ( pSVData->maWinData.mpAutoScrollWin )
1037 pSVData->maWinData.mpAutoScrollWin->EndAutoScroll();
1038 if ( nEvCode == KEY_ESCAPE )
1039 return 1;
1042 if ( pSVData->maWinData.mpTrackWin )
1044 USHORT nOrigCode = aKeyCode.GetCode();
1046 if ( (nOrigCode == KEY_ESCAPE) && !(pSVData->maWinData.mnTrackFlags & STARTTRACK_NOKEYCANCEL) )
1048 pSVData->maWinData.mpTrackWin->EndTracking( ENDTRACK_CANCEL | ENDTRACK_KEY );
1049 if ( pSVData->maWinData.mpFirstFloat )
1051 FloatingWindow* pLastLevelFloat = pSVData->maWinData.mpFirstFloat->ImplFindLastLevelFloat();
1052 if ( !(pLastLevelFloat->GetPopupModeFlags() & FLOATWIN_POPUPMODE_NOKEYCLOSE) )
1054 USHORT nEscCode = aKeyCode.GetCode();
1056 if ( nEscCode == KEY_ESCAPE )
1057 pLastLevelFloat->EndPopupMode( FLOATWIN_POPUPMODEEND_CANCEL | FLOATWIN_POPUPMODEEND_CLOSEALL );
1060 return 1;
1062 else if ( nOrigCode == KEY_RETURN )
1064 pSVData->maWinData.mpTrackWin->EndTracking( ENDTRACK_KEY );
1065 return 1;
1067 else if ( !(pSVData->maWinData.mnTrackFlags & STARTTRACK_KEYINPUT) )
1068 return 1;
1071 // handle FloatingMode
1072 if ( pSVData->maWinData.mpFirstFloat )
1074 FloatingWindow* pLastLevelFloat = pSVData->maWinData.mpFirstFloat->ImplFindLastLevelFloat();
1075 if ( !(pLastLevelFloat->GetPopupModeFlags() & FLOATWIN_POPUPMODE_NOKEYCLOSE) )
1077 USHORT nCode = aKeyCode.GetCode();
1079 if ( (nCode == KEY_ESCAPE) || bCtrlF6)
1081 pLastLevelFloat->EndPopupMode( FLOATWIN_POPUPMODEEND_CANCEL | FLOATWIN_POPUPMODEEND_CLOSEALL );
1082 if( !bCtrlF6 )
1083 return 1;
1088 // test for accel
1089 if ( pSVData->maAppData.mpAccelMgr )
1091 if ( pSVData->maAppData.mpAccelMgr->IsAccelKey( aKeyCode, nRepeat ) )
1092 return 1;
1096 // find window
1097 Window* pChild = ImplGetKeyInputWindow( pWindow );
1098 if ( !pChild )
1099 return 0;
1101 // --- RTL --- mirror cursor keys
1102 if( (aKeyCode.GetCode() == KEY_LEFT || aKeyCode.GetCode() == KEY_RIGHT) &&
1103 pChild->ImplHasMirroredGraphics() && pChild->IsRTLEnabled() )
1104 aKeyCode = KeyCode( aKeyCode.GetCode() == KEY_LEFT ? KEY_RIGHT : KEY_LEFT, aKeyCode.GetModifier() );
1106 // call handler
1107 ImplDelData aDelData;
1108 pChild->ImplAddDel( &aDelData );
1110 KeyEvent aKeyEvt( (xub_Unicode)nCharCode, aKeyCode, nRepeat );
1111 NotifyEvent aNotifyEvt( nSVEvent, pChild, &aKeyEvt );
1112 BOOL bKeyPreNotify = (ImplCallPreNotify( aNotifyEvt ) != 0);
1113 long nRet = 1;
1115 if ( !bKeyPreNotify && !aDelData.IsDelete() )
1117 if ( nSVEvent == EVENT_KEYINPUT )
1119 pChild->ImplGetWindowImpl()->mbKeyInput = FALSE;
1120 pChild->KeyInput( aKeyEvt );
1122 else
1124 pChild->ImplGetWindowImpl()->mbKeyUp = FALSE;
1125 pChild->KeyUp( aKeyEvt );
1127 // #82968#
1128 if( !aDelData.IsDelete() )
1129 aNotifyEvt.GetWindow()->ImplNotifyKeyMouseCommandEventListeners( aNotifyEvt );
1132 if ( aDelData.IsDelete() )
1133 return 1;
1135 pChild->ImplRemoveDel( &aDelData );
1137 if ( nSVEvent == EVENT_KEYINPUT )
1139 if ( !bKeyPreNotify && pChild->ImplGetWindowImpl()->mbKeyInput )
1141 USHORT nCode = aKeyCode.GetCode();
1143 // #101999# is focus in or below toolbox
1144 BOOL bToolboxFocus=FALSE;
1145 if( (nCode == KEY_F1) && aKeyCode.IsShift() )
1147 Window *pWin = pWindow->ImplGetWindowImpl()->mpFrameData->mpFocusWin;
1148 while( pWin )
1150 if( pWin->ImplGetWindowImpl()->mbToolBox )
1152 bToolboxFocus = TRUE;
1153 break;
1155 else
1156 pWin = pWin->GetParent();
1160 // ContextMenu
1161 if ( (nCode == KEY_CONTEXTMENU) || ((nCode == KEY_F10) && aKeyCode.IsShift() && !aKeyCode.IsMod1() && !aKeyCode.IsMod2() ) )
1162 nRet = !ImplCallCommand( pChild, COMMAND_CONTEXTMENU, NULL, FALSE );
1163 else if ( ( (nCode == KEY_F2) && aKeyCode.IsShift() ) || ( (nCode == KEY_F1) && aKeyCode.IsMod1() ) ||
1164 // #101999# no active help when focus in toolbox, simulate BallonHelp instead
1165 ( (nCode == KEY_F1) && aKeyCode.IsShift() && bToolboxFocus ) )
1167 // TipHelp via Keyboard (Shift-F2 or Ctrl-F1)
1168 // simulate mouseposition at center of window
1170 Size aSize = pChild->GetOutputSize();
1171 Point aPos = Point( aSize.getWidth()/2, aSize.getHeight()/2 );
1172 aPos = pChild->OutputToScreenPixel( aPos );
1174 HelpEvent aHelpEvent( aPos, HELPMODE_BALLOON );
1175 aHelpEvent.SetKeyboardActivated( TRUE );
1176 pSVData->maHelpData.mbSetKeyboardHelp = TRUE;
1177 pChild->RequestHelp( aHelpEvent );
1178 pSVData->maHelpData.mbSetKeyboardHelp = FALSE;
1180 else if ( (nCode == KEY_F1) || (nCode == KEY_HELP) )
1182 if ( !aKeyCode.GetModifier() )
1184 if ( pSVData->maHelpData.mbContextHelp )
1186 Point aMousePos = pChild->OutputToScreenPixel( pChild->GetPointerPosPixel() );
1187 HelpEvent aHelpEvent( aMousePos, HELPMODE_CONTEXT );
1188 pChild->RequestHelp( aHelpEvent );
1190 else
1191 nRet = 0;
1193 else if ( aKeyCode.IsShift() )
1195 if ( pSVData->maHelpData.mbExtHelp )
1196 Help::StartExtHelp();
1197 else
1198 nRet = 0;
1201 else
1203 if ( ImplCallHotKey( aKeyCode ) )
1204 nRet = 1;
1205 else
1206 nRet = 0;
1210 else
1212 if ( !bKeyPreNotify && pChild->ImplGetWindowImpl()->mbKeyUp )
1213 nRet = 0;
1216 // #105591# send keyinput to parent if we are a floating window and the key was not pocessed yet
1217 if( !nRet && pWindow->ImplGetWindowImpl()->mbFloatWin && pWindow->GetParent() && (pWindow->ImplGetWindowImpl()->mpFrame != pWindow->GetParent()->ImplGetWindowImpl()->mpFrame) )
1219 pChild = pWindow->GetParent();
1221 // call handler
1222 ImplDelData aChildDelData( pChild );
1223 KeyEvent aKEvt( (xub_Unicode)nCharCode, aKeyCode, nRepeat );
1224 NotifyEvent aNEvt( nSVEvent, pChild, &aKEvt );
1225 BOOL bPreNotify = (ImplCallPreNotify( aNEvt ) != 0);
1226 if ( aChildDelData.IsDelete() )
1227 return 1;
1229 if ( !bPreNotify )
1231 if ( nSVEvent == EVENT_KEYINPUT )
1233 pChild->ImplGetWindowImpl()->mbKeyInput = FALSE;
1234 pChild->KeyInput( aKEvt );
1236 else
1238 pChild->ImplGetWindowImpl()->mbKeyUp = FALSE;
1239 pChild->KeyUp( aKEvt );
1241 // #82968#
1242 if( !aChildDelData.IsDelete() )
1243 aNEvt.GetWindow()->ImplNotifyKeyMouseCommandEventListeners( aNEvt );
1244 if ( aChildDelData.IsDelete() )
1245 return 1;
1248 if( bPreNotify || !pChild->ImplGetWindowImpl()->mbKeyInput )
1249 nRet = 1;
1252 return nRet;
1255 // -----------------------------------------------------------------------
1257 static long ImplHandleExtTextInput( Window* pWindow,
1258 const XubString& rText,
1259 const USHORT* pTextAttr,
1260 ULONG nCursorPos, USHORT nCursorFlags )
1262 ImplSVData* pSVData = ImplGetSVData();
1263 Window* pChild = NULL;
1265 int nTries = 200;
1266 while( nTries-- )
1268 pChild = pSVData->maWinData.mpExtTextInputWin;
1269 if ( !pChild )
1271 pChild = ImplGetKeyInputWindow( pWindow );
1272 if ( !pChild )
1273 return 0;
1275 if( !pChild->ImplGetWindowImpl()->mpFrameData->mnFocusId )
1276 break;
1277 Application::Yield();
1280 // If it is the first ExtTextInput call, we inform the information
1281 // and allocate the data, which we must store in this mode
1282 ImplWinData* pWinData = pChild->ImplGetWinData();
1283 if ( !pChild->ImplGetWindowImpl()->mbExtTextInput )
1285 pChild->ImplGetWindowImpl()->mbExtTextInput = TRUE;
1286 if ( !pWinData->mpExtOldText )
1287 pWinData->mpExtOldText = new UniString;
1288 else
1289 pWinData->mpExtOldText->Erase();
1290 if ( pWinData->mpExtOldAttrAry )
1292 delete [] pWinData->mpExtOldAttrAry;
1293 pWinData->mpExtOldAttrAry = NULL;
1295 pSVData->maWinData.mpExtTextInputWin = pChild;
1296 ImplCallCommand( pChild, COMMAND_STARTEXTTEXTINPUT );
1299 // be aware of being recursively called in StartExtTextInput
1300 if ( !pChild->ImplGetWindowImpl()->mbExtTextInput )
1301 return 0;
1303 // Test for changes
1304 BOOL bOnlyCursor = FALSE;
1305 xub_StrLen nMinLen = Min( pWinData->mpExtOldText->Len(), rText.Len() );
1306 xub_StrLen nDeltaStart = 0;
1307 while ( nDeltaStart < nMinLen )
1309 if ( pWinData->mpExtOldText->GetChar( nDeltaStart ) != rText.GetChar( nDeltaStart ) )
1310 break;
1311 nDeltaStart++;
1313 if ( pWinData->mpExtOldAttrAry || pTextAttr )
1315 if ( !pWinData->mpExtOldAttrAry || !pTextAttr )
1316 nDeltaStart = 0;
1317 else
1319 xub_StrLen i = 0;
1320 while ( i < nDeltaStart )
1322 if ( pWinData->mpExtOldAttrAry[i] != pTextAttr[i] )
1324 nDeltaStart = i;
1325 break;
1327 i++;
1331 if ( (nDeltaStart >= nMinLen) &&
1332 (pWinData->mpExtOldText->Len() == rText.Len()) )
1333 bOnlyCursor = TRUE;
1335 // Call Event and store the information
1336 CommandExtTextInputData aData( rText, pTextAttr,
1337 (xub_StrLen)nCursorPos, nCursorFlags,
1338 nDeltaStart, pWinData->mpExtOldText->Len(),
1339 bOnlyCursor );
1340 *pWinData->mpExtOldText = rText;
1341 if ( pWinData->mpExtOldAttrAry )
1343 delete [] pWinData->mpExtOldAttrAry;
1344 pWinData->mpExtOldAttrAry = NULL;
1346 if ( pTextAttr )
1348 pWinData->mpExtOldAttrAry = new USHORT[rText.Len()];
1349 memcpy( pWinData->mpExtOldAttrAry, pTextAttr, rText.Len()*sizeof( USHORT ) );
1351 return !ImplCallCommand( pChild, COMMAND_EXTTEXTINPUT, &aData );
1354 // -----------------------------------------------------------------------
1356 static long ImplHandleEndExtTextInput( Window* /* pWindow */ )
1358 ImplSVData* pSVData = ImplGetSVData();
1359 Window* pChild = pSVData->maWinData.mpExtTextInputWin;
1360 long nRet = 0;
1362 if ( pChild )
1364 pChild->ImplGetWindowImpl()->mbExtTextInput = FALSE;
1365 pSVData->maWinData.mpExtTextInputWin = NULL;
1366 ImplWinData* pWinData = pChild->ImplGetWinData();
1367 if ( pWinData->mpExtOldText )
1369 delete pWinData->mpExtOldText;
1370 pWinData->mpExtOldText = NULL;
1372 if ( pWinData->mpExtOldAttrAry )
1374 delete [] pWinData->mpExtOldAttrAry;
1375 pWinData->mpExtOldAttrAry = NULL;
1377 nRet = !ImplCallCommand( pChild, COMMAND_ENDEXTTEXTINPUT );
1380 return nRet;
1383 // -----------------------------------------------------------------------
1385 static void ImplHandleExtTextInputPos( Window* pWindow,
1386 Rectangle& rRect, long& rInputWidth,
1387 bool * pVertical )
1389 ImplSVData* pSVData = ImplGetSVData();
1390 Window* pChild = pSVData->maWinData.mpExtTextInputWin;
1392 if ( !pChild )
1393 pChild = ImplGetKeyInputWindow( pWindow );
1394 else
1396 // Test, if the Window is related to the frame
1397 if ( !pWindow->ImplIsWindowOrChild( pChild ) )
1398 pChild = ImplGetKeyInputWindow( pWindow );
1401 if ( pChild )
1403 ImplCallCommand( pChild, COMMAND_CURSORPOS );
1404 const Rectangle* pRect = pChild->GetCursorRect();
1405 if ( pRect )
1406 rRect = pChild->ImplLogicToDevicePixel( *pRect );
1407 else
1409 Cursor* pCursor = pChild->GetCursor();
1410 if ( pCursor )
1412 Point aPos = pChild->ImplLogicToDevicePixel( pCursor->GetPos() );
1413 Size aSize = pChild->LogicToPixel( pCursor->GetSize() );
1414 if ( !aSize.Width() )
1415 aSize.Width() = pChild->GetSettings().GetStyleSettings().GetCursorSize();
1416 rRect = Rectangle( aPos, aSize );
1418 else
1419 rRect = Rectangle( Point( pChild->GetOutOffXPixel(), pChild->GetOutOffYPixel() ), Size() );
1421 rInputWidth = pChild->ImplLogicWidthToDevicePixel( pChild->GetCursorExtTextInputWidth() );
1422 if ( !rInputWidth )
1423 rInputWidth = rRect.GetWidth();
1425 if (pVertical != 0)
1426 *pVertical
1427 = pChild != 0 && pChild->GetInputContext().GetFont().IsVertical();
1430 // -----------------------------------------------------------------------
1432 static long ImplHandleInputContextChange( Window* pWindow, LanguageType eNewLang )
1434 Window* pChild = ImplGetKeyInputWindow( pWindow );
1435 CommandInputContextData aData( eNewLang );
1436 return !ImplCallCommand( pChild, COMMAND_INPUTCONTEXTCHANGE, &aData );
1439 // -----------------------------------------------------------------------
1441 static BOOL ImplCallWheelCommand( Window* pWindow, const Point& rPos,
1442 const CommandWheelData* pWheelData )
1444 Point aCmdMousePos = pWindow->ImplFrameToOutput( rPos );
1445 CommandEvent aCEvt( aCmdMousePos, COMMAND_WHEEL, TRUE, pWheelData );
1446 NotifyEvent aNCmdEvt( EVENT_COMMAND, pWindow, &aCEvt );
1447 ImplDelData aDelData( pWindow );
1448 BOOL bPreNotify = (ImplCallPreNotify( aNCmdEvt ) != 0);
1449 if ( aDelData.IsDelete() )
1450 return FALSE;
1451 if ( !bPreNotify )
1453 pWindow->ImplGetWindowImpl()->mbCommand = FALSE;
1454 pWindow->Command( aCEvt );
1455 if ( aDelData.IsDelete() )
1456 return FALSE;
1457 if ( pWindow->ImplGetWindowImpl()->mbCommand )
1458 return TRUE;
1460 return FALSE;
1463 // -----------------------------------------------------------------------
1465 static long ImplHandleWheelEvent( Window* pWindow, const SalWheelMouseEvent& rEvt )
1467 ImplDelData aDogTag( pWindow );
1469 ImplSVData* pSVData = ImplGetSVData();
1470 if ( pSVData->maWinData.mpAutoScrollWin )
1471 pSVData->maWinData.mpAutoScrollWin->EndAutoScroll();
1472 if ( pSVData->maHelpData.mpHelpWin )
1473 ImplDestroyHelpWindow( true );
1474 if( aDogTag.IsDelete() )
1475 return 0;
1477 USHORT nMode;
1478 USHORT nCode = rEvt.mnCode;
1479 bool bHorz = rEvt.mbHorz;
1480 if ( nCode & KEY_MOD1 )
1481 nMode = COMMAND_WHEEL_ZOOM;
1482 else if ( nCode & KEY_MOD2 )
1483 nMode = COMMAND_WHEEL_DATAZOOM;
1484 else
1486 nMode = COMMAND_WHEEL_SCROLL;
1487 // #i85450# interpret shift-wheel as horizontal wheel action
1488 if( (nCode & (KEY_SHIFT | KEY_MOD1 | KEY_MOD2 | KEY_MOD3)) == KEY_SHIFT )
1489 bHorz = true;
1492 CommandWheelData aWheelData( rEvt.mnDelta, rEvt.mnNotchDelta, rEvt.mnScrollLines, nMode, nCode, bHorz );
1493 Point aMousePos( rEvt.mnX, rEvt.mnY );
1494 BOOL bRet = TRUE;
1496 // first check any floating window ( eg. drop down listboxes)
1497 bool bIsFloat = false;
1498 Window *pMouseWindow = NULL;
1499 if ( pSVData->maWinData.mpFirstFloat && !pSVData->maWinData.mpCaptureWin &&
1500 !pSVData->maWinData.mpFirstFloat->ImplIsFloatPopupModeWindow( pWindow ) )
1502 USHORT nHitTest = IMPL_FLOATWIN_HITTEST_OUTSIDE;
1503 pMouseWindow = pSVData->maWinData.mpFirstFloat->ImplFloatHitTest( pWindow, aMousePos, nHitTest );
1505 // then try the window directly beneath the mouse
1506 if( !pMouseWindow )
1507 pMouseWindow = pWindow->ImplFindWindow( aMousePos );
1508 else
1510 // transform coordinates to float window frame coordinates
1511 pMouseWindow = pMouseWindow->ImplFindWindow(
1512 pMouseWindow->OutputToScreenPixel(
1513 pMouseWindow->AbsoluteScreenToOutputPixel(
1514 pWindow->OutputToAbsoluteScreenPixel(
1515 pWindow->ScreenToOutputPixel( aMousePos ) ) ) ) );
1516 bIsFloat = true;
1519 if ( pMouseWindow &&
1520 pMouseWindow->IsEnabled() && pMouseWindow->IsInputEnabled() && ! pMouseWindow->IsInModalMode() )
1522 // transform coordinates to float window frame coordinates
1523 Point aRelMousePos( pMouseWindow->OutputToScreenPixel(
1524 pMouseWindow->AbsoluteScreenToOutputPixel(
1525 pWindow->OutputToAbsoluteScreenPixel(
1526 pWindow->ScreenToOutputPixel( aMousePos ) ) ) ) );
1527 bRet = ImplCallWheelCommand( pMouseWindow, aRelMousePos, &aWheelData );
1530 // if the commad was not handled try the focus window
1531 if ( bRet )
1533 Window* pFocusWindow = pWindow->ImplGetWindowImpl()->mpFrameData->mpFocusWin;
1534 if ( pFocusWindow && (pFocusWindow != pMouseWindow) &&
1535 (pFocusWindow == pSVData->maWinData.mpFocusWin) )
1537 // no wheel-messages to disabled windows
1538 if ( pFocusWindow->IsEnabled() && pFocusWindow->IsInputEnabled() && ! pFocusWindow->IsInModalMode() )
1540 // transform coordinates to focus window frame coordinates
1541 Point aRelMousePos( pFocusWindow->OutputToScreenPixel(
1542 pFocusWindow->AbsoluteScreenToOutputPixel(
1543 pWindow->OutputToAbsoluteScreenPixel(
1544 pWindow->ScreenToOutputPixel( aMousePos ) ) ) ) );
1545 bRet = ImplCallWheelCommand( pFocusWindow, aRelMousePos, &aWheelData );
1550 // close floaters
1551 if( ! bIsFloat && pSVData->maWinData.mpFirstFloat )
1553 FloatingWindow* pLastLevelFloat = pSVData->maWinData.mpFirstFloat->ImplFindLastLevelFloat();
1554 if( pLastLevelFloat )
1556 ULONG nPopupFlags = pLastLevelFloat->GetPopupModeFlags();
1557 if ( nPopupFlags & FLOATWIN_POPUPMODE_ALLMOUSEBUTTONCLOSE )
1559 pLastLevelFloat->EndPopupMode( FLOATWIN_POPUPMODEEND_CANCEL | FLOATWIN_POPUPMODEEND_CLOSEALL );
1564 return !bRet;
1567 // -----------------------------------------------------------------------
1568 #define IMPL_PAINT_CHECKRTL ((USHORT)0x0020)
1570 static void ImplHandlePaint( Window* pWindow, const Rectangle& rBoundRect, bool bImmediateUpdate )
1572 // give up background save when sytem paints arrive
1573 Window* pSaveBackWin = pWindow->ImplGetWindowImpl()->mpFrameData->mpFirstBackWin;
1574 while ( pSaveBackWin )
1576 Window* pNext = pSaveBackWin->ImplGetWindowImpl()->mpOverlapData->mpNextBackWin;
1577 Rectangle aRect( Point( pSaveBackWin->GetOutOffXPixel(), pSaveBackWin->GetOutOffYPixel() ),
1578 Size( pSaveBackWin->GetOutputWidthPixel(), pSaveBackWin->GetOutputHeightPixel() ) );
1579 if ( aRect.IsOver( rBoundRect ) )
1580 pSaveBackWin->ImplDeleteOverlapBackground();
1581 pSaveBackWin = pNext;
1584 // system paint events must be checked for re-mirroring
1585 pWindow->ImplGetWindowImpl()->mnPaintFlags |= IMPL_PAINT_CHECKRTL;
1587 // trigger paint for all windows that live in the new paint region
1588 Region aRegion( rBoundRect );
1589 pWindow->ImplInvalidateOverlapFrameRegion( aRegion );
1590 if( bImmediateUpdate )
1592 // #i87663# trigger possible pending resize notifications
1593 // (GetSizePixel does that for us)
1594 pWindow->GetSizePixel();
1595 // force drawing inmmediately
1596 pWindow->Update();
1600 // -----------------------------------------------------------------------
1602 static void KillOwnPopups( Window* pWindow )
1604 ImplSVData* pSVData = ImplGetSVData();
1605 Window *pParent = pWindow->ImplGetWindowImpl()->mpFrameWindow;
1606 Window *pChild = pSVData->maWinData.mpFirstFloat;
1607 if ( pChild && pParent->ImplIsWindowOrChild( pChild, TRUE ) )
1609 if ( !(pSVData->maWinData.mpFirstFloat->GetPopupModeFlags() & FLOATWIN_POPUPMODE_NOAPPFOCUSCLOSE) )
1610 pSVData->maWinData.mpFirstFloat->EndPopupMode( FLOATWIN_POPUPMODEEND_CANCEL | FLOATWIN_POPUPMODEEND_CLOSEALL );
1614 // -----------------------------------------------------------------------
1616 void ImplHandleResize( Window* pWindow, long nNewWidth, long nNewHeight )
1618 if( pWindow->GetStyle() & (WB_MOVEABLE|WB_SIZEABLE) )
1620 KillOwnPopups( pWindow );
1621 if( pWindow->ImplGetWindow() != ImplGetSVData()->maHelpData.mpHelpWin )
1622 ImplDestroyHelpWindow( true );
1625 if (
1626 (nNewWidth > 0 && nNewHeight > 0) ||
1627 pWindow->ImplGetWindow()->ImplGetWindowImpl()->mbAllResize
1630 if ( (nNewWidth != pWindow->GetOutputWidthPixel()) || (nNewHeight != pWindow->GetOutputHeightPixel()) )
1632 pWindow->mnOutWidth = nNewWidth;
1633 pWindow->mnOutHeight = nNewHeight;
1634 pWindow->ImplGetWindowImpl()->mbWaitSystemResize = FALSE;
1635 if ( pWindow->IsReallyVisible() )
1636 pWindow->ImplSetClipFlag();
1637 if ( pWindow->IsVisible() || pWindow->ImplGetWindow()->ImplGetWindowImpl()->mbAllResize ||
1638 ( pWindow->ImplGetWindowImpl()->mbFrame && pWindow->ImplGetWindowImpl()->mpClientWindow ) ) // propagate resize for system border windows
1640 bool bStartTimer = true;
1641 // use resize buffering for user resizes
1642 // ownerdraw decorated windows and floating windows can be resized immediately (i.e. synchronously)
1643 if( pWindow->ImplGetWindowImpl()->mbFrame && (pWindow->GetStyle() & WB_SIZEABLE)
1644 && !(pWindow->GetStyle() & WB_OWNERDRAWDECORATION) // synchronous resize for ownerdraw decorated windows (toolbars)
1645 && !pWindow->ImplGetWindowImpl()->mbFloatWin ) // synchronous resize for floating windows, #i43799#
1647 if( pWindow->ImplGetWindowImpl()->mpClientWindow )
1649 // #i42750# presentation wants to be informed about resize
1650 // as early as possible
1651 WorkWindow* pWorkWindow = dynamic_cast<WorkWindow*>(pWindow->ImplGetWindowImpl()->mpClientWindow);
1652 if( pWorkWindow && pWorkWindow->IsPresentationMode() )
1653 bStartTimer = false;
1656 else
1657 bStartTimer = false;
1659 if( bStartTimer )
1660 pWindow->ImplGetWindowImpl()->mpFrameData->maResizeTimer.Start();
1661 else
1662 pWindow->ImplCallResize(); // otherwise menues cannot be positioned
1664 else
1665 pWindow->ImplGetWindowImpl()->mbCallResize = TRUE;
1669 pWindow->ImplGetWindowImpl()->mpFrameData->mbNeedSysWindow = (nNewWidth < IMPL_MIN_NEEDSYSWIN) ||
1670 (nNewHeight < IMPL_MIN_NEEDSYSWIN);
1671 BOOL bMinimized = (nNewWidth <= 0) || (nNewHeight <= 0);
1672 if( bMinimized != pWindow->ImplGetWindowImpl()->mpFrameData->mbMinimized )
1673 pWindow->ImplGetWindowImpl()->mpFrameWindow->ImplNotifyIconifiedState( bMinimized );
1674 pWindow->ImplGetWindowImpl()->mpFrameData->mbMinimized = bMinimized;
1677 // -----------------------------------------------------------------------
1679 static void ImplHandleMove( Window* pWindow )
1681 if( pWindow->ImplGetWindowImpl()->mbFrame && pWindow->ImplIsFloatingWindow() && pWindow->IsReallyVisible() )
1683 static_cast<FloatingWindow*>(pWindow)->EndPopupMode( FLOATWIN_POPUPMODEEND_TEAROFF );
1684 pWindow->ImplCallMove();
1687 if( pWindow->GetStyle() & (WB_MOVEABLE|WB_SIZEABLE) )
1689 KillOwnPopups( pWindow );
1690 if( pWindow->ImplGetWindow() != ImplGetSVData()->maHelpData.mpHelpWin )
1691 ImplDestroyHelpWindow( true );
1694 if ( pWindow->IsVisible() )
1695 pWindow->ImplCallMove();
1696 else
1697 pWindow->ImplGetWindowImpl()->mbCallMove = TRUE; // make sure the framepos will be updated on the next Show()
1699 if ( pWindow->ImplGetWindowImpl()->mbFrame && pWindow->ImplGetWindowImpl()->mpClientWindow )
1700 pWindow->ImplGetWindowImpl()->mpClientWindow->ImplCallMove(); // notify client to update geometry
1704 // -----------------------------------------------------------------------
1706 static void ImplHandleMoveResize( Window* pWindow, long nNewWidth, long nNewHeight )
1708 ImplHandleMove( pWindow );
1709 ImplHandleResize( pWindow, nNewWidth, nNewHeight );
1712 // -----------------------------------------------------------------------
1714 static void ImplActivateFloatingWindows( Window* pWindow, BOOL bActive )
1716 // Zuerst alle ueberlappenden Fenster ueberpruefen
1717 Window* pTempWindow = pWindow->ImplGetWindowImpl()->mpFirstOverlap;
1718 while ( pTempWindow )
1720 if ( !pTempWindow->GetActivateMode() )
1722 if ( (pTempWindow->GetType() == WINDOW_BORDERWINDOW) &&
1723 (pTempWindow->ImplGetWindow()->GetType() == WINDOW_FLOATINGWINDOW) )
1724 ((ImplBorderWindow*)pTempWindow)->SetDisplayActive( bActive );
1727 ImplActivateFloatingWindows( pTempWindow, bActive );
1728 pTempWindow = pTempWindow->ImplGetWindowImpl()->mpNext;
1733 // -----------------------------------------------------------------------
1735 IMPL_LINK( Window, ImplAsyncFocusHdl, void*, EMPTYARG )
1737 ImplGetWindowImpl()->mpFrameData->mnFocusId = 0;
1739 // Wenn Status erhalten geblieben ist, weil wir den Focus in der
1740 // zwischenzeit schon wiederbekommen haben, brauchen wir auch
1741 // nichts machen
1742 BOOL bHasFocus = ImplGetWindowImpl()->mpFrameData->mbHasFocus || ImplGetWindowImpl()->mpFrameData->mbSysObjFocus;
1744 // Dann die zeitverzoegerten Funktionen ausfuehren
1745 if ( bHasFocus )
1747 // Alle FloatingFenster deaktiv zeichnen
1748 if ( ImplGetWindowImpl()->mpFrameData->mbStartFocusState != bHasFocus )
1749 ImplActivateFloatingWindows( this, bHasFocus );
1751 if ( ImplGetWindowImpl()->mpFrameData->mpFocusWin )
1753 BOOL bHandled = FALSE;
1754 if ( ImplGetWindowImpl()->mpFrameData->mpFocusWin->IsInputEnabled() &&
1755 ! ImplGetWindowImpl()->mpFrameData->mpFocusWin->IsInModalMode() )
1757 if ( ImplGetWindowImpl()->mpFrameData->mpFocusWin->IsEnabled() )
1759 ImplGetWindowImpl()->mpFrameData->mpFocusWin->GrabFocus();
1760 bHandled = TRUE;
1762 else if( ImplGetWindowImpl()->mpFrameData->mpFocusWin->ImplHasDlgCtrl() )
1764 // #109094# if the focus is restored to a disabled dialog control (was disabled meanwhile)
1765 // try to move it to the next control
1766 ImplGetWindowImpl()->mpFrameData->mpFocusWin->ImplDlgCtrlNextWindow();
1767 bHandled = TRUE;
1770 if ( !bHandled )
1772 ImplSVData* pSVData = ImplGetSVData();
1773 Window* pTopLevelWindow = ImplGetWindowImpl()->mpFrameData->mpFocusWin->ImplGetFirstOverlapWindow();
1774 if ( ( ! pTopLevelWindow->IsInputEnabled() || pTopLevelWindow->IsInModalMode() )
1775 && pSVData->maWinData.mpLastExecuteDlg )
1776 pSVData->maWinData.mpLastExecuteDlg->ToTop( TOTOP_RESTOREWHENMIN | TOTOP_GRABFOCUSONLY);
1777 else
1778 pTopLevelWindow->GrabFocus();
1781 else
1782 GrabFocus();
1784 else
1786 Window* pFocusWin = ImplGetWindowImpl()->mpFrameData->mpFocusWin;
1787 if ( pFocusWin )
1789 ImplSVData* pSVData = ImplGetSVData();
1791 if ( pSVData->maWinData.mpFocusWin == pFocusWin )
1793 // FocusWindow umsetzen
1794 Window* pOverlapWindow = pFocusWin->ImplGetFirstOverlapWindow();
1795 pOverlapWindow->ImplGetWindowImpl()->mpLastFocusWindow = pFocusWin;
1796 pSVData->maWinData.mpFocusWin = NULL;
1798 if ( pFocusWin->ImplGetWindowImpl()->mpCursor )
1799 pFocusWin->ImplGetWindowImpl()->mpCursor->ImplHide();
1801 // Deaktivate rufen
1802 Window* pOldFocusWindow = pFocusWin;
1803 if ( pOldFocusWindow )
1805 Window* pOldOverlapWindow = pOldFocusWindow->ImplGetFirstOverlapWindow();
1806 Window* pOldRealWindow = pOldOverlapWindow->ImplGetWindow();
1808 pOldOverlapWindow->ImplGetWindowImpl()->mbActive = FALSE;
1809 pOldOverlapWindow->Deactivate();
1810 if ( pOldRealWindow != pOldOverlapWindow )
1812 pOldRealWindow->ImplGetWindowImpl()->mbActive = FALSE;
1813 pOldRealWindow->Deactivate();
1817 // TrackingMode is ended in ImplHandleLoseFocus
1818 // To avoid problems with the Unix IME
1819 // pFocusWin->EndExtTextInput( EXTTEXTINPUT_END_COMPLETE );
1821 // XXX #102010# hack for accessibility: do not close the menu,
1822 // even after focus lost
1823 static const char* pEnv = getenv("SAL_FLOATWIN_NOAPPFOCUSCLOSE");
1824 if( !(pEnv && *pEnv) )
1826 NotifyEvent aNEvt( EVENT_LOSEFOCUS, pFocusWin );
1827 if ( !ImplCallPreNotify( aNEvt ) )
1828 pFocusWin->LoseFocus();
1829 pFocusWin->ImplCallDeactivateListeners( NULL );
1830 GetpApp()->FocusChanged();
1832 // XXX
1836 // Alle FloatingFenster deaktiv zeichnen
1837 if ( ImplGetWindowImpl()->mpFrameData->mbStartFocusState != bHasFocus )
1838 ImplActivateFloatingWindows( this, bHasFocus );
1841 return 0;
1844 // -----------------------------------------------------------------------
1846 static void ImplHandleGetFocus( Window* pWindow )
1848 pWindow->ImplGetWindowImpl()->mpFrameData->mbHasFocus = TRUE;
1850 // Focus-Events zeitverzoegert ausfuehren, damit bei SystemChildFenstern
1851 // nicht alles flackert, wenn diese den Focus bekommen
1852 if ( !pWindow->ImplGetWindowImpl()->mpFrameData->mnFocusId )
1854 bool bCallDirect = ImplGetSVData()->mbIsTestTool;
1855 pWindow->ImplGetWindowImpl()->mpFrameData->mbStartFocusState = !pWindow->ImplGetWindowImpl()->mpFrameData->mbHasFocus;
1856 if( ! bCallDirect )
1857 Application::PostUserEvent( pWindow->ImplGetWindowImpl()->mpFrameData->mnFocusId, LINK( pWindow, Window, ImplAsyncFocusHdl ) );
1858 Window* pFocusWin = pWindow->ImplGetWindowImpl()->mpFrameData->mpFocusWin;
1859 if ( pFocusWin && pFocusWin->ImplGetWindowImpl()->mpCursor )
1860 pFocusWin->ImplGetWindowImpl()->mpCursor->ImplShow();
1861 if( bCallDirect )
1862 pWindow->ImplAsyncFocusHdl( NULL );
1866 // -----------------------------------------------------------------------
1868 static void ImplHandleLoseFocus( Window* pWindow )
1870 ImplSVData* pSVData = ImplGetSVData();
1872 // Wenn Frame den Focus verliert, brechen wir auch ein AutoScroll ab
1873 if ( pSVData->maWinData.mpAutoScrollWin )
1874 pSVData->maWinData.mpAutoScrollWin->EndAutoScroll();
1876 // Wenn Frame den Focus verliert, brechen wir auch ein Tracking ab
1877 if ( pSVData->maWinData.mpTrackWin )
1879 if ( pSVData->maWinData.mpTrackWin->ImplGetWindowImpl()->mpFrameWindow == pWindow )
1880 pSVData->maWinData.mpTrackWin->EndTracking( ENDTRACK_CANCEL );
1883 // handle FloatingMode
1884 // hier beenden wir immer den PopupModus, auch dann, wenn NOFOCUSCLOSE
1885 // gesetzt ist, damit wir nicht beim Wechsel noch Fenster stehen lassen
1886 if ( pSVData->maWinData.mpFirstFloat )
1888 if ( !(pSVData->maWinData.mpFirstFloat->GetPopupModeFlags() & FLOATWIN_POPUPMODE_NOAPPFOCUSCLOSE) )
1889 pSVData->maWinData.mpFirstFloat->EndPopupMode( FLOATWIN_POPUPMODEEND_CANCEL | FLOATWIN_POPUPMODEEND_CLOSEALL );
1892 pWindow->ImplGetWindowImpl()->mpFrameData->mbHasFocus = FALSE;
1894 // Focus-Events zeitverzoegert ausfuehren, damit bei SystemChildFenstern
1895 // nicht alles flackert, wenn diese den Focus bekommen
1896 bool bCallDirect = ImplGetSVData()->mbIsTestTool;
1897 if ( !pWindow->ImplGetWindowImpl()->mpFrameData->mnFocusId )
1899 pWindow->ImplGetWindowImpl()->mpFrameData->mbStartFocusState = !pWindow->ImplGetWindowImpl()->mpFrameData->mbHasFocus;
1900 if( ! bCallDirect )
1901 Application::PostUserEvent( pWindow->ImplGetWindowImpl()->mpFrameData->mnFocusId, LINK( pWindow, Window, ImplAsyncFocusHdl ) );
1904 Window* pFocusWin = pWindow->ImplGetWindowImpl()->mpFrameData->mpFocusWin;
1905 if ( pFocusWin && pFocusWin->ImplGetWindowImpl()->mpCursor )
1906 pFocusWin->ImplGetWindowImpl()->mpCursor->ImplHide();
1907 if( bCallDirect )
1908 pWindow->ImplAsyncFocusHdl( NULL );
1911 // -----------------------------------------------------------------------
1912 struct DelayedCloseEvent
1914 Window* pWindow;
1915 ImplDelData aDelData;
1918 static long DelayedCloseEventLink( void* pCEvent, void* )
1920 DelayedCloseEvent* pEv = (DelayedCloseEvent*)pCEvent;
1922 if( ! pEv->aDelData.IsDelete() )
1924 pEv->pWindow->ImplRemoveDel( &pEv->aDelData );
1925 // dispatch to correct window type
1926 if( pEv->pWindow->IsSystemWindow() )
1927 ((SystemWindow*)pEv->pWindow)->Close();
1928 else if( pEv->pWindow->ImplIsDockingWindow() )
1929 ((DockingWindow*)pEv->pWindow)->Close();
1931 delete pEv;
1933 return 0;
1936 void ImplHandleClose( Window* pWindow )
1938 ImplSVData* pSVData = ImplGetSVData();
1940 bool bWasPopup = false;
1941 if( pWindow->ImplIsFloatingWindow() &&
1942 static_cast<FloatingWindow*>(pWindow)->ImplIsInPrivatePopupMode() )
1944 bWasPopup = true;
1947 // on Close stop all floating modes and end popups
1948 if ( pSVData->maWinData.mpFirstFloat )
1950 FloatingWindow* pLastLevelFloat;
1951 pLastLevelFloat = pSVData->maWinData.mpFirstFloat->ImplFindLastLevelFloat();
1952 pLastLevelFloat->EndPopupMode( FLOATWIN_POPUPMODEEND_CANCEL | FLOATWIN_POPUPMODEEND_CLOSEALL );
1954 if ( pSVData->maHelpData.mbExtHelpMode )
1955 Help::EndExtHelp();
1956 if ( pSVData->maHelpData.mpHelpWin )
1957 ImplDestroyHelpWindow( false );
1958 // AutoScrollMode
1959 if ( pSVData->maWinData.mpAutoScrollWin )
1960 pSVData->maWinData.mpAutoScrollWin->EndAutoScroll();
1962 if ( pSVData->maWinData.mpTrackWin )
1963 pSVData->maWinData.mpTrackWin->EndTracking( ENDTRACK_CANCEL | ENDTRACK_KEY );
1965 if( ! bWasPopup )
1967 Window *pWin = pWindow->ImplGetWindow();
1968 // check whether close is allowed
1969 if ( !pWin->IsEnabled() || !pWin->IsInputEnabled() || pWin->IsInModalMode() )
1970 Sound::Beep( SOUND_DISABLE, pWin );
1971 else
1973 DelayedCloseEvent* pEv = new DelayedCloseEvent;
1974 pEv->pWindow = pWin;
1975 pWin->ImplAddDel( &pEv->aDelData );
1976 Application::PostUserEvent( Link( pEv, DelayedCloseEventLink ) );
1981 // -----------------------------------------------------------------------
1983 static void ImplHandleUserEvent( ImplSVEvent* pSVEvent )
1985 if ( pSVEvent )
1987 if ( pSVEvent->mbCall && !pSVEvent->maDelData.IsDelete() )
1989 if ( pSVEvent->mpWindow )
1991 pSVEvent->mpWindow->ImplRemoveDel( &(pSVEvent->maDelData) );
1992 if ( pSVEvent->mpLink )
1993 pSVEvent->mpLink->Call( pSVEvent->mpData );
1994 else
1995 pSVEvent->mpWindow->UserEvent( pSVEvent->mnEvent, pSVEvent->mpData );
1997 else
1999 if ( pSVEvent->mpLink )
2000 pSVEvent->mpLink->Call( pSVEvent->mpData );
2001 else
2002 GetpApp()->UserEvent( pSVEvent->mnEvent, pSVEvent->mpData );
2006 delete pSVEvent->mpLink;
2007 delete pSVEvent;
2011 // =======================================================================
2013 static USHORT ImplGetMouseMoveMode( SalMouseEvent* pEvent )
2015 USHORT nMode = 0;
2016 if ( !pEvent->mnCode )
2017 nMode |= MOUSE_SIMPLEMOVE;
2018 if ( (pEvent->mnCode & MOUSE_LEFT) && !(pEvent->mnCode & KEY_MOD1) )
2019 nMode |= MOUSE_DRAGMOVE;
2020 if ( (pEvent->mnCode & MOUSE_LEFT) && (pEvent->mnCode & KEY_MOD1) )
2021 nMode |= MOUSE_DRAGCOPY;
2022 return nMode;
2025 // -----------------------------------------------------------------------
2027 static USHORT ImplGetMouseButtonMode( SalMouseEvent* pEvent )
2029 USHORT nMode = 0;
2030 if ( pEvent->mnButton == MOUSE_LEFT )
2031 nMode |= MOUSE_SIMPLECLICK;
2032 if ( (pEvent->mnButton == MOUSE_LEFT) && !(pEvent->mnCode & (MOUSE_MIDDLE | MOUSE_RIGHT)) )
2033 nMode |= MOUSE_SELECT;
2034 if ( (pEvent->mnButton == MOUSE_LEFT) && (pEvent->mnCode & KEY_MOD1) &&
2035 !(pEvent->mnCode & (MOUSE_MIDDLE | MOUSE_RIGHT | KEY_SHIFT)) )
2036 nMode |= MOUSE_MULTISELECT;
2037 if ( (pEvent->mnButton == MOUSE_LEFT) && (pEvent->mnCode & KEY_SHIFT) &&
2038 !(pEvent->mnCode & (MOUSE_MIDDLE | MOUSE_RIGHT | KEY_MOD1)) )
2039 nMode |= MOUSE_RANGESELECT;
2040 return nMode;
2043 // -----------------------------------------------------------------------
2045 inline long ImplHandleSalMouseLeave( Window* pWindow, SalMouseEvent* pEvent )
2047 return ImplHandleMouseEvent( pWindow, EVENT_MOUSEMOVE, TRUE,
2048 pEvent->mnX, pEvent->mnY,
2049 pEvent->mnTime, pEvent->mnCode,
2050 ImplGetMouseMoveMode( pEvent ) );
2053 // -----------------------------------------------------------------------
2055 inline long ImplHandleSalMouseMove( Window* pWindow, SalMouseEvent* pEvent )
2057 return ImplHandleMouseEvent( pWindow, EVENT_MOUSEMOVE, FALSE,
2058 pEvent->mnX, pEvent->mnY,
2059 pEvent->mnTime, pEvent->mnCode,
2060 ImplGetMouseMoveMode( pEvent ) );
2063 // -----------------------------------------------------------------------
2065 inline long ImplHandleSalMouseButtonDown( Window* pWindow, SalMouseEvent* pEvent )
2067 return ImplHandleMouseEvent( pWindow, EVENT_MOUSEBUTTONDOWN, FALSE,
2068 pEvent->mnX, pEvent->mnY,
2069 pEvent->mnTime,
2070 #ifdef MACOSX
2071 pEvent->mnButton | (pEvent->mnCode & (KEY_SHIFT | KEY_MOD1 | KEY_MOD2 | KEY_MOD3)),
2072 #else
2073 pEvent->mnButton | (pEvent->mnCode & (KEY_SHIFT | KEY_MOD1 | KEY_MOD2)),
2074 #endif
2075 ImplGetMouseButtonMode( pEvent ) );
2078 // -----------------------------------------------------------------------
2080 inline long ImplHandleSalMouseButtonUp( Window* pWindow, SalMouseEvent* pEvent )
2082 return ImplHandleMouseEvent( pWindow, EVENT_MOUSEBUTTONUP, FALSE,
2083 pEvent->mnX, pEvent->mnY,
2084 pEvent->mnTime,
2085 #ifdef MACOSX
2086 pEvent->mnButton | (pEvent->mnCode & (KEY_SHIFT | KEY_MOD1 | KEY_MOD2 | KEY_MOD3)),
2087 #else
2088 pEvent->mnButton | (pEvent->mnCode & (KEY_SHIFT | KEY_MOD1 | KEY_MOD2)),
2089 #endif
2090 ImplGetMouseButtonMode( pEvent ) );
2093 // -----------------------------------------------------------------------
2095 static long ImplHandleSalMouseActivate( Window* /*pWindow*/, SalMouseActivateEvent* /*pEvent*/ )
2097 return FALSE;
2100 // -----------------------------------------------------------------------
2102 static long ImplHandleMenuEvent( Window* pWindow, SalMenuEvent* pEvent, USHORT nEvent )
2104 // Find SystemWindow and its Menubar and let it dispatch the command
2105 long nRet = 0;
2106 Window *pWin = pWindow->ImplGetWindowImpl()->mpFirstChild;
2107 while ( pWin )
2109 if ( pWin->ImplGetWindowImpl()->mbSysWin )
2110 break;
2111 pWin = pWin->ImplGetWindowImpl()->mpNext;
2113 if( pWin )
2115 MenuBar *pMenuBar = ((SystemWindow*) pWin)->GetMenuBar();
2116 if( pMenuBar )
2118 switch( nEvent )
2120 case SALEVENT_MENUACTIVATE:
2121 nRet = pMenuBar->HandleMenuActivateEvent( (Menu*) pEvent->mpMenu ) ? 1 : 0;
2122 break;
2123 case SALEVENT_MENUDEACTIVATE:
2124 nRet = pMenuBar->HandleMenuDeActivateEvent( (Menu*) pEvent->mpMenu ) ? 1 : 0;
2125 break;
2126 case SALEVENT_MENUHIGHLIGHT:
2127 nRet = pMenuBar->HandleMenuHighlightEvent( (Menu*) pEvent->mpMenu, pEvent->mnId ) ? 1 : 0;
2128 break;
2129 case SALEVENT_MENUBUTTONCOMMAND:
2130 nRet = pMenuBar->HandleMenuButtonEvent( (Menu*) pEvent->mpMenu, pEvent->mnId ) ? 1 : 0;
2131 break;
2132 case SALEVENT_MENUCOMMAND:
2133 nRet = pMenuBar->HandleMenuCommandEvent( (Menu*) pEvent->mpMenu, pEvent->mnId ) ? 1 : 0;
2134 break;
2135 default:
2136 break;
2140 return nRet;
2143 // -----------------------------------------------------------------------
2145 static void ImplHandleSalKeyMod( Window* pWindow, SalKeyModEvent* pEvent )
2147 ImplSVData* pSVData = ImplGetSVData();
2148 Window* pTrackWin = pSVData->maWinData.mpTrackWin;
2149 if ( pTrackWin )
2150 pWindow = pTrackWin;
2151 #ifdef MACOSX
2152 USHORT nOldCode = pWindow->ImplGetWindowImpl()->mpFrameData->mnMouseCode & (KEY_SHIFT | KEY_MOD1 | KEY_MOD2 | KEY_MOD3);
2153 #else
2154 USHORT nOldCode = pWindow->ImplGetWindowImpl()->mpFrameData->mnMouseCode & (KEY_SHIFT | KEY_MOD1 | KEY_MOD2);
2155 #endif
2156 USHORT nNewCode = pEvent->mnCode;
2157 if ( nOldCode != nNewCode )
2159 #ifdef MACOSX
2160 nNewCode |= pWindow->ImplGetWindowImpl()->mpFrameData->mnMouseCode & ~(KEY_SHIFT | KEY_MOD1 | KEY_MOD2 | KEY_MOD3);
2161 #else
2162 nNewCode |= pWindow->ImplGetWindowImpl()->mpFrameData->mnMouseCode & ~(KEY_SHIFT | KEY_MOD1 | KEY_MOD2);
2163 #endif
2164 pWindow->ImplGetWindowImpl()->mpFrameWindow->ImplCallMouseMove( nNewCode, TRUE );
2167 // #105224# send commandevent to allow special treatment of Ctrl-LeftShift/Ctrl-RightShift etc.
2169 // find window
2170 Window* pChild = ImplGetKeyInputWindow( pWindow );
2171 if ( !pChild )
2172 return;
2174 // send modkey events only if useful data is available
2175 if( pEvent->mnModKeyCode != 0 )
2177 CommandModKeyData data( pEvent->mnModKeyCode );
2178 ImplCallCommand( pChild, COMMAND_MODKEYCHANGE, &data );
2182 // -----------------------------------------------------------------------
2184 static void ImplHandleInputLanguageChange( Window* pWindow )
2186 // find window
2187 Window* pChild = ImplGetKeyInputWindow( pWindow );
2188 if ( !pChild )
2189 return;
2191 ImplCallCommand( pChild, COMMAND_INPUTLANGUAGECHANGE );
2194 // -----------------------------------------------------------------------
2196 static void ImplHandleSalSettings( Window* pWindow, USHORT nEvent )
2198 // Application Notification werden nur fuer das erste Window ausgeloest
2199 ImplSVData* pSVData = ImplGetSVData();
2200 if ( pWindow != pSVData->maWinData.mpFirstFrame )
2201 return;
2203 Application* pApp = GetpApp();
2204 if ( !pApp )
2205 return;
2207 if ( nEvent == SALEVENT_SETTINGSCHANGED )
2209 AllSettings aSettings = pApp->GetSettings();
2210 pApp->MergeSystemSettings( aSettings );
2211 pApp->SystemSettingsChanging( aSettings, pWindow );
2212 pApp->SetSettings( aSettings );
2214 else
2216 USHORT nType;
2217 switch ( nEvent )
2219 case SALEVENT_VOLUMECHANGED:
2220 nType = 0;
2221 break;
2222 case SALEVENT_PRINTERCHANGED:
2223 ImplDeletePrnQueueList();
2224 nType = DATACHANGED_PRINTER;
2225 break;
2226 case SALEVENT_DISPLAYCHANGED:
2227 nType = DATACHANGED_DISPLAY;
2228 break;
2229 case SALEVENT_FONTCHANGED:
2230 OutputDevice::ImplUpdateAllFontData( TRUE );
2231 nType = DATACHANGED_FONTS;
2232 break;
2233 case SALEVENT_DATETIMECHANGED:
2234 nType = DATACHANGED_DATETIME;
2235 break;
2236 case SALEVENT_KEYBOARDCHANGED:
2237 nType = 0;
2238 break;
2239 default:
2240 nType = 0;
2241 break;
2244 if ( nType )
2246 DataChangedEvent aDCEvt( nType );
2247 pApp->DataChanged( aDCEvt );
2248 pApp->NotifyAllWindows( aDCEvt );
2253 // -----------------------------------------------------------------------
2255 static void ImplHandleSalExtTextInputPos( Window* pWindow, SalExtTextInputPosEvent* pEvt )
2257 Rectangle aCursorRect;
2258 ImplHandleExtTextInputPos( pWindow, aCursorRect, pEvt->mnExtWidth, &pEvt->mbVertical );
2259 if ( aCursorRect.IsEmpty() )
2261 pEvt->mnX = -1;
2262 pEvt->mnY = -1;
2263 pEvt->mnWidth = -1;
2264 pEvt->mnHeight = -1;
2266 else
2268 pEvt->mnX = aCursorRect.Left();
2269 pEvt->mnY = aCursorRect.Top();
2270 pEvt->mnWidth = aCursorRect.GetWidth();
2271 pEvt->mnHeight = aCursorRect.GetHeight();
2275 // -----------------------------------------------------------------------
2277 static long ImplHandleShowDialog( Window* pWindow, int nDialogId )
2279 if( ! pWindow )
2280 return FALSE;
2282 if( pWindow->GetType() == WINDOW_BORDERWINDOW )
2284 Window* pWrkWin = pWindow->GetWindow( WINDOW_CLIENT );
2285 if( pWrkWin )
2286 pWindow = pWrkWin;
2288 CommandDialogData aCmdData( nDialogId );
2289 return ImplCallCommand( pWindow, COMMAND_SHOWDIALOG, &aCmdData );
2292 // -----------------------------------------------------------------------
2294 static void ImplHandleSurroundingTextRequest( Window *pWindow,
2295 XubString& rText,
2296 Selection &rSelRange )
2298 Window* pChild = ImplGetKeyInputWindow( pWindow );
2300 if ( !pChild )
2302 rText = XubString::EmptyString();
2303 rSelRange.setMin( 0 );
2304 rSelRange.setMax( 0 );
2306 else
2309 rText = pChild->GetSurroundingText();
2310 Selection aSel = pChild->GetSurroundingTextSelection();
2311 rSelRange.setMin( aSel.Min() );
2312 rSelRange.setMax( aSel.Max() );
2316 // -----------------------------------------------------------------------
2318 static void ImplHandleSalSurroundingTextRequest( Window *pWindow,
2319 SalSurroundingTextRequestEvent *pEvt )
2321 Selection aSelRange;
2322 ImplHandleSurroundingTextRequest( pWindow, pEvt->maText, aSelRange );
2324 aSelRange.Justify();
2326 if( aSelRange.Min() < 0 )
2327 pEvt->mnStart = 0;
2328 else if( aSelRange.Min() > pEvt->maText.Len() )
2329 pEvt->mnStart = pEvt->maText.Len();
2330 else
2331 pEvt->mnStart = aSelRange.Min();
2333 if( aSelRange.Max() < 0 )
2334 pEvt->mnStart = 0;
2335 else if( aSelRange.Max() > pEvt->maText.Len() )
2336 pEvt->mnEnd = pEvt->maText.Len();
2337 else
2338 pEvt->mnEnd = aSelRange.Max();
2341 // -----------------------------------------------------------------------
2343 static void ImplHandleSurroundingTextSelectionChange( Window *pWindow,
2344 ULONG nStart,
2345 ULONG nEnd )
2347 Window* pChild = ImplGetKeyInputWindow( pWindow );
2348 if( pChild )
2350 CommandSelectionChangeData data( nStart, nEnd );
2351 ImplCallCommand( pChild, COMMAND_SELECTIONCHANGE, &data );
2355 // -----------------------------------------------------------------------
2357 static void ImplHandleStartReconversion( Window *pWindow )
2359 Window* pChild = ImplGetKeyInputWindow( pWindow );
2360 if( pChild )
2361 ImplCallCommand( pChild, COMMAND_PREPARERECONVERSION );
2364 // -----------------------------------------------------------------------
2366 long ImplWindowFrameProc( Window* pWindow, SalFrame* /*pFrame*/,
2367 USHORT nEvent, const void* pEvent )
2369 DBG_TESTSOLARMUTEX();
2371 long nRet = 0;
2373 // #119709# for some unknown reason it is possible to receive events (in this case key events)
2374 // although the corresponding VCL window must have been destroyed already
2375 // at least ImplGetWindowImpl() was NULL in these cases, so check this here
2376 if( pWindow->ImplGetWindowImpl() == NULL )
2377 return 0;
2379 switch ( nEvent )
2381 case SALEVENT_MOUSEMOVE:
2382 nRet = ImplHandleSalMouseMove( pWindow, (SalMouseEvent*)pEvent );
2383 break;
2384 case SALEVENT_EXTERNALMOUSEMOVE:
2386 MouseEvent* pMouseEvt = (MouseEvent*) pEvent;
2387 SalMouseEvent aSalMouseEvent;
2389 aSalMouseEvent.mnTime = Time::GetSystemTicks();
2390 aSalMouseEvent.mnX = pMouseEvt->GetPosPixel().X();
2391 aSalMouseEvent.mnY = pMouseEvt->GetPosPixel().Y();
2392 aSalMouseEvent.mnButton = 0;
2393 aSalMouseEvent.mnCode = pMouseEvt->GetButtons() | pMouseEvt->GetModifier();
2395 nRet = ImplHandleSalMouseMove( pWindow, &aSalMouseEvent );
2397 break;
2398 case SALEVENT_MOUSELEAVE:
2399 nRet = ImplHandleSalMouseLeave( pWindow, (SalMouseEvent*)pEvent );
2400 break;
2401 case SALEVENT_MOUSEBUTTONDOWN:
2402 nRet = ImplHandleSalMouseButtonDown( pWindow, (SalMouseEvent*)pEvent );
2403 break;
2404 case SALEVENT_EXTERNALMOUSEBUTTONDOWN:
2406 MouseEvent* pMouseEvt = (MouseEvent*) pEvent;
2407 SalMouseEvent aSalMouseEvent;
2409 aSalMouseEvent.mnTime = Time::GetSystemTicks();
2410 aSalMouseEvent.mnX = pMouseEvt->GetPosPixel().X();
2411 aSalMouseEvent.mnY = pMouseEvt->GetPosPixel().Y();
2412 aSalMouseEvent.mnButton = pMouseEvt->GetButtons();
2413 aSalMouseEvent.mnCode = pMouseEvt->GetButtons() | pMouseEvt->GetModifier();
2415 nRet = ImplHandleSalMouseButtonDown( pWindow, &aSalMouseEvent );
2417 break;
2418 case SALEVENT_MOUSEBUTTONUP:
2419 nRet = ImplHandleSalMouseButtonUp( pWindow, (SalMouseEvent*)pEvent );
2420 break;
2421 case SALEVENT_EXTERNALMOUSEBUTTONUP:
2423 MouseEvent* pMouseEvt = (MouseEvent*) pEvent;
2424 SalMouseEvent aSalMouseEvent;
2426 aSalMouseEvent.mnTime = Time::GetSystemTicks();
2427 aSalMouseEvent.mnX = pMouseEvt->GetPosPixel().X();
2428 aSalMouseEvent.mnY = pMouseEvt->GetPosPixel().Y();
2429 aSalMouseEvent.mnButton = pMouseEvt->GetButtons();
2430 aSalMouseEvent.mnCode = pMouseEvt->GetButtons() | pMouseEvt->GetModifier();
2432 nRet = ImplHandleSalMouseButtonUp( pWindow, &aSalMouseEvent );
2434 break;
2435 case SALEVENT_MOUSEACTIVATE:
2436 nRet = ImplHandleSalMouseActivate( pWindow, (SalMouseActivateEvent*)pEvent );
2437 break;
2438 case SALEVENT_KEYINPUT:
2440 SalKeyEvent* pKeyEvt = (SalKeyEvent*)pEvent;
2441 nRet = ImplHandleKey( pWindow, EVENT_KEYINPUT,
2442 pKeyEvt->mnCode, pKeyEvt->mnCharCode, pKeyEvt->mnRepeat, TRUE );
2444 break;
2445 case SALEVENT_EXTERNALKEYINPUT:
2447 KeyEvent* pKeyEvt = (KeyEvent*) pEvent;
2448 nRet = ImplHandleKey( pWindow, EVENT_KEYINPUT,
2449 pKeyEvt->GetKeyCode().GetFullCode(), pKeyEvt->GetCharCode(), pKeyEvt->GetRepeat(), FALSE );
2451 break;
2452 case SALEVENT_KEYUP:
2454 SalKeyEvent* pKeyEvt = (SalKeyEvent*)pEvent;
2455 nRet = ImplHandleKey( pWindow, EVENT_KEYUP,
2456 pKeyEvt->mnCode, pKeyEvt->mnCharCode, pKeyEvt->mnRepeat, TRUE );
2458 break;
2459 case SALEVENT_EXTERNALKEYUP:
2461 KeyEvent* pKeyEvt = (KeyEvent*) pEvent;
2462 nRet = ImplHandleKey( pWindow, EVENT_KEYUP,
2463 pKeyEvt->GetKeyCode().GetFullCode(), pKeyEvt->GetCharCode(), pKeyEvt->GetRepeat(), FALSE );
2465 break;
2466 case SALEVENT_KEYMODCHANGE:
2467 ImplHandleSalKeyMod( pWindow, (SalKeyModEvent*)pEvent );
2468 break;
2470 case SALEVENT_INPUTLANGUAGECHANGE:
2471 ImplHandleInputLanguageChange( pWindow );
2472 break;
2474 case SALEVENT_MENUACTIVATE:
2475 case SALEVENT_MENUDEACTIVATE:
2476 case SALEVENT_MENUHIGHLIGHT:
2477 case SALEVENT_MENUCOMMAND:
2478 case SALEVENT_MENUBUTTONCOMMAND:
2479 nRet = ImplHandleMenuEvent( pWindow, (SalMenuEvent*)pEvent, nEvent );
2480 break;
2482 case SALEVENT_WHEELMOUSE:
2483 nRet = ImplHandleWheelEvent( pWindow, *(const SalWheelMouseEvent*)pEvent);
2484 break;
2486 case SALEVENT_PAINT:
2488 SalPaintEvent* pPaintEvt = (SalPaintEvent*)pEvent;
2490 if( Application::GetSettings().GetLayoutRTL() )
2492 // --- RTL --- (mirror paint rect)
2493 SalFrame* pSalFrame = pWindow->ImplGetWindowImpl()->mpFrame;
2494 pPaintEvt->mnBoundX = pSalFrame->maGeometry.nWidth-pPaintEvt->mnBoundWidth-pPaintEvt->mnBoundX;
2497 Rectangle aBoundRect( Point( pPaintEvt->mnBoundX, pPaintEvt->mnBoundY ),
2498 Size( pPaintEvt->mnBoundWidth, pPaintEvt->mnBoundHeight ) );
2499 ImplHandlePaint( pWindow, aBoundRect, pPaintEvt->mbImmediateUpdate );
2501 break;
2503 case SALEVENT_MOVE:
2504 ImplHandleMove( pWindow );
2505 break;
2507 case SALEVENT_RESIZE:
2509 long nNewWidth;
2510 long nNewHeight;
2511 pWindow->ImplGetWindowImpl()->mpFrame->GetClientSize( nNewWidth, nNewHeight );
2512 ImplHandleResize( pWindow, nNewWidth, nNewHeight );
2514 break;
2516 case SALEVENT_MOVERESIZE:
2518 SalFrameGeometry g = pWindow->ImplGetWindowImpl()->mpFrame->GetGeometry();
2519 ImplHandleMoveResize( pWindow, g.nWidth, g.nHeight );
2521 break;
2523 case SALEVENT_CLOSEPOPUPS:
2525 KillOwnPopups( pWindow );
2527 break;
2529 case SALEVENT_GETFOCUS:
2530 ImplHandleGetFocus( pWindow );
2531 break;
2532 case SALEVENT_LOSEFOCUS:
2533 ImplHandleLoseFocus( pWindow );
2534 break;
2536 case SALEVENT_CLOSE:
2537 ImplHandleClose( pWindow );
2538 break;
2540 case SALEVENT_SHUTDOWN:
2542 static bool bInQueryExit = false;
2543 if( !bInQueryExit )
2545 bInQueryExit = true;
2546 if ( GetpApp()->QueryExit() )
2548 // Message-Schleife beenden
2549 Application::Quit();
2550 return FALSE;
2552 else
2554 bInQueryExit = false;
2555 return TRUE;
2558 return FALSE;
2561 case SALEVENT_SETTINGSCHANGED:
2562 case SALEVENT_VOLUMECHANGED:
2563 case SALEVENT_PRINTERCHANGED:
2564 case SALEVENT_DISPLAYCHANGED:
2565 case SALEVENT_FONTCHANGED:
2566 case SALEVENT_DATETIMECHANGED:
2567 case SALEVENT_KEYBOARDCHANGED:
2568 ImplHandleSalSettings( pWindow, nEvent );
2569 break;
2571 case SALEVENT_USEREVENT:
2572 ImplHandleUserEvent( (ImplSVEvent*)pEvent );
2573 break;
2575 case SALEVENT_EXTTEXTINPUT:
2577 SalExtTextInputEvent* pEvt = (SalExtTextInputEvent*)pEvent;
2578 nRet = ImplHandleExtTextInput( pWindow,
2579 pEvt->maText, pEvt->mpTextAttr,
2580 pEvt->mnCursorPos, pEvt->mnCursorFlags );
2582 break;
2583 case SALEVENT_ENDEXTTEXTINPUT:
2584 nRet = ImplHandleEndExtTextInput( pWindow );
2585 break;
2586 case SALEVENT_EXTTEXTINPUTPOS:
2587 ImplHandleSalExtTextInputPos( pWindow, (SalExtTextInputPosEvent*)pEvent );
2588 break;
2589 case SALEVENT_INPUTCONTEXTCHANGE:
2590 nRet = ImplHandleInputContextChange( pWindow, ((SalInputContextChangeEvent*)pEvent)->meLanguage );
2591 break;
2592 case SALEVENT_SHOWDIALOG:
2594 int nDialogID = static_cast<int>(reinterpret_cast<sal_IntPtr>(pEvent));
2595 nRet = ImplHandleShowDialog( pWindow, nDialogID );
2597 break;
2598 case SALEVENT_SURROUNDINGTEXTREQUEST:
2599 ImplHandleSalSurroundingTextRequest( pWindow, (SalSurroundingTextRequestEvent*)pEvent );
2600 break;
2601 case SALEVENT_SURROUNDINGTEXTSELECTIONCHANGE:
2603 SalSurroundingTextSelectionChangeEvent* pEvt
2604 = (SalSurroundingTextSelectionChangeEvent*)pEvent;
2605 ImplHandleSurroundingTextSelectionChange( pWindow,
2606 pEvt->mnStart,
2607 pEvt->mnEnd );
2609 case SALEVENT_STARTRECONVERSION:
2610 ImplHandleStartReconversion( pWindow );
2611 break;
2612 #ifdef DBG_UTIL
2613 default:
2614 DBG_ERROR1( "ImplWindowFrameProc(): unknown event (%lu)", (ULONG)nEvent );
2615 break;
2616 #endif
2619 return nRet;