mirror of
https://github.com/reactos/reactos.git
synced 2025-08-05 15:13:05 +00:00
1532 lines
35 KiB
C
1532 lines
35 KiB
C
/* $Id: defwnd.c,v 1.37 2003/03/16 06:43:09 rcampbell Exp $
|
|
*
|
|
* COPYRIGHT: See COPYING in the top level directory
|
|
* PROJECT: ReactOS user32.dll
|
|
* FILE: lib/user32/windows/window.c
|
|
* PURPOSE: Window management
|
|
* PROGRAMMER: Casper S. Hornstrup (chorns@users.sourceforge.net)
|
|
* UPDATE HISTORY:
|
|
* 06-06-2001 CSH Created
|
|
*/
|
|
|
|
/* INCLUDES ******************************************************************/
|
|
|
|
#include <windows.h>
|
|
#include <user32.h>
|
|
#include <window.h>
|
|
#include <debug.h>
|
|
#include <user32/wininternal.h>
|
|
#include <string.h>
|
|
|
|
/* GLOBALS *******************************************************************/
|
|
|
|
static HBITMAP hbSysMenu;
|
|
/* TODO: widgets will be cached here.
|
|
static HBITMAP hbClose;
|
|
static HBITMAP hbCloseD;
|
|
static HBITMAP hbMinimize;
|
|
static HBITMAP hbMinimizeD;
|
|
static HBITMAP hbRestore;
|
|
static HBITMAP hbRestoreD;
|
|
static HBITMAP hbMaximize;
|
|
static HBITMAP hbScrUp;
|
|
static HBITMAP hbScrDwn;
|
|
static HBITMAP hbScrLeft;
|
|
static HBITMAP hbScrRight;
|
|
*/
|
|
static COLORREF SysColours[] =
|
|
{
|
|
RGB(224, 224, 224) /* COLOR_SCROLLBAR */,
|
|
RGB(58, 110, 165) /* COLOR_BACKGROUND */,
|
|
RGB(0, 0, 128) /* COLOR_ACTIVECAPTION */,
|
|
RGB(128, 128, 128) /* COLOR_INACTIVECAPTION */,
|
|
RGB(192, 192, 192) /* COLOR_MENU */,
|
|
RGB(192, 192, 192) /* COLOR_WINDOW */,
|
|
RGB(192, 192, 192) /* COLOR_WINDOWFRAME */,
|
|
RGB(0, 0, 0) /* COLOR_MENUTEXT */,
|
|
RGB(0, 0, 0) /* COLOR_WINDOWTEXT */,
|
|
RGB(255, 255, 255) /* COLOR_CAPTIONTEXT */,
|
|
RGB(128, 128, 128) /* COLOR_ACTIVEBORDER */,
|
|
RGB(255, 255, 255) /* COLOR_INACTIVEBORDER */,
|
|
RGB(255, 255, 232) /* COLOR_APPWORKSPACE */,
|
|
RGB(224, 224, 224) /* COLOR_HILIGHT */,
|
|
RGB(0, 0, 128) /* COLOR_HILIGHTTEXT */,
|
|
RGB(192, 192, 192) /* COLOR_BTNFACE */,
|
|
RGB(128, 128, 128) /* COLOR_BTNSHADOW */,
|
|
RGB(192, 192, 192) /* COLOR_GRAYTEXT */,
|
|
RGB(0, 0, 0) /* COLOR_BTNTEXT */,
|
|
RGB(192, 192, 192) /* COLOR_INACTIVECAPTIONTEXT */,
|
|
RGB(255, 255, 255) /* COLOR_BTNHILIGHT */,
|
|
RGB(32, 32, 32) /* COLOR_3DDKSHADOW */,
|
|
RGB(192, 192, 192) /* COLOR_3DLIGHT */,
|
|
RGB(0, 0, 0) /* COLOR_INFOTEXT */,
|
|
RGB(255, 255, 192) /* COLOR_INFOBK */,
|
|
RGB(184, 180, 184) /* COLOR_ALTERNATEBTNFACE */,
|
|
RGB(0, 0, 255) /* COLOR_HOTLIGHT */,
|
|
RGB(16, 132, 208) /* COLOR_GRADIENTACTIVECAPTION */,
|
|
RGB(181, 181, 181) /* COLOR_GRADIENTINACTIVECAPTION */,
|
|
};
|
|
|
|
static ATOM AtomInternalPos;
|
|
|
|
/* FUNCTIONS *****************************************************************/
|
|
|
|
BOOL IsMaxBoxActive(HWND hWnd)
|
|
{
|
|
ULONG uStyle = GetWindowLong(hWnd, GWL_STYLE);
|
|
return (uStyle & WS_MAXIMIZEBOX);
|
|
}
|
|
|
|
BOOL IsCloseBoxActive(HWND hWnd)
|
|
{
|
|
ULONG uStyle = GetWindowLong(hWnd, GWL_STYLE);
|
|
return (uStyle & WS_SYSMENU);
|
|
}
|
|
|
|
BOOL IsMinBoxActive(HWND hWnd)
|
|
{
|
|
ULONG uStyle = GetWindowLong(hWnd, GWL_STYLE);
|
|
return (uStyle & WS_MINIMIZEBOX);
|
|
}
|
|
|
|
VOID
|
|
UserSetupInternalPos(VOID)
|
|
{
|
|
LPSTR Str = "SysIP";
|
|
AtomInternalPos = GlobalAddAtomA(Str);
|
|
}
|
|
|
|
HPEN STDCALL
|
|
GetSysColorPen(int nIndex)
|
|
{
|
|
return(CreatePen(PS_SOLID, 1, SysColours[nIndex]));
|
|
}
|
|
|
|
HBRUSH STDCALL
|
|
GetSysColorBrush(int nIndex)
|
|
{
|
|
return(CreateSolidBrush(SysColours[nIndex]));
|
|
}
|
|
|
|
|
|
LRESULT STDCALL
|
|
DefFrameProcA(HWND hWnd,
|
|
HWND hWndMDIClient,
|
|
UINT uMsg,
|
|
WPARAM wParam,
|
|
LPARAM lParam)
|
|
{
|
|
return((LRESULT)0);
|
|
}
|
|
|
|
LRESULT STDCALL
|
|
DefFrameProcW(HWND hWnd,
|
|
HWND hWndMDIClient,
|
|
UINT uMsg,
|
|
WPARAM wParam,
|
|
LPARAM lParam)
|
|
{
|
|
return((LRESULT)0);
|
|
}
|
|
|
|
|
|
BOOL
|
|
DefWndRedrawIconTitle(HWND hWnd)
|
|
{
|
|
PINTERNALPOS lpPos = (PINTERNALPOS)GetPropA(hWnd,
|
|
(LPSTR)(DWORD)AtomInternalPos);
|
|
if (lpPos != NULL)
|
|
{
|
|
if (lpPos->IconTitle != NULL)
|
|
{
|
|
SendMessageA(lpPos->IconTitle, WM_SHOWWINDOW, TRUE, 0);
|
|
InvalidateRect(lpPos->IconTitle, NULL, TRUE);
|
|
return(TRUE);
|
|
}
|
|
}
|
|
return(FALSE);
|
|
}
|
|
|
|
BOOL
|
|
UserHasMenu(HWND hWnd, ULONG Style)
|
|
{
|
|
return(!(Style & WS_CHILD) && GetWindowLong(hWnd, GWL_ID) != 0);
|
|
}
|
|
|
|
ULONG
|
|
UserHasAnyFrameStyle(ULONG Style, ULONG ExStyle)
|
|
{
|
|
return((Style & (WS_THICKFRAME | WS_DLGFRAME | WS_BORDER)) ||
|
|
(ExStyle & WS_EX_DLGMODALFRAME) ||
|
|
(!(Style & (WS_CHILD | WS_POPUP))));
|
|
}
|
|
|
|
ULONG
|
|
UserHasDlgFrameStyle(ULONG Style, ULONG ExStyle)
|
|
{
|
|
return((ExStyle & WS_EX_DLGMODALFRAME) ||
|
|
((Style & WS_DLGFRAME) && (!(Style & WS_THICKFRAME))));
|
|
}
|
|
|
|
ULONG
|
|
UserHasThickFrameStyle(ULONG Style, ULONG ExStyle)
|
|
{
|
|
return((Style & WS_THICKFRAME) &&
|
|
(!((Style & (WS_DLGFRAME | WS_BORDER)) == WS_DLGFRAME)));
|
|
}
|
|
|
|
ULONG
|
|
UserHasThinFrameStyle(ULONG Style, ULONG ExStyle)
|
|
{
|
|
return((Style & WS_BORDER) ||
|
|
(!(Style & (WS_CHILD | WS_POPUP))));
|
|
}
|
|
|
|
ULONG
|
|
UserHasBigFrameStyle(ULONG Style, ULONG ExStyle)
|
|
{
|
|
return((Style & (WS_THICKFRAME | WS_DLGFRAME)) ||
|
|
(ExStyle & WS_EX_DLGMODALFRAME));
|
|
}
|
|
|
|
INT GetFrameSize(HWND hWnd)
|
|
{
|
|
ULONG uStyle;
|
|
ULONG uExStyle;
|
|
|
|
uStyle = GetWindowLong(hWnd, GWL_STYLE);
|
|
uExStyle = GetWindowLong(hWnd, GWL_EXSTYLE);
|
|
|
|
if (UserHasThinFrameStyle(uStyle, uExStyle))
|
|
{
|
|
return GetSystemMetrics( SM_CXBORDER );
|
|
}
|
|
else if (UserHasDlgFrameStyle(uStyle, uExStyle))
|
|
{
|
|
return GetSystemMetrics( SM_CXDLGFRAME );
|
|
}
|
|
return GetSystemMetrics( SM_CXFRAME );
|
|
}
|
|
|
|
void UserGetInsideRectNC( HWND hWnd, RECT *rect )
|
|
{
|
|
RECT WindowRect;
|
|
ULONG Style;
|
|
ULONG ExStyle;
|
|
|
|
Style = GetWindowLong(hWnd, GWL_STYLE);
|
|
ExStyle = GetWindowLong(hWnd, GWL_EXSTYLE);
|
|
GetWindowRect(hWnd, &WindowRect);
|
|
rect->top = rect->left = 0;
|
|
rect->right = WindowRect.right - WindowRect.left;
|
|
rect->bottom = WindowRect.bottom - WindowRect.top;
|
|
|
|
if (Style & WS_ICONIC)
|
|
{
|
|
return;
|
|
}
|
|
|
|
/* Remove frame from rectangle */
|
|
if (UserHasThickFrameStyle(Style, ExStyle ))
|
|
{
|
|
InflateRect( rect, -GetSystemMetrics(SM_CXFRAME),
|
|
-GetSystemMetrics(SM_CYFRAME) );
|
|
}
|
|
else
|
|
{
|
|
if (UserHasDlgFrameStyle(Style, ExStyle ))
|
|
{
|
|
InflateRect( rect, -GetSystemMetrics(SM_CXDLGFRAME),
|
|
-GetSystemMetrics(SM_CYDLGFRAME));
|
|
/* FIXME: this isn't in NC_AdjustRect? why not? */
|
|
if (ExStyle & WS_EX_DLGMODALFRAME)
|
|
InflateRect( rect, -1, 0 );
|
|
}
|
|
else
|
|
{
|
|
if (UserHasThinFrameStyle(Style, ExStyle))
|
|
{
|
|
InflateRect(rect, -GetSystemMetrics(SM_CXBORDER),
|
|
-GetSystemMetrics(SM_CYBORDER));
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
void UserDrawSysMenuButton( HWND hWnd, HDC hDC, BOOL down )
|
|
{
|
|
RECT Rect;
|
|
HDC hDcMem;
|
|
HBITMAP hSavedBitmap;
|
|
|
|
hbSysMenu = LoadBitmap(0, MAKEINTRESOURCE(OBM_CLOSE));
|
|
UserGetInsideRectNC(hWnd, &Rect);
|
|
hDcMem = CreateCompatibleDC(hDC);
|
|
hSavedBitmap = SelectObject(hDcMem, hbSysMenu);
|
|
BitBlt(hDC, Rect.left + 2, Rect.top +
|
|
2, 16, 16, hDcMem,
|
|
(GetWindowLong(hWnd, GWL_STYLE) & WS_CHILD) ?
|
|
GetSystemMetrics(SM_CXSIZE): 0, 0, SRCCOPY);
|
|
SelectObject(hDcMem, hSavedBitmap);
|
|
DeleteDC(hDcMem);
|
|
}
|
|
|
|
/* FIXME: Cache bitmaps, then just bitblt instead of calling DFC() (and
|
|
wasting precious CPU cycles) every time */
|
|
|
|
static void UserDrawCloseButton ( HWND hWnd, HDC hDC, BOOL bDown )
|
|
{
|
|
RECT rect;
|
|
BOOL bToolWindow = GetWindowLongA( hWnd, GWL_EXSTYLE ) & WS_EX_TOOLWINDOW;
|
|
INT iBmpWidth = (bToolWindow ? GetSystemMetrics(SM_CXSMSIZE) :
|
|
GetSystemMetrics(SM_CXSIZE)) - 2;
|
|
INT iBmpHeight = (bToolWindow ? GetSystemMetrics(SM_CYSMSIZE) :
|
|
GetSystemMetrics(SM_CYSIZE) - 4);
|
|
if(!(GetWindowLong( hWnd, GWL_STYLE ) & WS_SYSMENU))
|
|
{
|
|
return;
|
|
}
|
|
UserGetInsideRectNC(hWnd, &rect);
|
|
SetRect(&rect,
|
|
rect.right - iBmpWidth - GetSystemMetrics(SM_CXFIXEDFRAME),
|
|
rect.top + GetSystemMetrics(SM_CYFIXEDFRAME),
|
|
rect.right - GetSystemMetrics(SM_CXFIXEDFRAME),
|
|
rect.top + iBmpHeight + GetSystemMetrics(SM_CYFIXEDFRAME) );
|
|
|
|
DrawFrameControl( hDC, &rect, DFC_CAPTION,
|
|
(DFCS_CAPTIONCLOSE |
|
|
(bDown ? DFCS_PUSHED : 0) |
|
|
(IsCloseBoxActive(hWnd) ? 0 : DFCS_INACTIVE)) );
|
|
}
|
|
|
|
static void UserDrawMaxButton( HWND hWnd, HDC hDC, BOOL bDown )
|
|
{
|
|
RECT rect;
|
|
INT iBmpWidth = GetSystemMetrics(SM_CXSIZE) - 2;
|
|
INT iBmpHeight = GetSystemMetrics(SM_CYSIZE) - 4;
|
|
|
|
if (!IsMinBoxActive(hWnd) && !IsMaxBoxActive(hWnd))
|
|
return;
|
|
if ((GetWindowLongA( hWnd, GWL_EXSTYLE ) & WS_EX_TOOLWINDOW) == TRUE)
|
|
return; /* ToolWindows don't have min/max buttons */
|
|
|
|
UserGetInsideRectNC(hWnd, &rect );
|
|
|
|
SetRect(&rect,
|
|
rect.right - (iBmpWidth * 2) - (GetSystemMetrics(SM_CXFIXEDFRAME)) - 2,
|
|
rect.top + GetSystemMetrics(SM_CYFIXEDFRAME),
|
|
rect.right - iBmpWidth - GetSystemMetrics(SM_CXFIXEDFRAME) - 2,
|
|
rect.top + iBmpHeight + GetSystemMetrics(SM_CYFIXEDFRAME) );
|
|
|
|
DrawFrameControl( hDC, &rect, DFC_CAPTION,
|
|
(IsZoomed(hWnd) ? DFCS_CAPTIONMAX : DFCS_CAPTIONRESTORE) |
|
|
(bDown ? DFCS_PUSHED : 0) |
|
|
(IsMaxBoxActive(hWnd) ? 0 : DFCS_INACTIVE) );
|
|
}
|
|
|
|
static void UserDrawMinButton( HWND hWnd, HDC hDC, BOOL bDown )
|
|
{
|
|
|
|
RECT rect;
|
|
INT iBmpWidth = GetSystemMetrics(SM_CXSIZE) - 2;
|
|
INT iBmpHeight = GetSystemMetrics(SM_CYSIZE) - 4;
|
|
if (!IsMinBoxActive(hWnd) && !IsMaxBoxActive(hWnd))
|
|
return;
|
|
if ((GetWindowLongA( hWnd, GWL_EXSTYLE ) & WS_EX_TOOLWINDOW) == TRUE)
|
|
return; /*ToolWindows don't have min/max buttons */
|
|
|
|
UserGetInsideRectNC(hWnd, &rect );
|
|
|
|
SetRect(&rect,
|
|
rect.right - (iBmpWidth * 3) - (GetSystemMetrics(SM_CXFIXEDFRAME)) - 2,
|
|
rect.top + GetSystemMetrics(SM_CYFIXEDFRAME),
|
|
rect.right - (iBmpWidth * 2) - GetSystemMetrics(SM_CXFIXEDFRAME) - 2,
|
|
rect.top + iBmpHeight + GetSystemMetrics(SM_CYFIXEDFRAME) );
|
|
|
|
DrawFrameControl( hDC, &rect, DFC_CAPTION,
|
|
(IsZoomed(hWnd) ? DFCS_CAPTIONMAX : DFCS_CAPTIONRESTORE) |
|
|
(bDown ? DFCS_PUSHED : 0) |
|
|
(IsMinBoxActive(hWnd) ? 0 : DFCS_INACTIVE) );
|
|
}
|
|
|
|
static void UserDrawCaptionNC( HDC hDC, RECT *rect, HWND hWnd,
|
|
DWORD style, BOOL active )
|
|
{
|
|
RECT r = *rect;
|
|
char buffer[256];
|
|
/* Implement and Use DrawCaption() */
|
|
SelectObject( hDC, GetSysColorBrush(active ? COLOR_ACTIVECAPTION : COLOR_INACTIVECAPTION) );
|
|
PatBlt(hDC,rect->left + GetSystemMetrics(SM_CXFRAME), rect->top +
|
|
GetSystemMetrics(SM_CYFRAME), rect->right - (GetSystemMetrics(SM_CXFRAME) * 2) - 1, rect->top +
|
|
GetSystemMetrics(SM_CYCAPTION) - 1, PATCOPY );
|
|
|
|
if (style & WS_SYSMENU)
|
|
{
|
|
UserDrawSysMenuButton( hWnd, hDC, FALSE);
|
|
r.left += GetSystemMetrics(SM_CXSIZE) + 1;
|
|
UserDrawCloseButton( hWnd, hDC, FALSE);
|
|
r.right -= GetSystemMetrics(SM_CXSMSIZE) + 1;
|
|
UserDrawMinButton(hWnd, hDC, FALSE);
|
|
UserDrawMaxButton(hWnd, hDC, FALSE);
|
|
}
|
|
if (GetWindowTextA( hWnd, buffer, sizeof(buffer) ))
|
|
{
|
|
NONCLIENTMETRICS nclm;
|
|
HFONT hFont, hOldFont;
|
|
|
|
nclm.cbSize = sizeof(NONCLIENTMETRICS);
|
|
SystemParametersInfoW(SPI_GETNONCLIENTMETRICS, 0, &nclm, 0);
|
|
SetTextColor(hDC, SysColours[ active ? COLOR_CAPTIONTEXT : COLOR_INACTIVECAPTIONTEXT]);
|
|
SetBkMode( hDC, TRANSPARENT );
|
|
if (style & WS_EX_TOOLWINDOW)
|
|
hFont = CreateFontIndirectW(&nclm.lfSmCaptionFont);
|
|
else
|
|
hFont = CreateFontIndirectW(&nclm.lfCaptionFont);
|
|
hOldFont = SelectObject(hDC, hFont);
|
|
TextOutA(hDC, r.left + (GetSystemMetrics(SM_CXDLGFRAME) * 2), (r.top / 2) + (((int) nclm.lfCaptionFont.lfHeight) / 2) + (GetSystemMetrics(SM_CXDLGFRAME) / 2), buffer, strlen(buffer));
|
|
DeleteObject (SelectObject (hDC, hOldFont));
|
|
}
|
|
}
|
|
|
|
VOID
|
|
UserDrawFrameNC(HDC hDC, RECT* rect, BOOL dlgFrame, BOOL active)
|
|
{
|
|
SelectObject( hDC, GetSysColorBrush(COLOR_WINDOW) );
|
|
DrawEdge(hDC, rect,EDGE_RAISED, BF_RECT | BF_MIDDLE);
|
|
}
|
|
|
|
void SCROLL_DrawScrollBar (HWND hWnd, HDC hDC, INT nBar, BOOL arrows, BOOL interior);
|
|
|
|
VOID
|
|
DefWndDoPaintNC(HWND hWnd, HRGN clip)
|
|
{
|
|
ULONG Active;
|
|
HDC hDC;
|
|
RECT rect;
|
|
ULONG Style;
|
|
ULONG ExStyle;
|
|
Active = GetWindowLongW(hWnd, GWL_STYLE) & WIN_NCACTIVATED;
|
|
Style = GetWindowLong(hWnd, GWL_STYLE);
|
|
ExStyle = GetWindowLong(hWnd, GWL_EXSTYLE);
|
|
|
|
hDC = GetDCEx(hWnd, (clip > (HRGN)1) ? clip : 0, DCX_USESTYLE | DCX_WINDOW |
|
|
((clip > (HRGN)1) ? (DCX_INTERSECTRGN | DCX_KEEPCLIPRGN) : 0));
|
|
if (hDC == 0)
|
|
{
|
|
return;
|
|
}
|
|
|
|
/* FIXME: Test whether we need to draw anything at all. */
|
|
|
|
GetWindowRect(hWnd, &rect);
|
|
rect.right = rect.right - rect.left;
|
|
rect.bottom = rect.bottom - rect.top;
|
|
rect.top = rect.left = 0;
|
|
SelectObject(hDC, GetSysColorPen(COLOR_WINDOWFRAME));
|
|
if (UserHasThickFrameStyle(Style, ExStyle))
|
|
{
|
|
UserDrawFrameNC(hDC, &rect, FALSE, Active);
|
|
}
|
|
else if (UserHasDlgFrameStyle(Style, ExStyle))
|
|
{
|
|
UserDrawFrameNC(hDC, &rect, TRUE, Active);
|
|
}
|
|
if (Style & WS_CAPTION)
|
|
{
|
|
RECT r = rect;
|
|
r.bottom = rect.top + GetSystemMetrics(SM_CYSIZE);
|
|
rect.top += GetSystemMetrics(SM_CYSIZE) +
|
|
GetSystemMetrics(SM_CYBORDER);
|
|
UserDrawCaptionNC(hDC, &r, hWnd, Style, Active);
|
|
}
|
|
|
|
/* FIXME: Draw menu bar. */
|
|
|
|
DbgPrint("drawing scrollbars..\n");
|
|
/* Draw scrollbars */
|
|
if (Style & WS_VSCROLL)
|
|
SCROLL_DrawScrollBar(hWnd, hDC, SB_VERT, TRUE, TRUE);
|
|
if (Style & WS_HSCROLL)
|
|
SCROLL_DrawScrollBar(hWnd, hDC, SB_HORZ, TRUE, TRUE);
|
|
|
|
/* FIXME: Draw size box.*/
|
|
|
|
ReleaseDC(hWnd, hDC);
|
|
|
|
}
|
|
|
|
LRESULT
|
|
DefWndPaintNC(HWND hWnd, HRGN clip)
|
|
{
|
|
if (IsWindowVisible(hWnd))
|
|
{
|
|
if (IsIconic(hWnd))
|
|
{
|
|
DefWndRedrawIconTitle(hWnd);
|
|
}
|
|
else
|
|
{
|
|
DefWndDoPaintNC(hWnd, clip);
|
|
}
|
|
}
|
|
return(0);
|
|
}
|
|
|
|
LRESULT
|
|
DefWndHitTestNC(HWND hWnd, POINT Point)
|
|
{
|
|
RECT WindowRect;
|
|
ULONG Style = GetWindowLong(hWnd, GWL_STYLE);
|
|
ULONG ExStyle = GetWindowLong(hWnd, GWL_EXSTYLE);
|
|
|
|
GetWindowRect(hWnd, &WindowRect);
|
|
if (!PtInRect(&WindowRect, Point))
|
|
{
|
|
|
|
return(HTNOWHERE);
|
|
}
|
|
if (Style & WS_MINIMIZE)
|
|
{
|
|
return(HTCAPTION);
|
|
}
|
|
if (UserHasThickFrameStyle(Style, ExStyle))
|
|
{
|
|
InflateRect(&WindowRect, -GetSystemMetrics(SM_CXFRAME),
|
|
-GetSystemMetrics(SM_CYFRAME));
|
|
if (!PtInRect(&WindowRect, Point))
|
|
{
|
|
if (Point.y < WindowRect.top)
|
|
{
|
|
if (Point.x < (WindowRect.left + GetSystemMetrics(SM_CXSIZE)))
|
|
{
|
|
return(HTTOPLEFT);
|
|
}
|
|
if (Point.x >= (WindowRect.right - GetSystemMetrics(SM_CXSIZE)))
|
|
{
|
|
return(HTTOPRIGHT);
|
|
}
|
|
return(HTTOP);
|
|
}
|
|
if (Point.y >= WindowRect.bottom)
|
|
{
|
|
if (Point.x < (WindowRect.left + GetSystemMetrics(SM_CXSIZE)))
|
|
{
|
|
return(HTBOTTOMLEFT);
|
|
}
|
|
if (Point.x >= (WindowRect.right - GetSystemMetrics(SM_CXSIZE)))
|
|
{
|
|
return(HTBOTTOMRIGHT);
|
|
}
|
|
return(HTBOTTOM);
|
|
}
|
|
if (Point.x < WindowRect.left)
|
|
{
|
|
if (Point.y < (WindowRect.top + GetSystemMetrics(SM_CYSIZE)))
|
|
{
|
|
return(HTTOPLEFT);
|
|
}
|
|
if (Point.y >= (WindowRect.bottom - GetSystemMetrics(SM_CYSIZE)))
|
|
{
|
|
return(HTBOTTOMLEFT);
|
|
}
|
|
return(HTLEFT);
|
|
}
|
|
if (Point.x >= WindowRect.right)
|
|
{
|
|
if (Point.y < (WindowRect.top + GetSystemMetrics(SM_CYSIZE)))
|
|
{
|
|
return(HTTOPRIGHT);
|
|
}
|
|
if (Point.y >= (WindowRect.bottom - GetSystemMetrics(SM_CYSIZE)))
|
|
{
|
|
return(HTBOTTOMRIGHT);
|
|
}
|
|
return(HTRIGHT);
|
|
}
|
|
}
|
|
}
|
|
else
|
|
{
|
|
if (UserHasDlgFrameStyle(Style, ExStyle))
|
|
{
|
|
InflateRect(&WindowRect, -GetSystemMetrics(SM_CXDLGFRAME),
|
|
-GetSystemMetrics(SM_CYDLGFRAME));
|
|
}
|
|
else if (UserHasThinFrameStyle(Style, ExStyle))
|
|
{
|
|
InflateRect(&WindowRect, -GetSystemMetrics(SM_CXBORDER),
|
|
-GetSystemMetrics(SM_CYBORDER));
|
|
}
|
|
if (!PtInRect(&WindowRect, Point))
|
|
{
|
|
return(HTBORDER);
|
|
}
|
|
}
|
|
|
|
if ((Style & WS_CAPTION) == WS_CAPTION)
|
|
{
|
|
WindowRect.top += GetSystemMetrics(SM_CYCAPTION) -
|
|
GetSystemMetrics(SM_CYBORDER);
|
|
if (!PtInRect(&WindowRect, Point))
|
|
{
|
|
if ((Style & WS_SYSMENU) && !(ExStyle & WS_EX_TOOLWINDOW))
|
|
{
|
|
WindowRect.left += GetSystemMetrics(SM_CXSIZE);
|
|
WindowRect.right -= GetSystemMetrics(SM_CXSIZE) + 1;
|
|
}
|
|
if (Point.x <= WindowRect.left)
|
|
{
|
|
return(HTSYSMENU);
|
|
}
|
|
if (WindowRect.right <= Point.x)
|
|
{
|
|
return(HTCLOSE);
|
|
}
|
|
|
|
if (Style & WS_MAXIMIZEBOX || Style & WS_MINIMIZEBOX)
|
|
{
|
|
WindowRect.right -= GetSystemMetrics(SM_CXSMSIZE) + 1;
|
|
}
|
|
if (Point.x >= WindowRect.right)
|
|
{
|
|
return(HTMAXBUTTON);
|
|
}
|
|
|
|
if (Style & WS_MINIMIZEBOX)
|
|
{
|
|
WindowRect.right -= GetSystemMetrics(SM_CXSMSIZE) + 1;
|
|
}
|
|
if (Point.x >= WindowRect.right)
|
|
{
|
|
return(HTMINBUTTON);
|
|
}
|
|
return(HTCAPTION);
|
|
}
|
|
}
|
|
|
|
ScreenToClient(hWnd, &Point);
|
|
GetClientRect(hWnd, &WindowRect);
|
|
|
|
if (PtInRect(&WindowRect, Point))
|
|
{
|
|
return(HTCLIENT);
|
|
}
|
|
|
|
if (Style & WS_VSCROLL)
|
|
{
|
|
WindowRect.right += GetSystemMetrics(SM_CXVSCROLL);
|
|
if (PtInRect(&WindowRect, Point))
|
|
{
|
|
return(HTVSCROLL);
|
|
}
|
|
}
|
|
|
|
if (Style & WS_HSCROLL)
|
|
{
|
|
WindowRect.bottom += GetSystemMetrics(SM_CYHSCROLL);
|
|
if (PtInRect(&WindowRect, Point))
|
|
{
|
|
if ((Style & WS_VSCROLL) &&
|
|
(Point.x >= (WindowRect.right - GetSystemMetrics(SM_CXVSCROLL))))
|
|
{
|
|
return(HTSIZE);
|
|
}
|
|
return(HTHSCROLL);
|
|
}
|
|
}
|
|
|
|
if (UserHasMenu(hWnd, Style))
|
|
{
|
|
if (Point.y < 0 && Point.x >= 0 && Point.x <= WindowRect.right)
|
|
{
|
|
return(HTMENU);
|
|
}
|
|
}
|
|
|
|
return(HTNOWHERE);
|
|
}
|
|
|
|
VOID
|
|
DefWndDrawSysButton(HWND hWnd, HDC hDC, BOOL Down)
|
|
{
|
|
}
|
|
|
|
LRESULT
|
|
DefWndHandleLButtonDownNC(HWND hWnd, WPARAM wParam, LPARAM lParam)
|
|
{
|
|
switch (wParam)
|
|
{
|
|
case HTCAPTION:
|
|
{
|
|
HWND hTopWnd = GetDesktopWindow(); //GetAncestor(hWnd, GA_ROOT); temp fix.
|
|
if (SetActiveWindow(hTopWnd) || GetActiveWindow() == hTopWnd)
|
|
{
|
|
SendMessageA(hWnd, WM_SYSCOMMAND, SC_MOVE + HTCAPTION, lParam);
|
|
}
|
|
break;
|
|
}
|
|
case HTSYSMENU:
|
|
{
|
|
if (GetWindowLong(hWnd, GWL_STYLE) & WS_SYSMENU)
|
|
{
|
|
if (!(GetWindowLong(hWnd, GWL_STYLE) & WS_MINIMIZE))
|
|
{
|
|
HDC hDC = GetWindowDC(hWnd);
|
|
DefWndDrawSysButton(hWnd, hDC, TRUE);
|
|
ReleaseDC(hWnd, hDC);
|
|
}
|
|
SendMessageA(hWnd, WM_SYSCOMMAND, SC_MOUSEMENU + HTSYSMENU,
|
|
lParam);
|
|
}
|
|
break;
|
|
}
|
|
case HTMENU:
|
|
{
|
|
SendMessageA(hWnd, WM_SYSCOMMAND, SC_MOUSEMENU, lParam);
|
|
break;
|
|
}
|
|
case HTHSCROLL:
|
|
{
|
|
SendMessageA(hWnd, WM_SYSCOMMAND, SC_HSCROLL + HTHSCROLL, lParam);
|
|
break;
|
|
}
|
|
case HTVSCROLL:
|
|
{
|
|
SendMessageA(hWnd, WM_SYSCOMMAND, SC_VSCROLL + HTVSCROLL, lParam);
|
|
break;
|
|
}
|
|
case HTMINBUTTON:
|
|
{
|
|
UserDrawMinButton(hWnd, GetWindowDC(hWnd), IsMinBoxActive(hWnd) );
|
|
break;
|
|
}
|
|
case HTMAXBUTTON:
|
|
{
|
|
UserDrawMaxButton(hWnd,GetWindowDC(hWnd), IsMaxBoxActive(hWnd) );
|
|
break;
|
|
}
|
|
case HTCLOSE:
|
|
{
|
|
UserDrawCloseButton(hWnd,GetWindowDC(hWnd),TRUE);
|
|
break;
|
|
}
|
|
case HTLEFT:
|
|
case HTRIGHT:
|
|
case HTTOP:
|
|
case HTBOTTOM:
|
|
case HTTOPLEFT:
|
|
case HTTOPRIGHT:
|
|
case HTBOTTOMLEFT:
|
|
case HTBOTTOMRIGHT:
|
|
{
|
|
SendMessageA(hWnd, WM_SYSCOMMAND, SC_SIZE + wParam - 2, lParam);
|
|
break;
|
|
}
|
|
}
|
|
return(0);
|
|
}
|
|
|
|
LRESULT
|
|
DefWndHandleLButtonDblClkNC(HWND hWnd, WPARAM wParam, LPARAM lParam)
|
|
{
|
|
return(0);
|
|
}
|
|
|
|
LRESULT
|
|
DefWndHandleLButtonUpNC(HWND hWnd, WPARAM wParam, LPARAM lParam)
|
|
{
|
|
UserDrawMinButton(hWnd,GetWindowDC(hWnd),FALSE);
|
|
UserDrawMaxButton(hWnd,GetWindowDC(hWnd),FALSE);
|
|
UserDrawCloseButton(hWnd,GetWindowDC(hWnd),FALSE);
|
|
switch (wParam)
|
|
{
|
|
case HTMINBUTTON:
|
|
{
|
|
SendMessageA(hWnd, WM_SYSCOMMAND, SC_MINIMIZE, 0);
|
|
break;
|
|
}
|
|
case HTMAXBUTTON:
|
|
{
|
|
SendMessageA(hWnd, WM_SYSCOMMAND, SC_MAXIMIZE, 0);
|
|
break;
|
|
}
|
|
case HTCLOSE:
|
|
{
|
|
SendMessageA(hWnd, WM_CLOSE, 0, 0);
|
|
SendMessageA(hWnd, WM_SYSCOMMAND, SC_CLOSE, 0);
|
|
break;
|
|
}
|
|
}
|
|
return(0);
|
|
}
|
|
|
|
LRESULT
|
|
DefWndHandleActiveNC(HWND hWnd, WPARAM wParam)
|
|
{
|
|
/* FIXME: Implement this. */
|
|
return(0);
|
|
}
|
|
|
|
VOID
|
|
DefWndSetRedraw(HWND hWnd, WPARAM wParam)
|
|
{
|
|
}
|
|
|
|
LRESULT
|
|
DefWndHandleSetCursor(HWND hWnd, WPARAM wParam, LPARAM lParam)
|
|
{
|
|
/* Not for child windows. */
|
|
if (hWnd != (HWND)wParam)
|
|
{
|
|
return(0);
|
|
}
|
|
|
|
switch(LOWORD(lParam))
|
|
{
|
|
case HTERROR:
|
|
{
|
|
WORD Msg = HIWORD(lParam);
|
|
if (Msg == WM_LBUTTONDOWN || Msg == WM_MBUTTONDOWN ||
|
|
Msg == WM_RBUTTONDOWN)
|
|
{
|
|
MessageBeep(0);
|
|
}
|
|
break;
|
|
}
|
|
|
|
case HTCLIENT:
|
|
{
|
|
HICON hCursor = (HICON)GetClassLong(hWnd, GCL_HCURSOR);
|
|
if (hCursor)
|
|
{
|
|
SetCursor(hCursor);
|
|
return(TRUE);
|
|
}
|
|
return(FALSE);
|
|
}
|
|
|
|
case HTLEFT:
|
|
case HTRIGHT:
|
|
{
|
|
return((LRESULT)SetCursor(LoadCursorW(0, IDC_SIZEWE)));
|
|
}
|
|
|
|
case HTTOP:
|
|
case HTBOTTOM:
|
|
{
|
|
return((LRESULT)SetCursor(LoadCursorW(0, IDC_SIZENS)));
|
|
}
|
|
|
|
case HTTOPLEFT:
|
|
case HTBOTTOMRIGHT:
|
|
{
|
|
return((LRESULT)SetCursor(LoadCursorW(0, IDC_SIZENWSE)));
|
|
}
|
|
|
|
case HTBOTTOMLEFT:
|
|
case HTTOPRIGHT:
|
|
{
|
|
return((LRESULT)SetCursor(LoadCursorW(0, IDC_SIZENESW)));
|
|
}
|
|
}
|
|
return((LRESULT)SetCursor(LoadCursorW(0, IDC_ARROW)));
|
|
}
|
|
|
|
LRESULT
|
|
DefWndHandleSysCommand(HWND hWnd, WPARAM wParam, POINT Pt)
|
|
{
|
|
/* FIXME: Implement system commands. */
|
|
return(0);
|
|
}
|
|
|
|
VOID
|
|
DefWndAdjustRect(RECT* Rect, ULONG Style, BOOL Menu, ULONG ExStyle)
|
|
{
|
|
if (Style & WS_ICONIC)
|
|
{
|
|
return;
|
|
}
|
|
|
|
if (UserHasThickFrameStyle(Style, ExStyle))
|
|
{
|
|
InflateRect(Rect, GetSystemMetrics(SM_CXFRAME),
|
|
GetSystemMetrics(SM_CYFRAME));
|
|
}
|
|
else if (UserHasDlgFrameStyle(Style, ExStyle))
|
|
{
|
|
InflateRect(Rect, GetSystemMetrics(SM_CXDLGFRAME),
|
|
GetSystemMetrics(SM_CYDLGFRAME));
|
|
}
|
|
else if (UserHasThinFrameStyle(Style, ExStyle))
|
|
{
|
|
InflateRect(Rect, GetSystemMetrics(SM_CXBORDER),
|
|
GetSystemMetrics(SM_CYBORDER));
|
|
}
|
|
if (Style & WS_CAPTION)
|
|
{
|
|
Rect->top -= GetSystemMetrics(SM_CYCAPTION) -
|
|
GetSystemMetrics(SM_CYBORDER);
|
|
}
|
|
if (Menu)
|
|
{
|
|
Rect->top -= GetSystemMetrics(SM_CYMENU) + GetSystemMetrics(SM_CYBORDER);
|
|
}
|
|
if (Style & WS_VSCROLL)
|
|
{
|
|
Rect->right += GetSystemMetrics(SM_CXVSCROLL) - 1;
|
|
if (UserHasAnyFrameStyle(Style, ExStyle))
|
|
{
|
|
Rect->right++;
|
|
}
|
|
}
|
|
if (Style & WS_HSCROLL)
|
|
{
|
|
Rect->bottom += GetSystemMetrics(SM_CYHSCROLL) - 1;
|
|
if (UserHasAnyFrameStyle(Style, ExStyle))
|
|
{
|
|
Rect->bottom++;
|
|
}
|
|
}
|
|
}
|
|
|
|
LRESULT STDCALL
|
|
DefWndNCCalcSize(HWND hWnd, RECT* Rect)
|
|
{
|
|
LRESULT Result = 0;
|
|
LONG Style = GetClassLongW(hWnd, GCL_STYLE);
|
|
RECT TmpRect = {0, 0, 0, 0};
|
|
|
|
if (Style & CS_VREDRAW)
|
|
{
|
|
Result |= WVR_VREDRAW;
|
|
}
|
|
if (Style & CS_HREDRAW)
|
|
{
|
|
Result |= WVR_HREDRAW;
|
|
}
|
|
|
|
if (!(GetWindowLong(hWnd, GWL_STYLE) & WS_MINIMIZE))
|
|
{
|
|
DefWndAdjustRect(&TmpRect, GetWindowLong(hWnd, GWL_STYLE),
|
|
FALSE, GetWindowLong(hWnd, GWL_EXSTYLE));
|
|
Rect->left -= TmpRect.left;
|
|
Rect->top -= TmpRect.top;
|
|
Rect->right -= TmpRect.right;
|
|
Rect->bottom -= TmpRect.bottom;
|
|
/* FIXME: Adjust if the window has a menu. */
|
|
Rect->bottom = max(Rect->top, Rect->bottom);
|
|
Rect->right = max(Rect->left, Rect->right);
|
|
}
|
|
return(Result);
|
|
}
|
|
|
|
LRESULT
|
|
DefWndHandleWindowPosChanging(HWND hWnd, WINDOWPOS* Pos)
|
|
{
|
|
/* FIXME: Implement this. */
|
|
return(0);
|
|
}
|
|
|
|
LRESULT STDCALL
|
|
User32DefWindowProc(HWND hWnd,
|
|
UINT Msg,
|
|
WPARAM wParam,
|
|
LPARAM lParam,
|
|
BOOL bUnicode)
|
|
{
|
|
switch (Msg)
|
|
{
|
|
case WM_NCPAINT:
|
|
{
|
|
return(DefWndPaintNC(hWnd, (HRGN)wParam));
|
|
}
|
|
|
|
case WM_NCHITTEST:
|
|
{
|
|
POINT Point;
|
|
Point.x = SLOWORD(lParam);
|
|
Point.y = SHIWORD(lParam);
|
|
return(DefWndHitTestNC(hWnd, Point));
|
|
}
|
|
|
|
case WM_NCLBUTTONDOWN:
|
|
{
|
|
return(DefWndHandleLButtonDownNC(hWnd, wParam, lParam));
|
|
}
|
|
|
|
case WM_NCLBUTTONUP:
|
|
{
|
|
return(DefWndHandleLButtonUpNC(hWnd, wParam, lParam));
|
|
}
|
|
|
|
case WM_LBUTTONDBLCLK:
|
|
case WM_NCLBUTTONDBLCLK:
|
|
{
|
|
return(DefWndHandleLButtonDblClkNC(hWnd, wParam, lParam));
|
|
}
|
|
|
|
case WM_NCRBUTTONDOWN:
|
|
{
|
|
if (wParam == HTCAPTION)
|
|
{
|
|
SetCapture(hWnd);
|
|
}
|
|
break;
|
|
}
|
|
|
|
case WM_RBUTTONUP:
|
|
{
|
|
POINT Pt;
|
|
if (hWnd == GetCapture())
|
|
{
|
|
ReleaseCapture();
|
|
}
|
|
Pt.x = SLOWORD(lParam);
|
|
Pt.y = SHIWORD(lParam);
|
|
ClientToScreen(hWnd, &Pt);
|
|
lParam = MAKELPARAM(Pt.x, Pt.y);
|
|
if (bUnicode)
|
|
{
|
|
SendMessageW(hWnd, WM_CONTEXTMENU, (WPARAM)hWnd, lParam);
|
|
}
|
|
else
|
|
{
|
|
SendMessageA (hWnd, WM_CONTEXTMENU, (WPARAM)hWnd, lParam);
|
|
}
|
|
break;
|
|
}
|
|
|
|
case WM_NCRBUTTONUP:
|
|
{
|
|
/* Wine does nothing here. */
|
|
break;
|
|
}
|
|
|
|
case WM_CONTEXTMENU:
|
|
{
|
|
if (GetWindowLong(hWnd, GWL_STYLE) & WS_CHILD)
|
|
{
|
|
if (bUnicode)
|
|
{
|
|
SendMessageW(GetParent(hWnd), Msg, wParam, lParam);
|
|
}
|
|
else
|
|
{
|
|
SendMessageA(hWnd, WM_CONTEXTMENU, wParam, lParam);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
LONG HitCode;
|
|
POINT Pt;
|
|
|
|
Pt.x = SLOWORD(lParam);
|
|
Pt.y = SHIWORD(lParam);
|
|
|
|
if (GetWindowLong(hWnd, GWL_STYLE) & WS_CHILD)
|
|
{
|
|
ScreenToClient(GetParent(hWnd), &Pt);
|
|
}
|
|
|
|
HitCode = DefWndHitTestNC(hWnd, Pt);
|
|
|
|
if (HitCode == HTCAPTION || HitCode == HTSYSMENU)
|
|
{
|
|
TrackPopupMenu(GetSystemMenu(hWnd, FALSE),
|
|
TPM_LEFTBUTTON | TPM_RIGHTBUTTON,
|
|
Pt.x, Pt.y, 0, hWnd, NULL);
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
|
|
case WM_NCACTIVATE:
|
|
{
|
|
return(DefWndHandleActiveNC(hWnd, wParam));
|
|
}
|
|
|
|
case WM_NCDESTROY:
|
|
{
|
|
return(0);
|
|
}
|
|
|
|
case WM_PRINT:
|
|
{
|
|
return(0);
|
|
}
|
|
|
|
case WM_PAINTICON:
|
|
case WM_PAINT:
|
|
{
|
|
PAINTSTRUCT Ps;
|
|
HDC hDC = BeginPaint(hWnd, &Ps);
|
|
if (hDC)
|
|
{
|
|
|
|
HICON hIcon;
|
|
if (GetWindowLongW(hWnd, GWL_STYLE) & WS_MINIMIZE &&
|
|
(hIcon = (HICON)GetClassLongW(hWnd, GCL_HICON)) != NULL)
|
|
{
|
|
RECT WindowRect;
|
|
INT x, y;
|
|
GetWindowRect(hWnd, &WindowRect);
|
|
x = (WindowRect.right - WindowRect.left -
|
|
GetSystemMetrics(SM_CXICON)) / 2;
|
|
y = (WindowRect.bottom - WindowRect.top -
|
|
GetSystemMetrics(SM_CYICON)) / 2;
|
|
DrawIcon(hDC, x, y, hIcon);
|
|
}
|
|
EndPaint(hWnd, &Ps);
|
|
}
|
|
return(0);
|
|
}
|
|
|
|
case WM_SYNCPAINT:
|
|
{
|
|
HRGN hRgn;
|
|
hRgn = CreateRectRgn(0, 0, 0, 0);
|
|
if (GetUpdateRgn(hWnd, hRgn, FALSE) != NULLREGION)
|
|
{
|
|
RedrawWindow(hWnd, NULL, hRgn,
|
|
RDW_ERASENOW | RDW_ERASE | RDW_FRAME |
|
|
RDW_ALLCHILDREN);
|
|
}
|
|
DeleteObject(hRgn);
|
|
return(0);
|
|
}
|
|
|
|
case WM_SETREDRAW:
|
|
{
|
|
DefWndSetRedraw(hWnd, wParam);
|
|
return(0);
|
|
}
|
|
|
|
case WM_CLOSE:
|
|
{
|
|
DestroyWindow(hWnd);
|
|
return(0);
|
|
}
|
|
|
|
case WM_MOUSEACTIVATE:
|
|
{
|
|
if (GetWindowLong(hWnd, GWL_STYLE) & WS_CHILD)
|
|
{
|
|
LONG Ret;
|
|
if (bUnicode)
|
|
{
|
|
Ret = SendMessageW(GetParent(hWnd), WM_MOUSEACTIVATE,
|
|
wParam, lParam);
|
|
}
|
|
else
|
|
{
|
|
Ret = SendMessageA(GetParent(hWnd), WM_MOUSEACTIVATE,
|
|
wParam, lParam);
|
|
}
|
|
if (Ret)
|
|
{
|
|
return(Ret);
|
|
}
|
|
}
|
|
return((LOWORD(lParam) >= HTCLIENT) ? MA_ACTIVATE : MA_NOACTIVATE);
|
|
}
|
|
|
|
case WM_ACTIVATE:
|
|
{
|
|
if (LOWORD(lParam) != WA_INACTIVE &&
|
|
GetWindowLong(hWnd, GWL_STYLE) & WS_MINIMIZE)
|
|
{
|
|
/* Check if the window is minimized. */
|
|
SetFocus(hWnd);
|
|
}
|
|
break;
|
|
}
|
|
|
|
case WM_MOUSEWHEEL:
|
|
{
|
|
if (GetWindowLong(hWnd, GWL_STYLE & WS_CHILD))
|
|
{
|
|
if (bUnicode)
|
|
{
|
|
return(SendMessageW(GetParent(hWnd), WM_MOUSEWHEEL,
|
|
wParam, lParam));
|
|
}
|
|
else
|
|
{
|
|
return(SendMessageA(GetParent(hWnd), WM_MOUSEWHEEL,
|
|
wParam, lParam));
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
|
|
case WM_ERASEBKGND:
|
|
case WM_ICONERASEBKGND:
|
|
{
|
|
|
|
RECT Rect;
|
|
HBRUSH hBrush = (HBRUSH)GetClassLongW(hWnd, GCL_HBRBACKGROUND);
|
|
GetClipBox((HDC)wParam, &Rect);
|
|
FillRect((HDC)wParam, &Rect, hBrush);
|
|
return(1);
|
|
}
|
|
|
|
case WM_GETDLGCODE:
|
|
{
|
|
return(0);
|
|
}
|
|
|
|
/* FIXME: Implement colour controls. */
|
|
|
|
case WM_SETCURSOR:
|
|
{
|
|
if (GetWindowLong(hWnd, GWL_STYLE) & WS_CHILD)
|
|
{
|
|
if (LOWORD(lParam) < HTLEFT || LOWORD(lParam) > HTBOTTOMRIGHT)
|
|
{
|
|
BOOL bResult;
|
|
if (bUnicode)
|
|
{
|
|
bResult = SendMessageW(GetParent(hWnd), WM_SETCURSOR,
|
|
wParam, lParam);
|
|
}
|
|
else
|
|
{
|
|
bResult = SendMessageA(GetParent(hWnd), WM_SETCURSOR,
|
|
wParam, lParam);
|
|
}
|
|
if (bResult)
|
|
{
|
|
return(TRUE);
|
|
}
|
|
}
|
|
}
|
|
return(DefWndHandleSetCursor(hWnd, wParam, lParam));
|
|
}
|
|
|
|
case WM_SYSCOMMAND:
|
|
{
|
|
POINT Pt;
|
|
Pt.x = SLOWORD(lParam);
|
|
Pt.y = SHIWORD(lParam);
|
|
return(DefWndHandleSysCommand(hWnd, wParam, Pt));
|
|
}
|
|
|
|
/* FIXME: Handle key messages. */
|
|
|
|
case WM_SHOWWINDOW:
|
|
{
|
|
if (lParam)
|
|
{
|
|
return(0);
|
|
}
|
|
/* FIXME: Not done correctly */
|
|
if ((GetWindowLongW(hWnd, GWL_STYLE) & WS_VISIBLE && !wParam) ||
|
|
(!(GetWindowLongW(hWnd, GWL_STYLE) & WS_VISIBLE) && wParam))
|
|
{
|
|
return(0);
|
|
}
|
|
ShowWindow(hWnd, wParam ? SW_SHOWNA : SW_HIDE);
|
|
break;
|
|
}
|
|
|
|
case WM_CANCELMODE:
|
|
{
|
|
/* FIXME: Check for a desktop. */
|
|
if (GetCapture() == hWnd)
|
|
{
|
|
ReleaseCapture();
|
|
}
|
|
break;
|
|
}
|
|
|
|
case WM_VKEYTOITEM:
|
|
case WM_CHARTOITEM:
|
|
return(-1);
|
|
|
|
case WM_DROPOBJECT:
|
|
/* FIXME: Implement this. */
|
|
break;
|
|
|
|
case WM_QUERYDROPOBJECT:
|
|
{
|
|
if (GetWindowLongW(hWnd, GWL_EXSTYLE) & WS_EX_ACCEPTFILES)
|
|
{
|
|
return(1);
|
|
}
|
|
break;
|
|
}
|
|
|
|
case WM_QUERYDRAGICON:
|
|
{
|
|
UINT Len;
|
|
HICON hIcon;
|
|
|
|
hIcon = (HICON)GetClassLongW(hWnd, GCL_HICON);
|
|
if (hIcon)
|
|
{
|
|
return((LRESULT)hIcon);
|
|
}
|
|
for (Len = 1; Len < 64; Len++)
|
|
{
|
|
if ((hIcon = LoadIconW(NULL, MAKEINTRESOURCE(Len))) != NULL)
|
|
{
|
|
return((LRESULT)hIcon);
|
|
}
|
|
}
|
|
return((LRESULT)LoadIconW(0, IDI_APPLICATION));
|
|
}
|
|
|
|
/* FIXME: WM_ISACTIVEICON */
|
|
|
|
case WM_NOTIFYFORMAT:
|
|
{
|
|
if (IsWindowUnicode(hWnd))
|
|
{
|
|
return(NFR_UNICODE);
|
|
}
|
|
else
|
|
{
|
|
return(NFR_ANSI);
|
|
}
|
|
}
|
|
|
|
case WM_SETICON:
|
|
{
|
|
INT Index = (wParam != 0) ? GCL_HICON : GCL_HICONSM;
|
|
HICON hOldIcon = (HICON)GetClassLongW(hWnd, Index);
|
|
SetClassLongW(hWnd, Index, lParam);
|
|
SetWindowPos(hWnd, 0, 0, 0, 0, 0,
|
|
SWP_FRAMECHANGED | SWP_NOSIZE | SWP_NOMOVE |
|
|
SWP_NOACTIVATE | SWP_NOZORDER);
|
|
return((LRESULT)hOldIcon);
|
|
}
|
|
|
|
case WM_GETICON:
|
|
{
|
|
INT Index = (wParam != 0) ? GCL_HICON : GCL_HICONSM;
|
|
return(GetClassLongW(hWnd, Index));
|
|
}
|
|
|
|
case WM_HELP:
|
|
{
|
|
if (bUnicode)
|
|
{
|
|
SendMessageW(GetParent(hWnd), Msg, wParam, lParam);
|
|
}
|
|
else
|
|
{
|
|
SendMessageA(GetParent(hWnd), Msg, wParam, lParam);
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
|
|
LRESULT STDCALL
|
|
DefWindowProcA(HWND hWnd,
|
|
UINT Msg,
|
|
WPARAM wParam,
|
|
LPARAM lParam)
|
|
{
|
|
LRESULT Result;
|
|
static LPSTR WindowTextAtom = 0;
|
|
PSTR WindowText;
|
|
|
|
switch (Msg)
|
|
{
|
|
case WM_NCCREATE:
|
|
{
|
|
CREATESTRUCTA* Cs = (CREATESTRUCTA*)lParam;
|
|
if (HIWORD(Cs->lpszName))
|
|
{
|
|
WindowTextAtom =
|
|
(LPSTR)(ULONG)GlobalAddAtomA("USER32!WindowTextAtomA");
|
|
WindowText = RtlAllocateHeap(RtlGetProcessHeap(), 0,
|
|
strlen(Cs->lpszName) * sizeof(CHAR));
|
|
strcpy(WindowText, Cs->lpszName);
|
|
SetPropA(hWnd, WindowTextAtom, WindowText);
|
|
}
|
|
return(1);
|
|
}
|
|
|
|
case WM_NCCALCSIZE:
|
|
{
|
|
return(DefWndNCCalcSize(hWnd, (RECT*)lParam));
|
|
}
|
|
|
|
case WM_WINDOWPOSCHANGING:
|
|
{
|
|
return(DefWndHandleWindowPosChanging(hWnd, (WINDOWPOS*)lParam));
|
|
}
|
|
|
|
case WM_GETTEXTLENGTH:
|
|
{
|
|
if (WindowTextAtom == 0 ||
|
|
(WindowText = GetPropA(hWnd, WindowTextAtom)) == NULL)
|
|
{
|
|
return(0);
|
|
}
|
|
return(strlen(WindowText));
|
|
}
|
|
|
|
case WM_GETTEXT:
|
|
{
|
|
if (WindowTextAtom == 0 ||
|
|
(WindowText = GetPropA(hWnd, WindowTextAtom)) == NULL)
|
|
{
|
|
if (wParam > 1)
|
|
{
|
|
((PSTR)lParam) = '\0';
|
|
}
|
|
return(0);
|
|
}
|
|
strncpy((LPSTR)lParam, WindowText, wParam);
|
|
return(min(wParam, strlen(WindowText)));
|
|
}
|
|
|
|
case WM_SETTEXT:
|
|
{
|
|
if (WindowTextAtom != 0)
|
|
{
|
|
WindowTextAtom =
|
|
(LPSTR)(DWORD)GlobalAddAtomA("USER32!WindowTextAtomW");
|
|
}
|
|
if (WindowTextAtom != 0 &&
|
|
(WindowText = GetPropA(hWnd, WindowTextAtom)) == NULL)
|
|
{
|
|
RtlFreeHeap(RtlGetProcessHeap(), 0, WindowText);
|
|
}
|
|
WindowText = RtlAllocateHeap(RtlGetProcessHeap(), 0,
|
|
strlen((PSTR)lParam) * sizeof(CHAR));
|
|
strcpy(WindowText, (PSTR)lParam);
|
|
SetPropA(hWnd, WindowTextAtom, WindowText);
|
|
}
|
|
|
|
case WM_NCDESTROY:
|
|
{
|
|
if (WindowTextAtom != 0 &&
|
|
(WindowText = RemovePropA(hWnd, WindowTextAtom)) == NULL)
|
|
{
|
|
RtlFreeHeap(GetProcessHeap(), 0, WindowText);
|
|
}
|
|
if (WindowTextAtom != 0)
|
|
{
|
|
GlobalDeleteAtom((ATOM)(ULONG)WindowTextAtom);
|
|
}
|
|
return(0);
|
|
}
|
|
|
|
default:
|
|
Result = User32DefWindowProc(hWnd, Msg, wParam, lParam, FALSE);
|
|
break;
|
|
}
|
|
|
|
return(Result);
|
|
}
|
|
|
|
LRESULT STDCALL
|
|
DefWindowProcW(HWND hWnd,
|
|
UINT Msg,
|
|
WPARAM wParam,
|
|
LPARAM lParam)
|
|
{
|
|
LRESULT Result;
|
|
static LPWSTR WindowTextAtom = 0;
|
|
PWSTR WindowText;
|
|
|
|
switch (Msg)
|
|
{
|
|
case WM_NCCREATE:
|
|
{
|
|
CREATESTRUCTW* Cs = (CREATESTRUCTW*)lParam;
|
|
if (HIWORD(Cs->lpszName))
|
|
{
|
|
WindowTextAtom =
|
|
(LPWSTR)(DWORD)GlobalAddAtomW(L"USER32!WindowTextAtomW");
|
|
WindowText = RtlAllocateHeap(RtlGetProcessHeap(), 0,
|
|
wcslen(Cs->lpszName) * sizeof(WCHAR));
|
|
wcscpy(WindowText, Cs->lpszName);
|
|
SetPropW(hWnd, WindowTextAtom, WindowText);
|
|
}
|
|
return(1);
|
|
}
|
|
|
|
case WM_NCCALCSIZE:
|
|
{
|
|
return(DefWndNCCalcSize(hWnd, (RECT*)lParam));
|
|
}
|
|
|
|
case WM_WINDOWPOSCHANGING:
|
|
{
|
|
return(DefWndHandleWindowPosChanging(hWnd, (WINDOWPOS*)lParam));
|
|
}
|
|
|
|
case WM_GETTEXTLENGTH:
|
|
{
|
|
if (WindowTextAtom == 0 ||
|
|
(WindowText = GetPropW(hWnd, WindowTextAtom)) == NULL)
|
|
{
|
|
return(0);
|
|
}
|
|
return(wcslen(WindowText));
|
|
}
|
|
|
|
case WM_GETTEXT:
|
|
{
|
|
if (WindowTextAtom == 0 ||
|
|
(WindowText = GetPropW(hWnd, WindowTextAtom)) == NULL)
|
|
{
|
|
if (wParam > 1)
|
|
{
|
|
((PWSTR)lParam) = '\0';
|
|
}
|
|
return(0);
|
|
}
|
|
wcsncpy((PWSTR)lParam, WindowText, wParam);
|
|
return(min(wParam, wcslen(WindowText)));
|
|
}
|
|
|
|
case WM_SETTEXT:
|
|
{
|
|
if (WindowTextAtom != 0)
|
|
{
|
|
WindowTextAtom =
|
|
(LPWSTR)(DWORD)GlobalAddAtom(L"USER32!WindowTextAtomW");
|
|
}
|
|
if (WindowTextAtom != 0 &&
|
|
(WindowText = GetPropW(hWnd, WindowTextAtom)) == NULL)
|
|
{
|
|
RtlFreeHeap(RtlGetProcessHeap(), 0, WindowText);
|
|
}
|
|
WindowText = RtlAllocateHeap(RtlGetProcessHeap(), 0,
|
|
wcslen((PWSTR)lParam) * sizeof(WCHAR));
|
|
wcscpy(WindowText, (PWSTR)lParam);
|
|
SetPropW(hWnd, WindowTextAtom, WindowText);
|
|
}
|
|
//FIXME: return correct code
|
|
return TRUE;
|
|
|
|
case WM_NCDESTROY:
|
|
{
|
|
if (WindowTextAtom != 0 &&
|
|
(WindowText = RemovePropW(hWnd, WindowTextAtom)) == NULL)
|
|
{
|
|
RtlFreeHeap(RtlGetProcessHeap(), 0, WindowText);
|
|
}
|
|
if (WindowTextAtom != 0)
|
|
{
|
|
GlobalDeleteAtom((ATOM)(DWORD)WindowTextAtom);
|
|
}
|
|
|
|
return(0);
|
|
}
|
|
|
|
default:
|
|
Result = User32DefWindowProc(hWnd, Msg, wParam, lParam, TRUE);
|
|
break;
|
|
}
|
|
|
|
return(Result);
|
|
}
|