📄 barchart.cpp
字号:
// create fonts
LOGFONT lf;
ZeroMemory(&lf, sizeof(lf));
strcpy(lf.lfFaceName,"Tahoma");
lf.lfHeight=-20;
lf.lfWeight = 700;
lf.lfCharSet = ARABIC_CHARSET;
lf.lfOutPrecision = OUT_STROKE_PRECIS;
lf.lfClipPrecision=2;
lf.lfQuality=1;
lf.lfPitchAndFamily=2;
m_fontBold.CreateFontIndirect(&lf);
lf.lfWeight = 400;
m_fontNorm.CreateFontIndirect(&lf);
if (m_rgnTip.CreateRoundRectRgn(m_rcClient.left,
m_rcClient.top, m_rcClient.right, m_rcClient.bottom,
TIP_RGN_ROUND_CORNERS, TIP_RGN_ROUND_CORNERS))
{
// Window region
SetWindowRgn((HRGN)m_rgnTip.GetSafeHandle(), FALSE);
};
// Region for drawing bounding frame
m_rgnCopy.CreateRoundRectRgn(m_rcClient.left,
m_rcClient.top, m_rcClient.right, m_rcClient.bottom,
TIP_RGN_ROUND_CORNERS, TIP_RGN_ROUND_CORNERS);
/*
m_rgnShadow.CreateRoundRectRgn(m_rcClient.left +2,
m_rcClient.top +2, m_rcClient.right , m_rcClient.bottom ,
TIP_RGN_ROUND_CORNERS, TIP_RGN_ROUND_CORNERS);
*/
return TRUE;
}
void CChartTip::Pop()
{
if (!m_hWnd)
{
return;
}
if (!*m_pbEnable)
{
return;
}
if (IsWindowVisible() && m_szOldTitle==*m_lpszTitle)
{
/* m_pointOld = point;
SetWindowPos( 0,
point.x+TIP_RIGHT_OFFSET, point.y+TIP_TOP_OFFSET, 0, 0,
SWP_NOACTIVATE|SWP_NOZORDER|SWP_NOSIZE );*/
return;
}
else
{
m_szOldTitle = *m_lpszTitle;
}
CPoint point;
GetCursorPos( &point );
if (m_pointOld==point)
{
return;
}
if (!IsWindowVisible() ||
(IsWindowVisible() && m_pointOld != point) )
{
m_pointOld = point;
m_bTimer = FALSE;
KillTimer(TIP_DELAY_TIMER);
CRect rc(m_pointOld.x + TIP_RIGHT_OFFSET, m_pointOld.y + TIP_TOP_OFFSET,
m_pointOld.x + TIP_RIGHT_OFFSET + m_rcClient.right,
m_pointOld.y + TIP_TOP_OFFSET + m_rcClient.bottom);
CRect rcMonitor (0, 0, 0, 0);
rcMonitor.right = GetSystemMetrics( SM_CXSCREEN );
rcMonitor.bottom = GetSystemMetrics( SM_CYSCREEN );
if ( rc.right >= rcMonitor.right)
{
rc.OffsetRect( rcMonitor.right - rc.right - 4, 0 );
}
if ( rc.bottom >= rcMonitor.bottom )
{
rc.OffsetRect( 0, ( rcMonitor.bottom - rc.bottom ) );
}
SetWindowPos( &wndTopMost,
rc.left, rc.top, rc.Width(), rc.Height(),
SWP_SHOWWINDOW|SWP_NOACTIVATE );
Invalidate(TRUE);
UpdateWindow();
SetTimer(TIP_DELAY_TIMER , m_nDelay, NULL);
m_bTimer = TRUE;
return;
}
}
void CChartTip::OnTimer(UINT nIDEvent)
{
CWnd::OnTimer(nIDEvent);
if (nIDEvent==TIP_DELAY_TIMER)
{
m_bTimer = FALSE;
KillTimer(TIP_DELAY_TIMER);
HideWindow();
}
}
void CChartTip::OnLButtonDown(UINT nFlags, CPoint point)
{
CWnd::OnLButtonDown(nFlags, point);
HideWindow();
}
void CChartTip::OnMouseMove(UINT nFlags, CPoint point)
{
CWnd::OnMouseMove(nFlags, point);
if (!PtInRect(&m_rcClient, point))
{
return;
}
GetCursorPos(&point);
m_pointOld = point;
CRect rcMonitor (0, 0, 0, 0);
rcMonitor.right = GetSystemMetrics( SM_CXSCREEN );
rcMonitor.bottom = GetSystemMetrics( SM_CYSCREEN );
CRect rc(m_pointOld.x + TIP_RIGHT_OFFSET, m_pointOld.y + TIP_TOP_OFFSET,
m_pointOld.x + TIP_RIGHT_OFFSET + m_rcClient.right,
m_pointOld.y + TIP_TOP_OFFSET + m_rcClient.bottom);
if ( rc.right >= rcMonitor.right)
{
rc.OffsetRect( rcMonitor.right - rc.right - 4, 0 );
}
if ( rc.bottom >= rcMonitor.bottom )
{
rc.OffsetRect( 0, ( rcMonitor.bottom - rc.bottom ) );
}
SetWindowPos(0, rc.left, rc.top, 0, 0,
SWP_NOSIZE|SWP_NOZORDER|SWP_NOACTIVATE);
//HideWindow();
}
BOOL CChartTip::OnEraseBkgnd(CDC* pDC)
{
return TRUE;
}
void CChartTip::OnPaint()
{
if ( ! IsWindow( GetSafeHwnd() ) || ! IsWindowVisible() ) return;
CPaintDC dc(this); // device context for painting
// Draw tip
dc.FillRgn( &m_rgnCopy, &m_brBK);
dc.FrameRgn( &m_rgnCopy, &m_brFrame, TIP_FRAME_THICKNESS, TIP_FRAME_THICKNESS);
CFont* pOldFont;
int nIndex = 0, nLastIndex = 0;
nIndex = m_lpszTitle->Find("\n", 0);
dc.SetBkMode(TRANSPARENT);
if (nIndex!=-1)
{
nLastIndex = nIndex;
if ( m_szText != m_lpszTitle->Left(nIndex) )
{
m_szText = m_lpszTitle->Left(nIndex);
}
pOldFont = (CFont*) dc.SelectObject(&m_fontBold);
dc.SetTextColor(TIP_TITLE_COLOR);
// Draw label
dc.DrawText(m_szText,
CRect(m_rcClient.left + TIP_LEFT_MARGIN,
m_rcClient.top + TIP_TOP_MARGIN,
m_rcClient.right - TIP_LEFT_MARGIN,
m_rcClient.top + TIP_TEXT_MAX_HEIGHT),
DT_LEFT | DT_SINGLELINE | DT_VCENTER);
dc.SelectObject(pOldFont);
}
// Draw rest
pOldFont = (CFont*) dc.SelectObject(&m_fontNorm);
int i = 1;
dc.SetTextColor(TIP_TEXT_COLOR);
while (1)
{
if (nIndex+1>=m_lpszTitle->GetLength()) break;
nIndex = m_lpszTitle->Find("\n", nLastIndex+1);
if (nIndex!=-1)
{
m_szText = m_lpszTitle->Mid(nLastIndex+1, nIndex - nLastIndex-1);
nLastIndex = nIndex;
}
else
{
break;
}
dc.DrawText(m_szText,
CRect(m_rcClient.left + TIP_LEFT_MARGIN,
m_rcClient.top + TIP_TOP_MARGIN + i*TIP_TEXT_MAX_HEIGHT + 2,
m_rcClient.right - TIP_LEFT_MARGIN,
m_rcClient.top + i*TIP_TEXT_MAX_HEIGHT + 50),
DT_LEFT | DT_SINGLELINE | DT_VCENTER);
i++;
dc.SetTextColor(TIP_PERCENT_COLOR);
}
dc.SelectObject(pOldFont);
}
void CChartTip::HideWindow()
{
GetCursorPos( &m_pointOld );
if (m_bTimer)
{
m_bTimer = FALSE;
KillTimer(TIP_DELAY_TIMER);
}
ShowWindow(SW_HIDE);
}
int CChartTip::OnCreate(LPCREATESTRUCT lpCreateStruct)
{
if (CWnd::OnCreate(lpCreateStruct) == -1)
return -1;
m_bTimer = FALSE;
return 0;
}
void CChartTip::Hide()
{
HideWindow();
}
///////////////////////////////////////////////////////////////////////
// CChartDatabase Class
//
// This class gives the chart the ability to connect to an
// ODBC data source. Then it is able to read data of a table
// or use results of a stored procedure.
// The class uses ODBC Version 3.
//
///////////////////////////////////////////////////////////////////////
CBarChart::CChartDatabase::CChartDatabase()
{
// Some initializations...
m_hDbConn = SQL_NULL_HANDLE;
m_hOdbcEnv = SQL_NULL_HANDLE;
m_hstmt = SQL_NULL_HANDLE;
memset(&m_row, NULL, sizeof(m_row));
m_sqlRet = SQL_SUCCESS;
m_bEOF = FALSE;
m_szError = _T("");
}
CBarChart::CChartDatabase::~CChartDatabase()
{
Close();
}
/*****************************************************************************************
* Opens requested table or executes procedure.
* If this is a call to a procedure, then 'szTable' is name of the procedure
* And 'szFilter' parameter will be used as input parameter(s) of the procedure
*
* CAUTION : If you are using this to call a stored procedure, then LabelFieldName and
* ValueFieldName will be ignored. The Stored procedure is considered to have at least 2
* parameters. The fist parameter will be considered as Label and the second one as value.
*****************************************************************************************/
BOOL CBarChart::CChartDatabase::OpenTable(CString szDSN, CString szTable,
CString szLabelFieldName, CString szValueFieldName,
CString szFilter,
CString szUsername, CString szPass,
BOOL bStoredProc, ULONG ulODBCVer)
{
// Already opened, can't call open twice
ASSERT(!m_hOdbcEnv);
if (m_hOdbcEnv != SQL_NULL_HANDLE)
{
return FALSE;
}
// Lest prepare environment, etc.
if (! Prepare(ulODBCVer))
{
ASSERT(FALSE);
return FALSE;
};
// Connect to ODBC
if (!Connect(szDSN, szUsername, szPass))
{
ASSERT(FALSE);
return FALSE;
};
// We are not at the end of records
m_bEOF = FALSE;
// Execute query or run a stored procedure
if ( bStoredProc == FALSE )
{
if (!ExecuteQuery(szTable, szFilter, szLabelFieldName, szValueFieldName))
{
ASSERT(FALSE);
return FALSE;
}
else
{
// Fetch first row, ready for GetRow
MoveNext();
}
}
else
{
if (!ExecuteProc(szTable, szFilter, szLabelFieldName, szValueFieldName))
{
ASSERT(FALSE);
return FALSE;
}
else
{
// Fetch first row, ready for GetRow
MoveNext();
}
}
return TRUE;
}
BOOL CBarChart::CChartDatabase::OpenProc(CString szDSN, CString szStoredProc,
CString szParameterList,
CString szUsername, CString szPass,
ULONG ulODBCVer)
{
// Already opened, can't call open twice
ASSERT(!m_hOdbcEnv);
if (m_hOdbcEnv != SQL_NULL_HANDLE)
{
return FALSE;
}
return
OpenTable(szDSN, szStoredProc, "", "", szParameterList,
szUsername, szPass, TRUE, ulODBCVer);
}
BOOL CBarChart::CChartDatabase::Prepare(ULONG ulODBCVer)
{
// Allocate Environment
m_sqlRet = SQLAllocHandle(SQL_HANDLE_ENV, SQL_NULL_HANDLE, &m_hOdbcEnv);
if(m_sqlRet != SQL_SUCCESS && m_sqlRet != SQL_SUCCESS_WITH_INFO)
{
m_szError = _T("Error in Allocating Environment.");
return FALSE;
}
// Set the App's ODBC Version
m_sqlRet = SQLSetEnvAttr(m_hOdbcEnv, SQL_ATTR_ODBC_VERSION,
(SQLPOINTER)ulODBCVer, SQL_IS_INTEGER);
if(m_sqlRet != SQL_SUCCESS && m_sqlRet != SQL_SUCCESS_WITH_INFO)
{
m_szError = _T("Error in Setting ODBC Version.");
return FALSE;
}
// Allocate Connection
m_sqlRet = SQLAllocHandle(SQL_HANDLE_DBC, m_hOdbcEnv, &m_hDbConn);
if(m_sqlRet != SQL_SUCCESS && m_sqlRet != SQL_SUCCESS_WITH_INFO)
{
m_szError = _T("Error in Allocating Connection.");
return FALSE;
}
return TRUE;
}
BOOL CBarChart::CChartDatabase::Connect(CString szDSN, CString szUsername, CString szPass)
{
// Set Connect Timeout
m_sqlRet = SQLSetConnectAttr(m_hDbConn, SQL_ATTR_LOGIN_TIMEOUT, (void*)15, 0);
if(m_sqlRet != SQL_SUCCESS && m_sqlRet != SQL_SUCCESS_WITH_INFO)
{
m_szError = _T("Error in Setting Login Timeout.");
return FALSE;
}
// Connect to Data Source
m_sqlRet = SQLConnect(m_hDbConn, (UCHAR *)(LPCSTR)szDSN, SQL_NTS,
(UCHAR *)(LPCSTR)szUsername, SQL_NTS,
(UCHAR *)(LPCSTR)szPass, SQL_NTS);
if(m_sqlRet != SQL_SUCCESS && m_sqlRet != SQL_SUCCESS_WITH_INFO)
{
m_szError = _T("Error in SQLConnect");
return FALSE;
}
return TRUE;
}
BOOL CBarChart::CChartDatabase::ExecuteQuery(CString szTable, CString szFilter,
CString szLabelFieldName, CString szValueFieldName)
{
CString szQuery;
szQuery.Format("SELECT %s, %s FROM %s %s",
szLabelFieldName, szValueFieldName, szTable, szFilter);
szQuery.TrimLeft();
szQuery.TrimRight();
return ExecuteSQL(szQuery);
}
BOOL CBarChart::CChartDatabase::ExecuteProc(CString szTable, CString szFilter,
CString szLabelFieldName, CString szValueFieldName)
{
CString szQuery;
szQuery.Format("{call %s (%s)}",
szTable, szFilter);
return ExecuteSQL(szQuery);
}
BOOL CBarChart::CChartDatabase::ExecuteSQL(CString& szQuery)
{
// Allocate Statement Handle
m_sqlRet = SQLAllocHandle(SQL_HANDLE_STMT, m_hDbConn, &m_hstmt);
if(m_sqlRet != SQL_SUCCESS && m_sqlRet != SQL_SUCCESS_WITH_INFO)
{
m_szError = _T("Error in allocating statement");
return FALSE;
}
// Execute SQL statement
m_sqlRet = SQLExecDirect(m_hstmt, (UCHAR*)(LPCSTR)szQuery, SQL_NTS);
if(m_sqlRet != SQL_SUCCESS && m_sqlRet != SQL_SUCCESS_WITH_INFO)
{
m_szError = _T("Error executing statement");
return FALSE;
}
// Bind each column
m_sqlRet = SQLBindCol(m_hstmt, 1, SQL_C_CHAR,
m_row.szLabel, sizeof(m_row.szLabel), &m_row.nLabelLen);
if(m_sqlRet != SQL_SUCCESS && m_sqlRet != SQL_SUCCESS_WITH_INFO)
{
m_szError = _T("Error in Binding first column");
return FALSE;
}
m_sqlRet = SQLBindCol(m_hstmt, 2, SQL_C_DOUBLE,
&m_row.dValue, sizeof(m_row.dValue), &m_row.nValueLen);
if(m_sqlRet != SQL_SUCCESS && m_sqlRet != SQL_SUCCESS_WITH_INFO)
{
m_szError = _T("Error in Binding second column");
return FALSE;
}
return TRUE;
}
BOOL CBarChart::CChartDatabase::IsEOF()
{
return m_bEOF;
}
BOOL CBarChart::CChartDatabase::MoveNext()
{
if (m_hstmt == NULL || m_bEOF == TRUE)
{
return FALSE;
}
if (SQLFetch(m_hstmt) != SQL_SUCCESS)
{
m_bEOF = TRUE;
return FALSE;
}
return TRUE;
}
void CBarChart::CChartDatabase::GetRow(CString &szLabel, double &dValue)
{
if (m_row.nLabelLen!=0)
{
szLabel = m_row.szLabel;
}
if (m_row.nValueLen!=0)
{
dValue = m_row.dValue;
}
}
void CBarChart::CChartDatabase::Close()
{
if (m_hstmt != SQL_NULL_HANDLE)
{
SQLFreeHandle(SQL_HANDLE_STMT, m_hstmt);
}
if (m_hDbConn != SQL_NULL_HANDLE)
{
SQLDisconnect(m_hDbConn);
SQLFreeHandle(SQL_HANDLE_DBC, m_hDbConn);
}
if (m_hOdbcEnv != SQL_NULL_HANDLE)
{
SQLFreeHandle(SQL_HANDLE_ENV, m_hOdbcEnv);
}
}
CString CBarChart::CChartDatabase::GetLastErrorMessage()
{
return m_szError;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -