Update of /cvsroot/perl-win32-gui/Win32-GUI-Grid/MFCGrid In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv15861/MFCGrid Added Files: CellRange.h GridCell.cpp GridCell.h GridCellBase.cpp GridCellBase.h GridCellCheck.cpp GridCellCheck.h GridCellCombo.cpp GridCellCombo.h GridCellDateTime.cpp GridCellDateTime.h GridCellNumeric.cpp GridCellNumeric.h GridCellURL.cpp GridCellURL.h GridCtrl.cpp GridCtrl.h GridDropTarget.cpp GridDropTarget.h InPlaceEdit.cpp InPlaceEdit.h Makefile MemDC.h StdAfx.cpp StdAfx.h TitleTip.cpp TitleTip.h Log Message: Added to repository --- NEW FILE: InPlaceEdit.h --- ////////////////////////////////////////////////////////////////////// // InPlaceEdit.h : header file // // MFC Grid Control - inplace editing class // // Written by Chris Maunder <cma...@ma...> // Copyright (c) 1998-2002. All Rights Reserved. // // This code may be used in compiled form in any way you desire. This // file may be redistributed unmodified by any means PROVIDING it is // not sold for profit without the authors written consent, and // providing that this notice and the authors name and all copyright // notices remains intact. // // An email letting me know how you are using it would be nice as well. // // This file is provided "as is" with no expressed or implied warranty. // The author accepts no liability for any damage/loss of business that // this product may cause. // // For use with CGridCtrl v2.10+ // ////////////////////////////////////////////////////////////////////// #if !defined(AFX_INPLACEEDIT_H__ECD42821_16DF_11D1_992F_895E185F9C72__INCLUDED_) #define AFX_INPLACEEDIT_H__ECD42821_16DF_11D1_992F_895E185F9C72__INCLUDED_ #if _MSC_VER >= 1000 #pragma once #endif // _MSC_VER >= 1000 class CInPlaceEdit : public CEdit { // Construction public: CInPlaceEdit(CWnd* pParent, CRect& rect, DWORD dwStyle, UINT nID, int nRow, int nColumn, CString sInitText, UINT nFirstChar); // Attributes public: // Operations public: void EndEdit(); // Overrides // ClassWizard generated virtual function overrides //{{AFX_VIRTUAL(CInPlaceEdit) public: virtual BOOL PreTranslateMessage(MSG* pMsg); protected: virtual void PostNcDestroy(); //}}AFX_VIRTUAL // Implementation public: virtual ~CInPlaceEdit(); // Generated message map functions protected: //{{AFX_MSG(CInPlaceEdit) afx_msg void OnKillFocus(CWnd* pNewWnd); afx_msg void OnChar(UINT nChar, UINT nRepCnt, UINT nFlags); afx_msg void OnKeyDown(UINT nChar, UINT nRepCnt, UINT nFlags); afx_msg UINT OnGetDlgCode(); //}}AFX_MSG DECLARE_MESSAGE_MAP() private: int m_nRow; int m_nColumn; CString m_sInitText; UINT m_nLastChar; BOOL m_bExitOnArrows; CRect m_Rect; }; ///////////////////////////////////////////////////////////////////////////// //{{AFX_INSERT_LOCATION}} // Microsoft Developer Studio will insert additional declarations immediately before the previous line. #endif // !defined(AFX_INPLACEEDIT_H__ECD42821_16DF_11D1_992F_895E185F9C72__INCLUDED_) --- NEW FILE: GridCellCheck.cpp --- // GridCellCheck.cpp : implementation file // // MFC Grid Control - Main grid cell class // // Provides the implementation for a combobox cell type of the // grid control. // // Written by Chris Maunder <cma...@ma...> // Copyright (c) 1998-2002. All Rights Reserved. // // Parts of the code contained in this file are based on the original // CInPlaceList from http://www.codeguru.com/listview // // This code may be used in compiled form in any way you desire. This // file may be redistributed unmodified by any means PROVIDING it is // not sold for profit without the authors written consent, and // providing that this notice and the authors name and all copyright // notices remains intact. // // An email letting me know how you are using it would be nice as well. // // This file is provided "as is" with no expressed or implied warranty. // The author accepts no liability for any damage/loss of business that // this product may cause. // // For use with CGridCtrl v2.22+ // // History: // 23 Jul 2001 - Complete rewrite // ///////////////////////////////////////////////////////////////////////////// #include "StdAfx.h" #include "GridCell.h" #include "GridCtrl.h" #include "GridCellCheck.h" #ifdef _DEBUG #define new DEBUG_NEW #undef THIS_FILE static char THIS_FILE[] = __FILE__; #endif IMPLEMENT_DYNCREATE(CGridCellCheck, CGridCell) CGridCellCheck::CGridCellCheck() : CGridCell() { m_bChecked = FALSE; //m_Rect.IsRectNull(); } CSize CGridCellCheck::GetCellExtent(CDC* pDC) { // Using SM_CXHSCROLL as a guide to the size of the checkbox int nWidth = GetSystemMetrics(SM_CXHSCROLL) + 2*GetMargin(); // Yogurt $$LR$$ CSize cellSize = CGridCell::GetCellExtent(pDC); cellSize.cx += nWidth; cellSize.cy = max (cellSize.cy, nWidth); return cellSize; } // i/o: i=dims of cell rect; o=dims of text rect BOOL CGridCellCheck::GetTextRect( LPRECT pRect) { BOOL bResult = CGridCell::GetTextRect(pRect); if (bResult) { int nWidth = GetSystemMetrics(SM_CXHSCROLL) + 2*GetMargin(); pRect->left += nWidth; if (pRect->left > pRect->right) pRect->left = pRect->right; } return bResult; } // Override draw so that when the cell is selected, a drop arrow is shown in the RHS. BOOL CGridCellCheck::Draw(CDC* pDC, int nRow, int nCol, CRect rect, BOOL bEraseBkgnd /*=TRUE*/) { BOOL bResult = CGridCell::Draw(pDC, nRow, nCol, rect, bEraseBkgnd); #ifndef _WIN32_WCE // Store the cell's dimensions for later m_Rect = rect; CRect CheckRect = GetCheckPlacement(); rect.left = CheckRect.right; // enough room to draw? // if (CheckRect.Width() < rect.Width() && CheckRect.Height() < rect.Height()) { // Do the draw pDC->DrawFrameControl(GetCheckPlacement(), DFC_BUTTON, (m_bChecked)? DFCS_BUTTONCHECK | DFCS_CHECKED : DFCS_BUTTONCHECK); // } #endif return bResult; } void CGridCellCheck::OnClick(CPoint PointCellRelative) { // PointCellRelative is relative to the topleft of the cell. Convert to client coords PointCellRelative += m_Rect.TopLeft(); CCellID cell = GetGrid()->GetCellFromPt (PointCellRelative); if (!GetGrid()->IsCellEditable (cell)) return; // GetCheckPlacement returns the checkbox dimensions in client coords. Only check/ // uncheck if the user clicked in the box if (GetCheckPlacement().PtInRect(PointCellRelative)) { m_bChecked = !m_bChecked; GetGrid()->InvalidateRect(m_Rect); } } ////////////////////////////////////////////////////////////////////// // Operations ////////////////////////////////////////////////////////////////////// BOOL CGridCellCheck::SetCheck(BOOL bChecked /*=TRUE*/) { BOOL bTemp = m_bChecked; m_bChecked = bChecked; if (!m_Rect.IsRectEmpty()) GetGrid()->InvalidateRect(m_Rect); return bTemp; } BOOL CGridCellCheck::GetCheck() { return m_bChecked; } ////////////////////////////////////////////////////////////////////// // Protected implementation ////////////////////////////////////////////////////////////////////// // Returns the dimensions and placement of the checkbox in client coords. CRect CGridCellCheck::GetCheckPlacement() { int nWidth = GetSystemMetrics(SM_CXHSCROLL); CRect place = m_Rect + CSize(GetMargin(), GetMargin()); place.right = place.left + nWidth; place.bottom = place.top + nWidth; /* for centering int nDiff = (place.Width() - nWidth)/2; if (nDiff > 0) { place.left += nDiff; place.right = place.left + nWidth; } nDiff = (place.Height() - nWidth)/2; if (nDiff > 0) { place.top += nDiff; place.bottom = place.top + nWidth; } */ // Yogurt $$LR$$ if (m_Rect.Height() < nWidth + 2 * (int)GetMargin() ) { place.top = m_Rect.top + (m_Rect.Height() - nWidth) / 2; place.bottom = place.top + nWidth; } return place; } --- NEW FILE: GridCell.cpp --- // GridCell.cpp : implementation file // // MFC Grid Control - Main grid cell class // // Provides the implementation for the "default" cell type of the // grid control. Adds in cell editing. // // Written by Chris Maunder <cma...@ma...> // Copyright (c) 1998-2002. All Rights Reserved. // // This code may be used in compiled form in any way you desire. This // file may be redistributed unmodified by any means PROVIDING it is // not sold for profit without the authors written consent, and // providing that this notice and the authors name and all copyright // notices remains intact. // // An email letting me know how you are using it would be nice as well. // // This file is provided "as is" with no expressed or implied warranty. // The author accepts no liability for any damage/loss of business that // this product may cause. // // For use with CGridCtrl v2.20+ // // History: // Eric Woodruff - 20 Feb 2000 - Added PrintCell() plus other minor changes // Ken Bertelson - 12 Apr 2000 - Split CGridCell into CGridCell and CGridCellBase // <ken...@ho...> // C Maunder - 17 Jun 2000 - Font handling optimsed, Added CGridDefaultCell // ///////////////////////////////////////////////////////////////////////////// #include "stdafx.h" #include "GridCell.h" #include "InPlaceEdit.h" #include "GridCtrl.h" #ifdef _DEBUG #define new DEBUG_NEW #undef THIS_FILE static char THIS_FILE[] = __FILE__; #endif IMPLEMENT_DYNCREATE(CGridCell, CGridCellBase) IMPLEMENT_DYNCREATE(CGridDefaultCell, CGridCell) ///////////////////////////////////////////////////////////////////////////// // GridCell CGridCell::CGridCell() { m_plfFont = NULL; CGridCell::Reset(); } CGridCell::~CGridCell() { delete m_plfFont; } ///////////////////////////////////////////////////////////////////////////// // GridCell Attributes void CGridCell::operator=(const CGridCell& cell) { if (this != &cell) CGridCellBase::operator=(cell); } void CGridCell::Reset() { CGridCellBase::Reset(); m_strText.Empty(); m_nImage = -1; m_lParam = NULL; // BUG FIX J. Bloggs 20/10/03 m_pGrid = NULL; m_bEditing = FALSE; m_pEditWnd = NULL; m_nFormat = (DWORD)-1; // Use default from CGridDefaultCell m_crBkClr = CLR_DEFAULT; // Background colour (or CLR_DEFAULT) m_crFgClr = CLR_DEFAULT; // Forground colour (or CLR_DEFAULT) m_nMargin = (UINT)-1; // Use default from CGridDefaultCell delete m_plfFont; m_plfFont = NULL; // Cell font } void CGridCell::SetFont(const LOGFONT* plf) { if (plf == NULL) { delete m_plfFont; m_plfFont = NULL; } else { if (!m_plfFont) m_plfFont = new LOGFONT; if (m_plfFont) memcpy(m_plfFont, plf, sizeof(LOGFONT)); } } LOGFONT* CGridCell::GetFont() const { if (m_plfFont == NULL) { CGridDefaultCell *pDefaultCell = (CGridDefaultCell*) GetDefaultCell(); if (!pDefaultCell) return NULL; return pDefaultCell->GetFont(); } return m_plfFont; } CFont* CGridCell::GetFontObject() const { // If the default font is specified, use the default cell implementation if (m_plfFont == NULL) { CGridDefaultCell *pDefaultCell = (CGridDefaultCell*) GetDefaultCell(); if (!pDefaultCell) return NULL; return pDefaultCell->GetFontObject(); } else { static CFont Font; Font.DeleteObject(); Font.CreateFontIndirect(m_plfFont); return &Font; } } DWORD CGridCell::GetFormat() const { if (m_nFormat == (DWORD)-1) { CGridDefaultCell *pDefaultCell = (CGridDefaultCell*) GetDefaultCell(); if (!pDefaultCell) return 0; return pDefaultCell->GetFormat(); } return m_nFormat; } UINT CGridCell::GetMargin() const { if (m_nMargin == (UINT)-1) { CGridDefaultCell *pDefaultCell = (CGridDefaultCell*) GetDefaultCell(); if (!pDefaultCell) return 0; return pDefaultCell->GetMargin(); } return m_nMargin; } ///////////////////////////////////////////////////////////////////////////// // GridCell Operations BOOL CGridCell::Edit(int nRow, int nCol, CRect rect, CPoint /* point */, UINT nID, UINT nChar) { if ( m_bEditing ) { if (m_pEditWnd) m_pEditWnd->SendMessage ( WM_CHAR, nChar ); } else { DWORD dwStyle = ES_LEFT; if (GetFormat() & DT_RIGHT) dwStyle = ES_RIGHT; else if (GetFormat() & DT_CENTER) dwStyle = ES_CENTER; m_bEditing = TRUE; // InPlaceEdit auto-deletes itself CGridCtrl* pGrid = GetGrid(); m_pEditWnd = new CInPlaceEdit(pGrid, rect, dwStyle, nID, nRow, nCol, GetText(), nChar); } return TRUE; } void CGridCell::EndEdit() { if (m_pEditWnd) ((CInPlaceEdit*)m_pEditWnd)->EndEdit(); } void CGridCell::OnEndEdit() { m_bEditing = FALSE; m_pEditWnd = NULL; } ///////////////////////////////////////////////////////////////////////////// // CGridDefaultCell CGridDefaultCell::CGridDefaultCell() { #ifdef _WIN32_WCE m_nFormat = DT_LEFT|DT_VCENTER|DT_SINGLELINE|DT_NOPREFIX; #else m_nFormat = DT_LEFT|DT_VCENTER|DT_SINGLELINE|DT_NOPREFIX | DT_END_ELLIPSIS; #endif m_crFgClr = CLR_DEFAULT; m_crBkClr = CLR_DEFAULT; m_Size = CSize(30,10); m_dwStyle = 0; #ifdef _WIN32_WCE LOGFONT lf; GetObject(GetStockObject(SYSTEM_FONT), sizeof(LOGFONT), &lf); SetFont(&lf); #else // not CE NONCLIENTMETRICS ncm; ncm.cbSize = sizeof(NONCLIENTMETRICS); VERIFY(SystemParametersInfo(SPI_GETNONCLIENTMETRICS, sizeof(NONCLIENTMETRICS), &ncm, 0)); SetFont(&(ncm.lfMessageFont)); #endif } CGridDefaultCell::~CGridDefaultCell() { m_Font.DeleteObject(); } void CGridDefaultCell::SetFont(const LOGFONT* plf) { ASSERT(plf); if (!plf) return; m_Font.DeleteObject(); m_Font.CreateFontIndirect(plf); CGridCell::SetFont(plf); // Get the font size and hence the default cell size CDC* pDC = CDC::FromHandle(::GetDC(NULL)); if (pDC) { CFont* pOldFont = pDC->SelectObject(&m_Font); SetMargin(pDC->GetTextExtent(_T(" "), 1).cx); m_Size = pDC->GetTextExtent(_T(" XXXXXXXXXXXX "), 14); m_Size.cy = (m_Size.cy * 3) / 2; pDC->SelectObject(pOldFont); ReleaseDC(NULL, pDC->GetSafeHdc()); } else { SetMargin(3); m_Size = CSize(40,16); } } LOGFONT* CGridDefaultCell::GetFont() const { ASSERT(m_plfFont); // This is the default - it CAN'T be NULL! return m_plfFont; } CFont* CGridDefaultCell::GetFontObject() const { ASSERT(m_Font.GetSafeHandle()); return (CFont*) &m_Font; } --- NEW FILE: Makefile --- # Microsoft Developer Studio Generated NMAKE File, Based on MFCGrid.dsp !IF "$(OS)" == "Windows_NT" NULL= !ELSE NULL=nul !ENDIF CPP=cl.exe RSC=rc.exe OUTDIR=.\Lib INTDIR=.\Build # Begin Custom Macros OutDir=.\Lib # End Custom Macros ALL : "$(OUTDIR)\MFCGrid.lib" CLEAN : -@erase "$(INTDIR)\GridCellUrl.obj" -@erase "$(INTDIR)\GridCellNumeric.obj" -@erase "$(INTDIR)\GridCellDateTime.obj" -@erase "$(INTDIR)\GridCellCheck.obj" -@erase "$(INTDIR)\GridCellCombo.obj" -@erase "$(INTDIR)\GridCell.obj" -@erase "$(INTDIR)\GridCellBase.obj" -@erase "$(INTDIR)\GridCtrl.obj" -@erase "$(INTDIR)\GridDropTarget.obj" -@erase "$(INTDIR)\InPlaceEdit.obj" -@erase "$(INTDIR)\StdAfx.obj" -@erase "$(INTDIR)\TitleTip.obj" -@erase "$(INTDIR)\vc60.idb" -@erase "$(INTDIR)\MFCGrid.pch" -@erase "$(OUTDIR)\MFCGrid.lib" "$(OUTDIR)" : mkdir "$(OUTDIR)" "$(INTDIR)" : mkdir "$(INTDIR)" CPP=cl.exe CPP_PROJ=/nologo /MD /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D"_WINDLL" /D"_USRDLL" /D "_AFXDLL" /D "_AFX_NOFORCE_LIBS" /Fo"$(INTDIR)\\" /Fd"$(INTDIR)\\" /FD /c BSC32=bscmake.exe BSC32_FLAGS=/nologo /o"$(OUTDIR)\MFCGrid.bsc" BSC32_SBRS= \ LIB32=link.exe -lib LIB32_FLAGS=/nologo /out:"$(OUTDIR)\MFCGrid.lib" LIB32_OBJS= \ "$(INTDIR)\TitleTip.obj" \ "$(INTDIR)\InPlaceEdit.obj" \ "$(INTDIR)\GridDropTarget.obj" \ "$(INTDIR)\GridCtrl.obj" \ "$(INTDIR)\GridCellBase.obj" \ "$(INTDIR)\GridCell.obj" \ "$(INTDIR)\GridCellNumeric.obj" \ "$(INTDIR)\GridCellUrl.obj" \ "$(INTDIR)\GridCellDateTime.obj" \ "$(INTDIR)\GridCellCheck.obj" \ "$(INTDIR)\GridCellCombo.obj" \ "$(INTDIR)\StdAfx.obj" "$(OUTDIR)\MFCGrid.lib" : "$(OUTDIR)" "$(INTDIR)" $(DEF_FILE) $(LIB32_OBJS) $(LIB32) @<< $(LIB32_FLAGS) $(DEF_FLAGS) $(LIB32_OBJS) << .c{$(INTDIR)}.obj:: $(CPP) @<< $(CPP_PROJ) $< << .cpp{$(INTDIR)}.obj:: $(CPP) @<< $(CPP_PROJ) $< << .cxx{$(INTDIR)}.obj:: $(CPP) @<< $(CPP_PROJ) $< << .c{$(INTDIR)}.sbr:: $(CPP) @<< $(CPP_PROJ) $< << .cpp{$(INTDIR)}.sbr:: $(CPP) @<< $(CPP_PROJ) $< << .cxx{$(INTDIR)}.sbr:: $(CPP) @<< $(CPP_PROJ) $< << GridCell.cpp : \ "CellRange.h"\ "GridCell.h"\ "GridCellBase.h"\ "GridCtrl.h"\ "GridDropTarget.h"\ "InPlaceEdit.h"\ "StdAfx.h"\ "TitleTip.h" GridCellBase.cpp : \ "CellRange.h"\ "GridCell.h"\ "GridCellBase.h"\ "GridCtrl.h"\ "GridDropTarget.h"\ "StdAfx.h"\ "TitleTip.h" GridCtrl.cpp : \ "CellRange.h"\ "GridCell.h"\ "GridCellBase.h"\ "GridCtrl.h"\ "GridDropTarget.h"\ "MemDC.h"\ "StdAfx.h"\ "TitleTip.h" GridDropTarget.cpp : \ "CellRange.h"\ "GridCell.h"\ "GridCellBase.h"\ "GridCtrl.h"\ "GridDropTarget.h"\ "StdAfx.h"\ "TitleTip.h" InPlaceEdit.cpp : \ "CellRange.h"\ "GridCell.h"\ "GridCellBase.h"\ "GridCtrl.h"\ "GridDropTarget.h"\ "InPlaceEdit.h"\ "StdAfx.h"\ "TitleTip.h" StdAfx.cpp : \ "StdAfx.h" TitleTip.cpp : \ "CellRange.h"\ "GridCell.h"\ "GridCellBase.h"\ "GridCtrl.h"\ "GridDropTarget.h"\ "StdAfx.h"\ "TitleTip.h" GridCellNumeric.cpp : \ "GridCell.h"\ "GridCellBase.h"\ "GridCtrl.h"\ "InPlaceEdit.h"\ "StdAfx.h" GridCellDateTime.cpp : \ "GridCell.h"\ "GridCellBase.h"\ "GridCtrl.h"\ "StdAfx.h" GridCellCheck.cpp : \ "GridCellCheck.h"\ "GridCell.h"\ "GridCellBase.h"\ "GridCtrl.h"\ "StdAfx.h" GridCellCombo.cpp : \ "GridCellCombo.h"\ "GridCell.h"\ "GridCellBase.h"\ "GridCtrl.h"\ "StdAfx.h" GridCellUrl.cpp : \ "GridCellUrl.h"\ "GridCell.h"\ "GridCellBase.h"\ "GridCtrl.h"\ "StdAfx.h" SOURCE=GridCell.cpp "$(INTDIR)\GridCell.obj" : $(SOURCE) "$(INTDIR)" $(CPP) $(CPP_PROJ) $(SOURCE) SOURCE=GridCellBase.cpp "$(INTDIR)\GridCellBase.obj" : $(SOURCE) "$(INTDIR)" $(CPP) $(CPP_PROJ) $(SOURCE) SOURCE=GridCtrl.cpp "$(INTDIR)\GridCtrl.obj" : $(SOURCE) "$(INTDIR)" $(CPP) $(CPP_PROJ) $(SOURCE) SOURCE=GridDropTarget.cpp "$(INTDIR)\GridDropTarget.obj" : $(SOURCE) "$(INTDIR)" $(CPP) $(CPP_PROJ) $(SOURCE) SOURCE=InPlaceEdit.cpp "$(INTDIR)\InPlaceEdit.obj" : $(SOURCE) "$(INTDIR)" $(CPP) $(CPP_PROJ) $(SOURCE) SOURCE=StdAfx.cpp "$(INTDIR)\StdAfx.obj" : $(SOURCE) "$(INTDIR)" $(CPP) $(CPP_PROJ) $(SOURCE) SOURCE=TitleTip.cpp "$(INTDIR)\TitleTip.obj" : $(SOURCE) "$(INTDIR)" $(CPP) $(CPP_PROJ) $(SOURCE) SOURCE=GridCellNumeric.cpp "$(INTDIR)\GridCellNumeric.obj" : $(SOURCE) "$(INTDIR)" $(CPP) $(CPP_PROJ) $(SOURCE) SOURCE=GridCellDateTime.cpp "$(INTDIR)\GridCellDateTime.obj" : $(SOURCE) "$(INTDIR)" $(CPP) $(CPP_PROJ) $(SOURCE) SOURCE=GridCellCheck.cpp "$(INTDIR)\GridCellCheck.obj" : $(SOURCE) "$(INTDIR)" $(CPP) $(CPP_PROJ) $(SOURCE) SOURCE=GridCellCombo.cpp "$(INTDIR)\GridCellCombo.obj" : $(SOURCE) "$(INTDIR)" $(CPP) $(CPP_PROJ) $(SOURCE) SOURCE=GridCellUrl.cpp "$(INTDIR)\GridCellUrl.obj" : $(SOURCE) "$(INTDIR)" $(CPP) $(CPP_PROJ) $(SOURCE) --- NEW FILE: GridCellCombo.h --- #if !defined(AFX_GRIDCELLCOMBO_H__ECD42822_16DF_11D1_992F_895E185F9C72__INCLUDED_) #define AFX_GRIDCELLCOMBO_H__ECD42822_16DF_11D1_992F_895E185F9C72__INCLUDED_ #if _MSC_VER >= 1000 #pragma once #endif // _MSC_VER >= 1000 ///////////////////////////////////////////////////////////////////////////// // GridCellCombo.h : header file // // MFC Grid Control - Grid combo cell class header file // // Written by Chris Maunder <cma...@ma...> // Copyright (c) 1998-2002. All Rights Reserved. // // This code may be used in compiled form in any way you desire. This // file may be redistributed unmodified by any means PROVIDING it is // not sold for profit without the authors written consent, and // providing that this notice and the authors name and all copyright // notices remains intact. // // An email letting me know how you are using it would be nice as well. // // This file is provided "as is" with no expressed or implied warranty. // The author accepts no liability for any damage/loss of business that // this product may cause. // // For use with CGridCtrl v2.10 // ////////////////////////////////////////////////////////////////////// #include "GridCell.h" class CGridCellCombo : public CGridCell { friend class CGridCtrl; DECLARE_DYNCREATE(CGridCellCombo) public: CGridCellCombo(); // editing cells public: virtual BOOL Edit(int nRow, int nCol, CRect rect, CPoint point, UINT nID, UINT nChar); virtual CWnd* GetEditWnd() const; virtual void EndEdit(); // Operations public: virtual CSize GetCellExtent(CDC* pDC); // CGridCellCombo specific calls public: void SetOptions(const CStringArray& ar); void SetStyle(DWORD dwStyle) { m_dwStyle = dwStyle; } DWORD GetStyle() { return m_dwStyle; } protected: virtual BOOL Draw(CDC* pDC, int nRow, int nCol, CRect rect, BOOL bEraseBkgnd = TRUE); CStringArray m_Strings; DWORD m_dwStyle; }; class CGridCellList : public CGridCellCombo { DECLARE_DYNCREATE(CGridCellList) public: CGridCellList(); }; ///////////////////////////////////////////////////////////////////////////// // CComboEdit window #define IDC_COMBOEDIT 1001 class CComboEdit : public CEdit { // Construction public: CComboEdit(); // Attributes public: // Operations public: // Overrides // ClassWizard generated virtual function overrides //{{AFX_VIRTUAL(CComboEdit) virtual BOOL PreTranslateMessage(MSG* pMsg); //}}AFX_VIRTUAL // Implementation public: virtual ~CComboEdit(); // Generated message map functions protected: //{{AFX_MSG(CComboEdit) afx_msg void OnKillFocus(CWnd* pNewWnd); afx_msg void OnKeyDown(UINT nChar, UINT nRepCnt, UINT nFlags); afx_msg void OnKeyUp(UINT nChar, UINT nRepCnt, UINT nFlags); //}}AFX_MSG DECLARE_MESSAGE_MAP() }; ///////////////////////////////////////////////////////////////////////////// // CInPlaceList window class CInPlaceList : public CComboBox { friend class CComboEdit; // Construction public: CInPlaceList(CWnd* pParent, // parent CRect& rect, // dimensions & location DWORD dwStyle, // window/combobox style UINT nID, // control ID int nRow, int nColumn, // row and column COLORREF crFore, COLORREF crBack, // Foreground, background colour CStringArray& Items, // Items in list CString sInitText, // initial selection UINT nFirstChar); // first character to pass to control // Attributes public: CComboEdit m_edit; // subclassed edit control // Operations public: // Overrides // ClassWizard generated virtual function overrides //{{AFX_VIRTUAL(CInPlaceList) protected: virtual void PostNcDestroy(); //}}AFX_VIRTUAL // Implementation public: virtual ~CInPlaceList(); void EndEdit(); protected: int GetCorrectDropWidth(); // Generated message map functions protected: //{{AFX_MSG(CInPlaceList) afx_msg void OnKillFocus(CWnd* pNewWnd); afx_msg void OnKeyDown(UINT nChar, UINT nRepCnt, UINT nFlags); afx_msg void OnKeyUp(UINT nChar, UINT nRepCnt, UINT nFlags); afx_msg void OnDropdown(); afx_msg void OnSelChange(); afx_msg UINT OnGetDlgCode(); afx_msg HBRUSH CtlColor(CDC* pDC, UINT nCtlColor); //}}AFX_MSG //afx_msg void OnSelendOK(); DECLARE_MESSAGE_MAP() private: int m_nNumLines; CString m_sInitText; int m_nRow; int m_nCol; UINT m_nLastChar; BOOL m_bExitOnArrows; COLORREF m_crForeClr, m_crBackClr; }; ///////////////////////////////////////////////////////////////////////////// //{{AFX_INSERT_LOCATION}} // Microsoft Developer Studio will insert additional declarations immediately before the previous line. #endif // !defined(AFX_GRIDCELLCOMBO_H__ECD42822_16DF_11D1_992F_895E185F9C72__INCLUDED_) --- NEW FILE: GridCellURL.h --- // GridCellURL.h: interface for the CGridCellURL class. // ////////////////////////////////////////////////////////////////////// #if !defined(AFX_GridCellURL_H__9F4A50B4_D773_11D3_A439_F7E60631F563__INCLUDED_) #define AFX_GridCellURL_H__9F4A50B4_D773_11D3_A439_F7E60631F563__INCLUDED_ #if _MSC_VER > 1000 #pragma once #endif // _MSC_VER > 1000 #include "GridCell.h" typedef struct { LPCTSTR szURLPrefix; int nLength; } URLStruct; class CGridCellURL : public CGridCell { DECLARE_DYNCREATE(CGridCellURL) public: CGridCellURL(); virtual ~CGridCellURL(); virtual BOOL Draw(CDC* pDC, int nRow, int nCol, CRect rect, BOOL bEraseBkgnd = TRUE); // virtual BOOL Edit(int nRow, int nCol, CRect rect, CPoint point, UINT nID, UINT nChar); virtual LPCTSTR GetTipText() { return NULL; } void SetAutoLaunchUrl(BOOL bLaunch = TRUE) { m_bLaunchUrl = bLaunch; } BOOL GetAutoLaunchUrl() { return m_bLaunchUrl && !m_bEditing; } protected: virtual BOOL OnSetCursor(); virtual void OnClick(CPoint PointCellRelative); BOOL HasUrl(CString str); BOOL OverURL(CPoint& pt, CString& strURL); protected: #ifndef _WIN32_WCE static HCURSOR g_hLinkCursor; // Hyperlink mouse cursor HCURSOR GetHandCursor(); #endif static URLStruct g_szURIprefixes[]; protected: COLORREF m_clrUrl; COLORREF m_clrOld; BOOL m_bLaunchUrl; CRect m_Rect; }; #endif // !defined(AFX_GridCellURL_H__9F4A50B4_D773_11D3_A439_F7E60631F563__INCLUDED_) --- NEW FILE: GridCellDateTime.h --- // GridCellDateTime.h: interface for the CGridCellDateTime class. // // Provides the implementation for a datetime picker cell type of the // grid control. // // For use with CGridCtrl v2.22+ // ////////////////////////////////////////////////////////////////////// #if !defined(AFX_DATETIMECELL_H__A0B7DA0A_0AFE_4D28_A00E_846C96D7507A__INCLUDED_) #define AFX_DATETIMECELL_H__A0B7DA0A_0AFE_4D28_A00E_846C96D7507A__INCLUDED_ #if _MSC_VER > 1000 #pragma once #endif // _MSC_VER > 1000 #include "GridCell.h" #include "afxdtctl.h" // for CDateTimeCtrl class CGridCellDateTime : public CGridCell { friend class CGridCtrl; DECLARE_DYNCREATE(CGridCellDateTime) CTime m_cTime; DWORD m_dwStyle; public: CGridCellDateTime(); CGridCellDateTime(DWORD dwStyle); virtual ~CGridCellDateTime(); // editing cells public: void Init(DWORD dwStyle); virtual BOOL Edit(int nRow, int nCol, CRect rect, CPoint point, UINT nID, UINT nChar); virtual CWnd* GetEditWnd() const; virtual void EndEdit(); virtual CSize GetCellExtent(CDC* pDC); CTime* GetTime() {return &m_cTime;}; void SetTime(CTime time); }; class CInPlaceDateTime : public CDateTimeCtrl { // Construction public: CInPlaceDateTime(CWnd* pParent, // parent CRect& rect, // dimensions & location DWORD dwStyle, // window/combobox style UINT nID, // control ID int nRow, int nColumn, // row and column COLORREF crFore, COLORREF crBack, // Foreground, background colour CTime* pcTime, UINT nFirstChar); // first character to pass to control // Overrides // ClassWizard generated virtual function overrides //{{AFX_VIRTUAL(CInPlaceList) protected: virtual void PostNcDestroy(); //}}AFX_VIRTUAL // Implementation public: virtual ~CInPlaceDateTime(); void EndEdit(); // Generated message map functions protected: //{{AFX_MSG(CInPlaceList) afx_msg void OnKillFocus(CWnd* pNewWnd); afx_msg void OnKeyDown(UINT nChar, UINT nRepCnt, UINT nFlags); afx_msg void OnKeyUp(UINT nChar, UINT nRepCnt, UINT nFlags); afx_msg UINT OnGetDlgCode(); afx_msg void OnCloseUp ( NMHDR * pNotifyStruct, LRESULT* result ); //}}AFX_MSG //afx_msg void OnSelendOK(); DECLARE_MESSAGE_MAP() private: CTime* m_pcTime; int m_nRow; int m_nCol; UINT m_nLastChar; BOOL m_bExitOnArrows; COLORREF m_crForeClr, m_crBackClr; }; class CGridCellTime : public CGridCellDateTime { CGridCellTime():CGridCellDateTime(DTS_TIMEFORMAT) {} DECLARE_DYNCREATE(CGridCellTime) }; class CGridCellDateCal : public CGridCellDateTime { CGridCellDateCal():CGridCellDateTime() {} virtual BOOL Edit(int nRow, int nCol, CRect rect, CPoint /* point */, UINT nID, UINT nChar); DECLARE_DYNCREATE(CGridCellDateCal) }; #endif // !defined(AFX_DATETIMECELL_H__A0B7DA0A_0AFE_4D28_A00E_846C96D7507A__INCLUDED_) --- NEW FILE: GridCell.h --- ///////////////////////////////////////////////////////////////////////////// // GridCell.h : header file // // MFC Grid Control - Grid cell class header file // // Written by Chris Maunder <cma...@ma...> // Copyright (c) 1998-2002. All Rights Reserved. // // This code may be used in compiled form in any way you desire. This // file may be redistributed unmodified by any means PROVIDING it is // not sold for profit without the authors written consent, and // providing that this notice and the authors name and all copyright // notices remains intact. // // An email letting me know how you are using it would be nice as well. // // This file is provided "as is" with no expressed or implied warranty. // The author accepts no liability for any damage/loss of business that // this product may cause. // // For use with CGridCtrl v2.20+ // ////////////////////////////////////////////////////////////////////// #if !defined(AFX_GRIDCELL_H__519FA702_722C_11D1_ABBA_00A0243D1382__INCLUDED_) #define AFX_GRIDCELL_H__519FA702_722C_11D1_ABBA_00A0243D1382__INCLUDED_ #if _MSC_VER >= 1000 #pragma once #endif // _MSC_VER >= 1000 class CGridCtrl; #include "GridCellBase.h" // Each cell contains one of these. Fields "row" and "column" are not stored since we // will usually have acces to them in other ways, and they are an extra 8 bytes per // cell that is probably unnecessary. class CGridCell : public CGridCellBase { friend class CGridCtrl; DECLARE_DYNCREATE(CGridCell) // Construction/Destruction public: CGridCell(); virtual ~CGridCell(); // Attributes public: void operator=(const CGridCell& cell); virtual void SetText(LPCTSTR szText) { m_strText = szText; } virtual void SetImage(int nImage) { m_nImage = nImage; } virtual void SetData(LPARAM lParam) { m_lParam = lParam; } virtual void SetGrid(CGridCtrl* pGrid) { m_pGrid = pGrid; } // virtual void SetState(const DWORD nState); - use base class version virtual void SetFormat(DWORD nFormat) { m_nFormat = nFormat; } virtual void SetTextClr(COLORREF clr) { m_crFgClr = clr; } virtual void SetBackClr(COLORREF clr) { m_crBkClr = clr; } virtual void SetFont(const LOGFONT* plf); virtual void SetMargin(UINT nMargin) { m_nMargin = nMargin; } virtual CWnd* GetEditWnd() const { return m_pEditWnd; } virtual void SetCoords(int /*nRow*/, int /*nCol*/) {} // don't need to know the row and // column for base implementation virtual LPCTSTR GetText() const { return (m_strText.IsEmpty())? _T("") : LPCTSTR(m_strText); } virtual int GetImage() const { return m_nImage; } virtual LPARAM GetData() const { return m_lParam; } virtual CGridCtrl* GetGrid() const { return m_pGrid; } // virtual DWORD GetState() const - use base class virtual DWORD GetFormat() const; virtual COLORREF GetTextClr() const { return m_crFgClr; } // TODO: change to use default cell virtual COLORREF GetBackClr() const { return m_crBkClr; } virtual LOGFONT* GetFont() const; virtual CFont* GetFontObject() const; virtual UINT GetMargin() const; virtual BOOL IsEditing() const { return m_bEditing; } virtual BOOL IsDefaultFont() const { return (m_plfFont == NULL); } virtual void Reset(); // editing cells public: virtual BOOL Edit(int nRow, int nCol, CRect rect, CPoint point, UINT nID, UINT nChar); virtual void EndEdit(); protected: virtual void OnEndEdit(); protected: CString m_strText; // Cell text (or binary data if you wish...) LPARAM m_lParam; // 32-bit value to associate with item int m_nImage; // Index of the list view items icon DWORD m_nFormat; COLORREF m_crFgClr; COLORREF m_crBkClr; LOGFONT* m_plfFont; UINT m_nMargin; BOOL m_bEditing; // Cell being edited? CGridCtrl* m_pGrid; // Parent grid control CWnd* m_pEditWnd; }; // This class is for storing grid default values. It's a little heavy weight, so // don't use it in bulk class CGridDefaultCell : public CGridCell { DECLARE_DYNCREATE(CGridDefaultCell) // Construction/Destruction public: CGridDefaultCell(); virtual ~CGridDefaultCell(); public: virtual DWORD GetStyle() const { return m_dwStyle; } virtual void SetStyle(DWORD dwStyle) { m_dwStyle = dwStyle; } virtual int GetWidth() const { return m_Size.cx; } virtual int GetHeight() const { return m_Size.cy; } virtual void SetWidth(int nWidth) { m_Size.cx = nWidth; } virtual void SetHeight(int nHeight) { m_Size.cy = nHeight; } // Disable these properties virtual void SetData(LPARAM /*lParam*/) { ASSERT(FALSE); } virtual void SetState(DWORD /*nState*/) { ASSERT(FALSE); } virtual DWORD GetState() const { return CGridCell::GetState()|GVIS_READONLY; } virtual void SetCoords( int /*row*/, int /*col*/) { ASSERT(FALSE); } virtual void SetFont(const LOGFONT* /*plf*/); virtual LOGFONT* GetFont() const; virtual CFont* GetFontObject() const; protected: CSize m_Size; // Default Size CFont m_Font; // Cached font DWORD m_dwStyle; // Cell Style - unused }; //{{AFX_INSERT_LOCATION}} // Microsoft Developer Studio will insert additional declarations immediately before the previous line. #endif // !defined(AFX_GRIDCELL_H__519FA702_722C_11D1_ABBA_00A0243D1382__INCLUDED_) --- NEW FILE: GridCellNumeric.h --- // GridCellNumeric.h: interface for the CGridCellNumeric class. // // Written by Andrew Truckle [ajt...@ws...] // ////////////////////////////////////////////////////////////////////// #if !defined(AFX_GRIDINTEGERCELL_H__3479ED0D_B57D_4940_B83D_9E2296ED75B5__INCLUDED_) #define AFX_GRIDINTEGERCELL_H__3479ED0D_B57D_4940_B83D_9E2296ED75B5__INCLUDED_ #if _MSC_VER > 1000 #pragma once #endif // _MSC_VER > 1000 #include "GridCell.h" class CGridCellNumeric : public CGridCell { DECLARE_DYNCREATE(CGridCellNumeric) public: virtual BOOL Edit(int nRow, int nCol, CRect rect, CPoint point, UINT nID, UINT nChar); virtual void EndEdit(); }; #endif // !defined(AFX_GRIDINTEGERCELL_H__3479ED0D_B57D_4940_B83D_9E2296ED75B5__INCLUDED_) --- NEW FILE: CellRange.h --- /////////////////////////////////////////////////////////////////////// // CellRange.h: header file // // MFC Grid Control - interface for the CCellRange class. // // Written by Chris Maunder <cma...@ma...> // Copyright (c) 1998-2002. All Rights Reserved. // // This code may be used in compiled form in any way you desire. This // file may be redistributed unmodified by any means PROVIDING it is // not sold for profit without the authors written consent, and // providing that this notice and the authors name and all copyright // notices remains intact. // // An email letting me know how you are using it would be nice as well. // // This file is provided "as is" with no expressed or implied warranty. // The author accepts no liability for any damage/loss of business that // this product may cause. // // For use with CGridCtrl v2.20+ // ////////////////////////////////////////////////////////////////////// #if !defined(AFX_CELLRANGE_H__F86EF761_725A_11D1_ABBA_00A0243D1382__INCLUDED_) #define AFX_CELLRANGE_H__F86EF761_725A_11D1_ABBA_00A0243D1382__INCLUDED_ #if _MSC_VER >= 1000 #pragma once #endif // _MSC_VER >= 1000 // The code contained in this file is based on the original // WorldCom Grid control written by Joe Willcoxson, // mailto:chi...@ao... // http://users.aol.com/chinajoe class CCellID { // Attributes public: int row, col; // Operations public: explicit CCellID(int nRow = -1, int nCol = -1) : row(nRow), col(nCol) {} int IsValid() const { return (row >= 0 && col >= 0); } int operator==(const CCellID& rhs) const { return (row == rhs.row && col == rhs.col); } int operator!=(const CCellID& rhs) const { return !operator==(rhs); } }; class CCellRange { public: CCellRange(int nMinRow = -1, int nMinCol = -1, int nMaxRow = -1, int nMaxCol = -1) { Set(nMinRow, nMinCol, nMaxRow, nMaxCol); } void Set(int nMinRow = -1, int nMinCol = -1, int nMaxRow = -1, int nMaxCol = -1); int IsValid() const; int InRange(int row, int col) const; int InRange(const CCellID& cellID) const; int Count() { return (m_nMaxRow - m_nMinRow + 1) * (m_nMaxCol - m_nMinCol + 1); } CCellID GetTopLeft() const; CCellRange Intersect(const CCellRange& rhs) const; int GetMinRow() const {return m_nMinRow;} void SetMinRow(int minRow) {m_nMinRow = minRow;} int GetMinCol() const {return m_nMinCol;} void SetMinCol(int minCol) {m_nMinCol = minCol;} int GetMaxRow() const {return m_nMaxRow;} void SetMaxRow(int maxRow) {m_nMaxRow = maxRow;} int GetMaxCol() const {return m_nMaxCol;} void SetMaxCol(int maxCol) {m_nMaxCol = maxCol;} int GetRowSpan() const {return m_nMaxRow - m_nMinRow + 1;} int GetColSpan() const {return m_nMaxCol - m_nMinCol + 1;} void operator=(const CCellRange& rhs); int operator==(const CCellRange& rhs); int operator!=(const CCellRange& rhs); protected: int m_nMinRow; int m_nMinCol; int m_nMaxRow; int m_nMaxCol; }; inline void CCellRange::Set(int minRow, int minCol, int maxRow, int maxCol) { m_nMinRow = minRow; m_nMinCol = minCol; m_nMaxRow = maxRow; m_nMaxCol = maxCol; } inline void CCellRange::operator=(const CCellRange& rhs) { if (this != &rhs) Set(rhs.m_nMinRow, rhs.m_nMinCol, rhs.m_nMaxRow, rhs.m_nMaxCol); } inline int CCellRange::operator==(const CCellRange& rhs) { return ((m_nMinRow == rhs.m_nMinRow) && (m_nMinCol == rhs.m_nMinCol) && (m_nMaxRow == rhs.m_nMaxRow) && (m_nMaxCol == rhs.m_nMaxCol)); } inline int CCellRange::operator!=(const CCellRange& rhs) { return !operator==(rhs); } inline int CCellRange::IsValid() const { return (m_nMinRow >= 0 && m_nMinCol >= 0 && m_nMaxRow >= 0 && m_nMaxCol >= 0 && m_nMinRow <= m_nMaxRow && m_nMinCol <= m_nMaxCol); } inline int CCellRange::InRange(int row, int col) const { return (row >= m_nMinRow && row <= m_nMaxRow && col >= m_nMinCol && col <= m_nMaxCol); } inline int CCellRange::InRange(const CCellID& cellID) const { return InRange(cellID.row, cellID.col); } inline CCellID CCellRange::GetTopLeft() const { return CCellID(m_nMinRow, m_nMinCol); } inline CCellRange CCellRange::Intersect(const CCellRange& rhs) const { return CCellRange(max(m_nMinRow,rhs.m_nMinRow), max(m_nMinCol,rhs.m_nMinCol), min(m_nMaxRow,rhs.m_nMaxRow), min(m_nMaxCol,rhs.m_nMaxCol)); } #endif // !defined(AFX_CELLRANGE_H__F86EF761_725A_11D1_ABBA_00A0243D1382__INCLUDED_) --- NEW FILE: GridCellBase.cpp --- // GridCellBase.cpp : implementation file // // MFC Grid Control - Main grid cell base class // // Provides the implementation for the base cell type of the // grid control. No data is stored (except for state) but default // implementations of drawing, printingetc provided. MUST be derived // from to be used. // // Written by Chris Maunder <cma...@ma...> // Copyright (c) 1998-2002. All Rights Reserved. // // This code may be used in compiled form in any way you desire. This // file may be redistributed unmodified by any means PROVIDING it is // not sold for profit without the authors written consent, and // providing that this notice and the authors name and all copyright // notices remains intact. // // An email letting me know how you are using it would be nice as well. // // This file is provided "as is" with no expressed or implied warranty. // The author accepts no liability for any damage/loss of business that // this product may cause. // // For use with CGridCtrl v2.22+ // // History: // Ken Bertelson - 12 Apr 2000 - Split CGridCell into CGridCell and CGridCellBase // C Maunder - 19 May 2000 - Fixed sort arrow drawing (Ivan Ilinov) // C Maunder - 29 Aug 2000 - operator= checks for NULL font before setting (Martin Richter) // C Maunder - 15 Oct 2000 - GetTextExtent fixed (Martin Richter) // C Maunder - 1 Jan 2001 - Added ValidateEdit // Yogurt - 13 Mar 2004 - GetCellExtent fixed // // NOTES: Each grid cell should take care of it's own drawing, though the Draw() // method takes an "erase background" paramter that is called if the grid // decides to draw the entire grid background in on hit. Certain ambient // properties such as the default font to use, and hints on how to draw // fixed cells should be fetched from the parent grid. The grid trusts the // cells will behave in a certain way, and the cells trust the grid will // supply accurate information. // ///////////////////////////////////////////////////////////////////////////// #include "stdafx.h" #include "GridCtrl.h" #include "GridCellBase.h" #ifdef _DEBUG #define new DEBUG_NEW #undef THIS_FILE static char THIS_FILE[] = __FILE__; #endif IMPLEMENT_DYNAMIC(CGridCellBase, CObject) ///////////////////////////////////////////////////////////////////////////// // GridCellBase CGridCellBase::CGridCellBase() { Reset(); } CGridCellBase::~CGridCellBase() { } ///////////////////////////////////////////////////////////////////////////// // GridCellBase Operations void CGridCellBase::Reset() { m_nState = 0; } void CGridCellBase::operator=(const CGridCellBase& cell) { if (this == &cell) return; SetGrid(cell.GetGrid()); // do first in case of dependencies SetText(cell.GetText()); SetImage(cell.GetImage()); SetData(cell.GetData()); SetState(cell.GetState()); SetFormat(cell.GetFormat()); SetTextClr(cell.GetTextClr()); SetBackClr(cell.GetBackClr()); SetFont(cell.IsDefaultFont()? NULL : cell.GetFont()); SetMargin(cell.GetMargin()); } ///////////////////////////////////////////////////////////////////////////// // CGridCellBase Attributes // Returns a pointer to a cell that holds default values for this particular type of cell CGridCellBase* CGridCellBase::GetDefaultCell() const { if (GetGrid()) return GetGrid()->GetDefaultCell(IsFixedRow(), IsFixedCol()); return NULL; } ///////////////////////////////////////////////////////////////////////////// // CGridCellBase Operations // EFW - Various changes to make it draw cells better when using alternate // color schemes. Also removed printing references as that's now done // by PrintCell() and fixed the sort marker so that it doesn't draw out // of bounds. BOOL CGridCellBase::Draw(CDC* pDC, int nRow, int nCol, CRect rect, BOOL bEraseBkgnd /*=TRUE*/) { // Note - all through this function we totally brutalise 'rect'. Do not // depend on it's value being that which was passed in. CGridCtrl* pGrid = GetGrid(); ASSERT(pGrid); if (!pGrid || !pDC) return FALSE; if( rect.Width() <= 0 || rect.Height() <= 0) // prevents imagelist item from drawing even return FALSE; // though cell is hidden //TRACE3("Drawing %scell %d, %d\n", IsFixed()? _T("Fixed ") : _T(""), nRow, nCol); int nSavedDC = pDC->SaveDC(); pDC->SetBkMode(TRANSPARENT); // Get the default cell implementation for this kind of cell. We use it if this cell // has anything marked as "default" CGridDefaultCell *pDefaultCell = (CGridDefaultCell*) GetDefaultCell(); if (!pDefaultCell) return FALSE; // Set up text and background colours COLORREF TextClr, TextBkClr; TextClr = (GetTextClr() == CLR_DEFAULT)? pDefaultCell->GetTextClr() : GetTextClr(); if (GetBackClr() == CLR_DEFAULT) TextBkClr = pDefaultCell->GetBackClr(); else { bEraseBkgnd = TRUE; TextBkClr = GetBackClr(); } // Draw cell background and highlighting (if necessary) if ( IsFocused() || IsDropHighlighted() ) { // Always draw even in list mode so that we can tell where the // cursor is at. Use the highlight colors though. if(GetState() & GVIS_SELECTED) { TextBkClr = ::GetSysColor(COLOR_HIGHLIGHT); TextClr = ::GetSysColor(COLOR_HIGHLIGHTTEXT); bEraseBkgnd = TRUE; } rect.right++; rect.bottom++; // FillRect doesn't draw RHS or bottom if (bEraseBkgnd) { TRY { CBrush brush(TextBkClr); pDC->FillRect(rect, &brush); } CATCH(CResourceException, e) { //e->ReportError(); } END_CATCH } // Don't adjust frame rect if no grid lines so that the // whole cell is enclosed. if(pGrid->GetGridLines() != GVL_NONE) { rect.right--; rect.bottom--; } if (pGrid->GetFrameFocusCell()) { // Use same color as text to outline the cell so that it shows // up if the background is black. TRY { CBrush brush(TextClr); pDC->FrameRect(rect, &brush); } CATCH(CResourceException, e) { //e->ReportError(); } END_CATCH } pDC->SetTextColor(TextClr); // Adjust rect after frame draw if no grid lines if(pGrid->GetGridLines() == GVL_NONE) { rect.right--; rect.bottom--; } //rect.DeflateRect(0,1,1,1); - Removed by Yogurt } else if ((GetState() & GVIS_SELECTED)) { rect.right++; rect.bottom++; // FillRect doesn't draw RHS or bottom pDC->FillSolidRect(rect, ::GetSysColor(COLOR_HIGHLIGHT)); rect.right--; rect.bottom--; pDC->SetTextColor(::GetSysColor(COLOR_HIGHLIGHTTEXT)); } else { if (bEraseBkgnd) { rect.right++; rect.bottom++; // FillRect doesn't draw RHS or bottom CBrush brush(TextBkClr); pDC->FillRect(rect, &brush); rect.right--; rect.bottom--; } pDC->SetTextColor(TextClr); } // Draw lines only when wanted if (IsFixed() && pGrid->GetGridLines() != GVL_NONE) { CCellID FocusCell = pGrid->GetFocusCell(); // As above, always show current location even in list mode so // that we know where the cursor is at. BOOL bHiliteFixed = pGrid->GetTrackFocusCell() && pGrid->IsValid(FocusCell) && (FocusCell.row == nRow || FocusCell.col == nCol); // If this fixed cell is on the same row/col as the focus cell, // highlight it. if (bHiliteFixed) { rect.right++; rect.bottom++; pDC->DrawEdge(rect, BDR_SUNKENINNER /*EDGE_RAISED*/, BF_RECT); rect.DeflateRect(1,1); } else { CPen lightpen(PS_SOLID, 1, ::GetSysColor(COLOR_3DHIGHLIGHT)), darkpen(PS_SOLID, 1, ::GetSysColor(COLOR_3DDKSHADOW)), *pOldPen = pDC->GetCurrentPen(); pDC->SelectObject(&lightpen); pDC->MoveTo(rect.right, rect.top); pDC->LineTo(rect.left, rect.top); pDC->LineTo(rect.left, rect.bottom); pDC->SelectObject(&darkpen); pDC->MoveTo(rect.right, rect.top); pDC->LineTo(rect.right, rect.bottom); pDC->LineTo(rect.left, rect.bottom); pDC->SelectObject(pOldPen); rect.DeflateRect(1,1); } } // Draw Text and image #if !defined(_WIN32_WCE_NO_PRINTING) && !defined(GRIDCONTROL_NO_PRINTING) if (!pDC->m_bPrinting) #endif { CFont *pFont = GetFontObject(); ASSERT(pFont); if (pFont) pDC->SelectObject(pFont); } //rect.DeflateRect(GetMargin(), 0); - changed by Yogurt rect.DeflateRect(GetMargin(), GetMargin()); rect.right++; rect.bottom++; if (pGrid->GetImageList() && GetImage() >= 0) { IMAGEINFO Info; if (pGrid->GetImageList()->GetImageInfo(GetImage(), &Info)) { // would like to use a clipping region but seems to have issue // working with CMemDC directly. Instead, don't display image // if any part of it cut-off // // CRgn rgn; // rgn.CreateRectRgnIndirect(rect); // pDC->SelectClipRgn(&rgn); // rgn.DeleteObject(); /* // removed by Yogurt int nImageWidth = Info.rcImage.right-Info.rcImage.left+1; int nImageHeight = Info.rcImage.bottom-Info.rcImage.top+1; if( nImageWidth + rect.left <= rect.right + (int)(2*GetMargin()) && nImageHeight + rect.top <= rect.bottom + (int)(2*GetMargin()) ) { pGrid->GetImageList()->Draw(pDC, GetImage(), rect.TopLeft(), ILD_NORMAL); } */ // Added by Yogurt int nImageWidth = Info.rcImage.right-Info.rcImage.left; int nImageHeight = Info.rcImage.bottom-Info.rcImage.top; if ((nImageWidth + rect.left <= rect.right) && (nImageHeight + rect.top <= rect.bottom)) pGrid->GetImageList()->Draw(pDC, GetImage(), rect.TopLeft(), ILD_NORMAL); //rect.left += nImageWidth+GetMargin(); } } // Draw sort arrow if (pGrid->GetSortColumn() == nCol && nRow == 0) { CSize size = pDC->GetTextExtent(_T("M")); int nOffset = 2; // Base the size of the triangle on the smaller of the column // height or text height with a slight offset top and bottom. // Otherwise, it can get drawn outside the bounds of the cell. size.cy -= (nOffset * 2); if (size.cy >= rect.Height()) size.cy = rect.Height() - (nOffset * 2); size.cx = size.cy; // Make the dimensions square // Kludge for vertical text BOOL bVertical = (GetFont()->lfEscapement == 900); // Only draw if it'll fit! //if (size.cx + rect.left < rect.right + (int)(2*GetMargin())) - changed / Yogurt if (size.cx + rect.left < rect.right) { int nTriangleBase = rect.bottom - nOffset - size.cy; // Triangle bottom right //int nTriangleBase = (rect.top + rect.bottom - size.cy)/2; // Triangle middle right //int nTriangleBase = rect.top + nOffset; // Triangle top right //int nTriangleLeft = rect.right - size.cx; // Triangle RHS //int nTriangleLeft = (rect.right + rect.left - size.cx)/2; // Triangle middle //int nTriangleLeft = rect.left; // Triangle LHS int nTriangleLeft; if (bVertical) nTriangleLeft = (rect.right + rect.left - size.cx)/2; // Triangle middle else nTriangleLeft = rect.right - size.cx; // Triangle RHS CPen penShadow(PS_SOLID, 0, ::GetSysColor(COLOR_3DSHADOW)); CPen penLight(PS_SOLID, 0, ::GetSysColor(COLOR_3DHILIGHT)); if (pGrid->GetSortAscending()) { // Draw triangle pointing upwards CPen *pOldPen = (CPen*) pDC->SelectObject(&penLight); pDC->MoveTo( nTriangleLeft + 1, nTriangleBase + size.cy + 1); pDC->LineTo( nTriangleLeft + (size.cx / 2) + 1, nTriangleBase + 1 ); pDC->LineTo( nTriangleLeft + size.cx + 1, nTriangleBase + size.cy + 1); pDC->LineTo( nTriangleLeft + 1, nTriangleBase + size.cy + 1); pDC->SelectObject(&penShadow); pDC->MoveTo( nTriangleLeft, nTriangleBase + size.cy ); pDC->LineTo( nTriangleLeft + (size.cx / 2), nTriangleBase ); pDC->LineTo( nTriangleLeft + size.cx, nTriangleBase + size.cy ); pDC->LineTo( nTriangleLeft, nTriangleBase + size.cy ); pDC->SelectObject(pOldPen); } else { // Draw triangle pointing downwards CPen *pOldPen = (CPen*) pDC->SelectObject(&penLight); pDC->MoveTo( nTriangleLeft + 1, nTriangleBase + 1 ); pDC->LineTo( nTriangleLeft + (size.cx / 2) + 1, nTriangleBase + size.cy + 1 ); pDC->LineTo( nTriangleLeft + size.cx + 1, nTriangleBase + 1 ); pDC->LineTo( nTriangleLeft + 1, nTriangleBase + 1 ); pDC->SelectObject(&penShadow); pDC->MoveTo( nTriangleLeft, nTriangleBase ); pDC->LineTo( nTriangleLeft + (size.cx / 2), nTriangleBase + size.cy ); pDC->LineTo( nTriangleLeft + size.cx, nTriangleBase ); pDC->LineTo( nTriangleLeft, nTriangleBase ); pDC->SelectObject(pOldPen); } if (!bVertical) rect.right -= size.cy; } } // We want to see '&' characters so use DT_NOPREFIX GetTextRect(rect); rect.right++; rect.bottom++; DrawText(pDC->m_hDC, GetText(), -1, rect, GetFormat() | DT_NOPREFIX); pDC->RestoreDC(nSavedDC); return TRUE; } ///////////////////////////////////////////////////////////////////////////// // CGridCellBase Mouse and Cursor events // Not yet implemented void CGridCellBase::OnMouseEnter() { TRACE0("Mouse entered cell\n"); } void CGridCellBase::OnMouseOver() { //TRACE0("Mouse over cell\n"); } // Not Yet Implemented void CGridCellBase::OnMouseLeave() { TRACE0("Mouse left cell\n"); } void CGridCellBase::OnClick( CPoint PointCellRelative) { UNUSED_ALWAYS(PointCellRelative); TRACE2("Mouse Left btn up in cell at x=%i y=%i\n", PointCellRelative.x, PointCellRelative.y); } void CGridCellBase::OnClickDown( CPoint PointCellRelative) { UNUSED_ALWAYS(PointCellRelative); TRACE2("Mouse Left btn down in cell at x=%i y=%i\n", PointCellRelative.x, PointCellRelative.y); } void CGridCellBase::OnRClick( CPoint PointCellRelative) { UNUSED_ALWAYS(PointCellRelative); TRACE2("Mouse right-clicked in cell at x=%i y=%i\n", PointCellRelative.x, PointCellRelative.y); } void CGridCellBase::OnDblClick( CPoint PointCellRelative) { UNUSED_ALWAYS(PointCellRelative); TRACE2("Mouse double-clicked in cell at x=%i y=%i\n", PointCellRelative.x, PointCellRelative.y); } // Return TRUE if you set the cursor BOOL CGridCellBase::OnSetCursor() { #ifndef _WIN32_WCE_NO_CURSOR SetCursor(AfxGetApp()->LoadStandardCursor(IDC_ARROW)); #endif return TRUE; } ///////////////////////////////////////////////////////////////////////////// // CGridCellBase editing void CGridCellBase::OnEndEdit() { ASSERT( FALSE); } BOOL CGridCellBase::ValidateEdit(LPCTSTR str) { UNUSED_ALWAYS(str); return TRUE; } ///////////////////////////////////////////////////////////////////////////// // CGridCellBase Sizing BOOL CGridCellBase::GetTextRect( LPRECT pRect) // i/o: i=dims of cell rect; o=dims of text rect { if (GetImage() >= 0) { IMAGEINFO Info; CGridCtrl* pGrid = GetGrid(); CImageList* pImageList = pGrid->GetImageList(); if (pImageList && pImageList->GetImageInfo( GetImage(), &Info)) { int nImageWidth = Info.rcImage.right-Info.rcImage.left; //+1; pRect->left += nImageWidth + GetMargin(); } } return TRUE; } // By default this uses the selected font (which is a bigger font) CSize CGridCellBase::GetTextExtent(LPCTSTR szText, CDC* pDC /*= NULL*/) { CGridCtrl* pGrid = GetGrid(); ASSERT(pGrid); BOOL bReleaseDC = FALSE; if (pDC == NULL || szText == NULL) { if (szText) pDC = pGrid->GetDC(); if (pDC == NULL || szText == NULL) { CGridDefaultCell* pDefCell = (CGridDefaultCell*) GetDefaultCell(); ASSERT(pDefCell); return CSize(pDefCell->GetWidth(), pDefCell->GetHeight()); } bReleaseDC = TRUE; } CFont *pOldFont = NULL, *pFont = GetFontObject(); if (pFont) pOldFont = pDC->SelectObject(pFont); CSize size; int nFormat = GetFormat(); // If the cell is a multiline cell, then use the width of the cell // to get the height if ((nFormat & DT_WORDBREAK) && !(nFormat & DT_SINGLELINE)) { CString str = szText; int nMaxWidth = 0; while (TRUE) { int nPos = str.Find(_T('\n')); CString TempStr = (nPos < 0)? str : str.Left(nPos); int nTempWidth = pDC->GetTextExtent(TempStr).cx; if (nTempWidth > nMaxWidth) nMaxWidth = nTempWidth; if (nPos < 0) break; str = str.Mid(nPos + 1); // Bug fix by Thomas Steinborn } CRect rect; rect.SetRect(0,0, nMaxWidth+1, 0); pDC->DrawText(szText, -1, rect, nFormat | DT_CALCRECT); size = rect.Size(); } else size = pDC->GetTextExtent(szText, _tcslen(szText)); // Removed by Yogurt //TEXTMETRIC tm; //pDC->GetTextMetrics(&tm); //size.cx += (tm.tmOverhang); if (pOldFont) pDC->SelectObject(pOldFont); size += CSize(2*GetMargin(), 2*GetMargin()); // Kludge for vertical text LOGFONT *pLF = GetFont(); if (pLF->lfEscapement == 900 || pLF->lfEscapement == -900) { int nTemp = size.cx; size.cx = size.cy; size.cy = nTemp; size += CSize(0, 4*GetMargin()); } if (bReleaseDC) pGrid->ReleaseDC(pDC); return size; } CSize CGridCellBase::GetCellExtent(CDC* pDC) { CSize size = GetTextExtent(GetText(), pDC); CSize ImageSize(0... [truncated message content] |