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