/*
 * 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 "ldt.h"
#include "stackframe.h"
#include "user.h"
#include "message.h"
#include "stddebug.h"
/* #define DEBUG_DIALOG */
#include "debug.h"

  /* Dialog base units */
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( 0 ))) return FALSE;
    GetTextMetrics( hdc, &tm );
    ReleaseDC( 0, 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;

    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 SEGPTR DIALOG_GetControl( SEGPTR ptr, SEGPTR *class, SEGPTR *text )
{
    unsigned char *base = (unsigned char *)PTR_SEG_TO_LIN( ptr );
    unsigned char *p = base;

    p += 14;  /* size of control header */

    if (*p & 0x80)
    {
        *class = MAKEINTRESOURCE( *p );
        p++;
    }
    else 
    {
	*class = ptr + (WORD)(p - base);
	p += strlen(p) + 1;
    }

    if (*p == 0xff)
    {
	  /* Integer id, not documented (?). Only works for SS_ICON controls */
	*text = MAKEINTRESOURCE( p[1] + 256 * p[2] );
	p += 4;
    }
    else
    {
	*text = ptr + (WORD)(p - base);
	p += strlen(p) + 2;
    }
    return ptr + (WORD)(p - base);
}


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

    /* Get the menu name */

    if (*p == 0xff)
    {
        result->menuName = MAKEINTRESOURCE( p[1] + 256 * p[2] );
        p += 3;
    }
    else if (*p)
    {
        result->menuName = template + (WORD)(p - base);
        p += strlen(p) + 1;
    }
    else
    {
        result->menuName = 0;
        p++;
    }

    /* Get the class name */

    if (*p) result->className = template + (WORD)(p - base);
    else result->className = DIALOG_CLASS_ATOM;
    p += strlen(p) + 1;

    /* Get the window caption */

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

    /* Get the font name */

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

    return template + (WORD)(p - base);
}


/***********************************************************************
 *           DIALOG_DisplayTemplate
 */
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 %08lx\n", result->header.style );
    dprintf_dialog( stddeb, " CAPTION '%s'\n",
                    (char *)PTR_SEG_TO_LIN(result->caption) );

    if (HIWORD(result->className))
        dprintf_dialog( stddeb, " CLASS '%s'\n",
                        (char *)PTR_SEG_TO_LIN(result->className) );
    else
        dprintf_dialog( stddeb, " CLASS #%d\n", LOWORD(result->className) );

    if (HIWORD(result->menuName))
        dprintf_dialog( stddeb, " MENU '%s'\n",
                        (char *)PTR_SEG_TO_LIN(result->menuName) );
    else if (LOWORD(result->menuName))
	dprintf_dialog(stddeb, " MENU %04x\n", LOWORD(result->menuName) );

    if (result->header.style & DS_SETFONT)
	dprintf_dialog( stddeb, " FONT %d,'%s'\n", result->pointSize,
                        (char *)PTR_SEG_TO_LIN(result->faceName) );
}


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


/***********************************************************************
 *           CreateDialogParam   (USER.241)
 */
HWND CreateDialogParam( HINSTANCE hInst, SEGPTR dlgTemplate,
		        HWND owner, DLGPROC dlgProc, LPARAM param )
{
    HWND hwnd = 0;
    HRSRC hRsrc;
    HGLOBAL hmem;
    SEGPTR data;

    dprintf_dialog(stddeb, "CreateDialogParam: "NPFMT","SPFMT","NPFMT",%08lx,%ld\n",
	    hInst, dlgTemplate, owner, (DWORD)dlgProc, param );
     
    if (!(hRsrc = FindResource( hInst, dlgTemplate, RT_DIALOG ))) return 0;
    if (!(hmem = LoadResource( hInst, hRsrc ))) return 0;
    if (!(data = WIN16_LockResource( hmem ))) hwnd = 0;
    else hwnd = CreateDialogIndirectParam(hInst, data, owner, dlgProc, param);
    FreeResource( hmem );
    return hwnd;
}


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


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

      /* Parse dialog template */

    if (!dlgTemplate) return 0;
    headerPtr = DIALOG_ParseTemplate( dlgTemplate, &template );
    if (debugging_dialog) DIALOG_DisplayTemplate( &template );

      /* Load menu */

    if (template.menuName) hMenu = LoadMenu( hInst, template.menuName );

      /* Create custom font if needed */

    if (template.header.style & DS_SETFONT)
    {
          /* The font height must be negative as it is a point size */
          /* (see CreateFont() documentation in the Windows SDK).   */
	hFont = CreateFont( -template.pointSize, 0, 0, 0, FW_DONTCARE,
			    FALSE, FALSE, FALSE, DEFAULT_CHARSET, 0, 0,
			    DEFAULT_QUALITY, FF_DONTCARE,
                            (LPSTR)PTR_SEG_TO_LIN(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;
            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.header.cx * xUnit / 4;
    rect.bottom = template.header.cy * yUnit / 8;
    if (template.header.style & DS_MODALFRAME) exStyle |= WS_EX_DLGMODALFRAME;
    AdjustWindowRectEx( &rect, template.header.style, 
			hMenu ? TRUE : FALSE , exStyle );
    rect.right -= rect.left;
    rect.bottom -= rect.top;

    if ((INT)template.header.x == CW_USEDEFAULT)
        rect.left = rect.top = CW_USEDEFAULT;
    else
    {
        rect.left += template.header.x * xUnit / 4;
        rect.top += template.header.y * yUnit / 8;
        if (!(template.header.style & DS_ABSALIGN))
            ClientToScreen( owner, (POINT *)&rect );
    }

    hwnd = CreateWindowEx( exStyle, template.className, template.caption, 
			   template.header.style & ~WS_VISIBLE,
			   rect.left, rect.top, rect.right, rect.bottom,
			   owner, hMenu, hInst, (SEGPTR)0 );
    if (!hwnd)
    {
	if (hFont) DeleteObject( hFont );
	if (hMenu) DestroyMenu( hMenu );
	return 0;
    }
    wndPtr = WIN_FindWndPtr( hwnd );

      /* Purge junk from system menu */
      /* FIXME: this doesn't belong here */

    DeleteMenu(wndPtr->hSysMenu,SC_SIZE,MF_BYCOMMAND);
    if (!(wndPtr->dwStyle & WS_MAXIMIZEBOX) )
    {
        DeleteMenu(wndPtr->hSysMenu,SC_MAXIMIZE,MF_BYCOMMAND);
        if( !(wndPtr->dwStyle & WS_MINIMIZEBOX) )
        {
            DeleteMenu(wndPtr->hSysMenu,SC_MINIMIZE,MF_BYCOMMAND);
            DeleteMenu(wndPtr->hSysMenu,SC_RESTORE,MF_BYCOMMAND);
        }
    }
    else
        if (!(wndPtr->dwStyle & WS_MINIMIZEBOX) )
            DeleteMenu(wndPtr->hSysMenu,SC_MINIMIZE,MF_BYCOMMAND);

      /* Create control windows */

    dprintf_dialog(stddeb, " BEGIN\n" );

    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 *header;
	SEGPTR className, winName;
        HWND hwndDefButton = 0;
        char buffer[10];

        header = (DLGCONTROLHEADER *)PTR_SEG_TO_LIN( headerPtr );
	headerPtr = DIALOG_GetControl( headerPtr, &className, &winName );

        if (!HIWORD(className))
        {
            switch(LOWORD(className))
            {
            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;
            }
            className = MAKE_SEGPTR(buffer);
        }

        if (HIWORD(className))
            dprintf_dialog(stddeb, "   %s ", (char*)PTR_SEG_TO_LIN(className));
        else dprintf_dialog(stddeb, "   %04x ", LOWORD(className) );
	if (HIWORD(winName))
            dprintf_dialog(stddeb,"'%s'", (char *)PTR_SEG_TO_LIN(winName) );
	else dprintf_dialog(stddeb,"%04x", LOWORD(winName) );

	dprintf_dialog(stddeb," %d, %d, %d, %d, %d, %08lx\n", 
                       header->id, header->x, header->y, 
                       header->cx, header->cy, header->style );

	if (HIWORD(className) &&
            !strcmp( (char *)PTR_SEG_TO_LIN(className), "EDIT") &&
            ((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;
		}
		LocalInit(dlgInfo->hDialogHeap, 0, 0xffff);
	    }
	    hwndCtrl = CreateWindowEx(WS_EX_NOPARENTNOTIFY, className, winName,
                                      header->style | WS_CHILD,
                                      header->x * xUnit / 4,
                                      header->y * yUnit / 8,
                                      header->cx * xUnit / 4,
                                      header->cy * yUnit / 8,
                                      hwnd, (HMENU)((DWORD)header->id),
                                      dlgInfo->hDialogHeap, (SEGPTR)0 );
	}
	else
        {
	    hwndCtrl = CreateWindowEx(WS_EX_NOPARENTNOTIFY, className, winName,
                                      header->style | WS_CHILD,
                                      header->x * xUnit / 4,
                                      header->y * yUnit / 8,
                                      header->cx * xUnit / 4,
                                      header->cy * yUnit / 8,
                                      hwnd, (HMENU)((DWORD)header->id),
                                      hInst, (SEGPTR)0 );
	}

        /* Make the control last one in Z-order, so that controls remain
           in the order in which they were created */
	SetWindowPos( hwndCtrl, HWND_BOTTOM, 0, 0, 0, 0,
                      SWP_NOSIZE | SWP_NOMOVE | SWP_NOACTIVATE );

            /* Send initialisation messages to the control */
        if (hFont) SendMessage( hwndCtrl, WM_SETFONT, (WPARAM)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 = GetWindowWord( hwndCtrl, GWW_ID );
        }
    }    

    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, (WPARAM)dlgInfo->hUserFont, 0 );
    if (SendMessage( hwnd, WM_INITDIALOG, (WPARAM)dlgInfo->hwndFocus, param ))
	SetFocus( dlgInfo->hwndFocus );
    if (template.header.style & WS_VISIBLE) ShowWindow(hwnd, SW_SHOW);
    return hwnd;
}


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

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

    while (MSG_InternalGetMessage( (SEGPTR)USER_HEAP_SEG_ADDR(msgHandle), 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, SEGPTR dlgTemplate,
	       HWND owner, DLGPROC dlgProc )
{
    return DialogBoxParam( hInst, dlgTemplate, owner, dlgProc, 0 );
}


/***********************************************************************
 *           DialogBoxParam   (USER.239)
 */
INT DialogBoxParam( HINSTANCE hInst, SEGPTR dlgTemplate,
		    HWND owner, DLGPROC dlgProc, LPARAM param )
{
    HWND hwnd;
    
    dprintf_dialog(stddeb, "DialogBoxParam: "NPFMT","SPFMT","NPFMT",%08lx,%ld\n",
	    hInst, dlgTemplate, owner, (DWORD)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, DLGPROC dlgProc )
{
    return DialogBoxIndirectParam( hInst, dlgTemplate, owner, dlgProc, 0 );
}


/***********************************************************************
 *           DialogBoxIndirectParam   (USER.240)
 */
INT DialogBoxIndirectParam( HINSTANCE hInst, HANDLE dlgTemplate,
			    HWND owner, DLGPROC dlgProc, LPARAM param )
{
    HWND hwnd;
    SEGPTR ptr;

    if (!(ptr = (SEGPTR)WIN16_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)
 */
BOOL EndDialog( HWND hwnd, INT retval )
{
    WND * wndPtr = WIN_FindWndPtr( hwnd );
    DIALOGINFO * dlgInfo = (DIALOGINFO *)wndPtr->wExtra;
    dlgInfo->msgResult = retval;
    dlgInfo->fEnd = TRUE;
    dprintf_dialog(stddeb, "EndDialog: "NPFMT" %d\n", hwnd, retval );
    return TRUE;
}


/***********************************************************************
 *           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))
        return FALSE;

    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(),FALSE));
                return TRUE;
            }
            break;

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

        case VK_ESCAPE:
#ifdef WINELIB32
            SendMessage( hwndDlg, WM_COMMAND, 
			 MAKEWPARAM( IDCANCEL, 0 ),
                         (LPARAM)GetDlgItem(hwndDlg,IDCANCEL) );
#else
            SendMessage( hwndDlg, WM_COMMAND, IDCANCEL,
                         MAKELPARAM( GetDlgItem(hwndDlg,IDCANCEL), 0 ));
#endif
            break;

        case VK_RETURN:
            {
                DWORD dw = SendMessage( hwndDlg, DM_GETDEFID, 0, 0 );
                if (HIWORD(dw) == DC_HASDEFID)
#ifdef WINELIB32
                    SendMessage( hwndDlg, WM_COMMAND, 
				 MAKEWPARAM( LOWORD(dw), BN_CLICKED ),
                                 (LPARAM)GetDlgItem( hwndDlg, LOWORD(dw) ) );
                else
                    SendMessage( hwndDlg, WM_COMMAND, 
				 MAKEWPARAM( IDOK, 0 ),
                                 (LPARAM)GetDlgItem(hwndDlg,IDOK) );
#else
                    SendMessage( hwndDlg, WM_COMMAND, LOWORD(dw),
                                 MAKELPARAM( GetDlgItem( hwndDlg, LOWORD(dw) ),
                                             BN_CLICKED ));
                else
                    SendMessage( hwndDlg, WM_COMMAND, IDOK,
                                 MAKELPARAM( GetDlgItem(hwndDlg,IDOK), 0 ));
#endif
            }
            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)
 */
LRESULT SendDlgItemMessage(HWND hwnd, INT id, UINT msg, WPARAM wParam, LPARAM 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, SEGPTR lpString )
{
    SendDlgItemMessage( hwnd, id, WM_SETTEXT, 0, (DWORD)lpString );
}


/***********************************************************************
 *           GetDlgItemText   (USER.93)
 */
int GetDlgItemText( HWND hwnd, WORD id, SEGPTR 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 )
{
    char str[20];

    if (fSigned) sprintf( str, "%d", (int)value );
    else sprintf( str, "%u", value );
    SendDlgItemMessage( hwnd, id, WM_SETTEXT, 0, (LPARAM)MAKE_SEGPTR(str) );
}


/***********************************************************************
 *           GetDlgItemInt   (USER.95)
 */
WORD GetDlgItemInt( HWND hwnd, WORD id, BOOL * translated, BOOL fSigned )
{
    char str[30];
    long result = 0;
    
    if (translated) *translated = FALSE;
    if (SendDlgItemMessage( hwnd, id, WM_GETTEXT, 30, (LPARAM)MAKE_SEGPTR(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;
	    }
	}
    }
    return (WORD)result;
}


/***********************************************************************
 *           CheckDlgButton   (USER.97)
 */
BOOL CheckDlgButton( HWND hwnd, INT id, UINT check )
{
    SendDlgItemMessage( hwnd, id, BM_SETCHECK, check, 0 );
    return TRUE;
}


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


/***********************************************************************
 *           CheckRadioButton   (USER.96)
 */
BOOL CheckRadioButton( HWND hwndDlg, UINT firstID, UINT lastID, UINT checkID )
{
    HWND button = GetWindow( hwndDlg, GW_CHILD );
    WND *wndPtr;

    while (button)
    {
	if (!(wndPtr = WIN_FindWndPtr( button ))) return FALSE;
        if ((wndPtr->wIDmenu == firstID) || (wndPtr->wIDmenu == lastID)) break;
	button = wndPtr->hwndNext;
    }
    if (!button) return FALSE;

    if (wndPtr->wIDmenu == lastID)
        lastID = firstID;  /* Buttons are in reverse order */
    while (button)
    {
	if (!(wndPtr = WIN_FindWndPtr( button ))) return FALSE;
	SendMessage( button, BM_SETCHECK, (wndPtr->wIDmenu == checkID), 0 );
        if (wndPtr->wIDmenu == lastID) break;
	button = wndPtr->hwndNext;
    }
    return TRUE;
}


/***********************************************************************
 *           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;
    }

      /* Now we will have to find the start of the group */

    hwndStart = hwnd = dlgPtr->hwndChild;
    while (hwnd)
    {
	wndPtr = WIN_FindWndPtr( hwnd );
        if (wndPtr->dwStyle & WS_GROUP) hwndStart = hwnd;  /*Start of a group*/
	if (hwnd == hwndCtrl) break;
	hwnd = wndPtr->hwndNext;
    }

    if (!hwnd) fprintf(stderr, "GetNextDlgGroupItem: hwnd not in dialog!\n");

      /* only case left for forward search: wraparound */
    if (!fPrevious) return hwndStart;
    
    hwnd = hwndStart;
    wndPtr = WIN_FindWndPtr( hwnd );
    hwnd = wndPtr->hwndNext;
    while (hwnd && (hwnd != hwndCtrl))
    {
	wndPtr = WIN_FindWndPtr( hwnd );
	if (wndPtr->dwStyle & WS_GROUP) break;
	hwndStart = hwnd;
	hwnd = wndPtr->hwndNext;
    }
    return hwndStart;
}


/***********************************************************************
 *           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) && (wndPtr->dwStyle & WS_VISIBLE))
	{
	    hwndLast = hwnd;
	    if (!fPrevious) break;
	}
	hwnd = wndPtr->hwndNext;
    }
    return hwndLast;
}
