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