summaryrefslogtreecommitdiff
path: root/vcl/source/window/winproc.cxx
diff options
context:
space:
mode:
Diffstat (limited to 'vcl/source/window/winproc.cxx')
-rw-r--r--vcl/source/window/winproc.cxx2151
1 files changed, 2151 insertions, 0 deletions
diff --git a/vcl/source/window/winproc.cxx b/vcl/source/window/winproc.cxx
new file mode 100644
index 000000000000..db3382df3f88
--- /dev/null
+++ b/vcl/source/window/winproc.cxx
@@ -0,0 +1,2151 @@
+/*************************************************************************
+ *
+ * $RCSfile: winproc.cxx,v $
+ *
+ * $Revision: 1.1.1.1 $
+ *
+ * last change: $Author: hr $ $Date: 2000-09-18 17:05:40 $
+ *
+ * The Contents of this file are made available subject to the terms of
+ * either of the following licenses
+ *
+ * - GNU Lesser General Public License Version 2.1
+ * - Sun Industry Standards Source License Version 1.1
+ *
+ * Sun Microsystems Inc., October, 2000
+ *
+ * GNU Lesser General Public License Version 2.1
+ * =============================================
+ * Copyright 2000 by Sun Microsystems, Inc.
+ * 901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software Foundation.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ *
+ *
+ * Sun Industry Standards Source License Version 1.1
+ * =================================================
+ * The contents of this file are subject to the Sun Industry Standards
+ * Source License Version 1.1 (the "License"); You may not use this file
+ * except in compliance with the License. You may obtain a copy of the
+ * License at http://www.openoffice.org/license.html.
+ *
+ * Software provided under this License is provided on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+ * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+ * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+ * See the License for the specific provisions governing your rights and
+ * obligations concerning the Software.
+ *
+ * The Initial Developer of the Original Code is: Sun Microsystems, Inc.
+ *
+ * Copyright: 2000 by Sun Microsystems, Inc.
+ *
+ * All Rights Reserved.
+ *
+ * Contributor(s): _______________________________________
+ *
+ *
+ ************************************************************************/
+
+#define _SV_WINPROC_CXX
+
+#ifndef _SV_SVSYS_HXX
+#include <svsys.h>
+#endif
+
+#ifndef REMOTE_APPSERVER
+#ifndef _SV_SALWTYPE_HXX
+#include <salwtype.hxx>
+#endif
+#ifndef _SV_SALFRAME_HXX
+#include <salframe.hxx>
+#endif
+#else
+#include <rmwindow.hxx>
+#include <rmevents.hxx>
+#endif
+
+#ifndef _DEBUG_HXX
+#include <tools/debug.hxx>
+#endif
+#ifndef _INTN_HXX
+#include <tools/intn.hxx>
+#endif
+
+#define private public
+#ifndef _SV_SVDATA_HXX
+#include <svdata.hxx>
+#endif
+#ifndef _SV_DBGGUI_HXX
+#include <dbggui.hxx>
+#endif
+#ifndef _SV_WINDATA_HXX
+#include <windata.hxx>
+#endif
+#ifndef _SV_TIMER_HXX
+#include <timer.hxx>
+#endif
+#ifndef _SV_EVENT_HXX
+#include <event.hxx>
+#endif
+#ifndef _SV_SOUND_HXX
+#include <sound.hxx>
+#endif
+#ifndef _SV_SETTINGS_HXX
+#include <settings.hxx>
+#endif
+#ifndef _SV_SVAPP_HXX
+#include <svapp.hxx>
+#endif
+#ifndef _SV_CURSOR_HXX
+#include <cursor.hxx>
+#endif
+#ifndef _SV_ACCMGR_HXX
+#include <accmgr.hxx>
+#endif
+#ifndef _SV_PRINT_H
+#include <print.h>
+#endif
+#ifndef _SV_WINDOW_H
+#include <window.h>
+#endif
+#ifndef _SV_WRKWIN_HXX
+#include <wrkwin.hxx>
+#endif
+#ifndef _SV_FLOATWIN_HXX
+#include <floatwin.hxx>
+#endif
+#ifndef _SV_DRAG_HXX
+#include <drag.hxx>
+#endif
+#ifndef _SV_GETSYS_HXX
+#include <getsys.hxx>
+#endif
+#ifndef _SV_HELP_HXX
+#include <help.hxx>
+#endif
+#ifndef _SV_HELPWIN_HXX
+#include <helpwin.hxx>
+#endif
+#ifndef _SV_BRDWIN_HXX
+#include <brdwin.hxx>
+#endif
+#undef private
+
+#pragma hdrstop
+
+// =======================================================================
+
+#define IMPL_MIN_NEEDSYSWIN 49
+
+// =======================================================================
+
+long ImplCallPreNotify( NotifyEvent& rEvt )
+{
+ long nRet = Application::CallEventHooks( rEvt );
+ if ( !nRet )
+ nRet = rEvt.GetWindow()->PreNotify( rEvt );
+ return nRet;
+}
+
+// =======================================================================
+
+long ImplCallEvent( NotifyEvent& rEvt )
+{
+ long nRet = ImplCallPreNotify( rEvt );
+ if ( !nRet )
+ {
+ Window* pWindow = rEvt.GetWindow();
+ switch ( rEvt.GetType() )
+ {
+ case EVENT_MOUSEBUTTONDOWN:
+ pWindow->MouseButtonDown( *rEvt.GetMouseEvent() );
+ break;
+ case EVENT_MOUSEBUTTONUP:
+ pWindow->MouseButtonUp( *rEvt.GetMouseEvent() );
+ break;
+ case EVENT_MOUSEMOVE:
+ pWindow->MouseMove( *rEvt.GetMouseEvent() );
+ break;
+ case EVENT_KEYINPUT:
+ pWindow->KeyInput( *rEvt.GetKeyEvent() );
+ break;
+ case EVENT_KEYUP:
+ pWindow->KeyUp( *rEvt.GetKeyEvent() );
+ break;
+ case EVENT_GETFOCUS:
+ pWindow->GetFocus();
+ break;
+ case EVENT_LOSEFOCUS:
+ pWindow->LoseFocus();
+ break;
+ case EVENT_COMMAND:
+ pWindow->Command( *rEvt.GetCommandEvent() );
+ break;
+ case EVENT_QUERYDROP:
+ nRet = pWindow->QueryDrop( *rEvt.GetDropEvent() );
+ break;
+ case EVENT_DROP:
+ nRet = pWindow->QueryDrop( *rEvt.GetDropEvent() );
+ break;
+ }
+ }
+
+ return nRet;
+}
+
+// =======================================================================
+
+class ImplDragTimer : public AutoTimer
+{
+ Window* mpWindow;
+
+public:
+ ImplDragTimer( Window* pWindow );
+
+ virtual void Timeout();
+};
+
+static BOOL mbImplDragTimeoutHdl = FALSE;
+
+// -----------------------------------------------------------------------
+
+ImplDragTimer::ImplDragTimer( Window* pWindow )
+{
+ mpWindow = pWindow;
+ SetTimeout( 45 );
+ Start();
+}
+
+// -----------------------------------------------------------------------
+
+void ImplDragTimer::Timeout()
+{
+ if ( DragManager::GetDragManager() )
+ {
+ mbImplDragTimeoutHdl = TRUE;
+ mpWindow->ImplCallMouseMove( mpWindow->mpFrameData->mnMouseCode );
+ mbImplDragTimeoutHdl = FALSE;
+ }
+ else
+ {
+ mpWindow->mpFrameData->mpDragTimer = NULL;
+ delete this;
+ }
+}
+
+// =======================================================================
+
+static BOOL ImplHandleMouseFloatMode( Window* pChild, const Point& rMousePos,
+ USHORT nCode, USHORT nSVEvent,
+ BOOL bMouseLeave )
+{
+ ImplSVData* pSVData = ImplGetSVData();
+
+ if ( pSVData->maWinData.mpFirstFloat && !pSVData->maWinData.mpCaptureWin &&
+ !pSVData->maWinData.mpFirstFloat->ImplIsFloatPopupModeWindow( pChild ) )
+ {
+ USHORT nHitTest;
+ FloatingWindow* pFloat = pSVData->maWinData.mpFirstFloat->ImplFloatHitTest( rMousePos, nHitTest );
+ FloatingWindow* pLastLevelFloat;
+ ULONG nPopupFlags;
+ if ( nSVEvent == EVENT_MOUSEMOVE )
+ {
+ if ( bMouseLeave )
+ return TRUE;
+
+ if ( !pFloat || (nHitTest & IMPL_FLOATWIN_HITTEST_RECT) )
+ {
+ if ( pSVData->maHelpData.mpHelpWin )
+ ImplDestroyHelpWindow();
+ pChild->mpFrame->SetPointer( POINTER_ARROW );
+ return TRUE;
+ }
+ }
+ else
+ {
+ if ( nCode & MOUSE_LEFT )
+ {
+ if ( nSVEvent == EVENT_MOUSEBUTTONDOWN )
+ {
+ if ( !pFloat )
+ {
+ pLastLevelFloat = pSVData->maWinData.mpFirstFloat->ImplFindLastLevelFloat();
+ nPopupFlags = pLastLevelFloat->GetPopupModeFlags();
+ pLastLevelFloat->EndPopupMode( FLOATWIN_POPUPMODEEND_CANCEL | FLOATWIN_POPUPMODEEND_CLOSEALL );
+// Erstmal ausgebaut als Hack fuer Bug 53378
+// if ( nPopupFlags & FLOATWIN_POPUPMODE_PATHMOUSECANCELCLICK )
+// return FALSE;
+// else
+ return TRUE;
+ }
+ else if ( nHitTest & IMPL_FLOATWIN_HITTEST_RECT )
+ {
+ if ( !(pFloat->GetPopupModeFlags() & FLOATWIN_POPUPMODE_NOMOUSERECTCLOSE) )
+ pFloat->ImplSetMouseDown();
+ return TRUE;
+ }
+ }
+ else
+ {
+ if ( pFloat )
+ {
+ if ( nHitTest & IMPL_FLOATWIN_HITTEST_RECT )
+ {
+ if ( pFloat->ImplIsMouseDown() )
+ pFloat->EndPopupMode( FLOATWIN_POPUPMODEEND_CANCEL );
+ return TRUE;
+ }
+ }
+ else
+ {
+ pLastLevelFloat = pSVData->maWinData.mpFirstFloat->ImplFindLastLevelFloat();
+ nPopupFlags = pLastLevelFloat->GetPopupModeFlags();
+ if ( !(nPopupFlags & FLOATWIN_POPUPMODE_NOMOUSEUPCLOSE) )
+ {
+ pLastLevelFloat->EndPopupMode( FLOATWIN_POPUPMODEEND_CANCEL | FLOATWIN_POPUPMODEEND_CLOSEALL );
+ return TRUE;
+ }
+ }
+ }
+ }
+ else
+ {
+ if ( !pFloat )
+ {
+ pLastLevelFloat = pSVData->maWinData.mpFirstFloat->ImplFindLastLevelFloat();
+ nPopupFlags = pLastLevelFloat->GetPopupModeFlags();
+ if ( nPopupFlags & FLOATWIN_POPUPMODE_ALLMOUSEBUTTONCLOSE )
+ {
+ if ( (nPopupFlags & FLOATWIN_POPUPMODE_NOMOUSEUPCLOSE) &&
+ (nSVEvent == EVENT_MOUSEBUTTONDOWN) )
+ return TRUE;
+ pLastLevelFloat->EndPopupMode( FLOATWIN_POPUPMODEEND_CANCEL | FLOATWIN_POPUPMODEEND_CLOSEALL );
+ if ( nPopupFlags & FLOATWIN_POPUPMODE_PATHMOUSECANCELCLICK )
+ return FALSE;
+ else
+ return TRUE;
+ }
+ else
+ return TRUE;
+ }
+ }
+ }
+ }
+
+ return FALSE;
+}
+
+// -----------------------------------------------------------------------
+
+static void ImplHandleMouseHelpRequest( Window* pChild, const Point& rMousePos )
+{
+ ImplSVData* pSVData = ImplGetSVData();
+ if ( ( pChild != pSVData->maHelpData.mpHelpWin ) && !DragManager::GetDragManager() )
+ {
+ USHORT nHelpMode = 0;
+ if ( pSVData->maHelpData.mbQuickHelp )
+ nHelpMode = HELPMODE_QUICK;
+ if ( pSVData->maHelpData.mbBalloonHelp )
+ nHelpMode |= HELPMODE_BALLOON;
+ if ( nHelpMode )
+ {
+ if ( pChild->IsInputEnabled() )
+ {
+ HelpEvent aHelpEvent( rMousePos, nHelpMode );
+ pSVData->maHelpData.mbRequestingHelp = TRUE;
+ pChild->RequestHelp( aHelpEvent );
+ pSVData->maHelpData.mbRequestingHelp = FALSE;
+ }
+ else if ( pSVData->maHelpData.mpHelpWin )
+ {
+ ImplDestroyHelpWindow( FALSE );
+ }
+ }
+ }
+}
+
+// -----------------------------------------------------------------------
+
+static void ImplSetMousePointer( Window* pChild )
+{
+ // Drag&Drop active?
+ DragManager* pDragManager = DragManager::GetDragManager();
+ ImplSVData* pSVData = ImplGetSVData();
+
+ if( pDragManager && pDragManager->isModifyPointer() )
+ pChild->mpFrame->SetPointer( pDragManager->GetDragPointer().GetStyle() );
+ else if ( pSVData->maHelpData.mbExtHelpMode )
+ pChild->mpFrame->SetPointer( POINTER_HELP );
+ else
+ pChild->mpFrame->SetPointer( pChild->ImplGetMousePointer() );
+}
+
+// -----------------------------------------------------------------------
+
+long ImplHandleMouseEvent( Window* pWindow, USHORT nSVEvent, BOOL bMouseLeave,
+ long nX, long nY, ULONG nMsgTime,
+ USHORT nCode, USHORT nMode )
+{
+ ImplSVData* pSVData = ImplGetSVData();
+ Point aMousePos( nX, nY );
+ Window* pChild;
+ long nRet;
+ USHORT nClicks;
+ USHORT nOldCode = pWindow->mpFrameData->mnMouseCode;
+
+ // we need a mousemove event, befor we get a mousebuttondown or a
+ // mousebuttonup event
+ if ( (nSVEvent == EVENT_MOUSEBUTTONDOWN) ||
+ (nSVEvent == EVENT_MOUSEBUTTONUP) )
+ {
+ if ( (nSVEvent == EVENT_MOUSEBUTTONUP) && pSVData->maHelpData.mbExtHelpMode )
+ Help::EndExtHelp();
+ if ( pSVData->maHelpData.mpHelpWin )
+ ImplDestroyHelpWindow();
+
+ if ( (pWindow->mpFrameData->mnLastMouseX != nX) ||
+ (pWindow->mpFrameData->mnLastMouseY != nY) )
+ {
+ ImplHandleMouseEvent( pWindow, EVENT_MOUSEMOVE, FALSE, nX, nY, nMsgTime, nCode, nMode );
+ }
+ }
+
+ // update frame data
+ pWindow->mpFrameData->mnLastMouseX = nX;
+ pWindow->mpFrameData->mnLastMouseY = nY;
+ pWindow->mpFrameData->mnMouseCode = nCode;
+ pWindow->mpFrameData->mnMouseMode = nMode & ~(MOUSE_SYNTHETIC | MOUSE_MODIFIERCHANGED);
+ if ( bMouseLeave )
+ {
+ pWindow->mpFrameData->mbMouseIn = FALSE;
+ if ( pSVData->maHelpData.mpHelpWin )
+ ImplDestroyHelpWindow();
+
+ // If Drag&Drop is active try to start System-Drag&Drop
+ DragManager* pDragManager = DragManager::GetDragManager();
+ if ( pDragManager )
+ {
+ if ( pWindow->mpFrameData->mpDragTimer )
+ {
+ delete pWindow->mpFrameData->mpDragTimer;
+ pWindow->mpFrameData->mpDragTimer = NULL;
+ }
+ pDragManager->AppWindowLeaved();
+ }
+ }
+ else
+ {
+ // Handle Drag&Drop if window is (re)entered
+ if ( !pWindow->mpFrameData->mbMouseIn )
+ {
+ // Drag&Drop active?
+ DragManager* pDragManager = DragManager::GetDragManager();
+
+ // HRO: Nur Escape rufen, wenn es unser eigenes Drag & Drop war
+ if ( pDragManager && pDragManager->bOwnDragDrop )
+ {
+ // break Drag&Drop, if mouse button is not pressed
+ if( !( nCode & MOUSE_LEFT ) )
+ pDragManager->Escape( pWindow );
+ }
+ }
+
+ pWindow->mpFrameData->mbMouseIn = TRUE;
+ }
+
+ DBG_ASSERT( !pSVData->maWinData.mpTrackWin ||
+ (pSVData->maWinData.mpTrackWin == pSVData->maWinData.mpCaptureWin),
+ "ImplHandleMouseEvent: TrackWin != CaptureWin" );
+
+ // AutoScrollMode
+ if ( pSVData->maWinData.mpAutoScrollWin && (nSVEvent == EVENT_MOUSEBUTTONDOWN) )
+ {
+ pSVData->maWinData.mpAutoScrollWin->EndAutoScroll();
+ return 1;
+ }
+
+ // find mouse window
+ if ( pSVData->maWinData.mpCaptureWin )
+ {
+ pChild = pSVData->maWinData.mpCaptureWin;
+
+ DBG_ASSERT( !bMouseLeave || (pWindow != pChild->mpFrameWindow),
+ "ImplHandleMouseEvent: MouseLeave is send and Mouse is captured" );
+ DBG_ASSERT( pWindow == pChild->mpFrameWindow,
+ "ImplHandleMouseEvent: mouse event is not sent to capture window" );
+
+ if ( bMouseLeave )
+ return 0;
+ }
+ else
+ {
+ if ( bMouseLeave )
+ pChild = NULL;
+ else
+ pChild = pWindow->ImplFindWindow( aMousePos );
+ }
+
+ // test this because mouse events are buffered in the remote version
+ // and size may not be in sync
+ if ( !pChild && !bMouseLeave )
+ return 0;
+
+ // Ein paar Test ausfuehren und Message abfangen oder Status umsetzen
+ if ( pChild )
+ {
+ // no mouse messages to system object windows
+#ifndef REMOTE_APPSERVER
+ if ( pChild->mpSysObj )
+ return 0;
+#endif
+
+ // no mouse messages to disabled windows
+ if ( !pChild->IsEnabled() || !pChild->IsInputEnabled() )
+ {
+ ImplHandleMouseFloatMode( pChild, aMousePos, nCode, nSVEvent, bMouseLeave );
+ if ( nSVEvent == EVENT_MOUSEMOVE )
+ ImplHandleMouseHelpRequest( pChild, aMousePos );
+
+ if ( nSVEvent == EVENT_MOUSEBUTTONDOWN )
+ {
+ Sound::Beep( SOUND_DISABLE, pChild );
+ return 1;
+ }
+ else
+ {
+ if ( nSVEvent == EVENT_MOUSEMOVE )
+ ImplSetMousePointer( pChild );
+ return 0;
+ }
+ }
+
+ // ExtTextInput-Modus beenden, wenn in das Fenster geklickt wird
+ if ( pChild->IsExtTextInput() )
+ {
+ if ( (nSVEvent == EVENT_MOUSEBUTTONDOWN) ||
+ (nSVEvent == EVENT_MOUSEBUTTONUP) )
+ pChild->EndExtTextInput( EXTTEXTINPUT_END_COMPLETE );
+ }
+ }
+
+ // determine mouse event data
+ if ( nSVEvent == EVENT_MOUSEMOVE )
+ {
+ // Testen, ob MouseMove an das gleiche Fenster geht und sich der
+ // Status nicht geaendert hat
+ if ( pChild )
+ {
+ Point aChildMousePos = pChild->ImplFrameToOutput( aMousePos );
+ if ( !bMouseLeave &&
+ (pChild == pWindow->mpFrameData->mpMouseMoveWin) &&
+ (aChildMousePos.X() == pWindow->mpFrameData->mnLastMouseWinX) &&
+ (aChildMousePos.Y() == pWindow->mpFrameData->mnLastMouseWinY) &&
+ (nOldCode == pWindow->mpFrameData->mnMouseCode) &&
+ !mbImplDragTimeoutHdl )
+ {
+ // Mouse-Pointer neu setzen, da er sich geaendet haben
+ // koennte, da ein Modus umgesetzt wurde
+ ImplSetMousePointer( pChild );
+ return 0;
+ }
+
+ pWindow->mpFrameData->mnLastMouseWinX = aChildMousePos.X();
+ pWindow->mpFrameData->mnLastMouseWinY = aChildMousePos.Y();
+ }
+
+ // mouse click
+ nClicks = pWindow->mpFrameData->mnClickCount;
+
+ // Gegebenenfalls den Start-Drag-Handler rufen.
+ // Achtung: Muss vor Move gerufen werden, da sonst bei schnellen
+ // Mausbewegungen die Applikationen in den Selektionszustand gehen.
+ Window* pMouseDownWin = pWindow->mpFrameData->mpMouseDownWin;
+ if ( pMouseDownWin )
+ {
+ // Testen, ob StartDrag-Modus uebereinstimmt. Wir vergleichen nur
+ // den Status der Maustasten, damit man mit Mod1 z.B. sofort
+ // in den Kopiermodus gehen kann.
+ const MouseSettings& rMSettings = pMouseDownWin->GetSettings().GetMouseSettings();
+ if ( (nCode & (MOUSE_LEFT | MOUSE_RIGHT | MOUSE_MIDDLE)) ==
+ (rMSettings.GetStartDragCode() & (MOUSE_LEFT | MOUSE_RIGHT | MOUSE_MIDDLE)) )
+ {
+ if ( !pMouseDownWin->mpFrameData->mbStartDragCalled )
+ {
+ long nDragW = rMSettings.GetStartDragWidth();
+ long nDragH = rMSettings.GetStartDragWidth();
+ long nMouseX = nX;
+ long nMouseY = nY;
+ if ( !(((nMouseX-nDragW) <= pMouseDownWin->mpFrameData->mnFirstMouseX) &&
+ ((nMouseX+nDragW) >= pMouseDownWin->mpFrameData->mnFirstMouseX)) ||
+ !(((nMouseY-nDragH) <= pMouseDownWin->mpFrameData->mnFirstMouseY) &&
+ ((nMouseY+nDragH) >= pMouseDownWin->mpFrameData->mnFirstMouseY)) )
+ {
+ pMouseDownWin->mpFrameData->mbStartDragCalled = TRUE;
+ Point aCmdMousePos( pMouseDownWin->mpFrameData->mnFirstMouseX,
+ pMouseDownWin->mpFrameData->mnFirstMouseY );
+ aCmdMousePos = pMouseDownWin->ImplFrameToOutput( aCmdMousePos );
+ CommandEvent aCEvt( aCmdMousePos, COMMAND_STARTDRAG, TRUE );
+ NotifyEvent aNCmdEvt( EVENT_COMMAND, pMouseDownWin, &aCEvt );
+ ImplDelData aDelData;
+ pMouseDownWin->ImplAddDel( &aDelData );
+ if ( !ImplCallPreNotify( aNCmdEvt ) )
+ pMouseDownWin->Command( aCEvt );
+ if ( aDelData.IsDelete() )
+ return 1;
+ pMouseDownWin->ImplRemoveDel( &aDelData );
+ }
+ }
+ }
+ else
+ pMouseDownWin->mpFrameData->mbStartDragCalled = TRUE;
+ }
+
+ // test for mouseleave and mouseenter
+ Window* pMouseMoveWin = pWindow->mpFrameData->mpMouseMoveWin;
+ if ( pChild != pMouseMoveWin )
+ {
+ if ( pMouseMoveWin )
+ {
+ Point aLeaveMousePos = pMouseMoveWin->ImplFrameToOutput( aMousePos );
+ MouseEvent aMLeaveEvt( aLeaveMousePos, nClicks, nMode | MOUSE_LEAVEWINDOW, nCode, nCode );
+ NotifyEvent aNLeaveEvt( EVENT_MOUSEMOVE, pMouseMoveWin, &aMLeaveEvt );
+ ImplDelData aDelData;
+ ImplDelData aDelData2;
+ pWindow->mpFrameData->mbInMouseMove = TRUE;
+ pMouseMoveWin->ImplAddDel( &aDelData );
+ // Durch MouseLeave kann auch dieses Fenster zerstoert
+ // werden
+ if ( pChild )
+ pChild->ImplAddDel( &aDelData2 );
+ if ( !ImplCallPreNotify( aNLeaveEvt ) )
+ {
+ DragManager* pDragManager = DragManager::GetDragManager();
+ if ( pDragManager )
+ pDragManager->MouseMove( aMLeaveEvt, pMouseMoveWin );
+ else
+ pMouseMoveWin->MouseMove( aMLeaveEvt );
+ }
+
+ pWindow->mpFrameData->mpMouseMoveWin = NULL;
+ pWindow->mpFrameData->mbInMouseMove = FALSE;
+
+ if ( pChild )
+ {
+ if ( aDelData2.IsDelete() )
+ pChild = NULL;
+ else
+ pChild->ImplRemoveDel( &aDelData2 );
+ }
+ if ( aDelData.IsDelete() )
+ return 1;
+ pMouseMoveWin->ImplRemoveDel( &aDelData );
+ }
+
+ nMode |= MOUSE_ENTERWINDOW;
+ }
+ pWindow->mpFrameData->mpMouseMoveWin = pChild;
+
+ // MouseLeave
+ if ( !pChild )
+ return 0;
+ }
+ else
+ {
+ // mouse click
+ if ( nSVEvent == EVENT_MOUSEBUTTONDOWN )
+ {
+ const MouseSettings& rMSettings = pChild->GetSettings().GetMouseSettings();
+ ULONG nDblClkTime = rMSettings.GetDoubleClickTime();
+ long nDblClkW = rMSettings.GetDoubleClickWidth();
+ long nDblClkH = rMSettings.GetDoubleClickHeight();
+ long nMouseX = nX;
+ long nMouseY = nY;
+
+ if ( (pChild == pChild->mpFrameData->mpMouseDownWin) &&
+ (nCode == pChild->mpFrameData->mnFirstMouseCode) &&
+ ((nMsgTime-pChild->mpFrameData->mnMouseDownTime) < nDblClkTime) &&
+ ((nMouseX-nDblClkW) <= pChild->mpFrameData->mnFirstMouseX) &&
+ ((nMouseX+nDblClkW) >= pChild->mpFrameData->mnFirstMouseX) &&
+ ((nMouseY-nDblClkH) <= pChild->mpFrameData->mnFirstMouseY) &&
+ ((nMouseY+nDblClkH) >= pChild->mpFrameData->mnFirstMouseY) )
+ {
+ pChild->mpFrameData->mnClickCount++;
+ pChild->mpFrameData->mbStartDragCalled = TRUE;
+ }
+ else
+ {
+ pChild->mpFrameData->mpMouseDownWin = pChild;
+ pChild->mpFrameData->mnClickCount = 1;
+ pChild->mpFrameData->mnFirstMouseX = nMouseX;
+ pChild->mpFrameData->mnFirstMouseY = nMouseY;
+ pChild->mpFrameData->mnFirstMouseCode = nCode;
+ pChild->mpFrameData->mbStartDragCalled = !((nCode & (MOUSE_LEFT | MOUSE_RIGHT | MOUSE_MIDDLE)) ==
+ (rMSettings.GetStartDragCode() & (MOUSE_LEFT | MOUSE_RIGHT | MOUSE_MIDDLE)));
+ }
+ pChild->mpFrameData->mnMouseDownTime = nMsgTime;
+ }
+ nClicks = pChild->mpFrameData->mnClickCount;
+
+ pSVData->maAppData.mnLastInputTime = Time::GetSystemTicks();
+ }
+
+ DBG_ASSERT( pChild, "ImplHandleMouseEvent: pChild == NULL" );
+
+ // create mouse event
+ Point aChildPos = pChild->ImplFrameToOutput( aMousePos );
+ MouseEvent aMEvt( aChildPos, nClicks, nMode, nCode, nCode );
+
+ // tracking window gets the mouse events
+ BOOL bTracking = FALSE;
+ if ( pSVData->maWinData.mpTrackWin )
+ {
+ pChild = pSVData->maWinData.mpTrackWin;
+ bTracking = TRUE;
+ }
+
+ // handle FloatingMode
+ if ( !pSVData->maWinData.mpTrackWin && pSVData->maWinData.mpFirstFloat )
+ {
+ ImplDelData aDelData;
+ pChild->ImplAddDel( &aDelData );
+ if ( ImplHandleMouseFloatMode( pChild, aMousePos, nCode, nSVEvent, bMouseLeave ) )
+ {
+ if ( !aDelData.IsDelete() )
+ {
+ pChild->ImplRemoveDel( &aDelData );
+ pChild->mpFrameData->mbStartDragCalled = TRUE;
+ }
+ return 1;
+ }
+ else
+ pChild->ImplRemoveDel( &aDelData );
+ }
+
+ // call handler
+ BOOL bDrag = FALSE;
+ BOOL bCallHelpRequest = TRUE;
+ DBG_ASSERT( pChild, "ImplHandleMouseEvent: pChild is NULL" );
+
+ ImplDelData aDelData;
+ NotifyEvent aNEvt( nSVEvent, pChild, &aMEvt );
+ pChild->ImplAddDel( &aDelData );
+ if ( nSVEvent == EVENT_MOUSEMOVE )
+ pChild->mpFrameData->mbInMouseMove = TRUE;
+ // D&D im Gange?
+ DragManager* pDragManager = DragManager::GetDragManager();
+ if ( pDragManager )
+ {
+ bDrag = TRUE;
+ nRet = 1;
+ if ( nSVEvent == EVENT_MOUSEMOVE )
+ {
+ if ( !pChild->mpFrameData->mpDragTimer )
+ pChild->mpFrameData->mpDragTimer = new ImplDragTimer( pChild->ImplGetFrameWindow() );
+ pDragManager->MouseMove( aMEvt, pChild );
+ }
+ else if ( nSVEvent == EVENT_MOUSEBUTTONUP )
+ {
+ pChild->ImplGenerateMouseMove();
+ pDragManager->ButtonUp( aMEvt, pChild );
+ }
+ }
+ else
+ {
+ // Fenster bei Klick nach vorne bringen
+ if ( nSVEvent == EVENT_MOUSEBUTTONDOWN )
+ {
+ pChild->ToTop();
+ if ( aDelData.IsDelete() )
+ return 1;
+ }
+
+ if ( ImplCallPreNotify( aNEvt ) || aDelData.IsDelete() )
+ nRet = 1;
+ else
+ {
+ nRet = 0;
+ if ( nSVEvent == EVENT_MOUSEMOVE )
+ {
+ if ( bTracking )
+ {
+ TrackingEvent aTEvt( aMEvt );
+ pChild->Tracking( aTEvt );
+ if ( !aDelData.IsDelete() )
+ {
+ // When ScrollRepeat, we restart the timer
+ if ( pSVData->maWinData.mpTrackTimer &&
+ (pSVData->maWinData.mnTrackFlags & STARTTRACK_SCROLLREPEAT) )
+ pSVData->maWinData.mpTrackTimer->Start();
+ }
+ bCallHelpRequest = FALSE;
+ nRet = 1;
+ }
+ else
+ {
+ // Auto-ToTop
+ if ( !pSVData->maWinData.mpCaptureWin &&
+ (pChild->GetSettings().GetMouseSettings().GetOptions() & MOUSE_OPTION_AUTOFOCUS) )
+ pChild->ToTop( TOTOP_NOGRABFOCUS );
+
+ // Wenn Hilfe-Fenster im MouseMove angezeigt/gehidet wird,
+ // wird danach nicht mehr der HelpRequest-Handler gerufen
+ Window* pOldHelpTextWin = pSVData->maHelpData.mpHelpWin;
+ pChild->mbMouseMove = FALSE;
+ pChild->MouseMove( aMEvt );
+ if ( pOldHelpTextWin != pSVData->maHelpData.mpHelpWin )
+ bCallHelpRequest = FALSE;
+ }
+ }
+ else if ( nSVEvent == EVENT_MOUSEBUTTONDOWN )
+ {
+ if ( bTracking &&
+ !(pSVData->maWinData.mnTrackFlags & STARTTRACK_MOUSEBUTTONDOWN) )
+ nRet = 1;
+ else
+ {
+ pChild->mbMouseButtonDown = FALSE;
+ pChild->MouseButtonDown( aMEvt );
+ }
+ }
+ else
+ {
+ if ( bTracking )
+ {
+ pChild->EndTracking();
+ nRet = 1;
+ }
+ else
+ {
+ pChild->mbMouseButtonUp = FALSE;
+ pChild->MouseButtonUp( aMEvt );
+ }
+ }
+ }
+ }
+
+ if ( aDelData.IsDelete() )
+ return 1;
+
+ if ( nSVEvent == EVENT_MOUSEMOVE )
+ pChild->mpFrameData->mbInMouseMove = FALSE;
+
+ if ( nSVEvent == EVENT_MOUSEMOVE )
+ {
+ if ( bCallHelpRequest )
+ ImplHandleMouseHelpRequest( pChild, pChild->OutputToScreenPixel( aMEvt.GetPosPixel() ) );
+ nRet = 1;
+ }
+ else if ( !nRet )
+ {
+ if ( nSVEvent == EVENT_MOUSEBUTTONDOWN )
+ {
+ if ( !pChild->mbMouseButtonDown )
+ nRet = 1;
+ }
+ else
+ {
+ if ( !pChild->mbMouseButtonUp )
+ nRet = 1;
+ }
+ }
+
+ pChild->ImplRemoveDel( &aDelData );
+
+ // ContextMenu
+ if ( !bDrag && ((nSVEvent == EVENT_MOUSEBUTTONDOWN) || (nSVEvent == EVENT_MOUSEBUTTONUP)) )
+ {
+ // StartAutoScrollMode-Command-Event
+ if ( /*(nRet == 0) &&*/ (nClicks == 1) && (nSVEvent == EVENT_MOUSEBUTTONDOWN) &&
+ (nCode == MOUSE_MIDDLE) )
+ {
+ BOOL bPreNotify;
+ CommandEvent aCEvt( aChildPos, COMMAND_STARTAUTOSCROLL, TRUE );
+ NotifyEvent aNCmdEvt( EVENT_COMMAND, pChild, &aCEvt );
+ ImplDelData aDelData;
+ pChild->ImplAddDel( &aDelData );
+ if ( !ImplCallPreNotify( aNCmdEvt ) && !aDelData.IsDelete() )
+ {
+ bPreNotify = FALSE;
+
+ pChild->mbCommand = FALSE;
+ pChild->Command( aCEvt );
+ }
+ else
+ bPreNotify = TRUE;
+ if ( aDelData.IsDelete() )
+ return 1;
+ pChild->ImplRemoveDel( &aDelData );
+ if ( !bPreNotify && pChild->mbCommand )
+ nRet = 0;
+ else
+ nRet = 1;
+ }
+ else
+ {
+ const MouseSettings& rMSettings = pChild->GetSettings().GetMouseSettings();
+ if ( (nCode == rMSettings.GetContextMenuCode()) &&
+ (nClicks == rMSettings.GetContextMenuClicks()) )
+ {
+ BOOL bContextMenu;
+ if ( rMSettings.GetContextMenuDown() )
+ bContextMenu = (nSVEvent == EVENT_MOUSEBUTTONDOWN);
+ else
+ bContextMenu = (nSVEvent == EVENT_MOUSEBUTTONUP);
+ if ( bContextMenu )
+ {
+ BOOL bPreNotify;
+ CommandEvent aCEvt( aChildPos, COMMAND_CONTEXTMENU, TRUE );
+ NotifyEvent aNCmdEvt( EVENT_COMMAND, pChild, &aCEvt );
+ ImplDelData aDelData;
+ pChild->ImplAddDel( &aDelData );
+ if ( !ImplCallPreNotify( aNCmdEvt ) && !aDelData.IsDelete() )
+ {
+ bPreNotify = FALSE;
+
+ pChild->mbCommand = FALSE;
+ pChild->Command( aCEvt );
+ }
+ else
+ bPreNotify = TRUE;
+ if ( aDelData.IsDelete() )
+ return 1;
+ pChild->ImplRemoveDel( &aDelData );
+ if ( !bPreNotify && pChild->mbCommand )
+ nRet = 0;
+ else
+ nRet = 1;
+ }
+ }
+ }
+ }
+
+ // set new mouse pointer
+ if ( (nSVEvent == EVENT_MOUSEMOVE) && !bMouseLeave )
+ ImplSetMousePointer( pChild );
+
+ return nRet;
+}
+
+// -----------------------------------------------------------------------
+
+static Window* ImplGetKeyInputWindow( Window* pWindow )
+{
+ ImplSVData* pSVData = ImplGetSVData();
+
+ // determine last input time
+ pSVData->maAppData.mnLastInputTime = Time::GetSystemTicks();
+
+ // find window
+ Window* pChild = pWindow->mpFrameData->mpFocusWin;
+
+ // Nur KeyInput an das Focus-Window auswerten
+ if ( !pChild || (pChild != pSVData->maWinData.mpFocusWin) )
+ return 0;
+ DBG_ASSERT( pChild == pSVData->maWinData.mpFocusWin,
+ "ImplHandleKey: Keyboard-Input is sent to the wrong frame" );
+
+ // no keyinput to disabled windows
+ if ( !pChild->IsEnabled() || !pChild->IsInputEnabled() )
+ return 0;
+
+ return pChild;
+}
+
+// -----------------------------------------------------------------------
+
+static long ImplHandleKey( Window* pWindow, USHORT nSVEvent,
+ USHORT nKeyCode, USHORT nCharCode, USHORT nRepeat )
+{
+ ImplSVData* pSVData = ImplGetSVData();
+ KeyCode aKeyCode( nKeyCode, nKeyCode );
+ USHORT nCode = aKeyCode.GetCode();
+
+ // determine last input time
+ pSVData->maAppData.mnLastInputTime = Time::GetSystemTicks();
+
+ // handle tracking window
+ if ( nSVEvent == EVENT_KEYINPUT )
+ {
+#ifdef DBG_UTIL
+#ifdef REMOTE_APPSERVER
+ if ( aKeyCode.IsShift() && aKeyCode.IsMod2() && (aKeyCode.GetCode() == KEY_D) )
+#else
+ if ( aKeyCode.IsShift() && aKeyCode.IsMod1() && (aKeyCode.GetCode() == KEY_D) )
+#endif
+ {
+ DBGGUI_START();
+ return 1;
+ }
+#endif
+
+ if ( pSVData->maHelpData.mbExtHelpMode )
+ {
+ Help::EndExtHelp();
+ if ( nCode == KEY_ESCAPE )
+ return 1;
+ }
+ if ( pSVData->maHelpData.mpHelpWin )
+ ImplDestroyHelpWindow();
+
+ // AutoScrollMode
+ if ( pSVData->maWinData.mpAutoScrollWin )
+ {
+ pSVData->maWinData.mpAutoScrollWin->EndAutoScroll();
+ if ( nCode == KEY_ESCAPE )
+ return 1;
+ }
+
+ // D&D im Gange und Escape?
+ if ( nCode == KEY_ESCAPE )
+ {
+ DragManager* pDragManager = DragManager::GetDragManager();
+ if ( pDragManager )
+ {
+ // Ist pWindow immer das TargetWindow?
+ // Nicht unbedingt. Aktuelles TargetWindow im DragManager merken?
+ pWindow->ImplGenerateMouseMove();
+ pDragManager->Escape( pWindow );
+ return 1;
+ }
+ }
+
+ if ( pSVData->maWinData.mpTrackWin )
+ {
+ USHORT nCode = aKeyCode.GetCode();
+
+ if ( (nCode == KEY_ESCAPE) && !(pSVData->maWinData.mnTrackFlags & STARTTRACK_NOKEYCANCEL) )
+ {
+ pSVData->maWinData.mpTrackWin->EndTracking( ENDTRACK_CANCEL | ENDTRACK_KEY );
+ if ( pSVData->maWinData.mpFirstFloat )
+ {
+ FloatingWindow* pLastLevelFloat = pSVData->maWinData.mpFirstFloat->ImplFindLastLevelFloat();
+ if ( !(pLastLevelFloat->GetPopupModeFlags() & FLOATWIN_POPUPMODE_NOKEYCLOSE) )
+ {
+ USHORT nCode = aKeyCode.GetCode();
+
+ if ( nCode == KEY_ESCAPE )
+ pLastLevelFloat->EndPopupMode( FLOATWIN_POPUPMODEEND_CANCEL | FLOATWIN_POPUPMODEEND_CLOSEALL );
+ }
+ }
+ return 1;
+ }
+ else if ( nCode == KEY_RETURN )
+ {
+ pSVData->maWinData.mpTrackWin->EndTracking( ENDTRACK_KEY );
+ return 1;
+ }
+ else if ( !(pSVData->maWinData.mnTrackFlags & STARTTRACK_KEYINPUT) )
+ return 1;
+ }
+
+ // handle FloatingMode
+ if ( pSVData->maWinData.mpFirstFloat )
+ {
+ FloatingWindow* pLastLevelFloat = pSVData->maWinData.mpFirstFloat->ImplFindLastLevelFloat();
+ if ( !(pLastLevelFloat->GetPopupModeFlags() & FLOATWIN_POPUPMODE_NOKEYCLOSE) )
+ {
+ USHORT nCode = aKeyCode.GetCode();
+
+ if ( nCode == KEY_ESCAPE )
+ {
+ pLastLevelFloat->EndPopupMode( FLOATWIN_POPUPMODEEND_CANCEL | FLOATWIN_POPUPMODEEND_CLOSEALL );
+ return 1;
+ }
+ }
+ }
+
+ // test for accel
+ if ( pSVData->maAppData.mpAccelMgr )
+ {
+ if ( pSVData->maAppData.mpAccelMgr->IsAccelKey( aKeyCode, nRepeat ) )
+ return 1;
+ }
+ }
+
+ // find window
+ Window* pChild = pWindow->mpFrameData->mpFocusWin;
+
+ // Nur KeyInput an das Focus-Window auswerten
+ if ( !pChild || (pChild != pSVData->maWinData.mpFocusWin) )
+ return 0;
+ DBG_ASSERT( pChild == pSVData->maWinData.mpFocusWin,
+ "ImplHandleKey: Keyboard-Input is sent to the wrong frame" );
+
+ // no keyinput to disabled windows
+ if ( !pChild->IsEnabled() || !pChild->IsInputEnabled() )
+ return 0;
+
+ // call handler
+ ImplDelData aDelData;
+ KeyEvent aKEvt( (xub_Unicode)nCharCode, aKeyCode, nRepeat );
+ NotifyEvent aNEvt( nSVEvent, pChild, &aKEvt );
+ BOOL bPreNotify;
+ long nRet = 1;
+
+ pChild->ImplAddDel( &aDelData );
+ if ( !ImplCallPreNotify( aNEvt ) && !aDelData.IsDelete() )
+ {
+ bPreNotify = FALSE;
+
+ if ( nSVEvent == EVENT_KEYINPUT )
+ {
+ pChild->mbKeyInput = FALSE;
+ pChild->KeyInput( aKEvt );
+ }
+ else
+ {
+ pChild->mbKeyUp = FALSE;
+ pChild->KeyUp( aKEvt );
+ }
+ }
+ else
+ bPreNotify = TRUE;
+
+ if ( aDelData.IsDelete() )
+ return 1;
+
+ pChild->ImplRemoveDel( &aDelData );
+
+ if ( nSVEvent == EVENT_KEYINPUT )
+ {
+ if ( !bPreNotify && pChild->mbKeyInput )
+ {
+ USHORT nCode = aKeyCode.GetCode();
+
+ // ContextMenu
+ if ( (nCode == KEY_CONTEXTMENU) || ((nCode == KEY_F10) && aKeyCode.IsShift()) )
+ {
+ CommandEvent aCEvt( pChild->GetPointerPosPixel(), COMMAND_CONTEXTMENU, FALSE );
+ NotifyEvent aNCmdEvt( EVENT_COMMAND, pChild, &aCEvt );
+ ImplDelData aDelData;
+ pChild->ImplAddDel( &aDelData );
+ if ( !ImplCallPreNotify( aNCmdEvt ) && !aDelData.IsDelete() )
+ {
+ bPreNotify = FALSE;
+
+ pChild->mbCommand = FALSE;
+ pChild->Command( aCEvt );
+ }
+ else
+ bPreNotify = TRUE;
+ if ( aDelData.IsDelete() )
+ return 1;
+ pChild->ImplRemoveDel( &aDelData );
+ if ( !bPreNotify && pChild->mbCommand )
+ nRet = 0;
+ }
+ else if ( (nCode == KEY_F1) || (nCode == KEY_HELP) )
+ {
+ if ( !aKeyCode.GetModifier() )
+ {
+ if ( pSVData->maHelpData.mbContextHelp )
+ {
+ Point aMousePos = pChild->OutputToScreenPixel( pChild->GetPointerPosPixel() );
+ HelpEvent aHelpEvent( aMousePos, HELPMODE_CONTEXT );
+ pChild->RequestHelp( aHelpEvent );
+ }
+ else
+ nRet = 0;
+ }
+ else if ( aKeyCode.IsShift() )
+ {
+ if ( pSVData->maHelpData.mbExtHelp )
+ Help::StartExtHelp();
+ else
+ nRet = 0;
+ }
+ }
+ else
+ {
+ if ( ImplCallHotKey( aKeyCode ) )
+ nRet = 1;
+ else
+ nRet = 0;
+ }
+ }
+ }
+ else
+ {
+ if ( !bPreNotify && pChild->mbKeyUp )
+ nRet = 0;
+ }
+
+ return nRet;
+}
+
+// -----------------------------------------------------------------------
+
+static long ImplCallExtTextInput( Window* pChild, USHORT nEvt,
+ void* pData = NULL )
+{
+ CommandEvent aCEvt( pChild->GetPointerPosPixel(), nEvt, FALSE, pData );
+ NotifyEvent aNCmdEvt( EVENT_COMMAND, pChild, &aCEvt );
+ ImplDelData aDelData;
+ BOOL bPreNotify;
+ pChild->ImplAddDel( &aDelData );
+ if ( !ImplCallPreNotify( aNCmdEvt ) && !aDelData.IsDelete() )
+ {
+ bPreNotify = FALSE;
+
+ pChild->mbCommand = FALSE;
+ pChild->Command( aCEvt );
+ }
+ else
+ bPreNotify = TRUE;
+ if ( aDelData.IsDelete() )
+ return FALSE;
+ pChild->ImplRemoveDel( &aDelData );
+ if ( !bPreNotify && pChild->mbCommand )
+ return TRUE;
+
+ return FALSE;
+}
+
+// -----------------------------------------------------------------------
+
+static long ImplHandleStartExtTextInput( Window* pWindow )
+{
+ Window* pChild = ImplGetKeyInputWindow( pWindow );
+ long nRet = 0;
+ if ( pChild )
+ {
+ pChild->mbExtTextInput = TRUE;
+ pChild->ImplGetWinData()->mnExtOldTextLen = 0;
+ nRet = ImplCallExtTextInput( pChild, COMMAND_STARTEXTTEXTINPUT );
+ }
+ return nRet;
+}
+
+// -----------------------------------------------------------------------
+
+static long ImplHandleEndExtTextInput( Window* pWindow )
+{
+ Window* pChild = ImplGetKeyInputWindow( pWindow );
+ long nRet = 0;
+ if ( pChild )
+ {
+ pChild->mbExtTextInput = FALSE;
+ pChild->ImplGetWinData()->mnExtOldTextLen = 0;
+ nRet = ImplCallExtTextInput( pChild, COMMAND_ENDEXTTEXTINPUT );
+ }
+ return nRet;
+}
+
+// -----------------------------------------------------------------------
+
+static long ImplHandleExtTextInput( Window* pWindow, ULONG nTime,
+ const XubString& rText,
+ const USHORT* pTextAttr,
+ ULONG nCursorPos, BOOL bCursorVisible,
+ ULONG nDeltaStart, BOOL bOnlyCursor )
+{
+ Window* pChild = ImplGetKeyInputWindow( pWindow );
+ long nRet = 0;
+ if ( pChild )
+ {
+ BOOL bSmartMode = FALSE;
+ if ( !pChild->mbExtTextInput )
+ {
+ bSmartMode = TRUE;
+ ImplHandleStartExtTextInput( pWindow );
+ }
+ CommandExtTextInputData aData( rText, pTextAttr,
+ (USHORT)nCursorPos, bCursorVisible,
+ (USHORT)nDeltaStart,
+ pChild->ImplGetWinData()->mnExtOldTextLen,
+ bOnlyCursor );
+ pChild->ImplGetWinData()->mnExtOldTextLen = rText.Len();
+ nRet = ImplCallExtTextInput( pChild, COMMAND_EXTTEXTINPUT, &aData );
+ if ( bSmartMode )
+ {
+ // TextAttribute muessen zum Schluss restauriert ausgegeben werden
+ if ( pTextAttr )
+ {
+ ImplHandleExtTextInput( pWindow, nTime, rText, NULL,
+ nCursorPos, bCursorVisible,
+ nDeltaStart, bOnlyCursor );
+ }
+ ImplHandleEndExtTextInput( pWindow );
+ }
+ }
+ return nRet;
+}
+
+// -----------------------------------------------------------------------
+
+static Window* ImplHandleExtTextInputPos( Window* pWindow, ULONG nFirst,
+ ULONG nChars )
+{
+ Window* pChild = ImplGetKeyInputWindow( pWindow );
+ if ( pChild )
+ {
+ CommandExtTextInputPosData aData( (USHORT)nFirst, (USHORT)nChars, EXTTEXTINPUTPOS_NOSHOWPOS );
+ ImplCallExtTextInput( pChild, COMMAND_EXTTEXTINPUTPOS, &aData );
+ }
+ return pChild;
+}
+
+// -----------------------------------------------------------------------
+
+static long ImplHandleInputContextChange( Window* pWindow )
+{
+ return 0;
+}
+
+// -----------------------------------------------------------------------
+
+static void ImplHandleICursorPos( Window* pWindow, long& rX, long& rY,
+ long& rWidth, long& rHeight )
+{
+ rX = 0;
+ rY = 0;
+ rWidth = 0;
+ rHeight = 0;
+
+ Window* pChild = ImplGetKeyInputWindow( pWindow );
+ if ( pChild )
+ {
+ ImplCallExtTextInput( pChild, COMMAND_CURSORPOS );
+ Cursor* pCursor = pChild->GetCursor();
+ if ( pCursor )
+ {
+ Point aPos = pChild->ImplLogicToDevicePixel( pCursor->GetPos() );
+ rX = aPos.X();
+ rY = aPos.Y();
+ Size aSize = pChild->LogicToPixel( pCursor->GetSize() );
+ rWidth = aSize.Width();
+ rHeight = aSize.Height();
+ if ( !aSize.Width() )
+ rWidth = pChild->GetSettings().GetStyleSettings().GetCursorSize();
+ }
+ }
+}
+
+// -----------------------------------------------------------------------
+
+static BOOL ImplCallWheelCommand( Window* pWindow, const Point& rPos,
+ const CommandWheelData* pWheelData )
+{
+ Point aCmdMousePos = pWindow->ImplFrameToOutput( rPos );
+ CommandEvent aCEvt( aCmdMousePos, COMMAND_WHEEL, TRUE, pWheelData );
+ NotifyEvent aNCmdEvt( EVENT_COMMAND, pWindow, &aCEvt );
+ ImplDelData aDelData;
+ BOOL bPreNotify;
+ pWindow->ImplAddDel( &aDelData );
+ if ( !ImplCallPreNotify( aNCmdEvt ) && !aDelData.IsDelete() )
+ {
+ bPreNotify = FALSE;
+
+ pWindow->mbCommand = FALSE;
+ pWindow->Command( aCEvt );
+ }
+ else
+ bPreNotify = TRUE;
+ if ( aDelData.IsDelete() )
+ return FALSE;
+ pWindow->ImplRemoveDel( &aDelData );
+ if ( !bPreNotify && pWindow->mbCommand )
+ return TRUE;
+ return FALSE;
+}
+
+// -----------------------------------------------------------------------
+
+long ImplHandleWheelEvent( Window* pWindow,
+ long nX, long nY, ULONG nMsgTime,
+ long nDelta, long nNotchDelta,
+ ULONG nScrollLines, USHORT nCode, BOOL bHorz )
+{
+ ImplSVData* pSVData = ImplGetSVData();
+ USHORT nMode;
+
+ if ( pSVData->maHelpData.mpHelpWin )
+ ImplDestroyHelpWindow();
+
+ if ( nCode & KEY_MOD1 )
+ nMode = COMMAND_WHEEL_ZOOM;
+ else if ( nCode & KEY_SHIFT )
+ nMode = COMMAND_WHEEL_DATAZOOM;
+ else
+ nMode = COMMAND_WHEEL_SCROLL;
+
+ Point aMousePos( nX, nY );
+ CommandWheelData aWheelData( nDelta, nNotchDelta, nScrollLines, nMode, nCode, bHorz );
+ BOOL bRet = TRUE;
+
+ // Zuerst rufen wir den Command an dem Fenster, worueber die Maus steht
+ Window* pMouseWindow = pWindow->ImplFindWindow( aMousePos );
+ if ( pMouseWindow &&
+ pMouseWindow->IsEnabled() && pMouseWindow->IsInputEnabled() )
+ bRet = ImplCallWheelCommand( pMouseWindow, aMousePos, &aWheelData );
+
+ // Wenn das Fenster ueber dem die Maus steht, den Event nicht
+ // verarbeitet hat, rufen wir Command an dem Focus-Window
+ if ( bRet )
+ {
+ Window* pFocusWindow = pWindow->mpFrameData->mpFocusWin;
+ if ( pFocusWindow && (pFocusWindow != pMouseWindow) &&
+ (pFocusWindow == pSVData->maWinData.mpFocusWin) )
+ {
+ // no wheel-messages to disabled windows
+ if ( pFocusWindow->IsEnabled() && pFocusWindow->IsInputEnabled() )
+ bRet = ImplCallWheelCommand( pFocusWindow, aMousePos, &aWheelData );
+ }
+ }
+
+ return !bRet;
+}
+
+// -----------------------------------------------------------------------
+
+static void ImplHandlePaint( Window* pWindow, const Rectangle& rBoundRect )
+{
+ // Bei Paints vom System, auch Hintergrund-Sicherung aufgeben
+ Window* pSaveBackWin = pWindow->mpFrameData->mpFirstBackWin;
+ while ( pSaveBackWin )
+ {
+ Window* pNext = pSaveBackWin->mpOverlapData->mpNextBackWin;
+ Rectangle aRect( Point( pSaveBackWin->mnOutOffX, pSaveBackWin->mnOutOffY ),
+ Size( pSaveBackWin->mnOutWidth, pSaveBackWin->mnOutHeight ) );
+ if ( aRect.IsOver( rBoundRect ) )
+ pSaveBackWin->ImplDeleteOverlapBackground();
+ pSaveBackWin = pNext;
+ }
+
+ // Paint fuer alle Fenster ausloesen, die im neu zu malenden Bereich
+ // liegen
+ Region aRegion( rBoundRect );
+ pWindow->ImplInvalidateOverlapFrameRegion( aRegion );
+}
+
+// -----------------------------------------------------------------------
+
+void ImplHandleResize( Window* pWindow, long nNewWidth, long nNewHeight )
+{
+ if ( (nNewWidth > 0) && (nNewHeight > 0) ||
+ pWindow->ImplGetWindow()->mbAllResize )
+ {
+ if ( (nNewWidth != pWindow->mnOutWidth) || (nNewHeight != pWindow->mnOutHeight) )
+ {
+ pWindow->mnOutWidth = nNewWidth;
+ pWindow->mnOutHeight = nNewHeight;
+ pWindow->mbWaitSystemResize = FALSE;
+ if ( pWindow->IsReallyVisible() )
+ pWindow->ImplSetClipFlag();
+ if ( pWindow->IsVisible() || pWindow->ImplGetWindow()->mbAllResize )
+ pWindow->Resize();
+ else
+ pWindow->mbCallResize = TRUE;
+ }
+ }
+
+ pWindow->mpFrameData->mbNeedSysWindow = (nNewWidth < IMPL_MIN_NEEDSYSWIN) ||
+ (nNewHeight < IMPL_MIN_NEEDSYSWIN);
+ pWindow->mpFrameData->mbMinimized = (nNewWidth <= 0) || (nNewHeight <= 0);
+}
+
+// -----------------------------------------------------------------------
+
+static void ImplActivateFloatingWindows( Window* pWindow, BOOL bActive )
+{
+ // Zuerst alle ueberlappenden Fenster ueberpruefen
+ Window* pTempWindow = pWindow->mpFirstOverlap;
+ while ( pTempWindow )
+ {
+ if ( !pTempWindow->GetActivateMode() )
+ {
+ if ( (pTempWindow->GetType() == WINDOW_BORDERWINDOW) &&
+ (pTempWindow->ImplGetWindow()->GetType() == WINDOW_FLOATINGWINDOW) )
+ ((ImplBorderWindow*)pTempWindow)->SetDisplayActive( bActive );
+ }
+
+ ImplActivateFloatingWindows( pTempWindow, bActive );
+ pTempWindow = pTempWindow->mpNext;
+ }
+}
+
+// -----------------------------------------------------------------------
+
+IMPL_LINK( Window, ImplAsyncFocusHdl, void*, EMPTYARG )
+{
+ mpFrameData->mnFocusId = 0;
+
+ // Wenn Status erhalten geblieben ist, weil wir den Focus in der
+ // zwischenzeit schon wiederbekommen haben, brauchen wir auch
+ // nichts machen
+ BOOL bHasFocus = mpFrameData->mbHasFocus || mpFrameData->mbSysObjFocus;
+
+ // Dann die zeitverzoegerten Funktionen ausfuehren
+ if ( bHasFocus )
+ {
+ // Alle FloatingFenster deaktiv zeichnen
+ if ( mpFrameData->mbStartFocusState != bHasFocus )
+ ImplActivateFloatingWindows( this, bHasFocus );
+
+ if ( mpFrameData->mpFocusWin )
+ {
+ if ( mpFrameData->mpFocusWin->IsEnabled() )
+ mpFrameData->mpFocusWin->GrabFocus();
+ else
+ mpFrameData->mpFocusWin->ImplGetFirstOverlapWindow()->GrabFocus();
+ }
+ else
+ GrabFocus();
+ }
+ else
+ {
+ Window* pFocusWin = mpFrameData->mpFocusWin;
+ if ( pFocusWin )
+ {
+ ImplSVData* pSVData = ImplGetSVData();
+
+ if ( pSVData->maWinData.mpFocusWin == pFocusWin )
+ {
+ // FocusWindow umsetzen
+ Window* pOverlapWindow = pFocusWin->ImplGetFirstOverlapWindow();
+ pOverlapWindow->mpLastFocusWindow = pFocusWin;
+ pSVData->maWinData.mpFocusWin = NULL;
+
+ if ( pFocusWin->mpCursor )
+ pFocusWin->mpCursor->ImplHide();
+
+ // Deaktivate rufen
+ Window* pOldFocusWindow = pFocusWin;
+ if ( pOldFocusWindow )
+ {
+ Window* pOldOverlapWindow = pOldFocusWindow->ImplGetFirstOverlapWindow();
+ Window* pOldRealWindow = pOldOverlapWindow->ImplGetWindow();
+
+ pOldOverlapWindow->mbActive = FALSE;
+ pOldOverlapWindow->Deactivate();
+ if ( pOldRealWindow != pOldOverlapWindow )
+ {
+ pOldRealWindow->mbActive = FALSE;
+ pOldRealWindow->Deactivate();
+ }
+ }
+
+ // TrackingMode is ended in ImplHandleLoseFocus
+ pFocusWin->EndExtTextInput( EXTTEXTINPUT_END_COMPLETE );
+ NotifyEvent aNEvt( EVENT_LOSEFOCUS, pFocusWin );
+ if ( !ImplCallPreNotify( aNEvt ) )
+ pFocusWin->LoseFocus();
+ pFocusWin->ImplCallDeactivateListeners( NULL );
+ GetpApp()->FocusChanged();
+ }
+ }
+
+ // Alle FloatingFenster deaktiv zeichnen
+ if ( mpFrameData->mbStartFocusState != bHasFocus )
+ ImplActivateFloatingWindows( this, bHasFocus );
+ }
+
+ return 0;
+}
+
+// -----------------------------------------------------------------------
+
+static void ImplHandleGetFocus( Window* pWindow )
+{
+ ImplSVData* pSVData = ImplGetSVData();
+
+ InvalidateSystemClipboard();
+
+ pWindow->mpFrameData->mbHasFocus = TRUE;
+
+ // Focus-Events zeitverzoegert ausfuehren, damit bei SystemChildFenstern
+ // nicht alles flackert, wenn diese den Focus bekommen
+ if ( !pWindow->mpFrameData->mnFocusId )
+ {
+ pWindow->mpFrameData->mbStartFocusState = !pWindow->mpFrameData->mbHasFocus;
+ Application::PostUserEvent( pWindow->mpFrameData->mnFocusId, LINK( pWindow, Window, ImplAsyncFocusHdl ) );
+ }
+}
+
+// -----------------------------------------------------------------------
+
+static void ImplHandleLoseFocus( Window* pWindow )
+{
+ ImplSVData* pSVData = ImplGetSVData();
+
+ // Wenn wir den Focus verlieren gehen wir erst mal davon aus, dass sich das
+ // Systemclipboard aendert.
+ UpdateSystemClipboard();
+
+ // Wenn Frame den Focus verliert, brechen wir auch ein AutoScroll ab
+ if ( pSVData->maWinData.mpAutoScrollWin )
+ pSVData->maWinData.mpAutoScrollWin->EndAutoScroll();
+
+ // Wenn Frame den Focus verliert, brechen wir auch ein Tracking ab
+ if ( pSVData->maWinData.mpTrackWin )
+ {
+ if ( pSVData->maWinData.mpTrackWin->mpFrameWindow == pWindow )
+ pSVData->maWinData.mpTrackWin->EndTracking( ENDTRACK_CANCEL );
+ }
+
+ // handle FloatingMode
+ // hier beenden wir immer den PopupModus, auch dann, wenn NOFOCUSCLOSE
+ // gesetzt ist, damit wir nicht beim Wechsel noch Fenster stehen lassen
+ if ( pSVData->maWinData.mpFirstFloat )
+ {
+ if ( !(pSVData->maWinData.mpFirstFloat->GetPopupModeFlags() & FLOATWIN_POPUPMODE_NOAPPFOCUSCLOSE) )
+ pSVData->maWinData.mpFirstFloat->EndPopupMode( FLOATWIN_POPUPMODEEND_CANCEL | FLOATWIN_POPUPMODEEND_CLOSEALL );
+ }
+
+ pWindow->mpFrameData->mbHasFocus = FALSE;
+
+ // Focus-Events zeitverzoegert ausfuehren, damit bei SystemChildFenstern
+ // nicht alles flackert, wenn diese den Focus bekommen
+ if ( !pWindow->mpFrameData->mnFocusId )
+ {
+ pWindow->mpFrameData->mbStartFocusState = !pWindow->mpFrameData->mbHasFocus;
+ Application::PostUserEvent( pWindow->mpFrameData->mnFocusId, LINK( pWindow, Window, ImplAsyncFocusHdl ) );
+ }
+}
+
+// -----------------------------------------------------------------------
+
+void ImplHandleClose( Window* pWindow )
+{
+ ImplSVData* pSVData = ImplGetSVData();
+
+ // Bei Close schliessen wir erstmal alle FloatingModi mit
+ // und brechen auch sonstige Ablaeufe
+ if ( pSVData->maWinData.mpFirstFloat )
+ {
+ FloatingWindow* pLastLevelFloat;
+ pLastLevelFloat = pSVData->maWinData.mpFirstFloat->ImplFindLastLevelFloat();
+ pLastLevelFloat->EndPopupMode( FLOATWIN_POPUPMODEEND_CANCEL | FLOATWIN_POPUPMODEEND_CLOSEALL );
+ }
+ if ( pSVData->maHelpData.mbExtHelpMode )
+ Help::EndExtHelp();
+ if ( pSVData->maHelpData.mpHelpWin )
+ ImplDestroyHelpWindow();
+ // AutoScrollMode
+ if ( pSVData->maWinData.mpAutoScrollWin )
+ pSVData->maWinData.mpAutoScrollWin->EndAutoScroll();
+ DragManager* pDragManager = DragManager::GetDragManager();
+ if ( pDragManager )
+ {
+ pWindow->ImplGenerateMouseMove();
+ pDragManager->Escape( pWindow );
+ }
+ if ( pSVData->maWinData.mpTrackWin )
+ pSVData->maWinData.mpTrackWin->EndTracking( ENDTRACK_CANCEL | ENDTRACK_KEY );
+
+ // Dann stellen wir fest, ob Close ueberhaupt erlaubt ist
+ SystemWindow* pSysWindow = (SystemWindow*)pWindow->ImplGetWindow();
+ if ( !pSysWindow->IsEnabled() || !pSysWindow->IsInputEnabled() )
+ Sound::Beep( SOUND_DISABLE, pSysWindow );
+ else
+ pSysWindow->Close();
+}
+
+// -----------------------------------------------------------------------
+
+static void ImplHandleUserEvent( ImplSVEvent* pSVEvent )
+{
+ if ( pSVEvent )
+ {
+ if ( pSVEvent->mbCall && !pSVEvent->maDelData.IsDelete() )
+ {
+ if ( pSVEvent->mpWindow )
+ {
+ pSVEvent->mpWindow->ImplRemoveDel( &(pSVEvent->maDelData) );
+ if ( pSVEvent->mpLink )
+ pSVEvent->mpLink->Call( pSVEvent->mpData );
+ else
+ pSVEvent->mpWindow->UserEvent( pSVEvent->mnEvent, pSVEvent->mpData );
+ }
+ else
+ {
+ if ( pSVEvent->mpLink )
+ pSVEvent->mpLink->Call( pSVEvent->mpData );
+ else
+ GetpApp()->UserEvent( pSVEvent->mnEvent, pSVEvent->mpData );
+ }
+ }
+
+ delete pSVEvent->mpLink;
+ delete pSVEvent;
+ }
+}
+
+// =======================================================================
+
+#ifndef REMOTE_APPSERVER
+
+static USHORT ImplGetMouseMoveMode( SalMouseEvent* pEvent )
+{
+ USHORT nMode = 0;
+ if ( !pEvent->mnCode )
+ nMode |= MOUSE_SIMPLEMOVE;
+ if ( (pEvent->mnCode & MOUSE_LEFT) && !(pEvent->mnCode & KEY_MOD1) )
+ nMode |= MOUSE_DRAGMOVE;
+ if ( (pEvent->mnCode & MOUSE_LEFT) && (pEvent->mnCode & KEY_MOD1) )
+ nMode |= MOUSE_DRAGCOPY;
+ return nMode;
+}
+
+// -----------------------------------------------------------------------
+
+static USHORT ImplGetMouseButtonMode( SalMouseEvent* pEvent )
+{
+ USHORT nMode = 0;
+ if ( pEvent->mnButton == MOUSE_LEFT )
+ nMode |= MOUSE_SIMPLECLICK;
+ if ( (pEvent->mnButton == MOUSE_LEFT) && !(pEvent->mnCode & (MOUSE_MIDDLE | MOUSE_RIGHT)) )
+ nMode |= MOUSE_SELECT;
+ if ( (pEvent->mnButton == MOUSE_LEFT) && (pEvent->mnCode & KEY_MOD1) &&
+ !(pEvent->mnCode & (MOUSE_MIDDLE | MOUSE_RIGHT | KEY_SHIFT)) )
+ nMode |= MOUSE_MULTISELECT;
+ if ( (pEvent->mnButton == MOUSE_LEFT) && (pEvent->mnCode & KEY_SHIFT) &&
+ !(pEvent->mnCode & (MOUSE_MIDDLE | MOUSE_RIGHT | KEY_MOD1)) )
+ nMode |= MOUSE_RANGESELECT;
+ return nMode;
+}
+
+// -----------------------------------------------------------------------
+
+inline long ImplHandleSalMouseLeave( Window* pWindow, SalMouseEvent* pEvent )
+{
+ return ImplHandleMouseEvent( pWindow, EVENT_MOUSEMOVE, TRUE,
+ pEvent->mnX, pEvent->mnY,
+ pEvent->mnTime, pEvent->mnCode,
+ ImplGetMouseMoveMode( pEvent ) );
+}
+
+// -----------------------------------------------------------------------
+
+inline long ImplHandleSalMouseMove( Window* pWindow, SalMouseEvent* pEvent )
+{
+ return ImplHandleMouseEvent( pWindow, EVENT_MOUSEMOVE, FALSE,
+ pEvent->mnX, pEvent->mnY,
+ pEvent->mnTime, pEvent->mnCode,
+ ImplGetMouseMoveMode( pEvent ) );
+}
+
+// -----------------------------------------------------------------------
+
+inline long ImplHandleSalMouseButtonDown( Window* pWindow, SalMouseEvent* pEvent )
+{
+ return ImplHandleMouseEvent( pWindow, EVENT_MOUSEBUTTONDOWN, FALSE,
+ pEvent->mnX, pEvent->mnY,
+ pEvent->mnTime,
+ pEvent->mnButton | (pEvent->mnCode & (KEY_SHIFT | KEY_MOD1 | KEY_MOD2)),
+ ImplGetMouseButtonMode( pEvent ) );
+}
+
+// -----------------------------------------------------------------------
+
+inline long ImplHandleSalMouseButtonUp( Window* pWindow, SalMouseEvent* pEvent )
+{
+ return ImplHandleMouseEvent( pWindow, EVENT_MOUSEBUTTONUP, FALSE,
+ pEvent->mnX, pEvent->mnY,
+ pEvent->mnTime,
+ pEvent->mnButton | (pEvent->mnCode & (KEY_SHIFT | KEY_MOD1 | KEY_MOD2)),
+ ImplGetMouseButtonMode( pEvent ) );
+}
+
+// -----------------------------------------------------------------------
+
+long ImplHandleSalMouseActivate( Window* pWindow, SalMouseActivateEvent* pEvent )
+{
+ return FALSE;
+}
+
+// -----------------------------------------------------------------------
+
+static void ImplHandleSalKeyMod( Window* pWindow, SalKeyModEvent* pEvent )
+{
+ ImplSVData* pSVData = ImplGetSVData();
+ Window* pTrackWin = pSVData->maWinData.mpTrackWin;
+ if ( pTrackWin )
+ pWindow = pTrackWin;
+ USHORT nOldCode = pWindow->mpFrameData->mnMouseCode & (KEY_SHIFT | KEY_MOD1 | KEY_MOD2);
+ USHORT nNewCode = pEvent->mnCode;
+ if ( nOldCode != nNewCode )
+ {
+ nNewCode |= pWindow->mpFrameData->mnMouseCode & ~(KEY_SHIFT | KEY_MOD1 | KEY_MOD2);
+ pWindow->mpFrameWindow->ImplCallMouseMove( nNewCode, TRUE );
+ }
+}
+
+// -----------------------------------------------------------------------
+
+static void ImplHandleSalSettings( Window* pWindow, USHORT nEvent )
+{
+ // Application Notification werden nur fuer das AppWindow ausgeloest
+ SystemWindow* pSysWindow = (SystemWindow*)pWindow->ImplGetWindow();
+ WorkWindow* pAppWin = Application::GetAppWindow();
+
+ if ( pAppWin && (pSysWindow != pAppWin) )
+ return;
+
+ Application* pApp = GetpApp();
+ if ( nEvent == SALEVENT_SETTINGSCHANGED )
+ {
+ ImplSVData* pSVData = ImplGetSVData();
+ AllSettings aSettings = pApp->GetSettings();
+ // International so umsetzen, das Daten durch
+ // UpdateInternationalSystemTables() nicht geaendert werden,
+ // damit wir feststellen koennen, ob sich Einstellungen
+ // geaendert haben
+ International aIntn = aSettings.GetInternational();
+ aIntn.SetQuotationMarkStart( aIntn.GetQuotationMarkStart() );
+ aIntn.SetDateFormat( aIntn.GetDateFormat() );
+ UpdateInternationalSystemTables();
+ if ( aIntn != aSettings.GetInternational() )
+ pSVData->maAppData.mbIntnChanged = TRUE;
+ pApp->MergeSystemSettings( aSettings );
+ pApp->SystemSettingsChanging( aSettings, pWindow );
+ pApp->SetSettings( aSettings );
+ pSVData->maAppData.mbIntnChanged = FALSE;
+ }
+ else
+ {
+ USHORT nType;
+ switch ( nEvent )
+ {
+ case SALEVENT_VOLUMECHANGED:
+ nType = 0;
+ break;
+ case SALEVENT_PRINTERCHANGED:
+ ImplDeletePrnQueueList();
+ nType = DATACHANGED_PRINTER;
+ break;
+ case SALEVENT_DISPLAYCHANGED:
+ nType = DATACHANGED_DISPLAY;
+ break;
+ case SALEVENT_FONTCHANGED:
+ OutputDevice::ImplUpdateAllFontData( TRUE );
+ nType = DATACHANGED_FONTS;
+ break;
+ case SALEVENT_DATETIMECHANGED:
+ nType = DATACHANGED_DATETIME;
+ break;
+ case SALEVENT_KEYBOARDCHANGED:
+ nType = 0;
+ break;
+ default:
+ nType = 0;
+ break;
+ }
+
+ if ( nType )
+ {
+ DataChangedEvent aDCEvt( nType );
+ pApp->DataChanged( aDCEvt );
+ pApp->NotifyAllWindows( aDCEvt );
+ }
+ }
+}
+
+// -----------------------------------------------------------------------
+
+static void ImplHandleSalExtTextInputPos( Window* pWindow, SalExtTextInputPosEvent* pEvt )
+{
+ Window* pChild = ImplHandleExtTextInputPos( pWindow, pEvt->mnFirstPos, pEvt->mnChars );
+ if ( pChild )
+ {
+ USHORT nStart = pChild->GetExtTextInputPosStart();
+ USHORT nCount = pChild->GetExtTextInputPosCount();
+ const Rectangle* pAry = pChild->GetExtTextInputPosAry();
+ USHORT nPos;
+ for ( USHORT i = 0; i < pEvt->mnChars; i++ )
+ {
+ nPos = i+(USHORT)pEvt->mnFirstPos;
+ if ( (nPos >= nStart) && (nPos < nStart+nCount) )
+ {
+ SalExtCharPos* pSalPos = pEvt->mpPosAry+i;
+ const Rectangle* pPos = pAry+(nPos-nStart);
+ pSalPos->mnX = pChild->ImplLogicXToDevicePixel( pPos->Left() );
+ pSalPos->mnY = pChild->ImplLogicYToDevicePixel( pPos->Top() );
+ pSalPos->mnWidth = pChild->ImplLogicWidthToDevicePixel( pPos->GetWidth() );
+ pSalPos->mnHeight = pChild->ImplLogicHeightToDevicePixel( pPos->GetHeight() );
+ }
+ }
+ }
+}
+
+// -----------------------------------------------------------------------
+
+long ImplWindowFrameProc( void* pInst, SalFrame* pFrame,
+ USHORT nEvent, const void* pEvent )
+{
+ DBG_TESTSOLARMUTEX();
+
+ long nRet = 0;
+
+ switch ( nEvent )
+ {
+ case SALEVENT_MOUSEMOVE:
+ nRet = ImplHandleSalMouseMove( (Window*)pInst, (SalMouseEvent*)pEvent );
+ break;
+ case SALEVENT_MOUSELEAVE:
+ nRet = ImplHandleSalMouseLeave( (Window*)pInst, (SalMouseEvent*)pEvent );
+ break;
+ case SALEVENT_MOUSEBUTTONDOWN:
+ nRet = ImplHandleSalMouseButtonDown( (Window*)pInst, (SalMouseEvent*)pEvent );
+ break;
+ case SALEVENT_MOUSEBUTTONUP:
+ nRet = ImplHandleSalMouseButtonUp( (Window*)pInst, (SalMouseEvent*)pEvent );
+ break;
+ case SALEVENT_MOUSEACTIVATE:
+ nRet = ImplHandleSalMouseActivate( (Window*)pInst, (SalMouseActivateEvent*)pEvent );
+ break;
+
+ case SALEVENT_KEYINPUT:
+ {
+ SalKeyEvent* pKeyEvt = (SalKeyEvent*)pEvent;
+ nRet = ImplHandleKey( (Window*)pInst, EVENT_KEYINPUT,
+ pKeyEvt->mnCode, pKeyEvt->mnCharCode, pKeyEvt->mnRepeat );
+ }
+ break;
+ case SALEVENT_KEYUP:
+ {
+ SalKeyEvent* pKeyEvt = (SalKeyEvent*)pEvent;
+ nRet = ImplHandleKey( (Window*)pInst, EVENT_KEYUP,
+ pKeyEvt->mnCode, pKeyEvt->mnCharCode, pKeyEvt->mnRepeat );
+ }
+ break;
+ case SALEVENT_KEYMODCHANGE:
+ ImplHandleSalKeyMod( (Window*)pInst, (SalKeyModEvent*)pEvent );
+ break;
+
+ case SALEVENT_WHEELMOUSE:
+ {
+ ImplSVData* pSVData = ImplGetSVData();
+
+ if ( pSVData->maWinData.mpAutoScrollWin )
+ pSVData->maWinData.mpAutoScrollWin->EndAutoScroll();
+
+ SalWheelMouseEvent* pWheelEvt = (SalWheelMouseEvent*)pEvent;
+ nRet = ImplHandleWheelEvent( (Window*)pInst,
+ pWheelEvt->mnX, pWheelEvt->mnY,
+ pWheelEvt->mnTime,
+ pWheelEvt->mnDelta,
+ pWheelEvt->mnNotchDelta,
+ pWheelEvt->mnScrollLines,
+ pWheelEvt->mnCode, pWheelEvt->mbHorz );
+ }
+ break;
+
+ case SALEVENT_PAINT:
+ {
+ SalPaintEvent* pPaintEvt = (SalPaintEvent*)pEvent;
+ Rectangle aBoundRect( Point( pPaintEvt->mnBoundX, pPaintEvt->mnBoundY ),
+ Size( pPaintEvt->mnBoundWidth, pPaintEvt->mnBoundHeight ) );
+ ImplHandlePaint( (Window*)pInst, aBoundRect );
+ }
+ break;
+
+ case SALEVENT_RESIZE:
+ {
+ long nNewWidth;
+ long nNewHeight;
+ ((Window*)pInst)->mpFrame->GetClientSize( nNewWidth, nNewHeight );
+ ImplHandleResize( (Window*)pInst, nNewWidth, nNewHeight );
+ }
+ break;
+
+ case SALEVENT_GETFOCUS:
+ ImplHandleGetFocus( (Window*)pInst );
+ break;
+ case SALEVENT_LOSEFOCUS:
+ ImplHandleLoseFocus( (Window*)pInst );
+ break;
+
+ case SALEVENT_CLOSE:
+ ImplHandleClose( (Window*)pInst );
+ break;
+
+ case SALEVENT_SHUTDOWN:
+ if ( Application::GetAppWindow() == ((WorkWindow*)pInst)->ImplGetWindow() )
+ {
+ if ( GetpApp()->QueryExit() )
+ {
+ // Message-Schleife beenden
+ Application::Quit();
+ return FALSE;
+ }
+ else
+ return TRUE;
+ }
+ break;
+
+ case SALEVENT_SETTINGSCHANGED:
+ case SALEVENT_VOLUMECHANGED:
+ case SALEVENT_PRINTERCHANGED:
+ case SALEVENT_DISPLAYCHANGED:
+ case SALEVENT_FONTCHANGED:
+ case SALEVENT_DATETIMECHANGED:
+ case SALEVENT_KEYBOARDCHANGED:
+ ImplHandleSalSettings( (Window*)pInst, nEvent );
+ break;
+
+ case SALEVENT_USEREVENT:
+ ImplHandleUserEvent( (ImplSVEvent*)pEvent );
+ break;
+
+ case SALEVENT_STARTEXTTEXTINPUT:
+ ImplHandleStartExtTextInput( (Window*)pInst );
+ break;
+ case SALEVENT_EXTTEXTINPUT:
+ {
+ SalExtTextInputEvent* pEvt = (SalExtTextInputEvent*)pEvent;
+ ImplHandleExtTextInput( (Window*)pInst, pEvt->mnTime,
+ pEvt->maText, pEvt->mpTextAttr,
+ pEvt->mnCursorPos, pEvt->mbCursorVisible,
+ pEvt->mnDeltaStart, pEvt->mbOnlyCursor );
+ }
+ break;
+ case SALEVENT_ENDEXTTEXTINPUT:
+ ImplHandleEndExtTextInput( (Window*)pInst );
+ break;
+ case SALEVENT_EXTTEXTINPUTPOS:
+ ImplHandleSalExtTextInputPos( (Window*)pInst, (SalExtTextInputPosEvent*)pEvent );
+ break;
+ case SALEVENT_INPUTCONTEXTCHANGE:
+ {
+ ImplHandleInputContextChange( (Window*)pInst );
+ }
+ break;
+
+ case SALEVENT_CURSORPOS:
+ {
+ SalCursorPosEvent* pEvt = (SalCursorPosEvent*)pEvent;
+ ImplHandleICursorPos( (Window*)pInst,
+ pEvt->mnX, pEvt->mnY,
+ pEvt->mnWidth, pEvt->mnHeight );
+ }
+ break;
+
+#ifdef DBG_UTIL
+ default:
+ DBG_ERROR1( "ImplWindowFrameProc(): unknown event (%lu)", (ULONG)nEvent );
+ break;
+#endif
+ }
+
+ return nRet;
+}
+
+#else // => REMOTE_APPSERVER
+
+void ImplRemoteWindowFrameProc( ExtRmEvent* pEvent )
+{
+ DBG_TESTSOLARMUTEX();
+
+ ULONG nId = pEvent->GetId();
+ switch ( nId )
+ {
+ case RMEVENT_KEYINPUT:
+ {
+ RmKeyEventData* pData = (RmKeyEventData*)pEvent->GetData();
+ ImplHandleKey( pEvent->GetWindow(), EVENT_KEYINPUT,
+ pData->nKeyCode, pData->nChar, pData->nCount );
+ }
+ break;
+ case RMEVENT_KEYUP:
+ {
+ RmKeyEventData* pData = (RmKeyEventData*)pEvent->GetData();
+ ImplHandleKey( pEvent->GetWindow(), EVENT_KEYUP,
+ pData->nKeyCode, pData->nChar, 0 );
+ }
+ break;
+ case RMEVENT_MOUSEBUTTONDOWN:
+ case RMEVENT_MOUSEBUTTONUP:
+ case RMEVENT_MOUSEMOVE:
+ {
+ USHORT nSVEvent;
+ if ( nId == RMEVENT_MOUSEBUTTONDOWN )
+ nSVEvent = EVENT_MOUSEBUTTONDOWN;
+ else if ( nId == RMEVENT_MOUSEBUTTONUP )
+ nSVEvent = EVENT_MOUSEBUTTONUP;
+ else
+ nSVEvent = EVENT_MOUSEMOVE;
+ RmMouseEventData* pData = (RmMouseEventData*)pEvent->GetData();
+ BOOL bMouseLeave = ( pData->nMode & MOUSE_LEAVEWINDOW ) ? TRUE : FALSE;
+ pData->nMode &= ~(MOUSE_ENTERWINDOW|MOUSE_LEAVEWINDOW);
+
+ // Bei MOUSE_MOVE eine Bestaetigung zurueckschicken, damit der
+ // RClient solange verzoegert...
+ // Vorm ImplHandleMouseEvent, falls dort z.B. ein modaler Dialog
+ // aufgemacht wird.
+ if ( nId == RMEVENT_MOUSEMOVE )
+ {
+ DBG_ASSERT( pEvent->GetWindow()->ImplGetFrame(), "RemoteWindowProc: Frame?" );
+ if ( pEvent->GetWindow()->ImplGetFrame() )
+ pEvent->GetWindow()->ImplGetFrame()->MouseMoveProcessed();
+ }
+
+ ImplHandleMouseEvent( pEvent->GetWindow(), nSVEvent, bMouseLeave,
+ pData->nX, pData->nY, pData->nSysTime,
+ pData->nCode, pData->nMode );
+
+ }
+ break;
+ case RMEVENT_PAINT:
+ {
+ Rectangle* pRect = (Rectangle*)pEvent->GetData();
+ ImplHandlePaint( pEvent->GetWindow(), *pRect );
+ }
+ break;
+ case RMEVENT_RESIZE:
+ {
+ Size* pSize = (Size*)pEvent->GetData();
+ ImplHandleResize( pEvent->GetWindow(), pSize->Width(), pSize->Height() );
+ }
+ break;
+ case RMEVENT_USEREVENT:
+ {
+ ImplHandleUserEvent( (ImplSVEvent*)pEvent->GetData() );
+ }
+ break;
+ case RMEVENT_CLOSE:
+ {
+ ImplHandleClose( pEvent->GetWindow() );
+ }
+ break;
+ case RMEVENT_GETFOCUS:
+ {
+ ImplHandleGetFocus( pEvent->GetWindow() );
+ };
+ break;
+ case RMEVENT_LOSEFOCUS:
+ {
+ ImplHandleLoseFocus( pEvent->GetWindow() );
+ };
+ break;
+ case RMEVENT_MOUSEWHEEL:
+ {
+ RmMouseWheelEventData* pData = (RmMouseWheelEventData*)pEvent->GetData();
+ ImplHandleWheelEvent( pEvent->GetWindow(),
+ pData->nX,
+ pData->nY,
+ pData->nSysTime,
+ pData->nDelta,
+ pData->nNotchDelta,
+ pData->nScrollLines,
+ pData->nCode,
+ pData->bHorz );
+ };
+ break;
+ }
+}
+
+#endif