/***************************************************************************
**
**    $Header$
**
**    $Log$
** 
****************************************************************************/

/////////////////////////////////////////////////////////////////////////////
//
//  File name:  MYEDIT.CPP
//
//  Description:The implement file for the class: CMyEdit
//
//  Author:     Lane Li
//
//  Date:       09/10/95
//
//  Modification:
//
//      1. 09/10/95, Initial version
//
//
//  Copyright (C) 1995 Microtek International. All rights reserved.
//
/////////////////////////////////////////////////////////////////////////////

///////////////////////////////////////////
// myedit.cpp
// Lane Li
// 95/7
///////////////////////////////////////////
#include "stdafx.h"
#include "resource.h"
                                   
#include "myedit.h"

CEdit* CMyEdit::m_edit1 = NULL;
CEdit* CMyEdit::m_edit2 = NULL;

/////////////////////////////////////////////////////////////////////////////
// MyEdit

CMyEdit::CMyEdit()
: m_wParseStyle(0), m_nMin(0), m_nMax(0)
{
}

BEGIN_MESSAGE_MAP(CMyEdit, CEdit)
    //{{AFX_MSG_MAP(CMyEdit)
    ON_WM_CHAR()
    ON_WM_VSCROLL()     // for associated spin controls
    //}}AFX_MSG_MAP
END_MESSAGE_MAP()

/////////////////////////////////////////////////////////////////////////////
// Creating from C++ code

BOOL CMyEdit::Create(DWORD dwStyle, const RECT& rect,
        CWnd* pParentWnd, UINT nID)
{
    m_wParseStyle = LOWORD(dwStyle);
    // figure out edit control style
    DWORD dwEditStyle = MAKELONG(ES_LEFT, HIWORD(dwStyle));
    return CWnd::Create("EDIT", NULL, dwEditStyle, rect, pParentWnd, nID);
}

/////////////////////////////////////////////////////////////////////////////
// Aliasing on top of an existing Edit control

BOOL CMyEdit::SubclassEdit(UINT nID, CWnd* pParent, WORD wParseStyle)
{
    m_wParseStyle = wParseStyle;

    // SubclassWindow requires an HWND so we call the Windows GetDlgItem
    // and avoid creating a tempory CWnd and then calling GetSafeHwnd
    HWND hWndEdit = ::GetDlgItem(pParent->m_hWnd, nID);
    if (hWndEdit == NULL)   return FALSE;
    return SubclassWindow(hWndEdit);
}

BOOL CMyEdit::SubclassEdit2(UINT nID, CWnd* pParent, WORD wParseStyle)
{           
	static int count = 0;
	count++;
	if (count == 1) CMyEdit::m_edit1=this;
	if (count == 2) 
	{
		CMyEdit::m_edit2=this;
		count = 0;
	}
    m_wParseStyle = wParseStyle;

    // SubclassWindow requires an HWND so we call the Windows GetDlgItem
    // and avoid creating a tempory CWnd and then calling GetSafeHwnd
    HWND hWndEdit = ::GetDlgItem(pParent->m_hWnd, nID);
    if (hWndEdit == NULL)   return FALSE;
    return TRUE;
}

/////////////////////////////////////////////////////////////////////////////
// Input character filter

void CMyEdit::OnChar(UINT nChar, UINT nRepCnt, UINT nFlags)
{
    WORD type;
    char buf[20];
    
    GetParent()->GetDlgItemText(GetDlgCtrlID(),buf,10);
    if(nChar < 0x20)    type = PES_ALL;     // always allow control chars
    else if(nChar >= '0' && nChar <= '9')   type = PES_NUMBERS;
    else if(nChar >= 'A' && nChar <= 'Z')   type = PES_LETTERS;
    else if(nChar >= 'a' && nChar <= 'z')   type = PES_LETTERS;
    else                                    type = PES_OTHERCHARS;
                      
	if ((buf[0]=='0')&&(buf[1]!='x')&&(buf[1]!='X'))
	{
		if ((nChar =='x')||(nChar =='X')) type = PES_NUMBERS;
	}
	                      
	if ((buf[0]=='0')&&((buf[1]=='x')||(buf[1]=='X')))
	{
		if (nChar >= 'a' && nChar <= 'f') type = PES_NUMBERS;
		if (nChar >= 'A' && nChar <= 'F') type = PES_NUMBERS;
	}
    
    if (m_wParseStyle & type)
        CEdit::OnChar(nChar, nRepCnt, nFlags);  // permitted
    else        // illegal character - inform parent
        OnBadInput();
}

/////////////////////////////////////////////////////////////////////////////
// Spin controls will send scroll messages

void CMyEdit::OnVScroll(UINT nSBCode, UINT, CScrollBar*)
{       
	char buf[20];
	long value;
	int nOld,nNew;
    int nDelta = 0;
    if(nSBCode == SB_LINEDOWN)        nDelta = -1;
    else if(nSBCode == SB_LINEUP)     nDelta = +1;
    else        return; // nothing special

    // set the focus to this edit item and select it all
    SetFocus();

    //Get the number in the control.
    BOOL bOk;
//    int nOld = GetParent()->GetDlgItemInt(GetDlgCtrlID(), &bOk);
	bOk=TRUE;
	GetParent()->GetDlgItemText(GetDlgCtrlID(),buf,10);
	buf[10]='\0';
	if ((buf[0]=='0')&&((buf[1]=='x')||(buf[1]=='X')))
	{
		value = strtol(buf,NULL,16);
		nOld = (int)value;
	}                     
	else
	{
		nOld = GetParent()->GetDlgItemInt(GetDlgCtrlID(), &bOk);
	}
    if(bOk) {                             
        // The MuScroll control also supports range checking
        // for this example, we just prevent overflow
        nNew = nOld + nDelta;
        if(nNew >= m_nMin && nNew <= m_nMax)
//            GetParent()->SetDlgItemInt(GetDlgCtrlID(), nNew);
		{   
			if ((buf[0]=='0')&&((buf[1]=='x')||(buf[1]=='X')))
			{   
				_itoa(nNew,buf+2,16);
				GetParent()->SetDlgItemText(GetDlgCtrlID(),buf);
			}   
			else 
				GetParent()->SetDlgItemInt(GetDlgCtrlID(), nNew);
		}
        else    bOk = FALSE;
    }

    if (!bOk)   OnBadInput();
    SetSel(0, -1);
    
    if ((m_edit1!=NULL)&&(m_edit2!=NULL)&&bOk)
    {
    	if (m_edit1==this)
    	{    
    		bOk=TRUE;
			(m_edit2->GetParent())->GetDlgItemText(GetDlgCtrlID()+1,buf,10);
			if ((buf[0]=='0')&&((buf[1]=='x')||(buf[1]=='X')))
			{
				value = strtol(buf,NULL,16);
				nOld = (int)value;
			}                     
			else
			{
				nOld = (m_edit2->GetParent())->GetDlgItemInt(GetDlgCtrlID()+1, &bOk);
			}
		    if(bOk) 
		    {                             
		    	if (nNew>nOld) 
		    	{
					if ((buf[0]=='0')&&((buf[1]=='x')||(buf[1]=='X')))
					{   
						_itoa(nNew,buf+2,16);
						(m_edit2->GetParent())->SetDlgItemText(GetDlgCtrlID()+1,buf);
					}   
					else 
						(m_edit2->GetParent())->SetDlgItemInt(GetDlgCtrlID()+1, nNew);
		    	}
		    }
		    else
				(m_edit2->GetParent())->SetDlgItemInt(GetDlgCtrlID()+1, nNew);
    	}
    	if (m_edit2==this)
    	{
    		bOk=TRUE;
			(m_edit1->GetParent())->GetDlgItemText(GetDlgCtrlID()-1,buf,10);
			if ((buf[0]=='0')&&((buf[1]=='x')||(buf[1]=='X')))
			{
				value = strtol(buf,NULL,16);
				nOld = (int)value;
			}                     
			else
			{
				nOld = (m_edit1->GetParent())->GetDlgItemInt(GetDlgCtrlID()-1, &bOk);
			}
		    if(bOk) 
		    {                             
		    	if (nNew<nOld) 
		    	{
					if ((buf[0]=='0')&&((buf[1]=='x')||(buf[1]=='X')))
					{   
						_itoa(nNew,buf+2,16);
						(m_edit1->GetParent())->SetDlgItemText(GetDlgCtrlID()-1,buf);
					}   
					else 
						(m_edit1->GetParent())->SetDlgItemInt(GetDlgCtrlID()-1, nNew);
		    	}
		    }
		    else
				(m_edit1->GetParent())->SetDlgItemInt(GetDlgCtrlID()-1, nNew);
    	}
    }
    SetSel(0, -1);
}

/////////////////////////////////////////////////////////////////////////////
// default bad input handler, beep (unless parent notification
//    returns -1.  Most parent dialogs will return 0 or 1 for command
//    handlers (i.e. Beep is the default)

void CMyEdit::OnBadInput()
{
    if (GetParent()->SendMessage(WM_COMMAND,
        GetDlgCtrlID(), MAKELONG(m_hWnd, PEN_ILLEGALCHAR)) != -1)
        MessageBeep(-1);
}

/////////////////////////////////////////////////////////////////////////////
