Alexandre Julliard | e399fc3 | 1993-11-24 17:08:56 +0000 | [diff] [blame] | 1 | /* |
| 2 | * Scroll windows and DCs |
| 3 | * |
| 4 | * Copyright David W. Metcalfe, 1993 |
Alexandre Julliard | 8cc3a5e | 1996-08-11 15:49:51 +0000 | [diff] [blame] | 5 | * Alex Korobka 1995,1996 |
Alexandre Julliard | d471965 | 1995-12-12 18:49:11 +0000 | [diff] [blame] | 6 | * |
Alexandre Julliard | e399fc3 | 1993-11-24 17:08:56 +0000 | [diff] [blame] | 7 | * |
| 8 | */ |
| 9 | |
Alexandre Julliard | e399fc3 | 1993-11-24 17:08:56 +0000 | [diff] [blame] | 10 | #include <stdlib.h> |
Patrik Stridvall | b87fe2e | 1999-04-01 08:16:08 +0000 | [diff] [blame] | 11 | |
Patrik Stridvall | 1ed4ecf | 1999-06-26 14:58:24 +0000 | [diff] [blame] | 12 | #include "wine/winuser16.h" |
Marcus Meissner | 61afa33 | 1999-02-22 10:16:00 +0000 | [diff] [blame] | 13 | #include "winuser.h" |
Alexandre Julliard | f90efa9 | 1998-06-14 15:24:15 +0000 | [diff] [blame] | 14 | #include "dc.h" |
Alexandre Julliard | d471965 | 1995-12-12 18:49:11 +0000 | [diff] [blame] | 15 | #include "win.h" |
Alexandre Julliard | e399fc3 | 1993-11-24 17:08:56 +0000 | [diff] [blame] | 16 | #include "gdi.h" |
Alexandre Julliard | 9ea19e5 | 1997-01-01 17:29:55 +0000 | [diff] [blame] | 17 | #include "dce.h" |
Alexandre Julliard | 8cc3a5e | 1996-08-11 15:49:51 +0000 | [diff] [blame] | 18 | #include "region.h" |
Alexandre Julliard | 359f497e | 1999-07-04 16:02:24 +0000 | [diff] [blame] | 19 | #include "debugtools.h" |
Alexandre Julliard | d471965 | 1995-12-12 18:49:11 +0000 | [diff] [blame] | 20 | |
Patrik Stridvall | b4b9fae | 1999-04-19 14:56:29 +0000 | [diff] [blame] | 21 | DEFAULT_DEBUG_CHANNEL(scroll) |
| 22 | |
Alexandre Julliard | e399fc3 | 1993-11-24 17:08:56 +0000 | [diff] [blame] | 23 | /************************************************************************* |
Alexandre Julliard | 75d86e1 | 1996-11-17 18:59:11 +0000 | [diff] [blame] | 24 | * ScrollWindow16 (USER.61) |
Alexandre Julliard | e399fc3 | 1993-11-24 17:08:56 +0000 | [diff] [blame] | 25 | */ |
Alexandre Julliard | 670cdc4 | 1997-08-24 16:00:30 +0000 | [diff] [blame] | 26 | void WINAPI ScrollWindow16(HWND16 hwnd, INT16 dx, INT16 dy, const RECT16 *rect, |
| 27 | const RECT16 *clipRect ) |
Alexandre Julliard | 75d86e1 | 1996-11-17 18:59:11 +0000 | [diff] [blame] | 28 | { |
Alexandre Julliard | a396029 | 1999-02-26 11:11:13 +0000 | [diff] [blame] | 29 | RECT rect32, clipRect32; |
Alexandre Julliard | 75d86e1 | 1996-11-17 18:59:11 +0000 | [diff] [blame] | 30 | |
| 31 | if (rect) CONV_RECT16TO32( rect, &rect32 ); |
| 32 | if (clipRect) CONV_RECT16TO32( clipRect, &clipRect32 ); |
Alexandre Julliard | a396029 | 1999-02-26 11:11:13 +0000 | [diff] [blame] | 33 | ScrollWindow( hwnd, dx, dy, rect ? &rect32 : NULL, |
Alexandre Julliard | 75d86e1 | 1996-11-17 18:59:11 +0000 | [diff] [blame] | 34 | clipRect ? &clipRect32 : NULL ); |
| 35 | } |
| 36 | |
Alexandre Julliard | 75d86e1 | 1996-11-17 18:59:11 +0000 | [diff] [blame] | 37 | /************************************************************************* |
Alexandre Julliard | c7c217b | 1998-04-13 12:21:30 +0000 | [diff] [blame] | 38 | * ScrollWindow32 (USER32.450) |
Alexandre Julliard | 670cdc4 | 1997-08-24 16:00:30 +0000 | [diff] [blame] | 39 | * |
Alexandre Julliard | 75d86e1 | 1996-11-17 18:59:11 +0000 | [diff] [blame] | 40 | */ |
Alexandre Julliard | a396029 | 1999-02-26 11:11:13 +0000 | [diff] [blame] | 41 | BOOL WINAPI ScrollWindow( HWND hwnd, INT dx, INT dy, |
| 42 | const RECT *rect, const RECT *clipRect ) |
Alexandre Julliard | e399fc3 | 1993-11-24 17:08:56 +0000 | [diff] [blame] | 43 | { |
Jerome Vouillon | 1da6dba | 1999-02-14 13:32:13 +0000 | [diff] [blame] | 44 | return |
Alexandre Julliard | a396029 | 1999-02-26 11:11:13 +0000 | [diff] [blame] | 45 | (ERROR != ScrollWindowEx( hwnd, dx, dy, rect, clipRect, 0, NULL, |
Jerome Vouillon | 1da6dba | 1999-02-14 13:32:13 +0000 | [diff] [blame] | 46 | (rect ? 0 : SW_SCROLLCHILDREN) | |
| 47 | SW_INVALIDATE )); |
Alexandre Julliard | e399fc3 | 1993-11-24 17:08:56 +0000 | [diff] [blame] | 48 | } |
| 49 | |
Alexandre Julliard | e399fc3 | 1993-11-24 17:08:56 +0000 | [diff] [blame] | 50 | /************************************************************************* |
Alexandre Julliard | 75d86e1 | 1996-11-17 18:59:11 +0000 | [diff] [blame] | 51 | * ScrollDC16 (USER.221) |
Alexandre Julliard | e399fc3 | 1993-11-24 17:08:56 +0000 | [diff] [blame] | 52 | */ |
Alexandre Julliard | 670cdc4 | 1997-08-24 16:00:30 +0000 | [diff] [blame] | 53 | BOOL16 WINAPI ScrollDC16( HDC16 hdc, INT16 dx, INT16 dy, const RECT16 *rect, |
| 54 | const RECT16 *cliprc, HRGN16 hrgnUpdate, |
| 55 | LPRECT16 rcUpdate ) |
Alexandre Julliard | 75d86e1 | 1996-11-17 18:59:11 +0000 | [diff] [blame] | 56 | { |
Alexandre Julliard | a396029 | 1999-02-26 11:11:13 +0000 | [diff] [blame] | 57 | RECT rect32, clipRect32, rcUpdate32; |
Alexandre Julliard | 75d86e1 | 1996-11-17 18:59:11 +0000 | [diff] [blame] | 58 | BOOL16 ret; |
| 59 | |
| 60 | if (rect) CONV_RECT16TO32( rect, &rect32 ); |
| 61 | if (cliprc) CONV_RECT16TO32( cliprc, &clipRect32 ); |
Alexandre Julliard | a396029 | 1999-02-26 11:11:13 +0000 | [diff] [blame] | 62 | ret = ScrollDC( hdc, dx, dy, rect ? &rect32 : NULL, |
Alexandre Julliard | 75d86e1 | 1996-11-17 18:59:11 +0000 | [diff] [blame] | 63 | cliprc ? &clipRect32 : NULL, hrgnUpdate, &rcUpdate32 ); |
| 64 | if (rcUpdate) CONV_RECT32TO16( &rcUpdate32, rcUpdate ); |
| 65 | return ret; |
| 66 | } |
| 67 | |
| 68 | |
| 69 | /************************************************************************* |
Alexandre Julliard | c7c217b | 1998-04-13 12:21:30 +0000 | [diff] [blame] | 70 | * ScrollDC32 (USER32.449) |
Alexandre Julliard | 9ea19e5 | 1997-01-01 17:29:55 +0000 | [diff] [blame] | 71 | * |
Pascal Lessard | 83f39cf | 1999-02-25 16:35:22 +0000 | [diff] [blame] | 72 | * Only the hrgnUpdate is return in device coordinate. |
| 73 | * rcUpdate must be returned in logical coordinate to comply with win API. |
| 74 | * |
Alexandre Julliard | 75d86e1 | 1996-11-17 18:59:11 +0000 | [diff] [blame] | 75 | */ |
Alexandre Julliard | a396029 | 1999-02-26 11:11:13 +0000 | [diff] [blame] | 76 | BOOL WINAPI ScrollDC( HDC hdc, INT dx, INT dy, const RECT *rc, |
| 77 | const RECT *prLClip, HRGN hrgnUpdate, |
| 78 | LPRECT rcUpdate ) |
Alexandre Julliard | e399fc3 | 1993-11-24 17:08:56 +0000 | [diff] [blame] | 79 | { |
Alexandre Julliard | a396029 | 1999-02-26 11:11:13 +0000 | [diff] [blame] | 80 | RECT rect, rClip, rSrc; |
| 81 | POINT src, dest; |
Alexandre Julliard | e399fc3 | 1993-11-24 17:08:56 +0000 | [diff] [blame] | 82 | DC *dc = (DC *)GDI_GetObjPtr(hdc, DC_MAGIC); |
| 83 | |
Alexandre Julliard | 359f497e | 1999-07-04 16:02:24 +0000 | [diff] [blame] | 84 | TRACE("%04x %d,%d hrgnUpdate=%04x rcUpdate = %p cliprc = (%d,%d-%d,%d), rc=(%d,%d-%d,%d)\n", |
Alexandre Julliard | 9ea19e5 | 1997-01-01 17:29:55 +0000 | [diff] [blame] | 85 | (HDC16)hdc, dx, dy, hrgnUpdate, rcUpdate, |
| 86 | prLClip ? prLClip->left : 0, prLClip ? prLClip->top : 0, prLClip ? prLClip->right : 0, prLClip ? prLClip->bottom : 0, |
| 87 | rc ? rc->left : 0, rc ? rc->top : 0, rc ? rc->right : 0, rc ? rc->bottom : 0 ); |
Alexandre Julliard | e399fc3 | 1993-11-24 17:08:56 +0000 | [diff] [blame] | 88 | |
Alexandre Julliard | 8cc3a5e | 1996-08-11 15:49:51 +0000 | [diff] [blame] | 89 | if ( !dc || !hdc ) return FALSE; |
Alexandre Julliard | e399fc3 | 1993-11-24 17:08:56 +0000 | [diff] [blame] | 90 | |
Alexandre Julliard | 9ea19e5 | 1997-01-01 17:29:55 +0000 | [diff] [blame] | 91 | /* |
Alexandre Julliard | 54c2711 | 1998-03-29 19:44:57 +0000 | [diff] [blame] | 92 | TRACE(scroll,"\t[wndOrgX=%i, wndExtX=%i, vportOrgX=%i, vportExtX=%i]\n", |
| 93 | dc->wndOrgX, dc->wndExtX, dc->vportOrgX, dc->vportExtX ); |
| 94 | TRACE(scroll,"\t[wndOrgY=%i, wndExtY=%i, vportOrgY=%i, vportExtY=%i]\n", |
| 95 | dc->wndOrgY, dc->wndExtY, dc->vportOrgY, dc->vportExtY ); |
Alexandre Julliard | 9ea19e5 | 1997-01-01 17:29:55 +0000 | [diff] [blame] | 96 | */ |
Alexandre Julliard | e2bfa4c | 1996-05-16 18:21:06 +0000 | [diff] [blame] | 97 | |
Alexandre Julliard | 9ea19e5 | 1997-01-01 17:29:55 +0000 | [diff] [blame] | 98 | /* compute device clipping region */ |
Alexandre Julliard | 8cc3a5e | 1996-08-11 15:49:51 +0000 | [diff] [blame] | 99 | |
Alexandre Julliard | 9ea19e5 | 1997-01-01 17:29:55 +0000 | [diff] [blame] | 100 | if ( rc ) |
Jerome Vouillon | 1da6dba | 1999-02-14 13:32:13 +0000 | [diff] [blame] | 101 | rect = *rc; |
Alexandre Julliard | 9ea19e5 | 1997-01-01 17:29:55 +0000 | [diff] [blame] | 102 | else /* maybe we should just return FALSE? */ |
Alexandre Julliard | a396029 | 1999-02-26 11:11:13 +0000 | [diff] [blame] | 103 | GetClipBox( hdc, &rect ); |
Alexandre Julliard | 1e9ac79 | 1996-06-06 18:38:27 +0000 | [diff] [blame] | 104 | |
Alexandre Julliard | 9ea19e5 | 1997-01-01 17:29:55 +0000 | [diff] [blame] | 105 | if (prLClip) |
Alexandre Julliard | a396029 | 1999-02-26 11:11:13 +0000 | [diff] [blame] | 106 | IntersectRect( &rClip,&rect,prLClip ); |
Alexandre Julliard | 9ea19e5 | 1997-01-01 17:29:55 +0000 | [diff] [blame] | 107 | else |
Jerome Vouillon | 1da6dba | 1999-02-14 13:32:13 +0000 | [diff] [blame] | 108 | rClip = rect; |
Alexandre Julliard | 9ea19e5 | 1997-01-01 17:29:55 +0000 | [diff] [blame] | 109 | |
Jerome Vouillon | 1da6dba | 1999-02-14 13:32:13 +0000 | [diff] [blame] | 110 | rSrc = rClip; |
Alexandre Julliard | a396029 | 1999-02-26 11:11:13 +0000 | [diff] [blame] | 111 | OffsetRect( &rSrc, -dx, -dy ); |
| 112 | IntersectRect( &rSrc, &rSrc, &rect ); |
Alexandre Julliard | e399fc3 | 1993-11-24 17:08:56 +0000 | [diff] [blame] | 113 | |
Jerome Vouillon | 1da6dba | 1999-02-14 13:32:13 +0000 | [diff] [blame] | 114 | if(dc->w.hVisRgn) |
Alexandre Julliard | 9ea19e5 | 1997-01-01 17:29:55 +0000 | [diff] [blame] | 115 | { |
Alexandre Julliard | a396029 | 1999-02-26 11:11:13 +0000 | [diff] [blame] | 116 | if (!IsRectEmpty(&rSrc)) |
Jerome Vouillon | 1da6dba | 1999-02-14 13:32:13 +0000 | [diff] [blame] | 117 | { |
| 118 | dest.x = (src.x = rSrc.left) + dx; |
| 119 | dest.y = (src.y = rSrc.top) + dy; |
Alexandre Julliard | 9ea19e5 | 1997-01-01 17:29:55 +0000 | [diff] [blame] | 120 | |
Jerome Vouillon | 1da6dba | 1999-02-14 13:32:13 +0000 | [diff] [blame] | 121 | /* copy bits */ |
| 122 | |
Alexandre Julliard | a396029 | 1999-02-26 11:11:13 +0000 | [diff] [blame] | 123 | if (!BitBlt( hdc, dest.x, dest.y, |
Jerome Vouillon | 1da6dba | 1999-02-14 13:32:13 +0000 | [diff] [blame] | 124 | rSrc.right - rSrc.left, rSrc.bottom - rSrc.top, |
| 125 | hdc, src.x, src.y, SRCCOPY)) |
| 126 | { |
| 127 | GDI_HEAP_UNLOCK( hdc ); |
| 128 | return FALSE; |
| 129 | } |
| 130 | } |
| 131 | |
| 132 | /* compute update areas */ |
| 133 | |
| 134 | if (hrgnUpdate || rcUpdate) |
| 135 | { |
Alexandre Julliard | a396029 | 1999-02-26 11:11:13 +0000 | [diff] [blame] | 136 | HRGN hrgn = |
| 137 | (hrgnUpdate) ? hrgnUpdate : CreateRectRgn( 0,0,0,0 ); |
| 138 | HRGN hrgn2; |
Jerome Vouillon | 1da6dba | 1999-02-14 13:32:13 +0000 | [diff] [blame] | 139 | |
| 140 | dx = XLPTODP ( dc, rect.left + dx) - XLPTODP ( dc, rect.left); |
| 141 | dy = YLPTODP ( dc, rect.top + dy) - YLPTODP ( dc, rect.top); |
Alexandre Julliard | a396029 | 1999-02-26 11:11:13 +0000 | [diff] [blame] | 142 | LPtoDP( hdc, (LPPOINT)&rect, 2 ); |
| 143 | LPtoDP( hdc, (LPPOINT)&rClip, 2 ); |
| 144 | hrgn2 = CreateRectRgnIndirect( &rect ); |
| 145 | OffsetRgn( hrgn2, dc->w.DCOrgX, dc->w.DCOrgY ); |
| 146 | CombineRgn( hrgn2, hrgn2, dc->w.hVisRgn, RGN_AND ); |
| 147 | OffsetRgn( hrgn2, -dc->w.DCOrgX, -dc->w.DCOrgY ); |
| 148 | SetRectRgn( hrgn, rClip.left, rClip.top, |
Jerome Vouillon | 1da6dba | 1999-02-14 13:32:13 +0000 | [diff] [blame] | 149 | rClip.right, rClip.bottom ); |
Alexandre Julliard | a396029 | 1999-02-26 11:11:13 +0000 | [diff] [blame] | 150 | CombineRgn( hrgn, hrgn, hrgn2, RGN_AND ); |
| 151 | OffsetRgn( hrgn2, dx, dy ); |
| 152 | CombineRgn( hrgn, hrgn, hrgn2, RGN_DIFF ); |
Jerome Vouillon | 1da6dba | 1999-02-14 13:32:13 +0000 | [diff] [blame] | 153 | |
Pascal Lessard | 83f39cf | 1999-02-25 16:35:22 +0000 | [diff] [blame] | 154 | if( rcUpdate ) |
| 155 | { |
Alexandre Julliard | a396029 | 1999-02-26 11:11:13 +0000 | [diff] [blame] | 156 | GetRgnBox( hrgn, rcUpdate ); |
Jerome Vouillon | 1da6dba | 1999-02-14 13:32:13 +0000 | [diff] [blame] | 157 | |
Patrik Stridvall | 0f8bc5b | 1999-04-22 16:27:50 +0000 | [diff] [blame] | 158 | /* Put the rcUpdate in logical coordinate */ |
Alexandre Julliard | a396029 | 1999-02-26 11:11:13 +0000 | [diff] [blame] | 159 | DPtoLP( hdc, (LPPOINT)rcUpdate, 2 ); |
Pascal Lessard | 83f39cf | 1999-02-25 16:35:22 +0000 | [diff] [blame] | 160 | } |
Alexandre Julliard | a396029 | 1999-02-26 11:11:13 +0000 | [diff] [blame] | 161 | if (!hrgnUpdate) DeleteObject( hrgn ); |
| 162 | DeleteObject( hrgn2 ); |
Pascal Lessard | 83f39cf | 1999-02-25 16:35:22 +0000 | [diff] [blame] | 163 | |
Jerome Vouillon | 1da6dba | 1999-02-14 13:32:13 +0000 | [diff] [blame] | 164 | } |
Alexandre Julliard | 9ea19e5 | 1997-01-01 17:29:55 +0000 | [diff] [blame] | 165 | } |
Jerome Vouillon | 1da6dba | 1999-02-14 13:32:13 +0000 | [diff] [blame] | 166 | else |
Alexandre Julliard | e399fc3 | 1993-11-24 17:08:56 +0000 | [diff] [blame] | 167 | { |
Alexandre Julliard | a396029 | 1999-02-26 11:11:13 +0000 | [diff] [blame] | 168 | if (hrgnUpdate) SetRectRgn(hrgnUpdate, 0, 0, 0, 0); |
| 169 | if (rcUpdate) SetRectEmpty(rcUpdate); |
Alexandre Julliard | e399fc3 | 1993-11-24 17:08:56 +0000 | [diff] [blame] | 170 | } |
| 171 | |
Alexandre Julliard | f90efa9 | 1998-06-14 15:24:15 +0000 | [diff] [blame] | 172 | GDI_HEAP_UNLOCK( hdc ); |
Alexandre Julliard | 3ed37e0 | 1994-11-07 18:20:42 +0000 | [diff] [blame] | 173 | return TRUE; |
Alexandre Julliard | e399fc3 | 1993-11-24 17:08:56 +0000 | [diff] [blame] | 174 | } |
| 175 | |
| 176 | |
| 177 | /************************************************************************* |
Alexandre Julliard | 75d86e1 | 1996-11-17 18:59:11 +0000 | [diff] [blame] | 178 | * ScrollWindowEx16 (USER.319) |
| 179 | */ |
Alexandre Julliard | 670cdc4 | 1997-08-24 16:00:30 +0000 | [diff] [blame] | 180 | INT16 WINAPI ScrollWindowEx16( HWND16 hwnd, INT16 dx, INT16 dy, |
| 181 | const RECT16 *rect, const RECT16 *clipRect, |
| 182 | HRGN16 hrgnUpdate, LPRECT16 rcUpdate, |
| 183 | UINT16 flags ) |
Alexandre Julliard | 75d86e1 | 1996-11-17 18:59:11 +0000 | [diff] [blame] | 184 | { |
Alexandre Julliard | a396029 | 1999-02-26 11:11:13 +0000 | [diff] [blame] | 185 | RECT rect32, clipRect32, rcUpdate32; |
Alexandre Julliard | 75d86e1 | 1996-11-17 18:59:11 +0000 | [diff] [blame] | 186 | BOOL16 ret; |
| 187 | |
| 188 | if (rect) CONV_RECT16TO32( rect, &rect32 ); |
| 189 | if (clipRect) CONV_RECT16TO32( clipRect, &clipRect32 ); |
Alexandre Julliard | a396029 | 1999-02-26 11:11:13 +0000 | [diff] [blame] | 190 | ret = ScrollWindowEx( hwnd, dx, dy, rect ? &rect32 : NULL, |
Alexandre Julliard | 75d86e1 | 1996-11-17 18:59:11 +0000 | [diff] [blame] | 191 | clipRect ? &clipRect32 : NULL, hrgnUpdate, |
Alexandre Julliard | 9ea19e5 | 1997-01-01 17:29:55 +0000 | [diff] [blame] | 192 | (rcUpdate) ? &rcUpdate32 : NULL, flags ); |
Alexandre Julliard | 75d86e1 | 1996-11-17 18:59:11 +0000 | [diff] [blame] | 193 | if (rcUpdate) CONV_RECT32TO16( &rcUpdate32, rcUpdate ); |
| 194 | return ret; |
| 195 | } |
| 196 | |
Alexandre Julliard | 9ea19e5 | 1997-01-01 17:29:55 +0000 | [diff] [blame] | 197 | /************************************************************************* |
| 198 | * SCROLL_FixCaret |
| 199 | */ |
Alexandre Julliard | a396029 | 1999-02-26 11:11:13 +0000 | [diff] [blame] | 200 | static BOOL SCROLL_FixCaret(HWND hWnd, LPRECT lprc, UINT flags) |
Alexandre Julliard | 9ea19e5 | 1997-01-01 17:29:55 +0000 | [diff] [blame] | 201 | { |
Alexandre Julliard | a396029 | 1999-02-26 11:11:13 +0000 | [diff] [blame] | 202 | HWND hCaret = CARET_GetHwnd(); |
Alexandre Julliard | 9ea19e5 | 1997-01-01 17:29:55 +0000 | [diff] [blame] | 203 | |
| 204 | if( hCaret ) |
| 205 | { |
Alexandre Julliard | a396029 | 1999-02-26 11:11:13 +0000 | [diff] [blame] | 206 | RECT rc; |
Alexandre Julliard | 9ea19e5 | 1997-01-01 17:29:55 +0000 | [diff] [blame] | 207 | CARET_GetRect( &rc ); |
| 208 | if( hCaret == hWnd || |
Alexandre Julliard | a396029 | 1999-02-26 11:11:13 +0000 | [diff] [blame] | 209 | (flags & SW_SCROLLCHILDREN && IsChild(hWnd, hCaret)) ) |
Alexandre Julliard | 9ea19e5 | 1997-01-01 17:29:55 +0000 | [diff] [blame] | 210 | { |
Alexandre Julliard | a396029 | 1999-02-26 11:11:13 +0000 | [diff] [blame] | 211 | POINT pt; |
Alexandre Julliard | 9ea19e5 | 1997-01-01 17:29:55 +0000 | [diff] [blame] | 212 | |
| 213 | pt.x = rc.left; pt.y = rc.top; |
Alexandre Julliard | a396029 | 1999-02-26 11:11:13 +0000 | [diff] [blame] | 214 | MapWindowPoints( hCaret, hWnd, (LPPOINT)&rc, 2 ); |
| 215 | if( IntersectRect(lprc, lprc, &rc) ) |
Alexandre Julliard | 9ea19e5 | 1997-01-01 17:29:55 +0000 | [diff] [blame] | 216 | { |
Alexandre Julliard | a396029 | 1999-02-26 11:11:13 +0000 | [diff] [blame] | 217 | HideCaret(0); |
Alexandre Julliard | 9ea19e5 | 1997-01-01 17:29:55 +0000 | [diff] [blame] | 218 | lprc->left = pt.x; lprc->top = pt.y; |
| 219 | return TRUE; |
| 220 | } |
| 221 | } |
| 222 | } |
| 223 | return FALSE; |
| 224 | } |
Alexandre Julliard | 75d86e1 | 1996-11-17 18:59:11 +0000 | [diff] [blame] | 225 | |
| 226 | /************************************************************************* |
Alexandre Julliard | c7c217b | 1998-04-13 12:21:30 +0000 | [diff] [blame] | 227 | * ScrollWindowEx32 (USER32.451) |
Alexandre Julliard | 670cdc4 | 1997-08-24 16:00:30 +0000 | [diff] [blame] | 228 | * |
| 229 | * NOTE: Use this function instead of ScrollWindow32 |
Alexandre Julliard | e399fc3 | 1993-11-24 17:08:56 +0000 | [diff] [blame] | 230 | */ |
Alexandre Julliard | a396029 | 1999-02-26 11:11:13 +0000 | [diff] [blame] | 231 | INT WINAPI ScrollWindowEx( HWND hwnd, INT dx, INT dy, |
| 232 | const RECT *rect, const RECT *clipRect, |
| 233 | HRGN hrgnUpdate, LPRECT rcUpdate, |
| 234 | UINT flags ) |
Alexandre Julliard | e399fc3 | 1993-11-24 17:08:56 +0000 | [diff] [blame] | 235 | { |
Alexandre Julliard | a396029 | 1999-02-26 11:11:13 +0000 | [diff] [blame] | 236 | INT retVal = NULLREGION; |
| 237 | BOOL bCaret = FALSE, bOwnRgn = TRUE; |
| 238 | RECT rc, cliprc; |
Alexandre Julliard | 9ea19e5 | 1997-01-01 17:29:55 +0000 | [diff] [blame] | 239 | WND* wnd = WIN_FindWndPtr( hwnd ); |
Alexandre Julliard | e399fc3 | 1993-11-24 17:08:56 +0000 | [diff] [blame] | 240 | |
Francois Boisvert | 6b1b41c | 1999-03-14 17:25:32 +0000 | [diff] [blame] | 241 | if( !wnd || !WIN_IsWindowDrawable( wnd, TRUE )) |
| 242 | { |
| 243 | retVal = ERROR; |
| 244 | goto END; |
| 245 | } |
Alexandre Julliard | 75d86e1 | 1996-11-17 18:59:11 +0000 | [diff] [blame] | 246 | |
Alexandre Julliard | a396029 | 1999-02-26 11:11:13 +0000 | [diff] [blame] | 247 | GetClientRect(hwnd, &rc); |
| 248 | if (rect) IntersectRect(&rc, &rc, rect); |
Alexandre Julliard | e399fc3 | 1993-11-24 17:08:56 +0000 | [diff] [blame] | 249 | |
Alexandre Julliard | a396029 | 1999-02-26 11:11:13 +0000 | [diff] [blame] | 250 | if (clipRect) IntersectRect(&cliprc,&rc,clipRect); |
Alexandre Julliard | 9ea19e5 | 1997-01-01 17:29:55 +0000 | [diff] [blame] | 251 | else cliprc = rc; |
Alexandre Julliard | e399fc3 | 1993-11-24 17:08:56 +0000 | [diff] [blame] | 252 | |
Alexandre Julliard | a396029 | 1999-02-26 11:11:13 +0000 | [diff] [blame] | 253 | if (!IsRectEmpty(&cliprc) && (dx || dy)) |
Alexandre Julliard | e399fc3 | 1993-11-24 17:08:56 +0000 | [diff] [blame] | 254 | { |
Alexandre Julliard | 9ea19e5 | 1997-01-01 17:29:55 +0000 | [diff] [blame] | 255 | DC* dc; |
Alexandre Julliard | a396029 | 1999-02-26 11:11:13 +0000 | [diff] [blame] | 256 | HDC hDC; |
| 257 | BOOL bUpdate = (rcUpdate || hrgnUpdate || flags & (SW_INVALIDATE | SW_ERASE)); |
| 258 | HRGN hrgnClip = CreateRectRgnIndirect(&cliprc); |
| 259 | HRGN hrgnTemp = CreateRectRgnIndirect(&rc); |
| 260 | RECT caretrc; |
Alexandre Julliard | e399fc3 | 1993-11-24 17:08:56 +0000 | [diff] [blame] | 261 | |
Alexandre Julliard | 359f497e | 1999-07-04 16:02:24 +0000 | [diff] [blame] | 262 | TRACE("%04x, %d,%d hrgnUpdate=%04x rcUpdate = %p \ |
Alexandre Julliard | 9ea19e5 | 1997-01-01 17:29:55 +0000 | [diff] [blame] | 263 | cliprc = (%d,%d-%d,%d), rc=(%d,%d-%d,%d) %04x\n", |
| 264 | (HWND16)hwnd, dx, dy, hrgnUpdate, rcUpdate, |
| 265 | clipRect?clipRect->left:0, clipRect?clipRect->top:0, clipRect?clipRect->right:0, clipRect?clipRect->bottom:0, |
Jerome Vouillon | 1da6dba | 1999-02-14 13:32:13 +0000 | [diff] [blame] | 266 | rc.left, rc.top, rc.right, rc.bottom, (UINT16)flags ); |
Alexandre Julliard | 9ea19e5 | 1997-01-01 17:29:55 +0000 | [diff] [blame] | 267 | |
Jerome Vouillon | 1da6dba | 1999-02-14 13:32:13 +0000 | [diff] [blame] | 268 | caretrc = rc; |
| 269 | bCaret = SCROLL_FixCaret(hwnd, &caretrc, flags); |
Alexandre Julliard | 9ea19e5 | 1997-01-01 17:29:55 +0000 | [diff] [blame] | 270 | |
| 271 | if( hrgnUpdate ) bOwnRgn = FALSE; |
Alexandre Julliard | a396029 | 1999-02-26 11:11:13 +0000 | [diff] [blame] | 272 | else if( bUpdate ) hrgnUpdate = CreateRectRgn( 0, 0, 0, 0 ); |
Alexandre Julliard | 9ea19e5 | 1997-01-01 17:29:55 +0000 | [diff] [blame] | 273 | |
Alexandre Julliard | a396029 | 1999-02-26 11:11:13 +0000 | [diff] [blame] | 274 | hDC = GetDCEx( hwnd, hrgnClip, DCX_CACHE | DCX_USESTYLE | |
Jerome Vouillon | 1da6dba | 1999-02-14 13:32:13 +0000 | [diff] [blame] | 275 | DCX_KEEPCLIPRGN | DCX_INTERSECTRGN | |
Alexandre Julliard | 44ed71f | 1997-12-21 19:17:50 +0000 | [diff] [blame] | 276 | ((flags & SW_SCROLLCHILDREN) ? DCX_NOCLIPCHILDREN : 0) ); |
Alexandre Julliard | 9ea19e5 | 1997-01-01 17:29:55 +0000 | [diff] [blame] | 277 | if( (dc = (DC *)GDI_GetObjPtr(hDC, DC_MAGIC)) ) |
| 278 | { |
Jerome Vouillon | 1da6dba | 1999-02-14 13:32:13 +0000 | [diff] [blame] | 279 | if (dc->w.hVisRgn) { |
Alex Korobka | 4f1ac05 | 1999-03-28 09:37:57 +0000 | [diff] [blame] | 280 | wnd->pDriver->pSurfaceCopy(wnd,dc,dx,dy,&rc,bUpdate); |
Alexandre Julliard | 9ea19e5 | 1997-01-01 17:29:55 +0000 | [diff] [blame] | 281 | |
Jerome Vouillon | 1da6dba | 1999-02-14 13:32:13 +0000 | [diff] [blame] | 282 | if( bUpdate ) |
| 283 | { |
Alexandre Julliard | a396029 | 1999-02-26 11:11:13 +0000 | [diff] [blame] | 284 | OffsetRgn( hrgnTemp, dc->w.DCOrgX, dc->w.DCOrgY ); |
| 285 | CombineRgn( hrgnTemp, hrgnTemp, dc->w.hVisRgn, |
Jerome Vouillon | 1da6dba | 1999-02-14 13:32:13 +0000 | [diff] [blame] | 286 | RGN_AND ); |
Alexandre Julliard | a396029 | 1999-02-26 11:11:13 +0000 | [diff] [blame] | 287 | OffsetRgn( hrgnTemp, -dc->w.DCOrgX, -dc->w.DCOrgY ); |
| 288 | CombineRgn( hrgnUpdate, hrgnTemp, hrgnClip, |
Jerome Vouillon | 1da6dba | 1999-02-14 13:32:13 +0000 | [diff] [blame] | 289 | RGN_AND ); |
Alexandre Julliard | a396029 | 1999-02-26 11:11:13 +0000 | [diff] [blame] | 290 | OffsetRgn( hrgnTemp, dx, dy ); |
Jerome Vouillon | 1da6dba | 1999-02-14 13:32:13 +0000 | [diff] [blame] | 291 | retVal = |
Alexandre Julliard | a396029 | 1999-02-26 11:11:13 +0000 | [diff] [blame] | 292 | CombineRgn( hrgnUpdate, hrgnUpdate, hrgnTemp, |
Jerome Vouillon | 1da6dba | 1999-02-14 13:32:13 +0000 | [diff] [blame] | 293 | RGN_DIFF ); |
Alexandre Julliard | 9ea19e5 | 1997-01-01 17:29:55 +0000 | [diff] [blame] | 294 | |
Alexandre Julliard | a396029 | 1999-02-26 11:11:13 +0000 | [diff] [blame] | 295 | if( rcUpdate ) GetRgnBox( hrgnUpdate, rcUpdate ); |
Jerome Vouillon | 1da6dba | 1999-02-14 13:32:13 +0000 | [diff] [blame] | 296 | } |
| 297 | } |
Alexandre Julliard | a396029 | 1999-02-26 11:11:13 +0000 | [diff] [blame] | 298 | ReleaseDC(hwnd, hDC); |
Jerome Vouillon | 1da6dba | 1999-02-14 13:32:13 +0000 | [diff] [blame] | 299 | GDI_HEAP_UNLOCK( hDC ); |
| 300 | } |
Alexandre Julliard | 9ea19e5 | 1997-01-01 17:29:55 +0000 | [diff] [blame] | 301 | |
| 302 | if( wnd->hrgnUpdate > 1 ) |
| 303 | { |
Jerome Vouillon | 1da6dba | 1999-02-14 13:32:13 +0000 | [diff] [blame] | 304 | /* Takes into account the fact that some damages may have |
| 305 | occured during the scroll. */ |
Alexandre Julliard | a396029 | 1999-02-26 11:11:13 +0000 | [diff] [blame] | 306 | CombineRgn( hrgnTemp, wnd->hrgnUpdate, 0, RGN_COPY ); |
| 307 | OffsetRgn( hrgnTemp, dx, dy ); |
| 308 | CombineRgn( hrgnTemp, hrgnTemp, hrgnClip, RGN_AND ); |
| 309 | CombineRgn( wnd->hrgnUpdate, wnd->hrgnUpdate, hrgnTemp, RGN_OR ); |
Alexandre Julliard | 9ea19e5 | 1997-01-01 17:29:55 +0000 | [diff] [blame] | 310 | } |
| 311 | |
| 312 | if( flags & SW_SCROLLCHILDREN ) |
| 313 | { |
Alexandre Julliard | a396029 | 1999-02-26 11:11:13 +0000 | [diff] [blame] | 314 | RECT r; |
Alexandre Julliard | 9ea19e5 | 1997-01-01 17:29:55 +0000 | [diff] [blame] | 315 | WND* w; |
Francois Boisvert | 6b1b41c | 1999-03-14 17:25:32 +0000 | [diff] [blame] | 316 | for( w =WIN_LockWndPtr(wnd->child); w; WIN_UpdateWndPtr(&w, w->next)) |
Alexandre Julliard | 9ea19e5 | 1997-01-01 17:29:55 +0000 | [diff] [blame] | 317 | { |
| 318 | CONV_RECT16TO32( &w->rectWindow, &r ); |
Alexandre Julliard | a396029 | 1999-02-26 11:11:13 +0000 | [diff] [blame] | 319 | if( IntersectRect(&r, &r, &rc) ) |
| 320 | SetWindowPos(w->hwndSelf, 0, w->rectWindow.left + dx, |
Alexandre Julliard | 01d6346 | 1997-01-20 19:43:45 +0000 | [diff] [blame] | 321 | w->rectWindow.top + dy, 0,0, SWP_NOZORDER | |
| 322 | SWP_NOSIZE | SWP_NOACTIVATE | SWP_NOREDRAW | |
| 323 | SWP_DEFERERASE ); |
Alexandre Julliard | 9ea19e5 | 1997-01-01 17:29:55 +0000 | [diff] [blame] | 324 | } |
| 325 | } |
| 326 | |
| 327 | if( flags & (SW_INVALIDATE | SW_ERASE) ) |
Alexandre Julliard | 670cdc4 | 1997-08-24 16:00:30 +0000 | [diff] [blame] | 328 | PAINT_RedrawWindow( hwnd, NULL, hrgnUpdate, RDW_INVALIDATE | RDW_ERASE | |
| 329 | ((flags & SW_ERASE) ? RDW_ERASENOW : 0) | ((flags & SW_SCROLLCHILDREN) ? RDW_ALLCHILDREN : 0 ), 0 ); |
Alexandre Julliard | 9ea19e5 | 1997-01-01 17:29:55 +0000 | [diff] [blame] | 330 | |
| 331 | if( bCaret ) |
| 332 | { |
Alexandre Julliard | a396029 | 1999-02-26 11:11:13 +0000 | [diff] [blame] | 333 | SetCaretPos( caretrc.left + dx, caretrc.top + dy ); |
| 334 | ShowCaret(0); |
Alexandre Julliard | 9ea19e5 | 1997-01-01 17:29:55 +0000 | [diff] [blame] | 335 | } |
| 336 | |
Alexandre Julliard | a396029 | 1999-02-26 11:11:13 +0000 | [diff] [blame] | 337 | if( bOwnRgn && hrgnUpdate ) DeleteObject( hrgnUpdate ); |
| 338 | DeleteObject( hrgnClip ); |
| 339 | DeleteObject( hrgnTemp ); |
Alexandre Julliard | 9ea19e5 | 1997-01-01 17:29:55 +0000 | [diff] [blame] | 340 | } |
Francois Boisvert | 6b1b41c | 1999-03-14 17:25:32 +0000 | [diff] [blame] | 341 | END: |
| 342 | WIN_ReleaseWndPtr(wnd); |
Alexandre Julliard | 9ea19e5 | 1997-01-01 17:29:55 +0000 | [diff] [blame] | 343 | return retVal; |
Alexandre Julliard | e399fc3 | 1993-11-24 17:08:56 +0000 | [diff] [blame] | 344 | } |