// control.cpp : implementation file
//

#include "stdafx.h"
//#include "bar.h"
#include "control.h"
#include "auxdata.h"
#include "afxpriv.h"
#include "uicom.h"          
#include "srccom.h"
#include "resource.h"       
#include "hlistbox.h"


#ifdef _DEBUG
#undef THIS_FILE
static char BASED_CODE THIS_FILE[] = __FILE__;
#endif                               
extern UINT buttons[];                   
#define BORDER_ANY     0x0F00
#define BORDER_LEFT    0x0100
#define BORDER_TOP     0x0200
#define BORDER_RIGHT   0x0400
#define BORDER_BOTTOM  0x0800                   
/////////////////////////////////////////////////////////////////////////////
// CCONTROL

void GetToolIni(int* tools,UINT& count,char* entry)
{
    CString strOrder;   
    strOrder=AfxGetApp()->GetProfileString("toolbar",entry,"");
    if(strOrder.IsEmpty())
    {    tools=NULL;    
         count=0;
         return;
    }    
    char szT[128],*token;
    int Len=strOrder.GetLength(); 
    strncpy(szT,strOrder.GetBuffer(Len),min(Len,63));
    strOrder.ReleaseBuffer();
	szT[Len]=0;	
	token=strtok(szT,",");  
	int nT;              
	int i=0;
    do{
        nT=atoi(token);
        tools[i]=nT;
        token=strtok(NULL,",");
        i++;
     }while (token);    
    count=i; 
}

CCONTROL::CCONTROL()
{         
   	m_strUsrDefComm[0]=AfxGetApp()->GetProfileString("ToolBar","User-Def1","");
   	m_strUsrDefComm[1]=AfxGetApp()->GetProfileString("ToolBar","User-Def2","");
   	m_strUsrDefComm[2]=AfxGetApp()->GetProfileString("ToolBar","User-Def3","");
   	m_strUsrDefComm[3]=AfxGetApp()->GetProfileString("ToolBar","User-Def4","");
   	m_strUsrDefComm[4]=AfxGetApp()->GetProfileString("ToolBar","User-Def5","");
   	m_strUsrDefComm[5]=AfxGetApp()->GetProfileString("ToolBar","User-Def6","");
   	m_strUsrDefComm[6]=AfxGetApp()->GetProfileString("ToolBar","User-Def7","");
   	m_strUsrDefComm[7]=AfxGetApp()->GetProfileString("ToolBar","User-Def8","");

    m_bCanMove=0;
    GetToolIni(m_nMain,m_nMainCount,"Main");
    GetToolIni(m_nCPU,m_nCPUCount,"CPU");
    GetToolIni(m_nShell,m_nShellCount,"Shell");
    GetToolIni(m_nTrace,m_nTraceCount,"Trace");    
    GetToolIni(m_nMem,m_nMemCount,"Mem");
    GetToolIni(m_nSource,m_nSourceCount,"Source");
    GetToolIni(m_nStack,m_nStackCount,"Stack");
    GetToolIni(m_nVar,m_nVarCount,"Var");    
    GetToolIni(m_nBMem,m_nBMemCount,"BMem");
    GetToolIni(m_nPeri,m_nPeriCount,"Peri");    
    GetToolIni(m_nBrowse,m_nBrowseCount,"Browse");    
}

CCONTROL::~CCONTROL()
{     
//	free(m_pData);
}


BEGIN_MESSAGE_MAP(CCONTROL, CTipToolBar)
	//{{AFX_MSG_MAP(CCONTROL)
	ON_WM_PAINT()
	ON_WM_DESTROY()
	ON_WM_CREATE()
	ON_WM_LBUTTONDOWN()
	ON_WM_LBUTTONUP()
	ON_WM_MOUSEMOVE()
	//}}AFX_MSG_MAP
END_MESSAGE_MAP()

////////////////////////////////////////////////////////////////////
//	Function      SetPos()
//  Parameter     sPos : CBRS_LEFT, CBRS_RIGHT, CBRS_TOP, CBRS_BOTTOM
//	Return vlaue  1:position changed  
//				  0:POSITION NOT CHANGED.	
//Note:      Set the toolbar position.                        
//
//
//////////////////////////////////////////////////////////////// 
BOOL CCONTROL::SetWinButtons(UINT nWin)
{   
    switch (nWin){
    case  WID_MAIN: return SetButtons(m_nMain,m_nMainCount);
    case  WID_CPU: return SetButtons(m_nCPU,m_nCPUCount);
    case WID_SHELL: return SetButtons(m_nShell,m_nShellCount);
    case WID_TRACE: return SetButtons(m_nTrace,m_nTraceCount);
    case WID_MEMORY: return SetButtons(m_nMem,m_nMemCount);
    case WID_MEM2:return SetButtons(m_nMem,m_nMemCount);
    case WID_MEM3:return SetButtons(m_nMem,m_nMemCount);
    case WID_SOURCE:return SetButtons(m_nSource,m_nSourceCount);
    case WID_STACK:return SetButtons(m_nStack,m_nStackCount);
    case WID_VARIABLE:return SetButtons(m_nVar,m_nVarCount);
    case WID_BMEM:return SetButtons(m_nBMem,m_nBMemCount);
    case WID_PERI:return SetButtons(m_nPeri,m_nPeriCount);  
    case WID_BROWSE:return SetButtons(m_nBrowse,m_nBrowseCount);
    default:
    return SetButtons(m_nMain,m_nMainCount);
//    case WID_COUNT: return SetButtons(nWinButt,nCount);
  }
    return 0;   
}                  


BOOL CCONTROL::SetPos(DWORD wPos)
{                       
	ASSERT(wPos&(CBRS_LEFT|CBRS_TOP|CBRS_RIGHT|CBRS_BOTTOM));
	DWORD dwStyle;
	dwStyle=::GetWindowLong(m_hWnd,  GWL_STYLE	);
    if(dwStyle&wPos) return 0;
    else{
		m_cxLeftBorder=(wPos&(CBRS_LEFT|CBRS_RIGHT))?1:8;
		m_cyTopBorder=(wPos&(CBRS_LEFT|CBRS_RIGHT))?8:1;
		m_cyBottomBorder=(wPos&(CBRS_LEFT|CBRS_RIGHT))?8:1;
	
		dwStyle=dwStyle&~CBRS_TOP&~CBRS_BOTTOM&~CBRS_RIGHT&~CBRS_LEFT;
		dwStyle=dwStyle|wPos;                                    
		SetWindowLong(m_hWnd,  GWL_STYLE,dwStyle);
		CRect rect;
		rect.SetRectEmpty();
		CalcInsideRect(rect); 
		if(wPos&(CBRS_LEFT|CBRS_RIGHT) )
		{
			m_sizeFixedLayout.cx=m_sizeButton.cx-rect.Width();
			m_sizeFixedLayout.cy=32767;
		 }
		else
		{ 
			m_sizeFixedLayout.cy=m_sizeButton.cy-rect.Height();
			m_sizeFixedLayout.cx=32767;
        }
        GetParent()->SendMessage(WM_SIZE,SIZE_RESTORED,MAKELONG(1,1) );
		Invalidate();
		UpdateWindow();
		return 1;
	}
}                                        

/////////////////////////////////////////////////////////////////////////////
// CCONTROL message handlers
BOOL CCONTROL::ReplaceButton(int item ,int idleitem)
{
//  m_nMain[item]=idleitem;
    SetButtonInfo(item,buttons[idleitem],TBBS_BUTTON,idleitem);
    return 1; 
}              

void CCONTROL::SetButtonInfo(int nIndex, UINT nID, UINT nStyle, int iImage)
{
	ASSERT_VALID(this);

	AFX_TBBUTTON* pTBB = _GetButtonPtr(nIndex);
	pTBB->nID = nID;
	pTBB->iImage = iImage;
	pTBB->nStyle = nStyle;
	InvalidateButton(nIndex);
}

          

#define SPACE  0xffff


BOOL CCONTROL::InsertButton(int item,int idleitem,int att)
{
	AFX_TBBUTTON* pTBB1=(AFX_TBBUTTON*)m_pData;  
	void* pData;                           
	if( (pData=new AFX_TBBUTTON[m_nCount+1])==NULL)
	  return FALSE;         
	AFX_TBBUTTON* pTBB=(AFX_TBBUTTON*)pData;   
	for(UINT j=0;j<=item;j++,pTBB++){
	  pTBB->nID=pTBB1[j].nID;  
	  pTBB->nStyle=pTBB1[j].nStyle;  
	  pTBB->iImage=pTBB1[j].iImage;  
	}                      
	if(idleitem==-1){ 
      pTBB->nID=0;  
	  pTBB->nStyle=TBBS_SEPARATOR;  
	  pTBB->iImage=m_cxDefaultGap+2;  
    }
    else if(buttons[idleitem]==IDC_SRCHCOMBO){
   	  pTBB->nID=buttons[idleitem];  
	  pTBB->nStyle=TBBS_SEPARATOR;  
	  pTBB->iImage=80;  
    } else{
	  if(idleitem>33)  
	  	pTBB->nID=att;
	  else
	  pTBB->nID=buttons[idleitem];  
	  pTBB->nStyle=TBBS_BUTTON;  
	  pTBB->iImage=idleitem;  
    }
	pTBB++;  
	for( j=item+1;j<m_nCount;j++,pTBB++){ 
	  pTBB->nID=pTBB1[j].nID;  
	  pTBB->nStyle=pTBB1[j].nStyle;  
	  pTBB->iImage=pTBB1[j].iImage;  
	}       
	m_nCount++;
	delete m_pData;  
    m_pData=pData; 
//	Invalidate();
//	UpdateWindow(); 
    return 1; 
}

BOOL CCONTROL::IsButtonExsit(int iImage)
{
	AFX_TBBUTTON* pTBB=(AFX_TBBUTTON*)m_pData;
    for(UINT i=0;i<m_nCount-1;i++){
    	if(pTBB->iImage==iImage) return 1;
    	else pTBB++;
    }
    return 0;	
}

BOOL CCONTROL::RemoveButton(int item)
{
	AFX_TBBUTTON* pTBB=(AFX_TBBUTTON*)m_pData;
    for(UINT i=item;i<m_nCount-1;i++){
    	SetButtonInfo(i,pTBB[1+i].nID,pTBB[i+1].nStyle,pTBB[i+1].iImage);
    }	        
//    InvalidateButton(m_nMainCount);
	free((void*)&pTBB[i]); 
	m_nCount--;
//	Invalidate();
//	UpdateWindow();
	return 1;
}



void CCONTROL::DoPaint(CDC* pDC) 
{
	ASSERT_VALID(this);
	ASSERT_VALID(pDC);

	CControlBar::DoPaint(pDC);      // draw border
	CRect rect;
	GetClientRect(&rect);
	CalcInsideRect(rect);
	// force the full size of the button
	DWORD dwStyle=GetStyle();
	if(dwStyle&CBRS_TOP)
		rect.bottom = rect.top + m_sizeButton.cy;
    else if(dwStyle&CBRS_LEFT)
        rect.right=rect.left+ m_sizeButton.cx;
    else if(dwStyle&CBRS_BOTTOM)
        rect.top=rect.bottom-m_sizeButton.cy+2;
    else rect.left=rect.right-m_sizeButton.cx+2;        
        
	DrawState ds;
	if (!PrepareDrawButton(ds))
		return;   
	AFX_TBBUTTON* pTBB = (AFX_TBBUTTON*)m_pData;
	for (int iButton = 0; iButton < m_nCount; iButton++, pTBB++)
	{
		ASSERT(pTBB != NULL);
		if (pTBB->nStyle & TBBS_SEPARATOR)
		{
			// separator
  			if(dwStyle&CBRS_TOP)
				rect.right = rect.left + pTBB->iImage;
    		else if(dwStyle&CBRS_LEFT)
        		rect.bottom=rect.top+ pTBB->iImage;
    		else if(dwStyle&CBRS_BOTTOM)
        		rect.right = rect.left + pTBB->iImage;
    		else rect.bottom=rect.top+ pTBB->iImage;

			
		}
		else
		{   
		    if(dwStyle&CBRS_TOP)
				rect.right = rect.left + m_sizeButton.cx;
    		else if(dwStyle&CBRS_LEFT)
        		rect.bottom=rect.top+ m_sizeButton.cy;
    		else if(dwStyle&CBRS_BOTTOM)
        		rect.right = rect.left + m_sizeButton.cx;
    		else rect.bottom=rect.top+ m_sizeButton.cy;
			
			if (::RectVisible(pDC->m_hDC, &rect))
			{
				DrawButton(pDC->m_hDC, rect.left, rect.top,
					pTBB->iImage, pTBB->nStyle);
				
			}
		}
		// adjust for overlap
		if(dwStyle&CBRS_TOP||dwStyle&CBRS_BOTTOM)
		   rect.left = rect.right - 1;
		else rect.top=rect.bottom-1;   
	}
	EndDrawButton(ds);
}   

// input CRect should be client rectangle size
void CCONTROL::CalcInsideRect(CRect& rect) 
{
	ASSERT_VALID(this);
	DWORD dwStyle = GetStyle();

	// adjust for border size
	if (dwStyle & BORDER_LEFT)
		rect.left += CX_BORDER;
	if (dwStyle & BORDER_TOP)
		rect.top += CY_BORDER;
	if (dwStyle & BORDER_RIGHT)
		rect.right -= CX_BORDER;
	if (dwStyle & BORDER_BOTTOM)
		rect.bottom -= CY_BORDER;

	// inset the top and bottom.
	if(dwStyle&CBRS_TOP){
		rect.left += m_cxLeftBorder;
		rect.top += m_cyTopBorder;
		rect.bottom -= m_cyBottomBorder;
	}
	else if(dwStyle&CBRS_LEFT)
	{	 
	    rect.right -= m_cxLeftBorder;
		rect.top += m_cyTopBorder;
		rect.left+=m_cxLeftBorder;
	}	
    else if(dwStyle&CBRS_BOTTOM)
	{	 
	    rect.bottom -= m_cyBottomBorder+1;
		rect.top -= m_cyTopBorder;
		rect.left+=m_cxLeftBorder;
	}                          
	else if(dwStyle&CBRS_RIGHT)
	{	 
	    rect.right-= m_cxLeftBorder+1;
		rect.top += m_cyTopBorder;
		rect.left-=m_cxLeftBorder;
	}
}

int CCONTROL::HitTest(CPoint point) // in window relative coords
{
	CRect rect,Client;
	rect.SetRectEmpty();        // only need top and left
	CalcInsideRect(rect); 
	
	DWORD dwStyle=GetStyle();
	if( dwStyle&CBRS_TOP){
	   if (point.y < rect.top || point.y >= rect.top + m_sizeButton.cy)
	  	  return -1;}      // no Y hit
    else if(dwStyle&CBRS_LEFT){
       if (point.x < rect.left || point.x >= rect.left + m_sizeButton.cx)
	  	  return -1;}
	else if(dwStyle&CBRS_BOTTOM){  	        // no Y hit                                    
	   GetClientRect(&Client);
	   if (point.y > Client.bottom-rect.bottom || 
	         point.y <= rect.bottom )
	  	  return -1;} 	  
	else if(dwStyle&CBRS_RIGHT){ 
	   GetClientRect(&Client); 	        // no Y hit                                    
	   if (point.x > Client.right-rect.right || 
	          point.x <= rect.right )
	  	  return -1;} 	    	  
	AFX_TBBUTTON* pTBB = (AFX_TBBUTTON*)m_pData;
	ASSERT(pTBB != NULL);
	for (int iButton = 0; iButton < m_nCount; iButton++, pTBB++)
	{
		if( dwStyle&CBRS_TOP||dwStyle&CBRS_BOTTOM)
		{    if (point.x < rect.left)	break;     } // missed it
    	else if(dwStyle&CBRS_LEFT||dwStyle&CBRS_RIGHT)
       	{	if (point.y < rect.top)	break;         }// missed it
				
    	if( dwStyle&CBRS_TOP||dwStyle&CBRS_BOTTOM)
		{	
			
			rect.left += (pTBB->nStyle & TBBS_SEPARATOR) ?
							pTBB->iImage : m_sizeButton.cx;
							
			rect.left--;    // go back one for overlap
			if (point.x <= rect.left && ((!(pTBB->nStyle & TBBS_SEPARATOR))|pTBB->nID==IDC_SRCHCOMBO))
				return iButton;     // hit !
        }
    	else if(dwStyle&CBRS_LEFT||dwStyle&CBRS_RIGHT)
		{	rect.top += (pTBB->nStyle & TBBS_SEPARATOR) ?
							pTBB->iImage : m_sizeButton.cy;
			rect.top--;    // go back one for overlap
			if (point.y <= rect.top && !(pTBB->nStyle & TBBS_SEPARATOR))
				return iButton;     // hit !
        } 
        
	}
	return -1;      // nothing hit
}



void CCONTROL::OnPaint() 
{
	CPaintDC dc(this); // device context for painting
	
	// TODO: Add your message handler code here
	DoPaint(&dc);
	// Do not call CTipToolBar::OnPaint() for painting messages
}


BOOL CCONTROL::SetButtons(int FAR* lpIDArray, int nIDCount)
{
	ASSERT_VALID(this);
	ASSERT(nIDCount >= 1);  // must be at least one of them
	ASSERT(lpIDArray == NULL ||
		AfxIsValidAddress(lpIDArray, sizeof(UINT) * nIDCount, FALSE));

	// first allocate array for panes and copy initial data
	if (!AllocElements(nIDCount, sizeof(AFX_TBBUTTON)))
		return FALSE;
	ASSERT(nIDCount == m_nCount);

	if (lpIDArray != NULL)
	{
		int iImage = 0;
		// go through them adding buttons
		AFX_TBBUTTON* pTBB = (AFX_TBBUTTON*)m_pData;
		for (int i = 0; i < nIDCount; i++, pTBB++)
		{
			ASSERT(pTBB != NULL);
			
			if(*lpIDArray==-1)  pTBB->nID=0;
			else if(*lpIDArray>MAX_TOOLBAR_BUTTON)
			    pTBB->nID=*lpIDArray-MAX_TOOLBAR_BUTTON+WM_USER;
			else pTBB->nID= buttons[*lpIDArray];   
			if (pTBB->nID == 0)
			{
				// separator
				pTBB->nStyle = TBBS_SEPARATOR;
				// width of separator includes 2 pixel overlap
				pTBB->iImage = m_cxDefaultGap + 2;               
				lpIDArray++;
			}
			else
			{
				// a command button with image 
				if(pTBB->nID==IDC_SRCHCOMBO){
				   pTBB->nStyle = TBBS_SEPARATOR;
				   pTBB->iImage = 80;  
				   lpIDArray++;             
                }
                else{
				   pTBB->nStyle = TBBS_BUTTON;
				   pTBB->iImage = *lpIDArray++;
				}
				
			}
		}
	}
	return TRUE;
}



void CCONTROL::OnDestroy() 
{
	CTipToolBar::OnDestroy();
	AfxGetApp()->WriteProfileString("TOOLBAR","User-Def1",(m_strUsrDefComm[0]));
	AfxGetApp()->WriteProfileString("TOOLBAR","User-Def2",(m_strUsrDefComm[1]));
	AfxGetApp()->WriteProfileString("TOOLBAR","User-Def3",(m_strUsrDefComm[2]));
	AfxGetApp()->WriteProfileString("TOOLBAR","User-Def4",(m_strUsrDefComm[3]));
	AfxGetApp()->WriteProfileString("TOOLBAR","User-Def5",(m_strUsrDefComm[4]));
	AfxGetApp()->WriteProfileString("TOOLBAR","User-Def6",(m_strUsrDefComm[5]));
	AfxGetApp()->WriteProfileString("TOOLBAR","User-Def7",(m_strUsrDefComm[6]));
	AfxGetApp()->WriteProfileString("TOOLBAR","User-Def8",(m_strUsrDefComm[7]));
	
	char string[4]="";
	UINT i;
	char szT[2*MAX_BUTTON_NUM];                              
	if(m_nMainCount!=0)
	{
		memset(szT,0,2*MAX_BUTTON_NUM);
		for( i=0;i<m_nMainCount;i++)
		{
	   		strcat(szT,_itoa( m_nMain[i],string,10) );
	   		strcat(szT,"," );
		}
	   AfxGetApp()->WriteProfileString("TOOLBAR","Main",szT);
	}
	if(m_nSourceCount!=0)
	{
		memset(szT,0,2*MAX_BUTTON_NUM);
		for(i=0;i<m_nSourceCount;i++)
		{
	   		strcat(szT,_itoa( m_nSource[i],string,10) );
	   		strcat(szT,"," );
		}
	    AfxGetApp()->WriteProfileString("TOOLBAR","Source",szT);
	}
	if(m_nStackCount!=0)
	{
		memset(szT,0,2*MAX_BUTTON_NUM);
		for( i=0;i<m_nStackCount;i++)
		{
	   		strcat(szT,_itoa( m_nStack[i],string,10) );
	   		strcat(szT,"," );
		}
	   AfxGetApp()->WriteProfileString("TOOLBAR","Stack",szT);
	}
	if(m_nTraceCount!=0)
	{
		memset(szT,0,2*MAX_BUTTON_NUM);
		for( i=0;i<m_nTraceCount;i++)
		{
	   		strcat(szT,_itoa( m_nTrace[i],string,10) );
	   		strcat(szT,"," );
		}
	   AfxGetApp()->WriteProfileString("TOOLBAR","Trace",szT);
	}
	if(m_nVarCount!=0)
	{
		memset(szT,0,2*MAX_BUTTON_NUM);
		for( i=0;i<m_nVarCount;i++)
		{
	   		strcat(szT,_itoa( m_nVar[i],string,10) );
	   		strcat(szT,"," );
		}
	   AfxGetApp()->WriteProfileString("TOOLBAR","Var",szT);
	}         
	
	if(m_nCPUCount!=0)
	{
		memset(szT,0,2*MAX_BUTTON_NUM);
		for( i=0;i<m_nCPUCount;i++)
		{
	   		strcat(szT,_itoa( m_nCPU[i],string,10) );
	   		strcat(szT,"," );
		}            
	   AfxGetApp()->WriteProfileString("TOOLBAR","CPU",szT);
	}
}

    
int CCONTROL::OnCreate(LPCREATESTRUCT lpCreateStruct) 
{
	if (CTipToolBar::OnCreate(lpCreateStruct) == -1)
		return -1;
	
	// TODO: Add your specialized creation code here
	
	return 0;
}
    
void CCONTROL::DrawFrame(CRect WinRect)
{                           
	CDC *pDC;                    
	pDC=GetParent()->GetDC();
	pDC->DrawFocusRect(&WinRect);
    GetParent()->ReleaseDC(pDC);
}    
    
void CCONTROL::OnLButtonDown(UINT nFlags, CPoint point) 
{
	// TODO: Add your message handler code here and/or call default
	if(HitTest(point)<0){ 
	    SetCapture();
		GetWindowRect(&m_WinRect);  
		GetParent()->ScreenToClient(&m_WinRect);
		DWORD dwStyle=GetStyle(); 
		CRect rect;
		GetParent()->GetClientRect(&rect);
		m_LBDPoint=point;
        ClientToScreen(&m_LBDPoint);
		GetParent()->ScreenToClient(&m_LBDPoint);

	    m_bCanMove=1;
	    DrawFrame(m_WinRect);
	}
	
	// Copy from bartool.cpp, but can not call CTipToolBar::OnLButtonDown()	
	if ((m_iButtonCapture = HitTest(point)) < 0)
		return;     // nothing hit
	AFX_TBBUTTON* pTBB = _GetButtonPtr(m_iButtonCapture);
	ASSERT( (!(pTBB->nStyle & TBBS_SEPARATOR)|pTBB->nID==IDC_SRCHCOMBO));
    if(pTBB->nID==IDC_SRCHCOMBO) return;
	if (pTBB->nStyle & TBBS_DISABLED)
	{
		m_iButtonCapture = -1;
		return;     // don't press it
	}

	SetCapture();
	pTBB->nStyle |= TBBS_PRESSED;
	InvalidateButton(m_iButtonCapture);
	UpdateWindow(); // immediate feedback

	GetOwner()->SendMessage(WM_SETMESSAGESTRING, (WPARAM)pTBB->nID);

}

void CCONTROL::OnLButtonUp(UINT nFlags, CPoint point) 
{
	// TODO: Add your message handler code here and/or call default
	if(m_bCanMove){
	  if(!HitTest(point)) { ReleaseCapture();}
	  else{
		CRect ClientRect;
		GetParent()->GetClientRect(&ClientRect);
		DrawFrame(m_WinRect);
		int width=ClientRect.Width()/4;
		int height=ClientRect.Height()/2;
	    CPoint pointT=point; 
	    GetParent()->GetClientRect(&ClientRect); 
	    ClientToScreen(&pointT);
	    GetParent()->ScreenToClient(&pointT);

		if(pointT.x<width) SetPos(CBRS_LEFT);
		else if(pointT.x>3*width) SetPos(CBRS_RIGHT);
		else if(pointT.y>height) SetPos(CBRS_BOTTOM);
		else if(pointT.y<height) SetPos(CBRS_TOP);


		ReleaseCapture();
		m_bCanMove=0; 
	   }	
	}
	
// Copy from bartool.cpp, but can not call CTipToolBar::OnLButtonUp()	
	if (m_iButtonCapture < 0)
		return;     // not captured

	AFX_TBBUTTON* pTBB = _GetButtonPtr(m_iButtonCapture);
    if(pTBB->nID==IDC_SRCHCOMBO) return;
	ASSERT(!(pTBB->nStyle & TBBS_SEPARATOR));
	UINT nIDCmd = 0;

	UINT nNewStyle = (pTBB->nStyle & ~TBBS_PRESSED);
	if (GetCapture() == this)
	{
		// we did not lose the capture
		ReleaseCapture();
		if (HitTest(point) == m_iButtonCapture &&
		  !(pTBB->nStyle & TBBS_DISABLED))
		{
			// pressed, will send command notification
			nIDCmd = pTBB->nID;

			if (pTBB->nStyle & TBBS_CHECKBOX)
			{
				// auto check: three state => down
				if (nNewStyle & TBBS_INDETERMINATE)
					nNewStyle &= ~TBBS_INDETERMINATE;

				nNewStyle ^= TBBS_CHECKED;
			}
		}
	}

	_SetButtonStyle(m_iButtonCapture, nNewStyle);
	m_iButtonCapture = -1;
	UpdateWindow(); // immediate feedback

	// first flush the drag mode
	GetOwner()->SendMessage(WM_SETMESSAGESTRING, (WPARAM)AFX_IDS_IDLEMESSAGE);

	if (nIDCmd != 0)
		GetOwner()->SendMessage(WM_COMMAND, nIDCmd);    // send command

}

void CCONTROL::OnMouseMove(UINT nFlags, CPoint point) 
{
	// TODO: Add your message handler code here and/or call default
	
	if(m_iButtonCapture<0&&m_bCanMove){
		CRect ClientRect;
	   DWORD dwStyle=GetStyle();
	   CPoint Offset,pointT=point; 
       ClientToScreen(&pointT);
	   GetParent()->ScreenToClient(&pointT);
       GetParent()->GetClientRect(&ClientRect);
	   int width=ClientRect.Width()/4;
	   int height=ClientRect.Height()/2;
       CRect rectH(0,0,30000,22);
       CRect rectV(0,0,22,30000);
       DrawFrame(m_WinRect);
		if(pointT.x<width)
		{ 
		  if(m_WinRect.Width()>m_WinRect.Height())
		    m_WinRect=rectV+pointT;
		}  
		else if(pointT.x>3*width)                 
		{ if(m_WinRect.Width()>m_WinRect.Height())
		     m_WinRect=rectV+pointT;
		}
		else if(pointT.y>height) 
		     { if(m_WinRect.Width()<m_WinRect.Height())
		         m_WinRect=rectH+pointT;
		       
		      } 
		else if(pointT.y<height)
		       if(m_WinRect.Width()<m_WinRect.Height())
		  	      m_WinRect=rectH+pointT;  
	   Offset.y=pointT.y-m_LBDPoint.y;
	   Offset.x=pointT.x-m_LBDPoint.x;
       m_LBDPoint.x+=Offset.x;
       m_LBDPoint.y+=Offset.y;


	   m_WinRect+=Offset; 
	   m_LBDPoint=pointT;
	   DrawFrame(m_WinRect);
	}
	if (m_iButtonCapture < 0)
		return;     // not captured
	AFX_TBBUTTON* pTBB = _GetButtonPtr(m_iButtonCapture);
//	ASSERT(!(pTBB->nStyle & TBBS_SEPARATOR));
    if(pTBB->nID==IDC_SRCHCOMBO) return;
    
	UINT nNewStyle = (pTBB->nStyle & ~TBBS_PRESSED);
	if (GetCapture() != this)
	{
		m_iButtonCapture = -1; // lost capture
		GetOwner()->SendMessage(WM_SETMESSAGESTRING,
			(WPARAM)AFX_IDS_IDLEMESSAGE);
	}
	else
	{
		// should be pressed if still hitting the captured button
		if (HitTest(point) == m_iButtonCapture)
			nNewStyle |= TBBS_PRESSED;
	}
	_SetButtonStyle(m_iButtonCapture, nNewStyle);
	UpdateWindow(); // immediate feedback
}

AFX_TBBUTTON* CCONTROL::_GetButtonPtr(UINT nIndex)
{
	ASSERT(nIndex>=0 && nIndex<m_nCount);
	ASSERT(m_pData!=NULL);
	return ((AFX_TBBUTTON*)m_pData)+nIndex;
}	

void CCONTROL::_SetButtonStyle(int  nIndex,UINT nStyle)
{
	AFX_TBBUTTON* pTBB=_GetButtonPtr(nIndex);
	if (pTBB->nStyle != nStyle)
	{
		// change the style and invalidate
		pTBB->nStyle = nStyle;
		InvalidateButton(nIndex);
	}
}     
void CCONTROL::InvalidateButton(int nIndex)
{
	ASSERT_VALID(this);
	CRect rect;
	GetItemRect(nIndex,&rect);
	InvalidateRect(rect,FALSE);
}     
     
void CCONTROL::GetItemRect(int nIndex, LPRECT lpRect)
{
	ASSERT_VALID(this);
	ASSERT(nIndex >= 0 && nIndex < m_nCount);
	ASSERT(AfxIsValidAddress(lpRect, sizeof(RECT)));

	CRect rect;
	rect.SetRectEmpty();        // only need top and left
	CalcInsideRect(rect);
	DWORD dwStyle=GetStyle();
	AFX_TBBUTTON* pTBB = (AFX_TBBUTTON*)m_pData;
	for (int iButton = 0; iButton < nIndex; iButton++, pTBB++)
	{
		ASSERT(pTBB != NULL);                        
		// skip this button or separator
		if(dwStyle&CBRS_TOP||dwStyle&CBRS_BOTTOM)
		{
			if(pTBB->nID==IDC_SRCHCOMBO)
			   rect.left+=pTBB->iImage;
			else   
			   rect.left += (pTBB->nStyle & TBBS_SEPARATOR) ?
							pTBB->iImage : m_sizeButton.cx;
							
			rect.left--;    // go back one for overlap
		}
		else
		{
		    rect.top+= (pTBB->nStyle & TBBS_SEPARATOR) ?
							pTBB->iImage : m_sizeButton.cy;
			rect.top--;    // go back one for overlap    
		}	
				
	}
	ASSERT(iButton == nIndex);
	ASSERT(pTBB == _GetButtonPtr(nIndex));
                             
    if(dwStyle&CBRS_TOP||dwStyle&CBRS_BOTTOM)
	{
		// button or image width
		
		int cx = (pTBB->nStyle & TBBS_SEPARATOR) ? pTBB->iImage : m_sizeButton.cx;
		if(pTBB->nID==IDC_SRCHCOMBO) cx=pTBB->iImage;
		lpRect->right = (lpRect->left = rect.left) + cx;
		lpRect->bottom = (lpRect->top = rect.top) + m_sizeButton.cy;
	}
	else
	{
		int cy = (pTBB->nStyle & TBBS_SEPARATOR) ? pTBB->iImage : m_sizeButton.cy;
		lpRect->bottom = (lpRect->top = rect.top) + cy;
		lpRect->right = (lpRect->left = rect.left) + m_sizeButton.cx;
    }
}
