// GridURLCell.cpp: implementation of the CGridURLCell class. // ////////////////////////////////////////////////////////////////////// #include "stdafx.h" #include "GridURLCell.h" #include "GridCtrl.h" IMPLEMENT_DYNCREATE(CGridURLCell, CGridCell) #ifndef _WIN32_WCE HCURSOR CGridURLCell::g_hLinkCursor = NULL; #endif // Possible prefixes that indicate a hyperlink URLStruct CGridURLCell::g_szURIprefixes[] = { { _T("www."), _tcslen(_T("www.")) }, { _T("http:"), _tcslen(_T("http:")) }, { _T("mailto:"), _tcslen(_T("mailto:")) }, { _T("ftp:"), _tcslen(_T("ftp:")) }, { _T("https:"), _tcslen(_T("https:")) }, { _T("news:"), _tcslen(_T("news:")) }, { _T("gopher:"), _tcslen(_T("gopher:")) }, { _T("telnet:"), _tcslen(_T("telnet:")) }, { _T("url:"), _tcslen(_T("url:")) }, { _T("file:"), _tcslen(_T("file:")) }, { _T("ftp."), _tcslen(_T("ftp.")) } }; ////////////////////////////////////////////////////////////////////// // Construction/Destruction ////////////////////////////////////////////////////////////////////// CGridURLCell::CGridURLCell() { #ifndef _WIN32_WCE g_hLinkCursor = GetHandCursor(); #endif m_bLaunchUrl = TRUE; m_clrUrl = GetSysColor(COLOR_HIGHLIGHT); } CGridURLCell::~CGridURLCell() { } BOOL CGridURLCell::Draw(CDC* pDC, int nRow, int nCol, CRect rect, BOOL bEraseBkgnd) { // If url is present then change text color if (HasUrl(GetText())) SetTextClr(m_clrUrl); // Good a place as any to store the bounds of the rect m_Rect = rect; return CGridCell::Draw(pDC, nRow, nCol, rect, bEraseBkgnd); } #pragma warning(disable:4100) BOOL CGridURLCell::Edit(int nRow, int nCol, CRect rect, CPoint point, UINT nID, UINT nChar) { return FALSE; } #pragma warning(default:4100) void CGridURLCell::OnClick(CPoint PointCellRelative) { #ifndef _WIN32_WCE CString strURL; if (GetAutoLaunchUrl() && OverURL(PointCellRelative, strURL)) ShellExecute(NULL, _T("open"), strURL, NULL,NULL, SW_SHOW); #endif } // Return TRUE if you set the cursor BOOL CGridURLCell::OnSetCursor() { #ifndef _WIN32_WCE CString strURL; CPoint pt(GetMessagePos()); GetGrid()->ScreenToClient(&pt); pt = pt - m_Rect.TopLeft(); if (OverURL(pt, strURL)) { SetCursor(g_hLinkCursor); return TRUE; } else #endif return CGridCell::OnSetCursor(); } #ifndef _WIN32_WCE HCURSOR CGridURLCell::GetHandCursor() { if (g_hLinkCursor == NULL) // No cursor handle - load our own { // Get the windows directory CString strWndDir; GetWindowsDirectory(strWndDir.GetBuffer(MAX_PATH), MAX_PATH); strWndDir.ReleaseBuffer(); strWndDir += _T("\\winhlp32.exe"); // This retrieves cursor #106 from winhlp32.exe, which is a hand pointer HMODULE hModule = LoadLibrary(strWndDir); if( hModule ) { HCURSOR hHandCursor = ::LoadCursor(hModule, MAKEINTRESOURCE(106)); if( hHandCursor ) { g_hLinkCursor = CopyCursor(hHandCursor); } } FreeLibrary(hModule); } return g_hLinkCursor; } #endif //////////////////////////////////////////////////////////////////////////////////////////// // Helper functions BOOL CGridURLCell::HasUrl(CString str) { int nNumPrefixes = sizeof(g_szURIprefixes) / sizeof(g_szURIprefixes[0]); for (int i = 0; i < nNumPrefixes; i++) //if (str.Left(g_szURIprefixes[i].nLength) == g_szURIprefixes[i].szURLPrefix) if (str.Find(g_szURIprefixes[i].szURLPrefix) >= 0) return TRUE; return FALSE; } // here we figure out if we are over a URL or not BOOL CGridURLCell::OverURL(CPoint& pt, CString& strURL) { //TRACE2("Checking point %d,%d\n",pt.x,pt.y); BOOL bOverURL = FALSE; CSize size = GetTextExtent(GetText()); // Add left of cell so we know if we clicked on text or not pt.x += m_Rect.left; CPoint center = m_Rect.CenterPoint(); if ((m_nFormat & DT_RIGHT) && pt.x >= (m_Rect.right - size.cx)) { bOverURL = TRUE; } else if ((m_nFormat & DT_CENTER) && ((center.x - (size.cx/2)) <= pt.x) && (pt.x <= (center.x + (size.cx/2))) ) { bOverURL = TRUE; } else if (pt.x <= (size.cx + m_Rect.left)) { bOverURL = TRUE; } if (!bOverURL) return FALSE; // We are over text - but are we over a URL? bOverURL = FALSE; strURL = GetText(); // Use float, otherwise we get an incorrect letter from the point float width = (float)size.cx/(float)strURL.GetLength(); // remove left of cell so we have original point again pt.x -= m_Rect.left; if (m_nFormat & DT_RIGHT) { int wide = m_Rect.Width() - size.cx; pt.x -= wide; if (pt.x <= 0) return FALSE; } if (m_nFormat & DT_CENTER) { int wide = m_Rect.Width() - size.cx; pt.x -= (wide/2); if (pt.x <= 0 || pt.x > (size.cx + (wide/2))) return FALSE; } // Turn point into a letter int ltrs = (int)((float)pt.x/width); #if !defined(_WIN32_WCE) || (_WIN32_WCE > 210) // Find spaces before and after letter, process text between int endSpace = strURL.Find(_T(' '), ltrs); if (endSpace != -1) strURL.Delete(endSpace, strURL.GetLength()-endSpace); int beginSpace = strURL.ReverseFind(_T(' ')); if (beginSpace != -1) strURL.Delete(0, ++beginSpace); #endif // Does text have url return HasUrl(strURL); }