|  | /************************************************************** | 
|  | * | 
|  | * Licensed to the Apache Software Foundation (ASF) under one | 
|  | * or more contributor license agreements.  See the NOTICE file | 
|  | * distributed with this work for additional information | 
|  | * regarding copyright ownership.  The ASF licenses this file | 
|  | * to you under the Apache License, Version 2.0 (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.apache.org/licenses/LICENSE-2.0 | 
|  | * | 
|  | * Unless required by applicable law or agreed to in writing, | 
|  | * software distributed under the License is distributed on an | 
|  | * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY | 
|  | * KIND, either express or implied.  See the License for the | 
|  | * specific language governing permissions and limitations | 
|  | * under the License. | 
|  | * | 
|  | *************************************************************/ | 
|  |  | 
|  |  | 
|  |  | 
|  | // MARKER(update_precomp.py): autogen include statement, do not remove | 
|  | #include "precompiled_vcl.hxx" | 
|  |  | 
|  | // i72022: ad-hoc to forcibly enable reconversion | 
|  | #if WINVER < 0x0500 | 
|  | #undef WINVER | 
|  | #define WINVER 0x0500 | 
|  | #endif | 
|  |  | 
|  | #include <com/sun/star/lang/XMultiServiceFactory.hpp> | 
|  | #include <com/sun/star/container/XIndexAccess.hpp> | 
|  | #include <com/sun/star/beans/XPropertySet.hpp> | 
|  | #include <com/sun/star/awt/Rectangle.hpp> | 
|  | #include <comphelper/processfactory.hxx> | 
|  | #include <unotools/misccfg.hxx> | 
|  |  | 
|  | #include <string.h> | 
|  | #include <limits.h> | 
|  |  | 
|  | #include <stdio.h> | 
|  |  | 
|  | #include <tools/svwin.h> | 
|  | #ifdef __MINGW32__ | 
|  | #include <excpt.h> | 
|  | #endif | 
|  |  | 
|  | #include <rtl/string.h> | 
|  | #include <rtl/ustring.h> | 
|  |  | 
|  | #include <osl/module.h> | 
|  |  | 
|  | #include <tools/debug.hxx> | 
|  |  | 
|  | #include <vcl/sysdata.hxx> | 
|  | #include <vcl/timer.hxx> | 
|  | #include <vcl/settings.hxx> | 
|  | #include <vcl/keycodes.hxx> | 
|  | #include <vcl/window.hxx> | 
|  | #include <vcl/wrkwin.hxx> | 
|  | #include <vcl/svapp.hxx> | 
|  | #include <vcl/impdel.hxx> | 
|  |  | 
|  | // Warning in SDK header | 
|  | #if defined(_MSC_VER) && (_MSC_VER > 1400) | 
|  | #pragma warning( disable: 4242 4244 ) | 
|  | #endif | 
|  | #include <win/wincomp.hxx> | 
|  | #include <win/salids.hrc> | 
|  | #include <win/saldata.hxx> | 
|  | #include <win/salinst.h> | 
|  | #include <win/salbmp.h> | 
|  | #include <win/salgdi.h> | 
|  | #include <win/salsys.h> | 
|  | #include <win/salframe.h> | 
|  | #include <win/salvd.h> | 
|  | #include <win/salmenu.h> | 
|  | #include <win/salobj.h> | 
|  | #include <win/saltimer.h> | 
|  |  | 
|  | #include <impbmp.hxx> | 
|  | #include <window.h> | 
|  | #include <sallayout.hxx> | 
|  |  | 
|  | #define COMPILE_MULTIMON_STUBS | 
|  | #include <multimon.h> | 
|  | #include <vector> | 
|  | #ifdef __MINGW32__ | 
|  | #include <algorithm> | 
|  | using ::std::max; | 
|  | #endif | 
|  |  | 
|  | #ifdef WNT | 
|  | #include <oleacc.h> | 
|  | #include <com/sun/star/accessibility/XMSAAService.hpp> | 
|  | #ifndef _WIN32_WCE | 
|  | #define WM_GETOBJECT                    0x003D | 
|  | #endif | 
|  | #include <win/g_msaasvc.h> | 
|  | #endif | 
|  | #include <com/sun/star/uno/Exception.hdl> | 
|  |  | 
|  | #include <time.h> | 
|  |  | 
|  | using ::rtl::OUString; | 
|  | using namespace ::com::sun::star; | 
|  | using namespace ::com::sun::star::uno; | 
|  | using namespace ::com::sun::star::lang; | 
|  | using namespace ::com::sun::star::container; | 
|  | using namespace ::com::sun::star::beans; | 
|  |  | 
|  | // The following defines are newly added in Longhorn | 
|  | #ifndef WM_MOUSEHWHEEL | 
|  | # define WM_MOUSEHWHEEL            0x020E | 
|  | #endif | 
|  | #ifndef SPI_GETWHEELSCROLLCHARS | 
|  | # define SPI_GETWHEELSCROLLCHARS   0x006C | 
|  | #endif | 
|  | #ifndef SPI_SETWHEELSCROLLCHARS | 
|  | # define SPI_SETWHEELSCROLLCHARS   0x006D | 
|  | #endif | 
|  |  | 
|  |  | 
|  |  | 
|  | #if OSL_DEBUG_LEVEL > 1 | 
|  | void MyOutputDebugString( char *s) { OutputDebugString( s ); } | 
|  | #endif | 
|  |  | 
|  | // misssing prototypes and constants for LayeredWindows | 
|  | extern "C" { | 
|  | //WINUSERAPI sal_Bool WINAPI SetLayeredWindowAttributes(HWND,COLORREF,BYTE,DWORD); | 
|  | typedef sal_Bool ( WINAPI * SetLayeredWindowAttributes_Proc_T ) (HWND,COLORREF,BYTE,DWORD); | 
|  | static SetLayeredWindowAttributes_Proc_T lpfnSetLayeredWindowAttributes; | 
|  | }; | 
|  |  | 
|  | // ======================================================================= | 
|  |  | 
|  | const unsigned int WM_USER_SYSTEM_WINDOW_ACTIVATED = RegisterWindowMessageA("SYSTEM_WINDOW_ACTIVATED"); | 
|  |  | 
|  | sal_Bool WinSalFrame::mbInReparent = FALSE; | 
|  |  | 
|  | // ======================================================================= | 
|  |  | 
|  | // Wegen Fehler in Windows-Headerfiles | 
|  | #ifndef IMN_OPENCANDIDATE | 
|  | #define IMN_OPENCANDIDATE               0x0005 | 
|  | #endif | 
|  | #ifndef IMN_CLOSECANDIDATE | 
|  | #define IMN_CLOSECANDIDATE              0x0004 | 
|  | #endif | 
|  |  | 
|  | #ifndef WM_THEMECHANGED | 
|  | #define WM_THEMECHANGED                 0x031A | 
|  | #endif | 
|  |  | 
|  | // Macros for support of WM_UNICHAR & Keyman 6.0 | 
|  | #define Uni_UTF32ToSurrogate1(ch)   (((unsigned long) (ch) - 0x10000) / 0x400 + 0xD800) | 
|  | #define Uni_UTF32ToSurrogate2(ch)   (((unsigned long) (ch) - 0x10000) % 0x400 + 0xDC00) | 
|  | #define Uni_SupplementaryPlanesStart    0x10000 | 
|  |  | 
|  | // ======================================================================= | 
|  | #ifdef WNT | 
|  | using namespace ::com::sun::star::accessibility; | 
|  | XMSAAService* g_acc_manager1 = NULL; | 
|  | #endif | 
|  | static void UpdateFrameGeometry( HWND hWnd, WinSalFrame* pFrame ); | 
|  | static void SetMaximizedFrameGeometry( HWND hWnd, WinSalFrame* pFrame, RECT* pParentRect = NULL ); | 
|  |  | 
|  | static void ImplSaveFrameState( WinSalFrame* pFrame ) | 
|  | { | 
|  | // Position, Groesse und Status fuer GetWindowState() merken | 
|  | if ( !pFrame->mbFullScreen ) | 
|  | { | 
|  | sal_Bool bVisible = (GetWindowStyle( pFrame->mhWnd ) & WS_VISIBLE) != 0; | 
|  | if ( IsIconic( pFrame->mhWnd ) ) | 
|  | { | 
|  | pFrame->maState.mnState |= SAL_FRAMESTATE_MINIMIZED; | 
|  | if ( bVisible ) | 
|  | pFrame->mnShowState = SW_SHOWMAXIMIZED; | 
|  | } | 
|  | else if ( IsZoomed( pFrame->mhWnd ) ) | 
|  | { | 
|  | pFrame->maState.mnState &= ~SAL_FRAMESTATE_MINIMIZED; | 
|  | pFrame->maState.mnState |= SAL_FRAMESTATE_MAXIMIZED; | 
|  | if ( bVisible ) | 
|  | pFrame->mnShowState = SW_SHOWMAXIMIZED; | 
|  | pFrame->mbRestoreMaximize = TRUE; | 
|  |  | 
|  | WINDOWPLACEMENT aPlacement; | 
|  | aPlacement.length = sizeof(aPlacement); | 
|  | if( GetWindowPlacement( pFrame->mhWnd, &aPlacement ) ) | 
|  | { | 
|  | RECT aRect = aPlacement.rcNormalPosition; | 
|  | RECT aRect2 = aRect; | 
|  | AdjustWindowRectEx( &aRect2, GetWindowStyle( pFrame->mhWnd ), | 
|  | FALSE,  GetWindowExStyle( pFrame->mhWnd ) ); | 
|  | long nTopDeco = abs( aRect.top - aRect2.top ); | 
|  | long nLeftDeco = abs( aRect.left - aRect2.left ); | 
|  | long nBottomDeco = abs( aRect.bottom - aRect2.bottom ); | 
|  | long nRightDeco = abs( aRect.right - aRect2.right ); | 
|  |  | 
|  | pFrame->maState.mnX      = aRect.left + nLeftDeco; | 
|  | pFrame->maState.mnY      = aRect.top + nTopDeco; | 
|  | pFrame->maState.mnWidth  = aRect.right - aRect.left - nLeftDeco - nRightDeco; | 
|  | pFrame->maState.mnHeight = aRect.bottom - aRect.top - nTopDeco - nBottomDeco; | 
|  | } | 
|  | } | 
|  | else | 
|  | { | 
|  | RECT aRect; | 
|  | GetWindowRect( pFrame->mhWnd, &aRect ); | 
|  |  | 
|  | // to be consistent with Unix, the frame state is without(!) decoration | 
|  | RECT aRect2 = aRect; | 
|  | AdjustWindowRectEx( &aRect2, GetWindowStyle( pFrame->mhWnd ), | 
|  | FALSE,     GetWindowExStyle( pFrame->mhWnd ) ); | 
|  | long nTopDeco = abs( aRect.top - aRect2.top ); | 
|  | long nLeftDeco = abs( aRect.left - aRect2.left ); | 
|  | long nBottomDeco = abs( aRect.bottom - aRect2.bottom ); | 
|  | long nRightDeco = abs( aRect.right - aRect2.right ); | 
|  |  | 
|  | pFrame->maState.mnState &= ~(SAL_FRAMESTATE_MINIMIZED | SAL_FRAMESTATE_MAXIMIZED); | 
|  | // subtract decoration | 
|  | pFrame->maState.mnX      = aRect.left+nLeftDeco; | 
|  | pFrame->maState.mnY      = aRect.top+nTopDeco; | 
|  | pFrame->maState.mnWidth  = aRect.right-aRect.left-nLeftDeco-nRightDeco; | 
|  | pFrame->maState.mnHeight = aRect.bottom-aRect.top-nTopDeco-nBottomDeco; | 
|  | if ( bVisible ) | 
|  | pFrame->mnShowState = SW_SHOWNORMAL; | 
|  | pFrame->mbRestoreMaximize = FALSE; | 
|  | } | 
|  | } | 
|  | } | 
|  |  | 
|  | // ----------------------------------------------------------------------- | 
|  |  | 
|  | // if pParentRect is set, the workarea of the monitor that contains pParentRect is returned | 
|  | void ImplSalGetWorkArea( HWND hWnd, RECT *pRect, const RECT *pParentRect ) | 
|  | { | 
|  | static int winVerChecked = 0; | 
|  | static int winVerOk = 0; | 
|  |  | 
|  | // check if we or our parent is fullscreen, then the taskbar should be ignored | 
|  | bool bIgnoreTaskbar = false; | 
|  | WinSalFrame* pFrame = GetWindowPtr( hWnd ); | 
|  | if( pFrame ) | 
|  | { | 
|  | Window *pWin = pFrame->GetWindow(); | 
|  | while( pWin ) | 
|  | { | 
|  | WorkWindow *pWorkWin = (pWin->GetType() == WINDOW_WORKWINDOW) ? (WorkWindow *) pWin : NULL; | 
|  | if( pWorkWin && pWorkWin->ImplGetWindowImpl()->mbReallyVisible && pWorkWin->IsFullScreenMode() ) | 
|  | { | 
|  | bIgnoreTaskbar = true; | 
|  | break; | 
|  | } | 
|  | else | 
|  | pWin = pWin->ImplGetWindowImpl()->mpParent; | 
|  | } | 
|  | } | 
|  |  | 
|  | if( !winVerChecked ) | 
|  | { | 
|  | winVerChecked = 1; | 
|  | winVerOk = 1; | 
|  |  | 
|  | // multi monitor calls not available on Win95/NT | 
|  | if ( aSalShlData.maVersionInfo.dwPlatformId == VER_PLATFORM_WIN32_NT ) | 
|  | { | 
|  | if ( aSalShlData.maVersionInfo.dwMajorVersion <= 4 ) | 
|  | winVerOk = 0;	// NT | 
|  | } | 
|  | else if( aSalShlData.maVersionInfo.dwPlatformId == VER_PLATFORM_WIN32_WINDOWS ) | 
|  | { | 
|  | if ( aSalShlData.maVersionInfo.dwMajorVersion == 4 && aSalShlData.maVersionInfo.dwMinorVersion == 0 ) | 
|  | winVerOk = 0;	// Win95 | 
|  | } | 
|  | } | 
|  |  | 
|  | // calculates the work area taking multiple monitors into account | 
|  | if( winVerOk ) | 
|  | { | 
|  | static int nMonitors = GetSystemMetrics( SM_CMONITORS ); | 
|  | if( nMonitors == 1 ) | 
|  | { | 
|  | if( bIgnoreTaskbar ) | 
|  | { | 
|  | pRect->left = pRect->top = 0; | 
|  | pRect->right   = GetSystemMetrics( SM_CXSCREEN ); | 
|  | pRect->bottom  = GetSystemMetrics( SM_CYSCREEN ); | 
|  | } | 
|  | else | 
|  | SystemParametersInfo( SPI_GETWORKAREA, 0, pRect, 0 ); | 
|  | } | 
|  | else | 
|  | { | 
|  | if( pParentRect != NULL ) | 
|  | { | 
|  | // return the size of the monitor where pParentRect lives | 
|  | HMONITOR hMonitor; | 
|  | MONITORINFO mi; | 
|  |  | 
|  | // get the nearest monitor to the passed rect. | 
|  | hMonitor = MonitorFromRect(pParentRect, MONITOR_DEFAULTTONEAREST); | 
|  |  | 
|  | // get the work area or entire monitor rect. | 
|  | mi.cbSize = sizeof(mi); | 
|  | GetMonitorInfo(hMonitor, &mi); | 
|  | if( !bIgnoreTaskbar ) | 
|  | *pRect = mi.rcWork; | 
|  | else | 
|  | *pRect = mi.rcMonitor; | 
|  | } | 
|  | else | 
|  | { | 
|  | // return the union of all monitors | 
|  | pRect->left = GetSystemMetrics( SM_XVIRTUALSCREEN ); | 
|  | pRect->top = GetSystemMetrics( SM_YVIRTUALSCREEN ); | 
|  | pRect->right = pRect->left + GetSystemMetrics( SM_CXVIRTUALSCREEN ); | 
|  | pRect->bottom = pRect->top + GetSystemMetrics( SM_CYVIRTUALSCREEN ); | 
|  |  | 
|  | // virtualscreen does not take taskbar into account, so use the corresponding | 
|  | // diffs between screen and workarea from the default screen | 
|  | // however, this is still not perfect: the taskbar might not be on the primary screen | 
|  | if( !bIgnoreTaskbar ) | 
|  | { | 
|  | RECT wRect, scrRect; | 
|  | SystemParametersInfo( SPI_GETWORKAREA, 0, &wRect, 0 ); | 
|  | scrRect.left = 0; | 
|  | scrRect.top = 0; | 
|  | scrRect.right = GetSystemMetrics( SM_CXSCREEN ); | 
|  | scrRect.bottom = GetSystemMetrics( SM_CYSCREEN ); | 
|  |  | 
|  | pRect->left += wRect.left; | 
|  | pRect->top += wRect.top; | 
|  | pRect->right -= scrRect.right - wRect.right; | 
|  | pRect->bottom -= scrRect.bottom - wRect.bottom; | 
|  | } | 
|  | } | 
|  | } | 
|  | } | 
|  | else | 
|  | { | 
|  | if( bIgnoreTaskbar ) | 
|  | { | 
|  | pRect->left = pRect->top = 0; | 
|  | pRect->right   = GetSystemMetrics( SM_CXSCREEN ); | 
|  | pRect->bottom  = GetSystemMetrics( SM_CYSCREEN ); | 
|  | } | 
|  | else | 
|  | SystemParametersInfo( SPI_GETWORKAREA, 0, pRect, 0 ); | 
|  | } | 
|  | } | 
|  |  | 
|  | // ======================================================================= | 
|  |  | 
|  | SalFrame* ImplSalCreateFrame( WinSalInstance* pInst, | 
|  | HWND hWndParent, sal_uLong nSalFrameStyle ) | 
|  | { | 
|  | WinSalFrame*   pFrame = new WinSalFrame; | 
|  | HWND        hWnd; | 
|  | DWORD       nSysStyle = 0; | 
|  | DWORD       nExSysStyle = 0; | 
|  | sal_Bool        bSubFrame = FALSE; | 
|  |  | 
|  | if( getenv( "SAL_SYNCHRONIZE" ) )   // no buffering of drawing commands | 
|  | GdiSetBatchLimit( 1 ); | 
|  |  | 
|  | static int bLayeredAPI = -1; | 
|  | if( bLayeredAPI == -1 ) | 
|  | { | 
|  | bLayeredAPI = 0; | 
|  | // check for W2k and XP | 
|  | if ( aSalShlData.maVersionInfo.dwPlatformId == VER_PLATFORM_WIN32_NT && aSalShlData.maVersionInfo.dwMajorVersion >= 5 ) | 
|  | { | 
|  | oslModule pLib = osl_loadAsciiModule( "user32", SAL_LOADMODULE_DEFAULT ); | 
|  | oslGenericFunction pFunc = NULL; | 
|  | if( pLib ) | 
|  | pFunc = osl_getAsciiFunctionSymbol( pLib, "SetLayeredWindowAttributes" ); | 
|  |  | 
|  | lpfnSetLayeredWindowAttributes = ( SetLayeredWindowAttributes_Proc_T ) pFunc; | 
|  |  | 
|  | bLayeredAPI = pFunc ? 1 : 0; | 
|  | } | 
|  | } | 
|  | static const char* pEnvTransparentFloats = getenv("SAL_TRANSPARENT_FLOATS" ); | 
|  |  | 
|  | // determine creation data | 
|  | if ( nSalFrameStyle & (SAL_FRAME_STYLE_PLUG | SAL_FRAME_STYLE_SYSTEMCHILD) ) | 
|  | { | 
|  | nSysStyle |= WS_CHILD; | 
|  | if( nSalFrameStyle & SAL_FRAME_STYLE_SYSTEMCHILD ) | 
|  | nSysStyle |= WS_CLIPSIBLINGS; | 
|  | } | 
|  | else | 
|  | { | 
|  | // #i87402# commenting out WS_CLIPCHILDREN | 
|  | // this breaks SAL_FRAME_STYLE_SYSTEMCHILD handling, which is not | 
|  | // used currently. Probably SAL_FRAME_STYLE_SYSTEMCHILD should be | 
|  | // removed again. | 
|  |  | 
|  | // nSysStyle  |= WS_CLIPCHILDREN; | 
|  | if ( hWndParent ) | 
|  | { | 
|  | nSysStyle |= WS_POPUP; | 
|  | bSubFrame = TRUE; | 
|  | pFrame->mbNoIcon = TRUE; | 
|  | } | 
|  | else | 
|  | { | 
|  | // Only with WS_OVERLAPPED we get a useful default position/size | 
|  | if ( (nSalFrameStyle & (SAL_FRAME_STYLE_SIZEABLE | SAL_FRAME_STYLE_MOVEABLE)) == | 
|  | (SAL_FRAME_STYLE_SIZEABLE | SAL_FRAME_STYLE_MOVEABLE) ) | 
|  | nSysStyle |= WS_OVERLAPPED; | 
|  | else | 
|  | { | 
|  | nSysStyle |= WS_POPUP; | 
|  | if ( !(nSalFrameStyle & SAL_FRAME_STYLE_MOVEABLE) ) | 
|  | nExSysStyle |= WS_EX_TOOLWINDOW;    // avoid taskbar appearance, for e.g. splash screen | 
|  | } | 
|  | } | 
|  |  | 
|  | if ( nSalFrameStyle & SAL_FRAME_STYLE_MOVEABLE ) | 
|  | { | 
|  | pFrame->mbCaption = TRUE; | 
|  | nSysStyle |= WS_SYSMENU | WS_CAPTION; | 
|  | if ( !hWndParent ) | 
|  | nSysStyle |= WS_SYSMENU | WS_MINIMIZEBOX; | 
|  | else | 
|  | nExSysStyle |= WS_EX_DLGMODALFRAME; | 
|  |  | 
|  | if ( nSalFrameStyle & SAL_FRAME_STYLE_SIZEABLE ) | 
|  | { | 
|  | pFrame->mbSizeBorder = TRUE; | 
|  | nSysStyle |= WS_THICKFRAME; | 
|  | if ( !hWndParent ) | 
|  | nSysStyle |= WS_MAXIMIZEBOX; | 
|  | } | 
|  | else | 
|  | pFrame->mbFixBorder = TRUE; | 
|  |  | 
|  | if ( nSalFrameStyle & SAL_FRAME_STYLE_DEFAULT ) | 
|  | nExSysStyle |= WS_EX_APPWINDOW; | 
|  | } | 
|  | if( nSalFrameStyle & SAL_FRAME_STYLE_TOOLWINDOW | 
|  | // #100656# toolwindows lead to bad alt-tab behavior, if they have the focus | 
|  | // you must press it twice to leave the application | 
|  | // so toolwindows are only used for non sizeable windows | 
|  | // which are typically small, so a small caption makes sense | 
|  |  | 
|  | // #103578# looked too bad - above changes reverted | 
|  | /* && !(nSalFrameStyle & SAL_FRAME_STYLE_SIZEABLE) */ ) | 
|  | { | 
|  | pFrame->mbNoIcon = TRUE; | 
|  | nExSysStyle |= WS_EX_TOOLWINDOW; | 
|  | if ( pEnvTransparentFloats && bLayeredAPI == 1 /*&& !(nSalFrameStyle & SAL_FRAME_STYLE_MOVEABLE) */) | 
|  | nExSysStyle |= WS_EX_LAYERED; | 
|  | } | 
|  | } | 
|  | if ( nSalFrameStyle & SAL_FRAME_STYLE_FLOAT ) | 
|  | { | 
|  | nExSysStyle |= WS_EX_TOOLWINDOW; | 
|  | pFrame->mbFloatWin = TRUE; | 
|  |  | 
|  | if ( (bLayeredAPI == 1) && (pEnvTransparentFloats /* does not work remote! || (nSalFrameStyle & SAL_FRAME_STYLE_FLOAT_FOCUSABLE) */ )  ) | 
|  | nExSysStyle |= WS_EX_LAYERED; | 
|  |  | 
|  | } | 
|  | if( (nSalFrameStyle & SAL_FRAME_STYLE_TOOLTIP) || (nSalFrameStyle & SAL_FRAME_STYLE_FLOAT_FOCUSABLE) ) | 
|  | nExSysStyle |= WS_EX_TOPMOST; | 
|  |  | 
|  | // init frame data | 
|  | pFrame->mnStyle = nSalFrameStyle; | 
|  |  | 
|  | // determine show style | 
|  | pFrame->mnShowState = SW_SHOWNORMAL; | 
|  | if ( (nSysStyle & (WS_POPUP | WS_MAXIMIZEBOX | WS_THICKFRAME)) == (WS_MAXIMIZEBOX | WS_THICKFRAME) ) | 
|  | { | 
|  | if ( GetSystemMetrics( SM_CXSCREEN ) <= 1024 ) | 
|  | pFrame->mnShowState = SW_SHOWMAXIMIZED; | 
|  | else | 
|  | { | 
|  | if ( nSalFrameStyle & SAL_FRAME_STYLE_DEFAULT ) | 
|  | { | 
|  | SalData* pSalData = GetSalData(); | 
|  | pFrame->mnShowState = pSalData->mnCmdShow; | 
|  | if ( (pFrame->mnShowState != SW_SHOWMINIMIZED) && | 
|  | (pFrame->mnShowState != SW_MINIMIZE) && | 
|  | (pFrame->mnShowState != SW_SHOWMINNOACTIVE) ) | 
|  | { | 
|  | if ( (pFrame->mnShowState == SW_SHOWMAXIMIZED) || | 
|  | (pFrame->mnShowState == SW_MAXIMIZE) ) | 
|  | pFrame->mbOverwriteState = FALSE; | 
|  | pFrame->mnShowState = SW_SHOWMAXIMIZED; | 
|  | } | 
|  | else | 
|  | pFrame->mbOverwriteState = FALSE; | 
|  | } | 
|  | else | 
|  | { | 
|  | // Document Windows are also maximized, if the current Document Window | 
|  | // is also maximized | 
|  | HWND hWnd = GetForegroundWindow(); | 
|  | if ( hWnd && IsMaximized( hWnd ) && | 
|  | (GetWindowInstance( hWnd ) == pInst->mhInst) && | 
|  | ((GetWindowStyle( hWnd ) & (WS_POPUP | WS_MAXIMIZEBOX | WS_THICKFRAME)) == (WS_MAXIMIZEBOX | WS_THICKFRAME)) ) | 
|  | pFrame->mnShowState = SW_SHOWMAXIMIZED; | 
|  | } | 
|  | } | 
|  | } | 
|  |  | 
|  | // create frame | 
|  | if( true/*aSalShlData.mbWNT*/ ) | 
|  | { | 
|  | LPCWSTR pClassName; | 
|  | if ( bSubFrame ) | 
|  | { | 
|  | if ( nSalFrameStyle & (SAL_FRAME_STYLE_MOVEABLE|SAL_FRAME_STYLE_NOSHADOW) ) // check if shadow not wanted | 
|  | pClassName = SAL_SUBFRAME_CLASSNAMEW; | 
|  | else | 
|  | pClassName = SAL_TMPSUBFRAME_CLASSNAMEW;    // undecorated floaters will get shadow on XP | 
|  | } | 
|  | else | 
|  | { | 
|  | if ( nSalFrameStyle & SAL_FRAME_STYLE_MOVEABLE ) | 
|  | pClassName = SAL_FRAME_CLASSNAMEW; | 
|  | else | 
|  | pClassName = SAL_TMPSUBFRAME_CLASSNAMEW; | 
|  | } | 
|  | hWnd = CreateWindowExW( nExSysStyle, pClassName, L"", nSysStyle, | 
|  | CW_USEDEFAULT, 0, CW_USEDEFAULT, 0, | 
|  | hWndParent, 0, pInst->mhInst, (void*)pFrame ); | 
|  | if( !hWnd ) | 
|  | ImplWriteLastError( GetLastError(), "CreateWindowEx" ); | 
|  | #if OSL_DEBUG_LEVEL > 1 | 
|  | // set transparency value | 
|  | if( bLayeredAPI == 1 && GetWindowExStyle( hWnd ) & WS_EX_LAYERED ) | 
|  | lpfnSetLayeredWindowAttributes( hWnd, 0, 230, 0x00000002 /*LWA_ALPHA*/ ); | 
|  | #endif | 
|  | } | 
|  | if ( !hWnd ) | 
|  | { | 
|  | delete pFrame; | 
|  | return NULL; | 
|  | } | 
|  |  | 
|  | // If we have an Window with an Caption Bar and without | 
|  | // an MaximizeBox, we change the SystemMenu | 
|  | if ( (nSysStyle & (WS_CAPTION | WS_MAXIMIZEBOX)) == (WS_CAPTION) ) | 
|  | { | 
|  | HMENU hSysMenu = GetSystemMenu( hWnd, FALSE ); | 
|  | if ( hSysMenu ) | 
|  | { | 
|  | if ( !(nSysStyle & (WS_MINIMIZEBOX | WS_MAXIMIZEBOX)) ) | 
|  | DeleteMenu( hSysMenu, SC_RESTORE, MF_BYCOMMAND ); | 
|  | else | 
|  | EnableMenuItem( hSysMenu, SC_RESTORE, MF_BYCOMMAND | MF_GRAYED | MF_DISABLED ); | 
|  | if ( !(nSysStyle & WS_MINIMIZEBOX) ) | 
|  | DeleteMenu( hSysMenu, SC_MINIMIZE, MF_BYCOMMAND ); | 
|  | if ( !(nSysStyle & WS_MAXIMIZEBOX) ) | 
|  | DeleteMenu( hSysMenu, SC_MAXIMIZE, MF_BYCOMMAND ); | 
|  | if ( !(nSysStyle & WS_THICKFRAME) ) | 
|  | DeleteMenu( hSysMenu, SC_SIZE, MF_BYCOMMAND ); | 
|  | } | 
|  | } | 
|  | if ( (nSysStyle & WS_SYSMENU) && !(nSalFrameStyle & SAL_FRAME_STYLE_CLOSEABLE) ) | 
|  | { | 
|  | HMENU hSysMenu = GetSystemMenu( hWnd, FALSE ); | 
|  | if ( hSysMenu ) | 
|  | EnableMenuItem( hSysMenu, SC_CLOSE, MF_BYCOMMAND | MF_GRAYED | MF_DISABLED ); | 
|  | } | 
|  |  | 
|  | // reset input context | 
|  | pFrame->mhDefIMEContext = ImmAssociateContext( hWnd, 0 ); | 
|  |  | 
|  | // determine output size and state | 
|  | RECT aRect; | 
|  | GetClientRect( hWnd, &aRect ); | 
|  | pFrame->mnWidth  = aRect.right; | 
|  | pFrame->mnHeight = aRect.bottom; | 
|  | ImplSaveFrameState( pFrame ); | 
|  | pFrame->mbDefPos = TRUE; | 
|  |  | 
|  | UpdateFrameGeometry( hWnd, pFrame ); | 
|  |  | 
|  | if( pFrame->mnShowState == SW_SHOWMAXIMIZED ) | 
|  | { | 
|  | // #96084 set a useful internal window size because | 
|  | // the window will not be maximized (and the size updated) before show() | 
|  |  | 
|  | SetMaximizedFrameGeometry( hWnd, pFrame ); | 
|  | } | 
|  |  | 
|  | return pFrame; | 
|  | } | 
|  |  | 
|  | // helper that only creates the HWND | 
|  | // to allow for easy reparenting of system windows, (i.e. destroy and create new) | 
|  | HWND ImplSalReCreateHWND( HWND hWndParent, HWND oldhWnd, sal_Bool bAsChild ) | 
|  | { | 
|  | HINSTANCE hInstance = GetSalData()->mhInst; | 
|  | ULONG nSysStyle     = GetWindowLong( oldhWnd, GWL_STYLE ); | 
|  | ULONG nExSysStyle   = GetWindowLong( oldhWnd, GWL_EXSTYLE ); | 
|  |  | 
|  | if( bAsChild ) | 
|  | { | 
|  | nSysStyle = WS_CHILD; | 
|  | nExSysStyle = 0; | 
|  | } | 
|  |  | 
|  | LPCWSTR pClassName = SAL_SUBFRAME_CLASSNAMEW; | 
|  | HWND hWnd = CreateWindowExW( nExSysStyle, pClassName, L"", nSysStyle, | 
|  | CW_USEDEFAULT, 0, CW_USEDEFAULT, 0, | 
|  | hWndParent, 0, hInstance, (void*)GetWindowPtr( oldhWnd ) ); | 
|  | return hWnd; | 
|  | } | 
|  |  | 
|  | // ======================================================================= | 
|  |  | 
|  | // Uebersetzungstabelle von System-Keycodes in StarView-Keycodes | 
|  | #define KEY_TAB_SIZE     146 | 
|  |  | 
|  | static sal_uInt16 aImplTranslateKeyTab[KEY_TAB_SIZE] = | 
|  | { | 
|  | // StarView-Code      System-Code                         Index | 
|  | 0,                    //                                  0 | 
|  | 0,                    // VK_LBUTTON                       1 | 
|  | 0,                    // VK_RBUTTON                       2 | 
|  | 0,                    // VK_CANCEL                        3 | 
|  | 0,                    // VK_MBUTTON                       4 | 
|  | 0,                    //                                  5 | 
|  | 0,                    //                                  6 | 
|  | 0,                    //                                  7 | 
|  | KEY_BACKSPACE,        // VK_BACK                          8 | 
|  | KEY_TAB,              // VK_TAB                           9 | 
|  | 0,                    //                                  10 | 
|  | 0,                    //                                  11 | 
|  | 0,                    // VK_CLEAR                         12 | 
|  | KEY_RETURN,           // VK_RETURN                        13 | 
|  | 0,                    //                                  14 | 
|  | 0,                    //                                  15 | 
|  | 0,                    // VK_SHIFT                         16 | 
|  | 0,                    // VK_CONTROL                       17 | 
|  | 0,                    // VK_MENU                          18 | 
|  | 0,                    // VK_PAUSE                         19 | 
|  | 0,                    // VK_CAPITAL                       20 | 
|  | 0,                    // VK_HANGUL                        21 | 
|  | 0,                    //                                  22 | 
|  | 0,                    //                                  23 | 
|  | 0,                    //                                  24 | 
|  | KEY_HANGUL_HANJA,     // VK_HANJA                         25 | 
|  | 0,                    //                                  26 | 
|  | KEY_ESCAPE,           // VK_ESCAPE                        27 | 
|  | 0,                    //                                  28 | 
|  | 0,                    //                                  29 | 
|  | 0,                    //                                  30 | 
|  | 0,                    //                                  31 | 
|  | KEY_SPACE,            // VK_SPACE                         32 | 
|  | KEY_PAGEUP,           // VK_PRIOR                         33 | 
|  | KEY_PAGEDOWN,         // VK_NEXT                          34 | 
|  | KEY_END,              // VK_END                           35 | 
|  | KEY_HOME,             // VK_HOME                          36 | 
|  | KEY_LEFT,             // VK_LEFT                          37 | 
|  | KEY_UP,               // VK_UP                            38 | 
|  | KEY_RIGHT,            // VK_RIGHT                         39 | 
|  | KEY_DOWN,             // VK_DOWN                          40 | 
|  | 0,                    // VK_SELECT                        41 | 
|  | 0,                    // VK_PRINT                         42 | 
|  | 0,                    // VK_EXECUTE                       43 | 
|  | 0,                    // VK_SNAPSHOT                      44 | 
|  | KEY_INSERT,           // VK_INSERT                        45 | 
|  | KEY_DELETE,           // VK_DELETE                        46 | 
|  | KEY_HELP,             // VK_HELP                          47 | 
|  | KEY_0,                //                                  48 | 
|  | KEY_1,                //                                  49 | 
|  | KEY_2,                //                                  50 | 
|  | KEY_3,                //                                  51 | 
|  | KEY_4,                //                                  52 | 
|  | KEY_5,                //                                  53 | 
|  | KEY_6,                //                                  54 | 
|  | KEY_7,                //                                  55 | 
|  | KEY_8,                //                                  56 | 
|  | KEY_9,                //                                  57 | 
|  | 0,                    //                                  58 | 
|  | 0,                    //                                  59 | 
|  | 0,                    //                                  60 | 
|  | 0,                    //                                  61 | 
|  | 0,                    //                                  62 | 
|  | 0,                    //                                  63 | 
|  | 0,                    //                                  64 | 
|  | KEY_A,                //                                  65 | 
|  | KEY_B,                //                                  66 | 
|  | KEY_C,                //                                  67 | 
|  | KEY_D,                //                                  68 | 
|  | KEY_E,                //                                  69 | 
|  | KEY_F,                //                                  70 | 
|  | KEY_G,                //                                  71 | 
|  | KEY_H,                //                                  72 | 
|  | KEY_I,                //                                  73 | 
|  | KEY_J,                //                                  74 | 
|  | KEY_K,                //                                  75 | 
|  | KEY_L,                //                                  76 | 
|  | KEY_M,                //                                  77 | 
|  | KEY_N,                //                                  78 | 
|  | KEY_O,                //                                  79 | 
|  | KEY_P,                //                                  80 | 
|  | KEY_Q,                //                                  81 | 
|  | KEY_R,                //                                  82 | 
|  | KEY_S,                //                                  83 | 
|  | KEY_T,                //                                  84 | 
|  | KEY_U,                //                                  85 | 
|  | KEY_V,                //                                  86 | 
|  | KEY_W,                //                                  87 | 
|  | KEY_X,                //                                  88 | 
|  | KEY_Y,                //                                  89 | 
|  | KEY_Z,                //                                  90 | 
|  | 0,                    // VK_LWIN                          91 | 
|  | 0,                    // VK_RWIN                          92 | 
|  | KEY_CONTEXTMENU,      // VK_APPS                          93 | 
|  | 0,                    //                                  94 | 
|  | 0,                    //                                  95 | 
|  | KEY_0,                // VK_NUMPAD0                       96 | 
|  | KEY_1,                // VK_NUMPAD1                       97 | 
|  | KEY_2,                // VK_NUMPAD2                       98 | 
|  | KEY_3,                // VK_NUMPAD3                       99 | 
|  | KEY_4,                // VK_NUMPAD4                      100 | 
|  | KEY_5,                // VK_NUMPAD5                      101 | 
|  | KEY_6,                // VK_NUMPAD6                      102 | 
|  | KEY_7,                // VK_NUMPAD7                      103 | 
|  | KEY_8,                // VK_NUMPAD8                      104 | 
|  | KEY_9,                // VK_NUMPAD9                      105 | 
|  | KEY_MULTIPLY,         // VK_MULTIPLY                     106 | 
|  | KEY_ADD,              // VK_ADD                          107 | 
|  | KEY_DECIMAL,          // VK_SEPARATOR                    108 | 
|  | KEY_SUBTRACT,         // VK_SUBTRACT                     109 | 
|  | KEY_DECIMAL,          // VK_DECIMAL                      110 | 
|  | KEY_DIVIDE,           // VK_DIVIDE                       111 | 
|  | KEY_F1,               // VK_F1                           112 | 
|  | KEY_F2,               // VK_F2                           113 | 
|  | KEY_F3,               // VK_F3                           114 | 
|  | KEY_F4,               // VK_F4                           115 | 
|  | KEY_F5,               // VK_F5                           116 | 
|  | KEY_F6,               // VK_F6                           117 | 
|  | KEY_F7,               // VK_F7                           118 | 
|  | KEY_F8,               // VK_F8                           119 | 
|  | KEY_F9,               // VK_F9                           120 | 
|  | KEY_F10,              // VK_F10                          121 | 
|  | KEY_F11,              // VK_F11                          122 | 
|  | KEY_F12,              // VK_F12                          123 | 
|  | KEY_F13,              // VK_F13                          124 | 
|  | KEY_F14,              // VK_F14                          125 | 
|  | KEY_F15,              // VK_F15                          126 | 
|  | KEY_F16,              // VK_F16                          127 | 
|  | KEY_F17,              // VK_F17                          128 | 
|  | KEY_F18,              // VK_F18                          129 | 
|  | KEY_F19,              // VK_F19                          130 | 
|  | KEY_F20,              // VK_F20                          131 | 
|  | KEY_F21,              // VK_F21                          132 | 
|  | KEY_F22,              // VK_F22                          133 | 
|  | KEY_F23,              // VK_F23                          134 | 
|  | KEY_F24,              // VK_F24                          135 | 
|  | 0,                    //                                 136 | 
|  | 0,                    //                                 137 | 
|  | 0,                    //                                 138 | 
|  | 0,                    //                                 139 | 
|  | 0,                    //                                 140 | 
|  | 0,                    //                                 141 | 
|  | 0,                    //                                 142 | 
|  | 0,                    //                                 143 | 
|  | 0,                    // NUMLOCK                         144 | 
|  | 0                     // SCROLLLOCK                      145 | 
|  | }; | 
|  |  | 
|  | // ======================================================================= | 
|  |  | 
|  | static UINT ImplSalGetWheelScrollLines() | 
|  | { | 
|  | UINT nScrLines = 0; | 
|  | HWND hWndMsWheel = WIN_FindWindow( MSH_WHEELMODULE_CLASS, MSH_WHEELMODULE_TITLE ); | 
|  | if ( hWndMsWheel ) | 
|  | { | 
|  | UINT nGetScrollLinesMsgId = RegisterWindowMessage( MSH_SCROLL_LINES ); | 
|  | nScrLines = (UINT)ImplSendMessage( hWndMsWheel, nGetScrollLinesMsgId, 0, 0 ); | 
|  | } | 
|  |  | 
|  | if ( !nScrLines ) | 
|  | if( !SystemParametersInfo( SPI_GETWHEELSCROLLLINES, 0, &nScrLines, 0 ) ) | 
|  | nScrLines = 0 ; | 
|  |  | 
|  | if ( !nScrLines ) | 
|  | nScrLines = 3; | 
|  |  | 
|  | return nScrLines; | 
|  | } | 
|  |  | 
|  | // ----------------------------------------------------------------------- | 
|  |  | 
|  | static UINT ImplSalGetWheelScrollChars() | 
|  | { | 
|  | UINT nScrChars = 0; | 
|  | if( !SystemParametersInfo( SPI_GETWHEELSCROLLCHARS, 0, &nScrChars, 0 ) ) | 
|  | { | 
|  | // Depending on Windows version, use proper default or 1 (when | 
|  | // driver emulates hscroll) | 
|  | if( VER_PLATFORM_WIN32_NT == aSalShlData.maVersionInfo.dwPlatformId && | 
|  | aSalShlData.maVersionInfo.dwMajorVersion < 6 ) | 
|  | { | 
|  | // Windows 2000 & WinXP : emulating driver, use step size | 
|  | // of 1 | 
|  | return 1; | 
|  | } | 
|  | else | 
|  | { | 
|  | // Longhorn or above: use proper default value of 3 | 
|  | return 3; | 
|  | } | 
|  | } | 
|  |  | 
|  | // system settings successfully read | 
|  | return nScrChars; | 
|  | } | 
|  |  | 
|  | // ----------------------------------------------------------------------- | 
|  |  | 
|  | static void ImplSalAddBorder( const WinSalFrame* pFrame, int& width, int& height ) | 
|  | { | 
|  | // transform client size into window size | 
|  | RECT    aWinRect; | 
|  | aWinRect.left   = 0; | 
|  | aWinRect.right  = width-1; | 
|  | aWinRect.top    = 0; | 
|  | aWinRect.bottom = height-1; | 
|  | AdjustWindowRectEx( &aWinRect, GetWindowStyle( pFrame->mhWnd ), | 
|  | FALSE,     GetWindowExStyle( pFrame->mhWnd ) ); | 
|  | width  = aWinRect.right - aWinRect.left + 1; | 
|  | height = aWinRect.bottom - aWinRect.top + 1; | 
|  | } | 
|  |  | 
|  | // ----------------------------------------------------------------------- | 
|  |  | 
|  | static void ImplSalCalcFullScreenSize( const WinSalFrame* pFrame, | 
|  | int& rX, int& rY, int& rDX, int& rDY ) | 
|  | { | 
|  | // set window to screen size | 
|  | int nFrameX; | 
|  | int nFrameY; | 
|  | int nCaptionY; | 
|  | int nScreenX = 0; | 
|  | int nScreenY = 0; | 
|  | int nScreenDX = 0; | 
|  | int nScreenDY = 0; | 
|  |  | 
|  | if ( pFrame->mbSizeBorder ) | 
|  | { | 
|  | nFrameX = GetSystemMetrics( SM_CXSIZEFRAME ); | 
|  | nFrameY = GetSystemMetrics( SM_CYSIZEFRAME ); | 
|  | } | 
|  | else if ( pFrame->mbFixBorder ) | 
|  | { | 
|  | nFrameX = GetSystemMetrics( SM_CXFIXEDFRAME ); | 
|  | nFrameY = GetSystemMetrics( SM_CYFIXEDFRAME ); | 
|  | } | 
|  | else if ( pFrame->mbBorder ) | 
|  | { | 
|  | nFrameX = GetSystemMetrics( SM_CXBORDER ); | 
|  | nFrameY = GetSystemMetrics( SM_CYBORDER ); | 
|  | } | 
|  | else | 
|  | { | 
|  | nFrameX = 0; | 
|  | nFrameY = 0; | 
|  | } | 
|  | if ( pFrame->mbCaption ) | 
|  | nCaptionY = GetSystemMetrics( SM_CYCAPTION ); | 
|  | else | 
|  | nCaptionY = 0; | 
|  |  | 
|  | try | 
|  | { | 
|  | uno::Reference< XMultiServiceFactory > xFactory( ::comphelper::getProcessServiceFactory(), UNO_QUERY_THROW ); | 
|  | uno::Reference< XIndexAccess > xMultiMon( xFactory->createInstance(OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.awt.DisplayAccess" ) ) ), UNO_QUERY_THROW ); | 
|  | sal_Int32 nMonitors = xMultiMon->getCount(); | 
|  | if( (pFrame->mnDisplay >= 0) && (pFrame->mnDisplay < nMonitors) ) | 
|  | { | 
|  | uno::Reference< XPropertySet > xMonitor( xMultiMon->getByIndex( pFrame->mnDisplay ), UNO_QUERY_THROW ); | 
|  | com::sun::star::awt::Rectangle aRect; | 
|  | if( xMonitor->getPropertyValue( OUString( RTL_CONSTASCII_USTRINGPARAM( "ScreenArea" ) ) ) >>= aRect ) | 
|  | { | 
|  | nScreenX = aRect.X; | 
|  | nScreenY = aRect.Y; | 
|  | nScreenDX = aRect.Width+1;  // difference between java/awt convention and vcl | 
|  | nScreenDY = aRect.Height+1; // difference between java/awt convention and vcl | 
|  | } | 
|  | } | 
|  | else | 
|  | { | 
|  | Rectangle aCombined; | 
|  | uno::Reference< XPropertySet > xMonitor( xMultiMon->getByIndex( 0 ), UNO_QUERY_THROW ); | 
|  | com::sun::star::awt::Rectangle aRect; | 
|  | if( xMonitor->getPropertyValue( OUString( RTL_CONSTASCII_USTRINGPARAM( "ScreenArea" ) ) ) >>= aRect ) | 
|  | { | 
|  | aCombined.Left()   = aRect.X; | 
|  | aCombined.Top()    = aRect.Y; | 
|  | aCombined.Right()  = aRect.X + aRect.Width; | 
|  | aCombined.Bottom() = aRect.Y + aRect.Height; | 
|  | for( sal_Int32 i = 1 ; i < nMonitors ; i++ ) | 
|  | { | 
|  | xMonitor = uno::Reference< XPropertySet >( xMultiMon->getByIndex(i), UNO_QUERY_THROW ); | 
|  | if( xMonitor->getPropertyValue( OUString( RTL_CONSTASCII_USTRINGPARAM( "ScreenArea" ) ) ) >>= aRect ) | 
|  | { | 
|  | aCombined.Union( Rectangle( aRect.X, aRect.Y, aRect.X+aRect.Width, aRect.Y+aRect.Height ) ); | 
|  | } | 
|  | } | 
|  | } | 
|  | nScreenX  = aCombined.Left(); | 
|  | nScreenY  = aCombined.Top(); | 
|  | nScreenDX = aCombined.GetWidth(); | 
|  | nScreenDY = aCombined.GetHeight(); | 
|  | } | 
|  | } | 
|  | catch( Exception& ) | 
|  | { | 
|  | } | 
|  |  | 
|  | if( !nScreenDX || !nScreenDY ) | 
|  | { | 
|  | nScreenDX   = GetSystemMetrics( SM_CXSCREEN ); | 
|  | nScreenDY   = GetSystemMetrics( SM_CYSCREEN ); | 
|  | } | 
|  |  | 
|  | rX  = nScreenX -nFrameX; | 
|  | rY  = nScreenY -(nFrameY+nCaptionY); | 
|  | rDX = nScreenDX+(nFrameX*2); | 
|  | rDY = nScreenDY+(nFrameY*2)+nCaptionY; | 
|  | } | 
|  |  | 
|  | // ----------------------------------------------------------------------- | 
|  |  | 
|  | static void ImplSalFrameFullScreenPos( WinSalFrame* pFrame, sal_Bool bAlways = FALSE ) | 
|  | { | 
|  | if ( bAlways || !IsIconic( pFrame->mhWnd ) ) | 
|  | { | 
|  | // set window to screen size | 
|  | int nX; | 
|  | int nY; | 
|  | int nWidth; | 
|  | int nHeight; | 
|  | ImplSalCalcFullScreenSize( pFrame, nX, nY, nWidth, nHeight ); | 
|  | SetWindowPos( pFrame->mhWnd, 0, | 
|  | nX, nY, nWidth, nHeight, | 
|  | SWP_NOZORDER | SWP_NOACTIVATE ); | 
|  | } | 
|  | } | 
|  |  | 
|  | // ----------------------------------------------------------------------- | 
|  |  | 
|  | WinSalFrame::WinSalFrame() | 
|  | { | 
|  | SalData* pSalData = GetSalData(); | 
|  |  | 
|  | mhWnd               = 0; | 
|  | mhCursor            = LoadCursor( 0, IDC_ARROW ); | 
|  | mhDefIMEContext     = 0; | 
|  | mpGraphics          = NULL; | 
|  | mpGraphics2         = NULL; | 
|  | mnShowState         = SW_SHOWNORMAL; | 
|  | mnWidth             = 0; | 
|  | mnHeight            = 0; | 
|  | mnMinWidth          = 0; | 
|  | mnMinHeight         = 0; | 
|  | mnMaxWidth          = SHRT_MAX; | 
|  | mnMaxHeight         = SHRT_MAX; | 
|  | mnInputLang         = 0; | 
|  | mnInputCodePage     = 0; | 
|  | mbGraphics          = FALSE; | 
|  | mbCaption           = FALSE; | 
|  | mbBorder            = FALSE; | 
|  | mbFixBorder         = FALSE; | 
|  | mbSizeBorder        = FALSE; | 
|  | mbFullScreen        = FALSE; | 
|  | mbPresentation      = FALSE; | 
|  | mbInShow            = FALSE; | 
|  | mbRestoreMaximize   = FALSE; | 
|  | mbInMoveMsg         = FALSE; | 
|  | mbInSizeMsg         = FALSE; | 
|  | mbFullScreenToolWin = FALSE; | 
|  | mbDefPos            = TRUE; | 
|  | mbOverwriteState    = TRUE; | 
|  | mbIME               = FALSE; | 
|  | mbHandleIME         = FALSE; | 
|  | mbSpezIME           = FALSE; | 
|  | mbAtCursorIME       = FALSE; | 
|  | mbCandidateMode     = FALSE; | 
|  | mbFloatWin          = FALSE; | 
|  | mbNoIcon            = FALSE; | 
|  | mSelectedhMenu      = 0; | 
|  | mLastActivatedhMenu = 0; | 
|  | mpClipRgnData       = NULL; | 
|  | mbFirstClipRect     = TRUE; | 
|  | mpNextClipRect      = NULL; | 
|  | mnDisplay			= 0; | 
|  |  | 
|  | memset( &maState, 0, sizeof( SalFrameState ) ); | 
|  | maSysData.nSize     = sizeof( SystemEnvData ); | 
|  |  | 
|  | memset( &maGeometry, 0, sizeof( maGeometry ) ); | 
|  |  | 
|  | // Daten ermitteln, wenn erster Frame angelegt wird | 
|  | if ( !pSalData->mpFirstFrame ) | 
|  | { | 
|  | if ( !aSalShlData.mnWheelMsgId ) | 
|  | aSalShlData.mnWheelMsgId = RegisterWindowMessage( MSH_MOUSEWHEEL ); | 
|  | if ( !aSalShlData.mnWheelScrollLines ) | 
|  | aSalShlData.mnWheelScrollLines = ImplSalGetWheelScrollLines(); | 
|  | if ( !aSalShlData.mnWheelScrollChars ) | 
|  | aSalShlData.mnWheelScrollChars = ImplSalGetWheelScrollChars(); | 
|  | } | 
|  |  | 
|  | // insert frame in framelist | 
|  | mpNextFrame = pSalData->mpFirstFrame; | 
|  | pSalData->mpFirstFrame = this; | 
|  | } | 
|  |  | 
|  | // ----------------------------------------------------------------------- | 
|  | void WinSalFrame::updateScreenNumber() | 
|  | { | 
|  | if( mnDisplay == -1 ) // spans all monitors | 
|  | return; | 
|  | WinSalSystem* pSys = static_cast<WinSalSystem*>(ImplGetSalSystem()); | 
|  | if( pSys ) | 
|  | { | 
|  | const std::vector<WinSalSystem::DisplayMonitor>& rMonitors = | 
|  | pSys->getMonitors(); | 
|  | Point aPoint( maGeometry.nX, maGeometry.nY ); | 
|  | size_t nMon = rMonitors.size(); | 
|  | for( size_t i = 0; i < nMon; i++ ) | 
|  | { | 
|  | if( rMonitors[i].m_aArea.IsInside( aPoint ) ) | 
|  | { | 
|  | mnDisplay = static_cast<sal_Int32>(i); | 
|  | maGeometry.nScreenNumber = static_cast<unsigned int>(i); | 
|  | } | 
|  | } | 
|  | } | 
|  | } | 
|  |  | 
|  | // ----------------------------------------------------------------------- | 
|  |  | 
|  | WinSalFrame::~WinSalFrame() | 
|  | { | 
|  | SalData* pSalData = GetSalData(); | 
|  |  | 
|  | if( mpClipRgnData ) | 
|  | delete [] (BYTE*)mpClipRgnData; | 
|  |  | 
|  | // remove frame from framelist | 
|  | WinSalFrame** ppFrame = &pSalData->mpFirstFrame; | 
|  | for(; (*ppFrame != this) && *ppFrame; ppFrame = &(*ppFrame)->mpNextFrame ); | 
|  | if( *ppFrame ) | 
|  | *ppFrame = mpNextFrame; | 
|  | mpNextFrame = NULL; | 
|  |  | 
|  | // Release Cache DC | 
|  | if ( mpGraphics2 && | 
|  | mpGraphics2->getHDC() ) | 
|  | ReleaseGraphics( mpGraphics2 ); | 
|  |  | 
|  | // destroy saved DC | 
|  | if ( mpGraphics ) | 
|  | { | 
|  | if ( mpGraphics->mhDefPal ) | 
|  | SelectPalette( mpGraphics->getHDC(), mpGraphics->mhDefPal, TRUE ); | 
|  | ImplSalDeInitGraphics( mpGraphics ); | 
|  | ReleaseDC( mhWnd, mpGraphics->getHDC() ); | 
|  | delete mpGraphics; | 
|  | mpGraphics = NULL; | 
|  | } | 
|  |  | 
|  | if ( mhWnd ) | 
|  | { | 
|  | // reset mouse leave data | 
|  | if ( pSalData->mhWantLeaveMsg == mhWnd ) | 
|  | { | 
|  | pSalData->mhWantLeaveMsg = 0; | 
|  | if ( pSalData->mpMouseLeaveTimer ) | 
|  | { | 
|  | delete pSalData->mpMouseLeaveTimer; | 
|  | pSalData->mpMouseLeaveTimer = NULL; | 
|  | } | 
|  | } | 
|  |  | 
|  | // destroy system frame | 
|  | if ( !DestroyWindow( mhWnd ) ) | 
|  | SetWindowPtr( mhWnd, 0 ); | 
|  |  | 
|  | mhWnd = 0; | 
|  | } | 
|  | } | 
|  |  | 
|  | // ----------------------------------------------------------------------- | 
|  |  | 
|  | SalGraphics* WinSalFrame::GetGraphics() | 
|  | { | 
|  | if ( mbGraphics ) | 
|  | return NULL; | 
|  |  | 
|  | // Other threads get an own DC, because Windows modify in the | 
|  | // other case our DC (changing clip region), when they send a | 
|  | // WM_ERASEBACKGROUND message | 
|  | SalData* pSalData = GetSalData(); | 
|  | if ( pSalData->mnAppThreadId != GetCurrentThreadId() ) | 
|  | { | 
|  | // We use only three CacheDC's for all threads, because W9x is limited | 
|  | // to max. 5 Cache DC's per thread | 
|  | if ( pSalData->mnCacheDCInUse >= 3 ) | 
|  | return NULL; | 
|  |  | 
|  | if ( !mpGraphics2 ) | 
|  | { | 
|  | mpGraphics2 = new WinSalGraphics; | 
|  | mpGraphics2->setHDC(0); | 
|  | mpGraphics2->mhWnd       = mhWnd; | 
|  | mpGraphics2->mbPrinter   = FALSE; | 
|  | mpGraphics2->mbVirDev    = FALSE; | 
|  | mpGraphics2->mbWindow    = TRUE; | 
|  | mpGraphics2->mbScreen    = TRUE; | 
|  | } | 
|  |  | 
|  | HDC hDC = (HDC)ImplSendMessage( pSalData->mpFirstInstance->mhComWnd, | 
|  | SAL_MSG_GETDC, | 
|  | (WPARAM)mhWnd, 0 ); | 
|  | if ( hDC ) | 
|  | { | 
|  | mpGraphics2->setHDC(hDC); | 
|  | if ( pSalData->mhDitherPal ) | 
|  | { | 
|  | mpGraphics2->mhDefPal = SelectPalette( hDC, pSalData->mhDitherPal, TRUE ); | 
|  | RealizePalette( hDC ); | 
|  | } | 
|  | ImplSalInitGraphics( mpGraphics2 ); | 
|  | mbGraphics = TRUE; | 
|  |  | 
|  | pSalData->mnCacheDCInUse++; | 
|  | return mpGraphics2; | 
|  | } | 
|  | else | 
|  | return NULL; | 
|  | } | 
|  | else | 
|  | { | 
|  | if ( !mpGraphics ) | 
|  | { | 
|  | HDC hDC = GetDC( mhWnd ); | 
|  | if ( hDC ) | 
|  | { | 
|  | mpGraphics = new WinSalGraphics; | 
|  | mpGraphics->setHDC(hDC); | 
|  | mpGraphics->mhWnd     = mhWnd; | 
|  | mpGraphics->mbPrinter = FALSE; | 
|  | mpGraphics->mbVirDev  = FALSE; | 
|  | mpGraphics->mbWindow  = TRUE; | 
|  | mpGraphics->mbScreen  = TRUE; | 
|  | if ( pSalData->mhDitherPal ) | 
|  | { | 
|  | mpGraphics->mhDefPal = SelectPalette( hDC, pSalData->mhDitherPal, TRUE ); | 
|  | RealizePalette( hDC ); | 
|  | } | 
|  | ImplSalInitGraphics( mpGraphics ); | 
|  | mbGraphics = TRUE; | 
|  | } | 
|  | } | 
|  | else | 
|  | mbGraphics = TRUE; | 
|  |  | 
|  | return mpGraphics; | 
|  | } | 
|  | } | 
|  |  | 
|  | // ----------------------------------------------------------------------- | 
|  |  | 
|  | void WinSalFrame::ReleaseGraphics( SalGraphics* pGraphics ) | 
|  | { | 
|  | if ( mpGraphics2 == pGraphics ) | 
|  | { | 
|  | if ( mpGraphics2->getHDC() ) | 
|  | { | 
|  | SalData* pSalData = GetSalData(); | 
|  | if ( mpGraphics2->mhDefPal ) | 
|  | SelectPalette( mpGraphics2->getHDC(), mpGraphics2->mhDefPal, TRUE ); | 
|  | ImplSalDeInitGraphics( mpGraphics2 ); | 
|  | ImplSendMessage( pSalData->mpFirstInstance->mhComWnd, | 
|  | SAL_MSG_RELEASEDC, | 
|  | (WPARAM)mhWnd, | 
|  | (LPARAM)mpGraphics2->getHDC() ); | 
|  | mpGraphics2->setHDC(0); | 
|  | pSalData->mnCacheDCInUse--; | 
|  | } | 
|  | } | 
|  |  | 
|  | mbGraphics = FALSE; | 
|  | } | 
|  |  | 
|  | // ----------------------------------------------------------------------- | 
|  |  | 
|  | sal_Bool WinSalFrame::PostEvent( void* pData ) | 
|  | { | 
|  | return (sal_Bool)ImplPostMessage( mhWnd, SAL_MSG_USEREVENT, 0, (LPARAM)pData ); | 
|  | } | 
|  |  | 
|  | // ----------------------------------------------------------------------- | 
|  |  | 
|  | void WinSalFrame::SetTitle( const XubString& rTitle ) | 
|  | { | 
|  | DBG_ASSERT( sizeof( WCHAR ) == sizeof( xub_Unicode ), "WinSalFrame::SetTitle(): WCHAR != sal_Unicode" ); | 
|  |  | 
|  | if ( !SetWindowTextW( mhWnd, reinterpret_cast<LPCWSTR>(rTitle.GetBuffer()) ) ) | 
|  | { | 
|  | ByteString aAnsiTitle = ImplSalGetWinAnsiString( rTitle ); | 
|  | SetWindowTextA( mhWnd, aAnsiTitle.GetBuffer() ); | 
|  | } | 
|  | } | 
|  |  | 
|  | // ----------------------------------------------------------------------- | 
|  |  | 
|  | void WinSalFrame::SetIcon( sal_uInt16 nIcon ) | 
|  | { | 
|  | // If we have a window without an Icon (for example a dialog), ignore this call | 
|  | if ( mbNoIcon ) | 
|  | return; | 
|  |  | 
|  | // 0 means default (class) icon | 
|  | HICON hIcon = NULL, hSmIcon = NULL; | 
|  | if ( !nIcon ) | 
|  | nIcon = 1; | 
|  |  | 
|  | ImplLoadSalIcon( nIcon, hIcon, hSmIcon ); | 
|  |  | 
|  | DBG_ASSERT( hIcon ,   "WinSalFrame::SetIcon(): Could not load large icon !" ); | 
|  | DBG_ASSERT( hSmIcon , "WinSalFrame::SetIcon(): Could not load small icon !" ); | 
|  |  | 
|  | ImplSendMessage( mhWnd, WM_SETICON, ICON_BIG, (LPARAM)hIcon ); | 
|  | ImplSendMessage( mhWnd, WM_SETICON, ICON_SMALL, (LPARAM)hSmIcon ); | 
|  | } | 
|  |  | 
|  | // ----------------------------------------------------------------------- | 
|  |  | 
|  | void WinSalFrame::SetMenu( SalMenu* pSalMenu ) | 
|  | { | 
|  | WinSalMenu* pWMenu = static_cast<WinSalMenu*>(pSalMenu); | 
|  | if( pSalMenu && pWMenu->mbMenuBar ) | 
|  | ::SetMenu( mhWnd, pWMenu->mhMenu ); | 
|  | } | 
|  |  | 
|  | void WinSalFrame::DrawMenuBar() | 
|  | { | 
|  | ::DrawMenuBar( mhWnd ); | 
|  | } | 
|  |  | 
|  | // ----------------------------------------------------------------------- | 
|  | HWND ImplGetParentHwnd( HWND hWnd ) | 
|  | { | 
|  | WinSalFrame* pFrame = GetWindowPtr( hWnd ); | 
|  | if( !pFrame || !pFrame->GetWindow()) | 
|  | return ::GetParent( hWnd ); | 
|  | Window *pRealParent = pFrame->GetWindow()->ImplGetWindowImpl()->mpRealParent; | 
|  | if( pRealParent ) | 
|  | return static_cast<WinSalFrame*>(pRealParent->ImplGetWindowImpl()->mpFrame)->mhWnd; | 
|  | else | 
|  | return ::GetParent( hWnd ); | 
|  |  | 
|  | } | 
|  |  | 
|  | // ----------------------------------------------------------------------- | 
|  |  | 
|  | SalFrame* WinSalFrame::GetParent() const | 
|  | { | 
|  | return GetWindowPtr( ImplGetParentHwnd( mhWnd ) ); | 
|  | } | 
|  |  | 
|  | // ----------------------------------------------------------------------- | 
|  |  | 
|  | static void ImplSalShow( HWND hWnd, sal_Bool bVisible, sal_Bool bNoActivate ) | 
|  | { | 
|  | WinSalFrame* pFrame = GetWindowPtr( hWnd ); | 
|  | if ( !pFrame ) | 
|  | return; | 
|  |  | 
|  | if ( bVisible ) | 
|  | { | 
|  | pFrame->mbDefPos = FALSE; | 
|  | pFrame->mbOverwriteState = TRUE; | 
|  | pFrame->mbInShow = TRUE; | 
|  |  | 
|  | // #i4715, save position | 
|  | RECT aRectPreMatrox, aRectPostMatrox; | 
|  | GetWindowRect( hWnd, &aRectPreMatrox ); | 
|  |  | 
|  | vcl::DeletionListener aDogTag( pFrame ); | 
|  | if( bNoActivate ) | 
|  | ShowWindow( hWnd, SW_SHOWNOACTIVATE ); | 
|  | else | 
|  | ShowWindow( hWnd, pFrame->mnShowState ); | 
|  | if( aDogTag.isDeleted() ) | 
|  | return; | 
|  |  | 
|  | if ( aSalShlData.mbWXP && pFrame->mbFloatWin && !(pFrame->mnStyle & SAL_FRAME_STYLE_NOSHADOW)) | 
|  | { | 
|  | // erase the window immediately to improve XP shadow effect | 
|  | // otherwise the shadow may appears long time before the rest of the window | 
|  | // especially when accessibility is on | 
|  | HDC dc = GetDC( hWnd ); | 
|  | RECT aRect; | 
|  | GetClientRect( hWnd, &aRect ); | 
|  | FillRect( dc, &aRect, (HBRUSH) (COLOR_MENU+1) ); // choose the menucolor, because it's mostly noticeable for menus | 
|  | ReleaseDC( hWnd, dc ); | 
|  | } | 
|  |  | 
|  | // #i4715, matrox centerpopup might have changed our position | 
|  | // reposition popups without caption (menus, dropdowns, tooltips) | 
|  | GetWindowRect( hWnd, &aRectPostMatrox ); | 
|  | if( (GetWindowStyle( hWnd ) & WS_POPUP) && | 
|  | !pFrame->mbCaption && | 
|  | (aRectPreMatrox.left != aRectPostMatrox.left || aRectPreMatrox.top != aRectPostMatrox.top) ) | 
|  | SetWindowPos( hWnd, 0, aRectPreMatrox.left, aRectPreMatrox.top, 0, 0, SWP_NOZORDER | SWP_NOACTIVATE | SWP_NOSIZE  ); | 
|  |  | 
|  | if( aDogTag.isDeleted() ) | 
|  | return; | 
|  | Window *pClientWin = pFrame->GetWindow()->ImplGetClientWindow(); | 
|  | if ( pFrame->mbFloatWin || ( pClientWin && (pClientWin->GetStyle() & WB_SYSTEMFLOATWIN) ) ) | 
|  | pFrame->mnShowState = SW_SHOWNOACTIVATE; | 
|  | else | 
|  | pFrame->mnShowState = SW_SHOW; | 
|  | // Damit Taskleiste unter W98 auch gleich ausgeblendet wird | 
|  | if ( pFrame->mbPresentation ) | 
|  | { | 
|  | HWND hWndParent = ::GetParent( hWnd ); | 
|  | if ( hWndParent ) | 
|  | SetForegroundWindow( hWndParent ); | 
|  | SetForegroundWindow( hWnd ); | 
|  | } | 
|  |  | 
|  | pFrame->mbInShow = FALSE; | 
|  | pFrame->updateScreenNumber(); | 
|  |  | 
|  | // Direct Paint only, if we get the SolarMutx | 
|  | if ( ImplSalYieldMutexTryToAcquire() ) | 
|  | { | 
|  | UpdateWindow( hWnd ); | 
|  | ImplSalYieldMutexRelease(); | 
|  | } | 
|  | } | 
|  | else | 
|  | { | 
|  | // See also Bug #91813# and #68467# | 
|  | if ( pFrame->mbFullScreen && | 
|  | pFrame->mbPresentation && | 
|  | (aSalShlData.mnVersion < 500) && | 
|  | !::GetParent( hWnd ) ) | 
|  | { | 
|  | // Damit im Impress-Player in der Taskleiste nicht durch | 
|  | // einen Windows-Fehler hin- und wieder mal ein leerer | 
|  | // Button stehen bleibt, muessen wir hier die Taskleiste | 
|  | // etwas austricksen. Denn wenn wir im FullScreenMode sind | 
|  | // und das Fenster hiden kommt Windows anscheinend etwas aus | 
|  | // dem tritt und somit minimieren wir das Fenster damit es | 
|  | // nicht flackert | 
|  | ANIMATIONINFO aInfo; | 
|  | aInfo.cbSize = sizeof( aInfo ); | 
|  | SystemParametersInfo( SPI_GETANIMATION, 0, &aInfo, 0 ); | 
|  | if ( aInfo.iMinAnimate ) | 
|  | { | 
|  | int nOldAni = aInfo.iMinAnimate; | 
|  | aInfo.iMinAnimate = 0; | 
|  | SystemParametersInfo( SPI_SETANIMATION, 0, &aInfo, 0 ); | 
|  | ShowWindow( pFrame->mhWnd, SW_SHOWMINNOACTIVE ); | 
|  | aInfo.iMinAnimate = nOldAni; | 
|  | SystemParametersInfo( SPI_SETANIMATION, 0, &aInfo, 0 ); | 
|  | } | 
|  | else | 
|  | ShowWindow( hWnd, SW_SHOWMINNOACTIVE ); | 
|  | ShowWindow( hWnd, SW_HIDE ); | 
|  | } | 
|  | else | 
|  | ShowWindow( hWnd, SW_HIDE ); | 
|  | } | 
|  | } | 
|  |  | 
|  | // ----------------------------------------------------------------------- | 
|  |  | 
|  |  | 
|  | void WinSalFrame::SetExtendedFrameStyle( SalExtStyle ) | 
|  | { | 
|  | } | 
|  |  | 
|  | // ----------------------------------------------------------------------- | 
|  |  | 
|  | void WinSalFrame::Show( sal_Bool bVisible, sal_Bool bNoActivate ) | 
|  | { | 
|  | // Post this Message to the window, because this only works | 
|  | // in the thread of the window, which has create this window. | 
|  | // We post this message to avoid deadlocks | 
|  | if ( GetSalData()->mnAppThreadId != GetCurrentThreadId() ) | 
|  | ImplPostMessage( mhWnd, SAL_MSG_SHOW, bVisible, bNoActivate ); | 
|  | else | 
|  | ImplSalShow( mhWnd, bVisible, bNoActivate ); | 
|  | } | 
|  |  | 
|  | // ----------------------------------------------------------------------- | 
|  |  | 
|  | void WinSalFrame::Enable( sal_Bool bEnable ) | 
|  | { | 
|  | EnableWindow( mhWnd, bEnable ); | 
|  | } | 
|  |  | 
|  | // ----------------------------------------------------------------------- | 
|  |  | 
|  | void WinSalFrame::SetMinClientSize( long nWidth, long nHeight ) | 
|  | { | 
|  | mnMinWidth  = nWidth; | 
|  | mnMinHeight = nHeight; | 
|  | } | 
|  |  | 
|  | void WinSalFrame::SetMaxClientSize( long nWidth, long nHeight ) | 
|  | { | 
|  | mnMaxWidth  = nWidth; | 
|  | mnMaxHeight = nHeight; | 
|  | } | 
|  |  | 
|  | // ----------------------------------------------------------------------- | 
|  |  | 
|  | void WinSalFrame::SetPosSize( long nX, long nY, long nWidth, long nHeight, | 
|  | sal_uInt16 nFlags ) | 
|  | { | 
|  | sal_Bool bVisible = (GetWindowStyle( mhWnd ) & WS_VISIBLE) != 0; | 
|  | if ( !bVisible ) | 
|  | { | 
|  | Window *pClientWin = GetWindow()->ImplGetClientWindow(); | 
|  | if ( mbFloatWin || ( pClientWin && (pClientWin->GetStyle() & WB_SYSTEMFLOATWIN) ) ) | 
|  | mnShowState = SW_SHOWNOACTIVATE; | 
|  | else | 
|  | mnShowState = SW_SHOWNORMAL; | 
|  | } | 
|  | else | 
|  | { | 
|  | if ( IsIconic( mhWnd ) || IsZoomed( mhWnd ) ) | 
|  | ShowWindow( mhWnd, SW_RESTORE ); | 
|  | } | 
|  |  | 
|  | sal_uInt16 nEvent = 0; | 
|  | UINT    nPosSize = 0; | 
|  | RECT    aClientRect, aWindowRect; | 
|  | GetClientRect( mhWnd, &aClientRect );   // x,y always 0,0, but width and height without border | 
|  | GetWindowRect( mhWnd, &aWindowRect );   // x,y in screen coordinates, width and height with border | 
|  |  | 
|  | if ( !(nFlags & (SAL_FRAME_POSSIZE_X | SAL_FRAME_POSSIZE_Y)) ) | 
|  | nPosSize |= SWP_NOMOVE; | 
|  | else | 
|  | { | 
|  | //DBG_ASSERT( nX && nY, " Windowposition of (0,0) requested!" ); | 
|  | nEvent = SALEVENT_MOVE; | 
|  | } | 
|  | if ( !(nFlags & (SAL_FRAME_POSSIZE_WIDTH | SAL_FRAME_POSSIZE_HEIGHT)) ) | 
|  | nPosSize |= SWP_NOSIZE; | 
|  | else | 
|  | nEvent = (nEvent == SALEVENT_MOVE) ? SALEVENT_MOVERESIZE : SALEVENT_RESIZE; | 
|  |  | 
|  | if ( !(nFlags & SAL_FRAME_POSSIZE_X) ) | 
|  | nX = aWindowRect.left; | 
|  | if ( !(nFlags & SAL_FRAME_POSSIZE_Y) ) | 
|  | nY = aWindowRect.top; | 
|  | if ( !(nFlags & SAL_FRAME_POSSIZE_WIDTH) ) | 
|  | nWidth = aClientRect.right-aClientRect.left; | 
|  | if ( !(nFlags & SAL_FRAME_POSSIZE_HEIGHT) ) | 
|  | nHeight = aClientRect.bottom-aClientRect.top; | 
|  |  | 
|  | // Calculate window size including the border | 
|  | RECT    aWinRect; | 
|  | aWinRect.left   = 0; | 
|  | aWinRect.right  = (int)nWidth-1; | 
|  | aWinRect.top    = 0; | 
|  | aWinRect.bottom = (int)nHeight-1; | 
|  | AdjustWindowRectEx( &aWinRect, GetWindowStyle( mhWnd ), | 
|  | FALSE,     GetWindowExStyle( mhWnd ) ); | 
|  | nWidth  = aWinRect.right - aWinRect.left + 1; | 
|  | nHeight = aWinRect.bottom - aWinRect.top + 1; | 
|  |  | 
|  | if ( !(nPosSize & SWP_NOMOVE) && ::GetParent( mhWnd ) ) | 
|  | { | 
|  | // --- RTL --- (mirror window pos) | 
|  | RECT aParentRect; | 
|  | GetClientRect( ImplGetParentHwnd( mhWnd ), &aParentRect ); | 
|  | if( Application::GetSettings().GetLayoutRTL() ) | 
|  | nX = (aParentRect.right - aParentRect.left) - nWidth-1 - nX; | 
|  |  | 
|  | //#110386#, do not transform coordinates for system child windows | 
|  | if( !(GetWindowStyle( mhWnd ) & WS_CHILD) ) | 
|  | { | 
|  | POINT aPt; | 
|  | aPt.x = nX; | 
|  | aPt.y = nY; | 
|  |  | 
|  | HWND parentHwnd = ImplGetParentHwnd( mhWnd ); | 
|  | WinSalFrame* pParentFrame = GetWindowPtr( parentHwnd ); | 
|  | if ( pParentFrame && pParentFrame->mnShowState == SW_SHOWMAXIMIZED ) | 
|  | { | 
|  | // #i42485#: parent will be shown maximized in which case | 
|  | // a ClientToScreen uses the wrong coordinates (i.e. those from the restore pos) | 
|  | // so use the (already updated) frame geometry for the transformation | 
|  | aPt.x +=  pParentFrame->maGeometry.nX; | 
|  | aPt.y +=  pParentFrame->maGeometry.nY; | 
|  | } | 
|  | else | 
|  | ClientToScreen( parentHwnd, &aPt ); | 
|  |  | 
|  | nX = aPt.x; | 
|  | nY = aPt.y; | 
|  | } | 
|  | } | 
|  |  | 
|  | // #i3338# to be conformant to UNIX we must position the client window, i.e. without the decoration | 
|  | // #i43250# if the position was read from the system (GetWindowRect(), see above), it must not be modified | 
|  | if ( nFlags & SAL_FRAME_POSSIZE_X ) | 
|  | nX += aWinRect.left; | 
|  | if ( nFlags & SAL_FRAME_POSSIZE_Y ) | 
|  | nY += aWinRect.top; | 
|  |  | 
|  | int     nScreenX; | 
|  | int     nScreenY; | 
|  | int     nScreenWidth; | 
|  | int     nScreenHeight; | 
|  |  | 
|  |  | 
|  | RECT aRect; | 
|  | ImplSalGetWorkArea( mhWnd, &aRect, NULL ); | 
|  | nScreenX        = aRect.left; | 
|  | nScreenY        = aRect.top; | 
|  | nScreenWidth    = aRect.right-aRect.left; | 
|  | nScreenHeight   = aRect.bottom-aRect.top; | 
|  |  | 
|  | if ( mbDefPos && (nPosSize & SWP_NOMOVE)) // we got no positioning request, so choose default position | 
|  | { | 
|  | // center window | 
|  |  | 
|  | HWND hWndParent = ::GetParent( mhWnd ); | 
|  | // Search for TopLevel Frame | 
|  | while ( hWndParent && (GetWindowStyle( hWndParent ) & WS_CHILD) ) | 
|  | hWndParent = ::GetParent( hWndParent ); | 
|  | // if the Window has a Parent, than center the window to | 
|  | // the parent, in the other case to the screen | 
|  | if ( hWndParent && !IsIconic( hWndParent ) && | 
|  | (GetWindowStyle( hWndParent ) & WS_VISIBLE) ) | 
|  | { | 
|  | RECT aParentRect; | 
|  | GetWindowRect( hWndParent, &aParentRect ); | 
|  | int nParentWidth    = aParentRect.right-aParentRect.left; | 
|  | int nParentHeight   = aParentRect.bottom-aParentRect.top; | 
|  |  | 
|  | // We don't center, when Parent is smaller than our window | 
|  | if ( (nParentWidth-GetSystemMetrics( SM_CXFIXEDFRAME ) <= nWidth) && | 
|  | (nParentHeight-GetSystemMetrics( SM_CYFIXEDFRAME ) <= nHeight) ) | 
|  | { | 
|  | int nOff = GetSystemMetrics( SM_CYSIZEFRAME ) + GetSystemMetrics( SM_CYCAPTION ); | 
|  | nX = aParentRect.left+nOff; | 
|  | nY = aParentRect.top+nOff; | 
|  | } | 
|  | else | 
|  | { | 
|  | nX = (nParentWidth-nWidth)/2 + aParentRect.left; | 
|  | nY = (nParentHeight-nHeight)/2 + aParentRect.top; | 
|  | } | 
|  | } | 
|  | else | 
|  | { | 
|  | POINT pt; | 
|  | GetCursorPos( &pt ); | 
|  | RECT aRect; | 
|  | aRect.left = pt.x; | 
|  | aRect.top = pt.y; | 
|  | aRect.right = pt.x+2; | 
|  | aRect.bottom = pt.y+2; | 
|  |  | 
|  | // dualmonitor support: | 
|  | // Get screensize of the monitor with the mouse pointer | 
|  | ImplSalGetWorkArea( mhWnd, &aRect, &aRect ); | 
|  |  | 
|  | nX = ((aRect.right-aRect.left)-nWidth)/2 + aRect.left; | 
|  | nY = ((aRect.bottom-aRect.top)-nHeight)/2 + aRect.top; | 
|  | } | 
|  |  | 
|  |  | 
|  | //if ( bVisible ) | 
|  | //    mbDefPos = FALSE; | 
|  |  | 
|  | mbDefPos = FALSE;   // center only once | 
|  | nPosSize &= ~SWP_NOMOVE;        // activate positioning | 
|  | nEvent = SALEVENT_MOVERESIZE; | 
|  | } | 
|  |  | 
|  |  | 
|  | // Adjust Window in the screen | 
|  | sal_Bool bCheckOffScreen = TRUE; | 
|  |  | 
|  | // but don't do this for floaters or ownerdraw windows that are currently moved interactively | 
|  | if( (mnStyle & SAL_FRAME_STYLE_FLOAT) && !(mnStyle & SAL_FRAME_STYLE_OWNERDRAWDECORATION) ) | 
|  | bCheckOffScreen = FALSE; | 
|  |  | 
|  | if( mnStyle & SAL_FRAME_STYLE_OWNERDRAWDECORATION ) | 
|  | { | 
|  | // may be the window is currently being moved (mouse is captured), then no check is required | 
|  | if( mhWnd == ::GetCapture() ) | 
|  | bCheckOffScreen = FALSE; | 
|  | else | 
|  | bCheckOffScreen = TRUE; | 
|  | } | 
|  |  | 
|  | if( bCheckOffScreen ) | 
|  | { | 
|  | if ( nX+nWidth > nScreenX+nScreenWidth ) | 
|  | nX = (nScreenX+nScreenWidth) - nWidth; | 
|  | if ( nY+nHeight > nScreenY+nScreenHeight ) | 
|  | nY = (nScreenY+nScreenHeight) - nHeight; | 
|  | if ( nX < nScreenX ) | 
|  | nX = nScreenX; | 
|  | if ( nY < nScreenY ) | 
|  | nY = nScreenY; | 
|  | } | 
|  |  | 
|  | UINT nPosFlags = SWP_NOACTIVATE | SWP_NOOWNERZORDER | nPosSize; | 
|  | // bring floating windows always to top | 
|  | if( !(mnStyle & SAL_FRAME_STYLE_FLOAT) ) | 
|  | nPosFlags |= SWP_NOZORDER; // do not change z-order | 
|  |  | 
|  | SetWindowPos( mhWnd, HWND_TOP, nX, nY, (int)nWidth, (int)nHeight, nPosFlags  ); | 
|  |  | 
|  | UpdateFrameGeometry( mhWnd, this ); | 
|  |  | 
|  | // Notification -- really ??? | 
|  | if( nEvent ) | 
|  | CallCallback( nEvent, NULL ); | 
|  | } | 
|  |  | 
|  | // ----------------------------------------------------------------------- | 
|  |  | 
|  | static void ImplSetParentFrame( WinSalFrame* pThis, HWND hNewParentWnd, sal_Bool bAsChild ) | 
|  | { | 
|  | // save hwnd, will be overwritten in WM_CREATE during createwindow | 
|  | HWND hWndOld = pThis->mhWnd; | 
|  | HWND hWndOldParent = ::GetParent( hWndOld ); | 
|  | SalData* pSalData = GetSalData(); | 
|  |  | 
|  | if( hNewParentWnd == hWndOldParent ) | 
|  | return; | 
|  |  | 
|  | ::std::vector< WinSalFrame* > children; | 
|  | ::std::vector< WinSalObject* > systemChildren; | 
|  |  | 
|  | // search child windows | 
|  | WinSalFrame *pFrame = pSalData->mpFirstFrame; | 
|  | while( pFrame ) | 
|  | { | 
|  | HWND hWndParent = ::GetParent( pFrame->mhWnd ); | 
|  | if( pThis->mhWnd == hWndParent ) | 
|  | children.push_back( pFrame ); | 
|  | pFrame = pFrame->mpNextFrame; | 
|  | } | 
|  |  | 
|  | // search system child windows (plugins etc.) | 
|  | WinSalObject *pObject = pSalData->mpFirstObject; | 
|  | while( pObject ) | 
|  | { | 
|  | HWND hWndParent = ::GetParent( pObject->mhWnd ); | 
|  | if( pThis->mhWnd == hWndParent ) | 
|  | systemChildren.push_back( pObject ); | 
|  | pObject = pObject->mpNextObject; | 
|  | } | 
|  |  | 
|  | sal_Bool bNeedGraphics = pThis->mbGraphics; | 
|  | sal_Bool bNeedCacheDC  = FALSE; | 
|  |  | 
|  | HFONT   hFont   = NULL; | 
|  | HPEN    hPen    = NULL; | 
|  | HBRUSH  hBrush  = NULL; | 
|  |  | 
|  | #if OSL_DEBUG_LEVEL > 0 | 
|  | int oldCount = pSalData->mnCacheDCInUse; | 
|  | (void)oldCount; | 
|  | #endif | 
|  |  | 
|  | // Release Cache DC | 
|  | if ( pThis->mpGraphics2 && | 
|  | pThis->mpGraphics2->getHDC() ) | 
|  | { | 
|  | // save current gdi objects before hdc is gone | 
|  | hFont   = (HFONT)   GetCurrentObject( pThis->mpGraphics2->getHDC(), OBJ_FONT); | 
|  | hPen    = (HPEN)    GetCurrentObject( pThis->mpGraphics2->getHDC(), OBJ_PEN); | 
|  | hBrush  = (HBRUSH)  GetCurrentObject( pThis->mpGraphics2->getHDC(), OBJ_BRUSH); | 
|  | pThis->ReleaseGraphics( pThis->mpGraphics2 ); | 
|  |  | 
|  | // recreate cache dc only if it was destroyed | 
|  | bNeedCacheDC  = TRUE; | 
|  | } | 
|  |  | 
|  | // destroy saved DC | 
|  | if ( pThis->mpGraphics ) | 
|  | { | 
|  | if ( pThis->mpGraphics->mhDefPal ) | 
|  | SelectPalette( pThis->mpGraphics->getHDC(), pThis->mpGraphics->mhDefPal, TRUE ); | 
|  | ImplSalDeInitGraphics( pThis->mpGraphics ); | 
|  | ReleaseDC( pThis->mhWnd, pThis->mpGraphics->getHDC() ); | 
|  | } | 
|  |  | 
|  | // create a new hwnd with the same styles | 
|  | HWND hWndParent = hNewParentWnd; | 
|  | // forward to main thread | 
|  | HWND hWnd = (HWND) ImplSendMessage( pSalData->mpFirstInstance->mhComWnd, | 
|  | bAsChild ? SAL_MSG_RECREATECHILDHWND : SAL_MSG_RECREATEHWND, | 
|  | (WPARAM) hWndParent, (LPARAM)pThis->mhWnd ); | 
|  |  | 
|  | // succeeded ? | 
|  | DBG_ASSERT( IsWindow( hWnd ), "WinSalFrame::SetParent not successful"); | 
|  |  | 
|  | // recreate DCs | 
|  | if( bNeedGraphics ) | 
|  | { | 
|  | if( pThis->mpGraphics2 ) | 
|  | { | 
|  | pThis->mpGraphics2->mhWnd = hWnd; | 
|  |  | 
|  | if( bNeedCacheDC ) | 
|  | { | 
|  | // re-create cached DC | 
|  | HDC hDC = (HDC)ImplSendMessage( pSalData->mpFirstInstance->mhComWnd, | 
|  | SAL_MSG_GETDC, | 
|  | (WPARAM) hWnd, 0 ); | 
|  | if ( hDC ) | 
|  | { | 
|  | pThis->mpGraphics2->setHDC(hDC); | 
|  | if ( pSalData->mhDitherPal ) | 
|  | { | 
|  | pThis->mpGraphics2->mhDefPal = SelectPalette( hDC, pSalData->mhDitherPal, TRUE ); | 
|  | RealizePalette( hDC ); | 
|  | } | 
|  | ImplSalInitGraphics( pThis->mpGraphics2 ); | 
|  |  | 
|  | // re-select saved gdi objects | 
|  | if( hFont ) | 
|  | SelectObject( hDC, hFont ); | 
|  | if( hPen ) | 
|  | SelectObject( hDC, hPen ); | 
|  | if( hBrush ) | 
|  | SelectObject( hDC, hBrush ); | 
|  |  | 
|  | pThis->mbGraphics = TRUE; | 
|  |  | 
|  | pSalData->mnCacheDCInUse++; | 
|  |  | 
|  | DBG_ASSERT( oldCount == pSalData->mnCacheDCInUse, "WinSalFrame::SetParent() hDC count corrupted"); | 
|  | } | 
|  | } | 
|  | } | 
|  |  | 
|  | if( pThis->mpGraphics ) | 
|  | { | 
|  | // re-create DC | 
|  | pThis->mpGraphics->mhWnd = hWnd; | 
|  | pThis->mpGraphics->setHDC( GetDC( hWnd ) ); | 
|  | if ( GetSalData()->mhDitherPal ) | 
|  | { | 
|  | pThis->mpGraphics->mhDefPal = SelectPalette( pThis->mpGraphics->getHDC(), GetSalData()->mhDitherPal, TRUE ); | 
|  | RealizePalette( pThis->mpGraphics->getHDC() ); | 
|  | } | 
|  | ImplSalInitGraphics( pThis->mpGraphics ); | 
|  | pThis->mbGraphics = TRUE; | 
|  | } | 
|  | } | 
|  |  | 
|  |  | 
|  | // TODO: add SetParent() call for SalObjects | 
|  | DBG_ASSERT( systemChildren.empty(), "WinSalFrame::SetParent() parent of living system child window will be destroyed!"); | 
|  |  | 
|  | // reparent children before old parent is destroyed | 
|  | for( ::std::vector< WinSalFrame* >::iterator iChild = children.begin(); iChild != children.end(); iChild++ ) | 
|  | ImplSetParentFrame( *iChild, hWnd, FALSE ); | 
|  |  | 
|  | children.clear(); | 
|  | systemChildren.clear(); | 
|  |  | 
|  | // Now destroy original HWND in the thread where it was created. | 
|  | ImplSendMessage( GetSalData()->mpFirstInstance->mhComWnd, | 
|  | SAL_MSG_DESTROYHWND, (WPARAM) 0, (LPARAM)hWndOld); | 
|  | } | 
|  |  | 
|  | // ----------------------------------------------------------------------- | 
|  |  | 
|  | void WinSalFrame::SetParent( SalFrame* pNewParent ) | 
|  | { | 
|  | WinSalFrame::mbInReparent = TRUE; | 
|  | ImplSetParentFrame( this, static_cast<WinSalFrame*>(pNewParent)->mhWnd, FALSE ); | 
|  | WinSalFrame::mbInReparent = FALSE; | 
|  | } | 
|  |  | 
|  | bool WinSalFrame::SetPluginParent( SystemParentData* pNewParent ) | 
|  | { | 
|  | if ( pNewParent->hWnd == 0 ) | 
|  | { | 
|  | pNewParent->hWnd = GetDesktopWindow(); | 
|  | } | 
|  |  | 
|  | WinSalFrame::mbInReparent = TRUE; | 
|  | ImplSetParentFrame( this, pNewParent->hWnd, TRUE ); | 
|  | WinSalFrame::mbInReparent = FALSE; | 
|  | return true; | 
|  | } | 
|  |  | 
|  |  | 
|  | // ----------------------------------------------------------------------- | 
|  |  | 
|  | void WinSalFrame::GetWorkArea( Rectangle &rRect ) | 
|  | { | 
|  | RECT aRect; | 
|  | ImplSalGetWorkArea( mhWnd, &aRect, NULL ); | 
|  | rRect.nLeft     = aRect.left; | 
|  | rRect.nRight    = aRect.right-1; | 
|  | rRect.nTop      = aRect.top; | 
|  | rRect.nBottom   = aRect.bottom-1; | 
|  | } | 
|  |  | 
|  | // ----------------------------------------------------------------------- | 
|  |  | 
|  | void WinSalFrame::GetClientSize( long& rWidth, long& rHeight ) | 
|  | { | 
|  | rWidth  = maGeometry.nWidth; | 
|  | rHeight = maGeometry.nHeight; | 
|  | } | 
|  |  | 
|  | // ----------------------------------------------------------------------- | 
|  |  | 
|  | void WinSalFrame::SetWindowState( const SalFrameState* pState ) | 
|  | { | 
|  | // Wir testen, ob das Fenster ueberhaupt auf den Bildschirm passt, damit | 
|  | // nicht wenn die Bildschirm-Aufloesung geaendert wurde, das Fenster aus | 
|  | // diesem herausragt | 
|  | int     nX; | 
|  | int     nY; | 
|  | int     nWidth; | 
|  | int     nHeight; | 
|  | int     nScreenX; | 
|  | int     nScreenY; | 
|  | int     nScreenWidth; | 
|  | int     nScreenHeight; | 
|  |  | 
|  | RECT aRect; | 
|  | ImplSalGetWorkArea( mhWnd, &aRect, NULL ); | 
|  | // #102500# allow some overlap, the window could have been made a little larger than the physical screen | 
|  | nScreenX        = aRect.left-10; | 
|  | nScreenY        = aRect.top-10; | 
|  | nScreenWidth    = aRect.right-aRect.left+20; | 
|  | nScreenHeight   = aRect.bottom-aRect.top+20; | 
|  |  | 
|  | UINT    nPosSize    = 0; | 
|  | RECT    aWinRect; | 
|  | GetWindowRect( mhWnd, &aWinRect ); | 
|  |  | 
|  | // to be consistent with Unix, the frame state is without(!) decoration | 
|  | // ->add the decoration | 
|  | RECT aRect2 = aWinRect; | 
|  | AdjustWindowRectEx( &aRect2, GetWindowStyle( mhWnd ), | 
|  | FALSE,     GetWindowExStyle( mhWnd ) ); | 
|  | long nTopDeco = abs( aWinRect.top - aRect2.top ); | 
|  | long nLeftDeco = abs( aWinRect.left - aRect2.left ); | 
|  | long nBottomDeco = abs( aWinRect.bottom - aRect2.bottom ); | 
|  | long nRightDeco = abs( aWinRect.right - aRect2.right ); | 
|  |  | 
|  | // Fenster-Position/Groesse in den Bildschirm einpassen | 
|  | if ( !(pState->mnMask & (SAL_FRAMESTATE_MASK_X | SAL_FRAMESTATE_MASK_Y)) ) | 
|  | nPosSize |= SWP_NOMOVE; | 
|  | if ( !(pState->mnMask & (SAL_FRAMESTATE_MASK_WIDTH | SAL_FRAMESTATE_MASK_HEIGHT)) ) | 
|  | nPosSize |= SWP_NOSIZE; | 
|  | if ( pState->mnMask & SAL_FRAMESTATE_MASK_X ) | 
|  | nX = (int)pState->mnX - nLeftDeco; | 
|  | else | 
|  | nX = aWinRect.left; | 
|  | if ( pState->mnMask & SAL_FRAMESTATE_MASK_Y ) | 
|  | nY = (int)pState->mnY - nTopDeco; | 
|  | else | 
|  | nY = aWinRect.top; | 
|  | if ( pState->mnMask & SAL_FRAMESTATE_MASK_WIDTH ) | 
|  | nWidth = (int)pState->mnWidth + nLeftDeco + nRightDeco; | 
|  | else | 
|  | nWidth = aWinRect.right-aWinRect.left; | 
|  | if ( pState->mnMask & SAL_FRAMESTATE_MASK_HEIGHT ) | 
|  | nHeight = (int)pState->mnHeight + nTopDeco + nBottomDeco; | 
|  | else | 
|  | nHeight = aWinRect.bottom-aWinRect.top; | 
|  |  | 
|  | // Adjust Window in the screen: | 
|  | // if it does not fit into the screen do nothing, i.e. default pos/size will be used | 
|  | // if there is an overlap with the screen border move the window while keeping its size | 
|  |  | 
|  | if( nWidth > nScreenWidth || nHeight > nScreenHeight ) | 
|  | nPosSize |= (SWP_NOMOVE | SWP_NOSIZE); | 
|  |  | 
|  | if ( nX+nWidth > nScreenX+nScreenWidth ) | 
|  | nX = (nScreenX+nScreenWidth) - nWidth; | 
|  | if ( nY+nHeight > nScreenY+nScreenHeight ) | 
|  | nY = (nScreenY+nScreenHeight) - nHeight; | 
|  | if ( nX < nScreenX ) | 
|  | nX = nScreenX; | 
|  | if ( nY < nScreenY ) | 
|  | nY = nScreenY; | 
|  |  | 
|  | // Restore-Position setzen | 
|  | WINDOWPLACEMENT aPlacement; | 
|  | aPlacement.length = sizeof( aPlacement ); | 
|  | GetWindowPlacement( mhWnd, &aPlacement ); | 
|  |  | 
|  | // Status setzen | 
|  | sal_Bool bVisible = (GetWindowStyle( mhWnd ) & WS_VISIBLE) != 0; | 
|  | sal_Bool bUpdateHiddenFramePos = FALSE; | 
|  | if ( !bVisible ) | 
|  | { | 
|  | aPlacement.showCmd = SW_HIDE; | 
|  |  | 
|  | if ( mbOverwriteState ) | 
|  | { | 
|  | if ( pState->mnMask & SAL_FRAMESTATE_MASK_STATE ) | 
|  | { | 
|  | if ( pState->mnState & SAL_FRAMESTATE_MINIMIZED ) | 
|  | mnShowState = SW_SHOWMINIMIZED; | 
|  | else if ( pState->mnState & SAL_FRAMESTATE_MAXIMIZED ) | 
|  | { | 
|  | mnShowState = SW_SHOWMAXIMIZED; | 
|  | bUpdateHiddenFramePos = TRUE; | 
|  | } | 
|  | else if ( pState->mnState & SAL_FRAMESTATE_NORMAL ) | 
|  | mnShowState = SW_SHOWNORMAL; | 
|  | } | 
|  | } | 
|  | } | 
|  | else | 
|  | { | 
|  | if ( pState->mnMask & SAL_FRAMESTATE_MASK_STATE ) | 
|  | { | 
|  | if ( pState->mnState & SAL_FRAMESTATE_MINIMIZED ) | 
|  | { | 
|  | if ( pState->mnState & SAL_FRAMESTATE_MAXIMIZED ) | 
|  | aPlacement.flags |= WPF_RESTORETOMAXIMIZED; | 
|  | aPlacement.showCmd = SW_SHOWMINIMIZED; | 
|  | } | 
|  | else if ( pState->mnState & SAL_FRAMESTATE_MAXIMIZED ) | 
|  | aPlacement.showCmd = SW_SHOWMAXIMIZED; | 
|  | else if ( pState->mnState & SAL_FRAMESTATE_NORMAL ) | 
|  | aPlacement.showCmd = SW_RESTORE; | 
|  | } | 
|  | } | 
|  |  | 
|  | // if a window is neither minimized nor maximized or need not be | 
|  | // positioned visibly (that is in visible state), do not use | 
|  | // SetWindowPlacement since it calculates including the TaskBar | 
|  | if ( !IsIconic( mhWnd ) && !IsZoomed( mhWnd ) && | 
|  | (!bVisible || (aPlacement.showCmd == SW_RESTORE)) ) | 
|  | { | 
|  | if( bUpdateHiddenFramePos ) | 
|  | { | 
|  | RECT aStateRect; | 
|  | aStateRect.left   = nX; | 
|  | aStateRect.top    = nY; | 
|  | aStateRect.right  = nX+nWidth; | 
|  | aStateRect.bottom = nY+nHeight; | 
|  | // #96084 set a useful internal window size because | 
|  | // the window will not be maximized (and the size updated) before show() | 
|  | SetMaximizedFrameGeometry( mhWnd, this, &aStateRect ); | 
|  | SetWindowPos( mhWnd, 0, | 
|  | maGeometry.nX, maGeometry.nY, maGeometry.nWidth, maGeometry.nHeight, | 
|  | SWP_NOZORDER | SWP_NOACTIVATE | nPosSize ); | 
|  | } | 
|  | else | 
|  | SetWindowPos( mhWnd, 0, | 
|  | nX, nY, nWidth, nHeight, | 
|  | SWP_NOZORDER | SWP_NOACTIVATE | nPosSize ); | 
|  | } | 
|  | else | 
|  | { | 
|  | if( !(nPosSize & (SWP_NOMOVE|SWP_NOSIZE)) ) | 
|  | { | 
|  | aPlacement.rcNormalPosition.left    = nX-nScreenX; | 
|  | aPlacement.rcNormalPosition.top     = nY-nScreenY; | 
|  | aPlacement.rcNormalPosition.right   = nX+nWidth-nScreenX; | 
|  | aPlacement.rcNormalPosition.bottom  = nY+nHeight-nScreenY; | 
|  | } | 
|  | SetWindowPlacement( mhWnd, &aPlacement ); | 
|  | } | 
|  |  | 
|  | if( !(nPosSize & SWP_NOMOVE) ) | 
|  | mbDefPos = FALSE; // window was positioned | 
|  | } | 
|  |  | 
|  | // ----------------------------------------------------------------------- | 
|  |  | 
|  | sal_Bool WinSalFrame::GetWindowState( SalFrameState* pState ) | 
|  | { | 
|  | if ( maState.mnWidth && maState.mnHeight ) | 
|  | { | 
|  | *pState = maState; | 
|  | // #94144# allow Minimize again, should be masked out when read from configuration | 
|  | // 91625 - Don't save minimize | 
|  | //if ( !(pState->mnState & SAL_FRAMESTATE_MAXIMIZED) ) | 
|  | if ( !(pState->mnState & (SAL_FRAMESTATE_MINIMIZED | SAL_FRAMESTATE_MAXIMIZED)) ) | 
|  | pState->mnState |= SAL_FRAMESTATE_NORMAL; | 
|  | return TRUE; | 
|  | } | 
|  |  | 
|  | return FALSE; | 
|  | } | 
|  |  | 
|  | // ----------------------------------------------------------------------- | 
|  |  | 
|  | void WinSalFrame::SetScreenNumber( unsigned int nNewScreen ) | 
|  | { | 
|  | WinSalSystem* pSys = static_cast<WinSalSystem*>(ImplGetSalSystem()); | 
|  | if( pSys ) | 
|  | { | 
|  | const std::vector<WinSalSystem::DisplayMonitor>& rMonitors = | 
|  | pSys->getMonitors(); | 
|  | size_t nMon = rMonitors.size(); | 
|  | if( nNewScreen < nMon ) | 
|  | { | 
|  | Point aOldMonPos, aNewMonPos( rMonitors[nNewScreen].m_aArea.TopLeft() ); | 
|  | Point aCurPos( maGeometry.nX, maGeometry.nY ); | 
|  | for( size_t i = 0; i < nMon; i++ ) | 
|  | { | 
|  | if( rMonitors[i].m_aArea.IsInside( aCurPos ) ) | 
|  | { | 
|  | aOldMonPos = rMonitors[i].m_aArea.TopLeft(); | 
|  | break; | 
|  | } | 
|  | } | 
|  | mnDisplay = nNewScreen; | 
|  | maGeometry.nScreenNumber = nNewScreen; | 
|  | SetPosSize( aNewMonPos.X() + (maGeometry.nX - aOldMonPos.X()), | 
|  | aNewMonPos.Y() + (maGeometry.nY - aOldMonPos.Y()), | 
|  | 0, 0, | 
|  | SAL_FRAME_POSSIZE_X | SAL_FRAME_POSSIZE_Y ); | 
|  | } | 
|  | } | 
|  | } | 
|  |  | 
|  | // ----------------------------------------------------------------------- | 
|  |  | 
|  | void WinSalFrame::ShowFullScreen( sal_Bool bFullScreen, sal_Int32 nDisplay ) | 
|  | { | 
|  | if ( (mbFullScreen == bFullScreen) && (!bFullScreen || (mnDisplay == nDisplay)) ) | 
|  | return; | 
|  |  | 
|  | mbFullScreen = bFullScreen; | 
|  | mnDisplay = nDisplay; | 
|  |  | 
|  | if ( bFullScreen ) | 
|  | { | 
|  | // Damit Taskleiste von Windows ausgeblendet wird | 
|  | DWORD nExStyle = GetWindowExStyle( mhWnd ); | 
|  | if ( nExStyle & WS_EX_TOOLWINDOW ) | 
|  | { | 
|  | mbFullScreenToolWin = TRUE; | 
|  | nExStyle &= ~WS_EX_TOOLWINDOW; | 
|  | SetWindowExStyle( mhWnd, nExStyle ); | 
|  | } | 
|  | // save old position | 
|  | GetWindowRect( mhWnd, &maFullScreenRect ); | 
|  |  | 
|  | // save show state | 
|  | mnFullScreenShowState = mnShowState; | 
|  | if ( !(GetWindowStyle( mhWnd ) & WS_VISIBLE) ) | 
|  | mnShowState = SW_SHOW; | 
|  |  | 
|  | // set window to screen size | 
|  | ImplSalFrameFullScreenPos( this, TRUE ); | 
|  | } | 
|  | else | 
|  | { | 
|  | // wenn ShowState wieder hergestellt werden muss, hiden wir zuerst | 
|  | // das Fenster, damit es nicht so sehr flackert | 
|  | sal_Bool bVisible = (GetWindowStyle( mhWnd ) & WS_VISIBLE) != 0; | 
|  | if ( bVisible && (mnShowState != mnFullScreenShowState) ) | 
|  | ShowWindow( mhWnd, SW_HIDE ); | 
|  |  | 
|  | if ( mbFullScreenToolWin ) | 
|  | SetWindowExStyle( mhWnd, GetWindowExStyle( mhWnd ) | WS_EX_TOOLWINDOW ); | 
|  | mbFullScreenToolWin = FALSE; | 
|  |  | 
|  | SetWindowPos( mhWnd, 0, | 
|  | maFullScreenRect.left, | 
|  | maFullScreenRect.top, | 
|  | maFullScreenRect.right-maFullScreenRect.left, | 
|  | maFullScreenRect.bottom-maFullScreenRect.top, | 
|  | SWP_NOZORDER | SWP_NOACTIVATE ); | 
|  |  | 
|  | // restore show state | 
|  | if ( mnShowState != mnFullScreenShowState ) | 
|  | { | 
|  | mnShowState = mnFullScreenShowState; | 
|  | if ( bVisible ) | 
|  | { | 
|  | mbInShow = TRUE; | 
|  | ShowWindow( mhWnd, mnShowState ); | 
|  | mbInShow = FALSE; | 
|  | UpdateWindow( mhWnd ); | 
|  | } | 
|  | } | 
|  | } | 
|  | } | 
|  |  | 
|  | // ----------------------------------------------------------------------- | 
|  |  | 
|  | void WinSalFrame::StartPresentation( sal_Bool bStart ) | 
|  | { | 
|  | if ( mbPresentation == bStart ) | 
|  | return; | 
|  |  | 
|  | mbPresentation = bStart; | 
|  |  | 
|  | SalData* pSalData = GetSalData(); | 
|  | if ( bStart ) | 
|  | { | 
|  | if ( !pSalData->mpSageEnableProc ) | 
|  | { | 
|  | if ( pSalData->mnSageStatus != DISABLE_AGENT ) | 
|  | { | 
|  | OFSTRUCT aOS; | 
|  | OpenFile( "SAGE.DLL", &aOS, OF_EXIST ); | 
|  |  | 
|  | if ( !aOS.nErrCode ) | 
|  | { | 
|  | oslModule mhSageInst = osl_loadAsciiModule( aOS.szPathName, SAL_LOADMODULE_DEFAULT ); | 
|  | pSalData->mpSageEnableProc = (SysAgt_Enable_PROC)osl_getAsciiFunctionSymbol( mhSageInst, "System_Agent_Enable" ); | 
|  | } | 
|  | else | 
|  | pSalData->mnSageStatus = DISABLE_AGENT; | 
|  | } | 
|  | } | 
|  |  | 
|  | if ( pSalData->mpSageEnableProc ) | 
|  | { | 
|  | pSalData->mnSageStatus = pSalData->mpSageEnableProc( GET_AGENT_STATUS ); | 
|  | if ( pSalData->mnSageStatus == ENABLE_AGENT ) | 
|  | pSalData->mpSageEnableProc( DISABLE_AGENT ); | 
|  | } | 
|  |  | 
|  | // Bildschirmschoner ausschalten, wenn Praesentation laueft | 
|  | SystemParametersInfo( SPI_GETSCREENSAVEACTIVE, 0, | 
|  | &(pSalData->mbScrSvrEnabled), 0 ); | 
|  | if ( pSalData->mbScrSvrEnabled ) | 
|  | SystemParametersInfo( SPI_SETSCREENSAVEACTIVE, FALSE, 0, 0 ); | 
|  | } | 
|  | else | 
|  | { | 
|  | // Bildschirmschoner wieder einschalten | 
|  | if ( pSalData->mbScrSvrEnabled ) | 
|  | SystemParametersInfo( SPI_SETSCREENSAVEACTIVE, pSalData->mbScrSvrEnabled, 0, 0 ); | 
|  |  | 
|  | // Systemagenten wieder aktivieren | 
|  | if ( pSalData->mnSageStatus == ENABLE_AGENT ) | 
|  | pSalData->mpSageEnableProc( pSalData->mnSageStatus ); | 
|  | } | 
|  | } | 
|  |  | 
|  | // ----------------------------------------------------------------------- | 
|  |  | 
|  | void WinSalFrame::SetAlwaysOnTop( sal_Bool bOnTop ) | 
|  | { | 
|  | HWND hWnd; | 
|  | if ( bOnTop ) | 
|  | hWnd = HWND_TOPMOST; | 
|  | else | 
|  | hWnd = HWND_NOTOPMOST; | 
|  | SetWindowPos( mhWnd, hWnd, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE | SWP_NOACTIVATE ); | 
|  | } | 
|  |  | 
|  | // ----------------------------------------------------------------------- | 
|  |  | 
|  | static void ImplSalToTop( HWND hWnd, sal_uInt16 nFlags ) | 
|  | { | 
|  | WinSalFrame* pToTopFrame = GetWindowPtr( hWnd ); | 
|  | if( pToTopFrame && (pToTopFrame->mnStyle & SAL_FRAME_STYLE_SYSTEMCHILD) != 0 ) | 
|  | BringWindowToTop( hWnd ); | 
|  |  | 
|  | if ( nFlags & SAL_FRAME_TOTOP_FOREGROUNDTASK ) | 
|  | { | 
|  | // This magic code is necessary to connect the input focus of the | 
|  | // current window thread and the thread which owns the window that | 
|  | // should be the new foreground window. | 
|  | HWND   hCurrWnd     = GetForegroundWindow(); | 
|  | DWORD  myThreadID   = GetCurrentThreadId(); | 
|  | DWORD  currThreadID = GetWindowThreadProcessId(hCurrWnd,NULL); | 
|  | AttachThreadInput(myThreadID, currThreadID,TRUE); | 
|  | SetForegroundWindow(hWnd); | 
|  | AttachThreadInput(myThreadID,currThreadID,FALSE); | 
|  | } | 
|  |  | 
|  | if ( nFlags & SAL_FRAME_TOTOP_RESTOREWHENMIN ) | 
|  | { | 
|  | HWND hIconicWnd = hWnd; | 
|  | while ( hIconicWnd ) | 
|  | { | 
|  | if ( IsIconic( hIconicWnd ) ) | 
|  | { | 
|  | WinSalFrame* pFrame = GetWindowPtr( hIconicWnd ); | 
|  | if ( pFrame ) | 
|  | { | 
|  | if ( GetWindowPtr( hWnd )->mbRestoreMaximize ) | 
|  | ShowWindow( hIconicWnd, SW_MAXIMIZE ); | 
|  | else | 
|  | ShowWindow( hIconicWnd, SW_RESTORE ); | 
|  | } | 
|  | else | 
|  | ShowWindow( hIconicWnd, SW_RESTORE ); | 
|  | } | 
|  |  | 
|  | hIconicWnd = ::GetParent( hIconicWnd ); | 
|  | } | 
|  | } | 
|  |  | 
|  | if ( !IsIconic( hWnd ) && IsWindowVisible( hWnd ) ) | 
|  | { | 
|  | SetFocus( hWnd ); | 
|  |  | 
|  | // Windows behauptet oefters mal, das man den Focus hat, obwohl | 
|  | // man diesen nicht hat. Wenn dies der Fall ist, dann versuchen | 
|  | // wir diesen auch ganz richtig zu bekommen. | 
|  | if ( ::GetFocus() == hWnd ) | 
|  | SetForegroundWindow( hWnd ); | 
|  | } | 
|  | } | 
|  |  | 
|  | // ----------------------------------------------------------------------- | 
|  |  | 
|  | void WinSalFrame::ToTop( sal_uInt16 nFlags ) | 
|  | { | 
|  | nFlags &= ~SAL_FRAME_TOTOP_GRABFOCUS;	// this flag is not needed on win32 | 
|  | // Post this Message to the window, because this only works | 
|  | // in the thread of the window, which has create this window. | 
|  | // We post this message to avoid deadlocks | 
|  | if ( GetSalData()->mnAppThreadId != GetCurrentThreadId() ) | 
|  | ImplPostMessage( mhWnd, SAL_MSG_TOTOP, nFlags, 0 ); | 
|  | else | 
|  | ImplSalToTop( mhWnd, nFlags ); | 
|  | } | 
|  |  | 
|  | // ----------------------------------------------------------------------- | 
|  |  | 
|  | void WinSalFrame::SetPointer( PointerStyle ePointerStyle ) | 
|  | { | 
|  | struct ImplPtrData | 
|  | { | 
|  | HCURSOR         mhCursor; | 
|  | LPCSTR          mnSysId; | 
|  | UINT            mnOwnId; | 
|  | }; | 
|  |  | 
|  | static ImplPtrData aImplPtrTab[POINTER_COUNT] = | 
|  | { | 
|  | { 0, IDC_ARROW, 0 },                            // POINTER_ARROW | 
|  | { 0, 0, SAL_RESID_POINTER_NULL },               // POINTER_NULL | 
|  | { 0, IDC_WAIT, 0 },                             // POINTER_WAIT | 
|  | { 0, IDC_IBEAM, 0 },                            // POINTER_TEXT | 
|  | { 0, IDC_HELP, 0 },                             // POINTER_HELP | 
|  | { 0, 0, SAL_RESID_POINTER_CROSS },              // POINTER_CROSS | 
|  | { 0, 0, SAL_RESID_POINTER_MOVE },               // POINTER_MOVE | 
|  | { 0, IDC_SIZENS, 0 },                           // POINTER_NSIZE | 
|  | { 0, IDC_SIZENS, 0 },                           // POINTER_SSIZE | 
|  | { 0, IDC_SIZEWE, 0 },                           // POINTER_WSIZE | 
|  | { 0, IDC_SIZEWE, 0 },                           // POINTER_ESIZE | 
|  | { 0, IDC_SIZENWSE, 0 },                         // POINTER_NWSIZE | 
|  | { 0, IDC_SIZENESW, 0 },                         // POINTER_NESIZE | 
|  | { 0, IDC_SIZENESW, 0 },                         // POINTER_SWSIZE | 
|  | { 0, IDC_SIZENWSE, 0 },                         // POINTER_SESIZE | 
|  | { 0, IDC_SIZENS, 0 },                           // POINTER_WINDOW_NSIZE | 
|  | { 0, IDC_SIZENS, 0 },                           // POINTER_WINDOW_SSIZE | 
|  | { 0, IDC_SIZEWE, 0 },                           // POINTER_WINDOW_WSIZE | 
|  | { 0, IDC_SIZEWE, 0 },                           // POINTER_WINDOW_ESIZE | 
|  | { 0, IDC_SIZENWSE, 0 },                         // POINTER_WINDOW_NWSIZE | 
|  | { 0, IDC_SIZENESW, 0 },                         // POINTER_WINDOW_NESIZE | 
|  | { 0, IDC_SIZENESW, 0 },                         // POINTER_WINDOW_SWSIZE | 
|  | { 0, IDC_SIZENWSE, 0 },                         // POINTER_WINDOW_SESIZE | 
|  | { 0, 0, SAL_RESID_POINTER_HSPLIT },             // POINTER_HSPLIT | 
|  | { 0, 0, SAL_RESID_POINTER_VSPLIT },             // POINTER_VSPLIT | 
|  | { 0, 0, SAL_RESID_POINTER_HSIZEBAR },           // POINTER_HSIZEBAR | 
|  | { 0, 0, SAL_RESID_POINTER_VSIZEBAR },           // POINTER_VSIZEBAR | 
|  | { 0, 0, SAL_RESID_POINTER_HAND },               // POINTER_HAND | 
|  | { 0, 0, SAL_RESID_POINTER_REFHAND },            // POINTER_REFHAND | 
|  | { 0, 0, SAL_RESID_POINTER_PEN },                // POINTER_PEN | 
|  | { 0, 0, SAL_RESID_POINTER_MAGNIFY },            // POINTER_MAGNIFY | 
|  | { 0, 0, SAL_RESID_POINTER_FILL },               // POINTER_FILL | 
|  | { 0, 0, SAL_RESID_POINTER_ROTATE },             // POINTER_ROTATE | 
|  | { 0, 0, SAL_RESID_POINTER_HSHEAR },             // POINTER_HSHEAR | 
|  | { 0, 0, SAL_RESID_POINTER_VSHEAR },             // POINTER_VSHEAR | 
|  | { 0, 0, SAL_RESID_POINTER_MIRROR },             // POINTER_MIRROR | 
|  | { 0, 0, SAL_RESID_POINTER_CROOK },              // POINTER_CROOK | 
|  | { 0, 0, SAL_RESID_POINTER_CROP },               // POINTER_CROP | 
|  | { 0, 0, SAL_RESID_POINTER_MOVEPOINT },          // POINTER_MOVEPOINT | 
|  | { 0, 0, SAL_RESID_POINTER_MOVEBEZIERWEIGHT },   // POINTER_MOVEBEZIERWEIGHT | 
|  | { 0, 0, SAL_RESID_POINTER_MOVEDATA },           // POINTER_MOVEDATA | 
|  | { 0, 0, SAL_RESID_POINTER_COPYDATA },           // POINTER_COPYDATA | 
|  | { 0, 0, SAL_RESID_POINTER_LINKDATA },           // POINTER_LINKDATA | 
|  | { 0, 0, SAL_RESID_POINTER_MOVEDATALINK },       // POINTER_MOVEDATALINK | 
|  | { 0, 0, SAL_RESID_POINTER_COPYDATALINK },       // POINTER_COPYDATALINK | 
|  | { 0, 0, SAL_RESID_POINTER_MOVEFILE },           // POINTER_MOVEFILE | 
|  | { 0, 0, SAL_RESID_POINTER_COPYFILE },           // POINTER_COPYFILE | 
|  | { 0, 0, SAL_RESID_POINTER_LINKFILE },           // POINTER_LINKFILE | 
|  | { 0, 0, SAL_RESID_POINTER_MOVEFILELINK },       // POINTER_MOVEFILELINK | 
|  | { 0, 0, SAL_RESID_POINTER_COPYFILELINK },       // POINTER_COPYFILELINK | 
|  | { 0, 0, SAL_RESID_POINTER_MOVEFILES },          // POINTER_MOVEFILES | 
|  | { 0, 0, SAL_RESID_POINTER_COPYFILES },          // POINTER_COPYFILES | 
|  | { 0, 0, SAL_RESID_POINTER_NOTALLOWED },         // POINTER_NOTALLOWED | 
|  | { 0, 0, SAL_RESID_POINTER_DRAW_LINE },          // POINTER_DRAW_LINE | 
|  | { 0, 0, SAL_RESID_POINTER_DRAW_RECT },          // POINTER_DRAW_RECT | 
|  | { 0, 0, SAL_RESID_POINTER_DRAW_POLYGON },       // POINTER_DRAW_POLYGON | 
|  | { 0, 0, SAL_RESID_POINTER_DRAW_BEZIER },        // POINTER_DRAW_BEZIER | 
|  | { 0, 0, SAL_RESID_POINTER_DRAW_ARC },           // POINTER_DRAW_ARC | 
|  | { 0, 0, SAL_RESID_POINTER_DRAW_PIE },           // POINTER_DRAW_PIE | 
|  | { 0, 0, SAL_RESID_POINTER_DRAW_CIRCLECUT },     // POINTER_DRAW_CIRCLECUT | 
|  | { 0, 0, SAL_RESID_POINTER_DRAW_ELLIPSE },       // POINTER_DRAW_ELLIPSE | 
|  | { 0, 0, SAL_RESID_POINTER_DRAW_FREEHAND },      // POINTER_DRAW_FREEHAND | 
|  | { 0, 0, SAL_RESID_POINTER_DRAW_CONNECT },       // POINTER_DRAW_CONNECT | 
|  | { 0, 0, SAL_RESID_POINTER_DRAW_TEXT },          // POINTER_DRAW_TEXT | 
|  | { 0, 0, SAL_RESID_POINTER_DRAW_CAPTION },       // POINTER_DRAW_CAPTION | 
|  | { 0, 0, SAL_RESID_POINTER_CHART },              // POINTER_CHART | 
|  | { 0, 0, SAL_RESID_POINTER_DETECTIVE },          // POINTER_DETECTIVE | 
|  | { 0, 0, SAL_RESID_POINTER_PIVOT_COL },          // POINTER_PIVOT_COL | 
|  | { 0, 0, SAL_RESID_POINTER_PIVOT_ROW },          // POINTER_PIVOT_ROW | 
|  | { 0, 0, SAL_RESID_POINTER_PIVOT_FIELD },        // POINTER_PIVOT_FIELD | 
|  | { 0, 0, SAL_RESID_POINTER_CHAIN },              // POINTER_CHAIN | 
|  | { 0, 0, SAL_RESID_POINTER_CHAIN_NOTALLOWED },   // POINTER_CHAIN_NOTALLOWED | 
|  | { 0, 0, SAL_RESID_POINTER_TIMEEVENT_MOVE },     // POINTER_TIMEEVENT_MOVE | 
|  | { 0, 0, SAL_RESID_POINTER_TIMEEVENT_SIZE },     // POINTER_TIMEEVENT_SIZE | 
|  | { 0, 0, SAL_RESID_POINTER_AUTOSCROLL_N },       // POINTER_AUTOSCROLL_N | 
|  | { 0, 0, SAL_RESID_POINTER_AUTOSCROLL_S },       // POINTER_AUTOSCROLL_S | 
|  | { 0, 0, SAL_RESID_POINTER_AUTOSCROLL_W },       // POINTER_AUTOSCROLL_W | 
|  | { 0, 0, SAL_RESID_POINTER_AUTOSCROLL_E },       // POINTER_AUTOSCROLL_E | 
|  | { 0, 0, SAL_RESID_POINTER_AUTOSCROLL_NW },      // POINTER_AUTOSCROLL_NW | 
|  | { 0, 0, SAL_RESID_POINTER_AUTOSCROLL_NE },      // POINTER_AUTOSCROLL_NE | 
|  | { 0, 0, SAL_RESID_POINTER_AUTOSCROLL_SW },      // POINTER_AUTOSCROLL_SW | 
|  | { 0, 0, SAL_RESID_POINTER_AUTOSCROLL_SE },      // POINTER_AUTOSCROLL_SE | 
|  | { 0, 0, SAL_RESID_POINTER_AUTOSCROLL_NS },      // POINTER_AUTOSCROLL_NS | 
|  | { 0, 0, SAL_RESID_POINTER_AUTOSCROLL_WE },      // POINTER_AUTOSCROLL_WE | 
|  | { 0, 0, SAL_RESID_POINTER_AUTOSCROLL_NSWE },    // POINTER_AUTOSCROLL_NSWE | 
|  | { 0, 0, SAL_RESID_POINTER_AIRBRUSH },           // POINTER_AIRBRUSH | 
|  | { 0, 0, SAL_RESID_POINTER_TEXT_VERTICAL },      // POINTER_TEXT_VERTICAL | 
|  | { 0, 0, SAL_RESID_POINTER_PIVOT_DELETE },       // POINTER_PIVOT_DELETE | 
|  |  | 
|  | // --> FME 2004-07-30 #i32329# Enhanced table selection | 
|  | { 0, 0, SAL_RESID_POINTER_TAB_SELECT_S },       // POINTER_TAB_SELECT_S | 
|  | { 0, 0, SAL_RESID_POINTER_TAB_SELECT_E },       // POINTER_TAB_SELECT_E | 
|  | { 0, 0, SAL_RESID_POINTER_TAB_SELECT_SE },      // POINTER_TAB_SELECT_SE | 
|  | { 0, 0, SAL_RESID_POINTER_TAB_SELECT_W },       // POINTER_TAB_SELECT_W | 
|  | { 0, 0, SAL_RESID_POINTER_TAB_SELECT_SW },      // POINTER_TAB_SELECT_SW | 
|  | // <-- | 
|  |  | 
|  | // --> FME 2004-08-16 #i20119# Paintbrush tool | 
|  | { 0, 0, SAL_RESID_POINTER_PAINTBRUSH }          // POINTER_PAINTBRUSH | 
|  | // <-- | 
|  |  | 
|  | }; | 
|  |  | 
|  | #if POINTER_COUNT != 94 | 
|  | #error New Pointer must be defined! | 
|  | #endif | 
|  |  | 
|  | // Mousepointer loaded ? | 
|  | if ( !aImplPtrTab[ePointerStyle].mhCursor ) | 
|  | { | 
|  | if ( aImplPtrTab[ePointerStyle].mnOwnId ) | 
|  | aImplPtrTab[ePointerStyle].mhCursor = ImplLoadSalCursor( aImplPtrTab[ePointerStyle].mnOwnId ); | 
|  | else | 
|  | aImplPtrTab[ePointerStyle].mhCursor = LoadCursor( 0, aImplPtrTab[ePointerStyle].mnSysId ); | 
|  | } | 
|  |  | 
|  | // Unterscheidet sich der Mauspointer, dann den neuen setzen | 
|  | if ( mhCursor != aImplPtrTab[ePointerStyle].mhCursor ) | 
|  | { | 
|  | mhCursor = aImplPtrTab[ePointerStyle].mhCursor; | 
|  | SetCursor( mhCursor ); | 
|  | } | 
|  | } | 
|  |  | 
|  | // ----------------------------------------------------------------------- | 
|  |  | 
|  | void WinSalFrame::CaptureMouse( sal_Bool bCapture ) | 
|  | { | 
|  | // Send this Message to the window, because CaptureMouse() only work | 
|  | // in the thread of the window, which has create this window | 
|  | int nMsg; | 
|  | if ( bCapture ) | 
|  | nMsg = SAL_MSG_CAPTUREMOUSE; | 
|  | else | 
|  | nMsg = SAL_MSG_RELEASEMOUSE; | 
|  | ImplSendMessage( mhWnd, nMsg, 0, 0 ); | 
|  | } | 
|  |  | 
|  | // ----------------------------------------------------------------------- | 
|  |  | 
|  | void WinSalFrame::SetPointerPos( long nX, long nY ) | 
|  | { | 
|  | POINT aPt; | 
|  | aPt.x = (int)nX; | 
|  | aPt.y = (int)nY; | 
|  | ClientToScreen( mhWnd, &aPt ); | 
|  | SetCursorPos( aPt.x, aPt.y ); | 
|  | } | 
|  |  | 
|  | // ----------------------------------------------------------------------- | 
|  |  | 
|  | void WinSalFrame::Flush() | 
|  | { | 
|  | GdiFlush(); | 
|  | } | 
|  |  | 
|  | // ----------------------------------------------------------------------- | 
|  |  | 
|  | void WinSalFrame::Sync() | 
|  | { | 
|  | GdiFlush(); | 
|  | } | 
|  |  | 
|  | // ----------------------------------------------------------------------- | 
|  |  | 
|  | static void ImplSalFrameSetInputContext( HWND hWnd, const SalInputContext* pContext ) | 
|  | { | 
|  | WinSalFrame*   pFrame = GetWindowPtr( hWnd ); | 
|  | sal_Bool        bIME = (pContext->mnOptions & SAL_INPUTCONTEXT_TEXT) != 0; | 
|  | if ( bIME ) | 
|  | { | 
|  | if ( !pFrame->mbIME ) | 
|  | { | 
|  | pFrame->mbIME = TRUE; | 
|  |  | 
|  | if ( pFrame->mhDefIMEContext ) | 
|  | { | 
|  | ImmAssociateContext( pFrame->mhWnd, pFrame->mhDefIMEContext ); | 
|  | UINT nImeProps = ImmGetProperty( GetKeyboardLayout( 0 ), IGP_PROPERTY ); | 
|  | pFrame->mbSpezIME = (nImeProps & IME_PROP_SPECIAL_UI) != 0; | 
|  | pFrame->mbAtCursorIME = (nImeProps & IME_PROP_AT_CARET) != 0; | 
|  | pFrame->mbHandleIME = !pFrame->mbSpezIME; | 
|  | } | 
|  | } | 
|  |  | 
|  | // When the application can't handle IME messages, then the | 
|  | // System should handle the IME handling | 
|  | if ( !(pContext->mnOptions & SAL_INPUTCONTEXT_EXTTEXTINPUT) ) | 
|  | pFrame->mbHandleIME = FALSE; | 
|  |  | 
|  | // Set the Font for IME Handling | 
|  | if ( pContext->mpFont ) | 
|  | { | 
|  | HIMC hIMC = ImmGetContext( pFrame->mhWnd ); | 
|  | if ( hIMC ) | 
|  | { | 
|  | LOGFONTW aLogFont; | 
|  | HDC hDC = GetDC( pFrame->mhWnd ); | 
|  | // In case of vertical writing, always append a '@' to the | 
|  | // Windows font name, not only if such a Windows font really is | 
|  | // available (bTestVerticalAvail == false in the below call): | 
|  | // The Windows IME's candidates window seems to always use a | 
|  | // font that has all necessary glyphs, not necessarily the one | 
|  | // specified by this font name; but it seems to decide whether | 
|  | // to use that font's horizontal or vertical variant based on a | 
|  | // '@' in front of this font name. | 
|  | ImplGetLogFontFromFontSelect( hDC, pContext->mpFont, aLogFont, | 
|  | false ); | 
|  | ReleaseDC( pFrame->mhWnd, hDC ); | 
|  | ImmSetCompositionFontW( hIMC, &aLogFont ); | 
|  | ImmReleaseContext( pFrame->mhWnd, hIMC ); | 
|  | } | 
|  | } | 
|  | } | 
|  | else | 
|  | { | 
|  | if ( pFrame->mbIME ) | 
|  | { | 
|  | pFrame->mbIME = FALSE; | 
|  | pFrame->mbHandleIME = FALSE; | 
|  | ImmAssociateContext( pFrame->mhWnd, 0 ); | 
|  | } | 
|  | } | 
|  | } | 
|  |  | 
|  | // ----------------------------------------------------------------------- | 
|  |  | 
|  | void WinSalFrame::SetInputContext( SalInputContext* pContext ) | 
|  | { | 
|  | // Must be called in the main thread! | 
|  | ImplSendMessage( mhWnd, SAL_MSG_SETINPUTCONTEXT, 0, (LPARAM)(void*)pContext ); | 
|  | } | 
|  |  | 
|  | // ----------------------------------------------------------------------- | 
|  |  | 
|  | static void ImplSalFrameEndExtTextInput( HWND hWnd, sal_uInt16 nFlags ) | 
|  | { | 
|  | HIMC hIMC = ImmGetContext( hWnd ); | 
|  | if ( hIMC ) | 
|  | { | 
|  | DWORD nIndex; | 
|  | if ( nFlags & SAL_FRAME_ENDEXTTEXTINPUT_COMPLETE ) | 
|  | nIndex = CPS_COMPLETE; | 
|  | else | 
|  | nIndex = CPS_CANCEL; | 
|  |  | 
|  | ImmNotifyIME( hIMC, NI_COMPOSITIONSTR, nIndex, 0 ); | 
|  | ImmReleaseContext( hWnd, hIMC ); | 
|  | } | 
|  | } | 
|  |  | 
|  | // ----------------------------------------------------------------------- | 
|  |  | 
|  | void WinSalFrame::EndExtTextInput( sal_uInt16 nFlags ) | 
|  | { | 
|  | // Must be called in the main thread! | 
|  | ImplSendMessage( mhWnd, SAL_MSG_ENDEXTTEXTINPUT, (WPARAM)nFlags, 0 ); | 
|  | } | 
|  |  | 
|  | // ----------------------------------------------------------------------- | 
|  |  | 
|  | static void ImplGetKeyNameText( LONG lParam, sal_Unicode* pBuf, | 
|  | UINT& rCount, UINT nMaxSize, | 
|  | const sal_Char* pReplace ) | 
|  | { | 
|  | DBG_ASSERT( sizeof( WCHAR ) == sizeof( xub_Unicode ), "WinSalFrame::ImplGetKeyNameTextW(): WCHAR != sal_Unicode" ); | 
|  |  | 
|  | static const int nMaxKeyLen = 350; | 
|  | WCHAR aKeyBuf[ nMaxKeyLen ]; | 
|  | int nKeyLen = 0; | 
|  | if ( lParam ) | 
|  | { | 
|  | if ( true/*aSalShlData.mbWNT*/ ) | 
|  | { | 
|  | nKeyLen = GetKeyNameTextW( lParam, aKeyBuf, nMaxKeyLen ); | 
|  | DBG_ASSERT( nKeyLen <= nMaxKeyLen, "Invalid key name length!" ); | 
|  | if( nKeyLen > nMaxKeyLen ) | 
|  | nKeyLen = 0; | 
|  | else if( nKeyLen > 0 ) | 
|  | { | 
|  | // Capitalize just the first letter of key names | 
|  | CharLowerBuffW( aKeyBuf, nKeyLen ); | 
|  |  | 
|  | bool bUpper = true; | 
|  | for( WCHAR *pW=aKeyBuf, *pE=pW+nKeyLen; pW < pE; ++pW ) | 
|  | { | 
|  | if( bUpper ) | 
|  | CharUpperBuffW( pW, 1 ); | 
|  | bUpper = (*pW=='+') || (*pW=='-') || (*pW==' ') || (*pW=='.'); | 
|  | } | 
|  | } | 
|  | } | 
|  | } | 
|  |  | 
|  | if ( (nKeyLen > 0) || pReplace ) | 
|  | { | 
|  | if( (rCount > 0) && (rCount < nMaxSize) ) | 
|  | { | 
|  | pBuf[rCount] = '+'; | 
|  | rCount++; | 
|  | } | 
|  |  | 
|  | if( nKeyLen > 0 ) | 
|  | { | 
|  | if( nKeyLen + rCount > nMaxSize ) | 
|  | nKeyLen = nMaxSize - rCount; | 
|  | memcpy( pBuf+rCount, aKeyBuf, nKeyLen*sizeof( sal_Unicode ) ); | 
|  | rCount += nKeyLen; | 
|  | } | 
|  | else // fall back to provided default name | 
|  | { | 
|  | while( *pReplace && (rCount < nMaxSize) ) | 
|  | { | 
|  | pBuf[rCount] = *pReplace; | 
|  | rCount++; | 
|  | pReplace++; | 
|  | } | 
|  | } | 
|  | } | 
|  | else | 
|  | rCount = 0; | 
|  | } | 
|  |  | 
|  | // ----------------------------------------------------------------------- | 
|  |  | 
|  | XubString WinSalFrame::GetKeyName( sal_uInt16 nKeyCode ) | 
|  | { | 
|  | static const int nMaxKeyLen = 350; | 
|  | sal_Unicode aKeyBuf[ nMaxKeyLen ]; | 
|  | UINT        nKeyBufLen = 0; | 
|  | UINT        nSysCode = 0; | 
|  |  | 
|  | if ( nKeyCode & KEY_MOD1 ) | 
|  | { | 
|  | nSysCode = MapVirtualKey( VK_CONTROL, 0 ); | 
|  | nSysCode = (nSysCode << 16) | (((sal_uLong)1) << 25); | 
|  | ImplGetKeyNameText( nSysCode, aKeyBuf, nKeyBufLen, nMaxKeyLen, "Ctrl" ); | 
|  | } | 
|  |  | 
|  | if ( nKeyCode & KEY_MOD2 ) | 
|  | { | 
|  | nSysCode = MapVirtualKey( VK_MENU, 0 ); | 
|  | nSysCode = (nSysCode << 16) | (((sal_uLong)1) << 25); | 
|  | ImplGetKeyNameText( nSysCode, aKeyBuf, nKeyBufLen, nMaxKeyLen, "Alt" ); | 
|  | } | 
|  |  | 
|  | if ( nKeyCode & KEY_SHIFT ) | 
|  | { | 
|  | nSysCode = MapVirtualKey( VK_SHIFT, 0 ); | 
|  | nSysCode = (nSysCode << 16) | (((sal_uLong)1) << 25); | 
|  | ImplGetKeyNameText( nSysCode, aKeyBuf, nKeyBufLen, nMaxKeyLen, "Shift" ); | 
|  | } | 
|  |  | 
|  | sal_uInt16      nCode = nKeyCode & 0x0FFF; | 
|  | sal_uLong       nSysCode2 = 0; | 
|  | sal_Char*   pReplace = NULL; | 
|  | sal_Unicode cSVCode = 0; | 
|  | sal_Char    aFBuf[4]; | 
|  | nSysCode = 0; | 
|  |  | 
|  | if ( (nCode >= KEY_0) && (nCode <= KEY_9) ) | 
|  | cSVCode = '0' + (nCode - KEY_0); | 
|  | else if ( (nCode >= KEY_A) && (nCode <= KEY_Z) ) | 
|  | cSVCode = 'A' + (nCode - KEY_A); | 
|  | else if ( (nCode >= KEY_F1) && (nCode <= KEY_F26) ) | 
|  | { | 
|  | nSysCode = VK_F1 + (nCode - KEY_F1); | 
|  | aFBuf[0] = 'F'; | 
|  | if ( (nCode >= KEY_F1) && (nCode <= KEY_F9) ) | 
|  | { | 
|  | aFBuf[1] = sal::static_int_cast<sal_Char>('1' + (nCode - KEY_F1)); | 
|  | aFBuf[2] = 0; | 
|  | } | 
|  | else if ( (nCode >= KEY_F10) && (nCode <= KEY_F19) ) | 
|  | { | 
|  | aFBuf[1] = '1'; | 
|  | aFBuf[2] = sal::static_int_cast<sal_Char>('0' + (nCode - KEY_F10)); | 
|  | aFBuf[3] = 0; | 
|  | } | 
|  | else | 
|  | { | 
|  | aFBuf[1] = '2'; | 
|  | aFBuf[2] = sal::static_int_cast<sal_Char>('0' + (nCode - KEY_F20)); | 
|  | aFBuf[3] = 0; | 
|  | } | 
|  | pReplace = aFBuf; | 
|  | } | 
|  | else | 
|  | { | 
|  | switch ( nCode ) | 
|  | { | 
|  | case KEY_DOWN: | 
|  | nSysCode = VK_DOWN; | 
|  | nSysCode2 = (((sal_uLong)1) << 24); | 
|  | pReplace = "Down"; | 
|  | break; | 
|  | case KEY_UP: | 
|  | nSysCode = VK_UP; | 
|  | nSysCode2 = (((sal_uLong)1) << 24); | 
|  | pReplace = "Up"; | 
|  | break; | 
|  | case KEY_LEFT: | 
|  | nSysCode = VK_LEFT; | 
|  | nSysCode2 = (((sal_uLong)1) << 24); | 
|  | pReplace = "Left"; | 
|  | break; | 
|  | case KEY_RIGHT: | 
|  | nSysCode = VK_RIGHT; | 
|  | nSysCode2 = (((sal_uLong)1) << 24); | 
|  | pReplace = "Right"; | 
|  | break; | 
|  | case KEY_HOME: | 
|  | nSysCode = VK_HOME; | 
|  | nSysCode2 = (((sal_uLong)1) << 24); | 
|  | pReplace = "Home"; | 
|  | break; | 
|  | case KEY_END: | 
|  | nSysCode = VK_END; | 
|  | nSysCode2 = (((sal_uLong)1) << 24); | 
|  | pReplace = "End"; | 
|  | break; | 
|  | case KEY_PAGEUP: | 
|  | nSysCode = VK_PRIOR; | 
|  | nSysCode2 = (((sal_uLong)1) << 24); | 
|  | pReplace = "Page Up"; | 
|  | break; | 
|  | case KEY_PAGEDOWN: | 
|  | nSysCode = VK_NEXT; | 
|  | nSysCode2 = (((sal_uLong)1) << 24); | 
|  | pReplace = "Page Down"; | 
|  | break; | 
|  | case KEY_RETURN: | 
|  | nSysCode = VK_RETURN; | 
|  | pReplace = "Enter"; | 
|  | break; | 
|  | case KEY_ESCAPE: | 
|  | nSysCode = VK_ESCAPE; | 
|  | pReplace = "Escape"; | 
|  | break; | 
|  | case KEY_TAB: | 
|  | nSysCode = VK_TAB; | 
|  | pReplace = "Tab"; | 
|  | break; | 
|  | case KEY_BACKSPACE: | 
|  | nSysCode = VK_BACK; | 
|  | pReplace = "Backspace"; | 
|  | break; | 
|  | case KEY_SPACE: | 
|  | nSysCode = VK_SPACE; | 
|  | pReplace = "Space"; | 
|  | break; | 
|  | case KEY_INSERT: | 
|  | nSysCode = VK_INSERT; | 
|  | nSysCode2 = (((sal_uLong)1) << 24); | 
|  | pReplace = "Insert"; | 
|  | break; | 
|  | case KEY_DELETE: | 
|  | nSysCode = VK_DELETE; | 
|  | nSysCode2 = (((sal_uLong)1) << 24); | 
|  | pReplace = "Delete"; | 
|  | break; | 
|  |  | 
|  | case KEY_ADD: | 
|  | cSVCode  = '+'; | 
|  | break; | 
|  | case KEY_SUBTRACT: | 
|  | cSVCode  = '-'; | 
|  | break; | 
|  | case KEY_MULTIPLY: | 
|  | cSVCode  = '*'; | 
|  | break; | 
|  | case KEY_DIVIDE: | 
|  | cSVCode  = '/'; | 
|  | break; | 
|  | case KEY_POINT: | 
|  | cSVCode  = '.'; | 
|  | break; | 
|  | case KEY_COMMA: | 
|  | cSVCode  = ','; | 
|  | break; | 
|  | case KEY_LESS: | 
|  | cSVCode  = '<'; | 
|  | break; | 
|  | case KEY_GREATER: | 
|  | cSVCode  = '>'; | 
|  | break; | 
|  | case KEY_EQUAL: | 
|  | cSVCode  = '='; | 
|  | break; | 
|  | } | 
|  | } | 
|  |  | 
|  | if ( nSysCode ) | 
|  | { | 
|  | nSysCode = MapVirtualKey( (UINT)nSysCode, 0 ); | 
|  | if ( nSysCode ) | 
|  | nSysCode = (nSysCode << 16) | nSysCode2; | 
|  | ImplGetKeyNameText( nSysCode, aKeyBuf, nKeyBufLen, nMaxKeyLen, pReplace ); | 
|  | } | 
|  | else | 
|  | { | 
|  | if ( cSVCode ) | 
|  | { | 
|  | if ( nKeyBufLen > 0 ) | 
|  | aKeyBuf[ nKeyBufLen++ ] = '+'; | 
|  | if( nKeyBufLen < nMaxKeyLen ) | 
|  | aKeyBuf[ nKeyBufLen++ ] = cSVCode; | 
|  | } | 
|  | } | 
|  |  | 
|  | if( !nKeyBufLen ) | 
|  | return XubString(); | 
|  |  | 
|  | return XubString( aKeyBuf, sal::static_int_cast< sal_uInt16 >(nKeyBufLen) ); | 
|  | } | 
|  |  | 
|  | // ----------------------------------------------------------------------- | 
|  |  | 
|  | XubString WinSalFrame::GetSymbolKeyName( const XubString&, sal_uInt16 nKeyCode ) | 
|  | { | 
|  | return GetKeyName( nKeyCode ); | 
|  | } | 
|  |  | 
|  | // ----------------------------------------------------------------------- | 
|  |  | 
|  | inline Color ImplWinColorToSal( COLORREF nColor ) | 
|  | { | 
|  | return Color( GetRValue( nColor ), GetGValue( nColor ), GetBValue( nColor ) ); | 
|  | } | 
|  |  | 
|  | // ----------------------------------------------------------------------- | 
|  |  | 
|  | static void ImplSalUpdateStyleFontA( HDC hDC, const LOGFONTA& rLogFont, Font& rFont ) | 
|  | { | 
|  | ImplSalLogFontToFontA( hDC, rLogFont, rFont ); | 
|  |  | 
|  | // On Windows 9x, Windows NT we get sometimes very small sizes | 
|  | // (for example for the small Caption height). | 
|  | // So if it is MS Sans Serif, a none scalable font we use | 
|  | // 8 Point as the minimum control height, in all other cases | 
|  | // 6 Point is the smallest one | 
|  | if ( rFont.GetHeight() < 8 ) | 
|  | { | 
|  | if ( rtl_str_compareIgnoreAsciiCase( rLogFont.lfFaceName, "MS Sans Serif" ) == 0 ) | 
|  | rFont.SetHeight( 8 ); | 
|  | else if ( rFont.GetHeight() < 6 ) | 
|  | rFont.SetHeight( 6 ); | 
|  | } | 
|  | } | 
|  |  | 
|  | // ----------------------------------------------------------------------- | 
|  |  | 
|  | static void ImplSalUpdateStyleFontW( HDC hDC, const LOGFONTW& rLogFont, Font& rFont ) | 
|  | { | 
|  | ImplSalLogFontToFontW( hDC, rLogFont, rFont ); | 
|  |  | 
|  | // On Windows 9x, Windows NT we get sometimes very small sizes | 
|  | // (for example for the small Caption height). | 
|  | // So if it is MS Sans Serif, a none scalable font we use | 
|  | // 8 Point as the minimum control height, in all other cases | 
|  | // 6 Point is the smallest one | 
|  | if ( rFont.GetHeight() < 8 ) | 
|  | { | 
|  | if ( rtl_ustr_compareIgnoreAsciiCase( reinterpret_cast<const sal_Unicode*>(rLogFont.lfFaceName), reinterpret_cast<const sal_Unicode*>(L"MS Sans Serif") ) == 0 ) | 
|  | rFont.SetHeight( 8 ); | 
|  | else if ( rFont.GetHeight() < 6 ) | 
|  | rFont.SetHeight( 6 ); | 
|  | } | 
|  | } | 
|  |  | 
|  | // ----------------------------------------------------------------------- | 
|  |  | 
|  | static long ImplA2I( const BYTE* pStr ) | 
|  | { | 
|  | long    n = 0; | 
|  | int     nSign = 1; | 
|  |  | 
|  | if ( *pStr == '-' ) | 
|  | { | 
|  | nSign = -1; | 
|  | pStr++; | 
|  | } | 
|  |  | 
|  | while( (*pStr >= 48) && (*pStr <= 57) ) | 
|  | { | 
|  | n *= 10; | 
|  | n += ((*pStr) - 48); | 
|  | pStr++; | 
|  | } | 
|  |  | 
|  | n *= nSign; | 
|  |  | 
|  | return n; | 
|  | } | 
|  |  | 
|  | // ----------------------------------------------------------------------- | 
|  | static HRESULT WINAPI backwardCompatibleDwmIsCompositionEnabled( BOOL* pOut ) | 
|  | { | 
|  | *pOut = FALSE; | 
|  | return S_OK; | 
|  | } | 
|  |  | 
|  | static BOOL ImplDwmIsCompositionEnabled() | 
|  | { | 
|  | SalData* pSalData = GetSalData(); | 
|  | if( ! pSalData->mpDwmIsCompositionEnabled ) | 
|  | { | 
|  | pSalData->maDwmLib = osl_loadAsciiModule( "Dwmapi.dll", SAL_LOADMODULE_DEFAULT ); | 
|  | if( pSalData->maDwmLib ) | 
|  | pSalData->mpDwmIsCompositionEnabled = (DwmIsCompositionEnabled_ptr)osl_getAsciiFunctionSymbol( pSalData->maDwmLib, "DwmIsCompositionEnabled" ); | 
|  | if( ! pSalData->mpDwmIsCompositionEnabled ) // something failed | 
|  | pSalData->mpDwmIsCompositionEnabled = backwardCompatibleDwmIsCompositionEnabled; | 
|  | } | 
|  | BOOL aResult = FALSE; | 
|  | HRESULT nError = pSalData->mpDwmIsCompositionEnabled( &aResult ); | 
|  | return nError == S_OK && aResult; | 
|  | } | 
|  |  | 
|  |  | 
|  | void WinSalFrame::UpdateSettings( AllSettings& rSettings ) | 
|  | { | 
|  | MouseSettings aMouseSettings = rSettings.GetMouseSettings(); | 
|  | aMouseSettings.SetDoubleClickTime( GetDoubleClickTime() ); | 
|  | aMouseSettings.SetDoubleClickWidth( GetSystemMetrics( SM_CXDOUBLECLK ) ); | 
|  | aMouseSettings.SetDoubleClickHeight( GetSystemMetrics( SM_CYDOUBLECLK ) ); | 
|  | long nDragWidth = GetSystemMetrics( SM_CXDRAG ); | 
|  | long nDragHeight = GetSystemMetrics( SM_CYDRAG ); | 
|  | if ( nDragWidth ) | 
|  | aMouseSettings.SetStartDragWidth( nDragWidth ); | 
|  | if ( nDragHeight ) | 
|  | aMouseSettings.SetStartDragHeight( nDragHeight ); | 
|  | HKEY hRegKey; | 
|  | if ( RegOpenKey( HKEY_CURRENT_USER, | 
|  | "Control Panel\\Desktop", | 
|  | &hRegKey ) == ERROR_SUCCESS ) | 
|  | { | 
|  | BYTE    aValueBuf[10]; | 
|  | DWORD   nValueSize = sizeof( aValueBuf ); | 
|  | DWORD   nType; | 
|  | if ( RegQueryValueEx( hRegKey, "MenuShowDelay", 0, | 
|  | &nType, aValueBuf, &nValueSize ) == ERROR_SUCCESS ) | 
|  | { | 
|  | if ( nType == REG_SZ ) | 
|  | aMouseSettings.SetMenuDelay( (sal_uLong)ImplA2I( aValueBuf ) ); | 
|  | } | 
|  |  | 
|  | RegCloseKey( hRegKey ); | 
|  | } | 
|  |  | 
|  | StyleSettings aStyleSettings = rSettings.GetStyleSettings(); | 
|  | // TODO: once those options vanish: just set bCompBorder to TRUE | 
|  | // to have the system colors read | 
|  | aStyleSettings.SetScrollBarSize( GetSystemMetrics( SM_CXVSCROLL ) ); | 
|  | aStyleSettings.SetSpinSize( GetSystemMetrics( SM_CXVSCROLL ) ); | 
|  | aStyleSettings.SetCursorBlinkTime( GetCaretBlinkTime() ); | 
|  | aStyleSettings.SetFloatTitleHeight( GetSystemMetrics( SM_CYSMCAPTION ) ); | 
|  | aStyleSettings.SetTitleHeight( GetSystemMetrics( SM_CYCAPTION ) ); | 
|  | aStyleSettings.SetActiveBorderColor( ImplWinColorToSal( GetSysColor( COLOR_ACTIVEBORDER ) ) ); | 
|  | aStyleSettings.SetDeactiveBorderColor( ImplWinColorToSal( GetSysColor( COLOR_INACTIVEBORDER ) ) ); | 
|  | if ( aSalShlData.mnVersion >= 410 ) | 
|  | { | 
|  | aStyleSettings.SetActiveColor2( ImplWinColorToSal( GetSysColor( COLOR_GRADIENTACTIVECAPTION ) ) ); | 
|  | aStyleSettings.SetDeactiveColor( ImplWinColorToSal( GetSysColor( COLOR_GRADIENTINACTIVECAPTION ) ) ); | 
|  | } | 
|  | aStyleSettings.SetFaceColor( ImplWinColorToSal( GetSysColor( COLOR_3DFACE ) ) ); | 
|  | aStyleSettings.SetInactiveTabColor( aStyleSettings.GetFaceColor() ); | 
|  | aStyleSettings.SetLightColor( ImplWinColorToSal( GetSysColor( COLOR_3DHILIGHT ) ) ); | 
|  | aStyleSettings.SetLightBorderColor( ImplWinColorToSal( GetSysColor( COLOR_3DLIGHT ) ) ); | 
|  | aStyleSettings.SetShadowColor( ImplWinColorToSal( GetSysColor( COLOR_3DSHADOW ) ) ); | 
|  | aStyleSettings.SetDarkShadowColor( ImplWinColorToSal( GetSysColor( COLOR_3DDKSHADOW ) ) ); | 
|  | aStyleSettings.SetWorkspaceColor( ImplWinColorToSal( GetSysColor( COLOR_APPWORKSPACE ) ) ); | 
|  | aStyleSettings.SetHelpColor( ImplWinColorToSal( GetSysColor( COLOR_INFOBK ) ) ); | 
|  | aStyleSettings.SetHelpTextColor( ImplWinColorToSal( GetSysColor( COLOR_INFOTEXT ) ) ); | 
|  | aStyleSettings.SetDialogColor( aStyleSettings.GetFaceColor() ); | 
|  | aStyleSettings.SetDialogTextColor( aStyleSettings.GetButtonTextColor() ); | 
|  | aStyleSettings.SetButtonTextColor( ImplWinColorToSal( GetSysColor( COLOR_BTNTEXT ) ) ); | 
|  | aStyleSettings.SetButtonRolloverTextColor( aStyleSettings.GetButtonTextColor() ); | 
|  | aStyleSettings.SetRadioCheckTextColor( ImplWinColorToSal( GetSysColor( COLOR_WINDOWTEXT ) ) ); | 
|  | aStyleSettings.SetGroupTextColor( aStyleSettings.GetRadioCheckTextColor() ); | 
|  | aStyleSettings.SetLabelTextColor( aStyleSettings.GetRadioCheckTextColor() ); | 
|  | aStyleSettings.SetInfoTextColor( aStyleSettings.GetRadioCheckTextColor() ); | 
|  | aStyleSettings.SetWindowColor( ImplWinColorToSal( GetSysColor( COLOR_WINDOW ) ) ); | 
|  | aStyleSettings.SetActiveTabColor( aStyleSettings.GetWindowColor() ); | 
|  | aStyleSettings.SetWindowTextColor( ImplWinColorToSal( GetSysColor( COLOR_WINDOWTEXT ) ) ); | 
|  | aStyleSettings.SetFieldColor( aStyleSettings.GetWindowColor() ); | 
|  | aStyleSettings.SetFieldTextColor( aStyleSettings.GetWindowTextColor() ); | 
|  | aStyleSettings.SetFieldRolloverTextColor( aStyleSettings.GetFieldTextColor() ); | 
|  | aStyleSettings.SetHighlightColor( ImplWinColorToSal( GetSysColor( COLOR_HIGHLIGHT ) ) ); | 
|  | aStyleSettings.SetHighlightTextColor( ImplWinColorToSal( GetSysColor( COLOR_HIGHLIGHTTEXT ) ) ); | 
|  | aStyleSettings.SetMenuHighlightColor( aStyleSettings.GetHighlightColor() ); | 
|  | aStyleSettings.SetMenuHighlightTextColor( aStyleSettings.GetHighlightTextColor() ); | 
|  |  | 
|  | ImplSVData* pSVData = ImplGetSVData(); | 
|  | pSVData->maNWFData.mnMenuFormatExtraBorder = 0; | 
|  | pSVData->maNWFData.maMenuBarHighlightTextColor = Color( COL_TRANSPARENT ); | 
|  | GetSalData()->mbThemeMenuSupport = FALSE; | 
|  | aStyleSettings.SetMenuColor( ImplWinColorToSal( GetSysColor( COLOR_MENU ) ) ); | 
|  | aStyleSettings.SetMenuBarColor( aStyleSettings.GetMenuColor() ); | 
|  | aStyleSettings.SetMenuBorderColor( aStyleSettings.GetLightBorderColor() ); // overriden below for flat menus | 
|  | aStyleSettings.SetUseFlatBorders( FALSE ); | 
|  | aStyleSettings.SetUseFlatMenues( FALSE ); | 
|  | aStyleSettings.SetMenuTextColor( ImplWinColorToSal( GetSysColor( COLOR_MENUTEXT ) ) ); | 
|  | aStyleSettings.SetMenuBarTextColor( ImplWinColorToSal( GetSysColor( COLOR_MENUTEXT ) ) ); | 
|  | aStyleSettings.SetActiveColor( ImplWinColorToSal( GetSysColor( COLOR_ACTIVECAPTION ) ) ); | 
|  | aStyleSettings.SetActiveTextColor( ImplWinColorToSal( GetSysColor( COLOR_CAPTIONTEXT ) ) ); | 
|  | aStyleSettings.SetDeactiveColor( ImplWinColorToSal( GetSysColor( COLOR_INACTIVECAPTION ) ) ); | 
|  | aStyleSettings.SetDeactiveTextColor( ImplWinColorToSal( GetSysColor( COLOR_INACTIVECAPTIONTEXT ) ) ); | 
|  | if ( aSalShlData.mbWXP ) | 
|  | { | 
|  | // only xp supports a different menu bar color | 
|  | long bFlatMenues = 0; | 
|  | SystemParametersInfo( SPI_GETFLATMENU, 0, &bFlatMenues, 0); | 
|  | if( bFlatMenues ) | 
|  | { | 
|  | aStyleSettings.SetUseFlatMenues( TRUE ); | 
|  | aStyleSettings.SetMenuBarColor( ImplWinColorToSal( GetSysColor( COLOR_MENUBAR ) ) ); | 
|  | aStyleSettings.SetMenuHighlightColor( ImplWinColorToSal( GetSysColor( COLOR_MENUHILIGHT ) ) ); | 
|  | aStyleSettings.SetMenuBorderColor( ImplWinColorToSal( GetSysColor( COLOR_3DSHADOW ) ) ); | 
|  |  | 
|  | // flat borders for our controls etc. as well in this mode (i.e. no 3D borders) | 
|  | // this is not active in the classic style appearance | 
|  | aStyleSettings.SetUseFlatBorders( TRUE ); | 
|  | } | 
|  | } | 
|  | // check if vista or newer runs | 
|  | // in Aero theme (and similar ?) the menu text color does not change | 
|  | // for selected items; also on WinXP and earlier menus are not themed | 
|  | if( aSalShlData.maVersionInfo.dwMajorVersion >= 6 && | 
|  | ImplDwmIsCompositionEnabled() | 
|  | ) | 
|  | { | 
|  | // in Aero menuitem highlight text is drawn in the same color as normal | 
|  | aStyleSettings.SetMenuHighlightTextColor( aStyleSettings.GetMenuTextColor() ); | 
|  | pSVData->maNWFData.mnMenuFormatExtraBorder = 2; | 
|  | pSVData->maNWFData.maMenuBarHighlightTextColor = aStyleSettings.GetMenuTextColor(); | 
|  | GetSalData()->mbThemeMenuSupport = TRUE; | 
|  | } | 
|  | // Bei hellgrau geben wir die Farbe vor, damit es besser aussieht | 
|  | if ( aStyleSettings.GetFaceColor() == COL_LIGHTGRAY ) | 
|  | aStyleSettings.SetCheckedColor( Color( 0xCC, 0xCC, 0xCC ) ); | 
|  | else | 
|  | { | 
|  | // Checked-Color berechnen | 
|  | Color   aColor1 = aStyleSettings.GetFaceColor(); | 
|  | Color   aColor2 = aStyleSettings.GetLightColor(); | 
|  | BYTE    nRed    = (BYTE)(((sal_uInt16)aColor1.GetRed()   + (sal_uInt16)aColor2.GetRed())/2); | 
|  | BYTE    nGreen  = (BYTE)(((sal_uInt16)aColor1.GetGreen() + (sal_uInt16)aColor2.GetGreen())/2); | 
|  | BYTE    nBlue   = (BYTE)(((sal_uInt16)aColor1.GetBlue()  + (sal_uInt16)aColor2.GetBlue())/2); | 
|  | aStyleSettings.SetCheckedColor( Color( nRed, nGreen, nBlue ) ); | 
|  | } | 
|  |  | 
|  | // caret width | 
|  | DWORD nCaretWidth = 2; | 
|  | if( SystemParametersInfo( SPI_GETCARETWIDTH, 0, &nCaretWidth, 0 ) ) | 
|  | aStyleSettings.SetCursorSize( nCaretWidth ); | 
|  |  | 
|  | // High contrast | 
|  | HIGHCONTRAST hc; | 
|  | hc.cbSize = sizeof( HIGHCONTRAST ); | 
|  | if( SystemParametersInfo( SPI_GETHIGHCONTRAST, hc.cbSize, &hc, 0) && (hc.dwFlags & HCF_HIGHCONTRASTON) ) | 
|  | aStyleSettings.SetHighContrastMode( 1 ); | 
|  | else | 
|  | aStyleSettings.SetHighContrastMode( 0 ); | 
|  |  | 
|  |  | 
|  | // Query Fonts | 
|  | Font    aMenuFont = aStyleSettings.GetMenuFont(); | 
|  | Font    aTitleFont = aStyleSettings.GetTitleFont(); | 
|  | Font    aFloatTitleFont = aStyleSettings.GetFloatTitleFont(); | 
|  | Font    aHelpFont = aStyleSettings.GetHelpFont(); | 
|  | Font    aAppFont = aStyleSettings.GetAppFont(); | 
|  | Font    aIconFont = aStyleSettings.GetIconFont(); | 
|  | HDC     hDC = GetDC( 0 ); | 
|  | if( true/*aSalShlData.mbWNT*/ ) | 
|  | { | 
|  | NONCLIENTMETRICSW aNonClientMetrics; | 
|  | aNonClientMetrics.cbSize = sizeof( aNonClientMetrics ); | 
|  | if ( SystemParametersInfoW( SPI_GETNONCLIENTMETRICS, sizeof( aNonClientMetrics ), &aNonClientMetrics, 0 ) ) | 
|  | { | 
|  | ImplSalUpdateStyleFontW( hDC, aNonClientMetrics.lfMenuFont, aMenuFont ); | 
|  | ImplSalUpdateStyleFontW( hDC, aNonClientMetrics.lfCaptionFont, aTitleFont ); | 
|  | ImplSalUpdateStyleFontW( hDC, aNonClientMetrics.lfSmCaptionFont, aFloatTitleFont ); | 
|  | ImplSalUpdateStyleFontW( hDC, aNonClientMetrics.lfStatusFont, aHelpFont ); | 
|  | ImplSalUpdateStyleFontW( hDC, aNonClientMetrics.lfMessageFont, aAppFont ); | 
|  |  | 
|  | LOGFONTW aLogFont; | 
|  | if ( SystemParametersInfoW( SPI_GETICONTITLELOGFONT, 0, &aLogFont, 0 ) ) | 
|  | ImplSalUpdateStyleFontW( hDC, aLogFont, aIconFont ); | 
|  | } | 
|  | } | 
|  |  | 
|  | // get screen font resolution to calculate toolbox item size | 
|  | long nDPIY = GetDeviceCaps( hDC, LOGPIXELSY ); | 
|  |  | 
|  | ReleaseDC( 0, hDC ); | 
|  |  | 
|  | long nHeightPx = aMenuFont.GetHeight() * nDPIY / 72; | 
|  | aStyleSettings.SetToolbarIconSize( (((nHeightPx-1)*2) >= 28) ? STYLE_TOOLBAR_ICONSIZE_LARGE : STYLE_TOOLBAR_ICONSIZE_SMALL ); | 
|  |  | 
|  | aStyleSettings.SetMenuFont( aMenuFont ); | 
|  | aStyleSettings.SetTitleFont( aTitleFont ); | 
|  | aStyleSettings.SetFloatTitleFont( aFloatTitleFont ); | 
|  | aStyleSettings.SetHelpFont( aHelpFont ); | 
|  | aStyleSettings.SetIconFont( aIconFont ); | 
|  | // We prefer Arial in the Russian version, because MS Sans Serif | 
|  | // is to wide for the dialogs | 
|  | if ( rSettings.GetLanguage() == LANGUAGE_RUSSIAN ) | 
|  | { | 
|  | XubString aFontName = aAppFont.GetName(); | 
|  | XubString aFirstName = aFontName.GetToken( 0, ';' ); | 
|  | if ( aFirstName.EqualsIgnoreCaseAscii( "MS Sans Serif" ) ) | 
|  | { | 
|  | aFontName.InsertAscii( "Arial;", 0 ); | 
|  | aAppFont.SetName( aFontName ); | 
|  | } | 
|  | } | 
|  | aStyleSettings.SetAppFont( aAppFont ); | 
|  | aStyleSettings.SetGroupFont( aAppFont ); | 
|  | aStyleSettings.SetLabelFont( aAppFont ); | 
|  | aStyleSettings.SetRadioCheckFont( aAppFont ); | 
|  | aStyleSettings.SetPushButtonFont( aAppFont ); | 
|  | aStyleSettings.SetFieldFont( aAppFont ); | 
|  | if ( aAppFont.GetWeight() > WEIGHT_NORMAL ) | 
|  | aAppFont.SetWeight( WEIGHT_NORMAL ); | 
|  | aStyleSettings.SetInfoFont( aAppFont ); | 
|  | aStyleSettings.SetToolFont( aAppFont ); | 
|  |  | 
|  | BOOL bDragFull; | 
|  | if ( SystemParametersInfo( SPI_GETDRAGFULLWINDOWS, 0, &bDragFull, 0 ) ) | 
|  | { | 
|  | sal_uLong nDragFullOptions = aStyleSettings.GetDragFullOptions(); | 
|  | if ( bDragFull ) | 
|  | nDragFullOptions |=  DRAGFULL_OPTION_WINDOWMOVE | DRAGFULL_OPTION_WINDOWSIZE | DRAGFULL_OPTION_DOCKING | DRAGFULL_OPTION_SPLIT; | 
|  | else | 
|  | nDragFullOptions &= ~(DRAGFULL_OPTION_WINDOWMOVE | DRAGFULL_OPTION_WINDOWSIZE | DRAGFULL_OPTION_DOCKING | DRAGFULL_OPTION_SPLIT); | 
|  | aStyleSettings.SetDragFullOptions( nDragFullOptions ); | 
|  | } | 
|  |  | 
|  | aStyleSettings.SetIconHorzSpace( GetSystemMetrics( SM_CXICONSPACING ) ); | 
|  | aStyleSettings.SetIconVertSpace( GetSystemMetrics( SM_CYICONSPACING ) ); | 
|  | if ( RegOpenKey( HKEY_CURRENT_USER, | 
|  | "Control Panel\\International\\Calendars\\TwoDigitYearMax", | 
|  | &hRegKey ) == ERROR_SUCCESS ) | 
|  | { | 
|  | BYTE    aValueBuf[10]; | 
|  | DWORD   nValue; | 
|  | DWORD   nValueSize = sizeof( aValueBuf ); | 
|  | DWORD   nType; | 
|  | if ( RegQueryValueEx( hRegKey, "1", 0, | 
|  | &nType, aValueBuf, &nValueSize ) == ERROR_SUCCESS ) | 
|  | { | 
|  | if ( nType == REG_SZ ) | 
|  | { | 
|  | nValue = (sal_uLong)ImplA2I( aValueBuf ); | 
|  | if ( (nValue > 1000) && (nValue < 10000) ) | 
|  | { | 
|  | MiscSettings aMiscSettings = rSettings.GetMiscSettings(); | 
|  | utl::MiscCfg().SetYear2000( (sal_Int32)(nValue-99) ); | 
|  | rSettings.SetMiscSettings( aMiscSettings ); | 
|  | } | 
|  | } | 
|  | } | 
|  |  | 
|  | RegCloseKey( hRegKey ); | 
|  | } | 
|  |  | 
|  | rSettings.SetMouseSettings( aMouseSettings ); | 
|  | rSettings.SetStyleSettings( aStyleSettings ); | 
|  | } | 
|  |  | 
|  | // ----------------------------------------------------------------------- | 
|  |  | 
|  | SalBitmap* WinSalFrame::SnapShot() | 
|  | { | 
|  | WinSalBitmap* pSalBitmap = NULL; | 
|  |  | 
|  | RECT aRect; | 
|  | GetWindowRect( mhWnd, &aRect ); | 
|  |  | 
|  | int     nDX = aRect.right-aRect.left; | 
|  | int     nDY = aRect.bottom-aRect.top; | 
|  | HDC     hDC = GetWindowDC( mhWnd ); | 
|  | HBITMAP hBmpBitmap = CreateCompatibleBitmap( hDC, nDX, nDY ); | 
|  | HDC     hBmpDC = ImplGetCachedDC( CACHED_HDC_1, hBmpBitmap ); | 
|  | sal_Bool    bRet; | 
|  |  | 
|  | bRet = BitBlt( hBmpDC, 0, 0, nDX, nDY, hDC, 0, 0, SRCCOPY ) ? TRUE : FALSE; | 
|  | ImplReleaseCachedDC( CACHED_HDC_1 ); | 
|  |  | 
|  | if ( bRet ) | 
|  | { | 
|  | pSalBitmap = new WinSalBitmap; | 
|  |  | 
|  | if ( !pSalBitmap->Create( hBmpBitmap, FALSE, FALSE ) ) | 
|  | { | 
|  | delete pSalBitmap; | 
|  | pSalBitmap = NULL; | 
|  | } | 
|  | } | 
|  |  | 
|  | return pSalBitmap; | 
|  | } | 
|  |  | 
|  | // ----------------------------------------------------------------------- | 
|  |  | 
|  | const SystemEnvData* WinSalFrame::GetSystemData() const | 
|  | { | 
|  | return &maSysData; | 
|  | } | 
|  |  | 
|  | // ----------------------------------------------------------------------- | 
|  |  | 
|  | void WinSalFrame::Beep( SoundType eSoundType ) | 
|  | { | 
|  | static UINT aImplSoundTab[5] = | 
|  | { | 
|  | 0,                              // SOUND_DEFAULT | 
|  | MB_ICONASTERISK,                // SOUND_INFO | 
|  | MB_ICONEXCLAMATION,             // SOUND_WARNING | 
|  | MB_ICONHAND,                    // SOUND_ERROR | 
|  | MB_ICONQUESTION                 // SOUND_QUERY | 
|  | }; | 
|  |  | 
|  | if( eSoundType != SOUND_DISABLE ) // don't beep on disable | 
|  | MessageBeep( aImplSoundTab[eSoundType] ); | 
|  | } | 
|  |  | 
|  | // ----------------------------------------------------------------------- | 
|  |  | 
|  | SalFrame::SalPointerState WinSalFrame::GetPointerState() | 
|  | { | 
|  | SalPointerState aState; | 
|  | aState.mnState = 0; | 
|  |  | 
|  | if ( GetKeyState( VK_LBUTTON ) & 0x8000 ) | 
|  | aState.mnState |= MOUSE_LEFT; | 
|  | if ( GetKeyState( VK_MBUTTON ) & 0x8000 ) | 
|  | aState.mnState |= MOUSE_MIDDLE; | 
|  | if ( GetKeyState( VK_RBUTTON ) & 0x8000 ) | 
|  | aState.mnState |= MOUSE_RIGHT; | 
|  | if ( GetKeyState( VK_SHIFT ) & 0x8000 ) | 
|  | aState.mnState |= KEY_SHIFT; | 
|  | if ( GetKeyState( VK_CONTROL ) & 0x8000 ) | 
|  | aState.mnState |= KEY_MOD1; | 
|  | if ( GetKeyState( VK_MENU ) & 0x8000 ) | 
|  | aState.mnState |= KEY_MOD2; | 
|  |  | 
|  | POINT pt; | 
|  | GetCursorPos( &pt ); | 
|  |  | 
|  | aState.maPos = Point( pt.x - maGeometry.nX, pt.y - maGeometry.nY ); | 
|  | return aState; | 
|  | } | 
|  |  | 
|  | // ----------------------------------------------------------------------- | 
|  |  | 
|  | void WinSalFrame::SetBackgroundBitmap( SalBitmap* ) | 
|  | { | 
|  | } | 
|  |  | 
|  | // ----------------------------------------------------------------------- | 
|  |  | 
|  | void WinSalFrame::ResetClipRegion() | 
|  | { | 
|  | SetWindowRgn( mhWnd, 0, TRUE ); | 
|  | } | 
|  |  | 
|  | // ----------------------------------------------------------------------- | 
|  |  | 
|  | void WinSalFrame::BeginSetClipRegion( sal_uLong nRects ) | 
|  | { | 
|  | if( mpClipRgnData ) | 
|  | delete [] (BYTE*)mpClipRgnData; | 
|  | sal_uLong nRectBufSize = sizeof(RECT)*nRects; | 
|  | mpClipRgnData = (RGNDATA*)new BYTE[sizeof(RGNDATA)-1+nRectBufSize]; | 
|  | mpClipRgnData->rdh.dwSize	  = sizeof( RGNDATAHEADER ); | 
|  | mpClipRgnData->rdh.iType	  = RDH_RECTANGLES; | 
|  | mpClipRgnData->rdh.nCount	  = nRects; | 
|  | mpClipRgnData->rdh.nRgnSize  = nRectBufSize; | 
|  | SetRectEmpty( &(mpClipRgnData->rdh.rcBound) ); | 
|  | mpNextClipRect 		  = (RECT*)(&(mpClipRgnData->Buffer)); | 
|  | mbFirstClipRect		  = TRUE; | 
|  | } | 
|  |  | 
|  | // ----------------------------------------------------------------------- | 
|  |  | 
|  | void WinSalFrame::UnionClipRegion( long nX, long nY, long nWidth, long nHeight ) | 
|  | { | 
|  | if( ! mpClipRgnData ) | 
|  | return; | 
|  |  | 
|  | RECT*		pRect = mpNextClipRect; | 
|  | RECT*		pBoundRect = &(mpClipRgnData->rdh.rcBound); | 
|  | long		nRight = nX + nWidth; | 
|  | long		nBottom = nY + nHeight; | 
|  |  | 
|  | if ( mbFirstClipRect ) | 
|  | { | 
|  | pBoundRect->left	= nX; | 
|  | pBoundRect->top 	= nY; | 
|  | pBoundRect->right	= nRight; | 
|  | pBoundRect->bottom	= nBottom; | 
|  | mbFirstClipRect = FALSE; | 
|  | } | 
|  | else | 
|  | { | 
|  | if ( nX < pBoundRect->left ) | 
|  | pBoundRect->left = (int)nX; | 
|  |  | 
|  | if ( nY < pBoundRect->top ) | 
|  | pBoundRect->top = (int)nY; | 
|  |  | 
|  | if ( nRight > pBoundRect->right ) | 
|  | pBoundRect->right = (int)nRight; | 
|  |  | 
|  | if ( nBottom > pBoundRect->bottom ) | 
|  | pBoundRect->bottom = (int)nBottom; | 
|  | } | 
|  |  | 
|  | pRect->left 	= (int)nX; | 
|  | pRect->top		= (int)nY; | 
|  | pRect->right	= (int)nRight; | 
|  | pRect->bottom	= (int)nBottom; | 
|  | if( (mpNextClipRect  - (RECT*)(&mpClipRgnData->Buffer)) < (int)mpClipRgnData->rdh.nCount ) | 
|  | mpNextClipRect++; | 
|  | } | 
|  |  | 
|  | // ----------------------------------------------------------------------- | 
|  |  | 
|  | void WinSalFrame::EndSetClipRegion() | 
|  | { | 
|  | if( ! mpClipRgnData ) | 
|  | return; | 
|  |  | 
|  | HRGN hRegion; | 
|  |  | 
|  | // create region from accumulated rectangles | 
|  | if ( mpClipRgnData->rdh.nCount == 1 ) | 
|  | { | 
|  | RECT* pRect = &(mpClipRgnData->rdh.rcBound); | 
|  | hRegion = CreateRectRgn( pRect->left, pRect->top, | 
|  | pRect->right, pRect->bottom ); | 
|  | } | 
|  | else | 
|  | { | 
|  | sal_uLong nSize = mpClipRgnData->rdh.nRgnSize+sizeof(RGNDATAHEADER); | 
|  | hRegion = ExtCreateRegion( NULL, nSize, mpClipRgnData ); | 
|  | } | 
|  | delete [] (BYTE*)mpClipRgnData; | 
|  | mpClipRgnData = NULL; | 
|  |  | 
|  | DBG_ASSERT( hRegion, "WinSalFrame::EndSetClipRegion() - Can't create ClipRegion" ); | 
|  | if( hRegion ) | 
|  | { | 
|  | RECT aWindowRect; | 
|  | GetWindowRect( mhWnd, &aWindowRect ); | 
|  | POINT aPt; | 
|  | aPt.x=0; | 
|  | aPt.y=0; | 
|  | ClientToScreen( mhWnd, &aPt ); | 
|  | OffsetRgn( hRegion, aPt.x - aWindowRect.left, aPt.y - aWindowRect.top ); | 
|  |  | 
|  | if( SetWindowRgn( mhWnd, hRegion, TRUE ) == 0 ) | 
|  | DeleteObject( hRegion ); | 
|  | } | 
|  | } | 
|  |  | 
|  | // ----------------------------------------------------------------------- | 
|  |  | 
|  | static long ImplHandleMouseMsg( HWND hWnd, UINT nMsg, | 
|  | WPARAM wParam, LPARAM lParam ) | 
|  | { | 
|  | WinSalFrame* pFrame = GetWindowPtr( hWnd ); | 
|  | if ( !pFrame ) | 
|  | return 0; | 
|  |  | 
|  | if( nMsg == WM_LBUTTONDOWN || nMsg == WM_MBUTTONDOWN || nMsg == WM_RBUTTONDOWN ) | 
|  | { | 
|  | // #103168# post again if async focus has not arrived yet | 
|  | // hopefully we will not receive the corresponding button up before this | 
|  | // button down arrives again | 
|  | Window *pWin = pFrame->GetWindow(); | 
|  | if( pWin && pWin->ImplGetWindowImpl()->mpFrameData->mnFocusId ) | 
|  | { | 
|  | ImplPostMessage( hWnd, nMsg, wParam, lParam ); | 
|  | return 1; | 
|  | } | 
|  | } | 
|  | SalMouseEvent   aMouseEvt; | 
|  | long            nRet; | 
|  | sal_uInt16          nEvent = 0; | 
|  | sal_Bool            bCall = TRUE; | 
|  |  | 
|  | aMouseEvt.mnX       = (short)LOWORD( lParam ); | 
|  | aMouseEvt.mnY       = (short)HIWORD( lParam ); | 
|  | aMouseEvt.mnCode    = 0; | 
|  | aMouseEvt.mnTime    = GetMessageTime(); | 
|  |  | 
|  | // Wegen (Logitech-)MouseTreiber ueber GetKeyState() gehen, die auf | 
|  | // mittlerer Maustaste Doppelklick simulieren und den KeyStatus nicht | 
|  | // beruecksichtigen | 
|  |  | 
|  | if ( GetKeyState( VK_LBUTTON ) & 0x8000 ) | 
|  | aMouseEvt.mnCode |= MOUSE_LEFT; | 
|  | if ( GetKeyState( VK_MBUTTON ) & 0x8000 ) | 
|  | aMouseEvt.mnCode |= MOUSE_MIDDLE; | 
|  | if ( GetKeyState( VK_RBUTTON ) & 0x8000 ) | 
|  | aMouseEvt.mnCode |= MOUSE_RIGHT; | 
|  | if ( GetKeyState( VK_SHIFT ) & 0x8000 ) | 
|  | aMouseEvt.mnCode |= KEY_SHIFT; | 
|  | if ( GetKeyState( VK_CONTROL ) & 0x8000 ) | 
|  | aMouseEvt.mnCode |= KEY_MOD1; | 
|  | if ( GetKeyState( VK_MENU ) & 0x8000 ) | 
|  | aMouseEvt.mnCode |= KEY_MOD2; | 
|  |  | 
|  | switch ( nMsg ) | 
|  | { | 
|  | case WM_MOUSEMOVE: | 
|  | { | 
|  | // Da bei Druecken von Modifier-Tasten die MouseEvents | 
|  | // nicht zusammengefast werden (da diese durch KeyEvents | 
|  | // unterbrochen werden), machen wir dieses hier selber | 
|  | if ( aMouseEvt.mnCode & (KEY_SHIFT | KEY_MOD1 | KEY_MOD2) ) | 
|  | { | 
|  | MSG aTempMsg; | 
|  | if ( ImplPeekMessage( &aTempMsg, hWnd, WM_MOUSEFIRST, WM_MOUSELAST, PM_NOREMOVE | PM_NOYIELD ) ) | 
|  | { | 
|  | if ( (aTempMsg.message == WM_MOUSEMOVE) && | 
|  | (aTempMsg.wParam == wParam) ) | 
|  | return 1; | 
|  | } | 
|  | } | 
|  |  | 
|  | SalData* pSalData = GetSalData(); | 
|  | // Test for MouseLeave | 
|  | if ( pSalData->mhWantLeaveMsg && (pSalData->mhWantLeaveMsg != hWnd) ) | 
|  | ImplSendMessage( pSalData->mhWantLeaveMsg, SAL_MSG_MOUSELEAVE, 0, GetMessagePos() ); | 
|  |  | 
|  | pSalData->mhWantLeaveMsg = hWnd; | 
|  | // Start MouseLeave-Timer | 
|  | if ( !pSalData->mpMouseLeaveTimer ) | 
|  | { | 
|  | pSalData->mpMouseLeaveTimer = new AutoTimer; | 
|  | pSalData->mpMouseLeaveTimer->SetTimeout( SAL_MOUSELEAVE_TIMEOUT ); | 
|  | pSalData->mpMouseLeaveTimer->Start(); | 
|  | // We don't need to set a timeout handler, because we test | 
|  | // for mouseleave in the timeout callback | 
|  | } | 
|  | aMouseEvt.mnButton = 0; | 
|  | nEvent = SALEVENT_MOUSEMOVE; | 
|  | } | 
|  | break; | 
|  |  | 
|  | case WM_NCMOUSEMOVE: | 
|  | case SAL_MSG_MOUSELEAVE: | 
|  | { | 
|  | SalData* pSalData = GetSalData(); | 
|  | if ( pSalData->mhWantLeaveMsg == hWnd ) | 
|  | { | 
|  | pSalData->mhWantLeaveMsg = 0; | 
|  | if ( pSalData->mpMouseLeaveTimer ) | 
|  | { | 
|  | delete pSalData->mpMouseLeaveTimer; | 
|  | pSalData->mpMouseLeaveTimer = NULL; | 
|  | } | 
|  | // Mouse-Coordinates are relative to the screen | 
|  | POINT aPt; | 
|  | aPt.x = (short)LOWORD( lParam ); | 
|  | aPt.y = (short)HIWORD( lParam ); | 
|  | ScreenToClient( hWnd, &aPt ); | 
|  | aMouseEvt.mnX = aPt.x; | 
|  | aMouseEvt.mnY = aPt.y; | 
|  | aMouseEvt.mnButton = 0; | 
|  | nEvent = SALEVENT_MOUSELEAVE; | 
|  | } | 
|  | else | 
|  | bCall = FALSE; | 
|  | } | 
|  | break; | 
|  |  | 
|  | case WM_LBUTTONDOWN: | 
|  | aMouseEvt.mnButton = MOUSE_LEFT; | 
|  | nEvent = SALEVENT_MOUSEBUTTONDOWN; | 
|  | break; | 
|  |  | 
|  | case WM_MBUTTONDOWN: | 
|  | aMouseEvt.mnButton = MOUSE_MIDDLE; | 
|  | nEvent = SALEVENT_MOUSEBUTTONDOWN; | 
|  | break; | 
|  |  | 
|  | case WM_RBUTTONDOWN: | 
|  | aMouseEvt.mnButton = MOUSE_RIGHT; | 
|  | nEvent = SALEVENT_MOUSEBUTTONDOWN; | 
|  | break; | 
|  |  | 
|  | case WM_LBUTTONUP: | 
|  | aMouseEvt.mnButton = MOUSE_LEFT; | 
|  | nEvent = SALEVENT_MOUSEBUTTONUP; | 
|  | break; | 
|  |  | 
|  | case WM_MBUTTONUP: | 
|  | aMouseEvt.mnButton = MOUSE_MIDDLE; | 
|  | nEvent = SALEVENT_MOUSEBUTTONUP; | 
|  | break; | 
|  |  | 
|  | case WM_RBUTTONUP: | 
|  | aMouseEvt.mnButton = MOUSE_RIGHT; | 
|  | nEvent = SALEVENT_MOUSEBUTTONUP; | 
|  | break; | 
|  | } | 
|  |  | 
|  | // check if this window was destroyed - this might happen if we are the help window | 
|  | // and sent a mouse leave message to the application which killed the help window, i.e. ourself | 
|  | if( !IsWindow( hWnd ) ) | 
|  | return 0; | 
|  |  | 
|  | if ( bCall ) | 
|  | { | 
|  | if ( nEvent == SALEVENT_MOUSEBUTTONDOWN ) | 
|  | UpdateWindow( hWnd ); | 
|  |  | 
|  | // --- RTL --- (mirror mouse pos) | 
|  | if( Application::GetSettings().GetLayoutRTL() ) | 
|  | aMouseEvt.mnX = pFrame->maGeometry.nWidth-1-aMouseEvt.mnX; | 
|  |  | 
|  | nRet = pFrame->CallCallback( nEvent, &aMouseEvt ); | 
|  | if ( nMsg == WM_MOUSEMOVE ) | 
|  | SetCursor( pFrame->mhCursor ); | 
|  | } | 
|  | else | 
|  | nRet = 0; | 
|  |  | 
|  | return nRet; | 
|  | } | 
|  |  | 
|  | // ----------------------------------------------------------------------- | 
|  |  | 
|  | static long ImplHandleMouseActivateMsg( HWND hWnd ) | 
|  | { | 
|  | WinSalFrame* pFrame = GetWindowPtr( hWnd ); | 
|  | if ( !pFrame ) | 
|  | return 0; | 
|  |  | 
|  | if ( pFrame->mbFloatWin ) | 
|  | return TRUE; | 
|  |  | 
|  | SalMouseActivateEvent   aMouseActivateEvt; | 
|  | POINT                   aPt; | 
|  | GetCursorPos( &aPt ); | 
|  | ScreenToClient( hWnd, &aPt ); | 
|  | aMouseActivateEvt.mnX = aPt.x; | 
|  | aMouseActivateEvt.mnY = aPt.y; | 
|  | return pFrame->CallCallback( SALEVENT_MOUSEACTIVATE, &aMouseActivateEvt ); | 
|  | } | 
|  |  | 
|  | // ----------------------------------------------------------------------- | 
|  |  | 
|  | static long ImplHandleWheelMsg( HWND hWnd, UINT nMsg, WPARAM wParam, LPARAM lParam ) | 
|  | { | 
|  | DBG_ASSERT( nMsg == WM_MOUSEWHEEL || | 
|  | nMsg == WM_MOUSEHWHEEL, | 
|  | "ImplHandleWheelMsg() called with no wheel mouse event" ); | 
|  |  | 
|  | ImplSalYieldMutexAcquireWithWait(); | 
|  |  | 
|  | long        nRet = 0; | 
|  | WinSalFrame*   pFrame = GetWindowPtr( hWnd ); | 
|  | if ( pFrame ) | 
|  | { | 
|  | WORD    nWinModCode = LOWORD( wParam ); | 
|  | POINT   aWinPt; | 
|  | aWinPt.x    = (short)LOWORD( lParam ); | 
|  | aWinPt.y    = (short)HIWORD( lParam ); | 
|  | ScreenToClient( hWnd, &aWinPt ); | 
|  |  | 
|  | SalWheelMouseEvent aWheelEvt; | 
|  | aWheelEvt.mnTime        = GetMessageTime(); | 
|  | aWheelEvt.mnX           = aWinPt.x; | 
|  | aWheelEvt.mnY           = aWinPt.y; | 
|  | aWheelEvt.mnCode        = 0; | 
|  | aWheelEvt.mnDelta       = (short)HIWORD( wParam ); | 
|  | aWheelEvt.mnNotchDelta  = aWheelEvt.mnDelta/WHEEL_DELTA; | 
|  | if( aWheelEvt.mnNotchDelta == 0 ) | 
|  | { | 
|  | if( aWheelEvt.mnDelta > 0 ) | 
|  | aWheelEvt.mnNotchDelta = 1; | 
|  | else if( aWheelEvt.mnDelta < 0 ) | 
|  | aWheelEvt.mnNotchDelta = -1; | 
|  | } | 
|  |  | 
|  | if( nMsg == WM_MOUSEWHEEL ) | 
|  | { | 
|  | if ( aSalShlData.mnWheelScrollLines == WHEEL_PAGESCROLL ) | 
|  | aWheelEvt.mnScrollLines = SAL_WHEELMOUSE_EVENT_PAGESCROLL; | 
|  | else | 
|  | aWheelEvt.mnScrollLines = aSalShlData.mnWheelScrollLines; | 
|  | aWheelEvt.mbHorz        = FALSE; | 
|  | } | 
|  | else | 
|  | { | 
|  | aWheelEvt.mnScrollLines = aSalShlData.mnWheelScrollChars; | 
|  | aWheelEvt.mbHorz        = TRUE; | 
|  | // BZ 95390 - seems horiz scrolling has swapped direction | 
|  | aWheelEvt.mnDelta *= -1; | 
|  | aWheelEvt.mnNotchDelta *= -1; | 
|  | } | 
|  |  | 
|  | if ( nWinModCode & MK_SHIFT ) | 
|  | aWheelEvt.mnCode |= KEY_SHIFT; | 
|  | if ( nWinModCode & MK_CONTROL ) | 
|  | aWheelEvt.mnCode |= KEY_MOD1; | 
|  | if ( GetKeyState( VK_MENU ) & 0x8000 ) | 
|  | aWheelEvt.mnCode |= KEY_MOD2; | 
|  |  | 
|  | // --- RTL --- (mirror mouse pos) | 
|  | if( Application::GetSettings().GetLayoutRTL() ) | 
|  | aWheelEvt.mnX = pFrame->maGeometry.nWidth-1-aWheelEvt.mnX; | 
|  |  | 
|  | nRet = pFrame->CallCallback( SALEVENT_WHEELMOUSE, &aWheelEvt ); | 
|  | } | 
|  |  | 
|  | ImplSalYieldMutexRelease(); | 
|  |  | 
|  | return nRet; | 
|  | } | 
|  |  | 
|  | // ----------------------------------------------------------------------- | 
|  |  | 
|  | static sal_uInt16 ImplSalGetKeyCode( WPARAM wParam ) | 
|  | { | 
|  | sal_uInt16 nKeyCode; | 
|  |  | 
|  | // convert KeyCode | 
|  | if ( wParam < KEY_TAB_SIZE ) | 
|  | nKeyCode = aImplTranslateKeyTab[wParam]; | 
|  | else | 
|  | { | 
|  | SalData* pSalData = GetSalData(); | 
|  | std::map< UINT, sal_uInt16 >::const_iterator it = pSalData->maVKMap.find( (UINT)wParam ); | 
|  | if( it != pSalData->maVKMap.end() ) | 
|  | nKeyCode = it->second; | 
|  | else | 
|  | nKeyCode = 0; | 
|  | } | 
|  |  | 
|  | return nKeyCode; | 
|  | } | 
|  |  | 
|  | // ----------------------------------------------------------------------- | 
|  |  | 
|  | static UINT ImplStrToNum( const sal_Char* pStr ) | 
|  | { | 
|  | sal_uInt16 n = 0; | 
|  |  | 
|  | // Solange es sich um eine Ziffer handelt, String umwandeln | 
|  | while( (*pStr >= 48) && (*pStr <= 57) ) | 
|  | { | 
|  | n *= 10; | 
|  | n += ((*pStr) - 48); | 
|  | pStr++; | 
|  | } | 
|  |  | 
|  | return n; | 
|  | } | 
|  |  | 
|  | // ----------------------------------------------------------------------- | 
|  |  | 
|  | static void ImplUpdateInputLang( WinSalFrame* pFrame ) | 
|  | { | 
|  | sal_Bool bLanguageChange = FALSE; | 
|  | UINT nLang = LOWORD( GetKeyboardLayout( 0 ) ); | 
|  | if ( nLang && nLang != pFrame->mnInputLang ) | 
|  | { | 
|  | // keep input lang up-to-date | 
|  | pFrame->mnInputLang = nLang; | 
|  | bLanguageChange = TRUE; | 
|  | } | 
|  |  | 
|  | // If we are on Windows NT we use Unicode FrameProcs and so we | 
|  | // get Unicode charcodes directly from Windows | 
|  | // no need to set up a code page | 
|  | return; | 
|  | } | 
|  |  | 
|  |  | 
|  | static sal_Unicode ImplGetCharCode( WinSalFrame* pFrame, WPARAM nCharCode ) | 
|  | { | 
|  | ImplUpdateInputLang( pFrame ); | 
|  |  | 
|  | // If we are on Windows NT we use Unicode FrameProcs and so we | 
|  | // get Unicode charcodes directly from Windows | 
|  | return (sal_Unicode)nCharCode; | 
|  | } | 
|  |  | 
|  | // ----------------------------------------------------------------------- | 
|  |  | 
|  | LanguageType WinSalFrame::GetInputLanguage() | 
|  | { | 
|  | if( !mnInputLang ) | 
|  | ImplUpdateInputLang( this ); | 
|  |  | 
|  | if( !mnInputLang ) | 
|  | return LANGUAGE_DONTKNOW; | 
|  | else | 
|  | return (LanguageType) mnInputLang; | 
|  | } | 
|  |  | 
|  | // ----------------------------------------------------------------------- | 
|  |  | 
|  | sal_Bool WinSalFrame::MapUnicodeToKeyCode( sal_Unicode aUnicode, LanguageType aLangType, KeyCode& rKeyCode ) | 
|  | { | 
|  | sal_Bool bRet = FALSE; | 
|  | HKL hkl = 0; | 
|  |  | 
|  | // just use the passed language identifier, do not try to load additional keyboard support | 
|  | hkl = (HKL) aLangType; | 
|  |  | 
|  | if( hkl ) | 
|  | { | 
|  | SHORT scan = VkKeyScanExW( aUnicode, hkl ); | 
|  | if( LOWORD(scan) == 0xFFFF ) | 
|  | // keyboard not loaded or key cannot be mapped | 
|  | bRet = FALSE; | 
|  | else | 
|  | { | 
|  | BYTE vkeycode   = LOBYTE(scan); | 
|  | BYTE shiftstate = HIBYTE(scan); | 
|  |  | 
|  | // Last argument is set to FALSE, because there's no decision made | 
|  | // yet which key should be assigned to MOD3 modifier on Windows. | 
|  | // Windows key - user's can be confused, because it should display | 
|  | //               Windows menu (applies to both left/right key) | 
|  | // Menu key    - this key is used to display context menu | 
|  | // AltGr key   - probably it has no sense | 
|  | rKeyCode = KeyCode( ImplSalGetKeyCode( vkeycode ), | 
|  | (shiftstate & 0x01) ? TRUE : FALSE,     // shift | 
|  | (shiftstate & 0x02) ? TRUE : FALSE,     // ctrl | 
|  | (shiftstate & 0x04) ? TRUE : FALSE,     // alt | 
|  | FALSE ); | 
|  | bRet = TRUE; | 
|  | } | 
|  | } | 
|  |  | 
|  | return bRet; | 
|  | } | 
|  |  | 
|  | // ----------------------------------------------------------------------- | 
|  |  | 
|  | static long ImplHandleKeyMsg( HWND hWnd, UINT nMsg, | 
|  | WPARAM wParam, LPARAM lParam, LRESULT& rResult ) | 
|  | { | 
|  | static sal_Bool     bIgnoreCharMsg  = FALSE; | 
|  | static WPARAM   nDeadChar       = 0; | 
|  | static WPARAM   nLastVKChar     = 0; | 
|  | static sal_uInt16   nLastChar       = 0; | 
|  | static sal_uInt16   nLastModKeyCode = 0; | 
|  | static bool     bWaitForModKeyRelease = false; | 
|  | sal_uInt16          nRepeat         = LOWORD( lParam )-1; | 
|  | sal_uInt16          nModCode        = 0; | 
|  |  | 
|  | // Key wurde evtl. durch SysChild an uns weitergeleitet und | 
|  | // darf somit dann nicht doppelt verarbeitet werden | 
|  | GetSalData()->mnSalObjWantKeyEvt = 0; | 
|  |  | 
|  | if ( nMsg == WM_DEADCHAR ) | 
|  | { | 
|  | nDeadChar = wParam; | 
|  | return 0; | 
|  | } | 
|  |  | 
|  | WinSalFrame* pFrame = GetWindowPtr( hWnd ); | 
|  | if ( !pFrame ) | 
|  | return 0; | 
|  |  | 
|  | // Wir restaurieren den Background-Modus bei jeder Texteingabe, | 
|  | // da einige Tools wie RichWin uns diesen hin- und wieder umsetzen | 
|  | if ( pFrame->mpGraphics && | 
|  | pFrame->mpGraphics->getHDC() ) | 
|  | SetBkMode( pFrame->mpGraphics->getHDC(), TRANSPARENT ); | 
|  |  | 
|  | // determine modifiers | 
|  | if ( GetKeyState( VK_SHIFT ) & 0x8000 ) | 
|  | nModCode |= KEY_SHIFT; | 
|  | if ( GetKeyState( VK_CONTROL ) & 0x8000 ) | 
|  | nModCode |= KEY_MOD1; | 
|  | if ( GetKeyState( VK_MENU ) & 0x8000 ) | 
|  | nModCode |= KEY_MOD2; | 
|  |  | 
|  | if ( (nMsg == WM_CHAR) || (nMsg == WM_SYSCHAR) ) | 
|  | { | 
|  | nDeadChar = 0; | 
|  |  | 
|  | if ( bIgnoreCharMsg ) | 
|  | { | 
|  | bIgnoreCharMsg = FALSE; | 
|  | // #101635# if zero is returned here for WM_SYSCHAR (ALT+<key>) Windows will beep | 
|  | // becaus this 'hotkey' was not processed -> better return 1 | 
|  | // except for Alt-SPACE which should always open the sysmenu (#104616#) | 
|  |  | 
|  | // also return zero if a system menubar is available that might process this hotkey | 
|  | // this also applies to the OLE inplace embedding where we are a child window | 
|  | if( (GetWindowStyle( hWnd ) & WS_CHILD) || GetMenu( hWnd ) || (wParam == 0x20) ) | 
|  | return 0; | 
|  | else | 
|  | return 1; | 
|  | } | 
|  |  | 
|  | // Backspace ignorieren wir als eigenstaendige Taste, | 
|  | // damit wir keine Probleme in Kombination mit einem | 
|  | // DeadKey bekommen | 
|  | if ( wParam == 0x08 )    // BACKSPACE | 
|  | return 0; | 
|  |  | 
|  | // Hier kommen nur "freifliegende" WM_CHAR Message an, die durch | 
|  | // eintippen einer ALT-NUMPAD Kombination erzeugt wurden | 
|  | SalKeyEvent aKeyEvt; | 
|  |  | 
|  | if ( (wParam >= '0') && (wParam <= '9') ) | 
|  | aKeyEvt.mnCode = sal::static_int_cast<sal_uInt16>(KEYGROUP_NUM + wParam - '0'); | 
|  | else if ( (wParam >= 'A') && (wParam <= 'Z') ) | 
|  | aKeyEvt.mnCode = sal::static_int_cast<sal_uInt16>(KEYGROUP_ALPHA + wParam - 'A'); | 
|  | else if ( (wParam >= 'a') && (wParam <= 'z') ) | 
|  | aKeyEvt.mnCode = sal::static_int_cast<sal_uInt16>(KEYGROUP_ALPHA + wParam - 'a'); | 
|  | else if ( wParam == 0x0D )    // RETURN | 
|  | aKeyEvt.mnCode = KEY_RETURN; | 
|  | else if ( wParam == 0x1B )    // ESCAPE | 
|  | aKeyEvt.mnCode = KEY_ESCAPE; | 
|  | else if ( wParam == 0x09 )    // TAB | 
|  | aKeyEvt.mnCode = KEY_TAB; | 
|  | else if ( wParam == 0x20 )    // SPACE | 
|  | aKeyEvt.mnCode = KEY_SPACE; | 
|  | else | 
|  | aKeyEvt.mnCode = 0; | 
|  |  | 
|  | aKeyEvt.mnTime      = GetMessageTime(); | 
|  | aKeyEvt.mnCode     |= nModCode; | 
|  | aKeyEvt.mnCharCode  = ImplGetCharCode( pFrame, wParam ); | 
|  | aKeyEvt.mnRepeat    = nRepeat; | 
|  | nLastChar = 0; | 
|  | nLastVKChar = 0; | 
|  | long nRet = pFrame->CallCallback( SALEVENT_KEYINPUT, &aKeyEvt ); | 
|  | pFrame->CallCallback( SALEVENT_KEYUP, &aKeyEvt ); | 
|  | return nRet; | 
|  | } | 
|  | // #i11583#, MCD, 2003-01-13, Support for WM_UNICHAR & Keyman 6.0; addition begins | 
|  | else if( nMsg == WM_UNICHAR ) | 
|  | { | 
|  | // If Windows is asking if we accept WM_UNICHAR, return TRUE | 
|  | if(wParam == UNICODE_NOCHAR) | 
|  | { | 
|  | rResult = TRUE; // ssa: this will actually return TRUE to windows | 
|  | return 1;       // ...but this will only avoid calling the defwindowproc | 
|  | } | 
|  |  | 
|  | SalKeyEvent aKeyEvt; | 
|  | aKeyEvt.mnCode		= nModCode;	// Or should it be 0? - as this is always a character returned | 
|  | aKeyEvt.mnTime		= GetMessageTime(); | 
|  | aKeyEvt.mnRepeat	= 0; | 
|  |  | 
|  | if( wParam >= Uni_SupplementaryPlanesStart ) | 
|  | { | 
|  | // character is supplementary char in UTF-32 format - must be converted to UTF-16 supplementary pair | 
|  | // sal_Unicode ch = (sal_Unicode) Uni_UTF32ToSurrogate1(wParam); | 
|  | nLastChar = 0; | 
|  | nLastVKChar = 0; | 
|  | pFrame->CallCallback( SALEVENT_KEYINPUT, &aKeyEvt ); | 
|  | pFrame->CallCallback( SALEVENT_KEYUP, &aKeyEvt ); | 
|  | wParam = (sal_Unicode) Uni_UTF32ToSurrogate2( wParam ); | 
|  | } | 
|  |  | 
|  | aKeyEvt.mnCharCode	= (sal_Unicode) wParam; | 
|  |  | 
|  | nLastChar = 0; | 
|  | nLastVKChar = 0; | 
|  | long nRet = pFrame->CallCallback( SALEVENT_KEYINPUT, &aKeyEvt ); | 
|  | pFrame->CallCallback( SALEVENT_KEYUP, &aKeyEvt ); | 
|  |  | 
|  | return nRet; | 
|  | } | 
|  | // MCD, 2003-01-13, Support for WM_UNICHAR & Keyman 6.0; addition ends | 
|  | else | 
|  | { | 
|  | // Bei Shift, Control und Menu schicken wir einen KeyModChange-Event | 
|  | if ( (wParam == VK_SHIFT) || (wParam == VK_CONTROL) || (wParam == VK_MENU) ) | 
|  | { | 
|  | SalKeyModEvent aModEvt; | 
|  | aModEvt.mnTime = GetMessageTime(); | 
|  | aModEvt.mnCode = nModCode; | 
|  | aModEvt.mnModKeyCode = 0;   // no command events will be sent if this member is 0 | 
|  |  | 
|  | sal_uInt16 tmpCode = 0; | 
|  | if( GetKeyState( VK_LSHIFT )  & 0x8000 ) | 
|  | tmpCode |= MODKEY_LSHIFT; | 
|  | if( GetKeyState( VK_RSHIFT )  & 0x8000 ) | 
|  | tmpCode |= MODKEY_RSHIFT; | 
|  | if( GetKeyState( VK_LCONTROL ) & 0x8000 ) | 
|  | tmpCode |= MODKEY_LMOD1; | 
|  | if( GetKeyState( VK_RCONTROL ) & 0x8000 ) | 
|  | tmpCode |= MODKEY_RMOD1; | 
|  | if( GetKeyState( VK_LMENU )  & 0x8000 ) | 
|  | tmpCode |= MODKEY_LMOD2; | 
|  | if( GetKeyState( VK_RMENU )  & 0x8000 ) | 
|  | tmpCode |= MODKEY_RMOD2; | 
|  |  | 
|  | if( tmpCode < nLastModKeyCode ) | 
|  | { | 
|  | aModEvt.mnModKeyCode = nLastModKeyCode; | 
|  | nLastModKeyCode = 0; | 
|  | bWaitForModKeyRelease = true; | 
|  | } | 
|  | else | 
|  | { | 
|  | if( !bWaitForModKeyRelease ) | 
|  | nLastModKeyCode = tmpCode; | 
|  | } | 
|  |  | 
|  | if( !tmpCode ) | 
|  | bWaitForModKeyRelease = false; | 
|  |  | 
|  | return pFrame->CallCallback( SALEVENT_KEYMODCHANGE, &aModEvt ); | 
|  | } | 
|  | else | 
|  | { | 
|  | SalKeyEvent     aKeyEvt; | 
|  | sal_uInt16          nEvent; | 
|  | MSG             aCharMsg; | 
|  | BOOL        bCharPeek = FALSE; | 
|  | UINT            nCharMsg = WM_CHAR; | 
|  | sal_Bool            bKeyUp = (nMsg == WM_KEYUP) || (nMsg == WM_SYSKEYUP); | 
|  |  | 
|  | nLastModKeyCode = 0; // make sure no modkey messages are sent if they belong to a hotkey (see above) | 
|  | aKeyEvt.mnCharCode = 0; | 
|  | aKeyEvt.mnCode = 0; | 
|  |  | 
|  | aKeyEvt.mnCode = ImplSalGetKeyCode( wParam ); | 
|  | if ( !bKeyUp ) | 
|  | { | 
|  | // check for charcode | 
|  | // Mit Hilfe von PeekMessage holen wir uns jetzt die | 
|  | // zugehoerige WM_CHAR Message, wenn vorhanden. | 
|  | // Diese WM_CHAR Message steht immer am Anfang der | 
|  | // Messagequeue. Ausserdem ist sichergestellt, dass immer | 
|  | // nur eine WM_CHAR Message in der Queue steht. | 
|  | bCharPeek = ImplPeekMessage( &aCharMsg, hWnd, | 
|  | WM_CHAR, WM_CHAR, PM_NOREMOVE | PM_NOYIELD ); | 
|  | if ( bCharPeek && (nDeadChar == aCharMsg.wParam) ) | 
|  | { | 
|  | bCharPeek = FALSE; | 
|  | nDeadChar = 0; | 
|  |  | 
|  | if ( wParam == VK_BACK ) | 
|  | { | 
|  | ImplPeekMessage( &aCharMsg, hWnd, | 
|  | nCharMsg, nCharMsg, PM_REMOVE | PM_NOYIELD ); | 
|  | return 0; | 
|  | } | 
|  | } | 
|  | else | 
|  | { | 
|  | if ( !bCharPeek ) | 
|  | { | 
|  | bCharPeek = ImplPeekMessage( &aCharMsg, hWnd, | 
|  | WM_SYSCHAR, WM_SYSCHAR, PM_NOREMOVE | PM_NOYIELD ); | 
|  | nCharMsg = WM_SYSCHAR; | 
|  | } | 
|  | } | 
|  | if ( bCharPeek ) | 
|  | aKeyEvt.mnCharCode = ImplGetCharCode( pFrame, aCharMsg.wParam ); | 
|  | else | 
|  | aKeyEvt.mnCharCode = 0; | 
|  |  | 
|  | nLastChar = aKeyEvt.mnCharCode; | 
|  | nLastVKChar = wParam; | 
|  | } | 
|  | else | 
|  | { | 
|  | if ( wParam == nLastVKChar ) | 
|  | { | 
|  | aKeyEvt.mnCharCode = nLastChar; | 
|  | nLastChar = 0; | 
|  | nLastVKChar = 0; | 
|  | } | 
|  | } | 
|  |  | 
|  | if ( aKeyEvt.mnCode || aKeyEvt.mnCharCode ) | 
|  | { | 
|  | if ( bKeyUp ) | 
|  | nEvent = SALEVENT_KEYUP; | 
|  | else | 
|  | nEvent = SALEVENT_KEYINPUT; | 
|  |  | 
|  | aKeyEvt.mnTime      = GetMessageTime(); | 
|  | aKeyEvt.mnCode     |= nModCode; | 
|  | aKeyEvt.mnRepeat    = nRepeat; | 
|  |  | 
|  | if( (nModCode & (KEY_MOD1|KEY_MOD2)) == (KEY_MOD1|KEY_MOD2) && | 
|  | aKeyEvt.mnCharCode ) | 
|  | { | 
|  | // this is actually AltGr and should not be handled as Alt | 
|  | aKeyEvt.mnCode &= ~(KEY_MOD1|KEY_MOD2); | 
|  | } | 
|  |  | 
|  | bIgnoreCharMsg = bCharPeek ? TRUE : FALSE; | 
|  | long nRet = pFrame->CallCallback( nEvent, &aKeyEvt ); | 
|  | // independent part only reacts on keyup but Windows does not send | 
|  | // keyup for VK_HANJA | 
|  | if( aKeyEvt.mnCode == KEY_HANGUL_HANJA ) | 
|  | nRet = pFrame->CallCallback( SALEVENT_KEYUP, &aKeyEvt ); | 
|  |  | 
|  | bIgnoreCharMsg = FALSE; | 
|  |  | 
|  | // char-message, than remove or ignore | 
|  | if ( bCharPeek ) | 
|  | { | 
|  | nDeadChar = 0; | 
|  | if ( nRet ) | 
|  | { | 
|  | ImplPeekMessage( &aCharMsg, hWnd, | 
|  | nCharMsg, nCharMsg, PM_REMOVE | PM_NOYIELD ); | 
|  | } | 
|  | else | 
|  | bIgnoreCharMsg = TRUE; | 
|  | } | 
|  |  | 
|  | return nRet; | 
|  | } | 
|  | else | 
|  | return 0; | 
|  | } | 
|  | } | 
|  | } | 
|  |  | 
|  | // ----------------------------------------------------------------------- | 
|  |  | 
|  | long ImplHandleSalObjKeyMsg( HWND hWnd, UINT nMsg, | 
|  | WPARAM wParam, LPARAM lParam ) | 
|  | { | 
|  | if ( (nMsg == WM_KEYDOWN) || (nMsg == WM_KEYUP) ) | 
|  | { | 
|  | WinSalFrame* pFrame = GetWindowPtr( hWnd ); | 
|  | if ( !pFrame ) | 
|  | return 0; | 
|  |  | 
|  | sal_uInt16  nRepeat     = LOWORD( lParam )-1; | 
|  | sal_uInt16  nModCode    = 0; | 
|  |  | 
|  | // determine modifiers | 
|  | if ( GetKeyState( VK_SHIFT ) & 0x8000 ) | 
|  | nModCode |= KEY_SHIFT; | 
|  | if ( GetKeyState( VK_CONTROL ) & 0x8000 ) | 
|  | nModCode |= KEY_MOD1; | 
|  | if ( GetKeyState( VK_MENU ) & 0x8000 ) | 
|  | nModCode |= KEY_MOD2; | 
|  |  | 
|  | if ( (wParam != VK_SHIFT) && (wParam != VK_CONTROL) && (wParam != VK_MENU) ) | 
|  | { | 
|  | SalKeyEvent     aKeyEvt; | 
|  | sal_uInt16          nEvent; | 
|  | sal_Bool            bKeyUp = (nMsg == WM_KEYUP) || (nMsg == WM_SYSKEYUP); | 
|  |  | 
|  | // convert KeyCode | 
|  | aKeyEvt.mnCode      = ImplSalGetKeyCode( wParam ); | 
|  | aKeyEvt.mnCharCode  = 0; | 
|  |  | 
|  | if ( aKeyEvt.mnCode ) | 
|  | { | 
|  | if ( bKeyUp ) | 
|  | nEvent = SALEVENT_KEYUP; | 
|  | else | 
|  | nEvent = SALEVENT_KEYINPUT; | 
|  |  | 
|  | aKeyEvt.mnTime      = GetMessageTime(); | 
|  | aKeyEvt.mnCode     |= nModCode; | 
|  | aKeyEvt.mnRepeat    = nRepeat; | 
|  | long nRet = pFrame->CallCallback( nEvent, &aKeyEvt ); | 
|  | return nRet; | 
|  | } | 
|  | else | 
|  | return 0; | 
|  | } | 
|  | } | 
|  |  | 
|  | return 0; | 
|  | } | 
|  |  | 
|  | // ----------------------------------------------------------------------- | 
|  |  | 
|  | long ImplHandleSalObjSysCharMsg( HWND hWnd, WPARAM wParam, LPARAM lParam ) | 
|  | { | 
|  | WinSalFrame* pFrame = GetWindowPtr( hWnd ); | 
|  | if ( !pFrame ) | 
|  | return 0; | 
|  |  | 
|  | sal_uInt16  nRepeat     = LOWORD( lParam )-1; | 
|  | sal_uInt16  nModCode    = 0; | 
|  | sal_uInt16  cKeyCode    = (sal_uInt16)wParam; | 
|  |  | 
|  | // determine modifiers | 
|  | if ( GetKeyState( VK_SHIFT ) & 0x8000 ) | 
|  | nModCode |= KEY_SHIFT; | 
|  | if ( GetKeyState( VK_CONTROL ) & 0x8000 ) | 
|  | nModCode |= KEY_MOD1; | 
|  | nModCode |= KEY_MOD2; | 
|  |  | 
|  | // KeyEvent zusammenbauen | 
|  | SalKeyEvent aKeyEvt; | 
|  | aKeyEvt.mnTime      = GetMessageTime(); | 
|  | if ( (cKeyCode >= 48) && (cKeyCode <= 57) ) | 
|  | aKeyEvt.mnCode = KEY_0+(cKeyCode-48); | 
|  | else if ( (cKeyCode >= 65) && (cKeyCode <= 90) ) | 
|  | aKeyEvt.mnCode = KEY_A+(cKeyCode-65); | 
|  | else  if ( (cKeyCode >= 97) && (cKeyCode <= 122) ) | 
|  | aKeyEvt.mnCode = KEY_A+(cKeyCode-97); | 
|  | else | 
|  | aKeyEvt.mnCode = 0; | 
|  | aKeyEvt.mnCode     |= nModCode; | 
|  | aKeyEvt.mnCharCode  = ImplGetCharCode( pFrame, cKeyCode ); | 
|  | aKeyEvt.mnRepeat    = nRepeat; | 
|  | long nRet = pFrame->CallCallback( SALEVENT_KEYINPUT, &aKeyEvt ); | 
|  | pFrame->CallCallback( SALEVENT_KEYUP, &aKeyEvt ); | 
|  | return nRet; | 
|  | } | 
|  |  | 
|  | // ----------------------------------------------------------------------- | 
|  |  | 
|  | static bool ImplHandlePaintMsg( HWND hWnd ) | 
|  | { | 
|  | sal_Bool bMutex = FALSE; | 
|  | if ( ImplSalYieldMutexTryToAcquire() ) | 
|  | bMutex = TRUE; | 
|  |  | 
|  | // if we don't get the mutex, we can also change the clip region, | 
|  | // because other threads doesn't use the mutex from the main | 
|  | // thread --> see GetGraphics() | 
|  |  | 
|  | WinSalFrame* pFrame = GetWindowPtr( hWnd ); | 
|  | if ( pFrame ) | 
|  | { | 
|  | // Clip-Region muss zurueckgesetzt werden, da wir sonst kein | 
|  | // ordentliches Bounding-Rectangle bekommen | 
|  | if ( pFrame->mpGraphics && pFrame->mpGraphics->mhRegion ) | 
|  | SelectClipRgn( pFrame->mpGraphics->getHDC(), 0 ); | 
|  |  | 
|  | // Laut Window-Doku soll man erst abfragen, ob ueberhaupt eine | 
|  | // Paint-Region anliegt | 
|  | if ( GetUpdateRect( hWnd, NULL, FALSE ) ) | 
|  | { | 
|  | // Call BeginPaint/EndPaint to query the rect and send | 
|  | // this Notofication to rect | 
|  | RECT aUpdateRect; | 
|  | PAINTSTRUCT aPs; | 
|  | BeginPaint( hWnd, &aPs ); | 
|  | CopyRect( &aUpdateRect, &aPs.rcPaint ); | 
|  |  | 
|  | // Paint | 
|  | // ClipRegion wieder herstellen | 
|  | if ( pFrame->mpGraphics && pFrame->mpGraphics->mhRegion ) | 
|  | { | 
|  | SelectClipRgn( pFrame->mpGraphics->getHDC(), | 
|  | pFrame->mpGraphics->mhRegion ); | 
|  | } | 
|  |  | 
|  | if ( bMutex ) | 
|  | { | 
|  | SalPaintEvent aPEvt( aUpdateRect.left, aUpdateRect.top, aUpdateRect.right-aUpdateRect.left, aUpdateRect.bottom-aUpdateRect.top, pFrame->mbPresentation ); | 
|  | pFrame->CallCallback( SALEVENT_PAINT, &aPEvt ); | 
|  | } | 
|  | else | 
|  | { | 
|  | RECT* pRect = new RECT; | 
|  | CopyRect( pRect, &aUpdateRect ); | 
|  | ImplPostMessage( hWnd, SAL_MSG_POSTPAINT, (WPARAM)pRect, 0 ); | 
|  | } | 
|  | EndPaint( hWnd, &aPs ); | 
|  | } | 
|  | else | 
|  | { | 
|  | // ClipRegion wieder herstellen | 
|  | if ( pFrame->mpGraphics && pFrame->mpGraphics->mhRegion ) | 
|  | { | 
|  | SelectClipRgn( pFrame->mpGraphics->getHDC(), | 
|  | pFrame->mpGraphics->mhRegion ); | 
|  | } | 
|  | } | 
|  | } | 
|  |  | 
|  | if ( bMutex ) | 
|  | ImplSalYieldMutexRelease(); | 
|  |  | 
|  | return bMutex ? true : false; | 
|  | } | 
|  |  | 
|  | // ----------------------------------------------------------------------- | 
|  |  | 
|  | static void ImplHandlePaintMsg2( HWND hWnd, RECT* pRect ) | 
|  | { | 
|  | // Paint | 
|  | if ( ImplSalYieldMutexTryToAcquire() ) | 
|  | { | 
|  | WinSalFrame* pFrame = GetWindowPtr( hWnd ); | 
|  | if ( pFrame ) | 
|  | { | 
|  | SalPaintEvent aPEvt( pRect->left, pRect->top, pRect->right-pRect->left, pRect->bottom-pRect->top ); | 
|  | pFrame->CallCallback( SALEVENT_PAINT, &aPEvt ); | 
|  | } | 
|  | ImplSalYieldMutexRelease(); | 
|  | delete pRect; | 
|  | } | 
|  | else | 
|  | ImplPostMessage( hWnd, SAL_MSG_POSTPAINT, (WPARAM)pRect, 0 ); | 
|  | } | 
|  |  | 
|  | // ----------------------------------------------------------------------- | 
|  |  | 
|  | static void SetMaximizedFrameGeometry( HWND hWnd, WinSalFrame* pFrame, RECT* pParentRect ) | 
|  | { | 
|  | // calculate and set frame geometry of a maximized window - useful if the window is still hidden | 
|  |  | 
|  | // dualmonitor support: | 
|  | // Get screensize of the monitor with the mouse pointer | 
|  |  | 
|  | RECT aRectMouse; | 
|  | if( ! pParentRect ) | 
|  | { | 
|  | POINT pt; | 
|  | GetCursorPos( &pt ); | 
|  | aRectMouse.left = pt.x; | 
|  | aRectMouse.top = pt.y; | 
|  | aRectMouse.right = pt.x+2; | 
|  | aRectMouse.bottom = pt.y+2; | 
|  | pParentRect = &aRectMouse; | 
|  | } | 
|  |  | 
|  | RECT aRect; | 
|  | ImplSalGetWorkArea( hWnd, &aRect, pParentRect ); | 
|  |  | 
|  | // a maximized window has no other borders than the caption | 
|  | pFrame->maGeometry.nLeftDecoration = pFrame->maGeometry.nRightDecoration = pFrame->maGeometry.nBottomDecoration = 0; | 
|  | pFrame->maGeometry.nTopDecoration = pFrame->mbCaption ? GetSystemMetrics( SM_CYCAPTION ) : 0; | 
|  |  | 
|  | aRect.top += pFrame->maGeometry.nTopDecoration; | 
|  | pFrame->maGeometry.nX = aRect.left; | 
|  | pFrame->maGeometry.nY = aRect.top; | 
|  | pFrame->maGeometry.nWidth = aRect.right - aRect.left; | 
|  | pFrame->maGeometry.nHeight = aRect.bottom - aRect.top; | 
|  | } | 
|  |  | 
|  | static void UpdateFrameGeometry( HWND hWnd, WinSalFrame* pFrame ) | 
|  | { | 
|  | if( !pFrame ) | 
|  | return; | 
|  |  | 
|  | RECT aRect; | 
|  | GetWindowRect( hWnd, &aRect ); | 
|  | memset(&pFrame->maGeometry, 0, sizeof(SalFrameGeometry) ); | 
|  |  | 
|  | if ( IsIconic( hWnd ) ) | 
|  | return; | 
|  |  | 
|  | POINT aPt; | 
|  | aPt.x=0; | 
|  | aPt.y=0; | 
|  | ClientToScreen(hWnd, &aPt); | 
|  | int cx = aPt.x - aRect.left; | 
|  | pFrame->maGeometry.nTopDecoration = aPt.y - aRect.top; | 
|  |  | 
|  | pFrame->maGeometry.nLeftDecoration = cx; | 
|  | pFrame->maGeometry.nRightDecoration = cx; | 
|  |  | 
|  | pFrame->maGeometry.nX = aPt.x; | 
|  | pFrame->maGeometry.nY = aPt.y; | 
|  |  | 
|  | RECT aInnerRect; | 
|  | GetClientRect( hWnd, &aInnerRect ); | 
|  | if( aInnerRect.right ) | 
|  | { | 
|  | // improve right decoration | 
|  | aPt.x=aInnerRect.right; | 
|  | aPt.y=aInnerRect.top; | 
|  | ClientToScreen(hWnd, &aPt); | 
|  | pFrame->maGeometry.nRightDecoration = aRect.right - aPt.x; | 
|  | } | 
|  | if( aInnerRect.bottom ) // may be zero if window was not shown yet | 
|  | pFrame->maGeometry.nBottomDecoration += aRect.bottom - aPt.y - aInnerRect.bottom; | 
|  | else | 
|  | // bottom border is typically the same as left/right | 
|  | pFrame->maGeometry.nBottomDecoration = pFrame->maGeometry.nLeftDecoration; | 
|  |  | 
|  | int nWidth  = aRect.right - aRect.left | 
|  | - pFrame->maGeometry.nRightDecoration - pFrame->maGeometry.nLeftDecoration; | 
|  | int nHeight = aRect.bottom - aRect.top | 
|  | - pFrame->maGeometry.nBottomDecoration - pFrame->maGeometry.nTopDecoration; | 
|  | // clamp to zero | 
|  | pFrame->maGeometry.nHeight = nHeight < 0 ? 0 : nHeight; | 
|  | pFrame->maGeometry.nWidth = nWidth < 0 ? 0 : nWidth; | 
|  | pFrame->updateScreenNumber(); | 
|  | } | 
|  |  | 
|  | // ----------------------------------------------------------------------- | 
|  |  | 
|  | static void ImplCallMoveHdl( HWND hWnd ) | 
|  | { | 
|  | WinSalFrame* pFrame = GetWindowPtr( hWnd ); | 
|  | if ( pFrame ) | 
|  | { | 
|  | pFrame->CallCallback( SALEVENT_MOVE, 0 ); | 
|  | // Um doppelte Paints von VCL und SAL zu vermeiden | 
|  | //if ( IsWindowVisible( hWnd ) && !pFrame->mbInShow ) | 
|  | //    UpdateWindow( hWnd ); | 
|  | } | 
|  | } | 
|  |  | 
|  | // ----------------------------------------------------------------------- | 
|  |  | 
|  | static void ImplCallClosePopupsHdl( HWND hWnd ) | 
|  | { | 
|  | WinSalFrame* pFrame = GetWindowPtr( hWnd ); | 
|  | if ( pFrame ) | 
|  | { | 
|  | pFrame->CallCallback( SALEVENT_CLOSEPOPUPS, 0 ); | 
|  | } | 
|  | } | 
|  |  | 
|  | // ----------------------------------------------------------------------- | 
|  |  | 
|  | static void ImplHandleMoveMsg( HWND hWnd ) | 
|  | { | 
|  | if ( ImplSalYieldMutexTryToAcquire() ) | 
|  | { | 
|  | WinSalFrame* pFrame = GetWindowPtr( hWnd ); | 
|  | if ( pFrame ) | 
|  | { | 
|  | UpdateFrameGeometry( hWnd, pFrame ); | 
|  |  | 
|  | if ( GetWindowStyle( hWnd ) & WS_VISIBLE ) | 
|  | pFrame->mbDefPos = FALSE; | 
|  |  | 
|  | // Gegen moegliche Rekursionen sichern | 
|  | if ( !pFrame->mbInMoveMsg ) | 
|  | { | 
|  | // Fenster im FullScreenModus wieder einpassen | 
|  | pFrame->mbInMoveMsg = TRUE; | 
|  | if ( pFrame->mbFullScreen ) | 
|  | ImplSalFrameFullScreenPos( pFrame ); | 
|  | pFrame->mbInMoveMsg = FALSE; | 
|  | } | 
|  |  | 
|  | // Status merken | 
|  | ImplSaveFrameState( pFrame ); | 
|  |  | 
|  | // Call Hdl | 
|  | //#93851 if we call this handler, VCL floating windows are not updated correctly | 
|  | ImplCallMoveHdl( hWnd ); | 
|  |  | 
|  | } | 
|  |  | 
|  | ImplSalYieldMutexRelease(); | 
|  | } | 
|  | else | 
|  | ImplPostMessage( hWnd, SAL_MSG_POSTMOVE, 0, 0 ); | 
|  | } | 
|  |  | 
|  | // ----------------------------------------------------------------------- | 
|  |  | 
|  | static void ImplCallSizeHdl( HWND hWnd ) | 
|  | { | 
|  | // Da Windows diese Messages auch senden kann, muss hier auch die | 
|  | // Solar-Semaphore beruecksichtigt werden | 
|  | if ( ImplSalYieldMutexTryToAcquire() ) | 
|  | { | 
|  | WinSalFrame* pFrame = GetWindowPtr( hWnd ); | 
|  | if ( pFrame ) | 
|  | { | 
|  | pFrame->CallCallback( SALEVENT_RESIZE, 0 ); | 
|  | // Um doppelte Paints von VCL und SAL zu vermeiden | 
|  | if ( IsWindowVisible( hWnd ) && !pFrame->mbInShow ) | 
|  | UpdateWindow( hWnd ); | 
|  | } | 
|  |  | 
|  | ImplSalYieldMutexRelease(); | 
|  | } | 
|  | else | 
|  | ImplPostMessage( hWnd, SAL_MSG_POSTCALLSIZE, 0, 0 ); | 
|  | } | 
|  |  | 
|  | // ----------------------------------------------------------------------- | 
|  |  | 
|  | static void ImplHandleSizeMsg( HWND hWnd, WPARAM wParam, LPARAM lParam ) | 
|  | { | 
|  | if ( (wParam != SIZE_MAXSHOW) && (wParam != SIZE_MAXHIDE) ) | 
|  | { | 
|  | WinSalFrame* pFrame = GetWindowPtr( hWnd ); | 
|  | if ( pFrame ) | 
|  | { | 
|  | UpdateFrameGeometry( hWnd, pFrame ); | 
|  |  | 
|  | pFrame->mnWidth  = (int)LOWORD(lParam); | 
|  | pFrame->mnHeight = (int)HIWORD(lParam); | 
|  | // Status merken | 
|  | ImplSaveFrameState( pFrame ); | 
|  | // Call Hdl | 
|  | ImplCallSizeHdl( hWnd ); | 
|  | } | 
|  | } | 
|  | } | 
|  |  | 
|  | // ----------------------------------------------------------------------- | 
|  |  | 
|  | static void ImplHandleFocusMsg( HWND hWnd ) | 
|  | { | 
|  | if ( ImplSalYieldMutexTryToAcquire() ) | 
|  | { | 
|  | WinSalFrame* pFrame = GetWindowPtr( hWnd ); | 
|  | if ( pFrame && !WinSalFrame::mbInReparent ) | 
|  | { | 
|  | // Query the actual status | 
|  | if ( ::GetFocus() == hWnd ) | 
|  | { | 
|  | if ( IsWindowVisible( hWnd ) && !pFrame->mbInShow ) | 
|  | UpdateWindow( hWnd ); | 
|  |  | 
|  | // Feststellen, ob wir IME unterstuetzen | 
|  | if ( pFrame->mbIME && pFrame->mhDefIMEContext ) | 
|  | { | 
|  | UINT nImeProps = ImmGetProperty( GetKeyboardLayout( 0 ), IGP_PROPERTY ); | 
|  |  | 
|  | pFrame->mbSpezIME = (nImeProps & IME_PROP_SPECIAL_UI) != 0; | 
|  | pFrame->mbAtCursorIME = (nImeProps & IME_PROP_AT_CARET) != 0; | 
|  | pFrame->mbHandleIME = !pFrame->mbSpezIME; | 
|  | } | 
|  |  | 
|  | pFrame->CallCallback( SALEVENT_GETFOCUS, 0 ); | 
|  | } | 
|  | else | 
|  | { | 
|  | pFrame->CallCallback( SALEVENT_LOSEFOCUS, 0 ); | 
|  | } | 
|  | } | 
|  |  | 
|  | ImplSalYieldMutexRelease(); | 
|  | } | 
|  | else | 
|  | ImplPostMessage( hWnd, SAL_MSG_POSTFOCUS, 0, 0 ); | 
|  | } | 
|  |  | 
|  | // ----------------------------------------------------------------------- | 
|  |  | 
|  | static void ImplHandleCloseMsg( HWND hWnd ) | 
|  | { | 
|  | if ( ImplSalYieldMutexTryToAcquire() ) | 
|  | { | 
|  | WinSalFrame* pFrame = GetWindowPtr( hWnd ); | 
|  | if ( pFrame ) | 
|  | { | 
|  | pFrame->CallCallback( SALEVENT_CLOSE, 0 ); | 
|  | } | 
|  |  | 
|  | ImplSalYieldMutexRelease(); | 
|  | } | 
|  | else | 
|  | ImplPostMessage( hWnd, WM_CLOSE, 0, 0 ); | 
|  | } | 
|  |  | 
|  | // ----------------------------------------------------------------------- | 
|  |  | 
|  | static long ImplHandleShutDownMsg( HWND hWnd ) | 
|  | { | 
|  | ImplSalYieldMutexAcquireWithWait(); | 
|  | long        nRet = 0; | 
|  | WinSalFrame*   pFrame = GetWindowPtr( hWnd ); | 
|  | if ( pFrame ) | 
|  | { | 
|  | nRet = pFrame->CallCallback( SALEVENT_SHUTDOWN, 0 ); | 
|  | } | 
|  | ImplSalYieldMutexRelease(); | 
|  | return nRet; | 
|  | } | 
|  |  | 
|  | // ----------------------------------------------------------------------- | 
|  |  | 
|  | static void ImplHandleSettingsChangeMsg( HWND hWnd, UINT nMsg, | 
|  | WPARAM wParam, LPARAM lParam ) | 
|  | { | 
|  | sal_uInt16 nSalEvent = SALEVENT_SETTINGSCHANGED; | 
|  |  | 
|  | if ( nMsg == WM_DEVMODECHANGE ) | 
|  | nSalEvent = SALEVENT_PRINTERCHANGED; | 
|  | else if ( nMsg == WM_DISPLAYCHANGE ) | 
|  | nSalEvent = SALEVENT_DISPLAYCHANGED; | 
|  | else if ( nMsg == WM_FONTCHANGE ) | 
|  | nSalEvent = SALEVENT_FONTCHANGED; | 
|  | else if ( nMsg == WM_TIMECHANGE ) | 
|  | nSalEvent = SALEVENT_DATETIMECHANGED; | 
|  | else if ( nMsg == WM_WININICHANGE ) | 
|  | { | 
|  | if ( lParam ) | 
|  | { | 
|  | if ( ImplSalWICompareAscii( (const wchar_t*)lParam, "devices" ) == 0 ) | 
|  | nSalEvent = SALEVENT_PRINTERCHANGED; | 
|  | } | 
|  | } | 
|  |  | 
|  | if ( nMsg == WM_SETTINGCHANGE ) | 
|  | { | 
|  | if ( wParam == SPI_SETWHEELSCROLLLINES ) | 
|  | aSalShlData.mnWheelScrollLines = ImplSalGetWheelScrollLines(); | 
|  | else if( wParam == SPI_SETWHEELSCROLLCHARS ) | 
|  | aSalShlData.mnWheelScrollChars = ImplSalGetWheelScrollChars(); | 
|  | } | 
|  |  | 
|  | if ( WM_SYSCOLORCHANGE == nMsg && GetSalData()->mhDitherPal ) | 
|  | ImplUpdateSysColorEntries(); | 
|  |  | 
|  | ImplSalYieldMutexAcquireWithWait(); | 
|  |  | 
|  | WinSalFrame* pFrame = GetWindowPtr( hWnd ); | 
|  | if ( pFrame ) | 
|  | { | 
|  | if ( (nMsg == WM_DISPLAYCHANGE) || (nMsg == WM_WININICHANGE) ) | 
|  | { | 
|  | if ( pFrame->mbFullScreen ) | 
|  | ImplSalFrameFullScreenPos( pFrame ); | 
|  | } | 
|  |  | 
|  | pFrame->CallCallback( nSalEvent, 0 ); | 
|  | } | 
|  |  | 
|  | ImplSalYieldMutexRelease(); | 
|  | } | 
|  |  | 
|  | // ----------------------------------------------------------------------- | 
|  |  | 
|  | static void ImplHandleUserEvent( HWND hWnd, LPARAM lParam ) | 
|  | { | 
|  | ImplSalYieldMutexAcquireWithWait(); | 
|  | WinSalFrame* pFrame = GetWindowPtr( hWnd ); | 
|  | if ( pFrame ) | 
|  | { | 
|  | pFrame->CallCallback( SALEVENT_USEREVENT, (void*)lParam ); | 
|  | } | 
|  | ImplSalYieldMutexRelease(); | 
|  | } | 
|  |  | 
|  | // ----------------------------------------------------------------------- | 
|  |  | 
|  | static void ImplHandleForcePalette( HWND hWnd ) | 
|  | { | 
|  | SalData*    pSalData = GetSalData(); | 
|  | HPALETTE    hPal = pSalData->mhDitherPal; | 
|  | if ( hPal ) | 
|  | { | 
|  | if ( !ImplSalYieldMutexTryToAcquire() ) | 
|  | { | 
|  | ImplPostMessage( hWnd, SAL_MSG_FORCEPALETTE, 0, 0 ); | 
|  | return; | 
|  | } | 
|  |  | 
|  | WinSalFrame* pFrame = GetWindowPtr( hWnd ); | 
|  | if ( pFrame && pFrame->mpGraphics ) | 
|  | { | 
|  | WinSalGraphics* pGraphics = pFrame->mpGraphics; | 
|  | if ( pGraphics && pGraphics->mhDefPal ) | 
|  | { | 
|  | SelectPalette( pGraphics->getHDC(), hPal, FALSE ); | 
|  | if ( RealizePalette( pGraphics->getHDC() ) ) | 
|  | { | 
|  | InvalidateRect( hWnd, NULL, FALSE ); | 
|  | UpdateWindow( hWnd ); | 
|  | pFrame->CallCallback( SALEVENT_DISPLAYCHANGED, 0 ); | 
|  | } | 
|  | } | 
|  | } | 
|  |  | 
|  | ImplSalYieldMutexRelease(); | 
|  | } | 
|  | } | 
|  |  | 
|  | // ----------------------------------------------------------------------- | 
|  |  | 
|  | static LRESULT ImplHandlePalette( sal_Bool bFrame, HWND hWnd, UINT nMsg, | 
|  | WPARAM wParam, LPARAM lParam, int& rDef ) | 
|  | { | 
|  | SalData*    pSalData = GetSalData(); | 
|  | HPALETTE    hPal = pSalData->mhDitherPal; | 
|  | if ( !hPal ) | 
|  | return 0; | 
|  |  | 
|  | rDef = FALSE; | 
|  | if ( pSalData->mbInPalChange ) | 
|  | return 0; | 
|  |  | 
|  | if ( (nMsg == WM_PALETTECHANGED) || (nMsg == SAL_MSG_POSTPALCHANGED) ) | 
|  | { | 
|  | if ( (HWND)wParam == hWnd ) | 
|  | return 0; | 
|  | } | 
|  |  | 
|  | sal_Bool bReleaseMutex = FALSE; | 
|  | if ( (nMsg == WM_QUERYNEWPALETTE) || (nMsg == WM_PALETTECHANGED) ) | 
|  | { | 
|  | // Da Windows diese Messages auch sendet, muss hier auch die | 
|  | // Solar-Semaphore beruecksichtigt werden | 
|  | if ( ImplSalYieldMutexTryToAcquire() ) | 
|  | bReleaseMutex = TRUE; | 
|  | else if ( nMsg == WM_QUERYNEWPALETTE ) | 
|  | ImplPostMessage( hWnd, SAL_MSG_POSTQUERYNEWPAL, wParam, lParam ); | 
|  | else /* ( nMsg == WM_PALETTECHANGED ) */ | 
|  | ImplPostMessage( hWnd, SAL_MSG_POSTPALCHANGED, wParam, lParam ); | 
|  | } | 
|  |  | 
|  | WinSalVirtualDevice*pTempVD; | 
|  | WinSalFrame*        pTempFrame; | 
|  | WinSalGraphics*     pGraphics; | 
|  | HDC                 hDC; | 
|  | HPALETTE            hOldPal; | 
|  | UINT                nCols; | 
|  | sal_Bool                bStdDC; | 
|  | sal_Bool                bUpdate; | 
|  |  | 
|  | pSalData->mbInPalChange = TRUE; | 
|  |  | 
|  | // Alle Paletten in VirDevs und Frames zuruecksetzen | 
|  | pTempVD = pSalData->mpFirstVD; | 
|  | while ( pTempVD ) | 
|  | { | 
|  | pGraphics = pTempVD->mpGraphics; | 
|  | if ( pGraphics->mhDefPal ) | 
|  | { | 
|  | SelectPalette( pGraphics->getHDC(), | 
|  | pGraphics->mhDefPal, | 
|  | TRUE ); | 
|  | } | 
|  | pTempVD = pTempVD->mpNext; | 
|  | } | 
|  | pTempFrame = pSalData->mpFirstFrame; | 
|  | while ( pTempFrame ) | 
|  | { | 
|  | pGraphics = pTempFrame->mpGraphics; | 
|  | if ( pGraphics && pGraphics->mhDefPal ) | 
|  | { | 
|  | SelectPalette( pGraphics->getHDC(), | 
|  | pGraphics->mhDefPal, | 
|  | TRUE ); | 
|  | } | 
|  | pTempFrame = pTempFrame->mpNextFrame; | 
|  | } | 
|  |  | 
|  | // Palette neu realizen | 
|  | WinSalFrame* pFrame = NULL; | 
|  | if ( bFrame ) | 
|  | pFrame = GetWindowPtr( hWnd ); | 
|  | if ( pFrame && pFrame->mpGraphics ) | 
|  | { | 
|  | hDC = pFrame->mpGraphics->getHDC(); | 
|  | bStdDC = TRUE; | 
|  | } | 
|  | else | 
|  | { | 
|  | hDC = GetDC( hWnd ); | 
|  | bStdDC = FALSE; | 
|  | } | 
|  | UnrealizeObject( hPal ); | 
|  | hOldPal = SelectPalette( hDC, hPal, TRUE ); | 
|  | nCols = RealizePalette( hDC ); | 
|  | bUpdate = nCols != 0; | 
|  | if ( !bStdDC ) | 
|  | { | 
|  | SelectPalette( hDC, hOldPal, TRUE ); | 
|  | ReleaseDC( hWnd, hDC ); | 
|  | } | 
|  |  | 
|  | // Alle Paletten in VirDevs und Frames neu setzen | 
|  | pTempVD = pSalData->mpFirstVD; | 
|  | while ( pTempVD ) | 
|  | { | 
|  | pGraphics = pTempVD->mpGraphics; | 
|  | if ( pGraphics->mhDefPal ) | 
|  | { | 
|  | SelectPalette( pGraphics->getHDC(), hPal, TRUE ); | 
|  | RealizePalette( pGraphics->getHDC() ); | 
|  | } | 
|  | pTempVD = pTempVD->mpNext; | 
|  | } | 
|  | pTempFrame = pSalData->mpFirstFrame; | 
|  | while ( pTempFrame ) | 
|  | { | 
|  | if ( pTempFrame != pFrame ) | 
|  | { | 
|  | pGraphics = pTempFrame->mpGraphics; | 
|  | if ( pGraphics && pGraphics->mhDefPal ) | 
|  | { | 
|  | SelectPalette( pGraphics->getHDC(), hPal, TRUE ); | 
|  | if ( RealizePalette( pGraphics->getHDC() ) ) | 
|  | bUpdate = TRUE; | 
|  | } | 
|  | } | 
|  | pTempFrame = pTempFrame->mpNextFrame; | 
|  | } | 
|  |  | 
|  | // Wenn sich Farben geaendert haben, dann die Fenster updaten | 
|  | if ( bUpdate ) | 
|  | { | 
|  | pTempFrame = pSalData->mpFirstFrame; | 
|  | while ( pTempFrame ) | 
|  | { | 
|  | pGraphics = pTempFrame->mpGraphics; | 
|  | if ( pGraphics && pGraphics->mhDefPal ) | 
|  | { | 
|  | InvalidateRect( pTempFrame->mhWnd, NULL, FALSE ); | 
|  | UpdateWindow( pTempFrame->mhWnd ); | 
|  | pTempFrame->CallCallback( SALEVENT_DISPLAYCHANGED, 0 ); | 
|  | } | 
|  | pTempFrame = pTempFrame->mpNextFrame; | 
|  | } | 
|  | } | 
|  |  | 
|  | pSalData->mbInPalChange = FALSE; | 
|  |  | 
|  | if ( bReleaseMutex ) | 
|  | ImplSalYieldMutexRelease(); | 
|  |  | 
|  | if ( nMsg == WM_PALETTECHANGED ) | 
|  | return 0; | 
|  | else | 
|  | return nCols; | 
|  | } | 
|  |  | 
|  | // ----------------------------------------------------------------------- | 
|  |  | 
|  | static int ImplHandleMinMax( HWND hWnd, LPARAM lParam ) | 
|  | { | 
|  | int bRet = FALSE; | 
|  |  | 
|  | if ( ImplSalYieldMutexTryToAcquire() ) | 
|  | { | 
|  | WinSalFrame* pFrame = GetWindowPtr( hWnd ); | 
|  | if ( pFrame ) | 
|  | { | 
|  | MINMAXINFO* pMinMax = (MINMAXINFO*)lParam; | 
|  |  | 
|  | if ( pFrame->mbFullScreen ) | 
|  | { | 
|  | int         nX; | 
|  | int         nY; | 
|  | int         nDX; | 
|  | int         nDY; | 
|  | ImplSalCalcFullScreenSize( pFrame, nX, nY, nDX, nDY ); | 
|  |  | 
|  | if ( pMinMax->ptMaxPosition.x > nX ) | 
|  | pMinMax->ptMaxPosition.x = nX; | 
|  | if ( pMinMax->ptMaxPosition.y > nY ) | 
|  | pMinMax->ptMaxPosition.y = nY; | 
|  |  | 
|  | if ( pMinMax->ptMaxSize.x < nDX ) | 
|  | pMinMax->ptMaxSize.x = nDX; | 
|  | if ( pMinMax->ptMaxSize.y < nDY ) | 
|  | pMinMax->ptMaxSize.y = nDY; | 
|  | if ( pMinMax->ptMaxTrackSize.x < nDX ) | 
|  | pMinMax->ptMaxTrackSize.x = nDX; | 
|  | if ( pMinMax->ptMaxTrackSize.y < nDY ) | 
|  | pMinMax->ptMaxTrackSize.y = nDY; | 
|  |  | 
|  | pMinMax->ptMinTrackSize.x = nDX; | 
|  | pMinMax->ptMinTrackSize.y = nDY; | 
|  |  | 
|  | bRet = TRUE; | 
|  | } | 
|  |  | 
|  | if ( pFrame->mnMinWidth || pFrame->mnMinHeight ) | 
|  | { | 
|  | int nWidth   = pFrame->mnMinWidth; | 
|  | int nHeight  = pFrame->mnMinHeight; | 
|  |  | 
|  | ImplSalAddBorder( pFrame, nWidth, nHeight ); | 
|  |  | 
|  | if ( pMinMax->ptMinTrackSize.x < nWidth ) | 
|  | pMinMax->ptMinTrackSize.x = nWidth; | 
|  | if ( pMinMax->ptMinTrackSize.y < nHeight ) | 
|  | pMinMax->ptMinTrackSize.y = nHeight; | 
|  | } | 
|  |  | 
|  | if ( pFrame->mnMaxWidth || pFrame->mnMaxHeight ) | 
|  | { | 
|  | int nWidth   = pFrame->mnMaxWidth; | 
|  | int nHeight  = pFrame->mnMaxHeight; | 
|  |  | 
|  | ImplSalAddBorder( pFrame, nWidth, nHeight ); | 
|  |  | 
|  | if( nWidth > 0 && nHeight > 0 ) // protect against int overflow due to INT_MAX initialization | 
|  | { | 
|  | if ( pMinMax->ptMaxTrackSize.x > nWidth ) | 
|  | pMinMax->ptMaxTrackSize.x = nWidth; | 
|  | if ( pMinMax->ptMaxTrackSize.y > nHeight ) | 
|  | pMinMax->ptMaxTrackSize.y = nHeight; | 
|  | } | 
|  | } | 
|  | } | 
|  |  | 
|  | ImplSalYieldMutexRelease(); | 
|  | } | 
|  |  | 
|  | return bRet; | 
|  | } | 
|  |  | 
|  | // ----------------------------------------------------------------------- | 
|  |  | 
|  | // retrieves the SalMenuItem pointer from a hMenu | 
|  | // the pointer is stored in every item, so if no position | 
|  | // is specified we just use the first item (i.e. pos=0) | 
|  | // if bByPosition is FALSE then nPos denotes a menu id instead of a position | 
|  | static WinSalMenuItem* ImplGetSalMenuItem( HMENU hMenu, UINT nPos, sal_Bool bByPosition=TRUE ) | 
|  | { | 
|  | DWORD err=0; | 
|  |  | 
|  | MENUITEMINFOW mi; | 
|  | memset(&mi, 0, sizeof(mi)); | 
|  | mi.cbSize = sizeof( mi ); | 
|  | mi.fMask = MIIM_DATA; | 
|  | if( !GetMenuItemInfoW( hMenu, nPos, bByPosition, &mi) ) | 
|  | err = GetLastError(); | 
|  |  | 
|  | return (WinSalMenuItem *) mi.dwItemData; | 
|  | } | 
|  |  | 
|  | // returns the index of the currently selected item if any or -1 | 
|  | static int ImplGetSelectedIndex( HMENU hMenu ) | 
|  | { | 
|  | DWORD err=0; | 
|  |  | 
|  | MENUITEMINFOW mi; | 
|  | memset(&mi, 0, sizeof(mi)); | 
|  | mi.cbSize = sizeof( mi ); | 
|  | mi.fMask = MIIM_STATE; | 
|  | int n = GetMenuItemCount( hMenu ); | 
|  | if( n != -1 ) | 
|  | { | 
|  | for(int i=0; i<n; i++ ) | 
|  | { | 
|  | if( !GetMenuItemInfoW( hMenu, i, TRUE, &mi) ) | 
|  | err = GetLastError(); | 
|  | else | 
|  | { | 
|  | if( mi.fState & MFS_HILITE ) | 
|  | return i; | 
|  | } | 
|  | } | 
|  | } | 
|  | return -1; | 
|  | } | 
|  |  | 
|  | static int ImplMenuChar( HWND, WPARAM wParam, LPARAM lParam ) | 
|  | { | 
|  | int nRet = MNC_IGNORE; | 
|  | HMENU hMenu = (HMENU) lParam; | 
|  | String aMnemonic; | 
|  | aMnemonic.AssignAscii("&"); | 
|  | aMnemonic.Append( (sal_Unicode) LOWORD(wParam) ); | 
|  | aMnemonic.ToLowerAscii();   // we only have ascii mnemonics | 
|  |  | 
|  | // search the mnemonic in the current menu | 
|  | int nItemCount = GetMenuItemCount( hMenu ); | 
|  | int nFound = 0; | 
|  | int idxFound = -1; | 
|  | int idxSelected = ImplGetSelectedIndex( hMenu ); | 
|  | int idx = idxSelected != -1 ? idxSelected+1 : 0;    // if duplicate mnemonics cycle through menu | 
|  | for( int i=0; i< nItemCount; i++, idx++ ) | 
|  | { | 
|  | WinSalMenuItem* pSalMenuItem = ImplGetSalMenuItem( hMenu, idx % nItemCount ); | 
|  | if( !pSalMenuItem ) | 
|  | continue; | 
|  | String aStr = pSalMenuItem->mText; | 
|  | aStr.ToLowerAscii(); | 
|  | if( aStr.Search( aMnemonic ) != STRING_NOTFOUND) | 
|  | { | 
|  | if( idxFound == -1 ) | 
|  | idxFound = idx % nItemCount; | 
|  | if( nFound++ ) | 
|  | break;  // duplicate found | 
|  | } | 
|  | } | 
|  | if( nFound == 1 ) | 
|  | nRet = MAKELRESULT( idxFound, MNC_EXECUTE ); | 
|  | else | 
|  | // duplicate mnemonics, just select the next occurrence | 
|  | nRet = MAKELRESULT( idxFound, MNC_SELECT ); | 
|  |  | 
|  | return nRet; | 
|  | } | 
|  |  | 
|  | static int ImplMeasureItem( HWND hWnd, WPARAM wParam, LPARAM lParam ) | 
|  | { | 
|  | int nRet = 0; | 
|  | if( !wParam ) | 
|  | { | 
|  | // request was sent by a menu | 
|  | nRet = 1; | 
|  | MEASUREITEMSTRUCT *pMI = (LPMEASUREITEMSTRUCT) lParam; | 
|  | if( pMI->CtlType != ODT_MENU ) | 
|  | return 0; | 
|  |  | 
|  | WinSalMenuItem *pSalMenuItem = (WinSalMenuItem *) pMI->itemData; | 
|  | if( !pSalMenuItem ) | 
|  | return 0; | 
|  |  | 
|  | HDC hdc = GetDC( hWnd ); | 
|  | SIZE strSize; | 
|  |  | 
|  | NONCLIENTMETRICS ncm; | 
|  | memset( &ncm, 0, sizeof(ncm) ); | 
|  | ncm.cbSize = sizeof( ncm ); | 
|  | SystemParametersInfo( SPI_GETNONCLIENTMETRICS, 0, (PVOID) &ncm, 0 ); | 
|  |  | 
|  | // Assume every menu item can be default and printed bold | 
|  | //ncm.lfMenuFont.lfWeight = FW_BOLD; | 
|  |  | 
|  | HFONT hfntOld = (HFONT) SelectObject(hdc, (HFONT) CreateFontIndirect( &ncm.lfMenuFont )); | 
|  |  | 
|  | // menu text and accelerator | 
|  | String aStr(pSalMenuItem->mText.GetBuffer() ); | 
|  | if( pSalMenuItem->mAccelText.Len() ) | 
|  | { | 
|  | aStr.AppendAscii(" "); | 
|  | aStr.Append( pSalMenuItem->mAccelText ); | 
|  | } | 
|  | GetTextExtentPoint32W( hdc, (LPWSTR) aStr.GetBuffer(), | 
|  | aStr.Len(), &strSize ); | 
|  |  | 
|  | // image | 
|  | Size bmpSize( 16, 16 ); | 
|  | //if( !!pSalMenuItem->maBitmap ) | 
|  | //    bmpSize = pSalMenuItem->maBitmap.GetSizePixel(); | 
|  |  | 
|  | // checkmark | 
|  | Size checkSize( GetSystemMetrics( SM_CXMENUCHECK ), GetSystemMetrics( SM_CYMENUCHECK ) ); | 
|  |  | 
|  | pMI->itemWidth = checkSize.Width() + 3 + bmpSize.Width() + 3 + strSize.cx; | 
|  | pMI->itemHeight = Max( Max( checkSize.Height(), bmpSize.Height() ), strSize.cy ); | 
|  | pMI->itemHeight += 4; | 
|  |  | 
|  | DeleteObject( SelectObject(hdc, hfntOld) ); | 
|  | ReleaseDC( hWnd, hdc ); | 
|  | } | 
|  |  | 
|  | return nRet; | 
|  | } | 
|  |  | 
|  | static int ImplDrawItem(HWND, WPARAM wParam, LPARAM lParam ) | 
|  | { | 
|  | int nRet = 0; | 
|  | DWORD err = 0; | 
|  | if( !wParam ) | 
|  | { | 
|  | // request was sent by a menu | 
|  | nRet = 1; | 
|  | DRAWITEMSTRUCT *pDI = (LPDRAWITEMSTRUCT) lParam; | 
|  | if( pDI->CtlType != ODT_MENU ) | 
|  | return 0; | 
|  |  | 
|  | WinSalMenuItem *pSalMenuItem = (WinSalMenuItem *) pDI->itemData; | 
|  | if( !pSalMenuItem ) | 
|  | return 0; | 
|  |  | 
|  | COLORREF clrPrevText, clrPrevBkgnd; | 
|  | HFONT hfntOld; | 
|  | HBRUSH hbrOld; | 
|  | sal_Bool	fChecked = (pDI->itemState & ODS_CHECKED) ? TRUE : FALSE; | 
|  | sal_Bool	fSelected = (pDI->itemState & ODS_SELECTED) ? TRUE : FALSE; | 
|  | sal_Bool	fDisabled = (pDI->itemState & (ODS_DISABLED | ODS_GRAYED)) ? TRUE : FALSE; | 
|  |  | 
|  | // Set the appropriate foreground and background colors. | 
|  | RECT aRect = pDI->rcItem; | 
|  |  | 
|  | clrPrevBkgnd = SetBkColor( pDI->hDC, GetSysColor( COLOR_MENU ) ); | 
|  |  | 
|  | if ( fDisabled ) | 
|  | clrPrevText = SetTextColor( pDI->hDC, GetSysColor( COLOR_GRAYTEXT ) ); | 
|  | else | 
|  | clrPrevText = SetTextColor( pDI->hDC, GetSysColor( fSelected ? COLOR_HIGHLIGHTTEXT : COLOR_MENUTEXT ) ); | 
|  |  | 
|  | DWORD colBackground = GetSysColor( fSelected ? COLOR_HIGHLIGHT : COLOR_MENU ); | 
|  | if ( fSelected ) | 
|  | clrPrevBkgnd = SetBkColor( pDI->hDC, colBackground ); | 
|  | else | 
|  | clrPrevBkgnd = SetBkColor( pDI->hDC, colBackground ); | 
|  |  | 
|  | hbrOld = (HBRUSH)SelectObject( pDI->hDC, CreateSolidBrush( GetBkColor( pDI->hDC ) ) ); | 
|  |  | 
|  | // Fill background | 
|  | if(!PatBlt( pDI->hDC, aRect.left, aRect.top, aRect.right-aRect.left, aRect.bottom-aRect.top, PATCOPY )) | 
|  | err = GetLastError(); | 
|  |  | 
|  | int lineHeight = aRect.bottom-aRect.top; | 
|  |  | 
|  | int x = aRect.left; | 
|  | int y = aRect.top; | 
|  |  | 
|  | int checkWidth  = GetSystemMetrics( SM_CXMENUCHECK ); | 
|  | int checkHeight = GetSystemMetrics( SM_CYMENUCHECK ); | 
|  | if( fChecked ) | 
|  | { | 
|  | RECT r; | 
|  | r.left = 0; | 
|  | r.top = 0; | 
|  | r.right = checkWidth; | 
|  | r.bottom = checkWidth; | 
|  | HDC memDC = CreateCompatibleDC( pDI->hDC ); | 
|  | HBITMAP memBmp = CreateCompatibleBitmap( pDI->hDC, checkWidth, checkHeight ); | 
|  | HBITMAP hOldBmp = (HBITMAP) SelectObject( memDC, memBmp ); | 
|  | DrawFrameControl( memDC, &r, DFC_MENU, DFCS_MENUCHECK ); | 
|  | BitBlt( pDI->hDC, x, y+(lineHeight-checkHeight)/2, checkWidth, checkHeight, memDC, 0, 0, SRCAND ); | 
|  | DeleteObject( SelectObject( memDC, hOldBmp ) ); | 
|  | DeleteDC( memDC ); | 
|  | } | 
|  | x += checkWidth+3; | 
|  |  | 
|  | //Size bmpSize = aBitmap.GetSizePixel(); | 
|  | Size bmpSize(16, 16); | 
|  | if( !!pSalMenuItem->maBitmap ) | 
|  | { | 
|  | Bitmap aBitmap( pSalMenuItem->maBitmap ); | 
|  |  | 
|  | // set transparent pixels to background color | 
|  | if( fDisabled ) | 
|  | colBackground = RGB(255,255,255); | 
|  | aBitmap.Replace( Color( COL_LIGHTMAGENTA ), | 
|  | Color( GetRValue(colBackground),GetGValue(colBackground),GetBValue(colBackground) ), 0); | 
|  |  | 
|  | WinSalBitmap* pSalBmp = static_cast<WinSalBitmap*>(aBitmap.ImplGetImpBitmap()->ImplGetSalBitmap()); | 
|  | HGLOBAL hDrawDIB = pSalBmp->ImplGethDIB(); | 
|  |  | 
|  | if( hDrawDIB ) | 
|  | { | 
|  | PBITMAPINFO 		pBI = (PBITMAPINFO) GlobalLock( hDrawDIB ); | 
|  | PBITMAPINFOHEADER	pBIH = (PBITMAPINFOHEADER) pBI; | 
|  | PBYTE				pBits = (PBYTE) pBI + *(DWORD*) pBI + | 
|  | pSalBmp->ImplGetDIBColorCount( hDrawDIB ) * sizeof( RGBQUAD ); | 
|  |  | 
|  | HBITMAP hBmp = CreateDIBitmap( pDI->hDC, pBIH, CBM_INIT, pBits, pBI, DIB_RGB_COLORS ); | 
|  | GlobalUnlock( hDrawDIB ); | 
|  |  | 
|  | HBRUSH hbrIcon = CreateSolidBrush( GetSysColor( COLOR_GRAYTEXT ) ); | 
|  | DrawStateW( pDI->hDC, (HBRUSH)hbrIcon, (DRAWSTATEPROC)NULL, (LPARAM)hBmp, (WPARAM)0, | 
|  | x, y+(lineHeight-bmpSize.Height())/2, bmpSize.Width(), bmpSize.Height(), | 
|  | DST_BITMAP | (fDisabled ? (fSelected ? DSS_MONO : DSS_DISABLED) : DSS_NORMAL) ); | 
|  |  | 
|  | DeleteObject( hbrIcon ); | 
|  | DeleteObject( hBmp ); | 
|  | } | 
|  |  | 
|  | } | 
|  | x += bmpSize.Width() + 3; | 
|  | aRect.left = x; | 
|  |  | 
|  | NONCLIENTMETRICS ncm; | 
|  | memset( &ncm, 0, sizeof(ncm) ); | 
|  | ncm.cbSize = sizeof( ncm ); | 
|  | SystemParametersInfo( SPI_GETNONCLIENTMETRICS, 0, (PVOID) &ncm, 0 ); | 
|  |  | 
|  | // Print default menu entry with bold font | 
|  | //if ( pDI->itemState & ODS_DEFAULT ) | 
|  | //    ncm.lfMenuFont.lfWeight = FW_BOLD; | 
|  |  | 
|  | hfntOld = (HFONT) SelectObject(pDI->hDC, (HFONT) CreateFontIndirect( &ncm.lfMenuFont )); | 
|  |  | 
|  | SIZE strSize; | 
|  | String aStr( pSalMenuItem->mText.GetBuffer() ); | 
|  | GetTextExtentPoint32W( pDI->hDC, (LPWSTR) aStr.GetBuffer(), | 
|  | aStr.Len(), &strSize ); | 
|  |  | 
|  | if(!DrawStateW( pDI->hDC, (HBRUSH)NULL, (DRAWSTATEPROC)NULL, | 
|  | (LPARAM)(LPWSTR) aStr.GetBuffer(), | 
|  | (WPARAM)0, aRect.left, aRect.top + (lineHeight - strSize.cy)/2, 0, 0, | 
|  | DST_PREFIXTEXT | (fDisabled && !fSelected ? DSS_DISABLED : DSS_NORMAL) ) ) | 
|  | err = GetLastError(); | 
|  |  | 
|  | if( pSalMenuItem->mAccelText.Len() ) | 
|  | { | 
|  | SIZE strSizeA; | 
|  | aStr = pSalMenuItem->mAccelText; | 
|  | GetTextExtentPoint32W( pDI->hDC, (LPWSTR) aStr.GetBuffer(), | 
|  | aStr.Len(), &strSizeA ); | 
|  | TEXTMETRIC tm; | 
|  | GetTextMetrics( pDI->hDC, &tm ); | 
|  |  | 
|  | // position the accelerator string to the right but leave space for the | 
|  | // (potential) submenu arrow (tm.tmMaxCharWidth) | 
|  | if(!DrawStateW( pDI->hDC, (HBRUSH)NULL, (DRAWSTATEPROC)NULL, | 
|  | (LPARAM)(LPWSTR) aStr.GetBuffer(), | 
|  | (WPARAM)0, aRect.right-strSizeA.cx-tm.tmMaxCharWidth, aRect.top + (lineHeight - strSizeA.cy)/2, 0, 0, | 
|  | DST_TEXT | (fDisabled && !fSelected ? DSS_DISABLED : DSS_NORMAL) ) ) | 
|  | err = GetLastError(); | 
|  | } | 
|  |  | 
|  | // Restore the original font and colors. | 
|  | DeleteObject( SelectObject( pDI->hDC, hbrOld ) ); | 
|  | DeleteObject( SelectObject( pDI->hDC, hfntOld) ); | 
|  | SetTextColor(pDI->hDC, clrPrevText); | 
|  | SetBkColor(pDI->hDC, clrPrevBkgnd); | 
|  | } | 
|  | return nRet; | 
|  | } | 
|  |  | 
|  | static int ImplHandleMenuActivate( HWND hWnd, WPARAM wParam, LPARAM ) | 
|  | { | 
|  | // Menu activation | 
|  | WinSalFrame* pFrame = GetWindowPtr( hWnd ); | 
|  | if ( !pFrame ) | 
|  | return 0; | 
|  |  | 
|  | HMENU hMenu = (HMENU) wParam; | 
|  | // WORD nPos = LOWORD (lParam); | 
|  | // sal_Bool bWindowMenu = (sal_Bool) HIWORD(lParam); | 
|  |  | 
|  | // Send activate and deactivate together, so we have not keep track of opened menus | 
|  | // this will be enough to have the menus updated correctly | 
|  | SalMenuEvent aMenuEvt; | 
|  | WinSalMenuItem *pSalMenuItem = ImplGetSalMenuItem( hMenu, 0 ); | 
|  | if( pSalMenuItem ) | 
|  | aMenuEvt.mpMenu = pSalMenuItem->mpMenu; | 
|  | else | 
|  | aMenuEvt.mpMenu = NULL; | 
|  |  | 
|  | long nRet = pFrame->CallCallback( SALEVENT_MENUACTIVATE, &aMenuEvt ); | 
|  | if( nRet ) | 
|  | nRet = pFrame->CallCallback( SALEVENT_MENUDEACTIVATE, &aMenuEvt ); | 
|  | if( nRet ) | 
|  | pFrame->mLastActivatedhMenu = hMenu; | 
|  |  | 
|  | return (nRet!=0); | 
|  | } | 
|  |  | 
|  | static int ImplHandleMenuSelect( HWND hWnd, WPARAM wParam, LPARAM lParam ) | 
|  | { | 
|  | // Menu selection | 
|  | WinSalFrame* pFrame = GetWindowPtr( hWnd ); | 
|  | if ( !pFrame ) | 
|  | return 0; | 
|  |  | 
|  | WORD nId = LOWORD(wParam);      // menu item or submenu index | 
|  | WORD nFlags = HIWORD(wParam); | 
|  | HMENU hMenu = (HMENU) lParam; | 
|  |  | 
|  | // check if we have to process the message | 
|  | if( !GetSalData()->IsKnownMenuHandle( hMenu ) ) | 
|  | return 0; | 
|  |  | 
|  | sal_Bool bByPosition = FALSE; | 
|  | if( nFlags & MF_POPUP ) | 
|  | bByPosition = TRUE; | 
|  |  | 
|  | long nRet = 0; | 
|  | if ( hMenu && !pFrame->mLastActivatedhMenu ) | 
|  | { | 
|  | // we never activated a menu (i.e. no WM_INITMENUPOPUP has occurred yet) | 
|  | // which means this must be the menubar -> send activation/deactivation | 
|  | SalMenuEvent aMenuEvt; | 
|  | WinSalMenuItem *pSalMenuItem = ImplGetSalMenuItem( hMenu, nId, bByPosition ); | 
|  | if( pSalMenuItem ) | 
|  | aMenuEvt.mpMenu = pSalMenuItem->mpMenu; | 
|  | else | 
|  | aMenuEvt.mpMenu = NULL; | 
|  |  | 
|  | nRet = pFrame->CallCallback( SALEVENT_MENUACTIVATE, &aMenuEvt ); | 
|  | if( nRet ) | 
|  | nRet = pFrame->CallCallback( SALEVENT_MENUDEACTIVATE, &aMenuEvt ); | 
|  | if( nRet ) | 
|  | pFrame->mLastActivatedhMenu = hMenu; | 
|  | } | 
|  |  | 
|  | if( !hMenu && nFlags == 0xFFFF ) | 
|  | { | 
|  | // all menus are closed, reset activation logic | 
|  | pFrame->mLastActivatedhMenu = NULL; | 
|  | } | 
|  |  | 
|  | if( hMenu ) | 
|  | { | 
|  | // hMenu must be saved, as it is not passed in WM_COMMAND which always occurs after a selection | 
|  | // if a menu is closed due to a command selection then hMenu is NULL, but WM_COMMAND comes later | 
|  | // so we must not overwrite it in this case | 
|  | pFrame->mSelectedhMenu = hMenu; | 
|  |  | 
|  | // send highlight event | 
|  | if( nFlags & MF_POPUP ) | 
|  | { | 
|  | // submenu selected | 
|  | // wParam now carries an index instead of an id -> retrieve id | 
|  | MENUITEMINFOW mi; | 
|  | memset(&mi, 0, sizeof(mi)); | 
|  | mi.cbSize = sizeof( mi ); | 
|  | mi.fMask = MIIM_ID; | 
|  | if( GetMenuItemInfoW( hMenu, LOWORD(wParam), TRUE, &mi) ) | 
|  | nId = sal::static_int_cast<WORD>(mi.wID); | 
|  | } | 
|  |  | 
|  | SalMenuEvent aMenuEvt; | 
|  | aMenuEvt.mnId   = nId; | 
|  | WinSalMenuItem *pSalMenuItem = ImplGetSalMenuItem( hMenu, nId, FALSE ); | 
|  | if( pSalMenuItem ) | 
|  | aMenuEvt.mpMenu = pSalMenuItem->mpMenu; | 
|  | else | 
|  | aMenuEvt.mpMenu = NULL; | 
|  |  | 
|  | nRet = pFrame->CallCallback( SALEVENT_MENUHIGHLIGHT, &aMenuEvt ); | 
|  | } | 
|  |  | 
|  | return (nRet != 0); | 
|  | } | 
|  |  | 
|  | static int ImplHandleCommand( HWND hWnd, WPARAM wParam, LPARAM ) | 
|  | { | 
|  | WinSalFrame* pFrame = GetWindowPtr( hWnd ); | 
|  | if ( !pFrame ) | 
|  | return 0; | 
|  |  | 
|  | long nRet = 0; | 
|  | if( !HIWORD(wParam) ) | 
|  | { | 
|  | // Menu command | 
|  | WORD nId = LOWORD(wParam); | 
|  | if( nId )   // zero for separators | 
|  | { | 
|  | SalMenuEvent aMenuEvt; | 
|  | aMenuEvt.mnId   = nId; | 
|  | WinSalMenuItem *pSalMenuItem = ImplGetSalMenuItem( pFrame->mSelectedhMenu, nId, FALSE ); | 
|  | if( pSalMenuItem ) | 
|  | aMenuEvt.mpMenu = pSalMenuItem->mpMenu; | 
|  | else | 
|  | aMenuEvt.mpMenu = NULL; | 
|  |  | 
|  | nRet = pFrame->CallCallback( SALEVENT_MENUCOMMAND, &aMenuEvt ); | 
|  | } | 
|  | } | 
|  | return (nRet != 0); | 
|  | } | 
|  |  | 
|  | static int ImplHandleSysCommand( HWND hWnd, WPARAM wParam, LPARAM lParam ) | 
|  | { | 
|  | WinSalFrame* pFrame = GetWindowPtr( hWnd ); | 
|  | if ( !pFrame ) | 
|  | return 0; | 
|  |  | 
|  | WPARAM nCommand = wParam & 0xFFF0; | 
|  |  | 
|  | if ( pFrame->mbFullScreen ) | 
|  | { | 
|  | BOOL    bMaximize = IsZoomed( pFrame->mhWnd ); | 
|  | BOOL    bMinimize = IsIconic( pFrame->mhWnd ); | 
|  | if ( (nCommand == SC_SIZE) || | 
|  | (!bMinimize && (nCommand == SC_MOVE)) || | 
|  | (!bMaximize && (nCommand == SC_MAXIMIZE)) || | 
|  | (bMaximize && (nCommand == SC_RESTORE)) ) | 
|  | { | 
|  | MessageBeep( 0 ); | 
|  | return TRUE; | 
|  | } | 
|  | } | 
|  |  | 
|  | if ( nCommand == SC_KEYMENU ) | 
|  | { | 
|  | // do not process SC_KEYMENU if we have a native menu | 
|  | // Windows should handle this | 
|  | if( GetMenu( hWnd ) ) | 
|  | return FALSE; | 
|  |  | 
|  | // Hier verarbeiten wir nur KeyMenu-Events fuer Alt um | 
|  | // den MenuBar zu aktivieren, oder wenn ein SysChild-Fenster | 
|  | // den Focus hat, da diese Alt+Tasten-Kombinationen nur | 
|  | // ueber diesen Event verarbeitet werden | 
|  | if ( !LOWORD( lParam ) ) | 
|  | { | 
|  | // Nur ausloesen, wenn keine weitere Taste gedrueckt ist. Im | 
|  | // Gegensatz zur Doku wird in der X-Koordinaate der CharCode | 
|  | // geliefert, der zusaetzlich gedrueckt ist | 
|  | // Also 32 fuer Space, 99 fuer c, 100 fuer d, ... | 
|  | // Da dies nicht dokumentiert ist, fragen wir vorsichtshalber | 
|  | // auch den Status der Space-Taste ab | 
|  | if ( GetKeyState( VK_SPACE ) & 0x8000 ) | 
|  | return 0; | 
|  |  | 
|  | // Damit nicht bei Alt+Maustaste auch der MenuBar aktiviert wird | 
|  | if ( (GetKeyState( VK_LBUTTON ) & 0x8000) || | 
|  | (GetKeyState( VK_RBUTTON ) & 0x8000) || | 
|  | (GetKeyState( VK_MBUTTON ) & 0x8000) || | 
|  | (GetKeyState( VK_SHIFT )   & 0x8000) ) | 
|  | return 1; | 
|  |  | 
|  | SalKeyEvent aKeyEvt; | 
|  | aKeyEvt.mnTime      = GetMessageTime(); | 
|  | aKeyEvt.mnCode      = KEY_MENU; | 
|  | aKeyEvt.mnCharCode  = 0; | 
|  | aKeyEvt.mnRepeat    = 0; | 
|  | long nRet = pFrame->CallCallback( SALEVENT_KEYINPUT, &aKeyEvt ); | 
|  | pFrame->CallCallback( SALEVENT_KEYUP, &aKeyEvt ); | 
|  | return (nRet != 0); | 
|  | } | 
|  | else | 
|  | { | 
|  | // Testen, ob ein SysChild den Focus hat | 
|  | HWND hFocusWnd = ::GetFocus(); | 
|  | if ( hFocusWnd && ImplFindSalObject( hFocusWnd ) ) | 
|  | { | 
|  | char cKeyCode = (char)(unsigned char)LOWORD( lParam ); | 
|  | // LowerCase | 
|  | if ( (cKeyCode >= 65) && (cKeyCode <= 90) ) | 
|  | cKeyCode += 32; | 
|  | // Wir nehmen nur 0-9 und A-Z, alle anderen Tasten muessen durch | 
|  | // den Hook vom SalObj verarbeitet werden | 
|  | if ( ((cKeyCode >= 48) && (cKeyCode <= 57)) || | 
|  | ((cKeyCode >= 97) && (cKeyCode <= 122)) ) | 
|  | { | 
|  | sal_uInt16 nModCode = 0; | 
|  | if ( GetKeyState( VK_SHIFT ) & 0x8000 ) | 
|  | nModCode |= KEY_SHIFT; | 
|  | if ( GetKeyState( VK_CONTROL ) & 0x8000 ) | 
|  | nModCode |= KEY_MOD1; | 
|  | nModCode |= KEY_MOD2; | 
|  |  | 
|  | SalKeyEvent aKeyEvt; | 
|  | aKeyEvt.mnTime      = GetMessageTime(); | 
|  | if ( (cKeyCode >= 48) && (cKeyCode <= 57) ) | 
|  | aKeyEvt.mnCode = KEY_0+(cKeyCode-48); | 
|  | else | 
|  | aKeyEvt.mnCode = KEY_A+(cKeyCode-97); | 
|  | aKeyEvt.mnCode     |= nModCode; | 
|  | aKeyEvt.mnCharCode  = cKeyCode; | 
|  | aKeyEvt.mnRepeat    = 0; | 
|  | long nRet = pFrame->CallCallback( SALEVENT_KEYINPUT, &aKeyEvt ); | 
|  | pFrame->CallCallback( SALEVENT_KEYUP, &aKeyEvt ); | 
|  | return (nRet != 0); | 
|  | } | 
|  | } | 
|  | } | 
|  | } | 
|  |  | 
|  | return FALSE; | 
|  | } | 
|  |  | 
|  | // ----------------------------------------------------------------------- | 
|  |  | 
|  | static void ImplHandleInputLangChange( HWND hWnd, WPARAM, LPARAM lParam ) | 
|  | { | 
|  | ImplSalYieldMutexAcquireWithWait(); | 
|  |  | 
|  | // Feststellen, ob wir IME unterstuetzen | 
|  | WinSalFrame* pFrame = GetWindowPtr( hWnd ); | 
|  | if ( pFrame && pFrame->mbIME && pFrame->mhDefIMEContext ) | 
|  | { | 
|  | HKL     hKL = (HKL)lParam; | 
|  | UINT    nImeProps = ImmGetProperty( hKL, IGP_PROPERTY ); | 
|  |  | 
|  | pFrame->mbSpezIME = (nImeProps & IME_PROP_SPECIAL_UI) != 0; | 
|  | pFrame->mbAtCursorIME = (nImeProps & IME_PROP_AT_CARET) != 0; | 
|  | pFrame->mbHandleIME = !pFrame->mbSpezIME; | 
|  | } | 
|  |  | 
|  | // trigger input language and codepage update | 
|  | UINT nLang = pFrame->mnInputLang; | 
|  | ImplUpdateInputLang( pFrame ); | 
|  |  | 
|  | // notify change | 
|  | if( nLang != pFrame->mnInputLang ) | 
|  | pFrame->CallCallback( SALEVENT_INPUTLANGUAGECHANGE, 0 ); | 
|  |  | 
|  | ImplSalYieldMutexRelease(); | 
|  | } | 
|  |  | 
|  | // ----------------------------------------------------------------------- | 
|  |  | 
|  | static void ImplUpdateIMECursorPos( WinSalFrame* pFrame, HIMC hIMC ) | 
|  | { | 
|  | COMPOSITIONFORM aForm; | 
|  | memset( &aForm, 0, sizeof( aForm ) ); | 
|  |  | 
|  | // Cursor-Position ermitteln und aus der die Default-Position fuer | 
|  | // das Composition-Fenster berechnen | 
|  | SalExtTextInputPosEvent aPosEvt; | 
|  | pFrame->CallCallback( SALEVENT_EXTTEXTINPUTPOS, (void*)&aPosEvt ); | 
|  | if ( (aPosEvt.mnX == -1) && (aPosEvt.mnY == -1) ) | 
|  | aForm.dwStyle |= CFS_DEFAULT; | 
|  | else | 
|  | { | 
|  | aForm.dwStyle          |= CFS_POINT; | 
|  | aForm.ptCurrentPos.x    = aPosEvt.mnX; | 
|  | aForm.ptCurrentPos.y    = aPosEvt.mnY; | 
|  | } | 
|  | ImmSetCompositionWindow( hIMC, &aForm ); | 
|  |  | 
|  | // Because not all IME's use this values, we create | 
|  | // a Windows caret to force the Position from the IME | 
|  | if ( GetFocus() == pFrame->mhWnd ) | 
|  | { | 
|  | CreateCaret( pFrame->mhWnd, 0, | 
|  | aPosEvt.mnWidth, aPosEvt.mnHeight ); | 
|  | SetCaretPos( aPosEvt.mnX, aPosEvt.mnY ); | 
|  | } | 
|  | } | 
|  |  | 
|  | // ----------------------------------------------------------------------- | 
|  |  | 
|  | static sal_Bool ImplHandleIMEStartComposition( HWND hWnd ) | 
|  | { | 
|  | sal_Bool bDef = TRUE; | 
|  |  | 
|  | ImplSalYieldMutexAcquireWithWait(); | 
|  |  | 
|  | WinSalFrame* pFrame = GetWindowPtr( hWnd ); | 
|  | if ( pFrame ) | 
|  | { | 
|  | HIMC hIMC = ImmGetContext( hWnd ); | 
|  | if ( hIMC ) | 
|  | { | 
|  | ImplUpdateIMECursorPos( pFrame, hIMC ); | 
|  | ImmReleaseContext( hWnd, hIMC ); | 
|  | } | 
|  |  | 
|  | if ( pFrame->mbHandleIME ) | 
|  | { | 
|  | if ( pFrame->mbAtCursorIME ) | 
|  | bDef = FALSE; | 
|  | } | 
|  | } | 
|  |  | 
|  | ImplSalYieldMutexRelease(); | 
|  |  | 
|  | return bDef; | 
|  | } | 
|  |  | 
|  | // ----------------------------------------------------------------------- | 
|  |  | 
|  | static sal_Bool ImplHandleIMECompositionInput( WinSalFrame* pFrame, | 
|  | HIMC hIMC, LPARAM lParam ) | 
|  | { | 
|  | sal_Bool bDef = TRUE; | 
|  |  | 
|  | // Init Event | 
|  | SalExtTextInputEvent    aEvt; | 
|  | aEvt.mnTime             = GetMessageTime(); | 
|  | aEvt.mpTextAttr         = NULL; | 
|  | aEvt.mnCursorPos        = 0; | 
|  | aEvt.mnDeltaStart       = 0; | 
|  | aEvt.mbOnlyCursor       = FALSE; | 
|  | aEvt.mnCursorFlags      = 0; | 
|  |  | 
|  | // If we get a result string, then we handle this input | 
|  | if ( lParam & GCS_RESULTSTR ) | 
|  | { | 
|  | bDef = FALSE; | 
|  |  | 
|  | LONG nTextLen = ImmGetCompositionStringW( hIMC, GCS_RESULTSTR, 0, 0 ) / sizeof( WCHAR ); | 
|  | if ( nTextLen >= 0 ) | 
|  | { | 
|  | WCHAR* pTextBuf = new WCHAR[nTextLen]; | 
|  | ImmGetCompositionStringW( hIMC, GCS_RESULTSTR, pTextBuf, nTextLen*sizeof( WCHAR ) ); | 
|  | aEvt.maText = XubString( reinterpret_cast<const xub_Unicode*>(pTextBuf), (xub_StrLen)nTextLen ); | 
|  | delete [] pTextBuf; | 
|  | } | 
|  |  | 
|  | aEvt.mnCursorPos = aEvt.maText.Len(); | 
|  | pFrame->CallCallback( SALEVENT_EXTTEXTINPUT, (void*)&aEvt ); | 
|  | pFrame->CallCallback( SALEVENT_ENDEXTTEXTINPUT, (void*)NULL ); | 
|  | ImplUpdateIMECursorPos( pFrame, hIMC ); | 
|  | } | 
|  |  | 
|  | // If the IME doesn't support OnSpot input, then there is nothing to do | 
|  | if ( !pFrame->mbAtCursorIME ) | 
|  | return !bDef; | 
|  |  | 
|  | // If we get new Composition data, then we handle this new input | 
|  | if ( (lParam & (GCS_COMPSTR | GCS_COMPATTR)) || | 
|  | ((lParam & GCS_CURSORPOS) && !(lParam & GCS_RESULTSTR)) ) | 
|  | { | 
|  | bDef = FALSE; | 
|  |  | 
|  | sal_uInt16* pSalAttrAry = NULL; | 
|  | LONG    nTextLen = ImmGetCompositionStringW( hIMC, GCS_COMPSTR, 0, 0 ) / sizeof( WCHAR ); | 
|  | if ( nTextLen > 0 ) | 
|  | { | 
|  | WCHAR* pTextBuf = new WCHAR[nTextLen]; | 
|  | ImmGetCompositionStringW( hIMC, GCS_COMPSTR, pTextBuf, nTextLen*sizeof( WCHAR ) ); | 
|  | aEvt.maText = XubString( reinterpret_cast<const xub_Unicode*>(pTextBuf), (xub_StrLen)nTextLen ); | 
|  | delete [] pTextBuf; | 
|  |  | 
|  | BYTE*   pAttrBuf = NULL; | 
|  | LONG        nAttrLen = ImmGetCompositionStringW( hIMC, GCS_COMPATTR, 0, 0 ); | 
|  | if ( nAttrLen > 0 ) | 
|  | { | 
|  | pAttrBuf = new BYTE[nAttrLen]; | 
|  | ImmGetCompositionStringW( hIMC, GCS_COMPATTR, pAttrBuf, nAttrLen ); | 
|  | } | 
|  |  | 
|  | if ( pAttrBuf ) | 
|  | { | 
|  | xub_StrLen nTextLen = aEvt.maText.Len(); | 
|  | pSalAttrAry = new sal_uInt16[nTextLen]; | 
|  | memset( pSalAttrAry, 0, nTextLen*sizeof( sal_uInt16 ) ); | 
|  | for ( xub_StrLen i = 0; (i < nTextLen) && (i < nAttrLen); i++ ) | 
|  | { | 
|  | BYTE nWinAttr = pAttrBuf[i]; | 
|  | sal_uInt16   nSalAttr; | 
|  | if ( nWinAttr == ATTR_TARGET_CONVERTED ) | 
|  | { | 
|  | nSalAttr = SAL_EXTTEXTINPUT_ATTR_BOLDUNDERLINE; | 
|  | aEvt.mnCursorFlags |= SAL_EXTTEXTINPUT_CURSOR_INVISIBLE; | 
|  | } | 
|  | else if ( nWinAttr == ATTR_CONVERTED ) | 
|  | nSalAttr = SAL_EXTTEXTINPUT_ATTR_DASHDOTUNDERLINE; | 
|  | else if ( nWinAttr == ATTR_TARGET_NOTCONVERTED ) | 
|  | nSalAttr = SAL_EXTTEXTINPUT_ATTR_HIGHLIGHT; | 
|  | else if ( nWinAttr == ATTR_INPUT_ERROR ) | 
|  | nSalAttr = SAL_EXTTEXTINPUT_ATTR_REDTEXT | SAL_EXTTEXTINPUT_ATTR_DOTTEDUNDERLINE; | 
|  | else /* ( nWinAttr == ATTR_INPUT ) */ | 
|  | nSalAttr = SAL_EXTTEXTINPUT_ATTR_DOTTEDUNDERLINE; | 
|  | pSalAttrAry[i] = nSalAttr; | 
|  | } | 
|  |  | 
|  | aEvt.mpTextAttr = pSalAttrAry; | 
|  | delete [] pAttrBuf; | 
|  | } | 
|  | } | 
|  |  | 
|  | // Only when we get new composition data, we must send this event | 
|  | if ( (nTextLen > 0) || !(lParam & GCS_RESULTSTR) ) | 
|  | { | 
|  | // End the mode, if the last character is deleted | 
|  | if ( !nTextLen && !pFrame->mbCandidateMode ) | 
|  | { | 
|  | pFrame->CallCallback( SALEVENT_EXTTEXTINPUT, (void*)&aEvt ); | 
|  | pFrame->CallCallback( SALEVENT_ENDEXTTEXTINPUT, (void*)NULL ); | 
|  | } | 
|  | else | 
|  | { | 
|  | // Because Cursor-Position and DeltaStart never updated | 
|  | // from the Korean input engine, we must handle this here | 
|  | if ( lParam & CS_INSERTCHAR ) | 
|  | { | 
|  | aEvt.mnCursorPos = nTextLen; | 
|  | if ( aEvt.mnCursorPos && (lParam & CS_NOMOVECARET) ) | 
|  | aEvt.mnCursorPos--; | 
|  | } | 
|  | else | 
|  | aEvt.mnCursorPos = LOWORD( ImmGetCompositionStringW( hIMC, GCS_CURSORPOS, 0, 0 ) ); | 
|  |  | 
|  | if ( pFrame->mbCandidateMode ) | 
|  | aEvt.mnCursorFlags |= SAL_EXTTEXTINPUT_CURSOR_INVISIBLE; | 
|  | if ( lParam & CS_NOMOVECARET ) | 
|  | aEvt.mnCursorFlags |= SAL_EXTTEXTINPUT_CURSOR_OVERWRITE; | 
|  |  | 
|  | pFrame->CallCallback( SALEVENT_EXTTEXTINPUT, (void*)&aEvt ); | 
|  | } | 
|  | ImplUpdateIMECursorPos( pFrame, hIMC ); | 
|  | } | 
|  |  | 
|  | if ( pSalAttrAry ) | 
|  | delete [] pSalAttrAry; | 
|  | } | 
|  |  | 
|  | return !bDef; | 
|  | } | 
|  |  | 
|  | // ----------------------------------------------------------------------- | 
|  |  | 
|  | static sal_Bool ImplHandleIMEComposition( HWND hWnd, LPARAM lParam ) | 
|  | { | 
|  | sal_Bool bDef = TRUE; | 
|  | ImplSalYieldMutexAcquireWithWait(); | 
|  |  | 
|  | WinSalFrame* pFrame = GetWindowPtr( hWnd ); | 
|  | if ( pFrame && (!lParam || (lParam & GCS_RESULTSTR)) ) | 
|  | { | 
|  | // Wir restaurieren den Background-Modus bei jeder Texteingabe, | 
|  | // da einige Tools wie RichWin uns diesen hin- und wieder umsetzen | 
|  | if ( pFrame->mpGraphics && | 
|  | pFrame->mpGraphics->getHDC() ) | 
|  | SetBkMode( pFrame->mpGraphics->getHDC(), TRANSPARENT ); | 
|  | } | 
|  |  | 
|  | if ( pFrame && pFrame->mbHandleIME ) | 
|  | { | 
|  | if ( !lParam ) | 
|  | { | 
|  | SalExtTextInputEvent aEvt; | 
|  | aEvt.mnTime             = GetMessageTime(); | 
|  | aEvt.mpTextAttr         = NULL; | 
|  | aEvt.mnCursorPos        = 0; | 
|  | aEvt.mnDeltaStart       = 0; | 
|  | aEvt.mbOnlyCursor       = FALSE; | 
|  | aEvt.mnCursorFlags      = 0; | 
|  | pFrame->CallCallback( SALEVENT_EXTTEXTINPUT, (void*)&aEvt ); | 
|  | pFrame->CallCallback( SALEVENT_ENDEXTTEXTINPUT, (void*)NULL ); | 
|  | } | 
|  | else if ( lParam & (GCS_RESULTSTR | GCS_COMPSTR | GCS_COMPATTR | GCS_CURSORPOS) ) | 
|  | { | 
|  | HIMC hIMC = ImmGetContext( hWnd ); | 
|  | if ( hIMC ) | 
|  | { | 
|  | if ( ImplHandleIMECompositionInput( pFrame, hIMC, lParam ) ) | 
|  | bDef = FALSE; | 
|  |  | 
|  | ImmReleaseContext( hWnd, hIMC ); | 
|  | } | 
|  | } | 
|  | } | 
|  |  | 
|  | ImplSalYieldMutexRelease(); | 
|  | return bDef; | 
|  | } | 
|  |  | 
|  | // ----------------------------------------------------------------------- | 
|  |  | 
|  | static sal_Bool ImplHandleIMEEndComposition( HWND hWnd ) | 
|  | { | 
|  | sal_Bool bDef = TRUE; | 
|  |  | 
|  | ImplSalYieldMutexAcquireWithWait(); | 
|  |  | 
|  | WinSalFrame* pFrame = GetWindowPtr( hWnd ); | 
|  | if ( pFrame && pFrame->mbHandleIME ) | 
|  | { | 
|  | if ( pFrame->mbAtCursorIME ) | 
|  | bDef = FALSE; | 
|  | } | 
|  |  | 
|  | ImplSalYieldMutexRelease(); | 
|  |  | 
|  | return bDef; | 
|  | } | 
|  |  | 
|  | // ----------------------------------------------------------------------- | 
|  |  | 
|  | static boolean ImplHandleAppCommand( HWND hWnd, LPARAM lParam ) | 
|  | { | 
|  | sal_Int16 nCommand = 0; | 
|  | switch( GET_APPCOMMAND_LPARAM(lParam) ) | 
|  | { | 
|  | case APPCOMMAND_MEDIA_CHANNEL_DOWN:			nCommand = MEDIA_COMMAND_CHANNEL_DOWN; break; | 
|  | case APPCOMMAND_MEDIA_CHANNEL_UP:			nCommand = MEDIA_COMMAND_CHANNEL_UP; break; | 
|  | case APPCOMMAND_MEDIA_NEXTTRACK:			nCommand = MEDIA_COMMAND_NEXTTRACK; break; | 
|  | case APPCOMMAND_MEDIA_PAUSE:				nCommand = MEDIA_COMMAND_PAUSE; break; | 
|  | case APPCOMMAND_MEDIA_PLAY:					nCommand = MEDIA_COMMAND_PLAY; break; | 
|  | case APPCOMMAND_MEDIA_PLAY_PAUSE:			nCommand = MEDIA_COMMAND_PLAY_PAUSE; break; | 
|  | case APPCOMMAND_MEDIA_PREVIOUSTRACK:		nCommand = MEDIA_COMMAND_PREVIOUSTRACK; break; | 
|  | case APPCOMMAND_MEDIA_RECORD:				nCommand = MEDIA_COMMAND_RECORD; break; | 
|  | case APPCOMMAND_MEDIA_REWIND:				nCommand = MEDIA_COMMAND_REWIND; break; | 
|  | case APPCOMMAND_MEDIA_STOP:					nCommand = MEDIA_COMMAND_STOP; break; | 
|  | case APPCOMMAND_MIC_ON_OFF_TOGGLE:			nCommand = MEDIA_COMMAND_MIC_ON_OFF_TOGGLE; break; | 
|  | case APPCOMMAND_MICROPHONE_VOLUME_DOWN:		nCommand = MEDIA_COMMAND_MICROPHONE_VOLUME_DOWN; break; | 
|  | case APPCOMMAND_MICROPHONE_VOLUME_MUTE:		nCommand = MEDIA_COMMAND_MICROPHONE_VOLUME_MUTE; break; | 
|  | case APPCOMMAND_MICROPHONE_VOLUME_UP:		nCommand = MEDIA_COMMAND_MICROPHONE_VOLUME_UP; break; | 
|  | case APPCOMMAND_VOLUME_DOWN:				nCommand = MEDIA_COMMAND_VOLUME_DOWN; break; | 
|  | case APPCOMMAND_VOLUME_MUTE:				nCommand = MEDIA_COMMAND_VOLUME_MUTE; break; | 
|  | case APPCOMMAND_VOLUME_UP:					nCommand = MEDIA_COMMAND_VOLUME_UP; break; | 
|  | break; | 
|  | default: | 
|  | return false; | 
|  | } | 
|  |  | 
|  | WinSalFrame* pFrame = GetWindowPtr( hWnd ); | 
|  | Window *pWindow = pFrame ? pFrame->GetWindow() : NULL; | 
|  |  | 
|  | if( pWindow ) | 
|  | { | 
|  | const Point aPoint; | 
|  | CommandEvent aCEvt( aPoint, COMMAND_MEDIA, FALSE, &nCommand ); | 
|  | NotifyEvent aNCmdEvt( EVENT_COMMAND, pWindow, &aCEvt ); | 
|  |  | 
|  | if ( !ImplCallPreNotify( aNCmdEvt ) ) | 
|  | { | 
|  | pWindow->Command( aCEvt ); | 
|  | return true; | 
|  | } | 
|  | } | 
|  |  | 
|  | return false; | 
|  | } | 
|  |  | 
|  |  | 
|  | static void ImplHandleIMENotify( HWND hWnd, WPARAM wParam ) | 
|  | { | 
|  | if ( wParam == (WPARAM)IMN_OPENCANDIDATE ) | 
|  | { | 
|  | ImplSalYieldMutexAcquireWithWait(); | 
|  |  | 
|  | WinSalFrame* pFrame = GetWindowPtr( hWnd ); | 
|  | if ( pFrame && pFrame->mbHandleIME && | 
|  | pFrame->mbAtCursorIME ) | 
|  | { | 
|  | // Wir wollen den Cursor hiden | 
|  | pFrame->mbCandidateMode = TRUE; | 
|  | ImplHandleIMEComposition( hWnd, GCS_CURSORPOS ); | 
|  |  | 
|  | HWND hWnd = pFrame->mhWnd; | 
|  | HIMC hIMC = ImmGetContext( hWnd ); | 
|  | if ( hIMC ) | 
|  | { | 
|  | LONG nBufLen = ImmGetCompositionStringW( hIMC, GCS_COMPSTR, 0, 0 ); | 
|  | if ( nBufLen >= 1 ) | 
|  | { | 
|  | SalExtTextInputPosEvent aPosEvt; | 
|  | pFrame->CallCallback( SALEVENT_EXTTEXTINPUTPOS, (void*)&aPosEvt ); | 
|  |  | 
|  | // Vertical !!! | 
|  | CANDIDATEFORM aForm; | 
|  | aForm.dwIndex           = 0; | 
|  | aForm.dwStyle           = CFS_EXCLUDE; | 
|  | aForm.ptCurrentPos.x    = aPosEvt.mnX; | 
|  | aForm.ptCurrentPos.y    = aPosEvt.mnY+1; | 
|  | aForm.rcArea.left       = aPosEvt.mnX; | 
|  | aForm.rcArea.top        = aPosEvt.mnY; | 
|  | aForm.rcArea.right      = aForm.rcArea.left+aPosEvt.mnExtWidth+1; | 
|  | aForm.rcArea.bottom     = aForm.rcArea.top+aPosEvt.mnHeight+1; | 
|  | ImmSetCandidateWindow( hIMC, &aForm ); | 
|  | } | 
|  |  | 
|  | ImmReleaseContext( hWnd, hIMC ); | 
|  | } | 
|  | } | 
|  |  | 
|  | ImplSalYieldMutexRelease(); | 
|  | } | 
|  | else if ( wParam == (WPARAM)IMN_CLOSECANDIDATE ) | 
|  | { | 
|  | ImplSalYieldMutexAcquireWithWait(); | 
|  | WinSalFrame* pFrame = GetWindowPtr( hWnd ); | 
|  | if ( pFrame ) | 
|  | pFrame->mbCandidateMode = FALSE; | 
|  | ImplSalYieldMutexRelease(); | 
|  | } | 
|  | } | 
|  |  | 
|  | // ----------------------------------------------------------------------- | 
|  | #if WINVER >= 0x0500 | 
|  |  | 
|  | static LRESULT ImplHandleIMEReconvertString( HWND hWnd, LPARAM lParam ) | 
|  | { | 
|  | WinSalFrame* pFrame = GetWindowPtr( hWnd ); | 
|  | LPRECONVERTSTRING pReconvertString = (LPRECONVERTSTRING) lParam; | 
|  | LRESULT nRet = 0; | 
|  | SalSurroundingTextRequestEvent aEvt; | 
|  | aEvt.maText = UniString(); | 
|  | aEvt.mnStart = aEvt.mnEnd = 0; | 
|  |  | 
|  | UINT nImeProps = ImmGetProperty( GetKeyboardLayout( 0 ), IGP_SETCOMPSTR ); | 
|  | if( (nImeProps & SCS_CAP_SETRECONVERTSTRING) == 0 ) | 
|  | { | 
|  | // This IME does not support reconversion. | 
|  | return 0; | 
|  | } | 
|  |  | 
|  | if( !pReconvertString ) | 
|  | { | 
|  | // The first call for reconversion. | 
|  | pFrame->CallCallback( SALEVENT_STARTRECONVERSION, (void*)NULL ); | 
|  |  | 
|  | // Retrieve the surrounding text from the focused control. | 
|  | pFrame->CallCallback( SALEVENT_SURROUNDINGTEXTREQUEST, (void*)&aEvt ); | 
|  |  | 
|  | if( aEvt.maText.Len() == 0 ) | 
|  | { | 
|  | return 0; | 
|  | } | 
|  |  | 
|  | nRet = sizeof(RECONVERTSTRING) + (aEvt.maText.Len() + 1) * sizeof(WCHAR); | 
|  | } | 
|  | else | 
|  | { | 
|  | // The second call for reconversion. | 
|  |  | 
|  | // Retrieve the surrounding text from the focused control. | 
|  | pFrame->CallCallback( SALEVENT_SURROUNDINGTEXTREQUEST, (void*)&aEvt ); | 
|  | nRet = sizeof(RECONVERTSTRING) + (aEvt.maText.Len() + 1) * sizeof(WCHAR); | 
|  |  | 
|  | pReconvertString->dwStrOffset = sizeof(RECONVERTSTRING); | 
|  | pReconvertString->dwStrLen = aEvt.maText.Len(); | 
|  | pReconvertString->dwCompStrOffset = aEvt.mnStart * sizeof(WCHAR); | 
|  | pReconvertString->dwCompStrLen = aEvt.mnEnd - aEvt.mnStart; | 
|  | pReconvertString->dwTargetStrOffset = pReconvertString->dwCompStrOffset; | 
|  | pReconvertString->dwTargetStrLen = pReconvertString->dwCompStrLen; | 
|  |  | 
|  | memcpy( (LPWSTR)(pReconvertString + 1), aEvt.maText.GetBuffer(), (aEvt.maText.Len() + 1) * sizeof(WCHAR) ); | 
|  | } | 
|  |  | 
|  | // just return the required size of buffer to reconvert. | 
|  | return nRet; | 
|  | } | 
|  |  | 
|  | // ----------------------------------------------------------------------- | 
|  |  | 
|  | static LRESULT ImplHandleIMEConfirmReconvertString( HWND hWnd, LPARAM lParam ) | 
|  | { | 
|  | WinSalFrame* pFrame = GetWindowPtr( hWnd ); | 
|  | LPRECONVERTSTRING pReconvertString = (LPRECONVERTSTRING) lParam; | 
|  | SalSurroundingTextRequestEvent aEvt; | 
|  | aEvt.maText = UniString(); | 
|  | aEvt.mnStart = aEvt.mnEnd = 0; | 
|  |  | 
|  | pFrame->CallCallback( SALEVENT_SURROUNDINGTEXTREQUEST, (void*)&aEvt ); | 
|  |  | 
|  | sal_uLong nTmpStart = pReconvertString->dwCompStrOffset / sizeof(WCHAR); | 
|  | sal_uLong nTmpEnd = nTmpStart + pReconvertString->dwCompStrLen; | 
|  |  | 
|  | if( nTmpStart != aEvt.mnStart || nTmpEnd != aEvt.mnEnd ) | 
|  | { | 
|  | SalSurroundingTextSelectionChangeEvent aSelEvt; | 
|  | aSelEvt.mnStart = nTmpStart; | 
|  | aSelEvt.mnEnd = nTmpEnd; | 
|  |  | 
|  | pFrame->CallCallback( SALEVENT_SURROUNDINGTEXTSELECTIONCHANGE, (void*)&aSelEvt ); | 
|  | } | 
|  |  | 
|  | return TRUE; | 
|  | } | 
|  |  | 
|  | #endif // WINVER >= 0x0500 | 
|  |  | 
|  | // ----------------------------------------------------------------------- | 
|  |  | 
|  | void SalTestMouseLeave() | 
|  | { | 
|  | SalData* pSalData = GetSalData(); | 
|  |  | 
|  | if ( pSalData->mhWantLeaveMsg && !::GetCapture() ) | 
|  | { | 
|  | POINT aPt; | 
|  | GetCursorPos( &aPt ); | 
|  | if ( pSalData->mhWantLeaveMsg != WindowFromPoint( aPt ) ) | 
|  | ImplSendMessage( pSalData->mhWantLeaveMsg, SAL_MSG_MOUSELEAVE, 0, MAKELPARAM( aPt.x, aPt.y ) ); | 
|  | } | 
|  | } | 
|  |  | 
|  | // ----------------------------------------------------------------------- | 
|  |  | 
|  | static int ImplSalWheelMousePos( HWND hWnd, UINT nMsg, WPARAM wParam, LPARAM lParam , | 
|  | LRESULT& rResult ) | 
|  | { | 
|  | POINT aPt; | 
|  | POINT aScreenPt; | 
|  | aScreenPt.x = (short)LOWORD( lParam ); | 
|  | aScreenPt.y = (short)HIWORD( lParam ); | 
|  | // Child-Fenster suchen, welches an der entsprechenden | 
|  | // Position liegt | 
|  | HWND hChildWnd; | 
|  | HWND hWheelWnd = hWnd; | 
|  | do | 
|  | { | 
|  | hChildWnd = hWheelWnd; | 
|  | aPt = aScreenPt; | 
|  | ScreenToClient( hChildWnd, &aPt ); | 
|  | hWheelWnd = ChildWindowFromPointEx( hChildWnd, aPt, CWP_SKIPINVISIBLE | CWP_SKIPTRANSPARENT ); | 
|  | } | 
|  | while ( hWheelWnd && (hWheelWnd != hChildWnd) ); | 
|  | if ( hWheelWnd && (hWheelWnd != hWnd) && | 
|  | (hWheelWnd != ::GetFocus()) && IsWindowEnabled( hWheelWnd ) ) | 
|  | { | 
|  | rResult = ImplSendMessage( hWheelWnd, nMsg, wParam, lParam ); | 
|  | return FALSE; | 
|  | } | 
|  |  | 
|  | return TRUE; | 
|  | } | 
|  |  | 
|  | // ----------------------------------------------------------------------- | 
|  |  | 
|  | LRESULT CALLBACK SalFrameWndProc( HWND hWnd, UINT nMsg, WPARAM wParam, LPARAM lParam, int& rDef ) | 
|  | { | 
|  | LRESULT     nRet = 0; | 
|  | static int  bInWheelMsg = FALSE; | 
|  | static int	bInQueryEnd = FALSE; | 
|  |  | 
|  | // By WM_CREATE we connect the frame with the window handle | 
|  | if ( nMsg == WM_CREATE ) | 
|  | { | 
|  | // Window-Instanz am Windowhandle speichern | 
|  | // Can also be used for the W-Version, because the struct | 
|  | // to access lpCreateParams is the same structure | 
|  | CREATESTRUCTA* pStruct = (CREATESTRUCTA*)lParam; | 
|  | WinSalFrame* pFrame = (WinSalFrame*)pStruct->lpCreateParams; | 
|  | if ( pFrame != 0 ) | 
|  | { | 
|  | SetWindowPtr( hWnd, pFrame ); | 
|  | // HWND schon hier setzen, da schon auf den Instanzdaten | 
|  | // gearbeitet werden kann, wenn Messages waehrend | 
|  | // CreateWindow() gesendet werden | 
|  | pFrame->mhWnd = hWnd; | 
|  | pFrame->maSysData.hWnd = hWnd; | 
|  | } | 
|  | return 0; | 
|  | } | 
|  |  | 
|  | ImplSVData* pSVData = ImplGetSVData(); | 
|  | // #i72707# TODO: the mbDeInit check will not be needed | 
|  | // once all windows that are not properly closed on exit got fixed | 
|  | if( pSVData->mbDeInit ) | 
|  | return 0; | 
|  |  | 
|  | if ( WM_USER_SYSTEM_WINDOW_ACTIVATED == nMsg ) | 
|  | { | 
|  | if (pSVData->mpIntroWindow) | 
|  | pSVData->mpIntroWindow->Hide(); | 
|  |  | 
|  | return 0; | 
|  | } | 
|  |  | 
|  | bool bCheckTimers = false; | 
|  |  | 
|  | switch( nMsg ) | 
|  | { | 
|  | case WM_MOUSEMOVE: | 
|  | case WM_LBUTTONDOWN: | 
|  | case WM_MBUTTONDOWN: | 
|  | case WM_RBUTTONDOWN: | 
|  | case WM_LBUTTONUP: | 
|  | case WM_MBUTTONUP: | 
|  | case WM_RBUTTONUP: | 
|  | case WM_NCMOUSEMOVE: | 
|  | case SAL_MSG_MOUSELEAVE: | 
|  | ImplSalYieldMutexAcquireWithWait(); | 
|  | rDef = !ImplHandleMouseMsg( hWnd, nMsg, wParam, lParam ); | 
|  | ImplSalYieldMutexRelease(); | 
|  | break; | 
|  |  | 
|  | case WM_NCLBUTTONDOWN: | 
|  | case WM_NCMBUTTONDOWN: | 
|  | case WM_NCRBUTTONDOWN: | 
|  | ImplSalYieldMutexAcquireWithWait(); | 
|  | ImplCallClosePopupsHdl( hWnd );   // close popups... | 
|  | ImplSalYieldMutexRelease(); | 
|  | break; | 
|  |  | 
|  | case WM_MOUSEACTIVATE: | 
|  | if ( LOWORD( lParam ) == HTCLIENT ) | 
|  | { | 
|  | ImplSalYieldMutexAcquireWithWait(); | 
|  | nRet = ImplHandleMouseActivateMsg( hWnd ); | 
|  | ImplSalYieldMutexRelease(); | 
|  | if ( nRet ) | 
|  | { | 
|  | nRet = MA_NOACTIVATE; | 
|  | rDef = FALSE; | 
|  | } | 
|  | } | 
|  | break; | 
|  |  | 
|  | case WM_KEYDOWN: | 
|  | case WM_KEYUP: | 
|  | case WM_DEADCHAR: | 
|  | case WM_CHAR: | 
|  | case WM_UNICHAR:    // MCD, 2003-01-13, Support for WM_UNICHAR & Keyman 6.0 | 
|  | case WM_SYSKEYDOWN: | 
|  | case WM_SYSKEYUP: | 
|  | case WM_SYSCHAR: | 
|  | ImplSalYieldMutexAcquireWithWait(); | 
|  | rDef = !ImplHandleKeyMsg( hWnd, nMsg, wParam, lParam, nRet ); | 
|  | ImplSalYieldMutexRelease(); | 
|  | break; | 
|  |  | 
|  | case WM_MOUSEWHEEL: | 
|  | // FALLTHROUGH intended | 
|  | case WM_MOUSEHWHEEL: | 
|  | // Gegen Rekursion absichern, falls wir vom IE oder dem externen | 
|  | // Fenster die Message wieder zurueckbekommen | 
|  | if ( !bInWheelMsg ) | 
|  | { | 
|  | bInWheelMsg++; | 
|  | rDef = !ImplHandleWheelMsg( hWnd, nMsg, wParam, lParam ); | 
|  | // Wenn wir die Message nicht ausgewertet haben, schauen wir | 
|  | // noch einmal nach, ob dort ein geplugtes Fenster steht, | 
|  | // welches wir dann benachrichtigen | 
|  | if ( rDef ) | 
|  | rDef = ImplSalWheelMousePos( hWnd, nMsg, wParam, lParam, nRet ); | 
|  | bInWheelMsg--; | 
|  | } | 
|  | break; | 
|  |  | 
|  | case WM_COMMAND: | 
|  | ImplSalYieldMutexAcquireWithWait(); | 
|  | rDef = !ImplHandleCommand( hWnd, wParam, lParam ); | 
|  | ImplSalYieldMutexRelease(); | 
|  | break; | 
|  |  | 
|  | case WM_INITMENUPOPUP: | 
|  | ImplSalYieldMutexAcquireWithWait(); | 
|  | rDef = !ImplHandleMenuActivate( hWnd, wParam, lParam ); | 
|  | ImplSalYieldMutexRelease(); | 
|  | break; | 
|  |  | 
|  | case WM_MENUSELECT: | 
|  | ImplSalYieldMutexAcquireWithWait(); | 
|  | rDef = !ImplHandleMenuSelect( hWnd, wParam, lParam ); | 
|  | ImplSalYieldMutexRelease(); | 
|  | break; | 
|  |  | 
|  | case WM_SYSCOMMAND: | 
|  | ImplSalYieldMutexAcquireWithWait(); | 
|  | nRet = ImplHandleSysCommand( hWnd, wParam, lParam ); | 
|  | ImplSalYieldMutexRelease(); | 
|  | if ( nRet ) | 
|  | rDef = FALSE; | 
|  | break; | 
|  |  | 
|  | case WM_MENUCHAR: | 
|  | nRet = ImplMenuChar( hWnd, wParam, lParam ); | 
|  | if( nRet ) | 
|  | rDef = FALSE; | 
|  | break; | 
|  |  | 
|  | case WM_MEASUREITEM: | 
|  | nRet = ImplMeasureItem(hWnd, wParam, lParam); | 
|  | if( nRet ) | 
|  | rDef = FALSE; | 
|  | break; | 
|  |  | 
|  | case WM_DRAWITEM: | 
|  | nRet = ImplDrawItem(hWnd, wParam, lParam); | 
|  | if( nRet ) | 
|  | rDef = FALSE; | 
|  | break; | 
|  |  | 
|  | case WM_MOVE: | 
|  | case SAL_MSG_POSTMOVE: | 
|  | ImplHandleMoveMsg( hWnd ); | 
|  | rDef = FALSE; | 
|  | break; | 
|  | case WM_SIZE: | 
|  | ImplHandleSizeMsg( hWnd, wParam, lParam ); | 
|  | rDef = FALSE; | 
|  | break; | 
|  | case SAL_MSG_POSTCALLSIZE: | 
|  | ImplCallSizeHdl( hWnd ); | 
|  | rDef = FALSE; | 
|  | break; | 
|  |  | 
|  | case WM_GETMINMAXINFO: | 
|  | if ( ImplHandleMinMax( hWnd, lParam ) ) | 
|  | rDef = FALSE; | 
|  | break; | 
|  |  | 
|  | case WM_ERASEBKGND: | 
|  | nRet = 1; | 
|  | rDef = FALSE; | 
|  | break; | 
|  | case WM_PAINT: | 
|  | bCheckTimers = ImplHandlePaintMsg( hWnd ); | 
|  | rDef = FALSE; | 
|  | break; | 
|  | case SAL_MSG_POSTPAINT: | 
|  | ImplHandlePaintMsg2( hWnd, (RECT*)wParam ); | 
|  | bCheckTimers = true; | 
|  | rDef = FALSE; | 
|  | break; | 
|  |  | 
|  | case SAL_MSG_FORCEPALETTE: | 
|  | ImplHandleForcePalette( hWnd ); | 
|  | rDef = FALSE; | 
|  | break; | 
|  |  | 
|  | case WM_QUERYNEWPALETTE: | 
|  | case SAL_MSG_POSTQUERYNEWPAL: | 
|  | nRet = ImplHandlePalette( TRUE, hWnd, nMsg, wParam, lParam, rDef ); | 
|  | break; | 
|  |  | 
|  | case WM_ACTIVATE: | 
|  | // Wenn wir aktiviert werden, dann wollen wir auch unsere | 
|  | // Palette setzen. Wir machen dieses in Activate, | 
|  | // damit andere externe Child-Fenster auch unsere Palette | 
|  | // ueberschreiben koennen. So wird unsere jedenfalls nur einmal | 
|  | // gesetzt und nicht immer rekursiv, da an allen anderen Stellen | 
|  | // diese nur als Background-Palette gesetzt wird | 
|  | if ( LOWORD( wParam ) != WA_INACTIVE ) | 
|  | ImplSendMessage( hWnd, SAL_MSG_FORCEPALETTE, 0, 0 ); | 
|  | break; | 
|  |  | 
|  | case WM_ENABLE: | 
|  | // #95133# a system dialog is opened/closed, using our app window as parent | 
|  | { | 
|  | WinSalFrame* pFrame = GetWindowPtr( hWnd ); | 
|  | Window *pWin = NULL; | 
|  | if( pFrame ) | 
|  | pWin = pFrame->GetWindow(); | 
|  |  | 
|  | if( !wParam ) | 
|  | { | 
|  | ImplSVData* pSVData = ImplGetSVData(); | 
|  | pSVData->maAppData.mnModalMode++; | 
|  |  | 
|  | // #106431#, hide SplashScreen | 
|  | if( pSVData->mpIntroWindow ) | 
|  | pSVData->mpIntroWindow->Hide(); | 
|  |  | 
|  | if( pWin ) | 
|  | { | 
|  | pWin->EnableInput( FALSE, TRUE, TRUE, NULL ); | 
|  | pWin->ImplIncModalCount();  // #106303# support frame based modal count | 
|  | } | 
|  | } | 
|  | else | 
|  | { | 
|  | ImplGetSVData()->maAppData.mnModalMode--; | 
|  | if( pWin ) | 
|  | { | 
|  | pWin->EnableInput( TRUE, TRUE, TRUE, NULL ); | 
|  | pWin->ImplDecModalCount();  // #106303# support frame based modal count | 
|  | } | 
|  | } | 
|  | } | 
|  | break; | 
|  |  | 
|  | case WM_KILLFOCUS: | 
|  | DestroyCaret(); | 
|  | case WM_SETFOCUS: | 
|  | case SAL_MSG_POSTFOCUS: | 
|  | ImplHandleFocusMsg( hWnd ); | 
|  | rDef = FALSE; | 
|  | break; | 
|  |  | 
|  | case WM_CLOSE: | 
|  | ImplHandleCloseMsg( hWnd ); | 
|  | rDef = FALSE; | 
|  | break; | 
|  |  | 
|  | case WM_QUERYENDSESSION: | 
|  | if( !bInQueryEnd ) | 
|  | { | 
|  | // handle queryendsession only once | 
|  | bInQueryEnd = TRUE; | 
|  | nRet = !ImplHandleShutDownMsg( hWnd ); | 
|  | rDef = FALSE; | 
|  |  | 
|  | // Issue #16314#: ImplHandleShutDownMsg causes a PostMessage in case of allowing shutdown. | 
|  | // This posted message was never processed and cause Windows XP to hang after log off | 
|  | // if there are multiple sessions and the current session wasn't the first one started. | 
|  | // So if shutdown is allowed we assume that a post message was done and retrieve all | 
|  | // messages in the message queue and dispatch them before we return control to the system. | 
|  |  | 
|  | if ( nRet ) | 
|  | { | 
|  | MSG	msg; | 
|  |  | 
|  | while( PeekMessage( &msg, NULL, 0, 0, PM_REMOVE ) ) | 
|  | { | 
|  | DispatchMessage( &msg ); | 
|  | } | 
|  | } | 
|  | } | 
|  | else | 
|  | { | 
|  | ImplSalYieldMutexAcquireWithWait(); | 
|  | ImplSalYieldMutexRelease(); | 
|  | rDef = TRUE; | 
|  | } | 
|  | break; | 
|  |  | 
|  | case WM_ENDSESSION: | 
|  | if( !wParam ) | 
|  | bInQueryEnd = FALSE; // no shutdown: allow query again | 
|  | nRet = FALSE; | 
|  | rDef = FALSE; | 
|  | break; | 
|  |  | 
|  | case WM_DISPLAYCHANGE: | 
|  | case WM_SETTINGCHANGE: | 
|  | case WM_DEVMODECHANGE: | 
|  | case WM_FONTCHANGE: | 
|  | case WM_SYSCOLORCHANGE: | 
|  | case WM_TIMECHANGE: | 
|  | ImplHandleSettingsChangeMsg( hWnd, nMsg, wParam, lParam ); | 
|  | break; | 
|  |  | 
|  | case WM_THEMECHANGED: | 
|  | GetSalData()->mbThemeChanged = TRUE; | 
|  | break; | 
|  |  | 
|  | case SAL_MSG_USEREVENT: | 
|  | ImplHandleUserEvent( hWnd, lParam ); | 
|  | rDef = FALSE; | 
|  | break; | 
|  |  | 
|  | case SAL_MSG_CAPTUREMOUSE: | 
|  | SetCapture( hWnd ); | 
|  | rDef = FALSE; | 
|  | break; | 
|  | case SAL_MSG_RELEASEMOUSE: | 
|  | if ( ::GetCapture() == hWnd ) | 
|  | ReleaseCapture(); | 
|  | rDef = FALSE; | 
|  | break; | 
|  | case SAL_MSG_TOTOP: | 
|  | ImplSalToTop( hWnd, (sal_uInt16)wParam ); | 
|  | rDef = FALSE; | 
|  | break; | 
|  | case SAL_MSG_SHOW: | 
|  | ImplSalShow( hWnd, (sal_Bool)wParam, (sal_Bool)lParam ); | 
|  | rDef = FALSE; | 
|  | break; | 
|  | case SAL_MSG_SETINPUTCONTEXT: | 
|  | ImplSalFrameSetInputContext( hWnd, (const SalInputContext*)(void*)lParam ); | 
|  | rDef = FALSE; | 
|  | break; | 
|  | case SAL_MSG_ENDEXTTEXTINPUT: | 
|  | ImplSalFrameEndExtTextInput( hWnd, (sal_uInt16)(sal_uLong)(void*)wParam ); | 
|  | rDef = FALSE; | 
|  | break; | 
|  |  | 
|  | case WM_INPUTLANGCHANGE: | 
|  | ImplHandleInputLangChange( hWnd, wParam, lParam ); | 
|  | break; | 
|  |  | 
|  | case WM_IME_CHAR: | 
|  | // #103487#, some IMEs (e.g. those that do not work onspot) | 
|  | //           may send WM_IME_CHAR instead of WM_IME_COMPOSITION | 
|  | // we just handle it like a WM_CHAR message - seems to work fine | 
|  | ImplSalYieldMutexAcquireWithWait(); | 
|  | rDef = !ImplHandleKeyMsg( hWnd, WM_CHAR, wParam, lParam, nRet ); | 
|  | ImplSalYieldMutexRelease(); | 
|  | break; | 
|  |  | 
|  | case WM_IME_STARTCOMPOSITION: | 
|  | rDef = ImplHandleIMEStartComposition( hWnd ); | 
|  | break; | 
|  |  | 
|  | case WM_IME_COMPOSITION: | 
|  | rDef = ImplHandleIMEComposition( hWnd, lParam ); | 
|  | break; | 
|  |  | 
|  | case WM_IME_ENDCOMPOSITION: | 
|  | rDef = ImplHandleIMEEndComposition( hWnd ); | 
|  | break; | 
|  |  | 
|  | case WM_IME_NOTIFY: | 
|  | ImplHandleIMENotify( hWnd, wParam ); | 
|  | break; | 
|  |  | 
|  | #ifdef WNT | 
|  | case WM_GETOBJECT: | 
|  | { | 
|  | if (!Application::IsEnableAccessInterface()) | 
|  | { | 
|  | break; | 
|  | } | 
|  | else | 
|  | { | 
|  | // IA2 should be enabled automatically | 
|  | AllSettings aSettings = Application::GetSettings(); | 
|  | MiscSettings aMisc = aSettings.GetMiscSettings(); | 
|  | aMisc.SetEnableATToolSupport( sal_True ); | 
|  | aSettings.SetMiscSettings( aMisc ); | 
|  | Application::SetSettings( aSettings ); | 
|  |  | 
|  | if (Application::GetSettings().GetMiscSettings().GetEnableATToolSupport()) | 
|  | { | 
|  | // Make sure to launch Accessibility only the following criteria are satisfied to avoid RFT interrupts regular acc processing | 
|  | if (g_acc_manager1 == NULL) | 
|  | { | 
|  | sal_Bool bCancelled(sal_False); | 
|  | InitAccessBridge(sal_False,bCancelled); | 
|  | if( bCancelled ) | 
|  | break; | 
|  | } | 
|  | if (g_acc_manager1 != NULL) | 
|  | { | 
|  | // MT: mhOnSetTitleWnd not set to reasonable value anywhere... | 
|  | /* | 
|  | sal_Bool bSkipSetTitleClient = sal_False; | 
|  | SalFrame* pFrame = GetWindowPtr( hWnd ); | 
|  | if(pFrame) | 
|  | { | 
|  | bSkipSetTitleClient = (lParam == OBJID_CLIENT && hWnd == ((WinSalFrame*)pFrame)->mhOnSetTitleWnd); | 
|  | } | 
|  | */ | 
|  | if ( (lParam == OBJID_CLIENT ) /* && !bSkipSetTitleClient */ ) | 
|  | { | 
|  | long RetResult = g_acc_manager1->getAccObjectPtr((long)hWnd, lParam, wParam); | 
|  | if(RetResult != 0) | 
|  | { | 
|  | rDef = FALSE; | 
|  | return (HRESULT)RetResult; | 
|  | } | 
|  | } | 
|  | } | 
|  | } | 
|  | } | 
|  | break; | 
|  | } | 
|  | #endif | 
|  |  | 
|  | case WM_APPCOMMAND: | 
|  | if( ImplHandleAppCommand( hWnd, lParam ) ) | 
|  | { | 
|  | rDef = false; | 
|  | nRet = 1; | 
|  | } | 
|  | break; | 
|  | #if WINVER >= 0x0500 | 
|  | case WM_IME_REQUEST: | 
|  | if ( PtrToInt( wParam ) == IMR_RECONVERTSTRING ) | 
|  | { | 
|  | nRet = ImplHandleIMEReconvertString( hWnd, lParam ); | 
|  | rDef = FALSE; | 
|  | } | 
|  | else if( PtrToInt( wParam ) == IMR_CONFIRMRECONVERTSTRING ) | 
|  | { | 
|  | nRet = ImplHandleIMEConfirmReconvertString( hWnd, lParam ); | 
|  | rDef = FALSE; | 
|  | } | 
|  | break; | 
|  | #endif // WINVER >= 0x0500 | 
|  | } | 
|  |  | 
|  | // WheelMouse-Message abfangen | 
|  | if ( rDef && (nMsg == aSalShlData.mnWheelMsgId) && aSalShlData.mnWheelMsgId ) | 
|  | { | 
|  | // Gegen Rekursion absichern, falls wir vom IE oder dem externen | 
|  | // Fenster die Message wieder zurueckbekommen | 
|  | if ( !bInWheelMsg ) | 
|  | { | 
|  | bInWheelMsg++; | 
|  | // Zuerst wollen wir die Message dispatchen und dann darf auch | 
|  | // das SystemWindow drankommen | 
|  | WORD nKeyState = 0; | 
|  | if ( GetKeyState( VK_SHIFT ) & 0x8000 ) | 
|  | nKeyState |= MK_SHIFT; | 
|  | if ( GetKeyState( VK_CONTROL ) & 0x8000 ) | 
|  | nKeyState |= MK_CONTROL; | 
|  | // Mutex handling is inside from this call | 
|  | rDef = !ImplHandleWheelMsg( hWnd, | 
|  | WM_MOUSEWHEEL, | 
|  | MAKEWPARAM( nKeyState, (WORD)wParam ), | 
|  | lParam ); | 
|  | if ( rDef ) | 
|  | { | 
|  | HWND hWheelWnd = ::GetFocus(); | 
|  | if ( hWheelWnd && (hWheelWnd != hWnd) ) | 
|  | { | 
|  | nRet = ImplSendMessage( hWheelWnd, nMsg, wParam, lParam ); | 
|  | rDef = FALSE; | 
|  | } | 
|  | else | 
|  | rDef = ImplSalWheelMousePos( hWnd, nMsg, wParam, lParam, nRet ); | 
|  | } | 
|  | bInWheelMsg--; | 
|  | } | 
|  | } | 
|  |  | 
|  | if( bCheckTimers ) | 
|  | { | 
|  | SalData* pSalData = GetSalData(); | 
|  | if( pSalData->mnNextTimerTime ) | 
|  | { | 
|  | DWORD nCurTime = GetTickCount(); | 
|  | if( pSalData->mnNextTimerTime < nCurTime ) | 
|  | { | 
|  | MSG aMsg; | 
|  | if( ! ImplPeekMessage( &aMsg, 0, WM_PAINT, WM_PAINT, PM_NOREMOVE | PM_NOYIELD ) ) | 
|  | ImplPostMessage( pSalData->mpFirstInstance->mhComWnd, SAL_MSG_POSTTIMER, 0, nCurTime ); | 
|  | } | 
|  | } | 
|  | } | 
|  |  | 
|  | return nRet; | 
|  | } | 
|  |  | 
|  | LRESULT CALLBACK SalFrameWndProcA( HWND hWnd, UINT nMsg, WPARAM wParam, LPARAM lParam ) | 
|  | { | 
|  | int bDef = TRUE; | 
|  | LRESULT nRet = 0; | 
|  | #ifdef __MINGW32__ | 
|  | jmp_buf jmpbuf; | 
|  | __SEHandler han; | 
|  | if (__builtin_setjmp(jmpbuf) == 0) | 
|  | { | 
|  | han.Set(jmpbuf, NULL, (__SEHandler::PF)EXCEPTION_EXECUTE_HANDLER); | 
|  | #else | 
|  | __try | 
|  | { | 
|  | #endif | 
|  | nRet = SalFrameWndProc( hWnd, nMsg, wParam, lParam, bDef ); | 
|  | } | 
|  | #ifdef __MINGW32__ | 
|  | han.Reset(); | 
|  | #else | 
|  | __except(WinSalInstance::WorkaroundExceptionHandlingInUSER32Lib(GetExceptionCode(), GetExceptionInformation())) | 
|  | { | 
|  | } | 
|  | #endif | 
|  | if ( bDef ) | 
|  | nRet = DefWindowProcA( hWnd, nMsg, wParam, lParam ); | 
|  | return nRet; | 
|  | } | 
|  |  | 
|  | LRESULT CALLBACK SalFrameWndProcW( HWND hWnd, UINT nMsg, WPARAM wParam, LPARAM lParam ) | 
|  | { | 
|  | int bDef = TRUE; | 
|  | LRESULT nRet = 0; | 
|  | #ifdef __MINGW32__ | 
|  | jmp_buf jmpbuf; | 
|  | __SEHandler han; | 
|  | if (__builtin_setjmp(jmpbuf) == 0) | 
|  | { | 
|  | han.Set(jmpbuf, NULL, (__SEHandler::PF)EXCEPTION_EXECUTE_HANDLER); | 
|  | #else | 
|  | __try | 
|  | { | 
|  | #endif | 
|  | nRet = SalFrameWndProc( hWnd, nMsg, wParam, lParam, bDef ); | 
|  | } | 
|  | #ifdef __MINGW32__ | 
|  | han.Reset(); | 
|  | #else | 
|  | __except(WinSalInstance::WorkaroundExceptionHandlingInUSER32Lib(GetExceptionCode(), GetExceptionInformation())) | 
|  | { | 
|  | } | 
|  | #endif | 
|  |  | 
|  | if ( bDef ) | 
|  | nRet = DefWindowProcW( hWnd, nMsg, wParam, lParam ); | 
|  | return nRet; | 
|  | } | 
|  |  | 
|  | // ----------------------------------------------------------------------- | 
|  |  | 
|  | sal_Bool ImplHandleGlobalMsg( HWND hWnd, UINT nMsg, WPARAM wParam, LPARAM lParam, LRESULT& rlResult ) | 
|  | { | 
|  | // handle all messages concerning all frames so they get processed only once | 
|  | // Must work for Unicode and none Unicode | 
|  | sal_Bool bResult = FALSE; | 
|  | if ( (nMsg == WM_PALETTECHANGED) || (nMsg == SAL_MSG_POSTPALCHANGED) ) | 
|  | { | 
|  | int bDef = TRUE; | 
|  | rlResult = ImplHandlePalette( FALSE, hWnd, nMsg, wParam, lParam, bDef ); | 
|  | bResult = (bDef != 0); | 
|  | } | 
|  | else if( nMsg == WM_DISPLAYCHANGE ) | 
|  | { | 
|  | WinSalSystem* pSys = static_cast<WinSalSystem*>(ImplGetSalSystem()); | 
|  | if( pSys ) | 
|  | pSys->clearMonitors(); | 
|  | bResult = (pSys != NULL); | 
|  | } | 
|  | return bResult; | 
|  | } | 
|  |  | 
|  | // ----------------------------------------------------------------------- | 
|  |  | 
|  | sal_Bool ImplWriteLastError( DWORD lastError, const char *szApiCall ) | 
|  | { | 
|  | static int first=1; | 
|  | // if VCL_LOGFILE_ENABLED is set, Win32 API error messages can be written | 
|  | // to %TMP%/vcl.log or %TEMP%/vcl.log | 
|  | static char *logEnabled = getenv("VCL_LOGFILE_ENABLED"); | 
|  | if( logEnabled ) | 
|  | { | 
|  | sal_Bool bSuccess = FALSE; | 
|  | static char *szTmp = getenv("TMP"); | 
|  | if( !szTmp || !*szTmp ) | 
|  | szTmp = getenv("TEMP"); | 
|  | if( szTmp && *szTmp ) | 
|  | { | 
|  | char fname[5000]; | 
|  | strcpy( fname, szTmp ); | 
|  | if( fname[strlen(fname) - 1] != '\\' ) | 
|  | strcat( fname, "\\"); | 
|  | strcat( fname, "vcl.log" ); | 
|  | FILE *fp = fopen( fname, "a" ); // always append | 
|  | if( fp ) | 
|  | { | 
|  | if( first ) | 
|  | { | 
|  | first = 0; | 
|  | fprintf( fp, "Process ID: %d (0x%x)\n", GetCurrentProcessId(), GetCurrentProcessId() ); | 
|  | } | 
|  | time_t aclock; | 
|  | time( &aclock );                           // Get time in seconds | 
|  | struct tm *newtime = localtime( &aclock ); // Convert time to struct tm form | 
|  | fprintf( fp, asctime( newtime ) );         // print time stamp | 
|  |  | 
|  | fprintf( fp, "%s returned %u (0x%x)\n", szApiCall, lastError, lastError ); | 
|  | bSuccess = TRUE;    // may be FormatMessage fails but we wrote at least the error code | 
|  |  | 
|  | LPVOID lpMsgBuf; | 
|  | if (FormatMessageA( | 
|  | FORMAT_MESSAGE_ALLOCATE_BUFFER | | 
|  | FORMAT_MESSAGE_FROM_SYSTEM | | 
|  | FORMAT_MESSAGE_IGNORE_INSERTS, | 
|  | NULL, | 
|  | lastError, | 
|  | MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), // Default language | 
|  | (LPSTR) &lpMsgBuf, | 
|  | 0, | 
|  | NULL )) | 
|  | { | 
|  | fprintf( fp, " %s\n", (LPSTR)lpMsgBuf ); | 
|  | LocalFree( lpMsgBuf ); | 
|  | } | 
|  |  | 
|  | fclose( fp ); | 
|  | } | 
|  | } | 
|  | return bSuccess; | 
|  | } | 
|  | else | 
|  | return TRUE; | 
|  | } | 
|  |  | 
|  | // ----------------------------------------------------------------------- | 
|  |  | 
|  | #ifdef WNT | 
|  | bool IsWNTInitAccessBridge() | 
|  | { | 
|  | return NULL != g_acc_manager1; | 
|  | } | 
|  | #endif | 
|  | #ifdef WNT | 
|  | bool WNTEnableAccessInterface(bool bEnable) | 
|  | { | 
|  | ImplSVData* pSVData = ImplGetSVData(); | 
|  |  | 
|  | BOOL bPreVal = pSVData->maAppData.m_bEnableAccessInterface; | 
|  | long nEnable= bEnable; | 
|  | ::InterlockedExchange( | 
|  | (LPLONG)&(pSVData->maAppData.m_bEnableAccessInterface), | 
|  | nEnable); | 
|  |  | 
|  | return bPreVal; | 
|  | } | 
|  | #endif |