void CComputerGrid::AutoSort()
{
	if (CIBAConfig::GetInstance()->GetEnmergencyVisible() && IsSortingMode())
	{	
		INT nCol = GetSortColumn();

		BOOL bAscending = (GetColumnsInfo().GetColumnState(nCol) == 1); //正序排列

		Sort(nCol, bAscending);
	}
}
HRESULT GetDataFromRowset
(
 IRowset*	pIRowset
 )
{
	DBORDINAL		cCol;
	DBLENGTH		cbMaxRowSize;		// buffer size for 1 row's data
	DBORDINAL		cBind;
	DBBINDING		rgBind[MAX_BINDINGS];
	HACCESSOR		hAccessor		= NULL;
	DBCOLUMNINFO*	pColumnInfo 	= NULL;
	WCHAR*			pStringsBuffer  = NULL;
	HRESULT 		hr;



	DumpStatusMsg( "Reading all the data in the rowset...\n" );

	assert(pIRowset != NULL);
	assert(g_pIMalloc != NULL);

	hr = GetColumnsInfo( pIRowset, &cCol, &pColumnInfo, &pStringsBuffer );
	if (FAILED(hr))
	{
		DUMP_ERROR_LINENUMBER();
		DumpErrorHResult( hr,  "GetColumnsInfo");
		goto error;
	}

	hr = SetupBindings( cCol, pColumnInfo, rgBind, &cBind, &cbMaxRowSize );
	if (FAILED(hr))
	{
		DUMP_ERROR_LINENUMBER();
		DumpErrorHResult( hr,  "SetupBindings");
		goto error;
	}

	hr = CreateAccessor( pIRowset, rgBind, cBind, &hAccessor );
	if (FAILED(hr))
	{
		DUMP_ERROR_LINENUMBER();
		DumpErrorHResult( hr,  "CreateAccessor" );
		goto error;
	}

	hr = GetData( pIRowset, cbMaxRowSize, hAccessor, rgBind, cBind, pColumnInfo, cCol );
	if (FAILED(hr))
	{
		DUMP_ERROR_LINENUMBER();
		DumpErrorHResult( hr,  "GetData" );
		goto error;
	}

	g_pIMalloc->Free( pColumnInfo );
	pColumnInfo = NULL;
	g_pIMalloc->Free( pStringsBuffer );
	pStringsBuffer = NULL;

	hr = CleanupRowset( pIRowset, hAccessor );
	if (FAILED(hr))
	{
		DUMP_ERROR_LINENUMBER();
		DumpErrorHResult( hr,  "CleanupRowset" );
		goto error;
	}

	return ResultFromScode( S_OK );		

error:    
	if (pColumnInfo)
		g_pIMalloc->Free( pColumnInfo );
	if (pStringsBuffer)
		g_pIMalloc->Free( pStringsBuffer );	    	

	return ResultFromScode( hr );    
}
void CCxNDArrayDimGrid::OnLButtonDown(UINT nFlags, CPoint point)
{
	//CBCGPGridCtrl::OnLButtonDown(nFlags, point);

	CWnd::OnLButtonDown(nFlags, point);

	OnFilterBarSetFocus (-1);
	SetFocus ();

	//--------------------
	// Group-by-box click:
	//--------------------
	CRect rectColumn;
	int nGroupHit = HitTestGroupByBox (point, rectColumn);

	if (nGroupHit >= 0)
	{
		m_ptStartDrag = point;
		StartDragColumn (nGroupHit, rectColumn, TRUE, FALSE);
		return;
	}

	// -------------
	// Track header:
	// -------------
	CPoint ptHeader = point;
	if (OnTrackHeader () && m_rectList.PtInRect (point))
	{
		ptHeader.y = m_rectHeader.top;
	}
	int nColumnHit = GetColumnsInfo ().HitTestColumn (ptHeader, TRUE, STRETCH_DELTA);
	if (nColumnHit != -1)
	{
		int nLButton = GetSystemMetrics (SM_SWAPBUTTON) ? VK_RBUTTON : VK_LBUTTON;
		if ((GetAsyncKeyState (nLButton) & 0x8000) == 0)
		{
			return;
		}

		if (!GetColumnsInfo ().CanChangeWidth (nColumnHit))
		{
			// column can't be resized
			return;
		}

		CRect rectHeaderColumn;
		GetColumnsInfo ().GetColumnRect (nColumnHit, rectHeaderColumn);

		SetCapture ();
		m_nTrackColumn = nColumnHit;
		TrackHeader (rectHeaderColumn.right);
		m_bTracking = TRUE;
		return;
	}

	if (IsDragSelectionBorderEnabled () && HitTestSelectionBorder (point))
	{
		if (StartDragItems (point))
		{
			return;
		}
	}

	//--------------
	// Header click:
	//--------------
	CBCGPGridColumnsInfo::ClickArea clickAreaHeader;
	nColumnHit = GetColumnsInfo ().HitTestColumn (point, FALSE, STRETCH_DELTA, &clickAreaHeader);

	if (nColumnHit >= 0)
	{
		DoColumnHeaderClick (nColumnHit, point, clickAreaHeader);
		return;
	}

	//-------------------------
	// "Select all" area click:
	//-------------------------
	if (m_rectSelectAllArea.PtInRect (point))
	{
		OnSelectAllClick ();
		return;
	}

	//------------------
	// Row header click:
	//------------------
	CRect rectRowHeader;
	CCxNDArrayDimRow* pHitHeaderRow = (CCxNDArrayDimRow*)HitTestRowHeader (point, rectRowHeader);
	if (pHitHeaderRow != NULL)
	{
		DoRowHeaderClick (pHitHeaderRow, point, rectRowHeader);
		return;
	}

	// ---------------------------
	// Set selection (first click):
	// ---------------------------
	CBCGPGridRow::ClickArea clickArea;
	CBCGPGridItemID id;
	CBCGPGridItem* pHitItem = NULL;
	CBCGPGridRow* pHitRow = HitTest (point, id, pHitItem, &clickArea);

	BOOL bSelChanged = id != m_idLastSel;
	BOOL bIsButtonClick = pHitItem != NULL && ((CCxNDArrayDimItem*)pHitItem)->m_rectButton.PtInRect (point);

	const BOOL bShift = (::GetAsyncKeyState (VK_SHIFT) & 0x8000) != 0 && !m_bIgnoreShiftBtn;
	const BOOL bCtrl = (::GetAsyncKeyState (VK_CONTROL) & 0x8000) != 0 && !m_bIgnoreCtrlBtn;

	if (IsDragSelectionEnabled () && IsItemSelected (id) && !(bCtrl && m_bInvertSelOnCtrl))
	{
		if (StartDragItems (point))
		{
			return;
		}
	}

	DWORD dwSelMode = SM_NONE;
	if (!id.IsNull ())
	{
		dwSelMode = SM_FIRST_CLICK |
			(m_bSingleSel ? SM_SINGE_SEL_GROUP :
			(bCtrl ? SM_ADD_SEL_GROUP :
			(bShift ? SM_CONTINUE_SEL_GROUP : SM_SINGE_SEL_GROUP)));

		if (bCtrl && m_bInvertSelOnCtrl)
		{
			dwSelMode |= SM_INVERT_SEL;
		}

		if (pHitRow != NULL && id.IsRow ())
		{
			dwSelMode |= SM_ROW;
		}
		if (id.IsColumn ())
		{
			dwSelMode |= SM_COLUMN;
		}
	}
	
	m_bNoUpdateWindow = TRUE; // prevent flickering
	m_pSetSelItem = m_bVirtualMode ? NULL : pHitItem;

	SetCurSel (id, dwSelMode);

	m_pSetSelItem = NULL;
	m_bNoUpdateWindow = FALSE;

	if (id.IsNull () || pHitRow == NULL)
	{
		return;
	}

	ASSERT_VALID (pHitRow);
	EnsureVisible (pHitRow);

	CCxNDArrayDimRow* pCurSel = (CCxNDArrayDimRow*)GetCurSel ();
	CCxNDArrayDimItem* pItem = ( CCxNDArrayDimItem* )GetCurSelItem (pCurSel);
	if (id != m_idActive || pCurSel == NULL || (pItem == NULL && clickArea == CBCGPGridRow::ClickValue))
	{
		// The hitten item is not active - do not translate a click to the grid item.
		// Translate a click for single item only.
		return;
	}

	// ------------------------------
	// Translate a click to the item:
	// ------------------------------
	ASSERT_VALID (pCurSel); // pCurSel - hitten row

	switch (clickArea)
	{
	case CBCGPGridRow::ClickExpandBox:
		pCurSel->Expand (!pCurSel->IsExpanded ());
		break;

	case CBCGPGridRow::ClickName:
		pCurSel->OnClickName (point);

		// Start selecting range of items:
		StartSelectItems ();
		break;

	case CBCGPGridRow::ClickValue:
		ASSERT_VALID (pItem);	// pItem - hitten active item
		if (pCurSel->m_bEnabled && pItem->IsEnabled ())
		{
			if (bIsButtonClick || m_bSingleSel)
			{
				DoClickValue (pItem, WM_LBUTTONDOWN, point, bSelChanged, bIsButtonClick);
			}
			else
			{
				// Defer the item click:
				SetTimer (GRID_CLICKVALUE_TIMER_ID, GRID_CLICKVALUE_TIMER_INTERVAL, NULL);
				m_bClickTimer = TRUE;
				m_ptClickOnce = point;
				m_bIsFirstClick = bSelChanged;
				m_bIsButtonClick = bIsButtonClick;
				m_bHeaderRowSelecting = FALSE;
				m_bHeaderColSelecting = FALSE;

				StartSelectItems ();
				return;
			}
		}
		break;

	default:
		break;
	}
}
//****************************************************************************************
void CCxNDArrayDimGrid::DrawHeaderPart (CDC* pDC, const CBCGPGridHeaderParams& params)
{
	ASSERT_VALID (this);
	ASSERT_VALID (pDC);

	CRect rcCell = params.m_rect;

//	if (!visualManager->DrawHeaderPart (pDC, params))
	{
		switch (params.m_nHeaderPart)
		{
			//表头区域
		case CBCGPGridHeaderParams::HeaderTop:
			//if (params.m_nColumn != -1)
			{
				CBCGPGridColors::ColorData colorData = 
					params.IsSelected () && m_ColorData.m_HeaderSelColors.m_clrBackground != -1 ? 
						m_ColorData.m_HeaderSelColors :
						m_ColorData.m_HeaderColors;

				if (!colorData.Draw (pDC, rcCell))
				{
					m_bHeaderItemHovered = params.IsHighlighted ();
					GetColumnsInfo ().m_bInvertPressedColumn = 
						visualManager->OnDrawGridHeaderItemBorder (this, pDC, rcCell, params.IsPressed ());
				}

				//rcCell.top -= 1;
				//rcCell.left -= 1;
				//pDC->Draw3dRect (rcCell, g_crNDArrayHeaderBorder, g_crNDArrayHeaderBorder);

				{
					CPen pen (PS_SOLID, 1, g_crNDArrayHeaderBorder);
					CPen* pOldPen = pDC->SelectObject (&pen);
					//下
					pDC->MoveTo ( rcCell.left, rcCell.bottom - 1 );
					pDC->LineTo ( rcCell.right, rcCell.bottom - 1 );
					//右
					pDC->MoveTo ( rcCell.right - 1, rcCell.top );
					pDC->LineTo ( rcCell.right - 1, rcCell.bottom );
					pDC->SelectObject (pOldPen);
				}
			}
			break;
			//左侧行编号区域
		case CBCGPGridHeaderParams::HeaderLeft:
			{
				CBCGPGridColors::ColorData colorData = 
					params.IsSelected () && m_ColorData.m_HeaderSelColors.m_clrBackground != -1 ? 
						m_ColorData.m_HeaderSelColors :
						m_ColorData.m_HeaderColors;
				
				rcCell.top += 1;
				if (!colorData.Draw (pDC, rcCell))
				{
					m_bHeaderItemHovered = params.IsHighlighted ();
					GetColumnsInfo ().m_bInvertPressedColumn = 
						visualManager->OnDrawGridRowHeaderItemBorder (this, pDC, rcCell, params.IsPressed ());
				}

				if (m_bLineNumbers && params.m_pRow != NULL)
				{
					m_bHeaderItemHovered = params.IsHighlighted ();
					OnDrawLineNumber (pDC, params.m_pRow, rcCell, params.IsSelected (), params.IsPressed ());
				}
			}
			break;
			//行编号矩形区域、表头矩形区域 交叉的 矩形区域。
		case CBCGPGridHeaderParams::HeaderTopLeft:
			//----------------------
			// Draw Select All area:
			//----------------------
			{
				CBCGPGridColors::ColorData colorData = 
					params.IsSelected () && m_ColorData.m_HeaderSelColors.m_clrBackground != -1 ? 
						m_ColorData.m_HeaderSelColors :
						m_ColorData.m_HeaderColors;

				if (!colorData.Draw (pDC, rcCell))
				{
					m_bHeaderItemHovered = params.IsHighlighted ();
					GetColumnsInfo ().m_bInvertPressedColumn = 
						visualManager->OnDrawGridSelectAllAreaBorder (this, pDC, rcCell, params.IsPressed ());
				}
			}
			break;
		}
	}
}