user32: Use client-side user handles for DeferWindowPos.

This commit is contained in:
Alexandre Julliard 2009-10-12 15:31:22 +02:00
parent d996f7e334
commit da3c4c995a
1 changed files with 34 additions and 27 deletions

View File

@ -68,17 +68,13 @@ WINE_DEFAULT_DEBUG_CHANNEL(win);
#define PLACE_MAX 0x0002 #define PLACE_MAX 0x0002
#define PLACE_RECT 0x0004 #define PLACE_RECT 0x0004
#define DWP_MAGIC ((INT)('W' | ('P' << 8) | ('O' << 16) | ('S' << 24)))
typedef struct typedef struct
{ {
struct user_object obj;
INT actualCount; INT actualCount;
INT suggestedCount; INT suggestedCount;
BOOL valid;
INT wMagic;
HWND hwndParent; HWND hwndParent;
WINDOWPOS winPos[1]; WINDOWPOS *winPos;
} DWP; } DWP;
@ -2073,7 +2069,7 @@ BOOL WINAPI SetWindowPos( HWND hwnd, HWND hwndInsertAfter,
*/ */
HDWP WINAPI BeginDeferWindowPos( INT count ) HDWP WINAPI BeginDeferWindowPos( INT count )
{ {
HDWP handle; HDWP handle = 0;
DWP *pDWP; DWP *pDWP;
TRACE("%d\n", count); TRACE("%d\n", count);
@ -2086,15 +2082,19 @@ HDWP WINAPI BeginDeferWindowPos( INT count )
/* Windows allows zero count, in which case it allocates context for 8 moves */ /* Windows allows zero count, in which case it allocates context for 8 moves */
if (count == 0) count = 8; if (count == 0) count = 8;
handle = USER_HEAP_ALLOC( sizeof(DWP) + (count-1)*sizeof(WINDOWPOS) ); if (!(pDWP = HeapAlloc( GetProcessHeap(), 0, sizeof(DWP)))) return 0;
if (!handle) return 0;
pDWP = USER_HEAP_LIN_ADDR( handle );
pDWP->actualCount = 0; pDWP->actualCount = 0;
pDWP->suggestedCount = count; pDWP->suggestedCount = count;
pDWP->valid = TRUE;
pDWP->wMagic = DWP_MAGIC;
pDWP->hwndParent = 0; pDWP->hwndParent = 0;
if (!(pDWP->winPos = HeapAlloc( GetProcessHeap(), 0, count * sizeof(WINDOWPOS) )) ||
!(handle = alloc_user_handle( &pDWP->obj, USER_DWP )))
{
HeapFree( GetProcessHeap(), 0, pDWP->winPos );
HeapFree( GetProcessHeap(), 0, pDWP );
}
TRACE("returning hdwp %p\n", handle); TRACE("returning hdwp %p\n", handle);
return handle; return handle;
} }
@ -2109,7 +2109,7 @@ HDWP WINAPI DeferWindowPos( HDWP hdwp, HWND hwnd, HWND hwndAfter,
{ {
DWP *pDWP; DWP *pDWP;
int i; int i;
HDWP newhdwp = hdwp,retvalue; HDWP retvalue = hdwp;
TRACE("hdwp %p, hwnd %p, after %p, %d,%d (%dx%d), flags %08x\n", TRACE("hdwp %p, hwnd %p, after %p, %d,%d (%dx%d), flags %08x\n",
hdwp, hwnd, hwndAfter, x, y, cx, cy, flags); hdwp, hwnd, hwndAfter, x, y, cx, cy, flags);
@ -2117,9 +2117,12 @@ HDWP WINAPI DeferWindowPos( HDWP hdwp, HWND hwnd, HWND hwndAfter,
hwnd = WIN_GetFullHandle( hwnd ); hwnd = WIN_GetFullHandle( hwnd );
if (is_desktop_window( hwnd )) return 0; if (is_desktop_window( hwnd )) return 0;
if (!(pDWP = USER_HEAP_LIN_ADDR( hdwp ))) return 0; if (!(pDWP = get_user_handle_ptr( hdwp, USER_DWP ))) return 0;
if (pDWP == OBJ_OTHER_PROCESS)
USER_Lock(); {
FIXME( "other process handle %p?\n", hdwp );
return 0;
}
for (i = 0; i < pDWP->actualCount; i++) for (i = 0; i < pDWP->actualCount; i++)
{ {
@ -2146,21 +2149,20 @@ HDWP WINAPI DeferWindowPos( HDWP hdwp, HWND hwnd, HWND hwndAfter,
SWP_NOOWNERZORDER); SWP_NOOWNERZORDER);
pDWP->winPos[i].flags |= flags & (SWP_SHOWWINDOW | SWP_HIDEWINDOW | pDWP->winPos[i].flags |= flags & (SWP_SHOWWINDOW | SWP_HIDEWINDOW |
SWP_FRAMECHANGED); SWP_FRAMECHANGED);
retvalue = hdwp;
goto END; goto END;
} }
} }
if (pDWP->actualCount >= pDWP->suggestedCount) if (pDWP->actualCount >= pDWP->suggestedCount)
{ {
newhdwp = USER_HEAP_REALLOC( hdwp, WINDOWPOS *newpos = HeapReAlloc( GetProcessHeap(), 0, pDWP->winPos,
sizeof(DWP) + pDWP->suggestedCount*sizeof(WINDOWPOS) ); pDWP->suggestedCount * 2 * sizeof(WINDOWPOS) );
if (!newhdwp) if (!newpos)
{ {
retvalue = 0; retvalue = 0;
goto END; goto END;
} }
pDWP = USER_HEAP_LIN_ADDR( newhdwp ); pDWP->suggestedCount *= 2;
pDWP->suggestedCount++; pDWP->winPos = newpos;
} }
pDWP->winPos[pDWP->actualCount].hwnd = hwnd; pDWP->winPos[pDWP->actualCount].hwnd = hwnd;
pDWP->winPos[pDWP->actualCount].hwndInsertAfter = hwndAfter; pDWP->winPos[pDWP->actualCount].hwndInsertAfter = hwndAfter;
@ -2170,9 +2172,8 @@ HDWP WINAPI DeferWindowPos( HDWP hdwp, HWND hwnd, HWND hwndAfter,
pDWP->winPos[pDWP->actualCount].cy = cy; pDWP->winPos[pDWP->actualCount].cy = cy;
pDWP->winPos[pDWP->actualCount].flags = flags; pDWP->winPos[pDWP->actualCount].flags = flags;
pDWP->actualCount++; pDWP->actualCount++;
retvalue = newhdwp;
END: END:
USER_Unlock(); release_user_handle_ptr( pDWP );
return retvalue; return retvalue;
} }
@ -2189,8 +2190,13 @@ BOOL WINAPI EndDeferWindowPos( HDWP hdwp )
TRACE("%p\n", hdwp); TRACE("%p\n", hdwp);
pDWP = USER_HEAP_LIN_ADDR( hdwp ); if (!(pDWP = free_user_handle( hdwp, USER_DWP ))) return FALSE;
if (!pDWP) return FALSE; if (pDWP == OBJ_OTHER_PROCESS)
{
FIXME( "other process handle %p?\n", hdwp );
return FALSE;
}
for (i = 0, winpos = pDWP->winPos; res && i < pDWP->actualCount; i++, winpos++) for (i = 0, winpos = pDWP->winPos; res && i < pDWP->actualCount; i++, winpos++)
{ {
TRACE("hwnd %p, after %p, %d,%d (%dx%d), flags %08x\n", TRACE("hwnd %p, after %p, %d,%d (%dx%d), flags %08x\n",
@ -2202,7 +2208,8 @@ BOOL WINAPI EndDeferWindowPos( HDWP hdwp )
else else
res = SendMessageW( winpos->hwnd, WM_WINE_SETWINDOWPOS, 0, (LPARAM)winpos ); res = SendMessageW( winpos->hwnd, WM_WINE_SETWINDOWPOS, 0, (LPARAM)winpos );
} }
USER_HEAP_FREE( hdwp ); HeapFree( GetProcessHeap(), 0, pDWP->winPos );
HeapFree( GetProcessHeap(), 0, pDWP );
return res; return res;
} }