bump product version to 7.6.3.2-android
[LibreOffice.git] / vcl / win / window / salobj.cxx
blob05ad16b0d4cda7a3082cb27e02b06b1b242fc924
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
9 * This file incorporates work covered by the following license notice:
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
20 #include <string.h>
22 #include <svsys.h>
24 #include <vcl/svapp.hxx>
25 #include <sal/log.hxx>
27 #include <win/wincomp.hxx>
28 #include <win/saldata.hxx>
29 #include <win/salinst.h>
30 #include <win/salframe.h>
31 #include <win/salobj.h>
33 #include <comphelper/windowserrorstring.hxx>
35 static bool ImplIsSysWindowOrChild( HWND hWndParent, HWND hWndChild )
37 if ( hWndParent == hWndChild )
38 return true;
40 HWND hTempWnd = ::GetParent( hWndChild );
41 while ( hTempWnd )
43 // stop searching if not a child window
44 if ( !(GetWindowStyle( hTempWnd ) & WS_CHILD) )
45 return false;
46 if ( hTempWnd == hWndParent )
47 return true;
48 hTempWnd = ::GetParent( hTempWnd );
51 return false;
54 WinSalObject* ImplFindSalObject( HWND hWndChild )
56 SalData* pSalData = GetSalData();
57 WinSalObject* pObject = pSalData->mpFirstObject;
58 while ( pObject )
60 if ( ImplIsSysWindowOrChild( pObject->mhWndChild, hWndChild ) )
61 return pObject;
63 pObject = pObject->mpNextObject;
66 return nullptr;
69 static WinSalFrame* ImplFindSalObjectFrame( HWND hWnd )
71 WinSalFrame* pFrame = nullptr;
72 WinSalObject* pObject = ImplFindSalObject( hWnd );
73 if ( pObject )
75 // find matching frame
76 HWND hWnd2 = ::GetParent( pObject->mhWnd );
77 pFrame = GetSalData()->mpFirstFrame;
78 while ( pFrame )
80 if ( pFrame->mhWnd == hWnd2 )
81 break;
83 pFrame = pFrame->mpNextFrame;
87 return pFrame;
90 static LRESULT CALLBACK SalSysMsgProc( int nCode, WPARAM wParam, LPARAM lParam )
92 // Used for Unicode and none Unicode
93 SalData* pSalData = GetSalData();
95 if ( (nCode >= 0) && lParam )
97 CWPSTRUCT* pData = reinterpret_cast<CWPSTRUCT*>(lParam);
98 if ( (pData->message != WM_KEYDOWN) &&
99 (pData->message != WM_KEYUP) )
100 pSalData->mnSalObjWantKeyEvt = 0;
103 // check if we need to process data for a SalObject-window
104 WinSalObject* pObject;
105 if ( pData->message == WM_SETFOCUS )
107 pObject = ImplFindSalObject( pData->hwnd );
108 if ( pObject )
110 pObject->mhLastFocusWnd = pData->hwnd;
111 if ( ImplSalYieldMutexTryToAcquire() )
113 pObject->CallCallback( SalObjEvent::GetFocus );
114 ImplSalYieldMutexRelease();
116 else
118 bool const ret = PostMessageW(pObject->mhWnd, SALOBJ_MSG_POSTFOCUS, 0, 0);
119 SAL_WARN_IF(!ret, "vcl", "ERROR: PostMessage() failed!");
123 else if ( pData->message == WM_KILLFOCUS )
125 pObject = ImplFindSalObject( pData->hwnd );
126 if ( pObject && !ImplFindSalObject( reinterpret_cast<HWND>(pData->wParam) ) )
128 // only call LoseFocus, if truly no child window gets the focus
129 if ( !pData->wParam || !ImplFindSalObject( reinterpret_cast<HWND>(pData->wParam) ) )
131 if ( ImplSalYieldMutexTryToAcquire() )
133 pObject->CallCallback( SalObjEvent::LoseFocus );
134 ImplSalYieldMutexRelease();
136 else
138 bool const ret = PostMessageW(pObject->mhWnd, SALOBJ_MSG_POSTFOCUS, 0, 0);
139 SAL_WARN_IF(!ret, "vcl", "ERROR: PostMessage() failed!");
142 else
143 pObject->mhLastFocusWnd = reinterpret_cast<HWND>(pData->wParam);
148 return CallNextHookEx( pSalData->mhSalObjMsgHook, nCode, wParam, lParam );
151 bool ImplSalPreDispatchMsg( const MSG* pMsg )
153 // Used for Unicode and none Unicode
154 SalData* pSalData = GetSalData();
155 WinSalObject* pObject;
157 if ( (pMsg->message == WM_LBUTTONDOWN) ||
158 (pMsg->message == WM_RBUTTONDOWN) ||
159 (pMsg->message == WM_MBUTTONDOWN) )
161 ImplSalYieldMutexAcquireWithWait();
162 pObject = ImplFindSalObject( pMsg->hwnd );
163 if ( pObject && !pObject->IsMouseTransparent() )
165 bool const ret = PostMessageW(pObject->mhWnd, SALOBJ_MSG_TOTOP, 0, 0);
166 SAL_WARN_IF(!ret, "vcl", "ERROR: PostMessage() failed!");
168 ImplSalYieldMutexRelease();
171 if ( (pMsg->message == WM_KEYDOWN) ||
172 (pMsg->message == WM_KEYUP) )
174 // process KeyEvents even if the control does not process them itself
175 // SysKeys are processed as WM_SYSCOMMAND
176 // Char-Events are not processed, as they are not accelerator-relevant
177 bool bWantedKeyCode = false;
178 // A-Z, 0-9 only when combined with the Control-key
179 if ( ((pMsg->wParam >= 65) && (pMsg->wParam <= 90)) ||
180 ((pMsg->wParam >= 48) && (pMsg->wParam <= 57)) )
182 if ( GetKeyState( VK_CONTROL ) & 0x8000 )
183 bWantedKeyCode = true;
185 else if ( ((pMsg->wParam >= VK_F1) && (pMsg->wParam <= VK_F24)) ||
186 ((pMsg->wParam >= VK_SPACE) && (pMsg->wParam <= VK_HELP)) ||
187 (pMsg->wParam == VK_BACK) || (pMsg->wParam == VK_TAB) ||
188 (pMsg->wParam == VK_CLEAR) || (pMsg->wParam == VK_RETURN) ||
189 (pMsg->wParam == VK_ESCAPE) )
190 bWantedKeyCode = true;
191 if ( bWantedKeyCode )
193 ImplSalYieldMutexAcquireWithWait();
194 pObject = ImplFindSalObject( pMsg->hwnd );
195 if ( pObject )
196 pSalData->mnSalObjWantKeyEvt = pMsg->wParam;
197 ImplSalYieldMutexRelease();
200 // check WM_SYSCHAR, to activate menu with Alt key
201 else if ( pMsg->message == WM_SYSCHAR )
203 pSalData->mnSalObjWantKeyEvt = 0;
205 sal_uInt16 nKeyCode = LOWORD( pMsg->wParam );
206 // only 0-9 and A-Z
207 if ( ((nKeyCode >= 48) && (nKeyCode <= 57)) ||
208 ((nKeyCode >= 65) && (nKeyCode <= 90)) ||
209 ((nKeyCode >= 97) && (nKeyCode <= 122)) )
211 bool bRet = false;
212 ImplSalYieldMutexAcquireWithWait();
213 pObject = ImplFindSalObject( pMsg->hwnd );
214 if ( pObject )
216 if ( pMsg->hwnd == ::GetFocus() )
218 WinSalFrame* pFrame = ImplFindSalObjectFrame( pMsg->hwnd );
219 if ( pFrame )
221 if ( ImplHandleSalObjSysCharMsg( pFrame->mhWnd, pMsg->wParam, pMsg->lParam ) )
222 bRet = true;
226 ImplSalYieldMutexRelease();
227 if ( bRet )
228 return true;
231 else
232 pSalData->mnSalObjWantKeyEvt = 0;
234 return false;
237 void ImplSalPostDispatchMsg( const MSG* pMsg )
239 // Used for Unicode and none Unicode
240 SalData *pSalData = GetSalData();
242 if ( (pMsg->message == WM_KEYDOWN) || (pMsg->message == WM_KEYUP) )
244 if ( pSalData->mnSalObjWantKeyEvt == pMsg->wParam )
246 pSalData->mnSalObjWantKeyEvt = 0;
247 if ( pMsg->hwnd == ::GetFocus() )
249 ImplSalYieldMutexAcquireWithWait();
250 WinSalFrame* pFrame = ImplFindSalObjectFrame( pMsg->hwnd );
251 if ( pFrame )
252 ImplHandleSalObjKeyMsg( pFrame->mhWnd, pMsg->message, pMsg->wParam, pMsg->lParam );
253 ImplSalYieldMutexRelease();
258 pSalData->mnSalObjWantKeyEvt = 0;
261 static LRESULT CALLBACK SalSysObjWndProcW(HWND hWnd, UINT nMsg, WPARAM wParam, LPARAM lParam)
263 switch( nMsg )
265 case WM_ERASEBKGND:
266 return 1;
267 case WM_PAINT:
269 PAINTSTRUCT aPs;
270 BeginPaint( hWnd, &aPs );
271 EndPaint( hWnd, &aPs );
273 return 0;
275 case WM_PARENTNOTIFY:
276 if (UINT nNotifyMsg = LOWORD(wParam);
277 (nNotifyMsg == WM_LBUTTONDOWN) ||
278 (nNotifyMsg == WM_RBUTTONDOWN) ||
279 (nNotifyMsg == WM_MBUTTONDOWN) )
281 ImplSalYieldMutexAcquireWithWait();
282 WinSalObject* pSysObj = GetSalObjWindowPtr(hWnd);
283 if ( pSysObj && !pSysObj->IsMouseTransparent() )
284 pSysObj->CallCallback( SalObjEvent::ToTop );
285 ImplSalYieldMutexRelease();
287 break;
289 case WM_MOUSEACTIVATE:
290 ImplSalYieldMutexAcquireWithWait();
291 if (WinSalObject* pSysObj = GetSalObjWindowPtr(hWnd);
292 pSysObj && !pSysObj->IsMouseTransparent())
294 bool const ret = PostMessageW( hWnd, SALOBJ_MSG_TOTOP, 0, 0 );
295 SAL_WARN_IF(!ret, "vcl", "ERROR: PostMessage() failed!");
297 ImplSalYieldMutexRelease();
298 break;
300 case SALOBJ_MSG_TOTOP:
301 if ( ImplSalYieldMutexTryToAcquire() )
303 if (WinSalObject* pSysObj = GetSalObjWindowPtr(hWnd))
304 pSysObj->CallCallback(SalObjEvent::ToTop);
305 ImplSalYieldMutexRelease();
306 return 0;
308 else
310 bool const ret = PostMessageW( hWnd, SALOBJ_MSG_TOTOP, 0, 0 );
311 SAL_WARN_IF(!ret, "vcl", "ERROR: PostMessage() failed!");
313 break;
315 case SALOBJ_MSG_POSTFOCUS:
316 if ( ImplSalYieldMutexTryToAcquire() )
318 WinSalObject* pSysObj = GetSalObjWindowPtr(hWnd);
319 HWND hFocusWnd = ::GetFocus();
320 SalObjEvent nEvent;
321 if ( hFocusWnd && ImplIsSysWindowOrChild( hWnd, hFocusWnd ) )
322 nEvent = SalObjEvent::GetFocus;
323 else
324 nEvent = SalObjEvent::LoseFocus;
325 pSysObj->CallCallback( nEvent );
326 ImplSalYieldMutexRelease();
328 else
330 bool const ret = PostMessageW(hWnd, SALOBJ_MSG_POSTFOCUS, 0, 0);
331 SAL_WARN_IF(!ret, "vcl", "ERROR: PostMessage() failed!");
333 return 0;
335 case WM_SIZE:
336 if (HWND hWndChild = GetWindow(hWnd, GW_CHILD))
338 SetWindowPos( hWndChild,
339 nullptr, 0, 0, static_cast<int>(LOWORD( lParam )), static_cast<int>(HIWORD( lParam )),
340 SWP_NOZORDER | SWP_NOACTIVATE );
342 return 0;
344 case WM_CREATE:
346 // Save the window instance at the window handle.
347 CREATESTRUCTW* pStruct = reinterpret_cast<CREATESTRUCTW*>(lParam);
348 WinSalObject* pSysObj = static_cast<WinSalObject*>(pStruct->lpCreateParams);
349 SetSalObjWindowPtr( hWnd, pSysObj );
350 // set HWND already here,
351 // as instance data might be used during CreateWindow() events
352 pSysObj->mhWnd = hWnd;
353 return 0;
357 return DefWindowProcW(hWnd, nMsg, wParam, lParam);
360 static LRESULT CALLBACK SalSysObjChildWndProcW(HWND hWnd, UINT nMsg, WPARAM wParam, LPARAM lParam)
362 switch( nMsg )
364 // clear background for plugins
365 case WM_ERASEBKGND:
366 if (WinSalObject* pSysObj = GetSalObjWindowPtr(GetParent(hWnd));
367 pSysObj && !pSysObj->IsEraseBackgroundEnabled())
369 // do not erase background
370 return 1;
372 break;
374 case WM_PAINT:
376 PAINTSTRUCT aPs;
377 BeginPaint( hWnd, &aPs );
378 EndPaint( hWnd, &aPs );
380 return 0;
382 case WM_MOUSEMOVE:
383 case WM_LBUTTONDOWN:
384 case WM_MBUTTONDOWN:
385 case WM_RBUTTONDOWN:
386 case WM_LBUTTONUP:
387 case WM_MBUTTONUP:
388 case WM_RBUTTONUP:
389 if (WinSalObject* pSysObj = GetSalObjWindowPtr(GetParent(hWnd));
390 pSysObj && pSysObj->IsMouseTransparent())
392 // forward mouse events to parent frame
393 HWND hWndParent = GetParent(pSysObj->mhWnd);
395 // transform coordinates
396 POINT pt;
397 pt.x = static_cast<tools::Long>(LOWORD(lParam));
398 pt.y = static_cast<tools::Long>(HIWORD(lParam));
399 MapWindowPoints(hWnd, hWndParent, &pt, 1);
400 lParam = MAKELPARAM(static_cast<WORD>(pt.x), static_cast<WORD>(pt.y));
402 return SendMessageW(hWndParent, nMsg, wParam, lParam);
404 break;
407 return DefWindowProcW(hWnd, nMsg, wParam, lParam);
410 SalObject* ImplSalCreateObject( WinSalInstance* pInst, WinSalFrame* pParent )
412 SalData* pSalData = GetSalData();
414 // install hook, if it is the first SalObject
415 if ( !pSalData->mpFirstObject )
417 pSalData->mhSalObjMsgHook = SetWindowsHookExW( WH_CALLWNDPROC,
418 SalSysMsgProc,
419 pSalData->mhInst,
420 pSalData->mnAppThreadId );
423 if ( !pSalData->mbObjClassInit )
425 WNDCLASSEXW aWndClassEx;
426 aWndClassEx.cbSize = sizeof( aWndClassEx );
427 aWndClassEx.style = 0;
428 aWndClassEx.lpfnWndProc = SalSysObjWndProcW;
429 aWndClassEx.cbClsExtra = 0;
430 aWndClassEx.cbWndExtra = SAL_OBJECT_WNDEXTRA;
431 aWndClassEx.hInstance = pSalData->mhInst;
432 aWndClassEx.hIcon = nullptr;
433 aWndClassEx.hIconSm = nullptr;
434 aWndClassEx.hCursor = LoadCursor( nullptr, IDC_ARROW );
435 aWndClassEx.hbrBackground = nullptr;
436 aWndClassEx.lpszMenuName = nullptr;
437 aWndClassEx.lpszClassName = SAL_OBJECT_CLASSNAMEW;
438 if ( RegisterClassExW( &aWndClassEx ) )
440 // Clean background first because of plugins.
441 aWndClassEx.cbWndExtra = 0;
442 aWndClassEx.hbrBackground = reinterpret_cast<HBRUSH>(COLOR_WINDOW+1);
443 aWndClassEx.lpfnWndProc = SalSysObjChildWndProcW;
444 aWndClassEx.lpszClassName = SAL_OBJECT_CHILDCLASSNAMEW;
445 if ( RegisterClassExW( &aWndClassEx ) )
446 pSalData->mbObjClassInit = true;
450 if ( pSalData->mbObjClassInit )
452 WinSalObject* pObject = new WinSalObject;
454 // #135235# Clip siblings of this
455 // SystemChildWindow. Otherwise, DXCanvas (using a hidden
456 // SystemChildWindow) clobbers applets/plugins during
457 // animations .
458 HWND hWnd = CreateWindowExW( 0, SAL_OBJECT_CLASSNAMEW, L"",
459 WS_CHILD | WS_CLIPSIBLINGS, 0, 0, 0, 0,
460 pParent->mhWnd, nullptr,
461 pInst->mhInst, pObject );
463 HWND hWndChild = nullptr;
464 if ( hWnd )
466 // #135235# Explicitly stack SystemChildWindows in
467 // the order they're created - since there's no notion
468 // of zorder.
469 SetWindowPos(hWnd,HWND_TOP,0,0,0,0,
470 SWP_NOACTIVATE|SWP_NOMOVE|SWP_NOREDRAW|SWP_NOSIZE);
471 hWndChild = CreateWindowExW( 0, SAL_OBJECT_CHILDCLASSNAMEW, L"",
472 WS_CHILD | WS_CLIPCHILDREN | WS_CLIPSIBLINGS | WS_VISIBLE,
473 0, 0, 0, 0,
474 hWnd, nullptr,
475 pInst->mhInst, nullptr );
478 if ( !hWndChild )
480 SAL_WARN("vcl", "CreateWindowExW failed: " << WindowsErrorString(GetLastError()));
482 delete pObject;
483 return nullptr;
486 if ( hWnd )
488 pObject->mhWnd = hWnd;
489 pObject->mhWndChild = hWndChild;
490 pObject->maSysData.hWnd = hWndChild;
491 return pObject;
495 return nullptr;
498 WinSalObject::WinSalObject()
500 SalData* pSalData = GetSalData();
502 mhWnd = nullptr;
503 mhWndChild = nullptr;
504 mhLastFocusWnd = nullptr;
505 mpStdClipRgnData = nullptr;
507 // Insert object in objectlist
508 mpNextObject = pSalData->mpFirstObject;
509 pSalData->mpFirstObject = this;
512 WinSalObject::~WinSalObject()
514 SalData* pSalData = GetSalData();
516 // remove frame from framelist
517 if ( this == pSalData->mpFirstObject )
519 pSalData->mpFirstObject = mpNextObject;
521 // remove hook, if it is the last SalObject
522 if ( !pSalData->mpFirstObject )
523 UnhookWindowsHookEx( pSalData->mhSalObjMsgHook );
525 else
527 WinSalObject* pTempObject = pSalData->mpFirstObject;
528 while ( pTempObject->mpNextObject != this )
529 pTempObject = pTempObject->mpNextObject;
531 pTempObject->mpNextObject = mpNextObject;
534 // destroy cache data
535 delete [] reinterpret_cast<BYTE*>(mpStdClipRgnData);
537 HWND hWndParent = ::GetParent( mhWnd );
539 if ( mhWndChild )
540 DestroyWindow( mhWndChild );
541 if ( mhWnd )
542 DestroyWindow( mhWnd );
544 // reset palette, if no external child window is left,
545 // as they might have overwritten our palette
546 if ( hWndParent &&
547 ::GetActiveWindow() == hWndParent &&
548 !GetWindow( hWndParent, GW_CHILD ) )
549 SendMessageW( hWndParent, SAL_MSG_FORCEPALETTE, 0, 0 );
552 void WinSalObject::ResetClipRegion()
554 SetWindowRgn( mhWnd, nullptr, TRUE );
557 void WinSalObject::BeginSetClipRegion( sal_uInt32 nRectCount )
559 sal_uLong nRectBufSize = sizeof(RECT)*nRectCount;
560 if ( nRectCount < SAL_CLIPRECT_COUNT )
562 if ( !mpStdClipRgnData )
563 mpStdClipRgnData = reinterpret_cast<RGNDATA*>(new BYTE[sizeof(RGNDATA)-1+(SAL_CLIPRECT_COUNT*sizeof(RECT))]);
564 mpClipRgnData = mpStdClipRgnData;
566 else
567 mpClipRgnData = reinterpret_cast<RGNDATA*>(new BYTE[sizeof(RGNDATA)-1+nRectBufSize]);
568 mpClipRgnData->rdh.dwSize = sizeof( RGNDATAHEADER );
569 mpClipRgnData->rdh.iType = RDH_RECTANGLES;
570 mpClipRgnData->rdh.nCount = nRectCount;
571 mpClipRgnData->rdh.nRgnSize = nRectBufSize;
572 SetRectEmpty( &(mpClipRgnData->rdh.rcBound) );
573 mpNextClipRect = reinterpret_cast<RECT*>(&(mpClipRgnData->Buffer));
574 mbFirstClipRect = true;
577 void WinSalObject::UnionClipRegion( tools::Long nX, tools::Long nY, tools::Long nWidth, tools::Long nHeight )
579 RECT* pRect = mpNextClipRect;
580 RECT* pBoundRect = &(mpClipRgnData->rdh.rcBound);
581 tools::Long nRight = nX + nWidth;
582 tools::Long nBottom = nY + nHeight;
584 if ( mbFirstClipRect )
586 pBoundRect->left = nX;
587 pBoundRect->top = nY;
588 pBoundRect->right = nRight;
589 pBoundRect->bottom = nBottom;
590 mbFirstClipRect = false;
592 else
594 if ( nX < pBoundRect->left )
595 pBoundRect->left = static_cast<int>(nX);
597 if ( nY < pBoundRect->top )
598 pBoundRect->top = static_cast<int>(nY);
600 if ( nRight > pBoundRect->right )
601 pBoundRect->right = static_cast<int>(nRight);
603 if ( nBottom > pBoundRect->bottom )
604 pBoundRect->bottom = static_cast<int>(nBottom);
607 pRect->left = static_cast<int>(nX);
608 pRect->top = static_cast<int>(nY);
609 pRect->right = static_cast<int>(nRight);
610 pRect->bottom = static_cast<int>(nBottom);
611 mpNextClipRect++;
614 void WinSalObject::EndSetClipRegion()
616 HRGN hRegion;
618 // create a ClipRegion from the vcl::Region data
619 if ( mpClipRgnData->rdh.nCount == 1 )
621 RECT* pRect = &(mpClipRgnData->rdh.rcBound);
622 hRegion = CreateRectRgn( pRect->left, pRect->top,
623 pRect->right, pRect->bottom );
625 else
627 sal_uLong nSize = mpClipRgnData->rdh.nRgnSize+sizeof(RGNDATAHEADER);
628 hRegion = ExtCreateRegion( nullptr, nSize, mpClipRgnData );
629 if ( mpClipRgnData != mpStdClipRgnData )
630 delete [] reinterpret_cast<BYTE*>(mpClipRgnData);
633 SAL_WARN_IF( !hRegion, "vcl", "SalObject::EndSetClipRegion() - Can't create ClipRegion" );
634 SetWindowRgn( mhWnd, hRegion, TRUE );
637 void WinSalObject::SetPosSize( tools::Long nX, tools::Long nY, tools::Long nWidth, tools::Long nHeight )
639 sal_uLong nStyle = 0;
640 bool bVisible = (GetWindowStyle( mhWnd ) & WS_VISIBLE) != 0;
641 if ( bVisible )
643 ShowWindow( mhWnd, SW_HIDE );
644 nStyle |= SWP_SHOWWINDOW;
646 SetWindowPos( mhWnd, nullptr,
647 static_cast<int>(nX), static_cast<int>(nY), static_cast<int>(nWidth), static_cast<int>(nHeight),
648 SWP_NOZORDER | SWP_NOACTIVATE | nStyle );
651 void WinSalObject::Show( bool bVisible )
653 if ( bVisible )
654 ShowWindow( mhWnd, SW_SHOWNORMAL );
655 else
656 ShowWindow( mhWnd, SW_HIDE );
659 void WinSalObject::Enable( bool bEnable )
661 EnableWindow( mhWnd, bEnable );
664 void WinSalObject::GrabFocus()
666 if ( mhLastFocusWnd &&
667 IsWindow( mhLastFocusWnd ) &&
668 ImplIsSysWindowOrChild( mhWndChild, mhLastFocusWnd ) )
669 ::SetFocus( mhLastFocusWnd );
670 else
671 ::SetFocus( mhWndChild );
674 const SystemEnvData* WinSalObject::GetSystemData() const
676 return &maSysData;
679 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */