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
ImplIsSysWindowOrChild(HWND hWndParent,HWND hWndChild)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
ImplFindSalObject(HWND hWndChild)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
ImplFindSalObjectFrame(HWND hWnd)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
ImplInterceptChildWindowKeyDown(MSG & rMsg)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
SalSysMsgProc(int nCode,WPARAM wParam,LPARAM lParam)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
ImplSalPreDispatchMsg(MSG * pMsg)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
ImplSalPostDispatchMsg(MSG * pMsg,LRESULT)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
SalSysObjWndProc(HWND hWnd,UINT nMsg,WPARAM wParam,LPARAM lParam,int & rDef)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
SalSysObjWndProcA(HWND hWnd,UINT nMsg,WPARAM wParam,LPARAM lParam)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
SalSysObjWndProcW(HWND hWnd,UINT nMsg,WPARAM wParam,LPARAM lParam)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
SalSysObjChildWndProc(HWND hWnd,UINT nMsg,WPARAM wParam,LPARAM lParam,int & rDef)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
SalSysObjChildWndProcA(HWND hWnd,UINT nMsg,WPARAM wParam,LPARAM lParam)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
SalSysObjChildWndProcW(HWND hWnd,UINT nMsg,WPARAM wParam,LPARAM lParam)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
ImplSalCreateObject(WinSalInstance * pInst,WinSalFrame * pParent)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# Explicitly 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
WinSalObject()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
~WinSalObject()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
ResetClipRegion()706 void WinSalObject::ResetClipRegion()
707 {
708 SetWindowRgn( mhWnd, 0, TRUE );
709 }
710
711 // -----------------------------------------------------------------------
712
GetClipRegionType()713 sal_uInt16 WinSalObject::GetClipRegionType()
714 {
715 return SAL_OBJECT_CLIP_INCLUDERECTS;
716 }
717
718 // -----------------------------------------------------------------------
719
BeginSetClipRegion(sal_uLong nRectCount)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
UnionClipRegion(long nX,long nY,long nWidth,long nHeight)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
EndSetClipRegion()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
SetPosSize(long nX,long nY,long nWidth,long nHeight)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
Show(sal_Bool bVisible)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
Enable(sal_Bool bEnable)832 void WinSalObject::Enable( sal_Bool bEnable )
833 {
834 EnableWindow( mhWnd, bEnable );
835 }
836
837 // -----------------------------------------------------------------------
838
GrabFocus()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
SetBackground()851 void WinSalObject::SetBackground()
852 {
853 }
854
855 // -----------------------------------------------------------------------
856
SetBackground(SalColor)857 void WinSalObject::SetBackground( SalColor )
858 {
859 }
860
861 // -----------------------------------------------------------------------
862
GetSystemData() const863 const SystemEnvData* WinSalObject::GetSystemData() const
864 {
865 return &maSysData;
866 }
867
868 // -----------------------------------------------------------------------
869
InterceptChildWindowKeyDown(sal_Bool bIntercept)870 void WinSalObject::InterceptChildWindowKeyDown( sal_Bool bIntercept )
871 {
872 mbInterceptChildWindowKeyDown = bIntercept;
873 }
874
875