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