/*
 * Dialog functions
 *
 * Copyright 1993, 1994 Alexandre Julliard
 */


static char Copyright[] = "Copyright  Alexandre Julliard, 1993, 1994";

#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include "windows.h"
#include "dialog.h"
#include "win.h"
#include "user.h"
#include "message.h"
#include "heap.h"
#include "stddebug.h"
/* #define DEBUG_DIALOG */
/* #undef  DEBUG_DIALOG */
#include "debug.h"


  /* Dialog base units */
static WORD xBaseUnit = 0, yBaseUnit = 0;


/***********************************************************************
 *           DIALOG_Init
 *
 * Initialisation of the dialog manager.
 */
BOOL DIALOG_Init()
{
    TEXTMETRIC tm;
    HDC hdc;
    
      /* Calculate the dialog base units */

    if (!(hdc = GetDC(GetDesktopWindow()))) return FALSE;
    GetTextMetrics( hdc, &tm );
    ReleaseDC( 0, hdc );
    xBaseUnit = tm.tmAveCharWidth;
    yBaseUnit = tm.tmHeight;
    dprintf_dialog(stddeb, "DIALOG_Init: base units = %d,%d\n", xBaseUnit, yBaseUnit );
    return TRUE;
}


/***********************************************************************
 *           DIALOG_GetFirstTabItem
 *
 * Return the first item of the dialog that has the WS_TABSTOP style.
 */
HWND DIALOG_GetFirstTabItem( HWND hwndDlg )
{
    HWND hwnd;
    WND *wndPtr = WIN_FindWndPtr( hwndDlg );
    hwnd = wndPtr->hwndChild;
    while(hwnd)
    {
        wndPtr = WIN_FindWndPtr( hwnd );
        if (wndPtr->dwStyle & WS_TABSTOP) break;
        hwnd = wndPtr->hwndNext;
    }
    return hwnd;
}


/***********************************************************************
 *           DIALOG_GetControl
 *
 * Return the class and text of the control pointed to by ptr,
 * and return a pointer to the next control.
 */
static DLGCONTROLHEADER * DIALOG_GetControl( DLGCONTROLHEADER * ptr,
					     char ** class, char ** text )
{
    unsigned char * p = (unsigned char *)ptr;
    p += 14;  /* size of control header */

    if (*p & 0x80)
    {
	switch(*p++)
	{
	case 0x80: *class = "BUTTON"; break;
	case 0x81: *class = "EDIT"; break;
	case 0x82: *class = "STATIC"; break;
	case 0x83: *class = "LISTBOX"; break;
	case 0x84: *class = "SCROLLBAR"; break;
	case 0x85: *class = "COMBOBOX"; break;
	default:   *class = ""; break;
	}
    }
    else 
    {
	*class = p;
	p += strlen(p) + 1;
    }
    if (*p == 0xff)
    {
	  /* Integer id, not documented (?). Only works for SS_ICON controls */
	*text = (char *)MAKEINTRESOURCE( p[1] + 256*p[2] );
	p += 4;
    }
    else
    {
	*text = p;
	p += strlen(p) + 2;
    }
    return (DLGCONTROLHEADER *)p;
}


/***********************************************************************
 *           DIALOG_ParseTemplate
 *
 * Fill a DLGTEMPLATE structure from the dialog template, and return
 * a pointer to the first control.
 */
static DLGCONTROLHEADER * DIALOG_ParseTemplate( LPCSTR template,
					        DLGTEMPLATE * result )
{
    unsigned char * p = (unsigned char *)template;
 
    result->header = (DLGTEMPLATEHEADER *)p;
    p += 13;

    result->menuName = p;
    if (*p == 0xff) p += 3;
    else p += strlen(p) + 1;

    if (*p) result->className = p;
    else result->className = DIALOG_CLASS_NAME;
    p += strlen(p) + 1;

    result->caption = p;
    p += strlen(p) + 1;

    if (result->header->style & DS_SETFONT)
    {
	result->pointSize = *(WORD *)p;	p += sizeof(WORD);
	result->faceName = p;           p += strlen(p) + 1;
    }

    return (DLGCONTROLHEADER *)p;
}


/***********************************************************************
 *           DIALOG_DisplayTemplate
 */
#ifdef DEBUG_DIALOG
static void DIALOG_DisplayTemplate( DLGTEMPLATE * result )
{
    dprintf_dialog(stddeb, "DIALOG %d, %d, %d, %d\n", result->header->x, result->header->y,
	    result->header->cx, result->header->cy );
    dprintf_dialog(stddeb, " STYLE %08x\n", result->header->style );
    dprintf_dialog(stddeb, " CAPTION '%s'\n", result->caption );
    dprintf_dialog(stddeb, " CLASS '%s'\n", result->className );
    if (result->menuName[0] == 0xff)
	dprintf_dialog(stddeb, " MENU %d\n", result->menuName[1] + 256*result->menuName[2] );
    else 
        dprintf_dialog(stddeb, " MENU '%s'\n", result->menuName );
    if (result->header->style & DS_SETFONT)
	dprintf_dialog(stddeb, " FONT %d,'%s'\n", result->pointSize, result->faceName );
}
#endif  /* DEBUG_DIALOG */


/***********************************************************************
 *           CreateDialog   (USER.89)
 */
HWND CreateDialog( HINSTANCE hInst, LPCSTR dlgTemplate,
		   HWND owner, WNDPROC dlgProc )
{
    return CreateDialogParam( hInst, dlgTemplate, owner, dlgProc, 0 );
}


/***********************************************************************
 *           CreateDialogParam   (USER.241)
 */
HWND CreateDialogParam( HINSTANCE hInst, LPCSTR dlgTemplate,
		        HWND owner, WNDPROC dlgProc, LPARAM param )
{
    HWND hwnd = 0;
    HANDLE hres, hmem;
    LPCSTR data;

    dprintf_dialog(stddeb, "CreateDialogParam: %d,'%p',%d,%p,%ld\n",
	    hInst, dlgTemplate, owner, dlgProc, param );
     
      /* FIXME: MAKEINTRESOURCE should be replaced by RT_DIALOG */
    if (!(hres = FindResource( hInst, dlgTemplate, MAKEINTRESOURCE(0x8005) )))
	return 0;
    if (!(hmem = LoadResource( hInst, hres ))) return 0;
    if (!(data = LockResource( hmem ))) hwnd = 0;
    else hwnd = CreateDialogIndirectParam(hInst, data, owner, dlgProc, param);
    FreeResource( hmem );
    return hwnd;
}


/***********************************************************************
 *           CreateDialogIndirect   (USER.219)
 */
HWND CreateDialogIndirect( HINSTANCE hInst, LPCSTR dlgTemplate,
			   HWND owner, WNDPROC dlgProc )
{
    return CreateDialogIndirectParam( hInst, dlgTemplate, owner, dlgProc, 0 );
}


/***********************************************************************
 *           CreateDialogIndirectParam   (USER.242)
 */
HWND CreateDialogIndirectParam( HINSTANCE hInst, LPCSTR dlgTemplate,
			        HWND owner, WNDPROC dlgProc, LPARAM param )
{
    HMENU hMenu;
    HFONT hFont = 0;
    HWND hwnd, hwndCtrl;
    RECT rect;
    WND * wndPtr;
    int i;
    DLGTEMPLATE template;
    DLGCONTROLHEADER * header;
    DIALOGINFO * dlgInfo;
    DWORD exStyle = 0;
    WORD xUnit = xBaseUnit;
    WORD yUnit = yBaseUnit;

      /* Parse dialog template */

    if (!dlgTemplate) return 0;
    header = DIALOG_ParseTemplate( dlgTemplate, &template );
#ifdef DEBUG_DIALOG
    DIALOG_DisplayTemplate( &template );
#endif    

      /* Load menu */

    switch (template.menuName[0])
    {
      case 0x00:
	  hMenu = 0;
	  break;
      case 0xff:
	  hMenu = LoadMenu( hInst, MAKEINTRESOURCE( template.menuName[1] +
						   256*template.menuName[2] ));
	  break;
      default:
	  hMenu = LoadMenu( hInst, template.menuName );
	  break;
    }

      /* Create custom font if needed */

    if (template.header->style & DS_SETFONT)
    {
	hFont = CreateFont( template.pointSize, 0, 0, 0, FW_DONTCARE,
			    FALSE, FALSE, FALSE, DEFAULT_CHARSET, 0, 0,
			    DEFAULT_QUALITY, FF_DONTCARE, template.faceName );
	if (hFont)
	{
	    TEXTMETRIC tm;
	    HFONT oldFont;
	    HDC hdc;

	    hdc = GetDC(0);
	    oldFont = SelectObject( hdc, hFont );
	    GetTextMetrics( hdc, &tm );
	    SelectObject( hdc, oldFont );
	    ReleaseDC( 0, hdc );
	    xUnit = tm.tmAveCharWidth;
	    yUnit = tm.tmHeight;
	}
    }
    
      /* Create dialog main window */

    rect.left = rect.top = 0;
    if (!(template.header->style & DS_ABSALIGN))
	ClientToScreen( owner, (POINT *)&rect );
    rect.right = rect.left + template.header->cx * xUnit / 4;
    rect.bottom = rect.top + template.header->cy * yUnit / 8;
    if (template.header->style & DS_MODALFRAME) exStyle |= WS_EX_DLGMODALFRAME;
    AdjustWindowRectEx( &rect, template.header->style, hMenu, exStyle );

    hwnd = CreateWindowEx( exStyle, template.className, template.caption,
			   template.header->style,
			   rect.left + template.header->x * xUnit / 4,
			   rect.top + template.header->y * yUnit / 8,
			   rect.right - rect.left, rect.bottom - rect.top,
			   owner, hMenu, hInst,
			   NULL );
    if (!hwnd)
    {
	if (hFont) DeleteObject( hFont );
	if (hMenu) DestroyMenu( hMenu );
	return 0;
    }

      /* Create control windows */

    dprintf_dialog(stddeb, " BEGIN\n" );

    wndPtr = WIN_FindWndPtr( hwnd );
    dlgInfo = (DIALOGINFO *)wndPtr->wExtra;
    dlgInfo->msgResult = 0;  /* This is used to store the default button id */
    dlgInfo->hDialogHeap = 0;

    for (i = 0; i < template.header->nbItems; i++)
    {
	DLGCONTROLHEADER * next_header;
	LPSTR class, text;
        HWND hwndDefButton = 0;
	next_header = DIALOG_GetControl( header, &class, &text );

	dprintf_dialog(stddeb, "   %s ", class);
	if ((int)text & 0xffff0000) 
	  dprintf_dialog(stddeb,"'%s'", text);
	else 
	  dprintf_dialog(stddeb,"%4X", (int)text & 0xffff);
	dprintf_dialog(stddeb," %d, %d, %d, %d, %d, %08lx\n", 
		header->id, header->x, header->y, 
		header->cx, header->cy, header->style );

	if ((strcmp(class, "EDIT") == 0) &&
	            ((header->style & DS_LOCALEDIT) != DS_LOCALEDIT)) {
	    if (!dlgInfo->hDialogHeap) {
		dlgInfo->hDialogHeap = GlobalAlloc(GMEM_FIXED, 0x10000);
		if (!dlgInfo->hDialogHeap) {
		    fprintf(stderr,"CreateDialogIndirectParam: Insufficient memory to create heap for edit control\n");
		    continue;
		}
		HEAP_LocalInit(dlgInfo->hDialogHeap, GlobalLock(dlgInfo->hDialogHeap), 0x10000);
	    }
	    header->style |= WS_CHILD;
	    hwndCtrl = CreateWindowEx( WS_EX_NOPARENTNOTIFY, 
                           class, text, header->style,
                           header->x * xUnit / 4, header->y * yUnit / 8,
                           header->cx * xUnit / 4, header->cy * yUnit / 8,
                           hwnd, header->id, dlgInfo->hDialogHeap, NULL );
	}
	else
        {
	    header->style |= WS_CHILD;
	    hwndCtrl = CreateWindowEx( WS_EX_NOPARENTNOTIFY, 
                                class, text, header->style,
                                header->x * xUnit / 4, header->y * yUnit / 8,
                                header->cx * xUnit / 4, header->cy * yUnit / 8,
                                hwnd, header->id, hInst, NULL );
	}
            /* Send initialisation messages to the control */
        if (hFont) SendMessage( hwndCtrl, WM_SETFONT, hFont, 0 );
        if (SendMessage( 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)
                SendMessage( hwndDefButton, BM_SETSTYLE, BS_PUSHBUTTON, FALSE);
            hwndDefButton = hwndCtrl;
            dlgInfo->msgResult = header->id;
        }
	header = next_header;
    }    

    dprintf_dialog(stddeb, " END\n" );
    
      /* Initialise dialog extra data */

    dlgInfo->dlgProc   = dlgProc;
    dlgInfo->hUserFont = hFont;
    dlgInfo->hMenu     = hMenu;
    dlgInfo->xBaseUnit = xUnit;
    dlgInfo->yBaseUnit = yUnit;
    dlgInfo->hwndFocus = DIALOG_GetFirstTabItem( hwnd );

      /* Send initialisation messages and set focus */

    if (dlgInfo->hUserFont)
	SendMessage( hwnd, WM_SETFONT, dlgInfo->hUserFont, 0 );
    if (SendMessage( hwnd, WM_INITDIALOG, dlgInfo->hwndFocus, param ))
	SetFocus( dlgInfo->hwndFocus );

    return hwnd;
}


/***********************************************************************
 *           DIALOG_DoDialogBox
 */
static int DIALOG_DoDialogBox( HWND hwnd, HWND owner )
{
    WND * wndPtr;
    DIALOGINFO * dlgInfo;
    HANDLE msgHandle;
    MSG* lpmsg;
    int retval;

      /* Owner must be a top-level window */
    while (owner && GetParent(owner)) owner = GetParent(owner);
    if (!(wndPtr = WIN_FindWndPtr( hwnd ))) return -1;
    if (!(msgHandle = USER_HEAP_ALLOC( GMEM_MOVEABLE, sizeof(MSG)))) return -1;
    lpmsg = (MSG *) USER_HEAP_ADDR( msgHandle );
    dlgInfo = (DIALOGINFO *)wndPtr->wExtra;
    EnableWindow( owner, FALSE );
    ShowWindow( hwnd, SW_SHOW );

    while (MSG_InternalGetMessage( lpmsg, hwnd, owner,
                                   MSGF_DIALOGBOX, PM_REMOVE,
                                   !(wndPtr->dwStyle & DS_NOIDLEMSG) ))
    {
	if (!IsDialogMessage( hwnd, lpmsg))
	{
	    TranslateMessage( lpmsg );
	    DispatchMessage( lpmsg );
	}
	if (dlgInfo->fEnd) break;
    }
    retval = dlgInfo->msgResult;
    DestroyWindow( hwnd );
    USER_HEAP_FREE( msgHandle );
    EnableWindow( owner, TRUE );
    return retval;
}


/***********************************************************************
 *           DialogBox   (USER.87)
 */
int DialogBox( HINSTANCE hInst, LPCSTR dlgTemplate,
	       HWND owner, WNDPROC dlgProc )
{
    return DialogBoxParam( hInst, dlgTemplate, owner, dlgProc, 0 );
}


/***********************************************************************
 *           DialogBoxParam   (USER.239)
 */
int DialogBoxParam( HINSTANCE hInst, LPCSTR dlgTemplate,
		    HWND owner, WNDPROC dlgProc, LPARAM param )
{
    HWND hwnd;
    
    dprintf_dialog(stddeb, "DialogBoxParam: %d,'%x',%d,%p,%d\n",
	    hInst, dlgTemplate, owner, dlgProc, param );
    hwnd = CreateDialogParam( hInst, dlgTemplate, owner, dlgProc, param );
    if (hwnd) return DIALOG_DoDialogBox( hwnd, owner );
    return -1;
}


/***********************************************************************
 *           DialogBoxIndirect   (USER.218)
 */
int DialogBoxIndirect( HINSTANCE hInst, HANDLE dlgTemplate,
		       HWND owner, WNDPROC dlgProc )
{
    return DialogBoxIndirectParam( hInst, dlgTemplate, owner, dlgProc, 0 );
}


/***********************************************************************
 *           DialogBoxIndirectParam   (USER.240)
 */
int DialogBoxIndirectParam( HINSTANCE hInst, HANDLE dlgTemplate,
			    HWND owner, WNDPROC dlgProc, LPARAM param )
{
    HWND hwnd;
    LPCSTR ptr;

    if (!(ptr = GlobalLock( dlgTemplate ))) return -1;
    hwnd = CreateDialogIndirectParam( hInst, ptr, owner, dlgProc, param );
    GlobalUnlock( dlgTemplate );
    if (hwnd) return DIALOG_DoDialogBox( hwnd, owner );
    return -1;
}


/***********************************************************************
 *           EndDialog   (USER.88)
 */
void EndDialog( HWND hwnd, short retval )
{
    WND * wndPtr = WIN_FindWndPtr( hwnd );
    DIALOGINFO * dlgInfo = (DIALOGINFO *)wndPtr->wExtra;
    dlgInfo->msgResult = retval;
    dlgInfo->fEnd = TRUE;
    dprintf_dialog(stddeb, "EndDialog: %d %d\n", hwnd, retval );
}


/***********************************************************************
 *           IsDialogMessage   (USER.90)
 */
BOOL IsDialogMessage( HWND hwndDlg, LPMSG msg )
{
    WND * wndPtr;
    int dlgCode;

    if (!(wndPtr = WIN_FindWndPtr( hwndDlg ))) return FALSE;
    if ((hwndDlg != msg->hwnd) && !IsChild( hwndDlg, msg->hwnd )) return FALSE;

      /* Only the key messages get special processing */
    if ((msg->message == WM_KEYDOWN) ||
        (msg->message == WM_SYSCHAR) ||
	(msg->message == WM_CHAR))
    {
	dlgCode = SendMessage( msg->hwnd, WM_GETDLGCODE, 0, 0 );
        if (dlgCode & DLGC_WANTMESSAGE)
        {
            DispatchMessage( msg );
            return TRUE;
        }
    }

    switch(msg->message)
    {
    case WM_KEYDOWN:
        if (dlgCode & DLGC_WANTALLKEYS) break;
        switch(msg->wParam)
        {
        case VK_TAB:
            if (!(dlgCode & DLGC_WANTTAB))
            {
                SendMessage( hwndDlg, WM_NEXTDLGCTL,
                             !(GetKeyState(VK_SHIFT) & 0x80), 0 );
                return TRUE;
            }
            break;
            
        case VK_RIGHT:
        case VK_DOWN:
            if (!(dlgCode & DLGC_WANTARROWS))
            {
                SetFocus(GetNextDlgGroupItem(hwndDlg,GetFocus(),TRUE));
                return TRUE;
            }
            break;

        case VK_LEFT:
        case VK_UP:
            if (!(dlgCode & DLGC_WANTARROWS))
            {
                SetFocus(GetNextDlgGroupItem(hwndDlg,GetFocus(),FALSE));
                return TRUE;
            }
            break;

        case VK_ESCAPE:
            SendMessage( hwndDlg, WM_COMMAND, IDCANCEL,
                         MAKELPARAM( GetDlgItem(hwndDlg,IDCANCEL), 0 ));
            break;

        case VK_RETURN:
            {
                DWORD dw = SendMessage( hwndDlg, DM_GETDEFID, 0, 0 );
                if (HIWORD(dw) == DC_HASDEFID)
                    SendMessage( hwndDlg, WM_COMMAND, LOWORD(dw),
                                 MAKELPARAM( GetDlgItem( hwndDlg, LOWORD(dw) ),
                                             BN_CLICKED ));
                else
                    SendMessage( hwndDlg, WM_COMMAND, IDOK,
                                 MAKELPARAM( GetDlgItem(hwndDlg,IDOK), 0 ));
            }
            break;
        }
        break;  /* case WM_KEYDOWN */

        
    case WM_CHAR:
        if (dlgCode & (DLGC_WANTALLKEYS | DLGC_WANTCHARS)) break;
        break;

    case WM_SYSCHAR:
        if (dlgCode & DLGC_WANTALLKEYS) break;
        break;
    }

      /* If we get here, the message has not been treated specially */
      /* and can be sent to its destination window. */
    DispatchMessage( msg );
    return TRUE;
}


/****************************************************************
 *         GetDlgCtrlID           (USER.277)
 */
int GetDlgCtrlID( HWND hwnd )
{
    WND *wndPtr = WIN_FindWndPtr(hwnd);
    if (wndPtr) return wndPtr->wIDmenu;
    else return 0;
}
 

/***********************************************************************
 *           GetDlgItem   (USER.91)
 */
HWND GetDlgItem( HWND hwndDlg, WORD id )
{
    HWND curChild;
    WND * childPtr;
    WND * wndPtr;

    if (!(wndPtr = WIN_FindWndPtr( hwndDlg ))) return 0;
    curChild = wndPtr->hwndChild;
    while(curChild)
    {
	childPtr = WIN_FindWndPtr( curChild );
	if (childPtr->wIDmenu == id) return curChild;
	curChild = childPtr->hwndNext;
    }
    return 0;
}


/*******************************************************************
 *           SendDlgItemMessage   (USER.101)
 */
LONG SendDlgItemMessage(HWND hwnd, WORD id, UINT msg, WORD wParam, LONG lParam)
{
    HWND hwndCtrl = GetDlgItem( hwnd, id );
    if (hwndCtrl) return SendMessage( hwndCtrl, msg, wParam, lParam );
    else return 0;
}


/*******************************************************************
 *           SetDlgItemText   (USER.92)
 */
void SetDlgItemText( HWND hwnd, WORD id, LPSTR lpString )
{
    SendDlgItemMessage( hwnd, id, WM_SETTEXT, 0, (DWORD)lpString );
}


/***********************************************************************
 *           GetDlgItemText   (USER.93)
 */
int GetDlgItemText( HWND hwnd, WORD id, LPSTR str, WORD max )
{
    return (int)SendDlgItemMessage( hwnd, id, WM_GETTEXT, max, (DWORD)str );
}


/*******************************************************************
 *           SetDlgItemInt   (USER.94)
 */
void SetDlgItemInt( HWND hwnd, WORD id, WORD value, BOOL fSigned )
{
    HANDLE hText = USER_HEAP_ALLOC(0, 10 );
    char * str = (char *) USER_HEAP_ADDR( hText );

    if (fSigned) sprintf( str, "%d", value );
    else sprintf( str, "%u", value );
    SendDlgItemMessage( hwnd, id, WM_SETTEXT, 0, (DWORD)str );
    USER_HEAP_FREE( hText );
}


/***********************************************************************
 *           GetDlgItemInt   (USER.95)
 */
WORD GetDlgItemInt( HWND hwnd, WORD id, BOOL * translated, BOOL fSigned )
{
    int len;
    HANDLE hText;
    long result;
    char * str;
    
    if (translated) *translated = FALSE;
    if (!(len = SendDlgItemMessage( hwnd, id, WM_GETTEXTLENGTH, 0, 0 )))
	return 0;
    if (!(hText = USER_HEAP_ALLOC(0, len+1 )))
	return 0;
    str = (char *) USER_HEAP_ADDR( hText );
    if (SendDlgItemMessage( hwnd, id, WM_GETTEXT, len+1, (DWORD)str ))
    {
	char * endptr;
	result = strtol( str, &endptr, 10 );
	if (endptr && (endptr != str))  /* Conversion was successful */
	{
	    if (fSigned)
	    {
		if ((result < -32767) || (result > 32767)) result = 0;
		else if (translated) *translated = TRUE;
	    }
	    else
	    {
		if ((result < 0) || (result > 65535)) result = 0;
		else if (translated) *translated = TRUE;
	    }
	}
    }
    USER_HEAP_FREE( hText );
    return (WORD)result;
}


/***********************************************************************
 *           CheckDlgButton   (USER.97)
 */
void CheckDlgButton( HWND hwnd, WORD id, WORD check )
{
    SendDlgItemMessage( hwnd, id, BM_SETCHECK, check, 0 );
}


/***********************************************************************
 *           IsDlgButtonChecked   (USER.98)
 */
WORD IsDlgButtonChecked( HWND hwnd, WORD id )
{
    return (WORD)SendDlgItemMessage( hwnd, id, BM_GETCHECK, 0, 0 );
}


/***********************************************************************
 *           CheckRadioButton   (USER.96)
 */
void CheckRadioButton( HWND hwndDlg, WORD firstID, WORD lastID, WORD checkID )
{
    HWND button = GetDlgItem( hwndDlg, lastID );
    while (button != 0)
    {
	WND * wndPtr = WIN_FindWndPtr( button );
	if (!wndPtr) break;
	SendMessage( button, BM_SETCHECK, (wndPtr->wIDmenu == checkID), 0 );
        if (wndPtr->wIDmenu == firstID) break;
	button = wndPtr->hwndNext;
    }
}


/***********************************************************************
 *           GetDialogBaseUnits   (USER.243)
 */
DWORD GetDialogBaseUnits()
{
    return MAKELONG( xBaseUnit, yBaseUnit );
}


/***********************************************************************
 *           MapDialogRect   (USER.103)
 */
void MapDialogRect( HWND hwnd, LPRECT 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;
}


/***********************************************************************
 *           GetNextDlgGroupItem   (USER.227)
 */
HWND GetNextDlgGroupItem( HWND hwndDlg, HWND hwndCtrl, BOOL fPrevious )
{
    HWND hwnd, hwndStart;
    WND * dlgPtr, * ctrlPtr, * wndPtr;

    if (!(dlgPtr = WIN_FindWndPtr( hwndDlg ))) return 0;
    if (!(ctrlPtr = WIN_FindWndPtr( hwndCtrl ))) return 0;
    if (ctrlPtr->hwndParent != hwndDlg) return 0;

    if (!fPrevious && ctrlPtr->hwndNext)  /*Check if next control is in group*/
    {
	wndPtr = WIN_FindWndPtr( ctrlPtr->hwndNext );
        if (!(wndPtr->dwStyle & WS_GROUP)) return ctrlPtr->hwndNext;
    }

    if (ctrlPtr->dwStyle & WS_GROUP)  /* Control is the first of the group */
    {
        if (!fPrevious) return hwndCtrl;  /* Control is alone in his group */
        hwnd = ctrlPtr->hwndNext;
        while(hwnd)  /* Find last control of the group */
        {
            wndPtr = WIN_FindWndPtr( hwnd );
            if (wndPtr->dwStyle & WS_GROUP) break;
            hwndCtrl = hwnd;
            hwnd = wndPtr->hwndNext;
        }
        return hwndCtrl;
    }
    
      /* Now we will have to find the start of the group */

    hwndStart = 0;
    hwnd = dlgPtr->hwndChild;
    while (hwnd)
    {
	wndPtr = WIN_FindWndPtr( hwnd );
        if (wndPtr->dwStyle & WS_GROUP) hwndStart = hwnd;  /*Start of a group*/
        if (hwnd == hwndCtrl)
        {
            /* We found the control -> hwndStart is the first of the group */
            if (!fPrevious) return hwndStart;

            while(hwndStart)  /* Find the control placed before hwndCtrl */
            {
                wndPtr = WIN_FindWndPtr( hwndStart );
                if (wndPtr->hwndNext == hwndCtrl) return hwndStart;
                hwndStart = wndPtr->hwndNext;
            }
            break;
        }
	hwnd = wndPtr->hwndNext;
    }
    return hwndCtrl;  /* Not found -> return original control */
}


/***********************************************************************
 *           GetNextDlgTabItem   (USER.228)
 */
HWND GetNextDlgTabItem( HWND hwndDlg, HWND hwndCtrl, BOOL fPrevious )
{
    HWND hwnd, hwndLast;
    WND * dlgPtr, * ctrlPtr, * wndPtr;

    if (!(dlgPtr = WIN_FindWndPtr( hwndDlg ))) return 0;
    if (!(ctrlPtr = WIN_FindWndPtr( hwndCtrl ))) return 0;
    if (ctrlPtr->hwndParent != hwndDlg) return 0;

    hwndLast = hwndCtrl;
    hwnd = ctrlPtr->hwndNext;
    while (1)
    {
	if (!hwnd) hwnd = dlgPtr->hwndChild;
	if (hwnd == hwndCtrl) break;
	wndPtr = WIN_FindWndPtr( hwnd );
	if (wndPtr->dwStyle & WS_TABSTOP)
	{
	    hwndLast = hwnd;
	    if (!fPrevious) break;
	}
	hwnd = wndPtr->hwndNext;
    }
    return hwndLast;
}
