diff --git a/reactos/include/user32/debug.h b/reactos/include/user32/debug.h index 5a5c4259b30..271decc03d7 100644 --- a/reactos/include/user32/debug.h +++ b/reactos/include/user32/debug.h @@ -1,5 +1,6 @@ #ifndef DEBUG_H #define DEBUG_H #include - #define DPRINT printf + //#define DPRINT printf + #define DPRINT(args...) #endif \ No newline at end of file diff --git a/reactos/include/user32/heapdup.h b/reactos/include/user32/heapdup.h index 05a177b1ef2..d7e77a1073c 100644 --- a/reactos/include/user32/heapdup.h +++ b/reactos/include/user32/heapdup.h @@ -7,5 +7,5 @@ int lpstrncpyA( LPSTR ptr1,LPSTR ptr2, int nMaxCount); int lpstrncpyW( LPWSTR ptr1,LPWSTR ptr2, int nMaxCount); LPVOID HEAP_strdupAtoW(HANDLE hHeap,DWORD dwFlags, LPCSTR lpszAsciiString ); LPVOID HEAP_strdupWtoA(HANDLE hHeap,DWORD dwFlags, LPCWSTR lpszUnicodeString ); -LPSTR HEAP_strdupA(LPSTR ptr); -LPWSTR HEAP_strdupW(LPWSTR ptr); \ No newline at end of file +LPSTR HEAP_strdupA(HANDLE hHeap,DWORD dwFlags, LPCSTR ptr); +LPWSTR HEAP_strdupW(HANDLE hHeap,DWORD dwFlags, LPCWSTR ptr); \ No newline at end of file diff --git a/reactos/include/user32/paint.h b/reactos/include/user32/paint.h new file mode 100644 index 00000000000..7b11faf2a67 --- /dev/null +++ b/reactos/include/user32/paint.h @@ -0,0 +1,22 @@ + + +#include +#include +#include + + +#define DCX_DCEEMPTY 0x00000800 +#define DCX_DCEBUSY 0x00001000 +#define DCX_DCEDIRTY 0x00002000 +#define DCX_WINDOWPAINT 0x00020000 +#define DCX_KEEPCLIPRGN 0x00040000 +#define DCX_NOCLIPCHILDREN 0x00080000 + + + + +#define DCX_USESTYLE 0x00010000 + + +WINBOOL PAINT_RedrawWindow( HWND hwnd, const RECT *rectUpdate, + HRGN hrgnUpdate, UINT flags, UINT control ); diff --git a/reactos/include/user32/win.h b/reactos/include/user32/win.h index a76c050adab..41c7f9e5c82 100644 --- a/reactos/include/user32/win.h +++ b/reactos/include/user32/win.h @@ -73,7 +73,7 @@ typedef struct tagWND HINSTANCE hInstance; /* Window hInstance (from CreateWindow) */ RECT rectClient; /* Client area rel. to parent client area */ RECT rectWindow; /* Whole window rel. to parent client area */ - LPWSTR text; /* Window text */ + void *text; /* Window text */ void *pVScroll; /* Vertical scroll-bar info */ void *pHScroll; /* Horizontal scroll-bar info */ void *pProp; /* Pointer to properties list */ @@ -197,7 +197,8 @@ typedef struct /* Window functions */ HANDLE WIN_CreateWindowEx( CREATESTRUCTW *cs, ATOM atomName ); -WND* WIN_FindWndPtr( HWND hwnd ); +#define WIN_FindWndPtr(hwnd) (WND *)hwnd +//WND* WIN_FindWndPtr( HWND hwnd ); WND* WIN_GetDesktop(void); void WIN_DumpWindow( HWND hwnd ); void WIN_WalkWindows( HWND hwnd, int indent ); diff --git a/reactos/include/user32/winpos.h b/reactos/include/user32/winpos.h index c21484ca8a3..5d17cd7ec18 100644 --- a/reactos/include/user32/winpos.h +++ b/reactos/include/user32/winpos.h @@ -81,4 +81,13 @@ LPINTERNALPOS WINPOS_InitInternalPos( WND* wnd, POINT pt, LPRECT restoreRect ); WINBOOL WINPOS_SetPlacement( HWND hwnd, const WINDOWPLACEMENT *wndpl, UINT flags ); + +void WINPOS_MoveWindowZOrder( HWND hwnd, HWND hwndAfter ); + +UINT WINPOS_SizeMoveClean( WND* Wnd, HRGN oldVisRgn, + LPRECT lpOldWndRect, + LPRECT lpOldClientRect, UINT uFlags ); + +HWND WINPOS_ReorderOwnedPopups(HWND hwndInsertAfter,WND* wndPtr,WORD flags); + #endif /* __WINE_WINPOS_H */ diff --git a/reactos/lib/user32/graphics/draw.c b/reactos/lib/user32/graphics/draw.c index 8f03acaa964..d6f73a4ceb2 100644 --- a/reactos/lib/user32/graphics/draw.c +++ b/reactos/lib/user32/graphics/draw.c @@ -1,8 +1,15 @@ #include +#include WINBOOL STDCALL DrawEdge( HDC hdc, LPRECT rc, UINT edge, UINT flags ) { + DPRINT("graphics %04x %d,%d-%d,%d %04x %04x\n", + hdc, rc->left, rc->top, rc->right, rc->bottom, edge, flags ); + if(flags & BF_DIAGONAL) + return UITOOLS95_DrawDiagEdge(hdc, rc, edge, flags); + else + return UITOOLS95_DrawRectEdge(hdc, rc, edge, flags); } WINBOOL DrawIcon(HDC hDC, int xLeft, int yTop, HICON hIcon ) diff --git a/reactos/lib/user32/graphics/icon.c b/reactos/lib/user32/graphics/icon.c new file mode 100644 index 00000000000..bcb303cfc86 --- /dev/null +++ b/reactos/lib/user32/graphics/icon.c @@ -0,0 +1,66 @@ + +#include + + + +HICON +STDCALL +CreateIcon( + HINSTANCE hInstance, + int nWidth, + int nHeight, + BYTE cPlanes, + BYTE cBitsPixel, + CONST BYTE *lpbANDbits, + CONST BYTE *lpbXORbits) +{ +#if 0 + + ICONINFO IconInfo; + IconInfo.fIcon = TRUE; + IconInfo.hbmMask = NULL; + IconInfo.hbmColor = NULL; + return CreateIconIndirect( &IconInfo ); +#endif +} + +HICON +STDCALL +CreateIconIndirect( + PICONINFO piconinfo) +{ +} + + +HICON +STDCALL +CopyIcon( + HICON hIcon) +{ +} + + +WINBOOL +STDCALL +GetIconInfo( + HICON hIcon, + PICONINFO piconinfo) +{ +} + + + + +HICON LoadIconA(HINSTANCE hInstance,LPCSTR lpIconName ) +{ + return CreateIcon(hInstance, GetSystemMetrics(SM_CXSMICON), + GetSystemMetrics(SM_CYSMICON), + 0,0,NULL,NULL); +} + +HICON LoadIconW(HINSTANCE hInstance,LPCWSTR lpIconName ) +{ + return CreateIcon(hInstance, GetSystemMetrics(SM_CXSMICON), + GetSystemMetrics(SM_CYSMICON), + 0,0,NULL,NULL); +} \ No newline at end of file diff --git a/reactos/lib/user32/graphics/syscol.c b/reactos/lib/user32/graphics/syscol.c index 0a1b6ec0c87..feced1cabea 100644 --- a/reactos/lib/user32/graphics/syscol.c +++ b/reactos/lib/user32/graphics/syscol.c @@ -9,18 +9,91 @@ #include //#include +#include + void SYSCOLOR_SetColor( int index, COLORREF color ); +void SYSCOLOR_Init(void); + +static const char * const DefSysColors[] = +{ + "Scrollbar", "224 224 224", /* COLOR_SCROLLBAR */ + "Background", "192 192 192", /* COLOR_BACKGROUND */ + "ActiveTitle", "0 64 128", /* COLOR_ACTIVECAPTION */ + "InactiveTitle", "255 255 255", /* COLOR_INACTIVECAPTION */ + "Menu", "255 255 255", /* COLOR_MENU */ + "Window", "255 255 255", /* COLOR_WINDOW */ + "WindowFrame", "0 0 0", /* COLOR_WINDOWFRAME */ + "MenuText", "0 0 0", /* COLOR_MENUTEXT */ + "WindowText", "0 0 0", /* COLOR_WINDOWTEXT */ + "TitleText", "255 255 255", /* COLOR_CAPTIONTEXT */ + "ActiveBorder", "128 128 128", /* COLOR_ACTIVEBORDER */ + "InactiveBorder", "255 255 255", /* COLOR_INACTIVEBORDER */ + "AppWorkspace", "255 255 232", /* COLOR_APPWORKSPACE */ + "Hilight", "224 224 224", /* COLOR_HIGHLIGHT */ + "HilightText", "0 0 0", /* COLOR_HIGHLIGHTTEXT */ + "ButtonFace", "192 192 192", /* COLOR_BTNFACE */ + "ButtonShadow", "128 128 128", /* COLOR_BTNSHADOW */ + "GrayText", "192 192 192", /* COLOR_GRAYTEXT */ + "ButtonText", "0 0 0", /* COLOR_BTNTEXT */ + "InactiveTitleText", "0 0 0", /* COLOR_INACTIVECAPTIONTEXT */ + "ButtonHilight", "255 255 255", /* COLOR_BTNHIGHLIGHT */ + "3DDarkShadow", "32 32 32", /* COLOR_3DDKSHADOW */ + "3DLight", "192 192 192", /* COLOR_3DLIGHT */ + "InfoText", "0 0 0", /* COLOR_INFOTEXT */ + "InfoBackground", "255 255 192", /* COLOR_INFOBK */ + "AlternateButtonFace", "184 180 184", /* COLOR_ALTERNATEBTNFACE */ + "HotTrackingColor", "0 0 255", /* COLOR_HOTLIGHT */ + "GradientActiveTitle", "16 132 208", /* COLOR_GRADIENTACTIVECAPTION */ + "GradientInactiveTitle", "184 180 184" /* COLOR_GRADIENTINACTIVECAPTION */ +}; + +static const char * const DefSysColors95[] = +{ + "Scrollbar", "223 223 223", /* COLOR_SCROLLBAR */ + "Background", "192 192 192", /* COLOR_BACKGROUND */ + "ActiveTitle", "0 0 128", /* COLOR_ACTIVECAPTION */ + "InactiveTitle", "128 128 128", /* COLOR_INACTIVECAPTION */ + "Menu", "192 192 192", /* COLOR_MENU */ + "Window", "255 255 255", /* COLOR_WINDOW */ + "WindowFrame", "0 0 0", /* COLOR_WINDOWFRAME */ + "MenuText", "0 0 0", /* COLOR_MENUTEXT */ + "WindowText", "0 0 0", /* COLOR_WINDOWTEXT */ + "TitleText", "255 255 255", /* COLOR_CAPTIONTEXT */ + "ActiveBorder", "192 192 192", /* COLOR_ACTIVEBORDER */ + "InactiveBorder", "192 192 192", /* COLOR_INACTIVEBORDER */ + "AppWorkspace", "128 128 128", /* COLOR_APPWORKSPACE */ + "Hilight", "0 0 128", /* COLOR_HIGHLIGHT */ + "HilightText", "255 255 255", /* COLOR_HIGHLIGHTTEXT */ + "ButtonFace", "192 192 192", /* COLOR_BTNFACE */ + "ButtonShadow", "128 128 128", /* COLOR_BTNSHADOW */ + "GrayText", "192 192 192", /* COLOR_GRAYTEXT */ + "ButtonText", "0 0 0", /* COLOR_BTNTEXT */ + "InactiveTitleText", "0 0 0", /* COLOR_INACTIVECAPTIONTEXT */ + "ButtonHilight", "255 255 255", /* COLOR_BTNHIGHLIGHT */ + "3DDarkShadow", "0 0 0", /* COLOR_3DDKSHADOW */ + "3DLight", "223 223 223", /* COLOR_3DLIGHT */ + "InfoText", "0 0 0", /* COLOR_INFOTEXT */ + "InfoBackground", "255 255 192", /* COLOR_INFOBK */ + "AlternateButtonFace", "184 180 184", /* COLOR_ALTERNATEBTNFACE */ + "HotTrackingColor", "0 0 255", /* COLOR_HOTLIGHT */ + "GradientActiveTitle", "16 132 208", /* COLOR_GRADIENTACTIVECAPTION */ + "GradientInactiveTitle", "184 180 184" /* COLOR_GRADIENTINACTIVECAPTION */ +}; //#define NUM_SYS_COLORS (COLOR_GRADIENTINACTIVECAPTION+1) -#define NUM_SYS_COLORS 100 +#define NUM_SYS_COLORS 29 static COLORREF SysColors[NUM_SYS_COLORS]; static HBRUSH SysColorBrushes[NUM_SYS_COLORS]; static HPEN SysColorPens[NUM_SYS_COLORS]; +static char bSysColorInit = FALSE; + DWORD STDCALL GetSysColor( INT nIndex ) { + if ( bSysColorInit == FALSE ) + SYSCOLOR_Init(); if (nIndex >= 0 && nIndex < NUM_SYS_COLORS) return SysColors[nIndex]; else @@ -29,7 +102,6 @@ DWORD STDCALL GetSysColor( INT nIndex ) - /************************************************************************* * SetSysColors (USER.505) */ @@ -38,6 +110,8 @@ WINBOOL STDCALL SetSysColors( INT nChanges, const INT *lpSysColor, { int i; + if ( bSysColorInit == FALSE ) + SYSCOLOR_Init(); for (i = 0; i < nChanges; i++) { SYSCOLOR_SetColor( lpSysColor[i], lpColorValues[i] ); @@ -57,6 +131,8 @@ WINBOOL STDCALL SetSysColors( INT nChanges, const INT *lpSysColor, HBRUSH STDCALL GetSysColorBrush( INT index ) { + if ( bSysColorInit == FALSE ) + SYSCOLOR_Init(); if (0 <= index && index < NUM_SYS_COLORS) return SysColorBrushes[index]; @@ -66,6 +142,44 @@ HBRUSH STDCALL GetSysColorBrush( INT index ) ///////////////////////////////////////////////////////////////////////////////////// +/*********************************************************************** + * GetSysColorPen (Not a Windows API) + * + * This function is new to the Wine lib -- it does not exist in + * Windows. However, it is a natural complement for GetSysColorBrush + * in the Win API and is needed quite a bit inside Wine. + */ +HPEN STDCALL GetSysColorPen( INT index ) +{ + /* We can assert here, because this function is internal to Wine */ + //assert (0 <= index && index < NUM_SYS_COLORS); + if ( bSysColorInit == FALSE ) + SYSCOLOR_Init(); + return SysColorPens[index]; + +} + + +/************************************************************************* + * SYSCOLOR_Init + */ + +void SYSCOLOR_Init(void) +{ + int i, r, g, b; + const char * const *p; + char buffer[100]; + + p = (TWEAK_WineLook == WIN31_LOOK) ? DefSysColors : DefSysColors95; + for (i = 0; i < NUM_SYS_COLORS; i++, p += 2) + { +// GetProfileString32A( "colors", p[0], p[1], buffer, 100 ); + if (sscanf( p[1], " %d %d %d", &r, &g, &b ) != 3) r = g = b = 0; + SYSCOLOR_SetColor( i, RGB(r,g,b) ); + } + bSysColorInit = TRUE; +} + void SYSCOLOR_SetColor( int index, COLORREF color ) { if (index < 0 || index >= NUM_SYS_COLORS) return; @@ -78,18 +192,4 @@ void SYSCOLOR_SetColor( int index, COLORREF color ) -/*********************************************************************** - * GetSysColorPen (Not a Windows API) - * - * This function is new to the Wine lib -- it does not exist in - * Windows. However, it is a natural complement for GetSysColorBrush - * in the Win API and is needed quite a bit inside Wine. - */ -HPEN STDCALL GetSysColorPen( INT index ) -{ - /* We can assert here, because this function is internal to Wine */ - //assert (0 <= index && index < NUM_SYS_COLORS); - return SysColorPens[index]; - -} diff --git a/reactos/lib/user32/graphics/text.c b/reactos/lib/user32/graphics/text.c index 8a9670a52b2..6f8b18e1cb5 100644 --- a/reactos/lib/user32/graphics/text.c +++ b/reactos/lib/user32/graphics/text.c @@ -10,7 +10,7 @@ DrawTextA( DRAWTEXTPARAMS dtp; dtp.cbSize = sizeof(DRAWTEXTPARAMS); dtp.iTabLength = 0; - //return TEXT_DrawTextEx(hDC,(void *)lpString, nCount,lpRect,uFormat, &dtp, FALSE); + return TEXT_DrawTextEx(hDC,(void *)lpString, nCount,lpRect,uFormat, &dtp, FALSE); } diff --git a/reactos/lib/user32/internal/dialog.c b/reactos/lib/user32/internal/dialog.c new file mode 100644 index 00000000000..8fdef993926 --- /dev/null +++ b/reactos/lib/user32/internal/dialog.c @@ -0,0 +1,905 @@ +/* + * Dialog functions + * + * Copyright 1993, 1994, 1996 Alexandre Julliard + */ + +#include +#include +#include +#include +#include +#include "windows.h" +#include "dialog.h" +#include "drive.h" +#include "heap.h" +#include "win.h" +#include "ldt.h" +#include "user.h" +#include "winproc.h" +#include "message.h" +#include "sysmetrics.h" +#include "debug.h" + + + /* Dialog control information */ +typedef struct +{ + DWORD style; + DWORD exStyle; + DWORD helpId; + INT16 x; + INT16 y; + INT16 cx; + INT16 cy; + UINT32 id; + LPCSTR className; + LPCSTR windowName; + LPVOID data; +} DLG_CONTROL_INFO; + + /* Dialog template */ +typedef struct +{ + DWORD style; + DWORD exStyle; + DWORD helpId; + UINT16 nbItems; + INT16 x; + INT16 y; + INT16 cx; + INT16 cy; + LPCSTR menuName; + LPCSTR className; + LPCSTR caption; + WORD pointSize; + WORD weight; + WINBOOL italic; + LPCSTR faceName; + WINBOOL dialogEx; +} DLG_TEMPLATE; + + /* Dialog base units */ +static WORD xBaseUnit = 0, yBaseUnit = 0; + + +/*********************************************************************** + * DIALOG_Init + * + * Initialisation of the dialog manager. + */ +WINBOOL DIALOG_Init(void) +{ + TEXTMETRIC16 tm; + HDC16 hdc; + + /* Calculate the dialog base units */ + + if (!(hdc = CreateDC16( "DISPLAY", NULL, NULL, NULL ))) return FALSE; + GetTextMetrics16( hdc, &tm ); + DeleteDC32( hdc ); + xBaseUnit = tm.tmAveCharWidth; + yBaseUnit = tm.tmHeight; + + /* Dialog units are based on a proportional system font */ + /* so we adjust them a bit for a fixed font. */ + if (!(tm.tmPitchAndFamily & TMPF_FIXED_PITCH)) + xBaseUnit = xBaseUnit * 5 / 4; + + TRACE(dialog, "base units = %d,%d\n", + xBaseUnit, yBaseUnit ); + return TRUE; +} + + +/*********************************************************************** + * DIALOG_GetControl16 + * + * Return the class and text of the control pointed to by ptr, + * fill the header structure and return a pointer to the next control. + */ +static LPCSTR DIALOG_GetControl16( LPCSTR p, DLG_CONTROL_INFO *info ) +{ + static char buffer[10]; + int int_id; + + info->x = GET_WORD(p); p += sizeof(WORD); + info->y = GET_WORD(p); p += sizeof(WORD); + info->cx = GET_WORD(p); p += sizeof(WORD); + info->cy = GET_WORD(p); p += sizeof(WORD); + info->id = GET_WORD(p); p += sizeof(WORD); + info->style = GET_DWORD(p); p += sizeof(DWORD); + info->exStyle = 0; + + if (*p & 0x80) + { + switch((BYTE)*p) + { + case 0x80: strcpy( buffer, "BUTTON" ); break; + case 0x81: strcpy( buffer, "EDIT" ); break; + case 0x82: strcpy( buffer, "STATIC" ); break; + case 0x83: strcpy( buffer, "LISTBOX" ); break; + case 0x84: strcpy( buffer, "SCROLLBAR" ); break; + case 0x85: strcpy( buffer, "COMBOBOX" ); break; + default: buffer[0] = '\0'; break; + } + info->className = buffer; + p++; + } + else + { + info->className = p; + p += strlen(p) + 1; + } + + int_id = ((BYTE)*p == 0xff); + if (int_id) + { + /* Integer id, not documented (?). Only works for SS_ICON controls */ + info->windowName = (LPCSTR)(UINT32)GET_WORD(p+1); + p += 3; + } + else + { + info->windowName = p; + p += strlen(p) + 1; + } + + info->data = (LPVOID)(*p ? p + 1 : NULL); /* FIXME: should be a segptr */ + p += *p + 1; + + if(int_id) + TRACE(dialog," %s %04x %d, %d, %d, %d, %d, %08lx, %08lx\n", + info->className, LOWORD(info->windowName), + info->id, info->x, info->y, info->cx, info->cy, + info->style, (DWORD)info->data); + else + TRACE(dialog," %s '%s' %d, %d, %d, %d, %d, %08lx, %08lx\n", + info->className, info->windowName, + info->id, info->x, info->y, info->cx, info->cy, + info->style, (DWORD)info->data); + + return p; +} + + +/*********************************************************************** + * DIALOG_GetControl32 + * + * Return the class and text of the control pointed to by ptr, + * fill the header structure and return a pointer to the next control. + */ +static const WORD *DIALOG_GetControl32( const WORD *p, DLG_CONTROL_INFO *info, + WINBOOL dialogEx ) +{ + if (dialogEx) + { + info->helpId = GET_DWORD(p); p += 2; + info->exStyle = GET_DWORD(p); p += 2; + info->style = GET_DWORD(p); p += 2; + } + else + { + info->helpId = 0; + info->style = GET_DWORD(p); p += 2; + info->exStyle = GET_DWORD(p); p += 2; + } + info->x = GET_WORD(p); p++; + info->y = GET_WORD(p); p++; + info->cx = GET_WORD(p); p++; + info->cy = GET_WORD(p); p++; + + if (dialogEx) + { + /* id is a DWORD for DIALOGEX */ + info->id = GET_DWORD(p); + p += 2; + } + else + { + info->id = GET_WORD(p); + p++; + } + + if (GET_WORD(p) == 0xffff) + { + static const WCHAR class_names[6][10] = + { + { 'B','u','t','t','o','n', }, /* 0x80 */ + { 'E','d','i','t', }, /* 0x81 */ + { 'S','t','a','t','i','c', }, /* 0x82 */ + { 'L','i','s','t','B','o','x', }, /* 0x83 */ + { 'S','c','r','o','l','l','B','a','r', }, /* 0x84 */ + { 'C','o','m','b','o','B','o','x', } /* 0x85 */ + }; + WORD id = GET_WORD(p+1); + if ((id >= 0x80) && (id <= 0x85)) + info->className = (LPCSTR)class_names[id - 0x80]; + else + { + info->className = NULL; + ERR( dialog, "Unknown built-in class id %04x\n", id ); + } + p += 2; + } + else + { + info->className = (LPCSTR)p; + p += lstrlen32W( (LPCWSTR)p ) + 1; + } + + if (GET_WORD(p) == 0xffff) /* Is it an integer id? */ + { + info->windowName = (LPCSTR)(UINT32)GET_WORD(p + 1); + p += 2; + } + else + { + info->windowName = (LPCSTR)p; + p += lstrlen32W( (LPCWSTR)p ) + 1; + } + + TRACE(dialog," %s %s %d, %d, %d, %d, %d, %08lx, %08lx, %08lx\n", + debugstr_w( (LPCWSTR)info->className ), + debugres_w( (LPCWSTR)info->windowName ), + info->id, info->x, info->y, info->cx, info->cy, + info->style, info->exStyle, info->helpId ); + + if (GET_WORD(p)) + { + if (TRACE_ON(dialog)) + { + WORD i, count = GET_WORD(p) / sizeof(WORD); + TRACE(dialog, " BEGIN\n"); + TRACE(dialog, " "); + for (i = 0; i < count; i++) DUMP( "%04x,", GET_WORD(p+i+1) ); + DUMP("\n"); + TRACE(dialog, " END\n" ); + } + info->data = (LPVOID)(p + 1); + p += GET_WORD(p) / sizeof(WORD); + } + else info->data = NULL; + p++; + + /* Next control is on dword boundary */ + return (const WORD *)((((int)p) + 3) & ~3); +} + + +/*********************************************************************** + * DIALOG_CreateControls + * + * Create the control windows for a dialog. + */ +static WINBOOL DIALOG_CreateControls( WND *pWnd, LPCSTR template, + const DLG_TEMPLATE *dlgTemplate, + HINSTANCE32 hInst, WINBOOL win32 ) +{ + DIALOGINFO *dlgInfo = (DIALOGINFO *)pWnd->wExtra; + DLG_CONTROL_INFO info; + HWND32 hwndCtrl, hwndDefButton = 0; + INT32 items = dlgTemplate->nbItems; + + TRACE(dialog, " BEGIN\n" ); + while (items--) + { + if (!win32) + { + HINSTANCE16 instance; + template = DIALOG_GetControl16( template, &info ); + if (HIWORD(info.className) && !strcmp( info.className, "EDIT") && + ((pWnd->dwStyle & DS_LOCALEDIT) != DS_LOCALEDIT)) + { + if (!dlgInfo->hDialogHeap) + { + dlgInfo->hDialogHeap = GlobalAlloc16(GMEM_FIXED, 0x10000); + if (!dlgInfo->hDialogHeap) + { + ERR(dialog, "Insufficient memory to create heap for edit control\n" ); + continue; + } + LocalInit(dlgInfo->hDialogHeap, 0, 0xffff); + } + instance = dlgInfo->hDialogHeap; + } + else instance = (HINSTANCE16)hInst; + + hwndCtrl = CreateWindowEx16( info.exStyle | WS_EX_NOPARENTNOTIFY, + info.className, info.windowName, + info.style | WS_CHILD, + info.x * dlgInfo->xBaseUnit / 4, + info.y * dlgInfo->yBaseUnit / 8, + info.cx * dlgInfo->xBaseUnit / 4, + info.cy * dlgInfo->yBaseUnit / 8, + pWnd->hwndSelf, (HMENU16)info.id, + instance, info.data ); + } + else + { + template = (LPCSTR)DIALOG_GetControl32( (WORD *)template, &info, + dlgTemplate->dialogEx ); + hwndCtrl = CreateWindowEx32W( info.exStyle | WS_EX_NOPARENTNOTIFY, + (LPCWSTR)info.className, + (LPCWSTR)info.windowName, + info.style | WS_CHILD, + info.x * dlgInfo->xBaseUnit / 4, + info.y * dlgInfo->yBaseUnit / 8, + info.cx * dlgInfo->xBaseUnit / 4, + info.cy * dlgInfo->yBaseUnit / 8, + pWnd->hwndSelf, (HMENU32)info.id, + hInst, info.data ); + } + if (!hwndCtrl) return FALSE; + + /* Send initialisation messages to the control */ + if (dlgInfo->hUserFont) SendMessage32A( hwndCtrl, WM_SETFONT, + (WPARAM32)dlgInfo->hUserFont, 0 ); + if (SendMessage32A(hwndCtrl, WM_GETDLGCODE, 0, 0) & DLGC_DEFPUSHBUTTON) + { + /* If there's already a default push-button, set it back */ + /* to normal and use this one instead. */ + if (hwndDefButton) + SendMessage32A( hwndDefButton, BM_SETSTYLE32, + BS_PUSHBUTTON,FALSE ); + hwndDefButton = hwndCtrl; + dlgInfo->idResult = GetWindowWord32( hwndCtrl, GWW_ID ); + } + } + TRACE(dialog, " END\n" ); + return TRUE; +} + + +/*********************************************************************** + * DIALOG_ParseTemplate16 + * + * Fill a DLG_TEMPLATE structure from the dialog template, and return + * a pointer to the first control. + */ +static LPCSTR DIALOG_ParseTemplate16( LPCSTR p, DLG_TEMPLATE * result ) +{ + result->style = GET_DWORD(p); p += sizeof(DWORD); + result->exStyle = 0; + result->nbItems = *p++; + result->x = GET_WORD(p); p += sizeof(WORD); + result->y = GET_WORD(p); p += sizeof(WORD); + result->cx = GET_WORD(p); p += sizeof(WORD); + result->cy = GET_WORD(p); p += sizeof(WORD); + TRACE(dialog, "DIALOG %d, %d, %d, %d\n", + result->x, result->y, result->cx, result->cy ); + TRACE(dialog, " STYLE %08lx\n", result->style ); + + /* Get the menu name */ + + switch( (BYTE)*p ) + { + case 0: + result->menuName = 0; + p++; + break; + case 0xff: + result->menuName = (LPCSTR)(UINT32)GET_WORD( p + 1 ); + p += 3; + TRACE(dialog, " MENU %04x\n", LOWORD(result->menuName) ); + break; + default: + result->menuName = p; + TRACE(dialog, " MENU '%s'\n", p ); + p += strlen(p) + 1; + break; + } + + /* Get the class name */ + + if (*p) + { + result->className = p; + TRACE(dialog, " CLASS '%s'\n", result->className ); + } + else result->className = DIALOG_CLASS_ATOM; + p += strlen(p) + 1; + + /* Get the window caption */ + + result->caption = p; + p += strlen(p) + 1; + TRACE(dialog, " CAPTION '%s'\n", result->caption ); + + /* Get the font name */ + + if (result->style & DS_SETFONT) + { + result->pointSize = GET_WORD(p); + p += sizeof(WORD); + result->faceName = p; + p += strlen(p) + 1; + TRACE(dialog, " FONT %d,'%s'\n", + result->pointSize, result->faceName ); + } + return p; +} + + +/*********************************************************************** + * DIALOG_ParseTemplate32 + * + * Fill a DLG_TEMPLATE structure from the dialog template, and return + * a pointer to the first control. + */ +static LPCSTR DIALOG_ParseTemplate32( LPCSTR template, DLG_TEMPLATE * result ) +{ + const WORD *p = (const WORD *)template; + + result->style = GET_DWORD(p); p += 2; + if (result->style == 0xffff0001) /* DIALOGEX resource */ + { + result->dialogEx = TRUE; + result->helpId = GET_DWORD(p); p += 2; + result->exStyle = GET_DWORD(p); p += 2; + result->style = GET_DWORD(p); p += 2; + } + else + { + result->dialogEx = FALSE; + result->helpId = 0; + result->exStyle = GET_DWORD(p); p += 2; + } + result->nbItems = GET_WORD(p); p++; + result->x = GET_WORD(p); p++; + result->y = GET_WORD(p); p++; + result->cx = GET_WORD(p); p++; + result->cy = GET_WORD(p); p++; + TRACE( dialog, "DIALOG%s %d, %d, %d, %d, %ld\n", + result->dialogEx ? "EX" : "", result->x, result->y, + result->cx, result->cy, result->helpId ); + TRACE( dialog, " STYLE 0x%08lx\n", result->style ); + TRACE( dialog, " EXSTYLE 0x%08lx\n", result->exStyle ); + + /* Get the menu name */ + + switch(GET_WORD(p)) + { + case 0x0000: + result->menuName = NULL; + p++; + break; + case 0xffff: + result->menuName = (LPCSTR)(UINT32)GET_WORD( p + 1 ); + p += 2; + TRACE(dialog, " MENU %04x\n", LOWORD(result->menuName) ); + break; + default: + result->menuName = (LPCSTR)p; + TRACE(dialog, " MENU %s\n", debugstr_w( (LPCWSTR)p )); + p += lstrlen32W( (LPCWSTR)p ) + 1; + break; + } + + /* Get the class name */ + + switch(GET_WORD(p)) + { + case 0x0000: + result->className = DIALOG_CLASS_ATOM; + p++; + break; + case 0xffff: + result->className = (LPCSTR)(UINT32)GET_WORD( p + 1 ); + p += 2; + TRACE(dialog, " CLASS %04x\n", LOWORD(result->className) ); + break; + default: + result->className = (LPCSTR)p; + TRACE(dialog, " CLASS %s\n", debugstr_w( (LPCWSTR)p )); + p += lstrlen32W( (LPCWSTR)p ) + 1; + break; + } + + /* Get the window caption */ + + result->caption = (LPCSTR)p; + p += lstrlen32W( (LPCWSTR)p ) + 1; + TRACE(dialog, " CAPTION %s\n", debugstr_w( (LPCWSTR)result->caption ) ); + + /* Get the font name */ + + if (result->style & DS_SETFONT) + { + result->pointSize = GET_WORD(p); + p++; + if (result->dialogEx) + { + result->weight = GET_WORD(p); p++; + result->italic = LOBYTE(GET_WORD(p)); p++; + } + else + { + result->weight = FW_DONTCARE; + result->italic = FALSE; + } + result->faceName = (LPCSTR)p; + p += lstrlen32W( (LPCWSTR)p ) + 1; + TRACE(dialog, " FONT %d, %s, %d, %s\n", + result->pointSize, debugstr_w( (LPCWSTR)result->faceName ), + result->weight, result->italic ? "TRUE" : "FALSE" ); + } + + /* First control is on dword boundary */ + return (LPCSTR)((((int)p) + 3) & ~3); +} + + +/*********************************************************************** + * DIALOG_CreateIndirect + */ +HWND32 DIALOG_CreateIndirect( HINSTANCE32 hInst, LPCSTR dlgTemplate, + WINBOOL win32Template, HWND32 owner, + DLGPROC16 dlgProc, LPARAM param, + WINDOWPROCTYPE procType ) +{ + HMENU16 hMenu = 0; + HFONT16 hFont = 0; + HWND32 hwnd; + RECT32 rect; + WND * wndPtr; + DLG_TEMPLATE template; + DIALOGINFO * dlgInfo; + WORD xUnit = xBaseUnit; + WORD yUnit = yBaseUnit; + + /* Parse dialog template */ + + if (!dlgTemplate) return 0; + if (win32Template) + dlgTemplate = DIALOG_ParseTemplate32( dlgTemplate, &template ); + else + dlgTemplate = DIALOG_ParseTemplate16( dlgTemplate, &template ); + + /* Load menu */ + + if (template.menuName) + { + if (!win32Template) + { + LPSTR str = SEGPTR_STRDUP( template.menuName ); + hMenu = LoadMenu16( hInst, SEGPTR_GET(str) ); + SEGPTR_FREE( str ); + } + else hMenu = LoadMenu32W( hInst, (LPCWSTR)template.menuName ); + } + + /* Create custom font if needed */ + + if (template.style & DS_SETFONT) + { + /* The font height must be negative as it is a point size */ + /* (see CreateFont() documentation in the Windows SDK). */ + + if (win32Template) + hFont = CreateFont32W( -template.pointSize, 0, 0, 0, + template.weight, template.italic, FALSE, + FALSE, DEFAULT_CHARSET, 0, 0, PROOF_QUALITY, + FF_DONTCARE, (LPCWSTR)template.faceName ); + else + hFont = CreateFont16( -template.pointSize, 0, 0, 0, FW_DONTCARE, + FALSE, FALSE, FALSE, DEFAULT_CHARSET, 0, 0, + PROOF_QUALITY, FF_DONTCARE, + template.faceName ); + if (hFont) + { + TEXTMETRIC16 tm; + HFONT16 oldFont; + + HDC32 hdc = GetDC32(0); + oldFont = SelectObject32( hdc, hFont ); + GetTextMetrics16( hdc, &tm ); + SelectObject32( hdc, oldFont ); + ReleaseDC32( 0, hdc ); + xUnit = tm.tmAveCharWidth; + yUnit = tm.tmHeight; + if (!(tm.tmPitchAndFamily & TMPF_FIXED_PITCH)) + xBaseUnit = xBaseUnit * 5 / 4; /* See DIALOG_Init() */ + } + } + + /* Create dialog main window */ + + rect.left = rect.top = 0; + rect.right = template.cx * xUnit / 4; + rect.bottom = template.cy * yUnit / 8; + if (template.style & DS_MODALFRAME) + template.exStyle |= WS_EX_DLGMODALFRAME; + AdjustWindowRectEx32( &rect, template.style, + hMenu ? TRUE : FALSE , template.exStyle ); + rect.right -= rect.left; + rect.bottom -= rect.top; + + if ((INT16)template.x == CW_USEDEFAULT16) + { + rect.left = rect.top = (procType == WIN_PROC_16) ? CW_USEDEFAULT16 + : CW_USEDEFAULT32; + } + else + { + if (template.style & DS_CENTER) + { + rect.left = (SYSMETRICS_CXSCREEN - rect.right) / 2; + rect.top = (SYSMETRICS_CYSCREEN - rect.bottom) / 2; + } + else + { + rect.left += template.x * xUnit / 4; + rect.top += template.y * yUnit / 8; + } + if ( !(template.style & WS_CHILD) ) + { + INT16 dX, dY; + + if( !(template.style & DS_ABSALIGN) ) + ClientToScreen32( owner, (POINT32 *)&rect ); + + /* try to fit it into the desktop */ + + if( (dX = rect.left + rect.right + SYSMETRICS_CXDLGFRAME + - SYSMETRICS_CXSCREEN) > 0 ) rect.left -= dX; + if( (dY = rect.top + rect.bottom + SYSMETRICS_CYDLGFRAME + - SYSMETRICS_CYSCREEN) > 0 ) rect.top -= dY; + if( rect.left < 0 ) rect.left = 0; + if( rect.top < 0 ) rect.top = 0; + } + } + + if (procType == WIN_PROC_16) + hwnd = CreateWindowEx16(template.exStyle, template.className, + template.caption, template.style & ~WS_VISIBLE, + rect.left, rect.top, rect.right, rect.bottom, + owner, hMenu, hInst, NULL ); + else + hwnd = CreateWindowEx32W(template.exStyle, (LPCWSTR)template.className, + (LPCWSTR)template.caption, + template.style & ~WS_VISIBLE, + rect.left, rect.top, rect.right, rect.bottom, + owner, hMenu, hInst, NULL ); + + if (!hwnd) + { + if (hFont) DeleteObject32( hFont ); + if (hMenu) DestroyMenu32( hMenu ); + return 0; + } + wndPtr = WIN_FindWndPtr( hwnd ); + wndPtr->flags |= WIN_ISDIALOG; + wndPtr->helpContext = template.helpId; + + /* Initialise dialog extra data */ + + dlgInfo = (DIALOGINFO *)wndPtr->wExtra; + WINPROC_SetProc( &dlgInfo->dlgProc, dlgProc, procType, WIN_PROC_WINDOW ); + dlgInfo->hUserFont = hFont; + dlgInfo->hMenu = hMenu; + dlgInfo->xBaseUnit = xUnit; + dlgInfo->yBaseUnit = yUnit; + dlgInfo->msgResult = 0; + dlgInfo->idResult = 0; + dlgInfo->flags = 0; + dlgInfo->hDialogHeap = 0; + + if (dlgInfo->hUserFont) + SendMessage32A( hwnd, WM_SETFONT, (WPARAM32)dlgInfo->hUserFont, 0 ); + + /* Create controls */ + + if (DIALOG_CreateControls( wndPtr, dlgTemplate, &template, + hInst, win32Template )) + { + /* Send initialisation messages and set focus */ + + dlgInfo->hwndFocus = GetNextDlgTabItem32( hwnd, 0, FALSE ); + + if (SendMessage32A( hwnd, WM_INITDIALOG, (WPARAM32)dlgInfo->hwndFocus, param )) + SetFocus32( dlgInfo->hwndFocus ); + + if (template.style & WS_VISIBLE && !(wndPtr->dwStyle & WS_VISIBLE)) + { + ShowWindow32( hwnd, SW_SHOWNORMAL ); /* SW_SHOW doesn't always work */ + UpdateWindow32( hwnd ); + } + return hwnd; + } + + if( IsWindow32(hwnd) ) DestroyWindow32( hwnd ); + return 0; +} + + + +/********************************************************************** + * DIALOG_DlgDirSelect + * + * Helper function for DlgDirSelect* + */ +static WINBOOL DIALOG_DlgDirSelect( HWND32 hwnd, LPSTR str, INT32 len, + INT32 id, WINBOOL win32, WINBOOL unicode, + WINBOOL combo ) +{ + char *buffer, *ptr; + INT32 item, size; + WINBOOL ret; + HWND32 listbox = GetDlgItem32( hwnd, id ); + + TRACE(dialog, "%04x '%s' %d\n", hwnd, str, id ); + if (!listbox) return FALSE; + if (win32) + { + item = SendMessage32A(listbox, combo ? CB_GETCURSEL32 + : LB_GETCURSEL32, 0, 0 ); + if (item == LB_ERR) return FALSE; + size = SendMessage32A(listbox, combo ? CB_GETLBTEXTLEN32 + : LB_GETTEXTLEN32, 0, 0 ); + if (size == LB_ERR) return FALSE; + } + else + { + item = SendMessage32A(listbox, combo ? CB_GETCURSEL16 + : LB_GETCURSEL16, 0, 0 ); + if (item == LB_ERR) return FALSE; + size = SendMessage32A(listbox, combo ? CB_GETLBTEXTLEN16 + : LB_GETTEXTLEN16, 0, 0 ); + if (size == LB_ERR) return FALSE; + } + + if (!(buffer = SEGPTR_ALLOC( size+1 ))) return FALSE; + + if (win32) + SendMessage32A( listbox, combo ? CB_GETLBTEXT32 : LB_GETTEXT32, + item, (LPARAM)buffer ); + else + SendMessage16( listbox, combo ? CB_GETLBTEXT16 : LB_GETTEXT16, + item, (LPARAM)SEGPTR_GET(buffer) ); + + if ((ret = (buffer[0] == '['))) /* drive or directory */ + { + if (buffer[1] == '-') /* drive */ + { + buffer[3] = ':'; + buffer[4] = 0; + ptr = buffer + 2; + } + else + { + buffer[strlen(buffer)-1] = '\\'; + ptr = buffer + 1; + } + } + else ptr = buffer; + + if (unicode) lstrcpynAtoW( (LPWSTR)str, ptr, len ); + else lstrcpyn32A( str, ptr, len ); + SEGPTR_FREE( buffer ); + TRACE(dialog, "Returning %d '%s'\n", ret, str ); + return ret; +} + + +/********************************************************************** + * DIALOG_DlgDirList + * + * Helper function for DlgDirList* + */ +static INT32 DIALOG_DlgDirList( HWND32 hDlg, LPSTR spec, INT32 idLBox, + INT32 idStatic, UINT32 attrib, WINBOOL combo ) +{ + int drive; + HWND32 hwnd; + LPSTR orig_spec = spec; + +#define SENDMSG(msg,wparam,lparam) \ + ((attrib & DDL_POSTMSGS) ? PostMessage32A( hwnd, msg, wparam, lparam ) \ + : SendMessage32A( hwnd, msg, wparam, lparam )) + + TRACE(dialog, "%04x '%s' %d %d %04x\n", + hDlg, spec ? spec : "NULL", idLBox, idStatic, attrib ); + + if (spec && spec[0] && (spec[1] == ':')) + { + drive = toupper( spec[0] ) - 'A'; + spec += 2; + if (!DRIVE_SetCurrentDrive( drive )) return FALSE; + } + else drive = DRIVE_GetCurrentDrive(); + + /* If the path exists and is a directory, chdir to it */ + if (!spec || !spec[0] || DRIVE_Chdir( drive, spec )) spec = "*.*"; + else + { + char *p, *p2; + p = spec; + if ((p2 = strrchr( p, '\\' ))) p = p2; + if ((p2 = strrchr( p, '/' ))) p = p2; + if (p != spec) + { + char sep = *p; + *p = 0; + if (!DRIVE_Chdir( drive, spec )) + { + *p = sep; /* Restore the original spec */ + return FALSE; + } + spec = p + 1; + } + } + + TRACE(dialog, "path=%c:\\%s mask=%s\n", + 'A' + drive, DRIVE_GetDosCwd(drive), spec ); + + if (idLBox && ((hwnd = GetDlgItem32( hDlg, idLBox )) != 0)) + { + SENDMSG( combo ? CB_RESETCONTENT32 : LB_RESETCONTENT32, 0, 0 ); + if (attrib & DDL_DIRECTORY) + { + if (!(attrib & DDL_EXCLUSIVE)) + { + if (SENDMSG( combo ? CB_DIR32 : LB_DIR32, + attrib & ~(DDL_DIRECTORY | DDL_DRIVES), + (LPARAM)spec ) == LB_ERR) + return FALSE; + } + if (SENDMSG( combo ? CB_DIR32 : LB_DIR32, + (attrib & (DDL_DIRECTORY | DDL_DRIVES)) | DDL_EXCLUSIVE, + (LPARAM)"*.*" ) == LB_ERR) + return FALSE; + } + else + { + if (SENDMSG( combo ? CB_DIR32 : LB_DIR32, attrib, + (LPARAM)spec ) == LB_ERR) + return FALSE; + } + } + + if (idStatic && ((hwnd = GetDlgItem32( hDlg, idStatic )) != 0)) + { + char temp[512]; + int drive = DRIVE_GetCurrentDrive(); + strcpy( temp, "A:\\" ); + temp[0] += drive; + lstrcpyn32A( temp + 3, DRIVE_GetDosCwd(drive), sizeof(temp)-3 ); + CharLower32A( temp ); + /* Can't use PostMessage() here, because the string is on the stack */ + SetDlgItemText32A( hDlg, idStatic, temp ); + } + + if (orig_spec && (spec != orig_spec)) + { + /* Update the original file spec */ + char *p = spec; + while ((*orig_spec++ = *p++)); + } + + return TRUE; +#undef SENDMSG +} + + +/********************************************************************** + * DIALOG_DlgDirListW + * + * Helper function for DlgDirList*32W + */ +static INT32 DIALOG_DlgDirListW( HWND32 hDlg, LPWSTR spec, INT32 idLBox, + INT32 idStatic, UINT32 attrib, WINBOOL combo ) +{ + if (spec) + { + LPSTR specA = HEAP_strdupWtoA( GetProcessHeap(), 0, spec ); + INT32 ret = DIALOG_DlgDirList( hDlg, specA, idLBox, idStatic, + attrib, combo ); + lstrcpyAtoW( spec, specA ); + HeapFree( GetProcessHeap(), 0, specA ); + return ret; + } + return DIALOG_DlgDirList( hDlg, NULL, idLBox, idStatic, attrib, combo ); +} + + diff --git a/reactos/lib/user32/internal/menu.c b/reactos/lib/user32/internal/menu.c index 1b8d6418fd4..8c6c51c87e9 100644 --- a/reactos/lib/user32/internal/menu.c +++ b/reactos/lib/user32/internal/menu.c @@ -1093,16 +1093,16 @@ UINT MENU_DrawMenuBar( HDC hDC, LPRECT lprect, HWND hwnd, FillRect(hDC, lprect, GetSysColorBrush(COLOR_MENU) ); -// if (TWEAK_WineLook == WIN31_LOOK) { + if (TWEAK_WineLook == WIN31_LOOK) { SelectObject( hDC,(HGDIOBJ)GetSysColorPen(COLOR_WINDOWFRAME) ); MoveToEx( hDC, lprect->left, lprect->bottom,NULL ); LineTo( hDC, lprect->right, lprect->bottom ); -// } -// else { -// SelectObject( hDC,(HGDIOBJ) GetSysColorPen(COLOR_3DFACE)); -// MoveToEx( hDC, lprect->left, lprect->bottom,NULL ); -// LineTo( hDC, lprect->right, lprect->bottom ); -// } + } + else { + SelectObject( hDC,(HGDIOBJ) GetSysColorPen(COLOR_3DFACE)); + MoveToEx( hDC, lprect->left, lprect->bottom,NULL ); + LineTo( hDC, lprect->right, lprect->bottom ); + } if (lppop->nItems == 0) return SYSMETRICS_CYMENU; for (i = 0; i < lppop->nItems; i++) diff --git a/reactos/lib/user32/internal/nc.c b/reactos/lib/user32/internal/nc.c index 50bf59cbf90..25bda936cd6 100644 --- a/reactos/lib/user32/internal/nc.c +++ b/reactos/lib/user32/internal/nc.c @@ -142,6 +142,20 @@ NC_AdjustRectOuter95 (LPRECT rect, DWORD style, WINBOOL menu, DWORD exStyle) #endif } + if ((style & WS_CAPTION) == WS_CAPTION) + { + if (exStyle & WS_EX_TOOLWINDOW) + rect->top -= SYSMETRICS_CYSMCAPTION; + else + rect->top -= SYSMETRICS_CYCAPTION; + } + } else { + + + if (style & WS_BORDER) + InflateRect( rect, SYSMETRICS_CXBORDER, SYSMETRICS_CYBORDER); + + if ((style & WS_CAPTION) == WS_CAPTION) { if (exStyle & WS_EX_TOOLWINDOW) @@ -1174,7 +1188,8 @@ static void NC_DrawCaption95( MoveToEx( hdc, r.left, r.bottom - 1, NULL ); LineTo( hdc, r.right, r.bottom - 1 ); SelectObject( hdc, hPrevPen ); - r.bottom--; + r.bottom-2; + FillRect( hdc, &r, GetSysColorBrush(active ? COLOR_ACTIVECAPTION : COLOR_INACTIVECAPTION) ); diff --git a/reactos/lib/user32/internal/queue.c b/reactos/lib/user32/internal/queue.c index 9893531db8a..a3b60afce4a 100644 --- a/reactos/lib/user32/internal/queue.c +++ b/reactos/lib/user32/internal/queue.c @@ -93,7 +93,8 @@ void QUEUE_WalkQueues(void) */ WINBOOL QUEUE_IsExitingQueue( HQUEUE hQueue ) { - return (hExitingQueue && (hQueue == hExitingQueue)); + return FALSE; +// return (hExitingQueue && (hQueue == hExitingQueue)); } diff --git a/reactos/lib/user32/internal/uitools.c b/reactos/lib/user32/internal/uitools.c new file mode 100644 index 00000000000..ef53f5eed2d --- /dev/null +++ b/reactos/lib/user32/internal/uitools.c @@ -0,0 +1,1330 @@ +/* + * User Interface Functions + * + * Copyright 1997 Dimitrie O. Paun + * Copyright 1997 Bertho A. Stultiens + */ + +#include +#include + +HPEN STDCALL GetSysColorPen( INT index ); + +static const WORD wPattern_AA55[8] = { 0xaaaa, 0x5555, 0xaaaa, 0x5555, + 0xaaaa, 0x5555, 0xaaaa, 0x5555 }; + +/* These tables are used in: + * UITOOLS_DrawDiagEdge() + * UITOOLS_DrawRectEdge() + */ + +/* DrawEdge() flags */ +#define BDR_RAISEDOUTER 0x0001 +#define BDR_SUNKENOUTER 0x0002 +#define BDR_RAISEDINNER 0x0004 +#define BDR_SUNKENINNER 0x0008 + +#define BDR_OUTER 0x0003 +#define BDR_INNER 0x000c +#define BDR_RAISED 0x0005 +#define BDR_SUNKEN 0x000a + +static const char LTInnerNormal[] = { + -1, -1, -1, -1, + -1, COLOR_BTNHIGHLIGHT, COLOR_BTNHIGHLIGHT, -1, + -1, COLOR_3DDKSHADOW, COLOR_3DDKSHADOW, -1, + -1, -1, -1, -1 +}; + +static const char LTOuterNormal[] = { + -1, COLOR_3DLIGHT, COLOR_BTNSHADOW, -1, + COLOR_BTNHIGHLIGHT, COLOR_3DLIGHT, COLOR_BTNSHADOW, -1, + COLOR_3DDKSHADOW, COLOR_3DLIGHT, COLOR_BTNSHADOW, -1, + -1, COLOR_3DLIGHT, COLOR_BTNSHADOW, -1 +}; + +static const char RBInnerNormal[] = { + -1, -1, -1, -1, + -1, COLOR_BTNSHADOW, COLOR_BTNSHADOW, -1, + -1, COLOR_3DLIGHT, COLOR_3DLIGHT, -1, + -1, -1, -1, -1 +}; + +static const char RBOuterNormal[] = { + -1, COLOR_3DDKSHADOW, COLOR_BTNHIGHLIGHT, -1, + COLOR_BTNSHADOW, COLOR_3DDKSHADOW, COLOR_BTNHIGHLIGHT, -1, + COLOR_3DLIGHT, COLOR_3DDKSHADOW, COLOR_BTNHIGHLIGHT, -1, + -1, COLOR_3DDKSHADOW, COLOR_BTNHIGHLIGHT, -1 +}; + +static const char LTInnerSoft[] = { + -1, -1, -1, -1, + -1, COLOR_3DLIGHT, COLOR_3DLIGHT, -1, + -1, COLOR_BTNSHADOW, COLOR_BTNSHADOW, -1, + -1, -1, -1, -1 +}; + +static const char LTOuterSoft[] = { + -1, COLOR_BTNHIGHLIGHT, COLOR_3DDKSHADOW, -1, + COLOR_3DLIGHT, COLOR_BTNHIGHLIGHT, COLOR_3DDKSHADOW, -1, + COLOR_BTNSHADOW, COLOR_BTNHIGHLIGHT, COLOR_3DDKSHADOW, -1, + -1, COLOR_BTNHIGHLIGHT, COLOR_3DDKSHADOW, -1 +}; + +#define RBInnerSoft RBInnerNormal /* These are the same */ +#define RBOuterSoft RBOuterNormal + +static const char LTRBOuterMono[] = { + -1, COLOR_WINDOWFRAME, COLOR_WINDOWFRAME, COLOR_WINDOWFRAME, + COLOR_WINDOW, COLOR_WINDOWFRAME, COLOR_WINDOWFRAME, COLOR_WINDOWFRAME, + COLOR_WINDOW, COLOR_WINDOWFRAME, COLOR_WINDOWFRAME, COLOR_WINDOWFRAME, + COLOR_WINDOW, COLOR_WINDOWFRAME, COLOR_WINDOWFRAME, COLOR_WINDOWFRAME, +}; + +static const char LTRBInnerMono[] = { + -1, -1, -1, -1, + -1, COLOR_WINDOW, COLOR_WINDOW, COLOR_WINDOW, + -1, COLOR_WINDOW, COLOR_WINDOW, COLOR_WINDOW, + -1, COLOR_WINDOW, COLOR_WINDOW, COLOR_WINDOW, +}; + +static const char LTRBOuterFlat[] = { + -1, COLOR_BTNSHADOW, COLOR_BTNSHADOW, COLOR_BTNSHADOW, + COLOR_WINDOWFRAME, COLOR_BTNSHADOW, COLOR_BTNSHADOW, COLOR_BTNSHADOW, + COLOR_WINDOWFRAME, COLOR_BTNSHADOW, COLOR_BTNSHADOW, COLOR_BTNSHADOW, + COLOR_WINDOWFRAME, COLOR_BTNSHADOW, COLOR_BTNSHADOW, COLOR_BTNSHADOW, +}; + +static const char LTRBInnerFlat[] = { + -1, -1, -1, -1, + -1, COLOR_WINDOWFRAME, COLOR_WINDOWFRAME, COLOR_WINDOWFRAME, + -1, COLOR_WINDOWFRAME, COLOR_WINDOWFRAME, COLOR_WINDOWFRAME, + -1, COLOR_WINDOWFRAME, COLOR_WINDOWFRAME, COLOR_WINDOWFRAME, +}; + +/*********************************************************************** + * UITOOLS_DrawDiagEdge + * + * Same as DrawEdge invoked with BF_DIAGONAL + * + * 03-Dec-1997: Changed by Bertho Stultiens + * + * See also comments with UITOOLS_DrawRectEdge() + */ +WINBOOL UITOOLS95_DrawDiagEdge(HDC hdc, LPRECT rc, + UINT uType, UINT uFlags) +{ + POINT Points[4]; + char InnerI, OuterI; + HPEN InnerPen, OuterPen; + POINT SavePoint; + HPEN SavePen; + int spx, spy; + int epx, epy; + int Width = rc->right - rc->left; + int Height= rc->bottom - rc->top; + int SmallDiam = Width > Height ? Height : Width; + WINBOOL retval = !( ((uType & BDR_INNER) == BDR_INNER + || (uType & BDR_OUTER) == BDR_OUTER) + && !(uFlags & (BF_FLAT|BF_MONO)) ); + int add = (LTRBInnerMono[uType & (BDR_INNER|BDR_OUTER)] != -1 ? 1 : 0) + + (LTRBOuterMono[uType & (BDR_INNER|BDR_OUTER)] != -1 ? 1 : 0); + + /* Init some vars */ + OuterPen = InnerPen = (HPEN)GetStockObject(NULL_PEN); + SavePen = (HPEN)SelectObject(hdc, InnerPen); + spx = spy = epx = epy = 0; /* Satisfy the compiler... */ + + /* Determine the colors of the edges */ + if(uFlags & BF_MONO) + { + InnerI = LTRBInnerMono[uType & (BDR_INNER|BDR_OUTER)]; + OuterI = LTRBOuterMono[uType & (BDR_INNER|BDR_OUTER)]; + } + else if(uFlags & BF_FLAT) + { + InnerI = LTRBInnerFlat[uType & (BDR_INNER|BDR_OUTER)]; + OuterI = LTRBOuterFlat[uType & (BDR_INNER|BDR_OUTER)]; + } + else if(uFlags & BF_SOFT) + { + if(uFlags & BF_BOTTOM) + { + InnerI = RBInnerSoft[uType & (BDR_INNER|BDR_OUTER)]; + OuterI = RBOuterSoft[uType & (BDR_INNER|BDR_OUTER)]; + } + else + { + InnerI = LTInnerSoft[uType & (BDR_INNER|BDR_OUTER)]; + OuterI = LTOuterSoft[uType & (BDR_INNER|BDR_OUTER)]; + } + } + else + { + if(uFlags & BF_BOTTOM) + { + InnerI = RBInnerNormal[uType & (BDR_INNER|BDR_OUTER)]; + OuterI = RBOuterNormal[uType & (BDR_INNER|BDR_OUTER)]; + } + else + { + InnerI = LTInnerNormal[uType & (BDR_INNER|BDR_OUTER)]; + OuterI = LTOuterNormal[uType & (BDR_INNER|BDR_OUTER)]; + } + } + + if(InnerI != -1) InnerPen = GetSysColorPen(InnerI); + if(OuterI != -1) OuterPen = GetSysColorPen(OuterI); + + MoveToEx(hdc, 0, 0, &SavePoint); + + /* Don't ask me why, but this is what is visible... */ + /* This must be possible to do much simpler, but I fail to */ + /* see the logic in the MS implementation (sigh...). */ + /* So, this might look a bit brute force here (and it is), but */ + /* it gets the job done;) */ + + switch(uFlags & BF_RECT) + { + case 0: + case BF_LEFT: + case BF_BOTTOM: + case BF_BOTTOMLEFT: + /* Left bottom endpoint */ + epx = rc->left-1; + spx = epx + SmallDiam; + epy = rc->bottom; + spy = epy - SmallDiam; + break; + + case BF_TOPLEFT: + case BF_BOTTOMRIGHT: + /* Left top endpoint */ + epx = rc->left-1; + spx = epx + SmallDiam; + epy = rc->top-1; + spy = epy + SmallDiam; + break; + + case BF_TOP: + case BF_RIGHT: + case BF_TOPRIGHT: + case BF_RIGHT|BF_LEFT: + case BF_RIGHT|BF_LEFT|BF_TOP: + case BF_BOTTOM|BF_TOP: + case BF_BOTTOM|BF_TOP|BF_LEFT: + case BF_BOTTOMRIGHT|BF_LEFT: + case BF_BOTTOMRIGHT|BF_TOP: + case BF_RECT: + /* Right top endpoint */ + spx = rc->left; + epx = spx + SmallDiam; + spy = rc->bottom-1; + epy = spy - SmallDiam; + break; + } + + MoveToEx(hdc, spx, spy, NULL); + SelectObject(hdc, OuterPen); + LineTo(hdc, epx, epy); + + SelectObject(hdc, InnerPen); + + switch(uFlags & (BF_RECT|BF_DIAGONAL)) + { + case BF_DIAGONAL_ENDBOTTOMLEFT: + case (BF_DIAGONAL|BF_BOTTOM): + case BF_DIAGONAL: + case (BF_DIAGONAL|BF_LEFT): + MoveToEx(hdc, spx-1, spy, NULL); + LineTo(hdc, epx, epy-1); + Points[0].x = spx-add; + Points[0].y = spy; + Points[1].x = rc->left; + Points[1].y = rc->top; + Points[2].x = epx+1; + Points[2].y = epy-1-add; + Points[3] = Points[2]; + break; + + case BF_DIAGONAL_ENDBOTTOMRIGHT: + MoveToEx(hdc, spx-1, spy, NULL); + LineTo(hdc, epx, epy+1); + Points[0].x = spx-add; + Points[0].y = spy; + Points[1].x = rc->left; + Points[1].y = rc->bottom-1; + Points[2].x = epx+1; + Points[2].y = epy+1+add; + Points[3] = Points[2]; + break; + + case (BF_DIAGONAL|BF_BOTTOM|BF_RIGHT|BF_TOP): + case (BF_DIAGONAL|BF_BOTTOM|BF_RIGHT|BF_TOP|BF_LEFT): + case BF_DIAGONAL_ENDTOPRIGHT: + case (BF_DIAGONAL|BF_RIGHT|BF_TOP|BF_LEFT): + MoveToEx(hdc, spx+1, spy, NULL); + LineTo(hdc, epx, epy+1); + Points[0].x = epx-1; + Points[0].y = epy+1+add; + Points[1].x = rc->right-1; + Points[1].y = rc->top+add; + Points[2].x = rc->right-1; + Points[2].y = rc->bottom-1; + Points[3].x = spx+add; + Points[3].y = spy; + break; + + case BF_DIAGONAL_ENDTOPLEFT: + MoveToEx(hdc, spx, spy-1, NULL); + LineTo(hdc, epx+1, epy); + Points[0].x = epx+1+add; + Points[0].y = epy+1; + Points[1].x = rc->right-1; + Points[1].y = rc->top; + Points[2].x = rc->right-1; + Points[2].y = rc->bottom-1-add; + Points[3].x = spx; + Points[3].y = spy-add; + break; + + case (BF_DIAGONAL|BF_TOP): + case (BF_DIAGONAL|BF_BOTTOM|BF_TOP): + case (BF_DIAGONAL|BF_BOTTOM|BF_TOP|BF_LEFT): + MoveToEx(hdc, spx+1, spy-1, NULL); + LineTo(hdc, epx, epy); + Points[0].x = epx-1; + Points[0].y = epy+1; + Points[1].x = rc->right-1; + Points[1].y = rc->top; + Points[2].x = rc->right-1; + Points[2].y = rc->bottom-1-add; + Points[3].x = spx+add; + Points[3].y = spy-add; + break; + + case (BF_DIAGONAL|BF_RIGHT): + case (BF_DIAGONAL|BF_RIGHT|BF_LEFT): + case (BF_DIAGONAL|BF_RIGHT|BF_LEFT|BF_BOTTOM): + MoveToEx(hdc, spx, spy, NULL); + LineTo(hdc, epx-1, epy+1); + Points[0].x = spx; + Points[0].y = spy; + Points[1].x = rc->left; + Points[1].y = rc->top+add; + Points[2].x = epx-1-add; + Points[2].y = epy+1+add; + Points[3] = Points[2]; + break; + } + + /* Fill the interior if asked */ + if((uFlags & BF_MIDDLE) && retval) + { + HBRUSH hbsave; + HBRUSH hb = GetSysColorBrush(uFlags & BF_MONO ? COLOR_WINDOW + :COLOR_BTNFACE); + HPEN hpsave; + HPEN hp = GetSysColorPen(uFlags & BF_MONO ? COLOR_WINDOW + : COLOR_BTNFACE); + hbsave = (HBRUSH)SelectObject(hdc, hb); + hpsave = (HPEN)SelectObject(hdc, hp); + Polygon(hdc, Points, 4); + SelectObject(hdc, hbsave); + SelectObject(hdc, hpsave); + } + + /* Adjust rectangle if asked */ + if(uFlags & BF_ADJUST) + { + if(uFlags & BF_LEFT) rc->left += add; + if(uFlags & BF_RIGHT) rc->right -= add; + if(uFlags & BF_TOP) rc->top += add; + if(uFlags & BF_BOTTOM) rc->bottom -= add; + } + + /* Cleanup */ + SelectObject(hdc, SavePen); + MoveToEx(hdc, SavePoint.x, SavePoint.y, NULL); + + return retval; +} + +/*********************************************************************** + * UITOOLS_DrawRectEdge + * + * Same as DrawEdge invoked without BF_DIAGONAL + * + * 23-Nov-1997: Changed by Bertho Stultiens + * + * Well, I started testing this and found out that there are a few things + * that weren't quite as win95. The following rewrite should reproduce + * win95 results completely. + * The colorselection is table-driven to avoid awfull if-statements. + * The table below show the color settings. + * + * Pen selection table for uFlags = 0 + * + * uType | LTI | LTO | RBI | RBO + * ------+-------+-------+-------+------- + * 0000 | x | x | x | x + * 0001 | x | 22 | x | 21 + * 0010 | x | 16 | x | 20 + * 0011 | x | x | x | x + * ------+-------+-------+-------+------- + * 0100 | x | 20 | x | 16 + * 0101 | 20 | 22 | 16 | 21 + * 0110 | 20 | 16 | 16 | 20 + * 0111 | x | x | x | x + * ------+-------+-------+-------+------- + * 1000 | x | 21 | x | 22 + * 1001 | 21 | 22 | 22 | 21 + * 1010 | 21 | 16 | 22 | 20 + * 1011 | x | x | x | x + * ------+-------+-------+-------+------- + * 1100 | x | x | x | x + * 1101 | x | x (22)| x | x (21) + * 1110 | x | x (16)| x | x (20) + * 1111 | x | x | x | x + * + * Pen selection table for uFlags = BF_SOFT + * + * uType | LTI | LTO | RBI | RBO + * ------+-------+-------+-------+------- + * 0000 | x | x | x | x + * 0001 | x | 20 | x | 21 + * 0010 | x | 21 | x | 20 + * 0011 | x | x | x | x + * ------+-------+-------+-------+------- + * 0100 | x | 22 | x | 16 + * 0101 | 22 | 20 | 16 | 21 + * 0110 | 22 | 21 | 16 | 20 + * 0111 | x | x | x | x + * ------+-------+-------+-------+------- + * 1000 | x | 16 | x | 22 + * 1001 | 16 | 20 | 22 | 21 + * 1010 | 16 | 21 | 22 | 20 + * 1011 | x | x | x | x + * ------+-------+-------+-------+------- + * 1100 | x | x | x | x + * 1101 | x | x (20)| x | x (21) + * 1110 | x | x (21)| x | x (20) + * 1111 | x | x | x | x + * + * x = don't care; (n) = is what win95 actually uses + * LTI = left Top Inner line + * LTO = left Top Outer line + * RBI = Right Bottom Inner line + * RBO = Right Bottom Outer line + * 15 = COLOR_BTNFACE + * 16 = COLOR_BTNSHADOW + * 20 = COLOR_BTNHIGHLIGHT + * 21 = COLOR_3DDKSHADOW + * 22 = COLOR_3DLIGHT + */ + + +WINBOOL UITOOLS95_DrawRectEdge(HDC hdc, LPRECT rc, + UINT uType, UINT uFlags) +{ + char LTInnerI, LTOuterI; + char RBInnerI, RBOuterI; + HPEN LTInnerPen, LTOuterPen; + HPEN RBInnerPen, RBOuterPen; + RECT InnerRect = *rc; + POINT SavePoint; + HPEN SavePen; + int LBpenplus = 0; + int LTpenplus = 0; + int RTpenplus = 0; + int RBpenplus = 0; + WINBOOL retval = !( ((uType & BDR_INNER) == BDR_INNER + || (uType & BDR_OUTER) == BDR_OUTER) + && !(uFlags & (BF_FLAT|BF_MONO)) ); + + /* Init some vars */ + LTInnerPen = LTOuterPen = RBInnerPen = RBOuterPen = (HPEN)GetStockObject(NULL_PEN); + SavePen = (HPEN)SelectObject(hdc, LTInnerPen); + + /* Determine the colors of the edges */ + if(uFlags & BF_MONO) + { + LTInnerI = RBInnerI = LTRBInnerMono[uType & (BDR_INNER|BDR_OUTER)]; + LTOuterI = RBOuterI = LTRBOuterMono[uType & (BDR_INNER|BDR_OUTER)]; + } + else if(uFlags & BF_FLAT) + { + LTInnerI = RBInnerI = LTRBInnerFlat[uType & (BDR_INNER|BDR_OUTER)]; + LTOuterI = RBOuterI = LTRBOuterFlat[uType & (BDR_INNER|BDR_OUTER)]; + } + else if(uFlags & BF_SOFT) + { + LTInnerI = LTInnerSoft[uType & (BDR_INNER|BDR_OUTER)]; + LTOuterI = LTOuterSoft[uType & (BDR_INNER|BDR_OUTER)]; + RBInnerI = RBInnerSoft[uType & (BDR_INNER|BDR_OUTER)]; + RBOuterI = RBOuterSoft[uType & (BDR_INNER|BDR_OUTER)]; + } + else + { + LTInnerI = LTInnerNormal[uType & (BDR_INNER|BDR_OUTER)]; + LTOuterI = LTOuterNormal[uType & (BDR_INNER|BDR_OUTER)]; + RBInnerI = RBInnerNormal[uType & (BDR_INNER|BDR_OUTER)]; + RBOuterI = RBOuterNormal[uType & (BDR_INNER|BDR_OUTER)]; + } + + if((uFlags & BF_BOTTOMLEFT) == BF_BOTTOMLEFT) LBpenplus = 1; + if((uFlags & BF_TOPRIGHT) == BF_TOPRIGHT) RTpenplus = 1; + if((uFlags & BF_BOTTOMRIGHT) == BF_BOTTOMRIGHT) RBpenplus = 1; + if((uFlags & BF_TOPLEFT) == BF_TOPLEFT) LTpenplus = 1; + + if(LTInnerI != -1) LTInnerPen = GetSysColorPen(LTInnerI); + if(LTOuterI != -1) LTOuterPen = GetSysColorPen(LTOuterI); + if(RBInnerI != -1) RBInnerPen = GetSysColorPen(RBInnerI); + if(RBOuterI != -1) RBOuterPen = GetSysColorPen(RBOuterI); + + if((uFlags & BF_MIDDLE) && retval) + { + FillRect(hdc, &InnerRect, GetSysColorBrush(uFlags & BF_MONO ? + COLOR_WINDOW : COLOR_BTNFACE)); + } + + MoveToEx(hdc, 0, 0, &SavePoint); + + /* Draw the outer edge */ + SelectObject(hdc, LTOuterPen); + if(uFlags & BF_TOP) + { + MoveToEx(hdc, InnerRect.left, InnerRect.top, NULL); + LineTo(hdc, InnerRect.right, InnerRect.top); + } + if(uFlags & BF_LEFT) + { + MoveToEx(hdc, InnerRect.left, InnerRect.top, NULL); + LineTo(hdc, InnerRect.left, InnerRect.bottom); + } + SelectObject(hdc, RBOuterPen); + if(uFlags & BF_BOTTOM) + { + MoveToEx(hdc, InnerRect.right-1, InnerRect.bottom-1, NULL); + LineTo(hdc, InnerRect.left-1, InnerRect.bottom-1); + } + if(uFlags & BF_RIGHT) + { + MoveToEx(hdc, InnerRect.right-1, InnerRect.bottom-1, NULL); + LineTo(hdc, InnerRect.right-1, InnerRect.top-1); + } + + /* Draw the inner edge */ + SelectObject(hdc, LTInnerPen); + if(uFlags & BF_TOP) + { + MoveToEx(hdc, InnerRect.left+LTpenplus, InnerRect.top+1, NULL); + LineTo(hdc, InnerRect.right-RTpenplus, InnerRect.top+1); + } + if(uFlags & BF_LEFT) + { + MoveToEx(hdc, InnerRect.left+1, InnerRect.top+LTpenplus, NULL); + LineTo(hdc, InnerRect.left+1, InnerRect.bottom-LBpenplus); + } + SelectObject(hdc, RBInnerPen); + if(uFlags & BF_BOTTOM) + { + MoveToEx(hdc, InnerRect.right-1-RBpenplus, InnerRect.bottom-2, NULL); + LineTo(hdc, InnerRect.left-1+LBpenplus, InnerRect.bottom-2); + } + if(uFlags & BF_RIGHT) + { + MoveToEx(hdc, InnerRect.right-2, InnerRect.bottom-1-RBpenplus, NULL); + LineTo(hdc, InnerRect.right-2, InnerRect.top-1+RTpenplus); + } + + /* Adjust rectangle if asked */ + if(uFlags & BF_ADJUST) + { + int add = (LTRBInnerMono[uType & (BDR_INNER|BDR_OUTER)] != -1 ? 1 : 0) + + (LTRBOuterMono[uType & (BDR_INNER|BDR_OUTER)] != -1 ? 1 : 0); + if(uFlags & BF_LEFT) rc->left += add; + if(uFlags & BF_RIGHT) rc->right -= add; + if(uFlags & BF_TOP) rc->top += add; + if(uFlags & BF_BOTTOM) rc->bottom -= add; + } + + /* Cleanup */ + SelectObject(hdc, SavePen); + MoveToEx(hdc, SavePoint.x, SavePoint.y, NULL); + return retval; +} + +/************************************************************************ + * UITOOLS_MakeSquareRect + * + * Utility to create a square rectangle and returning the width + */ +int UITOOLS_MakeSquareRect(LPRECT src, LPRECT dst) +{ + int Width = src->right - src->left; + int Height = src->bottom - src->top; + int SmallDiam = Width > Height ? Height : Width; + + *dst = *src; + + /* Make it a square box */ + if(Width < Height) /* SmallDiam == Width */ + { + dst->top += (Height-Width)/2; + dst->bottom = dst->top + SmallDiam; + } + else if(Width > Height) /* SmallDiam == Height */ + { + dst->left += (Width-Height)/2; + dst->right = dst->left + SmallDiam; + } + + return SmallDiam; +} + + +/************************************************************************ + * UITOOLS_DFC_ButtonPush + * + * Draw a push button coming from DrawFrameControl() + * + * Does a pretty good job in emulating MS behavior. Some quirks are + * however there because MS uses a TrueType font (Marlett) to draw + * the buttons. + */ +WINBOOL UITOOLS95_DFC_ButtonPush(HDC dc, LPRECT r, UINT uFlags) +{ + UINT edge; + RECT myr = *r; + + if(uFlags & (DFCS_PUSHED | DFCS_CHECKED | DFCS_FLAT)) + edge = EDGE_SUNKEN; + else + edge = EDGE_RAISED; + + if(uFlags & DFCS_CHECKED) + { + if(uFlags & DFCS_MONO) + UITOOLS95_DrawRectEdge(dc, &myr, edge, BF_MONO|BF_RECT|BF_ADJUST); + else + UITOOLS95_DrawRectEdge(dc, &myr, edge, (uFlags&DFCS_FLAT)|BF_RECT|BF_SOFT|BF_ADJUST); + + if(GetSysColor(COLOR_BTNHIGHLIGHT) == RGB(255, 255, 255)) + { + HBITMAP hbm = CreateBitmap(8, 8, 1, 1, wPattern_AA55); + HBRUSH hbsave; + HBRUSH hb = CreatePatternBrush(hbm); + + FillRect(dc, &myr, GetSysColorBrush(COLOR_BTNFACE)); + hbsave = (HBRUSH)SelectObject(dc, hb); + PatBlt(dc, myr.left, myr.top, myr.right-myr.left, myr.bottom-myr.top, 0x00FA0089); + SelectObject(dc, hbsave); + DeleteObject(hb); + DeleteObject(hbm); + } + else + { + FillRect(dc, &myr, GetSysColorBrush(COLOR_BTNHIGHLIGHT)); + } + } + else + { + if(uFlags & DFCS_MONO) + { + UITOOLS95_DrawRectEdge(dc, &myr, edge, BF_MONO|BF_RECT|BF_ADJUST); + FillRect(dc, &myr, GetSysColorBrush(COLOR_BTNFACE)); + } + else + { + UITOOLS95_DrawRectEdge(dc, r, edge, (uFlags&DFCS_FLAT) | BF_MIDDLE |BF_SOFT| BF_RECT); + } + } + + /* Adjust rectangle if asked */ + if(uFlags & DFCS_ADJUSTRECT) + { + r->left += 2; + r->right -= 2; + r->top += 2; + r->bottom -= 2; + } + + return TRUE; +} + + +/************************************************************************ + * UITOOLS_DFC_ButtonChcek + * + * Draw a check/3state button coming from DrawFrameControl() + * + * Does a pretty good job in emulating MS behavior. Some quirks are + * however there because MS uses a TrueType font (Marlett) to draw + * the buttons. + */ +#define DFC_CHECKPOINTSMAX 6 + +WINBOOL UITOOLS95_DFC_ButtonCheck(HDC dc, LPRECT r, UINT uFlags) +{ + RECT myr; + int SmallDiam = UITOOLS_MakeSquareRect(r, &myr); + int BorderShrink = SmallDiam / 16; + + if(BorderShrink < 1) BorderShrink = 1; + + /* FIXME: The FillRect() sequence doesn't work for sizes less than */ + /* 4 pixels in diameter. Not really a problem but it isn't M$'s */ + /* 100% equivalent. */ + if(uFlags & (DFCS_FLAT|DFCS_MONO)) + { + FillRect(dc, &myr, GetSysColorBrush(COLOR_WINDOWFRAME)); + myr.left += 2 * BorderShrink; + myr.right -= 2 * BorderShrink; + myr.top += 2 * BorderShrink; + myr.bottom -= 2 * BorderShrink; + } + else + { + FillRect(dc, &myr, GetSysColorBrush(COLOR_BTNHIGHLIGHT)); + myr.right -= BorderShrink; + myr.bottom -= BorderShrink; + FillRect(dc, &myr, GetSysColorBrush(COLOR_BTNSHADOW)); + myr.left += BorderShrink; + myr.top += BorderShrink; + FillRect(dc, &myr, GetSysColorBrush(COLOR_3DLIGHT)); + myr.right -= BorderShrink; + myr.bottom -= BorderShrink; + FillRect(dc, &myr, GetSysColorBrush(COLOR_3DDKSHADOW)); + myr.left += BorderShrink; + myr.top += BorderShrink; + } + + if(uFlags & (DFCS_INACTIVE|DFCS_PUSHED)) + { + FillRect(dc, &myr, GetSysColorBrush(COLOR_BTNFACE)); + } + else if(uFlags & DFCS_CHECKED) + { + if(GetSysColor(COLOR_BTNHIGHLIGHT) == RGB(255, 255, 255)) + { + HBITMAP hbm = CreateBitmap(8, 8, 1, 1, wPattern_AA55); + HBRUSH hbsave; + HBRUSH hb = CreatePatternBrush(hbm); + + FillRect(dc, &myr, GetSysColorBrush(COLOR_BTNFACE)); + hbsave = (HBRUSH)SelectObject(dc, hb); + PatBlt(dc, myr.left, myr.top, myr.right-myr.left, myr.bottom-myr.top, 0x00FA0089); + SelectObject(dc, hbsave); + DeleteObject(hb); + DeleteObject(hbm); + } + else + { + FillRect(dc, &myr, GetSysColorBrush(COLOR_BTNHIGHLIGHT)); + } + } + else + { + FillRect(dc, &myr, GetSysColorBrush(COLOR_WINDOW)); + } + + if(uFlags & DFCS_CHECKED) + { + POINT CheckPoints[DFC_CHECKPOINTSMAX]; + int i; + HBRUSH hbsave; + HPEN hpsave; + + /* FIXME: This comes very close to M$'s checkmark, but not */ + /* exactly... When small or large there is a few pixels */ + /* shift. Not bad, but could be better :) */ + UITOOLS_MakeSquareRect(r, &myr); + CheckPoints[0].x = myr.left + 253*SmallDiam/1000; + CheckPoints[0].y = myr.top + 345*SmallDiam/1000; + CheckPoints[1].x = myr.left + 409*SmallDiam/1000; + CheckPoints[1].y = CheckPoints[0].y + (CheckPoints[1].x-CheckPoints[0].x); + CheckPoints[2].x = myr.left + 690*SmallDiam/1000; + CheckPoints[2].y = CheckPoints[1].y - (CheckPoints[2].x-CheckPoints[1].x); + CheckPoints[3].x = CheckPoints[2].x; + CheckPoints[3].y = CheckPoints[2].y + 3*SmallDiam/16; + CheckPoints[4].x = CheckPoints[1].x; + CheckPoints[4].y = CheckPoints[1].y + 3*SmallDiam/16; + CheckPoints[5].x = CheckPoints[0].x; + CheckPoints[5].y = CheckPoints[0].y + 3*SmallDiam/16; + + i = (uFlags & DFCS_INACTIVE) || (uFlags & 0xff) == DFCS_BUTTON3STATE ? COLOR_BTNSHADOW : COLOR_WINDOWTEXT; + hbsave = (HBRUSH)SelectObject(dc, GetSysColorBrush(i)); + hpsave = (HPEN)SelectObject(dc, GetSysColorPen(i)); + Polygon(dc, CheckPoints, DFC_CHECKPOINTSMAX); + SelectObject(dc, hpsave); + SelectObject(dc, hbsave); + } + return TRUE; +} + + +/************************************************************************ + * UITOOLS_DFC_ButtonRadio + * + * Draw a radio/radioimage/radiomask button coming from DrawFrameControl() + * + * Does a pretty good job in emulating MS behavior. Some quirks are + * however there because MS uses a TrueType font (Marlett) to draw + * the buttons. + */ +static WINBOOL UITOOLS95_DFC_ButtonRadio(HDC dc, LPRECT r, UINT uFlags) +{ + RECT myr; + int i; + int SmallDiam = UITOOLS_MakeSquareRect(r, &myr); + int BorderShrink = SmallDiam / 16; + HPEN hpsave; + HBRUSH hbsave; + int xe, ye; + int xc, yc; + + if(BorderShrink < 1) BorderShrink = 1; + + if((uFlags & 0xff) == DFCS_BUTTONRADIOIMAGE) + { + FillRect(dc, r, (HBRUSH)GetStockObject(BLACK_BRUSH)); + } + + xe = myr.left; + ye = myr.top + SmallDiam - SmallDiam/2; + + xc = myr.left + SmallDiam - SmallDiam/2; + yc = myr.top + SmallDiam - SmallDiam/2; + + /* Define bounding box */ + i = 14*SmallDiam/16; + myr.left = xc - i+i/2; + myr.right = xc + i/2; + myr.top = yc - i+i/2; + myr.bottom = yc + i/2; + + if((uFlags & 0xff) == DFCS_BUTTONRADIOMASK) + { + hbsave = (HBRUSH)SelectObject(dc, GetStockObject(BLACK_BRUSH)); + Pie(dc, myr.left, myr.top, myr.right, myr.bottom, xe, ye, xe, ye); + SelectObject(dc, hbsave); + } + else + { + if(uFlags & (DFCS_FLAT|DFCS_MONO)) + { + hpsave = (HPEN)SelectObject(dc, GetSysColorPen(COLOR_WINDOWFRAME)); + hbsave = (HBRUSH)SelectObject(dc, GetSysColorBrush(COLOR_WINDOWFRAME)); + Pie(dc, myr.left, myr.top, myr.right, myr.bottom, xe, ye, xe, ye); + SelectObject(dc, hbsave); + SelectObject(dc, hpsave); + } + else + { + hpsave = (HPEN)SelectObject(dc, GetSysColorPen(COLOR_BTNHIGHLIGHT)); + hbsave = (HBRUSH)SelectObject(dc, GetSysColorBrush(COLOR_BTNHIGHLIGHT)); + Pie(dc, myr.left, myr.top, myr.right, myr.bottom, myr.left-1, myr.bottom, myr.right-1, myr.top); + + SelectObject(dc, GetSysColorPen(COLOR_BTNSHADOW)); + SelectObject(dc, GetSysColorBrush(COLOR_BTNSHADOW)); + Pie(dc, myr.left, myr.top, myr.right, myr.bottom, myr.right+1, myr.top, myr.left+1, myr.bottom); + + myr.left += BorderShrink; + myr.right -= BorderShrink; + myr.top += BorderShrink; + myr.bottom -= BorderShrink; + + SelectObject(dc, GetSysColorPen(COLOR_3DLIGHT)); + SelectObject(dc, GetSysColorBrush(COLOR_3DLIGHT)); + Pie(dc, myr.left, myr.top, myr.right, myr.bottom, myr.left-1, myr.bottom, myr.right-1, myr.top); + + SelectObject(dc, GetSysColorPen(COLOR_3DDKSHADOW)); + SelectObject(dc, GetSysColorBrush(COLOR_3DDKSHADOW)); + Pie(dc, myr.left, myr.top, myr.right, myr.bottom, myr.right+1, myr.top, myr.left+1, myr.bottom); + SelectObject(dc, hbsave); + SelectObject(dc, hpsave); + } + + i = 10*SmallDiam/16; + myr.left = xc - i+i/2; + myr.right = xc + i/2; + myr.top = yc - i+i/2; + myr.bottom = yc + i/2; + i= !(uFlags & (DFCS_INACTIVE|DFCS_PUSHED)) ? COLOR_WINDOW : COLOR_BTNFACE; + hpsave = (HPEN)SelectObject(dc, GetSysColorPen(i)); + hbsave = (HBRUSH)SelectObject(dc, GetSysColorBrush(i)); + Pie(dc, myr.left, myr.top, myr.right, myr.bottom, xe, ye, xe, ye); + SelectObject(dc, hbsave); + SelectObject(dc, hpsave); + } + + if(uFlags & DFCS_CHECKED) + { + i = 6*SmallDiam/16; + i = i < 1 ? 1 : i; + myr.left = xc - i+i/2; + myr.right = xc + i/2; + myr.top = yc - i+i/2; + myr.bottom = yc + i/2; + + i = uFlags & DFCS_INACTIVE ? COLOR_BTNSHADOW : COLOR_WINDOWTEXT; + hbsave = (HBRUSH)SelectObject(dc, GetSysColorBrush(i)); + hpsave = (HPEN)SelectObject(dc, GetSysColorPen(i)); + Pie(dc, myr.left, myr.top, myr.right, myr.bottom, xe, ye, xe, ye); + SelectObject(dc, hpsave); + SelectObject(dc, hbsave); + } + + /* FIXME: M$ has a polygon in the center at relative points: */ + /* 0.476, 0.476 (times SmallDiam, SmallDiam) */ + /* 0.476, 0.525 */ + /* 0.500, 0.500 */ + /* 0.500, 0.499 */ + /* when the button is unchecked. The reason for it is unknown. The */ + /* color is COLOR_BTNHIGHLIGHT, although the polygon gets painted at */ + /* least 3 times (it looks like a clip-region when you see it happen). */ + /* I do not really see a reason why this should be implemented. If you */ + /* have a good reason, let me know. Maybe this is a quirk in the Marlett */ + /* font. */ + + return TRUE; +} + +/*********************************************************************** + * UITOOLS_DrawFrameButton + */ +static WINBOOL UITOOLS95_DrawFrameButton(HDC hdc, LPRECT rc, UINT uState) +{ + switch(uState & 0xff) + { + case DFCS_BUTTONPUSH: + return UITOOLS95_DFC_ButtonPush(hdc, rc, uState); + + case DFCS_BUTTONCHECK: + case DFCS_BUTTON3STATE: + return UITOOLS95_DFC_ButtonCheck(hdc, rc, uState); + + case DFCS_BUTTONRADIOIMAGE: + case DFCS_BUTTONRADIOMASK: + case DFCS_BUTTONRADIO: + return UITOOLS95_DFC_ButtonRadio(hdc, rc, uState); + + default: + DPRINT( "Invalid button state=0x%04x\n", uState); + } + + return FALSE; +} + +/*********************************************************************** + * UITOOLS_DrawFrameCaption + * + * Draw caption buttons (win95), coming from DrawFrameControl() + */ + +static WINBOOL UITOOLS95_DrawFrameCaption(HDC dc, LPRECT r, UINT uFlags) +{ + POINT Line1[10]; + POINT Line2[10]; + int Line1N; + int Line2N; + RECT myr; + int SmallDiam = UITOOLS_MakeSquareRect(r, &myr)-2; + int i; + HBRUSH hbsave; + HPEN hpsave; + HFONT hfsave, hf; + int xc = (myr.left+myr.right)/2; + int yc = (myr.top+myr.bottom)/2; + int edge, move; + char str[2] = "?"; + UINT alignsave; + int bksave; + COLORREF clrsave; + SIZE size; + + UITOOLS95_DFC_ButtonPush(dc, r, uFlags & 0xff00); + + switch(uFlags & 0xff) + { + case DFCS_CAPTIONCLOSE: + edge = 8*SmallDiam/1000; + move = 95*SmallDiam/1000; + Line1[0].x = Line2[0].x = Line1[1].x = Line2[1].x = xc - edge; + Line1[2].y = Line2[5].y = Line1[1].y = Line2[4].y = yc - edge; + Line1[3].x = Line2[3].x = Line1[4].x = Line2[4].x = xc + edge; + Line1[5].y = Line2[2].y = Line1[4].y = Line2[1].y = yc + edge; + Line1[2].x = Line2[2].x = Line1[1].x + move; + Line1[0].y = Line2[3].y = Line1[1].y + move; + Line1[5].x = Line2[5].x = Line1[4].x - move; + Line1[3].y = Line2[0].y = Line1[4].y - move; + Line1N = 6; + Line2N = 6; + break; + + case DFCS_CAPTIONHELP: + /* This one breaks the flow */ + /* FIXME: We need the Marlett font in order to get this right. */ + + hf = CreateFontA(-SmallDiam, 0, 0, 0, FW_NORMAL, FALSE, FALSE, FALSE, + ANSI_CHARSET, OUT_DEFAULT_PRECIS, CLIP_DEFAULT_PRECIS, + DEFAULT_QUALITY, FIXED_PITCH|FF_DONTCARE, "System"); + alignsave = SetTextAlign(dc, TA_TOP|TA_LEFT); + bksave = SetBkMode(dc, TRANSPARENT); + clrsave = GetTextColor(dc); + hfsave = (HFONT)SelectObject(dc, hf); + GetTextExtentPointA(dc, str, 1, &size); + + if(uFlags & DFCS_INACTIVE) + { + SetTextColor(dc, GetSysColor(COLOR_BTNHIGHLIGHT)); + TextOutA(dc, xc-size.cx/2+1, yc-size.cy/2+1, str, 1); + } + SetTextColor(dc, GetSysColor(uFlags & DFCS_INACTIVE ? COLOR_BTNSHADOW : COLOR_BTNTEXT)); + TextOutA(dc, xc-size.cx/2, yc-size.cy/2, str, 1); + + SelectObject(dc, hfsave); + SetTextColor(dc, clrsave); + SetBkMode(dc, bksave); + SetTextAlign(dc, alignsave); + DeleteObject(hf); + return TRUE; + + case DFCS_CAPTIONMIN: + Line1[0].x = Line1[3].x = myr.left + 96*SmallDiam/750+2; + Line1[1].x = Line1[2].x = Line1[0].x + 372*SmallDiam/750; + Line1[0].y = Line1[1].y = myr.top + 563*SmallDiam/750+1; + Line1[2].y = Line1[3].y = Line1[0].y + 92*SmallDiam/750; + Line1N = 4; + Line2N = 0; + break; + + case DFCS_CAPTIONMAX: + edge = 47*SmallDiam/750; + Line1[0].x = Line1[5].x = myr.left + 57*SmallDiam/750+3; + Line1[0].y = Line1[1].y = myr.top + 143*SmallDiam/750+1; + Line1[1].x = Line1[2].x = Line1[0].x + 562*SmallDiam/750; + Line1[5].y = Line1[4].y = Line1[0].y + 93*SmallDiam/750; + Line1[2].y = Line1[3].y = Line1[0].y + 513*SmallDiam/750; + Line1[3].x = Line1[4].x = Line1[1].x - edge; + + Line2[0].x = Line2[5].x = Line1[0].x; + Line2[3].x = Line2[4].x = Line1[1].x; + Line2[1].x = Line2[2].x = Line1[0].x + edge; + Line2[0].y = Line2[1].y = Line1[0].y; + Line2[4].y = Line2[5].y = Line1[2].y; + Line2[2].y = Line2[3].y = Line1[2].y - edge; + Line1N = 6; + Line2N = 6; + break; + + case DFCS_CAPTIONRESTORE: + /* FIXME: this one looks bad at small sizes < 15x15 :( */ + edge = 47*SmallDiam/750; + move = 420*SmallDiam/750; + Line1[0].x = Line1[9].x = myr.left + 198*SmallDiam/750+2; + Line1[0].y = Line1[1].y = myr.top + 169*SmallDiam/750+1; + Line1[6].y = Line1[7].y = Line1[0].y + 93*SmallDiam/750; + Line1[7].x = Line1[8].x = Line1[0].x + edge; + Line1[1].x = Line1[2].x = Line1[0].x + move; + Line1[5].x = Line1[6].x = Line1[1].x - edge; + Line1[9].y = Line1[8].y = Line1[0].y + 187*SmallDiam/750; + Line1[2].y = Line1[3].y = Line1[0].y + 7*SmallDiam/750; + Line1[4].y = Line1[5].y = Line1[2].y - edge; + Line1[3].x = Line1[4].x = Line1[2].x - 140*SmallDiam/750; + + Line2[1].x = Line2[2].x = Line1[3].x; + Line2[7].x = Line2[8].x = Line2[1].x - edge; + Line2[0].x = Line2[9].x = Line2[3].x = Line2[4].x = Line2[1].x - move; + Line2[5].x = Line2[6].x = Line2[0].x + edge; + Line2[0].y = Line2[1].y = Line1[9].y; + Line2[4].y = Line2[5].y = Line2[8].y = Line2[9].y = Line2[0].y + 93*SmallDiam/750; + Line2[2].y = Line2[3].y = Line2[0].y + 7*SmallDiam/750; + Line2[6].y = Line2[7].y = Line2[2].y - edge; + Line1N = 10; + Line2N = 10; + break; + + default: + DPRINT( "Invalid caption; flags=0x%04x\n", uFlags); + return FALSE; + } + + /* Here the drawing takes place */ + if(uFlags & DFCS_INACTIVE) + { + /* If we have an inactive button, then you see a shadow */ + hbsave = (HBRUSH)SelectObject(dc, GetSysColorBrush(COLOR_BTNHIGHLIGHT)); + hpsave = (HPEN)SelectObject(dc, GetSysColorPen(COLOR_BTNHIGHLIGHT)); + Polygon(dc, Line1, Line1N); + if(Line2N > 0) + Polygon(dc, Line2, Line2N); + SelectObject(dc, hpsave); + SelectObject(dc, hbsave); + } + + /* Correct for the shadow shift */ + for(i = 0; i < Line1N; i++) + { + Line1[i].x--; + Line1[i].y--; + } + for(i = 0; i < Line2N; i++) + { + Line2[i].x--; + Line2[i].y--; + } + + /* Make the final picture */ + i = uFlags & DFCS_INACTIVE ? COLOR_BTNSHADOW : COLOR_BTNTEXT; + hbsave = (HBRUSH)SelectObject(dc, GetSysColorBrush(i)); + hpsave = (HPEN)SelectObject(dc, GetSysColorPen(i)); + + Polygon(dc, Line1, Line1N); + if(Line2N > 0) + Polygon(dc, Line2, Line2N); + SelectObject(dc, hpsave); + SelectObject(dc, hbsave); + + return TRUE; +} + + +/************************************************************************ + * UITOOLS_DrawFrameScroll + * + * Draw a scroll-bar control coming from DrawFrameControl() + */ +static WINBOOL UITOOLS95_DrawFrameScroll(HDC dc, LPRECT r, UINT uFlags) +{ + POINT Line[4]; + RECT myr; + int SmallDiam = UITOOLS_MakeSquareRect(r, &myr) - 2; + int i; + HBRUSH hbsave, hb, hb2; + HPEN hpsave, hp, hp2; + int tri = 310*SmallDiam/1000; + int d46, d93; + + switch(uFlags & 0xff) + { + case DFCS_SCROLLCOMBOBOX: + case DFCS_SCROLLDOWN: + Line[2].x = myr.left + 470*SmallDiam/1000 + 2; + Line[2].y = myr.top + 687*SmallDiam/1000 + 1; + Line[0].x = Line[2].x - tri; + Line[1].x = Line[2].x + tri; + Line[0].y = Line[1].y = Line[2].y - tri; + break; + + case DFCS_SCROLLUP: + Line[2].x = myr.left + 470*SmallDiam/1000 + 2; + Line[2].y = myr.top + 313*SmallDiam/1000 + 1; + Line[0].x = Line[2].x - tri; + Line[1].x = Line[2].x + tri; + Line[0].y = Line[1].y = Line[2].y + tri; + break; + + case DFCS_SCROLLLEFT: + Line[2].x = myr.left + 313*SmallDiam/1000 + 1; + Line[2].y = myr.top + 470*SmallDiam/1000 + 2; + Line[0].y = Line[2].y - tri; + Line[1].y = Line[2].y + tri; + Line[0].x = Line[1].x = Line[2].x + tri; + break; + + case DFCS_SCROLLRIGHT: + Line[2].x = myr.left + 687*SmallDiam/1000 + 1; + Line[2].y = myr.top + 470*SmallDiam/1000 + 2; + Line[0].y = Line[2].y - tri; + Line[1].y = Line[2].y + tri; + Line[0].x = Line[1].x = Line[2].x - tri; + break; + + case DFCS_SCROLLSIZEGRIP: + /* This one breaks the flow... */ + UITOOLS95_DrawRectEdge(dc, r, EDGE_BUMP, BF_MIDDLE | ((uFlags&(DFCS_MONO|DFCS_FLAT)) ? BF_MONO : 0)); + hpsave = (HPEN)SelectObject(dc, GetStockObject(NULL_PEN)); + hbsave = (HBRUSH)SelectObject(dc, GetStockObject(NULL_BRUSH)); + if(uFlags & (DFCS_MONO|DFCS_FLAT)) + { + hp = hp2 = GetSysColorPen(COLOR_WINDOWFRAME); + hb = hb2 = GetSysColorBrush(COLOR_WINDOWFRAME); + } + else + { + hp = GetSysColorPen(COLOR_BTNHIGHLIGHT); + hp2 = GetSysColorPen(COLOR_BTNSHADOW); + hb = GetSysColorBrush(COLOR_BTNHIGHLIGHT); + hb2 = GetSysColorBrush(COLOR_BTNSHADOW); + } + Line[0].x = Line[1].x = r->right-1; + Line[2].y = Line[3].y = r->bottom-1; + d46 = 46*SmallDiam/750; + d93 = 93*SmallDiam/750; + + i = 586*SmallDiam/750; + Line[0].y = r->bottom - i - 1; + Line[3].x = r->right - i - 1; + Line[1].y = Line[0].y + d46; + Line[2].x = Line[3].x + d46; + SelectObject(dc, hb); + SelectObject(dc, hp); + Polygon(dc, Line, 4); + + Line[1].y++; Line[2].x++; + Line[0].y = Line[1].y + d93; + Line[3].x = Line[2].x + d93; + SelectObject(dc, hb2); + SelectObject(dc, hp2); + Polygon(dc, Line, 4); + + i = 398*SmallDiam/750; + Line[0].y = r->bottom - i - 1; + Line[3].x = r->right - i - 1; + Line[1].y = Line[0].y + d46; + Line[2].x = Line[3].x + d46; + SelectObject(dc, hb); + SelectObject(dc, hp); + Polygon(dc, Line, 4); + + Line[1].y++; Line[2].x++; + Line[0].y = Line[1].y + d93; + Line[3].x = Line[2].x + d93; + SelectObject(dc, hb2); + SelectObject(dc, hp2); + Polygon(dc, Line, 4); + + i = 210*SmallDiam/750; + Line[0].y = r->bottom - i - 1; + Line[3].x = r->right - i - 1; + Line[1].y = Line[0].y + d46; + Line[2].x = Line[3].x + d46; + SelectObject(dc, hb); + SelectObject(dc, hp); + Polygon(dc, Line, 4); + + Line[1].y++; Line[2].x++; + Line[0].y = Line[1].y + d93; + Line[3].x = Line[2].x + d93; + SelectObject(dc, hb2); + SelectObject(dc, hp2); + Polygon(dc, Line, 4); + + SelectObject(dc, hpsave); + SelectObject(dc, hbsave); + return TRUE; + + default: + DPRINT( "Invalid scroll; flags=0x%04x\n", uFlags); + return FALSE; + } + + /* Here do the real scroll-bar controls end up */ + UITOOLS95_DFC_ButtonPush(dc, r, uFlags & 0xff00); + + if(uFlags & DFCS_INACTIVE) + { + hbsave = (HBRUSH)SelectObject(dc, GetSysColorBrush(COLOR_BTNHIGHLIGHT)); + hpsave = (HPEN)SelectObject(dc, GetSysColorPen(COLOR_BTNHIGHLIGHT)); + Polygon(dc, Line, 3); + SelectObject(dc, hpsave); + SelectObject(dc, hbsave); + } + + for(i = 0; i < 3; i++) + { + Line[i].x--; + Line[i].y--; + } + + i = uFlags & DFCS_INACTIVE ? COLOR_BTNSHADOW : COLOR_BTNTEXT; + hbsave = (HBRUSH)SelectObject(dc, GetSysColorBrush(i)); + hpsave = (HPEN)SelectObject(dc, GetSysColorPen(i)); + Polygon(dc, Line, 3); + SelectObject(dc, hpsave); + SelectObject(dc, hbsave); + + return TRUE; +} + +/************************************************************************ + * UITOOLS_DrawFrameMenu + * + * Draw a menu control coming from DrawFrameControl() + */ +static WINBOOL UITOOLS95_DrawFrameMenu(HDC dc, LPRECT r, UINT uFlags) +{ + POINT Points[6]; + RECT myr; + int SmallDiam = UITOOLS_MakeSquareRect(r, &myr); + int i; + HBRUSH hbsave; + HPEN hpsave; + int xe, ye; + int xc, yc; + WINBOOL retval = TRUE; + + /* Using black and white seems to be utterly wrong, but win95 doesn't */ + /* use anything else. I think I tried all sys-colors to change things */ + /* without luck. It seems as if this behavior is inherited from the */ + /* win31 DFC() implementation... (you remember, B/W menus). */ + + FillRect(dc, r, (HBRUSH)GetStockObject(WHITE_BRUSH)); + + hbsave = (HBRUSH)SelectObject(dc, GetStockObject(BLACK_BRUSH)); + hpsave = (HPEN)SelectObject(dc, GetStockObject(BLACK_PEN)); + + switch(uFlags & 0xff) + { + case DFCS_MENUARROW: + i = 187*SmallDiam/750; + Points[2].x = myr.left + 468*SmallDiam/750; + Points[2].y = myr.top + 352*SmallDiam/750+1; + Points[0].y = Points[2].y - i; + Points[1].y = Points[2].y + i; + Points[0].x = Points[1].x = Points[2].x - i; + Polygon(dc, Points, 3); + break; + + case DFCS_MENUBULLET: + xe = myr.left; + ye = myr.top + SmallDiam - SmallDiam/2; + xc = myr.left + SmallDiam - SmallDiam/2; + yc = myr.top + SmallDiam - SmallDiam/2; + i = 234*SmallDiam/750; + i = i < 1 ? 1 : i; + myr.left = xc - i+i/2; + myr.right = xc + i/2; + myr.top = yc - i+i/2; + myr.bottom = yc + i/2; + Pie(dc, myr.left, myr.top, myr.right, myr.bottom, xe, ye, xe, ye); + break; + + case DFCS_MENUCHECK: + Points[0].x = myr.left + 253*SmallDiam/1000; + Points[0].y = myr.top + 445*SmallDiam/1000; + Points[1].x = myr.left + 409*SmallDiam/1000; + Points[1].y = Points[0].y + (Points[1].x-Points[0].x); + Points[2].x = myr.left + 690*SmallDiam/1000; + Points[2].y = Points[1].y - (Points[2].x-Points[1].x); + Points[3].x = Points[2].x; + Points[3].y = Points[2].y + 3*SmallDiam/16; + Points[4].x = Points[1].x; + Points[4].y = Points[1].y + 3*SmallDiam/16; + Points[5].x = Points[0].x; + Points[5].y = Points[0].y + 3*SmallDiam/16; + Polygon(dc, Points, 6); + break; + + default: + DPRINT( "Invalid menu; flags=0x%04x\n", uFlags); + retval = FALSE; + break; + } + + SelectObject(dc, hpsave); + SelectObject(dc, hbsave); + return retval; +} diff --git a/reactos/lib/user32/internal/win.c b/reactos/lib/user32/internal/win.c index 1c406b7c31d..904debabf1a 100644 --- a/reactos/lib/user32/internal/win.c +++ b/reactos/lib/user32/internal/win.c @@ -80,8 +80,7 @@ HANDLE WIN_CreateWindowEx( CREATESTRUCTW *cs, ATOM classAtom) wndPtr->hmemTaskQ = GetFastQueue(); wndPtr->hrgnUpdate = 0; wndPtr->hwndLastActive = wndPtr->hwndSelf; -// wndPtr->dwStyle = cs->style & ~WS_VISIBLE; - wndPtr->dwStyle = cs->style | WS_VISIBLE; + wndPtr->dwStyle = cs->style & ~WS_VISIBLE; wndPtr->dwExStyle = cs->dwExStyle; wndPtr->wIDmenu = 0; wndPtr->helpContext = 0; @@ -135,9 +134,11 @@ HANDLE WIN_CreateWindowEx( CREATESTRUCTW *cs, ATOM classAtom) /* Get class or window DC if needed */ + + if (classPtr->style & CS_OWNDC) wndPtr->dce = DCE_AllocDCE(hWnd,DCE_WINDOW_DC); else if (classPtr->style & CS_CLASSDC) wndPtr->dce = classPtr->dce; - else wndPtr->dce = NULL; + else wndPtr->dce = DCE_AllocDCE(hWnd,DCE_WINDOW_DC);; GetStartupInfoW((STARTUPINFO *)&StartupInfo); if (cs->x == CW_USEDEFAULT) @@ -199,6 +200,8 @@ HANDLE WIN_CreateWindowEx( CREATESTRUCTW *cs, ATOM classAtom) wndPtr->rectWindow.top = cs->y; wndPtr->rectWindow.right = cs->x + cs->cx; wndPtr->rectWindow.bottom = cs->y + cs->cy; + + wndPtr->rectClient = wndPtr->rectWindow; @@ -229,12 +232,20 @@ HANDLE WIN_CreateWindowEx( CREATESTRUCTW *cs, ATOM classAtom) maxPos.x = wndPtr->rectWindow.left; maxPos.y = wndPtr->rectWindow.top; - - if( SendMessageW( hWnd, WM_NCCREATE, 0, (LPARAM)cs) == 0) - { + if ( classPtr->bUnicode == TRUE ) { + if( SendMessageW( hWnd, WM_NCCREATE, 0, (LPARAM)cs) == 0) + { /* Abort window creation */ - WIN_DestroyWindow( wndPtr ); - return NULL; + WIN_DestroyWindow( wndPtr ); + return NULL; + } + } else { + if( SendMessageA( hWnd, WM_NCCREATE, 0, (LPARAM)cs) == 0) + { + /* Abort window creation */ + WIN_DestroyWindow( wndPtr ); + return NULL; + } } /* Insert the window in the linked list */ @@ -245,7 +256,9 @@ HANDLE WIN_CreateWindowEx( CREATESTRUCTW *cs, ATOM classAtom) NULL, NULL, 0, &wndPtr->rectClient ); OffsetRect(&wndPtr->rectWindow, maxPos.x - wndPtr->rectWindow.left, maxPos.y - wndPtr->rectWindow.top); - if( (SendMessageW( hWnd, WM_CREATE, 0, (LPARAM)cs )) == -1 ) + + + if( (SendMessageA( hWnd, WM_CREATE, 0, (LPARAM)cs )) == -1 ) { WIN_UnlinkWindow( hWnd ); WIN_DestroyWindow( wndPtr ); @@ -636,6 +649,9 @@ WND * WIN_FindWndPtr( HWND hWnd ) #endif + +#undef WIN_FindWndPtr +WND* WIN_FindWndPtr( HWND hwnd ); WND * WIN_FindWndPtr( HWND hwnd ) { WND * ptr; @@ -651,6 +667,7 @@ WND * WIN_FindWndPtr( HWND hwnd ) } return ptr; } + WND* WIN_GetDesktop(void) { return NULL; @@ -830,13 +847,17 @@ void WIN_UpdateNCArea(WND* wnd, BOOL bUpdate) WINBOOL WIN_IsWindowDrawable( WND* wnd, WINBOOL icon ) { + return TRUE; + + if ( wnd == NULL ) + return FALSE; if( (wnd->dwStyle & WS_MINIMIZE && icon && wnd->class->hIcon) || !(wnd->dwStyle & WS_VISIBLE) ) return FALSE; for(wnd = wnd->parent; wnd; wnd = wnd->parent) if( wnd->dwStyle & WS_MINIMIZE || !(wnd->dwStyle & WS_VISIBLE) ) break; - return (wnd == NULL); + return wnd == NULL; } @@ -886,6 +907,9 @@ void WIN_SendDestroyMsg( WND* pWnd ) } + + + /******************************************************************* * GetSysModalWindow16 (USER.52) */ diff --git a/reactos/lib/user32/makefile.main b/reactos/lib/user32/makefile.main index c12b8afb79b..1bfeeb50191 100644 --- a/reactos/lib/user32/makefile.main +++ b/reactos/lib/user32/makefile.main @@ -3,7 +3,7 @@ all: user32.exe INTERNAL_OBJECTS = internal/property.o internal/menu.o internal/heapdup.o internal/nc.o\ internal/scroll.o internal/win.o internal/dce.o internal/msg.o internal/queue.o\ internal/signal.o internal/event.o internal/timer.o internal/region.o\ - internal/text.o internal/defwnd.o internal/paint.o + internal/text.o internal/defwnd.o internal/paint.o internal/uitools.o MISC_OBJECTS = misc/sprintf.o misc/dllmain.o misc/string.o misc/sysmetr.o\ misc/main.o misc/bitmap.o misc/cursor.o misc/vk.o @@ -15,14 +15,14 @@ WINDOWS_OBJECTS = windows/wndproc.o windows/win.o windows/hook.o windows/spy.o\ windows/focus.o windows/paint.o GRAPHICS_OBJECTS = graphics/rect.o graphics/caret.o graphics/text.o graphics/syscol.o graphics/fill.o\ - graphics/draw.o + graphics/draw.o graphics/icon.o RESOURCE_OBJECTS = resources/sysres.o OBJECTS = $(MISC_OBJECTS) $(INTERNAL_OBJECTS) $(GRAPHICS_OBJECTS) $(RESOURCE_OBJECTS) $(WINDOWS_OBJECTS) user32.exe: $(OBJECTS) - $(LD) $(OBJECTS) F:/gnu/cygnus/cygwin-b20/H-i586-cygwin32/i586-cygwin32/lib/crt1.o F:/gnu/cygnus/cygwin-b20/H-i586-cygwin32/i586-cygwin32/lib/libgdi32.a F:/gnu/cygnus/cygwin-b20/H-i586-cygwin32/i586-cygwin32/lib/libkernel32.a F:/gnu/cygnus/cygwin-b20/H-i586-cygwin32/i586-cygwin32/lib/libcrtdll.a -o user32.exe + $(LD) $(OBJECTS) F:/gnu/cygnus/cygwin-b20/H-i586-cygwin32/i586-cygwin32/lib/crt1.o ./libgdi32.a ./libkernel32.a ./libcrtdll.a -o user32.exe dummy: diff --git a/reactos/lib/user32/misc/bitmap.c b/reactos/lib/user32/misc/bitmap.c index 4ff22c57e4b..99fbed8ec63 100644 --- a/reactos/lib/user32/misc/bitmap.c +++ b/reactos/lib/user32/misc/bitmap.c @@ -9,6 +9,9 @@ HBITMAP LoadBitmapW(HINSTANCE hInstance, LPCWSTR lpBitmapName) HBITMAP LoadBitmapA(HINSTANCE hInstance, LPCSTR lpBitmapName) { + return CreateBitmap(GetSystemMetrics(SM_CXSMICON), + GetSystemMetrics(SM_CXSMICON), + 1,1, NULL ); return NULL; // return BITMAP_LoadBitmap32W(hInstance, lpBitmapName, 0); } @@ -16,6 +19,9 @@ HBITMAP LoadBitmapA(HINSTANCE hInstance, LPCSTR lpBitmapName) HBITMAP BITMAP_LoadBitmapW(HINSTANCE instance,LPCWSTR name, UINT loadflags) { + return CreateBitmap(GetSystemMetrics(SM_CXSMICON), + GetSystemMetrics(SM_CXSMICON), + 1,1, NULL ); #if 0 HBITMAP hbitmap = 0; HDC hdc; diff --git a/reactos/lib/user32/misc/main.c b/reactos/lib/user32/misc/main.c index e5bed617424..33452c2c47e 100644 --- a/reactos/lib/user32/misc/main.c +++ b/reactos/lib/user32/misc/main.c @@ -9,16 +9,20 @@ int _CRT_glob = 0; int __main(int argc, char **argv) { + return 0; } int main(int argc, char **argv) { HWND hwnd; + HMENU hmenu; MSG msg; WNDCLASSEX wc1; HINSTANCE hInst = 0; - int nWinMode = SW_SHOWMAXIMIZED; + int nWinMode = SW_SHOW; + + RECT rect; wc1.hInstance = hInst; wc1.lpszClassName = szName; @@ -38,21 +42,26 @@ int main(int argc, char **argv) if ( !RegisterClassEx(&wc1)) return 0; - hwnd = CreateWindowEx(0, szName, "test", WS_OVERLAPPEDWINDOW| WS_VISIBLE, + hmenu = CreateMenu(); + + hwnd = CreateWindowEx(0, szName, "test", WS_OVERLAPPEDWINDOW, CW_USEDEFAULT,CW_USEDEFAULT,CW_USEDEFAULT,CW_USEDEFAULT, - NULL,NULL,hInst, NULL); + NULL,hmenu,hInst, NULL); - ShowWindow(hwnd,nWinMode); UpdateWindow(hwnd); - SendMessageW( hwnd, WM_MOVE, 0,MAKELONG(0,0)); - //while(GetMessage(&msg,NULL, 0, 0)) - //{ - // TranslateMessage(&msg); - // DispatchMessage(&msg); - //} + SetWindowText(hwnd,"Hallo"); + + DrawMenuBar(hwnd); +// SendMessage( hwnd, WM_MOVE, 0,MAKELONG(0,0)); +// SendMessage( hwnd, WM_PAINT, GetWindowDC(hwnd),0); + while(GetMessage(&msg,NULL, 0, 0)) + { + TranslateMessage(&msg); + DispatchMessage(&msg); + } Sleep(10000); return msg.wParam; } diff --git a/reactos/lib/user32/misc/sysmetr.c b/reactos/lib/user32/misc/sysmetr.c index f5894a74b68..2bbeb500847 100644 --- a/reactos/lib/user32/misc/sysmetr.c +++ b/reactos/lib/user32/misc/sysmetr.c @@ -31,7 +31,7 @@ short sysMetrics[SM_CMETRICS+1] = { 32, // [SM_CYCURSOR] /* 14 */ 19, // [SM_CYMENU] /* 15 */ 800, // [SM_CXFULLSCREEN] /* 16 */ - 0, // [SM_CYFULLSCREEN] /* 17 */ + 600, // [SM_CYFULLSCREEN] /* 17 */ 0, // [SM_CYKANJIWINDOW] /* 18 */ 0, // [SM_MOUSEPRESENT] /* 19 */ 0, // [SM_CYVSCROLL] /* 20 */ @@ -42,12 +42,12 @@ short sysMetrics[SM_CMETRICS+1] = { 0, // [SM_RESERVED2] /* 25 */ 0, // [SM_RESERVED3] /* 26 */ 0, // [SM_RESERVED4] /* 27 */ - 0, // [SM_CXMIN] /* 28 */ - 0, // [SM_CYMIN] /* 29 */ - 0, // [SM_CXSIZE] /* 30 */ - 0, // [SM_CYSIZE] /* 31 */ - 0, // [SM_CXFRAME] /* 32 */ - 0, // [SM_CYFRAME] /* 33 */ + 112, // [SM_CXMIN] /* 28 */ + 27, // [SM_CYMIN] /* 29 */ + 17, // [SM_CXSIZE] /* 30 */ + 17, // [SM_CYSIZE] /* 31 */ + 4, // [SM_CXFRAME] /* 32 */ + 4, // [SM_CYFRAME] /* 33 */ 0, // [SM_CXMINTRACK] /* 34 */ 0, // [SM_CYMINTRACK] /* 35 */ 0, // [SM_CXDOUBLECLK] /* 36 */ @@ -63,17 +63,17 @@ short sysMetrics[SM_CMETRICS+1] = { // [SM_CXFRAME] /* win40 name change */ // [SM_CYFRAME] /* win40 name change */ 0, // [SM_SECURE] /* 44 */ - 0, // [SM_CXEDGE] /* 45 */ - 0, // [SM_CYEDGE] /* 46 */ + 2, // [SM_CXEDGE] /* 45 */ // sysMetrics[SM_CXBORDER] + 1; + 2, // [SM_CYEDGE] /* 46 */ 0, // [SM_CXMINSPACING] /* 47 */ 0, // [SM_CYMINSPACING] /* 48 */ - 0, // [SM_CXSMICON] /* 49 */ - 0, // [SM_CYSMICON] /* 50 */ + 14, // [SM_CXSMICON] /* 49 */ + 14, // [SM_CYSMICON] /* 50 */ 0, // [SM_CYSMCAPTION] /* 51 */ 0, // [SM_CXSMSIZE] /* 52 */ 0, // [SM_CYSMSIZE] /* 53 */ - 0, // [SM_CXMENUSIZE] /* 54 */ - 0, // [SM_CYMENUSIZE] /* 55 */ + 19, // [SM_CXMENUSIZE] /* 54 */ + 19, // [SM_CYMENUSIZE] /* 55 */ 8, // [SM_ARRANGE] /* 56 */ 160, // [SM_CXMINIMIZED] /* 57 */ 24, // [SM_CYMINIMIZED] /* 58 */ diff --git a/reactos/lib/user32/windows/class.c b/reactos/lib/user32/windows/class.c index d8224822c6a..d3ceefd90c1 100644 --- a/reactos/lib/user32/windows/class.c +++ b/reactos/lib/user32/windows/class.c @@ -103,9 +103,9 @@ ATOM STDCALL RegisterClassExA(const WNDCLASSEX* wc) if (wc->style & CS_CLASSDC) classPtr->dce = DCE_AllocDCE( 0, DCE_CLASS_DC ) ; - else classPtr->style |= CS_OWNDC; + else + classPtr->dce = NULL; - if ( wc->lpszMenuName != NULL ) { len = lstrlenA(wc->lpszMenuName); diff --git a/reactos/lib/user32/windows/dc.c b/reactos/lib/user32/windows/dc.c index da33e70254c..ffea62b3d87 100644 --- a/reactos/lib/user32/windows/dc.c +++ b/reactos/lib/user32/windows/dc.c @@ -39,9 +39,12 @@ INT RestoreVisRgn(HDC hdc); HDC STDCALL GetDC( HWND hWnd ) { + WND *wndPtr; if (!hWnd) - return GetDCEx( GetDesktopWindow(), 0, DCX_CACHE | DCX_WINDOW ); - return GetDCEx( hWnd, 0, DCX_USESTYLE ); + hWnd= GetDesktopWindow(); + if (!(wndPtr = WIN_FindWndPtr( hWnd ))) return 0; + + return wndPtr->dce->hDC; } /*********************************************************************** @@ -51,6 +54,8 @@ HDC STDCALL GetDC( HWND hWnd ) * * FIXME: Full support for hrgnClip == 1 (alias for entire window). */ + + HDC WINAPI GetDCEx( HWND hwnd, HRGN hrgnClip, DWORD flags ) { HRGN hrgnVisible = 0; @@ -69,7 +74,10 @@ HDC WINAPI GetDCEx( HWND hwnd, HRGN hrgnClip, DWORD flags ) /* fixup flags */ - if (!(wndPtr->class->style & (CS_OWNDC | CS_CLASSDC))) flags |= DCX_CACHE; +#if 0 + if (!(wndPtr->class->style & (CS_OWNDC | CS_CLASSDC))) + flags |= DCX_CACHE; + if (flags & DCX_USESTYLE) { @@ -88,15 +96,19 @@ HDC WINAPI GetDCEx( HWND hwnd, HRGN hrgnClip, DWORD flags ) else flags |= DCX_CACHE; } + if( flags & DCX_NOCLIPCHILDREN ) { flags |= DCX_CACHE; flags &= ~(DCX_PARENTCLIP | DCX_CLIPCHILDREN); } - if (flags & DCX_WINDOW) - flags = (flags & ~DCX_CLIPCHILDREN) | DCX_CACHE; + if (flags & DCX_WINDOW) + flags = (flags & ~DCX_CLIPCHILDREN) | DCX_CACHE; + +#endif + if (!(wndPtr->dwStyle & WS_CHILD) || !wndPtr->parent ) flags &= ~DCX_PARENTCLIP; else if( flags & DCX_PARENTCLIP ) @@ -116,6 +128,7 @@ HDC WINAPI GetDCEx( HWND hwnd, HRGN hrgnClip, DWORD flags ) dcxFlags = flags & (DCX_PARENTCLIP | DCX_CLIPSIBLINGS | DCX_CLIPCHILDREN | DCX_CACHE | DCX_WINDOW); +#if 0 if (flags & DCX_CACHE) { DCE* dceEmpty; @@ -137,9 +150,9 @@ HDC WINAPI GetDCEx( HWND hwnd, HRGN hrgnClip, DWORD flags ) if (dce->DCXflags & DCX_DCEEMPTY) dceEmpty = dce; else - if ((dce->hwndCurrent == hwnd) && - ((dce->DCXflags & (DCX_CLIPSIBLINGS | DCX_CLIPCHILDREN | - DCX_CACHE | DCX_WINDOW | DCX_PARENTCLIP)) == dcxFlags)) + if ((dce->hwndCurrent == hwnd) + && ((dce->DCXflags & (DCX_CLIPSIBLINGS | DCX_CLIPCHILDREN | + DCX_CACHE | DCX_WINDOW | DCX_PARENTCLIP)) == dcxFlags)) { DPRINT("\tfound valid %08x dce [%04x], flags %08x\n", (unsigned)dce, hwnd, (unsigned)dcxFlags ); @@ -153,7 +166,13 @@ HDC WINAPI GetDCEx( HWND hwnd, HRGN hrgnClip, DWORD flags ) } else { - dce = (wndPtr->class->style & CS_OWNDC) ? wndPtr->dce : wndPtr->class->dce; + if (wndPtr->class->style & CS_OWNDC) + dce = wndPtr->dce; + else if ( wndPtr->class->style & CS_CLASSDC) + dce = wndPtr->class->dce; + else + return 0; + if( dce->hwndCurrent == hwnd ) { DPRINT("\tskipping hVisRgn update\n"); @@ -177,6 +196,9 @@ HDC WINAPI GetDCEx( HWND hwnd, HRGN hrgnClip, DWORD flags ) } if (!dce) return 0; +#endif + dce = wndPtr->dce; + dce->hwndCurrent = hwnd; dce->hClipRgn = 0; dce->DCXflags = dcxFlags | (flags & DCX_WINDOWPAINT) | DCX_DCEBUSY; diff --git a/reactos/lib/user32/windows/dialog.c b/reactos/lib/user32/windows/dialog.c new file mode 100644 index 00000000000..1cd4513cbaf --- /dev/null +++ b/reactos/lib/user32/windows/dialog.c @@ -0,0 +1,1018 @@ +/*********************************************************************** + * CreateDialog16 (USER.89) + */ +HWND16 WINAPI CreateDialog16( HINSTANCE16 hInst, SEGPTR dlgTemplate, + HWND16 owner, DLGPROC16 dlgProc ) +{ + return CreateDialogParam16( hInst, dlgTemplate, owner, dlgProc, 0 ); +} + + +/*********************************************************************** + * CreateDialogParam16 (USER.241) + */ +HWND16 WINAPI CreateDialogParam16( HINSTANCE16 hInst, SEGPTR dlgTemplate, + HWND16 owner, DLGPROC16 dlgProc, + LPARAM param ) +{ + HWND16 hwnd = 0; + HRSRC16 hRsrc; + HGLOBAL16 hmem; + LPCVOID data; + + TRACE(dialog, "%04x,%08lx,%04x,%08lx,%ld\n", + hInst, (DWORD)dlgTemplate, owner, (DWORD)dlgProc, param ); + + if (!(hRsrc = FindResource16( hInst, dlgTemplate, RT_DIALOG16 ))) return 0; + if (!(hmem = LoadResource16( hInst, hRsrc ))) return 0; + if (!(data = LockResource16( hmem ))) hwnd = 0; + else hwnd = CreateDialogIndirectParam16( hInst, data, owner, + dlgProc, param ); + FreeResource16( hmem ); + return hwnd; +} + +/*********************************************************************** + * CreateDialogParam32A (USER32.73) + */ +HWND32 WINAPI CreateDialogParam32A( HINSTANCE32 hInst, LPCSTR name, + HWND32 owner, DLGPROC32 dlgProc, + LPARAM param ) +{ + if (HIWORD(name)) + { + LPWSTR str = HEAP_strdupAtoW( GetProcessHeap(), 0, name ); + HWND32 hwnd = CreateDialogParam32W( hInst, str, owner, dlgProc, param); + HeapFree( GetProcessHeap(), 0, str ); + return hwnd; + } + return CreateDialogParam32W( hInst, (LPCWSTR)name, owner, dlgProc, param ); +} + + +/*********************************************************************** + * CreateDialogParam32W (USER32.74) + */ +HWND32 WINAPI CreateDialogParam32W( HINSTANCE32 hInst, LPCWSTR name, + HWND32 owner, DLGPROC32 dlgProc, + LPARAM param ) +{ + HANDLE32 hrsrc = FindResource32W( hInst, name, RT_DIALOG32W ); + if (!hrsrc) return 0; + return CreateDialogIndirectParam32W( hInst, + (LPVOID)LoadResource32(hInst, hrsrc), + owner, dlgProc, param ); +} + + +/*********************************************************************** + * CreateDialogIndirect16 (USER.219) + */ +HWND16 WINAPI CreateDialogIndirect16( HINSTANCE16 hInst, LPCVOID dlgTemplate, + HWND16 owner, DLGPROC16 dlgProc ) +{ + return CreateDialogIndirectParam16( hInst, dlgTemplate, owner, dlgProc, 0); +} + + +/*********************************************************************** + * CreateDialogIndirectParam16 (USER.242) + */ +HWND16 WINAPI CreateDialogIndirectParam16( HINSTANCE16 hInst, + LPCVOID dlgTemplate, + HWND16 owner, DLGPROC16 dlgProc, + LPARAM param ) +{ + return DIALOG_CreateIndirect( hInst, dlgTemplate, FALSE, owner, + dlgProc, param, WIN_PROC_16 ); +} + + +/*********************************************************************** + * CreateDialogIndirectParam32A (USER32.69) + */ +HWND32 WINAPI CreateDialogIndirectParam32A( HINSTANCE32 hInst, + LPCVOID dlgTemplate, + HWND32 owner, DLGPROC32 dlgProc, + LPARAM param ) +{ + return DIALOG_CreateIndirect( hInst, dlgTemplate, TRUE, owner, + (DLGPROC16)dlgProc, param, WIN_PROC_32A ); +} + +/*********************************************************************** + * CreateDialogIndirectParam32AorW (USER32.71) + */ +HWND32 WINAPI CreateDialogIndirectParam32AorW( HINSTANCE32 hInst, + LPCVOID dlgTemplate, + HWND32 owner, DLGPROC32 dlgProc, + LPARAM param ) +{ FIXME(dialog,"assume WIN_PROC_32W\n"); + return DIALOG_CreateIndirect( hInst, dlgTemplate, TRUE, owner, + (DLGPROC16)dlgProc, param, WIN_PROC_32W ); +} + +/*********************************************************************** + * CreateDialogIndirectParam32W (USER32.72) + */ +HWND32 WINAPI CreateDialogIndirectParam32W( HINSTANCE32 hInst, + LPCVOID dlgTemplate, + HWND32 owner, DLGPROC32 dlgProc, + LPARAM param ) +{ + return DIALOG_CreateIndirect( hInst, dlgTemplate, TRUE, owner, + (DLGPROC16)dlgProc, param, WIN_PROC_32W ); +} + + +/*********************************************************************** + * DIALOG_DoDialogBox + */ +INT32 DIALOG_DoDialogBox( HWND32 hwnd, HWND32 owner ) +{ + WND * wndPtr; + DIALOGINFO * dlgInfo; + MSG16 msg; + INT32 retval; + + /* Owner must be a top-level window */ + owner = WIN_GetTopParent( owner ); + if (!(wndPtr = WIN_FindWndPtr( hwnd ))) return -1; + dlgInfo = (DIALOGINFO *)wndPtr->wExtra; + EnableWindow32( owner, FALSE ); + ShowWindow32( hwnd, SW_SHOW ); + + while (MSG_InternalGetMessage(&msg, hwnd, owner, MSGF_DIALOGBOX, PM_REMOVE, + !(wndPtr->dwStyle & DS_NOIDLEMSG) )) + { + if (!IsDialogMessage16( hwnd, &msg)) + { + TranslateMessage16( &msg ); + DispatchMessage16( &msg ); + } + if (dlgInfo->flags & DF_END) break; + } + retval = dlgInfo->idResult; + EnableWindow32( owner, TRUE ); + dlgInfo->flags |= DF_ENDING; /* try to stop it being destroyed twice */ + DestroyWindow32( hwnd ); + return retval; +} + + +/*********************************************************************** + * DialogBox16 (USER.87) + */ +INT16 WINAPI DialogBox16( HINSTANCE16 hInst, SEGPTR dlgTemplate, + HWND16 owner, DLGPROC16 dlgProc ) +{ + return DialogBoxParam16( hInst, dlgTemplate, owner, dlgProc, 0 ); +} + + +/*********************************************************************** + * DialogBoxParam16 (USER.239) + */ +INT16 WINAPI DialogBoxParam16( HINSTANCE16 hInst, SEGPTR template, + HWND16 owner, DLGPROC16 dlgProc, LPARAM param ) +{ + HWND16 hwnd = CreateDialogParam16( hInst, template, owner, dlgProc, param); + if (hwnd) return (INT16)DIALOG_DoDialogBox( hwnd, owner ); + return -1; +} + + +/*********************************************************************** + * DialogBoxParam32A (USER32.139) + */ +INT32 WINAPI DialogBoxParam32A( HINSTANCE32 hInst, LPCSTR name, + HWND32 owner, DLGPROC32 dlgProc, LPARAM param ) +{ + HWND32 hwnd = CreateDialogParam32A( hInst, name, owner, dlgProc, param ); + if (hwnd) return DIALOG_DoDialogBox( hwnd, owner ); + return -1; +} + + +/*********************************************************************** + * DialogBoxParam32W (USER32.140) + */ +INT32 WINAPI DialogBoxParam32W( HINSTANCE32 hInst, LPCWSTR name, + HWND32 owner, DLGPROC32 dlgProc, LPARAM param ) +{ + HWND32 hwnd = CreateDialogParam32W( hInst, name, owner, dlgProc, param ); + if (hwnd) return DIALOG_DoDialogBox( hwnd, owner ); + return -1; +} + + +/*********************************************************************** + * DialogBoxIndirect16 (USER.218) + */ +INT16 WINAPI DialogBoxIndirect16( HINSTANCE16 hInst, HANDLE16 dlgTemplate, + HWND16 owner, DLGPROC16 dlgProc ) +{ + return DialogBoxIndirectParam16( hInst, dlgTemplate, owner, dlgProc, 0 ); +} + + +/*********************************************************************** + * DialogBoxIndirectParam16 (USER.240) + */ +INT16 WINAPI DialogBoxIndirectParam16( HINSTANCE16 hInst, HANDLE16 dlgTemplate, + HWND16 owner, DLGPROC16 dlgProc, + LPARAM param ) +{ + HWND16 hwnd; + LPCVOID ptr; + + if (!(ptr = GlobalLock16( dlgTemplate ))) return -1; + hwnd = CreateDialogIndirectParam16( hInst, ptr, owner, dlgProc, param ); + GlobalUnlock16( dlgTemplate ); + if (hwnd) return (INT16)DIALOG_DoDialogBox( hwnd, owner ); + return -1; +} + + +/*********************************************************************** + * DialogBoxIndirectParam32A (USER32.136) + */ +INT32 WINAPI DialogBoxIndirectParam32A(HINSTANCE32 hInstance, LPCVOID template, + HWND32 owner, DLGPROC32 dlgProc, + LPARAM param ) +{ + HWND32 hwnd = CreateDialogIndirectParam32A( hInstance, template, + owner, dlgProc, param ); + if (hwnd) return DIALOG_DoDialogBox( hwnd, owner ); + return -1; +} + + +/*********************************************************************** + * DialogBoxIndirectParam32W (USER32.138) + */ +INT32 WINAPI DialogBoxIndirectParam32W(HINSTANCE32 hInstance, LPCVOID template, + HWND32 owner, DLGPROC32 dlgProc, + LPARAM param ) +{ + HWND32 hwnd = CreateDialogIndirectParam32W( hInstance, template, + owner, dlgProc, param ); + if (hwnd) return DIALOG_DoDialogBox( hwnd, owner ); + return -1; +} + + +/*********************************************************************** + * EndDialog16 (USER32.173) + */ +BOOL16 WINAPI EndDialog16( HWND16 hwnd, INT16 retval ) +{ + return EndDialog32( hwnd, retval ); +} + + +/*********************************************************************** + * EndDialog32 (USER.88) + */ +WINBOOL WINAPI EndDialog32( HWND32 hwnd, INT32 retval ) +{ + WND * wndPtr = WIN_FindWndPtr( hwnd ); + DIALOGINFO * dlgInfo = (DIALOGINFO *)wndPtr->wExtra; + + TRACE(dialog, "%04x %d\n", hwnd, retval ); + + if( dlgInfo ) + { + dlgInfo->idResult = retval; + dlgInfo->flags |= DF_END; + } + return TRUE; +} + + +/*********************************************************************** + * DIALOG_IsAccelerator + */ +static WINBOOL DIALOG_IsAccelerator( HWND32 hwnd, HWND32 hwndDlg, WPARAM32 vKey ) +{ + HWND32 hwndControl = hwnd; + HWND32 hwndNext; + WND *wndPtr; + WINBOOL RetVal = FALSE; + INT32 dlgCode; + + if (vKey == VK_SPACE) + { + dlgCode = SendMessage32A( hwndControl, WM_GETDLGCODE, 0, 0 ); + if (dlgCode & DLGC_BUTTON) + { + SendMessage32A( hwndControl, WM_LBUTTONDOWN, 0, 0); + SendMessage32A( hwndControl, WM_LBUTTONUP, 0, 0); + RetVal = TRUE; + } + } + else + { + do + { + wndPtr = WIN_FindWndPtr( hwndControl ); + if (wndPtr != NULL && wndPtr->text != NULL && + (wndPtr->dwStyle & (WS_VISIBLE | WS_DISABLED)) == WS_VISIBLE) + { + dlgCode = SendMessage32A( hwndControl, WM_GETDLGCODE, 0, 0 ); + if (dlgCode & (DLGC_BUTTON | DLGC_STATIC)) + { + /* find the accelerator key */ + LPSTR p = wndPtr->text - 2; + do + { + p = strchr( p + 2, '&' ); + } + while (p != NULL && p[1] == '&'); + + /* and check if it's the one we're looking for */ + if (p != NULL && toupper( p[1] ) == toupper( vKey ) ) + { + if ((dlgCode & DLGC_STATIC) || + (wndPtr->dwStyle & 0x0f) == BS_GROUPBOX ) + { + /* set focus to the control */ + SendMessage32A( hwndDlg, WM_NEXTDLGCTL, + hwndControl, 1); + /* and bump it on to next */ + SendMessage32A( hwndDlg, WM_NEXTDLGCTL, 0, 0); + } + else if (dlgCode & + (DLGC_DEFPUSHBUTTON | DLGC_UNDEFPUSHBUTTON)) + { + /* send command message as from the control */ + SendMessage32A( hwndDlg, WM_COMMAND, + MAKEWPARAM( LOWORD(wndPtr->wIDmenu), + BN_CLICKED ), + (LPARAM)hwndControl ); + } + else + { + /* click the control */ + SendMessage32A( hwndControl, WM_LBUTTONDOWN, 0, 0); + SendMessage32A( hwndControl, WM_LBUTTONUP, 0, 0); + } + RetVal = TRUE; + break; + } + } + } + hwndNext = GetWindow32( hwndControl, GW_CHILD ); + if (!hwndNext) + { + hwndNext = GetWindow32( hwndControl, GW_HWNDNEXT ); + } + while (!hwndNext) + { + hwndControl = GetParent32( hwndControl ); + if (hwndControl == hwndDlg) + { + hwndNext = GetWindow32( hwndDlg, GW_CHILD ); + } + else + { + hwndNext = GetWindow32( hwndControl, GW_HWNDNEXT ); + } + } + hwndControl = hwndNext; + } + while (hwndControl != hwnd); + } + return RetVal; +} + + +/*********************************************************************** + * DIALOG_IsDialogMessage + */ +static WINBOOL DIALOG_IsDialogMessage( HWND32 hwnd, HWND32 hwndDlg, + UINT32 message, WPARAM32 wParam, + LPARAM lParam, WINBOOL *translate, + WINBOOL *dispatch, INT32 dlgCode ) +{ + *translate = *dispatch = FALSE; + + if (message == WM_PAINT) + { + /* Apparently, we have to handle this one as well */ + *dispatch = TRUE; + return TRUE; + } + + /* Only the key messages get special processing */ + if ((message != WM_KEYDOWN) && + (message != WM_SYSCHAR) && + (message != WM_CHAR)) + return FALSE; + + if (dlgCode & DLGC_WANTMESSAGE) + { + *translate = *dispatch = TRUE; + return TRUE; + } + + switch(message) + { + case WM_KEYDOWN: + switch(wParam) + { + case VK_TAB: + if (!(dlgCode & DLGC_WANTTAB)) + { + SendMessage32A( hwndDlg, WM_NEXTDLGCTL, + (GetKeyState32(VK_SHIFT) & 0x8000), 0 ); + return TRUE; + } + break; + + case VK_RIGHT: + case VK_DOWN: + case VK_LEFT: + case VK_UP: + if (!(dlgCode & DLGC_WANTARROWS)) + { + WINBOOL fPrevious = (wParam == VK_LEFT || wParam == VK_UP); + HWND32 hwndNext = + GetNextDlgGroupItem32 (hwndDlg, GetFocus32(), fPrevious ); + SendMessage32A( hwndDlg, WM_NEXTDLGCTL, hwndNext, 1 ); + return TRUE; + } + break; + + case VK_ESCAPE: + SendMessage32A( hwndDlg, WM_COMMAND, IDCANCEL, + (LPARAM)GetDlgItem32( hwndDlg, IDCANCEL ) ); + return TRUE; + + case VK_RETURN: + { + DWORD dw = SendMessage16( hwndDlg, DM_GETDEFID, 0, 0 ); + if (HIWORD(dw) == DC_HASDEFID) + { + SendMessage32A( hwndDlg, WM_COMMAND, + MAKEWPARAM( LOWORD(dw), BN_CLICKED ), + (LPARAM)GetDlgItem32(hwndDlg, LOWORD(dw))); + } + else + { + SendMessage32A( hwndDlg, WM_COMMAND, IDOK, + (LPARAM)GetDlgItem32( hwndDlg, IDOK ) ); + + } + } + return TRUE; + } + *translate = TRUE; + break; /* case WM_KEYDOWN */ + + case WM_CHAR: + if (dlgCode & DLGC_WANTCHARS) break; + /* drop through */ + + case WM_SYSCHAR: + if (DIALOG_IsAccelerator( hwnd, hwndDlg, wParam )) + { + /* don't translate or dispatch */ + return TRUE; + } + break; + } + + /* If we get here, the message has not been treated specially */ + /* and can be sent to its destination window. */ + *dispatch = TRUE; + return TRUE; +} + + +/*********************************************************************** + * IsDialogMessage16 (USER.90) + */ +BOOL16 WINAPI WIN16_IsDialogMessage16( HWND16 hwndDlg, SEGPTR msg16 ) +{ + LPMSG16 msg = PTR_SEG_TO_LIN(msg16); + WINBOOL ret, translate, dispatch; + INT32 dlgCode; + + if ((hwndDlg != msg->hwnd) && !IsChild16( hwndDlg, msg->hwnd )) + return FALSE; + + dlgCode = SendMessage16( msg->hwnd, WM_GETDLGCODE, 0, (LPARAM)msg16); + ret = DIALOG_IsDialogMessage( msg->hwnd, hwndDlg, msg->message, + msg->wParam, msg->lParam, + &translate, &dispatch, dlgCode ); + if (translate) TranslateMessage16( msg ); + if (dispatch) DispatchMessage16( msg ); + return ret; +} + + +BOOL16 WINAPI IsDialogMessage16( HWND16 hwndDlg, LPMSG16 msg ) +{ + LPMSG16 msg16 = SEGPTR_NEW(MSG16); + WINBOOL ret; + + *msg16 = *msg; + ret = WIN16_IsDialogMessage16( hwndDlg, SEGPTR_GET(msg16) ); + SEGPTR_FREE(msg16); + return ret; +} + +/*********************************************************************** + * IsDialogMessage32A (USER32.342) + */ +WINBOOL WINAPI IsDialogMessage32A( HWND32 hwndDlg, LPMSG32 msg ) +{ + WINBOOL ret, translate, dispatch; + INT32 dlgCode; + + if ((hwndDlg != msg->hwnd) && !IsChild32( hwndDlg, msg->hwnd )) + return FALSE; + + dlgCode = SendMessage32A( msg->hwnd, WM_GETDLGCODE, 0, (LPARAM)msg); + ret = DIALOG_IsDialogMessage( msg->hwnd, hwndDlg, msg->message, + msg->wParam, msg->lParam, + &translate, &dispatch, dlgCode ); + if (translate) TranslateMessage32( msg ); + if (dispatch) DispatchMessage32A( msg ); + return ret; +} + + +/*********************************************************************** + * IsDialogMessage32W (USER32.343) + */ +WINBOOL WINAPI IsDialogMessage32W( HWND32 hwndDlg, LPMSG32 msg ) +{ + WINBOOL ret, translate, dispatch; + INT32 dlgCode; + + if ((hwndDlg != msg->hwnd) && !IsChild32( hwndDlg, msg->hwnd )) + return FALSE; + + dlgCode = SendMessage32W( msg->hwnd, WM_GETDLGCODE, 0, (LPARAM)msg); + ret = DIALOG_IsDialogMessage( msg->hwnd, hwndDlg, msg->message, + msg->wParam, msg->lParam, + &translate, &dispatch, dlgCode ); + if (translate) TranslateMessage32( msg ); + if (dispatch) DispatchMessage32W( msg ); + return ret; +} + + +/**************************************************************** + * GetDlgCtrlID16 (USER.277) + */ +INT16 WINAPI GetDlgCtrlID16( HWND16 hwnd ) +{ + WND *wndPtr = WIN_FindWndPtr(hwnd); + if (wndPtr) return wndPtr->wIDmenu; + else return 0; +} + + +/**************************************************************** + * GetDlgCtrlID32 (USER32.234) + */ +INT32 WINAPI GetDlgCtrlID32( HWND32 hwnd ) +{ + WND *wndPtr = WIN_FindWndPtr(hwnd); + if (wndPtr) return wndPtr->wIDmenu; + else return 0; +} + + +/*********************************************************************** + * GetDlgItem16 (USER.91) + */ +HWND16 WINAPI GetDlgItem16( HWND16 hwndDlg, INT16 id ) +{ + WND *pWnd; + + if (!(pWnd = WIN_FindWndPtr( hwndDlg ))) return 0; + for (pWnd = pWnd->child; pWnd; pWnd = pWnd->next) + if (pWnd->wIDmenu == (UINT16)id) return pWnd->hwndSelf; + return 0; +} + + +/*********************************************************************** + * GetDlgItem32 (USER32.235) + */ +HWND32 WINAPI GetDlgItem32( HWND32 hwndDlg, INT32 id ) +{ + WND *pWnd; + + if (!(pWnd = WIN_FindWndPtr( hwndDlg ))) return 0; + for (pWnd = pWnd->child; pWnd; pWnd = pWnd->next) + if (pWnd->wIDmenu == (UINT16)id) return pWnd->hwndSelf; + return 0; +} + + +/******************************************************************* + * SendDlgItemMessage16 (USER.101) + */ +LRESULT WINAPI SendDlgItemMessage16( HWND16 hwnd, INT16 id, UINT16 msg, + WPARAM16 wParam, LPARAM lParam ) +{ + HWND16 hwndCtrl = GetDlgItem16( hwnd, id ); + if (hwndCtrl) return SendMessage16( hwndCtrl, msg, wParam, lParam ); + else return 0; +} + + +/******************************************************************* + * SendDlgItemMessage32A (USER32.452) + */ +LRESULT WINAPI SendDlgItemMessage32A( HWND32 hwnd, INT32 id, UINT32 msg, + WPARAM32 wParam, LPARAM lParam ) +{ + HWND32 hwndCtrl = GetDlgItem32( hwnd, id ); + if (hwndCtrl) return SendMessage32A( hwndCtrl, msg, wParam, lParam ); + else return 0; +} + + +/******************************************************************* + * SendDlgItemMessage32W (USER32.453) + */ +LRESULT WINAPI SendDlgItemMessage32W( HWND32 hwnd, INT32 id, UINT32 msg, + WPARAM32 wParam, LPARAM lParam ) +{ + HWND32 hwndCtrl = GetDlgItem32( hwnd, id ); + if (hwndCtrl) return SendMessage32W( hwndCtrl, msg, wParam, lParam ); + else return 0; +} + + +/******************************************************************* + * SetDlgItemText16 (USER.92) + */ +void WINAPI SetDlgItemText16( HWND16 hwnd, INT16 id, SEGPTR lpString ) +{ + SendDlgItemMessage16( hwnd, id, WM_SETTEXT, 0, (LPARAM)lpString ); +} + + +/******************************************************************* + * SetDlgItemText32A (USER32.478) + */ +WINBOOL WINAPI SetDlgItemText32A( HWND32 hwnd, INT32 id, LPCSTR lpString ) +{ + return SendDlgItemMessage32A( hwnd, id, WM_SETTEXT, 0, (LPARAM)lpString ); +} + + +/******************************************************************* + * SetDlgItemText32W (USER32.479) + */ +WINBOOL WINAPI SetDlgItemText32W( HWND32 hwnd, INT32 id, LPCWSTR lpString ) +{ + return SendDlgItemMessage32W( hwnd, id, WM_SETTEXT, 0, (LPARAM)lpString ); +} + + +/*********************************************************************** + * GetDlgItemText16 (USER.93) + */ +INT16 WINAPI GetDlgItemText16( HWND16 hwnd, INT16 id, SEGPTR str, UINT16 len ) +{ + return (INT16)SendDlgItemMessage16( hwnd, id, WM_GETTEXT, + len, (LPARAM)str ); +} + + +/*********************************************************************** + * GetDlgItemText32A (USER32.237) + */ +INT32 WINAPI GetDlgItemText32A( HWND32 hwnd, INT32 id, LPSTR str, UINT32 len ) +{ + return (INT32)SendDlgItemMessage32A( hwnd, id, WM_GETTEXT, + len, (LPARAM)str ); +} + + +/*********************************************************************** + * GetDlgItemText32W (USER32.238) + */ +INT32 WINAPI GetDlgItemText32W( HWND32 hwnd, INT32 id, LPWSTR str, UINT32 len ) +{ + return (INT32)SendDlgItemMessage32W( hwnd, id, WM_GETTEXT, + len, (LPARAM)str ); +} + + +/******************************************************************* + * SetDlgItemInt16 (USER.94) + */ +void WINAPI SetDlgItemInt16( HWND16 hwnd, INT16 id, UINT16 value, BOOL16 fSigned ) +{ + return SetDlgItemInt32( hwnd, (UINT32)(UINT16)id, value, fSigned ); +} + + +/******************************************************************* + * SetDlgItemInt32 (USER32.477) + */ +void WINAPI SetDlgItemInt32( HWND32 hwnd, INT32 id, UINT32 value, + WINBOOL fSigned ) +{ + char str[20]; + + if (fSigned) sprintf( str, "%d", (INT32)value ); + else sprintf( str, "%u", value ); + SendDlgItemMessage32A( hwnd, id, WM_SETTEXT, 0, (LPARAM)str ); +} + + +/*********************************************************************** + * GetDlgItemInt16 (USER.95) + */ +UINT16 WINAPI GetDlgItemInt16( HWND16 hwnd, INT16 id, BOOL16 *translated, + BOOL16 fSigned ) +{ + UINT32 result; + WINBOOL ok; + + if (translated) *translated = FALSE; + result = GetDlgItemInt32( hwnd, (UINT32)(UINT16)id, &ok, fSigned ); + if (!ok) return 0; + if (fSigned) + { + if (((INT32)result < -32767) || ((INT32)result > 32767)) return 0; + } + else + { + if (result > 65535) return 0; + } + if (translated) *translated = TRUE; + return (UINT16)result; +} + + +/*********************************************************************** + * GetDlgItemInt32 (USER32.236) + */ +UINT32 WINAPI GetDlgItemInt32( HWND32 hwnd, INT32 id, WINBOOL *translated, + WINBOOL fSigned ) +{ + char str[30]; + char * endptr; + long result = 0; + + if (translated) *translated = FALSE; + if (!SendDlgItemMessage32A(hwnd, id, WM_GETTEXT, sizeof(str), (LPARAM)str)) + return 0; + if (fSigned) + { + result = strtol( str, &endptr, 10 ); + if (!endptr || (endptr == str)) /* Conversion was unsuccessful */ + return 0; + if (((result == LONG_MIN) || (result == LONG_MAX)) && (errno==ERANGE)) + return 0; + } + else + { + result = strtoul( str, &endptr, 10 ); + if (!endptr || (endptr == str)) /* Conversion was unsuccessful */ + return 0; + if ((result == ULONG_MAX) && (errno == ERANGE)) return 0; + } + if (translated) *translated = TRUE; + return (UINT32)result; +} + + +/*********************************************************************** + * CheckDlgButton16 (USER.97) + */ +BOOL16 WINAPI CheckDlgButton16( HWND16 hwnd, INT16 id, UINT16 check ) +{ + SendDlgItemMessage32A( hwnd, id, BM_SETCHECK32, check, 0 ); + return TRUE; +} + + +/*********************************************************************** + * CheckDlgButton32 (USER32.45) + */ +WINBOOL WINAPI CheckDlgButton32( HWND32 hwnd, INT32 id, UINT32 check ) +{ + SendDlgItemMessage32A( hwnd, id, BM_SETCHECK32, check, 0 ); + return TRUE; +} + + +/*********************************************************************** + * IsDlgButtonChecked16 (USER.98) + */ +UINT16 WINAPI IsDlgButtonChecked16( HWND16 hwnd, UINT16 id ) +{ + return (UINT16)SendDlgItemMessage32A( hwnd, id, BM_GETCHECK32, 0, 0 ); +} + + +/*********************************************************************** + * IsDlgButtonChecked32 (USER32.344) + */ +UINT32 WINAPI IsDlgButtonChecked32( HWND32 hwnd, UINT32 id ) +{ + return (UINT32)SendDlgItemMessage32A( hwnd, id, BM_GETCHECK32, 0, 0 ); +} + + +/*********************************************************************** + * CheckRadioButton16 (USER.96) + */ +BOOL16 WINAPI CheckRadioButton16( HWND16 hwndDlg, UINT16 firstID, + UINT16 lastID, UINT16 checkID ) +{ + return CheckRadioButton32( hwndDlg, firstID, lastID, checkID ); +} + + +/*********************************************************************** + * CheckRadioButton32 (USER32.48) + */ +WINBOOL WINAPI CheckRadioButton32( HWND32 hwndDlg, UINT32 firstID, + UINT32 lastID, UINT32 checkID ) +{ + WND *pWnd = WIN_FindWndPtr( hwndDlg ); + if (!pWnd) return FALSE; + + for (pWnd = pWnd->child; pWnd; pWnd = pWnd->next) + if ((pWnd->wIDmenu == firstID) || (pWnd->wIDmenu == lastID)) break; + if (!pWnd) return FALSE; + + if (pWnd->wIDmenu == lastID) + lastID = firstID; /* Buttons are in reverse order */ + while (pWnd) + { + SendMessage32A( pWnd->hwndSelf, BM_SETCHECK32, + (pWnd->wIDmenu == checkID), 0 ); + if (pWnd->wIDmenu == lastID) break; + pWnd = pWnd->next; + } + return TRUE; +} + + +/*********************************************************************** + * GetDialogBaseUnits (USER.243) (USER32.233) + */ +DWORD WINAPI GetDialogBaseUnits(void) +{ + return MAKELONG( xBaseUnit, yBaseUnit ); +} + + +/*********************************************************************** + * MapDialogRect16 (USER.103) + */ +void WINAPI MapDialogRect16( HWND16 hwnd, LPRECT16 rect ) +{ + DIALOGINFO * dlgInfo; + WND * wndPtr = WIN_FindWndPtr( hwnd ); + if (!wndPtr) return; + dlgInfo = (DIALOGINFO *)wndPtr->wExtra; + rect->left = (rect->left * dlgInfo->xBaseUnit) / 4; + rect->right = (rect->right * dlgInfo->xBaseUnit) / 4; + rect->top = (rect->top * dlgInfo->yBaseUnit) / 8; + rect->bottom = (rect->bottom * dlgInfo->yBaseUnit) / 8; +} + + +/*********************************************************************** + * MapDialogRect32 (USER32.382) + */ +void WINAPI MapDialogRect32( HWND32 hwnd, LPRECT32 rect ) +{ + DIALOGINFO * dlgInfo; + WND * wndPtr = WIN_FindWndPtr( hwnd ); + if (!wndPtr) return; + dlgInfo = (DIALOGINFO *)wndPtr->wExtra; + rect->left = (rect->left * dlgInfo->xBaseUnit) / 4; + rect->right = (rect->right * dlgInfo->xBaseUnit) / 4; + rect->top = (rect->top * dlgInfo->yBaseUnit) / 8; + rect->bottom = (rect->bottom * dlgInfo->yBaseUnit) / 8; +} + + +/*********************************************************************** + * GetNextDlgGroupItem16 (USER.227) + */ +HWND16 WINAPI GetNextDlgGroupItem16( HWND16 hwndDlg, HWND16 hwndCtrl, + BOOL16 fPrevious ) +{ + return (HWND16)GetNextDlgGroupItem32( hwndDlg, hwndCtrl, fPrevious ); +} + + +/*********************************************************************** + * GetNextDlgGroupItem32 (USER32.275) + */ +HWND32 WINAPI GetNextDlgGroupItem32( HWND32 hwndDlg, HWND32 hwndCtrl, + WINBOOL fPrevious ) +{ + WND *pWnd, *pWndLast, *pWndCtrl, *pWndDlg; + + if (!(pWndDlg = WIN_FindWndPtr( hwndDlg ))) return 0; + if (hwndCtrl) + { + if (!(pWndCtrl = WIN_FindWndPtr( hwndCtrl ))) return 0; + /* Make sure hwndCtrl is a top-level child */ + while ((pWndCtrl->dwStyle & WS_CHILD) && (pWndCtrl->parent != pWndDlg)) + pWndCtrl = pWndCtrl->parent; + if (pWndCtrl->parent != pWndDlg) return 0; + } + else + { + /* No ctrl specified -> start from the beginning */ + if (!(pWndCtrl = pWndDlg->child)) return 0; + if (fPrevious) while (pWndCtrl->next) pWndCtrl = pWndCtrl->next; + } + + pWndLast = pWndCtrl; + pWnd = pWndCtrl->next; + while (1) + { + if (!pWnd || (pWnd->dwStyle & WS_GROUP)) + { + /* Wrap-around to the beginning of the group */ + WND *pWndStart = pWndDlg->child; + for (pWnd = pWndStart; pWnd; pWnd = pWnd->next) + { + if (pWnd->dwStyle & WS_GROUP) pWndStart = pWnd; + if (pWnd == pWndCtrl) break; + } + pWnd = pWndStart; + } + if (pWnd == pWndCtrl) break; + if ((pWnd->dwStyle & WS_VISIBLE) && !(pWnd->dwStyle & WS_DISABLED)) + { + pWndLast = pWnd; + if (!fPrevious) break; + } + pWnd = pWnd->next; + } + return pWndLast->hwndSelf; +} + + +/*********************************************************************** + * GetNextDlgTabItem16 (USER.228) + */ +HWND16 WINAPI GetNextDlgTabItem16( HWND16 hwndDlg, HWND16 hwndCtrl, + BOOL16 fPrevious ) +{ + return (HWND16)GetNextDlgTabItem32( hwndDlg, hwndCtrl, fPrevious ); +} + + +/*********************************************************************** + * GetNextDlgTabItem32 (USER32.276) + */ +HWND32 WINAPI GetNextDlgTabItem32( HWND32 hwndDlg, HWND32 hwndCtrl, + WINBOOL fPrevious ) +{ + WND *pWnd, *pWndLast, *pWndCtrl, *pWndDlg; + + if (!(pWndDlg = WIN_FindWndPtr( hwndDlg ))) return 0; + if (hwndCtrl) + { + if (!(pWndCtrl = WIN_FindWndPtr( hwndCtrl ))) return 0; + /* Make sure hwndCtrl is a top-level child */ + while ((pWndCtrl->dwStyle & WS_CHILD) && (pWndCtrl->parent != pWndDlg)) + pWndCtrl = pWndCtrl->parent; + if (pWndCtrl->parent != pWndDlg) return 0; + } + else + { + /* No ctrl specified -> start from the beginning */ + if (!(pWndCtrl = pWndDlg->child)) return 0; + if (!fPrevious) while (pWndCtrl->next) pWndCtrl = pWndCtrl->next; + } + + pWndLast = pWndCtrl; + pWnd = pWndCtrl->next; + while (1) + { + if (!pWnd) pWnd = pWndDlg->child; + if (pWnd == pWndCtrl) break; + if ((pWnd->dwStyle & WS_TABSTOP) && (pWnd->dwStyle & WS_VISIBLE) && + !(pWnd->dwStyle & WS_DISABLED)) + { + pWndLast = pWnd; + if (!fPrevious) break; + } + pWnd = pWnd->next; + } + return pWndLast->hwndSelf; +} + diff --git a/reactos/lib/user32/windows/msgbox.c b/reactos/lib/user32/windows/msgbox.c new file mode 100644 index 00000000000..3a752edd99b --- /dev/null +++ b/reactos/lib/user32/windows/msgbox.c @@ -0,0 +1,292 @@ +#define UNICODE +#include +#include +#include + + +#define MB_TYPEMASK 0x0000000F +#define MB_ICONMASK 0x000000F0 +#define MB_DEFMASK 0x00000F00 + +LRESULT CALLBACK MSGBOX_DlgProc( HWND hwnd, UINT message, + WPARAM wParam, LPARAM lParam ); + + +// FIXME ????????? + /* Static text */ +#define stc1 0x0440 +/************************************************************************** + * MessageBoxA (USER.391) + * + * NOTES + * The WARN is here to help debug erroneous MessageBoxes + * Use: -debugmsg warn+dialog,+relay + */ +INT STDCALL MessageBoxA(HWND hWnd, LPCSTR text, LPCSTR title, UINT type) +{ + + return MessageBoxExA(hWnd,text,title,type,0); + +} + + +/************************************************************************** + * MessageBoxW (USER.396) + */ +INT STDCALL MessageBoxW( HWND hWnd, LPCWSTR text, LPCWSTR title, + UINT type ) +{ + return MessageBoxExW(hWnd,text,title,type,0); +} + + +/************************************************************************** + * MessageBoxExA (USER.392) + */ +INT STDCALL MessageBoxExA( HWND hWnd, LPCSTR text, LPCSTR title, + UINT type, WORD langid ) +{ + MSGBOXPARAMS mbox; + + if (title == NULL) + title="Error"; + if (text == NULL) + text=" "; + + mbox.lpszCaption = title; + mbox.lpszText = text; + mbox.dwStyle = type; + return DialogBoxIndirectParamA( WIN_GetWindowInstance(hWnd), + SYSRES_GetResPtr( SYSRES_DIALOG_MSGBOX ), + hWnd, MSGBOX_DlgProc, (LPARAM)&mbox ); +} + +/************************************************************************** + * MessageBoxExW (USER.393) + */ +INT STDCALL MessageBoxExW( HWND hWnd, LPCWSTR text, LPCWSTR title, + UINT type, WORD langid ) +{ + MSGBOXPARAMS mbox; + + if (title == NULL) + title=L"Error"; + if (text == NULL) + text=L" "; + + mbox.lpszCaption = title; + mbox.lpszText = text; + mbox.dwStyle = type; + return DialogBoxIndirectParamW( WIN_GetWindowInstance(hWnd), + SYSRES_GetResPtr( SYSRES_DIALOG_MSGBOX ), + hWnd, MSGBOX_DlgProc, (LPARAM)&mbox ); +} + + + +/************************************************************************** + * MessageBoxIndirectA (USER.394) + */ +INT STDCALL MessageBoxIndirectA( LPMSGBOXPARAMS msgbox ) +{ + + return DialogBoxIndirectParamA( msgbox->hInstance, + SYSRES_GetResPtr( SYSRES_DIALOG_MSGBOX ), + msgbox->hwndOwner, MSGBOX_DlgProc, + (LPARAM)msgbox ); +} + +/************************************************************************** + * MessageBoxIndirectW (USER.395) + */ +INT STDCALL MessageBoxIndirectW( LPMSGBOXPARAMS msgbox ) +{ + + return DialogBoxIndirectParamW( msgbox->hInstance, + SYSRES_GetResPtr( SYSRES_DIALOG_MSGBOX ), + msgbox->hwndOwner, MSGBOX_DlgProc, + (LPARAM)msgbox ); +} + +/************************************************************************** + * MSGBOX_DlgProc + * + * Dialog procedure for message boxes. + */ +LRESULT CALLBACK MSGBOX_DlgProc( HWND hwnd, UINT message, + WPARAM wParam, LPARAM lParam ) +{ + static HFONT hFont = 0; + LPMSGBOXPARAMS lpmb; + + RECT rect, textrect; + HWND hItem; + HDC hdc; + LRESULT lRet; + int i, buttons, bwidth, bheight, theight, wwidth, bpos; + int borheight, iheight, tiheight; + + NONCLIENTMETRICS nclm; + + switch(message) { + case WM_INITDIALOG: + lpmb = (LPMSGBOXPARAMS)lParam; + + nclm.cbSize = sizeof(NONCLIENTMETRICS); + SystemParametersInfoW (SPI_GETNONCLIENTMETRICS, 0, &nclm, 0); + hFont = CreateFontIndirect(&nclm.lfMessageFont); + /* set button font */ + for (i=1; i < 8; i++) + SendDlgItemMessageW (hwnd, i, WM_SETFONT, (WPARAM)hFont, 0); + /* set text font */ + SendDlgItemMessageW (hwnd, 100, WM_SETFONT, (WPARAM)hFont, 0); + + if (lpmb->lpszCaption) + SetWindowTextW(hwnd, lpmb->lpszCaption); + SetWindowTextW(GetDlgItem(hwnd, 100), lpmb->lpszText); + /* Hide not selected buttons */ + switch(lpmb->dwStyle & MB_TYPEMASK) { + case MB_OK: + ShowWindow(GetDlgItem(hwnd, 2), SW_HIDE); + /* fall through */ + case MB_OKCANCEL: + ShowWindow(GetDlgItem(hwnd, 3), SW_HIDE); + ShowWindow(GetDlgItem(hwnd, 4), SW_HIDE); + ShowWindow(GetDlgItem(hwnd, 5), SW_HIDE); + ShowWindow(GetDlgItem(hwnd, 6), SW_HIDE); + ShowWindow(GetDlgItem(hwnd, 7), SW_HIDE); + break; + case MB_ABORTRETRYIGNORE: + ShowWindow(GetDlgItem(hwnd, 1), SW_HIDE); + ShowWindow(GetDlgItem(hwnd, 2), SW_HIDE); + ShowWindow(GetDlgItem(hwnd, 6), SW_HIDE); + ShowWindow(GetDlgItem(hwnd, 7), SW_HIDE); + break; + case MB_YESNO: + ShowWindow(GetDlgItem(hwnd, 2), SW_HIDE); + /* fall through */ + case MB_YESNOCANCEL: + ShowWindow(GetDlgItem(hwnd, 1), SW_HIDE); + ShowWindow(GetDlgItem(hwnd, 3), SW_HIDE); + ShowWindow(GetDlgItem(hwnd, 4), SW_HIDE); + ShowWindow(GetDlgItem(hwnd, 5), SW_HIDE); + break; + } + /* Set the icon */ + switch(lpmb->dwStyle & MB_ICONMASK) { + case MB_ICONEXCLAMATION: + SendDlgItemMessage(hwnd, stc1, STM_SETICON, + (WPARAM)LoadIcon(0, IDI_EXCLAMATION), 0); + break; + case MB_ICONQUESTION: + SendDlgItemMessage(hwnd, stc1, STM_SETICON, + (WPARAM)LoadIcon(0, IDI_QUESTION), 0); + break; + case MB_ICONASTERISK: + SendDlgItemMessage(hwnd, stc1, STM_SETICON, + (WPARAM)LoadIcon(0, IDI_ASTERISK), 0); + break; + case MB_ICONHAND: + default: + SendDlgItemMessage(hwnd, stc1, STM_SETICON, + (WPARAM)LoadIcon(0, IDI_HAND), 0); + break; + } + + /* Position everything */ + GetWindowRect(hwnd, &rect); + borheight = rect.bottom - rect.top; + wwidth = rect.right - rect.left; + GetClientRect(hwnd, &rect); + borheight -= rect.bottom - rect.top; + + /* Get the icon height */ + GetWindowRect(GetDlgItem(hwnd, 1088), &rect); + iheight = rect.bottom - rect.top; + + /* Get the number of visible buttons and their width */ + GetWindowRect(GetDlgItem(hwnd, 2), &rect); + bheight = rect.bottom - rect.top; + bwidth = rect.left; + GetWindowRect(GetDlgItem(hwnd, 1), &rect); + bwidth -= rect.left; + for (buttons = 0, i = 1; i < 8; i++) + { + hItem = GetDlgItem(hwnd, i); + if (GetWindowLongW(hItem, GWL_STYLE) & WS_VISIBLE) + buttons++; + } + + /* Get the text size */ + hItem = GetDlgItem(hwnd, 100); + GetWindowRect(hItem, &textrect); + MapWindowPoints(0, hwnd, (LPPOINT)&textrect, 2); + + GetClientRect(hItem, &rect); + hdc = GetDC(hItem); + lRet = DrawTextW( hdc, lpmb->lpszText, -1, &rect, + DT_LEFT | DT_EXPANDTABS | DT_WORDBREAK | DT_CALCRECT); + theight = rect.bottom - rect.top; + tiheight = 16 + max(iheight, theight); + ReleaseDC(hItem, hdc); + + /* Position the text */ + SetWindowPos(hItem, 0, textrect.left, (tiheight - theight) / 2, + rect.right - rect.left, theight, + SWP_NOZORDER | SWP_NOACTIVATE | SWP_NOREDRAW); + + /* Position the icon */ + hItem = GetDlgItem(hwnd, 1088); + GetWindowRect(hItem, &rect); + MapWindowPoints(0, hwnd, (LPPOINT)&rect, 2); + SetWindowPos(hItem, 0, rect.left, (tiheight - iheight) / 2, 0, 0, + SWP_NOSIZE | SWP_NOZORDER | SWP_NOACTIVATE | SWP_NOREDRAW); + + /* Resize the window */ + SetWindowPos(hwnd, 0, 0, 0, wwidth, 8 + tiheight + bheight + borheight, + SWP_NOMOVE | SWP_NOZORDER | SWP_NOACTIVATE | SWP_NOREDRAW); + + /* Position the buttons */ + bpos = (wwidth - bwidth * buttons) / 2; + GetWindowRect(GetDlgItem(hwnd, 1), &rect); + for (buttons = i = 0; i < 7; i++) { + /* some arithmetic to get the right order for YesNoCancel windows */ + hItem = GetDlgItem(hwnd, (i + 5) % 7 + 1); + if (GetWindowLongW(hItem, GWL_STYLE) & WS_VISIBLE) { + if (buttons++ == ((lpmb->dwStyle & MB_DEFMASK) >> 8)) { + SetFocus(hItem); + SendMessageW( hItem, BM_SETSTYLE, BS_DEFPUSHBUTTON, TRUE ); + } + SetWindowPos(hItem, 0, bpos, tiheight, 0, 0, + SWP_NOSIZE|SWP_NOZORDER|SWP_NOACTIVATE|SWP_NOREDRAW); + bpos += bwidth; + } + } + return 0; + break; + + case WM_COMMAND: + switch (wParam) + { + case IDOK: + case IDCANCEL: + case IDABORT: + case IDRETRY: + case IDIGNORE: + case IDYES: + case IDNO: + if ( hFont) + DeleteObject (hFont); + EndDialog(hwnd, wParam); + break; + } + + default: + break; + } + return 0; +} + + + + diff --git a/reactos/lib/user32/windows/paint.c b/reactos/lib/user32/windows/paint.c index 8a27006cd06..108c9de22e0 100644 --- a/reactos/lib/user32/windows/paint.c +++ b/reactos/lib/user32/windows/paint.c @@ -18,73 +18,7 @@ /* Last CTLCOLOR id */ //#define CTLCOLOR_MAX CTLCOLOR_STATIC -#if 0 -/*********************************************************************** - * WIN_UpdateNCArea - * - */ -void WIN_UpdateNCArea(WND* wnd, BOOL bUpdate) -{ - POINT16 pt = {0, 0}; - HRGN hClip = 1; - TRACE(nonclient,"hwnd %04x, hrgnUpdate %04x\n", - wnd->hwndSelf, wnd->hrgnUpdate ); - - /* desktop window doesn't have nonclient area */ - if(wnd == WIN_GetDesktop()) - { - wnd->flags &= ~WIN_NEEDS_NCPAINT; - return; - } - - if( wnd->hrgnUpdate > 1 ) - { - ClientToScreen16(wnd->hwndSelf, &pt); - - hClip = CreateRectRgn( 0, 0, 0, 0 ); - if (!CombineRgn( hClip, wnd->hrgnUpdate, 0, RGN_COPY )) - { - DeleteObject(hClip); - hClip = 1; - } - else - OffsetRgn( hClip, pt.x, pt.y ); - - if (bUpdate) - { - /* exclude non-client area from update region */ - HRGN hrgn = CreateRectRgn( 0, 0, - wnd->rectClient.right - wnd->rectClient.left, - wnd->rectClient.bottom - wnd->rectClient.top); - - if (hrgn && (CombineRgn( wnd->hrgnUpdate, wnd->hrgnUpdate, - hrgn, RGN_AND) == NULLREGION)) - { - DeleteObject( wnd->hrgnUpdate ); - wnd->hrgnUpdate = 1; - } - - DeleteObject( hrgn ); - } - } - - wnd->flags &= ~WIN_NEEDS_NCPAINT; - - if ((wnd->hwndSelf == GetActiveWindow()) && - !(wnd->flags & WIN_NCACTIVATED)) - { - wnd->flags |= WIN_NCACTIVATED; - if( hClip > 1) DeleteObject( hClip ); - hClip = 1; - } - - if (hClip) SendMessage16( wnd->hwndSelf, WM_NCPAINT, hClip, 0L ); - - if (hClip > 1) DeleteObject( hClip ); -} - -#endif @@ -123,7 +57,7 @@ BeginPaint( if (wndPtr->class->style & CS_PARENTDC) { /* Don't clip the output to the update region for CS_PARENTDC window */ - if(hrgnUpdate > 1) + if(hrgnUpdate > (HRGN)1) DeleteObject(hrgnUpdate); lpPaint->hdc = GetDCEx( hWnd, 0, DCX_WINDOWPAINT | DCX_USESTYLE | (bIcon ? DCX_WINDOW : 0) ); @@ -250,7 +184,7 @@ WINBOOL STDCALL GetUpdateRect( HWND hwnd, LPRECT rect, WINBOOL erase ) if (rect) { - if (wndPtr->hrgnUpdate > 1) + if (wndPtr->hrgnUpdate > (HRGN)1) { HRGN hrgn = CreateRectRgn( 0, 0, 0, 0 ); if (GetUpdateRgn( hwnd, hrgn, erase ) == ERROR) return FALSE; @@ -298,7 +232,7 @@ INT STDCALL ExcludeUpdateRgn( HDC hdc, HWND hwnd ) wndPtr->rectWindow.top - wndPtr->rectClient.top, wndPtr->rectClient.right - wndPtr->rectClient.left, wndPtr->rectClient.bottom - wndPtr->rectClient.top); - if( wndPtr->hrgnUpdate > 1 ) + if( wndPtr->hrgnUpdate > (HRGN)1 ) CombineRgn(hrgn, wndPtr->hrgnUpdate, 0, RGN_COPY); /* do ugly coordinate translations in dce.c */ diff --git a/reactos/lib/user32/windows/win.c b/reactos/lib/user32/windows/win.c index db48105412f..269f36646b6 100644 --- a/reactos/lib/user32/windows/win.c +++ b/reactos/lib/user32/windows/win.c @@ -676,6 +676,10 @@ WINBOOL STDCALL ShowWindow( HWND hwnd, INT cmd ) MAKELONG(wndPtr->rectClient.left, wndPtr->rectClient.top) ); } + + // SendMessage(hwnd, WM_NCACTIVATE,TRUE,0); + // SendMessage(hwnd, WM_NCPAINT,CreateRectRgn(100,100,100, 100) ,0); + return wasVisible; } diff --git a/reactos/lib/user32/windows/winpos.c b/reactos/lib/user32/windows/winpos.c index c1a28cd4f12..d76fcdebf78 100644 --- a/reactos/lib/user32/windows/winpos.c +++ b/reactos/lib/user32/windows/winpos.c @@ -11,8 +11,9 @@ #include #include #include -//#include -//#include +#include +#include +#include #include HWND ICONTITLE_Create( WND *pWnd ); @@ -171,14 +172,298 @@ HWND SetActiveWindow(HWND hWnd ) return NULL; } - WINBOOL STDCALL -SetWindowPos(HWND hWnd, HWND hWndInsertAfter , - int X, int Y, - int cx, int cy, UINT flags) +SetWindowPos( + HWND hWnd, + HWND hWndInsertAfter , + int X, + int Y, + int cx, + int cy, + UINT flags) { - return FALSE; + WINDOWPOS winpos; + WND * wndPtr; + RECT newWindowRect, newClientRect, oldWindowRect; + HRGN visRgn = 0; + HWND tempInsertAfter= 0; + int result = 0; + UINT uFlags; + WINBOOL resync = FALSE; + + DPRINT("hwnd %04x, (%i,%i)-(%i,%i) flags %08x\n", + hWnd, X, Y, X+cx, Y+cy, flags); + /* Check window handle */ + + if (hWnd == GetDesktopWindow()) return FALSE; + if (!(wndPtr = WIN_FindWndPtr( hWnd ))) return FALSE; + + if(wndPtr->dwStyle & WS_VISIBLE) + flags &= ~SWP_SHOWWINDOW; + else + { + uFlags |= SMC_NOPARENTERASE; + flags &= ~SWP_HIDEWINDOW; + if (!(flags & SWP_SHOWWINDOW)) flags |= SWP_NOREDRAW; + } + +/* Check for windows that may not be resized + FIXME: this should be done only for Windows 3.0 programs + if (flags & (SWP_SHOWWINDOW | SWP_HIDEWINDOW ) ) + flags |= SWP_NOSIZE | SWP_NOMOVE; +*/ + /* Check dimensions */ + + if (cx <= 0) cx = 1; + if (cy <= 0) cy = 1; + + /* Check flags */ + + if (hWnd == hwndActive) flags |= SWP_NOACTIVATE; /* Already active */ + if ((wndPtr->rectWindow.right - wndPtr->rectWindow.left == cx) && + (wndPtr->rectWindow.bottom - wndPtr->rectWindow.top == cy)) + flags |= SWP_NOSIZE; /* Already the right size */ + if ((wndPtr->rectWindow.left == X) && (wndPtr->rectWindow.top == Y)) + flags |= SWP_NOMOVE; /* Already the right position */ + + /* Check hWndInsertAfter */ + + if (!(flags & (SWP_NOZORDER | SWP_NOACTIVATE))) + { + /* Ignore TOPMOST flags when activating a window */ + /* _and_ moving it in Z order. */ + if ((hWndInsertAfter == HWND_TOPMOST) || + (hWndInsertAfter == HWND_NOTOPMOST)) + hWndInsertAfter = HWND_TOP; + } + /* TOPMOST not supported yet */ + if ((hWndInsertAfter == HWND_TOPMOST) || + (hWndInsertAfter == HWND_NOTOPMOST)) hWndInsertAfter = HWND_TOP; + + /* hWndInsertAfter must be a sibling of the window */ + if ((hWndInsertAfter != HWND_TOP) && (hWndInsertAfter != HWND_BOTTOM)) + { + WND* wnd = WIN_FindWndPtr(hWndInsertAfter); + + if( wnd ) { + if( wnd->parent != wndPtr->parent ) return FALSE; + if( wnd->next == wndPtr ) flags |= SWP_NOZORDER; + } + } + else + { + /* FIXME: the following optimization is no good for "X-ed" windows */ + if (hWndInsertAfter == HWND_TOP && wndPtr->parent) + flags |= ( wndPtr->parent->child == wndPtr)? SWP_NOZORDER: 0; + else /* HWND_BOTTOM */ + flags |= ( wndPtr->next )? 0: SWP_NOZORDER; + } + + + /* Fill the WINDOWPOS structure */ + + winpos.hwnd = hWnd; + winpos.hwndInsertAfter = hWndInsertAfter; + winpos.x = X; + winpos.y = Y; + winpos.cx = cx; + winpos.cy = cy; + winpos.flags = flags; + + /* Send WM_WINDOWPOSCHANGING message */ + + if (!(winpos.flags & SWP_NOSENDCHANGING)) + SendMessageA( hWnd, WM_WINDOWPOSCHANGING, 0, (LPARAM)&winpos ); + + /* Calculate new position and size */ + + newWindowRect = wndPtr->rectWindow; + newClientRect = (wndPtr->dwStyle & WS_MINIMIZE) ? wndPtr->rectWindow + : wndPtr->rectClient; + + if (!(winpos.flags & SWP_NOSIZE)) + { + newWindowRect.right = newWindowRect.left + winpos.cx; + newWindowRect.bottom = newWindowRect.top + winpos.cy; + } + if (!(winpos.flags & SWP_NOMOVE)) + { + newWindowRect.left = winpos.x; + newWindowRect.top = winpos.y; + newWindowRect.right += winpos.x - wndPtr->rectWindow.left; + newWindowRect.bottom += winpos.y - wndPtr->rectWindow.top; + + OffsetRect( &newClientRect, winpos.x - wndPtr->rectWindow.left, + winpos.y - wndPtr->rectWindow.top ); + } + + winpos.flags |= SWP_NOCLIENTMOVE | SWP_NOCLIENTSIZE; + + /* Reposition window in Z order */ + + if (!(winpos.flags & SWP_NOZORDER)) + { + /* reorder owned popups if hwnd is top-level window + */ + if( wndPtr->parent == WIN_GetDesktop() ) + hWndInsertAfter = WINPOS_ReorderOwnedPopups( hWndInsertAfter, + wndPtr, winpos.flags ); + + // if (((X11DRV_WND_DATA *) wndPtr->pDriverData)->window) + //{ + // WIN_UnlinkWindow( winpos.hwnd ); + // WIN_LinkWindow( winpos.hwnd, hWndInsertAfter ); + //} + else WINPOS_MoveWindowZOrder( winpos.hwnd, hWndInsertAfter ); + } + + if ( !(winpos.flags & SWP_NOREDRAW) && + ((winpos.flags & (SWP_NOMOVE | SWP_NOSIZE | SWP_FRAMECHANGED)) + != (SWP_NOMOVE | SWP_NOSIZE)) ) + visRgn = DCE_GetVisRgn(hWnd, DCX_WINDOW | DCX_CLIPSIBLINGS); + + + /* Send WM_NCCALCSIZE message to get new client area */ + if( (winpos.flags & (SWP_FRAMECHANGED | SWP_NOSIZE)) != SWP_NOSIZE ) + { + result = WINPOS_SendNCCalcSize( winpos.hwnd, TRUE, &newWindowRect, + &wndPtr->rectWindow, &wndPtr->rectClient, + &winpos, &newClientRect ); + + /* FIXME: WVR_ALIGNxxx */ + + if( newClientRect.left != wndPtr->rectClient.left || + newClientRect.top != wndPtr->rectClient.top ) + winpos.flags &= ~SWP_NOCLIENTMOVE; + + if( (newClientRect.right - newClientRect.left != + wndPtr->rectClient.right - wndPtr->rectClient.left) || + (newClientRect.bottom - newClientRect.top != + wndPtr->rectClient.bottom - wndPtr->rectClient.top) ) + winpos.flags &= ~SWP_NOCLIENTSIZE; + } + else + if( !(flags & SWP_NOMOVE) && (newClientRect.left != wndPtr->rectClient.left || + newClientRect.top != wndPtr->rectClient.top) ) + winpos.flags &= ~SWP_NOCLIENTMOVE; + + /* Update active DCEs + * TODO: Optimize conditions that trigger DCE update. + */ + + if( (((winpos.flags & SWP_AGG_NOPOSCHANGE) != SWP_AGG_NOPOSCHANGE) && + wndPtr->dwStyle & WS_VISIBLE) || + (flags & (SWP_HIDEWINDOW | SWP_SHOWWINDOW)) ) + { + RECT rect; + + UnionRect(&rect, &newWindowRect, &wndPtr->rectWindow); + DCE_InvalidateDCE(wndPtr, &rect); + } + + /* change geometry */ + + oldWindowRect = wndPtr->rectWindow; + { + RECT oldClientRect = wndPtr->rectClient; + + wndPtr->rectWindow = newWindowRect; + wndPtr->rectClient = newClientRect; + + if( oldClientRect.bottom - oldClientRect.top == + newClientRect.bottom - newClientRect.top ) result &= ~WVR_VREDRAW; + + if( oldClientRect.right - oldClientRect.left == + newClientRect.right - newClientRect.left ) result &= ~WVR_HREDRAW; + + if( !(flags & (SWP_NOREDRAW | SWP_HIDEWINDOW | SWP_SHOWWINDOW)) ) + { + uFlags |= ((winpos.flags & SWP_NOCOPYBITS) || + (result >= WVR_HREDRAW && result < WVR_VALIDRECTS)) ? SMC_NOCOPY : 0; + uFlags |= (winpos.flags & SWP_FRAMECHANGED) ? SMC_DRAWFRAME : 0; + + if( (winpos.flags & SWP_AGG_NOGEOMETRYCHANGE) != SWP_AGG_NOGEOMETRYCHANGE ) + uFlags = WINPOS_SizeMoveClean(wndPtr, visRgn, &oldWindowRect, + &oldClientRect, uFlags); + else + { + /* adjust the frame and do not erase the parent */ + + if( winpos.flags & SWP_FRAMECHANGED ) wndPtr->flags |= WIN_NEEDS_NCPAINT; + if( winpos.flags & SWP_NOZORDER ) uFlags |= SMC_NOPARENTERASE; + } + } + DeleteObject(visRgn); + } + + if (flags & SWP_SHOWWINDOW) + { + wndPtr->dwStyle |= WS_VISIBLE; + + { + if (!(flags & SWP_NOREDRAW)) + PAINT_RedrawWindow( winpos.hwnd, NULL, 0, + RDW_INVALIDATE | RDW_ALLCHILDREN | + RDW_FRAME | RDW_ERASENOW | RDW_ERASE, 0 ); + } + } + else if (flags & SWP_HIDEWINDOW) + { + wndPtr->dwStyle &= ~WS_VISIBLE; + + + + if (!(flags & SWP_NOREDRAW)) + PAINT_RedrawWindow( wndPtr->parent->hwndSelf, &oldWindowRect, + 0, RDW_INVALIDATE | RDW_ALLCHILDREN | + RDW_ERASE | RDW_ERASENOW, 0 ); + uFlags |= SMC_NOPARENTERASE; + + + if ((winpos.hwnd == GetFocus()) || + IsChild( winpos.hwnd, GetFocus())) + { + /* Revert focus to parent */ + SetFocus( GetParent(winpos.hwnd) ); + } + if (hWnd == CARET_GetHwnd()) DestroyCaret(); + + if (winpos.hwnd == hwndActive) + WINPOS_ActivateOtherWindow( wndPtr ); + } + + /* Activate the window */ + + if (!(flags & SWP_NOACTIVATE)) + WINPOS_ChangeActiveWindow( winpos.hwnd, FALSE ); + + /* Repaint the window */ + + // if (((X11DRV_WND_DATA *) wndPtr->pDriverData)->window) + // EVENT_Synchronize(); /* Wait for all expose events */ + + //if (!GetCapture()) + // EVENT_DummyMotionNotify(); /* Simulate a mouse event to set the cursor */ + + if (wndPtr->parent && !(flags & SWP_DEFERERASE) && !(uFlags & SMC_NOPARENTERASE) ) + PAINT_RedrawWindow( wndPtr->parent->hwndSelf, NULL, 0, RDW_ALLCHILDREN | RDW_ERASENOW, 0 ); + else if(wndPtr->parent && wndPtr->parent == WIN_GetDesktop() && wndPtr->parent->flags & WIN_NEEDS_ERASEBKGND ) + PAINT_RedrawWindow( wndPtr->parent->hwndSelf, NULL, 0, RDW_NOCHILDREN | RDW_ERASENOW, 0 ); + + /* And last, send the WM_WINDOWPOSCHANGED message */ + + DPRINT("\tstatus flags = %04x\n", winpos.flags & SWP_AGG_STATUSFLAGS); + + if ( resync || + (((winpos.flags & SWP_AGG_STATUSFLAGS) != SWP_AGG_NOPOSCHANGE) && + !(winpos.flags & SWP_NOSENDCHANGING)) ) + { + SendMessageA( winpos.hwnd, WM_WINDOWPOSCHANGED, 0, (LPARAM)&winpos ); + //if (resync) EVENT_Synchronize (); + } + + return TRUE; } @@ -466,7 +751,7 @@ WINBOOL WINPOS_ShowIconTitle( WND* pWnd, WINBOOL bShow ) { HWND hWnd = lpPos->hwndIconTitle; - //TRACE(win,"0x%04x %i\n", pWnd->hwndSelf, (bShow != 0) ); + //DPRINT("0x%04x %i\n", pWnd->hwndSelf, (bShow != 0) ); // if( !hWnd ) // lpPos->hwndIconTitle = hWnd = ICONTITLE_Create( pWnd ); @@ -570,7 +855,7 @@ UINT WINPOS_MinMaximize( WND* wndPtr, UINT cmd, LPRECT lpRect ) &wndPtr->rectWindow ); - //TRACE(win,"0x%04x %u\n", wndPtr->hwndSelf, cmd ); + //DPRINT("0x%04x %u\n", wndPtr->hwndSelf, cmd ); if ( wndPtr->class->bUnicode ) { if (HOOK_CallHooksW(WH_CBT, HCBT_MINMAX, (INT)wndPtr->hwndSelf, cmd)) { @@ -1101,7 +1386,7 @@ UINT WINPOS_SizeMoveClean( WND* Wnd, HRGN oldVisRgn, /* Blt valid bits using parent window DC */ - if( my != NULLREGION && (xfrom != xto || yfrom != yto) ) + if( Wnd->parent && my != NULLREGION && (xfrom != xto || yfrom != yto) ) { /* compute clipping region in parent client coordinates */ @@ -1114,9 +1399,10 @@ UINT WINPOS_SizeMoveClean( WND* Wnd, HRGN oldVisRgn, hDC = GetDCEx( Wnd->parent->hwndSelf, oldVisRgn, DCX_INTERSECTRGN | DCX_CACHE | DCX_CLIPSIBLINGS); - + BitBlt( hDC, xto, yto, width, height, hDC, xfrom, yfrom, SRCCOPY ); ReleaseDC( Wnd->parent->hwndSelf, hDC); + } if( update != NULLREGION )