xref: /trunk/main/vcl/win/source/window/salframe.cxx (revision 556524fe)
1 /**************************************************************
2  *
3  * Licensed to the Apache Software Foundation (ASF) under one
4  * or more contributor license agreements.  See the NOTICE file
5  * distributed with this work for additional information
6  * regarding copyright ownership.  The ASF licenses this file
7  * to you under the Apache License, Version 2.0 (the
8  * "License"); you may not use this file except in compliance
9  * with the License.  You may obtain a copy of the License at
10  *
11  *   http://www.apache.org/licenses/LICENSE-2.0
12  *
13  * Unless required by applicable law or agreed to in writing,
14  * software distributed under the License is distributed on an
15  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16  * KIND, either express or implied.  See the License for the
17  * specific language governing permissions and limitations
18  * under the License.
19  *
20  *************************************************************/
21 
22 
23 
24 // MARKER(update_precomp.py): autogen include statement, do not remove
25 #include "precompiled_vcl.hxx"
26 
27 // i72022: ad-hoc to forcibly enable reconversion
28 #if WINVER < 0x0500
29 #undef WINVER
30 #define WINVER 0x0500
31 #endif
32 
33 #include <com/sun/star/lang/XMultiServiceFactory.hpp>
34 #include <com/sun/star/container/XIndexAccess.hpp>
35 #include <com/sun/star/beans/XPropertySet.hpp>
36 #include <com/sun/star/awt/Rectangle.hpp>
37 #include <comphelper/processfactory.hxx>
38 #include <unotools/misccfg.hxx>
39 
40 #include <string.h>
41 #include <limits.h>
42 
43 #include <stdio.h>
44 
45 #include <tools/svwin.h>
46 #ifdef __MINGW32__
47 #include <excpt.h>
48 #endif
49 
50 #include <rtl/string.h>
51 #include <rtl/ustring.h>
52 
53 #include <osl/module.h>
54 
55 #include <tools/debug.hxx>
56 
57 #include <vcl/sysdata.hxx>
58 #include <vcl/timer.hxx>
59 #include <vcl/settings.hxx>
60 #include <vcl/keycodes.hxx>
61 #include <vcl/window.hxx>
62 #include <vcl/wrkwin.hxx>
63 #include <vcl/svapp.hxx>
64 #include <vcl/impdel.hxx>
65 
66 // Warning in SDK header
67 #if defined(_MSC_VER) && (_MSC_VER > 1400)
68 #pragma warning( disable: 4242 4244 )
69 #endif
70 #include <win/wincomp.hxx>
71 #include <win/salids.hrc>
72 #include <win/saldata.hxx>
73 #include <win/salinst.h>
74 #include <win/salbmp.h>
75 #include <win/salgdi.h>
76 #include <win/salsys.h>
77 #include <win/salframe.h>
78 #include <win/salvd.h>
79 #include <win/salmenu.h>
80 #include <win/salobj.h>
81 #include <win/saltimer.h>
82 
83 #include <impbmp.hxx>
84 #include <window.h>
85 #include <sallayout.hxx>
86 
87 #define COMPILE_MULTIMON_STUBS
88 #include <multimon.h>
89 #include <vector>
90 #ifdef __MINGW32__
91 #include <algorithm>
92 using ::std::max;
93 #endif
94 
95 //IAccessibility2 Implementation 2009-----
96 #ifdef WNT
97 #include <oleacc.h>
98 #include <com/sun/star/accessibility/XMSAAService.hpp>
99 #ifndef _WIN32_WCE
100 #define WM_GETOBJECT                    0x003D
101 #endif
102 #include <win/g_msaasvc.h>
103 #endif
104 //-----IAccessibility2 Implementation 2009
105 #include <com/sun/star/uno/Exception.hdl>
106 
107 #include <time.h>
108 
109 using ::rtl::OUString;
110 using namespace ::com::sun::star;
111 using namespace ::com::sun::star::uno;
112 using namespace ::com::sun::star::lang;
113 using namespace ::com::sun::star::container;
114 using namespace ::com::sun::star::beans;
115 
116 // The following defines are newly added in Longhorn
117 #ifndef WM_MOUSEHWHEEL
118 # define WM_MOUSEHWHEEL            0x020E
119 #endif
120 #ifndef SPI_GETWHEELSCROLLCHARS
121 # define SPI_GETWHEELSCROLLCHARS   0x006C
122 #endif
123 #ifndef SPI_SETWHEELSCROLLCHARS
124 # define SPI_SETWHEELSCROLLCHARS   0x006D
125 #endif
126 
127 
128 
129 #if OSL_DEBUG_LEVEL > 1
130 void MyOutputDebugString( char *s) { OutputDebugString( s ); }
131 #endif
132 
133 // misssing prototypes and constants for LayeredWindows
134 extern "C" {
135     //WINUSERAPI sal_Bool WINAPI SetLayeredWindowAttributes(HWND,COLORREF,BYTE,DWORD);
136     typedef sal_Bool ( WINAPI * SetLayeredWindowAttributes_Proc_T ) (HWND,COLORREF,BYTE,DWORD);
137     static SetLayeredWindowAttributes_Proc_T lpfnSetLayeredWindowAttributes;
138 };
139 
140 // =======================================================================
141 
142 const unsigned int WM_USER_SYSTEM_WINDOW_ACTIVATED = RegisterWindowMessageA("SYSTEM_WINDOW_ACTIVATED");
143 
144 sal_Bool WinSalFrame::mbInReparent = FALSE;
145 
146 // =======================================================================
147 
148 // Wegen Fehler in Windows-Headerfiles
149 #ifndef IMN_OPENCANDIDATE
150 #define IMN_OPENCANDIDATE               0x0005
151 #endif
152 #ifndef IMN_CLOSECANDIDATE
153 #define IMN_CLOSECANDIDATE              0x0004
154 #endif
155 
156 #ifndef WM_THEMECHANGED
157 #define WM_THEMECHANGED                 0x031A
158 #endif
159 
160 // Macros for support of WM_UNICHAR & Keyman 6.0
161 #define Uni_UTF32ToSurrogate1(ch)   (((unsigned long) (ch) - 0x10000) / 0x400 + 0xD800)
162 #define Uni_UTF32ToSurrogate2(ch)   (((unsigned long) (ch) - 0x10000) % 0x400 + 0xDC00)
163 #define Uni_SupplementaryPlanesStart    0x10000
164 
165 // =======================================================================
166 //IAccessibility2 Implementation 2009-----
167 #ifdef WNT
168 using namespace ::com::sun::star::accessibility;
169 XMSAAService* g_acc_manager1 = NULL;
170 #endif
171 //-----IAccessibility2 Implementation 2009
172 static void UpdateFrameGeometry( HWND hWnd, WinSalFrame* pFrame );
173 static void SetMaximizedFrameGeometry( HWND hWnd, WinSalFrame* pFrame, RECT* pParentRect = NULL );
174 
175 static void ImplSaveFrameState( WinSalFrame* pFrame )
176 {
177     // Position, Groesse und Status fuer GetWindowState() merken
178     if ( !pFrame->mbFullScreen )
179     {
180         sal_Bool bVisible = (GetWindowStyle( pFrame->mhWnd ) & WS_VISIBLE) != 0;
181         if ( IsIconic( pFrame->mhWnd ) )
182         {
183             pFrame->maState.mnState |= SAL_FRAMESTATE_MINIMIZED;
184             if ( bVisible )
185                 pFrame->mnShowState = SW_SHOWMAXIMIZED;
186         }
187         else if ( IsZoomed( pFrame->mhWnd ) )
188         {
189             pFrame->maState.mnState &= ~SAL_FRAMESTATE_MINIMIZED;
190             pFrame->maState.mnState |= SAL_FRAMESTATE_MAXIMIZED;
191             if ( bVisible )
192                 pFrame->mnShowState = SW_SHOWMAXIMIZED;
193             pFrame->mbRestoreMaximize = TRUE;
194 
195             WINDOWPLACEMENT aPlacement;
196             aPlacement.length = sizeof(aPlacement);
197             if( GetWindowPlacement( pFrame->mhWnd, &aPlacement ) )
198             {
199                 RECT aRect = aPlacement.rcNormalPosition;
200                 RECT aRect2 = aRect;
201                 AdjustWindowRectEx( &aRect2, GetWindowStyle( pFrame->mhWnd ),
202                                     FALSE,  GetWindowExStyle( pFrame->mhWnd ) );
203                 long nTopDeco = abs( aRect.top - aRect2.top );
204                 long nLeftDeco = abs( aRect.left - aRect2.left );
205                 long nBottomDeco = abs( aRect.bottom - aRect2.bottom );
206                 long nRightDeco = abs( aRect.right - aRect2.right );
207 
208                 pFrame->maState.mnX      = aRect.left + nLeftDeco;
209                 pFrame->maState.mnY      = aRect.top + nTopDeco;
210                 pFrame->maState.mnWidth  = aRect.right - aRect.left - nLeftDeco - nRightDeco;
211                 pFrame->maState.mnHeight = aRect.bottom - aRect.top - nTopDeco - nBottomDeco;
212             }
213         }
214         else
215         {
216             RECT aRect;
217             GetWindowRect( pFrame->mhWnd, &aRect );
218 
219             // to be consistent with Unix, the frame state is without(!) decoration
220             RECT aRect2 = aRect;
221 		    AdjustWindowRectEx( &aRect2, GetWindowStyle( pFrame->mhWnd ),
222 							FALSE,     GetWindowExStyle( pFrame->mhWnd ) );
223             long nTopDeco = abs( aRect.top - aRect2.top );
224             long nLeftDeco = abs( aRect.left - aRect2.left );
225             long nBottomDeco = abs( aRect.bottom - aRect2.bottom );
226             long nRightDeco = abs( aRect.right - aRect2.right );
227 
228             pFrame->maState.mnState &= ~(SAL_FRAMESTATE_MINIMIZED | SAL_FRAMESTATE_MAXIMIZED);
229             // subtract decoration
230             pFrame->maState.mnX      = aRect.left+nLeftDeco;
231             pFrame->maState.mnY      = aRect.top+nTopDeco;
232             pFrame->maState.mnWidth  = aRect.right-aRect.left-nLeftDeco-nRightDeco;
233             pFrame->maState.mnHeight = aRect.bottom-aRect.top-nTopDeco-nBottomDeco;
234             if ( bVisible )
235                 pFrame->mnShowState = SW_SHOWNORMAL;
236             pFrame->mbRestoreMaximize = FALSE;
237         }
238     }
239 }
240 
241 // -----------------------------------------------------------------------
242 
243 // if pParentRect is set, the workarea of the monitor that contains pParentRect is returned
244 void ImplSalGetWorkArea( HWND hWnd, RECT *pRect, const RECT *pParentRect )
245 {
246 	static int winVerChecked = 0;
247 	static int winVerOk = 0;
248 
249     // check if we or our parent is fullscreen, then the taskbar should be ignored
250     bool bIgnoreTaskbar = false;
251     WinSalFrame* pFrame = GetWindowPtr( hWnd );
252 	if( pFrame )
253     {
254 	    Window *pWin = pFrame->GetWindow();
255         while( pWin )
256         {
257             WorkWindow *pWorkWin = (pWin->GetType() == WINDOW_WORKWINDOW) ? (WorkWindow *) pWin : NULL;
258             if( pWorkWin && pWorkWin->ImplGetWindowImpl()->mbReallyVisible && pWorkWin->IsFullScreenMode() )
259             {
260                 bIgnoreTaskbar = true;
261                 break;
262             }
263             else
264                 pWin = pWin->ImplGetWindowImpl()->mpParent;
265         }
266     }
267 
268     if( !winVerChecked )
269 	{
270 		winVerChecked = 1;
271 		winVerOk = 1;
272 
273 		// multi monitor calls not available on Win95/NT
274         if ( aSalShlData.maVersionInfo.dwPlatformId == VER_PLATFORM_WIN32_NT )
275         {
276             if ( aSalShlData.maVersionInfo.dwMajorVersion <= 4 )
277                 winVerOk = 0;	// NT
278         }
279         else if( aSalShlData.maVersionInfo.dwPlatformId == VER_PLATFORM_WIN32_WINDOWS )
280         {
281             if ( aSalShlData.maVersionInfo.dwMajorVersion == 4 && aSalShlData.maVersionInfo.dwMinorVersion == 0 )
282                 winVerOk = 0;	// Win95
283         }
284 	}
285 
286     // calculates the work area taking multiple monitors into account
287     if( winVerOk )
288     {
289         static int nMonitors = GetSystemMetrics( SM_CMONITORS );
290         if( nMonitors == 1 )
291         {
292             if( bIgnoreTaskbar )
293             {
294                 pRect->left = pRect->top = 0;
295                 pRect->right   = GetSystemMetrics( SM_CXSCREEN );
296                 pRect->bottom  = GetSystemMetrics( SM_CYSCREEN );
297             }
298             else
299 	            SystemParametersInfo( SPI_GETWORKAREA, 0, pRect, 0 );
300         }
301         else
302         {
303             if( pParentRect != NULL )
304             {
305                 // return the size of the monitor where pParentRect lives
306                 HMONITOR hMonitor;
307                 MONITORINFO mi;
308 
309                 // get the nearest monitor to the passed rect.
310                 hMonitor = MonitorFromRect(pParentRect, MONITOR_DEFAULTTONEAREST);
311 
312                 // get the work area or entire monitor rect.
313                 mi.cbSize = sizeof(mi);
314                 GetMonitorInfo(hMonitor, &mi);
315                 if( !bIgnoreTaskbar )
316                     *pRect = mi.rcWork;
317                 else
318                     *pRect = mi.rcMonitor;
319             }
320             else
321             {
322                 // return the union of all monitors
323                 pRect->left = GetSystemMetrics( SM_XVIRTUALSCREEN );
324                 pRect->top = GetSystemMetrics( SM_YVIRTUALSCREEN );
325                 pRect->right = pRect->left + GetSystemMetrics( SM_CXVIRTUALSCREEN );
326                 pRect->bottom = pRect->top + GetSystemMetrics( SM_CYVIRTUALSCREEN );
327 
328                 // virtualscreen does not take taskbar into account, so use the corresponding
329                 // diffs between screen and workarea from the default screen
330                 // however, this is still not perfect: the taskbar might not be on the primary screen
331                 if( !bIgnoreTaskbar )
332                 {
333                     RECT wRect, scrRect;
334                     SystemParametersInfo( SPI_GETWORKAREA, 0, &wRect, 0 );
335                     scrRect.left = 0;
336                     scrRect.top = 0;
337                     scrRect.right = GetSystemMetrics( SM_CXSCREEN );
338                     scrRect.bottom = GetSystemMetrics( SM_CYSCREEN );
339 
340                     pRect->left += wRect.left;
341                     pRect->top += wRect.top;
342                     pRect->right -= scrRect.right - wRect.right;
343                     pRect->bottom -= scrRect.bottom - wRect.bottom;
344                 }
345             }
346         }
347     }
348     else
349     {
350         if( bIgnoreTaskbar )
351         {
352             pRect->left = pRect->top = 0;
353             pRect->right   = GetSystemMetrics( SM_CXSCREEN );
354             pRect->bottom  = GetSystemMetrics( SM_CYSCREEN );
355         }
356         else
357 	        SystemParametersInfo( SPI_GETWORKAREA, 0, pRect, 0 );
358     }
359 }
360 
361 // =======================================================================
362 
363 SalFrame* ImplSalCreateFrame( WinSalInstance* pInst,
364                               HWND hWndParent, sal_uLong nSalFrameStyle )
365 {
366     WinSalFrame*   pFrame = new WinSalFrame;
367     HWND        hWnd;
368     DWORD       nSysStyle = 0;
369     DWORD       nExSysStyle = 0;
370     sal_Bool        bSubFrame = FALSE;
371 
372     if( getenv( "SAL_SYNCHRONIZE" ) )   // no buffering of drawing commands
373         GdiSetBatchLimit( 1 );
374 
375     static int bLayeredAPI = -1;
376     if( bLayeredAPI == -1 )
377     {
378         bLayeredAPI = 0;
379         // check for W2k and XP
380         if ( aSalShlData.maVersionInfo.dwPlatformId == VER_PLATFORM_WIN32_NT && aSalShlData.maVersionInfo.dwMajorVersion >= 5 )
381         {
382             oslModule pLib = osl_loadAsciiModule( "user32", SAL_LOADMODULE_DEFAULT );
383             oslGenericFunction pFunc = NULL;
384             if( pLib )
385                 pFunc = osl_getAsciiFunctionSymbol( pLib, "SetLayeredWindowAttributes" );
386 
387             lpfnSetLayeredWindowAttributes = ( SetLayeredWindowAttributes_Proc_T ) pFunc;
388 
389             bLayeredAPI = pFunc ? 1 : 0;
390         }
391     }
392     static const char* pEnvTransparentFloats = getenv("SAL_TRANSPARENT_FLOATS" );
393 
394     // determine creation data
395     if ( nSalFrameStyle & (SAL_FRAME_STYLE_PLUG | SAL_FRAME_STYLE_SYSTEMCHILD) )
396     {
397         nSysStyle |= WS_CHILD;
398         if( nSalFrameStyle & SAL_FRAME_STYLE_SYSTEMCHILD )
399             nSysStyle |= WS_CLIPSIBLINGS;
400     }
401     else
402     {
403         // #i87402# commenting out WS_CLIPCHILDREN
404         // this breaks SAL_FRAME_STYLE_SYSTEMCHILD handling, which is not
405         // used currently. Probably SAL_FRAME_STYLE_SYSTEMCHILD should be
406         // removed again.
407 
408         // nSysStyle  |= WS_CLIPCHILDREN;
409         if ( hWndParent )
410         {
411             nSysStyle |= WS_POPUP;
412             bSubFrame = TRUE;
413             pFrame->mbNoIcon = TRUE;
414         }
415         else
416         {
417             // Only with WS_OVRLAPPED we get a useful default position/size
418             if ( (nSalFrameStyle & (SAL_FRAME_STYLE_SIZEABLE | SAL_FRAME_STYLE_MOVEABLE)) ==
419                  (SAL_FRAME_STYLE_SIZEABLE | SAL_FRAME_STYLE_MOVEABLE) )
420                 nSysStyle |= WS_OVERLAPPED;
421             else
422             {
423                 nSysStyle |= WS_POPUP;
424                 if ( !(nSalFrameStyle & SAL_FRAME_STYLE_MOVEABLE) )
425                     nExSysStyle |= WS_EX_TOOLWINDOW;    // avoid taskbar appearance, for eg splash screen
426             }
427         }
428 
429         if ( nSalFrameStyle & SAL_FRAME_STYLE_MOVEABLE )
430         {
431             pFrame->mbCaption = TRUE;
432             nSysStyle |= WS_SYSMENU | WS_CAPTION;
433             if ( !hWndParent )
434                 nSysStyle |= WS_SYSMENU | WS_MINIMIZEBOX;
435             else
436                 nExSysStyle |= WS_EX_DLGMODALFRAME;
437 
438             if ( nSalFrameStyle & SAL_FRAME_STYLE_SIZEABLE )
439             {
440                 pFrame->mbSizeBorder = TRUE;
441                 nSysStyle |= WS_THICKFRAME;
442                 if ( !hWndParent )
443                     nSysStyle |= WS_MAXIMIZEBOX;
444             }
445             else
446                 pFrame->mbFixBorder = TRUE;
447 
448             if ( nSalFrameStyle & SAL_FRAME_STYLE_DEFAULT )
449                 nExSysStyle |= WS_EX_APPWINDOW;
450         }
451         if( nSalFrameStyle & SAL_FRAME_STYLE_TOOLWINDOW
452             // #100656# toolwindows lead to bad alt-tab behaviour, if they have the focus
453             // you must press it twice to leave the application
454             // so toolwindows are only used for non sizeable windows
455             // which are typically small, so a small caption makes sense
456 
457             // #103578# looked too bad - above changes reverted
458             /* && !(nSalFrameStyle & SAL_FRAME_STYLE_SIZEABLE) */ )
459         {
460             pFrame->mbNoIcon = TRUE;
461             nExSysStyle |= WS_EX_TOOLWINDOW;
462             if ( pEnvTransparentFloats && bLayeredAPI == 1 /*&& !(nSalFrameStyle & SAL_FRAME_STYLE_MOVEABLE) */)
463                 nExSysStyle |= WS_EX_LAYERED;
464         }
465     }
466     if ( nSalFrameStyle & SAL_FRAME_STYLE_FLOAT )
467     {
468         nExSysStyle |= WS_EX_TOOLWINDOW;
469         pFrame->mbFloatWin = TRUE;
470 
471         if ( (bLayeredAPI == 1) && (pEnvTransparentFloats /* does not work remote! || (nSalFrameStyle & SAL_FRAME_STYLE_FLOAT_FOCUSABLE) */ )  )
472             nExSysStyle |= WS_EX_LAYERED;
473 
474     }
475     if( (nSalFrameStyle & SAL_FRAME_STYLE_TOOLTIP) || (nSalFrameStyle & SAL_FRAME_STYLE_FLOAT_FOCUSABLE) )
476         nExSysStyle |= WS_EX_TOPMOST;
477 
478     // init frame data
479     pFrame->mnStyle = nSalFrameStyle;
480 
481     // determine show style
482     pFrame->mnShowState = SW_SHOWNORMAL;
483     if ( (nSysStyle & (WS_POPUP | WS_MAXIMIZEBOX | WS_THICKFRAME)) == (WS_MAXIMIZEBOX | WS_THICKFRAME) )
484     {
485         if ( GetSystemMetrics( SM_CXSCREEN ) <= 1024 )
486             pFrame->mnShowState = SW_SHOWMAXIMIZED;
487         else
488         {
489             if ( nSalFrameStyle & SAL_FRAME_STYLE_DEFAULT )
490             {
491                 SalData* pSalData = GetSalData();
492                 pFrame->mnShowState = pSalData->mnCmdShow;
493                 if ( (pFrame->mnShowState != SW_SHOWMINIMIZED) &&
494                      (pFrame->mnShowState != SW_MINIMIZE) &&
495                      (pFrame->mnShowState != SW_SHOWMINNOACTIVE) )
496                 {
497                     if ( (pFrame->mnShowState == SW_SHOWMAXIMIZED) ||
498                          (pFrame->mnShowState == SW_MAXIMIZE) )
499                         pFrame->mbOverwriteState = FALSE;
500                     pFrame->mnShowState = SW_SHOWMAXIMIZED;
501                 }
502                 else
503                     pFrame->mbOverwriteState = FALSE;
504             }
505             else
506             {
507                 // Document Windows are also maximized, if the current Document Window
508                 // is also maximized
509                 HWND hWnd = GetForegroundWindow();
510                 if ( hWnd && IsMaximized( hWnd ) &&
511                      (GetWindowInstance( hWnd ) == pInst->mhInst) &&
512                      ((GetWindowStyle( hWnd ) & (WS_POPUP | WS_MAXIMIZEBOX | WS_THICKFRAME)) == (WS_MAXIMIZEBOX | WS_THICKFRAME)) )
513                     pFrame->mnShowState = SW_SHOWMAXIMIZED;
514             }
515         }
516     }
517 
518     // create frame
519     if( true/*aSalShlData.mbWNT*/ )
520     {
521         LPCWSTR pClassName;
522         if ( bSubFrame )
523         {
524             if ( nSalFrameStyle & (SAL_FRAME_STYLE_MOVEABLE|SAL_FRAME_STYLE_NOSHADOW) ) // check if shadow not wanted
525                 pClassName = SAL_SUBFRAME_CLASSNAMEW;
526             else
527                 pClassName = SAL_TMPSUBFRAME_CLASSNAMEW;    // undecorated floaters will get shadow on XP
528         }
529         else
530         {
531             if ( nSalFrameStyle & SAL_FRAME_STYLE_MOVEABLE )
532                 pClassName = SAL_FRAME_CLASSNAMEW;
533             else
534                 pClassName = SAL_TMPSUBFRAME_CLASSNAMEW;
535         }
536         hWnd = CreateWindowExW( nExSysStyle, pClassName, L"", nSysStyle,
537                                 CW_USEDEFAULT, 0, CW_USEDEFAULT, 0,
538                                 hWndParent, 0, pInst->mhInst, (void*)pFrame );
539         if( !hWnd )
540             ImplWriteLastError( GetLastError(), "CreateWindowEx" );
541 #if OSL_DEBUG_LEVEL > 1
542         // set transparency value
543         if( bLayeredAPI == 1 && GetWindowExStyle( hWnd ) & WS_EX_LAYERED )
544             lpfnSetLayeredWindowAttributes( hWnd, 0, 230, 0x00000002 /*LWA_ALPHA*/ );
545 #endif
546     }
547     if ( !hWnd )
548     {
549         delete pFrame;
550         return NULL;
551     }
552 
553     // If we have an Window with an Caption Bar and without
554     // an MaximizeBox, we change the SystemMenu
555     if ( (nSysStyle & (WS_CAPTION | WS_MAXIMIZEBOX)) == (WS_CAPTION) )
556     {
557         HMENU hSysMenu = GetSystemMenu( hWnd, FALSE );
558         if ( hSysMenu )
559         {
560             if ( !(nSysStyle & (WS_MINIMIZEBOX | WS_MAXIMIZEBOX)) )
561                 DeleteMenu( hSysMenu, SC_RESTORE, MF_BYCOMMAND );
562             else
563                 EnableMenuItem( hSysMenu, SC_RESTORE, MF_BYCOMMAND | MF_GRAYED | MF_DISABLED );
564             if ( !(nSysStyle & WS_MINIMIZEBOX) )
565                 DeleteMenu( hSysMenu, SC_MINIMIZE, MF_BYCOMMAND );
566             if ( !(nSysStyle & WS_MAXIMIZEBOX) )
567                 DeleteMenu( hSysMenu, SC_MAXIMIZE, MF_BYCOMMAND );
568             if ( !(nSysStyle & WS_THICKFRAME) )
569                 DeleteMenu( hSysMenu, SC_SIZE, MF_BYCOMMAND );
570         }
571     }
572     if ( (nSysStyle & WS_SYSMENU) && !(nSalFrameStyle & SAL_FRAME_STYLE_CLOSEABLE) )
573     {
574         HMENU hSysMenu = GetSystemMenu( hWnd, FALSE );
575         if ( hSysMenu )
576             EnableMenuItem( hSysMenu, SC_CLOSE, MF_BYCOMMAND | MF_GRAYED | MF_DISABLED );
577     }
578 
579     // reset input context
580     pFrame->mhDefIMEContext = ImmAssociateContext( hWnd, 0 );
581 
582     // determine output size and state
583     RECT aRect;
584     GetClientRect( hWnd, &aRect );
585     pFrame->mnWidth  = aRect.right;
586     pFrame->mnHeight = aRect.bottom;
587     ImplSaveFrameState( pFrame );
588     pFrame->mbDefPos = TRUE;
589 
590 	UpdateFrameGeometry( hWnd, pFrame );
591 
592     if( pFrame->mnShowState == SW_SHOWMAXIMIZED )
593 	{
594 		// #96084 set a useful internal window size because
595 		// the window will not be maximized (and the size updated) before show()
596 
597         SetMaximizedFrameGeometry( hWnd, pFrame );
598 	}
599 
600     return pFrame;
601 }
602 
603 // helper that only creates the HWND
604 // to allow for easy reparenting of system windows, (i.e. destroy and create new)
605 HWND ImplSalReCreateHWND( HWND hWndParent, HWND oldhWnd, sal_Bool bAsChild )
606 {
607     HINSTANCE hInstance = GetSalData()->mhInst;
608     ULONG nSysStyle     = GetWindowLong( oldhWnd, GWL_STYLE );
609     ULONG nExSysStyle   = GetWindowLong( oldhWnd, GWL_EXSTYLE );
610 
611     if( bAsChild )
612     {
613         nSysStyle = WS_CHILD;
614         nExSysStyle = 0;
615     }
616 
617     LPCWSTR pClassName = SAL_SUBFRAME_CLASSNAMEW;
618     HWND hWnd = CreateWindowExW( nExSysStyle, pClassName, L"", nSysStyle,
619                                 CW_USEDEFAULT, 0, CW_USEDEFAULT, 0,
620                                 hWndParent, 0, hInstance, (void*)GetWindowPtr( oldhWnd ) );
621     return hWnd;
622 }
623 
624 // =======================================================================
625 
626 // Uebersetzungstabelle von System-Keycodes in StarView-Keycodes
627 #define KEY_TAB_SIZE     146
628 
629 static sal_uInt16 aImplTranslateKeyTab[KEY_TAB_SIZE] =
630 {
631     // StarView-Code      System-Code                         Index
632     0,                    //                                  0
633     0,                    // VK_LBUTTON                       1
634     0,                    // VK_RBUTTON                       2
635     0,                    // VK_CANCEL                        3
636     0,                    // VK_MBUTTON                       4
637     0,                    //                                  5
638     0,                    //                                  6
639     0,                    //                                  7
640     KEY_BACKSPACE,        // VK_BACK                          8
641     KEY_TAB,              // VK_TAB                           9
642     0,                    //                                  10
643     0,                    //                                  11
644     0,                    // VK_CLEAR                         12
645     KEY_RETURN,           // VK_RETURN                        13
646     0,                    //                                  14
647     0,                    //                                  15
648     0,                    // VK_SHIFT                         16
649     0,                    // VK_CONTROL                       17
650     0,                    // VK_MENU                          18
651     0,                    // VK_PAUSE                         19
652     0,                    // VK_CAPITAL                       20
653     0,                    // VK_HANGUL                        21
654     0,                    //                                  22
655     0,                    //                                  23
656     0,                    //                                  24
657     KEY_HANGUL_HANJA,     // VK_HANJA                         25
658     0,                    //                                  26
659     KEY_ESCAPE,           // VK_ESCAPE                        27
660     0,                    //                                  28
661     0,                    //                                  29
662     0,                    //                                  30
663     0,                    //                                  31
664     KEY_SPACE,            // VK_SPACE                         32
665     KEY_PAGEUP,           // VK_PRIOR                         33
666     KEY_PAGEDOWN,         // VK_NEXT                          34
667     KEY_END,              // VK_END                           35
668     KEY_HOME,             // VK_HOME                          36
669     KEY_LEFT,             // VK_LEFT                          37
670     KEY_UP,               // VK_UP                            38
671     KEY_RIGHT,            // VK_RIGHT                         39
672     KEY_DOWN,             // VK_DOWN                          40
673     0,                    // VK_SELECT                        41
674     0,                    // VK_PRINT                         42
675     0,                    // VK_EXECUTE                       43
676     0,                    // VK_SNAPSHOT                      44
677     KEY_INSERT,           // VK_INSERT                        45
678     KEY_DELETE,           // VK_DELETE                        46
679     KEY_HELP,             // VK_HELP                          47
680     KEY_0,                //                                  48
681     KEY_1,                //                                  49
682     KEY_2,                //                                  50
683     KEY_3,                //                                  51
684     KEY_4,                //                                  52
685     KEY_5,                //                                  53
686     KEY_6,                //                                  54
687     KEY_7,                //                                  55
688     KEY_8,                //                                  56
689     KEY_9,                //                                  57
690     0,                    //                                  58
691     0,                    //                                  59
692     0,                    //                                  60
693     0,                    //                                  61
694     0,                    //                                  62
695     0,                    //                                  63
696     0,                    //                                  64
697     KEY_A,                //                                  65
698     KEY_B,                //                                  66
699     KEY_C,                //                                  67
700     KEY_D,                //                                  68
701     KEY_E,                //                                  69
702     KEY_F,                //                                  70
703     KEY_G,                //                                  71
704     KEY_H,                //                                  72
705     KEY_I,                //                                  73
706     KEY_J,                //                                  74
707     KEY_K,                //                                  75
708     KEY_L,                //                                  76
709     KEY_M,                //                                  77
710     KEY_N,                //                                  78
711     KEY_O,                //                                  79
712     KEY_P,                //                                  80
713     KEY_Q,                //                                  81
714     KEY_R,                //                                  82
715     KEY_S,                //                                  83
716     KEY_T,                //                                  84
717     KEY_U,                //                                  85
718     KEY_V,                //                                  86
719     KEY_W,                //                                  87
720     KEY_X,                //                                  88
721     KEY_Y,                //                                  89
722     KEY_Z,                //                                  90
723     0,                    // VK_LWIN                          91
724     0,                    // VK_RWIN                          92
725     KEY_CONTEXTMENU,      // VK_APPS                          93
726     0,                    //                                  94
727     0,                    //                                  95
728     KEY_0,                // VK_NUMPAD0                       96
729     KEY_1,                // VK_NUMPAD1                       97
730     KEY_2,                // VK_NUMPAD2                       98
731     KEY_3,                // VK_NUMPAD3                       99
732     KEY_4,                // VK_NUMPAD4                      100
733     KEY_5,                // VK_NUMPAD5                      101
734     KEY_6,                // VK_NUMPAD6                      102
735     KEY_7,                // VK_NUMPAD7                      103
736     KEY_8,                // VK_NUMPAD8                      104
737     KEY_9,                // VK_NUMPAD9                      105
738     KEY_MULTIPLY,         // VK_MULTIPLY                     106
739     KEY_ADD,              // VK_ADD                          107
740     KEY_DECIMAL,          // VK_SEPARATOR                    108
741     KEY_SUBTRACT,         // VK_SUBTRACT                     109
742     KEY_DECIMAL,          // VK_DECIMAL                      110
743     KEY_DIVIDE,           // VK_DIVIDE                       111
744     KEY_F1,               // VK_F1                           112
745     KEY_F2,               // VK_F2                           113
746     KEY_F3,               // VK_F3                           114
747     KEY_F4,               // VK_F4                           115
748     KEY_F5,               // VK_F5                           116
749     KEY_F6,               // VK_F6                           117
750     KEY_F7,               // VK_F7                           118
751     KEY_F8,               // VK_F8                           119
752     KEY_F9,               // VK_F9                           120
753     KEY_F10,              // VK_F10                          121
754     KEY_F11,              // VK_F11                          122
755     KEY_F12,              // VK_F12                          123
756     KEY_F13,              // VK_F13                          124
757     KEY_F14,              // VK_F14                          125
758     KEY_F15,              // VK_F15                          126
759     KEY_F16,              // VK_F16                          127
760     KEY_F17,              // VK_F17                          128
761     KEY_F18,              // VK_F18                          129
762     KEY_F19,              // VK_F19                          130
763     KEY_F20,              // VK_F20                          131
764     KEY_F21,              // VK_F21                          132
765     KEY_F22,              // VK_F22                          133
766     KEY_F23,              // VK_F23                          134
767     KEY_F24,              // VK_F24                          135
768     0,                    //                                 136
769     0,                    //                                 137
770     0,                    //                                 138
771     0,                    //                                 139
772     0,                    //                                 140
773     0,                    //                                 141
774     0,                    //                                 142
775     0,                    //                                 143
776     0,                    // NUMLOCK                         144
777     0                     // SCROLLLOCK                      145
778 };
779 
780 // =======================================================================
781 
782 static UINT ImplSalGetWheelScrollLines()
783 {
784     UINT nScrLines = 0;
785     HWND hWndMsWheel = WIN_FindWindow( MSH_WHEELMODULE_CLASS, MSH_WHEELMODULE_TITLE );
786     if ( hWndMsWheel )
787     {
788         UINT nGetScrollLinesMsgId = RegisterWindowMessage( MSH_SCROLL_LINES );
789         nScrLines = (UINT)ImplSendMessage( hWndMsWheel, nGetScrollLinesMsgId, 0, 0 );
790     }
791 
792     if ( !nScrLines )
793         if( !SystemParametersInfo( SPI_GETWHEELSCROLLLINES, 0, &nScrLines, 0 ) )
794             nScrLines = 0 ;
795 
796     if ( !nScrLines )
797         nScrLines = 3;
798 
799     return nScrLines;
800 }
801 
802 // -----------------------------------------------------------------------
803 
804 static UINT ImplSalGetWheelScrollChars()
805 {
806     UINT nScrChars = 0;
807     if( !SystemParametersInfo( SPI_GETWHEELSCROLLCHARS, 0, &nScrChars, 0 ) )
808     {
809         // Depending on Windows version, use proper default or 1 (when
810         // driver emulates hscroll)
811         if( VER_PLATFORM_WIN32_NT == aSalShlData.maVersionInfo.dwPlatformId &&
812             aSalShlData.maVersionInfo.dwMajorVersion < 6 )
813         {
814             // Windows 2000 & WinXP : emulating driver, use step size
815             // of 1
816             return 1;
817         }
818         else
819         {
820             // Longhorn or above: use proper default value of 3
821             return 3;
822         }
823     }
824 
825     // system settings successfully read
826     return nScrChars;
827 }
828 
829 // -----------------------------------------------------------------------
830 
831 static void ImplSalAddBorder( const WinSalFrame* pFrame, int& width, int& height )
832 {
833     // transform client size into window size
834     RECT    aWinRect;
835     aWinRect.left   = 0;
836     aWinRect.right  = width-1;
837     aWinRect.top    = 0;
838     aWinRect.bottom = height-1;
839     AdjustWindowRectEx( &aWinRect, GetWindowStyle( pFrame->mhWnd ),
840                         FALSE,     GetWindowExStyle( pFrame->mhWnd ) );
841     width  = aWinRect.right - aWinRect.left + 1;
842     height = aWinRect.bottom - aWinRect.top + 1;
843 }
844 
845 // -----------------------------------------------------------------------
846 
847 static void ImplSalCalcFullScreenSize( const WinSalFrame* pFrame,
848                                        int& rX, int& rY, int& rDX, int& rDY )
849 {
850     // set window to screen size
851     int nFrameX;
852     int nFrameY;
853     int nCaptionY;
854 	int nScreenX = 0;
855 	int nScreenY = 0;
856     int nScreenDX = 0;
857     int nScreenDY = 0;
858 
859     if ( pFrame->mbSizeBorder )
860     {
861         nFrameX = GetSystemMetrics( SM_CXSIZEFRAME );
862         nFrameY = GetSystemMetrics( SM_CYSIZEFRAME );
863     }
864     else if ( pFrame->mbFixBorder )
865     {
866         nFrameX = GetSystemMetrics( SM_CXFIXEDFRAME );
867         nFrameY = GetSystemMetrics( SM_CYFIXEDFRAME );
868     }
869     else if ( pFrame->mbBorder )
870     {
871         nFrameX = GetSystemMetrics( SM_CXBORDER );
872         nFrameY = GetSystemMetrics( SM_CYBORDER );
873     }
874     else
875     {
876         nFrameX = 0;
877         nFrameY = 0;
878     }
879     if ( pFrame->mbCaption )
880         nCaptionY = GetSystemMetrics( SM_CYCAPTION );
881     else
882         nCaptionY = 0;
883 
884 	try
885 	{
886 	    uno::Reference< XMultiServiceFactory > xFactory( ::comphelper::getProcessServiceFactory(), UNO_QUERY_THROW );
887 	    uno::Reference< XIndexAccess > xMultiMon( xFactory->createInstance(OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.awt.DisplayAccess" ) ) ), UNO_QUERY_THROW );
888         sal_Int32 nMonitors = xMultiMon->getCount();
889 		if( (pFrame->mnDisplay >= 0) && (pFrame->mnDisplay < nMonitors) )
890 		{
891 		    uno::Reference< XPropertySet > xMonitor( xMultiMon->getByIndex( pFrame->mnDisplay ), UNO_QUERY_THROW );
892 			com::sun::star::awt::Rectangle aRect;
893 			if( xMonitor->getPropertyValue( OUString( RTL_CONSTASCII_USTRINGPARAM( "ScreenArea" ) ) ) >>= aRect )
894 			{
895 				nScreenX = aRect.X;
896 				nScreenY = aRect.Y;
897 				nScreenDX = aRect.Width+1;  // difference between java/awt convention and vcl
898 				nScreenDY = aRect.Height+1; // difference between java/awt convention and vcl
899 			}
900 		}
901 		else
902 		{
903             Rectangle aCombined;
904             uno::Reference< XPropertySet > xMonitor( xMultiMon->getByIndex( 0 ), UNO_QUERY_THROW );
905 			com::sun::star::awt::Rectangle aRect;
906 			if( xMonitor->getPropertyValue( OUString( RTL_CONSTASCII_USTRINGPARAM( "ScreenArea" ) ) ) >>= aRect )
907 			{
908                 aCombined.Left()   = aRect.X;
909                 aCombined.Top()    = aRect.Y;
910                 aCombined.Right()  = aRect.X + aRect.Width;
911                 aCombined.Bottom() = aRect.Y + aRect.Height;
912                 for( sal_Int32 i = 1 ; i < nMonitors ; i++ )
913                 {
914                     xMonitor = uno::Reference< XPropertySet >( xMultiMon->getByIndex(i), UNO_QUERY_THROW );
915                     if( xMonitor->getPropertyValue( OUString( RTL_CONSTASCII_USTRINGPARAM( "ScreenArea" ) ) ) >>= aRect )
916                     {
917                         aCombined.Union( Rectangle( aRect.X, aRect.Y, aRect.X+aRect.Width, aRect.Y+aRect.Height ) );
918                     }
919                 }
920             }
921             nScreenX  = aCombined.Left();
922             nScreenY  = aCombined.Top();
923             nScreenDX = aCombined.GetWidth();
924             nScreenDY = aCombined.GetHeight();
925 		}
926 	}
927 	catch( Exception& )
928 	{
929 	}
930 
931 	if( !nScreenDX || !nScreenDY )
932 	{
933 	    nScreenDX   = GetSystemMetrics( SM_CXSCREEN );
934 		nScreenDY   = GetSystemMetrics( SM_CYSCREEN );
935 	}
936 
937     rX  = nScreenX -nFrameX;
938     rY  = nScreenY -(nFrameY+nCaptionY);
939     rDX = nScreenDX+(nFrameX*2);
940     rDY = nScreenDY+(nFrameY*2)+nCaptionY;
941 }
942 
943 // -----------------------------------------------------------------------
944 
945 static void ImplSalFrameFullScreenPos( WinSalFrame* pFrame, sal_Bool bAlways = FALSE )
946 {
947     if ( bAlways || !IsIconic( pFrame->mhWnd ) )
948     {
949         // set window to screen size
950         int nX;
951         int nY;
952         int nWidth;
953         int nHeight;
954         ImplSalCalcFullScreenSize( pFrame, nX, nY, nWidth, nHeight );
955         SetWindowPos( pFrame->mhWnd, 0,
956                       nX, nY, nWidth, nHeight,
957                       SWP_NOZORDER | SWP_NOACTIVATE );
958     }
959 }
960 
961 // -----------------------------------------------------------------------
962 
963 WinSalFrame::WinSalFrame()
964 {
965     SalData* pSalData = GetSalData();
966 
967     mhWnd               = 0;
968     mhCursor            = LoadCursor( 0, IDC_ARROW );
969     mhDefIMEContext     = 0;
970     mpGraphics          = NULL;
971     mpGraphics2         = NULL;
972     mnShowState         = SW_SHOWNORMAL;
973     mnWidth             = 0;
974     mnHeight            = 0;
975     mnMinWidth          = 0;
976     mnMinHeight         = 0;
977     mnMaxWidth          = SHRT_MAX;
978     mnMaxHeight         = SHRT_MAX;
979     mnInputLang         = 0;
980     mnInputCodePage     = 0;
981     mbGraphics          = FALSE;
982     mbCaption           = FALSE;
983     mbBorder            = FALSE;
984     mbFixBorder         = FALSE;
985     mbSizeBorder        = FALSE;
986     mbFullScreen        = FALSE;
987     mbPresentation      = FALSE;
988     mbInShow            = FALSE;
989     mbRestoreMaximize   = FALSE;
990     mbInMoveMsg         = FALSE;
991     mbInSizeMsg         = FALSE;
992     mbFullScreenToolWin = FALSE;
993     mbDefPos            = TRUE;
994     mbOverwriteState    = TRUE;
995     mbIME               = FALSE;
996     mbHandleIME         = FALSE;
997     mbSpezIME           = FALSE;
998     mbAtCursorIME       = FALSE;
999     mbCandidateMode     = FALSE;
1000     mbFloatWin          = FALSE;
1001     mbNoIcon            = FALSE;
1002     mSelectedhMenu      = 0;
1003     mLastActivatedhMenu = 0;
1004     mpClipRgnData       = NULL;
1005     mbFirstClipRect     = TRUE;
1006     mpNextClipRect      = NULL;
1007 	mnDisplay			= 0;
1008 
1009     memset( &maState, 0, sizeof( SalFrameState ) );
1010     maSysData.nSize     = sizeof( SystemEnvData );
1011 
1012     memset( &maGeometry, 0, sizeof( maGeometry ) );
1013 
1014     // Daten ermitteln, wenn erster Frame angelegt wird
1015     if ( !pSalData->mpFirstFrame )
1016     {
1017         if ( !aSalShlData.mnWheelMsgId )
1018             aSalShlData.mnWheelMsgId = RegisterWindowMessage( MSH_MOUSEWHEEL );
1019         if ( !aSalShlData.mnWheelScrollLines )
1020             aSalShlData.mnWheelScrollLines = ImplSalGetWheelScrollLines();
1021         if ( !aSalShlData.mnWheelScrollChars )
1022             aSalShlData.mnWheelScrollChars = ImplSalGetWheelScrollChars();
1023     }
1024 
1025     // insert frame in framelist
1026     mpNextFrame = pSalData->mpFirstFrame;
1027     pSalData->mpFirstFrame = this;
1028 }
1029 
1030 // -----------------------------------------------------------------------
1031 void WinSalFrame::updateScreenNumber()
1032 {
1033     if( mnDisplay == -1 ) // spans all monitors
1034         return;
1035     WinSalSystem* pSys = static_cast<WinSalSystem*>(ImplGetSalSystem());
1036     if( pSys )
1037     {
1038         const std::vector<WinSalSystem::DisplayMonitor>& rMonitors =
1039             pSys->getMonitors();
1040         Point aPoint( maGeometry.nX, maGeometry.nY );
1041         size_t nMon = rMonitors.size();
1042         for( size_t i = 0; i < nMon; i++ )
1043         {
1044             if( rMonitors[i].m_aArea.IsInside( aPoint ) )
1045             {
1046                 mnDisplay = static_cast<sal_Int32>(i);
1047                 maGeometry.nScreenNumber = static_cast<unsigned int>(i);
1048             }
1049         }
1050     }
1051 }
1052 
1053 // -----------------------------------------------------------------------
1054 
1055 WinSalFrame::~WinSalFrame()
1056 {
1057     SalData* pSalData = GetSalData();
1058 
1059     if( mpClipRgnData )
1060         delete [] (BYTE*)mpClipRgnData;
1061 
1062     // remove frame from framelist
1063     WinSalFrame** ppFrame = &pSalData->mpFirstFrame;
1064     for(; (*ppFrame != this) && *ppFrame; ppFrame = &(*ppFrame)->mpNextFrame );
1065     if( *ppFrame )
1066         *ppFrame = mpNextFrame;
1067     mpNextFrame = NULL;
1068 
1069     // Release Cache DC
1070     if ( mpGraphics2 &&
1071          mpGraphics2->getHDC() )
1072         ReleaseGraphics( mpGraphics2 );
1073 
1074     // destroy saved DC
1075     if ( mpGraphics )
1076     {
1077         if ( mpGraphics->mhDefPal )
1078             SelectPalette( mpGraphics->getHDC(), mpGraphics->mhDefPal, TRUE );
1079         ImplSalDeInitGraphics( mpGraphics );
1080         ReleaseDC( mhWnd, mpGraphics->getHDC() );
1081         delete mpGraphics;
1082         mpGraphics = NULL;
1083     }
1084 
1085     if ( mhWnd )
1086     {
1087         // reset mouse leave data
1088         if ( pSalData->mhWantLeaveMsg == mhWnd )
1089         {
1090             pSalData->mhWantLeaveMsg = 0;
1091             if ( pSalData->mpMouseLeaveTimer )
1092             {
1093                 delete pSalData->mpMouseLeaveTimer;
1094                 pSalData->mpMouseLeaveTimer = NULL;
1095             }
1096         }
1097 
1098         // destroy system frame
1099         if ( !DestroyWindow( mhWnd ) )
1100             SetWindowPtr( mhWnd, 0 );
1101 
1102         mhWnd = 0;
1103     }
1104 }
1105 
1106 // -----------------------------------------------------------------------
1107 
1108 SalGraphics* WinSalFrame::GetGraphics()
1109 {
1110     if ( mbGraphics )
1111         return NULL;
1112 
1113     // Other threads get an own DC, because Windows modify in the
1114     // other case our DC (changing clip region), when they send a
1115     // WM_ERASEBACKGROUND message
1116     SalData* pSalData = GetSalData();
1117     if ( pSalData->mnAppThreadId != GetCurrentThreadId() )
1118     {
1119         // We use only three CacheDC's for all threads, because W9x is limited
1120         // to max. 5 Cache DC's per thread
1121         if ( pSalData->mnCacheDCInUse >= 3 )
1122             return NULL;
1123 
1124         if ( !mpGraphics2 )
1125         {
1126             mpGraphics2 = new WinSalGraphics;
1127             mpGraphics2->setHDC(0);
1128             mpGraphics2->mhWnd       = mhWnd;
1129             mpGraphics2->mbPrinter   = FALSE;
1130             mpGraphics2->mbVirDev    = FALSE;
1131             mpGraphics2->mbWindow    = TRUE;
1132             mpGraphics2->mbScreen    = TRUE;
1133         }
1134 
1135         HDC hDC = (HDC)ImplSendMessage( pSalData->mpFirstInstance->mhComWnd,
1136                                         SAL_MSG_GETDC,
1137                                         (WPARAM)mhWnd, 0 );
1138         if ( hDC )
1139         {
1140             mpGraphics2->setHDC(hDC);
1141             if ( pSalData->mhDitherPal )
1142             {
1143                 mpGraphics2->mhDefPal = SelectPalette( hDC, pSalData->mhDitherPal, TRUE );
1144                 RealizePalette( hDC );
1145             }
1146             ImplSalInitGraphics( mpGraphics2 );
1147             mbGraphics = TRUE;
1148 
1149             pSalData->mnCacheDCInUse++;
1150             return mpGraphics2;
1151         }
1152         else
1153             return NULL;
1154     }
1155     else
1156     {
1157         if ( !mpGraphics )
1158         {
1159             HDC hDC = GetDC( mhWnd );
1160             if ( hDC )
1161             {
1162                 mpGraphics = new WinSalGraphics;
1163                 mpGraphics->setHDC(hDC);
1164                 mpGraphics->mhWnd     = mhWnd;
1165                 mpGraphics->mbPrinter = FALSE;
1166                 mpGraphics->mbVirDev  = FALSE;
1167                 mpGraphics->mbWindow  = TRUE;
1168                 mpGraphics->mbScreen  = TRUE;
1169                 if ( pSalData->mhDitherPal )
1170                 {
1171                     mpGraphics->mhDefPal = SelectPalette( hDC, pSalData->mhDitherPal, TRUE );
1172                     RealizePalette( hDC );
1173                 }
1174                 ImplSalInitGraphics( mpGraphics );
1175                 mbGraphics = TRUE;
1176             }
1177         }
1178         else
1179             mbGraphics = TRUE;
1180 
1181         return mpGraphics;
1182     }
1183 }
1184 
1185 // -----------------------------------------------------------------------
1186 
1187 void WinSalFrame::ReleaseGraphics( SalGraphics* pGraphics )
1188 {
1189     if ( mpGraphics2 == pGraphics )
1190     {
1191         if ( mpGraphics2->getHDC() )
1192         {
1193             SalData* pSalData = GetSalData();
1194             if ( mpGraphics2->mhDefPal )
1195                 SelectPalette( mpGraphics2->getHDC(), mpGraphics2->mhDefPal, TRUE );
1196             ImplSalDeInitGraphics( mpGraphics2 );
1197             ImplSendMessage( pSalData->mpFirstInstance->mhComWnd,
1198                              SAL_MSG_RELEASEDC,
1199                              (WPARAM)mhWnd,
1200                              (LPARAM)mpGraphics2->getHDC() );
1201             mpGraphics2->setHDC(0);
1202             pSalData->mnCacheDCInUse--;
1203         }
1204     }
1205 
1206     mbGraphics = FALSE;
1207 }
1208 
1209 // -----------------------------------------------------------------------
1210 
1211 sal_Bool WinSalFrame::PostEvent( void* pData )
1212 {
1213     return (sal_Bool)ImplPostMessage( mhWnd, SAL_MSG_USEREVENT, 0, (LPARAM)pData );
1214 }
1215 
1216 // -----------------------------------------------------------------------
1217 
1218 void WinSalFrame::SetTitle( const XubString& rTitle )
1219 {
1220     DBG_ASSERT( sizeof( WCHAR ) == sizeof( xub_Unicode ), "WinSalFrame::SetTitle(): WCHAR != sal_Unicode" );
1221 
1222     if ( !SetWindowTextW( mhWnd, reinterpret_cast<LPCWSTR>(rTitle.GetBuffer()) ) )
1223     {
1224         ByteString aAnsiTitle = ImplSalGetWinAnsiString( rTitle );
1225         SetWindowTextA( mhWnd, aAnsiTitle.GetBuffer() );
1226     }
1227 }
1228 
1229 // -----------------------------------------------------------------------
1230 
1231 void WinSalFrame::SetIcon( sal_uInt16 nIcon )
1232 {
1233     // If we have a window without an Icon (for example a dialog), ignore this call
1234     if ( mbNoIcon )
1235         return;
1236 
1237     // 0 means default (class) icon
1238     HICON hIcon = NULL, hSmIcon = NULL;
1239     if ( !nIcon )
1240         nIcon = 1;
1241 
1242     ImplLoadSalIcon( nIcon, hIcon, hSmIcon );
1243 
1244     DBG_ASSERT( hIcon ,   "WinSalFrame::SetIcon(): Could not load large icon !" );
1245     DBG_ASSERT( hSmIcon , "WinSalFrame::SetIcon(): Could not load small icon !" );
1246 
1247     ImplSendMessage( mhWnd, WM_SETICON, ICON_BIG, (LPARAM)hIcon );
1248     ImplSendMessage( mhWnd, WM_SETICON, ICON_SMALL, (LPARAM)hSmIcon );
1249 }
1250 
1251 // -----------------------------------------------------------------------
1252 
1253 void WinSalFrame::SetMenu( SalMenu* pSalMenu )
1254 {
1255     WinSalMenu* pWMenu = static_cast<WinSalMenu*>(pSalMenu);
1256     if( pSalMenu && pWMenu->mbMenuBar )
1257         ::SetMenu( mhWnd, pWMenu->mhMenu );
1258 }
1259 
1260 void WinSalFrame::DrawMenuBar()
1261 {
1262     ::DrawMenuBar( mhWnd );
1263 }
1264 
1265 // -----------------------------------------------------------------------
1266 HWND ImplGetParentHwnd( HWND hWnd )
1267 {
1268     WinSalFrame* pFrame = GetWindowPtr( hWnd );
1269 	if( !pFrame || !pFrame->GetWindow())
1270 		return ::GetParent( hWnd );
1271 	Window *pRealParent = pFrame->GetWindow()->ImplGetWindowImpl()->mpRealParent;
1272 	if( pRealParent )
1273 		return static_cast<WinSalFrame*>(pRealParent->ImplGetWindowImpl()->mpFrame)->mhWnd;
1274 	else
1275 		return ::GetParent( hWnd );
1276 
1277 }
1278 
1279 // -----------------------------------------------------------------------
1280 
1281 SalFrame* WinSalFrame::GetParent() const
1282 {
1283     return GetWindowPtr( ImplGetParentHwnd( mhWnd ) );
1284 }
1285 
1286 // -----------------------------------------------------------------------
1287 
1288 static void ImplSalShow( HWND hWnd, sal_Bool bVisible, sal_Bool bNoActivate )
1289 {
1290     WinSalFrame* pFrame = GetWindowPtr( hWnd );
1291     if ( !pFrame )
1292         return;
1293 
1294     if ( bVisible )
1295     {
1296         pFrame->mbDefPos = FALSE;
1297         pFrame->mbOverwriteState = TRUE;
1298         pFrame->mbInShow = TRUE;
1299 
1300         // #i4715, save position
1301         RECT aRectPreMatrox, aRectPostMatrox;
1302         GetWindowRect( hWnd, &aRectPreMatrox );
1303 
1304         vcl::DeletionListener aDogTag( pFrame );
1305         if( bNoActivate )
1306             ShowWindow( hWnd, SW_SHOWNOACTIVATE );
1307         else
1308             ShowWindow( hWnd, pFrame->mnShowState );
1309         if( aDogTag.isDeleted() )
1310             return;
1311 
1312         if ( aSalShlData.mbWXP && pFrame->mbFloatWin && !(pFrame->mnStyle & SAL_FRAME_STYLE_NOSHADOW))
1313         {
1314             // erase the window immediately to improve XP shadow effect
1315             // otherwise the shadow may appears long time before the rest of the window
1316             // especially when accessibility is on
1317             HDC dc = GetDC( hWnd );
1318             RECT aRect;
1319             GetClientRect( hWnd, &aRect );
1320             FillRect( dc, &aRect, (HBRUSH) (COLOR_MENU+1) ); // choose the menucolor, because its mostly noticeable for menues
1321             ReleaseDC( hWnd, dc );
1322         }
1323 
1324         // #i4715, matrox centerpopup might have changed our position
1325         // reposition popups without caption (menues, dropdowns, tooltips)
1326         GetWindowRect( hWnd, &aRectPostMatrox );
1327         if( (GetWindowStyle( hWnd ) & WS_POPUP) &&
1328             !pFrame->mbCaption &&
1329             (aRectPreMatrox.left != aRectPostMatrox.left || aRectPreMatrox.top != aRectPostMatrox.top) )
1330             SetWindowPos( hWnd, 0, aRectPreMatrox.left, aRectPreMatrox.top, 0, 0, SWP_NOZORDER | SWP_NOACTIVATE | SWP_NOSIZE  );
1331 
1332         if( aDogTag.isDeleted() )
1333             return;
1334 		Window *pClientWin = pFrame->GetWindow()->ImplGetClientWindow();
1335         if ( pFrame->mbFloatWin || ( pClientWin && (pClientWin->GetStyle() & WB_SYSTEMFLOATWIN) ) )
1336             pFrame->mnShowState = SW_SHOWNOACTIVATE;
1337         else
1338             pFrame->mnShowState = SW_SHOW;
1339         // Damit Taskleiste unter W98 auch gleich ausgeblendet wird
1340         if ( pFrame->mbPresentation )
1341         {
1342             HWND hWndParent = ::GetParent( hWnd );
1343             if ( hWndParent )
1344                 SetForegroundWindow( hWndParent );
1345             SetForegroundWindow( hWnd );
1346         }
1347 
1348         pFrame->mbInShow = FALSE;
1349         pFrame->updateScreenNumber();
1350 
1351         // Direct Paint only, if we get the SolarMutx
1352         if ( ImplSalYieldMutexTryToAcquire() )
1353         {
1354             UpdateWindow( hWnd );
1355             ImplSalYieldMutexRelease();
1356         }
1357     }
1358     else
1359     {
1360         // See also Bug #91813# and #68467#
1361         if ( pFrame->mbFullScreen &&
1362              pFrame->mbPresentation &&
1363              (aSalShlData.mnVersion < 500) &&
1364              !::GetParent( hWnd ) )
1365         {
1366             // Damit im Impress-Player in der Taskleiste nicht durch
1367             // einen Windows-Fehler hin- und wieder mal ein leerer
1368             // Button stehen bleibt, muessen wir hier die Taskleiste
1369             // etwas austricksen. Denn wenn wir im FullScreenMode sind
1370             // und das Fenster hiden kommt Windows anscheinend etwas aus
1371             // dem tritt und somit minimieren wir das Fenster damit es
1372             // nicht flackert
1373             ANIMATIONINFO aInfo;
1374             aInfo.cbSize = sizeof( aInfo );
1375             SystemParametersInfo( SPI_GETANIMATION, 0, &aInfo, 0 );
1376             if ( aInfo.iMinAnimate )
1377             {
1378                 int nOldAni = aInfo.iMinAnimate;
1379                 aInfo.iMinAnimate = 0;
1380                 SystemParametersInfo( SPI_SETANIMATION, 0, &aInfo, 0 );
1381                 ShowWindow( pFrame->mhWnd, SW_SHOWMINNOACTIVE );
1382                 aInfo.iMinAnimate = nOldAni;
1383                 SystemParametersInfo( SPI_SETANIMATION, 0, &aInfo, 0 );
1384             }
1385             else
1386                 ShowWindow( hWnd, SW_SHOWMINNOACTIVE );
1387             ShowWindow( hWnd, SW_HIDE );
1388         }
1389         else
1390             ShowWindow( hWnd, SW_HIDE );
1391     }
1392 }
1393 
1394 // -----------------------------------------------------------------------
1395 
1396 
1397 void WinSalFrame::SetExtendedFrameStyle( SalExtStyle )
1398 {
1399 }
1400 
1401 // -----------------------------------------------------------------------
1402 
1403 void WinSalFrame::Show( sal_Bool bVisible, sal_Bool bNoActivate )
1404 {
1405     // Post this Message to the window, because this only works
1406     // in the thread of the window, which has create this window.
1407     // We post this message to avoid deadlocks
1408     if ( GetSalData()->mnAppThreadId != GetCurrentThreadId() )
1409         ImplPostMessage( mhWnd, SAL_MSG_SHOW, bVisible, bNoActivate );
1410     else
1411         ImplSalShow( mhWnd, bVisible, bNoActivate );
1412 }
1413 
1414 // -----------------------------------------------------------------------
1415 
1416 void WinSalFrame::Enable( sal_Bool bEnable )
1417 {
1418     EnableWindow( mhWnd, bEnable );
1419 }
1420 
1421 // -----------------------------------------------------------------------
1422 
1423 void WinSalFrame::SetMinClientSize( long nWidth, long nHeight )
1424 {
1425     mnMinWidth  = nWidth;
1426     mnMinHeight = nHeight;
1427 }
1428 
1429 void WinSalFrame::SetMaxClientSize( long nWidth, long nHeight )
1430 {
1431     mnMaxWidth  = nWidth;
1432     mnMaxHeight = nHeight;
1433 }
1434 
1435 // -----------------------------------------------------------------------
1436 
1437 void WinSalFrame::SetPosSize( long nX, long nY, long nWidth, long nHeight,
1438                                                    sal_uInt16 nFlags )
1439 {
1440     sal_Bool bVisible = (GetWindowStyle( mhWnd ) & WS_VISIBLE) != 0;
1441     if ( !bVisible )
1442     {
1443 		Window *pClientWin = GetWindow()->ImplGetClientWindow();
1444         if ( mbFloatWin || ( pClientWin && (pClientWin->GetStyle() & WB_SYSTEMFLOATWIN) ) )
1445                 mnShowState = SW_SHOWNOACTIVATE;
1446         else
1447                 mnShowState = SW_SHOWNORMAL;
1448     }
1449     else
1450     {
1451         if ( IsIconic( mhWnd ) || IsZoomed( mhWnd ) )
1452                 ShowWindow( mhWnd, SW_RESTORE );
1453     }
1454 
1455     sal_uInt16 nEvent = 0;
1456     UINT    nPosSize = 0;
1457     RECT    aClientRect, aWindowRect;
1458     GetClientRect( mhWnd, &aClientRect );   // x,y always 0,0, but width and height without border
1459     GetWindowRect( mhWnd, &aWindowRect );   // x,y in screen coordinates, width and height with border
1460 
1461     if ( !(nFlags & (SAL_FRAME_POSSIZE_X | SAL_FRAME_POSSIZE_Y)) )
1462         nPosSize |= SWP_NOMOVE;
1463     else
1464     {
1465         //DBG_ASSERT( nX && nY, " Windowposition of (0,0) requested!" );
1466         nEvent = SALEVENT_MOVE;
1467     }
1468     if ( !(nFlags & (SAL_FRAME_POSSIZE_WIDTH | SAL_FRAME_POSSIZE_HEIGHT)) )
1469         nPosSize |= SWP_NOSIZE;
1470     else
1471         nEvent = (nEvent == SALEVENT_MOVE) ? SALEVENT_MOVERESIZE : SALEVENT_RESIZE;
1472 
1473     if ( !(nFlags & SAL_FRAME_POSSIZE_X) )
1474         nX = aWindowRect.left;
1475     if ( !(nFlags & SAL_FRAME_POSSIZE_Y) )
1476         nY = aWindowRect.top;
1477     if ( !(nFlags & SAL_FRAME_POSSIZE_WIDTH) )
1478         nWidth = aClientRect.right-aClientRect.left;
1479     if ( !(nFlags & SAL_FRAME_POSSIZE_HEIGHT) )
1480         nHeight = aClientRect.bottom-aClientRect.top;
1481 
1482     // Calculate window size including the border
1483     RECT    aWinRect;
1484     aWinRect.left   = 0;
1485     aWinRect.right  = (int)nWidth-1;
1486     aWinRect.top    = 0;
1487     aWinRect.bottom = (int)nHeight-1;
1488     AdjustWindowRectEx( &aWinRect, GetWindowStyle( mhWnd ),
1489                         FALSE,     GetWindowExStyle( mhWnd ) );
1490     nWidth  = aWinRect.right - aWinRect.left + 1;
1491     nHeight = aWinRect.bottom - aWinRect.top + 1;
1492 
1493     if ( !(nPosSize & SWP_NOMOVE) && ::GetParent( mhWnd ) )
1494     {
1495             // --- RTL --- (mirror window pos)
1496             RECT aParentRect;
1497             GetClientRect( ImplGetParentHwnd( mhWnd ), &aParentRect );
1498             if( Application::GetSettings().GetLayoutRTL() )
1499                 nX = (aParentRect.right - aParentRect.left) - nWidth-1 - nX;
1500 
1501             //#110386#, do not transform coordinates for system child windows
1502             if( !(GetWindowStyle( mhWnd ) & WS_CHILD) )
1503             {
1504                 POINT aPt;
1505                 aPt.x = nX;
1506                 aPt.y = nY;
1507 
1508                 HWND parentHwnd = ImplGetParentHwnd( mhWnd );
1509                 WinSalFrame* pParentFrame = GetWindowPtr( parentHwnd );
1510                 if ( pParentFrame && pParentFrame->mnShowState == SW_SHOWMAXIMIZED )
1511                 {
1512                     // #i42485#: parent will be shown maximized in which case
1513                     // a ClientToScreen uses the wrong coordinates (i.e. those from the restore pos)
1514                     // so use the (already updated) frame geometry for the transformation
1515                     aPt.x +=  pParentFrame->maGeometry.nX;
1516                     aPt.y +=  pParentFrame->maGeometry.nY;
1517                 }
1518                 else
1519                     ClientToScreen( parentHwnd, &aPt );
1520 
1521                 nX = aPt.x;
1522                 nY = aPt.y;
1523             }
1524     }
1525 
1526     // #i3338# to be conformant to UNIX we must position the client window, ie without the decoration
1527     // #i43250# if the position was read from the system (GetWindowRect(), see above), it must not be modified
1528     if ( nFlags & SAL_FRAME_POSSIZE_X )
1529         nX += aWinRect.left;
1530     if ( nFlags & SAL_FRAME_POSSIZE_Y )
1531         nY += aWinRect.top;
1532 
1533     int     nScreenX;
1534     int     nScreenY;
1535     int     nScreenWidth;
1536     int     nScreenHeight;
1537 
1538 
1539     RECT aRect;
1540     ImplSalGetWorkArea( mhWnd, &aRect, NULL );
1541     nScreenX        = aRect.left;
1542     nScreenY        = aRect.top;
1543     nScreenWidth    = aRect.right-aRect.left;
1544     nScreenHeight   = aRect.bottom-aRect.top;
1545 
1546     if ( mbDefPos && (nPosSize & SWP_NOMOVE)) // we got no positioning request, so choose default position
1547     {
1548         // center window
1549 
1550         HWND hWndParent = ::GetParent( mhWnd );
1551         // Search for TopLevel Frame
1552         while ( hWndParent && (GetWindowStyle( hWndParent ) & WS_CHILD) )
1553             hWndParent = ::GetParent( hWndParent );
1554         // if the Window has a Parent, than center the window to
1555         // the parent, in the other case to the screen
1556         if ( hWndParent && !IsIconic( hWndParent ) &&
1557              (GetWindowStyle( hWndParent ) & WS_VISIBLE) )
1558         {
1559             RECT aParentRect;
1560             GetWindowRect( hWndParent, &aParentRect );
1561             int nParentWidth    = aParentRect.right-aParentRect.left;
1562             int nParentHeight   = aParentRect.bottom-aParentRect.top;
1563 
1564             // We don't center, when Parent is smaller than our window
1565             if ( (nParentWidth-GetSystemMetrics( SM_CXFIXEDFRAME ) <= nWidth) &&
1566                  (nParentHeight-GetSystemMetrics( SM_CYFIXEDFRAME ) <= nHeight) )
1567             {
1568                 int nOff = GetSystemMetrics( SM_CYSIZEFRAME ) + GetSystemMetrics( SM_CYCAPTION );
1569                 nX = aParentRect.left+nOff;
1570                 nY = aParentRect.top+nOff;
1571             }
1572             else
1573             {
1574                 nX = (nParentWidth-nWidth)/2 + aParentRect.left;
1575                 nY = (nParentHeight-nHeight)/2 + aParentRect.top;
1576             }
1577         }
1578         else
1579         {
1580             POINT pt;
1581             GetCursorPos( &pt );
1582             RECT aRect;
1583             aRect.left = pt.x;
1584             aRect.top = pt.y;
1585             aRect.right = pt.x+2;
1586             aRect.bottom = pt.y+2;
1587 
1588             // dualmonitor support:
1589             // Get screensize of the monitor whith the mouse pointer
1590             ImplSalGetWorkArea( mhWnd, &aRect, &aRect );
1591 
1592             nX = ((aRect.right-aRect.left)-nWidth)/2 + aRect.left;
1593             nY = ((aRect.bottom-aRect.top)-nHeight)/2 + aRect.top;
1594         }
1595 
1596 
1597         //if ( bVisible )
1598         //    mbDefPos = FALSE;
1599 
1600         mbDefPos = FALSE;   // center only once
1601         nPosSize &= ~SWP_NOMOVE;        // activate positioning
1602         nEvent = SALEVENT_MOVERESIZE;
1603     }
1604 
1605 
1606     // Adjust Window in the screen
1607     sal_Bool bCheckOffScreen = TRUE;
1608 
1609     // but don't do this for floaters or ownerdraw windows that are currently moved interactively
1610     if( (mnStyle & SAL_FRAME_STYLE_FLOAT) && !(mnStyle & SAL_FRAME_STYLE_OWNERDRAWDECORATION) )
1611         bCheckOffScreen = FALSE;
1612 
1613     if( mnStyle & SAL_FRAME_STYLE_OWNERDRAWDECORATION )
1614     {
1615         // may be the window is currently being moved (mouse is captured), then no check is required
1616         if( mhWnd == ::GetCapture() )
1617             bCheckOffScreen = FALSE;
1618         else
1619             bCheckOffScreen = TRUE;
1620     }
1621 
1622     if( bCheckOffScreen )
1623     {
1624         if ( nX+nWidth > nScreenX+nScreenWidth )
1625             nX = (nScreenX+nScreenWidth) - nWidth;
1626         if ( nY+nHeight > nScreenY+nScreenHeight )
1627             nY = (nScreenY+nScreenHeight) - nHeight;
1628         if ( nX < nScreenX )
1629             nX = nScreenX;
1630         if ( nY < nScreenY )
1631             nY = nScreenY;
1632     }
1633 
1634     UINT nPosFlags = SWP_NOACTIVATE | SWP_NOOWNERZORDER | nPosSize;
1635     // bring floating windows always to top
1636     if( !(mnStyle & SAL_FRAME_STYLE_FLOAT) )
1637         nPosFlags |= SWP_NOZORDER; // do not change z-order
1638 
1639     SetWindowPos( mhWnd, HWND_TOP, nX, nY, (int)nWidth, (int)nHeight, nPosFlags  );
1640 
1641 	UpdateFrameGeometry( mhWnd, this );
1642 
1643     // Notification -- really ???
1644     if( nEvent )
1645         CallCallback( nEvent, NULL );
1646 }
1647 
1648 // -----------------------------------------------------------------------
1649 
1650 static void ImplSetParentFrame( WinSalFrame* pThis, HWND hNewParentWnd, sal_Bool bAsChild )
1651 {
1652     // save hwnd, will be overwritten in WM_CREATE during createwindow
1653     HWND hWndOld = pThis->mhWnd;
1654     HWND hWndOldParent = ::GetParent( hWndOld );
1655     SalData* pSalData = GetSalData();
1656 
1657     if( hNewParentWnd == hWndOldParent )
1658         return;
1659 
1660     ::std::vector< WinSalFrame* > children;
1661     ::std::vector< WinSalObject* > systemChildren;
1662 
1663     // search child windows
1664     WinSalFrame *pFrame = pSalData->mpFirstFrame;
1665     while( pFrame )
1666     {
1667         HWND hWndParent = ::GetParent( pFrame->mhWnd );
1668         if( pThis->mhWnd == hWndParent )
1669             children.push_back( pFrame );
1670         pFrame = pFrame->mpNextFrame;
1671     }
1672 
1673     // search system child windows (plugins etc.)
1674     WinSalObject *pObject = pSalData->mpFirstObject;
1675     while( pObject )
1676     {
1677         HWND hWndParent = ::GetParent( pObject->mhWnd );
1678         if( pThis->mhWnd == hWndParent )
1679             systemChildren.push_back( pObject );
1680         pObject = pObject->mpNextObject;
1681     }
1682 
1683     sal_Bool bNeedGraphics = pThis->mbGraphics;
1684     sal_Bool bNeedCacheDC  = FALSE;
1685 
1686     HFONT   hFont   = NULL;
1687     HPEN    hPen    = NULL;
1688     HBRUSH  hBrush  = NULL;
1689 
1690     #if OSL_DEBUG_LEVEL > 0
1691     int oldCount = pSalData->mnCacheDCInUse;
1692 	(void)oldCount;
1693     #endif
1694 
1695     // Release Cache DC
1696     if ( pThis->mpGraphics2 &&
1697          pThis->mpGraphics2->getHDC() )
1698     {
1699         // save current gdi objects before hdc is gone
1700         hFont   = (HFONT)   GetCurrentObject( pThis->mpGraphics2->getHDC(), OBJ_FONT);
1701         hPen    = (HPEN)    GetCurrentObject( pThis->mpGraphics2->getHDC(), OBJ_PEN);
1702         hBrush  = (HBRUSH)  GetCurrentObject( pThis->mpGraphics2->getHDC(), OBJ_BRUSH);
1703         pThis->ReleaseGraphics( pThis->mpGraphics2 );
1704 
1705         // recreate cache dc only if it was destroyed
1706         bNeedCacheDC  = TRUE;
1707     }
1708 
1709     // destroy saved DC
1710     if ( pThis->mpGraphics )
1711     {
1712         if ( pThis->mpGraphics->mhDefPal )
1713             SelectPalette( pThis->mpGraphics->getHDC(), pThis->mpGraphics->mhDefPal, TRUE );
1714         ImplSalDeInitGraphics( pThis->mpGraphics );
1715         ReleaseDC( pThis->mhWnd, pThis->mpGraphics->getHDC() );
1716     }
1717 
1718     // create a new hwnd with the same styles
1719     HWND hWndParent = hNewParentWnd;
1720     // forward to main thread
1721     HWND hWnd = (HWND) ImplSendMessage( pSalData->mpFirstInstance->mhComWnd,
1722                                         bAsChild ? SAL_MSG_RECREATECHILDHWND : SAL_MSG_RECREATEHWND,
1723                                         (WPARAM) hWndParent, (LPARAM)pThis->mhWnd );
1724 
1725     // succeeded ?
1726     DBG_ASSERT( IsWindow( hWnd ), "WinSalFrame::SetParent not successful");
1727 
1728     // recreate DCs
1729     if( bNeedGraphics )
1730     {
1731         if( pThis->mpGraphics2 )
1732         {
1733             pThis->mpGraphics2->mhWnd = hWnd;
1734 
1735             if( bNeedCacheDC )
1736             {
1737                 // re-create cached DC
1738                 HDC hDC = (HDC)ImplSendMessage( pSalData->mpFirstInstance->mhComWnd,
1739                                                 SAL_MSG_GETDC,
1740                                                 (WPARAM) hWnd, 0 );
1741                 if ( hDC )
1742                 {
1743                     pThis->mpGraphics2->setHDC(hDC);
1744                     if ( pSalData->mhDitherPal )
1745                     {
1746                         pThis->mpGraphics2->mhDefPal = SelectPalette( hDC, pSalData->mhDitherPal, TRUE );
1747                         RealizePalette( hDC );
1748                     }
1749                     ImplSalInitGraphics( pThis->mpGraphics2 );
1750 
1751                     // re-select saved gdi objects
1752                     if( hFont )
1753                         SelectObject( hDC, hFont );
1754                     if( hPen )
1755                         SelectObject( hDC, hPen );
1756                     if( hBrush )
1757                         SelectObject( hDC, hBrush );
1758 
1759                     pThis->mbGraphics = TRUE;
1760 
1761                     pSalData->mnCacheDCInUse++;
1762 
1763                     DBG_ASSERT( oldCount == pSalData->mnCacheDCInUse, "WinSalFrame::SetParent() hDC count corrupted");
1764                 }
1765             }
1766         }
1767 
1768         if( pThis->mpGraphics )
1769         {
1770             // re-create DC
1771             pThis->mpGraphics->mhWnd = hWnd;
1772             pThis->mpGraphics->setHDC( GetDC( hWnd ) );
1773             if ( GetSalData()->mhDitherPal )
1774             {
1775                 pThis->mpGraphics->mhDefPal = SelectPalette( pThis->mpGraphics->getHDC(), GetSalData()->mhDitherPal, TRUE );
1776                 RealizePalette( pThis->mpGraphics->getHDC() );
1777             }
1778             ImplSalInitGraphics( pThis->mpGraphics );
1779             pThis->mbGraphics = TRUE;
1780         }
1781     }
1782 
1783 
1784     // TODO: add SetParent() call for SalObjects
1785     DBG_ASSERT( systemChildren.empty(), "WinSalFrame::SetParent() parent of living system child window will be destroyed!");
1786 
1787     // reparent children before old parent is destroyed
1788     for( ::std::vector< WinSalFrame* >::iterator iChild = children.begin(); iChild != children.end(); iChild++ )
1789         ImplSetParentFrame( *iChild, hWnd, FALSE );
1790 
1791     children.clear();
1792     systemChildren.clear();
1793 
1794     // Now destroy original HWND in the thread where it was created.
1795     ImplSendMessage( GetSalData()->mpFirstInstance->mhComWnd,
1796                      SAL_MSG_DESTROYHWND, (WPARAM) 0, (LPARAM)hWndOld);
1797 }
1798 
1799 // -----------------------------------------------------------------------
1800 
1801 void WinSalFrame::SetParent( SalFrame* pNewParent )
1802 {
1803     WinSalFrame::mbInReparent = TRUE;
1804     ImplSetParentFrame( this, static_cast<WinSalFrame*>(pNewParent)->mhWnd, FALSE );
1805     WinSalFrame::mbInReparent = FALSE;
1806 }
1807 
1808 bool WinSalFrame::SetPluginParent( SystemParentData* pNewParent )
1809 {
1810     if ( pNewParent->hWnd == 0 )
1811     {
1812         pNewParent->hWnd = GetDesktopWindow();
1813     }
1814 
1815     WinSalFrame::mbInReparent = TRUE;
1816     ImplSetParentFrame( this, pNewParent->hWnd, TRUE );
1817     WinSalFrame::mbInReparent = FALSE;
1818     return true;
1819 }
1820 
1821 
1822 // -----------------------------------------------------------------------
1823 
1824 void WinSalFrame::GetWorkArea( Rectangle &rRect )
1825 {
1826     RECT aRect;
1827 	ImplSalGetWorkArea( mhWnd, &aRect, NULL );
1828     rRect.nLeft     = aRect.left;
1829     rRect.nRight    = aRect.right-1;
1830     rRect.nTop      = aRect.top;
1831     rRect.nBottom   = aRect.bottom-1;
1832 }
1833 
1834 // -----------------------------------------------------------------------
1835 
1836 void WinSalFrame::GetClientSize( long& rWidth, long& rHeight )
1837 {
1838     rWidth  = maGeometry.nWidth;
1839     rHeight = maGeometry.nHeight;
1840 }
1841 
1842 // -----------------------------------------------------------------------
1843 
1844 void WinSalFrame::SetWindowState( const SalFrameState* pState )
1845 {
1846     // Wir testen, ob das Fenster ueberhaupt auf den Bildschirm passt, damit
1847     // nicht wenn die Bildschirm-Aufloesung geaendert wurde, das Fenster aus
1848     // diesem herausragt
1849     int     nX;
1850     int     nY;
1851     int     nWidth;
1852     int     nHeight;
1853     int     nScreenX;
1854     int     nScreenY;
1855     int     nScreenWidth;
1856     int     nScreenHeight;
1857 
1858     RECT aRect;
1859 	ImplSalGetWorkArea( mhWnd, &aRect, NULL );
1860     // #102500# allow some overlap, the window could have been made a little larger than the physical screen
1861     nScreenX        = aRect.left-10;
1862     nScreenY        = aRect.top-10;
1863     nScreenWidth    = aRect.right-aRect.left+20;
1864     nScreenHeight   = aRect.bottom-aRect.top+20;
1865 
1866     UINT    nPosSize    = 0;
1867     RECT    aWinRect;
1868     GetWindowRect( mhWnd, &aWinRect );
1869 
1870     // to be consistent with Unix, the frame state is without(!) decoration
1871     // ->add the decoration
1872     RECT aRect2 = aWinRect;
1873 	AdjustWindowRectEx( &aRect2, GetWindowStyle( mhWnd ),
1874 					FALSE,     GetWindowExStyle( mhWnd ) );
1875     long nTopDeco = abs( aWinRect.top - aRect2.top );
1876     long nLeftDeco = abs( aWinRect.left - aRect2.left );
1877     long nBottomDeco = abs( aWinRect.bottom - aRect2.bottom );
1878     long nRightDeco = abs( aWinRect.right - aRect2.right );
1879 
1880     // Fenster-Position/Groesse in den Bildschirm einpassen
1881     if ( !(pState->mnMask & (SAL_FRAMESTATE_MASK_X | SAL_FRAMESTATE_MASK_Y)) )
1882         nPosSize |= SWP_NOMOVE;
1883     if ( !(pState->mnMask & (SAL_FRAMESTATE_MASK_WIDTH | SAL_FRAMESTATE_MASK_HEIGHT)) )
1884         nPosSize |= SWP_NOSIZE;
1885     if ( pState->mnMask & SAL_FRAMESTATE_MASK_X )
1886         nX = (int)pState->mnX - nLeftDeco;
1887     else
1888         nX = aWinRect.left;
1889     if ( pState->mnMask & SAL_FRAMESTATE_MASK_Y )
1890         nY = (int)pState->mnY - nTopDeco;
1891     else
1892         nY = aWinRect.top;
1893     if ( pState->mnMask & SAL_FRAMESTATE_MASK_WIDTH )
1894         nWidth = (int)pState->mnWidth + nLeftDeco + nRightDeco;
1895     else
1896         nWidth = aWinRect.right-aWinRect.left;
1897     if ( pState->mnMask & SAL_FRAMESTATE_MASK_HEIGHT )
1898         nHeight = (int)pState->mnHeight + nTopDeco + nBottomDeco;
1899     else
1900         nHeight = aWinRect.bottom-aWinRect.top;
1901 
1902     // Adjust Window in the screen:
1903     // if it does not fit into the screen do nothing, ie default pos/size will be used
1904     // if there is an overlap with the screen border move the window while keeping its size
1905 
1906     if( nWidth > nScreenWidth || nHeight > nScreenHeight )
1907         nPosSize |= (SWP_NOMOVE | SWP_NOSIZE);
1908 
1909     if ( nX+nWidth > nScreenX+nScreenWidth )
1910         nX = (nScreenX+nScreenWidth) - nWidth;
1911     if ( nY+nHeight > nScreenY+nScreenHeight )
1912         nY = (nScreenY+nScreenHeight) - nHeight;
1913     if ( nX < nScreenX )
1914         nX = nScreenX;
1915     if ( nY < nScreenY )
1916         nY = nScreenY;
1917 
1918     // Restore-Position setzen
1919     WINDOWPLACEMENT aPlacement;
1920     aPlacement.length = sizeof( aPlacement );
1921     GetWindowPlacement( mhWnd, &aPlacement );
1922 
1923     // Status setzen
1924     sal_Bool bVisible = (GetWindowStyle( mhWnd ) & WS_VISIBLE) != 0;
1925 	sal_Bool bUpdateHiddenFramePos = FALSE;
1926     if ( !bVisible )
1927     {
1928         aPlacement.showCmd = SW_HIDE;
1929 
1930         if ( mbOverwriteState )
1931         {
1932             if ( pState->mnMask & SAL_FRAMESTATE_MASK_STATE )
1933             {
1934                 if ( pState->mnState & SAL_FRAMESTATE_MINIMIZED )
1935                     mnShowState = SW_SHOWMINIMIZED;
1936                 else if ( pState->mnState & SAL_FRAMESTATE_MAXIMIZED )
1937 				{
1938                     mnShowState = SW_SHOWMAXIMIZED;
1939 					bUpdateHiddenFramePos = TRUE;
1940 				}
1941                 else if ( pState->mnState & SAL_FRAMESTATE_NORMAL )
1942                     mnShowState = SW_SHOWNORMAL;
1943             }
1944         }
1945     }
1946     else
1947     {
1948         if ( pState->mnMask & SAL_FRAMESTATE_MASK_STATE )
1949         {
1950             if ( pState->mnState & SAL_FRAMESTATE_MINIMIZED )
1951             {
1952                 if ( pState->mnState & SAL_FRAMESTATE_MAXIMIZED )
1953                     aPlacement.flags |= WPF_RESTORETOMAXIMIZED;
1954                 aPlacement.showCmd = SW_SHOWMINIMIZED;
1955             }
1956             else if ( pState->mnState & SAL_FRAMESTATE_MAXIMIZED )
1957                 aPlacement.showCmd = SW_SHOWMAXIMIZED;
1958             else if ( pState->mnState & SAL_FRAMESTATE_NORMAL )
1959                 aPlacement.showCmd = SW_RESTORE;
1960         }
1961     }
1962 
1963     // if a window is neither minimized nor maximized or need not be
1964     // positioned visibly (that is in visible state), do not use
1965     // SetWindowPlacement since it calculates including the TaskBar
1966     if ( !IsIconic( mhWnd ) && !IsZoomed( mhWnd ) &&
1967          (!bVisible || (aPlacement.showCmd == SW_RESTORE)) )
1968     {
1969 		if( bUpdateHiddenFramePos )
1970 		{
1971 		    RECT aStateRect;
1972 		    aStateRect.left   = nX;
1973 		    aStateRect.top    = nY;
1974 		    aStateRect.right  = nX+nWidth;
1975 		    aStateRect.bottom = nY+nHeight;
1976 			// #96084 set a useful internal window size because
1977 			// the window will not be maximized (and the size updated) before show()
1978             SetMaximizedFrameGeometry( mhWnd, this, &aStateRect );
1979 			SetWindowPos( mhWnd, 0,
1980                           maGeometry.nX, maGeometry.nY, maGeometry.nWidth, maGeometry.nHeight,
1981                           SWP_NOZORDER | SWP_NOACTIVATE | nPosSize );
1982 		}
1983 		else
1984 			SetWindowPos( mhWnd, 0,
1985                       nX, nY, nWidth, nHeight,
1986                       SWP_NOZORDER | SWP_NOACTIVATE | nPosSize );
1987     }
1988     else
1989     {
1990         if( !(nPosSize & (SWP_NOMOVE|SWP_NOSIZE)) )
1991         {
1992             aPlacement.rcNormalPosition.left    = nX-nScreenX;
1993             aPlacement.rcNormalPosition.top     = nY-nScreenY;
1994             aPlacement.rcNormalPosition.right   = nX+nWidth-nScreenX;
1995             aPlacement.rcNormalPosition.bottom  = nY+nHeight-nScreenY;
1996         }
1997         SetWindowPlacement( mhWnd, &aPlacement );
1998     }
1999 
2000     if( !(nPosSize & SWP_NOMOVE) )
2001         mbDefPos = FALSE; // window was positioned
2002 }
2003 
2004 // -----------------------------------------------------------------------
2005 
2006 sal_Bool WinSalFrame::GetWindowState( SalFrameState* pState )
2007 {
2008     if ( maState.mnWidth && maState.mnHeight )
2009     {
2010         *pState = maState;
2011         // #94144# allow Minimize again, should be masked out when read from configuration
2012         // 91625 - Don't save minimize
2013         //if ( !(pState->mnState & SAL_FRAMESTATE_MAXIMIZED) )
2014         if ( !(pState->mnState & (SAL_FRAMESTATE_MINIMIZED | SAL_FRAMESTATE_MAXIMIZED)) )
2015             pState->mnState |= SAL_FRAMESTATE_NORMAL;
2016         return TRUE;
2017     }
2018 
2019     return FALSE;
2020 }
2021 
2022 // -----------------------------------------------------------------------
2023 
2024 void WinSalFrame::SetScreenNumber( unsigned int nNewScreen )
2025 {
2026     WinSalSystem* pSys = static_cast<WinSalSystem*>(ImplGetSalSystem());
2027     if( pSys )
2028     {
2029         const std::vector<WinSalSystem::DisplayMonitor>& rMonitors =
2030             pSys->getMonitors();
2031         size_t nMon = rMonitors.size();
2032         if( nNewScreen < nMon )
2033         {
2034             Point aOldMonPos, aNewMonPos( rMonitors[nNewScreen].m_aArea.TopLeft() );
2035             Point aCurPos( maGeometry.nX, maGeometry.nY );
2036             for( size_t i = 0; i < nMon; i++ )
2037             {
2038                 if( rMonitors[i].m_aArea.IsInside( aCurPos ) )
2039                 {
2040                     aOldMonPos = rMonitors[i].m_aArea.TopLeft();
2041                     break;
2042                 }
2043             }
2044             mnDisplay = nNewScreen;
2045             maGeometry.nScreenNumber = nNewScreen;
2046             SetPosSize( aNewMonPos.X() + (maGeometry.nX - aOldMonPos.X()),
2047                         aNewMonPos.Y() + (maGeometry.nY - aOldMonPos.Y()),
2048                         0, 0,
2049                         SAL_FRAME_POSSIZE_X | SAL_FRAME_POSSIZE_Y );
2050         }
2051     }
2052 }
2053 
2054 // -----------------------------------------------------------------------
2055 
2056 void WinSalFrame::ShowFullScreen( sal_Bool bFullScreen, sal_Int32 nDisplay )
2057 {
2058     if ( (mbFullScreen == bFullScreen) && (!bFullScreen || (mnDisplay == nDisplay)) )
2059         return;
2060 
2061     mbFullScreen = bFullScreen;
2062 	mnDisplay = nDisplay;
2063 
2064 	if ( bFullScreen )
2065     {
2066         // Damit Taskleiste von Windows ausgeblendet wird
2067         DWORD nExStyle = GetWindowExStyle( mhWnd );
2068         if ( nExStyle & WS_EX_TOOLWINDOW )
2069         {
2070             mbFullScreenToolWin = TRUE;
2071             nExStyle &= ~WS_EX_TOOLWINDOW;
2072             SetWindowExStyle( mhWnd, nExStyle );
2073         }
2074         // save old position
2075         GetWindowRect( mhWnd, &maFullScreenRect );
2076 
2077         // save show state
2078         mnFullScreenShowState = mnShowState;
2079         if ( !(GetWindowStyle( mhWnd ) & WS_VISIBLE) )
2080             mnShowState = SW_SHOW;
2081 
2082         // set window to screen size
2083         ImplSalFrameFullScreenPos( this, TRUE );
2084     }
2085     else
2086     {
2087         // wenn ShowState wieder hergestellt werden muss, hiden wir zuerst
2088         // das Fenster, damit es nicht so sehr flackert
2089         sal_Bool bVisible = (GetWindowStyle( mhWnd ) & WS_VISIBLE) != 0;
2090         if ( bVisible && (mnShowState != mnFullScreenShowState) )
2091             ShowWindow( mhWnd, SW_HIDE );
2092 
2093         if ( mbFullScreenToolWin )
2094             SetWindowExStyle( mhWnd, GetWindowExStyle( mhWnd ) | WS_EX_TOOLWINDOW );
2095         mbFullScreenToolWin = FALSE;
2096 
2097         SetWindowPos( mhWnd, 0,
2098                       maFullScreenRect.left,
2099                       maFullScreenRect.top,
2100                       maFullScreenRect.right-maFullScreenRect.left,
2101                       maFullScreenRect.bottom-maFullScreenRect.top,
2102                       SWP_NOZORDER | SWP_NOACTIVATE );
2103 
2104         // restore show state
2105         if ( mnShowState != mnFullScreenShowState )
2106         {
2107             mnShowState = mnFullScreenShowState;
2108             if ( bVisible )
2109             {
2110                 mbInShow = TRUE;
2111                 ShowWindow( mhWnd, mnShowState );
2112                 mbInShow = FALSE;
2113                 UpdateWindow( mhWnd );
2114             }
2115         }
2116     }
2117 }
2118 
2119 // -----------------------------------------------------------------------
2120 
2121 void WinSalFrame::StartPresentation( sal_Bool bStart )
2122 {
2123     if ( mbPresentation == bStart )
2124         return;
2125 
2126     mbPresentation = bStart;
2127 
2128     SalData* pSalData = GetSalData();
2129     if ( bStart )
2130     {
2131         if ( !pSalData->mpSageEnableProc )
2132         {
2133             if ( pSalData->mnSageStatus != DISABLE_AGENT )
2134             {
2135                 OFSTRUCT aOS;
2136                 OpenFile( "SAGE.DLL", &aOS, OF_EXIST );
2137 
2138                 if ( !aOS.nErrCode )
2139                 {
2140                     oslModule mhSageInst = osl_loadAsciiModule( aOS.szPathName, SAL_LOADMODULE_DEFAULT );
2141                     pSalData->mpSageEnableProc = (SysAgt_Enable_PROC)osl_getAsciiFunctionSymbol( mhSageInst, "System_Agent_Enable" );
2142                 }
2143                 else
2144                     pSalData->mnSageStatus = DISABLE_AGENT;
2145             }
2146         }
2147 
2148         if ( pSalData->mpSageEnableProc )
2149         {
2150             pSalData->mnSageStatus = pSalData->mpSageEnableProc( GET_AGENT_STATUS );
2151             if ( pSalData->mnSageStatus == ENABLE_AGENT )
2152                 pSalData->mpSageEnableProc( DISABLE_AGENT );
2153         }
2154 
2155         // Bildschirmschoner ausschalten, wenn Praesentation laueft
2156         SystemParametersInfo( SPI_GETSCREENSAVEACTIVE, 0,
2157                               &(pSalData->mbScrSvrEnabled), 0 );
2158         if ( pSalData->mbScrSvrEnabled )
2159             SystemParametersInfo( SPI_SETSCREENSAVEACTIVE, FALSE, 0, 0 );
2160     }
2161     else
2162     {
2163         // Bildschirmschoner wieder einschalten
2164         if ( pSalData->mbScrSvrEnabled )
2165             SystemParametersInfo( SPI_SETSCREENSAVEACTIVE, pSalData->mbScrSvrEnabled, 0, 0 );
2166 
2167         // Systemagenten wieder aktivieren
2168         if ( pSalData->mnSageStatus == ENABLE_AGENT )
2169             pSalData->mpSageEnableProc( pSalData->mnSageStatus );
2170     }
2171 }
2172 
2173 // -----------------------------------------------------------------------
2174 
2175 void WinSalFrame::SetAlwaysOnTop( sal_Bool bOnTop )
2176 {
2177     HWND hWnd;
2178     if ( bOnTop )
2179         hWnd = HWND_TOPMOST;
2180     else
2181         hWnd = HWND_NOTOPMOST;
2182     SetWindowPos( mhWnd, hWnd, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE | SWP_NOACTIVATE );
2183 }
2184 
2185 // -----------------------------------------------------------------------
2186 
2187 static void ImplSalToTop( HWND hWnd, sal_uInt16 nFlags )
2188 {
2189     WinSalFrame* pToTopFrame = GetWindowPtr( hWnd );
2190     if( pToTopFrame && (pToTopFrame->mnStyle & SAL_FRAME_STYLE_SYSTEMCHILD) != 0 )
2191         BringWindowToTop( hWnd );
2192 
2193     if ( nFlags & SAL_FRAME_TOTOP_FOREGROUNDTASK )
2194     {
2195         // This magic code is necessary to connect the input focus of the
2196         // current window thread and the thread which owns the window that
2197         // should be the new foreground window.
2198         HWND   hCurrWnd     = GetForegroundWindow();
2199         DWORD  myThreadID   = GetCurrentThreadId();
2200         DWORD  currThreadID = GetWindowThreadProcessId(hCurrWnd,NULL);
2201         AttachThreadInput(myThreadID, currThreadID,TRUE);
2202         SetForegroundWindow(hWnd);
2203         AttachThreadInput(myThreadID,currThreadID,FALSE);
2204     }
2205 
2206     if ( nFlags & SAL_FRAME_TOTOP_RESTOREWHENMIN )
2207     {
2208         HWND hIconicWnd = hWnd;
2209         while ( hIconicWnd )
2210         {
2211             if ( IsIconic( hIconicWnd ) )
2212             {
2213                 WinSalFrame* pFrame = GetWindowPtr( hIconicWnd );
2214                 if ( pFrame )
2215                 {
2216                     if ( GetWindowPtr( hWnd )->mbRestoreMaximize )
2217                         ShowWindow( hIconicWnd, SW_MAXIMIZE );
2218                     else
2219                         ShowWindow( hIconicWnd, SW_RESTORE );
2220                 }
2221                 else
2222                     ShowWindow( hIconicWnd, SW_RESTORE );
2223             }
2224 
2225             hIconicWnd = ::GetParent( hIconicWnd );
2226         }
2227     }
2228 
2229     if ( !IsIconic( hWnd ) && IsWindowVisible( hWnd ) )
2230     {
2231         SetFocus( hWnd );
2232 
2233         // Windows behauptet oefters mal, das man den Focus hat, obwohl
2234         // man diesen nicht hat. Wenn dies der Fall ist, dann versuchen
2235         // wir diesen auch ganz richtig zu bekommen.
2236         if ( ::GetFocus() == hWnd )
2237             SetForegroundWindow( hWnd );
2238     }
2239 }
2240 
2241 // -----------------------------------------------------------------------
2242 
2243 void WinSalFrame::ToTop( sal_uInt16 nFlags )
2244 {
2245 	nFlags &= ~SAL_FRAME_TOTOP_GRABFOCUS;	// this flag is not needed on win32
2246     // Post this Message to the window, because this only works
2247     // in the thread of the window, which has create this window.
2248     // We post this message to avoid deadlocks
2249     if ( GetSalData()->mnAppThreadId != GetCurrentThreadId() )
2250         ImplPostMessage( mhWnd, SAL_MSG_TOTOP, nFlags, 0 );
2251     else
2252         ImplSalToTop( mhWnd, nFlags );
2253 }
2254 
2255 // -----------------------------------------------------------------------
2256 
2257 void WinSalFrame::SetPointer( PointerStyle ePointerStyle )
2258 {
2259     struct ImplPtrData
2260     {
2261         HCURSOR         mhCursor;
2262         LPCSTR          mnSysId;
2263         UINT            mnOwnId;
2264     };
2265 
2266     static ImplPtrData aImplPtrTab[POINTER_COUNT] =
2267     {
2268     { 0, IDC_ARROW, 0 },                            // POINTER_ARROW
2269     { 0, 0, SAL_RESID_POINTER_NULL },               // POINTER_NULL
2270     { 0, IDC_WAIT, 0 },                             // POINTER_WAIT
2271     { 0, IDC_IBEAM, 0 },                            // POINTER_TEXT
2272     { 0, IDC_HELP, 0 },                             // POINTER_HELP
2273     { 0, 0, SAL_RESID_POINTER_CROSS },              // POINTER_CROSS
2274     { 0, 0, SAL_RESID_POINTER_MOVE },               // POINTER_MOVE
2275     { 0, IDC_SIZENS, 0 },                           // POINTER_NSIZE
2276     { 0, IDC_SIZENS, 0 },                           // POINTER_SSIZE
2277     { 0, IDC_SIZEWE, 0 },                           // POINTER_WSIZE
2278     { 0, IDC_SIZEWE, 0 },                           // POINTER_ESIZE
2279     { 0, IDC_SIZENWSE, 0 },                         // POINTER_NWSIZE
2280     { 0, IDC_SIZENESW, 0 },                         // POINTER_NESIZE
2281     { 0, IDC_SIZENESW, 0 },                         // POINTER_SWSIZE
2282     { 0, IDC_SIZENWSE, 0 },                         // POINTER_SESIZE
2283     { 0, IDC_SIZENS, 0 },                           // POINTER_WINDOW_NSIZE
2284     { 0, IDC_SIZENS, 0 },                           // POINTER_WINDOW_SSIZE
2285     { 0, IDC_SIZEWE, 0 },                           // POINTER_WINDOW_WSIZE
2286     { 0, IDC_SIZEWE, 0 },                           // POINTER_WINDOW_ESIZE
2287     { 0, IDC_SIZENWSE, 0 },                         // POINTER_WINDOW_NWSIZE
2288     { 0, IDC_SIZENESW, 0 },                         // POINTER_WINDOW_NESIZE
2289     { 0, IDC_SIZENESW, 0 },                         // POINTER_WINDOW_SWSIZE
2290     { 0, IDC_SIZENWSE, 0 },                         // POINTER_WINDOW_SESIZE
2291     { 0, 0, SAL_RESID_POINTER_HSPLIT },             // POINTER_HSPLIT
2292     { 0, 0, SAL_RESID_POINTER_VSPLIT },             // POINTER_VSPLIT
2293     { 0, 0, SAL_RESID_POINTER_HSIZEBAR },           // POINTER_HSIZEBAR
2294     { 0, 0, SAL_RESID_POINTER_VSIZEBAR },           // POINTER_VSIZEBAR
2295     { 0, 0, SAL_RESID_POINTER_HAND },               // POINTER_HAND
2296     { 0, 0, SAL_RESID_POINTER_REFHAND },            // POINTER_REFHAND
2297     { 0, 0, SAL_RESID_POINTER_PEN },                // POINTER_PEN
2298     { 0, 0, SAL_RESID_POINTER_MAGNIFY },            // POINTER_MAGNIFY
2299     { 0, 0, SAL_RESID_POINTER_FILL },               // POINTER_FILL
2300     { 0, 0, SAL_RESID_POINTER_ROTATE },             // POINTER_ROTATE
2301     { 0, 0, SAL_RESID_POINTER_HSHEAR },             // POINTER_HSHEAR
2302     { 0, 0, SAL_RESID_POINTER_VSHEAR },             // POINTER_VSHEAR
2303     { 0, 0, SAL_RESID_POINTER_MIRROR },             // POINTER_MIRROR
2304     { 0, 0, SAL_RESID_POINTER_CROOK },              // POINTER_CROOK
2305     { 0, 0, SAL_RESID_POINTER_CROP },               // POINTER_CROP
2306     { 0, 0, SAL_RESID_POINTER_MOVEPOINT },          // POINTER_MOVEPOINT
2307     { 0, 0, SAL_RESID_POINTER_MOVEBEZIERWEIGHT },   // POINTER_MOVEBEZIERWEIGHT
2308     { 0, 0, SAL_RESID_POINTER_MOVEDATA },           // POINTER_MOVEDATA
2309     { 0, 0, SAL_RESID_POINTER_COPYDATA },           // POINTER_COPYDATA
2310     { 0, 0, SAL_RESID_POINTER_LINKDATA },           // POINTER_LINKDATA
2311     { 0, 0, SAL_RESID_POINTER_MOVEDATALINK },       // POINTER_MOVEDATALINK
2312     { 0, 0, SAL_RESID_POINTER_COPYDATALINK },       // POINTER_COPYDATALINK
2313     { 0, 0, SAL_RESID_POINTER_MOVEFILE },           // POINTER_MOVEFILE
2314     { 0, 0, SAL_RESID_POINTER_COPYFILE },           // POINTER_COPYFILE
2315     { 0, 0, SAL_RESID_POINTER_LINKFILE },           // POINTER_LINKFILE
2316     { 0, 0, SAL_RESID_POINTER_MOVEFILELINK },       // POINTER_MOVEFILELINK
2317     { 0, 0, SAL_RESID_POINTER_COPYFILELINK },       // POINTER_COPYFILELINK
2318     { 0, 0, SAL_RESID_POINTER_MOVEFILES },          // POINTER_MOVEFILES
2319     { 0, 0, SAL_RESID_POINTER_COPYFILES },          // POINTER_COPYFILES
2320     { 0, 0, SAL_RESID_POINTER_NOTALLOWED },         // POINTER_NOTALLOWED
2321     { 0, 0, SAL_RESID_POINTER_DRAW_LINE },          // POINTER_DRAW_LINE
2322     { 0, 0, SAL_RESID_POINTER_DRAW_RECT },          // POINTER_DRAW_RECT
2323     { 0, 0, SAL_RESID_POINTER_DRAW_POLYGON },       // POINTER_DRAW_POLYGON
2324     { 0, 0, SAL_RESID_POINTER_DRAW_BEZIER },        // POINTER_DRAW_BEZIER
2325     { 0, 0, SAL_RESID_POINTER_DRAW_ARC },           // POINTER_DRAW_ARC
2326     { 0, 0, SAL_RESID_POINTER_DRAW_PIE },           // POINTER_DRAW_PIE
2327     { 0, 0, SAL_RESID_POINTER_DRAW_CIRCLECUT },     // POINTER_DRAW_CIRCLECUT
2328     { 0, 0, SAL_RESID_POINTER_DRAW_ELLIPSE },       // POINTER_DRAW_ELLIPSE
2329     { 0, 0, SAL_RESID_POINTER_DRAW_FREEHAND },      // POINTER_DRAW_FREEHAND
2330     { 0, 0, SAL_RESID_POINTER_DRAW_CONNECT },       // POINTER_DRAW_CONNECT
2331     { 0, 0, SAL_RESID_POINTER_DRAW_TEXT },          // POINTER_DRAW_TEXT
2332     { 0, 0, SAL_RESID_POINTER_DRAW_CAPTION },       // POINTER_DRAW_CAPTION
2333     { 0, 0, SAL_RESID_POINTER_CHART },              // POINTER_CHART
2334     { 0, 0, SAL_RESID_POINTER_DETECTIVE },          // POINTER_DETECTIVE
2335     { 0, 0, SAL_RESID_POINTER_PIVOT_COL },          // POINTER_PIVOT_COL
2336     { 0, 0, SAL_RESID_POINTER_PIVOT_ROW },          // POINTER_PIVOT_ROW
2337     { 0, 0, SAL_RESID_POINTER_PIVOT_FIELD },        // POINTER_PIVOT_FIELD
2338     { 0, 0, SAL_RESID_POINTER_CHAIN },              // POINTER_CHAIN
2339     { 0, 0, SAL_RESID_POINTER_CHAIN_NOTALLOWED },   // POINTER_CHAIN_NOTALLOWED
2340     { 0, 0, SAL_RESID_POINTER_TIMEEVENT_MOVE },     // POINTER_TIMEEVENT_MOVE
2341     { 0, 0, SAL_RESID_POINTER_TIMEEVENT_SIZE },     // POINTER_TIMEEVENT_SIZE
2342     { 0, 0, SAL_RESID_POINTER_AUTOSCROLL_N },       // POINTER_AUTOSCROLL_N
2343     { 0, 0, SAL_RESID_POINTER_AUTOSCROLL_S },       // POINTER_AUTOSCROLL_S
2344     { 0, 0, SAL_RESID_POINTER_AUTOSCROLL_W },       // POINTER_AUTOSCROLL_W
2345     { 0, 0, SAL_RESID_POINTER_AUTOSCROLL_E },       // POINTER_AUTOSCROLL_E
2346     { 0, 0, SAL_RESID_POINTER_AUTOSCROLL_NW },      // POINTER_AUTOSCROLL_NW
2347     { 0, 0, SAL_RESID_POINTER_AUTOSCROLL_NE },      // POINTER_AUTOSCROLL_NE
2348     { 0, 0, SAL_RESID_POINTER_AUTOSCROLL_SW },      // POINTER_AUTOSCROLL_SW
2349     { 0, 0, SAL_RESID_POINTER_AUTOSCROLL_SE },      // POINTER_AUTOSCROLL_SE
2350     { 0, 0, SAL_RESID_POINTER_AUTOSCROLL_NS },      // POINTER_AUTOSCROLL_NS
2351     { 0, 0, SAL_RESID_POINTER_AUTOSCROLL_WE },      // POINTER_AUTOSCROLL_WE
2352     { 0, 0, SAL_RESID_POINTER_AUTOSCROLL_NSWE },    // POINTER_AUTOSCROLL_NSWE
2353     { 0, 0, SAL_RESID_POINTER_AIRBRUSH },           // POINTER_AIRBRUSH
2354     { 0, 0, SAL_RESID_POINTER_TEXT_VERTICAL },      // POINTER_TEXT_VERTICAL
2355     { 0, 0, SAL_RESID_POINTER_PIVOT_DELETE },       // POINTER_PIVOT_DELETE
2356 
2357     // --> FME 2004-07-30 #i32329# Enhanced table selection
2358     { 0, 0, SAL_RESID_POINTER_TAB_SELECT_S },       // POINTER_TAB_SELECT_S
2359     { 0, 0, SAL_RESID_POINTER_TAB_SELECT_E },       // POINTER_TAB_SELECT_E
2360     { 0, 0, SAL_RESID_POINTER_TAB_SELECT_SE },      // POINTER_TAB_SELECT_SE
2361     { 0, 0, SAL_RESID_POINTER_TAB_SELECT_W },       // POINTER_TAB_SELECT_W
2362     { 0, 0, SAL_RESID_POINTER_TAB_SELECT_SW },      // POINTER_TAB_SELECT_SW
2363     // <--
2364 
2365     // --> FME 2004-08-16 #i20119# Paintbrush tool
2366     { 0, 0, SAL_RESID_POINTER_PAINTBRUSH }          // POINTER_PAINTBRUSH
2367     // <--
2368 
2369     };
2370 
2371 #if POINTER_COUNT != 94
2372 #error New Pointer must be defined!
2373 #endif
2374 
2375     // Mousepointer loaded ?
2376     if ( !aImplPtrTab[ePointerStyle].mhCursor )
2377     {
2378         if ( aImplPtrTab[ePointerStyle].mnOwnId )
2379             aImplPtrTab[ePointerStyle].mhCursor = ImplLoadSalCursor( aImplPtrTab[ePointerStyle].mnOwnId );
2380         else
2381             aImplPtrTab[ePointerStyle].mhCursor = LoadCursor( 0, aImplPtrTab[ePointerStyle].mnSysId );
2382     }
2383 
2384     // Unterscheidet sich der Mauspointer, dann den neuen setzen
2385     if ( mhCursor != aImplPtrTab[ePointerStyle].mhCursor )
2386     {
2387         mhCursor = aImplPtrTab[ePointerStyle].mhCursor;
2388         SetCursor( mhCursor );
2389     }
2390 }
2391 
2392 // -----------------------------------------------------------------------
2393 
2394 void WinSalFrame::CaptureMouse( sal_Bool bCapture )
2395 {
2396     // Send this Message to the window, because CaptureMouse() only work
2397     // in the thread of the window, which has create this window
2398     int nMsg;
2399     if ( bCapture )
2400         nMsg = SAL_MSG_CAPTUREMOUSE;
2401     else
2402         nMsg = SAL_MSG_RELEASEMOUSE;
2403     ImplSendMessage( mhWnd, nMsg, 0, 0 );
2404 }
2405 
2406 // -----------------------------------------------------------------------
2407 
2408 void WinSalFrame::SetPointerPos( long nX, long nY )
2409 {
2410     POINT aPt;
2411     aPt.x = (int)nX;
2412     aPt.y = (int)nY;
2413     ClientToScreen( mhWnd, &aPt );
2414     SetCursorPos( aPt.x, aPt.y );
2415 }
2416 
2417 // -----------------------------------------------------------------------
2418 
2419 void WinSalFrame::Flush()
2420 {
2421     GdiFlush();
2422 }
2423 
2424 // -----------------------------------------------------------------------
2425 
2426 void WinSalFrame::Sync()
2427 {
2428     GdiFlush();
2429 }
2430 
2431 // -----------------------------------------------------------------------
2432 
2433 static void ImplSalFrameSetInputContext( HWND hWnd, const SalInputContext* pContext )
2434 {
2435     WinSalFrame*   pFrame = GetWindowPtr( hWnd );
2436     sal_Bool        bIME = (pContext->mnOptions & SAL_INPUTCONTEXT_TEXT) != 0;
2437     if ( bIME )
2438     {
2439         if ( !pFrame->mbIME )
2440         {
2441             pFrame->mbIME = TRUE;
2442 
2443             if ( pFrame->mhDefIMEContext )
2444             {
2445                 ImmAssociateContext( pFrame->mhWnd, pFrame->mhDefIMEContext );
2446                 UINT nImeProps = ImmGetProperty( GetKeyboardLayout( 0 ), IGP_PROPERTY );
2447                 pFrame->mbSpezIME = (nImeProps & IME_PROP_SPECIAL_UI) != 0;
2448                 pFrame->mbAtCursorIME = (nImeProps & IME_PROP_AT_CARET) != 0;
2449                 pFrame->mbHandleIME = !pFrame->mbSpezIME;
2450             }
2451         }
2452 
2453         // When the application can't handle IME messages, then the
2454         // System should handle the IME handling
2455         if ( !(pContext->mnOptions & SAL_INPUTCONTEXT_EXTTEXTINPUT) )
2456             pFrame->mbHandleIME = FALSE;
2457 
2458         // Set the Font for IME Handling
2459         if ( pContext->mpFont )
2460         {
2461             HIMC hIMC = ImmGetContext( pFrame->mhWnd );
2462             if ( hIMC )
2463             {
2464                 LOGFONTW aLogFont;
2465                 HDC hDC = GetDC( pFrame->mhWnd );
2466                 // In case of vertical writing, always append a '@' to the
2467                 // Windows font name, not only if such a Windows font really is
2468                 // available (bTestVerticalAvail == false in the below call):
2469                 // The Windows IME's candidates window seems to always use a
2470                 // font that has all necessary glyphs, not necessarily the one
2471                 // specified by this font name; but it seems to decide whether
2472                 // to use that font's horizontal or vertical variant based on a
2473                 // '@' in front of this font name.
2474                 ImplGetLogFontFromFontSelect( hDC, pContext->mpFont, aLogFont,
2475                                               false );
2476                 ReleaseDC( pFrame->mhWnd, hDC );
2477                 ImmSetCompositionFontW( hIMC, &aLogFont );
2478                 ImmReleaseContext( pFrame->mhWnd, hIMC );
2479             }
2480         }
2481     }
2482     else
2483     {
2484         if ( pFrame->mbIME )
2485         {
2486             pFrame->mbIME = FALSE;
2487             pFrame->mbHandleIME = FALSE;
2488             ImmAssociateContext( pFrame->mhWnd, 0 );
2489         }
2490     }
2491 }
2492 
2493 // -----------------------------------------------------------------------
2494 
2495 void WinSalFrame::SetInputContext( SalInputContext* pContext )
2496 {
2497     // Must be called in the main thread!
2498     ImplSendMessage( mhWnd, SAL_MSG_SETINPUTCONTEXT, 0, (LPARAM)(void*)pContext );
2499 }
2500 
2501 // -----------------------------------------------------------------------
2502 
2503 static void ImplSalFrameEndExtTextInput( HWND hWnd, sal_uInt16 nFlags )
2504 {
2505     HIMC hIMC = ImmGetContext( hWnd );
2506     if ( hIMC )
2507     {
2508         DWORD nIndex;
2509         if ( nFlags & SAL_FRAME_ENDEXTTEXTINPUT_COMPLETE )
2510             nIndex = CPS_COMPLETE;
2511         else
2512             nIndex = CPS_CANCEL;
2513 
2514         ImmNotifyIME( hIMC, NI_COMPOSITIONSTR, nIndex, 0 );
2515         ImmReleaseContext( hWnd, hIMC );
2516     }
2517 }
2518 
2519 // -----------------------------------------------------------------------
2520 
2521 void WinSalFrame::EndExtTextInput( sal_uInt16 nFlags )
2522 {
2523     // Must be called in the main thread!
2524     ImplSendMessage( mhWnd, SAL_MSG_ENDEXTTEXTINPUT, (WPARAM)nFlags, 0 );
2525 }
2526 
2527 // -----------------------------------------------------------------------
2528 
2529 static void ImplGetKeyNameText( LONG lParam, sal_Unicode* pBuf,
2530                                 UINT& rCount, UINT nMaxSize,
2531                                 const sal_Char* pReplace )
2532 {
2533     DBG_ASSERT( sizeof( WCHAR ) == sizeof( xub_Unicode ), "WinSalFrame::ImplGetKeyNameTextW(): WCHAR != sal_Unicode" );
2534 
2535     static const int nMaxKeyLen = 350;
2536     WCHAR aKeyBuf[ nMaxKeyLen ];
2537     int nKeyLen = 0;
2538     if ( lParam )
2539     {
2540         if ( true/*aSalShlData.mbWNT*/ )
2541         {
2542             nKeyLen = GetKeyNameTextW( lParam, aKeyBuf, nMaxKeyLen );
2543             DBG_ASSERT( nKeyLen <= nMaxKeyLen, "Invalid key name length!" );
2544             if( nKeyLen > nMaxKeyLen )
2545                 nKeyLen = 0;
2546             else if( nKeyLen > 0 )
2547             {
2548                 // Capitalize just the first letter of key names
2549                 CharLowerBuffW( aKeyBuf, nKeyLen );
2550 
2551                 bool bUpper = true;
2552                 for( WCHAR *pW=aKeyBuf, *pE=pW+nKeyLen; pW < pE; ++pW )
2553                 {
2554                     if( bUpper )
2555                         CharUpperBuffW( pW, 1 );
2556                     bUpper = (*pW=='+') || (*pW=='-') || (*pW==' ') || (*pW=='.');
2557                 }
2558             }
2559         }
2560     }
2561 
2562     if ( (nKeyLen > 0) || pReplace )
2563     {
2564         if( (rCount > 0) && (rCount < nMaxSize) )
2565         {
2566             pBuf[rCount] = '+';
2567             rCount++;
2568         }
2569 
2570         if( nKeyLen > 0 )
2571         {
2572             if( nKeyLen + rCount > nMaxSize )
2573                 nKeyLen = nMaxSize - rCount;
2574             memcpy( pBuf+rCount, aKeyBuf, nKeyLen*sizeof( sal_Unicode ) );
2575             rCount += nKeyLen;
2576         }
2577         else // fall back to provided default name
2578         {
2579             while( *pReplace && (rCount < nMaxSize) )
2580             {
2581                 pBuf[rCount] = *pReplace;
2582                 rCount++;
2583                 pReplace++;
2584             }
2585         }
2586     }
2587     else
2588         rCount = 0;
2589 }
2590 
2591 // -----------------------------------------------------------------------
2592 
2593 XubString WinSalFrame::GetKeyName( sal_uInt16 nKeyCode )
2594 {
2595     static const int nMaxKeyLen = 350;
2596     sal_Unicode aKeyBuf[ nMaxKeyLen ];
2597     UINT        nKeyBufLen = 0;
2598     UINT        nSysCode = 0;
2599 
2600     if ( nKeyCode & KEY_MOD1 )
2601     {
2602         nSysCode = MapVirtualKey( VK_CONTROL, 0 );
2603         nSysCode = (nSysCode << 16) | (((sal_uLong)1) << 25);
2604         ImplGetKeyNameText( nSysCode, aKeyBuf, nKeyBufLen, nMaxKeyLen, "Ctrl" );
2605     }
2606 
2607     if ( nKeyCode & KEY_MOD2 )
2608     {
2609         nSysCode = MapVirtualKey( VK_MENU, 0 );
2610         nSysCode = (nSysCode << 16) | (((sal_uLong)1) << 25);
2611         ImplGetKeyNameText( nSysCode, aKeyBuf, nKeyBufLen, nMaxKeyLen, "Alt" );
2612     }
2613 
2614     if ( nKeyCode & KEY_SHIFT )
2615     {
2616         nSysCode = MapVirtualKey( VK_SHIFT, 0 );
2617         nSysCode = (nSysCode << 16) | (((sal_uLong)1) << 25);
2618         ImplGetKeyNameText( nSysCode, aKeyBuf, nKeyBufLen, nMaxKeyLen, "Shift" );
2619     }
2620 
2621     sal_uInt16      nCode = nKeyCode & 0x0FFF;
2622     sal_uLong       nSysCode2 = 0;
2623     sal_Char*   pReplace = NULL;
2624     sal_Unicode cSVCode = 0;
2625     sal_Char    aFBuf[4];
2626     nSysCode = 0;
2627 
2628     if ( (nCode >= KEY_0) && (nCode <= KEY_9) )
2629         cSVCode = '0' + (nCode - KEY_0);
2630     else if ( (nCode >= KEY_A) && (nCode <= KEY_Z) )
2631         cSVCode = 'A' + (nCode - KEY_A);
2632     else if ( (nCode >= KEY_F1) && (nCode <= KEY_F26) )
2633     {
2634         nSysCode = VK_F1 + (nCode - KEY_F1);
2635         aFBuf[0] = 'F';
2636         if ( (nCode >= KEY_F1) && (nCode <= KEY_F9) )
2637         {
2638             aFBuf[1] = sal::static_int_cast<sal_Char>('1' + (nCode - KEY_F1));
2639             aFBuf[2] = 0;
2640         }
2641         else if ( (nCode >= KEY_F10) && (nCode <= KEY_F19) )
2642         {
2643             aFBuf[1] = '1';
2644             aFBuf[2] = sal::static_int_cast<sal_Char>('0' + (nCode - KEY_F10));
2645             aFBuf[3] = 0;
2646         }
2647         else
2648         {
2649             aFBuf[1] = '2';
2650             aFBuf[2] = sal::static_int_cast<sal_Char>('0' + (nCode - KEY_F20));
2651             aFBuf[3] = 0;
2652         }
2653         pReplace = aFBuf;
2654     }
2655     else
2656     {
2657         switch ( nCode )
2658         {
2659             case KEY_DOWN:
2660                 nSysCode = VK_DOWN;
2661                 nSysCode2 = (((sal_uLong)1) << 24);
2662                 pReplace = "Down";
2663                 break;
2664             case KEY_UP:
2665                 nSysCode = VK_UP;
2666                 nSysCode2 = (((sal_uLong)1) << 24);
2667                 pReplace = "Up";
2668                 break;
2669             case KEY_LEFT:
2670                 nSysCode = VK_LEFT;
2671                 nSysCode2 = (((sal_uLong)1) << 24);
2672                 pReplace = "Left";
2673                 break;
2674             case KEY_RIGHT:
2675                 nSysCode = VK_RIGHT;
2676                 nSysCode2 = (((sal_uLong)1) << 24);
2677                 pReplace = "Right";
2678                 break;
2679             case KEY_HOME:
2680                 nSysCode = VK_HOME;
2681                 nSysCode2 = (((sal_uLong)1) << 24);
2682                 pReplace = "Home";
2683                 break;
2684             case KEY_END:
2685                 nSysCode = VK_END;
2686                 nSysCode2 = (((sal_uLong)1) << 24);
2687                 pReplace = "End";
2688                 break;
2689             case KEY_PAGEUP:
2690                 nSysCode = VK_PRIOR;
2691                 nSysCode2 = (((sal_uLong)1) << 24);
2692                 pReplace = "Page Up";
2693                 break;
2694             case KEY_PAGEDOWN:
2695                 nSysCode = VK_NEXT;
2696                 nSysCode2 = (((sal_uLong)1) << 24);
2697                 pReplace = "Page Down";
2698                 break;
2699             case KEY_RETURN:
2700                 nSysCode = VK_RETURN;
2701                 pReplace = "Enter";
2702                 break;
2703             case KEY_ESCAPE:
2704                 nSysCode = VK_ESCAPE;
2705                 pReplace = "Escape";
2706                 break;
2707             case KEY_TAB:
2708                 nSysCode = VK_TAB;
2709                 pReplace = "Tab";
2710                 break;
2711             case KEY_BACKSPACE:
2712                 nSysCode = VK_BACK;
2713                 pReplace = "Backspace";
2714                 break;
2715             case KEY_SPACE:
2716                 nSysCode = VK_SPACE;
2717                 pReplace = "Space";
2718                 break;
2719             case KEY_INSERT:
2720                 nSysCode = VK_INSERT;
2721                 nSysCode2 = (((sal_uLong)1) << 24);
2722                 pReplace = "Insert";
2723                 break;
2724             case KEY_DELETE:
2725                 nSysCode = VK_DELETE;
2726                 nSysCode2 = (((sal_uLong)1) << 24);
2727                 pReplace = "Delete";
2728                 break;
2729 
2730             case KEY_ADD:
2731                 cSVCode  = '+';
2732                 break;
2733             case KEY_SUBTRACT:
2734                 cSVCode  = '-';
2735                 break;
2736             case KEY_MULTIPLY:
2737                 cSVCode  = '*';
2738                 break;
2739             case KEY_DIVIDE:
2740                 cSVCode  = '/';
2741                 break;
2742             case KEY_POINT:
2743                 cSVCode  = '.';
2744                 break;
2745             case KEY_COMMA:
2746                 cSVCode  = ',';
2747                 break;
2748             case KEY_LESS:
2749                 cSVCode  = '<';
2750                 break;
2751             case KEY_GREATER:
2752                 cSVCode  = '>';
2753                 break;
2754             case KEY_EQUAL:
2755                 cSVCode  = '=';
2756                 break;
2757         }
2758     }
2759 
2760     if ( nSysCode )
2761     {
2762         nSysCode = MapVirtualKey( (UINT)nSysCode, 0 );
2763         if ( nSysCode )
2764             nSysCode = (nSysCode << 16) | nSysCode2;
2765         ImplGetKeyNameText( nSysCode, aKeyBuf, nKeyBufLen, nMaxKeyLen, pReplace );
2766     }
2767     else
2768     {
2769         if ( cSVCode )
2770         {
2771             if ( nKeyBufLen > 0 )
2772                 aKeyBuf[ nKeyBufLen++ ] = '+';
2773             if( nKeyBufLen < nMaxKeyLen )
2774                 aKeyBuf[ nKeyBufLen++ ] = cSVCode;
2775         }
2776     }
2777 
2778     if( !nKeyBufLen )
2779         return XubString();
2780 
2781     return XubString( aKeyBuf, sal::static_int_cast< sal_uInt16 >(nKeyBufLen) );
2782 }
2783 
2784 // -----------------------------------------------------------------------
2785 
2786 XubString WinSalFrame::GetSymbolKeyName( const XubString&, sal_uInt16 nKeyCode )
2787 {
2788     return GetKeyName( nKeyCode );
2789 }
2790 
2791 // -----------------------------------------------------------------------
2792 
2793 inline Color ImplWinColorToSal( COLORREF nColor )
2794 {
2795     return Color( GetRValue( nColor ), GetGValue( nColor ), GetBValue( nColor ) );
2796 }
2797 
2798 // -----------------------------------------------------------------------
2799 
2800 static void ImplSalUpdateStyleFontA( HDC hDC, const LOGFONTA& rLogFont, Font& rFont )
2801 {
2802     ImplSalLogFontToFontA( hDC, rLogFont, rFont );
2803 
2804     // On Windows 9x, Windows NT we get sometimes very small sizes
2805     // (for example for the small Caption height).
2806     // So if it is MS Sans Serif, a none scalable font we use
2807     // 8 Point as the minimum control height, in all other cases
2808     // 6 Point is the smallest one
2809     if ( rFont.GetHeight() < 8 )
2810     {
2811         if ( rtl_str_compareIgnoreAsciiCase( rLogFont.lfFaceName, "MS Sans Serif" ) == 0 )
2812             rFont.SetHeight( 8 );
2813         else if ( rFont.GetHeight() < 6 )
2814             rFont.SetHeight( 6 );
2815     }
2816 }
2817 
2818 // -----------------------------------------------------------------------
2819 
2820 static void ImplSalUpdateStyleFontW( HDC hDC, const LOGFONTW& rLogFont, Font& rFont )
2821 {
2822     ImplSalLogFontToFontW( hDC, rLogFont, rFont );
2823 
2824     // On Windows 9x, Windows NT we get sometimes very small sizes
2825     // (for example for the small Caption height).
2826     // So if it is MS Sans Serif, a none scalable font we use
2827     // 8 Point as the minimum control height, in all other cases
2828     // 6 Point is the smallest one
2829     if ( rFont.GetHeight() < 8 )
2830     {
2831         if ( rtl_ustr_compareIgnoreAsciiCase( reinterpret_cast<const sal_Unicode*>(rLogFont.lfFaceName), reinterpret_cast<const sal_Unicode*>(L"MS Sans Serif") ) == 0 )
2832             rFont.SetHeight( 8 );
2833         else if ( rFont.GetHeight() < 6 )
2834             rFont.SetHeight( 6 );
2835     }
2836 }
2837 
2838 // -----------------------------------------------------------------------
2839 
2840 static long ImplA2I( const BYTE* pStr )
2841 {
2842     long    n = 0;
2843     int     nSign = 1;
2844 
2845     if ( *pStr == '-' )
2846     {
2847         nSign = -1;
2848         pStr++;
2849     }
2850 
2851     while( (*pStr >= 48) && (*pStr <= 57) )
2852     {
2853         n *= 10;
2854         n += ((*pStr) - 48);
2855         pStr++;
2856     }
2857 
2858     n *= nSign;
2859 
2860     return n;
2861 }
2862 
2863 // -----------------------------------------------------------------------
2864 static HRESULT WINAPI backwardCompatibleDwmIsCompositionEnabled( BOOL* pOut )
2865 {
2866     *pOut = FALSE;
2867     return S_OK;
2868 }
2869 
2870 static BOOL ImplDwmIsCompositionEnabled()
2871 {
2872     SalData* pSalData = GetSalData();
2873     if( ! pSalData->mpDwmIsCompositionEnabled )
2874     {
2875         pSalData->maDwmLib = osl_loadAsciiModule( "Dwmapi.dll", SAL_LOADMODULE_DEFAULT );
2876         if( pSalData->maDwmLib )
2877             pSalData->mpDwmIsCompositionEnabled = (DwmIsCompositionEnabled_ptr)osl_getAsciiFunctionSymbol( pSalData->maDwmLib, "DwmIsCompositionEnabled" );
2878         if( ! pSalData->mpDwmIsCompositionEnabled ) // something failed
2879             pSalData->mpDwmIsCompositionEnabled = backwardCompatibleDwmIsCompositionEnabled;
2880     }
2881     BOOL aResult = FALSE;
2882     HRESULT nError = pSalData->mpDwmIsCompositionEnabled( &aResult );
2883     return nError == S_OK && aResult;
2884 }
2885 
2886 
2887 void WinSalFrame::UpdateSettings( AllSettings& rSettings )
2888 {
2889     MouseSettings aMouseSettings = rSettings.GetMouseSettings();
2890     aMouseSettings.SetDoubleClickTime( GetDoubleClickTime() );
2891     aMouseSettings.SetDoubleClickWidth( GetSystemMetrics( SM_CXDOUBLECLK ) );
2892     aMouseSettings.SetDoubleClickHeight( GetSystemMetrics( SM_CYDOUBLECLK ) );
2893     long nDragWidth = GetSystemMetrics( SM_CXDRAG );
2894     long nDragHeight = GetSystemMetrics( SM_CYDRAG );
2895     if ( nDragWidth )
2896         aMouseSettings.SetStartDragWidth( nDragWidth );
2897     if ( nDragHeight )
2898         aMouseSettings.SetStartDragHeight( nDragHeight );
2899     HKEY hRegKey;
2900     if ( RegOpenKey( HKEY_CURRENT_USER,
2901                      "Control Panel\\Desktop",
2902                      &hRegKey ) == ERROR_SUCCESS )
2903     {
2904         BYTE    aValueBuf[10];
2905         DWORD   nValueSize = sizeof( aValueBuf );
2906         DWORD   nType;
2907         if ( RegQueryValueEx( hRegKey, "MenuShowDelay", 0,
2908                               &nType, aValueBuf, &nValueSize ) == ERROR_SUCCESS )
2909         {
2910             if ( nType == REG_SZ )
2911                 aMouseSettings.SetMenuDelay( (sal_uLong)ImplA2I( aValueBuf ) );
2912         }
2913 
2914         RegCloseKey( hRegKey );
2915     }
2916 
2917     StyleSettings aStyleSettings = rSettings.GetStyleSettings();
2918     // TODO: once those options vanish: just set bCompBorder to TRUE
2919     // to have the system colors read
2920     aStyleSettings.SetScrollBarSize( GetSystemMetrics( SM_CXVSCROLL ) );
2921     aStyleSettings.SetSpinSize( GetSystemMetrics( SM_CXVSCROLL ) );
2922     aStyleSettings.SetCursorBlinkTime( GetCaretBlinkTime() );
2923     aStyleSettings.SetFloatTitleHeight( GetSystemMetrics( SM_CYSMCAPTION ) );
2924     aStyleSettings.SetTitleHeight( GetSystemMetrics( SM_CYCAPTION ) );
2925     aStyleSettings.SetActiveBorderColor( ImplWinColorToSal( GetSysColor( COLOR_ACTIVEBORDER ) ) );
2926     aStyleSettings.SetDeactiveBorderColor( ImplWinColorToSal( GetSysColor( COLOR_INACTIVEBORDER ) ) );
2927     if ( aSalShlData.mnVersion >= 410 )
2928     {
2929         aStyleSettings.SetActiveColor2( ImplWinColorToSal( GetSysColor( COLOR_GRADIENTACTIVECAPTION ) ) );
2930         aStyleSettings.SetDeactiveColor( ImplWinColorToSal( GetSysColor( COLOR_GRADIENTINACTIVECAPTION ) ) );
2931     }
2932     aStyleSettings.SetFaceColor( ImplWinColorToSal( GetSysColor( COLOR_3DFACE ) ) );
2933     aStyleSettings.SetInactiveTabColor( aStyleSettings.GetFaceColor() );
2934     aStyleSettings.SetLightColor( ImplWinColorToSal( GetSysColor( COLOR_3DHILIGHT ) ) );
2935     aStyleSettings.SetLightBorderColor( ImplWinColorToSal( GetSysColor( COLOR_3DLIGHT ) ) );
2936     aStyleSettings.SetShadowColor( ImplWinColorToSal( GetSysColor( COLOR_3DSHADOW ) ) );
2937     aStyleSettings.SetDarkShadowColor( ImplWinColorToSal( GetSysColor( COLOR_3DDKSHADOW ) ) );
2938     aStyleSettings.SetWorkspaceColor( ImplWinColorToSal( GetSysColor( COLOR_APPWORKSPACE ) ) );
2939     aStyleSettings.SetHelpColor( ImplWinColorToSal( GetSysColor( COLOR_INFOBK ) ) );
2940     aStyleSettings.SetHelpTextColor( ImplWinColorToSal( GetSysColor( COLOR_INFOTEXT ) ) );
2941     aStyleSettings.SetDialogColor( aStyleSettings.GetFaceColor() );
2942     aStyleSettings.SetDialogTextColor( aStyleSettings.GetButtonTextColor() );
2943     aStyleSettings.SetButtonTextColor( ImplWinColorToSal( GetSysColor( COLOR_BTNTEXT ) ) );
2944     aStyleSettings.SetButtonRolloverTextColor( aStyleSettings.GetButtonTextColor() );
2945     aStyleSettings.SetRadioCheckTextColor( ImplWinColorToSal( GetSysColor( COLOR_WINDOWTEXT ) ) );
2946     aStyleSettings.SetGroupTextColor( aStyleSettings.GetRadioCheckTextColor() );
2947     aStyleSettings.SetLabelTextColor( aStyleSettings.GetRadioCheckTextColor() );
2948     aStyleSettings.SetInfoTextColor( aStyleSettings.GetRadioCheckTextColor() );
2949     aStyleSettings.SetWindowColor( ImplWinColorToSal( GetSysColor( COLOR_WINDOW ) ) );
2950     aStyleSettings.SetActiveTabColor( aStyleSettings.GetWindowColor() );
2951     aStyleSettings.SetWindowTextColor( ImplWinColorToSal( GetSysColor( COLOR_WINDOWTEXT ) ) );
2952     aStyleSettings.SetFieldColor( aStyleSettings.GetWindowColor() );
2953     aStyleSettings.SetFieldTextColor( aStyleSettings.GetWindowTextColor() );
2954     aStyleSettings.SetFieldRolloverTextColor( aStyleSettings.GetFieldTextColor() );
2955     aStyleSettings.SetHighlightColor( ImplWinColorToSal( GetSysColor( COLOR_HIGHLIGHT ) ) );
2956     aStyleSettings.SetHighlightTextColor( ImplWinColorToSal( GetSysColor( COLOR_HIGHLIGHTTEXT ) ) );
2957     aStyleSettings.SetMenuHighlightColor( aStyleSettings.GetHighlightColor() );
2958     aStyleSettings.SetMenuHighlightTextColor( aStyleSettings.GetHighlightTextColor() );
2959 
2960     ImplSVData* pSVData = ImplGetSVData();
2961     pSVData->maNWFData.mnMenuFormatExtraBorder = 0;
2962     pSVData->maNWFData.maMenuBarHighlightTextColor = Color( COL_TRANSPARENT );
2963     GetSalData()->mbThemeMenuSupport = FALSE;
2964     aStyleSettings.SetMenuColor( ImplWinColorToSal( GetSysColor( COLOR_MENU ) ) );
2965     aStyleSettings.SetMenuBarColor( aStyleSettings.GetMenuColor() );
2966     aStyleSettings.SetMenuBorderColor( aStyleSettings.GetLightBorderColor() ); // overriden below for flat menus
2967     aStyleSettings.SetUseFlatBorders( FALSE );
2968     aStyleSettings.SetUseFlatMenues( FALSE );
2969     aStyleSettings.SetMenuTextColor( ImplWinColorToSal( GetSysColor( COLOR_MENUTEXT ) ) );
2970     aStyleSettings.SetMenuBarTextColor( ImplWinColorToSal( GetSysColor( COLOR_MENUTEXT ) ) );
2971     aStyleSettings.SetActiveColor( ImplWinColorToSal( GetSysColor( COLOR_ACTIVECAPTION ) ) );
2972     aStyleSettings.SetActiveTextColor( ImplWinColorToSal( GetSysColor( COLOR_CAPTIONTEXT ) ) );
2973     aStyleSettings.SetDeactiveColor( ImplWinColorToSal( GetSysColor( COLOR_INACTIVECAPTION ) ) );
2974     aStyleSettings.SetDeactiveTextColor( ImplWinColorToSal( GetSysColor( COLOR_INACTIVECAPTIONTEXT ) ) );
2975     if ( aSalShlData.mbWXP )
2976     {
2977         // only xp supports a different menu bar color
2978         long bFlatMenues = 0;
2979         SystemParametersInfo( SPI_GETFLATMENU, 0, &bFlatMenues, 0);
2980         if( bFlatMenues )
2981         {
2982             aStyleSettings.SetUseFlatMenues( TRUE );
2983             aStyleSettings.SetMenuBarColor( ImplWinColorToSal( GetSysColor( COLOR_MENUBAR ) ) );
2984             aStyleSettings.SetMenuHighlightColor( ImplWinColorToSal( GetSysColor( COLOR_MENUHILIGHT ) ) );
2985             aStyleSettings.SetMenuBorderColor( ImplWinColorToSal( GetSysColor( COLOR_3DSHADOW ) ) );
2986 
2987             // flat borders for our controls etc. as well in this mode (ie, no 3d borders)
2988             // this is not active in the classic style appearance
2989             aStyleSettings.SetUseFlatBorders( TRUE );
2990         }
2991     }
2992     // check if vista or newer runs
2993     // in Aero theme (and similar ?) the menu text color does not change
2994     // for selected items; also on WinXP and earlier menus are not themed
2995     if( aSalShlData.maVersionInfo.dwMajorVersion >= 6 &&
2996        ImplDwmIsCompositionEnabled()
2997        )
2998     {
2999         // in aero menuitem highlight text is drawn in the same color as normal
3000         aStyleSettings.SetMenuHighlightTextColor( aStyleSettings.GetMenuTextColor() );
3001         pSVData->maNWFData.mnMenuFormatExtraBorder = 2;
3002         pSVData->maNWFData.maMenuBarHighlightTextColor = aStyleSettings.GetMenuTextColor();
3003         GetSalData()->mbThemeMenuSupport = TRUE;
3004     }
3005     // Bei hellgrau geben wir die Farbe vor, damit es besser aussieht
3006     if ( aStyleSettings.GetFaceColor() == COL_LIGHTGRAY )
3007         aStyleSettings.SetCheckedColor( Color( 0xCC, 0xCC, 0xCC ) );
3008     else
3009     {
3010         // Checked-Color berechnen
3011         Color   aColor1 = aStyleSettings.GetFaceColor();
3012         Color   aColor2 = aStyleSettings.GetLightColor();
3013         BYTE    nRed    = (BYTE)(((sal_uInt16)aColor1.GetRed()   + (sal_uInt16)aColor2.GetRed())/2);
3014         BYTE    nGreen  = (BYTE)(((sal_uInt16)aColor1.GetGreen() + (sal_uInt16)aColor2.GetGreen())/2);
3015         BYTE    nBlue   = (BYTE)(((sal_uInt16)aColor1.GetBlue()  + (sal_uInt16)aColor2.GetBlue())/2);
3016         aStyleSettings.SetCheckedColor( Color( nRed, nGreen, nBlue ) );
3017     }
3018 
3019     // caret width
3020     DWORD nCaretWidth = 2;
3021     if( SystemParametersInfo( SPI_GETCARETWIDTH, 0, &nCaretWidth, 0 ) )
3022         aStyleSettings.SetCursorSize( nCaretWidth );
3023 
3024 	// High contrast
3025 	HIGHCONTRAST hc;
3026 	hc.cbSize = sizeof( HIGHCONTRAST );
3027 	if( SystemParametersInfo( SPI_GETHIGHCONTRAST, hc.cbSize, &hc, 0) && (hc.dwFlags & HCF_HIGHCONTRASTON) )
3028 		aStyleSettings.SetHighContrastMode( 1 );
3029 	else
3030 		aStyleSettings.SetHighContrastMode( 0 );
3031 
3032 
3033     // Query Fonts
3034     Font    aMenuFont = aStyleSettings.GetMenuFont();
3035     Font    aTitleFont = aStyleSettings.GetTitleFont();
3036     Font    aFloatTitleFont = aStyleSettings.GetFloatTitleFont();
3037     Font    aHelpFont = aStyleSettings.GetHelpFont();
3038     Font    aAppFont = aStyleSettings.GetAppFont();
3039     Font    aIconFont = aStyleSettings.GetIconFont();
3040     HDC     hDC = GetDC( 0 );
3041     if( true/*aSalShlData.mbWNT*/ )
3042     {
3043         NONCLIENTMETRICSW aNonClientMetrics;
3044         aNonClientMetrics.cbSize = sizeof( aNonClientMetrics );
3045         if ( SystemParametersInfoW( SPI_GETNONCLIENTMETRICS, sizeof( aNonClientMetrics ), &aNonClientMetrics, 0 ) )
3046         {
3047             ImplSalUpdateStyleFontW( hDC, aNonClientMetrics.lfMenuFont, aMenuFont );
3048             ImplSalUpdateStyleFontW( hDC, aNonClientMetrics.lfCaptionFont, aTitleFont );
3049             ImplSalUpdateStyleFontW( hDC, aNonClientMetrics.lfSmCaptionFont, aFloatTitleFont );
3050             ImplSalUpdateStyleFontW( hDC, aNonClientMetrics.lfStatusFont, aHelpFont );
3051             ImplSalUpdateStyleFontW( hDC, aNonClientMetrics.lfMessageFont, aAppFont );
3052 
3053             LOGFONTW aLogFont;
3054             if ( SystemParametersInfoW( SPI_GETICONTITLELOGFONT, 0, &aLogFont, 0 ) )
3055                 ImplSalUpdateStyleFontW( hDC, aLogFont, aIconFont );
3056         }
3057     }
3058 
3059     // get screen font resolution to calculate toolbox item size
3060 	long nDPIY = GetDeviceCaps( hDC, LOGPIXELSY );
3061 
3062     ReleaseDC( 0, hDC );
3063 
3064     long nHeightPx = aMenuFont.GetHeight() * nDPIY / 72;
3065     aStyleSettings.SetToolbarIconSize( (((nHeightPx-1)*2) >= 28) ? STYLE_TOOLBAR_ICONSIZE_LARGE : STYLE_TOOLBAR_ICONSIZE_SMALL );
3066 
3067     aStyleSettings.SetMenuFont( aMenuFont );
3068     aStyleSettings.SetTitleFont( aTitleFont );
3069     aStyleSettings.SetFloatTitleFont( aFloatTitleFont );
3070     aStyleSettings.SetHelpFont( aHelpFont );
3071     aStyleSettings.SetIconFont( aIconFont );
3072     // We prefer Arial in the russian version, because MS Sans Serif
3073     // is to wide for the dialogs
3074     if ( rSettings.GetLanguage() == LANGUAGE_RUSSIAN )
3075     {
3076         XubString aFontName = aAppFont.GetName();
3077         XubString aFirstName = aFontName.GetToken( 0, ';' );
3078         if ( aFirstName.EqualsIgnoreCaseAscii( "MS Sans Serif" ) )
3079         {
3080             aFontName.InsertAscii( "Arial;", 0 );
3081             aAppFont.SetName( aFontName );
3082         }
3083     }
3084     aStyleSettings.SetAppFont( aAppFont );
3085     aStyleSettings.SetGroupFont( aAppFont );
3086     aStyleSettings.SetLabelFont( aAppFont );
3087     aStyleSettings.SetRadioCheckFont( aAppFont );
3088     aStyleSettings.SetPushButtonFont( aAppFont );
3089     aStyleSettings.SetFieldFont( aAppFont );
3090     if ( aAppFont.GetWeight() > WEIGHT_NORMAL )
3091         aAppFont.SetWeight( WEIGHT_NORMAL );
3092     aStyleSettings.SetInfoFont( aAppFont );
3093     aStyleSettings.SetToolFont( aAppFont );
3094 
3095     BOOL bDragFull;
3096     if ( SystemParametersInfo( SPI_GETDRAGFULLWINDOWS, 0, &bDragFull, 0 ) )
3097     {
3098         sal_uLong nDragFullOptions = aStyleSettings.GetDragFullOptions();
3099         if ( bDragFull )
3100             nDragFullOptions |=  DRAGFULL_OPTION_WINDOWMOVE | DRAGFULL_OPTION_WINDOWSIZE | DRAGFULL_OPTION_DOCKING | DRAGFULL_OPTION_SPLIT;
3101         else
3102             nDragFullOptions &= ~(DRAGFULL_OPTION_WINDOWMOVE | DRAGFULL_OPTION_WINDOWSIZE | DRAGFULL_OPTION_DOCKING | DRAGFULL_OPTION_SPLIT);
3103         aStyleSettings.SetDragFullOptions( nDragFullOptions );
3104     }
3105 
3106     aStyleSettings.SetIconHorzSpace( GetSystemMetrics( SM_CXICONSPACING ) );
3107     aStyleSettings.SetIconVertSpace( GetSystemMetrics( SM_CYICONSPACING ) );
3108     if ( RegOpenKey( HKEY_CURRENT_USER,
3109                      "Control Panel\\International\\Calendars\\TwoDigitYearMax",
3110                      &hRegKey ) == ERROR_SUCCESS )
3111     {
3112         BYTE    aValueBuf[10];
3113         DWORD   nValue;
3114         DWORD   nValueSize = sizeof( aValueBuf );
3115         DWORD   nType;
3116         if ( RegQueryValueEx( hRegKey, "1", 0,
3117                               &nType, aValueBuf, &nValueSize ) == ERROR_SUCCESS )
3118         {
3119             if ( nType == REG_SZ )
3120             {
3121                 nValue = (sal_uLong)ImplA2I( aValueBuf );
3122                 if ( (nValue > 1000) && (nValue < 10000) )
3123                 {
3124                     MiscSettings aMiscSettings = rSettings.GetMiscSettings();
3125 					utl::MiscCfg().SetYear2000( (sal_Int32)(nValue-99) );
3126                     rSettings.SetMiscSettings( aMiscSettings );
3127                 }
3128             }
3129         }
3130 
3131         RegCloseKey( hRegKey );
3132     }
3133 
3134     rSettings.SetMouseSettings( aMouseSettings );
3135     rSettings.SetStyleSettings( aStyleSettings );
3136 }
3137 
3138 // -----------------------------------------------------------------------
3139 
3140 SalBitmap* WinSalFrame::SnapShot()
3141 {
3142     WinSalBitmap* pSalBitmap = NULL;
3143 
3144     RECT aRect;
3145     GetWindowRect( mhWnd, &aRect );
3146 
3147     int     nDX = aRect.right-aRect.left;
3148     int     nDY = aRect.bottom-aRect.top;
3149     HDC     hDC = GetWindowDC( mhWnd );
3150     HBITMAP hBmpBitmap = CreateCompatibleBitmap( hDC, nDX, nDY );
3151     HDC     hBmpDC = ImplGetCachedDC( CACHED_HDC_1, hBmpBitmap );
3152     sal_Bool    bRet;
3153 
3154     bRet = BitBlt( hBmpDC, 0, 0, nDX, nDY, hDC, 0, 0, SRCCOPY ) ? TRUE : FALSE;
3155     ImplReleaseCachedDC( CACHED_HDC_1 );
3156 
3157     if ( bRet )
3158     {
3159         pSalBitmap = new WinSalBitmap;
3160 
3161         if ( !pSalBitmap->Create( hBmpBitmap, FALSE, FALSE ) )
3162         {
3163             delete pSalBitmap;
3164             pSalBitmap = NULL;
3165         }
3166     }
3167 
3168     return pSalBitmap;
3169 }
3170 
3171 // -----------------------------------------------------------------------
3172 
3173 const SystemEnvData* WinSalFrame::GetSystemData() const
3174 {
3175     return &maSysData;
3176 }
3177 
3178 // -----------------------------------------------------------------------
3179 
3180 void WinSalFrame::Beep( SoundType eSoundType )
3181 {
3182     static UINT aImplSoundTab[5] =
3183     {
3184         0,                              // SOUND_DEFAULT
3185         MB_ICONASTERISK,                // SOUND_INFO
3186         MB_ICONEXCLAMATION,             // SOUND_WARNING
3187         MB_ICONHAND,                    // SOUND_ERROR
3188         MB_ICONQUESTION                 // SOUND_QUERY
3189     };
3190 
3191     if( eSoundType != SOUND_DISABLE ) // don't beep on disable
3192         MessageBeep( aImplSoundTab[eSoundType] );
3193 }
3194 
3195 // -----------------------------------------------------------------------
3196 
3197 SalFrame::SalPointerState WinSalFrame::GetPointerState()
3198 {
3199     SalPointerState aState;
3200     aState.mnState = 0;
3201 
3202     if ( GetKeyState( VK_LBUTTON ) & 0x8000 )
3203         aState.mnState |= MOUSE_LEFT;
3204     if ( GetKeyState( VK_MBUTTON ) & 0x8000 )
3205         aState.mnState |= MOUSE_MIDDLE;
3206     if ( GetKeyState( VK_RBUTTON ) & 0x8000 )
3207         aState.mnState |= MOUSE_RIGHT;
3208     if ( GetKeyState( VK_SHIFT ) & 0x8000 )
3209         aState.mnState |= KEY_SHIFT;
3210     if ( GetKeyState( VK_CONTROL ) & 0x8000 )
3211         aState.mnState |= KEY_MOD1;
3212     if ( GetKeyState( VK_MENU ) & 0x8000 )
3213         aState.mnState |= KEY_MOD2;
3214 
3215     POINT pt;
3216     GetCursorPos( &pt );
3217 
3218     aState.maPos = Point( pt.x - maGeometry.nX, pt.y - maGeometry.nY );
3219     return aState;
3220 }
3221 
3222 // -----------------------------------------------------------------------
3223 
3224 void WinSalFrame::SetBackgroundBitmap( SalBitmap* )
3225 {
3226 }
3227 
3228 // -----------------------------------------------------------------------
3229 
3230 void WinSalFrame::ResetClipRegion()
3231 {
3232 	SetWindowRgn( mhWnd, 0, TRUE );
3233 }
3234 
3235 // -----------------------------------------------------------------------
3236 
3237 void WinSalFrame::BeginSetClipRegion( sal_uLong nRects )
3238 {
3239     if( mpClipRgnData )
3240         delete [] (BYTE*)mpClipRgnData;
3241 	sal_uLong nRectBufSize = sizeof(RECT)*nRects;
3242     mpClipRgnData = (RGNDATA*)new BYTE[sizeof(RGNDATA)-1+nRectBufSize];
3243 	mpClipRgnData->rdh.dwSize	  = sizeof( RGNDATAHEADER );
3244 	mpClipRgnData->rdh.iType	  = RDH_RECTANGLES;
3245 	mpClipRgnData->rdh.nCount	  = nRects;
3246 	mpClipRgnData->rdh.nRgnSize  = nRectBufSize;
3247 	SetRectEmpty( &(mpClipRgnData->rdh.rcBound) );
3248 	mpNextClipRect 		  = (RECT*)(&(mpClipRgnData->Buffer));
3249 	mbFirstClipRect		  = TRUE;
3250 }
3251 
3252 // -----------------------------------------------------------------------
3253 
3254 void WinSalFrame::UnionClipRegion( long nX, long nY, long nWidth, long nHeight )
3255 {
3256     if( ! mpClipRgnData )
3257         return;
3258 
3259 	RECT*		pRect = mpNextClipRect;
3260 	RECT*		pBoundRect = &(mpClipRgnData->rdh.rcBound);
3261 	long		nRight = nX + nWidth;
3262 	long		nBottom = nY + nHeight;
3263 
3264 	if ( mbFirstClipRect )
3265 	{
3266 		pBoundRect->left	= nX;
3267 		pBoundRect->top 	= nY;
3268 		pBoundRect->right	= nRight;
3269 		pBoundRect->bottom	= nBottom;
3270 		mbFirstClipRect = FALSE;
3271 	}
3272 	else
3273 	{
3274 		if ( nX < pBoundRect->left )
3275 			pBoundRect->left = (int)nX;
3276 
3277 		if ( nY < pBoundRect->top )
3278 			pBoundRect->top = (int)nY;
3279 
3280 		if ( nRight > pBoundRect->right )
3281 			pBoundRect->right = (int)nRight;
3282 
3283 		if ( nBottom > pBoundRect->bottom )
3284 			pBoundRect->bottom = (int)nBottom;
3285 	}
3286 
3287 	pRect->left 	= (int)nX;
3288 	pRect->top		= (int)nY;
3289 	pRect->right	= (int)nRight;
3290 	pRect->bottom	= (int)nBottom;
3291     if( (mpNextClipRect  - (RECT*)(&mpClipRgnData->Buffer)) < (int)mpClipRgnData->rdh.nCount )
3292         mpNextClipRect++;
3293 }
3294 
3295 // -----------------------------------------------------------------------
3296 
3297 void WinSalFrame::EndSetClipRegion()
3298 {
3299     if( ! mpClipRgnData )
3300         return;
3301 
3302 	HRGN hRegion;
3303 
3304 	// create region from accumulated rectangles
3305 	if ( mpClipRgnData->rdh.nCount == 1 )
3306 	{
3307 		RECT* pRect = &(mpClipRgnData->rdh.rcBound);
3308 		hRegion = CreateRectRgn( pRect->left, pRect->top,
3309 								 pRect->right, pRect->bottom );
3310 	}
3311 	else
3312 	{
3313 		sal_uLong nSize = mpClipRgnData->rdh.nRgnSize+sizeof(RGNDATAHEADER);
3314 		hRegion = ExtCreateRegion( NULL, nSize, mpClipRgnData );
3315 	}
3316     delete [] (BYTE*)mpClipRgnData;
3317     mpClipRgnData = NULL;
3318 
3319 	DBG_ASSERT( hRegion, "WinSalFrame::EndSetClipRegion() - Can't create ClipRegion" );
3320     if( hRegion )
3321     {
3322         RECT aWindowRect;
3323         GetWindowRect( mhWnd, &aWindowRect );
3324         POINT aPt;
3325         aPt.x=0;
3326         aPt.y=0;
3327         ClientToScreen( mhWnd, &aPt );
3328         OffsetRgn( hRegion, aPt.x - aWindowRect.left, aPt.y - aWindowRect.top );
3329 
3330         if( SetWindowRgn( mhWnd, hRegion, TRUE ) == 0 )
3331             DeleteObject( hRegion );
3332     }
3333 }
3334 
3335 // -----------------------------------------------------------------------
3336 
3337 static long ImplHandleMouseMsg( HWND hWnd, UINT nMsg,
3338                                 WPARAM wParam, LPARAM lParam )
3339 {
3340     WinSalFrame* pFrame = GetWindowPtr( hWnd );
3341     if ( !pFrame )
3342         return 0;
3343 
3344     if( nMsg == WM_LBUTTONDOWN || nMsg == WM_MBUTTONDOWN || nMsg == WM_RBUTTONDOWN )
3345     {
3346         // #103168# post again if async focus has not arrived yet
3347         // hopefully we will not receive the corresponding button up before this
3348         // button down arrives again
3349         Window *pWin = pFrame->GetWindow();
3350         if( pWin && pWin->ImplGetWindowImpl()->mpFrameData->mnFocusId )
3351         {
3352             ImplPostMessage( hWnd, nMsg, wParam, lParam );
3353             return 1;
3354         }
3355     }
3356     SalMouseEvent   aMouseEvt;
3357     long            nRet;
3358     sal_uInt16          nEvent = 0;
3359     sal_Bool            bCall = TRUE;
3360 
3361     aMouseEvt.mnX       = (short)LOWORD( lParam );
3362     aMouseEvt.mnY       = (short)HIWORD( lParam );
3363     aMouseEvt.mnCode    = 0;
3364     aMouseEvt.mnTime    = GetMessageTime();
3365 
3366     // Wegen (Logitech-)MouseTreiber ueber GetKeyState() gehen, die auf
3367     // mittlerer Maustaste Doppelklick simulieren und den KeyStatus nicht
3368     // beruecksichtigen
3369 
3370     if ( GetKeyState( VK_LBUTTON ) & 0x8000 )
3371         aMouseEvt.mnCode |= MOUSE_LEFT;
3372     if ( GetKeyState( VK_MBUTTON ) & 0x8000 )
3373         aMouseEvt.mnCode |= MOUSE_MIDDLE;
3374     if ( GetKeyState( VK_RBUTTON ) & 0x8000 )
3375         aMouseEvt.mnCode |= MOUSE_RIGHT;
3376     if ( GetKeyState( VK_SHIFT ) & 0x8000 )
3377         aMouseEvt.mnCode |= KEY_SHIFT;
3378     if ( GetKeyState( VK_CONTROL ) & 0x8000 )
3379         aMouseEvt.mnCode |= KEY_MOD1;
3380     if ( GetKeyState( VK_MENU ) & 0x8000 )
3381         aMouseEvt.mnCode |= KEY_MOD2;
3382 
3383     switch ( nMsg )
3384     {
3385         case WM_MOUSEMOVE:
3386             {
3387             // Da bei Druecken von Modifier-Tasten die MouseEvents
3388             // nicht zusammengefast werden (da diese durch KeyEvents
3389             // unterbrochen werden), machen wir dieses hier selber
3390             if ( aMouseEvt.mnCode & (KEY_SHIFT | KEY_MOD1 | KEY_MOD2) )
3391             {
3392                 MSG aTempMsg;
3393                 if ( ImplPeekMessage( &aTempMsg, hWnd, WM_MOUSEFIRST, WM_MOUSELAST, PM_NOREMOVE | PM_NOYIELD ) )
3394                 {
3395                     if ( (aTempMsg.message == WM_MOUSEMOVE) &&
3396                          (aTempMsg.wParam == wParam) )
3397                         return 1;
3398                 }
3399             }
3400 
3401             SalData* pSalData = GetSalData();
3402             // Test for MouseLeave
3403             if ( pSalData->mhWantLeaveMsg && (pSalData->mhWantLeaveMsg != hWnd) )
3404 				ImplSendMessage( pSalData->mhWantLeaveMsg, SAL_MSG_MOUSELEAVE, 0, GetMessagePos() );
3405 
3406             pSalData->mhWantLeaveMsg = hWnd;
3407             // Start MouseLeave-Timer
3408             if ( !pSalData->mpMouseLeaveTimer )
3409             {
3410                 pSalData->mpMouseLeaveTimer = new AutoTimer;
3411                 pSalData->mpMouseLeaveTimer->SetTimeout( SAL_MOUSELEAVE_TIMEOUT );
3412                 pSalData->mpMouseLeaveTimer->Start();
3413                 // We dont need to set a timeout handler, because we test
3414                 // for mouseleave in the timeout callback
3415             }
3416             aMouseEvt.mnButton = 0;
3417             nEvent = SALEVENT_MOUSEMOVE;
3418             }
3419             break;
3420 
3421         case WM_NCMOUSEMOVE:
3422         case SAL_MSG_MOUSELEAVE:
3423             {
3424             SalData* pSalData = GetSalData();
3425             if ( pSalData->mhWantLeaveMsg == hWnd )
3426             {
3427                 pSalData->mhWantLeaveMsg = 0;
3428                 if ( pSalData->mpMouseLeaveTimer )
3429                 {
3430                     delete pSalData->mpMouseLeaveTimer;
3431                     pSalData->mpMouseLeaveTimer = NULL;
3432                 }
3433                 // Mouse-Coordinaates are relativ to the screen
3434                 POINT aPt;
3435                 aPt.x = (short)LOWORD( lParam );
3436                 aPt.y = (short)HIWORD( lParam );
3437                 ScreenToClient( hWnd, &aPt );
3438                 aMouseEvt.mnX = aPt.x;
3439                 aMouseEvt.mnY = aPt.y;
3440                 aMouseEvt.mnButton = 0;
3441                 nEvent = SALEVENT_MOUSELEAVE;
3442             }
3443             else
3444                 bCall = FALSE;
3445             }
3446             break;
3447 
3448         case WM_LBUTTONDOWN:
3449             aMouseEvt.mnButton = MOUSE_LEFT;
3450             nEvent = SALEVENT_MOUSEBUTTONDOWN;
3451             break;
3452 
3453         case WM_MBUTTONDOWN:
3454             aMouseEvt.mnButton = MOUSE_MIDDLE;
3455             nEvent = SALEVENT_MOUSEBUTTONDOWN;
3456             break;
3457 
3458         case WM_RBUTTONDOWN:
3459             aMouseEvt.mnButton = MOUSE_RIGHT;
3460             nEvent = SALEVENT_MOUSEBUTTONDOWN;
3461             break;
3462 
3463         case WM_LBUTTONUP:
3464             aMouseEvt.mnButton = MOUSE_LEFT;
3465             nEvent = SALEVENT_MOUSEBUTTONUP;
3466             break;
3467 
3468         case WM_MBUTTONUP:
3469             aMouseEvt.mnButton = MOUSE_MIDDLE;
3470             nEvent = SALEVENT_MOUSEBUTTONUP;
3471             break;
3472 
3473         case WM_RBUTTONUP:
3474             aMouseEvt.mnButton = MOUSE_RIGHT;
3475             nEvent = SALEVENT_MOUSEBUTTONUP;
3476             break;
3477     }
3478 
3479 	// check if this window was destroyed - this might happen if we are the help window
3480 	// and sent a mouse leave message to the application which killed the help window, ie ourself
3481 	if( !IsWindow( hWnd ) )
3482 		return 0;
3483 
3484     if ( bCall )
3485     {
3486         if ( nEvent == SALEVENT_MOUSEBUTTONDOWN )
3487             UpdateWindow( hWnd );
3488 
3489         // --- RTL --- (mirror mouse pos)
3490         if( Application::GetSettings().GetLayoutRTL() )
3491             aMouseEvt.mnX = pFrame->maGeometry.nWidth-1-aMouseEvt.mnX;
3492 
3493         nRet = pFrame->CallCallback( nEvent, &aMouseEvt );
3494         if ( nMsg == WM_MOUSEMOVE )
3495             SetCursor( pFrame->mhCursor );
3496     }
3497     else
3498         nRet = 0;
3499 
3500     return nRet;
3501 }
3502 
3503 // -----------------------------------------------------------------------
3504 
3505 static long ImplHandleMouseActivateMsg( HWND hWnd )
3506 {
3507     WinSalFrame* pFrame = GetWindowPtr( hWnd );
3508     if ( !pFrame )
3509         return 0;
3510 
3511     if ( pFrame->mbFloatWin )
3512         return TRUE;
3513 
3514     SalMouseActivateEvent   aMouseActivateEvt;
3515     POINT                   aPt;
3516     GetCursorPos( &aPt );
3517     ScreenToClient( hWnd, &aPt );
3518     aMouseActivateEvt.mnX = aPt.x;
3519     aMouseActivateEvt.mnY = aPt.y;
3520     return pFrame->CallCallback( SALEVENT_MOUSEACTIVATE, &aMouseActivateEvt );
3521 }
3522 
3523 // -----------------------------------------------------------------------
3524 
3525 static long ImplHandleWheelMsg( HWND hWnd, UINT nMsg, WPARAM wParam, LPARAM lParam )
3526 {
3527     DBG_ASSERT( nMsg == WM_MOUSEWHEEL ||
3528                 nMsg == WM_MOUSEHWHEEL,
3529                 "ImplHandleWheelMsg() called with no wheel mouse event" );
3530 
3531     ImplSalYieldMutexAcquireWithWait();
3532 
3533     long        nRet = 0;
3534     WinSalFrame*   pFrame = GetWindowPtr( hWnd );
3535     if ( pFrame )
3536     {
3537         WORD    nWinModCode = LOWORD( wParam );
3538         POINT   aWinPt;
3539         aWinPt.x    = (short)LOWORD( lParam );
3540         aWinPt.y    = (short)HIWORD( lParam );
3541         ScreenToClient( hWnd, &aWinPt );
3542 
3543         SalWheelMouseEvent aWheelEvt;
3544         aWheelEvt.mnTime        = GetMessageTime();
3545         aWheelEvt.mnX           = aWinPt.x;
3546         aWheelEvt.mnY           = aWinPt.y;
3547         aWheelEvt.mnCode        = 0;
3548         aWheelEvt.mnDelta       = (short)HIWORD( wParam );
3549         aWheelEvt.mnNotchDelta  = aWheelEvt.mnDelta/WHEEL_DELTA;
3550         if( aWheelEvt.mnNotchDelta == 0 )
3551         {
3552             if( aWheelEvt.mnDelta > 0 )
3553                 aWheelEvt.mnNotchDelta = 1;
3554             else if( aWheelEvt.mnDelta < 0 )
3555                 aWheelEvt.mnNotchDelta = -1;
3556         }
3557 
3558         if( nMsg == WM_MOUSEWHEEL )
3559         {
3560             if ( aSalShlData.mnWheelScrollLines == WHEEL_PAGESCROLL )
3561                 aWheelEvt.mnScrollLines = SAL_WHEELMOUSE_EVENT_PAGESCROLL;
3562             else
3563                 aWheelEvt.mnScrollLines = aSalShlData.mnWheelScrollLines;
3564             aWheelEvt.mbHorz        = FALSE;
3565         }
3566         else
3567         {
3568             aWheelEvt.mnScrollLines = aSalShlData.mnWheelScrollChars;
3569             aWheelEvt.mbHorz        = TRUE;
3570         }
3571 
3572         if ( nWinModCode & MK_SHIFT )
3573             aWheelEvt.mnCode |= KEY_SHIFT;
3574         if ( nWinModCode & MK_CONTROL )
3575             aWheelEvt.mnCode |= KEY_MOD1;
3576         if ( GetKeyState( VK_MENU ) & 0x8000 )
3577             aWheelEvt.mnCode |= KEY_MOD2;
3578 
3579         // --- RTL --- (mirror mouse pos)
3580         if( Application::GetSettings().GetLayoutRTL() )
3581             aWheelEvt.mnX = pFrame->maGeometry.nWidth-1-aWheelEvt.mnX;
3582 
3583         nRet = pFrame->CallCallback( SALEVENT_WHEELMOUSE, &aWheelEvt );
3584     }
3585 
3586     ImplSalYieldMutexRelease();
3587 
3588     return nRet;
3589 }
3590 
3591 // -----------------------------------------------------------------------
3592 
3593 static sal_uInt16 ImplSalGetKeyCode( WPARAM wParam )
3594 {
3595     sal_uInt16 nKeyCode;
3596 
3597     // convert KeyCode
3598     if ( wParam < KEY_TAB_SIZE )
3599         nKeyCode = aImplTranslateKeyTab[wParam];
3600 	else
3601 	{
3602 		SalData* pSalData = GetSalData();
3603 		std::map< UINT, sal_uInt16 >::const_iterator it = pSalData->maVKMap.find( (UINT)wParam );
3604 		if( it != pSalData->maVKMap.end() )
3605 			nKeyCode = it->second;
3606 		else
3607 			nKeyCode = 0;
3608 	}
3609 
3610     return nKeyCode;
3611 }
3612 
3613 // -----------------------------------------------------------------------
3614 
3615 static UINT ImplStrToNum( const sal_Char* pStr )
3616 {
3617     sal_uInt16 n = 0;
3618 
3619     // Solange es sich um eine Ziffer handelt, String umwandeln
3620     while( (*pStr >= 48) && (*pStr <= 57) )
3621     {
3622         n *= 10;
3623         n += ((*pStr) - 48);
3624         pStr++;
3625     }
3626 
3627     return n;
3628 }
3629 
3630 // -----------------------------------------------------------------------
3631 
3632 static void ImplUpdateInputLang( WinSalFrame* pFrame )
3633 {
3634     sal_Bool bLanguageChange = FALSE;
3635     UINT nLang = LOWORD( GetKeyboardLayout( 0 ) );
3636     if ( nLang && nLang != pFrame->mnInputLang )
3637     {
3638         // keep input lang up-to-date
3639         pFrame->mnInputLang = nLang;
3640         bLanguageChange = TRUE;
3641     }
3642 
3643     // If we are on Windows NT we use Unicode FrameProcs and so we
3644     // get Unicode charcodes directly from Windows
3645     // no need to set up a code page
3646     return;
3647 }
3648 
3649 
3650 static sal_Unicode ImplGetCharCode( WinSalFrame* pFrame, WPARAM nCharCode )
3651 {
3652     ImplUpdateInputLang( pFrame );
3653 
3654     // If we are on Windows NT we use Unicode FrameProcs and so we
3655     // get Unicode charcodes directly from Windows
3656     return (sal_Unicode)nCharCode;
3657 }
3658 
3659 // -----------------------------------------------------------------------
3660 
3661 LanguageType WinSalFrame::GetInputLanguage()
3662 {
3663     if( !mnInputLang )
3664         ImplUpdateInputLang( this );
3665 
3666     if( !mnInputLang )
3667         return LANGUAGE_DONTKNOW;
3668     else
3669         return (LanguageType) mnInputLang;
3670 }
3671 
3672 // -----------------------------------------------------------------------
3673 
3674 sal_Bool WinSalFrame::MapUnicodeToKeyCode( sal_Unicode aUnicode, LanguageType aLangType, KeyCode& rKeyCode )
3675 {
3676     sal_Bool bRet = FALSE;
3677     HKL hkl = 0;
3678 
3679     // just use the passed language identifier, do not try to load additional keyboard support
3680     hkl = (HKL) aLangType;
3681 
3682     if( hkl )
3683     {
3684         SHORT scan = VkKeyScanExW( aUnicode, hkl );
3685         if( LOWORD(scan) == 0xFFFF )
3686             // keyboard not loaded or key cannot be mapped
3687             bRet = FALSE;
3688         else
3689         {
3690             BYTE vkeycode   = LOBYTE(scan);
3691             BYTE shiftstate = HIBYTE(scan);
3692 
3693             // Last argument is set to FALSE, because there's no decission made
3694             // yet which key should be assigned to MOD3 modifier on Windows.
3695             // Windows key - user's can be confused, because it should display
3696             //               Windows menu (applies to both left/right key)
3697             // Menu key    - this key is used to display context menu
3698             // AltGr key   - probably it has no sense
3699             rKeyCode = KeyCode( ImplSalGetKeyCode( vkeycode ),
3700                 (shiftstate & 0x01) ? TRUE : FALSE,     // shift
3701                 (shiftstate & 0x02) ? TRUE : FALSE,     // ctrl
3702                 (shiftstate & 0x04) ? TRUE : FALSE,     // alt
3703                 FALSE );
3704             bRet = TRUE;
3705         }
3706     }
3707 
3708     return bRet;
3709 }
3710 
3711 // -----------------------------------------------------------------------
3712 
3713 static long ImplHandleKeyMsg( HWND hWnd, UINT nMsg,
3714                               WPARAM wParam, LPARAM lParam, LRESULT& rResult )
3715 {
3716     static sal_Bool     bIgnoreCharMsg  = FALSE;
3717     static WPARAM   nDeadChar       = 0;
3718     static WPARAM   nLastVKChar     = 0;
3719     static sal_uInt16   nLastChar       = 0;
3720     static sal_uInt16   nLastModKeyCode = 0;
3721     static bool     bWaitForModKeyRelease = false;
3722     sal_uInt16          nRepeat         = LOWORD( lParam )-1;
3723     sal_uInt16          nModCode        = 0;
3724 
3725     // Key wurde evtl. durch SysChild an uns weitergeleitet und
3726     // darf somit dann nicht doppelt verarbeitet werden
3727     GetSalData()->mnSalObjWantKeyEvt = 0;
3728 
3729     if ( nMsg == WM_DEADCHAR )
3730     {
3731         nDeadChar = wParam;
3732         return 0;
3733     }
3734 
3735     WinSalFrame* pFrame = GetWindowPtr( hWnd );
3736     if ( !pFrame )
3737         return 0;
3738 
3739     // Wir restaurieren den Background-Modus bei jeder Texteingabe,
3740     // da einige Tools wie RichWin uns diesen hin- und wieder umsetzen
3741     if ( pFrame->mpGraphics &&
3742          pFrame->mpGraphics->getHDC() )
3743         SetBkMode( pFrame->mpGraphics->getHDC(), TRANSPARENT );
3744 
3745     // determine modifiers
3746     if ( GetKeyState( VK_SHIFT ) & 0x8000 )
3747         nModCode |= KEY_SHIFT;
3748     if ( GetKeyState( VK_CONTROL ) & 0x8000 )
3749         nModCode |= KEY_MOD1;
3750     if ( GetKeyState( VK_MENU ) & 0x8000 )
3751         nModCode |= KEY_MOD2;
3752 
3753     if ( (nMsg == WM_CHAR) || (nMsg == WM_SYSCHAR) )
3754     {
3755         nDeadChar = 0;
3756 
3757         if ( bIgnoreCharMsg )
3758         {
3759             bIgnoreCharMsg = FALSE;
3760             // #101635# if zero is returned here for WM_SYSCHAR (ALT+<key>) Windows will beep
3761             // becaus this 'hotkey' was not processed -> better return 1
3762             // except for Alt-SPACE which should always open the sysmenu (#104616#)
3763 
3764             // also return zero if a system menubar is available that might process this hotkey
3765             // this also applies to the OLE inplace embedding where we are a child window
3766             if( (GetWindowStyle( hWnd ) & WS_CHILD) || GetMenu( hWnd ) || (wParam == 0x20) )
3767                 return 0;
3768             else
3769                 return 1;
3770         }
3771 
3772         // Backspace ignorieren wir als eigenstaendige Taste,
3773         // damit wir keine Probleme in Kombination mit einem
3774         // DeadKey bekommen
3775         if ( wParam == 0x08 )    // BACKSPACE
3776             return 0;
3777 
3778         // Hier kommen nur "freifliegende" WM_CHAR Message an, die durch
3779         // eintippen einer ALT-NUMPAD Kombination erzeugt wurden
3780         SalKeyEvent aKeyEvt;
3781 
3782         if ( (wParam >= '0') && (wParam <= '9') )
3783             aKeyEvt.mnCode = sal::static_int_cast<sal_uInt16>(KEYGROUP_NUM + wParam - '0');
3784         else if ( (wParam >= 'A') && (wParam <= 'Z') )
3785             aKeyEvt.mnCode = sal::static_int_cast<sal_uInt16>(KEYGROUP_ALPHA + wParam - 'A');
3786         else if ( (wParam >= 'a') && (wParam <= 'z') )
3787             aKeyEvt.mnCode = sal::static_int_cast<sal_uInt16>(KEYGROUP_ALPHA + wParam - 'a');
3788         else if ( wParam == 0x0D )    // RETURN
3789             aKeyEvt.mnCode = KEY_RETURN;
3790         else if ( wParam == 0x1B )    // ESCAPE
3791             aKeyEvt.mnCode = KEY_ESCAPE;
3792         else if ( wParam == 0x09 )    // TAB
3793             aKeyEvt.mnCode = KEY_TAB;
3794         else if ( wParam == 0x20 )    // SPACE
3795             aKeyEvt.mnCode = KEY_SPACE;
3796         else
3797             aKeyEvt.mnCode = 0;
3798 
3799         aKeyEvt.mnTime      = GetMessageTime();
3800         aKeyEvt.mnCode     |= nModCode;
3801         aKeyEvt.mnCharCode  = ImplGetCharCode( pFrame, wParam );
3802         aKeyEvt.mnRepeat    = nRepeat;
3803         nLastChar = 0;
3804         nLastVKChar = 0;
3805         long nRet = pFrame->CallCallback( SALEVENT_KEYINPUT, &aKeyEvt );
3806         pFrame->CallCallback( SALEVENT_KEYUP, &aKeyEvt );
3807         return nRet;
3808     }
3809  	// #i11583#, MCD, 2003-01-13, Support for WM_UNICHAR & Keyman 6.0; addition begins
3810 	else if( nMsg == WM_UNICHAR )
3811  	{
3812  		// If Windows is asking if we accept WM_UNICHAR, return TRUE
3813  		if(wParam == UNICODE_NOCHAR)
3814         {
3815             rResult = TRUE; // ssa: this will actually return TRUE to windows
3816             return 1;       // ...but this will only avoid calling the defwindowproc
3817         }
3818 
3819  		SalKeyEvent aKeyEvt;
3820  		aKeyEvt.mnCode		= nModCode;	// Or should it be 0? - as this is always a character returned
3821  		aKeyEvt.mnTime		= GetMessageTime();
3822  		aKeyEvt.mnRepeat	= 0;
3823 
3824 		if( wParam >= Uni_SupplementaryPlanesStart )
3825 		{
3826 			// character is supplementary char in UTF-32 format - must be converted to UTF-16 supplementary pair
3827 			// sal_Unicode ch = (sal_Unicode) Uni_UTF32ToSurrogate1(wParam);
3828 	 		nLastChar = 0;
3829  			nLastVKChar = 0;
3830 	 		pFrame->CallCallback( SALEVENT_KEYINPUT, &aKeyEvt );
3831  			pFrame->CallCallback( SALEVENT_KEYUP, &aKeyEvt );
3832 			wParam = (sal_Unicode) Uni_UTF32ToSurrogate2( wParam );
3833  		}
3834 
3835  		aKeyEvt.mnCharCode	= (sal_Unicode) wParam;
3836 
3837  		nLastChar = 0;
3838  		nLastVKChar = 0;
3839  		long nRet = pFrame->CallCallback( SALEVENT_KEYINPUT, &aKeyEvt );
3840  		pFrame->CallCallback( SALEVENT_KEYUP, &aKeyEvt );
3841 
3842  		return nRet;
3843  	}
3844  	// MCD, 2003-01-13, Support for WM_UNICHAR & Keyman 6.0; addition ends
3845     else
3846     {
3847         // Bei Shift, Control und Menu schicken wir einen KeyModChange-Event
3848         if ( (wParam == VK_SHIFT) || (wParam == VK_CONTROL) || (wParam == VK_MENU) )
3849         {
3850             SalKeyModEvent aModEvt;
3851             aModEvt.mnTime = GetMessageTime();
3852             aModEvt.mnCode = nModCode;
3853             aModEvt.mnModKeyCode = 0;   // no command events will be sent if this member is 0
3854 
3855             sal_uInt16 tmpCode = 0;
3856             if( GetKeyState( VK_LSHIFT )  & 0x8000 )
3857                 tmpCode |= MODKEY_LSHIFT;
3858             if( GetKeyState( VK_RSHIFT )  & 0x8000 )
3859                 tmpCode |= MODKEY_RSHIFT;
3860             if( GetKeyState( VK_LCONTROL ) & 0x8000 )
3861                 tmpCode |= MODKEY_LMOD1;
3862             if( GetKeyState( VK_RCONTROL ) & 0x8000 )
3863                 tmpCode |= MODKEY_RMOD1;
3864             if( GetKeyState( VK_LMENU )  & 0x8000 )
3865                 tmpCode |= MODKEY_LMOD2;
3866             if( GetKeyState( VK_RMENU )  & 0x8000 )
3867                 tmpCode |= MODKEY_RMOD2;
3868 
3869             if( tmpCode < nLastModKeyCode )
3870             {
3871                 aModEvt.mnModKeyCode = nLastModKeyCode;
3872                 nLastModKeyCode = 0;
3873                 bWaitForModKeyRelease = true;
3874             }
3875             else
3876             {
3877                 if( !bWaitForModKeyRelease )
3878                     nLastModKeyCode = tmpCode;
3879             }
3880 
3881             if( !tmpCode )
3882                 bWaitForModKeyRelease = false;
3883 
3884             return pFrame->CallCallback( SALEVENT_KEYMODCHANGE, &aModEvt );
3885         }
3886         else
3887         {
3888             SalKeyEvent     aKeyEvt;
3889             sal_uInt16          nEvent;
3890             MSG             aCharMsg;
3891             BOOL        bCharPeek = FALSE;
3892             UINT            nCharMsg = WM_CHAR;
3893             sal_Bool            bKeyUp = (nMsg == WM_KEYUP) || (nMsg == WM_SYSKEYUP);
3894 
3895             nLastModKeyCode = 0; // make sure no modkey messages are sent if they belong to a hotkey (see above)
3896             aKeyEvt.mnCharCode = 0;
3897             aKeyEvt.mnCode = 0;
3898 
3899             aKeyEvt.mnCode = ImplSalGetKeyCode( wParam );
3900             if ( !bKeyUp )
3901             {
3902                 // check for charcode
3903                 // Mit Hilfe von PeekMessage holen wir uns jetzt die
3904                 // zugehoerige WM_CHAR Message, wenn vorhanden.
3905                 // Diese WM_CHAR Message steht immer am Anfang der
3906                 // Messagequeue. Ausserdem ist sichergestellt, dass immer
3907                 // nur eine WM_CHAR Message in der Queue steht.
3908                 bCharPeek = ImplPeekMessage( &aCharMsg, hWnd,
3909                                              WM_CHAR, WM_CHAR, PM_NOREMOVE | PM_NOYIELD );
3910                 if ( bCharPeek && (nDeadChar == aCharMsg.wParam) )
3911                 {
3912                     bCharPeek = FALSE;
3913                     nDeadChar = 0;
3914 
3915                     if ( wParam == VK_BACK )
3916                     {
3917                         ImplPeekMessage( &aCharMsg, hWnd,
3918                                          nCharMsg, nCharMsg, PM_REMOVE | PM_NOYIELD );
3919                         return 0;
3920                     }
3921                 }
3922                 else
3923                 {
3924                     if ( !bCharPeek )
3925                     {
3926                         bCharPeek = ImplPeekMessage( &aCharMsg, hWnd,
3927                                                     WM_SYSCHAR, WM_SYSCHAR, PM_NOREMOVE | PM_NOYIELD );
3928                         nCharMsg = WM_SYSCHAR;
3929                     }
3930                 }
3931                 if ( bCharPeek )
3932                     aKeyEvt.mnCharCode = ImplGetCharCode( pFrame, aCharMsg.wParam );
3933                 else
3934                     aKeyEvt.mnCharCode = 0;
3935 
3936                 nLastChar = aKeyEvt.mnCharCode;
3937                 nLastVKChar = wParam;
3938             }
3939             else
3940             {
3941                 if ( wParam == nLastVKChar )
3942                 {
3943                     aKeyEvt.mnCharCode = nLastChar;
3944                     nLastChar = 0;
3945                     nLastVKChar = 0;
3946                 }
3947             }
3948 
3949             if ( aKeyEvt.mnCode || aKeyEvt.mnCharCode )
3950             {
3951                 if ( bKeyUp )
3952                     nEvent = SALEVENT_KEYUP;
3953                 else
3954                     nEvent = SALEVENT_KEYINPUT;
3955 
3956                 aKeyEvt.mnTime      = GetMessageTime();
3957                 aKeyEvt.mnCode     |= nModCode;
3958                 aKeyEvt.mnRepeat    = nRepeat;
3959 
3960                 if( (nModCode & (KEY_MOD1|KEY_MOD2)) == (KEY_MOD1|KEY_MOD2) &&
3961                     aKeyEvt.mnCharCode )
3962                 {
3963                      // this is actually AltGr and should not be handled as Alt
3964                      aKeyEvt.mnCode &= ~(KEY_MOD1|KEY_MOD2);
3965                 }
3966 
3967                 bIgnoreCharMsg = bCharPeek ? TRUE : FALSE;
3968                 long nRet = pFrame->CallCallback( nEvent, &aKeyEvt );
3969                 // independent part only reacts on keyup but Windows does not send
3970                 // keyup for VK_HANJA
3971                 if( aKeyEvt.mnCode == KEY_HANGUL_HANJA )
3972                     nRet = pFrame->CallCallback( SALEVENT_KEYUP, &aKeyEvt );
3973 
3974                 bIgnoreCharMsg = FALSE;
3975 
3976                 // char-message, than remove or ignore
3977                 if ( bCharPeek )
3978                 {
3979                     nDeadChar = 0;
3980                     if ( nRet )
3981                     {
3982                         ImplPeekMessage( &aCharMsg, hWnd,
3983                                          nCharMsg, nCharMsg, PM_REMOVE | PM_NOYIELD );
3984                     }
3985                     else
3986                         bIgnoreCharMsg = TRUE;
3987                 }
3988 
3989                 return nRet;
3990             }
3991             else
3992                 return 0;
3993         }
3994     }
3995 }
3996 
3997 // -----------------------------------------------------------------------
3998 
3999 long ImplHandleSalObjKeyMsg( HWND hWnd, UINT nMsg,
4000                              WPARAM wParam, LPARAM lParam )
4001 {
4002     if ( (nMsg == WM_KEYDOWN) || (nMsg == WM_KEYUP) )
4003     {
4004         WinSalFrame* pFrame = GetWindowPtr( hWnd );
4005         if ( !pFrame )
4006             return 0;
4007 
4008         sal_uInt16  nRepeat     = LOWORD( lParam )-1;
4009         sal_uInt16  nModCode    = 0;
4010 
4011         // determine modifiers
4012         if ( GetKeyState( VK_SHIFT ) & 0x8000 )
4013             nModCode |= KEY_SHIFT;
4014         if ( GetKeyState( VK_CONTROL ) & 0x8000 )
4015             nModCode |= KEY_MOD1;
4016         if ( GetKeyState( VK_MENU ) & 0x8000 )
4017             nModCode |= KEY_MOD2;
4018 
4019         if ( (wParam != VK_SHIFT) && (wParam != VK_CONTROL) && (wParam != VK_MENU) )
4020         {
4021             SalKeyEvent     aKeyEvt;
4022             sal_uInt16          nEvent;
4023             sal_Bool            bKeyUp = (nMsg == WM_KEYUP) || (nMsg == WM_SYSKEYUP);
4024 
4025             // convert KeyCode
4026             aKeyEvt.mnCode      = ImplSalGetKeyCode( wParam );
4027             aKeyEvt.mnCharCode  = 0;
4028 
4029             if ( aKeyEvt.mnCode )
4030             {
4031                 if ( bKeyUp )
4032                     nEvent = SALEVENT_KEYUP;
4033                 else
4034                     nEvent = SALEVENT_KEYINPUT;
4035 
4036                 aKeyEvt.mnTime      = GetMessageTime();
4037                 aKeyEvt.mnCode     |= nModCode;
4038                 aKeyEvt.mnRepeat    = nRepeat;
4039                 long nRet = pFrame->CallCallback( nEvent, &aKeyEvt );
4040                 return nRet;
4041             }
4042             else
4043                 return 0;
4044         }
4045     }
4046 
4047     return 0;
4048 }
4049 
4050 // -----------------------------------------------------------------------
4051 
4052 long ImplHandleSalObjSysCharMsg( HWND hWnd, WPARAM wParam, LPARAM lParam )
4053 {
4054     WinSalFrame* pFrame = GetWindowPtr( hWnd );
4055     if ( !pFrame )
4056         return 0;
4057 
4058     sal_uInt16  nRepeat     = LOWORD( lParam )-1;
4059     sal_uInt16  nModCode    = 0;
4060     sal_uInt16  cKeyCode    = (sal_uInt16)wParam;
4061 
4062     // determine modifiers
4063     if ( GetKeyState( VK_SHIFT ) & 0x8000 )
4064         nModCode |= KEY_SHIFT;
4065     if ( GetKeyState( VK_CONTROL ) & 0x8000 )
4066         nModCode |= KEY_MOD1;
4067     nModCode |= KEY_MOD2;
4068 
4069     // KeyEvent zusammenbauen
4070     SalKeyEvent aKeyEvt;
4071     aKeyEvt.mnTime      = GetMessageTime();
4072     if ( (cKeyCode >= 48) && (cKeyCode <= 57) )
4073         aKeyEvt.mnCode = KEY_0+(cKeyCode-48);
4074     else if ( (cKeyCode >= 65) && (cKeyCode <= 90) )
4075         aKeyEvt.mnCode = KEY_A+(cKeyCode-65);
4076     else  if ( (cKeyCode >= 97) && (cKeyCode <= 122) )
4077         aKeyEvt.mnCode = KEY_A+(cKeyCode-97);
4078     else
4079         aKeyEvt.mnCode = 0;
4080     aKeyEvt.mnCode     |= nModCode;
4081     aKeyEvt.mnCharCode  = ImplGetCharCode( pFrame, cKeyCode );
4082     aKeyEvt.mnRepeat    = nRepeat;
4083     long nRet = pFrame->CallCallback( SALEVENT_KEYINPUT, &aKeyEvt );
4084     pFrame->CallCallback( SALEVENT_KEYUP, &aKeyEvt );
4085     return nRet;
4086 }
4087 
4088 // -----------------------------------------------------------------------
4089 
4090 static bool ImplHandlePaintMsg( HWND hWnd )
4091 {
4092     sal_Bool bMutex = FALSE;
4093     if ( ImplSalYieldMutexTryToAcquire() )
4094         bMutex = TRUE;
4095 
4096     // if we don't get the mutex, we can also change the clip region,
4097     // because other threads doesn't use the mutex from the main
4098     // thread --> see GetGraphics()
4099 
4100     WinSalFrame* pFrame = GetWindowPtr( hWnd );
4101     if ( pFrame )
4102     {
4103         // Clip-Region muss zurueckgesetzt werden, da wir sonst kein
4104         // ordentliches Bounding-Rectangle bekommen
4105         if ( pFrame->mpGraphics && pFrame->mpGraphics->mhRegion )
4106             SelectClipRgn( pFrame->mpGraphics->getHDC(), 0 );
4107 
4108         // Laut Window-Doku soll man erst abfragen, ob ueberhaupt eine
4109         // Paint-Region anliegt
4110         if ( GetUpdateRect( hWnd, NULL, FALSE ) )
4111         {
4112             // Call BeginPaint/EndPaint to query the rect and send
4113             // this Notofication to rect
4114             RECT aUpdateRect;
4115             PAINTSTRUCT aPs;
4116             BeginPaint( hWnd, &aPs );
4117             CopyRect( &aUpdateRect, &aPs.rcPaint );
4118 
4119             // Paint
4120             // ClipRegion wieder herstellen
4121             if ( pFrame->mpGraphics && pFrame->mpGraphics->mhRegion )
4122             {
4123                 SelectClipRgn( pFrame->mpGraphics->getHDC(),
4124                                pFrame->mpGraphics->mhRegion );
4125             }
4126 
4127             if ( bMutex )
4128             {
4129                 SalPaintEvent aPEvt( aUpdateRect.left, aUpdateRect.top, aUpdateRect.right-aUpdateRect.left, aUpdateRect.bottom-aUpdateRect.top, pFrame->mbPresentation );
4130                 pFrame->CallCallback( SALEVENT_PAINT, &aPEvt );
4131             }
4132             else
4133             {
4134                 RECT* pRect = new RECT;
4135                 CopyRect( pRect, &aUpdateRect );
4136                 ImplPostMessage( hWnd, SAL_MSG_POSTPAINT, (WPARAM)pRect, 0 );
4137             }
4138             EndPaint( hWnd, &aPs );
4139         }
4140         else
4141         {
4142             // ClipRegion wieder herstellen
4143             if ( pFrame->mpGraphics && pFrame->mpGraphics->mhRegion )
4144             {
4145                 SelectClipRgn( pFrame->mpGraphics->getHDC(),
4146                                pFrame->mpGraphics->mhRegion );
4147             }
4148         }
4149     }
4150 
4151     if ( bMutex )
4152         ImplSalYieldMutexRelease();
4153 
4154 	return bMutex ? true : false;
4155 }
4156 
4157 // -----------------------------------------------------------------------
4158 
4159 static void ImplHandlePaintMsg2( HWND hWnd, RECT* pRect )
4160 {
4161     // Paint
4162     if ( ImplSalYieldMutexTryToAcquire() )
4163     {
4164         WinSalFrame* pFrame = GetWindowPtr( hWnd );
4165         if ( pFrame )
4166         {
4167             SalPaintEvent aPEvt( pRect->left, pRect->top, pRect->right-pRect->left, pRect->bottom-pRect->top );
4168             pFrame->CallCallback( SALEVENT_PAINT, &aPEvt );
4169         }
4170         ImplSalYieldMutexRelease();
4171         delete pRect;
4172     }
4173     else
4174         ImplPostMessage( hWnd, SAL_MSG_POSTPAINT, (WPARAM)pRect, 0 );
4175 }
4176 
4177 // -----------------------------------------------------------------------
4178 
4179 static void SetMaximizedFrameGeometry( HWND hWnd, WinSalFrame* pFrame, RECT* pParentRect )
4180 {
4181     // calculate and set frame geometry of a maximized window - useful if the window is still hidden
4182 
4183     // dualmonitor support:
4184     // Get screensize of the monitor whith the mouse pointer
4185 
4186     RECT aRectMouse;
4187     if( ! pParentRect )
4188     {
4189         POINT pt;
4190         GetCursorPos( &pt );
4191         aRectMouse.left = pt.x;
4192         aRectMouse.top = pt.y;
4193         aRectMouse.right = pt.x+2;
4194         aRectMouse.bottom = pt.y+2;
4195         pParentRect = &aRectMouse;
4196     }
4197 
4198     RECT aRect;
4199     ImplSalGetWorkArea( hWnd, &aRect, pParentRect );
4200 
4201     // a maximized window has no other borders than the caption
4202     pFrame->maGeometry.nLeftDecoration = pFrame->maGeometry.nRightDecoration = pFrame->maGeometry.nBottomDecoration = 0;
4203     pFrame->maGeometry.nTopDecoration = pFrame->mbCaption ? GetSystemMetrics( SM_CYCAPTION ) : 0;
4204 
4205     aRect.top += pFrame->maGeometry.nTopDecoration;
4206     pFrame->maGeometry.nX = aRect.left;
4207     pFrame->maGeometry.nY = aRect.top;
4208     pFrame->maGeometry.nWidth = aRect.right - aRect.left;
4209     pFrame->maGeometry.nHeight = aRect.bottom - aRect.top;
4210 }
4211 
4212 static void UpdateFrameGeometry( HWND hWnd, WinSalFrame* pFrame )
4213 {
4214     if( !pFrame )
4215         return;
4216 
4217     RECT aRect;
4218     GetWindowRect( hWnd, &aRect );
4219     memset(&pFrame->maGeometry, 0, sizeof(SalFrameGeometry) );
4220 
4221     if ( IsIconic( hWnd ) )
4222         return;
4223 
4224     POINT aPt;
4225     aPt.x=0;
4226     aPt.y=0;
4227     ClientToScreen(hWnd, &aPt);
4228     int cx = aPt.x - aRect.left;
4229     pFrame->maGeometry.nTopDecoration = aPt.y - aRect.top;
4230 
4231     pFrame->maGeometry.nLeftDecoration = cx;
4232     pFrame->maGeometry.nRightDecoration = cx;
4233 
4234     pFrame->maGeometry.nX = aPt.x;
4235     pFrame->maGeometry.nY = aPt.y;
4236 
4237     RECT aInnerRect;
4238     GetClientRect( hWnd, &aInnerRect );
4239     if( aInnerRect.right )
4240     {
4241         // improve right decoration
4242         aPt.x=aInnerRect.right;
4243         aPt.y=aInnerRect.top;
4244         ClientToScreen(hWnd, &aPt);
4245         pFrame->maGeometry.nRightDecoration = aRect.right - aPt.x;
4246     }
4247     if( aInnerRect.bottom ) // may be zero if window was not shown yet
4248         pFrame->maGeometry.nBottomDecoration += aRect.bottom - aPt.y - aInnerRect.bottom;
4249     else
4250         // bottom border is typically the same as left/right
4251         pFrame->maGeometry.nBottomDecoration = pFrame->maGeometry.nLeftDecoration;
4252 
4253     int nWidth  = aRect.right - aRect.left
4254         - pFrame->maGeometry.nRightDecoration - pFrame->maGeometry.nLeftDecoration;
4255     int nHeight = aRect.bottom - aRect.top
4256         - pFrame->maGeometry.nBottomDecoration - pFrame->maGeometry.nTopDecoration;
4257     // clamp to zero
4258     pFrame->maGeometry.nHeight = nHeight < 0 ? 0 : nHeight;
4259     pFrame->maGeometry.nWidth = nWidth < 0 ? 0 : nWidth;
4260     pFrame->updateScreenNumber();
4261 }
4262 
4263 // -----------------------------------------------------------------------
4264 
4265 static void ImplCallMoveHdl( HWND hWnd )
4266 {
4267     WinSalFrame* pFrame = GetWindowPtr( hWnd );
4268     if ( pFrame )
4269     {
4270         pFrame->CallCallback( SALEVENT_MOVE, 0 );
4271         // Um doppelte Paints von VCL und SAL zu vermeiden
4272         //if ( IsWindowVisible( hWnd ) && !pFrame->mbInShow )
4273         //    UpdateWindow( hWnd );
4274     }
4275 }
4276 
4277 // -----------------------------------------------------------------------
4278 
4279 static void ImplCallClosePopupsHdl( HWND hWnd )
4280 {
4281     WinSalFrame* pFrame = GetWindowPtr( hWnd );
4282     if ( pFrame )
4283     {
4284         pFrame->CallCallback( SALEVENT_CLOSEPOPUPS, 0 );
4285     }
4286 }
4287 
4288 // -----------------------------------------------------------------------
4289 
4290 static void ImplHandleMoveMsg( HWND hWnd )
4291 {
4292     if ( ImplSalYieldMutexTryToAcquire() )
4293     {
4294         WinSalFrame* pFrame = GetWindowPtr( hWnd );
4295         if ( pFrame )
4296         {
4297             UpdateFrameGeometry( hWnd, pFrame );
4298 
4299             if ( GetWindowStyle( hWnd ) & WS_VISIBLE )
4300                 pFrame->mbDefPos = FALSE;
4301 
4302             // Gegen moegliche Rekursionen sichern
4303             if ( !pFrame->mbInMoveMsg )
4304             {
4305                 // Fenster im FullScreenModus wieder einpassen
4306                 pFrame->mbInMoveMsg = TRUE;
4307                 if ( pFrame->mbFullScreen )
4308                     ImplSalFrameFullScreenPos( pFrame );
4309                 pFrame->mbInMoveMsg = FALSE;
4310             }
4311 
4312             // Status merken
4313             ImplSaveFrameState( pFrame );
4314 
4315             // Call Hdl
4316             //#93851 if we call this handler, VCL floating windows are not updated correctly
4317             ImplCallMoveHdl( hWnd );
4318 
4319         }
4320 
4321         ImplSalYieldMutexRelease();
4322     }
4323     else
4324         ImplPostMessage( hWnd, SAL_MSG_POSTMOVE, 0, 0 );
4325 }
4326 
4327 // -----------------------------------------------------------------------
4328 
4329 static void ImplCallSizeHdl( HWND hWnd )
4330 {
4331     // Da Windows diese Messages auch senden kann, muss hier auch die
4332     // Solar-Semaphore beruecksichtigt werden
4333     if ( ImplSalYieldMutexTryToAcquire() )
4334     {
4335         WinSalFrame* pFrame = GetWindowPtr( hWnd );
4336         if ( pFrame )
4337         {
4338             pFrame->CallCallback( SALEVENT_RESIZE, 0 );
4339             // Um doppelte Paints von VCL und SAL zu vermeiden
4340             if ( IsWindowVisible( hWnd ) && !pFrame->mbInShow )
4341                 UpdateWindow( hWnd );
4342         }
4343 
4344         ImplSalYieldMutexRelease();
4345     }
4346     else
4347         ImplPostMessage( hWnd, SAL_MSG_POSTCALLSIZE, 0, 0 );
4348 }
4349 
4350 // -----------------------------------------------------------------------
4351 
4352 static void ImplHandleSizeMsg( HWND hWnd, WPARAM wParam, LPARAM lParam )
4353 {
4354     if ( (wParam != SIZE_MAXSHOW) && (wParam != SIZE_MAXHIDE) )
4355     {
4356         WinSalFrame* pFrame = GetWindowPtr( hWnd );
4357         if ( pFrame )
4358         {
4359             UpdateFrameGeometry( hWnd, pFrame );
4360 
4361             pFrame->mnWidth  = (int)LOWORD(lParam);
4362             pFrame->mnHeight = (int)HIWORD(lParam);
4363             // Status merken
4364             ImplSaveFrameState( pFrame );
4365             // Call Hdl
4366             ImplCallSizeHdl( hWnd );
4367         }
4368     }
4369 }
4370 
4371 // -----------------------------------------------------------------------
4372 
4373 static void ImplHandleFocusMsg( HWND hWnd )
4374 {
4375     if ( ImplSalYieldMutexTryToAcquire() )
4376     {
4377         WinSalFrame* pFrame = GetWindowPtr( hWnd );
4378         if ( pFrame && !WinSalFrame::mbInReparent )
4379         {
4380             // Query the actual status
4381             if ( ::GetFocus() == hWnd )
4382             {
4383                 if ( IsWindowVisible( hWnd ) && !pFrame->mbInShow )
4384                     UpdateWindow( hWnd );
4385 
4386                 // Feststellen, ob wir IME unterstuetzen
4387                 if ( pFrame->mbIME && pFrame->mhDefIMEContext )
4388                 {
4389                     UINT nImeProps = ImmGetProperty( GetKeyboardLayout( 0 ), IGP_PROPERTY );
4390 
4391                     pFrame->mbSpezIME = (nImeProps & IME_PROP_SPECIAL_UI) != 0;
4392                     pFrame->mbAtCursorIME = (nImeProps & IME_PROP_AT_CARET) != 0;
4393                     pFrame->mbHandleIME = !pFrame->mbSpezIME;
4394                 }
4395 
4396                 pFrame->CallCallback( SALEVENT_GETFOCUS, 0 );
4397             }
4398             else
4399             {
4400                 pFrame->CallCallback( SALEVENT_LOSEFOCUS, 0 );
4401             }
4402         }
4403 
4404         ImplSalYieldMutexRelease();
4405     }
4406     else
4407         ImplPostMessage( hWnd, SAL_MSG_POSTFOCUS, 0, 0 );
4408 }
4409 
4410 // -----------------------------------------------------------------------
4411 
4412 static void ImplHandleCloseMsg( HWND hWnd )
4413 {
4414     if ( ImplSalYieldMutexTryToAcquire() )
4415     {
4416         WinSalFrame* pFrame = GetWindowPtr( hWnd );
4417         if ( pFrame )
4418         {
4419             pFrame->CallCallback( SALEVENT_CLOSE, 0 );
4420         }
4421 
4422         ImplSalYieldMutexRelease();
4423     }
4424     else
4425         ImplPostMessage( hWnd, WM_CLOSE, 0, 0 );
4426 }
4427 
4428 // -----------------------------------------------------------------------
4429 
4430 static long ImplHandleShutDownMsg( HWND hWnd )
4431 {
4432     ImplSalYieldMutexAcquireWithWait();
4433     long        nRet = 0;
4434     WinSalFrame*   pFrame = GetWindowPtr( hWnd );
4435     if ( pFrame )
4436     {
4437         nRet = pFrame->CallCallback( SALEVENT_SHUTDOWN, 0 );
4438     }
4439     ImplSalYieldMutexRelease();
4440     return nRet;
4441 }
4442 
4443 // -----------------------------------------------------------------------
4444 
4445 static void ImplHandleSettingsChangeMsg( HWND hWnd, UINT nMsg,
4446                                          WPARAM wParam, LPARAM lParam )
4447 {
4448     sal_uInt16 nSalEvent = SALEVENT_SETTINGSCHANGED;
4449 
4450     if ( nMsg == WM_DEVMODECHANGE )
4451         nSalEvent = SALEVENT_PRINTERCHANGED;
4452     else if ( nMsg == WM_DISPLAYCHANGE )
4453         nSalEvent = SALEVENT_DISPLAYCHANGED;
4454     else if ( nMsg == WM_FONTCHANGE )
4455         nSalEvent = SALEVENT_FONTCHANGED;
4456     else if ( nMsg == WM_TIMECHANGE )
4457         nSalEvent = SALEVENT_DATETIMECHANGED;
4458     else if ( nMsg == WM_WININICHANGE )
4459     {
4460         if ( lParam )
4461         {
4462                 if ( ImplSalWICompareAscii( (const wchar_t*)lParam, "devices" ) == 0 )
4463                     nSalEvent = SALEVENT_PRINTERCHANGED;
4464         }
4465     }
4466 
4467     if ( nMsg == WM_SETTINGCHANGE )
4468     {
4469         if ( wParam == SPI_SETWHEELSCROLLLINES )
4470             aSalShlData.mnWheelScrollLines = ImplSalGetWheelScrollLines();
4471         else if( wParam == SPI_SETWHEELSCROLLCHARS )
4472             aSalShlData.mnWheelScrollChars = ImplSalGetWheelScrollChars();
4473     }
4474 
4475     if ( WM_SYSCOLORCHANGE == nMsg && GetSalData()->mhDitherPal )
4476         ImplUpdateSysColorEntries();
4477 
4478     ImplSalYieldMutexAcquireWithWait();
4479 
4480     WinSalFrame* pFrame = GetWindowPtr( hWnd );
4481     if ( pFrame )
4482     {
4483         if ( (nMsg == WM_DISPLAYCHANGE) || (nMsg == WM_WININICHANGE) )
4484         {
4485             if ( pFrame->mbFullScreen )
4486                 ImplSalFrameFullScreenPos( pFrame );
4487         }
4488 
4489         pFrame->CallCallback( nSalEvent, 0 );
4490     }
4491 
4492     ImplSalYieldMutexRelease();
4493 }
4494 
4495 // -----------------------------------------------------------------------
4496 
4497 static void ImplHandleUserEvent( HWND hWnd, LPARAM lParam )
4498 {
4499     ImplSalYieldMutexAcquireWithWait();
4500     WinSalFrame* pFrame = GetWindowPtr( hWnd );
4501     if ( pFrame )
4502     {
4503         pFrame->CallCallback( SALEVENT_USEREVENT, (void*)lParam );
4504     }
4505     ImplSalYieldMutexRelease();
4506 }
4507 
4508 // -----------------------------------------------------------------------
4509 
4510 static void ImplHandleForcePalette( HWND hWnd )
4511 {
4512     SalData*    pSalData = GetSalData();
4513     HPALETTE    hPal = pSalData->mhDitherPal;
4514     if ( hPal )
4515     {
4516         if ( !ImplSalYieldMutexTryToAcquire() )
4517         {
4518             ImplPostMessage( hWnd, SAL_MSG_FORCEPALETTE, 0, 0 );
4519             return;
4520         }
4521 
4522         WinSalFrame* pFrame = GetWindowPtr( hWnd );
4523         if ( pFrame && pFrame->mpGraphics )
4524         {
4525             WinSalGraphics* pGraphics = pFrame->mpGraphics;
4526             if ( pGraphics && pGraphics->mhDefPal )
4527             {
4528                 SelectPalette( pGraphics->getHDC(), hPal, FALSE );
4529                 if ( RealizePalette( pGraphics->getHDC() ) )
4530                 {
4531                     InvalidateRect( hWnd, NULL, FALSE );
4532                     UpdateWindow( hWnd );
4533                     pFrame->CallCallback( SALEVENT_DISPLAYCHANGED, 0 );
4534                 }
4535             }
4536         }
4537 
4538         ImplSalYieldMutexRelease();
4539     }
4540 }
4541 
4542 // -----------------------------------------------------------------------
4543 
4544 static LRESULT ImplHandlePalette( sal_Bool bFrame, HWND hWnd, UINT nMsg,
4545                                   WPARAM wParam, LPARAM lParam, int& rDef )
4546 {
4547     SalData*    pSalData = GetSalData();
4548     HPALETTE    hPal = pSalData->mhDitherPal;
4549     if ( !hPal )
4550         return 0;
4551 
4552     rDef = FALSE;
4553     if ( pSalData->mbInPalChange )
4554         return 0;
4555 
4556     if ( (nMsg == WM_PALETTECHANGED) || (nMsg == SAL_MSG_POSTPALCHANGED) )
4557     {
4558         if ( (HWND)wParam == hWnd )
4559             return 0;
4560     }
4561 
4562     sal_Bool bReleaseMutex = FALSE;
4563     if ( (nMsg == WM_QUERYNEWPALETTE) || (nMsg == WM_PALETTECHANGED) )
4564     {
4565         // Da Windows diese Messages auch sendet, muss hier auch die
4566         // Solar-Semaphore beruecksichtigt werden
4567         if ( ImplSalYieldMutexTryToAcquire() )
4568             bReleaseMutex = TRUE;
4569         else if ( nMsg == WM_QUERYNEWPALETTE )
4570             ImplPostMessage( hWnd, SAL_MSG_POSTQUERYNEWPAL, wParam, lParam );
4571         else /* ( nMsg == WM_PALETTECHANGED ) */
4572             ImplPostMessage( hWnd, SAL_MSG_POSTPALCHANGED, wParam, lParam );
4573     }
4574 
4575     WinSalVirtualDevice*pTempVD;
4576     WinSalFrame*        pTempFrame;
4577     WinSalGraphics*     pGraphics;
4578     HDC                 hDC;
4579     HPALETTE            hOldPal;
4580     UINT                nCols;
4581     sal_Bool                bStdDC;
4582     sal_Bool                bUpdate;
4583 
4584     pSalData->mbInPalChange = TRUE;
4585 
4586     // Alle Paletten in VirDevs und Frames zuruecksetzen
4587     pTempVD = pSalData->mpFirstVD;
4588     while ( pTempVD )
4589     {
4590         pGraphics = pTempVD->mpGraphics;
4591         if ( pGraphics->mhDefPal )
4592         {
4593             SelectPalette( pGraphics->getHDC(),
4594                            pGraphics->mhDefPal,
4595                            TRUE );
4596         }
4597         pTempVD = pTempVD->mpNext;
4598     }
4599     pTempFrame = pSalData->mpFirstFrame;
4600     while ( pTempFrame )
4601     {
4602         pGraphics = pTempFrame->mpGraphics;
4603         if ( pGraphics && pGraphics->mhDefPal )
4604         {
4605             SelectPalette( pGraphics->getHDC(),
4606                            pGraphics->mhDefPal,
4607                            TRUE );
4608         }
4609         pTempFrame = pTempFrame->mpNextFrame;
4610     }
4611 
4612     // Palette neu realizen
4613     WinSalFrame* pFrame = NULL;
4614     if ( bFrame )
4615         pFrame = GetWindowPtr( hWnd );
4616     if ( pFrame && pFrame->mpGraphics )
4617     {
4618         hDC = pFrame->mpGraphics->getHDC();
4619         bStdDC = TRUE;
4620     }
4621     else
4622     {
4623         hDC = GetDC( hWnd );
4624         bStdDC = FALSE;
4625     }
4626     UnrealizeObject( hPal );
4627     hOldPal = SelectPalette( hDC, hPal, TRUE );
4628     nCols = RealizePalette( hDC );
4629     bUpdate = nCols != 0;
4630     if ( !bStdDC )
4631     {
4632         SelectPalette( hDC, hOldPal, TRUE );
4633         ReleaseDC( hWnd, hDC );
4634     }
4635 
4636     // Alle Paletten in VirDevs und Frames neu setzen
4637     pTempVD = pSalData->mpFirstVD;
4638     while ( pTempVD )
4639     {
4640         pGraphics = pTempVD->mpGraphics;
4641         if ( pGraphics->mhDefPal )
4642         {
4643             SelectPalette( pGraphics->getHDC(), hPal, TRUE );
4644             RealizePalette( pGraphics->getHDC() );
4645         }
4646         pTempVD = pTempVD->mpNext;
4647     }
4648     pTempFrame = pSalData->mpFirstFrame;
4649     while ( pTempFrame )
4650     {
4651         if ( pTempFrame != pFrame )
4652         {
4653             pGraphics = pTempFrame->mpGraphics;
4654             if ( pGraphics && pGraphics->mhDefPal )
4655             {
4656                 SelectPalette( pGraphics->getHDC(), hPal, TRUE );
4657                 if ( RealizePalette( pGraphics->getHDC() ) )
4658                     bUpdate = TRUE;
4659             }
4660         }
4661         pTempFrame = pTempFrame->mpNextFrame;
4662     }
4663 
4664     // Wenn sich Farben geaendert haben, dann die Fenster updaten
4665     if ( bUpdate )
4666     {
4667         pTempFrame = pSalData->mpFirstFrame;
4668         while ( pTempFrame )
4669         {
4670             pGraphics = pTempFrame->mpGraphics;
4671             if ( pGraphics && pGraphics->mhDefPal )
4672             {
4673                 InvalidateRect( pTempFrame->mhWnd, NULL, FALSE );
4674                 UpdateWindow( pTempFrame->mhWnd );
4675                 pTempFrame->CallCallback( SALEVENT_DISPLAYCHANGED, 0 );
4676             }
4677             pTempFrame = pTempFrame->mpNextFrame;
4678         }
4679     }
4680 
4681     pSalData->mbInPalChange = FALSE;
4682 
4683     if ( bReleaseMutex )
4684         ImplSalYieldMutexRelease();
4685 
4686     if ( nMsg == WM_PALETTECHANGED )
4687         return 0;
4688     else
4689         return nCols;
4690 }
4691 
4692 // -----------------------------------------------------------------------
4693 
4694 static int ImplHandleMinMax( HWND hWnd, LPARAM lParam )
4695 {
4696     int bRet = FALSE;
4697 
4698     if ( ImplSalYieldMutexTryToAcquire() )
4699     {
4700         WinSalFrame* pFrame = GetWindowPtr( hWnd );
4701         if ( pFrame )
4702         {
4703             MINMAXINFO* pMinMax = (MINMAXINFO*)lParam;
4704 
4705             if ( pFrame->mbFullScreen )
4706             {
4707                 int         nX;
4708                 int         nY;
4709                 int         nDX;
4710                 int         nDY;
4711                 ImplSalCalcFullScreenSize( pFrame, nX, nY, nDX, nDY );
4712 
4713                 if ( pMinMax->ptMaxPosition.x > nX )
4714                     pMinMax->ptMaxPosition.x = nX;
4715                 if ( pMinMax->ptMaxPosition.y > nY )
4716                     pMinMax->ptMaxPosition.y = nY;
4717 
4718                 if ( pMinMax->ptMaxSize.x < nDX )
4719                     pMinMax->ptMaxSize.x = nDX;
4720                 if ( pMinMax->ptMaxSize.y < nDY )
4721                     pMinMax->ptMaxSize.y = nDY;
4722                 if ( pMinMax->ptMaxTrackSize.x < nDX )
4723                     pMinMax->ptMaxTrackSize.x = nDX;
4724                 if ( pMinMax->ptMaxTrackSize.y < nDY )
4725                     pMinMax->ptMaxTrackSize.y = nDY;
4726 
4727                 pMinMax->ptMinTrackSize.x = nDX;
4728                 pMinMax->ptMinTrackSize.y = nDY;
4729 
4730                 bRet = TRUE;
4731             }
4732 
4733             if ( pFrame->mnMinWidth || pFrame->mnMinHeight )
4734             {
4735                 int nWidth   = pFrame->mnMinWidth;
4736                 int nHeight  = pFrame->mnMinHeight;
4737 
4738                 ImplSalAddBorder( pFrame, nWidth, nHeight );
4739 
4740                 if ( pMinMax->ptMinTrackSize.x < nWidth )
4741                      pMinMax->ptMinTrackSize.x = nWidth;
4742                 if ( pMinMax->ptMinTrackSize.y < nHeight )
4743                      pMinMax->ptMinTrackSize.y = nHeight;
4744             }
4745 
4746             if ( pFrame->mnMaxWidth || pFrame->mnMaxHeight )
4747             {
4748                 int nWidth   = pFrame->mnMaxWidth;
4749                 int nHeight  = pFrame->mnMaxHeight;
4750 
4751                 ImplSalAddBorder( pFrame, nWidth, nHeight );
4752 
4753                 if( nWidth > 0 && nHeight > 0 ) // protect against int overflow due to INT_MAX initialisation
4754                 {
4755                     if ( pMinMax->ptMaxTrackSize.x > nWidth )
4756                         pMinMax->ptMaxTrackSize.x = nWidth;
4757                     if ( pMinMax->ptMaxTrackSize.y > nHeight )
4758                         pMinMax->ptMaxTrackSize.y = nHeight;
4759                 }
4760             }
4761         }
4762 
4763         ImplSalYieldMutexRelease();
4764     }
4765 
4766     return bRet;
4767 }
4768 
4769 // -----------------------------------------------------------------------
4770 
4771 // retrieves the SalMenuItem pointer from a hMenu
4772 // the pointer is stored in every item, so if no position
4773 // is specified we just use the first item (ie, pos=0)
4774 // if bByPosition is FALSE then nPos denotes a menu id instead of a position
4775 static WinSalMenuItem* ImplGetSalMenuItem( HMENU hMenu, UINT nPos, sal_Bool bByPosition=TRUE )
4776 {
4777     DWORD err=0;
4778 
4779     MENUITEMINFOW mi;
4780     memset(&mi, 0, sizeof(mi));
4781     mi.cbSize = sizeof( mi );
4782     mi.fMask = MIIM_DATA;
4783     if( !GetMenuItemInfoW( hMenu, nPos, bByPosition, &mi) )
4784         err = GetLastError();
4785 
4786     return (WinSalMenuItem *) mi.dwItemData;
4787 }
4788 
4789 // returns the index of the currently selected item if any or -1
4790 static int ImplGetSelectedIndex( HMENU hMenu )
4791 {
4792     DWORD err=0;
4793 
4794     MENUITEMINFOW mi;
4795     memset(&mi, 0, sizeof(mi));
4796     mi.cbSize = sizeof( mi );
4797     mi.fMask = MIIM_STATE;
4798     int n = GetMenuItemCount( hMenu );
4799     if( n != -1 )
4800     {
4801         for(int i=0; i<n; i++ )
4802         {
4803             if( !GetMenuItemInfoW( hMenu, i, TRUE, &mi) )
4804                 err = GetLastError();
4805             else
4806             {
4807                 if( mi.fState & MFS_HILITE )
4808                     return i;
4809             }
4810         }
4811     }
4812     return -1;
4813 }
4814 
4815 static int ImplMenuChar( HWND, WPARAM wParam, LPARAM lParam )
4816 {
4817     int nRet = MNC_IGNORE;
4818     HMENU hMenu = (HMENU) lParam;
4819     String aMnemonic;
4820     aMnemonic.AssignAscii("&");
4821     aMnemonic.Append( (sal_Unicode) LOWORD(wParam) );
4822     aMnemonic.ToLowerAscii();   // we only have ascii mnemonics
4823 
4824     // search the mnemonic in the current menu
4825     int nItemCount = GetMenuItemCount( hMenu );
4826     int nFound = 0;
4827     int idxFound = -1;
4828     int idxSelected = ImplGetSelectedIndex( hMenu );
4829     int idx = idxSelected != -1 ? idxSelected+1 : 0;    // if duplicate mnemonics cycle through menu
4830     for( int i=0; i< nItemCount; i++, idx++ )
4831     {
4832         WinSalMenuItem* pSalMenuItem = ImplGetSalMenuItem( hMenu, idx % nItemCount );
4833         if( !pSalMenuItem )
4834             continue;
4835         String aStr = pSalMenuItem->mText;
4836         aStr.ToLowerAscii();
4837         if( aStr.Search( aMnemonic ) != STRING_NOTFOUND)
4838         {
4839             if( idxFound == -1 )
4840                 idxFound = idx % nItemCount;
4841             if( nFound++ )
4842                 break;  // duplicate found
4843         }
4844     }
4845     if( nFound == 1 )
4846         nRet = MAKELRESULT( idxFound, MNC_EXECUTE );
4847     else
4848         // duplicate mnemonics, just select the next occurence
4849         nRet = MAKELRESULT( idxFound, MNC_SELECT );
4850 
4851     return nRet;
4852 }
4853 
4854 static int ImplMeasureItem( HWND hWnd, WPARAM wParam, LPARAM lParam )
4855 {
4856     int nRet = 0;
4857     if( !wParam )
4858     {
4859         // request was sent by a menu
4860         nRet = 1;
4861         MEASUREITEMSTRUCT *pMI = (LPMEASUREITEMSTRUCT) lParam;
4862         if( pMI->CtlType != ODT_MENU )
4863             return 0;
4864 
4865         WinSalMenuItem *pSalMenuItem = (WinSalMenuItem *) pMI->itemData;
4866         if( !pSalMenuItem )
4867             return 0;
4868 
4869         HDC hdc = GetDC( hWnd );
4870         SIZE strSize;
4871 
4872         NONCLIENTMETRICS ncm;
4873         memset( &ncm, 0, sizeof(ncm) );
4874         ncm.cbSize = sizeof( ncm );
4875         SystemParametersInfo( SPI_GETNONCLIENTMETRICS, 0, (PVOID) &ncm, 0 );
4876 
4877         // Assume every menu item can be default and printed bold
4878         //ncm.lfMenuFont.lfWeight = FW_BOLD;
4879 
4880         HFONT hfntOld = (HFONT) SelectObject(hdc, (HFONT) CreateFontIndirect( &ncm.lfMenuFont ));
4881 
4882         // menu text and accelerator
4883         String aStr(pSalMenuItem->mText.GetBuffer() );
4884         if( pSalMenuItem->mAccelText.Len() )
4885         {
4886             aStr.AppendAscii(" ");
4887             aStr.Append( pSalMenuItem->mAccelText );
4888         }
4889         GetTextExtentPoint32W( hdc, (LPWSTR) aStr.GetBuffer(),
4890                                 aStr.Len(), &strSize );
4891 
4892         // image
4893         Size bmpSize( 16, 16 );
4894         //if( !!pSalMenuItem->maBitmap )
4895         //    bmpSize = pSalMenuItem->maBitmap.GetSizePixel();
4896 
4897         // checkmark
4898         Size checkSize( GetSystemMetrics( SM_CXMENUCHECK ), GetSystemMetrics( SM_CYMENUCHECK ) );
4899 
4900         pMI->itemWidth = checkSize.Width() + 3 + bmpSize.Width() + 3 + strSize.cx;
4901         pMI->itemHeight = Max( Max( checkSize.Height(), bmpSize.Height() ), strSize.cy );
4902         pMI->itemHeight += 4;
4903 
4904         DeleteObject( SelectObject(hdc, hfntOld) );
4905         ReleaseDC( hWnd, hdc );
4906     }
4907 
4908     return nRet;
4909 }
4910 
4911 static int ImplDrawItem(HWND, WPARAM wParam, LPARAM lParam )
4912 {
4913     int nRet = 0;
4914     DWORD err = 0;
4915     if( !wParam )
4916     {
4917         // request was sent by a menu
4918         nRet = 1;
4919         DRAWITEMSTRUCT *pDI = (LPDRAWITEMSTRUCT) lParam;
4920         if( pDI->CtlType != ODT_MENU )
4921             return 0;
4922 
4923         WinSalMenuItem *pSalMenuItem = (WinSalMenuItem *) pDI->itemData;
4924         if( !pSalMenuItem )
4925             return 0;
4926 
4927         COLORREF clrPrevText, clrPrevBkgnd;
4928         HFONT hfntOld;
4929         HBRUSH hbrOld;
4930         sal_Bool	fChecked = (pDI->itemState & ODS_CHECKED) ? TRUE : FALSE;
4931         sal_Bool	fSelected = (pDI->itemState & ODS_SELECTED) ? TRUE : FALSE;
4932         sal_Bool	fDisabled = (pDI->itemState & (ODS_DISABLED | ODS_GRAYED)) ? TRUE : FALSE;
4933 
4934         // Set the appropriate foreground and background colors.
4935         RECT aRect = pDI->rcItem;
4936 
4937         clrPrevBkgnd = SetBkColor( pDI->hDC, GetSysColor( COLOR_MENU ) );
4938 
4939         if ( fDisabled )
4940             clrPrevText = SetTextColor( pDI->hDC, GetSysColor( COLOR_GRAYTEXT ) );
4941         else
4942             clrPrevText = SetTextColor( pDI->hDC, GetSysColor( fSelected ? COLOR_HIGHLIGHTTEXT : COLOR_MENUTEXT ) );
4943 
4944         DWORD colBackground = GetSysColor( fSelected ? COLOR_HIGHLIGHT : COLOR_MENU );
4945         if ( fSelected )
4946 	        clrPrevBkgnd = SetBkColor( pDI->hDC, colBackground );
4947         else
4948 	        clrPrevBkgnd = SetBkColor( pDI->hDC, colBackground );
4949 
4950         hbrOld = (HBRUSH)SelectObject( pDI->hDC, CreateSolidBrush( GetBkColor( pDI->hDC ) ) );
4951 
4952         // Fill background
4953         if(!PatBlt( pDI->hDC, aRect.left, aRect.top, aRect.right-aRect.left, aRect.bottom-aRect.top, PATCOPY ))
4954             err = GetLastError();
4955 
4956         int lineHeight = aRect.bottom-aRect.top;
4957 
4958         int x = aRect.left;
4959         int y = aRect.top;
4960 
4961         int checkWidth  = GetSystemMetrics( SM_CXMENUCHECK );
4962         int checkHeight = GetSystemMetrics( SM_CYMENUCHECK );
4963         if( fChecked )
4964         {
4965             RECT r;
4966             r.left = 0;
4967             r.top = 0;
4968             r.right = checkWidth;
4969             r.bottom = checkWidth;
4970             HDC memDC = CreateCompatibleDC( pDI->hDC );
4971             HBITMAP memBmp = CreateCompatibleBitmap( pDI->hDC, checkWidth, checkHeight );
4972             HBITMAP hOldBmp = (HBITMAP) SelectObject( memDC, memBmp );
4973             DrawFrameControl( memDC, &r, DFC_MENU, DFCS_MENUCHECK );
4974             BitBlt( pDI->hDC, x, y+(lineHeight-checkHeight)/2, checkWidth, checkHeight, memDC, 0, 0, SRCAND );
4975             DeleteObject( SelectObject( memDC, hOldBmp ) );
4976             DeleteDC( memDC );
4977         }
4978         x += checkWidth+3;
4979 
4980         //Size bmpSize = aBitmap.GetSizePixel();
4981         Size bmpSize(16, 16);
4982         if( !!pSalMenuItem->maBitmap )
4983         {
4984             Bitmap aBitmap( pSalMenuItem->maBitmap );
4985 
4986             // set transparent pixels to background color
4987             if( fDisabled )
4988                 colBackground = RGB(255,255,255);
4989             aBitmap.Replace( Color( COL_LIGHTMAGENTA ),
4990                 Color( GetRValue(colBackground),GetGValue(colBackground),GetBValue(colBackground) ), 0);
4991 
4992             WinSalBitmap* pSalBmp = static_cast<WinSalBitmap*>(aBitmap.ImplGetImpBitmap()->ImplGetSalBitmap());
4993 			HGLOBAL hDrawDIB = pSalBmp->ImplGethDIB();
4994 
4995             if( hDrawDIB )
4996             {
4997                 PBITMAPINFO 		pBI = (PBITMAPINFO) GlobalLock( hDrawDIB );
4998 			    PBITMAPINFOHEADER	pBIH = (PBITMAPINFOHEADER) pBI;
4999 			    PBYTE				pBits = (PBYTE) pBI + *(DWORD*) pBI +
5000 										    pSalBmp->ImplGetDIBColorCount( hDrawDIB ) * sizeof( RGBQUAD );
5001 
5002                 HBITMAP hBmp = CreateDIBitmap( pDI->hDC, pBIH, CBM_INIT, pBits, pBI, DIB_RGB_COLORS );
5003 			    GlobalUnlock( hDrawDIB );
5004 
5005                 HBRUSH hbrIcon = CreateSolidBrush( GetSysColor( COLOR_GRAYTEXT ) );
5006                 DrawStateW( pDI->hDC, (HBRUSH)hbrIcon, (DRAWSTATEPROC)NULL, (LPARAM)hBmp, (WPARAM)0,
5007                     x, y+(lineHeight-bmpSize.Height())/2, bmpSize.Width(), bmpSize.Height(),
5008                      DST_BITMAP | (fDisabled ? (fSelected ? DSS_MONO : DSS_DISABLED) : DSS_NORMAL) );
5009 
5010                 DeleteObject( hbrIcon );
5011                 DeleteObject( hBmp );
5012             }
5013 
5014         }
5015         x += bmpSize.Width() + 3;
5016         aRect.left = x;
5017 
5018         NONCLIENTMETRICS ncm;
5019         memset( &ncm, 0, sizeof(ncm) );
5020         ncm.cbSize = sizeof( ncm );
5021         SystemParametersInfo( SPI_GETNONCLIENTMETRICS, 0, (PVOID) &ncm, 0 );
5022 
5023         // Print default menu entry with bold font
5024         //if ( pDI->itemState & ODS_DEFAULT )
5025 	    //    ncm.lfMenuFont.lfWeight = FW_BOLD;
5026 
5027         hfntOld = (HFONT) SelectObject(pDI->hDC, (HFONT) CreateFontIndirect( &ncm.lfMenuFont ));
5028 
5029         SIZE strSize;
5030         String aStr( pSalMenuItem->mText.GetBuffer() );
5031         GetTextExtentPoint32W( pDI->hDC, (LPWSTR) aStr.GetBuffer(),
5032                                 aStr.Len(), &strSize );
5033 
5034         if(!DrawStateW( pDI->hDC, (HBRUSH)NULL, (DRAWSTATEPROC)NULL,
5035             (LPARAM)(LPWSTR) aStr.GetBuffer(),
5036             (WPARAM)0, aRect.left, aRect.top + (lineHeight - strSize.cy)/2, 0, 0,
5037             DST_PREFIXTEXT | (fDisabled && !fSelected ? DSS_DISABLED : DSS_NORMAL) ) )
5038             err = GetLastError();
5039 
5040         if( pSalMenuItem->mAccelText.Len() )
5041         {
5042             SIZE strSizeA;
5043             aStr = pSalMenuItem->mAccelText;
5044             GetTextExtentPoint32W( pDI->hDC, (LPWSTR) aStr.GetBuffer(),
5045                                     aStr.Len(), &strSizeA );
5046             TEXTMETRIC tm;
5047             GetTextMetrics( pDI->hDC, &tm );
5048 
5049             // position the accelerator string to the right but leave space for the
5050             // (potential) submenu arrow (tm.tmMaxCharWidth)
5051             if(!DrawStateW( pDI->hDC, (HBRUSH)NULL, (DRAWSTATEPROC)NULL,
5052                 (LPARAM)(LPWSTR) aStr.GetBuffer(),
5053                 (WPARAM)0, aRect.right-strSizeA.cx-tm.tmMaxCharWidth, aRect.top + (lineHeight - strSizeA.cy)/2, 0, 0,
5054                 DST_TEXT | (fDisabled && !fSelected ? DSS_DISABLED : DSS_NORMAL) ) )
5055                 err = GetLastError();
5056         }
5057 
5058         // Restore the original font and colors.
5059         DeleteObject( SelectObject( pDI->hDC, hbrOld ) );
5060         DeleteObject( SelectObject( pDI->hDC, hfntOld) );
5061         SetTextColor(pDI->hDC, clrPrevText);
5062         SetBkColor(pDI->hDC, clrPrevBkgnd);
5063     }
5064     return nRet;
5065 }
5066 
5067 static int ImplHandleMenuActivate( HWND hWnd, WPARAM wParam, LPARAM )
5068 {
5069     // Menu activation
5070     WinSalFrame* pFrame = GetWindowPtr( hWnd );
5071     if ( !pFrame )
5072         return 0;
5073 
5074     HMENU hMenu = (HMENU) wParam;
5075     // WORD nPos = LOWORD (lParam);
5076     // sal_Bool bWindowMenu = (sal_Bool) HIWORD(lParam);
5077 
5078     // Send activate and deactivate together, so we have not keep track of opened menues
5079     // this will be enough to have the menues updated correctly
5080     SalMenuEvent aMenuEvt;
5081     WinSalMenuItem *pSalMenuItem = ImplGetSalMenuItem( hMenu, 0 );
5082     if( pSalMenuItem )
5083         aMenuEvt.mpMenu = pSalMenuItem->mpMenu;
5084     else
5085         aMenuEvt.mpMenu = NULL;
5086 
5087     long nRet = pFrame->CallCallback( SALEVENT_MENUACTIVATE, &aMenuEvt );
5088     if( nRet )
5089         nRet = pFrame->CallCallback( SALEVENT_MENUDEACTIVATE, &aMenuEvt );
5090     if( nRet )
5091         pFrame->mLastActivatedhMenu = hMenu;
5092 
5093     return (nRet!=0);
5094 }
5095 
5096 static int ImplHandleMenuSelect( HWND hWnd, WPARAM wParam, LPARAM lParam )
5097 {
5098     // Menu selection
5099     WinSalFrame* pFrame = GetWindowPtr( hWnd );
5100     if ( !pFrame )
5101         return 0;
5102 
5103     WORD nId = LOWORD(wParam);      // menu item or submenu index
5104     WORD nFlags = HIWORD(wParam);
5105     HMENU hMenu = (HMENU) lParam;
5106 
5107     // check if we have to process the message
5108     if( !GetSalData()->IsKnownMenuHandle( hMenu ) )
5109         return 0;
5110 
5111     sal_Bool bByPosition = FALSE;
5112     if( nFlags & MF_POPUP )
5113         bByPosition = TRUE;
5114 
5115     long nRet = 0;
5116     if ( hMenu && !pFrame->mLastActivatedhMenu )
5117     {
5118         // we never activated a menu (ie, no WM_INITMENUPOPUP has occured yet)
5119         // which means this must be the menubar -> send activation/deactivation
5120         SalMenuEvent aMenuEvt;
5121         WinSalMenuItem *pSalMenuItem = ImplGetSalMenuItem( hMenu, nId, bByPosition );
5122         if( pSalMenuItem )
5123             aMenuEvt.mpMenu = pSalMenuItem->mpMenu;
5124         else
5125             aMenuEvt.mpMenu = NULL;
5126 
5127         nRet = pFrame->CallCallback( SALEVENT_MENUACTIVATE, &aMenuEvt );
5128         if( nRet )
5129             nRet = pFrame->CallCallback( SALEVENT_MENUDEACTIVATE, &aMenuEvt );
5130         if( nRet )
5131             pFrame->mLastActivatedhMenu = hMenu;
5132     }
5133 
5134     if( !hMenu && nFlags == 0xFFFF )
5135     {
5136         // all menus are closed, reset activation logic
5137         pFrame->mLastActivatedhMenu = NULL;
5138     }
5139 
5140     if( hMenu )
5141     {
5142         // hMenu must be saved, as it is not passed in WM_COMMAND which always occurs after a selection
5143         // if a menu is closed due to a command selection then hMenu is NULL, but WM_COMMAND comes later
5144         // so we must not overwrite it in this case
5145         pFrame->mSelectedhMenu = hMenu;
5146 
5147         // send highlight event
5148         if( nFlags & MF_POPUP )
5149         {
5150             // submenu selected
5151             // wParam now carries an index instead of an id -> retrieve id
5152             MENUITEMINFOW mi;
5153             memset(&mi, 0, sizeof(mi));
5154             mi.cbSize = sizeof( mi );
5155             mi.fMask = MIIM_ID;
5156             if( GetMenuItemInfoW( hMenu, LOWORD(wParam), TRUE, &mi) )
5157                 nId = sal::static_int_cast<WORD>(mi.wID);
5158         }
5159 
5160         SalMenuEvent aMenuEvt;
5161         aMenuEvt.mnId   = nId;
5162         WinSalMenuItem *pSalMenuItem = ImplGetSalMenuItem( hMenu, nId, FALSE );
5163         if( pSalMenuItem )
5164             aMenuEvt.mpMenu = pSalMenuItem->mpMenu;
5165         else
5166             aMenuEvt.mpMenu = NULL;
5167 
5168         nRet = pFrame->CallCallback( SALEVENT_MENUHIGHLIGHT, &aMenuEvt );
5169     }
5170 
5171     return (nRet != 0);
5172 }
5173 
5174 static int ImplHandleCommand( HWND hWnd, WPARAM wParam, LPARAM )
5175 {
5176     WinSalFrame* pFrame = GetWindowPtr( hWnd );
5177     if ( !pFrame )
5178         return 0;
5179 
5180     long nRet = 0;
5181     if( !HIWORD(wParam) )
5182     {
5183         // Menu command
5184         WORD nId = LOWORD(wParam);
5185         if( nId )   // zero for separators
5186         {
5187             SalMenuEvent aMenuEvt;
5188             aMenuEvt.mnId   = nId;
5189             WinSalMenuItem *pSalMenuItem = ImplGetSalMenuItem( pFrame->mSelectedhMenu, nId, FALSE );
5190             if( pSalMenuItem )
5191                 aMenuEvt.mpMenu = pSalMenuItem->mpMenu;
5192             else
5193                 aMenuEvt.mpMenu = NULL;
5194 
5195             nRet = pFrame->CallCallback( SALEVENT_MENUCOMMAND, &aMenuEvt );
5196         }
5197     }
5198     return (nRet != 0);
5199 }
5200 
5201 static int ImplHandleSysCommand( HWND hWnd, WPARAM wParam, LPARAM lParam )
5202 {
5203     WinSalFrame* pFrame = GetWindowPtr( hWnd );
5204     if ( !pFrame )
5205         return 0;
5206 
5207     WPARAM nCommand = wParam & 0xFFF0;
5208 
5209     if ( pFrame->mbFullScreen )
5210     {
5211         BOOL    bMaximize = IsZoomed( pFrame->mhWnd );
5212         BOOL    bMinimize = IsIconic( pFrame->mhWnd );
5213         if ( (nCommand == SC_SIZE) ||
5214              (!bMinimize && (nCommand == SC_MOVE)) ||
5215              (!bMaximize && (nCommand == SC_MAXIMIZE)) ||
5216              (bMaximize && (nCommand == SC_RESTORE)) )
5217         {
5218             MessageBeep( 0 );
5219             return TRUE;
5220         }
5221     }
5222 
5223     if ( nCommand == SC_KEYMENU )
5224     {
5225         // do not process SC_KEYMENU if we have a native menu
5226         // Windows should handle this
5227         if( GetMenu( hWnd ) )
5228             return FALSE;
5229 
5230         // Hier verarbeiten wir nur KeyMenu-Events fuer Alt um
5231         // den MenuBar zu aktivieren, oder wenn ein SysChild-Fenster
5232         // den Focus hat, da diese Alt+Tasten-Kombinationen nur
5233         // ueber diesen Event verarbeitet werden
5234         if ( !LOWORD( lParam ) )
5235         {
5236             // Nur ausloesen, wenn keine weitere Taste gedrueckt ist. Im
5237             // Gegensatz zur Doku wird in der X-Koordinaate der CharCode
5238             // geliefert, der zusaetzlich gedrueckt ist
5239             // Also 32 fuer Space, 99 fuer c, 100 fuer d, ...
5240             // Da dies nicht dokumentiert ist, fragen wir vorsichtshalber
5241             // auch den Status der Space-Taste ab
5242             if ( GetKeyState( VK_SPACE ) & 0x8000 )
5243                 return 0;
5244 
5245             // Damit nicht bei Alt+Maustaste auch der MenuBar aktiviert wird
5246             if ( (GetKeyState( VK_LBUTTON ) & 0x8000) ||
5247                  (GetKeyState( VK_RBUTTON ) & 0x8000) ||
5248                  (GetKeyState( VK_MBUTTON ) & 0x8000) ||
5249 				 (GetKeyState( VK_SHIFT )   & 0x8000) )
5250                 return 1;
5251 
5252             SalKeyEvent aKeyEvt;
5253             aKeyEvt.mnTime      = GetMessageTime();
5254             aKeyEvt.mnCode      = KEY_MENU;
5255             aKeyEvt.mnCharCode  = 0;
5256             aKeyEvt.mnRepeat    = 0;
5257             long nRet = pFrame->CallCallback( SALEVENT_KEYINPUT, &aKeyEvt );
5258             pFrame->CallCallback( SALEVENT_KEYUP, &aKeyEvt );
5259             return (nRet != 0);
5260         }
5261         else
5262         {
5263             // Testen, ob ein SysChild den Focus hat
5264             HWND hFocusWnd = ::GetFocus();
5265             if ( hFocusWnd && ImplFindSalObject( hFocusWnd ) )
5266             {
5267                 char cKeyCode = (char)(unsigned char)LOWORD( lParam );
5268                 // LowerCase
5269                 if ( (cKeyCode >= 65) && (cKeyCode <= 90) )
5270                     cKeyCode += 32;
5271                 // Wir nehmen nur 0-9 und A-Z, alle anderen Tasten muessen durch
5272                 // den Hook vom SalObj verarbeitet werden
5273                 if ( ((cKeyCode >= 48) && (cKeyCode <= 57)) ||
5274                      ((cKeyCode >= 97) && (cKeyCode <= 122)) )
5275                 {
5276                     sal_uInt16 nModCode = 0;
5277                     if ( GetKeyState( VK_SHIFT ) & 0x8000 )
5278                         nModCode |= KEY_SHIFT;
5279                     if ( GetKeyState( VK_CONTROL ) & 0x8000 )
5280                         nModCode |= KEY_MOD1;
5281                     nModCode |= KEY_MOD2;
5282 
5283                     SalKeyEvent aKeyEvt;
5284                     aKeyEvt.mnTime      = GetMessageTime();
5285                     if ( (cKeyCode >= 48) && (cKeyCode <= 57) )
5286                         aKeyEvt.mnCode = KEY_0+(cKeyCode-48);
5287                     else
5288                         aKeyEvt.mnCode = KEY_A+(cKeyCode-97);
5289                     aKeyEvt.mnCode     |= nModCode;
5290                     aKeyEvt.mnCharCode  = cKeyCode;
5291                     aKeyEvt.mnRepeat    = 0;
5292                     long nRet = pFrame->CallCallback( SALEVENT_KEYINPUT, &aKeyEvt );
5293                     pFrame->CallCallback( SALEVENT_KEYUP, &aKeyEvt );
5294                     return (nRet != 0);
5295                 }
5296             }
5297         }
5298     }
5299 
5300     return FALSE;
5301 }
5302 
5303 // -----------------------------------------------------------------------
5304 
5305 static void ImplHandleInputLangChange( HWND hWnd, WPARAM, LPARAM lParam )
5306 {
5307     ImplSalYieldMutexAcquireWithWait();
5308 
5309     // Feststellen, ob wir IME unterstuetzen
5310     WinSalFrame* pFrame = GetWindowPtr( hWnd );
5311     if ( pFrame && pFrame->mbIME && pFrame->mhDefIMEContext )
5312     {
5313         HKL     hKL = (HKL)lParam;
5314         UINT    nImeProps = ImmGetProperty( hKL, IGP_PROPERTY );
5315 
5316         pFrame->mbSpezIME = (nImeProps & IME_PROP_SPECIAL_UI) != 0;
5317         pFrame->mbAtCursorIME = (nImeProps & IME_PROP_AT_CARET) != 0;
5318         pFrame->mbHandleIME = !pFrame->mbSpezIME;
5319     }
5320 
5321     // trigger input language and codepage update
5322     UINT nLang = pFrame->mnInputLang;
5323     ImplUpdateInputLang( pFrame );
5324 
5325     // notify change
5326     if( nLang != pFrame->mnInputLang )
5327         pFrame->CallCallback( SALEVENT_INPUTLANGUAGECHANGE, 0 );
5328 
5329     ImplSalYieldMutexRelease();
5330 }
5331 
5332 // -----------------------------------------------------------------------
5333 
5334 static void ImplUpdateIMECursorPos( WinSalFrame* pFrame, HIMC hIMC )
5335 {
5336     COMPOSITIONFORM aForm;
5337     memset( &aForm, 0, sizeof( aForm ) );
5338 
5339     // Cursor-Position ermitteln und aus der die Default-Position fuer
5340     // das Composition-Fenster berechnen
5341     SalExtTextInputPosEvent aPosEvt;
5342     pFrame->CallCallback( SALEVENT_EXTTEXTINPUTPOS, (void*)&aPosEvt );
5343     if ( (aPosEvt.mnX == -1) && (aPosEvt.mnY == -1) )
5344         aForm.dwStyle |= CFS_DEFAULT;
5345     else
5346     {
5347         aForm.dwStyle          |= CFS_POINT;
5348         aForm.ptCurrentPos.x    = aPosEvt.mnX;
5349         aForm.ptCurrentPos.y    = aPosEvt.mnY;
5350     }
5351     ImmSetCompositionWindow( hIMC, &aForm );
5352 
5353     // Because not all IME's use this values, we create
5354     // a Windows caret to force the Position from the IME
5355     if ( GetFocus() == pFrame->mhWnd )
5356     {
5357         CreateCaret( pFrame->mhWnd, 0,
5358                      aPosEvt.mnWidth, aPosEvt.mnHeight );
5359         SetCaretPos( aPosEvt.mnX, aPosEvt.mnY );
5360     }
5361 }
5362 
5363 // -----------------------------------------------------------------------
5364 
5365 static sal_Bool ImplHandleIMEStartComposition( HWND hWnd )
5366 {
5367     sal_Bool bDef = TRUE;
5368 
5369     ImplSalYieldMutexAcquireWithWait();
5370 
5371     WinSalFrame* pFrame = GetWindowPtr( hWnd );
5372     if ( pFrame )
5373     {
5374         HIMC hIMC = ImmGetContext( hWnd );
5375         if ( hIMC )
5376         {
5377             ImplUpdateIMECursorPos( pFrame, hIMC );
5378             ImmReleaseContext( hWnd, hIMC );
5379         }
5380 
5381         if ( pFrame->mbHandleIME )
5382         {
5383             if ( pFrame->mbAtCursorIME )
5384                 bDef = FALSE;
5385         }
5386     }
5387 
5388     ImplSalYieldMutexRelease();
5389 
5390     return bDef;
5391 }
5392 
5393 // -----------------------------------------------------------------------
5394 
5395 static sal_Bool ImplHandleIMECompositionInput( WinSalFrame* pFrame,
5396                                            HIMC hIMC, LPARAM lParam )
5397 {
5398     sal_Bool bDef = TRUE;
5399 
5400     // Init Event
5401     SalExtTextInputEvent    aEvt;
5402     aEvt.mnTime             = GetMessageTime();
5403     aEvt.mpTextAttr         = NULL;
5404     aEvt.mnCursorPos        = 0;
5405     aEvt.mnDeltaStart       = 0;
5406     aEvt.mbOnlyCursor       = FALSE;
5407     aEvt.mnCursorFlags      = 0;
5408 
5409     // If we get a result string, then we handle this input
5410     if ( lParam & GCS_RESULTSTR )
5411     {
5412         bDef = FALSE;
5413 
5414         LONG nTextLen = ImmGetCompositionStringW( hIMC, GCS_RESULTSTR, 0, 0 ) / sizeof( WCHAR );
5415         if ( nTextLen >= 0 )
5416         {
5417             WCHAR* pTextBuf = new WCHAR[nTextLen];
5418             ImmGetCompositionStringW( hIMC, GCS_RESULTSTR, pTextBuf, nTextLen*sizeof( WCHAR ) );
5419             aEvt.maText = XubString( reinterpret_cast<const xub_Unicode*>(pTextBuf), (xub_StrLen)nTextLen );
5420             delete [] pTextBuf;
5421         }
5422 
5423         aEvt.mnCursorPos = aEvt.maText.Len();
5424         pFrame->CallCallback( SALEVENT_EXTTEXTINPUT, (void*)&aEvt );
5425         pFrame->CallCallback( SALEVENT_ENDEXTTEXTINPUT, (void*)NULL );
5426         ImplUpdateIMECursorPos( pFrame, hIMC );
5427     }
5428 
5429     // If the IME doesn't support OnSpot input, then there is nothing to do
5430     if ( !pFrame->mbAtCursorIME )
5431         return !bDef;
5432 
5433     // If we get new Composition data, then we handle this new input
5434     if ( (lParam & (GCS_COMPSTR | GCS_COMPATTR)) ||
5435          ((lParam & GCS_CURSORPOS) && !(lParam & GCS_RESULTSTR)) )
5436     {
5437         bDef = FALSE;
5438 
5439         sal_uInt16* pSalAttrAry = NULL;
5440         LONG    nTextLen = ImmGetCompositionStringW( hIMC, GCS_COMPSTR, 0, 0 ) / sizeof( WCHAR );
5441         if ( nTextLen > 0 )
5442         {
5443             WCHAR* pTextBuf = new WCHAR[nTextLen];
5444             ImmGetCompositionStringW( hIMC, GCS_COMPSTR, pTextBuf, nTextLen*sizeof( WCHAR ) );
5445             aEvt.maText = XubString( reinterpret_cast<const xub_Unicode*>(pTextBuf), (xub_StrLen)nTextLen );
5446             delete [] pTextBuf;
5447 
5448             BYTE*   pAttrBuf = NULL;
5449             LONG        nAttrLen = ImmGetCompositionStringW( hIMC, GCS_COMPATTR, 0, 0 );
5450             if ( nAttrLen > 0 )
5451             {
5452                 pAttrBuf = new BYTE[nAttrLen];
5453                 ImmGetCompositionStringW( hIMC, GCS_COMPATTR, pAttrBuf, nAttrLen );
5454             }
5455 
5456             if ( pAttrBuf )
5457             {
5458                 xub_StrLen nTextLen = aEvt.maText.Len();
5459                 pSalAttrAry = new sal_uInt16[nTextLen];
5460                 memset( pSalAttrAry, 0, nTextLen*sizeof( sal_uInt16 ) );
5461                 for ( xub_StrLen i = 0; (i < nTextLen) && (i < nAttrLen); i++ )
5462                 {
5463                     BYTE nWinAttr = pAttrBuf[i];
5464                     sal_uInt16   nSalAttr;
5465                     if ( nWinAttr == ATTR_TARGET_CONVERTED )
5466                     {
5467                         nSalAttr = SAL_EXTTEXTINPUT_ATTR_BOLDUNDERLINE;
5468                         aEvt.mnCursorFlags |= SAL_EXTTEXTINPUT_CURSOR_INVISIBLE;
5469                     }
5470                     else if ( nWinAttr == ATTR_CONVERTED )
5471                         nSalAttr = SAL_EXTTEXTINPUT_ATTR_DASHDOTUNDERLINE;
5472                     else if ( nWinAttr == ATTR_TARGET_NOTCONVERTED )
5473                         nSalAttr = SAL_EXTTEXTINPUT_ATTR_HIGHLIGHT;
5474                     else if ( nWinAttr == ATTR_INPUT_ERROR )
5475                         nSalAttr = SAL_EXTTEXTINPUT_ATTR_REDTEXT | SAL_EXTTEXTINPUT_ATTR_DOTTEDUNDERLINE;
5476                     else /* ( nWinAttr == ATTR_INPUT ) */
5477                         nSalAttr = SAL_EXTTEXTINPUT_ATTR_DOTTEDUNDERLINE;
5478                     pSalAttrAry[i] = nSalAttr;
5479                 }
5480 
5481                 aEvt.mpTextAttr = pSalAttrAry;
5482                 delete [] pAttrBuf;
5483             }
5484         }
5485 
5486         // Only when we get new composition data, we must send this event
5487         if ( (nTextLen > 0) || !(lParam & GCS_RESULTSTR) )
5488         {
5489             // End the mode, if the last character is deleted
5490             if ( !nTextLen && !pFrame->mbCandidateMode )
5491             {
5492                 pFrame->CallCallback( SALEVENT_EXTTEXTINPUT, (void*)&aEvt );
5493                 pFrame->CallCallback( SALEVENT_ENDEXTTEXTINPUT, (void*)NULL );
5494             }
5495             else
5496             {
5497                 // Because Cursor-Position and DeltaStart never updated
5498                 // from the korean input engine, we must handle this here
5499                 if ( lParam & CS_INSERTCHAR )
5500                 {
5501                     aEvt.mnCursorPos = nTextLen;
5502                     if ( aEvt.mnCursorPos && (lParam & CS_NOMOVECARET) )
5503                         aEvt.mnCursorPos--;
5504                 }
5505                 else
5506                     aEvt.mnCursorPos = LOWORD( ImmGetCompositionStringW( hIMC, GCS_CURSORPOS, 0, 0 ) );
5507 
5508                 if ( pFrame->mbCandidateMode )
5509                     aEvt.mnCursorFlags |= SAL_EXTTEXTINPUT_CURSOR_INVISIBLE;
5510                 if ( lParam & CS_NOMOVECARET )
5511                     aEvt.mnCursorFlags |= SAL_EXTTEXTINPUT_CURSOR_OVERWRITE;
5512 
5513                 pFrame->CallCallback( SALEVENT_EXTTEXTINPUT, (void*)&aEvt );
5514             }
5515             ImplUpdateIMECursorPos( pFrame, hIMC );
5516         }
5517 
5518         if ( pSalAttrAry )
5519             delete [] pSalAttrAry;
5520     }
5521 
5522     return !bDef;
5523 }
5524 
5525 // -----------------------------------------------------------------------
5526 
5527 static sal_Bool ImplHandleIMEComposition( HWND hWnd, LPARAM lParam )
5528 {
5529     sal_Bool bDef = TRUE;
5530     ImplSalYieldMutexAcquireWithWait();
5531 
5532     WinSalFrame* pFrame = GetWindowPtr( hWnd );
5533     if ( pFrame && (!lParam || (lParam & GCS_RESULTSTR)) )
5534     {
5535         // Wir restaurieren den Background-Modus bei jeder Texteingabe,
5536         // da einige Tools wie RichWin uns diesen hin- und wieder umsetzen
5537         if ( pFrame->mpGraphics &&
5538              pFrame->mpGraphics->getHDC() )
5539             SetBkMode( pFrame->mpGraphics->getHDC(), TRANSPARENT );
5540     }
5541 
5542     if ( pFrame && pFrame->mbHandleIME )
5543     {
5544         if ( !lParam )
5545         {
5546             SalExtTextInputEvent aEvt;
5547             aEvt.mnTime             = GetMessageTime();
5548             aEvt.mpTextAttr         = NULL;
5549             aEvt.mnCursorPos        = 0;
5550             aEvt.mnDeltaStart       = 0;
5551             aEvt.mbOnlyCursor       = FALSE;
5552             aEvt.mnCursorFlags      = 0;
5553             pFrame->CallCallback( SALEVENT_EXTTEXTINPUT, (void*)&aEvt );
5554             pFrame->CallCallback( SALEVENT_ENDEXTTEXTINPUT, (void*)NULL );
5555         }
5556         else if ( lParam & (GCS_RESULTSTR | GCS_COMPSTR | GCS_COMPATTR | GCS_CURSORPOS) )
5557         {
5558             HIMC hIMC = ImmGetContext( hWnd );
5559             if ( hIMC )
5560             {
5561                 if ( ImplHandleIMECompositionInput( pFrame, hIMC, lParam ) )
5562                     bDef = FALSE;
5563 
5564                 ImmReleaseContext( hWnd, hIMC );
5565             }
5566         }
5567     }
5568 
5569     ImplSalYieldMutexRelease();
5570     return bDef;
5571 }
5572 
5573 // -----------------------------------------------------------------------
5574 
5575 static sal_Bool ImplHandleIMEEndComposition( HWND hWnd )
5576 {
5577     sal_Bool bDef = TRUE;
5578 
5579     ImplSalYieldMutexAcquireWithWait();
5580 
5581     WinSalFrame* pFrame = GetWindowPtr( hWnd );
5582     if ( pFrame && pFrame->mbHandleIME )
5583     {
5584         if ( pFrame->mbAtCursorIME )
5585             bDef = FALSE;
5586     }
5587 
5588     ImplSalYieldMutexRelease();
5589 
5590     return bDef;
5591 }
5592 
5593 // -----------------------------------------------------------------------
5594 
5595 static boolean ImplHandleAppCommand( HWND hWnd, LPARAM lParam )
5596 {
5597 	sal_Int16 nCommand = 0;
5598 	switch( GET_APPCOMMAND_LPARAM(lParam) )
5599 	{
5600 	case APPCOMMAND_MEDIA_CHANNEL_DOWN:			nCommand = MEDIA_COMMAND_CHANNEL_DOWN; break;
5601 	case APPCOMMAND_MEDIA_CHANNEL_UP:			nCommand = MEDIA_COMMAND_CHANNEL_UP; break;
5602 	case APPCOMMAND_MEDIA_NEXTTRACK:			nCommand = MEDIA_COMMAND_NEXTTRACK; break;
5603 	case APPCOMMAND_MEDIA_PAUSE:				nCommand = MEDIA_COMMAND_PAUSE; break;
5604 	case APPCOMMAND_MEDIA_PLAY:					nCommand = MEDIA_COMMAND_PLAY; break;
5605 	case APPCOMMAND_MEDIA_PLAY_PAUSE:			nCommand = MEDIA_COMMAND_PLAY_PAUSE; break;
5606 	case APPCOMMAND_MEDIA_PREVIOUSTRACK:		nCommand = MEDIA_COMMAND_PREVIOUSTRACK; break;
5607 	case APPCOMMAND_MEDIA_RECORD:				nCommand = MEDIA_COMMAND_RECORD; break;
5608 	case APPCOMMAND_MEDIA_REWIND:				nCommand = MEDIA_COMMAND_REWIND; break;
5609 	case APPCOMMAND_MEDIA_STOP:					nCommand = MEDIA_COMMAND_STOP; break;
5610 	case APPCOMMAND_MIC_ON_OFF_TOGGLE:			nCommand = MEDIA_COMMAND_MIC_ON_OFF_TOGGLE; break;
5611 	case APPCOMMAND_MICROPHONE_VOLUME_DOWN:		nCommand = MEDIA_COMMAND_MICROPHONE_VOLUME_DOWN; break;
5612 	case APPCOMMAND_MICROPHONE_VOLUME_MUTE:		nCommand = MEDIA_COMMAND_MICROPHONE_VOLUME_MUTE; break;
5613 	case APPCOMMAND_MICROPHONE_VOLUME_UP:		nCommand = MEDIA_COMMAND_MICROPHONE_VOLUME_UP; break;
5614 	case APPCOMMAND_VOLUME_DOWN:				nCommand = MEDIA_COMMAND_VOLUME_DOWN; break;
5615 	case APPCOMMAND_VOLUME_MUTE:				nCommand = MEDIA_COMMAND_VOLUME_MUTE; break;
5616 	case APPCOMMAND_VOLUME_UP:					nCommand = MEDIA_COMMAND_VOLUME_UP; break;
5617 		break;
5618 	default:
5619 		return false;
5620 	}
5621 
5622     WinSalFrame* pFrame = GetWindowPtr( hWnd );
5623 	Window *pWindow = pFrame ? pFrame->GetWindow() : NULL;
5624 
5625 	if( pWindow )
5626 	{
5627 		const Point aPoint;
5628 		CommandEvent aCEvt( aPoint, COMMAND_MEDIA, FALSE, &nCommand );
5629 		NotifyEvent aNCmdEvt( EVENT_COMMAND, pWindow, &aCEvt );
5630 
5631 		if ( !ImplCallPreNotify( aNCmdEvt ) )
5632         {
5633 			pWindow->Command( aCEvt );
5634             return true;
5635         }
5636 	}
5637 
5638     return false;
5639 }
5640 
5641 
5642 static void ImplHandleIMENotify( HWND hWnd, WPARAM wParam )
5643 {
5644     if ( wParam == (WPARAM)IMN_OPENCANDIDATE )
5645     {
5646         ImplSalYieldMutexAcquireWithWait();
5647 
5648         WinSalFrame* pFrame = GetWindowPtr( hWnd );
5649         if ( pFrame && pFrame->mbHandleIME &&
5650              pFrame->mbAtCursorIME )
5651         {
5652             // Wir wollen den Cursor hiden
5653             pFrame->mbCandidateMode = TRUE;
5654             ImplHandleIMEComposition( hWnd, GCS_CURSORPOS );
5655 
5656             HWND hWnd = pFrame->mhWnd;
5657             HIMC hIMC = ImmGetContext( hWnd );
5658             if ( hIMC )
5659             {
5660                 LONG nBufLen = ImmGetCompositionStringW( hIMC, GCS_COMPSTR, 0, 0 );
5661                 if ( nBufLen >= 1 )
5662                 {
5663                     SalExtTextInputPosEvent aPosEvt;
5664                     pFrame->CallCallback( SALEVENT_EXTTEXTINPUTPOS, (void*)&aPosEvt );
5665 
5666                     // Vertical !!!
5667                     CANDIDATEFORM aForm;
5668                     aForm.dwIndex           = 0;
5669                     aForm.dwStyle           = CFS_EXCLUDE;
5670                     aForm.ptCurrentPos.x    = aPosEvt.mnX;
5671                     aForm.ptCurrentPos.y    = aPosEvt.mnY+1;
5672                     aForm.rcArea.left       = aPosEvt.mnX;
5673                     aForm.rcArea.top        = aPosEvt.mnY;
5674                     aForm.rcArea.right      = aForm.rcArea.left+aPosEvt.mnExtWidth+1;
5675                     aForm.rcArea.bottom     = aForm.rcArea.top+aPosEvt.mnHeight+1;
5676                     ImmSetCandidateWindow( hIMC, &aForm );
5677                 }
5678 
5679                 ImmReleaseContext( hWnd, hIMC );
5680             }
5681         }
5682 
5683         ImplSalYieldMutexRelease();
5684     }
5685     else if ( wParam == (WPARAM)IMN_CLOSECANDIDATE )
5686     {
5687         ImplSalYieldMutexAcquireWithWait();
5688         WinSalFrame* pFrame = GetWindowPtr( hWnd );
5689         if ( pFrame )
5690             pFrame->mbCandidateMode = FALSE;
5691         ImplSalYieldMutexRelease();
5692     }
5693 }
5694 
5695 // -----------------------------------------------------------------------
5696 #if WINVER >= 0x0500
5697 
5698 static LRESULT ImplHandleIMEReconvertString( HWND hWnd, LPARAM lParam )
5699 {
5700     WinSalFrame* pFrame = GetWindowPtr( hWnd );
5701     LPRECONVERTSTRING pReconvertString = (LPRECONVERTSTRING) lParam;
5702     LRESULT nRet = 0;
5703     SalSurroundingTextRequestEvent aEvt;
5704     aEvt.maText = UniString();
5705     aEvt.mnStart = aEvt.mnEnd = 0;
5706 
5707     UINT nImeProps = ImmGetProperty( GetKeyboardLayout( 0 ), IGP_SETCOMPSTR );
5708     if( (nImeProps & SCS_CAP_SETRECONVERTSTRING) == 0 )
5709     {
5710 	// This IME does not support reconversion.
5711 	return 0;
5712     }
5713 
5714     if( !pReconvertString )
5715     {
5716 	// The first call for reconversion.
5717 	pFrame->CallCallback( SALEVENT_STARTRECONVERSION, (void*)NULL );
5718 
5719 	// Retrieve the surrounding text from the focused control.
5720 	pFrame->CallCallback( SALEVENT_SURROUNDINGTEXTREQUEST, (void*)&aEvt );
5721 
5722 	if( aEvt.maText.Len() == 0 )
5723 	{
5724 	    return 0;
5725 	}
5726 
5727 	nRet = sizeof(RECONVERTSTRING) + (aEvt.maText.Len() + 1) * sizeof(WCHAR);
5728     }
5729     else
5730     {
5731 	// The second call for reconversion.
5732 
5733 	// Retrieve the surrounding text from the focused control.
5734 	pFrame->CallCallback( SALEVENT_SURROUNDINGTEXTREQUEST, (void*)&aEvt );
5735 	nRet = sizeof(RECONVERTSTRING) + (aEvt.maText.Len() + 1) * sizeof(WCHAR);
5736 
5737 	pReconvertString->dwStrOffset = sizeof(RECONVERTSTRING);
5738 	pReconvertString->dwStrLen = aEvt.maText.Len();
5739 	pReconvertString->dwCompStrOffset = aEvt.mnStart * sizeof(WCHAR);
5740 	pReconvertString->dwCompStrLen = aEvt.mnEnd - aEvt.mnStart;
5741 	pReconvertString->dwTargetStrOffset = pReconvertString->dwCompStrOffset;
5742 	pReconvertString->dwTargetStrLen = pReconvertString->dwCompStrLen;
5743 
5744 	memcpy( (LPWSTR)(pReconvertString + 1), aEvt.maText.GetBuffer(), (aEvt.maText.Len() + 1) * sizeof(WCHAR) );
5745     }
5746 
5747     // just return the required size of buffer to reconvert.
5748     return nRet;
5749 }
5750 
5751 // -----------------------------------------------------------------------
5752 
5753 static LRESULT ImplHandleIMEConfirmReconvertString( HWND hWnd, LPARAM lParam )
5754 {
5755     WinSalFrame* pFrame = GetWindowPtr( hWnd );
5756     LPRECONVERTSTRING pReconvertString = (LPRECONVERTSTRING) lParam;
5757     SalSurroundingTextRequestEvent aEvt;
5758     aEvt.maText = UniString();
5759     aEvt.mnStart = aEvt.mnEnd = 0;
5760 
5761     pFrame->CallCallback( SALEVENT_SURROUNDINGTEXTREQUEST, (void*)&aEvt );
5762 
5763     sal_uLong nTmpStart = pReconvertString->dwCompStrOffset / sizeof(WCHAR);
5764     sal_uLong nTmpEnd = nTmpStart + pReconvertString->dwCompStrLen;
5765 
5766     if( nTmpStart != aEvt.mnStart || nTmpEnd != aEvt.mnEnd )
5767     {
5768 	SalSurroundingTextSelectionChangeEvent aSelEvt;
5769 	aSelEvt.mnStart = nTmpStart;
5770 	aSelEvt.mnEnd = nTmpEnd;
5771 
5772 	pFrame->CallCallback( SALEVENT_SURROUNDINGTEXTSELECTIONCHANGE, (void*)&aSelEvt );
5773     }
5774 
5775     return TRUE;
5776 }
5777 
5778 #endif // WINVER >= 0x0500
5779 
5780 // -----------------------------------------------------------------------
5781 
5782 void SalTestMouseLeave()
5783 {
5784     SalData* pSalData = GetSalData();
5785 
5786     if ( pSalData->mhWantLeaveMsg && !::GetCapture() )
5787     {
5788         POINT aPt;
5789         GetCursorPos( &aPt );
5790         if ( pSalData->mhWantLeaveMsg != WindowFromPoint( aPt ) )
5791             ImplSendMessage( pSalData->mhWantLeaveMsg, SAL_MSG_MOUSELEAVE, 0, MAKELPARAM( aPt.x, aPt.y ) );
5792     }
5793 }
5794 
5795 // -----------------------------------------------------------------------
5796 
5797 static int ImplSalWheelMousePos( HWND hWnd, UINT nMsg, WPARAM wParam, LPARAM lParam ,
5798                                  LRESULT& rResult )
5799 {
5800     POINT aPt;
5801     POINT aScreenPt;
5802     aScreenPt.x = (short)LOWORD( lParam );
5803     aScreenPt.y = (short)HIWORD( lParam );
5804     // Child-Fenster suchen, welches an der entsprechenden
5805     // Position liegt
5806     HWND hChildWnd;
5807     HWND hWheelWnd = hWnd;
5808     do
5809     {
5810         hChildWnd = hWheelWnd;
5811         aPt = aScreenPt;
5812         ScreenToClient( hChildWnd, &aPt );
5813         hWheelWnd = ChildWindowFromPointEx( hChildWnd, aPt, CWP_SKIPINVISIBLE | CWP_SKIPTRANSPARENT );
5814     }
5815     while ( hWheelWnd && (hWheelWnd != hChildWnd) );
5816     if ( hWheelWnd && (hWheelWnd != hWnd) &&
5817          (hWheelWnd != ::GetFocus()) && IsWindowEnabled( hWheelWnd ) )
5818     {
5819         rResult = ImplSendMessage( hWheelWnd, nMsg, wParam, lParam );
5820         return FALSE;
5821     }
5822 
5823     return TRUE;
5824 }
5825 
5826 // -----------------------------------------------------------------------
5827 
5828 LRESULT CALLBACK SalFrameWndProc( HWND hWnd, UINT nMsg, WPARAM wParam, LPARAM lParam, int& rDef )
5829 {
5830     LRESULT     nRet = 0;
5831     static int  bInWheelMsg = FALSE;
5832 	static int	bInQueryEnd = FALSE;
5833 
5834     // By WM_CRETAE we connect the frame with the window handle
5835     if ( nMsg == WM_CREATE )
5836     {
5837         // Window-Instanz am Windowhandle speichern
5838         // Can also be used for the W-Version, because the struct
5839         // to access lpCreateParams is the same structure
5840         CREATESTRUCTA* pStruct = (CREATESTRUCTA*)lParam;
5841         WinSalFrame* pFrame = (WinSalFrame*)pStruct->lpCreateParams;
5842 		if ( pFrame != 0 )
5843 		{
5844 			SetWindowPtr( hWnd, pFrame );
5845 			// HWND schon hier setzen, da schon auf den Instanzdaten
5846 			// gearbeitet werden kann, wenn Messages waehrend
5847 			// CreateWindow() gesendet werden
5848 			pFrame->mhWnd = hWnd;
5849 			pFrame->maSysData.hWnd = hWnd;
5850 		}
5851         return 0;
5852     }
5853 
5854     ImplSVData* pSVData = ImplGetSVData();
5855     // #i72707# TODO: the mbDeInit check will not be needed
5856     // once all windows that are not properly closed on exit got fixed
5857     if( pSVData->mbDeInit )
5858         return 0;
5859 
5860     if ( WM_USER_SYSTEM_WINDOW_ACTIVATED == nMsg )
5861     {
5862         if (pSVData->mpIntroWindow)
5863             pSVData->mpIntroWindow->Hide();
5864 
5865         return 0;
5866     }
5867 
5868 	bool bCheckTimers = false;
5869 
5870     switch( nMsg )
5871     {
5872         case WM_MOUSEMOVE:
5873         case WM_LBUTTONDOWN:
5874         case WM_MBUTTONDOWN:
5875         case WM_RBUTTONDOWN:
5876         case WM_LBUTTONUP:
5877         case WM_MBUTTONUP:
5878         case WM_RBUTTONUP:
5879         case WM_NCMOUSEMOVE:
5880         case SAL_MSG_MOUSELEAVE:
5881             ImplSalYieldMutexAcquireWithWait();
5882             rDef = !ImplHandleMouseMsg( hWnd, nMsg, wParam, lParam );
5883             ImplSalYieldMutexRelease();
5884             break;
5885 
5886         case WM_NCLBUTTONDOWN:
5887         case WM_NCMBUTTONDOWN:
5888         case WM_NCRBUTTONDOWN:
5889             ImplSalYieldMutexAcquireWithWait();
5890             ImplCallClosePopupsHdl( hWnd );   // close popups...
5891             ImplSalYieldMutexRelease();
5892             break;
5893 
5894         case WM_MOUSEACTIVATE:
5895             if ( LOWORD( lParam ) == HTCLIENT )
5896             {
5897                 ImplSalYieldMutexAcquireWithWait();
5898                 nRet = ImplHandleMouseActivateMsg( hWnd );
5899                 ImplSalYieldMutexRelease();
5900                 if ( nRet )
5901                 {
5902                     nRet = MA_NOACTIVATE;
5903                     rDef = FALSE;
5904                 }
5905             }
5906             break;
5907 
5908         case WM_KEYDOWN:
5909         case WM_KEYUP:
5910         case WM_DEADCHAR:
5911         case WM_CHAR:
5912         case WM_UNICHAR:    // MCD, 2003-01-13, Support for WM_UNICHAR & Keyman 6.0
5913         case WM_SYSKEYDOWN:
5914         case WM_SYSKEYUP:
5915         case WM_SYSCHAR:
5916             ImplSalYieldMutexAcquireWithWait();
5917             rDef = !ImplHandleKeyMsg( hWnd, nMsg, wParam, lParam, nRet );
5918             ImplSalYieldMutexRelease();
5919             break;
5920 
5921         case WM_MOUSEWHEEL:
5922             // FALLTHROUGH intended
5923         case WM_MOUSEHWHEEL:
5924             // Gegen Rekursion absichern, falls wir vom IE oder dem externen
5925             // Fenster die Message wieder zurueckbekommen
5926             if ( !bInWheelMsg )
5927             {
5928                 bInWheelMsg++;
5929                 rDef = !ImplHandleWheelMsg( hWnd, nMsg, wParam, lParam );
5930                 // Wenn wir die Message nicht ausgewertet haben, schauen wir
5931                 // noch einmal nach, ob dort ein geplugtes Fenster steht,
5932                 // welches wir dann benachrichtigen
5933                 if ( rDef )
5934                     rDef = ImplSalWheelMousePos( hWnd, nMsg, wParam, lParam, nRet );
5935                 bInWheelMsg--;
5936             }
5937             break;
5938 
5939         case WM_COMMAND:
5940             ImplSalYieldMutexAcquireWithWait();
5941             rDef = !ImplHandleCommand( hWnd, wParam, lParam );
5942             ImplSalYieldMutexRelease();
5943             break;
5944 
5945         case WM_INITMENUPOPUP:
5946             ImplSalYieldMutexAcquireWithWait();
5947             rDef = !ImplHandleMenuActivate( hWnd, wParam, lParam );
5948             ImplSalYieldMutexRelease();
5949             break;
5950 
5951         case WM_MENUSELECT:
5952             ImplSalYieldMutexAcquireWithWait();
5953             rDef = !ImplHandleMenuSelect( hWnd, wParam, lParam );
5954             ImplSalYieldMutexRelease();
5955             break;
5956 
5957         case WM_SYSCOMMAND:
5958             ImplSalYieldMutexAcquireWithWait();
5959             nRet = ImplHandleSysCommand( hWnd, wParam, lParam );
5960             ImplSalYieldMutexRelease();
5961             if ( nRet )
5962                 rDef = FALSE;
5963             break;
5964 
5965         case WM_MENUCHAR:
5966             nRet = ImplMenuChar( hWnd, wParam, lParam );
5967             if( nRet )
5968                 rDef = FALSE;
5969             break;
5970 
5971         case WM_MEASUREITEM:
5972             nRet = ImplMeasureItem(hWnd, wParam, lParam);
5973             if( nRet )
5974                 rDef = FALSE;
5975             break;
5976 
5977         case WM_DRAWITEM:
5978             nRet = ImplDrawItem(hWnd, wParam, lParam);
5979             if( nRet )
5980                 rDef = FALSE;
5981             break;
5982 
5983         case WM_MOVE:
5984         case SAL_MSG_POSTMOVE:
5985             ImplHandleMoveMsg( hWnd );
5986             rDef = FALSE;
5987             break;
5988         case WM_SIZE:
5989             ImplHandleSizeMsg( hWnd, wParam, lParam );
5990             rDef = FALSE;
5991             break;
5992         case SAL_MSG_POSTCALLSIZE:
5993             ImplCallSizeHdl( hWnd );
5994             rDef = FALSE;
5995             break;
5996 
5997         case WM_GETMINMAXINFO:
5998             if ( ImplHandleMinMax( hWnd, lParam ) )
5999                 rDef = FALSE;
6000             break;
6001 
6002         case WM_ERASEBKGND:
6003             nRet = 1;
6004             rDef = FALSE;
6005             break;
6006         case WM_PAINT:
6007             bCheckTimers = ImplHandlePaintMsg( hWnd );
6008             rDef = FALSE;
6009             break;
6010         case SAL_MSG_POSTPAINT:
6011             ImplHandlePaintMsg2( hWnd, (RECT*)wParam );
6012 			bCheckTimers = true;
6013             rDef = FALSE;
6014             break;
6015 
6016         case SAL_MSG_FORCEPALETTE:
6017             ImplHandleForcePalette( hWnd );
6018             rDef = FALSE;
6019             break;
6020 
6021         case WM_QUERYNEWPALETTE:
6022         case SAL_MSG_POSTQUERYNEWPAL:
6023             nRet = ImplHandlePalette( TRUE, hWnd, nMsg, wParam, lParam, rDef );
6024             break;
6025 
6026         case WM_ACTIVATE:
6027             // Wenn wir aktiviert werden, dann wollen wir auch unsere
6028             // Palette setzen. Wir machen dieses in Activate,
6029             // damit andere externe Child-Fenster auch unsere Palette
6030             // ueberschreiben koennen. So wird unsere jedenfalls nur einmal
6031             // gesetzt und nicht immer rekursiv, da an allen anderen Stellen
6032             // diese nur als Background-Palette gesetzt wird
6033             if ( LOWORD( wParam ) != WA_INACTIVE )
6034                 ImplSendMessage( hWnd, SAL_MSG_FORCEPALETTE, 0, 0 );
6035             break;
6036 
6037         case WM_ENABLE:
6038             // #95133# a system dialog is opened/closed, using our app window as parent
6039             {
6040                 WinSalFrame* pFrame = GetWindowPtr( hWnd );
6041                 Window *pWin = NULL;
6042 	            if( pFrame )
6043 	                pWin = pFrame->GetWindow();
6044 
6045                 if( !wParam )
6046                 {
6047                     ImplSVData* pSVData = ImplGetSVData();
6048                     pSVData->maAppData.mnModalMode++;
6049 
6050                     // #106431#, hide SplashScreen
6051                     if( pSVData->mpIntroWindow )
6052                         pSVData->mpIntroWindow->Hide();
6053 
6054                     if( pWin )
6055                     {
6056                         pWin->EnableInput( FALSE, TRUE, TRUE, NULL );
6057                         pWin->ImplIncModalCount();  // #106303# support frame based modal count
6058                     }
6059                 }
6060                 else
6061                 {
6062                     ImplGetSVData()->maAppData.mnModalMode--;
6063                     if( pWin )
6064                     {
6065                         pWin->EnableInput( TRUE, TRUE, TRUE, NULL );
6066                         pWin->ImplDecModalCount();  // #106303# support frame based modal count
6067                     }
6068                 }
6069             }
6070             break;
6071 
6072         case WM_KILLFOCUS:
6073             DestroyCaret();
6074         case WM_SETFOCUS:
6075         case SAL_MSG_POSTFOCUS:
6076             ImplHandleFocusMsg( hWnd );
6077             rDef = FALSE;
6078             break;
6079 
6080         case WM_CLOSE:
6081             ImplHandleCloseMsg( hWnd );
6082             rDef = FALSE;
6083             break;
6084 
6085         case WM_QUERYENDSESSION:
6086 			if( !bInQueryEnd )
6087 			{
6088 				// handle queryendsession only once
6089 				bInQueryEnd = TRUE;
6090 				nRet = !ImplHandleShutDownMsg( hWnd );
6091 				rDef = FALSE;
6092 
6093 				// Issue #16314#: ImplHandleShutDownMsg causes a PostMessage in case of allowing shutdown.
6094 				// This posted message was never processed and cause Windows XP to hang after log off
6095 				// if there are multiple sessions and the current session wasn't the first one started.
6096 				// So if shutdown is allowed we assume that a post message was done and retrieve all
6097 				// messages in the message queue and dispatch them before we return control to the system.
6098 
6099 				if ( nRet )
6100 				{
6101 					MSG	msg;
6102 
6103 					while( PeekMessage( &msg, NULL, 0, 0, PM_REMOVE ) )
6104 					{
6105 						DispatchMessage( &msg );
6106 					}
6107 				}
6108 			}
6109 			else
6110 			{
6111 				ImplSalYieldMutexAcquireWithWait();
6112 				ImplSalYieldMutexRelease();
6113 				rDef = TRUE;
6114 			}
6115             break;
6116 
6117 		case WM_ENDSESSION:
6118 			if( !wParam )
6119 				bInQueryEnd = FALSE; // no shutdown: allow query again
6120 			nRet = FALSE;
6121 			rDef = FALSE;
6122 			break;
6123 
6124         case WM_DISPLAYCHANGE:
6125         case WM_SETTINGCHANGE:
6126         case WM_DEVMODECHANGE:
6127         case WM_FONTCHANGE:
6128         case WM_SYSCOLORCHANGE:
6129         case WM_TIMECHANGE:
6130             ImplHandleSettingsChangeMsg( hWnd, nMsg, wParam, lParam );
6131             break;
6132 
6133         case WM_THEMECHANGED:
6134             GetSalData()->mbThemeChanged = TRUE;
6135             break;
6136 
6137         case SAL_MSG_USEREVENT:
6138             ImplHandleUserEvent( hWnd, lParam );
6139             rDef = FALSE;
6140             break;
6141 
6142         case SAL_MSG_CAPTUREMOUSE:
6143             SetCapture( hWnd );
6144             rDef = FALSE;
6145             break;
6146         case SAL_MSG_RELEASEMOUSE:
6147             if ( ::GetCapture() == hWnd )
6148                 ReleaseCapture();
6149             rDef = FALSE;
6150             break;
6151         case SAL_MSG_TOTOP:
6152             ImplSalToTop( hWnd, (sal_uInt16)wParam );
6153             rDef = FALSE;
6154             break;
6155         case SAL_MSG_SHOW:
6156             ImplSalShow( hWnd, (sal_Bool)wParam, (sal_Bool)lParam );
6157             rDef = FALSE;
6158             break;
6159         case SAL_MSG_SETINPUTCONTEXT:
6160             ImplSalFrameSetInputContext( hWnd, (const SalInputContext*)(void*)lParam );
6161             rDef = FALSE;
6162             break;
6163         case SAL_MSG_ENDEXTTEXTINPUT:
6164             ImplSalFrameEndExtTextInput( hWnd, (sal_uInt16)(sal_uLong)(void*)wParam );
6165             rDef = FALSE;
6166             break;
6167 
6168         case WM_INPUTLANGCHANGE:
6169             ImplHandleInputLangChange( hWnd, wParam, lParam );
6170             break;
6171 
6172         case WM_IME_CHAR:
6173             // #103487#, some IMEs (eg, those that do not work onspot)
6174             //           may send WM_IME_CHAR instead of WM_IME_COMPOSITION
6175             // we just handle it like a WM_CHAR message - seems to work fine
6176             ImplSalYieldMutexAcquireWithWait();
6177             rDef = !ImplHandleKeyMsg( hWnd, WM_CHAR, wParam, lParam, nRet );
6178             ImplSalYieldMutexRelease();
6179             break;
6180 
6181          case WM_IME_STARTCOMPOSITION:
6182             rDef = ImplHandleIMEStartComposition( hWnd );
6183             break;
6184 
6185         case WM_IME_COMPOSITION:
6186             rDef = ImplHandleIMEComposition( hWnd, lParam );
6187             break;
6188 
6189         case WM_IME_ENDCOMPOSITION:
6190             rDef = ImplHandleIMEEndComposition( hWnd );
6191             break;
6192 
6193         case WM_IME_NOTIFY:
6194             ImplHandleIMENotify( hWnd, wParam );
6195             break;
6196 
6197 //IAccessibility2 implementation 2009-----
6198 #ifdef WNT
6199 		case WM_GETOBJECT:
6200 			{
6201 				if (!Application::IsEnableAccessInterface())
6202 				{
6203 					break;
6204 				}
6205 				else
6206 				{
6207 					// IA2 should be enabled automatically
6208 					AllSettings aSettings = Application::GetSettings();
6209 					MiscSettings aMisc = aSettings.GetMiscSettings();
6210 					aMisc.SetEnableATToolSupport( sal_True );
6211 					aSettings.SetMiscSettings( aMisc );
6212 					Application::SetSettings( aSettings );
6213 
6214 					if (Application::GetSettings().GetMiscSettings().GetEnableATToolSupport())
6215 					{
6216 						// Make sure to launch Accessibiliity only the following criterias are satisfied to avoid RFT interrupts regular acc processing
6217 						if (g_acc_manager1 == NULL)
6218 						{
6219 							sal_Bool bCancelled;
6220 							InitAccessBridge(sal_False,bCancelled);
6221 							if( bCancelled )
6222 								break;
6223 						}
6224 						if (g_acc_manager1 != NULL)
6225 						{
6226 							// MT: mhOnSetTitleWnd not set to reasonable value anywhere...
6227 							/*
6228 							sal_Bool bSkipSetTitleClient = sal_False;
6229 							SalFrame* pFrame = GetWindowPtr( hWnd );
6230 							if(pFrame)
6231 							{
6232 							bSkipSetTitleClient = (lParam == OBJID_CLIENT && hWnd == ((WinSalFrame*)pFrame)->mhOnSetTitleWnd);
6233 							}
6234 							*/
6235 							if ( (lParam == OBJID_CLIENT ) /* && !bSkipSetTitleClient */ )
6236 							{
6237 								long RetResult = g_acc_manager1->getAccObjectPtr((long)hWnd, lParam, wParam);
6238 								if(RetResult != 0)
6239 								{
6240 									rDef = FALSE;
6241 									return (HRESULT)RetResult;
6242 								}
6243 							}
6244 						}
6245 					}
6246 				}
6247 				break;
6248 			}
6249 #endif
6250 //-----IAccessibility2 implementation 2009
6251 
6252         case WM_APPCOMMAND:
6253             if( ImplHandleAppCommand( hWnd, lParam ) )
6254             {
6255                 rDef = false;
6256                 nRet = 1;
6257             }
6258             break;
6259 #if WINVER >= 0x0500
6260         case WM_IME_REQUEST:
6261             if ( PtrToInt( wParam ) == IMR_RECONVERTSTRING )
6262             {
6263                 nRet = ImplHandleIMEReconvertString( hWnd, lParam );
6264                 rDef = FALSE;
6265             }
6266 	    else if( PtrToInt( wParam ) == IMR_CONFIRMRECONVERTSTRING )
6267 	    {
6268 		nRet = ImplHandleIMEConfirmReconvertString( hWnd, lParam );
6269 		rDef = FALSE;
6270 	    }
6271             break;
6272 #endif // WINVER >= 0x0500
6273     }
6274 
6275     // WheelMouse-Message abfangen
6276     if ( rDef && (nMsg == aSalShlData.mnWheelMsgId) && aSalShlData.mnWheelMsgId )
6277     {
6278         // Gegen Rekursion absichern, falls wir vom IE oder dem externen
6279         // Fenster die Message wieder zurueckbekommen
6280         if ( !bInWheelMsg )
6281         {
6282             bInWheelMsg++;
6283             // Zuerst wollen wir die Message dispatchen und dann darf auch
6284             // das SystemWindow drankommen
6285             WORD nKeyState = 0;
6286             if ( GetKeyState( VK_SHIFT ) & 0x8000 )
6287                 nKeyState |= MK_SHIFT;
6288             if ( GetKeyState( VK_CONTROL ) & 0x8000 )
6289                 nKeyState |= MK_CONTROL;
6290             // Mutex handling is inside from this call
6291             rDef = !ImplHandleWheelMsg( hWnd,
6292                                         WM_MOUSEWHEEL,
6293                                         MAKEWPARAM( nKeyState, (WORD)wParam ),
6294                                         lParam );
6295             if ( rDef )
6296             {
6297                 HWND hWheelWnd = ::GetFocus();
6298                 if ( hWheelWnd && (hWheelWnd != hWnd) )
6299                 {
6300                     nRet = ImplSendMessage( hWheelWnd, nMsg, wParam, lParam );
6301                     rDef = FALSE;
6302                 }
6303                 else
6304                     rDef = ImplSalWheelMousePos( hWnd, nMsg, wParam, lParam, nRet );
6305             }
6306             bInWheelMsg--;
6307         }
6308     }
6309 
6310 	if( bCheckTimers )
6311 	{
6312 		SalData* pSalData = GetSalData();
6313 		if( pSalData->mnNextTimerTime )
6314 		{
6315 			DWORD nCurTime = GetTickCount();
6316 			if( pSalData->mnNextTimerTime < nCurTime )
6317 			{
6318 				MSG aMsg;
6319 				if( ! ImplPeekMessage( &aMsg, 0, WM_PAINT, WM_PAINT, PM_NOREMOVE | PM_NOYIELD ) )
6320 					ImplPostMessage( pSalData->mpFirstInstance->mhComWnd, SAL_MSG_POSTTIMER, 0, nCurTime );
6321 			}
6322 		}
6323 	}
6324 
6325     return nRet;
6326 }
6327 
6328 LRESULT CALLBACK SalFrameWndProcA( HWND hWnd, UINT nMsg, WPARAM wParam, LPARAM lParam )
6329 {
6330     int bDef = TRUE;
6331     LRESULT nRet = 0;
6332 #ifdef __MINGW32__
6333     jmp_buf jmpbuf;
6334     __SEHandler han;
6335     if (__builtin_setjmp(jmpbuf) == 0)
6336     {
6337         han.Set(jmpbuf, NULL, (__SEHandler::PF)EXCEPTION_EXECUTE_HANDLER);
6338 #else
6339     __try
6340     {
6341 #endif
6342         nRet = SalFrameWndProc( hWnd, nMsg, wParam, lParam, bDef );
6343     }
6344 #ifdef __MINGW32__
6345     han.Reset();
6346 #else
6347     __except(WinSalInstance::WorkaroundExceptionHandlingInUSER32Lib(GetExceptionCode(), GetExceptionInformation()))
6348     {
6349     }
6350 #endif
6351     if ( bDef )
6352         nRet = DefWindowProcA( hWnd, nMsg, wParam, lParam );
6353     return nRet;
6354 }
6355 
6356 LRESULT CALLBACK SalFrameWndProcW( HWND hWnd, UINT nMsg, WPARAM wParam, LPARAM lParam )
6357 {
6358     int bDef = TRUE;
6359     LRESULT nRet = 0;
6360 #ifdef __MINGW32__
6361     jmp_buf jmpbuf;
6362     __SEHandler han;
6363     if (__builtin_setjmp(jmpbuf) == 0)
6364     {
6365         han.Set(jmpbuf, NULL, (__SEHandler::PF)EXCEPTION_EXECUTE_HANDLER);
6366 #else
6367     __try
6368     {
6369 #endif
6370         nRet = SalFrameWndProc( hWnd, nMsg, wParam, lParam, bDef );
6371     }
6372 #ifdef __MINGW32__
6373     han.Reset();
6374 #else
6375     __except(WinSalInstance::WorkaroundExceptionHandlingInUSER32Lib(GetExceptionCode(), GetExceptionInformation()))
6376     {
6377     }
6378 #endif
6379 
6380     if ( bDef )
6381         nRet = DefWindowProcW( hWnd, nMsg, wParam, lParam );
6382     return nRet;
6383 }
6384 
6385 // -----------------------------------------------------------------------
6386 
6387 sal_Bool ImplHandleGlobalMsg( HWND hWnd, UINT nMsg, WPARAM wParam, LPARAM lParam, LRESULT& rlResult )
6388 {
6389 	// handle all messages concerning all frames so they get processed only once
6390     // Must work for Unicode and none Unicode
6391 	sal_Bool bResult = FALSE;
6392     if ( (nMsg == WM_PALETTECHANGED) || (nMsg == SAL_MSG_POSTPALCHANGED) )
6393     {
6394         int bDef = TRUE;
6395         rlResult = ImplHandlePalette( FALSE, hWnd, nMsg, wParam, lParam, bDef );
6396         bResult = (bDef != 0);
6397     }
6398 	else if( nMsg == WM_DISPLAYCHANGE )
6399 	{
6400 		WinSalSystem* pSys = static_cast<WinSalSystem*>(ImplGetSalSystem());
6401 		if( pSys )
6402 			pSys->clearMonitors();
6403 		bResult = (pSys != NULL);
6404 	}
6405 	return bResult;
6406 }
6407 
6408 // -----------------------------------------------------------------------
6409 
6410 sal_Bool ImplWriteLastError( DWORD lastError, const char *szApiCall )
6411 {
6412     static int first=1;
6413     // if VCL_LOGFILE_ENABLED is set, Win32 API error messages can be written
6414     // to %TMP%/vcl.log or %TEMP%/vcl.log
6415     static char *logEnabled = getenv("VCL_LOGFILE_ENABLED");
6416     if( logEnabled )
6417     {
6418         sal_Bool bSuccess = FALSE;
6419         static char *szTmp = getenv("TMP");
6420         if( !szTmp || !*szTmp )
6421             szTmp = getenv("TEMP");
6422         if( szTmp && *szTmp )
6423         {
6424             char fname[5000];
6425             strcpy( fname, szTmp );
6426             if( fname[strlen(fname) - 1] != '\\' )
6427                 strcat( fname, "\\");
6428             strcat( fname, "vcl.log" );
6429             FILE *fp = fopen( fname, "a" ); // always append
6430             if( fp )
6431             {
6432                 if( first )
6433                 {
6434                     first = 0;
6435                     fprintf( fp, "Process ID: %d (0x%x)\n", GetCurrentProcessId(), GetCurrentProcessId() );
6436                 }
6437                 time_t aclock;
6438                 time( &aclock );                           // Get time in seconds
6439                 struct tm *newtime = localtime( &aclock ); // Convert time to struct tm form
6440                 fprintf( fp, asctime( newtime ) );         // print time stamp
6441 
6442                 fprintf( fp, "%s returned %u (0x%x)\n", szApiCall, lastError, lastError );
6443                 bSuccess = TRUE;    // may be FormatMessage fails but we wrote at least the error code
6444 
6445                 LPVOID lpMsgBuf;
6446                 if (FormatMessageA(
6447                     FORMAT_MESSAGE_ALLOCATE_BUFFER |
6448                     FORMAT_MESSAGE_FROM_SYSTEM |
6449                     FORMAT_MESSAGE_IGNORE_INSERTS,
6450                     NULL,
6451                     lastError,
6452                     MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), // Default language
6453                     (LPSTR) &lpMsgBuf,
6454                     0,
6455                     NULL ))
6456                 {
6457                     fprintf( fp, " %s\n", (LPSTR)lpMsgBuf );
6458                     LocalFree( lpMsgBuf );
6459                 }
6460 
6461                 fclose( fp );
6462             }
6463         }
6464         return bSuccess;
6465     }
6466     else
6467         return TRUE;
6468 }
6469 
6470 // -----------------------------------------------------------------------
6471 
6472 //IAccessibility2 implementation 2009-----
6473 #ifdef WNT
6474 bool IsWNTInitAccessBridge()
6475 {
6476 	return NULL != g_acc_manager1;
6477 }
6478 #endif
6479 #ifdef WNT
6480 bool WNTEnableAccessInterface(bool bEnable)
6481 {
6482     ImplSVData* pSVData = ImplGetSVData();
6483 
6484 	BOOL bPreVal = pSVData->maAppData.m_bEnableAccessInterface;
6485 	long nEnable= bEnable;
6486 	::InterlockedExchange(
6487 		(LPLONG)&(pSVData->maAppData.m_bEnableAccessInterface),
6488 		nEnable);
6489 
6490 	return bPreVal;
6491 }
6492 #endif
6493 //-----IAccessibility2 implementation 2009
6494