merged tag ooo/DEV300_m102
[LibreOffice.git] / vcl / win / source / window / salobj.cxx
blob00ee39092afff6db9636d2479dfef7c0094c1d64
1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 * Copyright 2000, 2010 Oracle and/or its affiliates.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * This file is part of OpenOffice.org.
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.
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).
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.
26 ************************************************************************/
28 // MARKER(update_precomp.py): autogen include statement, do not remove
29 #include "precompiled_vcl.hxx"
31 #include <string.h>
33 #ifndef _SVWIN_HXX
34 #include <tools/svwin.h>
35 #endif
36 #include <wincomp.hxx>
37 #include <saldata.hxx>
38 #include <salinst.h>
39 #include <salframe.h>
40 #include <salobj.h>
41 #include <tools/debug.hxx>
42 #include <vcl/svapp.hxx>
44 // =======================================================================
46 static sal_Bool ImplIsSysWindowOrChild( HWND hWndParent, HWND hWndChild )
48 if ( hWndParent == hWndChild )
49 return TRUE;
51 HWND hTempWnd = ::GetParent( hWndChild );
52 while ( hTempWnd )
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 );
62 return FALSE;
65 // -----------------------------------------------------------------------
67 WinSalObject* ImplFindSalObject( HWND hWndChild )
69 SalData* pSalData = GetSalData();
70 WinSalObject* pObject = pSalData->mpFirstObject;
71 while ( pObject )
73 if ( ImplIsSysWindowOrChild( pObject->mhWndChild, hWndChild ) )
74 return pObject;
76 pObject = pObject->mpNextObject;
79 return NULL;
82 // -----------------------------------------------------------------------
84 WinSalFrame* ImplFindSalObjectFrame( HWND hWnd )
86 WinSalFrame* pFrame = NULL;
87 WinSalObject* pObject = ImplFindSalObject( hWnd );
88 if ( pObject )
90 // Dazugehoerenden Frame suchen
91 HWND hWnd = ::GetParent( pObject->mhWnd );
92 pFrame = GetSalData()->mpFirstFrame;
93 while ( pFrame )
95 if ( pFrame->mhWnd == hWnd )
96 break;
98 pFrame = pFrame->mpNextFrame;
102 return pFrame;
105 // -----------------------------------------------------------------------
107 sal_Bool ImplInterceptChildWindowKeyDown( MSG& rMsg )
109 sal_Bool bResult = sal_False;
110 if ( rMsg.message == WM_KEYDOWN )
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 ) )
116 // look for the first SalObject in the parent hierarchy
117 HWND hWin = rMsg.hwnd;
118 HWND hLastOLEWindow = hWin;
119 WinSalObject* pSalObj = NULL;
122 hLastOLEWindow = hWin;
123 hWin = ::GetParent( hWin );
124 if ( hWin )
126 nLen = GetClassNameW( hWin, pClassName, 10 );
127 if ( nLen == 9 && wcsncmp( pClassName, SAL_OBJECT_CLASSNAMEW, nLen ) == 0 )
128 pSalObj = GetSalObjWindowPtr( hWin );
130 } while( hWin && !pSalObj );
132 if ( pSalObj && pSalObj->mbInterceptChildWindowKeyDown && pSalObj->maSysData.hWnd )
134 bResult = ( 1 == ImplSendMessage( pSalObj->maSysData.hWnd, rMsg.message, rMsg.wParam, rMsg.lParam ) );
139 return bResult;
142 // -----------------------------------------------------------------------
145 // -----------------------------------------------------------------------
147 LRESULT CALLBACK SalSysMsgProc( int nCode, WPARAM wParam, LPARAM lParam )
149 // Used for Unicode and none Unicode
150 SalData* pSalData = GetSalData();
152 if ( (nCode >= 0) && lParam )
154 CWPSTRUCT* pData = (CWPSTRUCT*)lParam;
155 if ( (pData->message != WM_KEYDOWN) &&
156 (pData->message != WM_KEYUP) )
157 pSalData->mnSalObjWantKeyEvt = 0;
159 // Testen, ob wir Daten fuer ein SalObject-Fenster behandeln
160 // muessen
161 WinSalObject* pObject;
162 if ( pData->message == WM_SETFOCUS )
164 pObject = ImplFindSalObject( pData->hwnd );
165 if ( pObject )
167 pObject->mhLastFocusWnd = pData->hwnd;
168 if ( ImplSalYieldMutexTryToAcquire() )
170 pObject->CallCallback( SALOBJ_EVENT_GETFOCUS, 0 );
171 ImplSalYieldMutexRelease();
173 else
174 ImplPostMessage( pObject->mhWnd, SALOBJ_MSG_POSTFOCUS, 0, 0 );
177 else if ( pData->message == WM_KILLFOCUS )
179 pObject = ImplFindSalObject( pData->hwnd );
180 if ( pObject && !ImplFindSalObject( (HWND)pData->wParam ) )
182 // LoseFocus nur rufen, wenn wirklich kein ChildFenster
183 // den Focus bekommt
184 if ( !pData->wParam || !ImplFindSalObject( (HWND)pData->wParam ) )
186 if ( ImplSalYieldMutexTryToAcquire() )
188 pObject->CallCallback( SALOBJ_EVENT_LOSEFOCUS, 0 );
189 ImplSalYieldMutexRelease();
191 else
192 ImplPostMessage( pObject->mhWnd, SALOBJ_MSG_POSTFOCUS, 0, 0 );
194 else
195 pObject->mhLastFocusWnd = (HWND)pData->wParam;
200 return CallNextHookEx( pSalData->mhSalObjMsgHook, nCode, wParam, lParam );
203 // -----------------------------------------------------------------------
205 sal_Bool ImplSalPreDispatchMsg( MSG* pMsg )
207 // Used for Unicode and none Unicode
208 SalData* pSalData = GetSalData();
209 WinSalObject* pObject;
211 if ( (pMsg->message == WM_LBUTTONDOWN) ||
212 (pMsg->message == WM_RBUTTONDOWN) ||
213 (pMsg->message == WM_MBUTTONDOWN) )
215 ImplSalYieldMutexAcquireWithWait();
216 pObject = ImplFindSalObject( pMsg->hwnd );
217 if ( pObject && !pObject->IsMouseTransparent() )
218 ImplPostMessage( pObject->mhWnd, SALOBJ_MSG_TOTOP, 0, 0 );
219 ImplSalYieldMutexRelease();
222 if ( (pMsg->message == WM_KEYDOWN) ||
223 (pMsg->message == WM_KEYUP) )
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)) )
235 if ( GetKeyState( VK_CONTROL ) & 0x8000 )
236 bWantedKeyCode = TRUE;
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 )
246 ImplSalYieldMutexAcquireWithWait();
247 pObject = ImplFindSalObject( pMsg->hwnd );
248 if ( pObject )
249 pSalData->mnSalObjWantKeyEvt = pMsg->wParam;
250 ImplSalYieldMutexRelease();
253 // Hier WM_SYSCHAR abfangen, um mit Alt+Taste evtl. Menu zu aktivieren
254 else if ( pMsg->message == WM_SYSCHAR )
256 pSalData->mnSalObjWantKeyEvt = 0;
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)) )
264 sal_Bool bRet = FALSE;
265 ImplSalYieldMutexAcquireWithWait();
266 pObject = ImplFindSalObject( pMsg->hwnd );
267 if ( pObject )
269 if ( pMsg->hwnd == ::GetFocus() )
271 WinSalFrame* pFrame = ImplFindSalObjectFrame( pMsg->hwnd );
272 if ( pFrame )
274 if ( ImplHandleSalObjSysCharMsg( pFrame->mhWnd, pMsg->wParam, pMsg->lParam ) )
275 bRet = TRUE;
279 ImplSalYieldMutexRelease();
280 if ( bRet )
281 return TRUE;
284 else
285 pSalData->mnSalObjWantKeyEvt = 0;
287 return FALSE;
290 // -----------------------------------------------------------------------
292 void ImplSalPostDispatchMsg( MSG* pMsg, LRESULT /* nDispatchResult */ )
294 // Used for Unicode and none Unicode
295 SalData* pSalData = GetSalData();
296 WinSalFrame* pFrame;
298 if ( (pMsg->message == WM_KEYDOWN) || (pMsg->message == WM_KEYUP) )
300 if ( pSalData->mnSalObjWantKeyEvt == pMsg->wParam )
302 pSalData->mnSalObjWantKeyEvt = 0;
303 if ( pMsg->hwnd == ::GetFocus() )
305 ImplSalYieldMutexAcquireWithWait();
306 pFrame = ImplFindSalObjectFrame( pMsg->hwnd );
307 if ( pFrame )
308 ImplHandleSalObjKeyMsg( pFrame->mhWnd, pMsg->message, pMsg->wParam, pMsg->lParam );
309 ImplSalYieldMutexRelease();
314 pSalData->mnSalObjWantKeyEvt = 0;
317 // =======================================================================
319 LRESULT CALLBACK SalSysObjWndProc( HWND hWnd, UINT nMsg, WPARAM wParam, LPARAM lParam, int& rDef )
321 WinSalObject* pSysObj;
322 LRESULT nRet = 0;
324 switch( nMsg )
326 case WM_ERASEBKGND:
327 nRet = 1;
328 rDef = FALSE;
329 break;
330 case WM_PAINT:
332 PAINTSTRUCT aPs;
333 BeginPaint( hWnd, &aPs );
334 EndPaint( hWnd, &aPs );
335 rDef = FALSE;
337 break;
339 case WM_PARENTNOTIFY:
341 UINT nNotifyMsg = LOWORD( wParam );
342 if ( (nNotifyMsg == WM_LBUTTONDOWN) ||
343 (nNotifyMsg == WM_RBUTTONDOWN) ||
344 (nNotifyMsg == WM_MBUTTONDOWN) )
346 ImplSalYieldMutexAcquireWithWait();
347 pSysObj = GetSalObjWindowPtr( hWnd );
348 if ( pSysObj && !pSysObj->IsMouseTransparent() )
349 pSysObj->CallCallback( SALOBJ_EVENT_TOTOP, 0 );
350 ImplSalYieldMutexRelease();
353 break;
355 case WM_MOUSEACTIVATE:
357 ImplSalYieldMutexAcquireWithWait();
358 pSysObj = GetSalObjWindowPtr( hWnd );
359 if ( pSysObj && !pSysObj->IsMouseTransparent() )
360 ImplPostMessage( hWnd, SALOBJ_MSG_TOTOP, 0, 0 );
361 ImplSalYieldMutexRelease();
363 break;
365 case SALOBJ_MSG_TOTOP:
366 if ( ImplSalYieldMutexTryToAcquire() )
368 pSysObj = GetSalObjWindowPtr( hWnd );
369 pSysObj->CallCallback( SALOBJ_EVENT_TOTOP, 0 );
370 ImplSalYieldMutexRelease();
371 rDef = FALSE;
373 else
374 ImplPostMessage( hWnd, SALOBJ_MSG_TOTOP, 0, 0 );
375 break;
377 case SALOBJ_MSG_POSTFOCUS:
378 if ( ImplSalYieldMutexTryToAcquire() )
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();
390 else
391 ImplPostMessage( hWnd, SALOBJ_MSG_POSTFOCUS, 0, 0 );
392 rDef = FALSE;
393 break;
395 case WM_SIZE:
397 HWND hWndChild = GetWindow( hWnd, GW_CHILD );
398 if ( hWndChild )
400 SetWindowPos( hWndChild,
401 0, 0, 0, (int)LOWORD( lParam ), (int)HIWORD( lParam ),
402 SWP_NOZORDER | SWP_NOACTIVATE );
405 rDef = FALSE;
406 break;
408 case WM_CREATE:
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;
422 break;
425 return nRet;
428 LRESULT CALLBACK SalSysObjWndProcA( HWND hWnd, UINT nMsg, WPARAM wParam, LPARAM lParam )
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;
437 LRESULT CALLBACK SalSysObjWndProcW( HWND hWnd, UINT nMsg, WPARAM wParam, LPARAM lParam )
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;
446 // -----------------------------------------------------------------------
448 LRESULT CALLBACK SalSysObjChildWndProc( HWND hWnd, UINT nMsg, WPARAM wParam, LPARAM lParam, int& rDef )
450 LRESULT nRet = 0;
452 switch( nMsg )
454 // Wegen PlugIn's loeschen wir erstmal den Hintergrund
455 case WM_ERASEBKGND:
457 WinSalObject* pSysObj = GetSalObjWindowPtr( ::GetParent( hWnd ) );
459 if( pSysObj && !pSysObj->IsEraseBackgroundEnabled() )
461 // do not erase background
462 nRet = 1;
463 rDef = FALSE;
466 break;
468 case WM_PAINT:
470 PAINTSTRUCT aPs;
471 BeginPaint( hWnd, &aPs );
472 EndPaint( hWnd, &aPs );
473 rDef = FALSE;
475 break;
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:
485 WinSalObject* pSysObj;
486 pSysObj = GetSalObjWindowPtr( ::GetParent( hWnd ) );
488 if( pSysObj && pSysObj->IsMouseTransparent() )
490 // forward mouse events to parent frame
491 HWND hWndParent = ::GetParent( pSysObj->mhWnd );
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 );
500 nRet = ImplSendMessage( hWndParent, nMsg, wParam, lParam );
501 rDef = FALSE;
504 break;
507 return nRet;
510 LRESULT CALLBACK SalSysObjChildWndProcA( HWND hWnd, UINT nMsg, WPARAM wParam, LPARAM lParam )
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;
519 LRESULT CALLBACK SalSysObjChildWndProcW( HWND hWnd, UINT nMsg, WPARAM wParam, LPARAM lParam )
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;
528 // =======================================================================
530 SalObject* ImplSalCreateObject( WinSalInstance* pInst, WinSalFrame* pParent )
532 SalData* pSalData = GetSalData();
534 // Hook installieren, wenn es das erste SalObject ist
535 if ( !pSalData->mpFirstObject )
537 pSalData->mhSalObjMsgHook = SetWindowsHookExW( WH_CALLWNDPROC,
538 SalSysMsgProc,
539 pSalData->mhInst,
540 pSalData->mnAppThreadId );
543 if ( !pSalData->mbObjClassInit )
545 // #95301# shockwave plugin has bug; expects ASCII functions to be used
546 if ( false )//aSalShlData.mbWNT )
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 ) )
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;
572 else
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 ) )
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;
600 if ( pSalData->mbObjClassInit )
602 WinSalObject* pObject = new WinSalObject;
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 );
613 HWND hWndChild = 0;
614 if ( hWnd )
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 );
628 if ( !hWndChild )
630 delete pObject;
631 return NULL;
634 if ( hWnd )
636 pObject->mhWnd = hWnd;
637 pObject->mhWndChild = hWndChild;
638 pObject->maSysData.hWnd = hWndChild;
639 return pObject;
643 return NULL;
646 // =======================================================================
648 WinSalObject::WinSalObject()
650 SalData* pSalData = GetSalData();
652 mhWnd = 0;
653 mhWndChild = 0;
654 mhLastFocusWnd = 0;
655 maSysData.nSize = sizeof( SystemEnvData );
656 mpStdClipRgnData = NULL;
657 mbInterceptChildWindowKeyDown = sal_False;
659 // Insert object in objectlist
660 mpNextObject = pSalData->mpFirstObject;
661 pSalData->mpFirstObject = this;
664 // -----------------------------------------------------------------------
666 WinSalObject::~WinSalObject()
668 SalData* pSalData = GetSalData();
670 // remove frame from framelist
671 if ( this == pSalData->mpFirstObject )
673 pSalData->mpFirstObject = mpNextObject;
675 // Wenn letztes SalObject, dann Hook wieder entfernen
676 if ( !pSalData->mpFirstObject )
677 UnhookWindowsHookEx( pSalData->mhSalObjMsgHook );
679 else
681 WinSalObject* pTempObject = pSalData->mpFirstObject;
682 while ( pTempObject->mpNextObject != this )
683 pTempObject = pTempObject->mpNextObject;
685 pTempObject->mpNextObject = mpNextObject;
688 // Cache-Daten zerstoeren
689 if ( mpStdClipRgnData )
690 delete mpStdClipRgnData;
692 HWND hWndParent = ::GetParent( mhWnd );
694 if ( mhWndChild )
695 DestroyWindow( mhWndChild );
696 if ( mhWnd )
697 DestroyWindow( mhWnd );
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 );
708 // -----------------------------------------------------------------------
710 void WinSalObject::ResetClipRegion()
712 SetWindowRgn( mhWnd, 0, TRUE );
715 // -----------------------------------------------------------------------
717 sal_uInt16 WinSalObject::GetClipRegionType()
719 return SAL_OBJECT_CLIP_INCLUDERECTS;
722 // -----------------------------------------------------------------------
724 void WinSalObject::BeginSetClipRegion( sal_uLong nRectCount )
726 sal_uLong nRectBufSize = sizeof(RECT)*nRectCount;
727 if ( nRectCount < SAL_CLIPRECT_COUNT )
729 if ( !mpStdClipRgnData )
730 mpStdClipRgnData = (RGNDATA*)new BYTE[sizeof(RGNDATA)-1+(SAL_CLIPRECT_COUNT*sizeof(RECT))];
731 mpClipRgnData = mpStdClipRgnData;
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;
744 // -----------------------------------------------------------------------
746 void WinSalObject::UnionClipRegion( long nX, long nY, long nWidth, long nHeight )
748 RECT* pRect = mpNextClipRect;
749 RECT* pBoundRect = &(mpClipRgnData->rdh.rcBound);
750 long nRight = nX + nWidth;
751 long nBottom = nY + nHeight;
753 if ( mbFirstClipRect )
755 pBoundRect->left = nX;
756 pBoundRect->top = nY;
757 pBoundRect->right = nRight;
758 pBoundRect->bottom = nBottom;
759 mbFirstClipRect = FALSE;
761 else
763 if ( nX < pBoundRect->left )
764 pBoundRect->left = (int)nX;
766 if ( nY < pBoundRect->top )
767 pBoundRect->top = (int)nY;
769 if ( nRight > pBoundRect->right )
770 pBoundRect->right = (int)nRight;
772 if ( nBottom > pBoundRect->bottom )
773 pBoundRect->bottom = (int)nBottom;
776 pRect->left = (int)nX;
777 pRect->top = (int)nY;
778 pRect->right = (int)nRight;
779 pRect->bottom = (int)nBottom;
780 mpNextClipRect++;
783 // -----------------------------------------------------------------------
785 void WinSalObject::EndSetClipRegion()
787 HRGN hRegion;
789 // Aus den Region-Daten muessen wir jetzt eine ClipRegion erzeugen
790 if ( mpClipRgnData->rdh.nCount == 1 )
792 RECT* pRect = &(mpClipRgnData->rdh.rcBound);
793 hRegion = CreateRectRgn( pRect->left, pRect->top,
794 pRect->right, pRect->bottom );
796 else
798 sal_uLong nSize = mpClipRgnData->rdh.nRgnSize+sizeof(RGNDATAHEADER);
799 hRegion = ExtCreateRegion( NULL, nSize, mpClipRgnData );
800 if ( mpClipRgnData != mpStdClipRgnData )
801 delete [] (BYTE*)mpClipRgnData;
804 DBG_ASSERT( hRegion, "SalObject::EndSetClipRegion() - Can't create ClipRegion" );
805 SetWindowRgn( mhWnd, hRegion, TRUE );
808 // -----------------------------------------------------------------------
810 void WinSalObject::SetPosSize( long nX, long nY, long nWidth, long nHeight )
812 sal_uLong nStyle = 0;
813 sal_Bool bVisible = (GetWindowStyle( mhWnd ) & WS_VISIBLE) != 0;
814 if ( bVisible )
816 ShowWindow( mhWnd, SW_HIDE );
817 nStyle |= SWP_SHOWWINDOW;
819 SetWindowPos( mhWnd, 0,
820 (int)nX, (int)nY, (int)nWidth, (int)nHeight,
821 SWP_NOZORDER | SWP_NOACTIVATE | nStyle );
824 // -----------------------------------------------------------------------
826 void WinSalObject::Show( sal_Bool bVisible )
828 if ( bVisible )
829 ShowWindow( mhWnd, SW_SHOWNORMAL );
830 else
831 ShowWindow( mhWnd, SW_HIDE );
834 // -----------------------------------------------------------------------
836 void WinSalObject::Enable( sal_Bool bEnable )
838 EnableWindow( mhWnd, bEnable );
841 // -----------------------------------------------------------------------
843 void WinSalObject::GrabFocus()
845 if ( mhLastFocusWnd &&
846 IsWindow( mhLastFocusWnd ) &&
847 ImplIsSysWindowOrChild( mhWndChild, mhLastFocusWnd ) )
848 ::SetFocus( mhLastFocusWnd );
849 else
850 ::SetFocus( mhWndChild );
853 // -----------------------------------------------------------------------
855 void WinSalObject::SetBackground()
859 // -----------------------------------------------------------------------
861 void WinSalObject::SetBackground( SalColor )
865 // -----------------------------------------------------------------------
867 const SystemEnvData* WinSalObject::GetSystemData() const
869 return &maSysData;
872 // -----------------------------------------------------------------------
874 void WinSalObject::InterceptChildWindowKeyDown( sal_Bool bIntercept )
876 mbInterceptChildWindowKeyDown = bIntercept;