Release 940405
[wine/gsoc-2012-control.git] / windows / winpos.c
blob0534bc846e62fd831c13f423c9ce08d32a118612
1 /*
2 * Window position related functions.
4 * Copyright 1993 Alexandre Julliard
5 */
7 static char Copyright[] = "Copyright Alexandre Julliard, 1993";
9 #include "sysmetrics.h"
10 #include "user.h"
11 #include "win.h"
12 #include "message.h"
14 static HWND hwndActive = 0; /* Currently active window */
17 /***********************************************************************
18 * GetWindowRect (USER.32)
20 void GetWindowRect( HWND hwnd, LPRECT rect )
22 WND * wndPtr = WIN_FindWndPtr( hwnd );
23 if (!wndPtr) return;
25 *rect = wndPtr->rectWindow;
26 if (wndPtr->dwStyle & WS_CHILD)
27 MapWindowPoints( wndPtr->hwndParent, 0, (POINT *)rect, 2 );
31 /***********************************************************************
32 * GetClientRect (USER.33)
34 void GetClientRect( HWND hwnd, LPRECT rect )
36 WND * wndPtr = WIN_FindWndPtr( hwnd );
38 rect->left = rect->top = rect->right = rect->bottom = 0;
39 if (wndPtr)
41 rect->right = wndPtr->rectClient.right - wndPtr->rectClient.left;
42 rect->bottom = wndPtr->rectClient.bottom - wndPtr->rectClient.top;
47 /*******************************************************************
48 * ClientToScreen (USER.28)
50 void ClientToScreen( HWND hwnd, LPPOINT lppnt )
52 MapWindowPoints( hwnd, 0, lppnt, 1 );
56 /*******************************************************************
57 * ScreenToClient (USER.29)
59 void ScreenToClient( HWND hwnd, LPPOINT lppnt )
61 MapWindowPoints( 0, hwnd, lppnt, 1 );
65 /*******************************************************************
66 * WindowFromPoint (USER.30)
68 HWND WindowFromPoint( POINT pt )
70 HWND hwndRet = 0;
71 HWND hwnd = GetDesktopWindow();
73 while(hwnd)
75 /* If point is in window, and window is visible, */
76 /* not disabled and not transparent, then explore */
77 /* its children. Otherwise, go to the next window. */
79 WND *wndPtr = WIN_FindWndPtr( hwnd );
80 if ((pt.x >= wndPtr->rectWindow.left) &&
81 (pt.x < wndPtr->rectWindow.right) &&
82 (pt.y >= wndPtr->rectWindow.top) &&
83 (pt.y < wndPtr->rectWindow.bottom) &&
84 !(wndPtr->dwStyle & WS_DISABLED) &&
85 (wndPtr->dwStyle & WS_VISIBLE) &&
86 !(wndPtr->dwExStyle & WS_EX_TRANSPARENT))
88 pt.x -= wndPtr->rectClient.left;
89 pt.y -= wndPtr->rectClient.top;
90 hwndRet = hwnd;
91 hwnd = wndPtr->hwndChild;
93 else hwnd = wndPtr->hwndNext;
95 return hwndRet;
99 /*******************************************************************
100 * ChildWindowFromPoint (USER.191)
102 HWND ChildWindowFromPoint( HWND hwndParent, POINT pt )
104 RECT rect;
105 HWND hwnd;
107 GetWindowRect( hwndParent, &rect );
108 if (!PtInRect( &rect, pt )) return 0;
109 hwnd = GetTopWindow( hwndParent );
110 while (hwnd)
112 GetWindowRect( hwnd, &rect );
113 if (PtInRect( &rect, pt )) return hwnd;
114 hwnd = GetWindow( hwnd, GW_HWNDNEXT );
116 return hwndParent;
120 /*******************************************************************
121 * MapWindowPoints (USER.258)
123 void MapWindowPoints( HWND hwndFrom, HWND hwndTo, LPPOINT lppt, WORD count )
125 WND * wndPtr;
126 POINT * curpt;
127 POINT origin = { 0, 0 };
128 WORD i;
130 /* Translate source window origin to screen coords */
131 while(hwndFrom)
133 wndPtr = WIN_FindWndPtr( hwndFrom );
134 origin.x += wndPtr->rectClient.left;
135 origin.y += wndPtr->rectClient.top;
136 hwndFrom = (wndPtr->dwStyle & WS_CHILD) ? wndPtr->hwndParent : 0;
139 /* Translate origin to destination window coords */
140 while(hwndTo)
142 wndPtr = WIN_FindWndPtr( hwndTo );
143 origin.x -= wndPtr->rectClient.left;
144 origin.y -= wndPtr->rectClient.top;
145 hwndTo = (wndPtr->dwStyle & WS_CHILD) ? wndPtr->hwndParent : 0;
148 /* Translate points */
149 for (i = 0, curpt = lppt; i < count; i++, curpt++)
151 curpt->x += origin.x;
152 curpt->y += origin.y;
157 /***********************************************************************
158 * IsIconic (USER.31)
160 BOOL IsIconic(HWND hWnd)
162 WND * wndPtr = WIN_FindWndPtr(hWnd);
163 if (wndPtr == NULL) return FALSE;
164 return (wndPtr->dwStyle & WS_MINIMIZE) != 0;
168 /***********************************************************************
169 * IsZoomed (USER.272)
171 BOOL IsZoomed(HWND hWnd)
173 WND * wndPtr = WIN_FindWndPtr(hWnd);
174 if (wndPtr == NULL) return FALSE;
175 return (wndPtr->dwStyle & WS_MAXIMIZE) != 0;
179 /*******************************************************************
180 * GetActiveWindow (USER.60)
182 HWND GetActiveWindow()
184 return hwndActive;
187 /*******************************************************************
188 * SetActiveWindow (USER.59)
190 HWND SetActiveWindow( HWND hwnd )
192 HWND prev = hwndActive;
193 WND *wndPtr = WIN_FindWndPtr( hwnd );
194 if (!wndPtr || (wndPtr->dwStyle & WS_CHILD)) return 0;
195 SetWindowPos( hwnd, HWND_TOP, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE );
196 return prev;
200 /***********************************************************************
201 * BringWindowToTop (USER.45)
203 BOOL BringWindowToTop( HWND hwnd )
205 return SetWindowPos( hwnd, HWND_TOP, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE );
209 /***********************************************************************
210 * MoveWindow (USER.56)
212 BOOL MoveWindow( HWND hwnd, short x, short y, short cx, short cy, BOOL repaint)
214 int flags = SWP_NOZORDER | SWP_NOACTIVATE;
215 if (!repaint) flags |= SWP_NOREDRAW;
216 #ifdef DEBUG_WIN
217 printf( "MoveWindow: %d %d,%d %dx%d %d\n", hwnd, x, y, cx, cy, repaint );
218 #endif
219 return SetWindowPos( hwnd, 0, x, y, cx, cy, flags );
223 /***********************************************************************
224 * ShowWindow (USER.42)
226 BOOL ShowWindow( HWND hwnd, int cmd )
228 WND * wndPtr = WIN_FindWndPtr( hwnd );
229 BOOL wasVisible;
230 int swpflags = 0;
232 #ifdef DEBUG_WIN
233 printf("ShowWindow: hwnd=%d, cmd=%d\n", hwnd, cmd);
234 #endif
236 if (!wndPtr) return FALSE;
237 wasVisible = (wndPtr->dwStyle & WS_VISIBLE) != 0;
238 switch(cmd)
240 case SW_HIDE:
241 if (!wasVisible) return FALSE; /* Nothing to do */
242 swpflags |= SWP_HIDEWINDOW | SWP_NOSIZE | SWP_NOMOVE |
243 SWP_NOACTIVATE | SWP_NOZORDER;
244 break;
246 case SW_SHOWMINNOACTIVE:
247 case SW_SHOWMINIMIZED:
248 case SW_SHOWMAXIMIZED:
249 case SW_MINIMIZE:
250 wndPtr->dwStyle |= WS_MINIMIZE;
251 swpflags |= SWP_SHOWWINDOW | SWP_NOSIZE | SWP_NOMOVE |
252 SWP_NOACTIVATE | SWP_NOZORDER;
253 break;
255 case SW_SHOWNA:
256 case SW_MAXIMIZE:
257 case SW_SHOW:
258 swpflags |= SWP_SHOWWINDOW | SWP_NOSIZE | SWP_NOMOVE;
259 break;
261 case SW_NORMAL:
262 case SW_SHOWNORMAL:
263 case SW_SHOWNOACTIVATE:
264 case SW_RESTORE:
265 wndPtr->dwStyle &= ~WS_MINIMIZE;
266 wndPtr->dwStyle &= ~WS_MAXIMIZE;
267 swpflags |= SWP_SHOWWINDOW | SWP_NOSIZE | SWP_NOMOVE;
268 if (cmd == SW_SHOWNOACTIVATE)
270 swpflags |= SWP_NOZORDER;
271 if (GetActiveWindow()) swpflags |= SWP_NOACTIVATE;
273 break;
275 SendMessage( hwnd, WM_SHOWWINDOW, (cmd != SW_HIDE), 0 );
276 SetWindowPos( hwnd, 0, 0, 0, 0, 0, swpflags );
278 /* Send WM_SIZE and WM_MOVE messages if not already done */
279 if (!(wndPtr->flags & WIN_GOT_SIZEMSG))
281 int wParam = SIZE_RESTORED;
282 if (wndPtr->dwStyle & WS_MAXIMIZE) wParam = SIZE_MAXIMIZED;
283 else if (wndPtr->dwStyle & WS_MINIMIZE) wParam = SIZE_MINIMIZED;
284 wndPtr->flags |= WIN_GOT_SIZEMSG;
285 SendMessage( hwnd, WM_SIZE, wParam,
286 MAKELONG(wndPtr->rectClient.right-wndPtr->rectClient.left,
287 wndPtr->rectClient.bottom-wndPtr->rectClient.top));
288 SendMessage( hwnd, WM_MOVE, 0,
289 MAKELONG(wndPtr->rectClient.left, wndPtr->rectClient.top) );
291 return wasVisible;
295 /***********************************************************************
296 * GetInternalWindowPos (USER.460)
298 WORD GetInternalWindowPos( HWND hwnd, LPRECT rectWnd, LPPOINT ptIcon )
300 WINDOWPLACEMENT wndpl;
301 if (!GetWindowPlacement( hwnd, &wndpl )) return 0;
302 if (rectWnd) *rectWnd = wndpl.rcNormalPosition;
303 if (ptIcon) *ptIcon = wndpl.ptMinPosition;
304 return wndpl.showCmd;
308 /***********************************************************************
309 * SetInternalWindowPos (USER.461)
311 void SetInternalWindowPos( HWND hwnd, WORD showCmd, LPRECT rect, LPPOINT pt )
313 WINDOWPLACEMENT wndpl;
314 WND *wndPtr = WIN_FindWndPtr( hwnd );
316 wndpl.length = sizeof(wndpl);
317 wndpl.flags = (pt != NULL) ? WPF_SETMINPOSITION : 0;
318 wndpl.showCmd = showCmd;
319 if (pt) wndpl.ptMinPosition = *pt;
320 wndpl.rcNormalPosition = (rect != NULL) ? *rect : wndPtr->rectNormal;
321 wndpl.ptMaxPosition = wndPtr->ptMaxPos;
322 SetWindowPlacement( hwnd, &wndpl );
326 /***********************************************************************
327 * GetWindowPlacement (USER.370)
329 BOOL GetWindowPlacement( HWND hwnd, WINDOWPLACEMENT *wndpl )
331 WND *wndPtr = WIN_FindWndPtr( hwnd );
332 if (!wndPtr) return FALSE;
334 wndpl->length = sizeof(*wndpl);
335 wndpl->flags = 0;
336 wndpl->showCmd = IsZoomed(hwnd) ? SW_SHOWMAXIMIZED :
337 (IsIconic(hwnd) ? SW_SHOWMINIMIZED : SW_SHOWNORMAL);
338 wndpl->ptMinPosition = wndPtr->ptIconPos;
339 wndpl->ptMaxPosition = wndPtr->ptMaxPos;
340 wndpl->rcNormalPosition = wndPtr->rectNormal;
341 return TRUE;
345 /***********************************************************************
346 * SetWindowPlacement (USER.371)
348 BOOL SetWindowPlacement( HWND hwnd, WINDOWPLACEMENT *wndpl )
350 WND *wndPtr = WIN_FindWndPtr( hwnd );
351 if (!wndPtr) return FALSE;
353 if (wndpl->flags & WPF_SETMINPOSITION)
354 wndPtr->ptIconPos = wndpl->ptMinPosition;
355 if ((wndpl->flags & WPF_RESTORETOMAXIMIZED) &&
356 (wndpl->showCmd == SW_SHOWMINIMIZED)) wndPtr->flags |= WIN_RESTORE_MAX;
357 wndPtr->ptMaxPos = wndpl->ptMaxPosition;
358 wndPtr->rectNormal = wndpl->rcNormalPosition;
359 ShowWindow( hwnd, wndpl->showCmd );
360 return TRUE;
364 /*******************************************************************
365 * WINPOS_GetMinMaxInfo
367 * Send a WM_GETMINMAXINFO to the window.
369 void WINPOS_GetMinMaxInfo( HWND hwnd, POINT *maxSize, POINT *maxPos,
370 POINT *minTrack, POINT *maxTrack )
372 HANDLE minmaxHandle;
373 MINMAXINFO MinMax, *pMinMax;
374 WND *wndPtr = WIN_FindWndPtr( hwnd );
376 MinMax.ptMaxSize.x = SYSMETRICS_CXSCREEN;
377 MinMax.ptMaxSize.y = SYSMETRICS_CYSCREEN;
378 MinMax.ptMaxPosition = wndPtr->ptMaxPos;
379 MinMax.ptMinTrackSize.x = SYSMETRICS_CXMINTRACK;
380 MinMax.ptMinTrackSize.y = SYSMETRICS_CYMINTRACK;
381 MinMax.ptMaxTrackSize.x = SYSMETRICS_CXSCREEN;
382 MinMax.ptMaxTrackSize.y = SYSMETRICS_CYSCREEN;
384 minmaxHandle = USER_HEAP_ALLOC( LMEM_MOVEABLE, sizeof(MINMAXINFO) );
385 if (minmaxHandle)
387 pMinMax = (MINMAXINFO *) USER_HEAP_ADDR( minmaxHandle );
388 memcpy( pMinMax, &MinMax, sizeof(MinMax) );
389 SendMessage( hwnd, WM_GETMINMAXINFO, 0, (LONG)pMinMax );
391 else pMinMax = &MinMax;
393 /* Some sanity checks */
395 pMinMax->ptMaxTrackSize.x = max( pMinMax->ptMaxTrackSize.x,
396 pMinMax->ptMinTrackSize.x );
397 pMinMax->ptMaxTrackSize.y = max( pMinMax->ptMaxTrackSize.y,
398 pMinMax->ptMinTrackSize.y );
400 if (maxSize) *maxSize = pMinMax->ptMaxSize;
401 if (maxPos) *maxPos = pMinMax->ptMaxPosition;
402 if (minTrack) *minTrack = pMinMax->ptMinTrackSize;
403 if (maxTrack) *maxTrack = pMinMax->ptMaxTrackSize;
404 if (minmaxHandle) USER_HEAP_FREE( minmaxHandle );
408 /*******************************************************************
409 * WINPOS_ChangeActiveWindow
411 * Change the active window and send the corresponding messages.
413 HWND WINPOS_ChangeActiveWindow( HWND hwnd, BOOL mouseMsg )
415 HWND prevActive = hwndActive;
416 if (hwnd == hwndActive) return 0;
417 if (hwndActive)
419 if (!SendMessage( hwndActive, WM_NCACTIVATE, FALSE, 0 )) return 0;
420 SendMessage( hwndActive, WM_ACTIVATE, WA_INACTIVE,
421 MAKELONG( IsIconic(hwndActive), hwnd ) );
422 /* Send WM_ACTIVATEAPP here */
425 hwndActive = hwnd;
426 if (hwndActive)
428 /* Send WM_ACTIVATEAPP here */
429 SendMessage( hwnd, WM_NCACTIVATE, TRUE, 0 );
430 SendMessage( hwnd, WM_ACTIVATE, mouseMsg ? WA_CLICKACTIVE : WA_ACTIVE,
431 MAKELONG( IsIconic(hwnd), prevActive ) );
433 return prevActive;
437 /***********************************************************************
438 * SetWindowPos (USER.232)
440 /* Unimplemented flags: SWP_NOREDRAW
442 /* Note: all this code should be in the DeferWindowPos() routines,
443 * and SetWindowPos() should simply call them. This will be implemented
444 * some day...
446 BOOL SetWindowPos( HWND hwnd, HWND hwndInsertAfter, short x, short y,
447 short cx, short cy, WORD flags )
449 WINDOWPOS *winPos;
450 HANDLE hmem = 0;
451 RECT newWindowRect, newClientRect;
452 WND *wndPtr;
453 int calcsize_result = 0;
454 XWindowChanges winChanges;
455 int changeMask = 0;
457 #ifdef DEBUG_WIN
458 printf( "SetWindowPos: %d %d %d,%d %dx%d 0x%x\n",
459 hwnd, hwndInsertAfter, x, y, cx, cy, flags );
460 #endif
462 if (!(wndPtr = WIN_FindWndPtr( hwnd ))) return FALSE;
463 if (flags & (SWP_SHOWWINDOW | SWP_HIDEWINDOW))
464 flags |= SWP_NOMOVE | SWP_NOSIZE;
466 /* Send WM_WINDOWPOSCHANGING message */
468 if (!(hmem = USER_HEAP_ALLOC( GMEM_MOVEABLE, sizeof(WINDOWPOS) )))
469 return FALSE;
470 winPos = (WINDOWPOS *)USER_HEAP_ADDR( hmem );
471 winPos->hwnd = hwnd;
472 winPos->hwndInsertAfter = hwndInsertAfter;
473 winPos->x = x;
474 winPos->y = y;
475 winPos->cx = cx;
476 winPos->cy = cy;
477 winPos->flags = flags;
478 SendMessage( hwnd, WM_WINDOWPOSCHANGING, 0, (LONG)winPos );
479 hwndInsertAfter = winPos->hwndInsertAfter;
481 /* Some sanity checks */
483 if (!IsWindow( hwnd ) || (hwnd == GetDesktopWindow())) goto Abort;
484 if (flags & (SWP_SHOWWINDOW | SWP_HIDEWINDOW))
485 flags |= SWP_NOMOVE | SWP_NOSIZE;
486 if (!(flags & (SWP_NOZORDER | SWP_NOACTIVATE)))
488 if (hwnd != hwndActive) hwndInsertAfter = HWND_TOP;
489 else if ((hwndInsertAfter == HWND_TOPMOST) ||
490 (hwndInsertAfter == HWND_NOTOPMOST))
491 hwndInsertAfter = HWND_TOP;
494 /* Calculate new position and size */
496 newWindowRect = wndPtr->rectWindow;
497 newClientRect = wndPtr->rectClient;
499 if (!(winPos->flags & SWP_NOSIZE))
501 newWindowRect.right = newWindowRect.left + winPos->cx;
502 newWindowRect.bottom = newWindowRect.top + winPos->cy;
505 if (!(winPos->flags & SWP_NOMOVE))
507 newWindowRect.left = winPos->x;
508 newWindowRect.top = winPos->y;
509 newWindowRect.right += winPos->x - wndPtr->rectWindow.left;
510 newWindowRect.bottom += winPos->y - wndPtr->rectWindow.top;
513 /* Reposition window in Z order */
515 if (!(winPos->flags & SWP_NOZORDER))
517 /* TOPMOST not supported yet */
518 if ((hwndInsertAfter == HWND_TOPMOST) ||
519 (hwndInsertAfter == HWND_NOTOPMOST)) hwndInsertAfter = HWND_TOP;
521 /* Make sure hwndInsertAfter is a sibling of hwnd */
522 if ((hwndInsertAfter != HWND_TOP) && (hwndInsertAfter != HWND_BOTTOM))
523 if (GetParent(hwnd) != GetParent(hwndInsertAfter)) goto Abort;
525 WIN_UnlinkWindow( hwnd );
526 WIN_LinkWindow( hwnd, hwndInsertAfter );
529 /* Recalculate client area position */
531 if (winPos->flags & SWP_FRAMECHANGED)
533 /* Send WM_NCCALCSIZE message */
534 NCCALCSIZE_PARAMS *params;
535 HANDLE hparams;
537 if (!(hparams = USER_HEAP_ALLOC( GMEM_MOVEABLE, sizeof(*params) )))
538 goto Abort;
539 params = (NCCALCSIZE_PARAMS *) USER_HEAP_ADDR( hparams );
540 params->rgrc[0] = newWindowRect;
541 params->rgrc[1] = wndPtr->rectWindow;
542 params->rgrc[2] = wndPtr->rectClient;
543 params->lppos = winPos;
544 calcsize_result = SendMessage(hwnd, WM_NCCALCSIZE, TRUE, (LONG)params);
545 USER_HEAP_FREE( hparams );
546 newClientRect = params->rgrc[0];
547 /* Handle result here */
549 else
551 newClientRect.left = newWindowRect.left + wndPtr->rectClient.left
552 - wndPtr->rectWindow.left;
553 newClientRect.top = newWindowRect.top + wndPtr->rectClient.top
554 - wndPtr->rectWindow.top;
555 newClientRect.right = newWindowRect.right + wndPtr->rectClient.right
556 - wndPtr->rectWindow.right;
557 newClientRect.bottom = newWindowRect.bottom + wndPtr->rectClient.bottom
558 - wndPtr->rectWindow.bottom;
561 /* Perform the moving and resizing */
563 if (!(winPos->flags & SWP_NOMOVE))
565 WND * parentPtr;
566 winChanges.x = newWindowRect.left;
567 winChanges.y = newWindowRect.top;
568 if (wndPtr->dwStyle & WS_CHILD)
570 parentPtr = WIN_FindWndPtr(wndPtr->hwndParent);
571 winChanges.x += parentPtr->rectClient.left-parentPtr->rectWindow.left;
572 winChanges.y += parentPtr->rectClient.top-parentPtr->rectWindow.top;
574 changeMask |= CWX | CWY;
576 if (!(winPos->flags & SWP_NOSIZE))
578 winChanges.width = newWindowRect.right - newWindowRect.left;
579 winChanges.height = newWindowRect.bottom - newWindowRect.top;
580 changeMask |= CWWidth | CWHeight;
582 if (!(winPos->flags & SWP_NOZORDER))
584 if (hwndInsertAfter == HWND_TOP) winChanges.stack_mode = Above;
585 else winChanges.stack_mode = Below;
586 if ((hwndInsertAfter != HWND_TOP) && (hwndInsertAfter != HWND_BOTTOM))
588 WND * insertPtr = WIN_FindWndPtr( hwndInsertAfter );
589 winChanges.sibling = insertPtr->window;
590 changeMask |= CWSibling;
592 changeMask |= CWStackMode;
594 if (changeMask) XConfigureWindow( display, wndPtr->window,
595 changeMask, &winChanges );
597 if (winPos->flags & SWP_SHOWWINDOW)
599 wndPtr->dwStyle |= WS_VISIBLE;
600 XMapWindow( display, wndPtr->window );
601 MSG_Synchronize();
602 if (!(winPos->flags & SWP_NOREDRAW))
603 RedrawWindow( hwnd, NULL, 0, RDW_INVALIDATE | RDW_ERASE |
604 RDW_ERASENOW | RDW_FRAME );
605 else RedrawWindow( hwnd, NULL, 0, RDW_VALIDATE );
608 else if (winPos->flags & SWP_HIDEWINDOW)
610 wndPtr->dwStyle &= ~WS_VISIBLE;
611 XUnmapWindow( display, wndPtr->window );
614 if (!(winPos->flags & SWP_NOACTIVATE))
616 if (!(wndPtr->dwStyle & WS_CHILD))
617 WINPOS_ChangeActiveWindow( hwnd, FALSE );
620 /* Send WM_NCPAINT message if needed */
621 if ((winPos->flags & (SWP_FRAMECHANGED | SWP_SHOWWINDOW)) ||
622 (!(winPos->flags & SWP_NOSIZE)) ||
623 (!(winPos->flags & SWP_NOMOVE)) ||
624 (!(winPos->flags & SWP_NOACTIVATE)) ||
625 (!(winPos->flags & SWP_NOZORDER)))
626 SendMessage( hwnd, WM_NCPAINT, 1, 0L );
628 /* Finally send the WM_WINDOWPOSCHANGED message */
629 wndPtr->rectWindow = newWindowRect;
630 wndPtr->rectClient = newClientRect;
631 SendMessage( hwnd, WM_WINDOWPOSCHANGED, 0, (LONG)winPos );
632 USER_HEAP_FREE( hmem );
634 return TRUE;
636 Abort: /* Fatal error encountered */
637 if (hmem) USER_HEAP_FREE( hmem );
638 return FALSE;