1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * This file is part of OpenOffice.org.
11 * OpenOffice.org is free software: you can redistribute it and/or modify
12 * it under the terms of the GNU Lesser General Public License version 3
13 * only, as published by the Free Software Foundation.
15 * OpenOffice.org is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 * GNU Lesser General Public License version 3 for more details
19 * (a copy is included in the LICENSE file that accompanied this code).
21 * You should have received a copy of the GNU Lesser General Public License
22 * version 3 along with OpenOffice.org. If not, see
23 * <http://www.openoffice.org/license.html>
24 * for a copy of the LGPLv3 License.
26 ************************************************************************/
28 // MARKER(update_precomp.py): autogen include statement, do not remove
29 #include "precompiled_vcl.hxx"
31 // i72022: ad-hoc to forcibly enable reconversion
37 #include <com/sun/star/lang/XMultiServiceFactory.hpp>
38 #include <com/sun/star/container/XIndexAccess.hpp>
39 #include <com/sun/star/beans/XPropertySet.hpp>
40 #include <com/sun/star/awt/Rectangle.hpp>
41 #include <comphelper/processfactory.hxx>
49 #include <tools/svwin.h>
54 #include <rtl/string.h>
55 #include <rtl/ustring.h>
57 #include <osl/module.h>
58 #include <tools/debug.hxx>
60 // Warning in SDK header
61 #if defined(_MSC_VER) && (_MSC_VER > 1400)
62 #pragma warning( disable: 4242 4244 )
64 #include <wincomp.hxx>
65 #ifndef _SV_SALIDS_HRC
68 #include <vcl/sysdata.hxx>
69 #include <saldata.hxx>
78 #include <vcl/impbmp.hxx>
79 #include <vcl/timer.hxx>
81 #include <vcl/settings.hxx>
82 #ifndef _SV_KEYCOES_HXX
83 #include <vcl/keycodes.hxx>
85 #include <vcl/window.h>
86 #include <vcl/window.hxx>
87 #include <vcl/wrkwin.hxx>
88 #include <vcl/sallayout.hxx>
89 #include <vcl/svapp.hxx>
90 #ifndef _VCL_IMPDEL_HXX
93 #define COMPILE_MULTIMON_STUBS
101 #include <com/sun/star/uno/Exception.hdl>
105 using ::rtl::OUString
;
106 using namespace ::com::sun::star::uno
;
107 using namespace ::com::sun::star::lang
;
108 using namespace ::com::sun::star::container
;
109 using namespace ::com::sun::star::beans
;
111 // The following defines are newly added in Longhorn
112 #ifndef WM_MOUSEHWHEEL
113 # define WM_MOUSEHWHEEL 0x020E
115 #ifndef SPI_GETWHEELSCROLLCHARS
116 # define SPI_GETWHEELSCROLLCHARS 0x006C
118 #ifndef SPI_SETWHEELSCROLLCHARS
119 # define SPI_SETWHEELSCROLLCHARS 0x006D
124 #if OSL_DEBUG_LEVEL > 1
125 void MyOutputDebugString( char *s
) { OutputDebugString( s
); }
128 // misssing prototypes and constants for LayeredWindows
130 //WINUSERAPI BOOL WINAPI SetLayeredWindowAttributes(HWND,COLORREF,BYTE,DWORD);
131 typedef BOOL ( WINAPI
* SetLayeredWindowAttributes_Proc_T
) (HWND
,COLORREF
,BYTE
,DWORD
);
132 static SetLayeredWindowAttributes_Proc_T lpfnSetLayeredWindowAttributes
;
135 // =======================================================================
137 const unsigned int WM_USER_SYSTEM_WINDOW_ACTIVATED
= RegisterWindowMessageA("SYSTEM_WINDOW_ACTIVATED");
139 BOOL
WinSalFrame::mbInReparent
= FALSE
;
141 // =======================================================================
143 // Wegen Fehler in Windows-Headerfiles
144 #ifndef IMN_OPENCANDIDATE
145 #define IMN_OPENCANDIDATE 0x0005
147 #ifndef IMN_CLOSECANDIDATE
148 #define IMN_CLOSECANDIDATE 0x0004
151 #ifndef WM_THEMECHANGED
152 #define WM_THEMECHANGED 0x031A
155 // Macros for support of WM_UNICHAR & Keyman 6.0
156 #define Uni_UTF32ToSurrogate1(ch) (((unsigned long) (ch) - 0x10000) / 0x400 + 0xD800)
157 #define Uni_UTF32ToSurrogate2(ch) (((unsigned long) (ch) - 0x10000) % 0x400 + 0xDC00)
158 #define Uni_SupplementaryPlanesStart 0x10000
160 // =======================================================================
162 static void UpdateFrameGeometry( HWND hWnd
, WinSalFrame
* pFrame
);
163 static void SetMaximizedFrameGeometry( HWND hWnd
, WinSalFrame
* pFrame
);
165 static void ImplSaveFrameState( WinSalFrame
* pFrame
)
167 // Position, Groesse und Status fuer GetWindowState() merken
168 if ( !pFrame
->mbFullScreen
)
170 BOOL bVisible
= (GetWindowStyle( pFrame
->mhWnd
) & WS_VISIBLE
) != 0;
171 if ( IsIconic( pFrame
->mhWnd
) )
173 pFrame
->maState
.mnState
|= SAL_FRAMESTATE_MINIMIZED
;
175 pFrame
->mnShowState
= SW_SHOWMAXIMIZED
;
177 else if ( IsZoomed( pFrame
->mhWnd
) )
179 pFrame
->maState
.mnState
&= ~SAL_FRAMESTATE_MINIMIZED
;
180 pFrame
->maState
.mnState
|= SAL_FRAMESTATE_MAXIMIZED
;
182 pFrame
->mnShowState
= SW_SHOWMAXIMIZED
;
183 pFrame
->mbRestoreMaximize
= TRUE
;
188 GetWindowRect( pFrame
->mhWnd
, &aRect
);
190 // to be consistent with Unix, the frame state is without(!) decoration
192 AdjustWindowRectEx( &aRect2
, GetWindowStyle( pFrame
->mhWnd
),
193 FALSE
, GetWindowExStyle( pFrame
->mhWnd
) );
194 long nTopDeco
= abs( aRect
.top
- aRect2
.top
);
195 long nLeftDeco
= abs( aRect
.left
- aRect2
.left
);
196 long nBottomDeco
= abs( aRect
.bottom
- aRect2
.bottom
);
197 long nRightDeco
= abs( aRect
.right
- aRect2
.right
);
199 pFrame
->maState
.mnState
&= ~(SAL_FRAMESTATE_MINIMIZED
| SAL_FRAMESTATE_MAXIMIZED
);
200 // subtract decoration
201 pFrame
->maState
.mnX
= aRect
.left
+nLeftDeco
;
202 pFrame
->maState
.mnY
= aRect
.top
+nTopDeco
;
203 pFrame
->maState
.mnWidth
= aRect
.right
-aRect
.left
-nLeftDeco
-nRightDeco
;
204 pFrame
->maState
.mnHeight
= aRect
.bottom
-aRect
.top
-nTopDeco
-nBottomDeco
;
206 pFrame
->mnShowState
= SW_SHOWNORMAL
;
207 pFrame
->mbRestoreMaximize
= FALSE
;
212 // -----------------------------------------------------------------------
214 // if pParentRect is set, the workarea of the monitor that contains pParentRect is returned
215 void ImplSalGetWorkArea( HWND hWnd
, RECT
*pRect
, const RECT
*pParentRect
)
217 static int winVerChecked
= 0;
218 static int winVerOk
= 0;
220 // check if we or our parent is fullscreen, then the taskbar should be ignored
221 bool bIgnoreTaskbar
= false;
222 WinSalFrame
* pFrame
= GetWindowPtr( hWnd
);
225 Window
*pWin
= pFrame
->GetWindow();
228 WorkWindow
*pWorkWin
= (pWin
->GetType() == WINDOW_WORKWINDOW
) ? (WorkWindow
*) pWin
: NULL
;
229 if( pWorkWin
&& pWorkWin
->ImplGetWindowImpl()->mbReallyVisible
&& pWorkWin
->IsFullScreenMode() )
231 bIgnoreTaskbar
= true;
235 pWin
= pWin
->ImplGetWindowImpl()->mpParent
;
244 // multi monitor calls not available on Win95/NT
245 if ( aSalShlData
.maVersionInfo
.dwPlatformId
== VER_PLATFORM_WIN32_NT
)
247 if ( aSalShlData
.maVersionInfo
.dwMajorVersion
<= 4 )
250 else if( aSalShlData
.maVersionInfo
.dwPlatformId
== VER_PLATFORM_WIN32_WINDOWS
)
252 if ( aSalShlData
.maVersionInfo
.dwMajorVersion
== 4 && aSalShlData
.maVersionInfo
.dwMinorVersion
== 0 )
253 winVerOk
= 0; // Win95
257 // calculates the work area taking multiple monitors into account
260 static int nMonitors
= GetSystemMetrics( SM_CMONITORS
);
265 pRect
->left
= pRect
->top
= 0;
266 pRect
->right
= GetSystemMetrics( SM_CXSCREEN
);
267 pRect
->bottom
= GetSystemMetrics( SM_CYSCREEN
);
270 SystemParametersInfo( SPI_GETWORKAREA
, 0, pRect
, 0 );
274 if( pParentRect
!= NULL
)
276 // return the size of the monitor where pParentRect lives
280 // get the nearest monitor to the passed rect.
281 hMonitor
= MonitorFromRect(pParentRect
, MONITOR_DEFAULTTONEAREST
);
283 // get the work area or entire monitor rect.
284 mi
.cbSize
= sizeof(mi
);
285 GetMonitorInfo(hMonitor
, &mi
);
286 if( !bIgnoreTaskbar
)
289 *pRect
= mi
.rcMonitor
;
293 // return the union of all monitors
294 pRect
->left
= GetSystemMetrics( SM_XVIRTUALSCREEN
);
295 pRect
->top
= GetSystemMetrics( SM_YVIRTUALSCREEN
);
296 pRect
->right
= pRect
->left
+ GetSystemMetrics( SM_CXVIRTUALSCREEN
);
297 pRect
->bottom
= pRect
->top
+ GetSystemMetrics( SM_CYVIRTUALSCREEN
);
299 // virtualscreen does not take taskbar into account, so use the corresponding
300 // diffs between screen and workarea from the default screen
301 // however, this is still not perfect: the taskbar might not be on the primary screen
302 if( !bIgnoreTaskbar
)
305 SystemParametersInfo( SPI_GETWORKAREA
, 0, &wRect
, 0 );
308 scrRect
.right
= GetSystemMetrics( SM_CXSCREEN
);
309 scrRect
.bottom
= GetSystemMetrics( SM_CYSCREEN
);
311 pRect
->left
+= wRect
.left
;
312 pRect
->top
+= wRect
.top
;
313 pRect
->right
-= scrRect
.right
- wRect
.right
;
314 pRect
->bottom
-= scrRect
.bottom
- wRect
.bottom
;
323 pRect
->left
= pRect
->top
= 0;
324 pRect
->right
= GetSystemMetrics( SM_CXSCREEN
);
325 pRect
->bottom
= GetSystemMetrics( SM_CYSCREEN
);
328 SystemParametersInfo( SPI_GETWORKAREA
, 0, pRect
, 0 );
332 // =======================================================================
334 SalFrame
* ImplSalCreateFrame( WinSalInstance
* pInst
,
335 HWND hWndParent
, ULONG nSalFrameStyle
)
337 WinSalFrame
* pFrame
= new WinSalFrame
;
340 DWORD nExSysStyle
= 0;
341 BOOL bSubFrame
= FALSE
;
343 if( getenv( "SAL_SYNCHRONIZE" ) ) // no buffering of drawing commands
344 GdiSetBatchLimit( 1 );
346 static int bLayeredAPI
= -1;
347 if( bLayeredAPI
== -1 )
350 // check for W2k and XP
351 if ( aSalShlData
.maVersionInfo
.dwPlatformId
== VER_PLATFORM_WIN32_NT
&& aSalShlData
.maVersionInfo
.dwMajorVersion
>= 5 )
353 OUString
aLibraryName( RTL_CONSTASCII_USTRINGPARAM( "user32" ) );
354 oslModule pLib
= osl_loadModule( aLibraryName
.pData
, SAL_LOADMODULE_DEFAULT
);
355 oslGenericFunction pFunc
= NULL
;
357 pFunc
= osl_getAsciiFunctionSymbol( pLib
, "SetLayeredWindowAttributes" );
359 lpfnSetLayeredWindowAttributes
= ( SetLayeredWindowAttributes_Proc_T
) pFunc
;
361 bLayeredAPI
= pFunc
? 1 : 0;
364 static const char* pEnvTransparentFloats
= getenv("SAL_TRANSPARENT_FLOATS" );
366 // determine creation data
367 if ( nSalFrameStyle
& (SAL_FRAME_STYLE_PLUG
| SAL_FRAME_STYLE_SYSTEMCHILD
) )
369 nSysStyle
|= WS_CHILD
;
370 if( nSalFrameStyle
& SAL_FRAME_STYLE_SYSTEMCHILD
)
371 nSysStyle
|= WS_CLIPSIBLINGS
;
375 // #i87402# commenting out WS_CLIPCHILDREN
376 // this breaks SAL_FRAME_STYLE_SYSTEMCHILD handling, which is not
377 // used currently. Probably SAL_FRAME_STYLE_SYSTEMCHILD should be
380 // nSysStyle |= WS_CLIPCHILDREN;
383 nSysStyle
|= WS_POPUP
;
385 pFrame
->mbNoIcon
= TRUE
;
389 // Only with WS_OVRLAPPED we get a useful default position/size
390 if ( (nSalFrameStyle
& (SAL_FRAME_STYLE_SIZEABLE
| SAL_FRAME_STYLE_MOVEABLE
)) ==
391 (SAL_FRAME_STYLE_SIZEABLE
| SAL_FRAME_STYLE_MOVEABLE
) )
392 nSysStyle
|= WS_OVERLAPPED
;
395 nSysStyle
|= WS_POPUP
;
396 if ( !(nSalFrameStyle
& SAL_FRAME_STYLE_MOVEABLE
) )
397 nExSysStyle
|= WS_EX_TOOLWINDOW
; // avoid taskbar appearance, for eg splash screen
401 if ( nSalFrameStyle
& SAL_FRAME_STYLE_MOVEABLE
)
403 pFrame
->mbCaption
= TRUE
;
404 nSysStyle
|= WS_SYSMENU
| WS_CAPTION
;
406 nSysStyle
|= WS_SYSMENU
| WS_MINIMIZEBOX
;
408 nExSysStyle
|= WS_EX_DLGMODALFRAME
;
410 if ( nSalFrameStyle
& SAL_FRAME_STYLE_SIZEABLE
)
412 pFrame
->mbSizeBorder
= TRUE
;
413 nSysStyle
|= WS_THICKFRAME
;
415 nSysStyle
|= WS_MAXIMIZEBOX
;
418 pFrame
->mbFixBorder
= TRUE
;
420 if ( nSalFrameStyle
& SAL_FRAME_STYLE_DEFAULT
)
421 nExSysStyle
|= WS_EX_APPWINDOW
;
423 if( nSalFrameStyle
& SAL_FRAME_STYLE_TOOLWINDOW
424 // #100656# toolwindows lead to bad alt-tab behaviour, if they have the focus
425 // you must press it twice to leave the application
426 // so toolwindows are only used for non sizeable windows
427 // which are typically small, so a small caption makes sense
429 // #103578# looked too bad - above changes reverted
430 /* && !(nSalFrameStyle & SAL_FRAME_STYLE_SIZEABLE) */ )
432 pFrame
->mbNoIcon
= TRUE
;
433 nExSysStyle
|= WS_EX_TOOLWINDOW
;
434 if ( pEnvTransparentFloats
&& bLayeredAPI
== 1 /*&& !(nSalFrameStyle & SAL_FRAME_STYLE_MOVEABLE) */)
435 nExSysStyle
|= WS_EX_LAYERED
;
438 if ( nSalFrameStyle
& SAL_FRAME_STYLE_FLOAT
)
440 nExSysStyle
|= WS_EX_TOOLWINDOW
;
441 pFrame
->mbFloatWin
= TRUE
;
443 if ( pEnvTransparentFloats
&& bLayeredAPI
== 1 /*&& !(nSalFrameStyle & SAL_FRAME_STYLE_MOVEABLE) */)
444 nExSysStyle
|= WS_EX_LAYERED
;
447 if( nSalFrameStyle
& SAL_FRAME_STYLE_TOOLTIP
)
448 nExSysStyle
|= WS_EX_TOPMOST
;
451 pFrame
->mnStyle
= nSalFrameStyle
;
453 // determine show style
454 pFrame
->mnShowState
= SW_SHOWNORMAL
;
455 if ( (nSysStyle
& (WS_POPUP
| WS_MAXIMIZEBOX
| WS_THICKFRAME
)) == (WS_MAXIMIZEBOX
| WS_THICKFRAME
) )
457 if ( GetSystemMetrics( SM_CXSCREEN
) <= 1024 )
458 pFrame
->mnShowState
= SW_SHOWMAXIMIZED
;
461 if ( nSalFrameStyle
& SAL_FRAME_STYLE_DEFAULT
)
463 SalData
* pSalData
= GetSalData();
464 pFrame
->mnShowState
= pSalData
->mnCmdShow
;
465 if ( (pFrame
->mnShowState
!= SW_SHOWMINIMIZED
) &&
466 (pFrame
->mnShowState
!= SW_MINIMIZE
) &&
467 (pFrame
->mnShowState
!= SW_SHOWMINNOACTIVE
) )
469 if ( (pFrame
->mnShowState
== SW_SHOWMAXIMIZED
) ||
470 (pFrame
->mnShowState
== SW_MAXIMIZE
) )
471 pFrame
->mbOverwriteState
= FALSE
;
472 pFrame
->mnShowState
= SW_SHOWMAXIMIZED
;
475 pFrame
->mbOverwriteState
= FALSE
;
479 // Document Windows are also maximized, if the current Document Window
481 HWND hWnd
= GetForegroundWindow();
482 if ( hWnd
&& IsMaximized( hWnd
) &&
483 (GetWindowInstance( hWnd
) == pInst
->mhInst
) &&
484 ((GetWindowStyle( hWnd
) & (WS_POPUP
| WS_MAXIMIZEBOX
| WS_THICKFRAME
)) == (WS_MAXIMIZEBOX
| WS_THICKFRAME
)) )
485 pFrame
->mnShowState
= SW_SHOWMAXIMIZED
;
491 if ( aSalShlData
.mbWNT
)
496 if ( nSalFrameStyle
& (SAL_FRAME_STYLE_MOVEABLE
|SAL_FRAME_STYLE_NOSHADOW
) ) // check if shadow not wanted
497 pClassName
= SAL_SUBFRAME_CLASSNAMEW
;
499 pClassName
= SAL_TMPSUBFRAME_CLASSNAMEW
; // undecorated floaters will get shadow on XP
503 if ( nSalFrameStyle
& SAL_FRAME_STYLE_MOVEABLE
)
504 pClassName
= SAL_FRAME_CLASSNAMEW
;
506 pClassName
= SAL_TMPSUBFRAME_CLASSNAMEW
;
508 hWnd
= CreateWindowExW( nExSysStyle
, pClassName
, L
"", nSysStyle
,
509 CW_USEDEFAULT
, 0, CW_USEDEFAULT
, 0,
510 hWndParent
, 0, pInst
->mhInst
, (void*)pFrame
);
512 ImplWriteLastError( GetLastError(), "CreateWindowEx" );
513 #if OSL_DEBUG_LEVEL > 1
514 // set transparency value
515 if( bLayeredAPI
== 1 && GetWindowExStyle( hWnd
) & WS_EX_LAYERED
)
516 lpfnSetLayeredWindowAttributes( hWnd
, 0, 230, 0x00000002 /*LWA_ALPHA*/ );
523 pClassName
= SAL_SUBFRAME_CLASSNAMEA
;
525 pClassName
= SAL_FRAME_CLASSNAMEA
;
526 hWnd
= CreateWindowExA( nExSysStyle
, pClassName
, "", nSysStyle
,
527 CW_USEDEFAULT
, 0, CW_USEDEFAULT
, 0,
528 hWndParent
, 0, pInst
->mhInst
, (void*)pFrame
);
536 // If we have an Window with an Caption Bar and without
537 // an MaximizeBox, we change the SystemMenu
538 if ( (nSysStyle
& (WS_CAPTION
| WS_MAXIMIZEBOX
)) == (WS_CAPTION
) )
540 HMENU hSysMenu
= GetSystemMenu( hWnd
, FALSE
);
543 if ( !(nSysStyle
& (WS_MINIMIZEBOX
| WS_MAXIMIZEBOX
)) )
544 DeleteMenu( hSysMenu
, SC_RESTORE
, MF_BYCOMMAND
);
546 EnableMenuItem( hSysMenu
, SC_RESTORE
, MF_BYCOMMAND
| MF_GRAYED
| MF_DISABLED
);
547 if ( !(nSysStyle
& WS_MINIMIZEBOX
) )
548 DeleteMenu( hSysMenu
, SC_MINIMIZE
, MF_BYCOMMAND
);
549 if ( !(nSysStyle
& WS_MAXIMIZEBOX
) )
550 DeleteMenu( hSysMenu
, SC_MAXIMIZE
, MF_BYCOMMAND
);
551 if ( !(nSysStyle
& WS_THICKFRAME
) )
552 DeleteMenu( hSysMenu
, SC_SIZE
, MF_BYCOMMAND
);
555 if ( (nSysStyle
& WS_SYSMENU
) && !(nSalFrameStyle
& SAL_FRAME_STYLE_CLOSEABLE
) )
557 HMENU hSysMenu
= GetSystemMenu( hWnd
, FALSE
);
559 EnableMenuItem( hSysMenu
, SC_CLOSE
, MF_BYCOMMAND
| MF_GRAYED
| MF_DISABLED
);
562 // reset input context
563 pFrame
->mhDefIMEContext
= ImmAssociateContext( hWnd
, 0 );
565 // determine output size and state
567 GetClientRect( hWnd
, &aRect
);
568 pFrame
->mnWidth
= aRect
.right
;
569 pFrame
->mnHeight
= aRect
.bottom
;
570 ImplSaveFrameState( pFrame
);
571 pFrame
->mbDefPos
= TRUE
;
573 UpdateFrameGeometry( hWnd
, pFrame
);
575 if( pFrame
->mnShowState
== SW_SHOWMAXIMIZED
)
577 // #96084 set a useful internal window size because
578 // the window will not be maximized (and the size updated) before show()
580 SetMaximizedFrameGeometry( hWnd
, pFrame
);
586 // helper that only creates the HWND
587 // to allow for easy reparenting of system windows, (i.e. destroy and create new)
588 HWND
ImplSalReCreateHWND( HWND hWndParent
, HWND oldhWnd
, BOOL bAsChild
)
590 HINSTANCE hInstance
= GetSalData()->mhInst
;
591 ULONG nSysStyle
= GetWindowLong( oldhWnd
, GWL_STYLE
);
592 ULONG nExSysStyle
= GetWindowLong( oldhWnd
, GWL_EXSTYLE
);
596 nSysStyle
= WS_CHILD
;
601 if ( aSalShlData
.mbWNT
)
603 LPCWSTR pClassName
= SAL_SUBFRAME_CLASSNAMEW
;
604 hWnd
= CreateWindowExW( nExSysStyle
, pClassName
, L
"", nSysStyle
,
605 CW_USEDEFAULT
, 0, CW_USEDEFAULT
, 0,
606 hWndParent
, 0, hInstance
, (void*)GetWindowPtr( oldhWnd
) );
610 LPCSTR pClassName
= SAL_SUBFRAME_CLASSNAMEA
;
611 hWnd
= CreateWindowExA( nExSysStyle
, pClassName
, "", nSysStyle
,
612 CW_USEDEFAULT
, 0, CW_USEDEFAULT
, 0,
613 hWndParent
, 0, hInstance
, (void*)GetWindowPtr( oldhWnd
) );
618 // =======================================================================
620 // Uebersetzungstabelle von System-Keycodes in StarView-Keycodes
621 #define KEY_TAB_SIZE 146
623 static USHORT aImplTranslateKeyTab
[KEY_TAB_SIZE
] =
625 // StarView-Code System-Code Index
634 KEY_BACKSPACE
, // VK_BACK 8
639 KEY_RETURN
, // VK_RETURN 13
651 KEY_HANGUL_HANJA
, // VK_HANJA 25
653 KEY_ESCAPE
, // VK_ESCAPE 27
658 KEY_SPACE
, // VK_SPACE 32
659 KEY_PAGEUP
, // VK_PRIOR 33
660 KEY_PAGEDOWN
, // VK_NEXT 34
661 KEY_END
, // VK_END 35
662 KEY_HOME
, // VK_HOME 36
663 KEY_LEFT
, // VK_LEFT 37
665 KEY_RIGHT
, // VK_RIGHT 39
666 KEY_DOWN
, // VK_DOWN 40
671 KEY_INSERT
, // VK_INSERT 45
672 KEY_DELETE
, // VK_DELETE 46
673 KEY_HELP
, // VK_HELP 47
719 KEY_CONTEXTMENU
, // VK_APPS 93
722 KEY_0
, // VK_NUMPAD0 96
723 KEY_1
, // VK_NUMPAD1 97
724 KEY_2
, // VK_NUMPAD2 98
725 KEY_3
, // VK_NUMPAD3 99
726 KEY_4
, // VK_NUMPAD4 100
727 KEY_5
, // VK_NUMPAD5 101
728 KEY_6
, // VK_NUMPAD6 102
729 KEY_7
, // VK_NUMPAD7 103
730 KEY_8
, // VK_NUMPAD8 104
731 KEY_9
, // VK_NUMPAD9 105
732 KEY_MULTIPLY
, // VK_MULTIPLY 106
733 KEY_ADD
, // VK_ADD 107
734 KEY_DECIMAL
, // VK_SEPARATOR 108
735 KEY_SUBTRACT
, // VK_SUBTRACT 109
736 KEY_DECIMAL
, // VK_DECIMAL 110
737 KEY_DIVIDE
, // VK_DIVIDE 111
747 KEY_F10
, // VK_F10 121
748 KEY_F11
, // VK_F11 122
749 KEY_F12
, // VK_F12 123
750 KEY_F13
, // VK_F13 124
751 KEY_F14
, // VK_F14 125
752 KEY_F15
, // VK_F15 126
753 KEY_F16
, // VK_F16 127
754 KEY_F17
, // VK_F17 128
755 KEY_F18
, // VK_F18 129
756 KEY_F19
, // VK_F19 130
757 KEY_F20
, // VK_F20 131
758 KEY_F21
, // VK_F21 132
759 KEY_F22
, // VK_F22 133
760 KEY_F23
, // VK_F23 134
761 KEY_F24
, // VK_F24 135
774 // =======================================================================
776 static UINT
ImplSalGetWheelScrollLines()
779 HWND hWndMsWheel
= WIN_FindWindow( MSH_WHEELMODULE_CLASS
, MSH_WHEELMODULE_TITLE
);
782 UINT nGetScrollLinesMsgId
= RegisterWindowMessage( MSH_SCROLL_LINES
);
783 nScrLines
= (UINT
)ImplSendMessage( hWndMsWheel
, nGetScrollLinesMsgId
, 0, 0 );
787 if( !SystemParametersInfo( SPI_GETWHEELSCROLLLINES
, 0, &nScrLines
, 0 ) )
796 // -----------------------------------------------------------------------
798 static UINT
ImplSalGetWheelScrollChars()
801 if( !SystemParametersInfo( SPI_GETWHEELSCROLLCHARS
, 0, &nScrChars
, 0 ) )
803 // Depending on Windows version, use proper default or 1 (when
804 // driver emulates hscroll)
805 if( VER_PLATFORM_WIN32_NT
== aSalShlData
.maVersionInfo
.dwPlatformId
&&
806 aSalShlData
.maVersionInfo
.dwMajorVersion
< 6 )
808 // Windows 2000 & WinXP : emulating driver, use step size
814 // Longhorn or above: use proper default value of 3
819 // system settings successfully read
823 // -----------------------------------------------------------------------
825 static void ImplSalAddBorder( const WinSalFrame
* pFrame
, int& width
, int& height
)
827 // transform client size into window size
830 aWinRect
.right
= width
-1;
832 aWinRect
.bottom
= height
-1;
833 AdjustWindowRectEx( &aWinRect
, GetWindowStyle( pFrame
->mhWnd
),
834 FALSE
, GetWindowExStyle( pFrame
->mhWnd
) );
835 width
= aWinRect
.right
- aWinRect
.left
+ 1;
836 height
= aWinRect
.bottom
- aWinRect
.top
+ 1;
839 // -----------------------------------------------------------------------
841 static void ImplSalCalcFullScreenSize( const WinSalFrame
* pFrame
,
842 int& rX
, int& rY
, int& rDX
, int& rDY
)
844 // set window to screen size
853 if ( pFrame
->mbSizeBorder
)
855 nFrameX
= GetSystemMetrics( SM_CXSIZEFRAME
);
856 nFrameY
= GetSystemMetrics( SM_CYSIZEFRAME
);
858 else if ( pFrame
->mbFixBorder
)
860 nFrameX
= GetSystemMetrics( SM_CXFIXEDFRAME
);
861 nFrameY
= GetSystemMetrics( SM_CYFIXEDFRAME
);
863 else if ( pFrame
->mbBorder
)
865 nFrameX
= GetSystemMetrics( SM_CXBORDER
);
866 nFrameY
= GetSystemMetrics( SM_CYBORDER
);
873 if ( pFrame
->mbCaption
)
874 nCaptionY
= GetSystemMetrics( SM_CYCAPTION
);
880 Reference
< XMultiServiceFactory
> xFactory( ::comphelper::getProcessServiceFactory(), UNO_QUERY_THROW
);
881 Reference
< XIndexAccess
> xMultiMon( xFactory
->createInstance(OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.awt.DisplayAccess" ) ) ), UNO_QUERY_THROW
);
882 if( (pFrame
->mnDisplay
>= 0) && (pFrame
->mnDisplay
< xMultiMon
->getCount()) )
884 Reference
< XPropertySet
> xMonitor( xMultiMon
->getByIndex( pFrame
->mnDisplay
), UNO_QUERY_THROW
);
885 com::sun::star::awt::Rectangle aRect
;
886 if( xMonitor
->getPropertyValue( OUString( RTL_CONSTASCII_USTRINGPARAM( "ScreenArea" ) ) ) >>= aRect
)
890 nScreenDX
= aRect
.Width
+1; // difference between java/awt convention and vcl
891 nScreenDY
= aRect
.Height
+1; // difference between java/awt convention and vcl
896 nScreenX
= GetSystemMetrics( SM_XVIRTUALSCREEN
);
897 nScreenY
= GetSystemMetrics( SM_YVIRTUALSCREEN
);
898 nScreenDX
= GetSystemMetrics( SM_CXVIRTUALSCREEN
);
899 nScreenDY
= GetSystemMetrics( SM_CYVIRTUALSCREEN
);
906 if( !nScreenDX
|| !nScreenDY
)
908 nScreenDX
= GetSystemMetrics( SM_CXSCREEN
);
909 nScreenDY
= GetSystemMetrics( SM_CYSCREEN
);
912 rX
= nScreenX
-nFrameX
;
913 rY
= nScreenY
-(nFrameY
+nCaptionY
);
914 rDX
= nScreenDX
+(nFrameX
*2);
915 rDY
= nScreenDY
+(nFrameY
*2)+nCaptionY
;
918 // -----------------------------------------------------------------------
920 static void ImplSalFrameFullScreenPos( WinSalFrame
* pFrame
, BOOL bAlways
= FALSE
)
922 if ( bAlways
|| !IsIconic( pFrame
->mhWnd
) )
924 // set window to screen size
929 ImplSalCalcFullScreenSize( pFrame
, nX
, nY
, nWidth
, nHeight
);
930 SetWindowPos( pFrame
->mhWnd
, 0,
931 nX
, nY
, nWidth
, nHeight
,
932 SWP_NOZORDER
| SWP_NOACTIVATE
);
936 // -----------------------------------------------------------------------
938 WinSalFrame::WinSalFrame()
940 SalData
* pSalData
= GetSalData();
943 mhCursor
= LoadCursor( 0, IDC_ARROW
);
947 mnShowState
= SW_SHOWNORMAL
;
952 mnMaxWidth
= SHRT_MAX
;
953 mnMaxHeight
= SHRT_MAX
;
960 mbSizeBorder
= FALSE
;
961 mbFullScreen
= FALSE
;
962 mbPresentation
= FALSE
;
964 mbRestoreMaximize
= FALSE
;
967 mbFullScreenToolWin
= FALSE
;
969 mbOverwriteState
= TRUE
;
973 mbAtCursorIME
= FALSE
;
974 mbCandidateMode
= FALSE
;
978 mLastActivatedhMenu
= 0;
979 mpClipRgnData
= NULL
;
980 mbFirstClipRect
= TRUE
;
981 mpNextClipRect
= NULL
;
984 memset( &maState
, 0, sizeof( SalFrameState
) );
985 maSysData
.nSize
= sizeof( SystemEnvData
);
987 memset( &maGeometry
, 0, sizeof( maGeometry
) );
989 // Daten ermitteln, wenn erster Frame angelegt wird
990 if ( !pSalData
->mpFirstFrame
)
992 if ( !aSalShlData
.mnWheelMsgId
)
993 aSalShlData
.mnWheelMsgId
= RegisterWindowMessage( MSH_MOUSEWHEEL
);
994 if ( !aSalShlData
.mnWheelScrollLines
)
995 aSalShlData
.mnWheelScrollLines
= ImplSalGetWheelScrollLines();
996 if ( !aSalShlData
.mnWheelScrollChars
)
997 aSalShlData
.mnWheelScrollChars
= ImplSalGetWheelScrollChars();
1000 // insert frame in framelist
1001 mpNextFrame
= pSalData
->mpFirstFrame
;
1002 pSalData
->mpFirstFrame
= this;
1005 // -----------------------------------------------------------------------
1006 void WinSalFrame::updateScreenNumber()
1008 WinSalSystem
* pSys
= static_cast<WinSalSystem
*>(ImplGetSalSystem());
1011 const std::vector
<WinSalSystem::DisplayMonitor
>& rMonitors
=
1012 pSys
->getMonitors();
1013 Point
aPoint( maGeometry
.nX
, maGeometry
.nY
);
1014 size_t nMon
= rMonitors
.size();
1015 for( size_t i
= 0; i
< nMon
; i
++ )
1017 if( rMonitors
[i
].m_aArea
.IsInside( aPoint
) )
1019 mnDisplay
= static_cast<sal_Int32
>(i
);
1020 maGeometry
.nScreenNumber
= static_cast<unsigned int>(i
);
1026 // -----------------------------------------------------------------------
1028 WinSalFrame::~WinSalFrame()
1030 SalData
* pSalData
= GetSalData();
1033 delete [] (BYTE
*)mpClipRgnData
;
1035 // remove frame from framelist
1036 WinSalFrame
** ppFrame
= &pSalData
->mpFirstFrame
;
1037 for(; (*ppFrame
!= this) && *ppFrame
; ppFrame
= &(*ppFrame
)->mpNextFrame
);
1039 *ppFrame
= mpNextFrame
;
1045 ReleaseGraphics( mpGraphics2
);
1050 if ( mpGraphics
->mhDefPal
)
1051 SelectPalette( mpGraphics
->mhDC
, mpGraphics
->mhDefPal
, TRUE
);
1052 ImplSalDeInitGraphics( mpGraphics
);
1053 ReleaseDC( mhWnd
, mpGraphics
->mhDC
);
1060 // reset mouse leave data
1061 if ( pSalData
->mhWantLeaveMsg
== mhWnd
)
1063 pSalData
->mhWantLeaveMsg
= 0;
1064 if ( pSalData
->mpMouseLeaveTimer
)
1066 delete pSalData
->mpMouseLeaveTimer
;
1067 pSalData
->mpMouseLeaveTimer
= NULL
;
1071 // destroy system frame
1072 if ( !DestroyWindow( mhWnd
) )
1073 SetWindowPtr( mhWnd
, 0 );
1079 // -----------------------------------------------------------------------
1081 SalGraphics
* WinSalFrame::GetGraphics()
1086 // Other threads get an own DC, because Windows modify in the
1087 // other case our DC (changing clip region), when they send a
1088 // WM_ERASEBACKGROUND message
1089 SalData
* pSalData
= GetSalData();
1090 if ( pSalData
->mnAppThreadId
!= GetCurrentThreadId() )
1092 // We use only three CacheDC's for all threads, because W9x is limited
1093 // to max. 5 Cache DC's per thread
1094 if ( pSalData
->mnCacheDCInUse
>= 3 )
1099 mpGraphics2
= new WinSalGraphics
;
1100 mpGraphics2
->mhDC
= 0;
1101 mpGraphics2
->mhWnd
= mhWnd
;
1102 mpGraphics2
->mbPrinter
= FALSE
;
1103 mpGraphics2
->mbVirDev
= FALSE
;
1104 mpGraphics2
->mbWindow
= TRUE
;
1105 mpGraphics2
->mbScreen
= TRUE
;
1108 HDC hDC
= (HDC
)ImplSendMessage( pSalData
->mpFirstInstance
->mhComWnd
,
1113 mpGraphics2
->mhDC
= hDC
;
1114 if ( pSalData
->mhDitherPal
)
1116 mpGraphics2
->mhDefPal
= SelectPalette( hDC
, pSalData
->mhDitherPal
, TRUE
);
1117 RealizePalette( hDC
);
1119 ImplSalInitGraphics( mpGraphics2
);
1122 pSalData
->mnCacheDCInUse
++;
1132 HDC hDC
= GetDC( mhWnd
);
1135 mpGraphics
= new WinSalGraphics
;
1136 mpGraphics
->mhDC
= hDC
;
1137 mpGraphics
->mhWnd
= mhWnd
;
1138 mpGraphics
->mbPrinter
= FALSE
;
1139 mpGraphics
->mbVirDev
= FALSE
;
1140 mpGraphics
->mbWindow
= TRUE
;
1141 mpGraphics
->mbScreen
= TRUE
;
1142 if ( pSalData
->mhDitherPal
)
1144 mpGraphics
->mhDefPal
= SelectPalette( hDC
, pSalData
->mhDitherPal
, TRUE
);
1145 RealizePalette( hDC
);
1147 ImplSalInitGraphics( mpGraphics
);
1158 // -----------------------------------------------------------------------
1160 void WinSalFrame::ReleaseGraphics( SalGraphics
* pGraphics
)
1162 if ( mpGraphics2
== pGraphics
)
1164 if ( mpGraphics2
->mhDC
)
1166 SalData
* pSalData
= GetSalData();
1167 if ( mpGraphics2
->mhDefPal
)
1168 SelectPalette( mpGraphics2
->mhDC
, mpGraphics2
->mhDefPal
, TRUE
);
1169 ImplSalDeInitGraphics( mpGraphics2
);
1170 ImplSendMessage( pSalData
->mpFirstInstance
->mhComWnd
,
1173 (LPARAM
)mpGraphics2
->mhDC
);
1174 mpGraphics2
->mhDC
= 0;
1175 pSalData
->mnCacheDCInUse
--;
1182 // -----------------------------------------------------------------------
1184 BOOL
WinSalFrame::PostEvent( void* pData
)
1186 return (BOOL
)ImplPostMessage( mhWnd
, SAL_MSG_USEREVENT
, 0, (LPARAM
)pData
);
1189 // -----------------------------------------------------------------------
1191 void WinSalFrame::SetTitle( const XubString
& rTitle
)
1193 DBG_ASSERT( sizeof( WCHAR
) == sizeof( xub_Unicode
), "WinSalFrame::SetTitle(): WCHAR != sal_Unicode" );
1195 if ( !SetWindowTextW( mhWnd
, reinterpret_cast<LPCWSTR
>(rTitle
.GetBuffer()) ) )
1197 ByteString aAnsiTitle
= ImplSalGetWinAnsiString( rTitle
);
1198 SetWindowTextA( mhWnd
, aAnsiTitle
.GetBuffer() );
1202 // -----------------------------------------------------------------------
1204 void WinSalFrame::SetIcon( USHORT nIcon
)
1206 // If we have a window without an Icon (for example a dialog), ignore this call
1210 // 0 means default (class) icon
1211 HICON hIcon
= NULL
, hSmIcon
= NULL
;
1215 ImplLoadSalIcon( nIcon
, hIcon
, hSmIcon
);
1217 DBG_ASSERT( hIcon
, "WinSalFrame::SetIcon(): Could not load large icon !" );
1218 DBG_ASSERT( hSmIcon
, "WinSalFrame::SetIcon(): Could not load small icon !" );
1220 ImplSendMessage( mhWnd
, WM_SETICON
, ICON_BIG
, (LPARAM
)hIcon
);
1221 ImplSendMessage( mhWnd
, WM_SETICON
, ICON_SMALL
, (LPARAM
)hSmIcon
);
1224 // -----------------------------------------------------------------------
1226 void WinSalFrame::SetMenu( SalMenu
* pSalMenu
)
1228 WinSalMenu
* pWMenu
= static_cast<WinSalMenu
*>(pSalMenu
);
1229 if( pSalMenu
&& pWMenu
->mbMenuBar
)
1230 ::SetMenu( mhWnd
, pWMenu
->mhMenu
);
1233 void WinSalFrame::DrawMenuBar()
1235 ::DrawMenuBar( mhWnd
);
1238 // -----------------------------------------------------------------------
1239 HWND
ImplGetParentHwnd( HWND hWnd
)
1241 WinSalFrame
* pFrame
= GetWindowPtr( hWnd
);
1242 if( !pFrame
|| !pFrame
->GetWindow())
1243 return ::GetParent( hWnd
);
1244 Window
*pRealParent
= pFrame
->GetWindow()->ImplGetWindowImpl()->mpRealParent
;
1246 return static_cast<WinSalFrame
*>(pRealParent
->ImplGetWindowImpl()->mpFrame
)->mhWnd
;
1248 return ::GetParent( hWnd
);
1252 // -----------------------------------------------------------------------
1254 SalFrame
* WinSalFrame::GetParent() const
1256 return GetWindowPtr( ImplGetParentHwnd( mhWnd
) );
1259 // -----------------------------------------------------------------------
1261 static void ImplSalShow( HWND hWnd
, BOOL bVisible
, BOOL bNoActivate
)
1263 WinSalFrame
* pFrame
= GetWindowPtr( hWnd
);
1269 pFrame
->mbDefPos
= FALSE
;
1270 pFrame
->mbOverwriteState
= TRUE
;
1271 pFrame
->mbInShow
= TRUE
;
1273 // #i4715, save position
1274 RECT aRectPreMatrox
, aRectPostMatrox
;
1275 GetWindowRect( hWnd
, &aRectPreMatrox
);
1277 vcl::DeletionListener
aDogTag( pFrame
);
1279 ShowWindow( hWnd
, SW_SHOWNOACTIVATE
);
1281 ShowWindow( hWnd
, pFrame
->mnShowState
);
1282 if( aDogTag
.isDeleted() )
1285 if ( aSalShlData
.mbWXP
&& pFrame
->mbFloatWin
&& !(pFrame
->mnStyle
& SAL_FRAME_STYLE_NOSHADOW
))
1287 // erase the window immediately to improve XP shadow effect
1288 // otherwise the shadow may appears long time before the rest of the window
1289 // especially when accessibility is on
1290 HDC dc
= GetDC( hWnd
);
1292 GetClientRect( hWnd
, &aRect
);
1293 FillRect( dc
, &aRect
, (HBRUSH
) (COLOR_MENU
+1) ); // choose the menucolor, because its mostly noticeable for menues
1294 ReleaseDC( hWnd
, dc
);
1297 // #i4715, matrox centerpopup might have changed our position
1298 // reposition popups without caption (menues, dropdowns, tooltips)
1299 GetWindowRect( hWnd
, &aRectPostMatrox
);
1300 if( (GetWindowStyle( hWnd
) & WS_POPUP
) &&
1301 !pFrame
->mbCaption
&&
1302 (aRectPreMatrox
.left
!= aRectPostMatrox
.left
|| aRectPreMatrox
.top
!= aRectPostMatrox
.top
) )
1303 SetWindowPos( hWnd
, 0, aRectPreMatrox
.left
, aRectPreMatrox
.top
, 0, 0, SWP_NOZORDER
| SWP_NOACTIVATE
| SWP_NOSIZE
);
1305 if( aDogTag
.isDeleted() )
1307 Window
*pClientWin
= pFrame
->GetWindow()->ImplGetClientWindow();
1308 if ( pFrame
->mbFloatWin
|| ( pClientWin
&& (pClientWin
->GetStyle() & WB_SYSTEMFLOATWIN
) ) )
1309 pFrame
->mnShowState
= SW_SHOWNOACTIVATE
;
1311 pFrame
->mnShowState
= SW_SHOW
;
1312 // Damit Taskleiste unter W98 auch gleich ausgeblendet wird
1313 if ( pFrame
->mbPresentation
)
1315 HWND hWndParent
= ::GetParent( hWnd
);
1317 SetForegroundWindow( hWndParent
);
1318 SetForegroundWindow( hWnd
);
1321 pFrame
->mbInShow
= FALSE
;
1322 pFrame
->updateScreenNumber();
1324 // Direct Paint only, if we get the SolarMutx
1325 if ( ImplSalYieldMutexTryToAcquire() )
1327 UpdateWindow( hWnd
);
1328 ImplSalYieldMutexRelease();
1333 // See also Bug #91813# and #68467#
1334 if ( pFrame
->mbFullScreen
&&
1335 pFrame
->mbPresentation
&&
1336 (aSalShlData
.mnVersion
< 500) &&
1337 !::GetParent( hWnd
) )
1339 // Damit im Impress-Player in der Taskleiste nicht durch
1340 // einen Windows-Fehler hin- und wieder mal ein leerer
1341 // Button stehen bleibt, muessen wir hier die Taskleiste
1342 // etwas austricksen. Denn wenn wir im FullScreenMode sind
1343 // und das Fenster hiden kommt Windows anscheinend etwas aus
1344 // dem tritt und somit minimieren wir das Fenster damit es
1346 ANIMATIONINFO aInfo
;
1347 aInfo
.cbSize
= sizeof( aInfo
);
1348 SystemParametersInfo( SPI_GETANIMATION
, 0, &aInfo
, 0 );
1349 if ( aInfo
.iMinAnimate
)
1351 int nOldAni
= aInfo
.iMinAnimate
;
1352 aInfo
.iMinAnimate
= 0;
1353 SystemParametersInfo( SPI_SETANIMATION
, 0, &aInfo
, 0 );
1354 ShowWindow( pFrame
->mhWnd
, SW_SHOWMINNOACTIVE
);
1355 aInfo
.iMinAnimate
= nOldAni
;
1356 SystemParametersInfo( SPI_SETANIMATION
, 0, &aInfo
, 0 );
1359 ShowWindow( hWnd
, SW_SHOWMINNOACTIVE
);
1360 ShowWindow( hWnd
, SW_HIDE
);
1363 ShowWindow( hWnd
, SW_HIDE
);
1367 // -----------------------------------------------------------------------
1370 void WinSalFrame::SetExtendedFrameStyle( SalExtStyle
)
1374 // -----------------------------------------------------------------------
1376 void WinSalFrame::Show( BOOL bVisible
, BOOL bNoActivate
)
1378 // Post this Message to the window, because this only works
1379 // in the thread of the window, which has create this window.
1380 // We post this message to avoid deadlocks
1381 if ( GetSalData()->mnAppThreadId
!= GetCurrentThreadId() )
1382 ImplPostMessage( mhWnd
, SAL_MSG_SHOW
, bVisible
, bNoActivate
);
1384 ImplSalShow( mhWnd
, bVisible
, bNoActivate
);
1387 // -----------------------------------------------------------------------
1389 void WinSalFrame::Enable( BOOL bEnable
)
1391 EnableWindow( mhWnd
, bEnable
);
1394 // -----------------------------------------------------------------------
1396 void WinSalFrame::SetMinClientSize( long nWidth
, long nHeight
)
1398 mnMinWidth
= nWidth
;
1399 mnMinHeight
= nHeight
;
1402 void WinSalFrame::SetMaxClientSize( long nWidth
, long nHeight
)
1404 mnMaxWidth
= nWidth
;
1405 mnMaxHeight
= nHeight
;
1408 // -----------------------------------------------------------------------
1410 void WinSalFrame::SetPosSize( long nX
, long nY
, long nWidth
, long nHeight
,
1413 BOOL bVisible
= (GetWindowStyle( mhWnd
) & WS_VISIBLE
) != 0;
1416 Window
*pClientWin
= GetWindow()->ImplGetClientWindow();
1417 if ( mbFloatWin
|| ( pClientWin
&& (pClientWin
->GetStyle() & WB_SYSTEMFLOATWIN
) ) )
1418 mnShowState
= SW_SHOWNOACTIVATE
;
1420 mnShowState
= SW_SHOWNORMAL
;
1424 if ( IsIconic( mhWnd
) || IsZoomed( mhWnd
) )
1425 ShowWindow( mhWnd
, SW_RESTORE
);
1430 RECT aClientRect
, aWindowRect
;
1431 GetClientRect( mhWnd
, &aClientRect
); // x,y always 0,0, but width and height without border
1432 GetWindowRect( mhWnd
, &aWindowRect
); // x,y in screen coordinates, width and height with border
1434 if ( !(nFlags
& (SAL_FRAME_POSSIZE_X
| SAL_FRAME_POSSIZE_Y
)) )
1435 nPosSize
|= SWP_NOMOVE
;
1438 //DBG_ASSERT( nX && nY, " Windowposition of (0,0) requested!" );
1439 nEvent
= SALEVENT_MOVE
;
1441 if ( !(nFlags
& (SAL_FRAME_POSSIZE_WIDTH
| SAL_FRAME_POSSIZE_HEIGHT
)) )
1442 nPosSize
|= SWP_NOSIZE
;
1444 nEvent
= (nEvent
== SALEVENT_MOVE
) ? SALEVENT_MOVERESIZE
: SALEVENT_RESIZE
;
1446 if ( !(nFlags
& SAL_FRAME_POSSIZE_X
) )
1447 nX
= aWindowRect
.left
;
1448 if ( !(nFlags
& SAL_FRAME_POSSIZE_Y
) )
1449 nY
= aWindowRect
.top
;
1450 if ( !(nFlags
& SAL_FRAME_POSSIZE_WIDTH
) )
1451 nWidth
= aClientRect
.right
-aClientRect
.left
;
1452 if ( !(nFlags
& SAL_FRAME_POSSIZE_HEIGHT
) )
1453 nHeight
= aClientRect
.bottom
-aClientRect
.top
;
1455 // Calculate window size including the border
1458 aWinRect
.right
= (int)nWidth
-1;
1460 aWinRect
.bottom
= (int)nHeight
-1;
1461 AdjustWindowRectEx( &aWinRect
, GetWindowStyle( mhWnd
),
1462 FALSE
, GetWindowExStyle( mhWnd
) );
1463 nWidth
= aWinRect
.right
- aWinRect
.left
+ 1;
1464 nHeight
= aWinRect
.bottom
- aWinRect
.top
+ 1;
1466 if ( !(nPosSize
& SWP_NOMOVE
) && ::GetParent( mhWnd
) )
1468 // --- RTL --- (mirror window pos)
1470 GetClientRect( ImplGetParentHwnd( mhWnd
), &aParentRect
);
1471 if( Application::GetSettings().GetLayoutRTL() )
1472 nX
= (aParentRect
.right
- aParentRect
.left
) - nWidth
-1 - nX
;
1474 //#110386#, do not transform coordinates for system child windows
1475 if( !(GetWindowStyle( mhWnd
) & WS_CHILD
) )
1481 HWND parentHwnd
= ImplGetParentHwnd( mhWnd
);
1482 WinSalFrame
* pParentFrame
= GetWindowPtr( parentHwnd
);
1483 if ( pParentFrame
&& pParentFrame
->mnShowState
== SW_SHOWMAXIMIZED
)
1485 // #i42485#: parent will be shown maximized in which case
1486 // a ClientToScreen uses the wrong coordinates (i.e. those from the restore pos)
1487 // so use the (already updated) frame geometry for the transformation
1488 aPt
.x
+= pParentFrame
->maGeometry
.nX
;
1489 aPt
.y
+= pParentFrame
->maGeometry
.nY
;
1492 ClientToScreen( parentHwnd
, &aPt
);
1499 // #i3338# to be conformant to UNIX we must position the client window, ie without the decoration
1500 // #i43250# if the position was read from the system (GetWindowRect(), see above), it must not be modified
1501 if ( nFlags
& SAL_FRAME_POSSIZE_X
)
1502 nX
+= aWinRect
.left
;
1503 if ( nFlags
& SAL_FRAME_POSSIZE_Y
)
1513 ImplSalGetWorkArea( mhWnd
, &aRect
, NULL
);
1514 nScreenX
= aRect
.left
;
1515 nScreenY
= aRect
.top
;
1516 nScreenWidth
= aRect
.right
-aRect
.left
;
1517 nScreenHeight
= aRect
.bottom
-aRect
.top
;
1519 if ( mbDefPos
&& (nPosSize
& SWP_NOMOVE
)) // we got no positioning request, so choose default position
1523 HWND hWndParent
= ::GetParent( mhWnd
);
1524 // Search for TopLevel Frame
1525 while ( hWndParent
&& (GetWindowStyle( hWndParent
) & WS_CHILD
) )
1526 hWndParent
= ::GetParent( hWndParent
);
1527 // if the Window has a Parent, than center the window to
1528 // the parent, in the other case to the screen
1529 if ( hWndParent
&& !IsIconic( hWndParent
) &&
1530 (GetWindowStyle( hWndParent
) & WS_VISIBLE
) )
1533 GetWindowRect( hWndParent
, &aParentRect
);
1534 int nParentWidth
= aParentRect
.right
-aParentRect
.left
;
1535 int nParentHeight
= aParentRect
.bottom
-aParentRect
.top
;
1537 // We don't center, when Parent is smaller than our window
1538 if ( (nParentWidth
-GetSystemMetrics( SM_CXFIXEDFRAME
) <= nWidth
) &&
1539 (nParentHeight
-GetSystemMetrics( SM_CYFIXEDFRAME
) <= nHeight
) )
1541 int nOff
= GetSystemMetrics( SM_CYSIZEFRAME
) + GetSystemMetrics( SM_CYCAPTION
);
1542 nX
= aParentRect
.left
+nOff
;
1543 nY
= aParentRect
.top
+nOff
;
1547 nX
= (nParentWidth
-nWidth
)/2 + aParentRect
.left
;
1548 nY
= (nParentHeight
-nHeight
)/2 + aParentRect
.top
;
1554 GetCursorPos( &pt
);
1558 aRect
.right
= pt
.x
+2;
1559 aRect
.bottom
= pt
.y
+2;
1561 // dualmonitor support:
1562 // Get screensize of the monitor whith the mouse pointer
1563 ImplSalGetWorkArea( mhWnd
, &aRect
, &aRect
);
1565 nX
= ((aRect
.right
-aRect
.left
)-nWidth
)/2 + aRect
.left
;
1566 nY
= ((aRect
.bottom
-aRect
.top
)-nHeight
)/2 + aRect
.top
;
1571 // mbDefPos = FALSE;
1573 mbDefPos
= FALSE
; // center only once
1574 nPosSize
&= ~SWP_NOMOVE
; // activate positioning
1575 nEvent
= SALEVENT_MOVERESIZE
;
1579 // Adjust Window in the screen
1580 BOOL bCheckOffScreen
= TRUE
;
1582 // but don't do this for floaters or ownerdraw windows that are currently moved interactively
1583 if( (mnStyle
& SAL_FRAME_STYLE_FLOAT
) && !(mnStyle
& SAL_FRAME_STYLE_OWNERDRAWDECORATION
) )
1584 bCheckOffScreen
= FALSE
;
1586 if( mnStyle
& SAL_FRAME_STYLE_OWNERDRAWDECORATION
)
1588 // may be the window is currently being moved (mouse is captured), then no check is required
1589 if( mhWnd
== ::GetCapture() )
1590 bCheckOffScreen
= FALSE
;
1592 bCheckOffScreen
= TRUE
;
1595 if( bCheckOffScreen
)
1597 if ( nX
+nWidth
> nScreenX
+nScreenWidth
)
1598 nX
= (nScreenX
+nScreenWidth
) - nWidth
;
1599 if ( nY
+nHeight
> nScreenY
+nScreenHeight
)
1600 nY
= (nScreenY
+nScreenHeight
) - nHeight
;
1601 if ( nX
< nScreenX
)
1603 if ( nY
< nScreenY
)
1607 UINT nPosFlags
= SWP_NOACTIVATE
| SWP_NOOWNERZORDER
| nPosSize
;
1608 // bring floating windows always to top
1609 if( !(mnStyle
& SAL_FRAME_STYLE_FLOAT
) )
1610 nPosFlags
|= SWP_NOZORDER
; // do not change z-order
1612 SetWindowPos( mhWnd
, HWND_TOP
, nX
, nY
, (int)nWidth
, (int)nHeight
, nPosFlags
);
1614 UpdateFrameGeometry( mhWnd
, this );
1616 // Notification -- really ???
1618 CallCallback( nEvent
, NULL
);
1621 // -----------------------------------------------------------------------
1623 static void ImplSetParentFrame( WinSalFrame
* pThis
, HWND hNewParentWnd
, BOOL bAsChild
)
1625 // save hwnd, will be overwritten in WM_CREATE during createwindow
1626 HWND hWndOld
= pThis
->mhWnd
;
1627 HWND hWndOldParent
= ::GetParent( hWndOld
);
1628 SalData
* pSalData
= GetSalData();
1630 if( hNewParentWnd
== hWndOldParent
)
1633 ::std::vector
< WinSalFrame
* > children
;
1634 ::std::vector
< WinSalObject
* > systemChildren
;
1636 // search child windows
1637 WinSalFrame
*pFrame
= pSalData
->mpFirstFrame
;
1640 HWND hWndParent
= ::GetParent( pFrame
->mhWnd
);
1641 if( pThis
->mhWnd
== hWndParent
)
1642 children
.push_back( pFrame
);
1643 pFrame
= pFrame
->mpNextFrame
;
1646 // search system child windows (plugins etc.)
1647 WinSalObject
*pObject
= pSalData
->mpFirstObject
;
1650 HWND hWndParent
= ::GetParent( pObject
->mhWnd
);
1651 if( pThis
->mhWnd
== hWndParent
)
1652 systemChildren
.push_back( pObject
);
1653 pObject
= pObject
->mpNextObject
;
1656 BOOL bNeedGraphics
= pThis
->mbGraphics
;
1657 BOOL bNeedCacheDC
= FALSE
;
1661 HBRUSH hBrush
= NULL
;
1663 #if OSL_DEBUG_LEVEL > 0
1664 int oldCount
= pSalData
->mnCacheDCInUse
;
1669 if ( pThis
->mpGraphics2
&&
1670 pThis
->mpGraphics2
->mhDC
)
1672 // save current gdi objects before hdc is gone
1673 hFont
= (HFONT
) GetCurrentObject( pThis
->mpGraphics2
->mhDC
, OBJ_FONT
);
1674 hPen
= (HPEN
) GetCurrentObject( pThis
->mpGraphics2
->mhDC
, OBJ_PEN
);
1675 hBrush
= (HBRUSH
) GetCurrentObject( pThis
->mpGraphics2
->mhDC
, OBJ_BRUSH
);
1676 pThis
->ReleaseGraphics( pThis
->mpGraphics2
);
1678 // recreate cache dc only if it was destroyed
1679 bNeedCacheDC
= TRUE
;
1683 if ( pThis
->mpGraphics
)
1685 if ( pThis
->mpGraphics
->mhDefPal
)
1686 SelectPalette( pThis
->mpGraphics
->mhDC
, pThis
->mpGraphics
->mhDefPal
, TRUE
);
1687 ImplSalDeInitGraphics( pThis
->mpGraphics
);
1688 ReleaseDC( pThis
->mhWnd
, pThis
->mpGraphics
->mhDC
);
1691 // create a new hwnd with the same styles
1692 HWND hWndParent
= hNewParentWnd
;
1693 // forward to main thread
1694 HWND hWnd
= (HWND
) ImplSendMessage( pSalData
->mpFirstInstance
->mhComWnd
,
1695 bAsChild
? SAL_MSG_RECREATECHILDHWND
: SAL_MSG_RECREATEHWND
,
1696 (WPARAM
) hWndParent
, (LPARAM
)pThis
->mhWnd
);
1699 DBG_ASSERT( IsWindow( hWnd
), "WinSalFrame::SetParent not successful");
1704 if( pThis
->mpGraphics2
)
1706 pThis
->mpGraphics2
->mhWnd
= hWnd
;
1710 // re-create cached DC
1711 HDC hDC
= (HDC
)ImplSendMessage( pSalData
->mpFirstInstance
->mhComWnd
,
1716 pThis
->mpGraphics2
->mhDC
= hDC
;
1717 if ( pSalData
->mhDitherPal
)
1719 pThis
->mpGraphics2
->mhDefPal
= SelectPalette( hDC
, pSalData
->mhDitherPal
, TRUE
);
1720 RealizePalette( hDC
);
1722 ImplSalInitGraphics( pThis
->mpGraphics2
);
1724 // re-select saved gdi objects
1726 SelectObject( hDC
, hFont
);
1728 SelectObject( hDC
, hPen
);
1730 SelectObject( hDC
, hBrush
);
1732 pThis
->mbGraphics
= TRUE
;
1734 pSalData
->mnCacheDCInUse
++;
1736 DBG_ASSERT( oldCount
== pSalData
->mnCacheDCInUse
, "WinSalFrame::SetParent() hDC count corrupted");
1741 if( pThis
->mpGraphics
)
1744 pThis
->mpGraphics
->mhWnd
= hWnd
;
1745 pThis
->mpGraphics
->mhDC
= GetDC( hWnd
);
1746 if ( GetSalData()->mhDitherPal
)
1748 pThis
->mpGraphics
->mhDefPal
= SelectPalette( pThis
->mpGraphics
->mhDC
, GetSalData()->mhDitherPal
, TRUE
);
1749 RealizePalette( pThis
->mpGraphics
->mhDC
);
1751 ImplSalInitGraphics( pThis
->mpGraphics
);
1752 pThis
->mbGraphics
= TRUE
;
1757 // TODO: add SetParent() call for SalObjects
1758 DBG_ASSERT( systemChildren
.empty(), "WinSalFrame::SetParent() parent of living system child window will be destroyed!");
1760 // reparent children before old parent is destroyed
1761 for( ::std::vector
< WinSalFrame
* >::iterator iChild
= children
.begin(); iChild
!= children
.end(); iChild
++ )
1762 ImplSetParentFrame( *iChild
, hWnd
, FALSE
);
1765 systemChildren
.clear();
1767 // Now destroy original HWND in the thread where it was created.
1768 ImplSendMessage( GetSalData()->mpFirstInstance
->mhComWnd
,
1769 SAL_MSG_DESTROYHWND
, (WPARAM
) 0, (LPARAM
)hWndOld
);
1772 // -----------------------------------------------------------------------
1774 void WinSalFrame::SetParent( SalFrame
* pNewParent
)
1776 WinSalFrame::mbInReparent
= TRUE
;
1777 ImplSetParentFrame( this, static_cast<WinSalFrame
*>(pNewParent
)->mhWnd
, FALSE
);
1778 WinSalFrame::mbInReparent
= FALSE
;
1781 bool WinSalFrame::SetPluginParent( SystemParentData
* pNewParent
)
1783 if ( pNewParent
->hWnd
== 0 )
1785 pNewParent
->hWnd
= GetDesktopWindow();
1788 WinSalFrame::mbInReparent
= TRUE
;
1789 ImplSetParentFrame( this, pNewParent
->hWnd
, TRUE
);
1790 WinSalFrame::mbInReparent
= FALSE
;
1795 // -----------------------------------------------------------------------
1797 void WinSalFrame::GetWorkArea( Rectangle
&rRect
)
1800 ImplSalGetWorkArea( mhWnd
, &aRect
, NULL
);
1801 rRect
.nLeft
= aRect
.left
;
1802 rRect
.nRight
= aRect
.right
-1;
1803 rRect
.nTop
= aRect
.top
;
1804 rRect
.nBottom
= aRect
.bottom
-1;
1807 // -----------------------------------------------------------------------
1809 void WinSalFrame::GetClientSize( long& rWidth
, long& rHeight
)
1811 rWidth
= maGeometry
.nWidth
;
1812 rHeight
= maGeometry
.nHeight
;
1815 // -----------------------------------------------------------------------
1817 void WinSalFrame::SetWindowState( const SalFrameState
* pState
)
1819 // Wir testen, ob das Fenster ueberhaupt auf den Bildschirm passt, damit
1820 // nicht wenn die Bildschirm-Aufloesung geaendert wurde, das Fenster aus
1821 // diesem herausragt
1832 ImplSalGetWorkArea( mhWnd
, &aRect
, NULL
);
1833 // #102500# allow some overlap, the window could have been made a little larger than the physical screen
1834 nScreenX
= aRect
.left
-10;
1835 nScreenY
= aRect
.top
-10;
1836 nScreenWidth
= aRect
.right
-aRect
.left
+20;
1837 nScreenHeight
= aRect
.bottom
-aRect
.top
+20;
1841 GetWindowRect( mhWnd
, &aWinRect
);
1843 // to be consistent with Unix, the frame state is without(!) decoration
1844 // ->add the decoration
1845 RECT aRect2
= aWinRect
;
1846 AdjustWindowRectEx( &aRect2
, GetWindowStyle( mhWnd
),
1847 FALSE
, GetWindowExStyle( mhWnd
) );
1848 long nTopDeco
= abs( aWinRect
.top
- aRect2
.top
);
1849 long nLeftDeco
= abs( aWinRect
.left
- aRect2
.left
);
1850 long nBottomDeco
= abs( aWinRect
.bottom
- aRect2
.bottom
);
1851 long nRightDeco
= abs( aWinRect
.right
- aRect2
.right
);
1853 // Fenster-Position/Groesse in den Bildschirm einpassen
1854 if ( !(pState
->mnMask
& (SAL_FRAMESTATE_MASK_X
| SAL_FRAMESTATE_MASK_Y
)) )
1855 nPosSize
|= SWP_NOMOVE
;
1856 if ( !(pState
->mnMask
& (SAL_FRAMESTATE_MASK_WIDTH
| SAL_FRAMESTATE_MASK_HEIGHT
)) )
1857 nPosSize
|= SWP_NOSIZE
;
1858 if ( pState
->mnMask
& SAL_FRAMESTATE_MASK_X
)
1859 nX
= (int)pState
->mnX
- nLeftDeco
;
1862 if ( pState
->mnMask
& SAL_FRAMESTATE_MASK_Y
)
1863 nY
= (int)pState
->mnY
- nTopDeco
;
1866 if ( pState
->mnMask
& SAL_FRAMESTATE_MASK_WIDTH
)
1867 nWidth
= (int)pState
->mnWidth
+ nLeftDeco
+ nRightDeco
;
1869 nWidth
= aWinRect
.right
-aWinRect
.left
;
1870 if ( pState
->mnMask
& SAL_FRAMESTATE_MASK_HEIGHT
)
1871 nHeight
= (int)pState
->mnHeight
+ nTopDeco
+ nBottomDeco
;
1873 nHeight
= aWinRect
.bottom
-aWinRect
.top
;
1875 // Adjust Window in the screen:
1876 // if it does not fit into the screen do nothing, ie default pos/size will be used
1877 // if there is an overlap with the screen border move the window while keeping its size
1879 if( nWidth
> nScreenWidth
|| nHeight
> nScreenHeight
)
1880 nPosSize
|= (SWP_NOMOVE
| SWP_NOSIZE
);
1882 if ( nX
+nWidth
> nScreenX
+nScreenWidth
)
1883 nX
= (nScreenX
+nScreenWidth
) - nWidth
;
1884 if ( nY
+nHeight
> nScreenY
+nScreenHeight
)
1885 nY
= (nScreenY
+nScreenHeight
) - nHeight
;
1886 if ( nX
< nScreenX
)
1888 if ( nY
< nScreenY
)
1891 // Restore-Position setzen
1892 WINDOWPLACEMENT aPlacement
;
1893 aPlacement
.length
= sizeof( aPlacement
);
1894 GetWindowPlacement( mhWnd
, &aPlacement
);
1897 BOOL bVisible
= (GetWindowStyle( mhWnd
) & WS_VISIBLE
) != 0;
1898 BOOL bUpdateHiddenFramePos
= FALSE
;
1901 aPlacement
.showCmd
= SW_HIDE
;
1903 if ( mbOverwriteState
)
1905 if ( pState
->mnMask
& SAL_FRAMESTATE_MASK_STATE
)
1907 if ( pState
->mnState
& SAL_FRAMESTATE_MINIMIZED
)
1908 mnShowState
= SW_SHOWMINIMIZED
;
1909 else if ( pState
->mnState
& SAL_FRAMESTATE_MAXIMIZED
)
1911 mnShowState
= SW_SHOWMAXIMIZED
;
1912 bUpdateHiddenFramePos
= TRUE
;
1914 else if ( pState
->mnState
& SAL_FRAMESTATE_NORMAL
)
1915 mnShowState
= SW_SHOWNORMAL
;
1921 if ( pState
->mnMask
& SAL_FRAMESTATE_MASK_STATE
)
1923 if ( pState
->mnState
& SAL_FRAMESTATE_MINIMIZED
)
1925 if ( pState
->mnState
& SAL_FRAMESTATE_MAXIMIZED
)
1926 aPlacement
.flags
|= WPF_RESTORETOMAXIMIZED
;
1927 aPlacement
.showCmd
= SW_SHOWMINIMIZED
;
1929 else if ( pState
->mnState
& SAL_FRAMESTATE_MAXIMIZED
)
1930 aPlacement
.showCmd
= SW_SHOWMAXIMIZED
;
1931 else if ( pState
->mnState
& SAL_FRAMESTATE_NORMAL
)
1932 aPlacement
.showCmd
= SW_RESTORE
;
1936 // Wenn Fenster nicht minimiert/maximiert ist oder nicht optisch
1937 // umgesetzt werden muss, dann SetWindowPos() benutzen, da
1938 // SetWindowPlacement() die TaskBar mit einrechnet
1939 if ( !IsIconic( mhWnd
) && !IsZoomed( mhWnd
) &&
1940 (!bVisible
|| (aPlacement
.showCmd
== SW_RESTORE
)) )
1942 if( bUpdateHiddenFramePos
)
1944 // #96084 set a useful internal window size because
1945 // the window will not be maximized (and the size updated) before show()
1946 SetMaximizedFrameGeometry( mhWnd
, this );
1949 SetWindowPos( mhWnd
, 0,
1950 nX
, nY
, nWidth
, nHeight
,
1951 SWP_NOZORDER
| SWP_NOACTIVATE
| nPosSize
);
1955 if( !(nPosSize
& (SWP_NOMOVE
|SWP_NOSIZE
)) )
1957 aPlacement
.rcNormalPosition
.left
= nX
-nScreenX
;
1958 aPlacement
.rcNormalPosition
.top
= nY
-nScreenY
;
1959 aPlacement
.rcNormalPosition
.right
= nX
+nWidth
-nScreenX
;
1960 aPlacement
.rcNormalPosition
.bottom
= nY
+nHeight
-nScreenY
;
1962 SetWindowPlacement( mhWnd
, &aPlacement
);
1965 if( !(nPosSize
& SWP_NOMOVE
) )
1966 mbDefPos
= FALSE
; // window was positioned
1969 // -----------------------------------------------------------------------
1971 BOOL
WinSalFrame::GetWindowState( SalFrameState
* pState
)
1973 if ( maState
.mnWidth
&& maState
.mnHeight
)
1976 // #94144# allow Minimize again, should be masked out when read from configuration
1977 // 91625 - Don't save minimize
1978 //if ( !(pState->mnState & SAL_FRAMESTATE_MAXIMIZED) )
1979 if ( !(pState
->mnState
& (SAL_FRAMESTATE_MINIMIZED
| SAL_FRAMESTATE_MAXIMIZED
)) )
1980 pState
->mnState
|= SAL_FRAMESTATE_NORMAL
;
1987 // -----------------------------------------------------------------------
1989 void WinSalFrame::SetScreenNumber( unsigned int nNewScreen
)
1991 WinSalSystem
* pSys
= static_cast<WinSalSystem
*>(ImplGetSalSystem());
1994 const std::vector
<WinSalSystem::DisplayMonitor
>& rMonitors
=
1995 pSys
->getMonitors();
1996 size_t nMon
= rMonitors
.size();
1997 if( nNewScreen
< nMon
)
1999 Point aOldMonPos
, aNewMonPos( rMonitors
[nNewScreen
].m_aArea
.TopLeft() );
2000 Point
aCurPos( maGeometry
.nX
, maGeometry
.nY
);
2001 for( size_t i
= 0; i
< nMon
; i
++ )
2003 if( rMonitors
[i
].m_aArea
.IsInside( aCurPos
) )
2005 aOldMonPos
= rMonitors
[i
].m_aArea
.TopLeft();
2009 mnDisplay
= nNewScreen
;
2010 maGeometry
.nScreenNumber
= nNewScreen
;
2011 SetPosSize( aNewMonPos
.X() + (maGeometry
.nX
- aOldMonPos
.X()),
2012 aNewMonPos
.Y() + (maGeometry
.nY
- aOldMonPos
.Y()),
2014 SAL_FRAME_POSSIZE_X
| SAL_FRAME_POSSIZE_Y
);
2019 // -----------------------------------------------------------------------
2021 void WinSalFrame::ShowFullScreen( BOOL bFullScreen
, sal_Int32 nDisplay
)
2023 if ( (mbFullScreen
== bFullScreen
) && (!bFullScreen
|| (mnDisplay
== nDisplay
)) )
2026 mbFullScreen
= bFullScreen
;
2027 mnDisplay
= nDisplay
;
2031 // Damit Taskleiste von Windows ausgeblendet wird
2032 DWORD nExStyle
= GetWindowExStyle( mhWnd
);
2033 if ( nExStyle
& WS_EX_TOOLWINDOW
)
2035 mbFullScreenToolWin
= TRUE
;
2036 nExStyle
&= ~WS_EX_TOOLWINDOW
;
2037 SetWindowExStyle( mhWnd
, nExStyle
);
2039 // save old position
2040 GetWindowRect( mhWnd
, &maFullScreenRect
);
2043 mnFullScreenShowState
= mnShowState
;
2044 if ( !(GetWindowStyle( mhWnd
) & WS_VISIBLE
) )
2045 mnShowState
= SW_SHOW
;
2047 // set window to screen size
2048 ImplSalFrameFullScreenPos( this, TRUE
);
2052 // wenn ShowState wieder hergestellt werden muss, hiden wir zuerst
2053 // das Fenster, damit es nicht so sehr flackert
2054 BOOL bVisible
= (GetWindowStyle( mhWnd
) & WS_VISIBLE
) != 0;
2055 if ( bVisible
&& (mnShowState
!= mnFullScreenShowState
) )
2056 ShowWindow( mhWnd
, SW_HIDE
);
2058 if ( mbFullScreenToolWin
)
2059 SetWindowExStyle( mhWnd
, GetWindowExStyle( mhWnd
) | WS_EX_TOOLWINDOW
);
2060 mbFullScreenToolWin
= FALSE
;
2062 SetWindowPos( mhWnd
, 0,
2063 maFullScreenRect
.left
,
2064 maFullScreenRect
.top
,
2065 maFullScreenRect
.right
-maFullScreenRect
.left
,
2066 maFullScreenRect
.bottom
-maFullScreenRect
.top
,
2067 SWP_NOZORDER
| SWP_NOACTIVATE
);
2069 // restore show state
2070 if ( mnShowState
!= mnFullScreenShowState
)
2072 mnShowState
= mnFullScreenShowState
;
2076 ShowWindow( mhWnd
, mnShowState
);
2078 UpdateWindow( mhWnd
);
2084 // -----------------------------------------------------------------------
2086 void WinSalFrame::StartPresentation( BOOL bStart
)
2088 if ( mbPresentation
== bStart
)
2091 mbPresentation
= bStart
;
2093 SalData
* pSalData
= GetSalData();
2096 if ( !pSalData
->mpSageEnableProc
)
2098 if ( pSalData
->mnSageStatus
!= DISABLE_AGENT
)
2101 OpenFile( "SAGE.DLL", &aOS
, OF_EXIST
);
2103 if ( !aOS
.nErrCode
)
2105 OUString
aLibraryName( OUString::createFromAscii( aOS
.szPathName
) );
2106 oslModule mhSageInst
= osl_loadModule( aLibraryName
.pData
, SAL_LOADMODULE_DEFAULT
);
2107 pSalData
->mpSageEnableProc
= (SysAgt_Enable_PROC
)osl_getAsciiFunctionSymbol( mhSageInst
, "System_Agent_Enable" );
2110 pSalData
->mnSageStatus
= DISABLE_AGENT
;
2114 if ( pSalData
->mpSageEnableProc
)
2116 pSalData
->mnSageStatus
= pSalData
->mpSageEnableProc( GET_AGENT_STATUS
);
2117 if ( pSalData
->mnSageStatus
== ENABLE_AGENT
)
2118 pSalData
->mpSageEnableProc( DISABLE_AGENT
);
2121 // Bildschirmschoner ausschalten, wenn Praesentation laueft
2122 SystemParametersInfo( SPI_GETSCREENSAVEACTIVE
, 0,
2123 &(pSalData
->mbScrSvrEnabled
), 0 );
2124 if ( pSalData
->mbScrSvrEnabled
)
2125 SystemParametersInfo( SPI_SETSCREENSAVEACTIVE
, FALSE
, 0, 0 );
2129 // Bildschirmschoner wieder einschalten
2130 if ( pSalData
->mbScrSvrEnabled
)
2131 SystemParametersInfo( SPI_SETSCREENSAVEACTIVE
, pSalData
->mbScrSvrEnabled
, 0, 0 );
2133 // Systemagenten wieder aktivieren
2134 if ( pSalData
->mnSageStatus
== ENABLE_AGENT
)
2135 pSalData
->mpSageEnableProc( pSalData
->mnSageStatus
);
2139 // -----------------------------------------------------------------------
2141 void WinSalFrame::SetAlwaysOnTop( BOOL bOnTop
)
2145 hWnd
= HWND_TOPMOST
;
2147 hWnd
= HWND_NOTOPMOST
;
2148 SetWindowPos( mhWnd
, hWnd
, 0, 0, 0, 0, SWP_NOMOVE
| SWP_NOSIZE
| SWP_NOACTIVATE
);
2151 // -----------------------------------------------------------------------
2153 static void ImplSalToTop( HWND hWnd
, USHORT nFlags
)
2155 WinSalFrame
* pToTopFrame
= GetWindowPtr( hWnd
);
2156 if( pToTopFrame
&& (pToTopFrame
->mnStyle
& SAL_FRAME_STYLE_SYSTEMCHILD
) != 0 )
2157 BringWindowToTop( hWnd
);
2159 if ( nFlags
& SAL_FRAME_TOTOP_FOREGROUNDTASK
)
2160 SetForegroundWindow( hWnd
);
2162 if ( nFlags
& SAL_FRAME_TOTOP_RESTOREWHENMIN
)
2164 HWND hIconicWnd
= hWnd
;
2165 while ( hIconicWnd
)
2167 if ( IsIconic( hIconicWnd
) )
2169 WinSalFrame
* pFrame
= GetWindowPtr( hIconicWnd
);
2172 if ( GetWindowPtr( hWnd
)->mbRestoreMaximize
)
2173 ShowWindow( hIconicWnd
, SW_MAXIMIZE
);
2175 ShowWindow( hIconicWnd
, SW_RESTORE
);
2178 ShowWindow( hIconicWnd
, SW_RESTORE
);
2181 hIconicWnd
= ::GetParent( hIconicWnd
);
2185 if ( !IsIconic( hWnd
) && IsWindowVisible( hWnd
) )
2189 // Windows behauptet oefters mal, das man den Focus hat, obwohl
2190 // man diesen nicht hat. Wenn dies der Fall ist, dann versuchen
2191 // wir diesen auch ganz richtig zu bekommen.
2192 if ( ::GetFocus() == hWnd
)
2193 SetForegroundWindow( hWnd
);
2197 // -----------------------------------------------------------------------
2199 void WinSalFrame::ToTop( USHORT nFlags
)
2201 nFlags
&= ~SAL_FRAME_TOTOP_GRABFOCUS
; // this flag is not needed on win32
2202 // Post this Message to the window, because this only works
2203 // in the thread of the window, which has create this window.
2204 // We post this message to avoid deadlocks
2205 if ( GetSalData()->mnAppThreadId
!= GetCurrentThreadId() )
2206 ImplPostMessage( mhWnd
, SAL_MSG_TOTOP
, nFlags
, 0 );
2208 ImplSalToTop( mhWnd
, nFlags
);
2211 // -----------------------------------------------------------------------
2213 void WinSalFrame::SetPointer( PointerStyle ePointerStyle
)
2222 static ImplPtrData aImplPtrTab
[POINTER_COUNT
] =
2224 { 0, IDC_ARROW
, 0 }, // POINTER_ARROW
2225 { 0, 0, SAL_RESID_POINTER_NULL
}, // POINTER_NULL
2226 { 0, IDC_WAIT
, 0 }, // POINTER_WAIT
2227 { 0, IDC_IBEAM
, 0 }, // POINTER_TEXT
2228 { 0, IDC_HELP
, 0 }, // POINTER_HELP
2229 { 0, 0, SAL_RESID_POINTER_CROSS
}, // POINTER_CROSS
2230 { 0, 0, SAL_RESID_POINTER_MOVE
}, // POINTER_MOVE
2231 { 0, IDC_SIZENS
, 0 }, // POINTER_NSIZE
2232 { 0, IDC_SIZENS
, 0 }, // POINTER_SSIZE
2233 { 0, IDC_SIZEWE
, 0 }, // POINTER_WSIZE
2234 { 0, IDC_SIZEWE
, 0 }, // POINTER_ESIZE
2235 { 0, IDC_SIZENWSE
, 0 }, // POINTER_NWSIZE
2236 { 0, IDC_SIZENESW
, 0 }, // POINTER_NESIZE
2237 { 0, IDC_SIZENESW
, 0 }, // POINTER_SWSIZE
2238 { 0, IDC_SIZENWSE
, 0 }, // POINTER_SESIZE
2239 { 0, IDC_SIZENS
, 0 }, // POINTER_WINDOW_NSIZE
2240 { 0, IDC_SIZENS
, 0 }, // POINTER_WINDOW_SSIZE
2241 { 0, IDC_SIZEWE
, 0 }, // POINTER_WINDOW_WSIZE
2242 { 0, IDC_SIZEWE
, 0 }, // POINTER_WINDOW_ESIZE
2243 { 0, IDC_SIZENWSE
, 0 }, // POINTER_WINDOW_NWSIZE
2244 { 0, IDC_SIZENESW
, 0 }, // POINTER_WINDOW_NESIZE
2245 { 0, IDC_SIZENESW
, 0 }, // POINTER_WINDOW_SWSIZE
2246 { 0, IDC_SIZENWSE
, 0 }, // POINTER_WINDOW_SESIZE
2247 { 0, 0, SAL_RESID_POINTER_HSPLIT
}, // POINTER_HSPLIT
2248 { 0, 0, SAL_RESID_POINTER_VSPLIT
}, // POINTER_VSPLIT
2249 { 0, 0, SAL_RESID_POINTER_HSIZEBAR
}, // POINTER_HSIZEBAR
2250 { 0, 0, SAL_RESID_POINTER_VSIZEBAR
}, // POINTER_VSIZEBAR
2251 { 0, 0, SAL_RESID_POINTER_HAND
}, // POINTER_HAND
2252 { 0, 0, SAL_RESID_POINTER_REFHAND
}, // POINTER_REFHAND
2253 { 0, 0, SAL_RESID_POINTER_PEN
}, // POINTER_PEN
2254 { 0, 0, SAL_RESID_POINTER_MAGNIFY
}, // POINTER_MAGNIFY
2255 { 0, 0, SAL_RESID_POINTER_FILL
}, // POINTER_FILL
2256 { 0, 0, SAL_RESID_POINTER_ROTATE
}, // POINTER_ROTATE
2257 { 0, 0, SAL_RESID_POINTER_HSHEAR
}, // POINTER_HSHEAR
2258 { 0, 0, SAL_RESID_POINTER_VSHEAR
}, // POINTER_VSHEAR
2259 { 0, 0, SAL_RESID_POINTER_MIRROR
}, // POINTER_MIRROR
2260 { 0, 0, SAL_RESID_POINTER_CROOK
}, // POINTER_CROOK
2261 { 0, 0, SAL_RESID_POINTER_CROP
}, // POINTER_CROP
2262 { 0, 0, SAL_RESID_POINTER_MOVEPOINT
}, // POINTER_MOVEPOINT
2263 { 0, 0, SAL_RESID_POINTER_MOVEBEZIERWEIGHT
}, // POINTER_MOVEBEZIERWEIGHT
2264 { 0, 0, SAL_RESID_POINTER_MOVEDATA
}, // POINTER_MOVEDATA
2265 { 0, 0, SAL_RESID_POINTER_COPYDATA
}, // POINTER_COPYDATA
2266 { 0, 0, SAL_RESID_POINTER_LINKDATA
}, // POINTER_LINKDATA
2267 { 0, 0, SAL_RESID_POINTER_MOVEDATALINK
}, // POINTER_MOVEDATALINK
2268 { 0, 0, SAL_RESID_POINTER_COPYDATALINK
}, // POINTER_COPYDATALINK
2269 { 0, 0, SAL_RESID_POINTER_MOVEFILE
}, // POINTER_MOVEFILE
2270 { 0, 0, SAL_RESID_POINTER_COPYFILE
}, // POINTER_COPYFILE
2271 { 0, 0, SAL_RESID_POINTER_LINKFILE
}, // POINTER_LINKFILE
2272 { 0, 0, SAL_RESID_POINTER_MOVEFILELINK
}, // POINTER_MOVEFILELINK
2273 { 0, 0, SAL_RESID_POINTER_COPYFILELINK
}, // POINTER_COPYFILELINK
2274 { 0, 0, SAL_RESID_POINTER_MOVEFILES
}, // POINTER_MOVEFILES
2275 { 0, 0, SAL_RESID_POINTER_COPYFILES
}, // POINTER_COPYFILES
2276 { 0, 0, SAL_RESID_POINTER_NOTALLOWED
}, // POINTER_NOTALLOWED
2277 { 0, 0, SAL_RESID_POINTER_DRAW_LINE
}, // POINTER_DRAW_LINE
2278 { 0, 0, SAL_RESID_POINTER_DRAW_RECT
}, // POINTER_DRAW_RECT
2279 { 0, 0, SAL_RESID_POINTER_DRAW_POLYGON
}, // POINTER_DRAW_POLYGON
2280 { 0, 0, SAL_RESID_POINTER_DRAW_BEZIER
}, // POINTER_DRAW_BEZIER
2281 { 0, 0, SAL_RESID_POINTER_DRAW_ARC
}, // POINTER_DRAW_ARC
2282 { 0, 0, SAL_RESID_POINTER_DRAW_PIE
}, // POINTER_DRAW_PIE
2283 { 0, 0, SAL_RESID_POINTER_DRAW_CIRCLECUT
}, // POINTER_DRAW_CIRCLECUT
2284 { 0, 0, SAL_RESID_POINTER_DRAW_ELLIPSE
}, // POINTER_DRAW_ELLIPSE
2285 { 0, 0, SAL_RESID_POINTER_DRAW_FREEHAND
}, // POINTER_DRAW_FREEHAND
2286 { 0, 0, SAL_RESID_POINTER_DRAW_CONNECT
}, // POINTER_DRAW_CONNECT
2287 { 0, 0, SAL_RESID_POINTER_DRAW_TEXT
}, // POINTER_DRAW_TEXT
2288 { 0, 0, SAL_RESID_POINTER_DRAW_CAPTION
}, // POINTER_DRAW_CAPTION
2289 { 0, 0, SAL_RESID_POINTER_CHART
}, // POINTER_CHART
2290 { 0, 0, SAL_RESID_POINTER_DETECTIVE
}, // POINTER_DETECTIVE
2291 { 0, 0, SAL_RESID_POINTER_PIVOT_COL
}, // POINTER_PIVOT_COL
2292 { 0, 0, SAL_RESID_POINTER_PIVOT_ROW
}, // POINTER_PIVOT_ROW
2293 { 0, 0, SAL_RESID_POINTER_PIVOT_FIELD
}, // POINTER_PIVOT_FIELD
2294 { 0, 0, SAL_RESID_POINTER_CHAIN
}, // POINTER_CHAIN
2295 { 0, 0, SAL_RESID_POINTER_CHAIN_NOTALLOWED
}, // POINTER_CHAIN_NOTALLOWED
2296 { 0, 0, SAL_RESID_POINTER_TIMEEVENT_MOVE
}, // POINTER_TIMEEVENT_MOVE
2297 { 0, 0, SAL_RESID_POINTER_TIMEEVENT_SIZE
}, // POINTER_TIMEEVENT_SIZE
2298 { 0, 0, SAL_RESID_POINTER_AUTOSCROLL_N
}, // POINTER_AUTOSCROLL_N
2299 { 0, 0, SAL_RESID_POINTER_AUTOSCROLL_S
}, // POINTER_AUTOSCROLL_S
2300 { 0, 0, SAL_RESID_POINTER_AUTOSCROLL_W
}, // POINTER_AUTOSCROLL_W
2301 { 0, 0, SAL_RESID_POINTER_AUTOSCROLL_E
}, // POINTER_AUTOSCROLL_E
2302 { 0, 0, SAL_RESID_POINTER_AUTOSCROLL_NW
}, // POINTER_AUTOSCROLL_NW
2303 { 0, 0, SAL_RESID_POINTER_AUTOSCROLL_NE
}, // POINTER_AUTOSCROLL_NE
2304 { 0, 0, SAL_RESID_POINTER_AUTOSCROLL_SW
}, // POINTER_AUTOSCROLL_SW
2305 { 0, 0, SAL_RESID_POINTER_AUTOSCROLL_SE
}, // POINTER_AUTOSCROLL_SE
2306 { 0, 0, SAL_RESID_POINTER_AUTOSCROLL_NS
}, // POINTER_AUTOSCROLL_NS
2307 { 0, 0, SAL_RESID_POINTER_AUTOSCROLL_WE
}, // POINTER_AUTOSCROLL_WE
2308 { 0, 0, SAL_RESID_POINTER_AUTOSCROLL_NSWE
}, // POINTER_AUTOSCROLL_NSWE
2309 { 0, 0, SAL_RESID_POINTER_AIRBRUSH
}, // POINTER_AIRBRUSH
2310 { 0, 0, SAL_RESID_POINTER_TEXT_VERTICAL
}, // POINTER_TEXT_VERTICAL
2311 { 0, 0, SAL_RESID_POINTER_PIVOT_DELETE
}, // POINTER_PIVOT_DELETE
2313 // --> FME 2004-07-30 #i32329# Enhanced table selection
2314 { 0, 0, SAL_RESID_POINTER_TAB_SELECT_S
}, // POINTER_TAB_SELECT_S
2315 { 0, 0, SAL_RESID_POINTER_TAB_SELECT_E
}, // POINTER_TAB_SELECT_E
2316 { 0, 0, SAL_RESID_POINTER_TAB_SELECT_SE
}, // POINTER_TAB_SELECT_SE
2317 { 0, 0, SAL_RESID_POINTER_TAB_SELECT_W
}, // POINTER_TAB_SELECT_W
2318 { 0, 0, SAL_RESID_POINTER_TAB_SELECT_SW
}, // POINTER_TAB_SELECT_SW
2321 // --> FME 2004-08-16 #i20119# Paintbrush tool
2322 { 0, 0, SAL_RESID_POINTER_PAINTBRUSH
} // POINTER_PAINTBRUSH
2327 #if POINTER_COUNT != 94
2328 #error New Pointer must be defined!
2331 // Mousepointer loaded ?
2332 if ( !aImplPtrTab
[ePointerStyle
].mhCursor
)
2334 if ( aImplPtrTab
[ePointerStyle
].mnOwnId
)
2335 aImplPtrTab
[ePointerStyle
].mhCursor
= ImplLoadSalCursor( aImplPtrTab
[ePointerStyle
].mnOwnId
);
2337 aImplPtrTab
[ePointerStyle
].mhCursor
= LoadCursor( 0, aImplPtrTab
[ePointerStyle
].mnSysId
);
2340 // Unterscheidet sich der Mauspointer, dann den neuen setzen
2341 if ( mhCursor
!= aImplPtrTab
[ePointerStyle
].mhCursor
)
2343 mhCursor
= aImplPtrTab
[ePointerStyle
].mhCursor
;
2344 SetCursor( mhCursor
);
2348 // -----------------------------------------------------------------------
2350 void WinSalFrame::CaptureMouse( BOOL bCapture
)
2352 // Send this Message to the window, because CaptureMouse() only work
2353 // in the thread of the window, which has create this window
2356 nMsg
= SAL_MSG_CAPTUREMOUSE
;
2358 nMsg
= SAL_MSG_RELEASEMOUSE
;
2359 ImplSendMessage( mhWnd
, nMsg
, 0, 0 );
2362 // -----------------------------------------------------------------------
2364 void WinSalFrame::SetPointerPos( long nX
, long nY
)
2369 ClientToScreen( mhWnd
, &aPt
);
2370 SetCursorPos( aPt
.x
, aPt
.y
);
2373 // -----------------------------------------------------------------------
2375 void WinSalFrame::Flush()
2380 // -----------------------------------------------------------------------
2382 void WinSalFrame::Sync()
2387 // -----------------------------------------------------------------------
2389 static void ImplSalFrameSetInputContext( HWND hWnd
, const SalInputContext
* pContext
)
2391 WinSalFrame
* pFrame
= GetWindowPtr( hWnd
);
2392 BOOL bIME
= (pContext
->mnOptions
& SAL_INPUTCONTEXT_TEXT
) != 0;
2395 if ( !pFrame
->mbIME
)
2397 pFrame
->mbIME
= TRUE
;
2399 if ( pFrame
->mhDefIMEContext
)
2401 ImmAssociateContext( pFrame
->mhWnd
, pFrame
->mhDefIMEContext
);
2402 UINT nImeProps
= ImmGetProperty( GetKeyboardLayout( 0 ), IGP_PROPERTY
);
2403 pFrame
->mbSpezIME
= (nImeProps
& IME_PROP_SPECIAL_UI
) != 0;
2404 pFrame
->mbAtCursorIME
= (nImeProps
& IME_PROP_AT_CARET
) != 0;
2405 pFrame
->mbHandleIME
= !pFrame
->mbSpezIME
;
2409 // When the application can't handle IME messages, then the
2410 // System should handle the IME handling
2411 if ( !(pContext
->mnOptions
& SAL_INPUTCONTEXT_EXTTEXTINPUT
) )
2412 pFrame
->mbHandleIME
= FALSE
;
2414 // Set the Font for IME Handling
2415 if ( pContext
->mpFont
)
2417 HIMC hIMC
= ImmGetContext( pFrame
->mhWnd
);
2421 HDC hDC
= GetDC( pFrame
->mhWnd
);
2422 // In case of vertical writing, always append a '@' to the
2423 // Windows font name, not only if such a Windows font really is
2424 // available (bTestVerticalAvail == false in the below call):
2425 // The Windows IME's candidates window seems to always use a
2426 // font that has all necessary glyphs, not necessarily the one
2427 // specified by this font name; but it seems to decide whether
2428 // to use that font's horizontal or vertical variant based on a
2429 // '@' in front of this font name.
2430 ImplGetLogFontFromFontSelect( hDC
, pContext
->mpFont
, aLogFont
,
2432 ReleaseDC( pFrame
->mhWnd
, hDC
);
2433 ImmSetCompositionFontW( hIMC
, &aLogFont
);
2434 ImmReleaseContext( pFrame
->mhWnd
, hIMC
);
2440 if ( pFrame
->mbIME
)
2442 pFrame
->mbIME
= FALSE
;
2443 pFrame
->mbHandleIME
= FALSE
;
2444 ImmAssociateContext( pFrame
->mhWnd
, 0 );
2449 // -----------------------------------------------------------------------
2451 void WinSalFrame::SetInputContext( SalInputContext
* pContext
)
2453 // Must be called in the main thread!
2454 ImplSendMessage( mhWnd
, SAL_MSG_SETINPUTCONTEXT
, 0, (LPARAM
)(void*)pContext
);
2457 // -----------------------------------------------------------------------
2459 static void ImplSalFrameEndExtTextInput( HWND hWnd
, USHORT nFlags
)
2461 HIMC hIMC
= ImmGetContext( hWnd
);
2465 if ( nFlags
& SAL_FRAME_ENDEXTTEXTINPUT_COMPLETE
)
2466 nIndex
= CPS_COMPLETE
;
2468 nIndex
= CPS_CANCEL
;
2470 ImmNotifyIME( hIMC
, NI_COMPOSITIONSTR
, nIndex
, 0 );
2471 ImmReleaseContext( hWnd
, hIMC
);
2475 // -----------------------------------------------------------------------
2477 void WinSalFrame::EndExtTextInput( USHORT nFlags
)
2479 // Must be called in the main thread!
2480 ImplSendMessage( mhWnd
, SAL_MSG_ENDEXTTEXTINPUT
, (WPARAM
)nFlags
, 0 );
2483 // -----------------------------------------------------------------------
2485 static void ImplGetKeyNameText( LONG lParam
, sal_Unicode
* pBuf
,
2486 UINT
& rCount
, UINT nMaxSize
,
2487 const sal_Char
* pReplace
)
2489 DBG_ASSERT( sizeof( WCHAR
) == sizeof( xub_Unicode
), "WinSalFrame::ImplGetKeyNameTextW(): WCHAR != sal_Unicode" );
2491 static const int nMaxKeyLen
= 350;
2492 WCHAR aKeyBuf
[ nMaxKeyLen
];
2496 if ( aSalShlData
.mbWNT
)
2498 nKeyLen
= GetKeyNameTextW( lParam
, aKeyBuf
, nMaxKeyLen
);
2499 // #i12401# the current unicows.dll has a bug in CharUpperBuffW, which corrupts the stack
2500 // fall back to the ANSI version instead
2501 DBG_ASSERT( nKeyLen
<= nMaxKeyLen
, "Invalid key name length!" );
2502 if( nKeyLen
> nMaxKeyLen
)
2504 else if( nKeyLen
> 0 )
2506 // Capitalize just the first letter of key names
2507 CharLowerBuffW( aKeyBuf
, nKeyLen
);
2510 for( WCHAR
*pW
=aKeyBuf
, *pE
=pW
+nKeyLen
; pW
< pE
; ++pW
)
2513 CharUpperBuffW( pW
, 1 );
2514 bUpper
= (*pW
=='+') || (*pW
=='-') || (*pW
==' ') || (*pW
=='.');
2520 sal_Char aAnsiKeyBuf
[ nMaxKeyLen
];
2521 int nAnsiKeyLen
= GetKeyNameTextA( lParam
, aAnsiKeyBuf
, nMaxKeyLen
);
2522 DBG_ASSERT( nAnsiKeyLen
<= nMaxKeyLen
, "Invalid key name length!" );
2523 if( nAnsiKeyLen
> nMaxKeyLen
)
2525 else if( nAnsiKeyLen
> 0 )
2527 // Capitalize just the first letter of key names
2528 // TODO: check MCBS key names
2529 CharLowerBuffA( aAnsiKeyBuf
, nAnsiKeyLen
);
2532 for( sal_Char
*pA
=aAnsiKeyBuf
, *pE
=pA
+nAnsiKeyLen
; pA
< pE
; ++pA
)
2535 CharUpperBuffA( pA
, 1 );
2536 bUpper
= (*pA
=='+') || (*pA
=='-') || (*pA
==' ') || (*pA
=='.');
2539 // Convert to Unicode and copy the data in the Unicode Buffer
2540 nKeyLen
= MultiByteToWideChar( CP_ACP
, MB_PRECOMPOSED
,
2541 aAnsiKeyBuf
, nAnsiKeyLen
, aKeyBuf
, nMaxKeyLen
);
2546 if ( (nKeyLen
> 0) || pReplace
)
2548 if( (rCount
> 0) && (rCount
< nMaxSize
) )
2556 if( nKeyLen
+ rCount
> nMaxSize
)
2557 nKeyLen
= nMaxSize
- rCount
;
2558 memcpy( pBuf
+rCount
, aKeyBuf
, nKeyLen
*sizeof( sal_Unicode
) );
2561 else // fall back to provided default name
2563 while( *pReplace
&& (rCount
< nMaxSize
) )
2565 pBuf
[rCount
] = *pReplace
;
2575 // -----------------------------------------------------------------------
2577 XubString
WinSalFrame::GetKeyName( USHORT nKeyCode
)
2579 static const int nMaxKeyLen
= 350;
2580 sal_Unicode aKeyBuf
[ nMaxKeyLen
];
2581 UINT nKeyBufLen
= 0;
2584 if ( nKeyCode
& KEY_MOD1
)
2586 nSysCode
= MapVirtualKey( VK_CONTROL
, 0 );
2587 nSysCode
= (nSysCode
<< 16) | (((ULONG
)1) << 25);
2588 ImplGetKeyNameText( nSysCode
, aKeyBuf
, nKeyBufLen
, nMaxKeyLen
, "Ctrl" );
2591 if ( nKeyCode
& KEY_MOD2
)
2593 nSysCode
= MapVirtualKey( VK_MENU
, 0 );
2594 nSysCode
= (nSysCode
<< 16) | (((ULONG
)1) << 25);
2595 ImplGetKeyNameText( nSysCode
, aKeyBuf
, nKeyBufLen
, nMaxKeyLen
, "Alt" );
2598 if ( nKeyCode
& KEY_SHIFT
)
2600 nSysCode
= MapVirtualKey( VK_SHIFT
, 0 );
2601 nSysCode
= (nSysCode
<< 16) | (((ULONG
)1) << 25);
2602 ImplGetKeyNameText( nSysCode
, aKeyBuf
, nKeyBufLen
, nMaxKeyLen
, "Shift" );
2605 USHORT nCode
= nKeyCode
& 0x0FFF;
2606 ULONG nSysCode2
= 0;
2607 sal_Char
* pReplace
= NULL
;
2608 sal_Unicode cSVCode
= 0;
2612 if ( (nCode
>= KEY_0
) && (nCode
<= KEY_9
) )
2613 cSVCode
= '0' + (nCode
- KEY_0
);
2614 else if ( (nCode
>= KEY_A
) && (nCode
<= KEY_Z
) )
2615 cSVCode
= 'A' + (nCode
- KEY_A
);
2616 else if ( (nCode
>= KEY_F1
) && (nCode
<= KEY_F26
) )
2618 nSysCode
= VK_F1
+ (nCode
- KEY_F1
);
2620 if ( (nCode
>= KEY_F1
) && (nCode
<= KEY_F9
) )
2622 aFBuf
[1] = sal::static_int_cast
<sal_Char
>('1' + (nCode
- KEY_F1
));
2625 else if ( (nCode
>= KEY_F10
) && (nCode
<= KEY_F19
) )
2628 aFBuf
[2] = sal::static_int_cast
<sal_Char
>('0' + (nCode
- KEY_F10
));
2634 aFBuf
[2] = sal::static_int_cast
<sal_Char
>('0' + (nCode
- KEY_F20
));
2645 nSysCode2
= (((ULONG
)1) << 24);
2650 nSysCode2
= (((ULONG
)1) << 24);
2655 nSysCode2
= (((ULONG
)1) << 24);
2659 nSysCode
= VK_RIGHT
;
2660 nSysCode2
= (((ULONG
)1) << 24);
2665 nSysCode2
= (((ULONG
)1) << 24);
2670 nSysCode2
= (((ULONG
)1) << 24);
2674 nSysCode
= VK_PRIOR
;
2675 nSysCode2
= (((ULONG
)1) << 24);
2676 pReplace
= "Page Up";
2680 nSysCode2
= (((ULONG
)1) << 24);
2681 pReplace
= "Page Down";
2684 nSysCode
= VK_RETURN
;
2688 nSysCode
= VK_ESCAPE
;
2689 pReplace
= "Escape";
2697 pReplace
= "Backspace";
2700 nSysCode
= VK_SPACE
;
2704 nSysCode
= VK_INSERT
;
2705 nSysCode2
= (((ULONG
)1) << 24);
2706 pReplace
= "Insert";
2709 nSysCode
= VK_DELETE
;
2710 nSysCode2
= (((ULONG
)1) << 24);
2711 pReplace
= "Delete";
2746 nSysCode
= MapVirtualKey( (UINT
)nSysCode
, 0 );
2748 nSysCode
= (nSysCode
<< 16) | nSysCode2
;
2749 ImplGetKeyNameText( nSysCode
, aKeyBuf
, nKeyBufLen
, nMaxKeyLen
, pReplace
);
2755 if ( nKeyBufLen
> 0 )
2756 aKeyBuf
[ nKeyBufLen
++ ] = '+';
2757 if( nKeyBufLen
< nMaxKeyLen
)
2758 aKeyBuf
[ nKeyBufLen
++ ] = cSVCode
;
2765 return XubString( aKeyBuf
, sal::static_int_cast
< USHORT
>(nKeyBufLen
) );
2768 // -----------------------------------------------------------------------
2770 XubString
WinSalFrame::GetSymbolKeyName( const XubString
&, USHORT nKeyCode
)
2772 return GetKeyName( nKeyCode
);
2775 // -----------------------------------------------------------------------
2777 inline Color
ImplWinColorToSal( COLORREF nColor
)
2779 return Color( GetRValue( nColor
), GetGValue( nColor
), GetBValue( nColor
) );
2782 // -----------------------------------------------------------------------
2784 static void ImplSalUpdateStyleFontA( HDC hDC
, const LOGFONTA
& rLogFont
, Font
& rFont
)
2786 ImplSalLogFontToFontA( hDC
, rLogFont
, rFont
);
2788 // On Windows 9x, Windows NT we get sometimes very small sizes
2789 // (for example for the small Caption height).
2790 // So if it is MS Sans Serif, a none scalable font we use
2791 // 8 Point as the minimum control height, in all other cases
2792 // 6 Point is the smallest one
2793 if ( rFont
.GetHeight() < 8 )
2795 if ( rtl_str_compareIgnoreAsciiCase( rLogFont
.lfFaceName
, "MS Sans Serif" ) == 0 )
2796 rFont
.SetHeight( 8 );
2797 else if ( rFont
.GetHeight() < 6 )
2798 rFont
.SetHeight( 6 );
2802 // -----------------------------------------------------------------------
2804 static void ImplSalUpdateStyleFontW( HDC hDC
, const LOGFONTW
& rLogFont
, Font
& rFont
)
2806 ImplSalLogFontToFontW( hDC
, rLogFont
, rFont
);
2808 // On Windows 9x, Windows NT we get sometimes very small sizes
2809 // (for example for the small Caption height).
2810 // So if it is MS Sans Serif, a none scalable font we use
2811 // 8 Point as the minimum control height, in all other cases
2812 // 6 Point is the smallest one
2813 if ( rFont
.GetHeight() < 8 )
2815 if ( rtl_ustr_compareIgnoreAsciiCase( reinterpret_cast<const sal_Unicode
*>(rLogFont
.lfFaceName
), reinterpret_cast<const sal_Unicode
*>(L
"MS Sans Serif") ) == 0 )
2816 rFont
.SetHeight( 8 );
2817 else if ( rFont
.GetHeight() < 6 )
2818 rFont
.SetHeight( 6 );
2822 // -----------------------------------------------------------------------
2824 static long ImplA2I( const BYTE
* pStr
)
2835 while( (*pStr
>= 48) && (*pStr
<= 57) )
2838 n
+= ((*pStr
) - 48);
2847 // -----------------------------------------------------------------------
2849 void WinSalFrame::UpdateSettings( AllSettings
& rSettings
)
2851 MouseSettings aMouseSettings
= rSettings
.GetMouseSettings();
2852 aMouseSettings
.SetDoubleClickTime( GetDoubleClickTime() );
2853 aMouseSettings
.SetDoubleClickWidth( GetSystemMetrics( SM_CXDOUBLECLK
) );
2854 aMouseSettings
.SetDoubleClickHeight( GetSystemMetrics( SM_CYDOUBLECLK
) );
2855 long nDragWidth
= GetSystemMetrics( SM_CXDRAG
);
2856 long nDragHeight
= GetSystemMetrics( SM_CYDRAG
);
2858 aMouseSettings
.SetStartDragWidth( nDragWidth
);
2860 aMouseSettings
.SetStartDragHeight( nDragHeight
);
2862 if ( RegOpenKey( HKEY_CURRENT_USER
,
2863 "Control Panel\\Desktop",
2864 &hRegKey
) == ERROR_SUCCESS
)
2867 DWORD nValueSize
= sizeof( aValueBuf
);
2869 if ( RegQueryValueEx( hRegKey
, "MenuShowDelay", 0,
2870 &nType
, aValueBuf
, &nValueSize
) == ERROR_SUCCESS
)
2872 if ( nType
== REG_SZ
)
2873 aMouseSettings
.SetMenuDelay( (ULONG
)ImplA2I( aValueBuf
) );
2876 RegCloseKey( hRegKey
);
2879 StyleSettings aStyleSettings
= rSettings
.GetStyleSettings();
2880 BOOL bCompBorder
= (aStyleSettings
.GetOptions() & (STYLE_OPTION_MACSTYLE
| STYLE_OPTION_UNIXSTYLE
)) == 0;
2881 // TODO: once those options vanish: just set bCompBorder to TRUE
2882 // to have the system colors read
2883 aStyleSettings
.SetScrollBarSize( Min( GetSystemMetrics( SM_CXVSCROLL
), 20 ) ); // #99956# do not allow huge scrollbars, most of the UI is not scaled anymore
2884 aStyleSettings
.SetSpinSize( Min( GetSystemMetrics( SM_CXVSCROLL
), 20 ) );
2885 aStyleSettings
.SetCursorBlinkTime( GetCaretBlinkTime() );
2888 aStyleSettings
.SetFloatTitleHeight( GetSystemMetrics( SM_CYSMCAPTION
) );
2889 aStyleSettings
.SetTitleHeight( GetSystemMetrics( SM_CYCAPTION
) );
2890 aStyleSettings
.SetActiveBorderColor( ImplWinColorToSal( GetSysColor( COLOR_ACTIVEBORDER
) ) );
2891 aStyleSettings
.SetDeactiveBorderColor( ImplWinColorToSal( GetSysColor( COLOR_INACTIVEBORDER
) ) );
2892 if ( aSalShlData
.mnVersion
>= 410 )
2894 aStyleSettings
.SetActiveColor2( ImplWinColorToSal( GetSysColor( COLOR_GRADIENTACTIVECAPTION
) ) );
2895 aStyleSettings
.SetDeactiveColor( ImplWinColorToSal( GetSysColor( COLOR_GRADIENTINACTIVECAPTION
) ) );
2897 aStyleSettings
.SetFaceColor( ImplWinColorToSal( GetSysColor( COLOR_3DFACE
) ) );
2898 aStyleSettings
.SetInactiveTabColor( aStyleSettings
.GetFaceColor() );
2899 aStyleSettings
.SetLightColor( ImplWinColorToSal( GetSysColor( COLOR_3DHILIGHT
) ) );
2900 aStyleSettings
.SetLightBorderColor( ImplWinColorToSal( GetSysColor( COLOR_3DLIGHT
) ) );
2901 aStyleSettings
.SetShadowColor( ImplWinColorToSal( GetSysColor( COLOR_3DSHADOW
) ) );
2902 aStyleSettings
.SetDarkShadowColor( ImplWinColorToSal( GetSysColor( COLOR_3DDKSHADOW
) ) );
2904 aStyleSettings
.SetWorkspaceColor( ImplWinColorToSal( GetSysColor( COLOR_APPWORKSPACE
) ) );
2905 aStyleSettings
.SetHelpColor( ImplWinColorToSal( GetSysColor( COLOR_INFOBK
) ) );
2906 aStyleSettings
.SetHelpTextColor( ImplWinColorToSal( GetSysColor( COLOR_INFOTEXT
) ) );
2907 aStyleSettings
.SetDialogColor( aStyleSettings
.GetFaceColor() );
2908 aStyleSettings
.SetDialogTextColor( aStyleSettings
.GetButtonTextColor() );
2909 aStyleSettings
.SetButtonTextColor( ImplWinColorToSal( GetSysColor( COLOR_BTNTEXT
) ) );
2910 aStyleSettings
.SetButtonRolloverTextColor( aStyleSettings
.GetButtonTextColor() );
2911 aStyleSettings
.SetRadioCheckTextColor( ImplWinColorToSal( GetSysColor( COLOR_WINDOWTEXT
) ) );
2912 aStyleSettings
.SetGroupTextColor( aStyleSettings
.GetRadioCheckTextColor() );
2913 aStyleSettings
.SetLabelTextColor( aStyleSettings
.GetRadioCheckTextColor() );
2914 aStyleSettings
.SetInfoTextColor( aStyleSettings
.GetRadioCheckTextColor() );
2915 aStyleSettings
.SetWindowColor( ImplWinColorToSal( GetSysColor( COLOR_WINDOW
) ) );
2916 aStyleSettings
.SetActiveTabColor( aStyleSettings
.GetWindowColor() );
2917 aStyleSettings
.SetWindowTextColor( ImplWinColorToSal( GetSysColor( COLOR_WINDOWTEXT
) ) );
2918 aStyleSettings
.SetFieldColor( aStyleSettings
.GetWindowColor() );
2919 aStyleSettings
.SetFieldTextColor( aStyleSettings
.GetWindowTextColor() );
2920 aStyleSettings
.SetFieldRolloverTextColor( aStyleSettings
.GetFieldTextColor() );
2921 aStyleSettings
.SetHighlightColor( ImplWinColorToSal( GetSysColor( COLOR_HIGHLIGHT
) ) );
2922 aStyleSettings
.SetHighlightTextColor( ImplWinColorToSal( GetSysColor( COLOR_HIGHLIGHTTEXT
) ) );
2923 aStyleSettings
.SetMenuHighlightColor( aStyleSettings
.GetHighlightColor() );
2924 aStyleSettings
.SetMenuHighlightTextColor( aStyleSettings
.GetHighlightTextColor() );
2927 aStyleSettings
.SetMenuColor( ImplWinColorToSal( GetSysColor( COLOR_MENU
) ) );
2928 aStyleSettings
.SetMenuBarColor( aStyleSettings
.GetMenuColor() );
2929 aStyleSettings
.SetMenuBorderColor( aStyleSettings
.GetLightBorderColor() ); // overriden below for flat menus
2930 aStyleSettings
.SetUseFlatBorders( FALSE
);
2931 aStyleSettings
.SetUseFlatMenues( FALSE
);
2932 aStyleSettings
.SetMenuTextColor( ImplWinColorToSal( GetSysColor( COLOR_MENUTEXT
) ) );
2933 aStyleSettings
.SetMenuBarTextColor( ImplWinColorToSal( GetSysColor( COLOR_MENUTEXT
) ) );
2934 aStyleSettings
.SetActiveColor( ImplWinColorToSal( GetSysColor( COLOR_ACTIVECAPTION
) ) );
2935 aStyleSettings
.SetActiveTextColor( ImplWinColorToSal( GetSysColor( COLOR_CAPTIONTEXT
) ) );
2936 aStyleSettings
.SetDeactiveColor( ImplWinColorToSal( GetSysColor( COLOR_INACTIVECAPTION
) ) );
2937 aStyleSettings
.SetDeactiveTextColor( ImplWinColorToSal( GetSysColor( COLOR_INACTIVECAPTIONTEXT
) ) );
2938 if ( aSalShlData
.mbWXP
)
2940 // only xp supports a different menu bar color
2941 long bFlatMenues
= 0;
2942 SystemParametersInfo( SPI_GETFLATMENU
, 0, &bFlatMenues
, 0);
2945 aStyleSettings
.SetUseFlatMenues( TRUE
);
2946 aStyleSettings
.SetMenuBarColor( ImplWinColorToSal( GetSysColor( COLOR_MENUBAR
) ) );
2947 aStyleSettings
.SetMenuHighlightColor( ImplWinColorToSal( GetSysColor( COLOR_MENUHILIGHT
) ) );
2948 aStyleSettings
.SetMenuBorderColor( ImplWinColorToSal( GetSysColor( COLOR_3DSHADOW
) ) );
2950 // flat borders for our controls etc. as well in this mode (ie, no 3d borders)
2951 // this is not active in the classic style appearance
2952 aStyleSettings
.SetUseFlatBorders( TRUE
);
2956 // Bei hellgrau geben wir die Farbe vor, damit es besser aussieht
2957 if ( aStyleSettings
.GetFaceColor() == COL_LIGHTGRAY
)
2958 aStyleSettings
.SetCheckedColor( Color( 0xCC, 0xCC, 0xCC ) );
2961 // Checked-Color berechnen
2962 Color aColor1
= aStyleSettings
.GetFaceColor();
2963 Color aColor2
= aStyleSettings
.GetLightColor();
2964 BYTE nRed
= (BYTE
)(((USHORT
)aColor1
.GetRed() + (USHORT
)aColor2
.GetRed())/2);
2965 BYTE nGreen
= (BYTE
)(((USHORT
)aColor1
.GetGreen() + (USHORT
)aColor2
.GetGreen())/2);
2966 BYTE nBlue
= (BYTE
)(((USHORT
)aColor1
.GetBlue() + (USHORT
)aColor2
.GetBlue())/2);
2967 aStyleSettings
.SetCheckedColor( Color( nRed
, nGreen
, nBlue
) );
2972 hc
.cbSize
= sizeof( HIGHCONTRAST
);
2973 if( SystemParametersInfo( SPI_GETHIGHCONTRAST
, hc
.cbSize
, &hc
, 0) && (hc
.dwFlags
& HCF_HIGHCONTRASTON
) )
2974 aStyleSettings
.SetHighContrastMode( 1 );
2976 aStyleSettings
.SetHighContrastMode( 0 );
2980 Font aMenuFont
= aStyleSettings
.GetMenuFont();
2981 Font aTitleFont
= aStyleSettings
.GetTitleFont();
2982 Font aFloatTitleFont
= aStyleSettings
.GetFloatTitleFont();
2983 Font aHelpFont
= aStyleSettings
.GetHelpFont();
2984 Font aAppFont
= aStyleSettings
.GetAppFont();
2985 Font aIconFont
= aStyleSettings
.GetIconFont();
2986 HDC hDC
= GetDC( 0 );
2987 if ( aSalShlData
.mbWNT
)
2989 NONCLIENTMETRICSW aNonClientMetrics
;
2990 aNonClientMetrics
.cbSize
= sizeof( aNonClientMetrics
);
2991 if ( SystemParametersInfoW( SPI_GETNONCLIENTMETRICS
, sizeof( aNonClientMetrics
), &aNonClientMetrics
, 0 ) )
2993 ImplSalUpdateStyleFontW( hDC
, aNonClientMetrics
.lfMenuFont
, aMenuFont
);
2994 ImplSalUpdateStyleFontW( hDC
, aNonClientMetrics
.lfCaptionFont
, aTitleFont
);
2995 ImplSalUpdateStyleFontW( hDC
, aNonClientMetrics
.lfSmCaptionFont
, aFloatTitleFont
);
2996 ImplSalUpdateStyleFontW( hDC
, aNonClientMetrics
.lfStatusFont
, aHelpFont
);
2997 ImplSalUpdateStyleFontW( hDC
, aNonClientMetrics
.lfMessageFont
, aAppFont
);
3000 if ( SystemParametersInfoW( SPI_GETICONTITLELOGFONT
, 0, &aLogFont
, 0 ) )
3001 ImplSalUpdateStyleFontW( hDC
, aLogFont
, aIconFont
);
3006 NONCLIENTMETRICSA aNonClientMetrics
;
3007 aNonClientMetrics
.cbSize
= sizeof( aNonClientMetrics
);
3008 if ( SystemParametersInfoA( SPI_GETNONCLIENTMETRICS
, sizeof( aNonClientMetrics
), &aNonClientMetrics
, 0 ) )
3010 ImplSalUpdateStyleFontA( hDC
, aNonClientMetrics
.lfMenuFont
, aMenuFont
);
3011 ImplSalUpdateStyleFontA( hDC
, aNonClientMetrics
.lfCaptionFont
, aTitleFont
);
3012 ImplSalUpdateStyleFontA( hDC
, aNonClientMetrics
.lfSmCaptionFont
, aFloatTitleFont
);
3013 ImplSalUpdateStyleFontA( hDC
, aNonClientMetrics
.lfStatusFont
, aHelpFont
);
3014 ImplSalUpdateStyleFontA( hDC
, aNonClientMetrics
.lfMessageFont
, aAppFont
);
3017 if ( SystemParametersInfoA( SPI_GETICONTITLELOGFONT
, 0, &aLogFont
, 0 ) )
3018 ImplSalUpdateStyleFontA( hDC
, aLogFont
, aIconFont
);
3022 // get screen font resolution to calculate toolbox item size
3023 long nDPIY
= GetDeviceCaps( hDC
, LOGPIXELSY
);
3025 ReleaseDC( 0, hDC
);
3027 long nHeightPx
= aMenuFont
.GetHeight() * nDPIY
/ 72;
3028 aStyleSettings
.SetToolbarIconSize( (((nHeightPx
-1)*2) >= 28) ? STYLE_TOOLBAR_ICONSIZE_LARGE
: STYLE_TOOLBAR_ICONSIZE_SMALL
);
3030 aStyleSettings
.SetMenuFont( aMenuFont
);
3031 aStyleSettings
.SetTitleFont( aTitleFont
);
3032 aStyleSettings
.SetFloatTitleFont( aFloatTitleFont
);
3033 aStyleSettings
.SetHelpFont( aHelpFont
);
3034 aStyleSettings
.SetIconFont( aIconFont
);
3035 // We prefer Arial in the russian version, because MS Sans Serif
3036 // is to wide for the dialogs
3037 if ( rSettings
.GetLanguage() == LANGUAGE_RUSSIAN
)
3039 XubString aFontName
= aAppFont
.GetName();
3040 XubString aFirstName
= aFontName
.GetToken( 0, ';' );
3041 if ( aFirstName
.EqualsIgnoreCaseAscii( "MS Sans Serif" ) )
3043 aFontName
.InsertAscii( "Arial;", 0 );
3044 aAppFont
.SetName( aFontName
);
3047 aStyleSettings
.SetAppFont( aAppFont
);
3048 aStyleSettings
.SetGroupFont( aAppFont
);
3049 aStyleSettings
.SetLabelFont( aAppFont
);
3050 aStyleSettings
.SetRadioCheckFont( aAppFont
);
3051 aStyleSettings
.SetPushButtonFont( aAppFont
);
3052 aStyleSettings
.SetFieldFont( aAppFont
);
3053 if ( aAppFont
.GetWeight() > WEIGHT_NORMAL
)
3054 aAppFont
.SetWeight( WEIGHT_NORMAL
);
3055 aStyleSettings
.SetInfoFont( aAppFont
);
3056 aStyleSettings
.SetToolFont( aAppFont
);
3059 if ( SystemParametersInfo( SPI_GETDRAGFULLWINDOWS
, 0, &bDragFull
, 0 ) )
3061 ULONG nDragFullOptions
= aStyleSettings
.GetDragFullOptions();
3063 nDragFullOptions
|= DRAGFULL_OPTION_WINDOWMOVE
| DRAGFULL_OPTION_WINDOWSIZE
| DRAGFULL_OPTION_DOCKING
| DRAGFULL_OPTION_SPLIT
;
3065 nDragFullOptions
&= ~(DRAGFULL_OPTION_WINDOWMOVE
| DRAGFULL_OPTION_WINDOWSIZE
| DRAGFULL_OPTION_DOCKING
| DRAGFULL_OPTION_SPLIT
);
3066 aStyleSettings
.SetDragFullOptions( nDragFullOptions
);
3069 aStyleSettings
.SetIconHorzSpace( GetSystemMetrics( SM_CXICONSPACING
) );
3070 aStyleSettings
.SetIconVertSpace( GetSystemMetrics( SM_CYICONSPACING
) );
3071 if ( RegOpenKey( HKEY_CURRENT_USER
,
3072 "Control Panel\\International\\Calendars\\TwoDigitYearMax",
3073 &hRegKey
) == ERROR_SUCCESS
)
3077 DWORD nValueSize
= sizeof( aValueBuf
);
3079 if ( RegQueryValueEx( hRegKey
, "1", 0,
3080 &nType
, aValueBuf
, &nValueSize
) == ERROR_SUCCESS
)
3082 if ( nType
== REG_SZ
)
3084 nValue
= (ULONG
)ImplA2I( aValueBuf
);
3085 if ( (nValue
> 1000) && (nValue
< 10000) )
3087 MiscSettings aMiscSettings
= rSettings
.GetMiscSettings();
3088 aMiscSettings
.SetTwoDigitYearStart( (USHORT
)(nValue
-99) );
3089 rSettings
.SetMiscSettings( aMiscSettings
);
3094 RegCloseKey( hRegKey
);
3097 rSettings
.SetMouseSettings( aMouseSettings
);
3098 rSettings
.SetStyleSettings( aStyleSettings
);
3101 // -----------------------------------------------------------------------
3103 SalBitmap
* WinSalFrame::SnapShot()
3105 WinSalBitmap
* pSalBitmap
= NULL
;
3108 GetWindowRect( mhWnd
, &aRect
);
3110 int nDX
= aRect
.right
-aRect
.left
;
3111 int nDY
= aRect
.bottom
-aRect
.top
;
3112 HDC hDC
= GetWindowDC( mhWnd
);
3113 HBITMAP hBmpBitmap
= CreateCompatibleBitmap( hDC
, nDX
, nDY
);
3114 HDC hBmpDC
= ImplGetCachedDC( CACHED_HDC_1
, hBmpBitmap
);
3117 bRet
= BitBlt( hBmpDC
, 0, 0, nDX
, nDY
, hDC
, 0, 0, SRCCOPY
) ? TRUE
: FALSE
;
3118 ImplReleaseCachedDC( CACHED_HDC_1
);
3122 pSalBitmap
= new WinSalBitmap
;
3124 if ( !pSalBitmap
->Create( hBmpBitmap
, FALSE
, FALSE
) )
3134 // -----------------------------------------------------------------------
3136 const SystemEnvData
* WinSalFrame::GetSystemData() const
3141 // -----------------------------------------------------------------------
3143 void WinSalFrame::Beep( SoundType eSoundType
)
3145 static UINT aImplSoundTab
[5] =
3148 MB_ICONASTERISK
, // SOUND_INFO
3149 MB_ICONEXCLAMATION
, // SOUND_WARNING
3150 MB_ICONHAND
, // SOUND_ERROR
3151 MB_ICONQUESTION
// SOUND_QUERY
3154 if( eSoundType
!= SOUND_DISABLE
) // don't beep on disable
3155 MessageBeep( aImplSoundTab
[eSoundType
] );
3158 // -----------------------------------------------------------------------
3160 SalFrame::SalPointerState
WinSalFrame::GetPointerState()
3162 SalPointerState aState
;
3165 if ( GetKeyState( VK_LBUTTON
) & 0x8000 )
3166 aState
.mnState
|= MOUSE_LEFT
;
3167 if ( GetKeyState( VK_MBUTTON
) & 0x8000 )
3168 aState
.mnState
|= MOUSE_MIDDLE
;
3169 if ( GetKeyState( VK_RBUTTON
) & 0x8000 )
3170 aState
.mnState
|= MOUSE_RIGHT
;
3171 if ( GetKeyState( VK_SHIFT
) & 0x8000 )
3172 aState
.mnState
|= KEY_SHIFT
;
3173 if ( GetKeyState( VK_CONTROL
) & 0x8000 )
3174 aState
.mnState
|= KEY_MOD1
;
3175 if ( GetKeyState( VK_MENU
) & 0x8000 )
3176 aState
.mnState
|= KEY_MOD2
;
3179 GetCursorPos( &pt
);
3181 aState
.maPos
= Point( pt
.x
- maGeometry
.nX
, pt
.y
- maGeometry
.nY
);
3185 // -----------------------------------------------------------------------
3187 SalFrame::SalIndicatorState
WinSalFrame::GetIndicatorState()
3189 SalIndicatorState aState
;
3191 if (::GetKeyState(VK_CAPITAL
))
3192 aState
.mnState
|= INDICATOR_CAPSLOCK
;
3194 if (::GetKeyState(VK_NUMLOCK
))
3195 aState
.mnState
|= INDICATOR_NUMLOCK
;
3197 if (::GetKeyState(VK_SCROLL
))
3198 aState
.mnState
|= INDICATOR_SCROLLLOCK
;
3203 void WinSalFrame::SimulateKeyPress( USHORT nKeyCode
)
3213 if (nVKey
> 0 && nVKey
< 255)
3215 ::keybd_event(nVKey
, 0x45, KEYEVENTF_EXTENDEDKEY
, 0);
3216 ::keybd_event(nVKey
, 0x45, KEYEVENTF_EXTENDEDKEY
|KEYEVENTF_KEYUP
, 0);
3220 // -----------------------------------------------------------------------
3222 void WinSalFrame::SetBackgroundBitmap( SalBitmap
* )
3226 // -----------------------------------------------------------------------
3228 void WinSalFrame::ResetClipRegion()
3230 SetWindowRgn( mhWnd
, 0, TRUE
);
3233 // -----------------------------------------------------------------------
3235 void WinSalFrame::BeginSetClipRegion( ULONG nRects
)
3238 delete [] (BYTE
*)mpClipRgnData
;
3239 ULONG nRectBufSize
= sizeof(RECT
)*nRects
;
3240 mpClipRgnData
= (RGNDATA
*)new BYTE
[sizeof(RGNDATA
)-1+nRectBufSize
];
3241 mpClipRgnData
->rdh
.dwSize
= sizeof( RGNDATAHEADER
);
3242 mpClipRgnData
->rdh
.iType
= RDH_RECTANGLES
;
3243 mpClipRgnData
->rdh
.nCount
= nRects
;
3244 mpClipRgnData
->rdh
.nRgnSize
= nRectBufSize
;
3245 SetRectEmpty( &(mpClipRgnData
->rdh
.rcBound
) );
3246 mpNextClipRect
= (RECT
*)(&(mpClipRgnData
->Buffer
));
3247 mbFirstClipRect
= TRUE
;
3250 // -----------------------------------------------------------------------
3252 void WinSalFrame::UnionClipRegion( long nX
, long nY
, long nWidth
, long nHeight
)
3254 if( ! mpClipRgnData
)
3257 RECT
* pRect
= mpNextClipRect
;
3258 RECT
* pBoundRect
= &(mpClipRgnData
->rdh
.rcBound
);
3259 long nRight
= nX
+ nWidth
;
3260 long nBottom
= nY
+ nHeight
;
3262 if ( mbFirstClipRect
)
3264 pBoundRect
->left
= nX
;
3265 pBoundRect
->top
= nY
;
3266 pBoundRect
->right
= nRight
;
3267 pBoundRect
->bottom
= nBottom
;
3268 mbFirstClipRect
= FALSE
;
3272 if ( nX
< pBoundRect
->left
)
3273 pBoundRect
->left
= (int)nX
;
3275 if ( nY
< pBoundRect
->top
)
3276 pBoundRect
->top
= (int)nY
;
3278 if ( nRight
> pBoundRect
->right
)
3279 pBoundRect
->right
= (int)nRight
;
3281 if ( nBottom
> pBoundRect
->bottom
)
3282 pBoundRect
->bottom
= (int)nBottom
;
3285 pRect
->left
= (int)nX
;
3286 pRect
->top
= (int)nY
;
3287 pRect
->right
= (int)nRight
;
3288 pRect
->bottom
= (int)nBottom
;
3289 if( (mpNextClipRect
- (RECT
*)(&mpClipRgnData
->Buffer
)) < (int)mpClipRgnData
->rdh
.nCount
)
3293 // -----------------------------------------------------------------------
3295 void WinSalFrame::EndSetClipRegion()
3297 if( ! mpClipRgnData
)
3302 // create region from accumulated rectangles
3303 if ( mpClipRgnData
->rdh
.nCount
== 1 )
3305 RECT
* pRect
= &(mpClipRgnData
->rdh
.rcBound
);
3306 hRegion
= CreateRectRgn( pRect
->left
, pRect
->top
,
3307 pRect
->right
, pRect
->bottom
);
3311 ULONG nSize
= mpClipRgnData
->rdh
.nRgnSize
+sizeof(RGNDATAHEADER
);
3312 hRegion
= ExtCreateRegion( NULL
, nSize
, mpClipRgnData
);
3314 delete [] (BYTE
*)mpClipRgnData
;
3315 mpClipRgnData
= NULL
;
3317 DBG_ASSERT( hRegion
, "WinSalFrame::EndSetClipRegion() - Can't create ClipRegion" );
3321 GetWindowRect( mhWnd
, &aWindowRect
);
3325 ClientToScreen( mhWnd
, &aPt
);
3326 OffsetRgn( hRegion
, aPt
.x
- aWindowRect
.left
, aPt
.y
- aWindowRect
.top
);
3328 if( SetWindowRgn( mhWnd
, hRegion
, TRUE
) == 0 )
3329 DeleteObject( hRegion
);
3333 // -----------------------------------------------------------------------
3335 static long ImplHandleMouseMsg( HWND hWnd
, UINT nMsg
,
3336 WPARAM wParam
, LPARAM lParam
)
3338 WinSalFrame
* pFrame
= GetWindowPtr( hWnd
);
3342 if( nMsg
== WM_LBUTTONDOWN
|| nMsg
== WM_MBUTTONDOWN
|| nMsg
== WM_RBUTTONDOWN
)
3344 // #103168# post again if async focus has not arrived yet
3345 // hopefully we will not receive the corresponding button up before this
3346 // button down arrives again
3347 Window
*pWin
= pFrame
->GetWindow();
3348 if( pWin
&& pWin
->ImplGetWindowImpl()->mpFrameData
->mnFocusId
)
3350 ImplPostMessage( hWnd
, nMsg
, wParam
, lParam
);
3354 SalMouseEvent aMouseEvt
;
3359 aMouseEvt
.mnX
= (short)LOWORD( lParam
);
3360 aMouseEvt
.mnY
= (short)HIWORD( lParam
);
3361 aMouseEvt
.mnCode
= 0;
3362 aMouseEvt
.mnTime
= GetMessageTime();
3364 // Wegen (Logitech-)MouseTreiber ueber GetKeyState() gehen, die auf
3365 // mittlerer Maustaste Doppelklick simulieren und den KeyStatus nicht
3368 if ( GetKeyState( VK_LBUTTON
) & 0x8000 )
3369 aMouseEvt
.mnCode
|= MOUSE_LEFT
;
3370 if ( GetKeyState( VK_MBUTTON
) & 0x8000 )
3371 aMouseEvt
.mnCode
|= MOUSE_MIDDLE
;
3372 if ( GetKeyState( VK_RBUTTON
) & 0x8000 )
3373 aMouseEvt
.mnCode
|= MOUSE_RIGHT
;
3374 if ( GetKeyState( VK_SHIFT
) & 0x8000 )
3375 aMouseEvt
.mnCode
|= KEY_SHIFT
;
3376 if ( GetKeyState( VK_CONTROL
) & 0x8000 )
3377 aMouseEvt
.mnCode
|= KEY_MOD1
;
3378 if ( GetKeyState( VK_MENU
) & 0x8000 )
3379 aMouseEvt
.mnCode
|= KEY_MOD2
;
3385 // Da bei Druecken von Modifier-Tasten die MouseEvents
3386 // nicht zusammengefast werden (da diese durch KeyEvents
3387 // unterbrochen werden), machen wir dieses hier selber
3388 if ( aMouseEvt
.mnCode
& (KEY_SHIFT
| KEY_MOD1
| KEY_MOD2
) )
3391 if ( ImplPeekMessage( &aTempMsg
, hWnd
, WM_MOUSEFIRST
, WM_MOUSELAST
, PM_NOREMOVE
| PM_NOYIELD
) )
3393 if ( (aTempMsg
.message
== WM_MOUSEMOVE
) &&
3394 (aTempMsg
.wParam
== wParam
) )
3399 SalData
* pSalData
= GetSalData();
3400 // Test for MouseLeave
3401 if ( pSalData
->mhWantLeaveMsg
&& (pSalData
->mhWantLeaveMsg
!= hWnd
) )
3402 ImplSendMessage( pSalData
->mhWantLeaveMsg
, SAL_MSG_MOUSELEAVE
, 0, GetMessagePos() );
3404 pSalData
->mhWantLeaveMsg
= hWnd
;
3405 // Start MouseLeave-Timer
3406 if ( !pSalData
->mpMouseLeaveTimer
)
3408 pSalData
->mpMouseLeaveTimer
= new AutoTimer
;
3409 pSalData
->mpMouseLeaveTimer
->SetTimeout( SAL_MOUSELEAVE_TIMEOUT
);
3410 pSalData
->mpMouseLeaveTimer
->Start();
3411 // We dont need to set a timeout handler, because we test
3412 // for mouseleave in the timeout callback
3414 aMouseEvt
.mnButton
= 0;
3415 nEvent
= SALEVENT_MOUSEMOVE
;
3419 case WM_NCMOUSEMOVE
:
3420 case SAL_MSG_MOUSELEAVE
:
3422 SalData
* pSalData
= GetSalData();
3423 if ( pSalData
->mhWantLeaveMsg
== hWnd
)
3425 pSalData
->mhWantLeaveMsg
= 0;
3426 if ( pSalData
->mpMouseLeaveTimer
)
3428 delete pSalData
->mpMouseLeaveTimer
;
3429 pSalData
->mpMouseLeaveTimer
= NULL
;
3431 // Mouse-Coordinaates are relativ to the screen
3433 aPt
.x
= (short)LOWORD( lParam
);
3434 aPt
.y
= (short)HIWORD( lParam
);
3435 ScreenToClient( hWnd
, &aPt
);
3436 aMouseEvt
.mnX
= aPt
.x
;
3437 aMouseEvt
.mnY
= aPt
.y
;
3438 aMouseEvt
.mnButton
= 0;
3439 nEvent
= SALEVENT_MOUSELEAVE
;
3446 case WM_LBUTTONDOWN
:
3447 aMouseEvt
.mnButton
= MOUSE_LEFT
;
3448 nEvent
= SALEVENT_MOUSEBUTTONDOWN
;
3451 case WM_MBUTTONDOWN
:
3452 aMouseEvt
.mnButton
= MOUSE_MIDDLE
;
3453 nEvent
= SALEVENT_MOUSEBUTTONDOWN
;
3456 case WM_RBUTTONDOWN
:
3457 aMouseEvt
.mnButton
= MOUSE_RIGHT
;
3458 nEvent
= SALEVENT_MOUSEBUTTONDOWN
;
3462 aMouseEvt
.mnButton
= MOUSE_LEFT
;
3463 nEvent
= SALEVENT_MOUSEBUTTONUP
;
3467 aMouseEvt
.mnButton
= MOUSE_MIDDLE
;
3468 nEvent
= SALEVENT_MOUSEBUTTONUP
;
3472 aMouseEvt
.mnButton
= MOUSE_RIGHT
;
3473 nEvent
= SALEVENT_MOUSEBUTTONUP
;
3477 // check if this window was destroyed - this might happen if we are the help window
3478 // and sent a mouse leave message to the application which killed the help window, ie ourself
3479 if( !IsWindow( hWnd
) )
3484 if ( nEvent
== SALEVENT_MOUSEBUTTONDOWN
)
3485 UpdateWindow( hWnd
);
3487 // --- RTL --- (mirror mouse pos)
3488 if( Application::GetSettings().GetLayoutRTL() )
3489 aMouseEvt
.mnX
= pFrame
->maGeometry
.nWidth
-1-aMouseEvt
.mnX
;
3491 nRet
= pFrame
->CallCallback( nEvent
, &aMouseEvt
);
3492 if ( nMsg
== WM_MOUSEMOVE
)
3493 SetCursor( pFrame
->mhCursor
);
3501 // -----------------------------------------------------------------------
3503 static long ImplHandleMouseActivateMsg( HWND hWnd
)
3505 WinSalFrame
* pFrame
= GetWindowPtr( hWnd
);
3509 if ( pFrame
->mbFloatWin
)
3512 SalMouseActivateEvent aMouseActivateEvt
;
3514 GetCursorPos( &aPt
);
3515 ScreenToClient( hWnd
, &aPt
);
3516 aMouseActivateEvt
.mnX
= aPt
.x
;
3517 aMouseActivateEvt
.mnY
= aPt
.y
;
3518 return pFrame
->CallCallback( SALEVENT_MOUSEACTIVATE
, &aMouseActivateEvt
);
3521 // -----------------------------------------------------------------------
3523 static long ImplHandleWheelMsg( HWND hWnd
, UINT nMsg
, WPARAM wParam
, LPARAM lParam
)
3525 DBG_ASSERT( nMsg
== WM_MOUSEWHEEL
||
3526 nMsg
== WM_MOUSEHWHEEL
,
3527 "ImplHandleWheelMsg() called with no wheel mouse event" );
3529 ImplSalYieldMutexAcquireWithWait();
3532 WinSalFrame
* pFrame
= GetWindowPtr( hWnd
);
3535 WORD nWinModCode
= LOWORD( wParam
);
3537 aWinPt
.x
= (short)LOWORD( lParam
);
3538 aWinPt
.y
= (short)HIWORD( lParam
);
3539 ScreenToClient( hWnd
, &aWinPt
);
3541 SalWheelMouseEvent aWheelEvt
;
3542 aWheelEvt
.mnTime
= GetMessageTime();
3543 aWheelEvt
.mnX
= aWinPt
.x
;
3544 aWheelEvt
.mnY
= aWinPt
.y
;
3545 aWheelEvt
.mnCode
= 0;
3546 aWheelEvt
.mnDelta
= (short)HIWORD( wParam
);
3547 aWheelEvt
.mnNotchDelta
= aWheelEvt
.mnDelta
/WHEEL_DELTA
;
3548 if( aWheelEvt
.mnNotchDelta
== 0 )
3550 if( aWheelEvt
.mnDelta
> 0 )
3551 aWheelEvt
.mnNotchDelta
= 1;
3552 else if( aWheelEvt
.mnDelta
< 0 )
3553 aWheelEvt
.mnNotchDelta
= -1;
3556 if( nMsg
== WM_MOUSEWHEEL
)
3558 if ( aSalShlData
.mnWheelScrollLines
== WHEEL_PAGESCROLL
)
3559 aWheelEvt
.mnScrollLines
= SAL_WHEELMOUSE_EVENT_PAGESCROLL
;
3561 aWheelEvt
.mnScrollLines
= aSalShlData
.mnWheelScrollLines
;
3562 aWheelEvt
.mbHorz
= FALSE
;
3566 aWheelEvt
.mnScrollLines
= aSalShlData
.mnWheelScrollChars
;
3567 aWheelEvt
.mbHorz
= TRUE
;
3570 if ( nWinModCode
& MK_SHIFT
)
3571 aWheelEvt
.mnCode
|= KEY_SHIFT
;
3572 if ( nWinModCode
& MK_CONTROL
)
3573 aWheelEvt
.mnCode
|= KEY_MOD1
;
3574 if ( GetKeyState( VK_MENU
) & 0x8000 )
3575 aWheelEvt
.mnCode
|= KEY_MOD2
;
3577 // --- RTL --- (mirror mouse pos)
3578 if( Application::GetSettings().GetLayoutRTL() )
3579 aWheelEvt
.mnX
= pFrame
->maGeometry
.nWidth
-1-aWheelEvt
.mnX
;
3581 nRet
= pFrame
->CallCallback( SALEVENT_WHEELMOUSE
, &aWheelEvt
);
3584 ImplSalYieldMutexRelease();
3589 // -----------------------------------------------------------------------
3591 static USHORT
ImplSalGetKeyCode( WPARAM wParam
)
3596 if ( wParam
< KEY_TAB_SIZE
)
3597 nKeyCode
= aImplTranslateKeyTab
[wParam
];
3600 SalData
* pSalData
= GetSalData();
3601 std::map
< UINT
, USHORT
>::const_iterator it
= pSalData
->maVKMap
.find( (UINT
)wParam
);
3602 if( it
!= pSalData
->maVKMap
.end() )
3603 nKeyCode
= it
->second
;
3611 // -----------------------------------------------------------------------
3613 static UINT
ImplStrToNum( const sal_Char
* pStr
)
3617 // Solange es sich um eine Ziffer handelt, String umwandeln
3618 while( (*pStr
>= 48) && (*pStr
<= 57) )
3621 n
+= ((*pStr
) - 48);
3628 // -----------------------------------------------------------------------
3630 static void ImplUpdateInputLang( WinSalFrame
* pFrame
)
3632 BOOL bLanguageChange
= FALSE
;
3633 UINT nLang
= LOWORD( GetKeyboardLayout( 0 ) );
3634 if ( nLang
&& nLang
!= pFrame
->mnInputLang
)
3636 // keep input lang up-to-date
3637 pFrame
->mnInputLang
= nLang
;
3638 bLanguageChange
= TRUE
;
3641 // If we are on Windows NT we use Unicode FrameProcs and so we
3642 // get Unicode charcodes directly from Windows
3643 // no need to set up a code page
3644 if ( aSalShlData
.mbWNT
)
3649 pFrame
->mnInputLang
= 0;
3650 pFrame
->mnInputCodePage
= GetACP();
3652 else if ( bLanguageChange
)
3655 if ( GetLocaleInfoA( MAKELCID( nLang
, SORT_DEFAULT
), LOCALE_IDEFAULTANSICODEPAGE
,
3656 aBuf
, sizeof(aBuf
) ) > 0 )
3658 pFrame
->mnInputCodePage
= ImplStrToNum( aBuf
);
3659 if ( !pFrame
->mnInputCodePage
)
3660 pFrame
->mnInputCodePage
= GetACP();
3663 pFrame
->mnInputCodePage
= GetACP();
3668 static sal_Unicode
ImplGetCharCode( WinSalFrame
* pFrame
, WPARAM nCharCode
)
3670 ImplUpdateInputLang( pFrame
);
3672 // If we are on Windows NT we use Unicode FrameProcs and so we
3673 // get Unicode charcodes directly from Windows
3674 if ( aSalShlData
.mbWNT
)
3675 return (sal_Unicode
)nCharCode
;
3677 sal_Char aCharBuf
[2];
3680 if ( nCharCode
> 0xFF )
3682 aCharBuf
[0] = (sal_Char
)(nCharCode
>>8);
3683 aCharBuf
[1] = (sal_Char
)nCharCode
;
3688 aCharBuf
[0] = (sal_Char
)nCharCode
;
3691 if ( ::MultiByteToWideChar( pFrame
->mnInputCodePage
,
3693 aCharBuf
, nCharLen
, &c
, 1 ) )
3694 return (sal_Unicode
)c
;
3696 return (sal_Unicode
)nCharCode
;
3699 // -----------------------------------------------------------------------
3701 LanguageType
WinSalFrame::GetInputLanguage()
3704 ImplUpdateInputLang( this );
3707 return LANGUAGE_DONTKNOW
;
3709 return (LanguageType
) mnInputLang
;
3712 // -----------------------------------------------------------------------
3714 BOOL
WinSalFrame::MapUnicodeToKeyCode( sal_Unicode aUnicode
, LanguageType aLangType
, KeyCode
& rKeyCode
)
3719 // just use the passed language identifier, do not try to load additional keyboard support
3720 hkl
= (HKL
) aLangType
;
3724 SHORT scan
= VkKeyScanExW( aUnicode
, hkl
);
3725 if( LOWORD(scan
) == 0xFFFF )
3726 // keyboard not loaded or key cannot be mapped
3730 BYTE vkeycode
= LOBYTE(scan
);
3731 BYTE shiftstate
= HIBYTE(scan
);
3733 // Last argument is set to FALSE, because there's no decission made
3734 // yet which key should be assigned to MOD3 modifier on Windows.
3735 // Windows key - user's can be confused, because it should display
3736 // Windows menu (applies to both left/right key)
3737 // Menu key - this key is used to display context menu
3738 // AltGr key - probably it has no sense
3739 rKeyCode
= KeyCode( ImplSalGetKeyCode( vkeycode
),
3740 (shiftstate
& 0x01) ? TRUE
: FALSE
, // shift
3741 (shiftstate
& 0x02) ? TRUE
: FALSE
, // ctrl
3742 (shiftstate
& 0x04) ? TRUE
: FALSE
, // alt
3751 // -----------------------------------------------------------------------
3753 static long ImplHandleKeyMsg( HWND hWnd
, UINT nMsg
,
3754 WPARAM wParam
, LPARAM lParam
, LRESULT
& rResult
)
3756 static BOOL bIgnoreCharMsg
= FALSE
;
3757 static WPARAM nDeadChar
= 0;
3758 static WPARAM nLastVKChar
= 0;
3759 static USHORT nLastChar
= 0;
3760 static USHORT nLastModKeyCode
= 0;
3761 static bool bWaitForModKeyRelease
= false;
3762 USHORT nRepeat
= LOWORD( lParam
)-1;
3763 USHORT nModCode
= 0;
3765 // Key wurde evtl. durch SysChild an uns weitergeleitet und
3766 // darf somit dann nicht doppelt verarbeitet werden
3767 GetSalData()->mnSalObjWantKeyEvt
= 0;
3769 if ( nMsg
== WM_DEADCHAR
)
3775 WinSalFrame
* pFrame
= GetWindowPtr( hWnd
);
3779 // Wir restaurieren den Background-Modus bei jeder Texteingabe,
3780 // da einige Tools wie RichWin uns diesen hin- und wieder umsetzen
3781 if ( pFrame
->mpGraphics
&&
3782 pFrame
->mpGraphics
->mhDC
)
3783 SetBkMode( pFrame
->mpGraphics
->mhDC
, TRANSPARENT
);
3785 // determine modifiers
3786 if ( GetKeyState( VK_SHIFT
) & 0x8000 )
3787 nModCode
|= KEY_SHIFT
;
3788 if ( GetKeyState( VK_CONTROL
) & 0x8000 )
3789 nModCode
|= KEY_MOD1
;
3790 if ( GetKeyState( VK_MENU
) & 0x8000 )
3791 nModCode
|= KEY_MOD2
;
3793 if ( (nMsg
== WM_CHAR
) || (nMsg
== WM_SYSCHAR
) )
3797 if ( bIgnoreCharMsg
)
3799 bIgnoreCharMsg
= FALSE
;
3800 // #101635# if zero is returned here for WM_SYSCHAR (ALT+<key>) Windows will beep
3801 // becaus this 'hotkey' was not processed -> better return 1
3802 // except for Alt-SPACE which should always open the sysmenu (#104616#)
3804 // also return zero if a system menubar is available that might process this hotkey
3805 // this also applies to the OLE inplace embedding where we are a child window
3806 if( (GetWindowStyle( hWnd
) & WS_CHILD
) || GetMenu( hWnd
) || (wParam
== 0x20) )
3812 // Backspace ignorieren wir als eigenstaendige Taste,
3813 // damit wir keine Probleme in Kombination mit einem
3815 if ( wParam
== 0x08 ) // BACKSPACE
3818 // Hier kommen nur "freifliegende" WM_CHAR Message an, die durch
3819 // eintippen einer ALT-NUMPAD Kombination erzeugt wurden
3820 SalKeyEvent aKeyEvt
;
3822 if ( (wParam
>= '0') && (wParam
<= '9') )
3823 aKeyEvt
.mnCode
= sal::static_int_cast
<USHORT
>(KEYGROUP_NUM
+ wParam
- '0');
3824 else if ( (wParam
>= 'A') && (wParam
<= 'Z') )
3825 aKeyEvt
.mnCode
= sal::static_int_cast
<USHORT
>(KEYGROUP_ALPHA
+ wParam
- 'A');
3826 else if ( (wParam
>= 'a') && (wParam
<= 'z') )
3827 aKeyEvt
.mnCode
= sal::static_int_cast
<USHORT
>(KEYGROUP_ALPHA
+ wParam
- 'a');
3828 else if ( wParam
== 0x0D ) // RETURN
3829 aKeyEvt
.mnCode
= KEY_RETURN
;
3830 else if ( wParam
== 0x1B ) // ESCAPE
3831 aKeyEvt
.mnCode
= KEY_ESCAPE
;
3832 else if ( wParam
== 0x09 ) // TAB
3833 aKeyEvt
.mnCode
= KEY_TAB
;
3834 else if ( wParam
== 0x20 ) // SPACE
3835 aKeyEvt
.mnCode
= KEY_SPACE
;
3839 aKeyEvt
.mnTime
= GetMessageTime();
3840 aKeyEvt
.mnCode
|= nModCode
;
3841 aKeyEvt
.mnCharCode
= ImplGetCharCode( pFrame
, wParam
);
3842 aKeyEvt
.mnRepeat
= nRepeat
;
3845 long nRet
= pFrame
->CallCallback( SALEVENT_KEYINPUT
, &aKeyEvt
);
3846 pFrame
->CallCallback( SALEVENT_KEYUP
, &aKeyEvt
);
3849 // #i11583#, MCD, 2003-01-13, Support for WM_UNICHAR & Keyman 6.0; addition begins
3850 else if( nMsg
== WM_UNICHAR
)
3852 // If Windows is asking if we accept WM_UNICHAR, return TRUE
3853 if(wParam
== UNICODE_NOCHAR
)
3855 rResult
= TRUE
; // ssa: this will actually return TRUE to windows
3856 return 1; // ...but this will only avoid calling the defwindowproc
3859 SalKeyEvent aKeyEvt
;
3860 aKeyEvt
.mnCode
= nModCode
; // Or should it be 0? - as this is always a character returned
3861 aKeyEvt
.mnTime
= GetMessageTime();
3862 aKeyEvt
.mnRepeat
= 0;
3864 if( wParam
>= Uni_SupplementaryPlanesStart
)
3866 // character is supplementary char in UTF-32 format - must be converted to UTF-16 supplementary pair
3867 // sal_Unicode ch = (sal_Unicode) Uni_UTF32ToSurrogate1(wParam);
3870 pFrame
->CallCallback( SALEVENT_KEYINPUT
, &aKeyEvt
);
3871 pFrame
->CallCallback( SALEVENT_KEYUP
, &aKeyEvt
);
3872 wParam
= (sal_Unicode
) Uni_UTF32ToSurrogate2( wParam
);
3875 aKeyEvt
.mnCharCode
= (sal_Unicode
) wParam
;
3879 long nRet
= pFrame
->CallCallback( SALEVENT_KEYINPUT
, &aKeyEvt
);
3880 pFrame
->CallCallback( SALEVENT_KEYUP
, &aKeyEvt
);
3884 // MCD, 2003-01-13, Support for WM_UNICHAR & Keyman 6.0; addition ends
3887 // Bei Shift, Control und Menu schicken wir einen KeyModChange-Event
3888 if ( (wParam
== VK_SHIFT
) || (wParam
== VK_CONTROL
) || (wParam
== VK_MENU
) )
3890 SalKeyModEvent aModEvt
;
3891 aModEvt
.mnTime
= GetMessageTime();
3892 aModEvt
.mnCode
= nModCode
;
3893 aModEvt
.mnModKeyCode
= 0; // no command events will be sent if this member is 0
3896 if( GetKeyState( VK_LSHIFT
) & 0x8000 )
3897 tmpCode
|= MODKEY_LSHIFT
;
3898 if( GetKeyState( VK_RSHIFT
) & 0x8000 )
3899 tmpCode
|= MODKEY_RSHIFT
;
3900 if( GetKeyState( VK_LCONTROL
) & 0x8000 )
3901 tmpCode
|= MODKEY_LMOD1
;
3902 if( GetKeyState( VK_RCONTROL
) & 0x8000 )
3903 tmpCode
|= MODKEY_RMOD1
;
3904 if( GetKeyState( VK_LMENU
) & 0x8000 )
3905 tmpCode
|= MODKEY_LMOD2
;
3906 if( GetKeyState( VK_RMENU
) & 0x8000 )
3907 tmpCode
|= MODKEY_RMOD2
;
3909 if( tmpCode
< nLastModKeyCode
)
3911 aModEvt
.mnModKeyCode
= nLastModKeyCode
;
3912 nLastModKeyCode
= 0;
3913 bWaitForModKeyRelease
= true;
3917 if( !bWaitForModKeyRelease
)
3918 nLastModKeyCode
= tmpCode
;
3922 bWaitForModKeyRelease
= false;
3924 return pFrame
->CallCallback( SALEVENT_KEYMODCHANGE
, &aModEvt
);
3928 SalKeyEvent aKeyEvt
;
3931 WIN_BOOL bCharPeek
= FALSE
;
3932 UINT nCharMsg
= WM_CHAR
;
3933 BOOL bKeyUp
= (nMsg
== WM_KEYUP
) || (nMsg
== WM_SYSKEYUP
);
3935 nLastModKeyCode
= 0; // make sure no modkey messages are sent if they belong to a hotkey (see above)
3936 aKeyEvt
.mnCharCode
= 0;
3939 aKeyEvt
.mnCode
= ImplSalGetKeyCode( wParam
);
3942 // check for charcode
3943 // Mit Hilfe von PeekMessage holen wir uns jetzt die
3944 // zugehoerige WM_CHAR Message, wenn vorhanden.
3945 // Diese WM_CHAR Message steht immer am Anfang der
3946 // Messagequeue. Ausserdem ist sichergestellt, dass immer
3947 // nur eine WM_CHAR Message in der Queue steht.
3948 bCharPeek
= ImplPeekMessage( &aCharMsg
, hWnd
,
3949 WM_CHAR
, WM_CHAR
, PM_NOREMOVE
| PM_NOYIELD
);
3950 if ( bCharPeek
&& (nDeadChar
== aCharMsg
.wParam
) )
3955 if ( wParam
== VK_BACK
)
3957 ImplPeekMessage( &aCharMsg
, hWnd
,
3958 nCharMsg
, nCharMsg
, PM_REMOVE
| PM_NOYIELD
);
3966 bCharPeek
= ImplPeekMessage( &aCharMsg
, hWnd
,
3967 WM_SYSCHAR
, WM_SYSCHAR
, PM_NOREMOVE
| PM_NOYIELD
);
3968 nCharMsg
= WM_SYSCHAR
;
3972 aKeyEvt
.mnCharCode
= ImplGetCharCode( pFrame
, aCharMsg
.wParam
);
3974 aKeyEvt
.mnCharCode
= 0;
3976 nLastChar
= aKeyEvt
.mnCharCode
;
3977 nLastVKChar
= wParam
;
3981 if ( wParam
== nLastVKChar
)
3983 aKeyEvt
.mnCharCode
= nLastChar
;
3989 if ( aKeyEvt
.mnCode
|| aKeyEvt
.mnCharCode
)
3992 nEvent
= SALEVENT_KEYUP
;
3994 nEvent
= SALEVENT_KEYINPUT
;
3996 aKeyEvt
.mnTime
= GetMessageTime();
3997 aKeyEvt
.mnCode
|= nModCode
;
3998 aKeyEvt
.mnRepeat
= nRepeat
;
4000 if( (nModCode
& (KEY_MOD1
|KEY_MOD2
)) == (KEY_MOD1
|KEY_MOD2
) &&
4001 aKeyEvt
.mnCharCode
)
4003 // this is actually AltGr and should not be handled as Alt
4004 aKeyEvt
.mnCode
&= ~(KEY_MOD1
|KEY_MOD2
);
4007 bIgnoreCharMsg
= bCharPeek
? TRUE
: FALSE
;
4008 long nRet
= pFrame
->CallCallback( nEvent
, &aKeyEvt
);
4009 // independent part only reacts on keyup but Windows does not send
4010 // keyup for VK_HANJA
4011 if( aKeyEvt
.mnCode
== KEY_HANGUL_HANJA
)
4012 nRet
= pFrame
->CallCallback( SALEVENT_KEYUP
, &aKeyEvt
);
4014 bIgnoreCharMsg
= FALSE
;
4016 // char-message, than remove or ignore
4022 ImplPeekMessage( &aCharMsg
, hWnd
,
4023 nCharMsg
, nCharMsg
, PM_REMOVE
| PM_NOYIELD
);
4026 bIgnoreCharMsg
= TRUE
;
4037 // -----------------------------------------------------------------------
4039 long ImplHandleSalObjKeyMsg( HWND hWnd
, UINT nMsg
,
4040 WPARAM wParam
, LPARAM lParam
)
4042 if ( (nMsg
== WM_KEYDOWN
) || (nMsg
== WM_KEYUP
) )
4044 WinSalFrame
* pFrame
= GetWindowPtr( hWnd
);
4048 USHORT nRepeat
= LOWORD( lParam
)-1;
4049 USHORT nModCode
= 0;
4051 // determine modifiers
4052 if ( GetKeyState( VK_SHIFT
) & 0x8000 )
4053 nModCode
|= KEY_SHIFT
;
4054 if ( GetKeyState( VK_CONTROL
) & 0x8000 )
4055 nModCode
|= KEY_MOD1
;
4056 if ( GetKeyState( VK_MENU
) & 0x8000 )
4057 nModCode
|= KEY_MOD2
;
4059 if ( (wParam
!= VK_SHIFT
) && (wParam
!= VK_CONTROL
) && (wParam
!= VK_MENU
) )
4061 SalKeyEvent aKeyEvt
;
4063 BOOL bKeyUp
= (nMsg
== WM_KEYUP
) || (nMsg
== WM_SYSKEYUP
);
4066 aKeyEvt
.mnCode
= ImplSalGetKeyCode( wParam
);
4067 aKeyEvt
.mnCharCode
= 0;
4069 if ( aKeyEvt
.mnCode
)
4072 nEvent
= SALEVENT_KEYUP
;
4074 nEvent
= SALEVENT_KEYINPUT
;
4076 aKeyEvt
.mnTime
= GetMessageTime();
4077 aKeyEvt
.mnCode
|= nModCode
;
4078 aKeyEvt
.mnRepeat
= nRepeat
;
4079 long nRet
= pFrame
->CallCallback( nEvent
, &aKeyEvt
);
4090 // -----------------------------------------------------------------------
4092 long ImplHandleSalObjSysCharMsg( HWND hWnd
, WPARAM wParam
, LPARAM lParam
)
4094 WinSalFrame
* pFrame
= GetWindowPtr( hWnd
);
4098 USHORT nRepeat
= LOWORD( lParam
)-1;
4099 USHORT nModCode
= 0;
4100 USHORT cKeyCode
= (USHORT
)wParam
;
4102 // determine modifiers
4103 if ( GetKeyState( VK_SHIFT
) & 0x8000 )
4104 nModCode
|= KEY_SHIFT
;
4105 if ( GetKeyState( VK_CONTROL
) & 0x8000 )
4106 nModCode
|= KEY_MOD1
;
4107 nModCode
|= KEY_MOD2
;
4109 // KeyEvent zusammenbauen
4110 SalKeyEvent aKeyEvt
;
4111 aKeyEvt
.mnTime
= GetMessageTime();
4112 if ( (cKeyCode
>= 48) && (cKeyCode
<= 57) )
4113 aKeyEvt
.mnCode
= KEY_0
+(cKeyCode
-48);
4114 else if ( (cKeyCode
>= 65) && (cKeyCode
<= 90) )
4115 aKeyEvt
.mnCode
= KEY_A
+(cKeyCode
-65);
4116 else if ( (cKeyCode
>= 97) && (cKeyCode
<= 122) )
4117 aKeyEvt
.mnCode
= KEY_A
+(cKeyCode
-97);
4120 aKeyEvt
.mnCode
|= nModCode
;
4121 aKeyEvt
.mnCharCode
= ImplGetCharCode( pFrame
, cKeyCode
);
4122 aKeyEvt
.mnRepeat
= nRepeat
;
4123 long nRet
= pFrame
->CallCallback( SALEVENT_KEYINPUT
, &aKeyEvt
);
4124 pFrame
->CallCallback( SALEVENT_KEYUP
, &aKeyEvt
);
4128 // -----------------------------------------------------------------------
4130 static bool ImplHandlePaintMsg( HWND hWnd
)
4132 BOOL bMutex
= FALSE
;
4133 if ( ImplSalYieldMutexTryToAcquire() )
4136 // if we don't get the mutex, we can also change the clip region,
4137 // because other threads doesn't use the mutex from the main
4138 // thread --> see GetGraphics()
4140 WinSalFrame
* pFrame
= GetWindowPtr( hWnd
);
4143 // Clip-Region muss zurueckgesetzt werden, da wir sonst kein
4144 // ordentliches Bounding-Rectangle bekommen
4145 if ( pFrame
->mpGraphics
&& pFrame
->mpGraphics
->mhRegion
)
4146 SelectClipRgn( pFrame
->mpGraphics
->mhDC
, 0 );
4148 // Laut Window-Doku soll man erst abfragen, ob ueberhaupt eine
4149 // Paint-Region anliegt
4150 if ( GetUpdateRect( hWnd
, NULL
, FALSE
) )
4152 // Call BeginPaint/EndPaint to query the rect and send
4153 // this Notofication to rect
4156 BeginPaint( hWnd
, &aPs
);
4157 CopyRect( &aUpdateRect
, &aPs
.rcPaint
);
4160 // ClipRegion wieder herstellen
4161 if ( pFrame
->mpGraphics
&& pFrame
->mpGraphics
->mhRegion
)
4163 SelectClipRgn( pFrame
->mpGraphics
->mhDC
,
4164 pFrame
->mpGraphics
->mhRegion
);
4169 SalPaintEvent
aPEvt( aUpdateRect
.left
, aUpdateRect
.top
, aUpdateRect
.right
-aUpdateRect
.left
, aUpdateRect
.bottom
-aUpdateRect
.top
, pFrame
->mbPresentation
);
4170 pFrame
->CallCallback( SALEVENT_PAINT
, &aPEvt
);
4174 RECT
* pRect
= new RECT
;
4175 CopyRect( pRect
, &aUpdateRect
);
4176 ImplPostMessage( hWnd
, SAL_MSG_POSTPAINT
, (WPARAM
)pRect
, 0 );
4178 EndPaint( hWnd
, &aPs
);
4182 // ClipRegion wieder herstellen
4183 if ( pFrame
->mpGraphics
&& pFrame
->mpGraphics
->mhRegion
)
4185 SelectClipRgn( pFrame
->mpGraphics
->mhDC
,
4186 pFrame
->mpGraphics
->mhRegion
);
4192 ImplSalYieldMutexRelease();
4194 return bMutex
? true : false;
4197 // -----------------------------------------------------------------------
4199 static void ImplHandlePaintMsg2( HWND hWnd
, RECT
* pRect
)
4202 if ( ImplSalYieldMutexTryToAcquire() )
4204 WinSalFrame
* pFrame
= GetWindowPtr( hWnd
);
4207 SalPaintEvent
aPEvt( pRect
->left
, pRect
->top
, pRect
->right
-pRect
->left
, pRect
->bottom
-pRect
->top
);
4208 pFrame
->CallCallback( SALEVENT_PAINT
, &aPEvt
);
4210 ImplSalYieldMutexRelease();
4214 ImplPostMessage( hWnd
, SAL_MSG_POSTPAINT
, (WPARAM
)pRect
, 0 );
4217 // -----------------------------------------------------------------------
4219 static void SetMaximizedFrameGeometry( HWND hWnd
, WinSalFrame
* pFrame
)
4221 // calculate and set frame geometry of a maximized window - useful if the window is still hidden
4223 // dualmonitor support:
4224 // Get screensize of the monitor whith the mouse pointer
4227 GetCursorPos( &pt
);
4229 aRectMouse
.left
= pt
.x
;
4230 aRectMouse
.top
= pt
.y
;
4231 aRectMouse
.right
= pt
.x
+2;
4232 aRectMouse
.bottom
= pt
.y
+2;
4235 ImplSalGetWorkArea( hWnd
, &aRect
, &aRectMouse
);
4237 // a maximized window has no other borders than the caption
4238 pFrame
->maGeometry
.nLeftDecoration
= pFrame
->maGeometry
.nRightDecoration
= pFrame
->maGeometry
.nBottomDecoration
= 0;
4239 pFrame
->maGeometry
.nTopDecoration
= pFrame
->mbCaption
? GetSystemMetrics( SM_CYCAPTION
) : 0;
4241 aRect
.top
+= pFrame
->maGeometry
.nTopDecoration
;
4242 pFrame
->maGeometry
.nX
= aRect
.left
;
4243 pFrame
->maGeometry
.nY
= aRect
.top
;
4244 pFrame
->maGeometry
.nWidth
= aRect
.right
- aRect
.left
;
4245 pFrame
->maGeometry
.nHeight
= aRect
.bottom
- aRect
.top
;
4248 static void UpdateFrameGeometry( HWND hWnd
, WinSalFrame
* pFrame
)
4254 GetWindowRect( hWnd
, &aRect
);
4255 memset(&pFrame
->maGeometry
, 0, sizeof(SalFrameGeometry
) );
4257 if ( IsIconic( hWnd
) )
4263 ClientToScreen(hWnd
, &aPt
);
4264 int cx
= aPt
.x
- aRect
.left
;
4265 pFrame
->maGeometry
.nTopDecoration
= aPt
.y
- aRect
.top
;
4267 pFrame
->maGeometry
.nLeftDecoration
= cx
;
4268 pFrame
->maGeometry
.nRightDecoration
= cx
;
4270 pFrame
->maGeometry
.nX
= aPt
.x
;
4271 pFrame
->maGeometry
.nY
= aPt
.y
;
4274 GetClientRect( hWnd
, &aInnerRect
);
4275 if( aInnerRect
.right
)
4277 // improve right decoration
4278 aPt
.x
=aInnerRect
.right
;
4279 aPt
.y
=aInnerRect
.top
;
4280 ClientToScreen(hWnd
, &aPt
);
4281 pFrame
->maGeometry
.nRightDecoration
= aRect
.right
- aPt
.x
;
4283 if( aInnerRect
.bottom
) // may be zero if window was not shown yet
4284 pFrame
->maGeometry
.nBottomDecoration
+= aRect
.bottom
- aPt
.y
- aInnerRect
.bottom
;
4286 // bottom border is typically the same as left/right
4287 pFrame
->maGeometry
.nBottomDecoration
= pFrame
->maGeometry
.nLeftDecoration
;
4289 int nWidth
= aRect
.right
- aRect
.left
4290 - pFrame
->maGeometry
.nRightDecoration
- pFrame
->maGeometry
.nLeftDecoration
;
4291 int nHeight
= aRect
.bottom
- aRect
.top
4292 - pFrame
->maGeometry
.nBottomDecoration
- pFrame
->maGeometry
.nTopDecoration
;
4294 pFrame
->maGeometry
.nHeight
= nHeight
< 0 ? 0 : nHeight
;
4295 pFrame
->maGeometry
.nWidth
= nWidth
< 0 ? 0 : nWidth
;
4296 pFrame
->updateScreenNumber();
4299 // -----------------------------------------------------------------------
4301 static void ImplCallMoveHdl( HWND hWnd
)
4303 WinSalFrame
* pFrame
= GetWindowPtr( hWnd
);
4306 pFrame
->CallCallback( SALEVENT_MOVE
, 0 );
4307 // Um doppelte Paints von VCL und SAL zu vermeiden
4308 //if ( IsWindowVisible( hWnd ) && !pFrame->mbInShow )
4309 // UpdateWindow( hWnd );
4313 // -----------------------------------------------------------------------
4315 static void ImplCallClosePopupsHdl( HWND hWnd
)
4317 WinSalFrame
* pFrame
= GetWindowPtr( hWnd
);
4320 pFrame
->CallCallback( SALEVENT_CLOSEPOPUPS
, 0 );
4324 // -----------------------------------------------------------------------
4326 static void ImplHandleMoveMsg( HWND hWnd
)
4328 if ( ImplSalYieldMutexTryToAcquire() )
4330 WinSalFrame
* pFrame
= GetWindowPtr( hWnd
);
4333 UpdateFrameGeometry( hWnd
, pFrame
);
4335 if ( GetWindowStyle( hWnd
) & WS_VISIBLE
)
4336 pFrame
->mbDefPos
= FALSE
;
4338 // Gegen moegliche Rekursionen sichern
4339 if ( !pFrame
->mbInMoveMsg
)
4341 // Fenster im FullScreenModus wieder einpassen
4342 pFrame
->mbInMoveMsg
= TRUE
;
4343 if ( pFrame
->mbFullScreen
)
4344 ImplSalFrameFullScreenPos( pFrame
);
4345 pFrame
->mbInMoveMsg
= FALSE
;
4349 ImplSaveFrameState( pFrame
);
4352 //#93851 if we call this handler, VCL floating windows are not updated correctly
4353 ImplCallMoveHdl( hWnd
);
4357 ImplSalYieldMutexRelease();
4360 ImplPostMessage( hWnd
, SAL_MSG_POSTMOVE
, 0, 0 );
4363 // -----------------------------------------------------------------------
4365 static void ImplCallSizeHdl( HWND hWnd
)
4367 // Da Windows diese Messages auch senden kann, muss hier auch die
4368 // Solar-Semaphore beruecksichtigt werden
4369 if ( ImplSalYieldMutexTryToAcquire() )
4371 WinSalFrame
* pFrame
= GetWindowPtr( hWnd
);
4374 pFrame
->CallCallback( SALEVENT_RESIZE
, 0 );
4375 // Um doppelte Paints von VCL und SAL zu vermeiden
4376 if ( IsWindowVisible( hWnd
) && !pFrame
->mbInShow
)
4377 UpdateWindow( hWnd
);
4380 ImplSalYieldMutexRelease();
4383 ImplPostMessage( hWnd
, SAL_MSG_POSTCALLSIZE
, 0, 0 );
4386 // -----------------------------------------------------------------------
4388 static void ImplHandleSizeMsg( HWND hWnd
, WPARAM wParam
, LPARAM lParam
)
4390 if ( (wParam
!= SIZE_MAXSHOW
) && (wParam
!= SIZE_MAXHIDE
) )
4392 WinSalFrame
* pFrame
= GetWindowPtr( hWnd
);
4395 UpdateFrameGeometry( hWnd
, pFrame
);
4397 pFrame
->mnWidth
= (int)LOWORD(lParam
);
4398 pFrame
->mnHeight
= (int)HIWORD(lParam
);
4400 ImplSaveFrameState( pFrame
);
4402 ImplCallSizeHdl( hWnd
);
4407 // -----------------------------------------------------------------------
4409 static void ImplHandleFocusMsg( HWND hWnd
)
4411 if ( ImplSalYieldMutexTryToAcquire() )
4413 WinSalFrame
* pFrame
= GetWindowPtr( hWnd
);
4414 if ( pFrame
&& !WinSalFrame::mbInReparent
)
4416 // Query the actual status
4417 if ( ::GetFocus() == hWnd
)
4419 if ( IsWindowVisible( hWnd
) && !pFrame
->mbInShow
)
4420 UpdateWindow( hWnd
);
4422 // Feststellen, ob wir IME unterstuetzen
4423 if ( pFrame
->mbIME
&& pFrame
->mhDefIMEContext
)
4425 UINT nImeProps
= ImmGetProperty( GetKeyboardLayout( 0 ), IGP_PROPERTY
);
4427 pFrame
->mbSpezIME
= (nImeProps
& IME_PROP_SPECIAL_UI
) != 0;
4428 pFrame
->mbAtCursorIME
= (nImeProps
& IME_PROP_AT_CARET
) != 0;
4429 pFrame
->mbHandleIME
= !pFrame
->mbSpezIME
;
4432 pFrame
->CallCallback( SALEVENT_GETFOCUS
, 0 );
4436 pFrame
->CallCallback( SALEVENT_LOSEFOCUS
, 0 );
4440 ImplSalYieldMutexRelease();
4443 ImplPostMessage( hWnd
, SAL_MSG_POSTFOCUS
, 0, 0 );
4446 // -----------------------------------------------------------------------
4448 static void ImplHandleCloseMsg( HWND hWnd
)
4450 if ( ImplSalYieldMutexTryToAcquire() )
4452 WinSalFrame
* pFrame
= GetWindowPtr( hWnd
);
4455 pFrame
->CallCallback( SALEVENT_CLOSE
, 0 );
4458 ImplSalYieldMutexRelease();
4461 ImplPostMessage( hWnd
, WM_CLOSE
, 0, 0 );
4464 // -----------------------------------------------------------------------
4466 static long ImplHandleShutDownMsg( HWND hWnd
)
4468 ImplSalYieldMutexAcquireWithWait();
4470 WinSalFrame
* pFrame
= GetWindowPtr( hWnd
);
4473 nRet
= pFrame
->CallCallback( SALEVENT_SHUTDOWN
, 0 );
4475 ImplSalYieldMutexRelease();
4479 // -----------------------------------------------------------------------
4481 static void ImplHandleSettingsChangeMsg( HWND hWnd
, UINT nMsg
,
4482 WPARAM wParam
, LPARAM lParam
)
4484 USHORT nSalEvent
= SALEVENT_SETTINGSCHANGED
;
4486 if ( nMsg
== WM_DEVMODECHANGE
)
4487 nSalEvent
= SALEVENT_PRINTERCHANGED
;
4488 else if ( nMsg
== WM_DISPLAYCHANGE
)
4489 nSalEvent
= SALEVENT_DISPLAYCHANGED
;
4490 else if ( nMsg
== WM_FONTCHANGE
)
4491 nSalEvent
= SALEVENT_FONTCHANGED
;
4492 else if ( nMsg
== WM_TIMECHANGE
)
4493 nSalEvent
= SALEVENT_DATETIMECHANGED
;
4494 else if ( nMsg
== WM_WININICHANGE
)
4498 if ( aSalShlData
.mbWNT
)
4500 if ( ImplSalWICompareAscii( (const wchar_t*)lParam
, "devices" ) == 0 )
4501 nSalEvent
= SALEVENT_PRINTERCHANGED
;
4505 if ( stricmp( (const char*)lParam
, "devices" ) == 0 )
4506 nSalEvent
= SALEVENT_PRINTERCHANGED
;
4511 if ( nMsg
== WM_SETTINGCHANGE
)
4513 if ( wParam
== SPI_SETWHEELSCROLLLINES
)
4514 aSalShlData
.mnWheelScrollLines
= ImplSalGetWheelScrollLines();
4515 else if( wParam
== SPI_SETWHEELSCROLLCHARS
)
4516 aSalShlData
.mnWheelScrollChars
= ImplSalGetWheelScrollChars();
4519 if ( WM_SYSCOLORCHANGE
== nMsg
&& GetSalData()->mhDitherPal
)
4520 ImplUpdateSysColorEntries();
4522 ImplSalYieldMutexAcquireWithWait();
4524 WinSalFrame
* pFrame
= GetWindowPtr( hWnd
);
4527 if ( (nMsg
== WM_DISPLAYCHANGE
) || (nMsg
== WM_WININICHANGE
) )
4529 if ( pFrame
->mbFullScreen
)
4530 ImplSalFrameFullScreenPos( pFrame
);
4533 pFrame
->CallCallback( nSalEvent
, 0 );
4536 ImplSalYieldMutexRelease();
4539 // -----------------------------------------------------------------------
4541 static void ImplHandleUserEvent( HWND hWnd
, LPARAM lParam
)
4543 ImplSalYieldMutexAcquireWithWait();
4544 WinSalFrame
* pFrame
= GetWindowPtr( hWnd
);
4547 pFrame
->CallCallback( SALEVENT_USEREVENT
, (void*)lParam
);
4549 ImplSalYieldMutexRelease();
4552 // -----------------------------------------------------------------------
4554 static void ImplHandleForcePalette( HWND hWnd
)
4556 SalData
* pSalData
= GetSalData();
4557 HPALETTE hPal
= pSalData
->mhDitherPal
;
4560 if ( !ImplSalYieldMutexTryToAcquire() )
4562 ImplPostMessage( hWnd
, SAL_MSG_FORCEPALETTE
, 0, 0 );
4566 WinSalFrame
* pFrame
= GetWindowPtr( hWnd
);
4567 if ( pFrame
&& pFrame
->mpGraphics
)
4569 WinSalGraphics
* pGraphics
= pFrame
->mpGraphics
;
4570 if ( pGraphics
&& pGraphics
->mhDefPal
)
4572 SelectPalette( pGraphics
->mhDC
, hPal
, FALSE
);
4573 if ( RealizePalette( pGraphics
->mhDC
) )
4575 InvalidateRect( hWnd
, NULL
, FALSE
);
4576 UpdateWindow( hWnd
);
4577 pFrame
->CallCallback( SALEVENT_DISPLAYCHANGED
, 0 );
4582 ImplSalYieldMutexRelease();
4586 // -----------------------------------------------------------------------
4588 static LRESULT
ImplHandlePalette( BOOL bFrame
, HWND hWnd
, UINT nMsg
,
4589 WPARAM wParam
, LPARAM lParam
, int& rDef
)
4591 SalData
* pSalData
= GetSalData();
4592 HPALETTE hPal
= pSalData
->mhDitherPal
;
4597 if ( pSalData
->mbInPalChange
)
4600 if ( (nMsg
== WM_PALETTECHANGED
) || (nMsg
== SAL_MSG_POSTPALCHANGED
) )
4602 if ( (HWND
)wParam
== hWnd
)
4606 BOOL bReleaseMutex
= FALSE
;
4607 if ( (nMsg
== WM_QUERYNEWPALETTE
) || (nMsg
== WM_PALETTECHANGED
) )
4609 // Da Windows diese Messages auch sendet, muss hier auch die
4610 // Solar-Semaphore beruecksichtigt werden
4611 if ( ImplSalYieldMutexTryToAcquire() )
4612 bReleaseMutex
= TRUE
;
4613 else if ( nMsg
== WM_QUERYNEWPALETTE
)
4614 ImplPostMessage( hWnd
, SAL_MSG_POSTQUERYNEWPAL
, wParam
, lParam
);
4615 else /* ( nMsg == WM_PALETTECHANGED ) */
4616 ImplPostMessage( hWnd
, SAL_MSG_POSTPALCHANGED
, wParam
, lParam
);
4619 WinSalVirtualDevice
*pTempVD
;
4620 WinSalFrame
* pTempFrame
;
4621 WinSalGraphics
* pGraphics
;
4628 pSalData
->mbInPalChange
= TRUE
;
4630 // Alle Paletten in VirDevs und Frames zuruecksetzen
4631 pTempVD
= pSalData
->mpFirstVD
;
4634 pGraphics
= pTempVD
->mpGraphics
;
4635 if ( pGraphics
->mhDefPal
)
4637 SelectPalette( pGraphics
->mhDC
,
4638 pGraphics
->mhDefPal
,
4641 pTempVD
= pTempVD
->mpNext
;
4643 pTempFrame
= pSalData
->mpFirstFrame
;
4644 while ( pTempFrame
)
4646 pGraphics
= pTempFrame
->mpGraphics
;
4647 if ( pGraphics
&& pGraphics
->mhDefPal
)
4649 SelectPalette( pGraphics
->mhDC
,
4650 pGraphics
->mhDefPal
,
4653 pTempFrame
= pTempFrame
->mpNextFrame
;
4656 // Palette neu realizen
4657 WinSalFrame
* pFrame
= NULL
;
4659 pFrame
= GetWindowPtr( hWnd
);
4660 if ( pFrame
&& pFrame
->mpGraphics
)
4662 hDC
= pFrame
->mpGraphics
->mhDC
;
4667 hDC
= GetDC( hWnd
);
4670 UnrealizeObject( hPal
);
4671 hOldPal
= SelectPalette( hDC
, hPal
, TRUE
);
4672 nCols
= RealizePalette( hDC
);
4673 bUpdate
= nCols
!= 0;
4676 SelectPalette( hDC
, hOldPal
, TRUE
);
4677 ReleaseDC( hWnd
, hDC
);
4680 // Alle Paletten in VirDevs und Frames neu setzen
4681 pTempVD
= pSalData
->mpFirstVD
;
4684 pGraphics
= pTempVD
->mpGraphics
;
4685 if ( pGraphics
->mhDefPal
)
4687 SelectPalette( pGraphics
->mhDC
, hPal
, TRUE
);
4688 RealizePalette( pGraphics
->mhDC
);
4690 pTempVD
= pTempVD
->mpNext
;
4692 pTempFrame
= pSalData
->mpFirstFrame
;
4693 while ( pTempFrame
)
4695 if ( pTempFrame
!= pFrame
)
4697 pGraphics
= pTempFrame
->mpGraphics
;
4698 if ( pGraphics
&& pGraphics
->mhDefPal
)
4700 SelectPalette( pGraphics
->mhDC
, hPal
, TRUE
);
4701 if ( RealizePalette( pGraphics
->mhDC
) )
4705 pTempFrame
= pTempFrame
->mpNextFrame
;
4708 // Wenn sich Farben geaendert haben, dann die Fenster updaten
4711 pTempFrame
= pSalData
->mpFirstFrame
;
4712 while ( pTempFrame
)
4714 pGraphics
= pTempFrame
->mpGraphics
;
4715 if ( pGraphics
&& pGraphics
->mhDefPal
)
4717 InvalidateRect( pTempFrame
->mhWnd
, NULL
, FALSE
);
4718 UpdateWindow( pTempFrame
->mhWnd
);
4719 pTempFrame
->CallCallback( SALEVENT_DISPLAYCHANGED
, 0 );
4721 pTempFrame
= pTempFrame
->mpNextFrame
;
4725 pSalData
->mbInPalChange
= FALSE
;
4727 if ( bReleaseMutex
)
4728 ImplSalYieldMutexRelease();
4730 if ( nMsg
== WM_PALETTECHANGED
)
4736 // -----------------------------------------------------------------------
4738 static int ImplHandleMinMax( HWND hWnd
, LPARAM lParam
)
4742 if ( ImplSalYieldMutexTryToAcquire() )
4744 WinSalFrame
* pFrame
= GetWindowPtr( hWnd
);
4747 MINMAXINFO
* pMinMax
= (MINMAXINFO
*)lParam
;
4749 if ( pFrame
->mbFullScreen
)
4755 ImplSalCalcFullScreenSize( pFrame
, nX
, nY
, nDX
, nDY
);
4757 if ( pMinMax
->ptMaxPosition
.x
> nX
)
4758 pMinMax
->ptMaxPosition
.x
= nX
;
4759 if ( pMinMax
->ptMaxPosition
.y
> nY
)
4760 pMinMax
->ptMaxPosition
.y
= nY
;
4762 if ( pMinMax
->ptMaxSize
.x
< nDX
)
4763 pMinMax
->ptMaxSize
.x
= nDX
;
4764 if ( pMinMax
->ptMaxSize
.y
< nDY
)
4765 pMinMax
->ptMaxSize
.y
= nDY
;
4766 if ( pMinMax
->ptMaxTrackSize
.x
< nDX
)
4767 pMinMax
->ptMaxTrackSize
.x
= nDX
;
4768 if ( pMinMax
->ptMaxTrackSize
.y
< nDY
)
4769 pMinMax
->ptMaxTrackSize
.y
= nDY
;
4771 pMinMax
->ptMinTrackSize
.x
= nDX
;
4772 pMinMax
->ptMinTrackSize
.y
= nDY
;
4777 if ( pFrame
->mnMinWidth
|| pFrame
->mnMinHeight
)
4779 int nWidth
= pFrame
->mnMinWidth
;
4780 int nHeight
= pFrame
->mnMinHeight
;
4782 ImplSalAddBorder( pFrame
, nWidth
, nHeight
);
4784 if ( pMinMax
->ptMinTrackSize
.x
< nWidth
)
4785 pMinMax
->ptMinTrackSize
.x
= nWidth
;
4786 if ( pMinMax
->ptMinTrackSize
.y
< nHeight
)
4787 pMinMax
->ptMinTrackSize
.y
= nHeight
;
4790 if ( pFrame
->mnMaxWidth
|| pFrame
->mnMaxHeight
)
4792 int nWidth
= pFrame
->mnMaxWidth
;
4793 int nHeight
= pFrame
->mnMaxHeight
;
4795 ImplSalAddBorder( pFrame
, nWidth
, nHeight
);
4797 if( nWidth
> 0 && nHeight
> 0 ) // protect against int overflow due to INT_MAX initialisation
4799 if ( pMinMax
->ptMaxTrackSize
.x
> nWidth
)
4800 pMinMax
->ptMaxTrackSize
.x
= nWidth
;
4801 if ( pMinMax
->ptMaxTrackSize
.y
> nHeight
)
4802 pMinMax
->ptMaxTrackSize
.y
= nHeight
;
4807 ImplSalYieldMutexRelease();
4813 // -----------------------------------------------------------------------
4815 // retrieves the SalMenuItem pointer from a hMenu
4816 // the pointer is stored in every item, so if no position
4817 // is specified we just use the first item (ie, pos=0)
4818 // if bByPosition is FALSE then nPos denotes a menu id instead of a position
4819 static WinSalMenuItem
* ImplGetSalMenuItem( HMENU hMenu
, UINT nPos
, BOOL bByPosition
=TRUE
)
4824 memset(&mi
, 0, sizeof(mi
));
4825 mi
.cbSize
= sizeof( mi
);
4826 mi
.fMask
= MIIM_DATA
;
4827 if( !GetMenuItemInfoW( hMenu
, nPos
, bByPosition
, &mi
) )
4828 err
= GetLastError();
4830 return (WinSalMenuItem
*) mi
.dwItemData
;
4833 // returns the index of the currently selected item if any or -1
4834 static int ImplGetSelectedIndex( HMENU hMenu
)
4839 memset(&mi
, 0, sizeof(mi
));
4840 mi
.cbSize
= sizeof( mi
);
4841 mi
.fMask
= MIIM_STATE
;
4842 int n
= GetMenuItemCount( hMenu
);
4845 for(int i
=0; i
<n
; i
++ )
4847 if( !GetMenuItemInfoW( hMenu
, i
, TRUE
, &mi
) )
4848 err
= GetLastError();
4851 if( mi
.fState
& MFS_HILITE
)
4859 static int ImplMenuChar( HWND
, WPARAM wParam
, LPARAM lParam
)
4861 int nRet
= MNC_IGNORE
;
4862 HMENU hMenu
= (HMENU
) lParam
;
4864 aMnemonic
.AssignAscii("&");
4865 aMnemonic
.Append( (sal_Unicode
) LOWORD(wParam
) );
4866 aMnemonic
.ToLowerAscii(); // we only have ascii mnemonics
4868 // search the mnemonic in the current menu
4869 int nItemCount
= GetMenuItemCount( hMenu
);
4872 int idxSelected
= ImplGetSelectedIndex( hMenu
);
4873 int idx
= idxSelected
!= -1 ? idxSelected
+1 : 0; // if duplicate mnemonics cycle through menu
4874 for( int i
=0; i
< nItemCount
; i
++, idx
++ )
4876 WinSalMenuItem
* pSalMenuItem
= ImplGetSalMenuItem( hMenu
, idx
% nItemCount
);
4879 String aStr
= pSalMenuItem
->mText
;
4880 aStr
.ToLowerAscii();
4881 if( aStr
.Search( aMnemonic
) != STRING_NOTFOUND
)
4883 if( idxFound
== -1 )
4884 idxFound
= idx
% nItemCount
;
4886 break; // duplicate found
4890 nRet
= MAKELRESULT( idxFound
, MNC_EXECUTE
);
4892 // duplicate mnemonics, just select the next occurence
4893 nRet
= MAKELRESULT( idxFound
, MNC_SELECT
);
4898 static int ImplMeasureItem( HWND hWnd
, WPARAM wParam
, LPARAM lParam
)
4903 // request was sent by a menu
4905 MEASUREITEMSTRUCT
*pMI
= (LPMEASUREITEMSTRUCT
) lParam
;
4906 if( pMI
->CtlType
!= ODT_MENU
)
4909 WinSalMenuItem
*pSalMenuItem
= (WinSalMenuItem
*) pMI
->itemData
;
4913 HDC hdc
= GetDC( hWnd
);
4916 NONCLIENTMETRICS ncm
;
4917 memset( &ncm
, 0, sizeof(ncm
) );
4918 ncm
.cbSize
= sizeof( ncm
);
4919 SystemParametersInfo( SPI_GETNONCLIENTMETRICS
, 0, (PVOID
) &ncm
, 0 );
4921 // Assume every menu item can be default and printed bold
4922 //ncm.lfMenuFont.lfWeight = FW_BOLD;
4924 HFONT hfntOld
= (HFONT
) SelectObject(hdc
, (HFONT
) CreateFontIndirect( &ncm
.lfMenuFont
));
4926 // menu text and accelerator
4927 String
aStr(pSalMenuItem
->mText
.GetBuffer() );
4928 if( pSalMenuItem
->mAccelText
.Len() )
4930 aStr
.AppendAscii(" ");
4931 aStr
.Append( pSalMenuItem
->mAccelText
);
4933 GetTextExtentPoint32W( hdc
, (LPWSTR
) aStr
.GetBuffer(),
4934 aStr
.Len(), &strSize
);
4937 Size
bmpSize( 16, 16 );
4938 //if( !!pSalMenuItem->maBitmap )
4939 // bmpSize = pSalMenuItem->maBitmap.GetSizePixel();
4942 Size
checkSize( GetSystemMetrics( SM_CXMENUCHECK
), GetSystemMetrics( SM_CYMENUCHECK
) );
4944 pMI
->itemWidth
= checkSize
.Width() + 3 + bmpSize
.Width() + 3 + strSize
.cx
;
4945 pMI
->itemHeight
= Max( Max( checkSize
.Height(), bmpSize
.Height() ), strSize
.cy
);
4946 pMI
->itemHeight
+= 4;
4948 DeleteObject( SelectObject(hdc
, hfntOld
) );
4949 ReleaseDC( hWnd
, hdc
);
4955 static int ImplDrawItem(HWND
, WPARAM wParam
, LPARAM lParam
)
4961 // request was sent by a menu
4963 DRAWITEMSTRUCT
*pDI
= (LPDRAWITEMSTRUCT
) lParam
;
4964 if( pDI
->CtlType
!= ODT_MENU
)
4967 WinSalMenuItem
*pSalMenuItem
= (WinSalMenuItem
*) pDI
->itemData
;
4971 COLORREF clrPrevText
, clrPrevBkgnd
;
4974 BOOL fChecked
= (pDI
->itemState
& ODS_CHECKED
) ? TRUE
: FALSE
;
4975 BOOL fSelected
= (pDI
->itemState
& ODS_SELECTED
) ? TRUE
: FALSE
;
4976 BOOL fDisabled
= (pDI
->itemState
& (ODS_DISABLED
| ODS_GRAYED
)) ? TRUE
: FALSE
;
4978 // Set the appropriate foreground and background colors.
4979 RECT aRect
= pDI
->rcItem
;
4981 clrPrevBkgnd
= SetBkColor( pDI
->hDC
, GetSysColor( COLOR_MENU
) );
4984 clrPrevText
= SetTextColor( pDI
->hDC
, GetSysColor( COLOR_GRAYTEXT
) );
4986 clrPrevText
= SetTextColor( pDI
->hDC
, GetSysColor( fSelected
? COLOR_HIGHLIGHTTEXT
: COLOR_MENUTEXT
) );
4988 DWORD colBackground
= GetSysColor( fSelected
? COLOR_HIGHLIGHT
: COLOR_MENU
);
4990 clrPrevBkgnd
= SetBkColor( pDI
->hDC
, colBackground
);
4992 clrPrevBkgnd
= SetBkColor( pDI
->hDC
, colBackground
);
4994 hbrOld
= (HBRUSH
)SelectObject( pDI
->hDC
, CreateSolidBrush( GetBkColor( pDI
->hDC
) ) );
4997 if(!PatBlt( pDI
->hDC
, aRect
.left
, aRect
.top
, aRect
.right
-aRect
.left
, aRect
.bottom
-aRect
.top
, PATCOPY
))
4998 err
= GetLastError();
5000 int lineHeight
= aRect
.bottom
-aRect
.top
;
5005 int checkWidth
= GetSystemMetrics( SM_CXMENUCHECK
);
5006 int checkHeight
= GetSystemMetrics( SM_CYMENUCHECK
);
5012 r
.right
= checkWidth
;
5013 r
.bottom
= checkWidth
;
5014 HDC memDC
= CreateCompatibleDC( pDI
->hDC
);
5015 HBITMAP memBmp
= CreateCompatibleBitmap( pDI
->hDC
, checkWidth
, checkHeight
);
5016 HBITMAP hOldBmp
= (HBITMAP
) SelectObject( memDC
, memBmp
);
5017 DrawFrameControl( memDC
, &r
, DFC_MENU
, DFCS_MENUCHECK
);
5018 BitBlt( pDI
->hDC
, x
, y
+(lineHeight
-checkHeight
)/2, checkWidth
, checkHeight
, memDC
, 0, 0, SRCAND
);
5019 DeleteObject( SelectObject( memDC
, hOldBmp
) );
5024 //Size bmpSize = aBitmap.GetSizePixel();
5025 Size
bmpSize(16, 16);
5026 if( !!pSalMenuItem
->maBitmap
)
5028 Bitmap
aBitmap( pSalMenuItem
->maBitmap
);
5030 // set transparent pixels to background color
5032 colBackground
= RGB(255,255,255);
5033 aBitmap
.Replace( Color( COL_LIGHTMAGENTA
),
5034 Color( GetRValue(colBackground
),GetGValue(colBackground
),GetBValue(colBackground
) ), 0);
5036 WinSalBitmap
* pSalBmp
= static_cast<WinSalBitmap
*>(aBitmap
.ImplGetImpBitmap()->ImplGetSalBitmap());
5037 HGLOBAL hDrawDIB
= pSalBmp
->ImplGethDIB();
5041 PBITMAPINFO pBI
= (PBITMAPINFO
) GlobalLock( hDrawDIB
);
5042 PBITMAPINFOHEADER pBIH
= (PBITMAPINFOHEADER
) pBI
;
5043 PBYTE pBits
= (PBYTE
) pBI
+ *(DWORD
*) pBI
+
5044 pSalBmp
->ImplGetDIBColorCount( hDrawDIB
) * sizeof( RGBQUAD
);
5046 HBITMAP hBmp
= CreateDIBitmap( pDI
->hDC
, pBIH
, CBM_INIT
, pBits
, pBI
, DIB_RGB_COLORS
);
5047 GlobalUnlock( hDrawDIB
);
5049 HBRUSH hbrIcon
= CreateSolidBrush( GetSysColor( COLOR_GRAYTEXT
) );
5050 DrawStateW( pDI
->hDC
, (HBRUSH
)hbrIcon
, (DRAWSTATEPROC
)NULL
, (LPARAM
)hBmp
, (WPARAM
)0,
5051 x
, y
+(lineHeight
-bmpSize
.Height())/2, bmpSize
.Width(), bmpSize
.Height(),
5052 DST_BITMAP
| (fDisabled
? (fSelected
? DSS_MONO
: DSS_DISABLED
) : DSS_NORMAL
) );
5054 DeleteObject( hbrIcon
);
5055 DeleteObject( hBmp
);
5059 x
+= bmpSize
.Width() + 3;
5062 NONCLIENTMETRICS ncm
;
5063 memset( &ncm
, 0, sizeof(ncm
) );
5064 ncm
.cbSize
= sizeof( ncm
);
5065 SystemParametersInfo( SPI_GETNONCLIENTMETRICS
, 0, (PVOID
) &ncm
, 0 );
5067 // Print default menu entry with bold font
5068 //if ( pDI->itemState & ODS_DEFAULT )
5069 // ncm.lfMenuFont.lfWeight = FW_BOLD;
5071 hfntOld
= (HFONT
) SelectObject(pDI
->hDC
, (HFONT
) CreateFontIndirect( &ncm
.lfMenuFont
));
5074 String
aStr( pSalMenuItem
->mText
.GetBuffer() );
5075 GetTextExtentPoint32W( pDI
->hDC
, (LPWSTR
) aStr
.GetBuffer(),
5076 aStr
.Len(), &strSize
);
5078 if(!DrawStateW( pDI
->hDC
, (HBRUSH
)NULL
, (DRAWSTATEPROC
)NULL
,
5079 (LPARAM
)(LPWSTR
) aStr
.GetBuffer(),
5080 (WPARAM
)0, aRect
.left
, aRect
.top
+ (lineHeight
- strSize
.cy
)/2, 0, 0,
5081 DST_PREFIXTEXT
| (fDisabled
&& !fSelected
? DSS_DISABLED
: DSS_NORMAL
) ) )
5082 err
= GetLastError();
5084 if( pSalMenuItem
->mAccelText
.Len() )
5087 aStr
= pSalMenuItem
->mAccelText
;
5088 GetTextExtentPoint32W( pDI
->hDC
, (LPWSTR
) aStr
.GetBuffer(),
5089 aStr
.Len(), &strSizeA
);
5091 GetTextMetrics( pDI
->hDC
, &tm
);
5093 // position the accelerator string to the right but leave space for the
5094 // (potential) submenu arrow (tm.tmMaxCharWidth)
5095 if(!DrawStateW( pDI
->hDC
, (HBRUSH
)NULL
, (DRAWSTATEPROC
)NULL
,
5096 (LPARAM
)(LPWSTR
) aStr
.GetBuffer(),
5097 (WPARAM
)0, aRect
.right
-strSizeA
.cx
-tm
.tmMaxCharWidth
, aRect
.top
+ (lineHeight
- strSizeA
.cy
)/2, 0, 0,
5098 DST_TEXT
| (fDisabled
&& !fSelected
? DSS_DISABLED
: DSS_NORMAL
) ) )
5099 err
= GetLastError();
5102 // Restore the original font and colors.
5103 DeleteObject( SelectObject( pDI
->hDC
, hbrOld
) );
5104 DeleteObject( SelectObject( pDI
->hDC
, hfntOld
) );
5105 SetTextColor(pDI
->hDC
, clrPrevText
);
5106 SetBkColor(pDI
->hDC
, clrPrevBkgnd
);
5111 static int ImplHandleMenuActivate( HWND hWnd
, WPARAM wParam
, LPARAM
)
5114 WinSalFrame
* pFrame
= GetWindowPtr( hWnd
);
5118 HMENU hMenu
= (HMENU
) wParam
;
5119 // WORD nPos = LOWORD (lParam);
5120 // BOOL bWindowMenu = (BOOL) HIWORD(lParam);
5122 // Send activate and deactivate together, so we have not keep track of opened menues
5123 // this will be enough to have the menues updated correctly
5124 SalMenuEvent aMenuEvt
;
5125 WinSalMenuItem
*pSalMenuItem
= ImplGetSalMenuItem( hMenu
, 0 );
5127 aMenuEvt
.mpMenu
= pSalMenuItem
->mpMenu
;
5129 aMenuEvt
.mpMenu
= NULL
;
5131 long nRet
= pFrame
->CallCallback( SALEVENT_MENUACTIVATE
, &aMenuEvt
);
5133 nRet
= pFrame
->CallCallback( SALEVENT_MENUDEACTIVATE
, &aMenuEvt
);
5135 pFrame
->mLastActivatedhMenu
= hMenu
;
5140 static int ImplHandleMenuSelect( HWND hWnd
, WPARAM wParam
, LPARAM lParam
)
5143 WinSalFrame
* pFrame
= GetWindowPtr( hWnd
);
5147 WORD nId
= LOWORD(wParam
); // menu item or submenu index
5148 WORD nFlags
= HIWORD(wParam
);
5149 HMENU hMenu
= (HMENU
) lParam
;
5151 // check if we have to process the message
5152 if( !GetSalData()->IsKnownMenuHandle( hMenu
) )
5155 BOOL bByPosition
= FALSE
;
5156 if( nFlags
& MF_POPUP
)
5160 if ( hMenu
&& !pFrame
->mLastActivatedhMenu
)
5162 // we never activated a menu (ie, no WM_INITMENUPOPUP has occured yet)
5163 // which means this must be the menubar -> send activation/deactivation
5164 SalMenuEvent aMenuEvt
;
5165 WinSalMenuItem
*pSalMenuItem
= ImplGetSalMenuItem( hMenu
, nId
, bByPosition
);
5167 aMenuEvt
.mpMenu
= pSalMenuItem
->mpMenu
;
5169 aMenuEvt
.mpMenu
= NULL
;
5171 nRet
= pFrame
->CallCallback( SALEVENT_MENUACTIVATE
, &aMenuEvt
);
5173 nRet
= pFrame
->CallCallback( SALEVENT_MENUDEACTIVATE
, &aMenuEvt
);
5175 pFrame
->mLastActivatedhMenu
= hMenu
;
5178 if( !hMenu
&& nFlags
== 0xFFFF )
5180 // all menus are closed, reset activation logic
5181 pFrame
->mLastActivatedhMenu
= NULL
;
5186 // hMenu must be saved, as it is not passed in WM_COMMAND which always occurs after a selection
5187 // if a menu is closed due to a command selection then hMenu is NULL, but WM_COMMAND comes later
5188 // so we must not overwrite it in this case
5189 pFrame
->mSelectedhMenu
= hMenu
;
5191 // send highlight event
5192 if( nFlags
& MF_POPUP
)
5195 // wParam now carries an index instead of an id -> retrieve id
5197 memset(&mi
, 0, sizeof(mi
));
5198 mi
.cbSize
= sizeof( mi
);
5200 if( GetMenuItemInfoW( hMenu
, LOWORD(wParam
), TRUE
, &mi
) )
5201 nId
= sal::static_int_cast
<WORD
>(mi
.wID
);
5204 SalMenuEvent aMenuEvt
;
5205 aMenuEvt
.mnId
= nId
;
5206 WinSalMenuItem
*pSalMenuItem
= ImplGetSalMenuItem( hMenu
, nId
, FALSE
);
5208 aMenuEvt
.mpMenu
= pSalMenuItem
->mpMenu
;
5210 aMenuEvt
.mpMenu
= NULL
;
5212 nRet
= pFrame
->CallCallback( SALEVENT_MENUHIGHLIGHT
, &aMenuEvt
);
5218 static int ImplHandleCommand( HWND hWnd
, WPARAM wParam
, LPARAM
)
5220 WinSalFrame
* pFrame
= GetWindowPtr( hWnd
);
5225 if( !HIWORD(wParam
) )
5228 WORD nId
= LOWORD(wParam
);
5229 if( nId
) // zero for separators
5231 SalMenuEvent aMenuEvt
;
5232 aMenuEvt
.mnId
= nId
;
5233 WinSalMenuItem
*pSalMenuItem
= ImplGetSalMenuItem( pFrame
->mSelectedhMenu
, nId
, FALSE
);
5235 aMenuEvt
.mpMenu
= pSalMenuItem
->mpMenu
;
5237 aMenuEvt
.mpMenu
= NULL
;
5239 nRet
= pFrame
->CallCallback( SALEVENT_MENUCOMMAND
, &aMenuEvt
);
5245 static int ImplHandleSysCommand( HWND hWnd
, WPARAM wParam
, LPARAM lParam
)
5247 WinSalFrame
* pFrame
= GetWindowPtr( hWnd
);
5251 WPARAM nCommand
= wParam
& 0xFFF0;
5253 if ( pFrame
->mbFullScreen
)
5255 WIN_BOOL bMaximize
= IsZoomed( pFrame
->mhWnd
);
5256 WIN_BOOL bMinimize
= IsIconic( pFrame
->mhWnd
);
5257 if ( (nCommand
== SC_SIZE
) ||
5258 (!bMinimize
&& (nCommand
== SC_MOVE
)) ||
5259 (!bMaximize
&& (nCommand
== SC_MAXIMIZE
)) ||
5260 (bMaximize
&& (nCommand
== SC_RESTORE
)) )
5267 if ( nCommand
== SC_KEYMENU
)
5269 // do not process SC_KEYMENU if we have a native menu
5270 // Windows should handle this
5271 if( GetMenu( hWnd
) )
5274 // Hier verarbeiten wir nur KeyMenu-Events fuer Alt um
5275 // den MenuBar zu aktivieren, oder wenn ein SysChild-Fenster
5276 // den Focus hat, da diese Alt+Tasten-Kombinationen nur
5277 // ueber diesen Event verarbeitet werden
5278 if ( !LOWORD( lParam
) )
5280 // Nur ausloesen, wenn keine weitere Taste gedrueckt ist. Im
5281 // Gegensatz zur Doku wird in der X-Koordinaate der CharCode
5282 // geliefert, der zusaetzlich gedrueckt ist
5283 // Also 32 fuer Space, 99 fuer c, 100 fuer d, ...
5284 // Da dies nicht dokumentiert ist, fragen wir vorsichtshalber
5285 // auch den Status der Space-Taste ab
5286 if ( GetKeyState( VK_SPACE
) & 0x8000 )
5289 // Damit nicht bei Alt+Maustaste auch der MenuBar aktiviert wird
5290 if ( (GetKeyState( VK_LBUTTON
) & 0x8000) ||
5291 (GetKeyState( VK_RBUTTON
) & 0x8000) ||
5292 (GetKeyState( VK_MBUTTON
) & 0x8000) ||
5293 (GetKeyState( VK_SHIFT
) & 0x8000) )
5296 SalKeyEvent aKeyEvt
;
5297 aKeyEvt
.mnTime
= GetMessageTime();
5298 aKeyEvt
.mnCode
= KEY_MENU
;
5299 aKeyEvt
.mnCharCode
= 0;
5300 aKeyEvt
.mnRepeat
= 0;
5301 long nRet
= pFrame
->CallCallback( SALEVENT_KEYINPUT
, &aKeyEvt
);
5302 pFrame
->CallCallback( SALEVENT_KEYUP
, &aKeyEvt
);
5307 // Testen, ob ein SysChild den Focus hat
5308 HWND hFocusWnd
= ::GetFocus();
5309 if ( hFocusWnd
&& ImplFindSalObject( hFocusWnd
) )
5311 char cKeyCode
= (char)(unsigned char)LOWORD( lParam
);
5313 if ( (cKeyCode
>= 65) && (cKeyCode
<= 90) )
5315 // Wir nehmen nur 0-9 und A-Z, alle anderen Tasten muessen durch
5316 // den Hook vom SalObj verarbeitet werden
5317 if ( ((cKeyCode
>= 48) && (cKeyCode
<= 57)) ||
5318 ((cKeyCode
>= 97) && (cKeyCode
<= 122)) )
5320 USHORT nModCode
= 0;
5321 if ( GetKeyState( VK_SHIFT
) & 0x8000 )
5322 nModCode
|= KEY_SHIFT
;
5323 if ( GetKeyState( VK_CONTROL
) & 0x8000 )
5324 nModCode
|= KEY_MOD1
;
5325 nModCode
|= KEY_MOD2
;
5327 SalKeyEvent aKeyEvt
;
5328 aKeyEvt
.mnTime
= GetMessageTime();
5329 if ( (cKeyCode
>= 48) && (cKeyCode
<= 57) )
5330 aKeyEvt
.mnCode
= KEY_0
+(cKeyCode
-48);
5332 aKeyEvt
.mnCode
= KEY_A
+(cKeyCode
-97);
5333 aKeyEvt
.mnCode
|= nModCode
;
5334 aKeyEvt
.mnCharCode
= cKeyCode
;
5335 aKeyEvt
.mnRepeat
= 0;
5336 long nRet
= pFrame
->CallCallback( SALEVENT_KEYINPUT
, &aKeyEvt
);
5337 pFrame
->CallCallback( SALEVENT_KEYUP
, &aKeyEvt
);
5347 // -----------------------------------------------------------------------
5349 static void ImplHandleInputLangChange( HWND hWnd
, WPARAM
, LPARAM lParam
)
5351 ImplSalYieldMutexAcquireWithWait();
5353 // Feststellen, ob wir IME unterstuetzen
5354 WinSalFrame
* pFrame
= GetWindowPtr( hWnd
);
5355 if ( pFrame
&& pFrame
->mbIME
&& pFrame
->mhDefIMEContext
)
5357 HKL hKL
= (HKL
)lParam
;
5358 UINT nImeProps
= ImmGetProperty( hKL
, IGP_PROPERTY
);
5360 pFrame
->mbSpezIME
= (nImeProps
& IME_PROP_SPECIAL_UI
) != 0;
5361 pFrame
->mbAtCursorIME
= (nImeProps
& IME_PROP_AT_CARET
) != 0;
5362 pFrame
->mbHandleIME
= !pFrame
->mbSpezIME
;
5365 // trigger input language and codepage update
5366 UINT nLang
= pFrame
->mnInputLang
;
5367 ImplUpdateInputLang( pFrame
);
5370 if( nLang
!= pFrame
->mnInputLang
)
5371 pFrame
->CallCallback( SALEVENT_INPUTLANGUAGECHANGE
, 0 );
5373 ImplSalYieldMutexRelease();
5376 // -----------------------------------------------------------------------
5378 static void ImplUpdateIMECursorPos( WinSalFrame
* pFrame
, HIMC hIMC
)
5380 COMPOSITIONFORM aForm
;
5381 memset( &aForm
, 0, sizeof( aForm
) );
5383 // Cursor-Position ermitteln und aus der die Default-Position fuer
5384 // das Composition-Fenster berechnen
5385 SalExtTextInputPosEvent aPosEvt
;
5386 pFrame
->CallCallback( SALEVENT_EXTTEXTINPUTPOS
, (void*)&aPosEvt
);
5387 if ( (aPosEvt
.mnX
== -1) && (aPosEvt
.mnY
== -1) )
5388 aForm
.dwStyle
|= CFS_DEFAULT
;
5391 aForm
.dwStyle
|= CFS_POINT
;
5392 aForm
.ptCurrentPos
.x
= aPosEvt
.mnX
;
5393 aForm
.ptCurrentPos
.y
= aPosEvt
.mnY
;
5395 ImmSetCompositionWindow( hIMC
, &aForm
);
5397 // Because not all IME's use this values, we create
5398 // a Windows caret to force the Position from the IME
5399 if ( GetFocus() == pFrame
->mhWnd
)
5401 CreateCaret( pFrame
->mhWnd
, 0,
5402 aPosEvt
.mnWidth
, aPosEvt
.mnHeight
);
5403 SetCaretPos( aPosEvt
.mnX
, aPosEvt
.mnY
);
5407 // -----------------------------------------------------------------------
5409 static BOOL
ImplHandleIMEStartComposition( HWND hWnd
)
5413 ImplSalYieldMutexAcquireWithWait();
5415 WinSalFrame
* pFrame
= GetWindowPtr( hWnd
);
5418 HIMC hIMC
= ImmGetContext( hWnd
);
5421 ImplUpdateIMECursorPos( pFrame
, hIMC
);
5422 ImmReleaseContext( hWnd
, hIMC
);
5425 if ( pFrame
->mbHandleIME
)
5427 if ( pFrame
->mbAtCursorIME
)
5432 ImplSalYieldMutexRelease();
5437 // -----------------------------------------------------------------------
5439 static BOOL
ImplHandleIMECompositionInput( WinSalFrame
* pFrame
,
5440 HIMC hIMC
, LPARAM lParam
)
5445 SalExtTextInputEvent aEvt
;
5446 aEvt
.mnTime
= GetMessageTime();
5447 aEvt
.mpTextAttr
= NULL
;
5448 aEvt
.mnCursorPos
= 0;
5449 aEvt
.mnDeltaStart
= 0;
5450 aEvt
.mbOnlyCursor
= FALSE
;
5451 aEvt
.mnCursorFlags
= 0;
5453 // If we get a result string, then we handle this input
5454 if ( lParam
& GCS_RESULTSTR
)
5458 LONG nTextLen
= ImmGetCompositionStringW( hIMC
, GCS_RESULTSTR
, 0, 0 ) / sizeof( WCHAR
);
5459 if ( nTextLen
>= 0 )
5461 WCHAR
* pTextBuf
= new WCHAR
[nTextLen
];
5462 ImmGetCompositionStringW( hIMC
, GCS_RESULTSTR
, pTextBuf
, nTextLen
*sizeof( WCHAR
) );
5463 aEvt
.maText
= XubString( reinterpret_cast<const xub_Unicode
*>(pTextBuf
), (xub_StrLen
)nTextLen
);
5467 aEvt
.mnCursorPos
= aEvt
.maText
.Len();
5468 pFrame
->CallCallback( SALEVENT_EXTTEXTINPUT
, (void*)&aEvt
);
5469 pFrame
->CallCallback( SALEVENT_ENDEXTTEXTINPUT
, (void*)NULL
);
5470 ImplUpdateIMECursorPos( pFrame
, hIMC
);
5473 // If the IME doesn't support OnSpot input, then there is nothing to do
5474 if ( !pFrame
->mbAtCursorIME
)
5477 // If we get new Composition data, then we handle this new input
5478 if ( (lParam
& (GCS_COMPSTR
| GCS_COMPATTR
)) ||
5479 ((lParam
& GCS_CURSORPOS
) && !(lParam
& GCS_RESULTSTR
)) )
5483 USHORT
* pSalAttrAry
= NULL
;
5484 LONG nTextLen
= ImmGetCompositionStringW( hIMC
, GCS_COMPSTR
, 0, 0 ) / sizeof( WCHAR
);
5487 WCHAR
* pTextBuf
= new WCHAR
[nTextLen
];
5488 ImmGetCompositionStringW( hIMC
, GCS_COMPSTR
, pTextBuf
, nTextLen
*sizeof( WCHAR
) );
5489 aEvt
.maText
= XubString( reinterpret_cast<const xub_Unicode
*>(pTextBuf
), (xub_StrLen
)nTextLen
);
5492 WIN_BYTE
* pAttrBuf
= NULL
;
5493 LONG nAttrLen
= ImmGetCompositionStringW( hIMC
, GCS_COMPATTR
, 0, 0 );
5496 pAttrBuf
= new WIN_BYTE
[nAttrLen
];
5497 ImmGetCompositionStringW( hIMC
, GCS_COMPATTR
, pAttrBuf
, nAttrLen
);
5502 xub_StrLen nTextLen
= aEvt
.maText
.Len();
5503 pSalAttrAry
= new USHORT
[nTextLen
];
5504 memset( pSalAttrAry
, 0, nTextLen
*sizeof( USHORT
) );
5505 for ( xub_StrLen i
= 0; (i
< nTextLen
) && (i
< nAttrLen
); i
++ )
5507 WIN_BYTE nWinAttr
= pAttrBuf
[i
];
5509 if ( nWinAttr
== ATTR_TARGET_CONVERTED
)
5511 nSalAttr
= SAL_EXTTEXTINPUT_ATTR_BOLDUNDERLINE
;
5512 aEvt
.mnCursorFlags
|= SAL_EXTTEXTINPUT_CURSOR_INVISIBLE
;
5514 else if ( nWinAttr
== ATTR_CONVERTED
)
5515 nSalAttr
= SAL_EXTTEXTINPUT_ATTR_DASHDOTUNDERLINE
;
5516 else if ( nWinAttr
== ATTR_TARGET_NOTCONVERTED
)
5517 nSalAttr
= SAL_EXTTEXTINPUT_ATTR_HIGHLIGHT
;
5518 else if ( nWinAttr
== ATTR_INPUT_ERROR
)
5519 nSalAttr
= SAL_EXTTEXTINPUT_ATTR_REDTEXT
| SAL_EXTTEXTINPUT_ATTR_DOTTEDUNDERLINE
;
5520 else /* ( nWinAttr == ATTR_INPUT ) */
5521 nSalAttr
= SAL_EXTTEXTINPUT_ATTR_DOTTEDUNDERLINE
;
5522 pSalAttrAry
[i
] = nSalAttr
;
5525 aEvt
.mpTextAttr
= pSalAttrAry
;
5530 // Only when we get new composition data, we must send this event
5531 if ( (nTextLen
> 0) || !(lParam
& GCS_RESULTSTR
) )
5533 // End the mode, if the last character is deleted
5534 if ( !nTextLen
&& !pFrame
->mbCandidateMode
)
5536 pFrame
->CallCallback( SALEVENT_EXTTEXTINPUT
, (void*)&aEvt
);
5537 pFrame
->CallCallback( SALEVENT_ENDEXTTEXTINPUT
, (void*)NULL
);
5541 // Because Cursor-Position and DeltaStart never updated
5542 // from the korean input engine, we must handle this here
5543 if ( lParam
& CS_INSERTCHAR
)
5545 aEvt
.mnCursorPos
= nTextLen
;
5546 if ( aEvt
.mnCursorPos
&& (lParam
& CS_NOMOVECARET
) )
5550 aEvt
.mnCursorPos
= LOWORD( ImmGetCompositionStringW( hIMC
, GCS_CURSORPOS
, 0, 0 ) );
5552 if ( pFrame
->mbCandidateMode
)
5553 aEvt
.mnCursorFlags
|= SAL_EXTTEXTINPUT_CURSOR_INVISIBLE
;
5554 if ( lParam
& CS_NOMOVECARET
)
5555 aEvt
.mnCursorFlags
|= SAL_EXTTEXTINPUT_CURSOR_OVERWRITE
;
5557 pFrame
->CallCallback( SALEVENT_EXTTEXTINPUT
, (void*)&aEvt
);
5559 ImplUpdateIMECursorPos( pFrame
, hIMC
);
5569 // -----------------------------------------------------------------------
5571 static BOOL
ImplHandleIMEComposition( HWND hWnd
, LPARAM lParam
)
5574 ImplSalYieldMutexAcquireWithWait();
5576 WinSalFrame
* pFrame
= GetWindowPtr( hWnd
);
5577 if ( pFrame
&& (!lParam
|| (lParam
& GCS_RESULTSTR
)) )
5579 // Wir restaurieren den Background-Modus bei jeder Texteingabe,
5580 // da einige Tools wie RichWin uns diesen hin- und wieder umsetzen
5581 if ( pFrame
->mpGraphics
&&
5582 pFrame
->mpGraphics
->mhDC
)
5583 SetBkMode( pFrame
->mpGraphics
->mhDC
, TRANSPARENT
);
5586 if ( pFrame
&& pFrame
->mbHandleIME
)
5590 SalExtTextInputEvent aEvt
;
5591 aEvt
.mnTime
= GetMessageTime();
5592 aEvt
.mpTextAttr
= NULL
;
5593 aEvt
.mnCursorPos
= 0;
5594 aEvt
.mnDeltaStart
= 0;
5595 aEvt
.mbOnlyCursor
= FALSE
;
5596 aEvt
.mnCursorFlags
= 0;
5597 pFrame
->CallCallback( SALEVENT_EXTTEXTINPUT
, (void*)&aEvt
);
5598 pFrame
->CallCallback( SALEVENT_ENDEXTTEXTINPUT
, (void*)NULL
);
5600 else if ( lParam
& (GCS_RESULTSTR
| GCS_COMPSTR
| GCS_COMPATTR
| GCS_CURSORPOS
) )
5602 HIMC hIMC
= ImmGetContext( hWnd
);
5605 if ( ImplHandleIMECompositionInput( pFrame
, hIMC
, lParam
) )
5608 ImmReleaseContext( hWnd
, hIMC
);
5613 ImplSalYieldMutexRelease();
5617 // -----------------------------------------------------------------------
5619 static BOOL
ImplHandleIMEEndComposition( HWND hWnd
)
5623 ImplSalYieldMutexAcquireWithWait();
5625 WinSalFrame
* pFrame
= GetWindowPtr( hWnd
);
5626 if ( pFrame
&& pFrame
->mbHandleIME
)
5628 if ( pFrame
->mbAtCursorIME
)
5632 ImplSalYieldMutexRelease();
5637 // -----------------------------------------------------------------------
5639 static boolean
ImplHandleAppCommand( HWND hWnd
, LPARAM lParam
)
5641 sal_Int16 nCommand
= 0;
5642 switch( GET_APPCOMMAND_LPARAM(lParam
) )
5644 case APPCOMMAND_MEDIA_CHANNEL_DOWN
: nCommand
= MEDIA_COMMAND_CHANNEL_DOWN
; break;
5645 case APPCOMMAND_MEDIA_CHANNEL_UP
: nCommand
= MEDIA_COMMAND_CHANNEL_UP
; break;
5646 case APPCOMMAND_MEDIA_NEXTTRACK
: nCommand
= MEDIA_COMMAND_NEXTTRACK
; break;
5647 case APPCOMMAND_MEDIA_PAUSE
: nCommand
= MEDIA_COMMAND_PAUSE
; break;
5648 case APPCOMMAND_MEDIA_PLAY
: nCommand
= MEDIA_COMMAND_PLAY
; break;
5649 case APPCOMMAND_MEDIA_PLAY_PAUSE
: nCommand
= MEDIA_COMMAND_PLAY_PAUSE
; break;
5650 case APPCOMMAND_MEDIA_PREVIOUSTRACK
: nCommand
= MEDIA_COMMAND_PREVIOUSTRACK
; break;
5651 case APPCOMMAND_MEDIA_RECORD
: nCommand
= MEDIA_COMMAND_RECORD
; break;
5652 case APPCOMMAND_MEDIA_REWIND
: nCommand
= MEDIA_COMMAND_REWIND
; break;
5653 case APPCOMMAND_MEDIA_STOP
: nCommand
= MEDIA_COMMAND_STOP
; break;
5654 case APPCOMMAND_MIC_ON_OFF_TOGGLE
: nCommand
= MEDIA_COMMAND_MIC_ON_OFF_TOGGLE
; break;
5655 case APPCOMMAND_MICROPHONE_VOLUME_DOWN
: nCommand
= MEDIA_COMMAND_MICROPHONE_VOLUME_DOWN
; break;
5656 case APPCOMMAND_MICROPHONE_VOLUME_MUTE
: nCommand
= MEDIA_COMMAND_MICROPHONE_VOLUME_MUTE
; break;
5657 case APPCOMMAND_MICROPHONE_VOLUME_UP
: nCommand
= MEDIA_COMMAND_MICROPHONE_VOLUME_UP
; break;
5658 case APPCOMMAND_VOLUME_DOWN
: nCommand
= MEDIA_COMMAND_VOLUME_DOWN
; break;
5659 case APPCOMMAND_VOLUME_MUTE
: nCommand
= MEDIA_COMMAND_VOLUME_MUTE
; break;
5660 case APPCOMMAND_VOLUME_UP
: nCommand
= MEDIA_COMMAND_VOLUME_UP
; break;
5666 WinSalFrame
* pFrame
= GetWindowPtr( hWnd
);
5667 Window
*pWindow
= pFrame
? pFrame
->GetWindow() : NULL
;
5672 CommandEvent
aCEvt( aPoint
, COMMAND_MEDIA
, FALSE
, &nCommand
);
5673 NotifyEvent
aNCmdEvt( EVENT_COMMAND
, pWindow
, &aCEvt
);
5675 if ( !ImplCallPreNotify( aNCmdEvt
) )
5677 pWindow
->Command( aCEvt
);
5686 static void ImplHandleIMENotify( HWND hWnd
, WPARAM wParam
)
5688 if ( wParam
== (WPARAM
)IMN_OPENCANDIDATE
)
5690 ImplSalYieldMutexAcquireWithWait();
5692 WinSalFrame
* pFrame
= GetWindowPtr( hWnd
);
5693 if ( pFrame
&& pFrame
->mbHandleIME
&&
5694 pFrame
->mbAtCursorIME
)
5696 // Wir wollen den Cursor hiden
5697 pFrame
->mbCandidateMode
= TRUE
;
5698 ImplHandleIMEComposition( hWnd
, GCS_CURSORPOS
);
5700 HWND hWnd
= pFrame
->mhWnd
;
5701 HIMC hIMC
= ImmGetContext( hWnd
);
5704 LONG nBufLen
= ImmGetCompositionStringW( hIMC
, GCS_COMPSTR
, 0, 0 );
5707 SalExtTextInputPosEvent aPosEvt
;
5708 pFrame
->CallCallback( SALEVENT_EXTTEXTINPUTPOS
, (void*)&aPosEvt
);
5711 CANDIDATEFORM aForm
;
5713 aForm
.dwStyle
= CFS_EXCLUDE
;
5714 aForm
.ptCurrentPos
.x
= aPosEvt
.mnX
;
5715 aForm
.ptCurrentPos
.y
= aPosEvt
.mnY
+1;
5716 aForm
.rcArea
.left
= aPosEvt
.mnX
;
5717 aForm
.rcArea
.top
= aPosEvt
.mnY
;
5718 aForm
.rcArea
.right
= aForm
.rcArea
.left
+aPosEvt
.mnExtWidth
+1;
5719 aForm
.rcArea
.bottom
= aForm
.rcArea
.top
+aPosEvt
.mnHeight
+1;
5720 ImmSetCandidateWindow( hIMC
, &aForm
);
5723 ImmReleaseContext( hWnd
, hIMC
);
5727 ImplSalYieldMutexRelease();
5729 else if ( wParam
== (WPARAM
)IMN_CLOSECANDIDATE
)
5731 ImplSalYieldMutexAcquireWithWait();
5732 WinSalFrame
* pFrame
= GetWindowPtr( hWnd
);
5734 pFrame
->mbCandidateMode
= FALSE
;
5735 ImplSalYieldMutexRelease();
5739 // -----------------------------------------------------------------------
5740 #if WINVER >= 0x0500
5742 static LRESULT
ImplHandleIMEReconvertString( HWND hWnd
, LPARAM lParam
)
5744 WinSalFrame
* pFrame
= GetWindowPtr( hWnd
);
5745 LPRECONVERTSTRING pReconvertString
= (LPRECONVERTSTRING
) lParam
;
5747 SalSurroundingTextRequestEvent aEvt
;
5748 aEvt
.maText
= UniString();
5749 aEvt
.mnStart
= aEvt
.mnEnd
= 0;
5751 UINT nImeProps
= ImmGetProperty( GetKeyboardLayout( 0 ), IGP_SETCOMPSTR
);
5752 if( (nImeProps
& SCS_CAP_SETRECONVERTSTRING
) == 0 )
5754 // This IME does not support reconversion.
5758 if( !pReconvertString
)
5760 // The first call for reconversion.
5761 pFrame
->CallCallback( SALEVENT_STARTRECONVERSION
, (void*)NULL
);
5763 // Retrieve the surrounding text from the focused control.
5764 pFrame
->CallCallback( SALEVENT_SURROUNDINGTEXTREQUEST
, (void*)&aEvt
);
5766 if( aEvt
.maText
.Len() == 0 )
5771 nRet
= sizeof(RECONVERTSTRING
) + (aEvt
.maText
.Len() + 1) * sizeof(WCHAR
);
5775 // The second call for reconversion.
5777 // Retrieve the surrounding text from the focused control.
5778 pFrame
->CallCallback( SALEVENT_SURROUNDINGTEXTREQUEST
, (void*)&aEvt
);
5779 nRet
= sizeof(RECONVERTSTRING
) + (aEvt
.maText
.Len() + 1) * sizeof(WCHAR
);
5781 pReconvertString
->dwStrOffset
= sizeof(RECONVERTSTRING
);
5782 pReconvertString
->dwStrLen
= aEvt
.maText
.Len();
5783 pReconvertString
->dwCompStrOffset
= aEvt
.mnStart
* sizeof(WCHAR
);
5784 pReconvertString
->dwCompStrLen
= aEvt
.mnEnd
- aEvt
.mnStart
;
5785 pReconvertString
->dwTargetStrOffset
= pReconvertString
->dwCompStrOffset
;
5786 pReconvertString
->dwTargetStrLen
= pReconvertString
->dwCompStrLen
;
5788 memcpy( (LPWSTR
)(pReconvertString
+ 1), aEvt
.maText
.GetBuffer(), (aEvt
.maText
.Len() + 1) * sizeof(WCHAR
) );
5791 // just return the required size of buffer to reconvert.
5795 // -----------------------------------------------------------------------
5797 static LRESULT
ImplHandleIMEConfirmReconvertString( HWND hWnd
, LPARAM lParam
)
5799 WinSalFrame
* pFrame
= GetWindowPtr( hWnd
);
5800 LPRECONVERTSTRING pReconvertString
= (LPRECONVERTSTRING
) lParam
;
5801 SalSurroundingTextRequestEvent aEvt
;
5802 aEvt
.maText
= UniString();
5803 aEvt
.mnStart
= aEvt
.mnEnd
= 0;
5805 pFrame
->CallCallback( SALEVENT_SURROUNDINGTEXTREQUEST
, (void*)&aEvt
);
5807 ULONG nTmpStart
= pReconvertString
->dwCompStrOffset
/ sizeof(WCHAR
);
5808 ULONG nTmpEnd
= nTmpStart
+ pReconvertString
->dwCompStrLen
;
5810 if( nTmpStart
!= aEvt
.mnStart
|| nTmpEnd
!= aEvt
.mnEnd
)
5812 SalSurroundingTextSelectionChangeEvent aSelEvt
;
5813 aSelEvt
.mnStart
= nTmpStart
;
5814 aSelEvt
.mnEnd
= nTmpEnd
;
5816 pFrame
->CallCallback( SALEVENT_SURROUNDINGTEXTSELECTIONCHANGE
, (void*)&aSelEvt
);
5822 #endif // WINVER >= 0x0500
5824 // -----------------------------------------------------------------------
5826 void SalTestMouseLeave()
5828 SalData
* pSalData
= GetSalData();
5830 if ( pSalData
->mhWantLeaveMsg
&& !::GetCapture() )
5833 GetCursorPos( &aPt
);
5834 if ( pSalData
->mhWantLeaveMsg
!= WindowFromPoint( aPt
) )
5835 ImplSendMessage( pSalData
->mhWantLeaveMsg
, SAL_MSG_MOUSELEAVE
, 0, MAKELPARAM( aPt
.x
, aPt
.y
) );
5839 // -----------------------------------------------------------------------
5841 static int ImplSalWheelMousePos( HWND hWnd
, UINT nMsg
, WPARAM wParam
, LPARAM lParam
,
5846 aScreenPt
.x
= (short)LOWORD( lParam
);
5847 aScreenPt
.y
= (short)HIWORD( lParam
);
5848 // Child-Fenster suchen, welches an der entsprechenden
5851 HWND hWheelWnd
= hWnd
;
5854 hChildWnd
= hWheelWnd
;
5856 ScreenToClient( hChildWnd
, &aPt
);
5857 hWheelWnd
= ChildWindowFromPointEx( hChildWnd
, aPt
, CWP_SKIPINVISIBLE
| CWP_SKIPTRANSPARENT
);
5859 while ( hWheelWnd
&& (hWheelWnd
!= hChildWnd
) );
5860 if ( hWheelWnd
&& (hWheelWnd
!= hWnd
) &&
5861 (hWheelWnd
!= ::GetFocus()) && IsWindowEnabled( hWheelWnd
) )
5863 rResult
= ImplSendMessage( hWheelWnd
, nMsg
, wParam
, lParam
);
5870 // -----------------------------------------------------------------------
5872 LRESULT CALLBACK
SalFrameWndProc( HWND hWnd
, UINT nMsg
, WPARAM wParam
, LPARAM lParam
, int& rDef
)
5875 static int bInWheelMsg
= FALSE
;
5876 static int bInQueryEnd
= FALSE
;
5878 // By WM_CRETAE we connect the frame with the window handle
5879 if ( nMsg
== WM_CREATE
)
5881 // Window-Instanz am Windowhandle speichern
5882 // Can also be used for the W-Version, because the struct
5883 // to access lpCreateParams is the same structure
5884 CREATESTRUCTA
* pStruct
= (CREATESTRUCTA
*)lParam
;
5885 WinSalFrame
* pFrame
= (WinSalFrame
*)pStruct
->lpCreateParams
;
5888 SetWindowPtr( hWnd
, pFrame
);
5889 // HWND schon hier setzen, da schon auf den Instanzdaten
5890 // gearbeitet werden kann, wenn Messages waehrend
5891 // CreateWindow() gesendet werden
5892 pFrame
->mhWnd
= hWnd
;
5893 pFrame
->maSysData
.hWnd
= hWnd
;
5898 ImplSVData
* pSVData
= ImplGetSVData();
5899 // #i72707# TODO: the mbDeInit check will not be needed
5900 // once all windows that are not properly closed on exit got fixed
5901 if( pSVData
->mbDeInit
)
5904 if ( WM_USER_SYSTEM_WINDOW_ACTIVATED
== nMsg
)
5906 if (pSVData
->mpIntroWindow
)
5907 pSVData
->mpIntroWindow
->Hide();
5912 bool bCheckTimers
= false;
5917 case WM_LBUTTONDOWN
:
5918 case WM_MBUTTONDOWN
:
5919 case WM_RBUTTONDOWN
:
5923 case WM_NCMOUSEMOVE
:
5924 case SAL_MSG_MOUSELEAVE
:
5925 ImplSalYieldMutexAcquireWithWait();
5926 rDef
= !ImplHandleMouseMsg( hWnd
, nMsg
, wParam
, lParam
);
5927 ImplSalYieldMutexRelease();
5930 case WM_NCLBUTTONDOWN
:
5931 case WM_NCMBUTTONDOWN
:
5932 case WM_NCRBUTTONDOWN
:
5933 ImplSalYieldMutexAcquireWithWait();
5934 ImplCallClosePopupsHdl( hWnd
); // close popups...
5935 ImplSalYieldMutexRelease();
5938 case WM_MOUSEACTIVATE
:
5939 if ( LOWORD( lParam
) == HTCLIENT
)
5941 ImplSalYieldMutexAcquireWithWait();
5942 nRet
= ImplHandleMouseActivateMsg( hWnd
);
5943 ImplSalYieldMutexRelease();
5946 nRet
= MA_NOACTIVATE
;
5956 case WM_UNICHAR
: // MCD, 2003-01-13, Support for WM_UNICHAR & Keyman 6.0
5960 ImplSalYieldMutexAcquireWithWait();
5961 rDef
= !ImplHandleKeyMsg( hWnd
, nMsg
, wParam
, lParam
, nRet
);
5962 ImplSalYieldMutexRelease();
5966 // FALLTHROUGH intended
5967 case WM_MOUSEHWHEEL
:
5968 // Gegen Rekursion absichern, falls wir vom IE oder dem externen
5969 // Fenster die Message wieder zurueckbekommen
5973 rDef
= !ImplHandleWheelMsg( hWnd
, nMsg
, wParam
, lParam
);
5974 // Wenn wir die Message nicht ausgewertet haben, schauen wir
5975 // noch einmal nach, ob dort ein geplugtes Fenster steht,
5976 // welches wir dann benachrichtigen
5978 rDef
= ImplSalWheelMousePos( hWnd
, nMsg
, wParam
, lParam
, nRet
);
5984 ImplSalYieldMutexAcquireWithWait();
5985 rDef
= !ImplHandleCommand( hWnd
, wParam
, lParam
);
5986 ImplSalYieldMutexRelease();
5989 case WM_INITMENUPOPUP
:
5990 ImplSalYieldMutexAcquireWithWait();
5991 rDef
= !ImplHandleMenuActivate( hWnd
, wParam
, lParam
);
5992 ImplSalYieldMutexRelease();
5996 ImplSalYieldMutexAcquireWithWait();
5997 rDef
= !ImplHandleMenuSelect( hWnd
, wParam
, lParam
);
5998 ImplSalYieldMutexRelease();
6002 ImplSalYieldMutexAcquireWithWait();
6003 nRet
= ImplHandleSysCommand( hWnd
, wParam
, lParam
);
6004 ImplSalYieldMutexRelease();
6010 nRet
= ImplMenuChar( hWnd
, wParam
, lParam
);
6015 case WM_MEASUREITEM
:
6016 nRet
= ImplMeasureItem(hWnd
, wParam
, lParam
);
6022 nRet
= ImplDrawItem(hWnd
, wParam
, lParam
);
6028 case SAL_MSG_POSTMOVE
:
6029 ImplHandleMoveMsg( hWnd
);
6033 ImplHandleSizeMsg( hWnd
, wParam
, lParam
);
6036 case SAL_MSG_POSTCALLSIZE
:
6037 ImplCallSizeHdl( hWnd
);
6041 case WM_GETMINMAXINFO
:
6042 if ( ImplHandleMinMax( hWnd
, lParam
) )
6051 bCheckTimers
= ImplHandlePaintMsg( hWnd
);
6054 case SAL_MSG_POSTPAINT
:
6055 ImplHandlePaintMsg2( hWnd
, (RECT
*)wParam
);
6056 bCheckTimers
= true;
6060 case SAL_MSG_FORCEPALETTE
:
6061 ImplHandleForcePalette( hWnd
);
6065 case WM_QUERYNEWPALETTE
:
6066 case SAL_MSG_POSTQUERYNEWPAL
:
6067 nRet
= ImplHandlePalette( TRUE
, hWnd
, nMsg
, wParam
, lParam
, rDef
);
6071 // Wenn wir aktiviert werden, dann wollen wir auch unsere
6072 // Palette setzen. Wir machen dieses in Activate,
6073 // damit andere externe Child-Fenster auch unsere Palette
6074 // ueberschreiben koennen. So wird unsere jedenfalls nur einmal
6075 // gesetzt und nicht immer rekursiv, da an allen anderen Stellen
6076 // diese nur als Background-Palette gesetzt wird
6077 if ( LOWORD( wParam
) != WA_INACTIVE
)
6078 ImplSendMessage( hWnd
, SAL_MSG_FORCEPALETTE
, 0, 0 );
6082 // #95133# a system dialog is opened/closed, using our app window as parent
6084 WinSalFrame
* pFrame
= GetWindowPtr( hWnd
);
6085 Window
*pWin
= NULL
;
6087 pWin
= pFrame
->GetWindow();
6091 ImplSVData
* pSVData
= ImplGetSVData();
6092 pSVData
->maAppData
.mnModalMode
++;
6094 // #106431#, hide SplashScreen
6095 if( pSVData
->mpIntroWindow
)
6096 pSVData
->mpIntroWindow
->Hide();
6100 pWin
->EnableInput( FALSE
, TRUE
, TRUE
, NULL
);
6101 pWin
->ImplIncModalCount(); // #106303# support frame based modal count
6106 ImplGetSVData()->maAppData
.mnModalMode
--;
6109 pWin
->EnableInput( TRUE
, TRUE
, TRUE
, NULL
);
6110 pWin
->ImplDecModalCount(); // #106303# support frame based modal count
6119 case SAL_MSG_POSTFOCUS
:
6120 ImplHandleFocusMsg( hWnd
);
6125 ImplHandleCloseMsg( hWnd
);
6129 case WM_QUERYENDSESSION
:
6132 // handle queryendsession only once
6134 nRet
= !ImplHandleShutDownMsg( hWnd
);
6137 // Issue #16314#: ImplHandleShutDownMsg causes a PostMessage in case of allowing shutdown.
6138 // This posted message was never processed and cause Windows XP to hang after log off
6139 // if there are multiple sessions and the current session wasn't the first one started.
6140 // So if shutdown is allowed we assume that a post message was done and retrieve all
6141 // messages in the message queue and dispatch them before we return control to the system.
6147 while( PeekMessage( &msg
, NULL
, 0, 0, PM_REMOVE
) )
6149 DispatchMessage( &msg
);
6155 ImplSalYieldMutexAcquireWithWait();
6156 ImplSalYieldMutexRelease();
6163 bInQueryEnd
= FALSE
; // no shutdown: allow query again
6168 case WM_DISPLAYCHANGE
:
6169 case WM_SETTINGCHANGE
:
6170 case WM_DEVMODECHANGE
:
6172 case WM_SYSCOLORCHANGE
:
6174 ImplHandleSettingsChangeMsg( hWnd
, nMsg
, wParam
, lParam
);
6177 case WM_THEMECHANGED
:
6178 GetSalData()->mbThemeChanged
= TRUE
;
6181 case SAL_MSG_USEREVENT
:
6182 ImplHandleUserEvent( hWnd
, lParam
);
6186 case SAL_MSG_CAPTUREMOUSE
:
6190 case SAL_MSG_RELEASEMOUSE
:
6191 if ( ::GetCapture() == hWnd
)
6196 ImplSalToTop( hWnd
, (USHORT
)wParam
);
6200 ImplSalShow( hWnd
, (BOOL
)wParam
, (BOOL
)lParam
);
6203 case SAL_MSG_SETINPUTCONTEXT
:
6204 ImplSalFrameSetInputContext( hWnd
, (const SalInputContext
*)(void*)lParam
);
6207 case SAL_MSG_ENDEXTTEXTINPUT
:
6208 ImplSalFrameEndExtTextInput( hWnd
, (USHORT
)(ULONG
)(void*)wParam
);
6212 case WM_INPUTLANGCHANGE
:
6213 ImplHandleInputLangChange( hWnd
, wParam
, lParam
);
6217 // #103487#, some IMEs (eg, those that do not work onspot)
6218 // may send WM_IME_CHAR instead of WM_IME_COMPOSITION
6219 // we just handle it like a WM_CHAR message - seems to work fine
6220 ImplSalYieldMutexAcquireWithWait();
6221 rDef
= !ImplHandleKeyMsg( hWnd
, WM_CHAR
, wParam
, lParam
, nRet
);
6222 ImplSalYieldMutexRelease();
6225 case WM_IME_STARTCOMPOSITION
:
6226 rDef
= ImplHandleIMEStartComposition( hWnd
);
6229 case WM_IME_COMPOSITION
:
6230 rDef
= ImplHandleIMEComposition( hWnd
, lParam
);
6233 case WM_IME_ENDCOMPOSITION
:
6234 rDef
= ImplHandleIMEEndComposition( hWnd
);
6238 ImplHandleIMENotify( hWnd
, wParam
);
6241 if( ImplHandleAppCommand( hWnd
, lParam
) )
6247 #if WINVER >= 0x0500
6248 case WM_IME_REQUEST
:
6249 if ( PtrToInt( wParam
) == IMR_RECONVERTSTRING
)
6251 nRet
= ImplHandleIMEReconvertString( hWnd
, lParam
);
6254 else if( PtrToInt( wParam
) == IMR_CONFIRMRECONVERTSTRING
)
6256 nRet
= ImplHandleIMEConfirmReconvertString( hWnd
, lParam
);
6260 #endif // WINVER >= 0x0500
6263 // WheelMouse-Message abfangen
6264 if ( rDef
&& (nMsg
== aSalShlData
.mnWheelMsgId
) && aSalShlData
.mnWheelMsgId
)
6266 // Gegen Rekursion absichern, falls wir vom IE oder dem externen
6267 // Fenster die Message wieder zurueckbekommen
6271 // Zuerst wollen wir die Message dispatchen und dann darf auch
6272 // das SystemWindow drankommen
6274 if ( GetKeyState( VK_SHIFT
) & 0x8000 )
6275 nKeyState
|= MK_SHIFT
;
6276 if ( GetKeyState( VK_CONTROL
) & 0x8000 )
6277 nKeyState
|= MK_CONTROL
;
6278 // Mutex handling is inside from this call
6279 rDef
= !ImplHandleWheelMsg( hWnd
,
6281 MAKEWPARAM( nKeyState
, (WORD
)wParam
),
6285 HWND hWheelWnd
= ::GetFocus();
6286 if ( hWheelWnd
&& (hWheelWnd
!= hWnd
) )
6288 nRet
= ImplSendMessage( hWheelWnd
, nMsg
, wParam
, lParam
);
6292 rDef
= ImplSalWheelMousePos( hWnd
, nMsg
, wParam
, lParam
, nRet
);
6300 SalData
* pSalData
= GetSalData();
6301 if( pSalData
->mnNextTimerTime
)
6303 DWORD nCurTime
= GetTickCount();
6304 if( pSalData
->mnNextTimerTime
< nCurTime
)
6307 if( ! ImplPeekMessage( &aMsg
, 0, WM_PAINT
, WM_PAINT
, PM_NOREMOVE
| PM_NOYIELD
) )
6308 ImplPostMessage( pSalData
->mpFirstInstance
->mhComWnd
, SAL_MSG_POSTTIMER
, 0, nCurTime
);
6316 LRESULT CALLBACK
SalFrameWndProcA( HWND hWnd
, UINT nMsg
, WPARAM wParam
, LPARAM lParam
)
6323 if (__builtin_setjmp(jmpbuf
) == 0)
6325 han
.Set(jmpbuf
, NULL
, (__SEHandler::PF
)EXCEPTION_EXECUTE_HANDLER
);
6330 nRet
= SalFrameWndProc( hWnd
, nMsg
, wParam
, lParam
, bDef
);
6335 __except(WinSalInstance::WorkaroundExceptionHandlingInUSER32Lib(GetExceptionCode(), GetExceptionInformation()))
6340 nRet
= DefWindowProcA( hWnd
, nMsg
, wParam
, lParam
);
6344 LRESULT CALLBACK
SalFrameWndProcW( HWND hWnd
, UINT nMsg
, WPARAM wParam
, LPARAM lParam
)
6351 if (__builtin_setjmp(jmpbuf
) == 0)
6353 han
.Set(jmpbuf
, NULL
, (__SEHandler::PF
)EXCEPTION_EXECUTE_HANDLER
);
6358 nRet
= SalFrameWndProc( hWnd
, nMsg
, wParam
, lParam
, bDef
);
6363 __except(WinSalInstance::WorkaroundExceptionHandlingInUSER32Lib(GetExceptionCode(), GetExceptionInformation()))
6369 nRet
= DefWindowProcW( hWnd
, nMsg
, wParam
, lParam
);
6373 // -----------------------------------------------------------------------
6375 BOOL
ImplHandleGlobalMsg( HWND hWnd
, UINT nMsg
, WPARAM wParam
, LPARAM lParam
, LRESULT
& rlResult
)
6377 // handle all messages concerning all frames so they get processed only once
6378 // Must work for Unicode and none Unicode
6379 BOOL bResult
= FALSE
;
6380 if ( (nMsg
== WM_PALETTECHANGED
) || (nMsg
== SAL_MSG_POSTPALCHANGED
) )
6383 rlResult
= ImplHandlePalette( FALSE
, hWnd
, nMsg
, wParam
, lParam
, bDef
);
6384 bResult
= (bDef
!= 0);
6386 else if( nMsg
== WM_DISPLAYCHANGE
)
6388 WinSalSystem
* pSys
= static_cast<WinSalSystem
*>(ImplGetSalSystem());
6390 pSys
->clearMonitors();
6391 bResult
= (pSys
!= NULL
);
6396 // -----------------------------------------------------------------------
6398 BOOL
ImplWriteLastError( DWORD lastError
, const char *szApiCall
)
6401 // if VCL_LOGFILE_ENABLED is set, Win32 API error messages can be written
6402 // to %TMP%/vcl.log or %TEMP%/vcl.log
6403 static char *logEnabled
= getenv("VCL_LOGFILE_ENABLED");
6406 BOOL bSuccess
= FALSE
;
6407 static char *szTmp
= getenv("TMP");
6408 if( !szTmp
|| !*szTmp
)
6409 szTmp
= getenv("TEMP");
6410 if( szTmp
&& *szTmp
)
6413 strcpy( fname
, szTmp
);
6414 if( fname
[strlen(fname
) - 1] != '\\' )
6415 strcat( fname
, "\\");
6416 strcat( fname
, "vcl.log" );
6417 FILE *fp
= fopen( fname
, "a" ); // always append
6423 fprintf( fp
, "Process ID: %d (0x%x)\n", GetCurrentProcessId(), GetCurrentProcessId() );
6426 time( &aclock
); // Get time in seconds
6427 struct tm
*newtime
= localtime( &aclock
); // Convert time to struct tm form
6428 fprintf( fp
, asctime( newtime
) ); // print time stamp
6430 fprintf( fp
, "%s returned %u (0x%x)\n", szApiCall
, lastError
, lastError
);
6431 bSuccess
= TRUE
; // may be FormatMessage fails but we wrote at least the error code
6435 FORMAT_MESSAGE_ALLOCATE_BUFFER
|
6436 FORMAT_MESSAGE_FROM_SYSTEM
|
6437 FORMAT_MESSAGE_IGNORE_INSERTS
,
6440 MAKELANGID(LANG_NEUTRAL
, SUBLANG_DEFAULT
), // Default language
6445 fprintf( fp
, " %s\n", (LPSTR
)lpMsgBuf
);
6446 LocalFree( lpMsgBuf
);
6458 // -----------------------------------------------------------------------