
/***************************************************************************
**
**    $Header:   C:/EPSLDV1/SRC/LOG/BWSWIN.CPP   1.0   02 May 1996 10:26:04   ZJRD  
**
**    $Log:   D:/ECB2S/SRC/LOG/BWSWIN.CPP  $
** 
**    Rev 1.2.1.5   17 Apr 1997 15:42:32   ZJRD
** No change.
** 
**    Rev 1.2.1.4   16 Apr 1997 10:17:08   ZJRD
** No change.
** 
**    Rev 1.2.1.3   10 Apr 1997 15:28:28   ZJRD
** 2.09F
** 
**    Rev 1.2.1.1   03 Apr 1997 15:10:00   ZJRD
** No change.
** 
**    Rev 1.2.1.0   28 Mar 1997 10:14:58   ZJRD
** easy pack sld 2.09d
** 
**    Rev 1.1   19 Mar 1997 11:26:14   ZJRD
** No change.
** 
**    Rev 1.0   12 Mar 1997 14:44:50   ZJRD
** Initial revision.
** 
**    Rev 1.6.1.0.1.2   09 Dec 1996 10:14:26   ZJRD
** EasyPack/SLD Version 2.0P
** 
**    Rev 1.6.1.0.1.0   11 Nov 1996 12:57:42   ZJRD
** EasyPack/SLD Version 2.01
** 
**    Rev 1.6.1.4   09 Sep 1996 13:14:06   ZJRD
** No change.
** 
**    Rev 1.6.1.3   05 Sep 1996 11:25:38   ZJRD
** No change.
** 
**    Rev 1.6.1.2   02 Sep 1996 09:52:44   ZJRD
** No change.
** 
**    Rev 1.6.1.1   28 Aug 1996 15:45:30   ZJRD
** No change.
** 
**    Rev 1.6.1.0   12 Aug 1996 10:50:32   ZJRD
** EasyPack/SLD Version 1.98
** 
**    Rev 1.4   05 Jun 1996 14:52:42   ZJRD
** EasyPack/SLD Version 1.96
** 
**    Rev 1.3   29 May 1996 09:33:48   ZJRD
** EasyPack/SLD Version 1.95
** 
**    Rev 1.2   16 May 1996 09:02:24   ZJRD
** EasyPack/SLD Version 1.94
** 
**    Rev 1.0   02 May 1996 10:26:04   ZJRD
** Initial revision.
** 
**    Rev 1.31   18 Apr 1996 12:52:44   Shirley
** No change.
** 
**    Rev 1.30   12 Apr 1996 10:33:34   Shirley
** EasyPack/SLD Version 1.90
** 
**    Rev 1.28   15 Feb 1996 08:46:32   Shirley
** EasyPack/SLD Version 1.01
** 
**    Rev 1.27   12 Feb 1996 14:01:48   Shirley
** No change.
** 
**    Rev 1.26   06 Feb 1996 15:27:02   Shirley
** No change.
** 
**    Rev 1.25   06 Feb 1996 13:42:40   Shirley
** No change.
** 
**    Rev 1.24   01 Feb 1996 10:11:18   Shirley
** No change.
** 
**    Rev 1.23   26 Jan 1996 09:11:50   Shirley
** No change.
** 
**    Rev 1.22   25 Jan 1996 13:12:10   Shirley
** EasyPack/SLD Version 0.35
** 
**    Rev 1.21   24 Jan 1996 10:32:00   Shirley
** No change.
** 
**    Rev 1.20   23 Jan 1996 11:21:54   Shirley
** EasypPack/SLD Version 0.34c
** 
**    Rev 1.19   18 Jan 1996 10:07:18   Shirley
** EasyPack/SLD Version 0.34b
** 
**    Rev 1.18   15 Jan 1996 16:10:02   Shirley
** EasyPack/SLD Version 0.34a
** 
**    Rev 1.17   04 Jan 1996 11:07:32   Shirley
** EasyPack/SLD Version 0.34
** 
**    Rev 1.16   30 Nov 1995 09:08:02   Shirley
** No change.
** 
**    Rev 1.15   28 Nov 1995 15:28:56   Shirley
** No change.
** 
**    Rev 1.14   21 Nov 1995 11:17:50   Shirley
** No change.
** 
**    Rev 1.13   13 Nov 1995 09:21:38   Shirley
** No change.
** 
**    Rev 1.12   12 Nov 1995 11:28:02   Shirley
** EasyPack/SLD Version 0.24
** 
**    Rev 1.11   08 Nov 1995 16:27:34   Shirley
** No change.
** 
**    Rev 1.10   08 Nov 1995 12:39:30   Shirley
** EasyPack/SLD Version 0.22
** 
**    Rev 1.9   02 Nov 1995 10:02:14   Shirley
** EasyPack/SLD Version 0.21
** 
**    Rev 1.8   27 Oct 1995 16:44:52   Shirley
** No change.
** 
**    Rev 1.7   27 Oct 1995 13:43:10   Shirley
** EasyPack/SLD Version 0.1g
** 
**    Rev 1.6   25 Oct 1995 14:25:40   Shirley
** EasyPack/SLD Version 0.1f
** 
**    Rev 1.5   18 Oct 1995 14:46:44   Shirley
** EasyPack/SLD Version 0.1e
** 
**    Rev 1.4   13 Oct 1995 13:18:36   Shirley
** EasyPack/SLD Version 0.1d
** 
**    Rev 1.3   29 Sep 1995 09:48:00   Shirley
** No change.
** 
**    Rev 1.2   20 Sep 1995 10:55:20   Shirley
** EasyPack/SLD Version 0.1b
** 
**    Rev 1.1   15 Sep 1995 09:47:42   Shirley
** EasyPack/SLDV0.1a 
** 
**    Rev 1.0   07 Sep 1995 09:55:04   Shirley
** Initial revision.
**
****************************************************************************/

/////////////////////////////////////////////////////////////////////////////
//
//  File name:  BWSWIN.CPP
//
//  Description:The implement file for the class: CBrowseWindow
//
//  Author:     HuWei
//
//  Date:       05/1/96
//
//
//  Copyright (C) 1995 Microtek International. All rights reserved.
//
/////////////////////////////////////////////////////////////////////////////

#include "stdafx.h"
#include "resource.h"
                                     
#include "colors.h"                                     
#include "zqueue.h"
#include "uicom.h"
#include "srccom.h"
#include "btnbar.h"
#include "zlist.h"
#include "srclist.h" 
#include "SRCMDL.h"
#include "BWSMDL.h"
#include "srcfile.h"
#include "meter.h"
#include "srcdlg1.h"
#include "srcgrp.h"
#include "mainfrm.h"
#include "Toolwnd.h"
#include "bwswin.h"
#include "cfmtadr.h"
//#include "bwsdlg.h"

#ifdef _DEBUG
#undef THIS_FILE
static char BASED_CODE THIS_FILE[] = __FILE__;
#endif                       

extern ADDR_SIZE  dwpMax;        // program  max address
void BwsResetView(void);
BOOL browseOpenSwitch=0;

void BwsSetText()
{
     if(isBrowseOn&&pBrowseWnd)
       ((CBrowseWindow *)pBrowseWnd)->SelectText(FALSE);
}       

BOOL g_bBrowseActive=0;
/////////////////////////////////////////////////////////////////////////////
//
//  Name:         BwsCleanAsm
//
//  Description: 
//
//  Input:  
//
//  Output: 
//
//  Return: 
//
/////////////////////////////////////////////////////////////////////////////
void BwsCleanAsm(void)
{
  BwsAsm.DeleteList();
}
/////////////////////////////////////////////////////////////////////////////
//
//  Name:         BwsCleanMix
//
//  Description: 
//
//  Input:  
//
//  Output: 
//
//  Return: 
//
/////////////////////////////////////////////////////////////////////////////
void BwsCleanMix(void)
{
  BwsMix.DeleteList();
}

/////////////////////////////////////////////////////////////////////////////
//
//  Name:         BwsLoadModule
//
//  Description: 
//
//  Input:  
//
//  Output: 
//
//  Return: 
//
/////////////////////////////////////////////////////////////////////////////
/*
int BwsLoadModule(unsigned long dwModule, BOOL isHist)
{
	AfxGetApp()->DoWaitCursor(1);            
    int nRval = bwsMdlInfo.LoadModuleIdx(dwModule);
	AfxGetApp()->DoWaitCursor(-1);            
    if(isHist && nRval != SRC_LOAD_ERROR)
        bwsBrsMdl.AddTail(dwModule);                        
    return nRval;
}
*/                              

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



//extern int SrcGetFuncRange(const char *command, unsigned short& uStart, 
//        unsigned short& uEnd);
extern int SrcIsFunction(const char *command);
extern int SrcIsVariable(const char* str,int nLineNo);  
int BwsModuleName2Index(const char * pszModule, unsigned long & dwModule);
//extern void VarAddVariable(const CString strToken);
     
    
/////////////////////////////////////////////////////////////////////////////
//
//  Name:   
//
//  Description: 
//
//  Input:  
//
//  Output: 
//
//  Return: 
//
/////////////////////////////////////////////////////////////////////////////
void DoBwsBrowseModule(CSrcBrowse &dlg)
{                                   
    unsigned long dwModule;
    if(dlg.m_strMdl_2 != "") {
            if(SrcGetModuleFullName(dlg.m_strMdl_2) == "" ||
                BwsModuleName2Index(dlg.m_strMdl_2, dwModule) == -1 ||
                BwsLoadModule(dwModule) == SRC_LOAD_ERROR) {
                CString str("Can't open module: ");
                str += dlg.m_strMdl_2;
                AfxMessageBox(str);
                return;
            }
            if(!isBrowseOn) {
                BwsOpenWindow(FALSE, 
                    (CMDIFrameWnd *)(AfxGetApp()->m_pMainWnd));
            } else BwsResetView();    
    }

#ifdef  BWS_TOOL_WND  
    BOOL b=(BOOL)(!bwsBrsMdl.IsEmpty() && !bwsBrsMdl.IsHead());
    if(isBrowseOn&&pBrowseWnd)
       ((CBrowseWindow *)pBrowseWnd)->m_pToolWnd->EnableBrowsePrev(b);
#endif       
}
/////////////////////////////////////////////////////////////////////////////
//
//  Name:   
//
//  Description: Convert Module Name to Module Index        
//
//  Input:  
//
//  Output: 
//
//  Return: 
//
/////////////////////////////////////////////////////////////////////////////
int BwsModuleName2Index(const char * pszModule, unsigned long & dwModule)
{                                                 
    char psz[80];  
        
    for(int i = 0; i < int(bwsMdlInfo.m_uModules); i ++) {
        if(SrcGetModuleName(bwsMdlInfo.m_pModule[i], psz) == 0)
            if(stricmp(pszModule, psz) == 0) {
                dwModule = bwsMdlInfo.m_pModule[i];    
                return  0;
            }
    }         
    
    return -1;
}


/////////////////////////////////////////////////////////////////////////////
//
//  Name:   
//
//  Description: 
//
//  Input:  
//
//  Output: 
//
//  Return: 
//
/////////////////////////////////////////////////////////////////////////////
/*BOOL GetLineRange(unsigned short & uStart, unsigned short & uEnd)
{
    unsigned long dwModule;
    unsigned short uLine;    
    unsigned long dwStartAddr, dwEndAddr;
    
    dwStartAddr = SrcGetPC();
    if(SrcAddr2Linenum(dwStartAddr, uLine, dwModule) == -1) 
        return FALSE;
    if(SrcLinenum2Range(dwModule, uLine, dwStartAddr, dwEndAddr) == -1)
        return FALSE;

    uStart = (unsigned short)dwStartAddr;
    uEnd = (unsigned short)dwEndAddr;          
    if(!isBrowseOn) return TRUE;
    else if(((CBrowseWindow *)pBrowseWnd)->m_nDispMode == MODE_SOURCE)  
        return TRUE;
    else return FALSE;        
}*/

/////////////////////////////////////////////////////////////////////////////
//
//  Name:   
//
//  Description: 
//
//  Input:  
//
//  Output: 
//
//  Return: 
//
/////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////
extern SyntaxColor SrcColor;

/////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////
//
//  Name:   
//
//  Description: 
//
//  Input:  
//
//  Output: 
//
//  Return: 
//
/////////////////////////////////////////////////////////////////////////////
void BwsOpenWindow(BOOL isPCOn, CMDIFrameWnd * pParent, BOOL isHide)
{
    if(isBrowseOn)    return;
    pBrowseWnd = new CBrowseWindow(isPCOn);                        
    DWORD dwFlag = isHide ? 0 : WS_VISIBLE;
    if(!((CBrowseWindow *)pBrowseWnd)->Create("BROWSE", WS_CHILD
        |WS_OVERLAPPEDWINDOW|WS_CLIPCHILDREN|WS_HSCROLL|WS_VSCROLL|dwFlag,
        CFrameWnd::rectDefault, pParent)) {
        ASSERT(0);                         
        if(LoadOpt.m_isWarnings)
            AfxMessageBox(IDS_ERR_OPENSRC);
    }
    isBrowseOn = TRUE;
}
/////////////////////////////////////////////////////////////////////////////
//
//  Name:   
//
//  Description: 
//
//  Input:  
//
//  Output: 
//
//  Return: 
//
/////////////////////////////////////////////////////////////////////////////
void BwsPostLoad(void)
{             
    browseOpenSwitch=1;   
               
    if(isBrowseOn) {
        BwsResetView();
    }
}             

/////////////////////////////////////////////////////////////////////////////
//
//  Name:   
//
//  Description: 
//
//  Input:  
//
//  Output: 
//
//  Return: 
//
/////////////////////////////////////////////////////////////////////////////
void BwsResetView(void)
{
    if(!isBrowseOn) return;
    ((CBrowseWindow *)pBrowseWnd)->NewSource();
}

/////////////////////////////////////////////////////////////////////////////
//
//  Name:   
//
//  Description: Update display of source window by re-disassemble
//
//  Input:  
//
//  Output: 
//
//  Return: 
//
/////////////////////////////////////////////////////////////////////////////
void BwsUpdate()
{
    if(!isBrowseOn) return;
    ((CBrowseWindow *)pBrowseWnd)->UpdateDisp();
}

/////////////////////////////////////////////////////////////////////////////
//
//  Name:   SrcDispMode()
//
//  Description: Get display mode of the source window
//
//  Input:  NULL
//
//  Output: NULL
//
//  Return: -1  -- source window is not opened
//          0   -- Source Mode
//          1   -- Mixed Mode
//          2   -- Asm Mode    
//
/////////////////////////////////////////////////////////////////////////////
int BwsDispMode(void)
{
    if(!isBrowseOn) return -1;
    else return ((CBrowseWindow *)pBrowseWnd)->m_nDispMode;
}

/////////////////////////////////////////////////////////////////////////////
//
//  Name:   
//
//  Description: Show C source code at the specified address
//
//  Input:  
//      uAddr   --  the address
//
//  Output: NULL
//
//  Return: NULL
//
/////////////////////////////////////////////////////////////////////////////
/*
void CBrowseWindow::OnInspectFunc()
void SrcShowSource(unsigned short uAddr)
{       
    unsigned short uLine;
    unsigned long dwModule;
    char ach[40];                 
                                              
    if(SrcIsLoaded() == -1) {   // no symbol information
        if(LoadOpt.m_isWarnings)
            AfxMessageBox(IDS_PRM_NOSYMINFO);
        return;
    }
                                                        
    if(SrcAddr2Linenum(uAddr, uLine, dwModule) != 0) {  // invalid address
        wsprintf(ach, "No source code at address: %Xh!", uAddr);        
        if(LoadOpt.m_isWarnings)
            AfxMessageBox(ach);
        return;
    }
    
    if(BwsLoadModule(dwModule, TRUE) == SRC_LOAD_ERROR) {   // load error
        return;
    }             
    
    ((CBrowseWindow *)pBrowseWnd)->SelectText(FALSE);
    
    if(!isBrowseOn) {   //  source window hasn't been opened
        SrcOpenWindow(FALSE, 
            (CMDIFrameWnd *)(AfxGetApp()->m_pMainWnd), TRUE);
        pBrowseWnd->BringWindowToTop();
        ((CBrowseWindow *)pBrowseWnd)->UpdateSource(uLine - 1);
        pBrowseWnd->ShowWindow(SW_SHOW);
    } else if(pBrowseWnd->IsIconic()) { // source window is minimized
        ((CBrowseWindow *)pBrowseWnd)->UpdateSource(uLine - 1);
        pBrowseWnd->ShowWindow(SW_RESTORE);
    } else {    // source window may be not on top
        ((CBrowseWindow *)pBrowseWnd)->UpdateSource(uLine - 1);
        pBrowseWnd->BringWindowToTop();
    }        
}
*/
/////////////////////////////////////////////////////////////////////////////
CMenu NEAR CBrowseWindow::m_menu;                                            

/////////////////////////////////////////////////////////////////////////////
// CBrowseWindow                                                             
/////////////////////////////////////////////////////////////////////////////

IMPLEMENT_DYNCREATE(CBrowseWindow, CMDIChildWnd)

/////////////////////////////////////////////////////////////////////////////         
// Constructor/Destructor
/////////////////////////////////////////////////////////////////////////////

/////////////////////////////////////////////////////////////////////////////
//
//  Name:   
//
//  Description: 
//
//  Input:  
//
//  Output: 
//
//  Return: 
//
/////////////////////////////////////////////////////////////////////////////
BOOL CBrowseWindow::Create(LPCSTR szTitle, LONG style,
    const RECT& rect, CMDIFrameWnd * pParent)
{
    // Setup the shared m_menu
    if(m_menu.m_hMenu == NULL)
        m_menu.LoadMenu(IDR_BROWSE);
    m_hMenuShared = m_menu.m_hMenu;

    const char * pszBrowseClass =
        AfxRegisterWndClass(CS_HREDRAW | CS_VREDRAW | CS_DBLCLKS, 
                            ::LoadCursor(NULL,IDC_ARROW),
                            (HBRUSH)(COLOR_WINDOW+1),
                            AfxGetApp()->LoadIcon(IDR_BROWSE));
                            
    return CMDIChildWnd::Create(pszBrowseClass, szTitle,
        style, rect, pParent);
}

/////////////////////////////////////////////////////////////////////////////
//
//  Name:   
//
//  Description: 
//
//  Input:  
//
//  Output: 
//
//  Return: 
//
/////////////////////////////////////////////////////////////////////////////
CBrowseWindow::CBrowseWindow(BOOL isPCOn)
 : m_nFont(STANDARD_FONT), m_ptOffset(0, 0), m_rectClip(5, 5, 10, 10),
   m_isSel(FALSE/*TRUE*/)
{              
    // Set Help ID
    m_nIDHelp = IDR_BROWSE;

    // Load BP Markers  
/*    
    if(m_bmpBP.LoadBitmap(IDB_BP)==FALSE)
        TRACE("Error Loading Bitmap : bp.bmp\n");
*/        
    if(SrcEmu.GetPC())
    {
    	SrcEmu.GetModule();
		m_nBank=SrcEmu.m_nPCBank;		//bank1
	}
                                        
    if(bwsMdlInfo.m_uModules != 0 && bwsMdlInfo.IsModuleOn()) {             
    // File has been downloaded, and at least one source module
    // has been loaded
        if(!isPCOn || SrcEmu.IsPCModule(bwsMdlInfo.CurModule())) {
        // We need not mark PC or the current module is PC module,
        // then we can display on source mode
            m_nDispMode = MODE_SOURCE;
/////////////////////////////            
//            SetStepOpt();  

            //SrcEmu.m_nStepOpt = STEP_LINE;
            //m_nLeft = ::isBwsLineNo ? 8 : 2;
            CalcLeftEdge();
            m_ptOffset.x = 0;
            m_ptIndex.x = 0;
            if(SrcEmu.IsPCModule(bwsMdlInfo.CurModule())) {
            // The current module is PC module, we display from PC line
                m_ptIndex.y = SrcEmu.m_nPCLine;
                m_ptOffset.y = SrcEmu.m_nPCLine;            
            } else {
            // The current module is not PC module, display from first line
                m_ptIndex.y = 0;
                m_ptOffset.y = 0;            
            }
            Index2Caret();
            return;    
        }
    }                  
             
    // No file been downloaded, or no source module been loaded,             
    // then dispalay on asm mode
    long    lAddr;
    m_nDispMode = MODE_ASM;
////////////////////    
//    SetStepOpt(); 

    //SrcEmu.m_nStepOpt = STEP_INSTRUCTION;
    
    if(SrcEmu.m_lPCAddr < dwpMax+1) lAddr = SrcEmu.m_lPCAddr;
    else    lAddr = 0;    
    if(!BwsAsm.Dsm(m_nBank, (unsigned short)lAddr)) {
        AfxMessageBox(IDS_ERR_MEM);
    }        
    //m_nLeft = 7;           
    CalcLeftEdge();
    BwsAsm.m_nOffset = 0;
    BwsAsm.m_nIndex = 0;
    m_ptOffset.y = int(SrcEmu.m_lPCAddr) / 4;
    m_ptOffset.x = 0;
    m_ptIndex.x = 0;
    Index2Caret();
}

/////////////////////////////////////////////////////////////////////////////
//
//  Name:   
//
//  Description: 
//
//  Input:  
//
//  Output: 
//
//  Return: 
//
/////////////////////////////////////////////////////////////////////////////
CBrowseWindow::~CBrowseWindow()
{
    isBrowseOn = FALSE;

///////////////////////////////////////////    
//    SrcEmu.m_nStepOpt = STEP_INSTRUCTION;
                   
}                                                           

/////////////////////////////////////////////////////////////////////////////
//
//  Name:   
//
//  Description: Update display of source window by re-disassemble
//
//  Input:  
//
//  Output: 
//
//  Return: 
//
/////////////////////////////////////////////////////////////////////////////
void CBrowseWindow::UpdateDisp(void)
{
    if(m_nDispMode == MODE_SOURCE)  return;
    else if(m_nDispMode == MODE_MIXED) {
        UpdateMixed(m_ptOffset.y);
    } else {
        UpdateAsm(m_nBank, long(m_ptOffset.y)*4);    
    }
}

/////////////////////////////////////////////////////////////////////////////
// Set window status
/////////////////////////////////////////////////////////////////////////////


/////////////////////////////////////////////////////////////////////////////
//
//  Name:   
//
//  Description: Set Step Option
//
//  Input:  
//
//  Output: 
//
//  Return: 
//
/////////////////////////////////////////////////////////////////////////////
void CBrowseWindow::SetStepOpt(void)
{
/*
    if(m_nDispMode == MODE_SOURCE) {
        if(SrcEmu.m_isStatement) {
            SrcEmu.m_nStepOpt = STEP_STATEMENT;            
        } else {
            SrcEmu.m_nStepOpt = STEP_LINE;            
        }
    } else {
        SrcEmu.m_nStepOpt = STEP_INSTRUCTION;            
    } 
*/    
}

/////////////////////////////////////////////////////////////////////////////
//
//  Name:   
//
//  Description: Set the title of the source window
//
//  Input:  
//
//  Output: 
//
//  Return: 
//
/////////////////////////////////////////////////////////////////////////////
void CBrowseWindow::SetTitle(void)
{
    CString str;
    
    if(m_nDispMode != MODE_ASM) {
        str = "Browse: ";
        str += BWSSRCMDL.m_strFileName;
    } else {
        str = "Browse: [Disassembly]";
    }                                 
    
    SetWindowText(str);
}
                                          
/////////////////////////////////////////////////////////////////////////////
//
//  Name:   
//
//  Description: Set caret position
//
//  Input:  
//
//  Output: 
//
//  Return: 
//
/////////////////////////////////////////////////////////////////////////////
void CBrowseWindow::SetCaret(void)
{                       
    if(GetFocus() == this) {
        SetCaretPos(CPoint(Col2X(m_ptCaret.x), Row2Y(m_ptCaret.y)));
    }    
}                      

/////////////////////////////////////////////////////////////////////////////
//
//  Name:   
//
//  Description: calculate font size
//
//  Input:  
//
//  Output: 
//
//  Return: 
//
/////////////////////////////////////////////////////////////////////////////
void CBrowseWindow::CalcFontSize(void)
{
    TEXTMETRIC tm;
    CDC * pDC = GetDC();
    CFont * font = (CFont *)(pDC->SelectStockObject(m_nFont));
    pDC->GetTextMetrics(&tm);
    m_szFont.cy = tm.tmHeight + tm.tmExternalLeading;
    m_szFont.cx = tm.tmAveCharWidth;
    pDC->SelectObject(font);
    ReleaseDC(pDC); 
} 

/////////////////////////////////////////////////////////////////////////////
//
//  Name:   
//
//  Description: Calculate left space left for various display mode
//
//  Input:  
//
//  Output: 
//
//  Return: 
//
/////////////////////////////////////////////////////////////////////////////
void CBrowseWindow::CalcLeftEdge(void)
{
    if(m_nDispMode == MODE_ASM) m_nLeft = 10;    // 2+4+1
    else if(::isBwsLineNo)           m_nLeft = 8;    // 2+5+1
    else                        m_nLeft = 2;    // 2
}

/////////////////////////////////////////////////////////////////////////////
//
//  Name:   
//
//  Description: calculate view size
//
//  Input:  
//
//  Output: 
//
//  Return: 
//
/////////////////////////////////////////////////////////////////////////////
void CBrowseWindow::CalcViewSize(int cx, int cy)
{                               
    // Calculate left space left for various display mode
    /*if(m_nDispMode == MODE_ASM) m_nLeft = 7;    // 2+4+1
    else if(::isBwsLineNo)           m_nLeft = 8;    // 2+5+1
    else                        m_nLeft = 2;    // 2
    */


#ifdef  BWS_TOOL_WND  
    int nVWidth=GetSystemMetrics(SM_CXVSCROLL);
    int nHHight=GetSystemMetrics(SM_CYHSCROLL);
    m_pVScrollBar->MoveWindow(cx-nVWidth,0,nVWidth,cy-nHHight);
    m_pToolWnd->MoveWindow(0,cy-nHHight,200,nHHight);
    m_pHScrollBar->MoveWindow(200,cy-nHHight,cx-nVWidth-200,nHHight);
    cx-=nVWidth;
    cy-=nHHight;
#endif

     
    CalcLeftEdge();

    m_szView.cx = (cx - m_rectClip.left) / m_szFont.cx;
    m_szView.cy = (cy - m_rectClip.top) / m_szFont.cy;

    m_rectClip.right = m_rectClip.left + m_szView.cx * m_szFont.cx;
    m_rectClip.bottom = m_rectClip.top + m_szView.cy * m_szFont.cy;

    m_rectScroll = m_rectClip;
    m_rectScroll.left += m_nLeft * m_szFont.cx;
    
}                                 
                      
/////////////////////////////////////////////////////////////////////////////
//
//  Name:   
//
//  Description: calculate scroll szie                      
//
//  Input:  
//
//  Output: 
//
//  Return: 
//
/////////////////////////////////////////////////////////////////////////////
void CBrowseWindow::CalcScrollSize(void)
{                       

#ifdef BWS_TOOL_WND

    m_pHScrollBar->SetScrollRange(0, SourceList::MAX_LINELEN);
                                               
    if(m_nDispMode == MODE_ASM) 
        m_pVScrollBar->SetScrollRange(0, MAX_ASM_RANGE/(0x10000/(dwpMax+1)));
    else                                               
        m_pVScrollBar->SetScrollRange(0, BWSSRCLINES);

    m_pVScrollBar->SetScrollPos(m_ptOffset.y);            
    m_pHScrollBar->SetScrollPos(m_ptOffset.x);            
#else 
    SetScrollRange(SB_HORZ, 0, SourceList::MAX_LINELEN);
                                               
    if(m_nDispMode == MODE_ASM) 
        SetScrollRange(SB_VERT, 0, MAX_ASM_RANGE/(0x10000/(dwpMax+1)));
    else                                               
        SetScrollRange(SB_VERT, 0, BWSSRCLINES);

    SetScrollPos(SB_HORZ, m_ptOffset.x);
    SetScrollPos(SB_VERT, m_ptOffset.y);
#endif    
}                                                   
                                                 
/////////////////////////////////////////////////////////////////////////////
//
//  Name:   
//
//  Description: return the start address of the line with caret on it  
//
//  Input:  
//
//  Output: 
//
//  Return: 
//
/////////////////////////////////////////////////////////////////////////////
long CBrowseWindow::GetCaretAddr(void)
{    
    unsigned long dwAddr;
    AsmLine * pAsm;
    int nLine, nAsm;  
    int nBank;
    
    if(m_nDispMode == MODE_SOURCE) {
        if(m_ptIndex.y >= BWSSRCLINES) return dwpMax+1;
        if(SrcLinenum2Addr(bwsMdlInfo.CurModule(), 
            (unsigned short)(m_ptIndex.y + 1), dwAddr, nBank) == -1) 
            return dwpMax+1;    
    } else if(m_nDispMode == MODE_ASM) {
        if(BwsAsm.m_nIndex >= BWSASMLINES) return dwpMax+1;
        pAsm = (AsmLine *)(BwsAsm.GetLine(BwsAsm.m_nIndex));
        if(pAsm->m_chLabel) return dwpMax+1;
        else dwAddr = pAsm->m_uAddr;    
    } else {
        if(BwsMix.m_nIndex >= BWSMIXLINES) return dwpMax+1;
        nLine = BwsMix.Ofs2Line(BwsMix.m_nIndex, nAsm); 
        if(nAsm == -1)  return dwpMax+1;
        pAsm = (AsmLine *)(BwsMix.GetLine(nLine, nAsm));           
        if(pAsm->m_chLabel) return dwpMax+1;
        else dwAddr = pAsm->m_uAddr;    
    }
    
    return dwAddr;
}

/////////////////////////////////////////////////////////////////////////////
//
//  Name:   
//
//  Description: Must have been get PC & get PC module                  
//
//  Input:  
//
//  Output: 
//
//  Return: 
//
/////////////////////////////////////////////////////////////////////////////
BOOL CBrowseWindow::LoadModule(unsigned long dwModule, BOOL isHist)
{   
    if(BwsLoadModule(dwModule, isHist) == SRC_LOAD_ERROR) {
        return FALSE;
    }                       
    
    SelectText(FALSE);

    if(SrcEmu.IsPCModule(bwsMdlInfo.CurModule()))
        return UpdateSource(SrcEmu.m_nPCLine);
    else    return UpdateSource(0);    
}

/////////////////////////////////////////////////////////////////////////////
//
//  Name:   
//
//  Description: called when download a new source                 
//
//  Input:  
//
//  Output: 
//
//  Return: 
//
/////////////////////////////////////////////////////////////////////////////
void CBrowseWindow::NewSource(void)
{                                                  
    SelectText(FALSE);
    if(bwsMdlInfo.IsModuleOn()) {
        if(SrcEmu.IsPCModule(bwsMdlInfo.CurModule())) 
            UpdateSource(SrcEmu.m_nPCLine);
        else UpdateSource(0);
    } else if(SrcEmu.GetPC())
    {
        m_nBank=SrcEmu.m_nPCBank;
    	UpdateAsm(m_nBank, SrcEmu.m_lPCAddr);
    }
    else UpdateAsm(m_nBank, 0);
}

/////////////////////////////////////////////////////////////////////////////
//
//  Name:   
//
//  Description: Update Source Window
//
//  Input:  
//
//  Output: 
//
//  Return: 
//
/////////////////////////////////////////////////////////////////////////////
BOOL CBrowseWindow::UpdateSource(int nLine)
{
    ASSERT(bwsMdlInfo.IsModuleOn());
    ASSERT(nLine >= 0 && nLine <= BWSSRCLINES);
    
/*    if(m_nDispMode != MODE_SOURCE)
        SrcEmu.m_nStepOpt = STEP_LINE;*/
    m_nDispMode = MODE_SOURCE;
    //SetStepOpt();                

    //m_nLeft = ::isBwsLineNo ? 8 : 2;
    CalcLeftEdge();
    m_ptOffset.x = 0;
    m_ptIndex.x = 0;
    m_ptIndex.y = nLine;
    m_ptOffset.y = nLine;

    Index2Caret();

    CRect rect;
    GetClientRect(rect);
    CalcViewSize(rect.Width(), rect.Height());
    CalcScrollSize();
    InvalidateRect(NULL);          

    SetTitle();

#ifdef  BWS_TOOL_WND  
    if(m_pToolWnd)
       m_pToolWnd->SetBtn(1);
#endif

    return TRUE;
}

/////////////////////////////////////////////////////////////////////////////
//
//  Name:   
//
//  Description: 
//
//  Input:  
//
//  Output: 
//
//  Return: 
//
/////////////////////////////////////////////////////////////////////////////
BOOL CBrowseWindow::UpdateAsm(int nBank, long lAddr)
{
    SelectText(FALSE);

    long lAddr1;
    
    ASSERT(nBank==1||nBank>5&&nBank<=9);
    if(lAddr > dwpMax) lAddr1 = dwpMax-0xf;
    else lAddr1 = lAddr;
    
    if(!BwsAsm.Dsm(nBank, (unsigned short)lAddr1)) {
        AfxMessageBox(IDS_ERR_MEM);
        return FALSE;
    }          
    m_nBank=nBank;
    m_nDispMode = MODE_ASM;
    //SrcEmu.m_nStepOpt = STEP_INSTRUCTION;
    //SetStepOpt();
    
    //m_nLeft = 7;           
    CalcLeftEdge();
    m_ptOffset.x = 0;        
    m_ptIndex.x = 0;
    
    if(lAddr < dwpMax+1) {
        BwsAsm.m_nOffset = 0;
        BwsAsm.m_nIndex = 0;  
    } else {
        BwsAsm.m_nOffset = BWSASMLINES;
        BwsAsm.m_nIndex = BWSASMLINES;  
    }
    m_ptOffset.y = int(lAddr) / 4;
    
    Index2Caret();

    CRect rect;
    GetClientRect(rect);
    CalcViewSize(rect.Width(), rect.Height());
    CalcScrollSize();
    InvalidateRect(NULL);          

    SetTitle(); 

#ifdef  BWS_TOOL_WND  
    if(m_pToolWnd)
       m_pToolWnd->SetBtn(3);
#endif

    return TRUE;
}

/////////////////////////////////////////////////////////////////////////////
//
//  Name:   
//
//  Description: 
//
//  Input:  
//
//  Output: 
//
//  Return: 
//
/////////////////////////////////////////////////////////////////////////////
BOOL CBrowseWindow::UpdateMixed(int nLine)
{
    ASSERT(bwsMdlInfo.IsModuleOn());
    ASSERT(nLine >= 0 && nLine <= BWSSRCLINES);
    
    SelectText(FALSE);

    int nLine1;
    if(nLine < BWSSRCLINES)    nLine1 = nLine;
    else    nLine1 = BWSSRCLINES - 1;

    if(!BwsMix.Dsm(nLine1)) {
        AfxMessageBox(IDS_ERR_MEM);
        return FALSE;
    }
                                             
    int nOfs = nLine < BWSSRCLINES ? 0 : BWSMIXLINES;
                                                 
    UpdateMixedMode(nOfs);

#ifdef  BWS_TOOL_WND  
    if(m_pToolWnd)
       m_pToolWnd->SetBtn(2);
#endif

    return TRUE;
}

/////////////////////////////////////////////////////////////////////////////
//
//  Name:   
//
//  Description: 
//
//  Input:  
//
//  Output: 
//
//  Return: 
//
/////////////////////////////////////////////////////////////////////////////
BOOL CBrowseWindow::UpdateMixed(int nBank, long lAddr)
{
    ASSERT(lAddr >= 0 && lAddr < dwpMax+1);
    
    unsigned short uLine;
    unsigned long dwModule;
    
    ASSERT(nBank==1||nBank>5&&nBank<=9);
    if(SrcAddr2Linenum(nBank, lAddr, uLine, dwModule) != 0)    
        return FALSE;

    if(!bwsMdlInfo.IsModuleOn() || dwModule != bwsMdlInfo.CurModule()) {
        if(BwsLoadModule(dwModule) == SRC_LOAD_ERROR) 
            return FALSE;
    }

    if(!BwsMix.Dsm(uLine - 1)) {
        AfxMessageBox(IDS_ERR_MEM);
        return FALSE;
    }                  
    m_nBank=nBank;
    int nOfs = BwsMix.Addr2Ofs(nBank, (unsigned short)lAddr);
            
    UpdateMixedMode(nOfs); 

#ifdef  BWS_TOOL_WND  
    if(m_pToolWnd)
       m_pToolWnd->SetBtn(2);
#endif
    
    return TRUE;
}

/////////////////////////////////////////////////////////////////////////////
//
//  Name:   
//
//  Description: 
//
//  Input:  
//
//  Output: 
//
//  Return: 
//
/////////////////////////////////////////////////////////////////////////////
void CBrowseWindow::UpdateMixedMode(int nOfs)
{
    m_nDispMode = MODE_MIXED;
    //SrcEmu.m_nStepOpt = STEP_INSTRUCTION;
//    SetStepOpt();

    CRect rect;          
    GetClientRect(rect);
    CalcViewSize(rect.Width(), rect.Height());            
    CalcScrollSize();
               
    int nLine, nAsm;
    nLine = BwsMix.Ofs2Line(nOfs, nAsm);
                   
    m_ptOffset.x = 0;
    m_ptOffset.y = nLine;
    m_ptIndex.x = 0;
    BwsMix.m_nOffset = nOfs;
    BwsMix.m_nIndex = nOfs;                
    
    Index2Caret();
    InvalidateRect(NULL);
    
#ifdef BWS_TOOL_WND
    m_pVScrollBar->SetScrollPos(m_ptOffset.y);            
    m_pHScrollBar->SetScrollPos(m_ptOffset.x);            
#else    
    SetScrollPos(SB_HORZ, m_ptOffset.x);
    SetScrollPos(SB_VERT, m_ptOffset.y);
#endif    
    
    SetTitle();
}

/////////////////////////////////////////////////////////////////////////////
// Char position <-> Point position                        
/////////////////////////////////////////////////////////////////////////////             
/////////////////////////////////////////////////////////////////////////////
//
//  Name:   
//
//  Description: 
//
//  Input:  
//
//  Output: 
//
//  Return: 
//
/////////////////////////////////////////////////////////////////////////////
int CBrowseWindow::Row2Y(int nRow) const
{
    return  nRow * m_szFont.cy + m_rectClip.top;
}

/////////////////////////////////////////////////////////////////////////////
//
//  Name:   
//
//  Description: 
//
//  Input:  
//
//  Output: 
//
//  Return: 
//
/////////////////////////////////////////////////////////////////////////////
int CBrowseWindow::Col2X(int nCol) const
{
    return  nCol * m_szFont.cx + m_rectClip.left;
}

/////////////////////////////////////////////////////////////////////////////
//
//  Name:   
//
//  Description: 
//
//  Input:  
//
//  Output: 
//
//  Return: 
//
/////////////////////////////////////////////////////////////////////////////
int CBrowseWindow::Y2Row(int ny) const
{
    return  (ny - m_rectClip.top) / m_szFont.cy;
}

/////////////////////////////////////////////////////////////////////////////
//
//  Name:   
//
//  Description: 
//
//  Input:  
//
//  Output: 
//
//  Return: 
//
/////////////////////////////////////////////////////////////////////////////
int CBrowseWindow::X2Col(int nx) const
{
    return  (nx - m_rectClip.left) / m_szFont.cx;
}                   

/////////////////////////////////////////////////////////////////////////////
// Caret position <-> Buffer position                       
/////////////////////////////////////////////////////////////////////////////            
/////////////////////////////////////////////////////////////////////////////
//
//  Name:   
//
//  Description: 
//
//  Input:  
//
//  Output: 
//
//  Return: 
//
/////////////////////////////////////////////////////////////////////////////
void CBrowseWindow::Caret2Index(void)
{                              
    m_ptIndex.x = m_ptCaret.x - m_nLeft + m_ptOffset.x;
    
    if(m_nDispMode == MODE_SOURCE)
        m_ptIndex.y = Row2Line(m_ptCaret.y); 
    else if(m_nDispMode == MODE_ASM) 
        BwsAsm.m_nIndex = Row2Line(m_ptCaret.y);
    else 
        BwsMix.m_nIndex = Row2Line(m_ptCaret.y);  
}                                           

/////////////////////////////////////////////////////////////////////////////
//
//  Name:   
//
//  Description: 
//
//  Input:  
//
//  Output: 
//
//  Return: 
//
/////////////////////////////////////////////////////////////////////////////
void CBrowseWindow::Index2Caret(void)
{
    m_ptCaret.x = m_ptIndex.x + m_nLeft - m_ptOffset.x;
    
    if(m_nDispMode == MODE_SOURCE) 
        m_ptCaret.y = Line2Row(m_ptIndex.y);
    else if(m_nDispMode == MODE_ASM) 
        m_ptCaret.y = Line2Row(BwsAsm.m_nIndex);        
    else 
        m_ptCaret.y = Line2Row(BwsMix.m_nIndex);
}

/////////////////////////////////////////////////////////////////////////////         
// Line number <-> Row Number                          
/////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////
//
//  Name:   
//
//  Description: 
//
//  Input:  
//
//  Output: 
//
//  Return: 
//
/////////////////////////////////////////////////////////////////////////////
int CBrowseWindow::Line2Row(int nLine) const
{                                           
    if(m_nDispMode == MODE_SOURCE)  // nLine is offset to source lines 
        return  nLine - m_ptOffset.y;
    else if(m_nDispMode == MODE_ASM)    // nLine is offset to asm lines in buffer     
        return  nLine - BwsAsm.m_nOffset;
    else    // nLine is offset to current mixed lines in buffer
        return  nLine - BwsMix.m_nOffset;
}


/////////////////////////////////////////////////////////////////////////////
//
//  Name:   
//
//  Description: 
//
//  Input:  
//
//  Output: 
//
//  Return: 
//
/////////////////////////////////////////////////////////////////////////////
int CBrowseWindow::Row2Line(int nRow) const
{
    if(m_nDispMode == MODE_SOURCE) 
        return  nRow + m_ptOffset.y;
    else if(m_nDispMode == MODE_ASM) 
        return  nRow + BwsAsm.m_nOffset;
    else    // return offset to mixed lines
        return  nRow + BwsMix.m_nOffset;
}
                                                       
/////////////////////////////////////////////////////////////////////////////                                                       
// Hit Test
/////////////////////////////////////////////////////////////////////////////

/////////////////////////////////////////////////////////////////////////////
//
//  Name:   
//
//  Description: Test if Line in view                                  
//
//  Input:  
//
//  Output: 
//
//  Return: 
//
/////////////////////////////////////////////////////////////////////////////
BOOL CBrowseWindow::IsYIn(int ny) const
{                                         
    int nRow = Line2Row(ny);
    return nRow >= 0 && nRow < m_szView.cy;
}                                    
                       
/////////////////////////////////////////////////////////////////////////////
//
//  Name:   
//
//  Description: test if Col in view                                    
//
//  Input:  
//
//  Output: 
//
//  Return: 
//
/////////////////////////////////////////////////////////////////////////////
BOOL CBrowseWindow::IsXIn(int nx) const
{
    return nx >= m_ptOffset.x && nx < m_ptOffset.x + m_szView.cx - m_nLeft;
}                                    
  


////////////////////// ///////////////////////////////////////////////////////                                                         
// Show PC Marker
/////////////////////////////////////////////////////////////////////////////                                                         
/////////////////////////////////////////////////////////////////////////////
//
//  Name:   
//
//  Description: 
//
//  Input:  
//
//  Output: 
//
//  Return: 
//
/////////////////////////////////////////////////////////////////////////////
void CBrowseWindow::ShowPCMarker(void)
{           
    if(m_nDispMode == MODE_SOURCE) {
        ShowPCLineMarker();
    } else if(m_nDispMode == MODE_ASM) {
        ShowPCAsmMarker();
    } else {
        ShowPCMixMarker();
    }
}

/////////////////////////////////////////////////////////////////////////////
//
//  Name:   
//
//  Description: 
//
//  Input:  
//
//  Output: 
//
//  Return: 
//
/////////////////////////////////////////////////////////////////////////////
void CBrowseWindow::ShowPCAsmMarker(void)
{
    ASSERT(m_nDispMode == MODE_ASM);
    //ASSERT(SrcEmu.m_nStepOpt == STEP_INSTRUCTION);
        
    int nRow, nLine;   
    
    // Clear old PC Marker                     
    if(SrcEmu.m_lPCAddr < dwpMax+1) {
        nLine = BwsAsm.Addr2Line(m_nBank, SrcEmu.m_lPCAddr);
        if(nLine < BWSASMLINES) {
            nRow = Line2Row(nLine);        
            if(nRow >= 0 && nRow < m_szView.cy) {
                SrcEmu.m_lPCAddr = dwpMax+1;
                UpdateRow(nRow);
            }
        }
    }
                
    // Get new PC Addr            
    if(!SrcEmu.GetPC()) return;
    
    if(SrcEmu.GetModule()) {
        if(LoadModule(SrcEmu.m_dwPCModule)) {
            //if(SrcEmu.m_nStepOpt == STEP_INSTRUCTION)
              //  SrcEmu.m_nStepOpt = STEP_LINE;
            //SetStepOpt();  
            return;
        }
    }
    m_nBank=SrcEmu.m_nPCBank;
    // PC Line is in view
    nLine = BwsAsm.Addr2Line(m_nBank, SrcEmu.m_lPCAddr);
    if(nLine < BWSASMLINES) {
        nRow = Line2Row(nLine);        
        if(nRow >= 0 && nRow < m_szView.cy) {
            BwsAsm.m_nIndex = nLine;
            Index2Caret();
            SetCaret();
            UpdateRow(nRow);  
            return;
        }
    }
                    
    // PC Line is not in view                    
    UpdateAsm(m_nBank,SrcEmu.m_lPCAddr);
}                            

/////////////////////////////////////////////////////////////////////////////
//
//  Name:   
//
//  Description: 
//
//  Input:  
//
//  Output: 
//
//  Return: 
//
/////////////////////////////////////////////////////////////////////////////
void CBrowseWindow::ShowPCLineMarker(void)
{
    ASSERT(m_nDispMode == MODE_SOURCE);
    ASSERT(bwsMdlInfo.IsModuleOn());
//    ASSERT(SrcEmu.m_nStepOpt == STEP_LINE);

    int nRow;                   

    // Clear old PC Marker                 
    if(SrcEmu.IsPCModule(bwsMdlInfo.CurModule()) && 
        SrcEmu.m_nPCLine >= 0 && SrcEmu.m_nPCLine < BWSSRCLINES) {
        nRow = Line2Row(SrcEmu.m_nPCLine);    
        if(nRow >= 0 && nRow < m_szView.cy) {
            SrcEmu.m_lPCAddr = dwpMax+1;
            UpdateRow(nRow);
        }
    }    
         
    // Get new PC Addr     
    if(!SrcEmu.GetPC()) return;
    SrcEmu.GetModule();
    m_nBank=SrcEmu.m_nPCBank;
    if(SrcEmu.m_nPCLine >= 0 && SrcEmu.m_dwPCModule == bwsMdlInfo.CurModule()) {
        nRow = Line2Row(SrcEmu.m_nPCLine);
        if(nRow >= 0 && nRow < m_szView.cy) {
            m_ptIndex.y = SrcEmu.m_nPCLine;
            Index2Caret();
            SetCaret();
            UpdateRow(nRow);  
        } else UpdateSource(SrcEmu.m_nPCLine);
    } else if(SrcEmu.m_nPCLine >= 0 && 
        BwsLoadModule(SrcEmu.m_dwPCModule) != SRC_LOAD_ERROR) {
        SelectText(FALSE);
        UpdateSource(SrcEmu.m_nPCLine);                        
    } else UpdateAsm(m_nBank, SrcEmu.m_lPCAddr);
}   

/////////////////////////////////////////////////////////////////////////////
//
//  Name:   
//
//  Description: 
//
//  Input:  
//
//  Output: 
//
//  Return: 
//
/////////////////////////////////////////////////////////////////////////////
void CBrowseWindow::ShowPCMixMarker(void)
{
    ASSERT(m_nDispMode == MODE_MIXED);
    //ASSERT(SrcEmu.m_nStepOpt == STEP_INSTRUCTION);

    int nRow;   
    int nOfs;
    
    // Clear old PC Marker                     
    if(SrcEmu.IsPCModule(bwsMdlInfo.CurModule()) && 
        SrcEmu.m_nPCLine >= 0 && SrcEmu.m_nPCLine < BWSSRCLINES) {
        nOfs = BwsMix.Addr2Ofs(m_nBank, (unsigned short)(SrcEmu.m_lPCAddr));
        if(nOfs < BWSMIXLINES) {
            nRow = Line2Row(nOfs);        
            if(nRow >= 0 && nRow < m_szView.cy) {
                SrcEmu.m_lPCAddr = dwpMax+1;
                UpdateRow(nRow);
            }
        }
    }
                
    // Get new PC Addr            
    if(!SrcEmu.GetPC()) return;
    SrcEmu.GetModule();
	m_nBank=SrcEmu.m_nPCBank;
    if(SrcEmu.m_nPCLine >= 0 && SrcEmu.m_dwPCModule == bwsMdlInfo.CurModule()) {
        nOfs = BwsMix.Addr2Ofs(m_nBank, (unsigned short)(SrcEmu.m_lPCAddr));
        if(nOfs < BWSMIXLINES) {
            nRow = Line2Row(nOfs);        
            if(nRow >= 0 && nRow < m_szView.cy) {
                BwsMix.m_nIndex = nOfs;
                Index2Caret();
                SetCaret();
                UpdateRow(nRow);
                return;
            }
        } 
        UpdateMixed(m_nBank, SrcEmu.m_lPCAddr);
    } else if(SrcEmu.m_nPCLine >= 0 && BwsLoadModule(SrcEmu.m_dwPCModule) 
        != SRC_LOAD_ERROR)
        UpdateMixed(m_nBank, SrcEmu.m_lPCAddr);
    else UpdateAsm(m_nBank, SrcEmu.m_lPCAddr);
}

/////////////////////////////////////////////////////////////////////////////
//
//  Name:   
//
//  Description: 
//
//  Input:  
//
//  Output: 
//
//  Return: 
//
/////////////////////////////////////////////////////////////////////////////
void CBrowseWindow::UpdateRow(int nRow)
{             
    ASSERT(nRow >= 0 && nRow < m_szView.cy);

    CRect   rect(CPoint(m_rectClip.left, Row2Y(nRow)),
                CSize(m_rectClip.Width(), m_szFont.cy)); 
    InvalidateRect(&rect);
}  
                        
/////////////////////////////////////////////////////////////////////////////
//
//  Name:   
//
//  Description: 
//
//  Input:  
//
//  Output: 
//
//  Return: 
//
/////////////////////////////////////////////////////////////////////////////
void CBrowseWindow::ClearMarker(CDC * pDC, int nRow)
{                                                 
    ASSERT(pDC);

    if(nRow < 0 || nRow >= m_szView.cy) return;

    CRect   rect(CPoint(Col2X(0), Row2Y(nRow)),
                CSize(2 * m_szFont.cx, m_szFont.cy));
    CBrush br(PALETTEINDEX(SrcColor.m_nBackground));
    pDC->FillRect(rect, &br);    
}

/////////////////////////////////////////////////////////////////////////////
//
//  Name:   
//
//  Description: 
//
//  Input:  
//
//  Output: 
//
//  Return: 
//
/////////////////////////////////////////////////////////////////////////////
void CBrowseWindow::SetMarker(CDC * /*pDC*/, int /*nRow*/, int /*nType*/)
{                 
/*
    ASSERT(pDC);                               
    
    if(nRow < 0 || nRow >= m_szView.cy) return;

    CRect   rect(CPoint(Col2X(0), Row2Y(nRow)),
                CSize(2 * m_szFont.cx, m_szFont.cy));
    if(nType == MARKER_PC) {
        if(m_bmpPC.m_hObject != NULL) 
            DrawBitmap(&m_bmpPC, rect, pDC);
    } else if(nType == MARKER_BP) {
        if(m_bmpBP.m_hObject != NULL) 
            DrawBitmap(&m_bmpBP, rect, pDC);
    } else if(nType == MARKER_PCBP) {
        if(m_bmpPCBP.m_hObject != NULL) 
            DrawBitmap(&m_bmpPCBP, rect, pDC);
    }
*/    
}

/////////////////////////////////////////////////////////////////////////////
// Show Line
/////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////
//
//  Name:   
//
//  Description: 
//
//  Input:  
//
//  Output: 
//
//  Return: 
//
/////////////////////////////////////////////////////////////////////////////
void CBrowseWindow::ShowSourceLine(CDC * pDC, int nRow, int nLine)
{       
    ASSERT(m_nDispMode != MODE_ASM);
    ASSERT(pDC);
    ASSERT(nRow >= 0 && nRow < m_szView.cy);
    
    if(nLine < 0 || nLine >= BWSSRCLINES)  return;

    int ny = Row2Y(nRow);
    int nx;
    int nNext;
             
    nNext = 2;
    nx = Col2X(nNext);

    // Show Line Number         
    if(::isBwsLineNo) {  
        char szLineNo[7];
        wsprintf(szLineNo, "%5d ", nLine + 1);
        pDC->SetTextColor(PALETTEINDEX(SrcColor.m_nCodeLine));
        pDC->SetBkColor(PALETTEINDEX(SrcColor.m_nBackground));
        pDC->TextOut(nx, ny, szLineNo);    
        nNext += 6;
        nx = Col2X(nNext);
    }
                   
    // Show Source Line                   
    int nFirst = m_ptOffset.x;
    SourceElement * p1 = BWSSRCMDL.GetLine(nLine);
    if(!p1) return;

   if(p1->m_nLength == 0 || nFirst > p1->m_nLength - 1)   return;//goto SRC_BP1;

   SyntaxColorElement * p2 = 
            (SyntaxColorElement *)(p1->m_Color.GetFirst());

   while(p2) {
            if(nFirst >= p2->m_nFirstCol && nFirst <= p2->m_nLastCol) {
                if(p2->m_nSyntaxType == CSYN_CODE || 
                    p2->m_nSyntaxType == CSYN_STRING) {
                    if(m_nDispMode == MODE_SOURCE)
                        pDC->SetTextColor(PALETTEINDEX(SrcColor.m_nSource));
                    else
                        pDC->SetTextColor(PALETTEINDEX(SrcColor.m_nSrcKey));
                    pDC->SetBkColor(PALETTEINDEX(SrcColor.m_nBackground));
                } else if(p2->m_nSyntaxType == CSYN_KEYWORD) {
                    pDC->SetTextColor(PALETTEINDEX(SrcColor.m_nKeyword));
                    pDC->SetBkColor(PALETTEINDEX(SrcColor.m_nBackground));
                } else if(p2->m_nSyntaxType == CSYN_COMMENT) {
                    pDC->SetTextColor(PALETTEINDEX(SrcColor.m_nComment));
                    pDC->SetBkColor(PALETTEINDEX(SrcColor.m_nBackground));
                }
                pDC->TextOut(nx, ny, p1->m_szLine + nFirst, 
                    p2->m_nLastCol - nFirst + 1);
                nNext += p2->m_nLastCol - nFirst + 1;
                nFirst = p2->m_nLastCol + 1;
                nx = Col2X(nNext);
            }   
            p2 = (SyntaxColorElement *)(p1->m_Color.GetNext());
   }                 

    // Show Selected text
    if(m_isSel && m_nDispMode == MODE_SOURCE && 
        nLine == m_nSelLine) {
        pDC->SetTextColor(PALETTEINDEX(COLOR_WHITE));
        pDC->SetBkColor(PALETTEINDEX(COLOR_BLACK));
        if(m_nSelCol + m_strSel.GetLength() <= m_ptOffset.x)   return; //goto SRC_BP1;
        else if(m_nSelCol >= m_ptOffset.x)
            pDC->TextOut(Col2X(m_nSelCol - m_ptOffset.x + m_nLeft), 
                ny, p1->m_szLine + m_nSelCol, m_strSel.GetLength());
        else
            pDC->TextOut(Col2X(m_nLeft), ny, p1->m_szLine + m_ptOffset.x, 
                m_nSelCol + m_strSel.GetLength() - m_ptOffset.x);
    }   
       
}                                  

/////////////////////////////////////////////////////////////////////////////
//
//  Name:   
//
//  Description: 
//
//  Input:  
//
//  Output: 
//
//  Return: 
//
/////////////////////////////////////////////////////////////////////////////
void CBrowseWindow::ShowDsmLine(CDC * pDC, int nRow, int nLine)
{
    ASSERT(m_nDispMode == MODE_ASM);
    ASSERT(pDC);
    ASSERT(nRow >= 0 && nRow < m_szView.cy);

    int ny = Row2Y(nRow);
    
    AsmLine * pAsm = BwsAsm.GetLine(nLine);
    if(!pAsm)   return;

    pDC->SetTextColor(PALETTEINDEX(COLOR_BLACK));
    pDC->SetBkColor(PALETTEINDEX(COLOR_WHITE));
    
    // Show Address    
    //modify by Chris, 12/23/96
    if(pAsm->m_chLabel == 0) {
        char szAddr[9];
        if(pAsm->m_nBank==1)
        	wsprintf(szAddr, "%04X    ", pAsm->m_uAddr);
        else
        {
        	ASSERT(pAsm->m_nBank>5&&pAsm->m_nBank<=9);
        	wsprintf(szAddr, "P%d:%04X ", pAsm->m_nBank-6, pAsm->m_uAddr);
        }
        pDC->TextOut(Col2X(2), ny, szAddr );    
    }
    
    // Show Source Line                         
    if(m_ptOffset.x < pAsm->m_strText.GetLength())
        pDC->TextOut(Col2X(m_nLeft), ny, 
            (const char *)(pAsm->m_strText) + m_ptOffset.x);
                                         
    BYTE eFlag;
    BYTE spacebank=BYTE(pAsm->m_nBank);
    if(!(pAsm->m_chLabel) && BptSearchBpt(spacebank, pAsm->m_uAddr, eFlag)) 
        if(eFlag)   SetMarker(pDC, nRow, MARKER_BP);                                             
}       

/////////////////////////////////////////////////////////////////////////////
//
//  Name:   
//
//  Description: 
//
//  Input:  
//
//  Output: 
//
//  Return: 
//
/////////////////////////////////////////////////////////////////////////////
void CBrowseWindow::ShowMixedLine(CDC * pDC, int nRow, int nSrc, int nAsm)
{   
    ASSERT(m_nDispMode == MODE_MIXED);
    ASSERT(pDC);
    ASSERT(nRow >= 0 && nRow < m_szView.cy);
    
    if(nSrc < 0 || nSrc >= BWSSRCLINES)    return;
    if(nAsm < 0)    return;

    int ny = Row2Y(nRow);
    AsmLine * pAsm = BwsMix.GetLine(nSrc, nAsm);
    if(!pAsm)   return;
                                                      
    char szAddr[9];
    if(pAsm->m_chLabel == 0) {
        if(pAsm->m_nBank==1)
        	wsprintf(szAddr, "%04X    ", pAsm->m_uAddr);
        else
        {
        	ASSERT(pAsm->m_nBank>5&&pAsm->m_nBank<=9);
        	wsprintf(szAddr, "P%d:%04X ", pAsm->m_nBank-6, pAsm->m_uAddr);
        }
    } else {
        strcpy(szAddr, "        ");
    }
    CString str(szAddr);
    str += pAsm->m_strText;

    pDC->SetTextColor(PALETTEINDEX(COLOR_BLACK));
    pDC->SetBkColor(PALETTEINDEX(COLOR_WHITE));

    if(m_ptOffset.x < pAsm->m_strText.GetLength() + 5)
        pDC->TextOut(Col2X(m_nLeft), ny, (const char *)str + m_ptOffset.x);
                                           
}                           

/////////////////////////////////////////////////////////////////////////////
// Scroll viewport                                                 
/////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////
//
//  Name:   
//
//  Description: 
//
//  Input:  
//
//  Output: 
//
//  Return: 
//
/////////////////////////////////////////////////////////////////////////////
void CBrowseWindow::OnUp(void)
{
long lAddr;

    if(m_nDispMode == MODE_SOURCE) {
        if(m_ptOffset.y > 0) {
            -- m_ptOffset.y;
            ScrollWindow(0, m_szFont.cy, &m_rectClip, &m_rectClip);
        }
    } else if(m_nDispMode == MODE_ASM) {
        if(BwsAsm.m_nOffset == 0 && BwsAsm.IsHome()) return;
        if(BwsAsm.m_nOffset > 0) {
            -- BwsAsm.m_nOffset;
            ScrollWindow(0, m_szFont.cy, &m_rectClip, &m_rectClip);
        } else {
            BwsAsm.Line2AddrL(BwsAsm.m_nOffset, m_nBank, lAddr);
            if(!BwsAsm.DsmPrev()) {
                AfxMessageBox(IDS_ERR_MEM);
                return;
            } else Invalidate();
            BwsAsm.m_nOffset = BwsAsm.MatchAddr2LineL(m_nBank, lAddr);
            if(BwsAsm.m_nOffset > 0) {
                -- BwsAsm.m_nOffset;
                ScrollWindow(0, m_szFont.cy, &m_rectClip, &m_rectClip);
            }
        }    
        BwsAsm.Line2AddrL(BwsAsm.m_nOffset, m_nBank, lAddr);
        m_ptOffset.y=int(lAddr/4);
    } else {          
        if(BwsMix.m_nOffset == 0 && BwsMix.IsHome()) return;
        int nSrc, nAsm;
        if(BwsMix.m_nOffset > 0) {
            -- BwsMix.m_nOffset;
        } else {
            nSrc = BwsMix.Ofs2Line(BwsMix.m_nOffset, nAsm);
            if(!BwsMix.DsmPrev()) {
                AfxMessageBox(IDS_ERR_MEM);
                return;
            } else Invalidate();                            
            BwsMix.m_nOffset = BwsMix.Line2Ofs(nSrc, nAsm);            
            -- BwsMix.m_nOffset;
        }   
        m_ptOffset.y = BwsMix.Ofs2Line(BwsMix.m_nOffset, nAsm);
        ScrollWindow(0, m_szFont.cy, &m_rectClip, &m_rectClip);
    }
    
#ifdef BWS_TOOL_WND
    m_pVScrollBar->SetScrollPos(m_ptOffset.y);            
#else    
    SetScrollPos(SB_VERT, m_ptOffset.y);
#endif    
    Caret2Index();
}

/////////////////////////////////////////////////////////////////////////////
//
//  Name:   
//
//  Description: 
//
//  Input:  
//
//  Output: 
//
//  Return: 
//
/////////////////////////////////////////////////////////////////////////////
void CBrowseWindow::OnDown(void)
{
long lAddr;

    if(m_nDispMode == MODE_SOURCE) {
        if(m_ptOffset.y < BWSSRCLINES) {
            ++ m_ptOffset.y;
            ScrollWindow(0, -m_szFont.cy, &m_rectClip, &m_rectClip);
        }
    } else if(m_nDispMode == MODE_ASM) {
        if(BwsAsm.m_nOffset >= BWSASMLINES && BwsAsm.IsEnd())   
            return;                           
        if(BwsAsm.m_nOffset + m_szView.cy < BWSASMLINES || 
            BwsAsm.IsEnd()) {   
            if(BwsAsm.m_nOffset < BWSASMLINES) {
                ++ BwsAsm.m_nOffset;   
                ScrollWindow(0, -m_szFont.cy, &m_rectClip, &m_rectClip);
            }
        } else {
            BwsAsm.Line2AddrL(BwsAsm.m_nOffset, m_nBank, lAddr);
            if(!BwsAsm.DsmNext()) {
                AfxMessageBox(IDS_ERR_MEM);
                return;
            } else Invalidate();
            BwsAsm.m_nOffset = BwsAsm.MatchAddr2LineL(m_nBank, lAddr); 
            if(BwsAsm.m_nOffset < BWSASMLINES) {
                ++ BwsAsm.m_nOffset;   
                ScrollWindow(0, -m_szFont.cy, &m_rectClip, &m_rectClip);
            }
        }    
        BwsAsm.Line2AddrL(BwsAsm.m_nOffset, m_nBank, lAddr);
        m_ptOffset.y = int(lAddr/4);
    } else {                    
        if(BwsMix.m_nOffset >= BWSMIXLINES && BwsMix.IsEnd())  return;
        int nSrc, nAsm;    
        if(BwsMix.m_nOffset + m_szView.cy < BWSMIXLINES || BwsMix.IsEnd()) {
            ++ BwsMix.m_nOffset;
        } else {
            nSrc = BwsMix.Ofs2Line(BwsMix.m_nOffset, nAsm);
            if(!BwsMix.DsmNext()) {
                AfxMessageBox(IDS_ERR_MEM);
                return;
            } else Invalidate();
            BwsMix.m_nOffset = BwsMix.Line2Ofs(nSrc, nAsm);            
            ++ BwsMix.m_nOffset;
        }
        m_ptOffset.y = BwsMix.Ofs2Line(BwsMix.m_nOffset, nAsm);
        ScrollWindow(0, -m_szFont.cy, &m_rectClip, &m_rectClip);
    }
    
#ifdef BWS_TOOL_WND
    m_pVScrollBar->SetScrollPos(m_ptOffset.y);            
#else    
    SetScrollPos(SB_VERT, m_ptOffset.y);
#endif    

    Caret2Index();
}

/////////////////////////////////////////////////////////////////////////////
//
//  Name:   
//
//  Description: 
//
//  Input:  
//
//  Output: 
//
//  Return: 
//
/////////////////////////////////////////////////////////////////////////////
void CBrowseWindow::OnLeft(void)
{
    if(m_ptOffset.x > 0) {
        -- m_ptOffset.x;
        ScrollWindow(m_szFont.cx, 0, &m_rectScroll, &m_rectScroll);
    }
    
#ifdef BWS_TOOL_WND
    m_pHScrollBar->SetScrollPos(m_ptOffset.x);            
#else    
    SetScrollPos(SB_HORZ, m_ptOffset.x);
#endif    

    Caret2Index();
}

/////////////////////////////////////////////////////////////////////////////
//
//  Name:   
//
//  Description: 
//
//  Input:  
//
//  Output: 
//
//  Return: 
//
/////////////////////////////////////////////////////////////////////////////
void CBrowseWindow::OnRight(void)
{
    if(m_ptOffset.x < SourceList::MAX_LINELEN) {
        ++ m_ptOffset.x;
        ScrollWindow(-m_szFont.cx, 0, &m_rectScroll, &m_rectScroll);
    }
    
#ifdef BWS_TOOL_WND
    m_pHScrollBar->SetScrollPos(m_ptOffset.x);            
#else    
    SetScrollPos(SB_HORZ, m_ptOffset.x);
#endif    

    Caret2Index();
}

/////////////////////////////////////////////////////////////////////////////
//
//  Name:   
//
//  Description: 
//
//  Input:  
//
//  Output: 
//
//  Return: 
//
/////////////////////////////////////////////////////////////////////////////
void CBrowseWindow::OnPgUp(void)
{                         
long lAddr;
int nPage = 0;
    
    if(m_nDispMode == MODE_SOURCE) {
        if(m_ptOffset.y >= m_szView.cy) nPage = m_szView.cy;
        else nPage = m_ptOffset.y;
        m_ptOffset.y -= nPage;
        ScrollWindow(0, m_szFont.cy * nPage, &m_rectClip, &m_rectClip);
    } else if(m_nDispMode == MODE_ASM) {
        if(BwsAsm.m_nOffset == 0 && BwsAsm.IsHome()) return;
        if(BwsAsm.m_nOffset > m_szView.cy) {
            BwsAsm.m_nOffset -= m_szView.cy;
            ScrollWindow(0, m_szFont.cy * m_szView.cy, &m_rectClip, &m_rectClip);
        } else if(BwsAsm.IsHome()) { 
            nPage = BwsAsm.m_nOffset;
            BwsAsm.m_nOffset = 0;
            ScrollWindow(0, m_szFont.cy * nPage, &m_rectClip, &m_rectClip);
        } else {              
            BwsAsm.Line2AddrL(BwsAsm.m_nOffset, m_nBank, lAddr);
            if(!BwsAsm.DsmPrev()) {
                AfxMessageBox(IDS_ERR_MEM);
                return;
            } else Invalidate();
            BwsAsm.m_nOffset = BwsAsm.MatchAddr2LineL(m_nBank, lAddr);
            if(BwsAsm.m_nOffset > m_szView.cy) {
                nPage = m_szView.cy;
                BwsAsm.m_nOffset -= m_szView.cy;
            } else {
                nPage = BwsAsm.m_nOffset;
                BwsAsm.m_nOffset = 0;
            }
            ScrollWindow(0, m_szFont.cy * nPage, &m_rectClip, &m_rectClip);
        }    
        BwsAsm.Line2AddrL(BwsAsm.m_nOffset, m_nBank, lAddr);
        m_ptOffset.y = int(lAddr/4);
    } else {                               
        int nSrc, nAsm;
        if(BwsMix.m_nOffset == 0 && BwsMix.IsHome())    return;
        else if(BwsMix.m_nOffset < m_szView.cy && !BwsMix.IsHome()) {
            nSrc = BwsMix.Ofs2Line(BwsMix.m_nOffset, nAsm);
            if(!BwsMix.DsmPrev()) {
                AfxMessageBox(IDS_ERR_MEM);
                return;
            } else Invalidate();        
            BwsMix.m_nOffset = BwsMix.Line2Ofs(nSrc, nAsm);            
        }
        if(BwsMix.m_nOffset >= m_szView.cy) 
            nPage = m_szView.cy;
        else  
            nPage = BwsMix.m_nOffset;
        BwsMix.m_nOffset -= nPage;
        m_ptOffset.y = BwsMix.Ofs2Line(BwsMix.m_nOffset, nAsm);
        ScrollWindow(0, m_szFont.cy * nPage, &m_rectClip, &m_rectClip);
    }
    
#ifdef BWS_TOOL_WND
    m_pVScrollBar->SetScrollPos(m_ptOffset.y);            
#else    
    SetScrollPos(SB_VERT, m_ptOffset.y);
#endif    

    Caret2Index();
}

/////////////////////////////////////////////////////////////////////////////
//
//  Name:   
//
//  Description: 
//
//  Input:  
//
//  Output: 
//
//  Return: 
//
/////////////////////////////////////////////////////////////////////////////
void CBrowseWindow::OnPgDn(void)
{
long lAddr;
int nPage = 0;
    
    if(m_nDispMode == MODE_SOURCE) {
        if(m_ptOffset.y <= BWSSRCLINES - m_szView.cy) nPage = m_szView.cy;
        else nPage = BWSSRCLINES - m_ptOffset.y;
        m_ptOffset.y += nPage;
        ScrollWindow(0, -m_szFont.cy * nPage, &m_rectClip, &m_rectClip);
    } else if(m_nDispMode == MODE_ASM) {
        if(BwsAsm.m_nOffset >= BWSASMLINES && BwsAsm.IsEnd())   
            return;                           
        if(BwsAsm.m_nOffset + m_szView.cy * 2 < BWSASMLINES || 
            BwsAsm.IsEnd()) {   
            if(BwsAsm.m_nOffset + m_szView.cy < BWSASMLINES) {
                nPage = m_szView.cy;
                BwsAsm.m_nOffset += m_szView.cy;   
            } else {
                nPage = BWSASMLINES - BwsAsm.m_nOffset;
                BwsAsm.m_nOffset = BWSASMLINES;            
            }    
            ScrollWindow(0, -m_szFont.cy * nPage, &m_rectClip, &m_rectClip);
        } else {
            BwsAsm.Line2AddrL(BwsAsm.m_nOffset, m_nBank, lAddr);
            if(!BwsAsm.DsmNext()) {
                AfxMessageBox(IDS_ERR_MEM);
                return;
            } else Invalidate();
            BwsAsm.m_nOffset = BwsAsm.MatchAddr2LineL(m_nBank, lAddr); 
            if(BwsAsm.m_nOffset + m_szView.cy < BWSASMLINES) {
                nPage = m_szView.cy;
                BwsAsm.m_nOffset += m_szView.cy;   
            } else {
                nPage = BWSASMLINES - BwsAsm.m_nOffset;
                BwsAsm.m_nOffset = BWSASMLINES;            
            }    
            ScrollWindow(0, -m_szFont.cy * nPage, &m_rectClip, &m_rectClip);
        }    
        BwsAsm.Line2AddrL(BwsAsm.m_nOffset, m_nBank, lAddr);
        m_ptOffset.y = int(lAddr/4);
    } else {                        
        int nSrc, nAsm;
        if(BwsMix.m_nOffset + 2 * m_szView.cy > BWSMIXLINES && !BwsMix.IsEnd()) {
            nSrc = BwsMix.Ofs2Line(BwsMix.m_nOffset, nAsm);
            if(!BwsMix.DsmNext()) {
                AfxMessageBox(IDS_ERR_MEM);
                return;
            } else Invalidate();                                             
            BwsMix.m_nOffset = BwsMix.Line2Ofs(nSrc, nAsm);
        }
        if(BwsMix.m_nOffset + m_szView.cy <= BWSMIXLINES) 
            nPage = m_szView.cy;
        else 
            nPage = BWSMIXLINES - BwsMix.m_nOffset;
        BwsMix.m_nOffset += nPage;
        m_ptOffset.y = BwsMix.Ofs2Line(BwsMix.m_nOffset, nAsm);
        ScrollWindow(0, -m_szFont.cy * nPage, &m_rectClip, &m_rectClip);
    }
    
#ifdef BWS_TOOL_WND
    m_pVScrollBar->SetScrollPos(m_ptOffset.y);            
#else    
    SetScrollPos(SB_VERT, m_ptOffset.y);
#endif    

    Caret2Index();
}

/////////////////////////////////////////////////////////////////////////////
//
//  Name:   
//
//  Description: 
//
//  Input:  
//
//  Output: 
//
//  Return: 
//
/////////////////////////////////////////////////////////////////////////////
void CBrowseWindow::OnPgLeft(void)
{                         
    int nPage = 0;
    if(m_ptOffset.x >= m_szView.cx - m_nLeft) 
        nPage = m_szView.cx - m_nLeft;
    else nPage = m_ptOffset.x;
    m_ptOffset.x -= nPage;
    ScrollWindow(m_szFont.cx * nPage, 0, &m_rectScroll, &m_rectScroll);
    
#ifdef BWS_TOOL_WND
    m_pHScrollBar->SetScrollPos(m_ptOffset.x);            
#else    
    SetScrollPos(SB_HORZ, m_ptOffset.x);
#endif    
    
    Caret2Index();
}

/////////////////////////////////////////////////////////////////////////////
//
//  Name:   
//
//  Description: 
//
//  Input:  
//
//  Output: 
//
//  Return: 
//
/////////////////////////////////////////////////////////////////////////////
void CBrowseWindow::OnPgRight(void)
{
    int nPage = 0;
    if(m_ptOffset.x <= SourceList::MAX_LINELEN - m_szView.cx + m_nLeft) 
        nPage = m_szView.cx - m_nLeft;
    else nPage = SourceList::MAX_LINELEN - m_ptOffset.x + m_nLeft;
    m_ptOffset.x += nPage;
    ScrollWindow(-m_szFont.cx * nPage, 0, &m_rectScroll, &m_rectScroll);
    
#ifdef BWS_TOOL_WND
    m_pHScrollBar->SetScrollPos(m_ptOffset.x);            
#else    
    SetScrollPos(SB_HORZ, m_ptOffset.x);
#endif    

    Caret2Index();
}

/////////////////////////////////////////////////////////////////////////////
//
//  Name:   
//
//  Description: 
//
//  Input:  
//
//  Output: 
//
//  Return: 
//
/////////////////////////////////////////////////////////////////////////////
void CBrowseWindow::OnHome(void)
{
    ScrollWindow(m_szFont.cx * m_ptOffset.x, 0, 
        &m_rectScroll, &m_rectScroll);
    m_ptOffset.x = 0;
    
#ifdef BWS_TOOL_WND
    m_pHScrollBar->SetScrollPos(m_ptOffset.x);            
#else    
    SetScrollPos(SB_HORZ, m_ptOffset.x);
#endif    

    Caret2Index();
}

/////////////////////////////////////////////////////////////////////////////
//
//  Name:   
//
//  Description: 
//
//  Input:  
//
//  Output: 
//
//  Return: return right most index,-1 means no text in this line
//
/////////////////////////////////////////////////////////////////////////////
int CBrowseWindow::OnEnd(void)
{                                   
    int n1, n2;
    if(m_nDispMode == MODE_SOURCE) {
        SourceElement * p = BWSSRCMDL.GetLine(m_ptIndex.y);
        if(!p)  return -1;
        else n1 = p->m_nLength;
    } else if(m_nDispMode == MODE_ASM) {
        AsmLine * p = BwsAsm.GetLine(BwsAsm.m_nIndex);
        if(!p)  return -1;
        else n1 = p->m_strText.GetLength();
    } else {           
        int nSrc, nAsm;
        nSrc = BwsMix.Ofs2Line(BwsMix.m_nIndex, nAsm);     
        if(nAsm == -1) {
            SourceElement * p = BWSSRCMDL.GetLine(nSrc);
            if(!p)  return -1;
            else n1 = p->m_nLength;
        } else {
            AsmLine * p = BwsMix.GetLine(nSrc, nAsm);
            if(!p)  return -1;
            else n1 = p->m_strText.GetLength() + 5+3;
        }
    }
        
    if(n1 >= SourceList::MAX_LINELEN)    n1 = SourceList::MAX_LINELEN - 1;
    if(!IsXIn(n1)) {
        n2 = n1 - m_szView.cx + m_nLeft + 1;
        if(n2 < 0)  n2 = 0;
        HorzScroll(n2);
    }     
    
    return  n1;
}

/////////////////////////////////////////////////////////////////////////////
//
//  Name:   
//
//  Description: 
//
//  Input:  
//
//  Output: 
//
//  Return: 
//
/////////////////////////////////////////////////////////////////////////////
void CBrowseWindow::OnUpMost(void)
{
    if(m_nDispMode == MODE_SOURCE) {
        ScrollWindow(0, m_szFont.cy * m_ptOffset.y, 
            &m_rectClip, &m_rectClip);
        m_ptOffset.y = 0;
    } else if(m_nDispMode == MODE_ASM) {
        return;    
    } else {
        if(!BwsMix.Dsm(0)) {
            AfxMessageBox(IDS_ERR_MEM);
            return;
        } else Invalidate();                            
        BwsMix.m_nOffset = 0;                                
        int nAsm;
        m_ptOffset.y = BwsMix.Ofs2Line(BwsMix.m_nOffset, nAsm);
        InvalidateRect(&m_rectClip);    
    }
    
#ifdef BWS_TOOL_WND
    m_pVScrollBar->SetScrollPos(m_ptOffset.y);            
#else    
    SetScrollPos(SB_VERT, m_ptOffset.y);
#endif    

    Caret2Index();
}

/////////////////////////////////////////////////////////////////////////////
//
//  Name:   
//
//  Description: 
//
//  Input:  
//
//  Output: 
//
//  Return: 
//
/////////////////////////////////////////////////////////////////////////////
void CBrowseWindow::OnDownMost(void)
{
    if(m_nDispMode == MODE_SOURCE) {
        ScrollWindow(0, -m_szFont.cy * (BWSSRCLINES - m_ptOffset.y), 
            &m_rectClip, &m_rectClip);
        m_ptOffset.y = BWSSRCLINES;
    } else if(m_nDispMode == MODE_ASM) {
        return;    
    } else {
        if(!BwsMix.Dsm(BWSSRCLINES - 1)) {
            AfxMessageBox(IDS_ERR_MEM);
            return;
        } else Invalidate();                           
        BwsMix.m_nOffset = BWSMIXLINES;                          
        int nAsm;
        m_ptOffset.y = BwsMix.Ofs2Line(BwsMix.m_nOffset, nAsm);
        InvalidateRect(&m_rectClip);    
    }
    
#ifdef BWS_TOOL_WND
    m_pVScrollBar->SetScrollPos(m_ptOffset.y);            
#else    
    SetScrollPos(SB_VERT, m_ptOffset.y);
#endif    

    Caret2Index();
}

/////////////////////////////////////////////////////////////////////////////
//
//  Name:   
//
//  Description: 
//
//  Input:  
//
//  Output: 
//
//  Return: 
//
/////////////////////////////////////////////////////////////////////////////
void CBrowseWindow::HorzScroll(int nx)
{
    ScrollWindow(m_szFont.cx * (m_ptOffset.x - nx), 0, 
        &m_rectScroll, &m_rectScroll);
    m_ptOffset.x = nx;
    
#ifdef BWS_TOOL_WND
    m_pHScrollBar->SetScrollPos(m_ptOffset.x);            
#else    
    SetScrollPos(SB_HORZ, m_ptOffset.x);
#endif    
    
    Caret2Index();
}

/////////////////////////////////////////////////////////////////////////////
//
//  Name:   
//
//  Description: 
//
//  Input:  
//
//  Output: 
//
//  Return: 
//
/////////////////////////////////////////////////////////////////////////////
void CBrowseWindow::VertScroll(int ny)
{
    if(m_nDispMode == MODE_SOURCE) {
        ScrollWindow(0, m_szFont.cy * (m_ptOffset.y - ny), 
            &m_rectClip, &m_rectClip);
        m_ptOffset.y = ny;
    } else if(m_nDispMode == MODE_ASM) {
        unsigned k = (ny == MAX_ASM_RANGE/(0x10000L/(dwpMax+1))) ? 4 * (unsigned(ny) - 16) : 
            4 * unsigned(ny);
        if(!BwsAsm.Dsm(m_nBank, (unsigned short)k)) {
            AfxMessageBox(IDS_ERR_MEM);
            return;
        } else Invalidate();                            
        BwsAsm.m_nOffset = BwsAsm.MatchAddr2LineL(m_nBank, long(ny) * 4);
        m_ptOffset.y = ny;
        InvalidateRect(&m_rectClip);
    } else {
        m_ptOffset.y = ny >= BWSSRCLINES ? BWSSRCLINES - 1 : ny;
        if(!BwsMix.Dsm(m_ptOffset.y)) {
            AfxMessageBox(IDS_ERR_MEM);
            return;
        } else Invalidate();                           
        BwsMix.m_nOffset = BwsMix.Line2Ofs(m_ptOffset.y, -1);
        InvalidateRect(&m_rectClip);    
    }
    
#ifdef BWS_TOOL_WND
    m_pVScrollBar->SetScrollPos(m_ptOffset.y);            
#else    
    SetScrollPos(SB_VERT, m_ptOffset.y);
#endif    

    Caret2Index();
} 

/////////////////////////////////////////////////////////////////////////////
//
//  Name:   
//
//  Description: 
//
//  Input:  
//
//  Output: 
//
//  Return: 
//
/////////////////////////////////////////////////////////////////////////////
void CBrowseWindow::ScrollTo(int nLine, int nCol, int nLen, BOOL isLeft)
{                              
    ASSERT(m_nDispMode == MODE_SOURCE);
    
    if(!IsYIn(nLine))   VertScroll(nLine);                                     
            
    if(IsXIn(nCol) && IsXIn(nCol + nLen))   return;        

    if(isLeft) {
        if(!IsXIn(nCol))    HorzScroll(nCol);
    } else {
        int n = nCol + nLen - m_szView.cx + m_nLeft + 1;
        if(n < 0)   n = 0;
        HorzScroll(n);
    }
}

/////////////////////////////////////////////////////////////////////////////
//
//  Name:   
//
//  Description: Search Text
//
//  Input:  
//
//  Output: 
//
//  Return: 
//
/////////////////////////////////////////////////////////////////////////////
BOOL CBrowseWindow::Search(void)
{                             
    int nLine = m_ptIndex.y, nCol = m_ptIndex.x;
    if(nLine < 0 || nLine >= BWSSRCLINES)
        nLine = 0; 
    
    BOOL isRval;
    if(SrcSrchData.m_nUp == 0) {            // Up
        isRval = BWSSRCMDL.SearchBefore(nLine, nCol, 0);
        if(isRval == FALSE) {
            MessageBeep(-1);
            return  FALSE;
        }
    } else if(SrcSrchData.m_nUp == 1) {     // Down
        isRval = BWSSRCMDL.SearchAfter(nLine, nCol, BWSSRCLINES - 1);
        if(isRval == FALSE) {
            MessageBeep(-1);
            return  FALSE;
        }
    } else {                                // All
        isRval = BWSSRCMDL.SearchAfter(nLine, nCol, BWSSRCLINES - 1);
        if(isRval == FALSE) isRval = BWSSRCMDL.SearchAfter(0, 0, nLine);
        if(isRval == FALSE) {
            MessageBeep(-1);
            return  FALSE;
        } else {
            if(SrcSrchData.m_isFirst == TRUE) {
                SrcSrchData.m_isFirst = FALSE;
                SrcSrchData.m_nInitLine = SrcSrchData.m_nCurLine;
                SrcSrchData.m_nInitCol  = SrcSrchData.m_nCurCol;
            } /*else if(SrcSrchData.m_nCurLine == SrcSrchData.m_nInitLine &&
                SrcSrchData.m_nCurCol == SrcSrchData.m_nInitCol) {                                
                MessageBeep(-1);
                return  FALSE;  
            }*/
        } 
    }
    if(SrcSrchData.m_nUp == 0) {    
        ScrollTo(SrcSrchData.m_nCurLine, SrcSrchData.m_nCurCol, 
            SrcSrchData.m_strText.GetLength(), TRUE);
        m_ptIndex.x = SrcSrchData.m_nCurCol;
    } else {
        ScrollTo(SrcSrchData.m_nCurLine, SrcSrchData.m_nCurCol, 
            SrcSrchData.m_strText.GetLength(), FALSE);
        m_ptIndex.x = SrcSrchData.m_nCurCol + 
            SrcSrchData.m_strText.GetLength();
    }       
    m_ptIndex.y = SrcSrchData.m_nCurLine;
    Index2Caret();
    SetCaret();
    return  TRUE;
}

/////////////////////////////////////////////////////////////////////////////
//
//  Name:   
//
//  Description: Hilite text found by search command
//
//  Input:  
//
//  Output: 
//
//  Return: 
//
/////////////////////////////////////////////////////////////////////////////
void CBrowseWindow::SelectText(BOOL isSel)
{                  
    if(m_nDispMode != MODE_SOURCE)  return;

    //int nRow = Line2Row(SrcSrchData.m_nCurLine);
    int nRow = Line2Row(m_nSelLine);
    if(isSel) { 
        if(m_isSel) SelectText(FALSE);
        m_isSel = TRUE;
    } else {
        m_isSel = FALSE;
    }
    if(nRow >= 0 && nRow < m_szView.cy) UpdateRow(nRow);
}                                  
                                                         
/////////////////////////////////////////////////////////////////////////////
//
//  Name:   
//
//  Description: Set Breakpoint
//
//  Input:  
//
//  Output: 
//
//  Return: 
//
/////////////////////////////////////////////////////////////////////////////
/*
void CBrowseWindow::SetBreakpoint(int nRow)
{       
    AsmLine * pAsm;
    int nLine = Row2Line(nRow);
    unsigned long dwAddr;  
    BYTE eFlag;
    if(m_nDispMode == MODE_SOURCE) {
        if(nLine >= BWSSRCLINES)   return;
        if(SrcLinenum2Addr(bwsMdlInfo.CurModule(), (unsigned short)(nLine + 1), 
            dwAddr) == 0) {
            if(BptSearchBpt((unsigned short)dwAddr, eFlag)) {
                if(eFlag) BptClrOneBptfromWnd((unsigned short)dwAddr);
                else if(!BptEnableBpt((unsigned short)dwAddr)) return;
            } else if(!BptAddBptfromWnd((unsigned short)dwAddr)) return;
        }
    } else if(m_nDispMode == MODE_ASM) {
        if(nLine >= BWSASMLINES)   return;
        pAsm = (AsmLine *)BwsAsm.GetLine(nLine);
        if(pAsm->m_chLabel) return;          
        if(BptSearchBpt(pAsm->m_uAddr, eFlag)) {
            if(eFlag)   BptClrOneBptfromWnd(pAsm->m_uAddr);
            else if(!BptEnableBpt(pAsm->m_uAddr)) return;
        } else if(!BptAddBptfromWnd(pAsm->m_uAddr))    return;
    } else {
        if(nLine >= BWSMIXLINES)   return;            
        int nSrc, nAsm;
        nSrc = BwsMix.Ofs2Line(nLine, nAsm);
        if(nAsm == -1)  return;
        pAsm = (AsmLine *)BwsMix.GetLine(nSrc, nAsm);
        if(pAsm->m_chLabel) return;          
        if(BptSearchBpt(pAsm->m_uAddr, eFlag)) {
            if(eFlag)   BptClrOneBptfromWnd(pAsm->m_uAddr);
            else if(!BptEnableBpt(pAsm->m_uAddr)) return;
        } else if(!BptAddBptfromWnd(pAsm->m_uAddr))    return;
    }         
    UpdateRow(nRow);
}                      
*/


BOOL CBrowseWindow::PreTranslateMessage(MSG *pMsg)
{                   
  if(pMsg->message==WM_KEYDOWN && pMsg->wParam==VK_RETURN)
  {                
	if(GetFocus()!=this)
	   pBrowseWnd->PostMessage(WM_COMMAND,ID_EDIT_SEARCHNEXT);
  }
  return CMDIChildWnd::PreTranslateMessage(pMsg);
}

/////////////////////////////////////////////////////////////////////////////
BEGIN_MESSAGE_MAP(CBrowseWindow, CMDIChildWnd)
    //{{AFX_MSG_MAP(CBrowseWindow)
    ON_CBN_KILLFOCUS(IDC_SRCHCOMBO, OnSrchComboKillFocus)
    ON_MESSAGE(XM_SRCSHOWPC, OnXMSrcShowPC)
    ON_MESSAGE(XM_REPAINT, OnXMRepaint)
    ON_WM_CHILDACTIVATE()
    ON_WM_MDIACTIVATE()
    ON_WM_CREATE()
    ON_WM_SIZE()
    ON_WM_VSCROLL()
    ON_WM_HSCROLL()
    ON_WM_KEYDOWN()
    ON_WM_KILLFOCUS()
    ON_WM_LBUTTONDOWN()
    ON_WM_PAINT()
    ON_WM_RBUTTONDOWN()
    ON_WM_SETFOCUS()
    ON_COMMAND(ID_EDIT_BROWSEFROMADDRESS, OnEditBrowsefromaddress)
    ON_COMMAND(ID_EDIT_BROWSEFROMLINE, OnEditBrowsefromline)
    ON_COMMAND(ID_EDIT_BROWSEFROMPC, OnEditBrowsefrompc)
    ON_COMMAND(ID_EDIT_SEARCH, OnEditSearch)
    ON_COMMAND(ID_EDIT_SEARCHNEXT, OnEditSearchnext)
    ON_COMMAND(ID_FILE_PREVMODULE, OnFilePrevmodule)
    ON_COMMAND(ID_FILE_NEXTMODULE, OnFileNextmodule)
    ON_COMMAND(ID_VIEW_SOURCEONLY, OnViewSourceonly)
    ON_COMMAND(ID_VIEW_MIXED, OnViewMixed)
    ON_UPDATE_COMMAND_UI(ID_VIEW_MIXED, OnUpdateViewMixed)
    ON_UPDATE_COMMAND_UI(ID_VIEW_SOURCEONLY, OnUpdateViewSourceonly)
    ON_COMMAND(ID_VIEW_SYMBOLICDISASSEMBLY, OnViewSymbolicdisassembly)
    ON_UPDATE_COMMAND_UI(ID_VIEW_SYMBOLICDISASSEMBLY, OnUpdateViewSymbolicdisassembly)
    ON_COMMAND(ID_VIEW_LINENUMBERING, OnViewLinenumbering)
    ON_UPDATE_COMMAND_UI(ID_VIEW_LINENUMBERING, OnUpdateViewLinenumbering)
    ON_COMMAND(ID_VIEW_SYNTAXCOLORING, OnViewSyntaxcoloring)
    ON_UPDATE_COMMAND_UI(ID_VIEW_SYNTAXCOLORING, OnUpdateViewSyntaxcoloring)
    ON_UPDATE_COMMAND_UI(ID_EDIT_SEARCH, OnUpdateEditSearch)
    ON_UPDATE_COMMAND_UI(ID_EDIT_BROWSEFROMLINE, OnUpdateEditBrowsefromline)
    ON_UPDATE_COMMAND_UI(ID_EDIT_SEARCHNEXT, OnUpdateEditSearchnext)
    ON_WM_CLOSE()
    ON_UPDATE_COMMAND_UI(ID_FILE_PREVMODULE, OnUpdateFilePrevmodule)
    ON_UPDATE_COMMAND_UI(ID_FILE_NEXTMODULE, OnUpdateFileNextmodule)
    ON_COMMAND(ID_FILE_BROWSEMODULE, OnFileBrowsemodule)
    ON_UPDATE_COMMAND_UI(ID_FILE_BROWSEMODULE, OnUpdateFileBrowsemodule)
    ON_COMMAND(ID_VIEW_SMA, OnViewSma)  
    ON_COMMAND(ID_VIEW_ASM, OnViewAsm)
    ON_COMMAND(ID_SHIFTRETURN, OnShiftreturn)
    ON_WM_LBUTTONDBLCLK()
    ON_UPDATE_COMMAND_UI(IDC_SRCHCOMBO, OnUpdateSearchCombo)
	ON_WM_KEYUP()
	ON_WM_DESTROY()
    ON_WM_SETCURSOR()
    ON_WM_MOUSEMOVE()
	ON_WM_SETCURSOR()
	ON_COMMAND(ID_VIEW_ASSEMBLE, OnViewAssemble)
	ON_UPDATE_COMMAND_UI(ID_VIEW_ASSEMBLE, OnUpdateViewAssemble)
	//}}AFX_MSG_MAP
END_MESSAGE_MAP()

/*    
    ON_COMMAND(ID_RUN_GOTOCURSOR, OnRunGotocursor)
    ON_COMMAND(ID_RUN_GOFROMCURSOR, OnRunGofromcursor)
    ON_COMMAND(ID_RUN_JUMPTOCURSOR, OnRunJumptocursor)
    ON_COMMAND(ID_RUN_BREAKPOINT, OnRunBreakpoint)
    ON_COMMAND(ID_RUN_JUMP, OnRunJump)
    ON_COMMAND(ID_RUN_RESET, OnRunReset)
    
    ON_COMMAND(ID_OPTIONS_SOURCEEXTENSIONNAMES, OnOptionsSourceextensionnames)
    ON_COMMAND(ID_OPTIONS_SOURCEOPTIONS, OnOptionsSourceoptions)
    ON_COMMAND(ID_OPTIONS_SOURCEPATH, OnOptionsSourcepath)
    ON_COMMAND(ID_RUN_GOTOCURSOR, OnRunGotocursor)
    ON_COMMAND(ID_RUN_GOFROMCURSOR, OnRunGofromcursor)
    ON_COMMAND(ID_RUN_JUMPTOCURSOR, OnRunJumptocursor)
*/
/*    
    ON_COMMAND(IDM_SETBP_FUNC, OnSetBPFunc)
    ON_COMMAND(IDM_CLRBP_FUNC, OnClrBPFunc)
    ON_COMMAND(IDM_SETBP_VAR, OnSetBPVar)
    ON_COMMAND(IDM_CLRBP_VAR, OnClrBPVar)
    ON_COMMAND(IDM_LOAD_ADDR, OnShowLoadAddr)
    ON_COMMAND(IDM_WATCH_VAR, OnWatchVariable)
    ON_COMMAND(IDM_INSPECT_FUNC, OnInspectFunc)
*/    
/*    ON_COMMAND(ID_FILE_LOAD, OnFileLoad)
    ON_COMMAND(ID_RUN_BREAKPOINT, OnRunBreakpoint)
    ON_COMMAND(ID_RUN_JUMP, OnRunJump)
    ON_COMMAND(ID_RUN_RESET, OnRunReset)
*/

/////////////////////////////////////////////////////////////////////////////
// CBrowseWindow message handlers
                            
/////////////////////////////////////////////////////////////////////////////
// Tool Bar Message Handler -- Search ComboBox                            
/////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////
//
//  Name:   
//
//  Description: 
//
//  Input:  
//
//  Output: 
//
//  Return: 
//
/////////////////////////////////////////////////////////////////////////////
void CBrowseWindow::OnSrchComboKillFocus(void)
{   
    CMainFrame * pMain = (CMainFrame *)AfxGetApp()->m_pMainWnd;
    CString str = pMain->m_wndToolBar.GetSrchEditText();    
    if(str != "") { 
        pMain->m_wndToolBar.AddSrchText(str);
        SrcSrchData.AddNew(str);       
        SrcSrchData.m_strText = str;
    } else {
        SrcSrchData.m_strText = "";
    }
}

/////////////////////////////////////////////////////////////////////////////
// User Defined Message Handler -- Show PC Marker
/////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////
//
//  Name:   
//
//  Description: 
//
//  Input:  
//
//  Output: 
//
//  Return: 
//
/////////////////////////////////////////////////////////////////////////////
LONG CBrowseWindow::OnXMRepaint(UINT /*wParam*/, LONG /*lParam*/)
{
    Invalidate();
    UpdateWindow(); 
    return  0;
}

/////////////////////////////////////////////////////////////////////////////
//
//  Name:   
//
//  Description: 
//
//  Input:  
//
//  Output: 
//
//  Return: 
//
/////////////////////////////////////////////////////////////////////////////
LONG CBrowseWindow::OnXMSrcShowPC(UINT /*wParam*/, LONG /*lParam*/)
{             
    ShowPCMarker();   
    return  0;
}
                                                 
/////////////////////////////////////////////////////////////////////////////
// Windows Standard Message Handler
/////////////////////////////////////////////////////////////////////////////                                                 
/////////////////////////////////////////////////////////////////////////////
//
//  Name:   
//
//  Description: 
//
//  Input:  
//
//  Output: 
//
//  Return: 
//
/////////////////////////////////////////////////////////////////////////////
void CBrowseWindow::OnMDIActivate(BOOL bActivate, CWnd* pActivateWnd, CWnd* pDeactivateWnd)
{
    CMDIChildWnd::OnMDIActivate(bActivate, pActivateWnd, pDeactivateWnd);
    
    // TODO: Add your message handler code here
    if(bActivate && pActivateWnd == this) 
    {
        AfxGetApp()->m_pMainWnd->SendMessage(XM_MDIACTIVE, WORD(bActivate), 
            LONG(WID_BROWSE));
    }        
    else if(!bActivate && !pActivateWnd)
        AfxGetApp()->m_pMainWnd->SendMessage(XM_MDIACTIVE, WORD(bActivate)); 
}

/////////////////////////////////////////////////////////////////////////////
//
//  Name:   
//
//  Description: 
//
//  Input:  
//
//  Output: 
//
//  Return: 
//
/////////////////////////////////////////////////////////////////////////////

BOOL CBrowseWindow::OnSetCursor(CWnd* pWnd, UINT nHitTest, UINT message)
{
    // TODO: Add your message handler code here and/or call default
    
    if(message == WM_RBUTTONDOWN)   return FALSE;
    return CMDIChildWnd::OnSetCursor(pWnd, nHitTest, message);
}

/////////////////////////////////////////////////////////////////////////////
//
//  Name:   
//
//  Description: 
//
//  Input:  
//
//  Output: 
//
//  Return: 
//
/////////////////////////////////////////////////////////////////////////////
int CBrowseWindow::OnCreate(LPCREATESTRUCT lpCreateStruct)
{
    if (CMDIChildWnd::OnCreate(lpCreateStruct) == -1)
        return -1;
    
    // TODO: Add your specialized creation code here

#ifdef  BWS_TOOL_WND  
    m_pVScrollBar=new CScrollBar();
    m_pHScrollBar=new CScrollBar();
    m_pToolWnd   =new CToolWnd();

    if(!m_pVScrollBar || !m_pHScrollBar || !m_pToolWnd)
    return 0;

    BOOL bCreateVBar=
    m_pVScrollBar->Create(WS_CHILD|WS_VISIBLE|SBS_RIGHTALIGN|SBS_VERT,
                          CFrameWnd::rectDefault,this,ID_VSCROLL);

    BOOL bCreateHBar=                      
    m_pHScrollBar->Create(WS_CHILD|WS_VISIBLE|SBS_BOTTOMALIGN|SBS_HORZ,
                          CFrameWnd::rectDefault,this,ID_HSCROLL);

    if(!m_pToolWnd->Create(this)||!bCreateHBar || !bCreateVBar) 
       return 0;
#endif

    
    CalcFontSize();       

    SetTitle();             

    return 0;
}

/////////////////////////////////////////////////////////////////////////////
//
//  Name:   
//
//  Description: 
//
//  Input:  
//
//  Output: 
//
//  Return: 
//
/////////////////////////////////////////////////////////////////////////////
void CBrowseWindow::OnSize(UINT nType, int cx, int cy)
{
    CMDIChildWnd::OnSize(nType, cx, cy);
    
    // TODO: Add your message handler code here
    CalcViewSize(cx, cy);            
    CalcScrollSize();        
    
    if(m_nDispMode == MODE_ASM) {
        if(BwsAsm.m_nOffset + m_szView.cy < BWSASMLINES) {                  
            AsmLine * pAsm = (AsmLine *)(BwsAsm.GetLine(BwsAsm.m_nOffset));
            unsigned short uAddr = pAsm->m_uAddr;
            char chLabel = pAsm->m_chLabel;
            if(!BwsAsm.Dsm(m_nBank, uAddr)) {
                AfxMessageBox(IDS_ERR_MEM);
                return;
            } else Invalidate();                            
            pAsm = (AsmLine *)(BwsAsm.GetLine(0));
            if(pAsm->m_chLabel == chLabel)  BwsAsm.m_nOffset = 0;
            else BwsAsm.m_nOffset = 1;
            m_ptOffset.y = uAddr / 4;
            InvalidateRect(&m_rectClip);         
            
         #ifdef BWS_TOOL_WND
            m_pVScrollBar->SetScrollPos(m_ptOffset.y);            
         #else    
            SetScrollPos(SB_VERT, m_ptOffset.y);
         #endif    
         
        } 
    } else if(m_nDispMode == MODE_MIXED) {
        if(m_ptOffset.y < BWSSRCLINES) {
            int nAsm;
            BwsMix.Ofs2Line(BwsMix.m_nOffset, nAsm);
            if(!BwsMix.Dsm(m_ptOffset.y)) {
                AfxMessageBox(IDS_ERR_MEM);
                return;
            } else 
            {Invalidate();                           
            // RedrawWindow(NULL,NULL,RDW_INVALIDATE|RDW_UPDATENOW);
            }                                      
            
            BwsMix.m_nOffset = BwsMix.Line2Ofs(m_ptOffset.y, nAsm);
            InvalidateRect(&m_rectClip);    
            ///RedrawWindow(&m_rectClip,NULL,RDW_INVALIDATE|RDW_UPDATENOW);
        }
    }
    
    
    m_ptCaret.x = m_nLeft;
    m_ptCaret.y = 0;
    Caret2Index();
}

/////////////////////////////////////////////////////////////////////////////
//
//  Name:   
//
//  Description: 
//
//  Input:  
//
//  Output: 
//
//  Return: 
//
/////////////////////////////////////////////////////////////////////////////
void CBrowseWindow::OnVScroll(UINT nSBCode, UINT nPos, CScrollBar* pScrollBar)
{
    // TODO: Add your message handler code here and/or call default
    if(m_nDispMode == MODE_SOURCE) {
        if(!bwsMdlInfo.IsModuleOn() || BWSSRCLINES == 0)   return;
    } else if(m_nDispMode == MODE_MIXED) {
        if(!bwsMdlInfo.IsModuleOn() || BWSMIXLINES == 0)   return;
    } else {    
        if(BWSASMLINES == 0) return;
    }     
    
    switch(nSBCode) {
        case SB_LINEUP:  
            OnUp();
            break;
        case SB_LINEDOWN:
            OnDown();
            break;
        case SB_PAGEUP: 
            OnPgUp();
            break;
        case SB_PAGEDOWN:
            OnPgDn();
            break;
        case SB_THUMBPOSITION:           
            VertScroll(nPos);
            break;
        case SB_THUMBTRACK:
            if(m_nDispMode == MODE_SOURCE) VertScroll(nPos);
            break;
    }          
                  
    CMDIChildWnd::OnVScroll(nSBCode, nPos, pScrollBar);
}

/////////////////////////////////////////////////////////////////////////////
//
//  Name:   
//
//  Description: 
//
//  Input:  
//
//  Output: 
//
//  Return: 
//
/////////////////////////////////////////////////////////////////////////////
void CBrowseWindow::OnHScroll(UINT nSBCode, UINT nPos, CScrollBar* pScrollBar)
{
    // TODO: Add your message handler code here and/or call default
    if(m_nDispMode == MODE_SOURCE) {
        if(!bwsMdlInfo.IsModuleOn() || BWSSRCLINES == 0)   return;
    } else if(m_nDispMode == MODE_MIXED) {
        if(!bwsMdlInfo.IsModuleOn() || BWSMIXLINES == 0)   return;
    } else {    
        if(BWSASMLINES == 0) return;
    }     
    
    switch(nSBCode) {
        case SB_LINELEFT:
            OnLeft();
            break;
        case SB_LINERIGHT:
            OnRight();
            break;     
        case SB_PAGELEFT: 
            OnPgLeft();
            break;
        case SB_PAGERIGHT:
            OnPgRight();
            break;
        case SB_THUMBPOSITION:           
            HorzScroll(nPos);
            break;
        case SB_THUMBTRACK:
            HorzScroll(nPos);
            break;
    }          

    CMDIChildWnd::OnHScroll(nSBCode, nPos, pScrollBar);
}

/////////////////////////////////////////////////////////////////////////////
//
//  Name:   
//
//  Description: 
//
//  Input:  
//
//  Output: 
//
//  Return: 
//
/////////////////////////////////////////////////////////////////////////////
void CBrowseWindow::OnKeyDown(UINT nChar, UINT nRepCnt, UINT nFlags)
{
    // TODO: Add your message handler code here and/or call default
    if(m_nbCanDo>0)
       return;
    else
       m_nbCanDo=1;
          
    if(m_nDispMode == MODE_SOURCE) {
        if(!bwsMdlInfo.IsModuleOn() || BWSSRCLINES == 0)   return;
    } else if(m_nDispMode == MODE_MIXED) {
        if(!bwsMdlInfo.IsModuleOn() || BWSMIXLINES == 0)   return;
    } else {    
        if(BWSASMLINES == 0) return;
    }     
    
    SelectText(FALSE);
    
    int nState = GetKeyState(VK_CONTROL) & 0x8000;  
    int nTmp;
        
    switch(nChar)
    {
        case VK_HOME:
            OnHome();
            m_ptIndex.x = 0;
            Index2Caret();
            if(nState && m_nDispMode != MODE_ASM) {    // Ctrl+Home              
                OnUpMost();
                m_ptCaret.y = 0;
                Caret2Index();
            }
            break;
    
        case VK_END:                                              
            if(!nState) {
                nTmp = OnEnd();
                if(nTmp != -1)  m_ptIndex.x = nTmp;
            } else if(m_nDispMode != MODE_ASM) {    // Ctrl+End
                OnHome();
                OnDownMost();
                m_ptIndex.x = 0;  
                if(m_nDispMode == MODE_SOURCE)  
                    m_ptIndex.y = BWSSRCLINES;
                else if(m_nDispMode == MODE_MIXED)   
                    BwsMix.m_nIndex = BWSMIXLINES;
            }       
            break;              
            
        case VK_LEFT:
            if(m_ptCaret.x > m_nLeft) {
                -- m_ptCaret.x;
                Caret2Index();
            } else{
             m_nbCanDo=2;
             OnLeft();
            } 
            break;              
            
        case VK_RIGHT:
            if(m_ptCaret.x < m_szView.cx - 1) {
                ++ m_ptCaret.x;
                Caret2Index();
            } else{      
             m_nbCanDo=2;
             OnRight();
            } 
            break;              
            
        case VK_UP:
            if(m_ptCaret.y > 0) {
                -- m_ptCaret.y;
                Caret2Index();
            } else{ 
             m_nbCanDo=2;
             OnUp();
            } 
            break;

        case VK_DOWN:
            if(m_ptCaret.y < m_szView.cy - 1) {
                ++ m_ptCaret.y;
                Caret2Index();
            } else{
             m_nbCanDo=2;
             OnDown();
            } 
            break;    
            
        case VK_PRIOR:
            if(!nState) {
                OnPgUp();
                Caret2Index();
            }
            break;
        
        case VK_NEXT:
            if(!nState) {
                OnPgDn();
                Caret2Index();
            }
            break;
    }
    
    Index2Caret();
    SetCaret();
    m_nbCanDo--;
    CMDIChildWnd::OnKeyDown(nChar, nRepCnt, nFlags);
}

/////////////////////////////////////////////////////////////////////////////
//
//  Name:   
//
//  Description: 
//
//  Input:  
//
//  Output: 
//
//  Return: 
//
/////////////////////////////////////////////////////////////////////////////
void CBrowseWindow::OnKillFocus(CWnd* pNewWnd)
{
    CMDIChildWnd::OnKillFocus(pNewWnd);
    
    // TODO: Add your message handler code here
    g_bBrowseActive=0;
    DestroyCaret();
}

/////////////////////////////////////////////////////////////////////////////
//
//  Name:   
//
//  Description: 
//
//  Input:  
//
//  Output: 
//
//  Return: 
//
/////////////////////////////////////////////////////////////////////////////
void CBrowseWindow::OnLButtonDown(UINT nFlags, CPoint point)
{
    // TODO: Add your message handler code here and/or call default
/*    
    SetFocus();
    SelectText(FALSE);
    
    CPoint  pt = point;

    if(point.x < m_rectScroll.left)         pt.x = m_rectScroll.left;
    if(point.x > m_rectScroll.right - 1)    pt.x = m_rectScroll.right - 1;
    if(point.y < m_rectScroll.top)          pt.y = m_rectScroll.top;
    if(point.y > m_rectScroll.bottom - 1)   pt.y = m_rectScroll.bottom - 1;
    
    m_ptCaret.x = X2Col(pt.x);
    m_ptCaret.y = Y2Row(pt.y);

    Caret2Index();
    SetCaret();           
        
    int nRow;    
    if(m_rectClip.PtInRect(point) && !m_rectScroll.PtInRect(point)) {
        nRow = Y2Row(point.y);
        if(nRow >= 0 && nRow < m_szView.cy)
            SetBreakpoint(nRow);            
    }
 */       
    CMDIChildWnd::OnLButtonDown(nFlags, point);
}

/////////////////////////////////////////////////////////////////////////////
//
//  Name:   
//
//  Description: 
//
//  Input:  
//
//  Output: 
//
//  Return: 
//
/////////////////////////////////////////////////////////////////////////////
void CBrowseWindow::OnPaint()
{                          
    m_nbCanDo=1;
    CPaintDC dc(this); // device context for painting
    
    // TODO: Add your message handler code here

#ifdef BWS_TOOL_WND  
    DrawScrollRect(&dc);
#endif
    
    dc.IntersectClipRect(m_rectClip);
    CFont * font = (CFont *)(dc.SelectStockObject(m_nFont));
        
    int i;        
    if(m_nDispMode == MODE_SOURCE) {
        for(i = 0; i < m_szView.cy 
            && i + m_ptOffset.y < BWSSRCLINES; i++) {
            ShowSourceLine(&dc, i, Row2Line(i));    
        }                               
    } else if(m_nDispMode == MODE_ASM) {
        for(i = 0; i < m_szView.cy 
            && i + BwsAsm.m_nOffset < BWSASMLINES; i++) {
            ShowDsmLine(&dc, i, Row2Line(i));    
        }                               
    } else {
        for(i = 0; i < m_szView.cy; i++) {
            int nSrc, nAsm;
            nSrc = BwsMix.Ofs2Line(Row2Line(i), nAsm);
            if(nAsm == -1)  
                ShowSourceLine(&dc, i, nSrc);
            else
                ShowMixedLine(&dc, i, nSrc, nAsm);    
        }                               
    }       
    
    dc.SelectObject(font);
                               
    SetCaret();
    m_nbCanDo=0;
    // Do not call CMDIChildWnd::OnPaint() for painting messages
}


/////////////////////////////////////////////////////////////////////////////
//
//  Name:   
//
//  Description: 
//
//  Input:  
//
//  Output: 
//
//  Return: 
//
/////////////////////////////////////////////////////////////////////////////
BOOL CBrowseWindow::IsFunction()
{
    if(m_nDispMode != MODE_SOURCE)  return  FALSE;
    
    if(!m_isSel)    return FALSE;
    
    CString str("#");
    str += m_strSel;              
    
    return BOOL(SrcIsFunction(str) == 0);
}

BOOL CBrowseWindow::IsVariable()
{
    if(m_nDispMode != MODE_SOURCE)  return  FALSE;
    
    if(!m_isSel)    return FALSE;

    unsigned long dwModule = bwsMdlInfo.CurModule();
    
    char tmp[200];
    if(SrcGetModuleName(dwModule, tmp) == -1)   return FALSE;
    
    CString str("#");
    str += tmp;
    str += "#";
    str += m_strSel;
    
    return BOOL(SrcIsVariable(str, m_nSelLine + 1) == 0);
}

void CBrowseWindow::OnLocalMenu(CPoint point)
{                                                            
    CString str;
    
    CMenu * pLocalMenu = new CMenu;
    ASSERT( NULL != pLocalMenu );

    pLocalMenu->CreatePopupMenu();
/*    
    if(IsFunction()) {
        str = "Inspect Source of the Function:";
        str += m_strSel;
        pLocalMenu->AppendMenu(MF_STRING, IDM_INSPECT_FUNC, str);
        pLocalMenu->AppendMenu(MF_STRING, IDM_LOAD_ADDR, "Show Load Address");
        pLocalMenu->AppendMenu(MF_STRING, IDM_SETBP_FUNC, "Set Breakpoint");
        pLocalMenu->AppendMenu(MF_STRING, IDM_CLRBP_FUNC, "Clear Breakpoint");
    } else if(IsVariable()) {
        str = "Watch variable:";
        str += m_strSel;
        pLocalMenu->AppendMenu(MF_STRING, IDM_WATCH_VAR, str);
        pLocalMenu->AppendMenu(MF_STRING, IDM_SETBP_VAR, "Set Breakpoint");
        pLocalMenu->AppendMenu(MF_STRING, IDM_CLRBP_VAR, "Clear Breakpoint");
    } else {                       
*/    
//        pLocalMenu->AppendMenu(MF_STRING, ID_FILE_LOAD, "Load...");
        pLocalMenu->AppendMenu(MF_STRING, ID_FILE_BROWSEMODULE,
                                "Browse Module...");
//        pLocalMenu->AppendMenu(MF_SEPARATOR);
//        pLocalMenu->AppendMenu(MF_STRING, ID_RUN_JUMPTOCURSOR,
//                                "Jump To Cursor");
//        pLocalMenu->AppendMenu(MF_STRING, ID_RUN_JUMP,
//                                "Jump...");
//        pLocalMenu->AppendMenu(MF_SEPARATOR);
//        pLocalMenu->AppendMenu(MF_STRING, ID_RUN_RESET,
//                                "Reset");
//        pLocalMenu->AppendMenu(MF_STRING, ID_RUN_BREAKPOINT, "Breakpoint...");
//        pLocalMenu->AppendMenu(MF_SEPARATOR);
        pLocalMenu->AppendMenu(MF_STRING, ID_EDIT_BROWSEFROMLINE,
                                "Browse From Line...");
        pLocalMenu->AppendMenu(MF_STRING, ID_EDIT_BROWSEFROMADDRESS,
                                "Browse From Address...");
        pLocalMenu->AppendMenu(MF_STRING, ID_EDIT_BROWSEFROMPC,
                                "Browse From PC");
        pLocalMenu->AppendMenu(MF_SEPARATOR);
        pLocalMenu->AppendMenu(MF_STRING, ID_EDIT_SEARCH,
                                "Search...");
        pLocalMenu->AppendMenu(MF_STRING, ID_EDIT_SEARCHNEXT,
                                "Search Next");
//        pLocalMenu->AppendMenu(MF_SEPARATOR);
//        pLocalMenu->AppendMenu(MF_STRING, ID_OPTIONS_SOURCEOPTIONS,
//                                "Source Options...");
        pLocalMenu->AppendMenu(MF_SEPARATOR);
        pLocalMenu->AppendMenu(MF_STRING, ID_VIEW_SOURCEONLY,
                                "Source Only");
        pLocalMenu->AppendMenu(MF_STRING, ID_VIEW_MIXED,
                                "Mixed Source And Asm");
        pLocalMenu->AppendMenu(MF_STRING, ID_VIEW_ASSEMBLE,
                                "Assemble");
        pLocalMenu->SetMenuItemBitmaps(ID_VIEW_SOURCEONLY, MF_BYCOMMAND, 
            &bmpMenuUncheck, &bmpMenuCheck);
        pLocalMenu->SetMenuItemBitmaps(ID_VIEW_MIXED, MF_BYCOMMAND, 
            &bmpMenuUncheck, &bmpMenuCheck);
    
//    }

    ClientToScreen(&point);
    pLocalMenu->TrackPopupMenu(TPM_LEFTALIGN, point.x, point.y, this);
    delete pLocalMenu;
}


void CBrowseWindow::OnShiftreturn()
{
    // TODO: Add your command handler code here
    OnLocalMenu(CPoint(20, 20));
}

/////////////////////////////////////////////////////////////////////////////
//
//  Name:   
//
//  Description: 
//
//  Input:  
//
//  Output: 
//
//  Return: 
//
/////////////////////////////////////////////////////////////////////////////
void CBrowseWindow::OnRButtonDown(UINT nFlags, CPoint point)
{
    // TODO: Add your message handler code here and/or call default
    
    OnLocalMenu(point);
    
    CMDIChildWnd::OnRButtonDown(nFlags, point);
}

/////////////////////////////////////////////////////////////////////////////
//
//  Name:   
//
//  Description: 
//
//  Input:  
//
//  Output: 
//
//  Return: 
//
/////////////////////////////////////////////////////////////////////////////
void CBrowseWindow::OnSetFocus(CWnd* pOldWnd)
{
    CMDIChildWnd::OnSetFocus(pOldWnd);
    
    // TODO: Add your message handler code here
    CreateSolidCaret(2, m_szFont.cy);
    SetCaret();                      
    ShowCaret();            
    g_bBrowseActive=1;
}

/////////////////////////////////////////////////////////////////////////////
//
//  Name:   
//
//  Description: 
//
//  Input:  
//
//  Output: 
//
//  Return: 
//
/////////////////////////////////////////////////////////////////////////////
void CBrowseWindow::OnChildActivate()
{
    CMDIChildWnd::OnChildActivate();

    // TODO: Add your message handler code here
    SetFocus();
}

/////////////////////////////////////////////////////////////////////////////
//
//  Name:   
//
//  Description: 
//
//  Input:  
//
//  Output: 
//
//  Return: 
//
/////////////////////////////////////////////////////////////////////////////
/*
void CBrowseWindow::OnMouseMove(UINT nFlags, CPoint point)
{
    // TODO: Add your message handler code here and/or call default
                       
    // Set cursor shape                            
    if(m_rectScroll.left > point.x)
        SetCursor(AfxGetApp()->LoadCursor(IDC_BULLEYE));    
    else 
        SetCursor(AfxGetApp()->LoadStandardCursor(IDC_ARROW));
    
    CMDIChildWnd::OnMouseMove(nFlags, point);
}
*/
/////////////////////////////////////////////////////////////////////////////
//
//  Name:   
//
//  Description: 
//
//  Input:  
//
//  Output: 
//
//  Return: 
//
/////////////////////////////////////////////////////////////////////////////
void CBrowseWindow::OnClose()
{
    // TODO: Add your message handler code here and/or call default
    if(isSrcSrchDlg)    m_pdlgSrch->DestroyWindow();
    g_bBrowseActive=0;
    CMDIChildWnd::OnClose();
}

/////////////////////////////////////////////////////////////////////////////
// Menu Message Handler -- Edit Submenu
/////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////
//
//  Name:   
//
//  Description: 
//
//  Input:  
//
//  Output: 
//
//  Return: 
//
/////////////////////////////////////////////////////////////////////////////
void CBrowseWindow::OnEditBrowsefromaddress()
{
    // TODO: Add your command handler code here
    CBrowseAddrDialog dlg(TRUE, this);
    if(dlg.DoModal() != IDOK) return;
    
    UpdateAsm(nBrowseBank, uBrowseAddr);
}

/////////////////////////////////////////////////////////////////////////////
//
//  Name:   
//
//  Description: 
//
//  Input:  
//
//  Output: 
//
//  Return: 
//
/////////////////////////////////////////////////////////////////////////////
void CBrowseWindow::OnEditBrowsefromline()
{
    // TODO: Add your command handler code here
    CBrowseAddrDialog dlg(FALSE, this);
    if(dlg.DoModal() == IDOK) {
        if(nBrowseLine > BWSSRCLINES)  nBrowseLine = BWSSRCLINES;
        UpdateSource(nBrowseLine - 1);
    }
}

/////////////////////////////////////////////////////////////////////////////
//
//  Name:   
//
//  Description: 
//
//  Input:  
//
//  Output: 
//
//  Return: 
//
/////////////////////////////////////////////////////////////////////////////
void CBrowseWindow::OnEditBrowsefrompc()
{
    // TODO: Add your command handler code here
    if(!SrcEmu.GetPC()) return;
    if(SrcEmu.GetModule()) {
        BwsLoadModule(SrcEmu.m_dwPCModule);    
        SelectText(FALSE);
    }   

    if(m_nDispMode == MODE_SOURCE) {
        if(SrcEmu.m_nPCLine >= 0 && SrcEmu.IsPCModule(bwsMdlInfo.CurModule())) 
            UpdateSource(SrcEmu.m_nPCLine);
        else UpdateAsm(SrcEmu.m_nPCBank, SrcEmu.m_lPCAddr);
    } else if(m_nDispMode == MODE_MIXED) {
        if(UpdateMixed(SrcEmu.m_nPCBank, SrcEmu.m_lPCAddr))   return;
        else UpdateAsm(SrcEmu.m_nPCBank, SrcEmu.m_lPCAddr);
    } else UpdateAsm(SrcEmu.m_nPCBank, SrcEmu.m_lPCAddr);
}

/////////////////////////////////////////////////////////////////////////////
//
//  Name:   
//
//  Description: 
//
//  Input:  
//
//  Output: 
//
//  Return: 
//
/////////////////////////////////////////////////////////////////////////////
void CBrowseWindow::OnUpdateEditBrowsefromline(CCmdUI* pCmdUI)
{
    // TODO: Add your command update UI handler code here
    pCmdUI->Enable(m_nDispMode != MODE_ASM);    
}

/////////////////////////////////////////////////////////////////////////////
//
//  Name:   
//
//  Description: 
//
//  Input:  
//
//  Output: 
//
//  Return: 
//
/////////////////////////////////////////////////////////////////////////////
void CBrowseWindow::OnEditSearch()
{
    // TODO: Add your command handler code here
    m_pdlgSrch = new CSourceSearch(this,TRUE);
    m_pdlgSrch->ShowWindow(SW_SHOW);    
    isSrcSrchDlg = TRUE;
}

/////////////////////////////////////////////////////////////////////////////
//
//  Name:   
//
//  Description: 
//
//  Input:  
//
//  Output: 
//
//  Return: 
//
/////////////////////////////////////////////////////////////////////////////
void CBrowseWindow::OnUpdateEditSearch(CCmdUI* pCmdUI)
{
    // TODO: Add your command update UI handler code here
    pCmdUI->Enable(!isSrcSrchDlg && m_nDispMode == MODE_SOURCE);    
}

/////////////////////////////////////////////////////////////////////////////
//
//  Name:   
//
//  Description: 
//
//  Input:  
//
//  Output: 
//
//  Return: 
//
/////////////////////////////////////////////////////////////////////////////
void CBrowseWindow::OnEditSearchnext()
{
    // TODO: Add your command handler code here
    ActivateFrame(-1);
    SelectText(FALSE);                     
    
    if(SrcSrchData.m_strText == "") return;
    
    BOOL is = Search();
    if(!is) {                              
        CString str("Can't find \"");
        str += SrcSrchData.m_strText;
        str += "\"";
        AfxMessageBox(str);
        if(isSrcSrchDlg)    m_pdlgSrch->DestroyWindow();
    } else {
        m_strSel = SrcSrchData.m_strText;
        m_nSelLine = SrcSrchData.m_nCurLine;
        m_nSelCol = SrcSrchData.m_nCurCol;
        SelectText(TRUE);
    }   
}

/////////////////////////////////////////////////////////////////////////////
//
//  Name:   
//
//  Description: 
//
//  Input:  
//
//  Output: 
//
//  Return: 
//
/////////////////////////////////////////////////////////////////////////////
void CBrowseWindow::OnUpdateEditSearchnext(CCmdUI* pCmdUI)
{
    // TODO: Add your command update UI handler code here
    pCmdUI->Enable(m_nDispMode == MODE_SOURCE);    
}

/////////////////////////////////////////////////////////////////////////////
// Menu Message Handler -- File Submenu
/////////////////////////////////////////////////////////////////////////////
/*
void CBrowseWindow::OnFileLoadinfo()
{
    // TODO: Add your command handler code here
    // Get load information
    char szModule[100];       
    int nDummy;
    if(SrcGetLdrStats(szModule, &(LoadInfo.m_lSymbols),
        &((unsigned short &)(LoadInfo.m_lModules)), &(LoadInfo.m_lTypes), 
        &(LoadInfo.m_lFunctions), &(LoadInfo.m_lLines),
        &(LoadInfo.m_lBytes), &nDummy) == -1) {
        if(LoadOpt.m_isWarnings)
            AfxMessageBox(IDS_ERR_LOADINFO);
        return;                          
    }      
              
    // Show load information              
    CLoadInfoDialog dlg(this);
    dlg.DoModal();
}
*/
/////////////////////////////////////////////////////////////////////////////
//
//  Name:   
//
//  Description: 
//
//  Input:  
//
//  Output: 
//
//  Return: 
//
/////////////////////////////////////////////////////////////////////////////
void CBrowseWindow::OnFilePrevmodule()
{
    // TODO: Add your command handler code here
    bwsBrsMdl.GotoPrev();   
    //int n = SrcEmu.m_nStepOpt;
    SelectText(FALSE);
    LoadModule(bwsBrsMdl.GetElem(), FALSE);
        //SrcEmu.m_nStepOpt = n;    
       // SetStepOpt();
}

/////////////////////////////////////////////////////////////////////////////
//
//  Name:   
//
//  Description: 
//
//  Input:  
//
//  Output: 
//
//  Return: 
//
/////////////////////////////////////////////////////////////////////////////
void CBrowseWindow::OnFileNextmodule()
{
    // TODO: Add your command handler code here
    bwsBrsMdl.GotoNext();
    //int n = SrcEmu.m_nStepOpt;
    SelectText(FALSE);
    LoadModule(bwsBrsMdl.GetElem(), FALSE);    
        //SrcEmu.m_nStepOpt = n;    
        //SetStepOpt();
}

/////////////////////////////////////////////////////////////////////////////
//
//  Name:   
//
//  Description: 
//
//  Input:  
//
//  Output: 
//
//  Return: 
//
/////////////////////////////////////////////////////////////////////////////
void CBrowseWindow::OnUpdateFilePrevmodule(CCmdUI* pCmdUI)
{
    // TODO: Add your command update UI handler code here
    pCmdUI->Enable(!bwsBrsMdl.IsEmpty() && !bwsBrsMdl.IsHead());
    BOOL b=(BOOL)(!bwsBrsMdl.IsEmpty() && !bwsBrsMdl.IsHead());

#ifdef BWS_TOOL_WND
    m_pToolWnd->EnableBrowsePrev(b);
#endif    

}

/////////////////////////////////////////////////////////////////////////////
//
//  Name:   
//
//  Description: 
//
//  Input:  
//
//  Output: 
//
//  Return: 
//
/////////////////////////////////////////////////////////////////////////////
void CBrowseWindow::OnUpdateFileNextmodule(CCmdUI* pCmdUI)
{
    // TODO: Add your command update UI handler code here
    pCmdUI->Enable(!bwsBrsMdl.IsEmpty() && !bwsBrsMdl.IsTail());
    BOOL b=(BOOL)(!bwsBrsMdl.IsEmpty() && !bwsBrsMdl.IsTail());
#ifdef BWS_TOOL_WND
    m_pToolWnd->EnableBrowseNext(b);//!bwsBrsMdl.IsEmpty() && !bwsBrsMdl.IsTail());
#endif    
}

/////////////////////////////////////////////////////////////////////////////
//
//  Name:   
//
//  Description: 
//
//  Input:  
//
//  Output: 
//
//  Return: 
//
/////////////////////////////////////////////////////////////////////////////
void CBrowseWindow::OnFileBrowsemodule()
{
    // TODO: Add your command handler code here
    CSrcGrpDlg    dlg(3,this,TRUE);         
    dlg.DoModal();
    
/*    
    CSourceGroup    dlg(1,this,TRUE);         
    if(dlg.DoModal() == IDOK) {
        SelectText(FALSE);
        DoBwsBrowseModule(dlg);
    }   
    Invalidate();
*/    
}

/////////////////////////////////////////////////////////////////////////////
//
//  Name:   
//
//  Description: 
//
//  Input:  
//
//  Output: 
//
//  Return: 
//
/////////////////////////////////////////////////////////////////////////////
void CBrowseWindow::OnUpdateFileBrowsemodule(CCmdUI* pCmdUI)
{
    // TODO: Add your command update UI handler code here
    if(bwsMdlInfo.m_uModules == 0) {
     	pCmdUI->Enable(FALSE);
    } else {
     	for(int i = 0; i < int(bwsMdlInfo.m_uModules); i ++) {
			if(SrcCheckModuleHasLineInfo(bwsMdlInfo.m_pModule[i]) == 0) {
		     	pCmdUI->Enable(TRUE);
		     	return;
			}    		 	
     	}
    }
    pCmdUI->Enable(FALSE);    
}

/////////////////////////////////////////////////////////////////////////////
//
//  Name:   
//
//  Description: 
//
//  Input:  
//
//  Output: 
//
//  Return: 
//
/////////////////////////////////////////////////////////////////////////////
/*
void CBrowseWindow::OnFileLoad()
{
    // TODO: Add your command handler code here
    DoFileLoad();    
}
*/
/////////////////////////////////////////////////////////////////////////////
// Menu Message Handler -- Options Submenu
/////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////
//
//  Name:   
//
//  Description: 
//
//  Input:  
//
//  Output: 
//
//  Return: 
//
/////////////////////////////////////////////////////////////////////////////
/*
void CBrowseWindow::OnOptionsSourceextensionnames()
{
    // TODO: Add your command handler code here
    CSourceGroup    dlg(4, this);
    if(dlg.DoModal() == IDOK) {
        DoBrowseModule(dlg);
    }   
    Invalidate();    
  
}*/

/////////////////////////////////////////////////////////////////////////////
//
//  Name:   
//
//  Description: 
//
//  Input:  
//
//  Output: 
//
//  Return: 
//
/////////////////////////////////////////////////////////////////////////////
/*
void CBrowseWindow::OnOptionsSourceoptions()
{
    // TODO: Add your command handler code here
    CSourceGroup    dlg(3, this);
    if(dlg.DoModal() == IDOK) {
        DoBrowseModule(dlg);
    }   
    Invalidate();
}
*/
/////////////////////////////////////////////////////////////////////////////
//
//  Name:   
//
//  Description: 
//
//  Input:  
//
//  Output: 
//
//  Return: 
//
/////////////////////////////////////////////////////////////////////////////
/*
void CBrowseWindow::OnOptionsSourcepath()
{
    // TODO: Add your command handler code here
    CSourceGroup    dlg(2, this);
    if(dlg.DoModal() == IDOK) {
        DoBrowseModule(dlg);
    }   
    Invalidate();
}
*/
/////////////////////////////////////////////////////////////////////////////
// Menu Message Handler -- Run Submenu
/////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////
//
//  Name:   
//
//  Description: 
//
//  Input:  
//
//  Output: 
//
//  Return: 
//
/////////////////////////////////////////////////////////////////////////////
/*
void CBrowseWindow::OnRunGotocursor()
{
    // TODO: Add your command handler code here
    extern void EmuServerGo(int nMode, unsigned short uAddr);
    long lAddr = GetCaretAddr();
    if(lAddr == 0x10000L) {
        MessageBeep(-1);
        return;
    }          

    BeginWaitCursor();
    EmuServerGo(3, (unsigned short)lAddr);
    EndWaitCursor();
    OnEmulation();
}
*/
/////////////////////////////////////////////////////////////////////////////
//
//  Name:   
//
//  Description: 
//
//  Input:  
//
//  Output: 
//
//  Return: 
//
/////////////////////////////////////////////////////////////////////////////
/*
void CBrowseWindow::OnRunGofromcursor()
{
    // TODO: Add your command handler code here
    extern void EmuServerGo(int nMode, unsigned short uAddr);
    long lAddr = GetCaretAddr();
    if(lAddr == 0x10000L) {
        MessageBeep(-1);
        return;
    }          

    BeginWaitCursor();
    EmuServerGo(2, (unsigned short)lAddr);
    EndWaitCursor();
    OnEmulation();
}
*/
/////////////////////////////////////////////////////////////////////////////
//
//  Name:   
//
//  Description: 
//
//  Input:  
//
//  Output: 
//
//  Return: 
//
/////////////////////////////////////////////////////////////////////////////
/*
void CBrowseWindow::OnRunJumptocursor()
{
    // TODO: Add your command handler code here
    SelectText(FALSE);

    extern void EmuServerJump(unsigned short uAddr);
    long lAddr = GetCaretAddr();
    if(lAddr == 0x10000L) {
        MessageBeep(-1);
        return;
    }          
    
    BeginWaitCursor();
    EmuServerJump((unsigned short)lAddr);
    EndWaitCursor();
    OnEmulation();
}
*/
/////////////////////////////////////////////////////////////////////////////
//
//  Name:   
//
//  Description: 
//
//  Input:  
//
//  Output: 
//
//  Return: 
//
/////////////////////////////////////////////////////////////////////////////
/*
void CBrowseWindow::OnRunBreakpoint()
{
    // TODO: Add your command handler code here
    DoBreakPoint(this);    
}
*/
/////////////////////////////////////////////////////////////////////////////
//
//  Name:   
//
//  Description: 
//
//  Input:  
//
//  Output: 
//
//  Return: 
//
/////////////////////////////////////////////////////////////////////////////
/*
void CBrowseWindow::OnRunJump()
{
    // TODO: Add your command handler code here
    SelectText(FALSE);

    BeginWaitCursor();
    if(DoJump(this)) {    
        OnEmulation();
    }    
    EndWaitCursor();
}
*/
/////////////////////////////////////////////////////////////////////////////
//
//  Name:   
//
//  Description: 
//
//  Input:  
//
//  Output: 
//
//  Return: 
//
/////////////////////////////////////////////////////////////////////////////
/*
void CBrowseWindow::OnRunReset()
{
    // TODO: Add your command handler code here
    if(AfxMessageBox("Confirm reset operation?", MB_YESNO|MB_ICONQUESTION)
        == IDNO)    
        return;

    SelectText(FALSE);
        
    BeginWaitCursor();
    DoReset();    
    EndWaitCursor();
    OnEmulation();
}
*/
/////////////////////////////////////////////////////////////////////////////
// Menu Message Handler -- View Submenu
/////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////
//
//  Name:   
//
//  Description: 
//
//  Input:  
//
//  Output: 
//
//  Return: 
//
/////////////////////////////////////////////////////////////////////////////
void CBrowseWindow::OnViewSourceonly()
{
    // TODO: Add your command handler code here
    if(m_nDispMode == MODE_SOURCE)  return;    
    SelectText(FALSE);
    if(m_nDispMode == MODE_MIXED) {   
        if(SrcEmu.IsPCModule(bwsMdlInfo.CurModule())) 
            UpdateSource(SrcEmu.m_nPCLine);       
        else    UpdateSource(m_ptOffset.y);
        return;
    }
               
    // no source file downloaded               
    if(bwsMdlInfo.m_uModules == 0) {
        //AfxMessageBox(IDS_PRM_NOSYMINFO);
        return;
    }                              
    
    if(SrcEmu.GetPC() && SrcEmu.GetModule()) 
        if(BwsLoadModule(SrcEmu.m_dwPCModule) != SRC_LOAD_ERROR) {                
            UpdateSource(SrcEmu.m_nPCLine);   
            return;
        }
                                              
    if(BwsLoadModule(bwsMdlInfo.m_pModule[0]) == SRC_LOAD_ERROR)                 
        return;
    
    UpdateSource(0);    

#ifdef BWS_TOOL_WND
    if(m_pToolWnd)  
    {    
      if(m_nDispMode == MODE_ASM)
         m_pToolWnd->ResetButton();
    }              
#endif    

}

/////////////////////////////////////////////////////////////////////////////
//
//  Name:   
//
//  Description: 
//
//  Input:  
//
//  Output: 
//
//  Return: 
//
/////////////////////////////////////////////////////////////////////////////
void CBrowseWindow::OnUpdateViewSourceonly(CCmdUI* pCmdUI)
{
    // TODO: Add your command update UI handler code here
    pCmdUI->SetRadio(m_nDispMode == MODE_SOURCE);
    //browseOpenSwitch=BOOL(m_nDispMode != MODE_ASM);
}

/////////////////////////////////////////////////////////////////////////////
//
//  Name:   
//
//  Description: 
//
//  Input:  
//
//  Output: 
//
//  Return: 
//
/////////////////////////////////////////////////////////////////////////////
void CBrowseWindow::OnViewMixed()
{
    // TODO: Add your command handler code here
    if(m_nDispMode == MODE_MIXED)   return;    
    SelectText(FALSE);
    if(m_nDispMode == MODE_SOURCE) {
        if(SrcEmu.IsPCModule(bwsMdlInfo.CurModule())) 
            UpdateMixed(m_nBank, SrcEmu.m_lPCAddr);       
        else    UpdateMixed(m_ptOffset.y);
        return;
    }
        
    if(bwsMdlInfo.m_uModules == 0) {
        if(LoadOpt.m_isWarnings)
            AfxMessageBox(IDS_PRM_NOSYMINFO);
        return;
    }
    
    if(SrcEmu.GetPC() && SrcEmu.GetModule()) 
        if(UpdateMixed(SrcEmu.m_nPCBank, SrcEmu.m_lPCAddr))   return;
                                              
    if(BwsLoadModule(bwsMdlInfo.m_pModule[0]) == SRC_LOAD_ERROR)                 
        return;
    
    UpdateMixed(0);    

#ifdef BWS_TOOL_WND
    if(m_pToolWnd)  
    {    
      if(m_nDispMode == MODE_ASM)
         m_pToolWnd->ResetButton();
    }              
#endif    
   
}

/////////////////////////////////////////////////////////////////////////////
//
//  Name:   
//
//  Description: 
//
//  Input:  
//
//  Output: 
//
//  Return: 
//
/////////////////////////////////////////////////////////////////////////////
void CBrowseWindow::OnUpdateViewMixed(CCmdUI* pCmdUI)
{
    // TODO: Add your command update UI handler code here
    pCmdUI->SetRadio(m_nDispMode == MODE_MIXED);
    //browseOpenSwitch=BOOL(m_nDispMode != MODE_ASM);
}

//add by Chris, 12/16/96
void CBrowseWindow::OnViewAssemble()
{
	// TODO: Add your command handler code here
	if(m_nDispMode == MODE_ASM)
		return;
	SelectText(FALSE);
    if(SrcEmu.GetPC())
    	UpdateAsm(SrcEmu.m_nPCBank, SrcEmu.m_lPCAddr);
    else
    	UpdateAsm(m_nBank, 0);
}

//add by Chris, 12/16/96
void CBrowseWindow::OnUpdateViewAssemble(CCmdUI* pCmdUI)
{
	// TODO: Add your command update UI handler code here
	pCmdUI->SetRadio(m_nDispMode == MODE_ASM);
}

/////////////////////////////////////////////////////////////////////////////
//
//  Name:   
//
//  Description: 
//
//  Input:  
//
//  Output: 
//
//  Return: 
//
/////////////////////////////////////////////////////////////////////////////
void CBrowseWindow::OnViewSymbolicdisassembly()
{
    // TODO: Add your command handler code here
    if(isSymDsm)    isSymDsm = FALSE;
    else    isSymDsm = TRUE;

    AsmLine * pAsm;                
    int nLine, nAsm;
    if(m_nDispMode == MODE_ASM) {
        pAsm = (AsmLine *)BwsAsm.GetLine(BwsAsm.m_nOffset);
        if(!pAsm)   UpdateAsm(m_nBank, 0L);
        else    UpdateAsm(m_nBank, pAsm->m_uAddr);
    } else if(m_nDispMode == MODE_MIXED) {
        nLine = BwsMix.Ofs2Line(BwsMix.m_nOffset, nAsm);            
        if(nAsm == -1)  UpdateMixed(nLine);
        else {
            pAsm = (AsmLine *)BwsMix.GetLine(nLine, nAsm);
            if(!pAsm)   UpdateMixed(m_nBank, 0L);
            else    UpdateMixed(m_nBank, long(pAsm->m_uAddr));
        }
    }
}

/////////////////////////////////////////////////////////////////////////////
//
//  Name:   
//
//  Description: 
//
//  Input:  
//
//  Output: 
//
//  Return: 
//
/////////////////////////////////////////////////////////////////////////////
void CBrowseWindow::OnUpdateViewSymbolicdisassembly(CCmdUI* pCmdUI)
{
    // TODO: Add your command update UI handler code here
    pCmdUI->SetCheck(isSymDsm);
}

/////////////////////////////////////////////////////////////////////////////
//
//  Name:   
//
//  Description: 
//
//  Input:  
//
//  Output: 
//
//  Return: 
//
/////////////////////////////////////////////////////////////////////////////
void CBrowseWindow::OnViewLinenumbering()
{
    // TODO: Add your command handler code here
    ASSERT(m_nDispMode != MODE_ASM);

    ::isBwsLineNo = ::isBwsLineNo ? FALSE : TRUE;    
    //m_nLeft = ::isBwsLineNo ? 8 : 2;
    CalcLeftEdge();

    CRect rect;          
    GetClientRect(rect);
    CalcViewSize(rect.Width(), rect.Height());            
    CalcScrollSize();
    m_ptCaret.x = m_nLeft;
    Caret2Index();
    InvalidateRect(NULL);
}

/////////////////////////////////////////////////////////////////////////////
//
//  Name:   
//
//  Description: 
//
//  Input:  
//
//  Output: 
//
//  Return: 
//
/////////////////////////////////////////////////////////////////////////////
void CBrowseWindow::OnUpdateViewLinenumbering(CCmdUI* pCmdUI)
{
    // TODO: Add your command update UI handler code here
    pCmdUI->SetCheck(::isBwsLineNo);    
    pCmdUI->Enable(m_nDispMode != MODE_ASM);
}

/////////////////////////////////////////////////////////////////////////////
//
//  Name:   
//
//  Description: 
//
//  Input:  
//
//  Output: 
//
//  Return: 
//
/////////////////////////////////////////////////////////////////////////////
void CBrowseWindow::OnViewSyntaxcoloring()
{
    // TODO: Add your command handler code here
    if(SrcColor.m_isColorOn)    SrcColor.DisableColor();
    else                        SrcColor.EnableColor();
    InvalidateRect(NULL);
}

/////////////////////////////////////////////////////////////////////////////
//
//  Name:   
//
//  Description: 
//
//  Input:  
//
//  Output: 
//
//  Return: 
//
/////////////////////////////////////////////////////////////////////////////
void CBrowseWindow::OnUpdateViewSyntaxcoloring(CCmdUI* pCmdUI)
{
    // TODO: Add your command update UI handler code here
    pCmdUI->SetCheck(SrcColor.m_isColorOn);    
    pCmdUI->Enable(m_nDispMode != MODE_ASM);
}

/////////////////////////////////////////////////////////////////////////////
//
//  Name:   
//
//  Description: Switch between Source/Mixed/Asm Mode
//
//  Input:  
//
//  Output: 
//
//  Return: 
//
/////////////////////////////////////////////////////////////////////////////
void CBrowseWindow::OnViewSma()
{
    // TODO: Add your command handler code here
    if(m_nDispMode == MODE_SOURCE) 
        SendMessage(WM_COMMAND, ID_VIEW_MIXED);
    else if(m_nDispMode == MODE_ASM)   
        SendMessage(WM_COMMAND, ID_VIEW_SOURCEONLY);
    else { 
        if(SrcEmu.GetPC())  UpdateAsm(SrcEmu.m_nPCBank, SrcEmu.m_lPCAddr);
        else                UpdateAsm(m_nBank, 0);
    }
}                              

void CBrowseWindow::OnViewAsm()
{  
    if(m_nDispMode == MODE_ASM)   return;    
    
	if(SrcEmu.GetPC())  
	   UpdateAsm(SrcEmu.m_nPCBank, SrcEmu.m_lPCAddr);
	else                
	   UpdateAsm(m_nBank, 0);
}
/*static BOOL IsDelimit(char ch)
{
    return BOOL(strchr("~`!@$%^&*()-+=|\\}]{[\"\':;<,>.?/ \t\n\r", ch) 
                != NULL);
}*/

void CBrowseWindow::OnLButtonDblClk(UINT nFlags, CPoint point)
{
    // TODO: Add your message handler code here and/or call default
    int nLeft, nRight;
    
    SetFocus();
    SelectText(FALSE);
    
    CPoint  pt = point;

    if(point.x < m_rectScroll.left)         pt.x = m_rectScroll.left;
    if(point.x > m_rectScroll.right - 1)    pt.x = m_rectScroll.right - 1;
    if(point.y < m_rectScroll.top)          pt.y = m_rectScroll.top;
    if(point.y > m_rectScroll.bottom - 1)   pt.y = m_rectScroll.bottom - 1;
    
    m_ptCaret.x = X2Col(pt.x);
    m_ptCaret.y = Y2Row(pt.y);

    Caret2Index();
    SetCaret();                   
    
    if(m_nDispMode != MODE_SOURCE)  return;
    
    if(m_ptIndex.y < 0 || m_ptIndex.y >= BWSSRCLINES)  return;
    
    SourceElement * p1 = BWSSRCMDL.GetLine(m_ptIndex.y);
    if(!p1) return;                                
                                   
    if(p1->m_nLength <= m_ptIndex.x)    return;
    
    SyntaxColorElement * p2 = (SyntaxColorElement *)(p1->m_Color.GetFirst());
    while(p2) {
        if(m_ptIndex.x >= p2->m_nFirstCol && m_ptIndex.x <= p2->m_nLastCol) {
            if(p2->m_nSyntaxType == CSYN_CODE)  goto DBC1;
        }    
        p2 = (SyntaxColorElement *)(p1->m_Color.GetNext());
    }           
    
    return;
    
DBC1:      
    nLeft = m_ptIndex.x;          
    if(!::IsDelimit(p1->m_szLine[nLeft])) {
        while(nLeft) {
            if(::IsDelimit(p1->m_szLine[nLeft -1])) break;
            -- nLeft;
        }                 
    }
    
    nRight = m_ptIndex.x;
    while(nRight < p1->m_nLength) {
        if(::IsDelimit(p1->m_szLine[nRight]))   break;
        ++ nRight;
    }             
    
    if(nRight == nLeft) return;     
    
    m_strSel = CString(p1->m_szLine + nLeft, nRight - nLeft);
    m_nSelLine = m_ptIndex.y;
    m_nSelCol = nLeft;
    SelectText(TRUE);
  
    CMDIChildWnd::OnLButtonDblClk(nFlags, point);
}
/*
void CBrowseWindow::OnSetBPFunc()
{
    CString str("#");
    str += m_strSel;
    
    WORD wStart, wEnd;
    if(SrcGetFuncRange(str, wStart, wEnd) != 0) return;

    BYTE eFlag;
    if(BptSearchBpt(wStart, eFlag)) {
        if(!eFlag) BptEnableBpt(wStart);
    } else BptAddBptfromWnd(wStart);
    Invalidate();
}
 
void CBrowseWindow::OnClrBPFunc()
{
    CString str("#");
    str += m_strSel;
    
    WORD wStart, wEnd;
    if(SrcGetFuncRange(str, wStart, wEnd) != 0) return;

    BYTE eFlag;
    if(BptSearchBpt(wStart, eFlag)) 
        BptClrOneBptfromWnd(wStart);
    Invalidate();
}

void CBrowseWindow::OnSetBPVar()
{
    unsigned long dwAddr;  
    BYTE eFlag;
    if(SrcLinenum2Addr(bwsMdlInfo.CurModule(), (unsigned short)(m_nSelLine + 1), 
        dwAddr) == 0) {
        if(BptSearchBpt((unsigned short)dwAddr, eFlag)) {
            if(!eFlag) BptEnableBpt((unsigned short)dwAddr);
        } else BptAddBptfromWnd((unsigned short)dwAddr);
        UpdateRow(Line2Row(m_nSelLine));
    }
}
 
void CBrowseWindow::OnClrBPVar()
{
    unsigned long dwAddr;  
    BYTE eFlag;
    if(SrcLinenum2Addr(bwsMdlInfo.CurModule(), (unsigned short)(m_nSelLine + 1), 
        dwAddr) == 0) {
        if(BptSearchBpt((unsigned short)dwAddr, eFlag)) {
            BptClrOneBptfromWnd((unsigned short)dwAddr);
            UpdateRow(Line2Row(m_nSelLine));
        }   
    }
}

void CBrowseWindow::OnShowLoadAddr()
{
    CString str("#");
    str += m_strSel;
    
    CString str1;              
    
    char szStart[10], szEnd[10];    
        
    WORD wStart, wEnd;
    if(SrcGetFuncRange(str, wStart, wEnd) != 0) {
        if(LoadOpt.m_isWarnings)
            AfxMessageBox("Can't get load address!");
    } else {
        wsprintf(szStart, "%04Xh", wStart);
        wsprintf(szEnd, "%04Xh", wEnd);
        str1 = "The load address of the function: ";
        str1 += m_strSel;
        str1 += "\n";
        str1 += szStart;
        str1 += " -- ";
        str1 += szEnd;
        AfxMessageBox(str1);
    }
}

void CBrowseWindow::OnWatchVariable()
{
    unsigned long dwModule = bwsMdlInfo.CurModule();
    
    char tmp[200];
    if(SrcGetModuleName(dwModule, tmp) == -1)   return;
    
    CString str("#");
    str += tmp;
    str += "#";
    str += m_strSel;
    
    VarAddVariable(str);
}

void CBrowseWindow::OnInspectFunc()
{
    CString str("#");
    str += m_strSel;

    WORD wStart, wEnd;
    if(SrcGetFuncRange(str, wStart, wEnd) != 0) {
        if(LoadOpt.m_isWarnings)
            AfxMessageBox("Can't get load address!");
    } else {         
//////////////////////////////////    
///        SrcShowSource(wStart);    
///////////////////////////////////        
    }
}
*/
void CBrowseWindow::OnUpdateSearchCombo(CCmdUI* pCmdUI)
{
    pCmdUI->Enable(m_nDispMode == MODE_SOURCE);
}



void CBrowseWindow::OnKeyUp(UINT nChar, UINT nRepCnt, UINT nFlags)
{
	// TODO: Add your message handler code here and/or call default
	m_nbCanDo=0;
	CMDIChildWnd::OnKeyUp(nChar, nRepCnt, nFlags);
}

void CBrowseWindow::OnDestroy()
{
	CMDIChildWnd::OnDestroy();
	g_bBrowseActive=0;

#ifdef BWS_TOOL_WND
    m_pVScrollBar->DestroyWindow();
    m_pHScrollBar->DestroyWindow();
    if(m_pToolWnd)
    {
       m_pToolWnd->DestroyWindow();
	   delete m_pToolWnd;
	}   
	delete m_pVScrollBar;
	delete m_pHScrollBar;    
#endif    

	// TODO: Add your message handler code here
	
}

void CBrowseWindow::DrawScrollRect(CDC *pDC)
{
  int nVWidth=GetSystemMetrics(SM_CXVSCROLL);
  int nHHight=GetSystemMetrics(SM_CYHSCROLL);
  CRect rect;
  GetClientRect(&rect);
  
  CRect rectFill(rect.Width() -nVWidth,
                 rect.Height()-nHHight,
                 rect.right, rect.bottom);
  CBrush brush(GetSysColor(COLOR_BTNFACE));               
  pDC->FillRect(&rectFill,&brush);
  
}

/////////////////////////////////(EOF)///////////////////////////////////////
