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