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