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