Newer
Older
* 1995, 1996, 1999 Alex Korobka
#include "winerror.h"
#include "windef.h"
#include "wingdi.h"
#include "wine/winuser16.h"
#include "wine/server.h"
#include "controls.h"
#include "region.h"
#include "debugtools.h"
#include "input.h"
DEFAULT_DEBUG_CHANNEL(win);
#define HAS_DLGFRAME(style,exStyle) \
(((exStyle) & WS_EX_DLGMODALFRAME) || \
(((style) & WS_DLGFRAME) && !((style) & WS_BORDER)))
#define HAS_THICKFRAME(style) \
(((style) & WS_THICKFRAME) && \
!(((style) & (WS_DLGFRAME|WS_BORDER)) == WS_DLGFRAME))
#define EMPTYPOINT(pt) ((*(LONG*)&(pt)) == -1)
#define PLACE_MIN 0x0001
#define PLACE_MAX 0x0002
#define PLACE_RECT 0x0004
#define DWP_MAGIC ((INT)('W' | ('P' << 8) | ('O' << 16) | ('S' << 24)))
typedef struct
{
INT actualCount;
INT suggestedCount;
BOOL valid;
INT wMagic;
HWND hwndParent;
WINDOWPOS winPos[1];
} DWP;
static HWND hwndPrevActive = 0; /* Previously active window */
static HWND hGlobalShellWindow=0; /*the shell*/
static HWND hGlobalTaskmanWindow=0;
static HWND hGlobalProgmanWindow=0;
extern HQUEUE16 hActiveQueue;
/***********************************************************************
BOOL WINPOS_CreateInternalPosAtom()
atomInternalPos = (LPCSTR)(DWORD)GlobalAddAtomA(str);
return (atomInternalPos) ? TRUE : FALSE;
}
/***********************************************************************
* WINPOS_CheckInternalPos
*
* Called when a window is destroyed.
*/
void WINPOS_CheckInternalPos( HWND hwnd )
LPINTERNALPOS lpPos;
MESSAGEQUEUE *pMsgQ = 0;
WND *wndPtr = WIN_GetPtr( hwnd );
if (!wndPtr || wndPtr == WND_OTHER_PROCESS) return;
lpPos = (LPINTERNALPOS) GetPropA( hwnd, atomInternalPos );
/* Retrieve the message queue associated with this window */
pMsgQ = (MESSAGEQUEUE *)QUEUE_Lock( wndPtr->hmemTaskQ );
if ( !pMsgQ )
{
WARN("\tMessage queue not found. Exiting!\n" );
WIN_ReleasePtr( wndPtr );
return;
}
if( hwnd == hwndPrevActive ) hwndPrevActive = 0;
if( hwnd == PERQDATA_GetActiveWnd( pMsgQ->pQData ) )
PERQDATA_SetActiveWnd( pMsgQ->pQData, 0 );
WARN("\tattempt to activate destroyed window!\n");
if( IsWindow(lpPos->hwndIconTitle) )
DestroyWindow( lpPos->hwndIconTitle );
HeapFree( GetProcessHeap(), 0, lpPos );
QUEUE_Unlock( pMsgQ );
WIN_ReleasePtr( wndPtr );
/***********************************************************************
UINT WINAPI ArrangeIconicWindows( HWND parent )
RECT rectParent;
HWND hwndChild;
INT x, y, xspacing, yspacing;
GetClientRect( parent, &rectParent );
xspacing = GetSystemMetrics(SM_CXICONSPACING);
yspacing = GetSystemMetrics(SM_CYICONSPACING);
hwndChild = GetWindow( parent, GW_CHILD );
if( IsIconic( hwndChild ) )
WINPOS_ShowIconTitle( hwndChild, FALSE );
SetWindowPos( hwndChild, 0, x + (xspacing - GetSystemMetrics(SM_CXICON)) / 2,
y - yspacing - GetSystemMetrics(SM_CYICON)/2, 0, 0,
if( IsWindow(hwndChild) )
WINPOS_ShowIconTitle(hwndChild , TRUE );
if (x <= rectParent.right - xspacing) x += xspacing;
else
{
x = rectParent.left;
y -= yspacing;
}
}
hwndChild = GetWindow( hwndChild, GW_HWNDNEXT );
/***********************************************************************
void WINAPI SwitchToThisWindow( HWND hwnd, BOOL restore )
ShowWindow( hwnd, restore ? SW_RESTORE : SW_SHOWMINIMIZED );
/***********************************************************************
BOOL WINAPI GetWindowRect( HWND hwnd, LPRECT rect )
BOOL ret;
WND *wndPtr = WIN_GetPtr( hwnd );
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
if (wndPtr != WND_OTHER_PROCESS)
{
*rect = wndPtr->rectWindow;
WIN_ReleasePtr( wndPtr );
ret = TRUE;
}
else
{
SERVER_START_REQ( get_window_rectangles )
{
req->handle = hwnd;
if ((ret = !SERVER_CALL_ERR()))
{
rect->left = req->window.left;
rect->top = req->window.top;
rect->right = req->window.right;
rect->bottom = req->window.bottom;
}
}
SERVER_END_REQ;
}
if (ret)
{
MapWindowPoints( GetAncestor( hwnd, GA_PARENT ), 0, (POINT *)rect, 2 );
TRACE( "hwnd %04x (%d,%d)-(%d,%d)\n",
hwnd, rect->left, rect->top, rect->right, rect->bottom);
}
return ret;
/***********************************************************************
int WINAPI GetWindowRgn ( HWND hwnd, HRGN hrgn )
{
int nRet = ERROR;
WND *wndPtr = WIN_GetPtr( hwnd );
if (wndPtr == WND_OTHER_PROCESS)
{
if (IsWindow( hwnd ))
FIXME( "not supported on other process window %x\n", hwnd );
wndPtr = NULL;
}
if (!wndPtr)
SetLastError( ERROR_INVALID_WINDOW_HANDLE );
return ERROR;
if (wndPtr->hrgnWnd) nRet = CombineRgn( hrgn, wndPtr->hrgnWnd, 0, RGN_COPY );
WIN_ReleasePtr( wndPtr );
return nRet;
}
/***********************************************************************
*/
int WINAPI SetWindowRgn( HWND hwnd, HRGN hrgn, BOOL bRedraw )
RECT rect;
WND *wndPtr;
if (hrgn) /* verify that region really exists */
{
if (GetRgnBox( hrgn, &rect ) == ERROR) return FALSE;
}
if (USER_Driver.pSetWindowRgn)
return USER_Driver.pSetWindowRgn( hwnd, hrgn, bRedraw );
if ((wndPtr = WIN_GetPtr( hwnd )) == WND_OTHER_PROCESS)
if (IsWindow( hwnd ))
FIXME( "not supported on other process window %x\n", hwnd );
wndPtr = NULL;
}
if (!wndPtr)
{
SetLastError( ERROR_INVALID_WINDOW_HANDLE );
return FALSE;
if (wndPtr->hrgnWnd == hrgn)
WIN_ReleasePtr( wndPtr );
return TRUE;
if (wndPtr->hrgnWnd)
{
/* delete previous region */
DeleteObject(wndPtr->hrgnWnd);
wndPtr->hrgnWnd = 0;
}
wndPtr->hrgnWnd = hrgn;
WIN_ReleasePtr( wndPtr );
/* Size the window to the rectangle of the new region (if it isn't NULL) */
if (hrgn) SetWindowPos( hwnd, 0, rect.left, rect.top,
rect.right - rect.left, rect.bottom - rect.top,
SWP_NOSIZE | SWP_FRAMECHANGED | SWP_NOMOVE | SWP_NOACTIVATE |
SWP_NOZORDER | (bRedraw ? 0 : SWP_NOREDRAW) );
return TRUE;
/***********************************************************************
BOOL WINAPI GetClientRect( HWND hwnd, LPRECT rect )
BOOL ret;
WND *wndPtr = WIN_GetPtr( hwnd );
rect->left = rect->top = rect->right = rect->bottom = 0;
if (!wndPtr) return FALSE;
if (wndPtr != WND_OTHER_PROCESS)
{
rect->right = wndPtr->rectClient.right - wndPtr->rectClient.left;
rect->bottom = wndPtr->rectClient.bottom - wndPtr->rectClient.top;
WIN_ReleasePtr( wndPtr );
ret = TRUE;
}
else
{
SERVER_START_REQ( get_window_rectangles )
{
req->handle = hwnd;
if ((ret = !SERVER_CALL_ERR()))
{
rect->right = req->client.right - req->client.left;
rect->bottom = req->client.bottom - req->client.top;
}
}
SERVER_END_REQ;
}
return ret;
}
/*******************************************************************
BOOL WINAPI ClientToScreen( HWND hwnd, LPPOINT lppnt )
MapWindowPoints( hwnd, 0, lppnt, 1 );
return TRUE;
}
/*******************************************************************
BOOL WINAPI ScreenToClient( HWND hwnd, LPPOINT lppnt )
MapWindowPoints( 0, hwnd, lppnt, 1 );
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
/***********************************************************************
* find_child_from_point
*
* Find the child that contains pt. Helper for WindowFromPoint.
* pt is in parent client coordinates.
* lparam is the param to pass in the WM_NCHITTEST message.
*/
static HWND find_child_from_point( HWND parent, POINT pt, INT *hittest, LPARAM lparam )
{
int i, res;
WND *wndPtr;
HWND *list = WIN_ListChildren( parent );
if (!list) return 0;
for (i = 0; list[i]; i++)
{
if (!(wndPtr = WIN_FindWndPtr( list[i] ))) continue;
/* If point is in window, and window is visible, and it */
/* is enabled (or it's a top-level window), then explore */
/* its children. Otherwise, go to the next window. */
if (!(wndPtr->dwStyle & WS_VISIBLE)) goto next; /* not visible -> skip */
if ((wndPtr->dwStyle & (WS_POPUP | WS_CHILD | WS_DISABLED)) == (WS_CHILD | WS_DISABLED))
goto next; /* disabled child -> skip */
if ((wndPtr->dwExStyle & (WS_EX_LAYERED | WS_EX_TRANSPARENT)) == (WS_EX_LAYERED | WS_EX_TRANSPARENT))
goto next; /* transparent -> skip */
if (wndPtr->hrgnWnd)
{
if (!PtInRegion( wndPtr->hrgnWnd, pt.x - wndPtr->rectWindow.left,
pt.y - wndPtr->rectWindow.top ))
goto next; /* point outside window region -> skip */
}
else if (!PtInRect( &wndPtr->rectWindow, pt )) goto next; /* not in window -> skip */
/* If window is minimized or disabled, return at once */
if (wndPtr->dwStyle & WS_MINIMIZE)
{
WIN_ReleaseWndPtr( wndPtr );
*hittest = HTCAPTION;
return list[i];
}
if (wndPtr->dwStyle & WS_DISABLED)
{
WIN_ReleaseWndPtr( wndPtr );
*hittest = HTERROR;
return list[i];
}
/* If point is in client area, explore children */
if (PtInRect( &wndPtr->rectClient, pt ))
{
POINT new_pt;
HWND ret;
new_pt.x = pt.x - wndPtr->rectClient.left;
new_pt.y = pt.y - wndPtr->rectClient.top;
WIN_ReleaseWndPtr( wndPtr );
if ((ret = find_child_from_point( list[i], new_pt, hittest, lparam )))
return ret;
}
else WIN_ReleaseWndPtr( wndPtr );
/* Now it's inside window, send WM_NCCHITTEST (if same thread) */
if (!WIN_IsCurrentThread( list[i] ))
{
*hittest = HTCLIENT;
return list[i];
}
if ((res = SendMessageA( list[i], WM_NCHITTEST, 0, lparam )) != HTTRANSPARENT)
{
*hittest = res; /* Found the window */
return list[i];
}
continue; /* continue search with next sibling */
next:
WIN_ReleaseWndPtr( wndPtr );
}
return 0;
}
/***********************************************************************
* WINPOS_WindowFromPoint

Alexandre Julliard
committed
HWND WINPOS_WindowFromPoint( HWND hwndScope, POINT pt, INT *hittest )
WND *wndScope;
POINT xy = pt;
int res;

Alexandre Julliard
committed
TRACE("scope %04x %ld,%ld\n", hwndScope, pt.x, pt.y);
if (!hwndScope) hwndScope = GetDesktopWindow();
if (!(wndScope = WIN_FindWndPtr( hwndScope ))) return 0;
hwndScope = wndScope->hwndSelf; /* make it a full handle */

Alexandre Julliard
committed
*hittest = HTERROR;
if( wndScope->dwStyle & WS_DISABLED )
{
WIN_ReleaseWndPtr(wndScope);
return 0;
}
if (wndScope->parent)
MapWindowPoints( GetDesktopWindow(), wndScope->parent, &xy, 1 );
if (!(wndScope->dwStyle & WS_MINIMIZE) && PtInRect( &wndScope->rectClient, xy ))
HWND ret;
xy.x -= wndScope->rectClient.left;
xy.y -= wndScope->rectClient.top;
WIN_ReleaseWndPtr( wndScope );
if ((ret = find_child_from_point( hwndScope, xy, hittest, MAKELONG( pt.x, pt.y ) )))
{
TRACE( "found child %x\n", ret );
return ret;
}
else WIN_ReleaseWndPtr( wndScope );
/* If nothing found, try the scope window */
if (!WIN_IsCurrentThread( hwndScope ))
{
*hittest = HTCLIENT;
TRACE( "returning %x\n", hwndScope );
return hwndScope;
}
res = SendMessageA( hwndScope, WM_NCHITTEST, 0, MAKELONG( pt.x, pt.y ) );
if (res != HTTRANSPARENT)
{
*hittest = res; /* Found the window */
TRACE( "returning %x\n", hwndScope );
return hwndScope;
}
*hittest = HTNOWHERE;
TRACE( "nothing found\n" );
return 0;
/*******************************************************************
HWND WINAPI WindowFromPoint( POINT pt )

Alexandre Julliard
committed
INT hittest;
return WINPOS_WindowFromPoint( 0, pt, &hittest );
/*******************************************************************
HWND WINAPI ChildWindowFromPoint( HWND hwndParent, POINT pt )
return ChildWindowFromPointEx( hwndParent, pt, CWP_ALL );
/*******************************************************************
HWND WINAPI ChildWindowFromPointEx( HWND hwndParent, POINT pt, UINT uFlags)
{
/* pt is in the client coordinates */
HWND *list;
int i;
RECT rect;
HWND retvalue = 0;
GetClientRect( hwndParent, &rect );
if (!PtInRect( &rect, pt )) return 0;
if (!(list = WIN_ListChildren( hwndParent ))) return 0;
for (i = 0; list[i] && !retvalue; i++)
WND *wnd = WIN_FindWndPtr( list[i] );
if (!wnd) continue;
if (PtInRect( &wnd->rectWindow, pt ))
{
if ( (uFlags & CWP_SKIPINVISIBLE) &&
!(wnd->dwStyle & WS_VISIBLE) );
else if ( (uFlags & CWP_SKIPDISABLED) &&
(wnd->dwStyle & WS_DISABLED) );
else if ( (uFlags & CWP_SKIPTRANSPARENT) &&
(wnd->dwExStyle & WS_EX_TRANSPARENT) );
else retvalue = list[i];
}
WIN_ReleaseWndPtr( wnd );
HeapFree( GetProcessHeap(), 0, list );
if (!retvalue) retvalue = hwndParent;
/*******************************************************************
* WINPOS_GetWinOffset
*
* Calculate the offset between the origin of the two windows. Used
* to implement MapWindowPoints.
*/
static void WINPOS_GetWinOffset( HWND hwndFrom, HWND hwndTo, POINT *offset )
WND * wndPtr;
/* Translate source window origin to screen coords */
HWND hwnd = hwndFrom;
while (hwnd)
if (hwnd == hwndTo) return;
if (!(wndPtr = WIN_GetPtr( hwnd )))
ERR( "bad hwndFrom = %04x\n", hwnd );
return;
if (wndPtr == WND_OTHER_PROCESS) goto other_process;
offset->x += wndPtr->rectClient.left;
offset->y += wndPtr->rectClient.top;
hwnd = wndPtr->parent;
WIN_ReleasePtr( wndPtr );
/* Translate origin to destination window coords */
HWND hwnd = hwndTo;
while (hwnd)
if (!(wndPtr = WIN_GetPtr( hwnd )))
ERR( "bad hwndTo = %04x\n", hwnd );
return;
if (wndPtr == WND_OTHER_PROCESS) goto other_process;
offset->x -= wndPtr->rectClient.left;
offset->y -= wndPtr->rectClient.top;
hwnd = wndPtr->parent;
WIN_ReleasePtr( wndPtr );
}
}
return;
other_process: /* one of the parents may belong to another process, do it the hard way */
offset->x = offset->y = 0;
SERVER_START_REQ( get_windows_offset )
{
req->from = hwndFrom;
req->to = hwndTo;
if (!SERVER_CALL())
{
offset->x = req->x;
offset->y = req->y;
SERVER_END_REQ;
}
/*******************************************************************
void WINAPI MapWindowPoints16( HWND16 hwndFrom, HWND16 hwndTo,
LPPOINT16 lppt, UINT16 count )
POINT offset;
WINPOS_GetWinOffset( WIN_Handle32(hwndFrom), WIN_Handle32(hwndTo), &offset );
while (count--)
{
lppt->x += offset.x;
lppt->y += offset.y;
lppt++;
}
}
/*******************************************************************
INT WINAPI MapWindowPoints( HWND hwndFrom, HWND hwndTo, LPPOINT lppt, UINT count )
POINT offset;
WINPOS_GetWinOffset( hwndFrom, hwndTo, &offset );
lppt->x += offset.x;
lppt->y += offset.y;
lppt++;
return MAKELONG( LOWORD(offset.x), LOWORD(offset.y) );
/***********************************************************************
BOOL WINAPI IsIconic(HWND hWnd)
return (GetWindowLongW( hWnd, GWL_STYLE ) & WS_MINIMIZE) != 0;
/***********************************************************************
BOOL WINAPI IsZoomed(HWND hWnd)
return (GetWindowLongW( hWnd, GWL_STYLE ) & WS_MAXIMIZE) != 0;
/*******************************************************************
HWND WINAPI GetActiveWindow(void)
MESSAGEQUEUE *pCurMsgQ = 0;
/* Get the messageQ for the current thread */
if (!(pCurMsgQ = QUEUE_Current()))
WARN("\tCurrent message queue not found. Exiting!\n" );
return 0;
}
/* Return the current active window from the perQ data of the current message Q */
return PERQDATA_GetActiveWnd( pCurMsgQ->pQData );
/*******************************************************************
static BOOL WINPOS_CanActivate(HWND hwnd)
if (!hwnd) return FALSE;
return ((GetWindowLongW( hwnd, GWL_STYLE ) & (WS_DISABLED|WS_VISIBLE|WS_CHILD)) == WS_VISIBLE);
/*******************************************************************
HWND WINAPI SetActiveWindow( HWND hwnd )
HWND prev = 0;
MESSAGEQUEUE *pMsgQ = 0, *pCurMsgQ = 0;
if (!wndPtr) return 0;
if (wndPtr->dwStyle & (WS_DISABLED | WS_CHILD)) goto error;
/* Get the messageQ for the current thread */
if (!(pCurMsgQ = QUEUE_Current()))
WARN("\tCurrent message queue not found. Exiting!\n" );
goto error;
/* Retrieve the message queue associated with this window */
pMsgQ = (MESSAGEQUEUE *)QUEUE_Lock( wndPtr->hmemTaskQ );
if ( !pMsgQ )
{
WARN("\tWindow message queue not found. Exiting!\n" );
goto error;
}
/* Make sure that the window is associated with the calling threads
* message queue. It must share the same perQ data.
*/
if ( pCurMsgQ->pQData != pMsgQ->pQData )
{
QUEUE_Unlock( pMsgQ );
goto error;
}
/* Save current active window */
prev = PERQDATA_GetActiveWnd( pMsgQ->pQData );
QUEUE_Unlock( pMsgQ );
WIN_ReleaseWndPtr(wndPtr);
WINPOS_SetActiveWindow( hwnd, FALSE, TRUE );
return prev;
error:
WIN_ReleaseWndPtr(wndPtr);
return 0;
/*******************************************************************
HWND WINAPI GetForegroundWindow(void)
HWND hwndActive = 0;
/* Get the foreground window (active window of hActiveQueue) */
if ( hActiveQueue )
{
MESSAGEQUEUE *pActiveQueue = QUEUE_Lock( hActiveQueue );
if ( pActiveQueue )
hwndActive = PERQDATA_GetActiveWnd( pActiveQueue->pQData );
QUEUE_Unlock( pActiveQueue );
}
return hwndActive;
}
/*******************************************************************
BOOL WINAPI SetForegroundWindow( HWND hwnd )
if (!hwnd) return WINPOS_SetActiveWindow( 0, FALSE, TRUE );
/* child windows get WM_CHILDACTIVATE message */
if ((GetWindowLongW( hwnd, GWL_STYLE ) & (WS_CHILD | WS_POPUP)) == WS_CHILD)
return SendMessageA( hwnd, WM_CHILDACTIVATE, 0, 0 );
hwnd = WIN_GetFullHandle( hwnd );
if( hwnd == GetForegroundWindow() ) return FALSE;
return WINPOS_SetActiveWindow( hwnd, FALSE, TRUE );
/*******************************************************************
*/
BOOL WINAPI AllowSetForegroundWindow( DWORD procid )
{
/* FIXME: If Win98/2000 style SetForegroundWindow behavior is
* implemented, then fix this function. */
return TRUE;
}
/*******************************************************************
*/
BOOL WINAPI LockSetForegroundWindow( UINT lockcode )
{
/* FIXME: If Win98/2000 style SetForegroundWindow behavior is
* implemented, then fix this function. */
return TRUE;
}
/*******************************************************************
HWND WINAPI SetShellWindow(HWND hwndshell)
{ WARN("(hWnd=%08x) semi stub\n",hwndshell );
hGlobalShellWindow = WIN_GetFullHandle( hwndshell );
/*******************************************************************
HWND WINAPI GetShellWindow(void)
{ WARN("(hWnd=%x) semi stub\n",hGlobalShellWindow );
/***********************************************************************
BOOL WINAPI BringWindowToTop( HWND hwnd )
return SetWindowPos( hwnd, HWND_TOP, 0, 0, 0, 0, SWP_NOMOVE|SWP_NOSIZE );
/***********************************************************************
BOOL WINAPI MoveWindow( HWND hwnd, INT x, INT y, INT cx, INT cy,
BOOL repaint )
int flags = SWP_NOZORDER | SWP_NOACTIVATE;
if (!repaint) flags |= SWP_NOREDRAW;
TRACE("%04x %d,%d %dx%d %d\n",
return SetWindowPos( hwnd, 0, x, y, cx, cy, flags );
/***********************************************************************
* WINPOS_InitInternalPos
*/
static LPINTERNALPOS WINPOS_InitInternalPos( WND* wnd, POINT pt, const RECT *restoreRect )
LPINTERNALPOS lpPos = (LPINTERNALPOS) GetPropA( wnd->hwndSelf,
if( !lpPos )
{
/* this happens when the window is minimized/maximized
* for the first time (rectWindow is not adjusted yet) */
lpPos = HeapAlloc( GetProcessHeap(), 0, sizeof(INTERNALPOS) );
SetPropA( wnd->hwndSelf, atomInternalPos, (HANDLE)lpPos );
lpPos->hwndIconTitle = 0; /* defer until needs to be shown */
CONV_RECT32TO16( &wnd->rectWindow, &lpPos->rectNormal );
*(UINT*)&lpPos->ptIconPos = *(UINT*)&lpPos->ptMaxPos = 0xFFFFFFFF;
return lpPos;
}
/***********************************************************************
* WINPOS_RedrawIconTitle
*/
BOOL WINPOS_RedrawIconTitle( HWND hWnd )
LPINTERNALPOS lpPos = (LPINTERNALPOS)GetPropA( hWnd, atomInternalPos );
if( lpPos )
{
if( lpPos->hwndIconTitle )
{
SendMessageA( lpPos->hwndIconTitle, WM_SHOWWINDOW, TRUE, 0);
InvalidateRect( lpPos->hwndIconTitle, NULL, TRUE );
return TRUE;
}
}
return FALSE;
}
/***********************************************************************
* WINPOS_ShowIconTitle
*/
BOOL WINPOS_ShowIconTitle( HWND hwnd, BOOL bShow )
LPINTERNALPOS lpPos = (LPINTERNALPOS)GetPropA( hwnd, atomInternalPos );
if( lpPos && !(GetWindowLongA( hwnd, GWL_EXSTYLE) & WS_EX_MANAGED))
HWND title = lpPos->hwndIconTitle;
TRACE("0x%04x %i\n", hwnd, (bShow != 0) );
if( !title )
lpPos->hwndIconTitle = title = ICONTITLE_Create( hwnd );
if (!IsWindowVisible(title))
{
SendMessageA( title, WM_SHOWWINDOW, TRUE, 0 );
SetWindowPos( title, 0, 0, 0, 0, 0, SWP_NOSIZE | SWP_NOMOVE |
SWP_NOACTIVATE | SWP_NOZORDER | SWP_SHOWWINDOW );
}
else ShowWindow( title, SW_HIDE );
}
return FALSE;
}
/*******************************************************************
* WINPOS_GetMinMaxInfo
*
* Get the minimized and maximized information for a window.
*/
void WINPOS_GetMinMaxInfo( HWND hwnd, POINT *maxSize, POINT *maxPos,
POINT *minTrack, POINT *maxTrack )
MINMAXINFO MinMax;
INT xinc, yinc;
LONG style = GetWindowLongA( hwnd, GWL_STYLE );
LONG exstyle = GetWindowLongA( hwnd, GWL_EXSTYLE );
MinMax.ptMaxSize.x = GetSystemMetrics(SM_CXSCREEN);
MinMax.ptMaxSize.y = GetSystemMetrics(SM_CYSCREEN);
MinMax.ptMinTrackSize.x = GetSystemMetrics(SM_CXMINTRACK);
MinMax.ptMinTrackSize.y = GetSystemMetrics(SM_CYMINTRACK);
MinMax.ptMaxTrackSize.x = GetSystemMetrics(SM_CXSCREEN);
MinMax.ptMaxTrackSize.y = GetSystemMetrics(SM_CYSCREEN);
if (HAS_DLGFRAME( style, exstyle ))
xinc = GetSystemMetrics(SM_CXDLGFRAME);
yinc = GetSystemMetrics(SM_CYDLGFRAME);
if (HAS_THICKFRAME(style))
xinc += GetSystemMetrics(SM_CXFRAME);
yinc += GetSystemMetrics(SM_CYFRAME);
if (style & WS_BORDER)
xinc += GetSystemMetrics(SM_CXBORDER);
yinc += GetSystemMetrics(SM_CYBORDER);
MinMax.ptMaxSize.x += 2 * xinc;
MinMax.ptMaxSize.y += 2 * yinc;
lpPos = (LPINTERNALPOS)GetPropA( hwnd, atomInternalPos );
CONV_POINT16TO32( &lpPos->ptMaxPos, &MinMax.ptMaxPosition );
MinMax.ptMaxPosition.x = -xinc;
MinMax.ptMaxPosition.y = -yinc;
SendMessageA( hwnd, WM_GETMINMAXINFO, 0, (LPARAM)&MinMax );
TRACE("%ld %ld / %ld %ld / %ld %ld / %ld %ld\n",
MinMax.ptMaxSize.x, MinMax.ptMaxSize.y,
MinMax.ptMaxPosition.x, MinMax.ptMaxPosition.y,
MinMax.ptMaxTrackSize.x, MinMax.ptMaxTrackSize.y,
MinMax.ptMinTrackSize.x, MinMax.ptMinTrackSize.y);
MinMax.ptMaxTrackSize.x = max( MinMax.ptMaxTrackSize.x,
MinMax.ptMaxTrackSize.y = max( MinMax.ptMaxTrackSize.y,
MinMax.ptMinTrackSize.y );
if (maxSize) *maxSize = MinMax.ptMaxSize;
if (maxPos) *maxPos = MinMax.ptMaxPosition;
if (minTrack) *minTrack = MinMax.ptMinTrackSize;
if (maxTrack) *maxTrack = MinMax.ptMaxTrackSize;