Added missing goto.
[wine.git] / windows / painting.c
blob5cc8d3f8d7a0f15c84193c1b0b65a65d34f87c07
1 /*
2 * Window painting functions
4 * Copyright 1993, 1994, 1995 Alexandre Julliard
5 * 1999 Alex Korobka
7 */
9 #include "region.h"
10 #include "win.h"
11 #include "queue.h"
12 #include "dce.h"
13 #include "heap.h"
14 #include "debug.h"
15 #include "wine/winuser16.h"
17 /* client rect in window coordinates */
19 #define GETCLIENTRECTW( wnd, r ) (r).left = (wnd)->rectClient.left - (wnd)->rectWindow.left; \
20 (r).top = (wnd)->rectClient.top - (wnd)->rectWindow.top; \
21 (r).right = (wnd)->rectClient.right - (wnd)->rectWindow.left; \
22 (r).bottom = (wnd)->rectClient.bottom - (wnd)->rectWindow.top
24 /* Last CTLCOLOR id */
25 #define CTLCOLOR_MAX CTLCOLOR_STATIC
28 /***********************************************************************
29 * WIN_UpdateNCRgn
31 * NOTE: Caller is responsible for the returned region.
33 HRGN WIN_UpdateNCRgn(WND* wnd, BOOL bUpdate, BOOL bForceEntire )
35 HRGN hClip = 0;
37 TRACE(nonclient,"hwnd %04x, hrgnUpdate %04x, ncf %i\n",
38 wnd->hwndSelf, wnd->hrgnUpdate, (wnd->flags & WIN_NEEDS_NCPAINT)!=0 );
40 /* desktop window doesn't have nonclient area */
41 if(wnd == WIN_GetDesktop())
43 wnd->flags &= ~WIN_NEEDS_NCPAINT;
44 WIN_ReleaseDesktop();
45 return 0;
47 WIN_ReleaseDesktop();
49 if ((wnd->hwndSelf == GetActiveWindow()) &&
50 !(wnd->flags & WIN_NCACTIVATED) )
52 wnd->flags |= WIN_NCACTIVATED;
53 bForceEntire = TRUE;
56 if( (wnd->flags & WIN_NEEDS_NCPAINT) && wnd->hrgnUpdate )
58 RECT r, r2, r3;
60 GETCLIENTRECTW( wnd, r );
62 TRACE(nonclient, "\tclient box (%i,%i-%i,%i)\n", r.left, r.top, r.right, r.bottom );
64 if( wnd->hrgnUpdate > 1 )
66 GetRgnBox( wnd->hrgnUpdate, &r2 );
67 UnionRect( &r3, &r2, &r );
68 if( r3.left != r.left || r3.top != r.top ||
69 r3.right != r.right || r3.bottom != r.bottom )
71 hClip = CreateRectRgn( 0, 0, 0, 0 );
72 CombineRgn( hClip, wnd->hrgnUpdate, 0, RGN_COPY );
75 else
76 hClip = wnd->hrgnUpdate;
78 if( wnd->hrgnUpdate > 1 )
80 REGION_CropRgn( wnd->hrgnUpdate, wnd->hrgnUpdate, &r, NULL );
82 if( bUpdate )
84 GetRgnBox( wnd->hrgnUpdate, &r3 );
85 if( IsRectEmpty( &r3 ) )
87 /* delete update region since all invalid
88 * parts were in the nonclient area */
90 DeleteObject( wnd->hrgnUpdate );
91 wnd->hrgnUpdate = 0;
92 if(!(wnd->flags & WIN_INTERNAL_PAINT))
93 QUEUE_DecPaintCount( wnd->hmemTaskQ );
94 wnd->flags &= ~WIN_NEEDS_ERASEBKGND;
98 else /* entire client rect */
99 wnd->hrgnUpdate = CreateRectRgnIndirect( &r );
102 if(!hClip && bForceEntire ) hClip = 1;
103 wnd->flags &= ~WIN_NEEDS_NCPAINT;
105 if( hClip )
106 SendMessageA( wnd->hwndSelf, WM_NCPAINT, hClip, 0L );
108 return hClip;
112 /***********************************************************************
113 * BeginPaint16 (USER.39)
115 HDC16 WINAPI BeginPaint16( HWND16 hwnd, LPPAINTSTRUCT16 lps )
117 BOOL bIcon;
118 HRGN hrgnUpdate;
119 WND *wndPtr = WIN_FindWndPtr( hwnd );
120 if (!wndPtr) return 0;
122 bIcon = (wndPtr->dwStyle & WS_MINIMIZE && wndPtr->class->hIcon);
124 wndPtr->flags &= ~WIN_NEEDS_BEGINPAINT;
126 if( (hrgnUpdate = WIN_UpdateNCRgn( wndPtr, FALSE, FALSE )) > 1 )
127 DeleteObject( hrgnUpdate );
129 if( ((hrgnUpdate = wndPtr->hrgnUpdate) != 0) || (wndPtr->flags & WIN_INTERNAL_PAINT))
130 QUEUE_DecPaintCount( wndPtr->hmemTaskQ );
132 wndPtr->hrgnUpdate = 0;
133 wndPtr->flags &= ~WIN_INTERNAL_PAINT;
135 HideCaret( hwnd );
137 TRACE(win,"hrgnUpdate = %04x, \n", hrgnUpdate);
139 if (wndPtr->class->style & CS_PARENTDC)
141 /* Don't clip the output to the update region for CS_PARENTDC window */
142 if( hrgnUpdate > 1 )
143 DeleteObject(hrgnUpdate);
144 lps->hdc = GetDCEx16( hwnd, 0, DCX_WINDOWPAINT | DCX_USESTYLE |
145 (bIcon ? DCX_WINDOW : 0) );
147 else
149 if( hrgnUpdate )
150 OffsetRgn( hrgnUpdate, wndPtr->rectWindow.left - wndPtr->rectClient.left,
151 wndPtr->rectWindow.top - wndPtr->rectClient.top );
152 lps->hdc = GetDCEx16(hwnd, hrgnUpdate, DCX_INTERSECTRGN |
153 DCX_WINDOWPAINT | DCX_USESTYLE |
154 (bIcon ? DCX_WINDOW : 0) );
157 TRACE(win,"hdc = %04x\n", lps->hdc);
159 if (!lps->hdc)
161 WARN(win, "GetDCEx() failed in BeginPaint(), hwnd=%04x\n", hwnd);
162 WIN_ReleaseWndPtr(wndPtr);
163 return 0;
166 GetClipBox16( lps->hdc, &lps->rcPaint );
168 TRACE(win,"box = (%i,%i - %i,%i)\n", lps->rcPaint.left, lps->rcPaint.top,
169 lps->rcPaint.right, lps->rcPaint.bottom );
171 if (wndPtr->flags & WIN_NEEDS_ERASEBKGND)
173 wndPtr->flags &= ~WIN_NEEDS_ERASEBKGND;
174 lps->fErase = !SendMessage16(hwnd, (bIcon) ? WM_ICONERASEBKGND
175 : WM_ERASEBKGND,
176 (WPARAM16)lps->hdc, 0 );
178 else lps->fErase = TRUE;
180 WIN_ReleaseWndPtr(wndPtr);
181 return lps->hdc;
185 /***********************************************************************
186 * BeginPaint32 (USER32.10)
188 HDC WINAPI BeginPaint( HWND hwnd, PAINTSTRUCT *lps )
190 PAINTSTRUCT16 ps;
192 BeginPaint16( hwnd, &ps );
193 lps->hdc = (HDC)ps.hdc;
194 lps->fErase = ps.fErase;
195 lps->rcPaint.top = ps.rcPaint.top;
196 lps->rcPaint.left = ps.rcPaint.left;
197 lps->rcPaint.right = ps.rcPaint.right;
198 lps->rcPaint.bottom = ps.rcPaint.bottom;
199 lps->fRestore = ps.fRestore;
200 lps->fIncUpdate = ps.fIncUpdate;
201 return lps->hdc;
205 /***********************************************************************
206 * EndPaint16 (USER.40)
208 BOOL16 WINAPI EndPaint16( HWND16 hwnd, const PAINTSTRUCT16* lps )
210 ReleaseDC16( hwnd, lps->hdc );
211 ShowCaret( hwnd );
212 return TRUE;
216 /***********************************************************************
217 * EndPaint32 (USER32.176)
219 BOOL WINAPI EndPaint( HWND hwnd, const PAINTSTRUCT *lps )
221 ReleaseDC( hwnd, lps->hdc );
222 ShowCaret( hwnd );
223 return TRUE;
227 /***********************************************************************
228 * FillWindow (USER.324)
230 void WINAPI FillWindow16( HWND16 hwndParent, HWND16 hwnd, HDC16 hdc, HBRUSH16 hbrush )
232 RECT16 rect;
233 GetClientRect16( hwnd, &rect );
234 DPtoLP16( hdc, (LPPOINT16)&rect, 2 );
235 PaintRect16( hwndParent, hwnd, hdc, hbrush, &rect );
239 /***********************************************************************
240 * PAINT_GetControlBrush
242 static HBRUSH16 PAINT_GetControlBrush( HWND hParent, HWND hWnd, HDC16 hDC, UINT16 ctlType )
244 HBRUSH16 bkgBrush = (HBRUSH16)SendMessageA( hParent, WM_CTLCOLORMSGBOX + ctlType,
245 (WPARAM)hDC, (LPARAM)hWnd );
246 if( !IsGDIObject16(bkgBrush) )
247 bkgBrush = DEFWND_ControlColor( hDC, ctlType );
248 return bkgBrush;
252 /***********************************************************************
253 * PaintRect (USER.325)
255 void WINAPI PaintRect16( HWND16 hwndParent, HWND16 hwnd, HDC16 hdc,
256 HBRUSH16 hbrush, const RECT16 *rect)
258 if( hbrush <= CTLCOLOR_MAX )
260 if( hwndParent )
261 hbrush = PAINT_GetControlBrush( hwndParent, hwnd, hdc, (UINT16)hbrush );
262 else
263 return;
265 if( hbrush )
266 FillRect16( hdc, rect, hbrush );
270 /***********************************************************************
271 * GetControlBrush (USER.326)
273 HBRUSH16 WINAPI GetControlBrush16( HWND16 hwnd, HDC16 hdc, UINT16 ctlType )
275 WND* wndPtr = WIN_FindWndPtr( hwnd );
276 HBRUSH16 retvalue;
278 if((ctlType <= CTLCOLOR_MAX) && wndPtr )
280 WND* parent;
281 if( wndPtr->dwStyle & WS_POPUP ) parent = WIN_LockWndPtr(wndPtr->owner);
282 else parent = WIN_LockWndPtr(wndPtr->parent);
283 if( !parent ) parent = wndPtr;
284 retvalue = (HBRUSH16)PAINT_GetControlBrush( parent->hwndSelf, hwnd, hdc, ctlType );
285 WIN_ReleaseWndPtr(parent);
286 goto END;
288 retvalue = (HBRUSH16)0;
289 END:
290 WIN_ReleaseWndPtr(wndPtr);
291 return retvalue;
295 /***********************************************************************
296 * PAINT_RedrawWindow
298 * FIXME: Windows uses WM_SYNCPAINT to cut down the number of intertask
299 * SendMessage() calls. This is a comment inside DefWindowProc() source
300 * from 16-bit SDK:
302 * This message avoids lots of inter-app message traffic
303 * by switching to the other task and continuing the
304 * recursion there.
306 * wParam = flags
307 * LOWORD(lParam) = hrgnClip
308 * HIWORD(lParam) = hwndSkip (not used; always NULL)
311 BOOL PAINT_RedrawWindow( HWND hwnd, const RECT *rectUpdate,
312 HRGN hrgnUpdate, UINT flags, UINT ex )
314 BOOL bIcon;
315 HRGN hrgn = 0, hrgn2 = 0;
316 RECT r, r2;
317 POINT pt;
318 WND* wndPtr;
319 WND **list, **ppWnd;
321 if (!hwnd) hwnd = GetDesktopWindow();
322 if (!(wndPtr = WIN_FindWndPtr( hwnd ))) return FALSE;
323 if (!WIN_IsWindowDrawable( wndPtr, !(flags & RDW_FRAME) ) )
325 WIN_ReleaseWndPtr(wndPtr);
326 return TRUE; /* No redraw needed */
329 bIcon = (wndPtr->dwStyle & WS_MINIMIZE && wndPtr->class->hIcon);
330 if (rectUpdate)
332 TRACE(win, "%04x (%04x) %d,%d-%d,%d %04x flags=%04x, exflags=%04x\n",
333 hwnd, wndPtr->hrgnUpdate, rectUpdate->left, rectUpdate->top,
334 rectUpdate->right, rectUpdate->bottom, hrgnUpdate, flags, ex );
336 else
338 if( hrgnUpdate ) GetRgnBox( hrgnUpdate, &r );
339 else SetRectEmpty( &r );
340 TRACE(win, "%04x (%04x) NULL %04x box (%i,%i-%i,%i) flags=%04x, exflags=%04x\n",
341 hwnd, wndPtr->hrgnUpdate, hrgnUpdate, r.left, r.top, r.right, r.bottom, flags, ex);
344 if( flags & RDW_FRAME )
345 r = wndPtr->rectWindow;
346 else
347 r = wndPtr->rectClient;
348 if( ex & RDW_EX_XYWINDOW )
349 OffsetRect( &r, -wndPtr->rectWindow.left, -wndPtr->rectWindow.top );
350 else
351 OffsetRect( &r, -wndPtr->rectClient.left, -wndPtr->rectClient.top );
353 /* r is the rectangle we crop the supplied update rgn/rect with */
355 GETCLIENTRECTW( wndPtr, r2 );
356 pt.x = r2.left; pt.y = r2.top;
358 if (flags & RDW_INVALIDATE) /* ------------------------- Invalidate */
360 BOOL bHasUpdateRgn = (BOOL)wndPtr->hrgnUpdate;
362 /* wndPtr->hrgnUpdate is in window coordinates, parameters are
363 * in client coordinates unless RDW_EX_XYWINDOW is set.
366 if( hrgnUpdate )
368 hrgn = REGION_CropRgn( 0, hrgnUpdate, &r, (ex & RDW_EX_XYWINDOW) ? NULL : &pt );
369 GetRgnBox( hrgn, &r2 );
370 if( IsRectEmpty( &r2 ) )
371 goto END;
373 if( wndPtr->hrgnUpdate == 0 )
375 wndPtr->hrgnUpdate = CreateRectRgn( 0, 0, 0, 0 );
376 CombineRgn( wndPtr->hrgnUpdate, hrgn, 0, RGN_COPY );
378 else
379 if( wndPtr->hrgnUpdate > 1 )
380 CombineRgn( wndPtr->hrgnUpdate, wndPtr->hrgnUpdate, hrgn, RGN_OR );
382 else if( rectUpdate )
384 if( !IntersectRect( &r2, &r, rectUpdate ) )
385 goto END;
386 if( !(ex & RDW_EX_XYWINDOW) )
387 OffsetRect( &r2, pt.x, pt.y );
389 rect2i: /* r2 contains a rect to add to the update region */
391 hrgn = CreateRectRgnIndirect( &r2 );
392 if( wndPtr->hrgnUpdate == 0 )
393 wndPtr->hrgnUpdate = CreateRectRgnIndirect( &r2 );
394 else
395 if( wndPtr->hrgnUpdate > 1 )
396 REGION_UnionRectWithRgn( wndPtr->hrgnUpdate, &r2 );
398 else /* entire window or client depending on RDW_FRAME */
400 hrgn = 1;
401 if( flags & RDW_FRAME )
403 if( wndPtr->hrgnUpdate )
404 DeleteObject( wndPtr->hrgnUpdate );
405 wndPtr->hrgnUpdate = 1;
407 else /* by default r2 contains client rect in window coordinates */
408 goto rect2i;
411 if( !bHasUpdateRgn && wndPtr->hrgnUpdate && !(wndPtr->flags & WIN_INTERNAL_PAINT))
412 QUEUE_IncPaintCount( wndPtr->hmemTaskQ );
414 if (flags & RDW_FRAME) wndPtr->flags |= WIN_NEEDS_NCPAINT;
415 if (flags & RDW_ERASE) wndPtr->flags |= WIN_NEEDS_ERASEBKGND;
416 flags |= RDW_FRAME; /* Force children frame invalidation */
418 else if (flags & RDW_VALIDATE) /* ------------------------- Validate */
420 if (wndPtr->hrgnUpdate) /* need an update region in order to validate anything */
422 if( hrgnUpdate || rectUpdate )
424 if( hrgnUpdate )
426 hrgn = REGION_CropRgn( hrgn, hrgnUpdate, &r, (ex & RDW_EX_XYWINDOW) ? NULL : &pt );
427 GetRgnBox( hrgn, &r2 );
428 if( IsRectEmpty( &r2 ) )
429 goto END;
431 else
433 if( !IntersectRect( &r2, &r, rectUpdate ) )
434 goto END;
435 if( !(ex & RDW_EX_XYWINDOW) )
436 OffsetRect( &r2, pt.x, pt.y );
437 rect2v:
438 hrgn = CreateRectRgnIndirect( &r2 );
441 if( wndPtr->hrgnUpdate == 1 )
443 wndPtr->hrgnUpdate = CreateRectRgn( 0, 0,
444 wndPtr->rectWindow.right - wndPtr->rectWindow.left,
445 wndPtr->rectWindow.bottom - wndPtr->rectWindow.top );
448 if( CombineRgn( wndPtr->hrgnUpdate,
449 wndPtr->hrgnUpdate, hrgn, RGN_DIFF ) == NULLREGION )
451 DeleteObject( wndPtr->hrgnUpdate );
452 wndPtr->hrgnUpdate = 0;
455 else /* entire window or client depending on RDW_FRAME */
457 wndPtr->flags &= ~WIN_NEEDS_ERASEBKGND;
459 hrgn = 1;
460 if( flags & RDW_FRAME )
462 if( wndPtr->hrgnUpdate != 1 )
463 DeleteObject( wndPtr->hrgnUpdate );
464 wndPtr->hrgnUpdate = 0;
466 else /* by default r2 contains client rect in window coordinates */
467 goto rect2v;
470 if (!wndPtr->hrgnUpdate && /* No more update region */
471 !(wndPtr->flags & WIN_INTERNAL_PAINT) )
472 QUEUE_DecPaintCount( wndPtr->hmemTaskQ );
474 if (flags & RDW_NOFRAME) wndPtr->flags &= ~WIN_NEEDS_NCPAINT;
475 if (flags & RDW_NOERASE) wndPtr->flags &= ~WIN_NEEDS_ERASEBKGND;
478 /* At this point hrgn contains new update region in window coordinates */
480 /* Set/clear internal paint flag */
482 if (flags & RDW_INTERNALPAINT)
484 if ( !wndPtr->hrgnUpdate && !(wndPtr->flags & WIN_INTERNAL_PAINT))
485 QUEUE_IncPaintCount( wndPtr->hmemTaskQ );
486 wndPtr->flags |= WIN_INTERNAL_PAINT;
488 else if (flags & RDW_NOINTERNALPAINT)
490 if ( !wndPtr->hrgnUpdate && (wndPtr->flags & WIN_INTERNAL_PAINT))
491 QUEUE_DecPaintCount( wndPtr->hmemTaskQ );
492 wndPtr->flags &= ~WIN_INTERNAL_PAINT;
495 /* Erase/update window */
497 if (flags & RDW_UPDATENOW)
499 if (wndPtr->hrgnUpdate) /* wm_painticon wparam is 1 */
500 SendMessage16( hwnd, (bIcon) ? WM_PAINTICON : WM_PAINT, bIcon, 0 );
502 else if ((flags & RDW_ERASENOW) || (ex & RDW_EX_TOPFRAME))
504 hrgn2 = WIN_UpdateNCRgn( wndPtr, TRUE, (ex & RDW_EX_TOPFRAME) );
506 if( wndPtr->flags & WIN_NEEDS_ERASEBKGND )
508 HDC hdc;
510 if( hrgn2 > 1 )
512 OffsetRgn( hrgn2, -pt.x, -pt.y );
513 GetRgnBox( hrgn2, &r2 );
515 else
517 hrgn2 = CreateRectRgn( 0, 0, 0, 0 );
518 CombineRgn( hrgn2, wndPtr->hrgnUpdate, 0, RGN_COPY );
519 OffsetRgn( hrgn2, -pt.x, -pt.y );
521 hdc = GetDCEx( hwnd, hrgn2,
522 DCX_INTERSECTRGN | DCX_USESTYLE |
523 DCX_KEEPCLIPRGN | DCX_WINDOWPAINT |
524 (bIcon ? DCX_WINDOW : 0) );
525 if (hdc)
527 if (SendMessage16( hwnd, (bIcon) ? WM_ICONERASEBKGND
528 : WM_ERASEBKGND,
529 (WPARAM16)hdc, 0 ))
530 wndPtr->flags &= ~WIN_NEEDS_ERASEBKGND;
531 ReleaseDC( hwnd, hdc );
536 if ( !IsWindow( hwnd ) )
538 WIN_ReleaseWndPtr(wndPtr);
539 return TRUE;
542 /* Recursively process children */
544 if (!(flags & RDW_NOCHILDREN) &&
545 ((flags & RDW_ALLCHILDREN) || !(wndPtr->dwStyle & WS_CLIPCHILDREN)) &&
546 !(wndPtr->dwStyle & WS_MINIMIZE) )
548 if( hrgnUpdate || rectUpdate )
550 if( hrgn2 <= 1 )
551 hrgn2 = (ex & RDW_EX_USEHRGN) ? hrgnUpdate : 0;
553 if( (list = WIN_BuildWinArray( wndPtr, 0, NULL )) )
555 POINT delta = pt;
557 for (ppWnd = list; *ppWnd; ppWnd++)
559 WIN_UpdateWndPtr(&wndPtr,*ppWnd);
560 if (!IsWindow(wndPtr->hwndSelf)) continue;
561 if (wndPtr->dwStyle & WS_VISIBLE)
563 r.left = wndPtr->rectWindow.left + delta.x;
564 r.top = wndPtr->rectWindow.top + delta.y;
565 r.right = wndPtr->rectWindow.right + delta.x;
566 r.bottom = wndPtr->rectWindow.bottom + delta.y;
568 pt.x = -r.left; pt.y = -r.top;
570 hrgn2 = REGION_CropRgn( hrgn2, hrgn, &r, &pt );
572 GetRgnBox( hrgn2, &r2 );
573 if( !IsRectEmpty( &r2 ) )
575 PAINT_RedrawWindow( wndPtr->hwndSelf, NULL, hrgn2, flags,
576 RDW_EX_USEHRGN | RDW_EX_XYWINDOW );
580 WIN_ReleaseWinArray(list);
583 else
585 if( (list = WIN_BuildWinArray( wndPtr, 0, NULL )) )
587 for (ppWnd = list; *ppWnd; ppWnd++)
589 WIN_UpdateWndPtr(&wndPtr,*ppWnd);
590 if (IsWindow( wndPtr->hwndSelf ))
591 PAINT_RedrawWindow( wndPtr->hwndSelf, NULL, 0, flags, 0 );
593 WIN_ReleaseWinArray(list);
599 END:
600 if( hrgn2 > 1 && (hrgn2 != hrgnUpdate) )
601 DeleteObject( hrgn2 );
602 if( hrgn > 1 && (hrgn != hrgnUpdate) )
603 DeleteObject( hrgn );
604 WIN_ReleaseWndPtr(wndPtr);
605 return TRUE;
609 /***********************************************************************
610 * RedrawWindow32 (USER32.426)
612 BOOL WINAPI RedrawWindow( HWND hwnd, const RECT *rectUpdate,
613 HRGN hrgnUpdate, UINT flags )
615 return PAINT_RedrawWindow( hwnd, rectUpdate, hrgnUpdate, flags, 0 );
619 /***********************************************************************
620 * RedrawWindow16 (USER.290)
622 BOOL16 WINAPI RedrawWindow16( HWND16 hwnd, const RECT16 *rectUpdate,
623 HRGN16 hrgnUpdate, UINT16 flags )
625 if (rectUpdate)
627 RECT r;
628 CONV_RECT16TO32( rectUpdate, &r );
629 return (BOOL16)RedrawWindow( (HWND)hwnd, &r, hrgnUpdate, flags );
631 return (BOOL16)PAINT_RedrawWindow( (HWND)hwnd, NULL,
632 (HRGN)hrgnUpdate, flags, 0 );
636 /***********************************************************************
637 * UpdateWindow16 (USER.124)
639 void WINAPI UpdateWindow16( HWND16 hwnd )
641 PAINT_RedrawWindow( hwnd, NULL, 0, RDW_UPDATENOW | RDW_NOCHILDREN, 0 );
644 /***********************************************************************
645 * UpdateWindow32 (USER32.567)
647 void WINAPI UpdateWindow( HWND hwnd )
649 PAINT_RedrawWindow( hwnd, NULL, 0, RDW_UPDATENOW | RDW_NOCHILDREN, 0 );
652 /***********************************************************************
653 * InvalidateRgn16 (USER.126)
655 void WINAPI InvalidateRgn16( HWND16 hwnd, HRGN16 hrgn, BOOL16 erase )
657 PAINT_RedrawWindow((HWND)hwnd, NULL, (HRGN)hrgn,
658 RDW_INVALIDATE | (erase ? RDW_ERASE : 0), 0 );
662 /***********************************************************************
663 * InvalidateRgn32 (USER32.329)
665 BOOL WINAPI InvalidateRgn( HWND hwnd, HRGN hrgn, BOOL erase )
667 return PAINT_RedrawWindow(hwnd, NULL, hrgn, RDW_INVALIDATE | (erase ? RDW_ERASE : 0), 0 );
671 /***********************************************************************
672 * InvalidateRect16 (USER.125)
674 void WINAPI InvalidateRect16( HWND16 hwnd, const RECT16 *rect, BOOL16 erase )
676 RedrawWindow16( hwnd, rect, 0, RDW_INVALIDATE | (erase ? RDW_ERASE : 0) );
680 /***********************************************************************
681 * InvalidateRect32 (USER32.328)
683 BOOL WINAPI InvalidateRect( HWND hwnd, const RECT *rect, BOOL erase )
685 return PAINT_RedrawWindow( hwnd, rect, 0,
686 RDW_INVALIDATE | (erase ? RDW_ERASE : 0), 0 );
690 /***********************************************************************
691 * ValidateRgn16 (USER.128)
693 void WINAPI ValidateRgn16( HWND16 hwnd, HRGN16 hrgn )
695 PAINT_RedrawWindow( (HWND)hwnd, NULL, (HRGN)hrgn,
696 RDW_VALIDATE | RDW_NOCHILDREN, 0 );
700 /***********************************************************************
701 * ValidateRgn32 (USER32.572)
703 void WINAPI ValidateRgn( HWND hwnd, HRGN hrgn )
705 PAINT_RedrawWindow( hwnd, NULL, hrgn, RDW_VALIDATE | RDW_NOCHILDREN, 0 );
709 /***********************************************************************
710 * ValidateRect16 (USER.127)
712 void WINAPI ValidateRect16( HWND16 hwnd, const RECT16 *rect )
714 RedrawWindow16( hwnd, rect, 0, RDW_VALIDATE | RDW_NOCHILDREN );
718 /***********************************************************************
719 * ValidateRect32 (USER32.571)
721 void WINAPI ValidateRect( HWND hwnd, const RECT *rect )
723 PAINT_RedrawWindow( hwnd, rect, 0, RDW_VALIDATE | RDW_NOCHILDREN, 0 );
727 /***********************************************************************
728 * GetUpdateRect16 (USER.190)
730 BOOL16 WINAPI GetUpdateRect16( HWND16 hwnd, LPRECT16 rect, BOOL16 erase )
732 RECT r;
733 BOOL16 ret;
735 if (!rect) return GetUpdateRect( hwnd, NULL, erase );
736 ret = GetUpdateRect( hwnd, &r, erase );
737 CONV_RECT32TO16( &r, rect );
738 return ret;
742 /***********************************************************************
743 * GetUpdateRect32 (USER32.297)
745 BOOL WINAPI GetUpdateRect( HWND hwnd, LPRECT rect, BOOL erase )
747 BOOL retvalue;
748 WND * wndPtr = WIN_FindWndPtr( hwnd );
749 if (!wndPtr) return FALSE;
751 if (rect)
753 if (wndPtr->hrgnUpdate > 1)
755 HRGN hrgn = CreateRectRgn( 0, 0, 0, 0 );
756 if (GetUpdateRgn( hwnd, hrgn, erase ) == ERROR)
758 retvalue = FALSE;
759 goto END;
761 GetRgnBox( hrgn, rect );
762 DeleteObject( hrgn );
763 if (wndPtr->class->style & CS_OWNDC)
765 if (GetMapMode(wndPtr->dce->hDC) != MM_TEXT)
767 DPtoLP (wndPtr->dce->hDC, (LPPOINT)rect, 2);
771 else
772 if( wndPtr->hrgnUpdate == 1 )
774 GetClientRect( hwnd, rect );
775 if (erase) RedrawWindow( hwnd, NULL, 0, RDW_FRAME | RDW_ERASENOW | RDW_NOCHILDREN );
777 else
778 SetRectEmpty( rect );
780 retvalue = (wndPtr->hrgnUpdate >= 1);
781 END:
782 WIN_ReleaseWndPtr(wndPtr);
783 return retvalue;
787 /***********************************************************************
788 * GetUpdateRgn16 (USER.237)
790 INT16 WINAPI GetUpdateRgn16( HWND16 hwnd, HRGN16 hrgn, BOOL16 erase )
792 return GetUpdateRgn( hwnd, hrgn, erase );
796 /***********************************************************************
797 * GetUpdateRgn (USER32.298)
799 INT WINAPI GetUpdateRgn( HWND hwnd, HRGN hrgn, BOOL erase )
801 INT retval;
802 WND * wndPtr = WIN_FindWndPtr( hwnd );
803 if (!wndPtr) return ERROR;
805 if (wndPtr->hrgnUpdate == 0)
807 SetRectRgn( hrgn, 0, 0, 0, 0 );
808 retval = NULLREGION;
809 goto END;
811 else
812 if (wndPtr->hrgnUpdate == 1)
814 SetRectRgn( hrgn, 0, 0, wndPtr->rectClient.right - wndPtr->rectClient.left,
815 wndPtr->rectClient.bottom - wndPtr->rectClient.top );
816 retval = SIMPLEREGION;
818 else
820 retval = CombineRgn( hrgn, wndPtr->hrgnUpdate, 0, RGN_COPY );
821 OffsetRgn( hrgn, wndPtr->rectWindow.left - wndPtr->rectClient.left,
822 wndPtr->rectWindow.top - wndPtr->rectClient.top );
824 if (erase) RedrawWindow( hwnd, NULL, 0, RDW_ERASENOW | RDW_NOCHILDREN );
825 END:
826 WIN_ReleaseWndPtr(wndPtr);
827 return retval;
831 /***********************************************************************
832 * ExcludeUpdateRgn16 (USER.238)
834 INT16 WINAPI ExcludeUpdateRgn16( HDC16 hdc, HWND16 hwnd )
836 return ExcludeUpdateRgn( hdc, hwnd );
840 /***********************************************************************
841 * ExcludeUpdateRgn32 (USER32.195)
843 INT WINAPI ExcludeUpdateRgn( HDC hdc, HWND hwnd )
845 RECT rect;
846 WND * wndPtr;
848 if (!(wndPtr = WIN_FindWndPtr( hwnd ))) return ERROR;
850 if (wndPtr->hrgnUpdate)
852 INT ret;
853 HRGN hrgn = CreateRectRgn(wndPtr->rectWindow.left - wndPtr->rectClient.left,
854 wndPtr->rectWindow.top - wndPtr->rectClient.top,
855 wndPtr->rectWindow.right - wndPtr->rectClient.left,
856 wndPtr->rectWindow.bottom - wndPtr->rectClient.top);
857 if( wndPtr->hrgnUpdate > 1 )
859 CombineRgn(hrgn, wndPtr->hrgnUpdate, 0, RGN_COPY);
860 OffsetRgn(hrgn, wndPtr->rectWindow.left - wndPtr->rectClient.left,
861 wndPtr->rectWindow.top - wndPtr->rectClient.top );
864 /* do ugly coordinate translations in dce.c */
866 ret = DCE_ExcludeRgn( hdc, wndPtr, hrgn );
867 DeleteObject( hrgn );
868 WIN_ReleaseWndPtr(wndPtr);
869 return ret;
871 WIN_ReleaseWndPtr(wndPtr);
872 return GetClipBox( hdc, &rect );