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