1 /************************************************************************* 2 * 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * Copyright 2000, 2010 Oracle and/or its affiliates. 6 * 7 * OpenOffice.org - a multi-platform office productivity suite 8 * 9 * This file is part of OpenOffice.org. 10 * 11 * OpenOffice.org is free software: you can redistribute it and/or modify 12 * it under the terms of the GNU Lesser General Public License version 3 13 * only, as published by the Free Software Foundation. 14 * 15 * OpenOffice.org is distributed in the hope that it will be useful, 16 * but WITHOUT ANY WARRANTY; without even the implied warranty of 17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 18 * GNU Lesser General Public License version 3 for more details 19 * (a copy is included in the LICENSE file that accompanied this code). 20 * 21 * You should have received a copy of the GNU Lesser General Public License 22 * version 3 along with OpenOffice.org. If not, see 23 * <http://www.openoffice.org/license.html> 24 * for a copy of the LGPLv3 License. 25 * 26 ************************************************************************/ 27 28 // MARKER(update_precomp.py): autogen include statement, do not remove 29 #include "precompiled_vcl.hxx" 30 31 #include <string.h> 32 33 #include <tools/debug.hxx> 34 #include <tools/svwin.h> 35 36 #include <vcl/svapp.hxx> 37 38 #include <win/wincomp.hxx> 39 #include <win/saldata.hxx> 40 #include <win/salinst.h> 41 #include <win/salframe.h> 42 #include <win/salobj.h> 43 44 // ======================================================================= 45 46 static sal_Bool ImplIsSysWindowOrChild( HWND hWndParent, HWND hWndChild ) 47 { 48 if ( hWndParent == hWndChild ) 49 return TRUE; 50 51 HWND hTempWnd = ::GetParent( hWndChild ); 52 while ( hTempWnd ) 53 { 54 // Ab nicht Child-Fenstern hoeren wir auf zu suchen 55 if ( !(GetWindowStyle( hTempWnd ) & WS_CHILD) ) 56 return FALSE; 57 if ( hTempWnd == hWndParent ) 58 return TRUE; 59 hTempWnd = ::GetParent( hTempWnd ); 60 } 61 62 return FALSE; 63 } 64 65 // ----------------------------------------------------------------------- 66 67 WinSalObject* ImplFindSalObject( HWND hWndChild ) 68 { 69 SalData* pSalData = GetSalData(); 70 WinSalObject* pObject = pSalData->mpFirstObject; 71 while ( pObject ) 72 { 73 if ( ImplIsSysWindowOrChild( pObject->mhWndChild, hWndChild ) ) 74 return pObject; 75 76 pObject = pObject->mpNextObject; 77 } 78 79 return NULL; 80 } 81 82 // ----------------------------------------------------------------------- 83 84 WinSalFrame* ImplFindSalObjectFrame( HWND hWnd ) 85 { 86 WinSalFrame* pFrame = NULL; 87 WinSalObject* pObject = ImplFindSalObject( hWnd ); 88 if ( pObject ) 89 { 90 // Dazugehoerenden Frame suchen 91 HWND hWnd = ::GetParent( pObject->mhWnd ); 92 pFrame = GetSalData()->mpFirstFrame; 93 while ( pFrame ) 94 { 95 if ( pFrame->mhWnd == hWnd ) 96 break; 97 98 pFrame = pFrame->mpNextFrame; 99 } 100 } 101 102 return pFrame; 103 } 104 105 // ----------------------------------------------------------------------- 106 107 sal_Bool ImplInterceptChildWindowKeyDown( MSG& rMsg ) 108 { 109 sal_Bool bResult = sal_False; 110 if ( rMsg.message == WM_KEYDOWN ) 111 { 112 wchar_t pClassName[10]; 113 sal_Int32 nLen = GetClassNameW( rMsg.hwnd, pClassName, 10 ); 114 if ( !( nLen == 9 && wcsncmp( pClassName, SAL_OBJECT_CLASSNAMEW, nLen ) == 0 ) ) 115 { 116 // look for the first SalObject in the parent hierarchy 117 HWND hWin = rMsg.hwnd; 118 HWND hLastOLEWindow = hWin; 119 WinSalObject* pSalObj = NULL; 120 do 121 { 122 hLastOLEWindow = hWin; 123 hWin = ::GetParent( hWin ); 124 if ( hWin ) 125 { 126 nLen = GetClassNameW( hWin, pClassName, 10 ); 127 if ( nLen == 9 && wcsncmp( pClassName, SAL_OBJECT_CLASSNAMEW, nLen ) == 0 ) 128 pSalObj = GetSalObjWindowPtr( hWin ); 129 } 130 } while( hWin && !pSalObj ); 131 132 if ( pSalObj && pSalObj->mbInterceptChildWindowKeyDown && pSalObj->maSysData.hWnd ) 133 { 134 bResult = ( 1 == ImplSendMessage( pSalObj->maSysData.hWnd, rMsg.message, rMsg.wParam, rMsg.lParam ) ); 135 } 136 } 137 } 138 139 return bResult; 140 } 141 142 // ----------------------------------------------------------------------- 143 144 145 // ----------------------------------------------------------------------- 146 147 LRESULT CALLBACK SalSysMsgProc( int nCode, WPARAM wParam, LPARAM lParam ) 148 { 149 // Used for Unicode and none Unicode 150 SalData* pSalData = GetSalData(); 151 152 if ( (nCode >= 0) && lParam ) 153 { 154 CWPSTRUCT* pData = (CWPSTRUCT*)lParam; 155 if ( (pData->message != WM_KEYDOWN) && 156 (pData->message != WM_KEYUP) ) 157 pSalData->mnSalObjWantKeyEvt = 0; 158 159 // Testen, ob wir Daten fuer ein SalObject-Fenster behandeln 160 // muessen 161 WinSalObject* pObject; 162 if ( pData->message == WM_SETFOCUS ) 163 { 164 pObject = ImplFindSalObject( pData->hwnd ); 165 if ( pObject ) 166 { 167 pObject->mhLastFocusWnd = pData->hwnd; 168 if ( ImplSalYieldMutexTryToAcquire() ) 169 { 170 pObject->CallCallback( SALOBJ_EVENT_GETFOCUS, 0 ); 171 ImplSalYieldMutexRelease(); 172 } 173 else 174 ImplPostMessage( pObject->mhWnd, SALOBJ_MSG_POSTFOCUS, 0, 0 ); 175 } 176 } 177 else if ( pData->message == WM_KILLFOCUS ) 178 { 179 pObject = ImplFindSalObject( pData->hwnd ); 180 if ( pObject && !ImplFindSalObject( (HWND)pData->wParam ) ) 181 { 182 // LoseFocus nur rufen, wenn wirklich kein ChildFenster 183 // den Focus bekommt 184 if ( !pData->wParam || !ImplFindSalObject( (HWND)pData->wParam ) ) 185 { 186 if ( ImplSalYieldMutexTryToAcquire() ) 187 { 188 pObject->CallCallback( SALOBJ_EVENT_LOSEFOCUS, 0 ); 189 ImplSalYieldMutexRelease(); 190 } 191 else 192 ImplPostMessage( pObject->mhWnd, SALOBJ_MSG_POSTFOCUS, 0, 0 ); 193 } 194 else 195 pObject->mhLastFocusWnd = (HWND)pData->wParam; 196 } 197 } 198 } 199 200 return CallNextHookEx( pSalData->mhSalObjMsgHook, nCode, wParam, lParam ); 201 } 202 203 // ----------------------------------------------------------------------- 204 205 sal_Bool ImplSalPreDispatchMsg( MSG* pMsg ) 206 { 207 // Used for Unicode and none Unicode 208 SalData* pSalData = GetSalData(); 209 WinSalObject* pObject; 210 211 if ( (pMsg->message == WM_LBUTTONDOWN) || 212 (pMsg->message == WM_RBUTTONDOWN) || 213 (pMsg->message == WM_MBUTTONDOWN) ) 214 { 215 ImplSalYieldMutexAcquireWithWait(); 216 pObject = ImplFindSalObject( pMsg->hwnd ); 217 if ( pObject && !pObject->IsMouseTransparent() ) 218 ImplPostMessage( pObject->mhWnd, SALOBJ_MSG_TOTOP, 0, 0 ); 219 ImplSalYieldMutexRelease(); 220 } 221 222 if ( (pMsg->message == WM_KEYDOWN) || 223 (pMsg->message == WM_KEYUP) ) 224 { 225 // KeyEvents wollen wir nach Moeglichkeit auch abarbeiten, 226 // wenn das Control diese nicht selber auswertet 227 // SysKeys werden als WM_SYSCOMMAND verarbeitet 228 // Char-Events verarbeiten wir nicht, da wir nur 229 // Accelerator relevante Keys verarbeiten wollen 230 sal_Bool bWantedKeyCode = FALSE; 231 // A-Z, 0-9 nur in Verbindung mit Control-Taste 232 if ( ((pMsg->wParam >= 65) && (pMsg->wParam <= 90)) || 233 ((pMsg->wParam >= 48) && (pMsg->wParam <= 57)) ) 234 { 235 if ( GetKeyState( VK_CONTROL ) & 0x8000 ) 236 bWantedKeyCode = TRUE; 237 } 238 else if ( ((pMsg->wParam >= VK_F1) && (pMsg->wParam <= VK_F24)) || 239 ((pMsg->wParam >= VK_SPACE) && (pMsg->wParam <= VK_HELP)) || 240 (pMsg->wParam == VK_BACK) || (pMsg->wParam == VK_TAB) || 241 (pMsg->wParam == VK_CLEAR) || (pMsg->wParam == VK_RETURN) || 242 (pMsg->wParam == VK_ESCAPE) ) 243 bWantedKeyCode = TRUE; 244 if ( bWantedKeyCode ) 245 { 246 ImplSalYieldMutexAcquireWithWait(); 247 pObject = ImplFindSalObject( pMsg->hwnd ); 248 if ( pObject ) 249 pSalData->mnSalObjWantKeyEvt = pMsg->wParam; 250 ImplSalYieldMutexRelease(); 251 } 252 } 253 // Hier WM_SYSCHAR abfangen, um mit Alt+Taste evtl. Menu zu aktivieren 254 else if ( pMsg->message == WM_SYSCHAR ) 255 { 256 pSalData->mnSalObjWantKeyEvt = 0; 257 258 sal_uInt16 nKeyCode = LOWORD( pMsg->wParam ); 259 // Nur 0-9 und A-Z 260 if ( ((nKeyCode >= 48) && (nKeyCode <= 57)) || 261 ((nKeyCode >= 65) && (nKeyCode <= 90)) || 262 ((nKeyCode >= 97) && (nKeyCode <= 122)) ) 263 { 264 sal_Bool bRet = FALSE; 265 ImplSalYieldMutexAcquireWithWait(); 266 pObject = ImplFindSalObject( pMsg->hwnd ); 267 if ( pObject ) 268 { 269 if ( pMsg->hwnd == ::GetFocus() ) 270 { 271 WinSalFrame* pFrame = ImplFindSalObjectFrame( pMsg->hwnd ); 272 if ( pFrame ) 273 { 274 if ( ImplHandleSalObjSysCharMsg( pFrame->mhWnd, pMsg->wParam, pMsg->lParam ) ) 275 bRet = TRUE; 276 } 277 } 278 } 279 ImplSalYieldMutexRelease(); 280 if ( bRet ) 281 return TRUE; 282 } 283 } 284 else 285 pSalData->mnSalObjWantKeyEvt = 0; 286 287 return FALSE; 288 } 289 290 // ----------------------------------------------------------------------- 291 292 void ImplSalPostDispatchMsg( MSG* pMsg, LRESULT /* nDispatchResult */ ) 293 { 294 // Used for Unicode and none Unicode 295 SalData* pSalData = GetSalData(); 296 WinSalFrame* pFrame; 297 298 if ( (pMsg->message == WM_KEYDOWN) || (pMsg->message == WM_KEYUP) ) 299 { 300 if ( pSalData->mnSalObjWantKeyEvt == pMsg->wParam ) 301 { 302 pSalData->mnSalObjWantKeyEvt = 0; 303 if ( pMsg->hwnd == ::GetFocus() ) 304 { 305 ImplSalYieldMutexAcquireWithWait(); 306 pFrame = ImplFindSalObjectFrame( pMsg->hwnd ); 307 if ( pFrame ) 308 ImplHandleSalObjKeyMsg( pFrame->mhWnd, pMsg->message, pMsg->wParam, pMsg->lParam ); 309 ImplSalYieldMutexRelease(); 310 } 311 } 312 } 313 314 pSalData->mnSalObjWantKeyEvt = 0; 315 } 316 317 // ======================================================================= 318 319 LRESULT CALLBACK SalSysObjWndProc( HWND hWnd, UINT nMsg, WPARAM wParam, LPARAM lParam, int& rDef ) 320 { 321 WinSalObject* pSysObj; 322 LRESULT nRet = 0; 323 324 switch( nMsg ) 325 { 326 case WM_ERASEBKGND: 327 nRet = 1; 328 rDef = FALSE; 329 break; 330 case WM_PAINT: 331 { 332 PAINTSTRUCT aPs; 333 BeginPaint( hWnd, &aPs ); 334 EndPaint( hWnd, &aPs ); 335 rDef = FALSE; 336 } 337 break; 338 339 case WM_PARENTNOTIFY: 340 { 341 UINT nNotifyMsg = LOWORD( wParam ); 342 if ( (nNotifyMsg == WM_LBUTTONDOWN) || 343 (nNotifyMsg == WM_RBUTTONDOWN) || 344 (nNotifyMsg == WM_MBUTTONDOWN) ) 345 { 346 ImplSalYieldMutexAcquireWithWait(); 347 pSysObj = GetSalObjWindowPtr( hWnd ); 348 if ( pSysObj && !pSysObj->IsMouseTransparent() ) 349 pSysObj->CallCallback( SALOBJ_EVENT_TOTOP, 0 ); 350 ImplSalYieldMutexRelease(); 351 } 352 } 353 break; 354 355 case WM_MOUSEACTIVATE: 356 { 357 ImplSalYieldMutexAcquireWithWait(); 358 pSysObj = GetSalObjWindowPtr( hWnd ); 359 if ( pSysObj && !pSysObj->IsMouseTransparent() ) 360 ImplPostMessage( hWnd, SALOBJ_MSG_TOTOP, 0, 0 ); 361 ImplSalYieldMutexRelease(); 362 } 363 break; 364 365 case SALOBJ_MSG_TOTOP: 366 if ( ImplSalYieldMutexTryToAcquire() ) 367 { 368 pSysObj = GetSalObjWindowPtr( hWnd ); 369 pSysObj->CallCallback( SALOBJ_EVENT_TOTOP, 0 ); 370 ImplSalYieldMutexRelease(); 371 rDef = FALSE; 372 } 373 else 374 ImplPostMessage( hWnd, SALOBJ_MSG_TOTOP, 0, 0 ); 375 break; 376 377 case SALOBJ_MSG_POSTFOCUS: 378 if ( ImplSalYieldMutexTryToAcquire() ) 379 { 380 pSysObj = GetSalObjWindowPtr( hWnd ); 381 HWND hFocusWnd = ::GetFocus(); 382 sal_uInt16 nEvent; 383 if ( hFocusWnd && ImplIsSysWindowOrChild( hWnd, hFocusWnd ) ) 384 nEvent = SALOBJ_EVENT_GETFOCUS; 385 else 386 nEvent = SALOBJ_EVENT_LOSEFOCUS; 387 pSysObj->CallCallback( nEvent, 0 ); 388 ImplSalYieldMutexRelease(); 389 } 390 else 391 ImplPostMessage( hWnd, SALOBJ_MSG_POSTFOCUS, 0, 0 ); 392 rDef = FALSE; 393 break; 394 395 case WM_SIZE: 396 { 397 HWND hWndChild = GetWindow( hWnd, GW_CHILD ); 398 if ( hWndChild ) 399 { 400 SetWindowPos( hWndChild, 401 0, 0, 0, (int)LOWORD( lParam ), (int)HIWORD( lParam ), 402 SWP_NOZORDER | SWP_NOACTIVATE ); 403 } 404 } 405 rDef = FALSE; 406 break; 407 408 case WM_CREATE: 409 { 410 // Window-Instanz am Windowhandle speichern 411 // Can also be used for the W-Version, because the struct 412 // to access lpCreateParams is the same structure 413 CREATESTRUCTA* pStruct = (CREATESTRUCTA*)lParam; 414 pSysObj = (WinSalObject*)pStruct->lpCreateParams; 415 SetSalObjWindowPtr( hWnd, pSysObj ); 416 // HWND schon hier setzen, da schon auf den Instanzdaten 417 // gearbeitet werden kann, wenn Messages waehrend 418 // CreateWindow() gesendet werden 419 pSysObj->mhWnd = hWnd; 420 rDef = FALSE; 421 } 422 break; 423 } 424 425 return nRet; 426 } 427 428 LRESULT CALLBACK SalSysObjWndProcA( HWND hWnd, UINT nMsg, WPARAM wParam, LPARAM lParam ) 429 { 430 int bDef = TRUE; 431 LRESULT nRet = SalSysObjWndProc( hWnd, nMsg, wParam, lParam, bDef ); 432 if ( bDef ) 433 nRet = DefWindowProcA( hWnd, nMsg, wParam, lParam ); 434 return nRet; 435 } 436 437 LRESULT CALLBACK SalSysObjWndProcW( HWND hWnd, UINT nMsg, WPARAM wParam, LPARAM lParam ) 438 { 439 int bDef = TRUE; 440 LRESULT nRet = SalSysObjWndProc( hWnd, nMsg, wParam, lParam, bDef ); 441 if ( bDef ) 442 nRet = DefWindowProcW( hWnd, nMsg, wParam, lParam ); 443 return nRet; 444 } 445 446 // ----------------------------------------------------------------------- 447 448 LRESULT CALLBACK SalSysObjChildWndProc( HWND hWnd, UINT nMsg, WPARAM wParam, LPARAM lParam, int& rDef ) 449 { 450 LRESULT nRet = 0; 451 452 switch( nMsg ) 453 { 454 // Wegen PlugIn's loeschen wir erstmal den Hintergrund 455 case WM_ERASEBKGND: 456 { 457 WinSalObject* pSysObj = GetSalObjWindowPtr( ::GetParent( hWnd ) ); 458 459 if( pSysObj && !pSysObj->IsEraseBackgroundEnabled() ) 460 { 461 // do not erase background 462 nRet = 1; 463 rDef = FALSE; 464 } 465 } 466 break; 467 468 case WM_PAINT: 469 { 470 PAINTSTRUCT aPs; 471 BeginPaint( hWnd, &aPs ); 472 EndPaint( hWnd, &aPs ); 473 rDef = FALSE; 474 } 475 break; 476 477 case WM_MOUSEMOVE: 478 case WM_LBUTTONDOWN: 479 case WM_MBUTTONDOWN: 480 case WM_RBUTTONDOWN: 481 case WM_LBUTTONUP: 482 case WM_MBUTTONUP: 483 case WM_RBUTTONUP: 484 { 485 WinSalObject* pSysObj; 486 pSysObj = GetSalObjWindowPtr( ::GetParent( hWnd ) ); 487 488 if( pSysObj && pSysObj->IsMouseTransparent() ) 489 { 490 // forward mouse events to parent frame 491 HWND hWndParent = ::GetParent( pSysObj->mhWnd ); 492 493 // transform coordinates 494 POINT pt; 495 pt.x = (long) LOWORD( lParam ); 496 pt.y = (long) HIWORD( lParam ); 497 MapWindowPoints( hWnd, hWndParent, &pt, 1 ); 498 lParam = MAKELPARAM( (WORD) pt.x, (WORD) pt.y ); 499 500 nRet = ImplSendMessage( hWndParent, nMsg, wParam, lParam ); 501 rDef = FALSE; 502 } 503 } 504 break; 505 } 506 507 return nRet; 508 } 509 510 LRESULT CALLBACK SalSysObjChildWndProcA( HWND hWnd, UINT nMsg, WPARAM wParam, LPARAM lParam ) 511 { 512 int bDef = TRUE; 513 LRESULT nRet = SalSysObjChildWndProc( hWnd, nMsg, wParam, lParam, bDef ); 514 if ( bDef ) 515 nRet = DefWindowProcA( hWnd, nMsg, wParam, lParam ); 516 return nRet; 517 } 518 519 LRESULT CALLBACK SalSysObjChildWndProcW( HWND hWnd, UINT nMsg, WPARAM wParam, LPARAM lParam ) 520 { 521 int bDef = TRUE; 522 LRESULT nRet = SalSysObjChildWndProc( hWnd, nMsg, wParam, lParam, bDef ); 523 if ( bDef ) 524 nRet = DefWindowProcW( hWnd, nMsg, wParam, lParam ); 525 return nRet; 526 } 527 528 // ======================================================================= 529 530 SalObject* ImplSalCreateObject( WinSalInstance* pInst, WinSalFrame* pParent ) 531 { 532 SalData* pSalData = GetSalData(); 533 534 // Hook installieren, wenn es das erste SalObject ist 535 if ( !pSalData->mpFirstObject ) 536 { 537 pSalData->mhSalObjMsgHook = SetWindowsHookExW( WH_CALLWNDPROC, 538 SalSysMsgProc, 539 pSalData->mhInst, 540 pSalData->mnAppThreadId ); 541 } 542 543 if ( !pSalData->mbObjClassInit ) 544 { 545 // #95301# shockwave plugin has bug; expects ASCII functions to be used 546 if ( false )//aSalShlData.mbWNT ) 547 { 548 WNDCLASSEXW aWndClassEx; 549 aWndClassEx.cbSize = sizeof( aWndClassEx ); 550 aWndClassEx.style = 0; 551 aWndClassEx.lpfnWndProc = SalSysObjWndProcW; 552 aWndClassEx.cbClsExtra = 0; 553 aWndClassEx.cbWndExtra = SAL_OBJECT_WNDEXTRA; 554 aWndClassEx.hInstance = pSalData->mhInst; 555 aWndClassEx.hIcon = 0; 556 aWndClassEx.hIconSm = 0; 557 aWndClassEx.hCursor = LoadCursor( 0, IDC_ARROW ); 558 aWndClassEx.hbrBackground = 0; 559 aWndClassEx.lpszMenuName = 0; 560 aWndClassEx.lpszClassName = SAL_OBJECT_CLASSNAMEW; 561 if ( RegisterClassExW( &aWndClassEx ) ) 562 { 563 // Wegen PlugIn's loeschen wir erstmal den Hintergrund 564 aWndClassEx.cbWndExtra = 0; 565 aWndClassEx.hbrBackground = (HBRUSH)(COLOR_WINDOW+1); 566 aWndClassEx.lpfnWndProc = SalSysObjChildWndProcW; 567 aWndClassEx.lpszClassName = SAL_OBJECT_CHILDCLASSNAMEW; 568 if ( RegisterClassExW( &aWndClassEx ) ) 569 pSalData->mbObjClassInit = TRUE; 570 } 571 } 572 else 573 { 574 WNDCLASSEXA aWndClassEx; 575 aWndClassEx.cbSize = sizeof( aWndClassEx ); 576 aWndClassEx.style = 0; 577 aWndClassEx.lpfnWndProc = SalSysObjWndProcA; 578 aWndClassEx.cbClsExtra = 0; 579 aWndClassEx.cbWndExtra = SAL_OBJECT_WNDEXTRA; 580 aWndClassEx.hInstance = pSalData->mhInst; 581 aWndClassEx.hIcon = 0; 582 aWndClassEx.hIconSm = 0; 583 aWndClassEx.hCursor = LoadCursor( 0, IDC_ARROW ); 584 aWndClassEx.hbrBackground = 0; 585 aWndClassEx.lpszMenuName = 0; 586 aWndClassEx.lpszClassName = SAL_OBJECT_CLASSNAMEA; 587 if ( RegisterClassExA( &aWndClassEx ) ) 588 { 589 // Wegen PlugIn's loeschen wir erstmal den Hintergrund 590 aWndClassEx.cbWndExtra = 0; 591 aWndClassEx.hbrBackground = (HBRUSH)(COLOR_WINDOW+1); 592 aWndClassEx.lpfnWndProc = SalSysObjChildWndProcA; 593 aWndClassEx.lpszClassName = SAL_OBJECT_CHILDCLASSNAMEA; 594 if ( RegisterClassExA( &aWndClassEx ) ) 595 pSalData->mbObjClassInit = TRUE; 596 } 597 } 598 } 599 600 if ( pSalData->mbObjClassInit ) 601 { 602 WinSalObject* pObject = new WinSalObject; 603 604 // #135235# Clip siblings of this 605 // SystemChildWindow. Otherwise, DXCanvas (using a hidden 606 // SystemChildWindow) clobbers applets/plugins during 607 // animations . 608 HWND hWnd = CreateWindowExA( 0, SAL_OBJECT_CLASSNAMEA, "", 609 WS_CHILD | WS_CLIPSIBLINGS, 0, 0, 0, 0, 610 pParent->mhWnd, 0, 611 pInst->mhInst, (void*)pObject ); 612 613 HWND hWndChild = 0; 614 if ( hWnd ) 615 { 616 // #135235# Explicitely stack SystemChildWindows in 617 // the order they're created - since there's no notion 618 // of zorder. 619 SetWindowPos(hWnd,HWND_TOP,0,0,0,0, 620 SWP_NOACTIVATE|SWP_NOMOVE|SWP_NOREDRAW|SWP_NOSIZE); 621 hWndChild = CreateWindowExA( 0, SAL_OBJECT_CHILDCLASSNAMEA, "", 622 WS_CHILD | WS_CLIPCHILDREN | WS_CLIPSIBLINGS | WS_VISIBLE, 623 0, 0, 0, 0, 624 hWnd, 0, 625 pInst->mhInst, NULL ); 626 } 627 628 if ( !hWndChild ) 629 { 630 delete pObject; 631 return NULL; 632 } 633 634 if ( hWnd ) 635 { 636 pObject->mhWnd = hWnd; 637 pObject->mhWndChild = hWndChild; 638 pObject->maSysData.hWnd = hWndChild; 639 return pObject; 640 } 641 } 642 643 return NULL; 644 } 645 646 // ======================================================================= 647 648 WinSalObject::WinSalObject() 649 { 650 SalData* pSalData = GetSalData(); 651 652 mhWnd = 0; 653 mhWndChild = 0; 654 mhLastFocusWnd = 0; 655 maSysData.nSize = sizeof( SystemEnvData ); 656 mpStdClipRgnData = NULL; 657 mbInterceptChildWindowKeyDown = sal_False; 658 659 // Insert object in objectlist 660 mpNextObject = pSalData->mpFirstObject; 661 pSalData->mpFirstObject = this; 662 } 663 664 // ----------------------------------------------------------------------- 665 666 WinSalObject::~WinSalObject() 667 { 668 SalData* pSalData = GetSalData(); 669 670 // remove frame from framelist 671 if ( this == pSalData->mpFirstObject ) 672 { 673 pSalData->mpFirstObject = mpNextObject; 674 675 // Wenn letztes SalObject, dann Hook wieder entfernen 676 if ( !pSalData->mpFirstObject ) 677 UnhookWindowsHookEx( pSalData->mhSalObjMsgHook ); 678 } 679 else 680 { 681 WinSalObject* pTempObject = pSalData->mpFirstObject; 682 while ( pTempObject->mpNextObject != this ) 683 pTempObject = pTempObject->mpNextObject; 684 685 pTempObject->mpNextObject = mpNextObject; 686 } 687 688 // Cache-Daten zerstoeren 689 if ( mpStdClipRgnData ) 690 delete mpStdClipRgnData; 691 692 HWND hWndParent = ::GetParent( mhWnd ); 693 694 if ( mhWndChild ) 695 DestroyWindow( mhWndChild ); 696 if ( mhWnd ) 697 DestroyWindow( mhWnd ); 698 699 // Palette wieder zuruecksetzen, wenn kein externes Child-Fenster 700 // mehr vorhanden ist, da diese unsere Palette ueberschrieben haben 701 // koennen 702 if ( hWndParent && 703 ::GetActiveWindow() == hWndParent && 704 !GetWindow( hWndParent, GW_CHILD ) ) 705 ImplSendMessage( hWndParent, SAL_MSG_FORCEPALETTE, 0, 0 ); 706 } 707 708 // ----------------------------------------------------------------------- 709 710 void WinSalObject::ResetClipRegion() 711 { 712 SetWindowRgn( mhWnd, 0, TRUE ); 713 } 714 715 // ----------------------------------------------------------------------- 716 717 sal_uInt16 WinSalObject::GetClipRegionType() 718 { 719 return SAL_OBJECT_CLIP_INCLUDERECTS; 720 } 721 722 // ----------------------------------------------------------------------- 723 724 void WinSalObject::BeginSetClipRegion( sal_uLong nRectCount ) 725 { 726 sal_uLong nRectBufSize = sizeof(RECT)*nRectCount; 727 if ( nRectCount < SAL_CLIPRECT_COUNT ) 728 { 729 if ( !mpStdClipRgnData ) 730 mpStdClipRgnData = (RGNDATA*)new BYTE[sizeof(RGNDATA)-1+(SAL_CLIPRECT_COUNT*sizeof(RECT))]; 731 mpClipRgnData = mpStdClipRgnData; 732 } 733 else 734 mpClipRgnData = (RGNDATA*)new BYTE[sizeof(RGNDATA)-1+nRectBufSize]; 735 mpClipRgnData->rdh.dwSize = sizeof( RGNDATAHEADER ); 736 mpClipRgnData->rdh.iType = RDH_RECTANGLES; 737 mpClipRgnData->rdh.nCount = nRectCount; 738 mpClipRgnData->rdh.nRgnSize = nRectBufSize; 739 SetRectEmpty( &(mpClipRgnData->rdh.rcBound) ); 740 mpNextClipRect = (RECT*)(&(mpClipRgnData->Buffer)); 741 mbFirstClipRect = TRUE; 742 } 743 744 // ----------------------------------------------------------------------- 745 746 void WinSalObject::UnionClipRegion( long nX, long nY, long nWidth, long nHeight ) 747 { 748 RECT* pRect = mpNextClipRect; 749 RECT* pBoundRect = &(mpClipRgnData->rdh.rcBound); 750 long nRight = nX + nWidth; 751 long nBottom = nY + nHeight; 752 753 if ( mbFirstClipRect ) 754 { 755 pBoundRect->left = nX; 756 pBoundRect->top = nY; 757 pBoundRect->right = nRight; 758 pBoundRect->bottom = nBottom; 759 mbFirstClipRect = FALSE; 760 } 761 else 762 { 763 if ( nX < pBoundRect->left ) 764 pBoundRect->left = (int)nX; 765 766 if ( nY < pBoundRect->top ) 767 pBoundRect->top = (int)nY; 768 769 if ( nRight > pBoundRect->right ) 770 pBoundRect->right = (int)nRight; 771 772 if ( nBottom > pBoundRect->bottom ) 773 pBoundRect->bottom = (int)nBottom; 774 } 775 776 pRect->left = (int)nX; 777 pRect->top = (int)nY; 778 pRect->right = (int)nRight; 779 pRect->bottom = (int)nBottom; 780 mpNextClipRect++; 781 } 782 783 // ----------------------------------------------------------------------- 784 785 void WinSalObject::EndSetClipRegion() 786 { 787 HRGN hRegion; 788 789 // Aus den Region-Daten muessen wir jetzt eine ClipRegion erzeugen 790 if ( mpClipRgnData->rdh.nCount == 1 ) 791 { 792 RECT* pRect = &(mpClipRgnData->rdh.rcBound); 793 hRegion = CreateRectRgn( pRect->left, pRect->top, 794 pRect->right, pRect->bottom ); 795 } 796 else 797 { 798 sal_uLong nSize = mpClipRgnData->rdh.nRgnSize+sizeof(RGNDATAHEADER); 799 hRegion = ExtCreateRegion( NULL, nSize, mpClipRgnData ); 800 if ( mpClipRgnData != mpStdClipRgnData ) 801 delete [] (BYTE*)mpClipRgnData; 802 } 803 804 DBG_ASSERT( hRegion, "SalObject::EndSetClipRegion() - Can't create ClipRegion" ); 805 SetWindowRgn( mhWnd, hRegion, TRUE ); 806 } 807 808 // ----------------------------------------------------------------------- 809 810 void WinSalObject::SetPosSize( long nX, long nY, long nWidth, long nHeight ) 811 { 812 sal_uLong nStyle = 0; 813 sal_Bool bVisible = (GetWindowStyle( mhWnd ) & WS_VISIBLE) != 0; 814 if ( bVisible ) 815 { 816 ShowWindow( mhWnd, SW_HIDE ); 817 nStyle |= SWP_SHOWWINDOW; 818 } 819 SetWindowPos( mhWnd, 0, 820 (int)nX, (int)nY, (int)nWidth, (int)nHeight, 821 SWP_NOZORDER | SWP_NOACTIVATE | nStyle ); 822 } 823 824 // ----------------------------------------------------------------------- 825 826 void WinSalObject::Show( sal_Bool bVisible ) 827 { 828 if ( bVisible ) 829 ShowWindow( mhWnd, SW_SHOWNORMAL ); 830 else 831 ShowWindow( mhWnd, SW_HIDE ); 832 } 833 834 // ----------------------------------------------------------------------- 835 836 void WinSalObject::Enable( sal_Bool bEnable ) 837 { 838 EnableWindow( mhWnd, bEnable ); 839 } 840 841 // ----------------------------------------------------------------------- 842 843 void WinSalObject::GrabFocus() 844 { 845 if ( mhLastFocusWnd && 846 IsWindow( mhLastFocusWnd ) && 847 ImplIsSysWindowOrChild( mhWndChild, mhLastFocusWnd ) ) 848 ::SetFocus( mhLastFocusWnd ); 849 else 850 ::SetFocus( mhWndChild ); 851 } 852 853 // ----------------------------------------------------------------------- 854 855 void WinSalObject::SetBackground() 856 { 857 } 858 859 // ----------------------------------------------------------------------- 860 861 void WinSalObject::SetBackground( SalColor ) 862 { 863 } 864 865 // ----------------------------------------------------------------------- 866 867 const SystemEnvData* WinSalObject::GetSystemData() const 868 { 869 return &maSysData; 870 } 871 872 // ----------------------------------------------------------------------- 873 874 void WinSalObject::InterceptChildWindowKeyDown( sal_Bool bIntercept ) 875 { 876 mbInterceptChildWindowKeyDown = bIntercept; 877 } 878 879